aboutsummaryrefslogtreecommitdiff
path: root/js/controllers/code-editor-controller.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/controllers/code-editor-controller.js')
-rw-r--r--js/controllers/code-editor-controller.js237
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>
2This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
3No 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//
9var Montage = require("montage/core/core").Montage,
10 Component = require("montage/ui/component").Component;
11
12var 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