OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 /** | |
32 * @constructor | |
33 * @extends {WebInspector.InplaceEditor} | |
34 */ | |
35 WebInspector.CodeMirrorUtils = function() | |
36 { | |
37 WebInspector.InplaceEditor.call(this); | |
38 } | |
39 | |
40 /** | |
41 * @param {!WebInspector.TextRange} range | |
42 * @return {!{start: !CodeMirror.Pos, end: !CodeMirror.Pos}} | |
43 */ | |
44 WebInspector.CodeMirrorUtils.toPos = function(range) | |
45 { | |
46 return { | |
47 start: new CodeMirror.Pos(range.startLine, range.startColumn), | |
48 end: new CodeMirror.Pos(range.endLine, range.endColumn) | |
49 }; | |
50 } | |
51 | |
52 /** | |
53 * @param {!CodeMirror.Pos} start | |
54 * @param {!CodeMirror.Pos} end | |
55 * @return {!WebInspector.TextRange} | |
56 */ | |
57 WebInspector.CodeMirrorUtils.toRange = function(start, end) | |
58 { | |
59 return new WebInspector.TextRange(start.line, start.ch, end.line, end.ch); | |
60 } | |
61 | |
62 /** | |
63 * @param {!CodeMirror.ChangeObject} changeObject | |
64 * @return {{oldRange: !WebInspector.TextRange, newRange: !WebInspector.TextRang
e}} | |
65 */ | |
66 WebInspector.CodeMirrorUtils.changeObjectToEditOperation = function(changeObject
) | |
67 { | |
68 var oldRange = WebInspector.CodeMirrorUtils.toRange(changeObject.from, chang
eObject.to); | |
69 var newRange = oldRange.clone(); | |
70 var linesAdded = changeObject.text.length; | |
71 if (linesAdded === 0) { | |
72 newRange.endLine = newRange.startLine; | |
73 newRange.endColumn = newRange.startColumn; | |
74 } else if (linesAdded === 1) { | |
75 newRange.endLine = newRange.startLine; | |
76 newRange.endColumn = newRange.startColumn + changeObject.text[0].length; | |
77 } else { | |
78 newRange.endLine = newRange.startLine + linesAdded - 1; | |
79 newRange.endColumn = changeObject.text[linesAdded - 1].length; | |
80 } | |
81 return { | |
82 oldRange: oldRange, | |
83 newRange: newRange | |
84 }; | |
85 } | |
86 | |
87 /** | |
88 * @param {!CodeMirror} codeMirror | |
89 * @param {number} linesCount | |
90 * @return {!Array.<string>} | |
91 */ | |
92 WebInspector.CodeMirrorUtils.pullLines = function(codeMirror, linesCount) | |
93 { | |
94 var lines = []; | |
95 codeMirror.eachLine(0, linesCount, onLineHandle); | |
96 return lines; | |
97 | |
98 /** | |
99 * @param {!{text: string}} lineHandle | |
100 */ | |
101 function onLineHandle(lineHandle) | |
102 { | |
103 lines.push(lineHandle.text); | |
104 } | |
105 } | |
106 | |
107 WebInspector.CodeMirrorUtils.prototype = { | |
108 /** | |
109 * @override | |
110 * @return {string} | |
111 */ | |
112 editorContent: function(editingContext) { | |
113 return editingContext.codeMirror.getValue(); | |
114 }, | |
115 | |
116 /** | |
117 * @param {!Event} e | |
118 */ | |
119 _consumeCopy: function(e) | |
120 { | |
121 e.consume(); | |
122 }, | |
123 | |
124 setUpEditor: function(editingContext) | |
125 { | |
126 var element = editingContext.element; | |
127 var config = editingContext.config; | |
128 editingContext.cssLoadView = new WebInspector.CodeMirrorCSSLoadView(); | |
129 editingContext.cssLoadView.show(element); | |
130 WebInspector.setCurrentFocusElement(element); | |
131 element.addEventListener("copy", this._consumeCopy, false); | |
132 var codeMirror = new window.CodeMirror(element, { | |
133 mode: config.mode, | |
134 lineWrapping: config.lineWrapping, | |
135 lineWiseCopyCut: false, | |
136 smartIndent: config.smartIndent, | |
137 autofocus: true, | |
138 theme: config.theme, | |
139 value: config.initialValue | |
140 }); | |
141 codeMirror.getWrapperElement().classList.add("source-code"); | |
142 codeMirror.on("cursorActivity", function(cm) { | |
143 cm.display.cursorDiv.scrollIntoViewIfNeeded(false); | |
144 }); | |
145 editingContext.codeMirror = codeMirror; | |
146 }, | |
147 | |
148 closeEditor: function(editingContext) | |
149 { | |
150 editingContext.element.removeEventListener("copy", this._consumeCopy, fa
lse); | |
151 editingContext.cssLoadView.detach(); | |
152 }, | |
153 | |
154 cancelEditing: function(editingContext) | |
155 { | |
156 editingContext.codeMirror.setValue(editingContext.oldText); | |
157 }, | |
158 | |
159 augmentEditingHandle: function(editingContext, handle) | |
160 { | |
161 function setWidth(editingContext, width) | |
162 { | |
163 var padding = 30; | |
164 var codeMirror = editingContext.codeMirror; | |
165 codeMirror.getWrapperElement().style.width = (width - codeMirror.get
WrapperElement().offsetLeft - padding) + "px"; | |
166 codeMirror.refresh(); | |
167 } | |
168 | |
169 handle.codeMirror = editingContext.codeMirror; | |
170 handle.setWidth = setWidth.bind(null, editingContext); | |
171 }, | |
172 | |
173 __proto__: WebInspector.InplaceEditor.prototype | |
174 } | |
175 | |
176 /** | |
177 * @constructor | |
178 * @implements {WebInspector.TokenizerFactory} | |
179 */ | |
180 WebInspector.CodeMirrorUtils.TokenizerFactory = function() { } | |
181 | |
182 WebInspector.CodeMirrorUtils.TokenizerFactory.prototype = { | |
183 /** | |
184 * @override | |
185 * @param {string} mimeType | |
186 * @return {function(string, function(string, ?string, number, number))} | |
187 */ | |
188 createTokenizer: function(mimeType) | |
189 { | |
190 var mode = CodeMirror.getMode({indentUnit: 2}, mimeType); | |
191 var state = CodeMirror.startState(mode); | |
192 function tokenize(line, callback) | |
193 { | |
194 var stream = new CodeMirror.StringStream(line); | |
195 while (!stream.eol()) { | |
196 var style = mode.token(stream, state); | |
197 var value = stream.current(); | |
198 callback(value, style, stream.start, stream.start + value.length
); | |
199 stream.start = stream.pos; | |
200 } | |
201 } | |
202 return tokenize; | |
203 } | |
204 } | |
205 | |
206 /** | |
207 * This bogus view is needed to load/unload CodeMirror-related CSS on demand. | |
208 * | |
209 * @constructor | |
210 * @extends {WebInspector.VBox} | |
211 */ | |
212 WebInspector.CodeMirrorCSSLoadView = function() | |
213 { | |
214 WebInspector.VBox.call(this); | |
215 this.element.classList.add("hidden"); | |
216 this.registerRequiredCSS("cm/codemirror.css"); | |
217 this.registerRequiredCSS("source_frame/cmdevtools.css"); | |
218 WebInspector.CodeMirrorUtils.appendThemeStyle(this.element); | |
219 } | |
220 | |
221 WebInspector.CodeMirrorCSSLoadView.prototype = { | |
222 __proto__: WebInspector.VBox.prototype | |
223 } | |
224 | |
225 | |
226 /** | |
227 * @param {!Element} element | |
228 */ | |
229 WebInspector.CodeMirrorUtils.appendThemeStyle = function(element) | |
230 { | |
231 if (WebInspector.themeSupport.hasTheme()) | |
232 return; | |
233 var backgroundColor = InspectorFrontendHost.getSelectionBackgroundColor(); | |
234 var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selecte
d { background-color: " + backgroundColor + ";}" : ""; | |
235 var foregroundColor = InspectorFrontendHost.getSelectionForegroundColor(); | |
236 var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selecte
dtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!import
ant;}" : ""; | |
237 var style = createElement("style"); | |
238 if (foregroundColorRule || backgroundColorRule) | |
239 style.textContent = backgroundColorRule + foregroundColorRule; | |
240 element.appendChild(style); | |
241 } | |
OLD | NEW |