diff options
Diffstat (limited to 'js/controllers/code-editor-controller.js')
-rw-r--r-- | js/controllers/code-editor-controller.js | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/js/controllers/code-editor-controller.js b/js/controllers/code-editor-controller.js new file mode 100644 index 00000000..08320db7 --- /dev/null +++ b/js/controllers/code-editor-controller.js | |||
@@ -0,0 +1,237 @@ | |||
1 | /* <copyright> | ||
2 | This file contains proprietary software owned by Motorola Mobility, Inc.<br/> | ||
3 | No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> | ||
4 | (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. | ||
5 | </copyright> */ | ||
6 | |||
7 | //////////////////////////////////////////////////////////////////////// | ||
8 | // | ||
9 | var Montage = require("montage/core/core").Montage, | ||
10 | Component = require("montage/ui/component").Component; | ||
11 | |||
12 | var CodeEditorController = exports.CodeEditorController = Montage.create(Component, { | ||
13 | hasTemplate: { | ||
14 | value: false | ||
15 | }, | ||
16 | |||
17 | _codeEditor : { | ||
18 | value:null | ||
19 | }, | ||
20 | |||
21 | codeEditor:{ | ||
22 | get: function(){return this._codeEditor;}, | ||
23 | set: function(value){this._codeEditor = value;} | ||
24 | }, | ||
25 | |||
26 | codeCompletionSupport : { | ||
27 | value: {"javascript": true} | ||
28 | }, | ||
29 | |||
30 | _automaticCodeComplete: { | ||
31 | value:true | ||
32 | }, | ||
33 | |||
34 | automaticCodeComplete:{ | ||
35 | get: function(){return this._automaticCodeComplete;}, | ||
36 | set: function(value){this._automaticCodeComplete = value;} | ||
37 | }, | ||
38 | |||
39 | _editorTheme: { | ||
40 | value:"default" | ||
41 | }, | ||
42 | |||
43 | editorTheme:{ | ||
44 | get: function(){return this._editorTheme;}, | ||
45 | set: function(value){this._editorTheme = value;} | ||
46 | }, | ||
47 | |||
48 | originalEditorFont:{ | ||
49 | value:"13"//px | ||
50 | }, | ||
51 | |||
52 | _editorFont:{ | ||
53 | value:null | ||
54 | }, | ||
55 | |||
56 | editorFont:{ | ||
57 | get: function(){return this._editorFont;}, | ||
58 | set: function(value){//gets a zoom % | ||
59 | var codeLineElems = null, i=0; | ||
60 | this._editorFont = (value/100) * CodeEditorController.originalEditorFont; | ||
61 | //set the font size | ||
62 | codeLineElems = document.getElementsByClassName("CodeMirror-lines"); | ||
63 | for(i=0;i<codeLineElems.length;i++){ | ||
64 | codeLineElems[i].style.fontSize = ""+this._editorFont+"px"; | ||
65 | } | ||
66 | } | ||
67 | }, | ||
68 | |||
69 | deserializedFromTemplate: { | ||
70 | value: function() { | ||
71 | //TODO:add logic to check some configuration file to load the right code editor | ||
72 | this.codeEditor = CodeMirror; | ||
73 | } | ||
74 | }, | ||
75 | |||
76 | /** | ||
77 | * Public method | ||
78 | * Creates an editor instance | ||
79 | */ | ||
80 | createEditor : { | ||
81 | value:function(doc, type){ | ||
82 | var self = this, editorOptions = null; | ||
83 | |||
84 | editorOptions = { | ||
85 | lineNumbers: true, | ||
86 | matchBrackets:true, | ||
87 | mode: type, | ||
88 | onChange: function(){ | ||
89 | var historySize = doc.editor.historySize(); | ||
90 | if(historySize.undo>0){ | ||
91 | doc.needsSave = true; | ||
92 | }else if(historySize.undo===0 && historySize.redo>0){ | ||
93 | doc.needsSave = false; | ||
94 | } | ||
95 | }, | ||
96 | onCursorActivity: function() { | ||
97 | doc.editor.matchHighlight("CodeMirror-matchhighlight"); | ||
98 | doc.editor.setLineClass(doc.editor.hline, null, null); | ||
99 | doc.editor.hline = doc.editor.setLineClass(doc.editor.getCursor().line, null, "activeline"); | ||
100 | } | ||
101 | }; | ||
102 | |||
103 | //configure auto code completion if it is supported for that document type | ||
104 | if(this.codeCompletionSupport[type] === true){ | ||
105 | editorOptions.onKeyEvent = function(cm, keyEvent){self._codeCompletionKeyEventHandler.call(self, cm, keyEvent, type)}; | ||
106 | } | ||
107 | |||
108 | var editor = self.codeEditor.fromTextArea(doc.textArea, editorOptions); | ||
109 | |||
110 | //editor.setOption("theme", "night"); | ||
111 | |||
112 | return editor; | ||
113 | } | ||
114 | }, | ||
115 | |||
116 | /** | ||
117 | * Private method | ||
118 | * key event handler for showing code completion dropdown | ||
119 | */ | ||
120 | _codeCompletionKeyEventHandler:{ | ||
121 | enumerable:false, | ||
122 | value: function(cm, keyEvent, type) { | ||
123 | //===manually triggered code completion | ||
124 | if((this.automaticCodeComplete === false)){ | ||
125 | if((keyEvent.ctrlKey || keyEvent.metaKey) && keyEvent.keyCode === 32){//Ctrl-Space | ||
126 | this.codeEditor.simpleHint(cm, this.codeEditor.javascriptHint); | ||
127 | } | ||
128 | } | ||
129 | //===automatic auto complete [performance is slower] | ||
130 | else if(this._showAutoComplete(type, keyEvent)){ | ||
131 | this.codeEditor.simpleHint(cm, this.codeEditor.javascriptHint); | ||
132 | } | ||
133 | } | ||
134 | }, | ||
135 | |||
136 | /** | ||
137 | * Private method | ||
138 | * checks for valid keyset to show code completion dropdown | ||
139 | */ | ||
140 | _showAutoComplete : { | ||
141 | enumerable:false, | ||
142 | value:function(type, keyEvent){ | ||
143 | switch(type){ | ||
144 | case "javascript": | ||
145 | if((keyEvent.type === "keyup")//need seperate keycode set per mode | ||
146 | && ((keyEvent.keyCode > 47 && keyEvent.keyCode < 57)//numbers | ||
147 | || (keyEvent.keyCode > 64 && keyEvent.keyCode <91)//letters | ||
148 | || (keyEvent.keyCode === 190)//period | ||
149 | || (keyEvent.keyCode === 189)//underscore, dash | ||
150 | ) | ||
151 | && !( (keyEvent.keyCode === 219)//open bracket [ | ||
152 | || (keyEvent.ctrlKey || keyEvent.metaKey)//ctrl | ||
153 | || (keyEvent.keyCode === 221)//close bracket ] | ||
154 | || (keyEvent.shiftKey && keyEvent.keyCode === 219)//open bracket { | ||
155 | || (keyEvent.shiftKey && keyEvent.keyCode === 221)//close bracket } | ||
156 | || (keyEvent.shiftKey && keyEvent.keyCode === 57)//open bracket ( | ||
157 | || (keyEvent.shiftKey && keyEvent.keyCode === 48)//close bracket ) | ||
158 | || ((keyEvent.ctrlKey || keyEvent.metaKey) && keyEvent.keyCode === 83)//ctrl+S | ||
159 | ) | ||
160 | ){return true;} | ||
161 | default : | ||
162 | return false; | ||
163 | } | ||
164 | } | ||
165 | }, | ||
166 | |||
167 | handleCodeCompletionSupport:{ | ||
168 | value:function(fileType){ | ||
169 | var autoCodeCompleteElem = document.getElementsByClassName("autoCodeComplete")[0], elems=null, i=0; | ||
170 | if(autoCodeCompleteElem){ | ||
171 | elems = autoCodeCompleteElem.getElementsByTagName("*"); | ||
172 | } | ||
173 | |||
174 | if(elems && (this.codeCompletionSupport[fileType] === true)){ | ||
175 | //enable elements | ||
176 | for(i=0;i<elems.length;i++){ | ||
177 | if(elems[i].hasAttribute("disabled")){ | ||
178 | elems[i].removeAttribute("disabled"); | ||
179 | } | ||
180 | if(elems[i].classList.contains("disabled")){ | ||
181 | elems[i].classList.remove("disabled"); | ||
182 | } | ||
183 | } | ||
184 | }else if(elems && !this.codeCompletionSupport[fileType]){ | ||
185 | //disable elements | ||
186 | for(i=0;i<elems.length;i++){ | ||
187 | if(!elems[i].hasAttribute("disabled")){ | ||
188 | elems[i].setAttribute("disabled", "disabled"); | ||
189 | } | ||
190 | if(!elems[i].classList.contains("disabled")){ | ||
191 | elems[i].classList.add("disabled"); | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | } | ||
196 | }, | ||
197 | |||
198 | getSelectedRange:{ | ||
199 | value:function(editor){ | ||
200 | return { from: editor.getCursor(true), to: editor.getCursor(false) }; | ||
201 | } | ||
202 | }, | ||
203 | |||
204 | autoFormatSelection:{ | ||
205 | value: function(){ | ||
206 | var range = this.getSelectedRange(this.application.ninja.documentController.activeDocument.editor); | ||
207 | this.application.ninja.documentController.activeDocument.editor.autoFormatRange(range.from, range.to); | ||
208 | } | ||
209 | }, | ||
210 | |||
211 | commentSelection:{ | ||
212 | value: function(isComment){ | ||
213 | var range = this.getSelectedRange(this.application.ninja.documentController.activeDocument.editor); | ||
214 | this.application.ninja.documentController.activeDocument.editor.commentRange(isComment, range.from, range.to); | ||
215 | } | ||
216 | }, | ||
217 | |||
218 | handleThemeSelection:{ | ||
219 | value: function(){ | ||
220 | this.application.ninja.documentController.activeDocument.editor.setOption("theme", this.editorTheme); | ||
221 | this.application.ninja.stage.stageView.applyTheme("cm-s-"+this.editorTheme); | ||
222 | } | ||
223 | }, | ||
224 | |||
225 | applySettings:{ | ||
226 | value:functi |