Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / devtools / front_end / source_frame / CodeMirrorUtils.js
blobb3da969296dfb8481cd00f3933b0eed85713a978
1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
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.
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.
31 /**
32 * @constructor
33 * @extends {WebInspector.InplaceEditor}
35 WebInspector.CodeMirrorUtils = function()
37 WebInspector.InplaceEditor.call(this);
40 /**
41 * @param {!WebInspector.TextRange} range
42 * @return {!{start: !CodeMirror.Pos, end: !CodeMirror.Pos}}
44 WebInspector.CodeMirrorUtils.toPos = function(range)
46 return {
47 start: new CodeMirror.Pos(range.startLine, range.startColumn),
48 end: new CodeMirror.Pos(range.endLine, range.endColumn)
52 /**
53 * @param {!CodeMirror.Pos} start
54 * @param {!CodeMirror.Pos} end
55 * @return {!WebInspector.TextRange}
57 WebInspector.CodeMirrorUtils.toRange = function(start, end)
59 return new WebInspector.TextRange(start.line, start.ch, end.line, end.ch);
62 /**
63 * @param {!CodeMirror.ChangeObject} changeObject
64 * @return {{oldRange: !WebInspector.TextRange, newRange: !WebInspector.TextRange}}
66 WebInspector.CodeMirrorUtils.changeObjectToEditOperation = function(changeObject)
68 var oldRange = WebInspector.CodeMirrorUtils.toRange(changeObject.from, changeObject.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;
81 return {
82 oldRange: oldRange,
83 newRange: newRange
87 /**
88 * @param {!CodeMirror} codeMirror
89 * @param {number} linesCount
90 * @return {!Array.<string>}
92 WebInspector.CodeMirrorUtils.pullLines = function(codeMirror, linesCount)
94 var lines = [];
95 codeMirror.eachLine(0, linesCount, onLineHandle);
96 return lines;
98 /**
99 * @param {!{text: string}} lineHandle
101 function onLineHandle(lineHandle)
103 lines.push(lineHandle.text);
107 WebInspector.CodeMirrorUtils.prototype = {
109 * @override
110 * @return {string}
112 editorContent: function(editingContext) {
113 return editingContext.codeMirror.getValue();
117 * @param {!Event} e
119 _consumeCopy: function(e)
121 e.consume();
124 setUpEditor: function(editingContext)
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 smartIndent: config.smartIndent,
136 autofocus: true,
137 theme: config.theme,
138 value: config.initialValue
140 codeMirror.getWrapperElement().classList.add("source-code");
141 codeMirror.on("cursorActivity", function(cm) {
142 cm.display.cursorDiv.scrollIntoViewIfNeeded(false);
144 editingContext.codeMirror = codeMirror;
147 closeEditor: function(editingContext)
149 editingContext.element.removeEventListener("copy", this._consumeCopy, false);
150 editingContext.cssLoadView.detach();
153 cancelEditing: function(editingContext)
155 editingContext.codeMirror.setValue(editingContext.oldText);
158 augmentEditingHandle: function(editingContext, handle)
160 function setWidth(editingContext, width)
162 var padding = 30;
163 var codeMirror = editingContext.codeMirror;
164 codeMirror.getWrapperElement().style.width = (width - codeMirror.getWrapperElement().offsetLeft - padding) + "px";
165 codeMirror.refresh();
168 handle.codeMirror = editingContext.codeMirror;
169 handle.setWidth = setWidth.bind(null, editingContext);
172 __proto__: WebInspector.InplaceEditor.prototype
176 * @constructor
177 * @implements {WebInspector.TokenizerFactory}
179 WebInspector.CodeMirrorUtils.TokenizerFactory = function() { }
181 WebInspector.CodeMirrorUtils.TokenizerFactory.prototype = {
183 * @override
184 * @param {string} mimeType
185 * @return {function(string, function(string, ?string, number, number))}
187 createTokenizer: function(mimeType)
189 var mode = CodeMirror.getMode({indentUnit: 2}, mimeType);
190 var state = CodeMirror.startState(mode);
191 function tokenize(line, callback)
193 var stream = new CodeMirror.StringStream(line);
194 while (!stream.eol()) {
195 var style = mode.token(stream, state);
196 var value = stream.current();
197 callback(value, style, stream.start, stream.start + value.length);
198 stream.start = stream.pos;
201 return tokenize;
206 * This bogus view is needed to load/unload CodeMirror-related CSS on demand.
208 * @constructor
209 * @extends {WebInspector.VBox}
211 WebInspector.CodeMirrorCSSLoadView = function()
213 WebInspector.VBox.call(this);
214 this.element.classList.add("hidden");
215 this.registerRequiredCSS("cm/codemirror.css");
216 this.registerRequiredCSS("source_frame/cmdevtools.css");
217 this.element.appendChild(WebInspector.CodeMirrorUtils.createThemeStyle());
220 WebInspector.CodeMirrorCSSLoadView.prototype = {
221 __proto__: WebInspector.VBox.prototype
226 * @return {!Element}
228 WebInspector.CodeMirrorUtils.createThemeStyle = function()
230 var backgroundColor = InspectorFrontendHost.getSelectionBackgroundColor();
231 var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selected { background-color: " + backgroundColor + ";}" : "";
232 var foregroundColor = InspectorFrontendHost.getSelectionForegroundColor();
233 var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!important;}" : "";
234 var style = createElement("style");
235 if (foregroundColorRule || backgroundColorRule)
236 style.textContent = backgroundColorRule + foregroundColorRule;
237 return style;