├── .gitignore
├── LICENSE
├── README.md
├── index.html
├── javascripts
├── autoComplete.js
├── autoCompleteView.js
├── compilationService.js
├── documentPositionUtil.js
├── editorPosition.js
├── fileService.js
├── lib
│ ├── ace
│ │ ├── ace.js
│ │ ├── mode-javascript.js
│ │ ├── mode-typescript.js
│ │ ├── theme-monokai.js
│ │ ├── worker-javascript.js
│ │ └── worker-typescript.js
│ ├── jquery-1.8.2.min.js
│ └── typescript
│ │ └── typescriptServices.js
├── lightHarness.js
└── main.js
├── samples
├── animal.ts
├── greeter.ts
└── raytracer.ts
├── src
├── coffee
│ ├── autoCompleteView.coffee
│ ├── compilationService.coffee
│ ├── documentPositionUtil.coffee
│ ├── editorPosition.coffee
│ └── fileService.coffee
└── typescript-mode
│ ├── typescript.js
│ └── typescript
│ ├── DocumentPositionUtil.js
│ ├── lightHarness.js
│ └── typescriptServices.js
├── stylesheets
├── bootstrap.min.css
└── style.css
└── typescripts
└── lib.d.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | *#
2 | #*
3 | *~
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012 Hitoshi Nakada
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | TypeScript Playground on Ace
2 | ==========================
3 | TypeScript Playground build on ace editor
4 |
5 | https://hi104.github.io/typescript-playground-on-ace/
6 |
7 | See Also
8 | -----------------
9 |
10 | TypeScript Playground
11 | http://www.typescriptlang.org/Playground/
12 |
13 | Ace
14 | http://ace.ajax.org
15 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Typescript playground on ace editor
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
TypeScript Playground on Ace Editor
14 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
typescript
32 |
33 |
34 |
35 | Walkthrough:Classes
36 | Raytracer
37 | Simple inheritance
38 |
39 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
50 |
51 |
54 |
55 |
javascript
56 |
57 |
58 |
59 |
63 |
64 |
65 |
66 |
69 |
70 |
71 |
72 |
73 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/javascripts/autoComplete.js:
--------------------------------------------------------------------------------
1 | define('autocomplete', ['require', 'exports', 'module', 'ace/keyboard/hash_handler'], function(require, exports, module) {
2 |
3 | var HashHandler = require('ace/keyboard/hash_handler').HashHandler;
4 | var EventEmitter = require("ace/lib/event_emitter").EventEmitter;
5 | var AutoCompleteView = require('AutoCompleteView').AutoCompleteView;
6 |
7 | var oop = require("ace/lib/oop");
8 |
9 | exports.AutoComplete = function(editor,script, compilationService){
10 |
11 | var self = this;
12 |
13 | oop.implement(self, EventEmitter);
14 | this.handler = new HashHandler();
15 | this.view = new AutoCompleteView(editor, self);
16 | this.scriptName = script;
17 | this._active = false;
18 | this.inputText =''; //TODO imporve name
19 |
20 | this.isActive = function () {
21 | return self._active;
22 | };
23 |
24 | this.setScriptName = function (name){
25 | self.scriptName = name;
26 | };
27 |
28 | this.show = function () {
29 | self.listElement = self.view.listElement;
30 | editor.container.appendChild(self.view.wrap);
31 | self.listElement.innerHTML = '';
32 | };
33 |
34 | this.compilation = function(cursor){
35 | var compilationInfo = compilationService.getCursorCompilation(self.scriptName, cursor);
36 | var text = compilationService.matchText;
37 | var coords = editor.renderer.textToScreenCoordinates(cursor.row, cursor.column - text.length);
38 |
39 | self.view.setPosition(coords);
40 | self.inputText = text;
41 |
42 | var compilations = compilationInfo.entries;
43 |
44 | if (self.inputText.length > 0){
45 | compilations = compilationInfo.entries.filter(function(elm){
46 | return elm.name.toLowerCase().indexOf(self.inputText.toLowerCase()) == 0 ;
47 | });
48 | }
49 |
50 | var matchFunc = function(elm) {
51 | return elm.name.indexOf(self.inputText) == 0 ? 1 : 0;
52 | };
53 |
54 | var matchCompare = function(a, b){
55 | return matchFunc(b) - matchFunc(a);
56 | };
57 |
58 | var textCompare = function(a, b){
59 | if (a.name == b.name){
60 | return 0;
61 | }else{
62 | return (a.name > b.name) ? 1 : -1;
63 | }
64 | };
65 | var compare = function(a, b){
66 | var ret = matchCompare(a, b);
67 | return (ret != 0) ? ret : textCompare(a, b);
68 | };
69 |
70 | compilations = compilations.sort(compare);
71 |
72 | self.showCompilation(compilations);
73 |
74 | return compilations.length;
75 | };
76 |
77 | this.refreshCompilation = function(e){
78 | var cursor = editor.getCursorPosition();
79 | if(e.data.action == "insertText"){
80 | cursor.column += 1;
81 | } else if (e.data.action == "removeText"){
82 | if(e.data.text == '\n'){
83 | self.deactivate();
84 | return;
85 | }
86 | }
87 |
88 | self.compilation(cursor);
89 | };
90 |
91 | this.showCompilation = function(infos){
92 | if (infos.length > 0){
93 | self.view.show();
94 | var html = '';
95 | // TODO use template
96 | for(var n in infos) {
97 | var info = infos[n];
98 | var name = '' + info.name + ' ';
99 | var type = '' + info.type + ' ';
100 | var kind = '' + info.kind.charAt(0) + ' ';
101 |
102 | html += '' + kind + name + type + ' ';
103 | }
104 | self.listElement.innerHTML = html;
105 | self.view.ensureFocus();
106 | }else{
107 | self.view.hide();
108 | }
109 | };
110 |
111 | this.active = function () {
112 | self.show();
113 | var count = self.compilation(editor.getCursorPosition());
114 | if(!(count > 0)){
115 | self.hide();
116 | return;
117 | }
118 | editor.keyBinding.addKeyboardHandler(self.handler);
119 | };
120 |
121 | this.deactivate = function() {
122 | editor.keyBinding.removeKeyboardHandler(self.handler);
123 | };
124 |
125 | this.handler.attach = function(){
126 | editor.addEventListener("change", self.refreshCompilation);
127 | self._emit("attach", {sender: self});
128 | self._active = true;
129 | };
130 |
131 | this.handler.detach = function(){
132 | editor.removeEventListener("change", self.refreshCompilation);
133 | self.view.hide();
134 | self._emit("detach", {sender: self});
135 | self._active = false;
136 | };
137 |
138 | this.handler.handleKeyboard = function(data, hashId, key, keyCode) {
139 | if (hashId == -1) {
140 |
141 | if(" -=,[]_/()!';:<>".indexOf(key) != -1){ //TODO
142 | self.deactivate();
143 | }
144 | return null;
145 | }
146 |
147 | var command = self.handler.findKeyCommand(hashId, key);
148 |
149 | if (!command){
150 |
151 | var defaultCommand = editor.commands.findKeyCommand(hashId, key);
152 | if(defaultCommand){
153 | if(defaultCommand.name == "backspace"){
154 | return null;
155 | }
156 | self.deactivate();
157 | }
158 | return null;
159 | }
160 |
161 | if (typeof command != "string") {
162 | var args = command.args;
163 | command = command.command;
164 | }
165 |
166 | if (typeof command == "string") {
167 | command = this.commands[command];
168 | }
169 |
170 | return {command: command, args: args};
171 | };
172 |
173 |
174 | exports.Keybinding = {
175 | "Up|Ctrl-p" : "focusprev",
176 | "Down|Ctrl-n" : "focusnext",
177 | "esc|Ctrl-g" : "cancel",
178 | "Return|Tab": "insertComplete"
179 | };
180 |
181 | this.handler.bindKeys(exports.Keybinding);
182 |
183 | this.handler.addCommands({
184 | focusnext:function(editor){
185 | self.view.focusNext();
186 | },
187 | focusprev:function(editor){
188 | self.view.focusPrev();
189 | },
190 | cancel:function(editor){
191 | self.deactivate();
192 | },
193 | insertComplete:function(editor){
194 | editor.removeEventListener("change", self.refreshCompilation);
195 | var curr = self.view.current();
196 |
197 | for(var i = 0; i< self.inputText.length; i++){
198 | editor.remove("left");
199 | }
200 |
201 | if(curr){
202 | editor.insert($(curr).data("name"));
203 | }
204 | self.deactivate();
205 |
206 | }
207 | });
208 | };
209 | });
--------------------------------------------------------------------------------
/javascripts/autoCompleteView.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
3 |
4 | define('AutoCompleteView', ['require', 'exports', 'module'], function(require, exports, module) {
5 | var AutoCompleteView, selectedClassName;
6 | selectedClassName = 'ace_autocomplete_selected';
7 | AutoCompleteView = (function() {
8 |
9 | function AutoCompleteView(editor, autoComplete) {
10 | this.editor = editor;
11 | this.autoComplete = autoComplete;
12 | this.init = __bind(this.init, this);
13 | this.init();
14 | }
15 |
16 | AutoCompleteView.prototype.init = function() {
17 | this.wrap = document.createElement('div');
18 | this.listElement = document.createElement('ul');
19 | this.wrap.className = 'ace_autocomplete';
20 | this.wrap.style.display = 'none';
21 | this.listElement.style.listStyleType = 'none';
22 | this.wrap.style.position = 'fixed';
23 | this.wrap.style.zIndex = '1000';
24 | return this.wrap.appendChild(this.listElement);
25 | };
26 |
27 | AutoCompleteView.prototype.show = function() {
28 | return this.wrap.style.display = 'block';
29 | };
30 |
31 | AutoCompleteView.prototype.hide = function() {
32 | return this.wrap.style.display = 'none';
33 | };
34 |
35 | AutoCompleteView.prototype.setPosition = function(coords) {
36 | var bottom, editorBottom, top;
37 | top = coords.pageY + 20;
38 | editorBottom = $(this.editor.container).offset().top + $(this.editor.container).height();
39 | bottom = top + $(this.wrap).height();
40 | if (bottom < editorBottom) {
41 | this.wrap.style.top = top + 'px';
42 | return this.wrap.style.left = coords.pageX + 'px';
43 | } else {
44 | this.wrap.style.top = (top - $(this.wrap).height() - 20) + 'px';
45 | return this.wrap.style.left = coords.pageX + 'px';
46 | }
47 | };
48 |
49 | AutoCompleteView.prototype.current = function() {
50 | var child, children, i;
51 | children = this.listElement.childNodes;
52 | for (i in children) {
53 | child = children[i];
54 | if (child.className === selectedClassName) return child;
55 | }
56 | return null;
57 | };
58 |
59 | AutoCompleteView.prototype.focusNext = function() {
60 | var curr, focus;
61 | curr = this.current();
62 | focus = curr.nextSibling;
63 | if (focus) {
64 | curr.className = '';
65 | focus.className = selectedClassName;
66 | return this.adjustPosition();
67 | }
68 | };
69 |
70 | AutoCompleteView.prototype.focusPrev = function() {
71 | var curr, focus;
72 | curr = this.current();
73 | focus = curr.previousSibling;
74 | if (focus) {
75 | curr.className = '';
76 | focus.className = selectedClassName;
77 | return this.adjustPosition();
78 | }
79 | };
80 |
81 | AutoCompleteView.prototype.ensureFocus = function() {
82 | if (!this.current()) {
83 | if (this.listElement.firstChild) {
84 | this.listElement.firstChild.className = selectedClassName;
85 | return this.adjustPosition();
86 | }
87 | }
88 | };
89 |
90 | AutoCompleteView.prototype.adjustPosition = function() {
91 | var elm, elmOuterHeight, newMargin, pos, preMargin, wrapHeight;
92 | elm = this.current();
93 | if (elm) {
94 | newMargin = '';
95 | wrapHeight = $(this.wrap).height();
96 | elmOuterHeight = $(elm).outerHeight();
97 | preMargin = $(this.listElement).css("margin-top").replace('px', '');
98 | preMargin = parseInt(preMargin);
99 | pos = $(elm).position();
100 | if (pos.top >= (wrapHeight - elmOuterHeight)) {
101 | newMargin = (preMargin - elmOuterHeight) + 'px';
102 | $(this.listElement).css("margin-top", newMargin);
103 | }
104 | if (pos.top < 0) {
105 | newMargin = (-pos.top + preMargin) + 'px';
106 | return $(this.listElement).css("margin-top", newMargin);
107 | }
108 | }
109 | };
110 |
111 | return AutoCompleteView;
112 |
113 | })();
114 | exports.AutoCompleteView = AutoCompleteView;
115 | return exports;
116 | });
117 |
118 | }).call(this);
119 |
--------------------------------------------------------------------------------
/javascripts/compilationService.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
3 |
4 | define('CompilationService', ['require', 'exports', 'module', 'EditorPosition'], function(require, exports, module) {
5 | var CompilationService, EditorPosition;
6 | EditorPosition = require('EditorPosition').EditorPosition;
7 | CompilationService = (function() {
8 |
9 | function CompilationService(editor, ServiceShim) {
10 | this.editor = editor;
11 | this.ServiceShim = ServiceShim;
12 | this.getCurrentPositionCompilation = __bind(this.getCurrentPositionCompilation, this);
13 | this.getCursorCompilation = __bind(this.getCursorCompilation, this);
14 | this.getCompilation = __bind(this.getCompilation, this);
15 | this.editorPos = new EditorPosition(this.editor);
16 | }
17 |
18 | CompilationService.prototype.getCompilation = function(script, charpos, isMemberCompletion) {
19 | var compInfo;
20 | compInfo = this.ServiceShim.languageService.getCompletionsAtPosition(script, charpos, isMemberCompletion);
21 | return compInfo;
22 | };
23 |
24 | CompilationService.prototype.getCursorCompilation = function(script, cursor) {
25 | var isMemberCompletion, matches, pos, text;
26 | pos = this.editorPos.getPositionChars(cursor);
27 | text = this.editor.session.getLine(cursor.row).slice(0, cursor.column);
28 | isMemberCompletion = false;
29 | matches = text.match(/\.([a-zA-Z_0-9\$]*$)/);
30 | if (matches && matches.length > 0) {
31 | this.matchText = matches[1];
32 | isMemberCompletion = true;
33 | pos -= this.matchText.length;
34 | } else {
35 | matches = text.match(/[a-zA-Z_0-9\$]*$/);
36 | this.matchText = matches[0];
37 | }
38 | return this.getCompilation(script, pos, isMemberCompletion);
39 | };
40 |
41 | CompilationService.prototype.getCurrentPositionCompilation = function(script) {
42 | return this.getCursorCompilation(script, this.editor.getCursorPosition());
43 | };
44 |
45 | return CompilationService;
46 |
47 | })();
48 | exports.CompilationService = CompilationService;
49 | return exports;
50 | });
51 |
52 | }).call(this);
53 |
--------------------------------------------------------------------------------
/javascripts/documentPositionUtil.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | define('DocumentPositionUtil', ['require', 'exports', 'module'], function(require, exports, module) {
4 | var DocumentPositionUtil;
5 | DocumentPositionUtil = (function() {
6 |
7 | function DocumentPositionUtil() {}
8 |
9 | DocumentPositionUtil.getLinesChars = function(lines) {
10 | var count,
11 | _this = this;
12 | count = 0;
13 | lines.forEach(function(line) {
14 | return count += line.length + 1;
15 | });
16 | return count;
17 | };
18 |
19 | DocumentPositionUtil.getChars = function(doc, pos) {
20 | return this.getLinesChars(doc.getLines(0, pos.row - 1)) + pos.column;
21 | };
22 |
23 | DocumentPositionUtil.getPosition = function(doc, chars) {
24 | var count, i, line, lines, row;
25 | lines = doc.getAllLines();
26 | count = 0;
27 | row = 0;
28 | for (i in lines) {
29 | line = lines[i];
30 | if (chars < (count + (line.length + 1))) {
31 | return {
32 | row: row,
33 | column: chars - count
34 | };
35 | }
36 | count += line.length + 1;
37 | row += 1;
38 | }
39 | return {
40 | row: row,
41 | column: chars - count
42 | };
43 | };
44 |
45 | return DocumentPositionUtil;
46 |
47 | })();
48 | exports.DocumentPositionUtil = DocumentPositionUtil;
49 | return exports;
50 | });
51 |
52 | }).call(this);
53 |
--------------------------------------------------------------------------------
/javascripts/editorPosition.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
3 |
4 | define('EditorPosition', ['require', 'exports', 'module'], function(require, exports, module) {
5 | var DocumentPositionUtil, EditorPosition;
6 | DocumentPositionUtil = require('DocumentPositionUtil').DocumentPositionUtil;
7 | EditorPosition = (function() {
8 |
9 | function EditorPosition(editor) {
10 | this.editor = editor;
11 | this.getPositionLeftChar = __bind(this.getPositionLeftChar, this);
12 | this.getPositionChar = __bind(this.getPositionChar, this);
13 | this.getCurrentLeftChar = __bind(this.getCurrentLeftChar, this);
14 | this.getCurrentCharPosition = __bind(this.getCurrentCharPosition, this);
15 | this.getAcePositionFromChars = __bind(this.getAcePositionFromChars, this);
16 | this.getPositionChars = __bind(this.getPositionChars, this);
17 | }
18 |
19 | EditorPosition.prototype.getLinesChars = function(lines) {
20 | return DocumentPositionUtil.getLinesChars(lines);
21 | };
22 |
23 | EditorPosition.prototype.getPositionChars = function(pos) {
24 | var doc;
25 | doc = this.editor.getSession().getDocument();
26 | return DocumentPositionUtil.getChars(doc, pos);
27 | };
28 |
29 | EditorPosition.prototype.getAcePositionFromChars = function(chars) {
30 | var doc;
31 | doc = this.editor.getSession().getDocument();
32 | return DocumentPositionUtil.getPosition(doc, chars);
33 | };
34 |
35 | EditorPosition.prototype.getCurrentCharPosition = function() {
36 | return this.getPositionChars(this.editor.getCursorPosition());
37 | };
38 |
39 | EditorPosition.prototype.getCurrentLeftChar = function() {
40 | return this.getPositionLeftChar(this.editor.getCursorPosition());
41 | };
42 |
43 | EditorPosition.prototype.getPositionChar = function(cursor) {
44 | var range;
45 | range = {
46 | start: {
47 | row: cursor.row,
48 | column: cursor.column
49 | },
50 | end: {
51 | row: cursor.row,
52 | column: cursor.column + 1
53 | }
54 | };
55 | return this.editor.getSession().getDocument().getTextRange(range);
56 | };
57 |
58 | EditorPosition.prototype.getPositionLeftChar = function(cursor) {
59 | var range;
60 | range = {
61 | start: {
62 | row: cursor.row,
63 | column: cursor.column
64 | },
65 | end: {
66 | row: cursor.row,
67 | column: cursor.column - 1
68 | }
69 | };
70 | return this.editor.getSession().getDocument().getTextRange(range);
71 | };
72 |
73 | return EditorPosition;
74 |
75 | })();
76 | exports.EditorPosition = EditorPosition;
77 | return exports;
78 | });
79 |
80 | }).call(this);
81 |
--------------------------------------------------------------------------------
/javascripts/fileService.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
3 |
4 | define('FileService', ['require', 'exports', 'module'], function(require, exports, module) {
5 | var FileService;
6 | FileService = (function() {
7 |
8 | function FileService(ajaxHost) {
9 | this.ajaxHost = ajaxHost;
10 | this.getInfo = __bind(this.getInfo, this);
11 | this.writeFile = __bind(this.writeFile, this);
12 | this.readFile = __bind(this.readFile, this);
13 | }
14 |
15 | FileService.prototype.readFile = function(path, cb) {
16 | var _this = this;
17 | return this.ajaxHost.ajax({
18 | type: "GET",
19 | url: path,
20 | success: cb,
21 | error: (function(jqXHR, textStatus) {
22 | return console.log(textStatus);
23 | })
24 | });
25 | };
26 |
27 | FileService.prototype.writeFile = function(path, content, cb) {
28 | var _this = this;
29 | return this.ajaxHost.ajax({
30 | type: "POST",
31 | url: path,
32 | data: {
33 | content: content
34 | },
35 | success: cb,
36 | error: (function(jqXHR, textStatus) {
37 | return console.log(textStatus);
38 | })
39 | });
40 | };
41 |
42 | FileService.prototype.getInfo = function() {};
43 |
44 | return FileService;
45 |
46 | })();
47 | exports.FileService = FileService;
48 | return exports;
49 | });
50 |
51 | }).call(this);
52 |
--------------------------------------------------------------------------------
/javascripts/lib/ace/mode-javascript.js:
--------------------------------------------------------------------------------
1 | /* ***** BEGIN LICENSE BLOCK *****
2 | * Distributed under the BSD license:
3 | *
4 | * Copyright (c) 2010, Ajax.org B.V.
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of Ajax.org B.V. nor the
15 | * names of its contributors may be used to endorse or promote products
16 | * derived from this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 | *
29 | * ***** END LICENSE BLOCK ***** */
30 |
31 | define('ace/mode/javascript', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/javascript_highlight_rules', 'ace/mode/matching_brace_outdent', 'ace/range', 'ace/worker/worker_client', 'ace/mode/behaviour/cstyle', 'ace/mode/folding/cstyle'], function(require, exports, module) {
32 |
33 |
34 | var oop = require("../lib/oop");
35 | var TextMode = require("./text").Mode;
36 | var Tokenizer = require("../tokenizer").Tokenizer;
37 | var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules;
38 | var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
39 | var Range = require("../range").Range;
40 | var WorkerClient = require("../worker/worker_client").WorkerClient;
41 | var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
42 | var CStyleFoldMode = require("./folding/cstyle").FoldMode;
43 |
44 | var Mode = function() {
45 | this.$tokenizer = new Tokenizer(new JavaScriptHighlightRules().getRules());
46 | this.$outdent = new MatchingBraceOutdent();
47 | this.$behaviour = new CstyleBehaviour();
48 | this.foldingRules = new CStyleFoldMode();
49 | };
50 | oop.inherits(Mode, TextMode);
51 |
52 | (function() {
53 |
54 |
55 | this.toggleCommentLines = function(state, doc, startRow, endRow) {
56 | var outdent = true;
57 | var re = /^(\s*)\/\//;
58 |
59 | for (var i=startRow; i<= endRow; i++) {
60 | if (!re.test(doc.getLine(i))) {
61 | outdent = false;
62 | break;
63 | }
64 | }
65 |
66 | if (outdent) {
67 | var deleteRange = new Range(0, 0, 0, 0);
68 | for (var i=startRow; i<= endRow; i++)
69 | {
70 | var line = doc.getLine(i);
71 | var m = line.match(re);
72 | deleteRange.start.row = i;
73 | deleteRange.end.row = i;
74 | deleteRange.end.column = m[0].length;
75 | doc.replace(deleteRange, m[1]);
76 | }
77 | }
78 | else {
79 | doc.indentRows(startRow, endRow, "//");
80 | }
81 | };
82 |
83 | this.getNextLineIndent = function(state, line, tab) {
84 | var indent = this.$getIndent(line);
85 |
86 | var tokenizedLine = this.$tokenizer.getLineTokens(line, state);
87 | var tokens = tokenizedLine.tokens;
88 | var endState = tokenizedLine.state;
89 |
90 | if (tokens.length && tokens[tokens.length-1].type == "comment") {
91 | return indent;
92 | }
93 |
94 | if (state == "start" || state == "regex_allowed") {
95 | var match = line.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);
96 | if (match) {
97 | indent += tab;
98 | }
99 | } else if (state == "doc-start") {
100 | if (endState == "start" || state == "regex_allowed") {
101 | return "";
102 | }
103 | var match = line.match(/^\s*(\/?)\*/);
104 | if (match) {
105 | if (match[1]) {
106 | indent += " ";
107 | }
108 | indent += "* ";
109 | }
110 | }
111 |
112 | return indent;
113 | };
114 |
115 | this.checkOutdent = function(state, line, input) {
116 | return this.$outdent.checkOutdent(line, input);
117 | };
118 |
119 | this.autoOutdent = function(state, doc, row) {
120 | this.$outdent.autoOutdent(doc, row);
121 | };
122 |
123 | this.createWorker = function(session) {
124 | var worker = new WorkerClient(["ace"], "ace/mode/javascript_worker", "JavaScriptWorker");
125 | worker.attachToDocument(session.getDocument());
126 |
127 | worker.on("jslint", function(results) {
128 | session.setAnnotations(results.data);
129 | });
130 |
131 | worker.on("terminate", function() {
132 | session.clearAnnotations();
133 | });
134 |
135 | return worker;
136 | };
137 |
138 | }).call(Mode.prototype);
139 |
140 | exports.Mode = Mode;
141 | });
142 |
143 | define('ace/mode/javascript_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/doc_comment_highlight_rules', 'ace/mode/text_highlight_rules'], function(require, exports, module) {
144 |
145 |
146 | var oop = require("../lib/oop");
147 | var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
148 | var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
149 |
150 | var JavaScriptHighlightRules = function() {
151 | // see: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects
152 | var keywordMapper = this.createKeywordMapper({
153 | "variable.language":
154 | "Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|" + // Constructors
155 | "Namespace|QName|XML|XMLList|" + // E4X
156 | "ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|" +
157 | "Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|" +
158 | "Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|" + // Errors
159 | "SyntaxError|TypeError|URIError|" +
160 | "decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|" + // Non-constructor functions
161 | "isNaN|parseFloat|parseInt|" +
162 | "JSON|Math|" + // Other
163 | "this|arguments|prototype|window|document" , // Pseudo
164 | "invalid.deprecated":
165 | "__parent__|__count__|escape|unescape|with|__proto__",
166 | "keyword":
167 | "const|yield|import|get|set" +
168 | "break|case|catch|continue|default|delete|do|else|finally|for|function|" +
169 | "if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger",
170 | "storage.type":
171 | "const|let|var|function",
172 | "invalid.illegal":
173 | "class|enum|extends|super|export|implements|private|" +
174 | "public|interface|package|protected|static",
175 | "constant.language":
176 | "null|Infinity|NaN|undefined",
177 | "support.function":
178 | "alert"
179 | }, "identifier");
180 |
181 | // keywords which can be followed by regular expressions
182 | var kwBeforeRe = "case|do|else|finally|in|instanceof|return|throw|try|typeof|yield";
183 |
184 | // TODO: Unicode escape sequences
185 | var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b";
186 |
187 | var escapedRe = "\\\\(?:x[0-9a-fA-F]{2}|" + // hex
188 | "u[0-9a-fA-F]{4}|" + // unicode
189 | "[0-2][0-7]{0,2}|" + // oct
190 | "3[0-6][0-7]?|" + // oct
191 | "37[0-7]?|" + // oct
192 | "[4-7][0-7]?|" + //oct
193 | ".)";
194 |
195 | // regexp must not have capturing parentheses. Use (?:) instead.
196 | // regexps are ordered -> the first match is used
197 |
198 | this.$rules = {
199 | "start" : [
200 | {
201 | token : "comment",
202 | regex : /\/\/.*$/
203 | },
204 | DocCommentHighlightRules.getStartRule("doc-start"),
205 | {
206 | token : "comment", // multi line comment
207 | merge : true,
208 | regex : /\/\*/,
209 | next : "comment"
210 | }, {
211 | token : "string",
212 | regex : "'(?=.)",
213 | next : "qstring"
214 | }, {
215 | token : "string",
216 | regex : '"(?=.)',
217 | next : "qqstring"
218 | }, {
219 | token : "constant.numeric", // hex
220 | regex : /0[xX][0-9a-fA-F]+\b/
221 | }, {
222 | token : "constant.numeric", // float
223 | regex : /[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/
224 | }, {
225 | // Sound.prototype.play =
226 | token : [
227 | "storage.type", "punctuation.operator", "support.function",
228 | "punctuation.operator", "entity.name.function", "text","keyword.operator"
229 | ],
230 | regex : "(" + identifierRe + ")(\\.)(prototype)(\\.)(" + identifierRe +")(\\s*)(=)",
231 | next: "function_arguments"
232 | }, {
233 | // Sound.play = function() { }
234 | token : [
235 | "storage.type", "punctuation.operator", "entity.name.function", "text",
236 | "keyword.operator", "text", "storage.type", "text", "paren.lparen"
237 | ],
238 | regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",
239 | next: "function_arguments"
240 | }, {
241 | // play = function() { }
242 | token : [
243 | "entity.name.function", "text", "keyword.operator", "text", "storage.type",
244 | "text", "paren.lparen"
245 | ],
246 | regex : "(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",
247 | next: "function_arguments"
248 | }, {
249 | // Sound.play = function play() { }
250 | token : [
251 | "storage.type", "punctuation.operator", "entity.name.function", "text",
252 | "keyword.operator", "text",
253 | "storage.type", "text", "entity.name.function", "text", "paren.lparen"
254 | ],
255 | regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",
256 | next: "function_arguments"
257 | }, {
258 | // function myFunc(arg) { }
259 | token : [
260 | "storage.type", "text", "entity.name.function", "text", "paren.lparen"
261 | ],
262 | regex : "(function)(\\s+)(" + identifierRe + ")(\\s*)(\\()",
263 | next: "function_arguments"
264 | }, {
265 | // foobar: function() { }
266 | token : [
267 | "entity.name.function", "text", "punctuation.operator",
268 | "text", "storage.type", "text", "paren.lparen"
269 | ],
270 | regex : "(" + identifierRe + ")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",
271 | next: "function_arguments"
272 | }, {
273 | // : function() { } (this is for issues with 'foo': function() { })
274 | token : [
275 | "text", "text", "storage.type", "text", "paren.lparen"
276 | ],
277 | regex : "(:)(\\s*)(function)(\\s*)(\\()",
278 | next: "function_arguments"
279 | }, {
280 | token : "constant.language.boolean",
281 | regex : /(?:true|false)\b/
282 | }, {
283 | token : "keyword",
284 | regex : "(?:" + kwBeforeRe + ")\\b",
285 | next : "regex_allowed"
286 | }, {
287 | token : ["punctuation.operator", "support.function"],
288 | regex : /(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:opzzzz|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/
289 | }, {
290 | token : ["punctuation.operator", "support.function.dom"],
291 | regex : /(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/
292 | }, {
293 | token : ["punctuation.operator", "support.constant"],
294 | regex : /(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/
295 | }, {
296 | token : ["storage.type", "punctuation.operator", "support.function.firebug"],
297 | regex : /(console)(\.)(warn|info|log|error|time|timeEnd|assert)\b/
298 | }, {
299 | token : keywordMapper,
300 | regex : identifierRe
301 | }, {
302 | token : "keyword.operator",
303 | regex : /!|\$|%|&|\*|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=|\b(?:in|instanceof|new|delete|typeof|void)/,
304 | next : "regex_allowed"
305 | }, {
306 | token : "punctuation.operator",
307 | regex : /\?|\:|\,|\;|\./,
308 | next : "regex_allowed"
309 | }, {
310 | token : "paren.lparen",
311 | regex : /[\[({]/,
312 | next : "regex_allowed"
313 | }, {
314 | token : "paren.rparen",
315 | regex : /[\])}]/
316 | }, {
317 | token : "keyword.operator",
318 | regex : /\/=?/,
319 | next : "regex_allowed"
320 | }, {
321 | token: "comment",
322 | regex: /^#!.*$/
323 | }, {
324 | token : "text",
325 | regex : /\s+/
326 | }
327 | ],
328 | // regular expressions are only allowed after certain tokens. This
329 | // makes sure we don't mix up regexps with the divison operator
330 | "regex_allowed": [
331 | DocCommentHighlightRules.getStartRule("doc-start"),
332 | {
333 | token : "comment", // multi line comment
334 | merge : true,
335 | regex : "\\/\\*",
336 | next : "comment_regex_allowed"
337 | }, {
338 | token : "comment",
339 | regex : "\\/\\/.*$"
340 | }, {
341 | token: "string.regexp",
342 | regex: "\\/",
343 | next: "regex",
344 | merge: true
345 | }, {
346 | token : "text",
347 | regex : "\\s+"
348 | }, {
349 | // immediately return to the start mode without matching
350 | // anything
351 | token: "empty",
352 | regex: "",
353 | next: "start"
354 | }
355 | ],
356 | "regex": [
357 | {
358 | // escapes
359 | token: "regexp.keyword.operator",
360 | regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"
361 | }, {
362 | // flag
363 | token: "string.regexp",
364 | regex: "/\\w*",
365 | next: "start",
366 | merge: true
367 | }, {
368 | // invalid operators
369 | token : "invalid",
370 | regex: /\{\d+,?(?:\d+)?}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/
371 | }, {
372 | // operators
373 | token : "constant.language.escape",
374 | regex: /\(\?[:=!]|\)|{\d+,?(?:\d+)?}|{,\d+}|[+*]\?|[(|)$^+*?]/
375 | }, {
376 | token: "string.regexp",
377 | regex: /{|[^{\[\/\\(|)$^+*?]+/,
378 | merge: true
379 | }, {
380 | token: "constant.language.escape",
381 | regex: /\[\^?/,
382 | next: "regex_character_class",
383 | merge: true
384 | }, {
385 | token: "empty",
386 | regex: "",
387 | next: "start"
388 | }
389 | ],
390 | "regex_character_class": [
391 | {
392 | token: "regexp.keyword.operator",
393 | regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"
394 | }, {
395 | token: "constant.language.escape",
396 | regex: "]",
397 | next: "regex",
398 | merge: true
399 | }, {
400 | token: "constant.language.escape",
401 | regex: "-"
402 | }, {
403 | token: "string.regexp.charachterclass",
404 | regex: /[^\]\-\\]+/,
405 | merge: true
406 | }, {
407 | token: "empty",
408 | regex: "",
409 | next: "start"
410 | }
411 | ],
412 | "function_arguments": [
413 | {
414 | token: "variable.parameter",
415 | regex: identifierRe
416 | }, {
417 | token: "punctuation.operator",
418 | regex: "[, ]+",
419 | merge: true
420 | }, {
421 | token: "punctuation.operator",
422 | regex: "$",
423 | merge: true
424 | }, {
425 | token: "empty",
426 | regex: "",
427 | next: "start"
428 | }
429 | ],
430 | "comment_regex_allowed" : [
431 | {
432 | token : "comment", // closing comment
433 | regex : ".*?\\*\\/",
434 | merge : true,
435 | next : "regex_allowed"
436 | }, {
437 | token : "comment", // comment spanning whole line
438 | merge : true,
439 | regex : ".+"
440 | }
441 | ],
442 | "comment" : [
443 | {
444 | token : "comment", // closing comment
445 | regex : ".*?\\*\\/",
446 | merge : true,
447 | next : "start"
448 | }, {
449 | token : "comment", // comment spanning whole line
450 | merge : true,
451 | regex : ".+"
452 | }
453 | ],
454 | "qqstring" : [
455 | {
456 | token : "constant.language.escape",
457 | regex : escapedRe
458 | }, {
459 | token : "string",
460 | regex : '[^"\\\\]+',
461 | merge : true
462 | }, {
463 | token : "string",
464 | regex : "\\\\$",
465 | next : "qqstring",
466 | merge : true
467 | }, {
468 | token : "string",
469 | regex : '"|$',
470 | next : "start",
471 | merge : true
472 | }
473 | ],
474 | "qstring" : [
475 | {
476 | token : "constant.language.escape",
477 | regex : escapedRe
478 | }, {
479 | token : "string",
480 | regex : "[^'\\\\]+",
481 | merge : true
482 | }, {
483 | token : "string",
484 | regex : "\\\\$",
485 | next : "qstring",
486 | merge : true
487 | }, {
488 | token : "string",
489 | regex : "'|$",
490 | next : "start",
491 | merge : true
492 | }
493 | ]
494 | };
495 |
496 | this.embedRules(DocCommentHighlightRules, "doc-",
497 | [ DocCommentHighlightRules.getEndRule("start") ]);
498 | };
499 |
500 | oop.inherits(JavaScriptHighlightRules, TextHighlightRules);
501 |
502 | exports.JavaScriptHighlightRules = JavaScriptHighlightRules;
503 | });
504 |
505 | define('ace/mode/doc_comment_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function(require, exports, module) {
506 |
507 |
508 | var oop = require("../lib/oop");
509 | var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
510 |
511 | var DocCommentHighlightRules = function() {
512 |
513 | this.$rules = {
514 | "start" : [ {
515 | token : "comment.doc.tag",
516 | regex : "@[\\w\\d_]+" // TODO: fix email addresses
517 | }, {
518 | token : "comment.doc",
519 | merge : true,
520 | regex : "\\s+"
521 | }, {
522 | token : "comment.doc",
523 | merge : true,
524 | regex : "TODO"
525 | }, {
526 | token : "comment.doc",
527 | merge : true,
528 | regex : "[^@\\*]+"
529 | }, {
530 | token : "comment.doc",
531 | merge : true,
532 | regex : "."
533 | }]
534 | };
535 | };
536 |
537 | oop.inherits(DocCommentHighlightRules, TextHighlightRules);
538 |
539 | DocCommentHighlightRules.getStartRule = function(start) {
540 | return {
541 | token : "comment.doc", // doc comment
542 | merge : true,
543 | regex : "\\/\\*(?=\\*)",
544 | next : start
545 | };
546 | };
547 |
548 | DocCommentHighlightRules.getEndRule = function (start) {
549 | return {
550 | token : "comment.doc", // closing comment
551 | merge : true,
552 | regex : "\\*\\/",
553 | next : start
554 | };
555 | };
556 |
557 |
558 | exports.DocCommentHighlightRules = DocCommentHighlightRules;
559 |
560 | });
561 |
562 | define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
563 |
564 |
565 | var Range = require("../range").Range;
566 |
567 | var MatchingBraceOutdent = function() {};
568 |
569 | (function() {
570 |
571 | this.checkOutdent = function(line, input) {
572 | if (! /^\s+$/.test(line))
573 | return false;
574 |
575 | return /^\s*\}/.test(input);
576 | };
577 |
578 | this.autoOutdent = function(doc, row) {
579 | var line = doc.getLine(row);
580 | var match = line.match(/^(\s*\})/);
581 |
582 | if (!match) return 0;
583 |
584 | var column = match[1].length;
585 | var openBracePos = doc.findMatchingBracket({row: row, column: column});
586 |
587 | if (!openBracePos || openBracePos.row == row) return 0;
588 |
589 | var indent = this.$getIndent(doc.getLine(openBracePos.row));
590 | doc.replace(new Range(row, 0, row, column-1), indent);
591 | };
592 |
593 | this.$getIndent = function(line) {
594 | var match = line.match(/^(\s+)/);
595 | if (match) {
596 | return match[1];
597 | }
598 |
599 | return "";
600 | };
601 |
602 | }).call(MatchingBraceOutdent.prototype);
603 |
604 | exports.MatchingBraceOutdent = MatchingBraceOutdent;
605 | });
606 |
607 | define('ace/mode/behaviour/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour'], function(require, exports, module) {
608 |
609 |
610 | var oop = require("../../lib/oop");
611 | var Behaviour = require("../behaviour").Behaviour;
612 |
613 | var CstyleBehaviour = function () {
614 |
615 | this.add("braces", "insertion", function (state, action, editor, session, text) {
616 | if (text == '{') {
617 | var selection = editor.getSelectionRange();
618 | var selected = session.doc.getTextRange(selection);
619 | if (selected !== "") {
620 | return {
621 | text: '{' + selected + '}',
622 | selection: false
623 | };
624 | } else {
625 | return {
626 | text: '{}',
627 | selection: [1, 1]
628 | };
629 | }
630 | } else if (text == '}') {
631 | var cursor = editor.getCursorPosition();
632 | var line = session.doc.getLine(cursor.row);
633 | var rightChar = line.substring(cursor.column, cursor.column + 1);
634 | if (rightChar == '}') {
635 | var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
636 | if (matching !== null) {
637 | return {
638 | text: '',
639 | selection: [1, 1]
640 | };
641 | }
642 | }
643 | } else if (text == "\n") {
644 | var cursor = editor.getCursorPosition();
645 | var line = session.doc.getLine(cursor.row);
646 | var rightChar = line.substring(cursor.column, cursor.column + 1);
647 | if (rightChar == '}') {
648 | var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column + 1});
649 | if (!openBracePos)
650 | return null;
651 |
652 | var indent = this.getNextLineIndent(state, line.substring(0, line.length - 1), session.getTabString());
653 | var next_indent = this.$getIndent(session.doc.getLine(openBracePos.row));
654 |
655 | return {
656 | text: '\n' + indent + '\n' + next_indent,
657 | selection: [1, indent.length, 1, indent.length]
658 | };
659 | }
660 | }
661 | });
662 |
663 | this.add("braces", "deletion", function (state, action, editor, session, range) {
664 | var selected = session.doc.getTextRange(range);
665 | if (!range.isMultiLine() && selected == '{') {
666 | var line = session.doc.getLine(range.start.row);
667 | var rightChar = line.substring(range.end.column, range.end.column + 1);
668 | if (rightChar == '}') {
669 | range.end.column++;
670 | return range;
671 | }
672 | }
673 | });
674 |
675 | this.add("parens", "insertion", function (state, action, editor, session, text) {
676 | if (text == '(') {
677 | var selection = editor.getSelectionRange();
678 | var selected = session.doc.getTextRange(selection);
679 | if (selected !== "") {
680 | return {
681 | text: '(' + selected + ')',
682 | selection: false
683 | };
684 | } else {
685 | return {
686 | text: '()',
687 | selection: [1, 1]
688 | };
689 | }
690 | } else if (text == ')') {
691 | var cursor = editor.getCursorPosition();
692 | var line = session.doc.getLine(cursor.row);
693 | var rightChar = line.substring(cursor.column, cursor.column + 1);
694 | if (rightChar == ')') {
695 | var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});
696 | if (matching !== null) {
697 | return {
698 | text: '',
699 | selection: [1, 1]
700 | };
701 | }
702 | }
703 | }
704 | });
705 |
706 | this.add("parens", "deletion", function (state, action, editor, session, range) {
707 | var selected = session.doc.getTextRange(range);
708 | if (!range.isMultiLine() && selected == '(') {
709 | var line = session.doc.getLine(range.start.row);
710 | var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
711 | if (rightChar == ')') {
712 | range.end.column++;
713 | return range;
714 | }
715 | }
716 | });
717 |
718 | this.add("brackets", "insertion", function (state, action, editor, session, text) {
719 | if (text == '[') {
720 | var selection = editor.getSelectionRange();
721 | var selected = session.doc.getTextRange(selection);
722 | if (selected !== "") {
723 | return {
724 | text: '[' + selected + ']',
725 | selection: false
726 | };
727 | } else {
728 | return {
729 | text: '[]',
730 | selection: [1, 1]
731 | };
732 | }
733 | } else if (text == ']') {
734 | var cursor = editor.getCursorPosition();
735 | var line = session.doc.getLine(cursor.row);
736 | var rightChar = line.substring(cursor.column, cursor.column + 1);
737 | if (rightChar == ']') {
738 | var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});
739 | if (matching !== null) {
740 | return {
741 | text: '',
742 | selection: [1, 1]
743 | };
744 | }
745 | }
746 | }
747 | });
748 |
749 | this.add("brackets", "deletion", function (state, action, editor, session, range) {
750 | var selected = session.doc.getTextRange(range);
751 | if (!range.isMultiLine() && selected == '[') {
752 | var line = session.doc.getLine(range.start.row);
753 | var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
754 | if (rightChar == ']') {
755 | range.end.column++;
756 | return range;
757 | }
758 | }
759 | });
760 |
761 | this.add("string_dquotes", "insertion", function (state, action, editor, session, text) {
762 | if (text == '"' || text == "'") {
763 | var quote = text;
764 | var selection = editor.getSelectionRange();
765 | var selected = session.doc.getTextRange(selection);
766 | if (selected !== "") {
767 | return {
768 | text: quote + selected + quote,
769 | selection: false
770 | };
771 | } else {
772 | var cursor = editor.getCursorPosition();
773 | var line = session.doc.getLine(cursor.row);
774 | var leftChar = line.substring(cursor.column-1, cursor.column);
775 |
776 | // We're escaped.
777 | if (leftChar == '\\') {
778 | return null;
779 | }
780 |
781 | // Find what token we're inside.
782 | var tokens = session.getTokens(selection.start.row);
783 | var col = 0, token;
784 | var quotepos = -1; // Track whether we're inside an open quote.
785 |
786 | for (var x = 0; x < tokens.length; x++) {
787 | token = tokens[x];
788 | if (token.type == "string") {
789 | quotepos = -1;
790 | } else if (quotepos < 0) {
791 | quotepos = token.value.indexOf(quote);
792 | }
793 | if ((token.value.length + col) > selection.start.column) {
794 | break;
795 | }
796 | col += tokens[x].value.length;
797 | }
798 |
799 | // Try and be smart about when we auto insert.
800 | if (!token || (quotepos < 0 && token.type !== "comment" && (token.type !== "string" || ((selection.start.column !== token.value.length+col-1) && token.value.lastIndexOf(quote) === token.value.length-1)))) {
801 | return {
802 | text: quote + quote,
803 | selection: [1,1]
804 | };
805 | } else if (token && token.type === "string") {
806 | // Ignore input and move right one if we're typing over the closing quote.
807 | var rightChar = line.substring(cursor.column, cursor.column + 1);
808 | if (rightChar == quote) {
809 | return {
810 | text: '',
811 | selection: [1, 1]
812 | };
813 | }
814 | }
815 | }
816 | }
817 | });
818 |
819 | this.add("string_dquotes", "deletion", function (state, action, editor, session, range) {
820 | var selected = session.doc.getTextRange(range);
821 | if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
822 | var line = session.doc.getLine(range.start.row);
823 | var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
824 | if (rightChar == '"') {
825 | range.end.column++;
826 | return range;
827 | }
828 | }
829 | });
830 |
831 | };
832 |
833 | oop.inherits(CstyleBehaviour, Behaviour);
834 |
835 | exports.CstyleBehaviour = CstyleBehaviour;
836 | });
837 |
838 | define('ace/mode/folding/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/range', 'ace/mode/folding/fold_mode'], function(require, exports, module) {
839 |
840 |
841 | var oop = require("../../lib/oop");
842 | var Range = require("../../range").Range;
843 | var BaseFoldMode = require("./fold_mode").FoldMode;
844 |
845 | var FoldMode = exports.FoldMode = function() {};
846 | oop.inherits(FoldMode, BaseFoldMode);
847 |
848 | (function() {
849 |
850 | this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/;
851 | this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/;
852 |
853 | this.getFoldWidgetRange = function(session, foldStyle, row) {
854 | var line = session.getLine(row);
855 | var match = line.match(this.foldingStartMarker);
856 | if (match) {
857 | var i = match.index;
858 |
859 | if (match[1])
860 | return this.openingBracketBlock(session, match[1], row, i);
861 |
862 | var range = session.getCommentFoldRange(row, i + match[0].length);
863 | range.end.column -= 2;
864 | return range;
865 | }
866 |
867 | if (foldStyle !== "markbeginend")
868 | return;
869 |
870 | var match = line.match(this.foldingStopMarker);
871 | if (match) {
872 | var i = match.index + match[0].length;
873 |
874 | if (match[2]) {
875 | var range = session.getCommentFoldRange(row, i);
876 | range.end.column -= 2;
877 | return range;
878 | }
879 |
880 | var end = {row: row, column: i};
881 | var start = session.$findOpeningBracket(match[1], end);
882 |
883 | if (!start)
884 | return;
885 |
886 | start.column++;
887 | end.column--;
888 |
889 | return Range.fromPoints(start, end);
890 | }
891 | };
892 |
893 | }).call(FoldMode.prototype);
894 |
895 | });
896 |
897 | define('ace/mode/folding/fold_mode', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
898 |
899 |
900 | var Range = require("../../range").Range;
901 |
902 | var FoldMode = exports.FoldMode = function() {};
903 |
904 | (function() {
905 |
906 | this.foldingStartMarker = null;
907 | this.foldingStopMarker = null;
908 |
909 | // must return "" if there's no fold, to enable caching
910 | this.getFoldWidget = function(session, foldStyle, row) {
911 | var line = session.getLine(row);
912 | if (this.foldingStartMarker.test(line))
913 | return "start";
914 | if (foldStyle == "markbeginend"
915 | && this.foldingStopMarker
916 | && this.foldingStopMarker.test(line))
917 | return "end";
918 | return "";
919 | };
920 |
921 | this.getFoldWidgetRange = function(session, foldStyle, row) {
922 | return null;
923 | };
924 |
925 | this.indentationBlock = function(session, row, column) {
926 | var re = /\S/;
927 | var line = session.getLine(row);
928 | var startLevel = line.search(re);
929 | if (startLevel == -1)
930 | return;
931 |
932 | var startColumn = column || line.length;
933 | var maxRow = session.getLength();
934 | var startRow = row;
935 | var endRow = row;
936 |
937 | while (++row < maxRow) {
938 | var level = session.getLine(row).search(re);
939 |
940 | if (level == -1)
941 | continue;
942 |
943 | if (level <= startLevel)
944 | break;
945 |
946 | endRow = row;
947 | }
948 |
949 | if (endRow > startRow) {
950 | var endColumn = session.getLine(endRow).length;
951 | return new Range(startRow, startColumn, endRow, endColumn);
952 | }
953 | };
954 |
955 | this.openingBracketBlock = function(session, bracket, row, column, typeRe) {
956 | var start = {row: row, column: column + 1};
957 | var end = session.$findClosingBracket(bracket, start, typeRe);
958 | if (!end)
959 | return;
960 |
961 | var fw = session.foldWidgets[end.row];
962 | if (fw == null)
963 | fw = this.getFoldWidget(session, end.row);
964 |
965 | if (fw == "start" && end.row > start.row) {
966 | end.row --;
967 | end.column = session.getLine(end.row).length;
968 | }
969 | return Range.fromPoints(start, end);
970 | };
971 |
972 | }).call(FoldMode.prototype);
973 |
974 | });
975 |
--------------------------------------------------------------------------------
/javascripts/lib/ace/mode-typescript.js:
--------------------------------------------------------------------------------
1 | /* ***** BEGIN LICENSE BLOCK *****
2 | * Distributed under the BSD license:
3 | *
4 | * Copyright (c) 2012, Ajax.org B.V.
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of Ajax.org B.V. nor the
15 | * names of its contributors may be used to endorse or promote products
16 | * derived from this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 | *
29 | *
30 | * Contributor(s):
31 | *
32 | *
33 | *
34 | * ***** END LICENSE BLOCK ***** */
35 |
36 | define('ace/mode/typescript', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/typescript_highlight_rules', 'ace/worker/worker_client'], function(require, exports, module) {
37 |
38 |
39 | var oop = require("../lib/oop");
40 | var TextMode = require("./text").Mode;
41 | var Tokenizer = require("../tokenizer").Tokenizer;
42 | var TypeScriptHighlightRules = require("./typescript_highlight_rules").TypeScriptHighlightRules;
43 | var WorkerClient = require("../worker/worker_client").WorkerClient;
44 |
45 | var Mode = function() {
46 | var highlighter = new TypeScriptHighlightRules();
47 |
48 | this.$tokenizer = new Tokenizer(highlighter.getRules());
49 | };
50 | oop.inherits(Mode, TextMode);
51 |
52 | (function() {
53 |
54 | this.createWorker = function(session) {
55 | var worker = new WorkerClient(["ace"], "ace/mode/typescript_worker", "TypeScriptWorker");
56 | worker.attachToDocument(session.getDocument());
57 |
58 | worker.on("terminate", function() {
59 | session.clearAnnotations();
60 | });
61 |
62 | worker.on("compileErrors", function(results) {
63 | session.setAnnotations(results.data);
64 | session._emit("compileErrors", {data: results.data});
65 |
66 | });
67 |
68 | worker.on("compiled", function(result) {
69 | session._emit("compiled", {data: result.data});
70 | });
71 |
72 | return worker;
73 | };
74 | }).call(Mode.prototype);
75 |
76 | exports.Mode = Mode;
77 | });
78 |
79 |
80 | define('ace/mode/typescript_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/javascript_highlight_rules'], function(require, exports, module) {
81 |
82 |
83 | var oop = require("../lib/oop");
84 | var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules;
85 |
86 | var TypeScriptHighlightRules = function() {
87 |
88 | var tsRules = [
89 | {
90 | "token": ["keyword.operator.ts", "text", "variable.parameter.function.ts", "text"],
91 | "regex": "\\b(module)(\\s*)([a-zA-Z0-9_?.$][\\w?.$]*)(\\s*\\{)"
92 | },
93 | {
94 | "token": ["storage.type.variable.ts", "text", "keyword.other.ts", "text"],
95 | "regex": "(super)(\\s*\\()([a-zA-Z0-9,_?.$\\s]+\\s*)(\\))"
96 | },
97 | {
98 | "token": ["entity.name.function.ts","paren.lparen", "paren.rparen"],
99 | "regex": "([a-zA-Z_?.$][\\w?.$]*)(\\()(\\))"
100 | },
101 | {
102 | "token": ["variable.parameter.function.ts", "text", "variable.parameter.function.ts"],
103 | "regex": "([a-zA-Z0-9_?.$][\\w?.$]*)(\\s*:\\s*)([a-zA-Z0-9_?.$][\\w?.$]*)"
104 | },
105 | {
106 | "token": ["keyword.operator.ts"],
107 | "regex": "(?:\\b(constructor|declare|interface|as|AS|public|private|class|extends|export|super)\\b)"
108 | },
109 | {
110 | "token": ["storage.type.variable.ts"],
111 | "regex": "(?:\\b(this\\.|string\\b|bool\\b|number)\\b)"
112 | },
113 | {
114 | "token": ["keyword.operator.ts", "storage.type.variable.ts", "keyword.operator.ts", "storage.type.variable.ts"],
115 | "regex": "(class)(\\s+[a-zA-Z0-9_?.$][\\w?.$]*\\s+)(extends)(\\s+[a-zA-Z0-9_?.$][\\w?.$]*\\s+)?"
116 | },
117 | {
118 | "token": "keyword",
119 | "regex": "(?:super|export|class|extends|import)\\b"
120 | }
121 | ];
122 |
123 | var JSRules = new JavaScriptHighlightRules().getRules();
124 |
125 | JSRules.start = tsRules.concat(JSRules.start);
126 | this.$rules = JSRules;
127 | };
128 |
129 | oop.inherits(TypeScriptHighlightRules, JavaScriptHighlightRules);
130 |
131 | exports.TypeScriptHighlightRules = TypeScriptHighlightRules;
132 | });
133 |
134 | define('ace/mode/javascript_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/doc_comment_highlight_rules', 'ace/mode/text_highlight_rules'], function(require, exports, module) {
135 |
136 |
137 | var oop = require("../lib/oop");
138 | var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
139 | var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
140 |
141 | var JavaScriptHighlightRules = function() {
142 | var keywordMapper = this.createKeywordMapper({
143 | "variable.language":
144 | "Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|" + // Constructors
145 | "Namespace|QName|XML|XMLList|" + // E4X
146 | "ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|" +
147 | "Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|" +
148 | "Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|" + // Errors
149 | "SyntaxError|TypeError|URIError|" +
150 | "decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|" + // Non-constructor functions
151 | "isNaN|parseFloat|parseInt|" +
152 | "JSON|Math|" + // Other
153 | "this|arguments|prototype|window|document" , // Pseudo
154 | "keyword":
155 | "const|yield|import|get|set|" +
156 | "break|case|catch|continue|default|delete|do|else|finally|for|function|" +
157 | "if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|" +
158 | "__parent__|__count__|escape|unescape|with|__proto__|" +
159 | "class|enum|extends|super|export|implements|private|public|interface|package|protected|static",
160 | "storage.type":
161 | "const|let|var|function",
162 | "constant.language":
163 | "null|Infinity|NaN|undefined",
164 | "support.function":
165 | "alert"
166 | }, "identifier");
167 | var kwBeforeRe = "case|do|else|finally|in|instanceof|return|throw|try|typeof|yield";
168 | var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b";
169 |
170 | var escapedRe = "\\\\(?:x[0-9a-fA-F]{2}|" + // hex
171 | "u[0-9a-fA-F]{4}|" + // unicode
172 | "[0-2][0-7]{0,2}|" + // oct
173 | "3[0-6][0-7]?|" + // oct
174 | "37[0-7]?|" + // oct
175 | "[4-7][0-7]?|" + //oct
176 | ".)";
177 |
178 | this.$rules = {
179 | "start" : [
180 | {
181 | token : "comment",
182 | regex : /\/\/.*$/
183 | },
184 | DocCommentHighlightRules.getStartRule("doc-start"),
185 | {
186 | token : "comment", // multi line comment
187 | merge : true,
188 | regex : /\/\*/,
189 | next : "comment"
190 | }, {
191 | token : "string",
192 | regex : "'(?=.)",
193 | next : "qstring"
194 | }, {
195 | token : "string",
196 | regex : '"(?=.)',
197 | next : "qqstring"
198 | }, {
199 | token : "constant.numeric", // hex
200 | regex : /0[xX][0-9a-fA-F]+\b/
201 | }, {
202 | token : "constant.numeric", // float
203 | regex : /[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/
204 | }, {
205 | token : [
206 | "storage.type", "punctuation.operator", "support.function",
207 | "punctuation.operator", "entity.name.function", "text","keyword.operator"
208 | ],
209 | regex : "(" + identifierRe + ")(\\.)(prototype)(\\.)(" + identifierRe +")(\\s*)(=)",
210 | next: "function_arguments"
211 | }, {
212 | token : [
213 | "storage.type", "punctuation.operator", "entity.name.function", "text",
214 | "keyword.operator", "text", "storage.type", "text", "paren.lparen"
215 | ],
216 | regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",
217 | next: "function_arguments"
218 | }, {
219 | token : [
220 | "entity.name.function", "text", "keyword.operator", "text", "storage.type",
221 | "text", "paren.lparen"
222 | ],
223 | regex : "(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",
224 | next: "function_arguments"
225 | }, {
226 | token : [
227 | "storage.type", "punctuation.operator", "entity.name.function", "text",
228 | "keyword.operator", "text",
229 | "storage.type", "text", "entity.name.function", "text", "paren.lparen"
230 | ],
231 | regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",
232 | next: "function_arguments"
233 | }, {
234 | token : [
235 | "storage.type", "text", "entity.name.function", "text", "paren.lparen"
236 | ],
237 | regex : "(function)(\\s+)(" + identifierRe + ")(\\s*)(\\()",
238 | next: "function_arguments"
239 | }, {
240 | token : [
241 | "entity.name.function", "text", "punctuation.operator",
242 | "text", "storage.type", "text", "paren.lparen"
243 | ],
244 | regex : "(" + identifierRe + ")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",
245 | next: "function_arguments"
246 | }, {
247 | token : [
248 | "text", "text", "storage.type", "text", "paren.lparen"
249 | ],
250 | regex : "(:)(\\s*)(function)(\\s*)(\\()",
251 | next: "function_arguments"
252 | }, {
253 | token : "constant.language.boolean",
254 | regex : /(?:true|false)\b/
255 | }, {
256 | token : "keyword",
257 | regex : "(?:" + kwBeforeRe + ")\\b",
258 | next : "regex_allowed"
259 | }, {
260 | token : ["punctuation.operator", "support.function"],
261 | regex : /(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:opzzzz|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/
262 | }, {
263 | token : ["punctuation.operator", "support.function.dom"],
264 | regex : /(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/
265 | }, {
266 | token : ["punctuation.operator", "support.constant"],
267 | regex : /(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/
268 | }, {
269 | token : ["storage.type", "punctuation.operator", "support.function.firebug"],
270 | regex : /(console)(\.)(warn|info|log|error|time|timeEnd|assert)\b/
271 | }, {
272 | token : keywordMapper,
273 | regex : identifierRe
274 | }, {
275 | token : "keyword.operator",
276 | regex : /!|\$|%|&|\*|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=|\b(?:in|instanceof|new|delete|typeof|void)/,
277 | next : "regex_allowed"
278 | }, {
279 | token : "punctuation.operator",
280 | regex : /\?|\:|\,|\;|\./,
281 | next : "regex_allowed"
282 | }, {
283 | token : "paren.lparen",
284 | regex : /[\[({]/,
285 | next : "regex_allowed"
286 | }, {
287 | token : "paren.rparen",
288 | regex : /[\])}]/
289 | }, {
290 | token : "keyword.operator",
291 | regex : /\/=?/,
292 | next : "regex_allowed"
293 | }, {
294 | token: "comment",
295 | regex: /^#!.*$/
296 | }, {
297 | token : "text",
298 | regex : /\s+/
299 | }
300 | ],
301 | "regex_allowed": [
302 | DocCommentHighlightRules.getStartRule("doc-start"),
303 | {
304 | token : "comment", // multi line comment
305 | merge : true,
306 | regex : "\\/\\*",
307 | next : "comment_regex_allowed"
308 | }, {
309 | token : "comment",
310 | regex : "\\/\\/.*$"
311 | }, {
312 | token: "string.regexp",
313 | regex: "\\/",
314 | next: "regex",
315 | merge: true
316 | }, {
317 | token : "text",
318 | regex : "\\s+"
319 | }, {
320 | token: "empty",
321 | regex: "",
322 | next: "start"
323 | }
324 | ],
325 | "regex": [
326 | {
327 | token: "regexp.keyword.operator",
328 | regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"
329 | }, {
330 | token: "string.regexp",
331 | regex: "/\\w*",
332 | next: "start",
333 | merge: true
334 | }, {
335 | token : "invalid",
336 | regex: /\{\d+,?(?:\d+)?}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/
337 | }, {
338 | token : "constant.language.escape",
339 | regex: /\(\?[:=!]|\)|{\d+,?(?:\d+)?}|{,\d+}|[+*]\?|[(|)$^+*?]/
340 | }, {
341 | token: "string.regexp",
342 | regex: /{|[^{\[\/\\(|)$^+*?]+/,
343 | merge: true
344 | }, {
345 | token: "constant.language.escape",
346 | regex: /\[\^?/,
347 | next: "regex_character_class",
348 | merge: true
349 | }, {
350 | token: "empty",
351 | regex: "",
352 | next: "start"
353 | }
354 | ],
355 | "regex_character_class": [
356 | {
357 | token: "regexp.keyword.operator",
358 | regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"
359 | }, {
360 | token: "constant.language.escape",
361 | regex: "]",
362 | next: "regex",
363 | merge: true
364 | }, {
365 | token: "constant.language.escape",
366 | regex: "-"
367 | }, {
368 | token: "string.regexp.charachterclass",
369 | regex: /[^\]\-\\]+/,
370 | merge: true
371 | }, {
372 | token: "empty",
373 | regex: "",
374 | next: "start"
375 | }
376 | ],
377 | "function_arguments": [
378 | {
379 | token: "variable.parameter",
380 | regex: identifierRe
381 | }, {
382 | token: "punctuation.operator",
383 | regex: "[, ]+",
384 | merge: true
385 | }, {
386 | token: "punctuation.operator",
387 | regex: "$",
388 | merge: true
389 | }, {
390 | token: "empty",
391 | regex: "",
392 | next: "start"
393 | }
394 | ],
395 | "comment_regex_allowed" : [
396 | {
397 | token : "comment", // closing comment
398 | regex : ".*?\\*\\/",
399 | merge : true,
400 | next : "regex_allowed"
401 | }, {
402 | token : "comment", // comment spanning whole line
403 | merge : true,
404 | regex : ".+"
405 | }
406 | ],
407 | "comment" : [
408 | {
409 | token : "comment", // closing comment
410 | regex : ".*?\\*\\/",
411 | merge : true,
412 | next : "start"
413 | }, {
414 | token : "comment", // comment spanning whole line
415 | merge : true,
416 | regex : ".+"
417 | }
418 | ],
419 | "qqstring" : [
420 | {
421 | token : "constant.language.escape",
422 | regex : escapedRe
423 | }, {
424 | token : "string",
425 | regex : '[^"\\\\]+',
426 | merge : true
427 | }, {
428 | token : "string",
429 | regex : "\\\\$",
430 | next : "qqstring",
431 | merge : true
432 | }, {
433 | token : "string",
434 | regex : '"|$',
435 | next : "start",
436 | merge : true
437 | }
438 | ],
439 | "qstring" : [
440 | {
441 | token : "constant.language.escape",
442 | regex : escapedRe
443 | }, {
444 | token : "string",
445 | regex : "[^'\\\\]+",
446 | merge : true
447 | }, {
448 | token : "string",
449 | regex : "\\\\$",
450 | next : "qstring",
451 | merge : true
452 | }, {
453 | token : "string",
454 | regex : "'|$",
455 | next : "start",
456 | merge : true
457 | }
458 | ]
459 | };
460 |
461 | this.embedRules(DocCommentHighlightRules, "doc-",
462 | [ DocCommentHighlightRules.getEndRule("start") ]);
463 | };
464 |
465 | oop.inherits(JavaScriptHighlightRules, TextHighlightRules);
466 |
467 | exports.JavaScriptHighlightRules = JavaScriptHighlightRules;
468 | });
469 |
470 | define('ace/mode/doc_comment_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function(require, exports, module) {
471 |
472 |
473 | var oop = require("../lib/oop");
474 | var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
475 |
476 | var DocCommentHighlightRules = function() {
477 |
478 | this.$rules = {
479 | "start" : [ {
480 | token : "comment.doc.tag",
481 | regex : "@[\\w\\d_]+" // TODO: fix email addresses
482 | }, {
483 | token : "comment.doc",
484 | merge : true,
485 | regex : "\\s+"
486 | }, {
487 | token : "comment.doc",
488 | merge : true,
489 | regex : "TODO"
490 | }, {
491 | token : "comment.doc",
492 | merge : true,
493 | regex : "[^@\\*]+"
494 | }, {
495 | token : "comment.doc",
496 | merge : true,
497 | regex : "."
498 | }]
499 | };
500 | };
501 |
502 | oop.inherits(DocCommentHighlightRules, TextHighlightRules);
503 |
504 | DocCommentHighlightRules.getStartRule = function(start) {
505 | return {
506 | token : "comment.doc", // doc comment
507 | merge : true,
508 | regex : "\\/\\*(?=\\*)",
509 | next : start
510 | };
511 | };
512 |
513 | DocCommentHighlightRules.getEndRule = function (start) {
514 | return {
515 | token : "comment.doc", // closing comment
516 | merge : true,
517 | regex : "\\*\\/",
518 | next : start
519 | };
520 | };
521 |
522 |
523 | exports.DocCommentHighlightRules = DocCommentHighlightRules;
524 |
525 | });
526 |
--------------------------------------------------------------------------------
/javascripts/lib/ace/theme-monokai.js:
--------------------------------------------------------------------------------
1 | /* ***** BEGIN LICENSE BLOCK *****
2 | * Distributed under the BSD license:
3 | *
4 | * Copyright (c) 2010, Ajax.org B.V.
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of Ajax.org B.V. nor the
15 | * names of its contributors may be used to endorse or promote products
16 | * derived from this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 | *
29 | * ***** END LICENSE BLOCK ***** */
30 |
31 | define('ace/theme/monokai', ['require', 'exports', 'module', 'ace/lib/dom'], function(require, exports, module) {
32 |
33 | exports.isDark = true;
34 | exports.cssClass = "ace-monokai";
35 | exports.cssText = ".ace-monokai .ace_gutter {\
36 | background: #2f3129;\
37 | color: #f1f1f1\
38 | }\
39 | \
40 | .ace-monokai .ace_print-margin {\
41 | width: 1px;\
42 | background: #555651\
43 | }\
44 | \
45 | .ace-monokai .ace_scroller {\
46 | background-color: #272822\
47 | }\
48 | \
49 | .ace-monokai .ace_text-layer {\
50 | color: #F8F8F2\
51 | }\
52 | \
53 | .ace-monokai .ace_cursor {\
54 | border-left: 2px solid #F8F8F0\
55 | }\
56 | \
57 | .ace-monokai .ace_cursor.ace_overwrite {\
58 | border-left: 0px;\
59 | border-bottom: 1px solid #F8F8F0\
60 | }\
61 | \
62 | .ace-monokai .ace_marker-layer .ace_selection {\
63 | background: #49483E\
64 | }\
65 | \
66 | .ace-monokai.ace_multiselect .ace_selection.ace_start {\
67 | box-shadow: 0 0 3px 0px #272822;\
68 | border-radius: 2px\
69 | }\
70 | \
71 | .ace-monokai .ace_marker-layer .ace_step {\
72 | background: rgb(102, 82, 0)\
73 | }\
74 | \
75 | .ace-monokai .ace_marker-layer .ace_bracket {\
76 | margin: -1px 0 0 -1px;\
77 | border: 1px solid #49483E\
78 | }\
79 | \
80 | .ace-monokai .ace_marker-layer .ace_active-line {\
81 | background: #202020\
82 | }\
83 | \
84 | .ace-monokai .ace_gutter-active-line {\
85 | background-color: #272727\
86 | }\
87 | \
88 | .ace-monokai .ace_marker-layer .ace_selected-word {\
89 | border: 1px solid #49483E\
90 | }\
91 | \
92 | .ace-monokai .ace_invisible {\
93 | color: #49483E\
94 | }\
95 | \
96 | .ace-monokai .ace_entity.ace_name.ace_tag,\
97 | .ace-monokai .ace_keyword,\
98 | .ace-monokai .ace_meta,\
99 | .ace-monokai .ace_storage {\
100 | color: #F92672\
101 | }\
102 | \
103 | .ace-monokai .ace_constant.ace_character,\
104 | .ace-monokai .ace_constant.ace_language,\
105 | .ace-monokai .ace_constant.ace_numeric,\
106 | .ace-monokai .ace_constant.ace_other {\
107 | color: #AE81FF\
108 | }\
109 | \
110 | .ace-monokai .ace_invalid {\
111 | color: #F8F8F0;\
112 | background-color: #F92672\
113 | }\
114 | \
115 | .ace-monokai .ace_invalid.ace_deprecated {\
116 | color: #F8F8F0;\
117 | background-color: #AE81FF\
118 | }\
119 | \
120 | .ace-monokai .ace_support.ace_constant,\
121 | .ace-monokai .ace_support.ace_function {\
122 | color: #66D9EF\
123 | }\
124 | \
125 | .ace-monokai .ace_fold {\
126 | background-color: #A6E22E;\
127 | border-color: #F8F8F2\
128 | }\
129 | \
130 | .ace-monokai .ace_storage.ace_type,\
131 | .ace-monokai .ace_support.ace_class,\
132 | .ace-monokai .ace_support.ace_type {\
133 | font-style: italic;\
134 | color: #66D9EF\
135 | }\
136 | \
137 | .ace-monokai .ace_entity.ace_name.ace_function,\
138 | .ace-monokai .ace_entity.ace_other.ace_attribute-name,\
139 | .ace-monokai .ace_variable {\
140 | color: #A6E22E\
141 | }\
142 | \
143 | .ace-monokai .ace_variable.ace_parameter {\
144 | font-style: italic;\
145 | color: #FD971F\
146 | }\
147 | \
148 | .ace-monokai .ace_string {\
149 | color: #E6DB74\
150 | }\
151 | \
152 | .ace-monokai .ace_comment {\
153 | color: #75715E\
154 | }\
155 | \
156 | .ace-monokai .ace_markup.ace_underline {\
157 | text-decoration: underline\
158 | }\
159 | \
160 | .ace-monokai .ace_indent-guide {\
161 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQ11D6z7Bq1ar/ABCKBG6g04U2AAAAAElFTkSuQmCC) right repeat-y\
162 | }";
163 |
164 | var dom = require("../lib/dom");
165 | dom.importCssString(exports.cssText, exports.cssClass);
166 | });
167 |
--------------------------------------------------------------------------------
/javascripts/lightHarness.js:
--------------------------------------------------------------------------------
1 | // parcial copy from typescript harness.js
2 |
3 | // Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
4 | define('lightHarness', ['require', 'exports', 'module', 'ace/keyboard/hash_handler'], function(require, exports, module) {
5 |
6 | var __extends = this.__extends || function (d, b) {
7 | function __() {
8 | this.constructor = d;
9 | }
10 | __.prototype = b.prototype;
11 | d.prototype = new __();
12 | };
13 |
14 | var ScriptInfo = (function () {
15 | function ScriptInfo(name, content, isResident, maxScriptVersions) {
16 | this.name = name;
17 | this.content = content;
18 | this.isResident = isResident;
19 | this.maxScriptVersions = maxScriptVersions;
20 | this.editRanges = [];
21 | this.version = 1;
22 | }
23 | ScriptInfo.prototype.updateContent = function (content, isResident) {
24 | this.editRanges = [];
25 | this.content = content;
26 | this.isResident = isResident;
27 | this.version++;
28 | };
29 | ScriptInfo.prototype.editContent = function (minChar, limChar, newText) {
30 | var prefix = this.content.substring(0, minChar);
31 | var middle = newText;
32 | var suffix = this.content.substring(limChar);
33 | this.content = prefix + middle + suffix;
34 | this.editRanges.push({
35 | length: this.content.length,
36 | editRange: new TypeScript.ScriptEditRange(minChar, limChar, (limChar - minChar) + newText.length)
37 | });
38 | if(this.editRanges.length > this.maxScriptVersions) {
39 | this.editRanges.splice(0, this.maxScriptVersions - this.editRanges.length);
40 | }
41 | this.version++;
42 | };
43 | ScriptInfo.prototype.getEditRangeSinceVersion = function (version) {
44 | if(this.version == version) {
45 | return null;
46 | }
47 | var initialEditRangeIndex = this.editRanges.length - (this.version - version);
48 | if(initialEditRangeIndex < 0 || initialEditRangeIndex >= this.editRanges.length) {
49 | return TypeScript.ScriptEditRange.unknown();
50 | }
51 | var entries = this.editRanges.slice(initialEditRangeIndex);
52 | var minDistFromStart = entries.map(function (x) {
53 | return x.editRange.minChar;
54 | }).reduce(function (prev, current) {
55 | return Math.min(prev, current);
56 | });
57 | var minDistFromEnd = entries.map(function (x) {
58 | return x.length - x.editRange.limChar;
59 | }).reduce(function (prev, current) {
60 | return Math.min(prev, current);
61 | });
62 | var aggDelta = entries.map(function (x) {
63 | return x.editRange.delta;
64 | }).reduce(function (prev, current) {
65 | return prev + current;
66 | });
67 | return new TypeScript.ScriptEditRange(minDistFromStart, entries[0].length - minDistFromEnd, aggDelta);
68 | };
69 | return ScriptInfo;
70 | })();
71 | exports.ScriptInfo = ScriptInfo;
72 | var TypeScriptLS = (function () {
73 | function TypeScriptLS() {
74 | this.ls = null;
75 | this.scripts = [];
76 | this.maxScriptVersions = 100;
77 | }
78 | TypeScriptLS.prototype.addDefaultLibrary = function () {
79 | this.addScript("lib.d.ts", Harness.Compiler.libText, true);
80 | };
81 | TypeScriptLS.prototype.addFile = function (name, isResident) {
82 | if (typeof isResident === "undefined") { isResident = false; }
83 | var code = Harness.CollateralReader.read(name);
84 | this.addScript(name, code, isResident);
85 | };
86 | TypeScriptLS.prototype.addScript = function (name, content, isResident) {
87 | if (typeof isResident === "undefined") { isResident = false; }
88 | var script = new ScriptInfo(name, content, isResident, this.maxScriptVersions);
89 | this.scripts.push(script);
90 | };
91 | TypeScriptLS.prototype.updateScript = function (name, content, isResident) {
92 | if (typeof isResident === "undefined") { isResident = false; }
93 | for(var i = 0; i < this.scripts.length; i++) {
94 | if(this.scripts[i].name == name) {
95 | this.scripts[i].updateContent(content, isResident);
96 | return;
97 | }
98 | }
99 | this.addScript(name, content, isResident);
100 | };
101 | TypeScriptLS.prototype.editScript = function (name, minChar, limChar, newText) {
102 | for(var i = 0; i < this.scripts.length; i++) {
103 | if(this.scripts[i].name == name) {
104 | this.scripts[i].editContent(minChar, limChar, newText);
105 | return;
106 | }
107 | }
108 | throw new Error("No script with name '" + name + "'");
109 | };
110 | TypeScriptLS.prototype.getScriptContent = function (scriptIndex) {
111 | return this.scripts[scriptIndex].content;
112 | };
113 | TypeScriptLS.prototype.information = function () {
114 | return true;
115 | };
116 | TypeScriptLS.prototype.debug = function () {
117 | return true;
118 | };
119 | TypeScriptLS.prototype.warning = function () {
120 | return true;
121 | };
122 | TypeScriptLS.prototype.error = function () {
123 | return true;
124 | };
125 | TypeScriptLS.prototype.fatal = function () {
126 | return true;
127 | };
128 | TypeScriptLS.prototype.log = function (s) {
129 | // console.log("TypeScriptLS:" + s);
130 | };
131 | TypeScriptLS.prototype.getCompilationSettings = function () {
132 | return "";
133 | };
134 | TypeScriptLS.prototype.getScriptCount = function () {
135 | return this.scripts.length;
136 | };
137 | TypeScriptLS.prototype.getScriptSourceText = function (scriptIndex, start, end) {
138 | return this.scripts[scriptIndex].content.substring(start, end);
139 | };
140 | TypeScriptLS.prototype.getScriptSourceLength = function (scriptIndex) {
141 | return this.scripts[scriptIndex].content.length;
142 | };
143 | TypeScriptLS.prototype.getScriptId = function (scriptIndex) {
144 | return this.scripts[scriptIndex].name;
145 | };
146 | TypeScriptLS.prototype.getScriptIsResident = function (scriptIndex) {
147 | return this.scripts[scriptIndex].isResident;
148 | };
149 | TypeScriptLS.prototype.getScriptVersion = function (scriptIndex) {
150 | return this.scripts[scriptIndex].version;
151 | };
152 | TypeScriptLS.prototype.getScriptEditRangeSinceVersion = function (scriptIndex, scriptVersion) {
153 | var range = this.scripts[scriptIndex].getEditRangeSinceVersion(scriptVersion);
154 | return (range.minChar + "," + range.limChar + "," + range.delta);
155 | };
156 | TypeScriptLS.prototype.getLanguageService = function () {
157 | var ls = new Services.TypeScriptServicesFactory().createLanguageServiceShim(this);
158 | ls.refresh(true);
159 | this.ls = ls;
160 | return ls;
161 | };
162 | TypeScriptLS.prototype.parseSourceText = function (fileName, sourceText) {
163 | var parser = new TypeScript.Parser();
164 | parser.setErrorRecovery(null, -1, -1);
165 | parser.errorCallback = function (a, b, c, d) {
166 | };
167 | var script = parser.parse(sourceText, fileName, 0);
168 | return script;
169 | };
170 | TypeScriptLS.prototype.parseFile = function (fileName) {
171 | var sourceText = new TypeScript.StringSourceText(IO.readFile(fileName));
172 | return this.parseSourceText(fileName, sourceText);
173 | };
174 | TypeScriptLS.prototype.lineColToPosition = function (fileName, line, col) {
175 | var script = this.ls.languageService.getScriptAST(fileName);
176 | assert.notNull(script);
177 | assert(line >= 1);
178 | assert(col >= 1);
179 | assert(line < script.locationInfo.lineMap.length);
180 | return TypeScript.getPositionFromLineColumn(script, line, col);
181 | };
182 | TypeScriptLS.prototype.positionToLineCol = function (fileName, position) {
183 | var script = this.ls.languageService.getScriptAST(fileName);
184 | assert.notNull(script);
185 | var result = TypeScript.getLineColumnFromPosition(script, position);
186 | assert(result.line >= 1);
187 | assert(result.col >= 1);
188 | return result;
189 | };
190 | TypeScriptLS.prototype.checkEdits = function (sourceFileName, baselineFileName, edits) {
191 | var script = Harness.CollateralReader.read(sourceFileName);
192 | var formattedScript = this.applyEdits(script, edits);
193 | var baseline = Harness.CollateralReader.read(baselineFileName);
194 | assert.noDiff(formattedScript, baseline);
195 | assert.equal(formattedScript, baseline);
196 | };
197 | TypeScriptLS.prototype.applyEdits = function (content, edits) {
198 | var result = content;
199 | edits = this.normalizeEdits(edits);
200 | for(var i = edits.length - 1; i >= 0; i--) {
201 | var edit = edits[i];
202 | var prefix = result.substring(0, edit.minChar);
203 | var middle = edit.text;
204 | var suffix = result.substring(edit.limChar);
205 | result = prefix + middle + suffix;
206 | }
207 | return result;
208 | };
209 | TypeScriptLS.prototype.normalizeEdits = function (edits) {
210 | var result = [];
211 | function mapEdits(edits) {
212 | var result = [];
213 | for(var i = 0; i < edits.length; i++) {
214 | result.push({
215 | edit: edits[i],
216 | index: i
217 | });
218 | }
219 | return result;
220 | }
221 | var temp = mapEdits(edits).sort(function (a, b) {
222 | var result = a.edit.minChar - b.edit.minChar;
223 | if(result == 0) {
224 | result = a.index - b.index;
225 | }
226 | return result;
227 | });
228 | var current = 0;
229 | var next = 1;
230 | while(current < temp.length) {
231 | var currentEdit = temp[current].edit;
232 | if(next >= temp.length) {
233 | result.push(currentEdit);
234 | current++;
235 | continue;
236 | }
237 | var nextEdit = temp[next].edit;
238 | var gap = nextEdit.minChar - currentEdit.limChar;
239 | if(gap >= 0) {
240 | result.push(currentEdit);
241 | current = next;
242 | next++;
243 | continue;
244 | }
245 | if(currentEdit.limChar >= nextEdit.limChar) {
246 | next++;
247 | continue;
248 | } else {
249 | throw new Error("Trying to apply overlapping edits");
250 | }
251 | }
252 | return result;
253 | };
254 | return TypeScriptLS;
255 | })();
256 | exports.TypeScriptLS = TypeScriptLS;
257 |
258 | });
--------------------------------------------------------------------------------
/javascripts/main.js:
--------------------------------------------------------------------------------
1 | var AceRange = require('ace/range').Range;
2 | var AutoComplete = require('autocomplete').AutoComplete;
3 | var lang = require("ace/lib/lang");
4 | var EditorPosition = require('EditorPosition').EditorPosition;
5 | var CompilationService = require('CompilationService').CompilationService;
6 | var FileService = require('FileService').FileService;
7 | var deferredCall = require("ace/lib/lang").deferredCall;
8 |
9 | var Services = require('typescriptServices').Services;
10 | var TypeScript = require('typescriptServices').TypeScript;
11 | var TypeScriptLS = require('lightHarness').TypeScriptLS;
12 |
13 | var aceEditorPosition = null;
14 | var appFileService = null;
15 | var editor = null;
16 | var outputEditor = null;
17 | var typeCompilationService = null;
18 | var docUpdateCount = 0;
19 | var typeScriptLS = new TypeScriptLS();
20 | var ServicesFactory = new Services.TypeScriptServicesFactory();
21 | var serviceShim = ServicesFactory.createLanguageServiceShim(typeScriptLS);
22 |
23 | var selectFileName = "";
24 |
25 | var syncStop = false; //for stop sync on loadfile
26 | var autoComplete = null;
27 | var refMarkers = [];
28 | var errorMarkers =[];
29 |
30 | function loadTypeScriptLibrary(){
31 | var libnames = [
32 | "typescripts/lib.d.ts"
33 | ];
34 |
35 | libnames.forEach(function(libname){
36 | appFileService.readFile(libname, function(content){
37 | typeScriptLS.addScript(libname, content.replace(/\r\n?/g,"\n"), true);
38 | });
39 | });
40 | }
41 |
42 | function loadFile(filename) {
43 | appFileService.readFile(filename, function(content){
44 | selectFileName = filename;
45 | syncStop = true;
46 | var data= content.replace(/\r\n?/g,"\n");
47 | editor.setValue(data);
48 | editor.moveCursorTo(0, 0);
49 | typeScriptLS.updateScript(filename, editor.getSession().getDocument().getValue() , false);
50 | syncStop = false;
51 | });
52 | }
53 |
54 | function startAutoComplete(editor){
55 | if (autoComplete.isActive() == false){
56 | autoComplete.setScriptName(selectFileName);
57 | autoComplete.active();
58 | }
59 | }
60 |
61 | function onUpdateDocument(e){
62 | if (selectFileName){
63 | if (!syncStop){
64 | try{
65 | syncTypeScriptServiceContent(selectFileName, e);
66 | updateMarker(e);
67 | }catch(ex){
68 |
69 | }
70 | }
71 | }
72 | }
73 |
74 | // TODO check column
75 | function updateMarker(aceChangeEvent){
76 | var data = aceChangeEvent.data;
77 | var action = data.action;
78 | var range = data.range;
79 | var markers = editor.getSession().getMarkers(true);
80 | var line_count = 0;
81 | var isNewLine = editor.getSession().getDocument().isNewLine;
82 |
83 | if(action == "insertText"){
84 | if(isNewLine(data.text)){
85 | line_count = 1;
86 | }
87 | }else if(action == "insertLines"){
88 | line_count = data.lines.length;
89 |
90 | }else if (action == "removeText") {
91 | if(isNewLine(data.text)){
92 | line_count = -1;
93 | }
94 |
95 | }else if (action == "removeLines"){
96 | line_count = -data.lines.length;
97 | }
98 |
99 | if(line_count != 0){
100 |
101 | var markerUpdate = function(id){
102 | var marker = markers[id];
103 | var row = range.start.row;
104 |
105 | if(line_count > 0){
106 | row = +1;
107 | }
108 |
109 | if(marker && marker.range.start.row > row ){
110 | marker.range.start.row += line_count ;
111 | marker.range.end.row += line_count ;
112 | }
113 | };
114 |
115 | errorMarkers.forEach(markerUpdate);
116 | refMarkers.forEach(markerUpdate);
117 | editor.onChangeFrontMarker();
118 | }
119 |
120 | }
121 |
122 | //sync LanguageService content and ace editor content
123 | function syncTypeScriptServiceContent(script, aceChangeEvent){
124 |
125 | var data = aceChangeEvent.data;
126 | var action = data.action;
127 | var range = data.range;
128 | var start = aceEditorPosition.getPositionChars(range.start);
129 |
130 | if(action == "insertText"){
131 | editLanguageService(script, new Services.TextEdit(start , start, data.text));
132 | }else if(action == "insertLines"){
133 |
134 | var text = data.lines.map(function(line) {
135 | return line+ '\n'; //TODO newline hard code
136 | }).join('');
137 | editLanguageService(script,new Services.TextEdit(start , start, text));
138 |
139 | }else if (action == "removeText") {
140 | var end = start + data.text.length;
141 | editLanguageService(script, new Services.TextEdit(start, end, ""));
142 | }else if (action == "removeLines"){
143 | var len = aceEditorPosition.getLinesChars(data.lines);
144 | var end = start + len;
145 | editLanguageService(script, new Services.TextEdit(start, end, ""));
146 | }
147 | };
148 |
149 |
150 | function editLanguageService(name, textEdit){
151 | typeScriptLS.editScript(name, textEdit.minChar, textEdit.limChar, textEdit.text);
152 | }
153 |
154 | function onChangeCursor(e){
155 | if(!syncStop){
156 | try{
157 | deferredShowOccurrences.schedule(200);
158 | }catch (ex){
159 | //TODO
160 | }
161 | }
162 | };
163 |
164 | function languageServiceIndent(){
165 | var cursor = editor.getCursorPosition();
166 | var lineNumber = cursor.row;
167 |
168 | var text = editor.session.getLine(lineNumber);
169 | var matches = text.match(/^[\t ]*/);
170 | var preIndent = 0;
171 | var wordLen = 0;
172 |
173 | if(matches){
174 | wordLen = matches[0].length;
175 | for(var i = 0; i < matches[0].length; i++){
176 | var elm = matches[0].charAt(i);
177 | var spaceLen = (elm == " ") ? 1: editor.session.getTabSize();
178 | preIndent += spaceLen;
179 | };
180 | }
181 |
182 | var option = new Services.EditorOptions();
183 | option.NewLineCharacter = "\n";
184 |
185 | var smartIndent = serviceShim.languageService.getSmartIndentAtLineNumber(selectFileName, lineNumber, option);
186 |
187 | if(preIndent > smartIndent){
188 | editor.indent();
189 | }else{
190 | var indent = smartIndent - preIndent;
191 |
192 | if(indent > 0){
193 | editor.getSelection().moveCursorLineStart();
194 | editor.commands.exec("inserttext", editor, {text:" ", times:indent});
195 | }
196 |
197 | if( cursor.column > wordLen){
198 | cursor.column += indent;
199 | }else{
200 | cursor.column = indent + wordLen;
201 | }
202 |
203 | editor.getSelection().moveCursorToPosition(cursor);
204 | }
205 | }
206 |
207 | function refactor(){
208 | var references = serviceShim.languageService.getOccurrencesAtPosition(selectFileName, aceEditorPosition.getCurrentCharPosition());
209 |
210 | references.forEach(function(ref){
211 | var getpos = aceEditorPosition.getAcePositionFromChars;
212 | var start = getpos(ref.ast.minChar);
213 | var end = getpos(ref.ast.limChar);
214 | var range = new AceRange(start.row, start.column, end.row, end.column);
215 | editor.session.multiSelect.addRange(range);
216 | });
217 | }
218 |
219 | function showOccurrences(){
220 | var references = serviceShim.languageService.getOccurrencesAtPosition(selectFileName, aceEditorPosition.getCurrentCharPosition());
221 | var session = editor.getSession();
222 | refMarkers.forEach(function (id){
223 | session.removeMarker(id);
224 | });
225 | references.forEach(function(ref){
226 | //TODO check script name
227 | // console.log(ref.unitIndex);
228 | var getpos = aceEditorPosition.getAcePositionFromChars;
229 | var start = getpos(ref.ast.minChar);
230 | var end = getpos(ref.ast.limChar);
231 | var range = new AceRange(start.row, start.column, end.row, end.column);
232 | refMarkers.push(session.addMarker(range, "typescript-ref", "text", true));
233 | });
234 | }
235 |
236 | var deferredShowOccurrences = deferredCall(showOccurrences);
237 |
238 | function Compile(typeScriptContent){
239 | var output = "";
240 |
241 | var outfile = {
242 | Write: function (s) {
243 | output += s;
244 | },
245 | WriteLine: function (s) {
246 | output += s + "\n";
247 | },
248 | Close: function () {
249 | }
250 | };
251 |
252 | var outerr = {
253 | Write: function (s) {
254 | },
255 | WriteLine: function (s) {
256 | },
257 | Close: function () {
258 | }
259 | };
260 | var compiler = new TypeScript.TypeScriptCompiler(outfile, outerr, new TypeScript.NullLogger(), new TypeScript.CompilationSettings());
261 | compiler.addUnit(typeScriptContent, "output.js", false);
262 | compiler.typeCheck();
263 | compiler.emit(false, function (name) {
264 |
265 | });
266 | return output;
267 | }
268 |
269 | function workerOnCreate(func, timeout){
270 | if(editor.getSession().$worker){
271 | func(editor.getSession().$worker);
272 | }else{
273 | setTimeout(function(){
274 | workerOnCreate(func, timeout);
275 | });
276 | }
277 | }
278 |
279 | function javascriptRun(){
280 | var external = window.open();
281 | var script = external.window.document.createElement("script");
282 | script.textContent = outputEditor.getSession().doc.getValue();
283 | external.window.document.body.appendChild(script);
284 | }
285 |
286 | $(function(){
287 | appFileService = new FileService($);
288 | editor = ace.edit("editor");
289 | editor.setTheme("ace/theme/monokai");
290 | editor.getSession().setMode('ace/mode/typescript');
291 |
292 | outputEditor = ace.edit("output");
293 | outputEditor.setTheme("ace/theme/monokai");
294 | outputEditor.getSession().setMode('ace/mode/javascript');
295 | document.getElementById('editor').style.fontSize='14px';
296 | document.getElementById('output').style.fontSize='14px';
297 |
298 | loadTypeScriptLibrary();
299 | loadFile("samples/greeter.ts");
300 |
301 | editor.addEventListener("change", onUpdateDocument);
302 | editor.addEventListener("changeSelection", onChangeCursor);
303 |
304 | editor.commands.addCommands([{
305 | name:"autoComplete",
306 | bindKey:"Ctrl-Space",
307 | exec:function(editor) {
308 | startAutoComplete(editor);
309 | }
310 | }]);
311 |
312 | editor.commands.addCommands([{
313 | name:"refactor",
314 | bindKey: "F2",
315 | exec:function(editor) {
316 | refactor();
317 | }
318 | }]);
319 |
320 | editor.commands.addCommands([{
321 | name: "indent",
322 | bindKey: "Tab",
323 | exec: function(editor) {
324 | languageServiceIndent();
325 | },
326 | multiSelectAction: "forEach"
327 | }]);
328 |
329 | aceEditorPosition = new EditorPosition(editor);
330 | typeCompilationService = new CompilationService(editor, serviceShim);
331 | autoComplete = new AutoComplete(editor, selectFileName, typeCompilationService);
332 |
333 | // override editor onTextInput
334 | var originalTextInput = editor.onTextInput;
335 | editor.onTextInput = function (text){
336 | originalTextInput.call(editor, text);
337 | if(text == "."){
338 | editor.commands.exec("autoComplete");
339 |
340 | }else if (editor.getSession().getDocument().isNewLine(text)) {
341 | var lineNumber = editor.getCursorPosition().row;
342 | var option = new Services.EditorOptions();
343 | option.NewLineCharacter = "\n";
344 | var indent = serviceShim.languageService.getSmartIndentAtLineNumber(selectFileName, lineNumber, option);
345 | if(indent > 0) {
346 | editor.commands.exec("inserttext", editor, {text:" ", times:indent});
347 | }
348 | }
349 | };
350 |
351 | editor.addEventListener("mousedown", function(e){
352 | if(autoComplete.isActive()){
353 | autoComplete.deactivate();
354 | }
355 | });
356 |
357 | editor.getSession().on("compiled", function(e){
358 | outputEditor.getSession().doc.setValue(e.data);
359 | });
360 |
361 | editor.getSession().on("compileErrors", function(e){
362 | var session = editor.getSession();
363 | errorMarkers.forEach(function (id){
364 | session.removeMarker(id);
365 | });
366 | e.data.forEach(function(error){
367 | var getpos = aceEditorPosition.getAcePositionFromChars;
368 | var start = getpos(error.minChar);
369 | var end = getpos(error.limChar);
370 | var range = new AceRange(start.row, start.column, end.row, end.column);
371 | errorMarkers.push(session.addMarker(range, "typescript-error", "text", true));
372 | });
373 | });
374 |
375 | workerOnCreate(function(){//TODO use worker init event
376 |
377 | ["typescripts/lib.d.ts"].forEach(function(libname){
378 | appFileService.readFile(libname, function(content){
379 | var params = {
380 | data: {
381 | name:libname,
382 | content:content.replace(/\r\n?/g,"\n")
383 | }
384 | };
385 | editor.getSession().$worker.emit("addLibrary", params );
386 | });
387 | });
388 | }, 100);
389 |
390 | $("#javascript-run").click(function(e){
391 | javascriptRun();
392 | });
393 |
394 | $("#select-sample").change(function(e){
395 | var path = "samples/" + $(this).val();
396 | loadFile(path);
397 | });
398 |
399 | });
400 |
401 |
402 |
403 |
--------------------------------------------------------------------------------
/samples/animal.ts:
--------------------------------------------------------------------------------
1 | class Animal {
2 | constructor(public name) { }
3 | move(meters) {
4 | alert(this.name + " moved " + meters + "m.");
5 | }
6 | }
7 |
8 | class Snake extends Animal {
9 | constructor(name) { super(name); }
10 | move() {
11 | alert("Slithering...");
12 | super.move(5);
13 | }
14 | }
15 |
16 | class Horse extends Animal {
17 | constructor(name) { super(name); }
18 | move() {
19 | alert("Galloping...");
20 | super.move(45);
21 | }
22 | }
23 |
24 | var sam = new Snake("Sammy the Python")
25 | var tom: Animal = new Horse("Tommy the Palomino")
26 |
27 | sam.move()
28 | tom.move(34)
--------------------------------------------------------------------------------
/samples/greeter.ts:
--------------------------------------------------------------------------------
1 |
2 | class Greeter {
3 | greeting: string;
4 | constructor (message: string) {
5 | this.greeting = message;
6 | }
7 | greet() {
8 | return "Hello, " + this.greeting;
9 | }
10 | }
11 |
12 | var greeter = new Greeter("world");
13 |
14 | var button = document.createElement('button')
15 | button.innerText = "Say Hello"
16 | button.onclick = function() {
17 | alert(greeter.greet())
18 | }
19 |
20 | document.body.appendChild(button)
21 |
--------------------------------------------------------------------------------
/samples/raytracer.ts:
--------------------------------------------------------------------------------
1 |
2 | class Vector {
3 | constructor(public x: number,
4 | public y: number,
5 | public z: number) {
6 | }
7 | static times(k: number, v: Vector) { return new Vector(k * v.x, k * v.y, k * v.z); }
8 | static minus(v1: Vector, v2: Vector) { return new Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); }
9 | static plus(v1: Vector, v2: Vector) { return new Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); }
10 | static dot(v1: Vector, v2: Vector) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; }
11 | static mag(v: Vector) { return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z); }
12 | static norm(v: Vector) {
13 | var mag = Vector.mag(v);
14 | var div = (mag === 0) ? Infinity : 1.0 / mag;
15 | return Vector.times(div, v);
16 | }
17 | static cross(v1: Vector, v2: Vector) {
18 | return new Vector(v1.y * v2.z - v1.z * v2.y,
19 | v1.z * v2.x - v1.x * v2.z,
20 | v1.x * v2.y - v1.y * v2.x);
21 | }
22 | }
23 |
24 | class Color {
25 | constructor(public r: number,
26 | public g: number,
27 | public b: number) {
28 | }
29 | static scale(k: number, v: Color) { return new Color(k * v.r, k * v.g, k * v.b); }
30 | static plus(v1: Color, v2: Color) { return new Color(v1.r + v2.r, v1.g + v2.g, v1.b + v2.b); }
31 | static times(v1: Color, v2: Color) { return new Color(v1.r * v2.r, v1.g * v2.g, v1.b * v2.b); }
32 | static white = new Color(1.0, 1.0, 1.0);
33 | static grey = new Color(0.5, 0.5, 0.5);
34 | static black = new Color(0.0, 0.0, 0.0);
35 | static background = Color.black;
36 | static defaultColor = Color.black;
37 | static toDrawingColor(c: Color) {
38 | var legalize = d => d > 1 ? 1 : d;
39 | return {
40 | r: Math.floor(legalize(c.r) * 255),
41 | g: Math.floor(legalize(c.g) * 255),
42 | b: Math.floor(legalize(c.b) * 255)
43 | }
44 | }
45 | }
46 |
47 | class Camera {
48 | public forward: Vector;
49 | public right: Vector;
50 | public up: Vector;
51 |
52 | constructor(public pos: Vector, lookAt: Vector) {
53 | var down = new Vector(0.0, -1.0, 0.0);
54 | this.forward = Vector.norm(Vector.minus(lookAt, this.pos));
55 | this.right = Vector.times(1.5, Vector.norm(Vector.cross(this.forward, down)));
56 | this.up = Vector.times(1.5, Vector.norm(Vector.cross(this.forward, this.right)));
57 | }
58 | }
59 |
60 | interface Ray {
61 | start: Vector;
62 | dir: Vector;
63 | }
64 |
65 | interface Intersection {
66 | thing: Thing;
67 | ray: Ray;
68 | dist: number;
69 | }
70 |
71 | interface Surface {
72 | diffuse: (pos: Vector) => Color;
73 | specular: (pos: Vector) => Color;
74 | reflect: (pos: Vector) => number;
75 | roughness: number;
76 | }
77 |
78 | interface Thing {
79 | intersect: (ray: Ray) => Intersection;
80 | normal: (pos: Vector) => Vector;
81 | surface: Surface;
82 | }
83 |
84 | interface Light {
85 | pos: Vector;
86 | color: Color;
87 | }
88 |
89 | interface Scene {
90 | things: Thing[];
91 | lights: Light[];
92 | camera: Camera;
93 | }
94 |
95 | class Sphere implements Thing {
96 | public radius2: number;
97 |
98 | constructor(public center: Vector, radius: number, public surface: Surface) {
99 | this.radius2 = radius * radius;
100 | }
101 | normal(pos: Vector): Vector { return Vector.norm(Vector.minus(pos, this.center)); };
102 | intersect(ray: Ray) {
103 | var eo = Vector.minus(this.center, ray.start);
104 | var v = Vector.dot(eo, ray.dir);
105 | var dist = 0;
106 | if (v >= 0) {
107 | var disc = this.radius2 - (Vector.dot(eo, eo) - v * v);
108 | if (disc >= 0) {
109 | dist = v - Math.sqrt(disc);
110 | }
111 | }
112 | if (dist === 0) {
113 | return null;
114 | } else {
115 | return { thing: this, ray: ray, dist: dist };
116 | }
117 | }
118 | }
119 |
120 | class Plane implements Thing {
121 | public normal: (pos: Vector) =>Vector;
122 | public intersect: (ray: Ray) =>Intersection;
123 | constructor(norm: Vector, offset: number, public surface: Surface) {
124 | this.normal = function(pos: Vector) { return norm; }
125 | this.intersect = function(ray: Ray): Intersection {
126 | var denom = Vector.dot(norm, ray.dir);
127 | if (denom > 0) {
128 | return null;
129 | } else {
130 | var dist = (Vector.dot(norm, ray.start) + offset) / (-denom);
131 | return { thing: this, ray: ray, dist: dist };
132 | }
133 | }
134 | }
135 | }
136 |
137 | module Surfaces {
138 | export var shiny: Surface = {
139 | diffuse: function(pos) { return Color.white; },
140 | specular: function(pos) { return Color.grey; },
141 | reflect: function(pos) { return 0.7; },
142 | roughness: 250
143 | }
144 | export var checkerboard: Surface = {
145 | diffuse: function(pos) {
146 | if ((Math.floor(pos.z) + Math.floor(pos.x)) % 2 !== 0) {
147 | return Color.white;
148 | } else {
149 | return Color.black;
150 | }
151 | },
152 | specular: function(pos) { return Color.white; },
153 | reflect: function(pos) {
154 | if ((Math.floor(pos.z) + Math.floor(pos.x)) % 2 !== 0) {
155 | return 0.1;
156 | } else {
157 | return 0.7;
158 | }
159 | },
160 | roughness: 150
161 | }
162 | }
163 |
164 |
165 | class RayTracer {
166 | private maxDepth = 5;
167 |
168 | private intersections(ray: Ray, scene: Scene) {
169 | var closest = +Infinity;
170 | var closestInter: Intersection = undefined;
171 | for (var i in scene.things) {
172 | var inter = scene.things[i].intersect(ray);
173 | if (inter != null && inter.dist < closest) {
174 | closestInter = inter;
175 | closest = inter.dist;
176 | }
177 | }
178 | return closestInter;
179 | }
180 |
181 | private testRay(ray: Ray, scene: Scene) {
182 | var isect = this.intersections(ray, scene);
183 | if (isect != null) {
184 | return isect.dist;
185 | } else {
186 | return undefined;
187 | }
188 | }
189 |
190 | private traceRay(ray: Ray, scene: Scene, depth: number): Color {
191 | var isect = this.intersections(ray, scene);
192 | if (isect === undefined) {
193 | return Color.background;
194 | } else {
195 | return this.shade(isect, scene, depth);
196 | }
197 | }
198 |
199 | private shade(isect: Intersection, scene: Scene, depth: number) {
200 | var d = isect.ray.dir;
201 | var pos = Vector.plus(Vector.times(isect.dist, d), isect.ray.start);
202 | var normal = isect.thing.normal(pos);
203 | var reflectDir = Vector.minus(d, Vector.times(2, Vector.times(Vector.dot(normal, d), normal)));
204 | var naturalColor = Color.plus(Color.background,
205 | this.getNaturalColor(isect.thing, pos, normal, reflectDir, scene));
206 | var reflectedColor = (depth >= this.maxDepth) ? Color.grey : this.getReflectionColor(isect.thing, pos, normal, reflectDir, scene, depth);
207 | return Color.plus(naturalColor, reflectedColor);
208 | }
209 |
210 | private getReflectionColor(thing: Thing, pos: Vector, normal: Vector, rd: Vector, scene: Scene, depth: number) {
211 | return Color.scale(thing.surface.reflect(pos), this.traceRay({ start: pos, dir: rd }, scene, depth + 1));
212 | }
213 |
214 | private getNaturalColor(thing: Thing, pos: Vector, norm: Vector, rd: Vector, scene: Scene) {
215 | var addLight = (col, light) => {
216 | var ldis = Vector.minus(light.pos, pos);
217 | var livec = Vector.norm(ldis);
218 | var neatIsect = this.testRay({ start: pos, dir: livec }, scene);
219 | var isInShadow = (neatIsect === undefined) ? false : (neatIsect <= Vector.mag(ldis));
220 | if (isInShadow) {
221 | return col;
222 | } else {
223 | var illum = Vector.dot(livec, norm);
224 | var lcolor = (illum > 0) ? Color.scale(illum, light.color)
225 | : Color.defaultColor;
226 | var specular = Vector.dot(livec, Vector.norm(rd));
227 | var scolor = (specular > 0) ? Color.scale(Math.pow(specular, thing.surface.roughness), light.color)
228 | : Color.defaultColor;
229 | return Color.plus(col, Color.plus(Color.times(thing.surface.diffuse(pos), lcolor),
230 | Color.times(thing.surface.specular(pos), scolor)));
231 | }
232 | }
233 | return scene.lights.reduce(addLight, Color.defaultColor);
234 | }
235 |
236 | render(scene, ctx, screenWidth, screenHeight) {
237 | var getPoint = (x, y, camera) => {
238 | var recenterX = x =>(x - (screenWidth / 2.0)) / 2.0 / screenWidth;
239 | var recenterY = y => - (y - (screenHeight / 2.0)) / 2.0 / screenHeight;
240 | return Vector.norm(Vector.plus(camera.forward, Vector.plus(Vector.times(recenterX(x), camera.right), Vector.times(recenterY(y), camera.up))));
241 | }
242 | for (var y = 0; y < screenHeight; y++) {
243 | for (var x = 0; x < screenWidth; x++) {
244 | var color = this.traceRay({ start: scene.camera.pos, dir: getPoint(x, y, scene.camera) }, scene, 0);
245 | var c = Color.toDrawingColor(color);
246 | ctx.fillStyle = "rgb(" + String(c.r) + ", " + String(c.g) + ", " + String(c.b) + ")";
247 | ctx.fillRect(x, y, x + 1, y + 1);
248 | }
249 | }
250 | }
251 | }
252 |
253 |
254 | function defaultScene(): Scene {
255 | return {
256 | things: [new Plane(new Vector(0.0, 1.0, 0.0), 0.0, Surfaces.checkerboard),
257 | new Sphere(new Vector(0.0, 1.0, -0.25), 1.0, Surfaces.shiny),
258 | new Sphere(new Vector(-1.0, 0.5, 1.5), 0.5, Surfaces.shiny)],
259 | lights: [{ pos: new Vector(-2.0, 2.5, 0.0), color: new Color(0.49, 0.07, 0.07) },
260 | { pos: new Vector(1.5, 2.5, 1.5), color: new Color(0.07, 0.07, 0.49) },
261 | { pos: new Vector(1.5, 2.5, -1.5), color: new Color(0.07, 0.49, 0.071) },
262 | { pos: new Vector(0.0, 3.5, 0.0), color: new Color(0.21, 0.21, 0.35) }],
263 | camera: new Camera(new Vector(3.0, 2.0, 4.0), new Vector(-1.0, 0.5, 0.0))
264 | };
265 | }
266 |
267 | function exec() {
268 | var canv = document.createElement("canvas");
269 | canv.width = 256;
270 | canv.height = 256;
271 | document.body.appendChild(canv);
272 | var ctx = canv.getContext("2d");
273 | var rayTracer = new RayTracer();
274 | return rayTracer.render(defaultScene(), ctx, 256, 256);
275 | }
276 |
277 | exec();
278 |
--------------------------------------------------------------------------------
/src/coffee/autoCompleteView.coffee:
--------------------------------------------------------------------------------
1 | define('AutoCompleteView', ['require', 'exports', 'module'], (require, exports, module) ->
2 |
3 | selectedClassName = 'ace_autocomplete_selected'
4 |
5 | #
6 | # TODO mouse scrool
7 | #
8 | class AutoCompleteView
9 | constructor:(@editor, @autoComplete) ->
10 | @init()
11 |
12 | init:()=>
13 | @wrap = document.createElement('div')
14 | @listElement = document.createElement('ul')
15 | @wrap.className = 'ace_autocomplete'
16 | @wrap.style.display = 'none'
17 | @listElement.style.listStyleType = 'none'
18 | @wrap.style.position = 'fixed' #TODO use position absolute for scroll
19 | @wrap.style.zIndex = '1000'
20 | @wrap.appendChild(@listElement)
21 |
22 | show:() ->
23 | @wrap.style.display = 'block'
24 |
25 | hide:() ->
26 | @wrap.style.display = 'none'
27 |
28 | #
29 | # TODO hardcode position value
30 | #
31 | setPosition:(coords) ->
32 | top = coords.pageY + 20
33 | editorBottom = $(@editor.container).offset().top + $(@editor.container).height()
34 | bottom = top + $(@wrap).height()
35 | if(bottom < editorBottom)
36 | @wrap.style.top = top + 'px'
37 | @wrap.style.left = coords.pageX + 'px'
38 | else
39 | @wrap.style.top = (top - $(@wrap).height() - 20) + 'px'
40 | @wrap.style.left = coords.pageX + 'px'
41 |
42 | current:()->
43 | children = @listElement.childNodes
44 | for i, child of children
45 | if(child.className == selectedClassName)
46 | return child
47 | null
48 |
49 | focusNext:()->
50 | curr = @current()
51 | focus = curr.nextSibling
52 | if(focus)
53 | curr.className = ''
54 | focus.className = selectedClassName
55 | @adjustPosition()
56 |
57 | focusPrev:()->
58 | curr = @current()
59 | focus = curr.previousSibling
60 | if(focus)
61 | curr.className = ''
62 | focus.className = selectedClassName
63 | @adjustPosition()
64 |
65 | ensureFocus:()->
66 | if(!@current())
67 | if(@listElement.firstChild)
68 | @listElement.firstChild.className = selectedClassName
69 | @adjustPosition()
70 |
71 | adjustPosition:()->
72 | elm = @current()
73 | if(elm)
74 | newMargin = ''
75 | wrapHeight = $(@wrap).height();
76 | elmOuterHeight = $(elm).outerHeight()
77 | preMargin = $(@listElement).css("margin-top").replace('px', '')
78 | preMargin = parseInt(preMargin)
79 | pos = $(elm).position()
80 |
81 | if(pos.top >= (wrapHeight - elmOuterHeight))
82 | newMargin = (preMargin - elmOuterHeight) + 'px'
83 | $(@listElement).css("margin-top", newMargin)
84 |
85 | if(pos.top < 0)
86 | newMargin = (-pos.top + preMargin) + 'px'
87 | $(@listElement).css("margin-top", newMargin)
88 |
89 | exports.AutoCompleteView = AutoCompleteView
90 | return exports
91 | )
92 |
--------------------------------------------------------------------------------
/src/coffee/compilationService.coffee:
--------------------------------------------------------------------------------
1 | define('CompilationService', ['require', 'exports', 'module', 'EditorPosition'], (require, exports, module) ->
2 |
3 | EditorPosition = require('EditorPosition').EditorPosition
4 |
5 | class CompilationService
6 | constructor:(@editor, @ServiceShim) ->
7 | @editorPos = new EditorPosition(@editor)
8 |
9 | getCompilation:(script, charpos, isMemberCompletion) =>
10 | compInfo = @ServiceShim.languageService.getCompletionsAtPosition(script, charpos, isMemberCompletion);
11 | compInfo
12 |
13 | getCursorCompilation:(script, cursor) =>
14 | pos = @editorPos.getPositionChars(cursor)
15 | text = @editor.session.getLine(cursor.row).slice(0, cursor.column)
16 |
17 | isMemberCompletion = false
18 | matches = text.match(/\.([a-zA-Z_0-9\$]*$)/)
19 |
20 | if (matches && matches.length > 0)
21 | @matchText = matches[1]
22 | isMemberCompletion = true
23 | pos -= @matchText.length
24 | else
25 | matches = text.match(/[a-zA-Z_0-9\$]*$/)
26 | @matchText = matches[0]
27 |
28 | @getCompilation(script, pos, isMemberCompletion)
29 |
30 | getCurrentPositionCompilation:(script) =>
31 | @getCursorCompilation(script, @editor.getCursorPosition())
32 |
33 | exports.CompilationService = CompilationService
34 | exports
35 | )
--------------------------------------------------------------------------------
/src/coffee/documentPositionUtil.coffee:
--------------------------------------------------------------------------------
1 | define('DocumentPositionUtil', ['require', 'exports', 'module'], (require, exports, module) ->
2 | class DocumentPositionUtil
3 |
4 | @getLinesChars:(lines)->
5 | count = 0
6 | lines.forEach((line) =>
7 | count += (line.length + 1)
8 | )
9 | count
10 |
11 | @getChars:(doc, pos) ->
12 | @getLinesChars(doc.getLines(0, pos.row - 1)) + pos.column
13 |
14 | @getPosition:(doc, chars) ->
15 | lines = doc.getAllLines()
16 | count = 0
17 | row = 0
18 | for i,line of lines
19 | if(chars < (count + (line.length + 1)))
20 | return {row: row, column: (chars - count)}
21 | count += (line.length + 1)
22 | row += 1
23 |
24 | {row: row, column: (chars - count)}
25 |
26 | exports.DocumentPositionUtil = DocumentPositionUtil
27 | exports
28 | )
--------------------------------------------------------------------------------
/src/coffee/editorPosition.coffee:
--------------------------------------------------------------------------------
1 | define('EditorPosition', ['require', 'exports', 'module'], (require, exports, module) ->
2 |
3 | DocumentPositionUtil = require('DocumentPositionUtil').DocumentPositionUtil
4 |
5 | class EditorPosition
6 | constructor:(@editor) ->
7 |
8 | getLinesChars:(lines) ->
9 | DocumentPositionUtil.getLinesChars(lines)
10 |
11 | getPositionChars:(pos) =>
12 | doc = @editor.getSession().getDocument()
13 | DocumentPositionUtil.getChars(doc, pos)
14 |
15 | getAcePositionFromChars:(chars) =>
16 | doc = @editor.getSession().getDocument()
17 | DocumentPositionUtil.getPosition(doc, chars)
18 |
19 | getCurrentCharPosition:() =>
20 | @getPositionChars(@editor.getCursorPosition())
21 |
22 | getCurrentLeftChar:() =>
23 | @getPositionLeftChar(@editor.getCursorPosition())
24 |
25 | getPositionChar:(cursor)=>
26 | range = {
27 | start:{ row: cursor.row, column:cursor.column },
28 | end:{ row: cursor.row, column:cursor.column + 1 }
29 | }
30 | @editor.getSession().getDocument().getTextRange(range)
31 |
32 | getPositionLeftChar:(cursor) =>
33 | range = {
34 | start:{ row: cursor.row, column:cursor.column },
35 | end:{ row: cursor.row, column:cursor.column - 1 }
36 | }
37 | @editor.getSession().getDocument().getTextRange(range)
38 |
39 | exports.EditorPosition = EditorPosition
40 | exports
41 | )
--------------------------------------------------------------------------------
/src/coffee/fileService.coffee:
--------------------------------------------------------------------------------
1 | define('FileService', ['require', 'exports', 'module' ], (require, exports, module) ->
2 | class FileService
3 | constructor:(@ajaxHost) ->
4 |
5 | readFile:(path, cb) =>
6 | @ajaxHost.ajax({
7 | type: "GET",
8 | url: path,
9 | success: cb
10 | error :((jqXHR, textStatus) =>
11 | console.log(textStatus)
12 | )}
13 | )
14 |
15 | writeFile:(path, content, cb) =>
16 | @ajaxHost.ajax({
17 | type: "POST",
18 | url: path,
19 | data: { content:content}
20 | success: cb
21 | error :((jqXHR, textStatus) =>
22 | console.log(textStatus)
23 | )}
24 | )
25 |
26 | exports.FileService = FileService
27 | exports
28 | )
--------------------------------------------------------------------------------
/src/typescript-mode/typescript.js:
--------------------------------------------------------------------------------
1 | /* ***** BEGIN LICENSE BLOCK *****
2 | * Distributed under the BSD license:
3 | *
4 | * Copyright (c) 2012, Ajax.org B.V.
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of Ajax.org B.V. nor the
15 | * names of its contributors may be used to endorse or promote products
16 | * derived from this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 | *
29 | *
30 | * Contributor(s):
31 | *
32 | *
33 | *
34 | * ***** END LICENSE BLOCK ***** */
35 |
36 | /*
37 | THIS FILE WAS AUTOGENERATED BY mode.tmpl.js
38 | */
39 |
40 | define(function(require, exports, module) {
41 | "use strict";
42 |
43 | var oop = require("../lib/oop");
44 | var TextMode = require("./text").Mode;
45 | var Tokenizer = require("../tokenizer").Tokenizer;
46 | var TypeScriptHighlightRules = require("./typescript_highlight_rules").TypeScriptHighlightRules;
47 | var WorkerClient = require("../worker/worker_client").WorkerClient;
48 |
49 | var Mode = function() {
50 | var highlighter = new TypeScriptHighlightRules();
51 |
52 | this.$tokenizer = new Tokenizer(highlighter.getRules());
53 | };
54 | oop.inherits(Mode, TextMode);
55 |
56 | (function() {
57 | // Extra logic goes here.
58 |
59 | this.createWorker = function(session) {
60 | var worker = new WorkerClient(["ace"], "ace/mode/typescript_worker", "TypeScriptWorker");
61 | worker.attachToDocument(session.getDocument());
62 |
63 | worker.on("terminate", function() {
64 | session.clearAnnotations();
65 | });
66 |
67 | worker.on("compileErrors", function(results) {
68 | session.setAnnotations(results.data);
69 | });
70 |
71 | worker.on("compiled", function(result) {
72 | session._emit("compiled", {data: result.data});
73 | });
74 |
75 | return worker;
76 | };
77 | }).call(Mode.prototype);
78 |
79 | exports.Mode = Mode;
80 | });
--------------------------------------------------------------------------------
/src/typescript-mode/typescript/DocumentPositionUtil.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | define(function(require, exports, module) {
4 | var DocumentPositionUtil;
5 | DocumentPositionUtil = (function() {
6 |
7 | function DocumentPositionUtil() {}
8 |
9 | DocumentPositionUtil.getLinesChars = function(lines) {
10 | var count;
11 | count = 0;
12 | lines.forEach(function(line) {
13 | return count += line.length + 1;
14 | });
15 | return count;
16 | };
17 |
18 | DocumentPositionUtil.getChars = function(doc, pos) {
19 | return DocumentPositionUtil.getLinesChars(doc.getLines(0, pos.row - 1)) + pos.column;
20 | };
21 |
22 | DocumentPositionUtil.getPosition = function(doc, chars) {
23 | var count, i, line, lines, row;
24 | lines = doc.getAllLines();
25 | count = 0;
26 | row = 0;
27 | for (i in lines) {
28 | line = lines[i];
29 | if (chars < (count + (line.length + 1))) {
30 | return {
31 | row: row,
32 | column: chars - count
33 | };
34 | }
35 | count += line.length + 1;
36 | row += 1;
37 | }
38 | return {
39 | row: row,
40 | column: chars - count
41 | };
42 | };
43 |
44 | return DocumentPositionUtil;
45 |
46 | }).call(this);
47 | exports.DocumentPositionUtil = DocumentPositionUtil;
48 | return exports;
49 | });
50 |
51 | }).call(this);
52 |
--------------------------------------------------------------------------------
/src/typescript-mode/typescript/lightHarness.js:
--------------------------------------------------------------------------------
1 | // parcial copy from typescript harness.js
2 | define( function(require, exports, module) {
3 |
4 | var __extends = this.__extends || function (d, b) {
5 | function __() {
6 | this.constructor = d;
7 | }
8 | __.prototype = b.prototype;
9 | d.prototype = new __();
10 | };
11 |
12 | var Services = require('./typescriptServices').Services;
13 | var TypeScript = require('./typescriptServices').TypeScript;
14 |
15 | var ScriptInfo = (function () {
16 | function ScriptInfo(name, content, isResident, maxScriptVersions) {
17 | this.name = name;
18 | this.content = content;
19 | this.isResident = isResident;
20 | this.maxScriptVersions = maxScriptVersions;
21 | this.editRanges = [];
22 | this.version = 1;
23 | }
24 | ScriptInfo.prototype.updateContent = function (content, isResident) {
25 | this.editRanges = [];
26 | this.content = content;
27 | this.isResident = isResident;
28 | this.version++;
29 | };
30 | ScriptInfo.prototype.editContent = function (minChar, limChar, newText) {
31 | var prefix = this.content.substring(0, minChar);
32 | var middle = newText;
33 | var suffix = this.content.substring(limChar);
34 | this.content = prefix + middle + suffix;
35 | this.editRanges.push({
36 | length: this.content.length,
37 | editRange: new TypeScript.ScriptEditRange(minChar, limChar, (limChar - minChar) + newText.length)
38 | });
39 | if(this.editRanges.length > this.maxScriptVersions) {
40 | this.editRanges.splice(0, this.maxScriptVersions - this.editRanges.length);
41 | }
42 | this.version++;
43 | };
44 | ScriptInfo.prototype.getEditRangeSinceVersion = function (version) {
45 | if(this.version == version) {
46 | return null;
47 | }
48 | var initialEditRangeIndex = this.editRanges.length - (this.version - version);
49 | if(initialEditRangeIndex < 0 || initialEditRangeIndex >= this.editRanges.length) {
50 | return TypeScript.ScriptEditRange.unknown();
51 | }
52 | var entries = this.editRanges.slice(initialEditRangeIndex);
53 | var minDistFromStart = entries.map(function (x) {
54 | return x.editRange.minChar;
55 | }).reduce(function (prev, current) {
56 | return Math.min(prev, current);
57 | });
58 | var minDistFromEnd = entries.map(function (x) {
59 | return x.length - x.editRange.limChar;
60 | }).reduce(function (prev, current) {
61 | return Math.min(prev, current);
62 | });
63 | var aggDelta = entries.map(function (x) {
64 | return x.editRange.delta;
65 | }).reduce(function (prev, current) {
66 | return prev + current;
67 | });
68 | return new TypeScript.ScriptEditRange(minDistFromStart, entries[0].length - minDistFromEnd, aggDelta);
69 | };
70 | return ScriptInfo;
71 | })();
72 | exports.ScriptInfo = ScriptInfo;
73 | var TypeScriptLS = (function () {
74 | function TypeScriptLS() {
75 | this.ls = null;
76 | this.scripts = [];
77 | this.maxScriptVersions = 100;
78 | }
79 | TypeScriptLS.prototype.addDefaultLibrary = function () {
80 | this.addScript("lib.d.ts", Harness.Compiler.libText, true);
81 | };
82 | TypeScriptLS.prototype.addFile = function (name, isResident) {
83 | if (typeof isResident === "undefined") { isResident = false; }
84 | var code = Harness.CollateralReader.read(name);
85 | this.addScript(name, code, isResident);
86 | };
87 | TypeScriptLS.prototype.addScript = function (name, content, isResident) {
88 | if (typeof isResident === "undefined") { isResident = false; }
89 | var script = new ScriptInfo(name, content, isResident, this.maxScriptVersions);
90 | this.scripts.push(script);
91 | };
92 | TypeScriptLS.prototype.updateScript = function (name, content, isResident) {
93 | if (typeof isResident === "undefined") { isResident = false; }
94 | for(var i = 0; i < this.scripts.length; i++) {
95 | if(this.scripts[i].name == name) {
96 | this.scripts[i].updateContent(content, isResident);
97 | return;
98 | }
99 | }
100 | this.addScript(name, content, isResident);
101 | };
102 | TypeScriptLS.prototype.editScript = function (name, minChar, limChar, newText) {
103 | for(var i = 0; i < this.scripts.length; i++) {
104 | if(this.scripts[i].name == name) {
105 | this.scripts[i].editContent(minChar, limChar, newText);
106 | return;
107 | }
108 | }
109 | throw new Error("No script with name '" + name + "'");
110 | };
111 | TypeScriptLS.prototype.getScriptContent = function (scriptIndex) {
112 | return this.scripts[scriptIndex].content;
113 | };
114 | TypeScriptLS.prototype.information = function () {
115 | return true;
116 | };
117 | TypeScriptLS.prototype.debug = function () {
118 | return true;
119 | };
120 | TypeScriptLS.prototype.warning = function () {
121 | return true;
122 | };
123 | TypeScriptLS.prototype.error = function () {
124 | return true;
125 | };
126 | TypeScriptLS.prototype.fatal = function () {
127 | return true;
128 | };
129 | TypeScriptLS.prototype.log = function (s) {
130 | // console.log("TypeScriptLS:" + s);
131 | };
132 | TypeScriptLS.prototype.getCompilationSettings = function () {
133 | return "";
134 | };
135 | TypeScriptLS.prototype.getScriptCount = function () {
136 | return this.scripts.length;
137 | };
138 | TypeScriptLS.prototype.getScriptSourceText = function (scriptIndex, start, end) {
139 | return this.scripts[scriptIndex].content.substring(start, end);
140 | };
141 | TypeScriptLS.prototype.getScriptSourceLength = function (scriptIndex) {
142 | return this.scripts[scriptIndex].content.length;
143 | };
144 | TypeScriptLS.prototype.getScriptId = function (scriptIndex) {
145 | return this.scripts[scriptIndex].name;
146 | };
147 | TypeScriptLS.prototype.getScriptIsResident = function (scriptIndex) {
148 | return this.scripts[scriptIndex].isResident;
149 | };
150 | TypeScriptLS.prototype.getScriptVersion = function (scriptIndex) {
151 | return this.scripts[scriptIndex].version;
152 | };
153 | TypeScriptLS.prototype.getScriptEditRangeSinceVersion = function (scriptIndex, scriptVersion) {
154 | var range = this.scripts[scriptIndex].getEditRangeSinceVersion(scriptVersion);
155 | return (range.minChar + "," + range.limChar + "," + range.delta);
156 | };
157 | TypeScriptLS.prototype.getLanguageService = function () {
158 | var ls = new Services.TypeScriptServicesFactory().createLanguageServiceShim(this);
159 | ls.refresh(true);
160 | this.ls = ls;
161 | return ls;
162 | };
163 | TypeScriptLS.prototype.parseSourceText = function (fileName, sourceText) {
164 | var parser = new TypeScript.Parser();
165 | parser.setErrorRecovery(null, -1, -1);
166 | parser.errorCallback = function (a, b, c, d) {
167 | };
168 | var script = parser.parse(sourceText, fileName, 0);
169 | return script;
170 | };
171 | TypeScriptLS.prototype.parseFile = function (fileName) {
172 | var sourceText = new TypeScript.StringSourceText(IO.readFile(fileName));
173 | return this.parseSourceText(fileName, sourceText);
174 | };
175 | TypeScriptLS.prototype.lineColToPosition = function (fileName, line, col) {
176 | var script = this.ls.languageService.getScriptAST(fileName);
177 | assert.notNull(script);
178 | assert(line >= 1);
179 | assert(col >= 1);
180 | assert(line < script.locationInfo.lineMap.length);
181 | return TypeScript.getPositionFromLineColumn(script, line, col);
182 | };
183 | TypeScriptLS.prototype.positionToLineCol = function (fileName, position) {
184 | var script = this.ls.languageService.getScriptAST(fileName);
185 | assert.notNull(script);
186 | var result = TypeScript.getLineColumnFromPosition(script, position);
187 | assert(result.line >= 1);
188 | assert(result.col >= 1);
189 | return result;
190 | };
191 | TypeScriptLS.prototype.checkEdits = function (sourceFileName, baselineFileName, edits) {
192 | var script = Harness.CollateralReader.read(sourceFileName);
193 | var formattedScript = this.applyEdits(script, edits);
194 | var baseline = Harness.CollateralReader.read(baselineFileName);
195 | assert.noDiff(formattedScript, baseline);
196 | assert.equal(formattedScript, baseline);
197 | };
198 | TypeScriptLS.prototype.applyEdits = function (content, edits) {
199 | var result = content;
200 | edits = this.normalizeEdits(edits);
201 | for(var i = edits.length - 1; i >= 0; i--) {
202 | var edit = edits[i];
203 | var prefix = result.substring(0, edit.minChar);
204 | var middle = edit.text;
205 | var suffix = result.substring(edit.limChar);
206 | result = prefix + middle + suffix;
207 | }
208 | return result;
209 | };
210 | TypeScriptLS.prototype.normalizeEdits = function (edits) {
211 | var result = [];
212 | function mapEdits(edits) {
213 | var result = [];
214 | for(var i = 0; i < edits.length; i++) {
215 | result.push({
216 | edit: edits[i],
217 | index: i
218 | });
219 | }
220 | return result;
221 | }
222 | var temp = mapEdits(edits).sort(function (a, b) {
223 | var result = a.edit.minChar - b.edit.minChar;
224 | if(result == 0) {
225 | result = a.index - b.index;
226 | }
227 | return result;
228 | });
229 | var current = 0;
230 | var next = 1;
231 | while(current < temp.length) {
232 | var currentEdit = temp[current].edit;
233 | if(next >= temp.length) {
234 | result.push(currentEdit);
235 | current++;
236 | continue;
237 | }
238 | var nextEdit = temp[next].edit;
239 | var gap = nextEdit.minChar - currentEdit.limChar;
240 | if(gap >= 0) {
241 | result.push(currentEdit);
242 | current = next;
243 | next++;
244 | continue;
245 | }
246 | if(currentEdit.limChar >= nextEdit.limChar) {
247 | next++;
248 | continue;
249 | } else {
250 | throw new Error("Trying to apply overlapping edits");
251 | }
252 | }
253 | return result;
254 | };
255 | return TypeScriptLS;
256 | })();
257 | exports.TypeScriptLS = TypeScriptLS;
258 |
259 | });
--------------------------------------------------------------------------------
/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | body{
2 |
3 | }
4 |
5 | .warp-container{
6 | float:left;
7 | width:49%;
8 | }
9 |
10 | .editor-container {
11 | position:relative;
12 | /* padding:20px; */
13 | height:100%;
14 | width:99%;
15 | float:left;
16 | }
17 | #editor {
18 | position:absolute;
19 | max-height:10000px;
20 | top: 6px;
21 | right: 0;
22 | bottom: 0;
23 | left: 0;
24 | }
25 |
26 | #output {
27 | position:absolute;
28 | max-height:10000;
29 | top: 6px;
30 | right: 0;
31 | bottom: 0;
32 | left: 10;
33 | }
34 |
35 | .editor-area{
36 | height: auto;
37 | padding-bottom: 50px;
38 | height:70%;
39 | /* margin-bottom:20px; */
40 | }
41 |
42 | .typescript-ref{
43 | position: absolute;
44 | border:1px solid white;
45 | opacity:0.7;
46 | }
47 |
48 | .typescript-error{
49 | position: absolute;
50 | border-bottom: 1px solid red;
51 | }
52 |
53 | .langauge-title h2{
54 | padding: 5px 10px;
55 | font-size:14pt;
56 | background: #eee;
57 | border:1px solid black;
58 | display:block;
59 | margin:0px;
60 | height:30px;
61 | line-height:30px;
62 | }
63 | #javascript-run {
64 | margin:0px;
65 | margin-top:10px;
66 | padding:5px;
67 | background:#999;
68 | color:white;
69 | }
70 |
71 | .ace_autocomplete{
72 | height:226px;
73 | background:white;
74 | overflow:hidden;
75 | border:1px solid #ccc;
76 | }
77 |
78 | .ace_autocomplete ul{
79 | width:400px;
80 | margin:0px;
81 | padding:2px;
82 | }
83 |
84 | .ace_autocomplete li:hover{
85 |
86 | }
87 |
88 | .ace_autocomplete li{
89 | padding:1px;
90 | line-height:1.2em;
91 | height:1.2em;
92 | overflow:hidden;
93 | }
94 |
95 | .ace_autocomplete_selected{
96 | background:#eee;
97 | }
98 |
99 | .ace_autocomplete_selected .label-name{
100 | font-weight:bold;
101 | }
102 |
103 | .label-kind{
104 | background:#666;
105 | color:white;
106 | padding:0px 3px;
107 | margin-right:3px;
108 | }
109 |
110 | .label-kind-property{
111 | background:green;
112 | }
113 |
114 | .label-kind-method{
115 | background:blue;
116 | }
117 |
118 | .label-kind-interface{
119 | background:#666;
120 | }
121 |
122 | .label-kind-variable{
123 | background:orangered;
124 | }
125 |
126 | .label-type{
127 | padding-left:10px;
128 | color:blue;
129 | visibility:hidden;
130 | }
131 |
132 | .ace_autocomplete_selected .label-type{
133 | visibility:visible;
134 | }
--------------------------------------------------------------------------------