aboutsummaryrefslogtreecommitdiff
path: root/js/code-editor/code-editor-wrapper.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/code-editor/code-editor-wrapper.js')
-rw-r--r--js/code-editor/code-editor-wrapper.js255
1 files changed, 255 insertions, 0 deletions
diff --git a/js/code-editor/code-editor-wrapper.js b/js/code-editor/code-editor-wrapper.js
new file mode 100644
index 00000000..942bd5cd
--- /dev/null
+++ b/js/code-editor/code-editor-wrapper.js
@@ -0,0 +1,255 @@
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
12exports.CodeEditorWrapper = Montage.create(Component, {
13 hasTemplate: {
14 value: false
15 },
16
17 _currentDocument: {
18 value : null
19 },
20
21 currentDocument : {
22 get : function() {
23 return this._currentDocument;
24 },
25 set : function(value) {
26 if (value === this._currentDocument) {
27 return;
28 }
29
30 this._currentDocument = value;
31
32 if(!value) {
33
34 } else if(this._currentDocument.currentView === "code") {
35 this.autocomplete = this.codeCompletionSupport[this._currentDocument.model.file.extension];
36 this._currentDocument.model.views.code.editor.focus();
37
38 this.applySettings();
39 }
40 }
41 },
42
43 _codeEditor : {
44 value:null
45 },
46
47 codeEditor:{
48 get: function(){return this._codeEditor;},
49 set: function(value){this._codeEditor = value;}
50 },
51
52 codeCompletionSupport : {
53 value: {"js": true}
54 },
55
56 autocomplete: {
57 value: false
58 },
59
60 _editorTheme: {
61 value:"default"
62 },
63
64 editorTheme:{
65 get: function(){
66 return this._editorTheme;
67 },
68 set: function(value){
69 this._editorTheme = value;
70 }
71 },
72
73 _zoomFactor: {
74 value:100
75 },
76
77 zoomFactor:{
78 get: function() {
79 return this._zoomFactor;
80 },
81 set: function(value) {
82 if(value !== this._zoomFactor){
83 this._zoomFactor = value;
84 this.handleZoom(value);
85 }
86 }
87 },
88
89 deserializedFromTemplate: {
90 value: function() {
91 //TODO:add logic to check some configuration file to load the right code editor
92 this.codeEditor = CodeMirror;
93 }
94 },
95
96 /**
97 * Public method
98 * Creates an editor instance
99 */
100 createEditor : {
101 value:function(codeDocumentView, type, documentType, textDocument){
102 var self = this, editorOptions = null;
103
104 if(!this.application.ninja.editorViewOptions.codeEditorWrapper){
105 this.application.ninja.editorViewOptions.codeEditorWrapper = this;
106 }
107
108 editorOptions = {
109 lineNumbers: true,
110 matchBrackets:true,
111 mode: type,
112 onChange: function(){
113 var historySize = codeDocumentView.editor.historySize();
114 if(historySize.undo>0){
115 textDocument.model.needsSave = true;
116 }else if(historySize.undo===0 && historySize.redo>0){
117 textDocument.model.needsSave = false;
118 }
119 },
120 onCursorActivity: function() {
121 codeDocumentView.editor.matchHighlight("CodeMirror-matchhighlight");
122 codeDocumentView.editor.setLineClass(codeDocumentView.editor.hline, null, null);
123 codeDocumentView.editor.hline = codeDocumentView.editor.setLineClass(codeDocumentView.editor.getCursor().line, null, "activeline");
124 }
125 };
126
127 //configure auto code completion if it is supported for that document type
128
129 this.autocomplete = this.codeCompletionSupport[documentType];
130
131 if(this.autocomplete) {
132
133 editorOptions.onKeyEvent = function(cm, keyEvent){
134 self._codeCompletionKeyEventHandler.call(self, cm, keyEvent, documentType)
135 };
136
137 }
138
139 return self.codeEditor.fromTextArea(codeDocumentView.textArea, editorOptions);
140 }
141 },
142
143 /**
144 * Private method
145 * key event handler for showing code completion dropdown
146 */
147 _codeCompletionKeyEventHandler:{
148 enumerable:false,
149 value: function(cm, keyEvent, documentType) {
150 //comment shortkeys
151 if((keyEvent.metaKey || keyEvent.ctrlKey) && !keyEvent.shiftKey && keyEvent.keyCode === 191){//ctrl+/
152 this.commentSelection(true);
153 return;
154 }
155 //uncomment shortkeys
156 if((keyEvent.metaKey || keyEvent.ctrlKey) && keyEvent.shiftKey && keyEvent.keyCode === 191){//ctrl+shift+/
157 this.commentSelection(false);
158 return;
159 }
160
161 //===manually triggered code completion
162 if((this.currentDocument.model.views.code.editor.automaticCodeHint === false)){
163 if(keyEvent.ctrlKey && keyEvent.keyCode === 32){//Ctrl+Space
164 this.codeEditor.simpleHint(cm, this.codeEditor.javascriptHint);
165 }
166 }
167 //===automatic auto complete [performance is slower]
168 else if(this._showAutoComplete(documentType, keyEvent)){
169 this.codeEditor.simpleHint(cm, this.codeEditor.javascriptHint);
170 }
171 }
172 },
173
174 /**
175 * Private method
176 * checks for valid keyset to show code completion dropdown
177 */
178 _showAutoComplete : {
179 enumerable:false,
180 value:function(documentType, keyEvent){
181 var status=false;
182
183 if((keyEvent.metaKey || keyEvent.ctrlKey) && (keyEvent.keyCode === 83)){//ctrl+s
184 return false;
185 }
186
187 switch(documentType){
188 case "js":
189 if((keyEvent.type === "keyup")//need seperate keycode set per mode
190 && ((keyEvent.keyCode > 47 && keyEvent.keyCode < 57)//numbers
191 || (keyEvent.keyCode > 64 && keyEvent.keyCode <91)//letters
192 || (keyEvent.keyCode === 190)//period
193 || (keyEvent.keyCode === 189)//underscore, dash
194 )
195 && !(keyEvent.ctrlKey //ctrl
196 || keyEvent.metaKey//cmd
197 || (keyEvent.keyCode === 219)//open bracket [
198 || (keyEvent.keyCode === 221)//close bracket ]
199 || (keyEvent.shiftKey && keyEvent.keyCode === 219)//open bracket {
200 || (keyEvent.shiftKey && keyEvent.keyCode === 221)//close bracket }
201 || (keyEvent.shiftKey && keyEvent.keyCode === 57)//open bracket (
202 || (keyEvent.shiftKey && keyEvent.keyCode === 48)//close bracket )
203 )
204 ){
205 status = true;
206 break;
207 }
208 default :
209 status = false;
210 }
211
212 return status;
213 }
214 },
215
216 getSelectedRange:{
217 value:function(editor){
218 return { from: editor.getCursor(true), to: editor.getCursor(false) };
219 }
220 },
221
222 commentSelection:{
223 value: function(isComment){
224 var range = this.getSelectedRange(this.currentDocument.model.views.code.editor);
225 this.currentDocument.model.views.code.editor.commentRange(isComment, range.from, range.to);
226 }
227 },
228
229 handleThemeSelection:{
230 value: function(){
231 this.currentDocument.model.views.code.editor.setOption("theme", this.editorTheme);
232 this.currentDocument.model.views.code.applyTheme("cm-s-"+this.edito