aboutsummaryrefslogtreecommitdiff
path: root/js/controllers/code-editor-controller.js
diff options
context:
space:
mode:
authorArmen Kesablyan2012-05-08 16:43:43 -0700
committerArmen Kesablyan2012-05-08 16:43:43 -0700
commitdc075ffcc6dd03c090d90fad999eee9b924d56ee (patch)
tree867f8bdd588c8f9076979233ca46a688ff70523e /js/controllers/code-editor-controller.js
parent5d7e470351fd150d5e70a97332fa2f2553797499 (diff)
parent4d949f141247215b5f2a6ec0cfc7d2d31cf2bb1f (diff)
downloadninja-dc075ffcc6dd03c090d90fad999eee9b924d56ee.tar.gz
Merge branch 'refs/heads/dom-architecture' into binding
Conflicts: js/components/layout/tools-properties.reel/tools-properties.html Signed-off-by: Armen Kesablyan <armen@motorola.com>
Diffstat (limited to 'js/controllers/code-editor-controller.js')
-rw-r--r--js/controllers/code-editor-controller.js258
1 files changed, 258 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..7913cfc1
--- /dev/null
+++ b/js/controllers/code-editor-controller.js
@@ -0,0 +1,258 @@
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: {"js": true}
28 },
29
30 _automaticCodeComplete: {
31 value:false
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 _zoomFactor:{
49 value:100
50 },
51
52 zoomFactor:{
53 get: function(){return this._zoomFactor;},
54 set: function(value){
55 this.handleZoom(value);
56 }
57 },
58
59 deserializedFromTemplate: {
60 value: function() {
61 //TODO:add logic to check some configuration file to load the right code editor
62 this.codeEditor = CodeMirror;
63 }
64 },
65
66 /**
67 * Public method
68 * Creates an editor instance
69 */
70 createEditor : {
71 value:function(doc, type, documentType){
72 var self = this, editorOptions = null;
73
74 editorOptions = {
75 lineNumbers: true,
76 matchBrackets:true,
77 mode: type,
78 onChange: function(){
79 var historySize = doc.editor.historySize();
80 if(historySize.undo>0){
81 doc.needsSave = true;
82 }else if(historySize.undo===0 && historySize.redo>0){
83 doc.needsSave = false;
84 }
85 },
86 onCursorActivity: function() {
87 doc.editor.matchHighlight("CodeMirror-matchhighlight");
88 doc.editor.setLineClass(doc.editor.hline, null, null);
89 doc.editor.hline = doc.editor.setLineClass(doc.editor.getCursor().line, null, "activeline");
90 }
91 };
92
93 //configure auto code completion if it is supported for that document type
94 if(this.codeCompletionSupport[documentType] === true){
95 editorOptions.onKeyEvent = function(cm, keyEvent){self._codeCompletionKeyEventHandler.call(self, cm, keyEvent, documentType)};
96 }
97
98 var editor = self.codeEditor.fromTextArea(doc.textArea, editorOptions);
99
100 //editor.setOption("theme", "night");
101
102 return editor;
103 }
104 },
105
106 /**
107 * Private method
108 * key event handler for showing code completion dropdown
109 */
110 _codeCompletionKeyEventHandler:{
111 enumerable:false,
112 value: function(cm, keyEvent, documentType) {
113 //comment shortkeys
114 if((keyEvent.metaKey || keyEvent.ctrlKey) && !keyEvent.shiftKey && keyEvent.keyCode === 191){//ctrl+/
115 this.commentSelection(true);
116 return;
117 }
118 //uncomment shortkeys
119 if((keyEvent.metaKey || keyEvent.ctrlKey) && keyEvent.shiftKey && keyEvent.keyCode === 191){//ctrl+shift+/
120 this.commentSelection(false);
121 return;
122 }
123
124 //===manually triggered code completion
125 if((this.automaticCodeComplete === false)){
126 if(keyEvent.ctrlKey && keyEvent.keyCode === 32){//Ctrl+Space
127 this.codeEditor.simpleHint(cm, this.codeEditor.javascriptHint);
128 }
129 }
130 //===automatic auto complete [performance is slower]
131 else if(this._showAutoComplete(documentType, keyEvent)){
132 this.codeEditor.simpleHint(cm, this.codeEditor.javascriptHint);
133 }
134 }
135 },
136
137 /**
138 * Private method
139 * checks for valid keyset to show code completion dropdown
140 */
141 _showAutoComplete : {
142 enumerable:false,
143 value:function(documentType, keyEvent){
144 var status=false;
145
146 if((keyEvent.metaKey || keyEvent.ctrlKey) && (keyEvent.keyCode === 83)){//ctrl+s
147 return false;
148 }
149
150 switch(documentType){
151 case "js":
152 if((keyEvent.type === "keyup")//need seperate keycode set per mode
153 && ((keyEvent.keyCode > 47 && keyEvent.keyCode < 57)//numbers
154 || (keyEvent.keyCode > 64 && keyEvent.keyCode <91)//letters
155 || (keyEvent.keyCode === 190)//period
156 || (keyEvent.keyCode === 189)//underscore, dash
157 )
158 && !(keyEvent.ctrlKey //ctrl
159 || keyEvent.metaKey//cmd
160 || (keyEvent.keyCode === 219)//open bracket [
161 || (keyEvent.keyCode === 221)//close bracket ]
162 || (keyEvent.shiftKey && keyEvent.keyCode === 219)//open bracket {
163 || (keyEvent.shiftKey && keyEvent.keyCode === 221)//close bracket }
164 || (keyEvent.shiftKey && keyEvent.keyCode === 57)//open bracket (
165 || (keyEvent.shiftKey && keyEvent.keyCode === 48)//close bracket )
166 )
167 ){
168 status = true;
169 break;
170 }
171 default :
172 status = false;
173 }
174
175 return status;
176 }
177 },
178
179 handleCodeCompletionSupport:{
180 value:function(fileType){
181 var autoCodeCompleteElem = document.getElementsByClassName("autoCodeComplete")[0], elems=null, i=0;
182 if(autoCodeCompleteElem){
183 elems = autoCodeCompleteElem.getElementsByTagName("*");
184 }
185
186 if(elems && (this.codeCompletionSupport[fileType] === true)){
187 //enable elements
188 for(i=0;i<elems.length;i++){
189 if(elems[i].hasAttribute("disabled")){
190 elems[i].removeAttribute("disabled");
191 }
192 if(elems[i].classList.contains("disabled")){
193 elems[i].classList.remove("disabled");
194 }
195 }
196 }else if(elems && !this.codeCompletionSupport[fileType]){
197 //disable elements
198 for(i=0;i<elems.length;i++){
199 if(!elems[i].hasAttribute("disabled")){
200 elems[i].setAttribute("disabled", "disabled");
201 }
202 if(!elems[i].classList.contains("disabled")){
203 elems[i].classList.add("disabled");
204 }
205 }
206 }
207 }
208 },
209
210 getSelectedRange:{
211 value:function(editor){
212 return { from: editor.getCursor(true), to: editor.getCursor(false) };
213 }
214 },
215
216 autoFormatSelection:{
217 value: function(){
218 var range = this.getSelectedRange(this.application.ninja.documentController.activeDocument.editor);
219 this.application.ninja.documentController.activeDocument.editor.autoFormatRange(range.from, range.to);