Web Inspector: add Ace editor experiment
[WebKit-https.git] / Source / WebCore / inspector / front-end / AceTextEditor.js
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  * Copyright (C) 2010 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
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
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 importScript("ace/ace.js");
33
34
35 /**
36  * @constructor
37  * @extends {WebInspector.View}
38  * @implements {WebInspector.TextEditor}
39  * @param {?string} url
40  * @param {WebInspector.TextEditorDelegate} delegate
41  */
42
43 WebInspector.AceTextEditor = function(url, delegate)
44 {
45     WebInspector.View.call(this);
46     this._delegate = delegate;
47     this._url = url;
48     this.element.className = "ace-editor-container";
49
50     var prefix = window.flattenImports ? "" : "ace/";
51     ace.config.setModuleUrl("ace/mode/javascript", prefix + "mode_javascript.js");
52     ace.config.setModuleUrl("ace/mode/javascript", prefix + "mode_css.js");
53     ace.config.setModuleUrl("ace/mode/javascript", prefix + "mode_html.js");
54     ace.config.setModuleUrl("ace/theme/textmate", prefix + "theme_textmate.js");
55     this._aceEditor = window.ace.edit(this.element);
56
57     this._aceEditor.setShowFoldWidgets(false);
58     this._aceEditor.on("gutterclick", this._gutterClick.bind(this));
59     this._aceEditor.on("change", this._onTextChange.bind(this));
60     this._aceEditor.setHighlightActiveLine(false);
61     this._aceEditor.session.setUseWorker(false);
62     this.registerRequiredCSS("ace/acedevtools.css");
63 }
64
65 WebInspector.AceTextEditor.prototype = {
66
67     _onTextChange: function(event)
68     {
69         this._delegate.onTextChanged(null, null);
70     },
71
72     _gutterClick: function(event)
73     {
74         var lineNumber = parseInt(event.domEvent.target.textContent) - 1;
75         this.dispatchEventToListeners(WebInspector.TextEditor.Events.GutterClick, { lineNumber: lineNumber, event: event.domEvent });
76     },
77
78     /**
79      * @param {string} mimeType
80      */
81     set mimeType(mimeType)
82     {
83         switch(mimeType) {
84         case "text/html":
85             this._aceEditor.getSession().setMode("ace/mode/html");
86             break;
87         case "text/css":
88             this._aceEditor.getSession().setMode("ace/mode/css");
89             break;
90         case "text/javascript":
91             this._aceEditor.getSession().setMode("ace/mode/javascript");
92             break;
93         }
94     },
95
96     /**
97      * @param {boolean} readOnly
98      */
99     setReadOnly: function(readOnly)
100     {
101         this._aceEditor.setReadOnly(readOnly);
102     },
103
104     /**
105      * @return {boolean}
106      */
107     readOnly: function()
108     {
109         return this._aceEditor.getReadOnly();
110     },
111
112     focus: function()
113     {
114         this._aceEditor.focus();
115     },
116
117     /**
118      * @return {Element}
119      */
120     defaultFocusedElement: function()
121     {
122         return this.element.firstChild;
123     },
124
125     /**
126      * @param {string} regex
127      * @param {string} cssClass
128      * @return {WebInspector.TextEditorMainPanel.HighlightDescriptor}
129      */
130     highlightRegex: function(regex, cssClass)
131     {
132         console.log("aceEditor.highlightRegex not implemented");
133     },
134
135     /**
136      * @param {WebInspector.TextRange} range
137      * @param {string} cssClass
138      */
139     highlightRange: function(range, cssClass)
140     {
141         console.log("aceEditor.highlightRange not implemented");
142     },
143
144     /**
145      * @param {WebInspector.TextEditorMainPanel.HighlightDescriptor} highlightDescriptor
146      */
147     removeHighlight: function(highlightDescriptor)
148     {
149         console.log("aceEditor.removeHighlight not implemented");
150     },
151
152     /**
153      * @param {number} lineNumber
154      */
155     revealLine: function(lineNumber) {
156         this._aceEditor.scrollToLine(lineNumber, false, true);
157     },
158
159     /**
160      * @param {number} lineNumber
161      * @param {boolean} disabled
162      * @param {boolean} conditional
163      */
164     addBreakpoint: function(lineNumber, disabled, conditional)
165     {
166         this._aceEditor.getSession().setBreakpoint(lineNumber, "webkit-breakpoint");
167     },
168
169     /**
170      * @param {number} lineNumber
171      */
172     removeBreakpoint: function(lineNumber)
173     {
174         this._aceEditor.getSession().clearBreakpoint(lineNumber);
175     },
176
177     /**
178      * @param {number} lineNumber
179      */
180     setExecutionLine: function(lineNumber)
181     {
182         console.log("aceEditor.setExecutionLine not implemented");
183     },
184
185     /**
186      * @param {WebInspector.TextRange} range
187      * @return {string}
188      */
189     copyRange: function(range)
190     {
191         console.log("aceEditor.copyRange not implemented");
192         return "";
193     },
194
195     clearExecutionLine: function()
196     {
197         console.log("aceEditor.clearExecutionLine not implemented");
198     },
199
200     /**
201      * @param {number} lineNumber
202      * @param {Element} element
203      */
204     addDecoration: function(lineNumber, element)
205     {
206         console.log("aceEditor.addDecoration not implemented");
207     },
208
209     /**
210      * @param {number} lineNumber
211      * @param {Element} element
212      */
213     removeDecoration: function(lineNumber, element)
214     {
215         console.log("aceEditor.removeDecoration not implemented");
216     },
217
218     /**
219      * @param {WebInspector.TextRange} range
220      */
221     markAndRevealRange: function(range)
222     {
223         console.log("aceEditor.markAndRevealRange not implemented");
224     },
225
226     /**
227      * @param {number} lineNumber
228      */
229     highlightLine: function(lineNumber)
230     {
231         console.log("aceEditor.highlightLine not implemented");
232     },
233
234     clearLineHighlight: function() {
235         console.log("aceEditor.clearLineHighlight not implemented");
236     },
237
238     /**
239      * @return {Array.<Element>}
240      */
241     elementsToRestoreScrollPositionsFor: function()
242     {
243         return [];
244     },
245
246     /**
247      * @param {WebInspector.TextEditor} textEditor
248      */
249     inheritScrollPositions: function(textEditor)
250     {
251         console.log("aceEditor.inheritScrollPositions not implemented");
252     },
253
254     beginUpdates: function() { },
255
256     endUpdates: function() { },
257
258     onResize: function() { },
259
260     /**
261      * @param {WebInspector.TextRange} range
262      * @param {string} text
263      * @return {WebInspector.TextRange}
264      */
265     editRange: function(range, text)
266     {
267         console.log("aceEditor.editRange not implemented");
268     },
269
270     /**
271      * @param {number} lineNumber
272      */
273     scrollToLine: function(lineNumber)
274     {
275         this._aceEditor.scrollToLine(lineNumber, false, true);
276     },
277
278     /**
279      * @return {WebInspector.TextRange}
280      */
281     selection: function()
282     {
283         console.log("aceEditor.selection not implemented");
284     },
285
286     /**
287      * @return {WebInspector.TextRange?}
288      */
289     lastSelection: function()
290     {
291         console.log("aceEditor.lastSelection not implemented");
292     },
293
294     /**
295      * @param {WebInspector.TextRange} textRange
296      */
297     setSelection: function(textRange)
298     {
299         console.log("aceEditor.setSelection not implemented");
300     },
301
302     /**
303      * @param {string} text
304      */
305     setText: function(text)
306     {
307         this._aceEditor.getSession().setValue(text);
308     },
309
310     /**
311      * @return {string}
312      */
313     text: function()
314     {
315         return this._aceEditor.getSession().getValue();
316     },
317
318     /**
319      * @return {WebInspector.TextRange}
320      */
321     range: function()
322     {
323         console.log("aceEditor.range not implemented");
324     },
325
326     /**
327      * @param {number} lineNumber
328      * @return {string}
329      */
330     line: function(lineNumber)
331     {
332         return this._aceEditor.getSession().getLine(lineNumber);
333     },
334
335     /**
336      * @return {number}
337      */
338     get linesCount() {
339         return this._aceEditor.getSession().getLength();
340     },
341
342     /**
343      * @param {number} line
344      * @param {string} name
345      * @param {Object?} value
346      */
347     setAttribute: function(line, name, value)
348     {
349         console.log("aceEditor.setAttribute not implemented");
350     },
351
352     /**
353      * @param {number} line
354      * @param {string} name
355      * @return {Object|null} value
356      */
357     getAttribute: function(line, name)
358     {
359         console.log("aceEditor.getAttribute not implemented");
360     },
361
362     /**
363      * @param {number} line
364      * @param {string} name
365      */
366     removeAttribute: function(line, name)
367     {
368         console.log("aceEditor.removeAttribute not implemented");
369     },
370
371     wasShown: function() { },
372
373     __proto__: WebInspector.View.prototype
374 }