Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js

Issue 2331053002: DevTools: Implement the console prompt with CodeMirror (Closed)
Patch Set: Fix browser tests Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /**
6 * @constructor
7 * @extends {WebInspector.Widget}
8 */
9 WebInspector.ConsolePrompt = function()
10 {
11 WebInspector.Widget.call(this);
12 this._addCompletionsFromHistory = true;
13 this._history = new WebInspector.HistoryManager();
14
15 this._initialText = "";
16 this._editor = null;
17
18 this.element.tabIndex = 0;
19 this.element.addEventListener("keydown", this._editorKeyDown.bind(this), tru e);
20
21 self.runtime.extension(WebInspector.TextEditorFactory).instance().then(gotFa ctory.bind(this));
22
23 /**
24 * @param {!WebInspector.TextEditorFactory} factory
25 * @this {WebInspector.ConsolePrompt}
26 */
27 function gotFactory(factory)
28 {
29 this._editor = factory.createEditor({
30 lineNumbers: false,
31 lineWrapping: true,
32 mimeType: "javascript",
33 autoHeight: true
34 });
35
36 this._editor.configureAutocomplete({
37 substituteRangeCallback: this._substituteRange.bind(this),
38 suggestionsCallback: this._wordsWithPrefix.bind(this),
39 captureEnter: true
40 })
41 this._editor.widget().show(this.element);
42
43 this.setText(this._initialText);
44 delete this._initialText;
45 if (this.hasFocus())
46 this.focus();
47 this.element.tabIndex = -1;
48 }
49 }
50
51 WebInspector.ConsolePrompt.prototype = {
52 /**
53 * @return {!WebInspector.HistoryManager}
54 */
55 history: function()
56 {
57 return this._history;
58 },
59
60 clearAutocomplete: function()
61 {
62 if (this._editor)
63 this._editor.clearAutocomplete();
64 },
65
66 /**
67 * @return {boolean}
68 */
69 isCaretInsidePrompt: function()
70 {
71 return this.hasFocus();
72 },
73
74 /**
75 * @return {boolean}
76 */
77 isCaretAtEndOfPrompt: function()
78 {
79 return !!this._editor && this._editor.selection().collapseToEnd().equal( this._editor.fullRange().collapseToEnd());
80 },
81
82 /**
83 * @return {boolean}
84 */
85 isCaretOnLastLine: function()
86 {
87 return !!this._editor && this._editor.selection().endLine === this._edit or.fullRange().endLine;
88 },
89
90 /**
91 * @return {boolean}
92 */
93 isCaretOnFirstLine: function()
94 {
95 return !!this._editor && this._editor.selection().endLine === 0;
96 },
97
98 moveCaretToEndOfPrompt: function()
99 {
100 if (this._editor)
101 this._editor.setSelection(WebInspector.TextRange.createFromLocation( Infinity,Infinity));
102 },
103
104 moveCaretToEndOfFirstLine: function()
105 {
106 if (this._editor)
107 this._editor.setSelection(WebInspector.TextRange.createFromLocation( 0,Infinity));
108 },
109
110 /**
111 * @param {string} text
112 */
113 setText: function(text)
114 {
115 if (this._editor)
116 this._editor.setText(text);
117 else
118 this._initialText = text;
119 },
120
121 /**
122 * @return {string}
123 */
124 text: function()
125 {
126 return this._editor ? this._editor.text() : this._initialText;
127 },
128
129 /**
130 * @param {boolean} value
131 */
132 setAddCompletionsFromHistory: function(value)
133 {
134 this._addCompletionsFromHistory = value;
135 },
136
137 /**
138 * @param {!Event} event
139 */
140 _editorKeyDown: function(event)
141 {
142 var keyboardEvent = /** @type {!KeyboardEvent} */ (event);
143 var newText;
144 var isPrevious;
145
146 switch (keyboardEvent.keyCode) {
147 case WebInspector.KeyboardShortcut.Keys.Up.code:
148 if (!this.isCaretOnFirstLine())
149 break;
150 newText = this._history.previous(this.text());
151 isPrevious = true;
152 break;
153 case WebInspector.KeyboardShortcut.Keys.Down.code:
154 if (!this.isCaretOnLastLine())
155 break;
156 newText = this._history.next();
157 break;
158 case WebInspector.KeyboardShortcut.Keys.P.code: // Ctrl+P = Previous
159 if (WebInspector.isMac() && keyboardEvent.ctrlKey && !keyboardEvent. metaKey && !keyboardEvent.altKey && !keyboardEvent.shiftKey) {
160 newText = this._history.previous(this.text());
161 isPrevious = true;
162 }
163 break;
164 case WebInspector.KeyboardShortcut.Keys.N.code: // Ctrl+N = Next
165 if (WebInspector.isMac() && keyboardEvent.ctrlKey && !keyboardEvent. metaKey && !keyboardEvent.altKey && !keyboardEvent.shiftKey)
166 newText = this._history.next();
167 break;
168 }
169
170 if (newText === undefined)
171 return;
172 keyboardEvent.consume(true);
173 this.setText(newText);
174
175 if (isPrevious)
176 this.moveCaretToEndOfFirstLine();
177 else
178 this.moveCaretToEndOfPrompt();
179 },
180
181 /**
182 * @param {string} prefix
183 * @return {!WebInspector.SuggestBox.Suggestions}
184 */
185 _historyCompletions: function(prefix)
186 {
187 if (!this._addCompletionsFromHistory || !this.isCaretAtEndOfPrompt())
188 return [];
189 var result = [];
190 var text = this.text();
191 var set = new Set();
192 var data = this._history.historyData();
193 for (var i = data.length - 1; i >= 0 && result.length < 50; --i) {
194 var item = data[i];
195 if (!item.startsWith(text))
196 continue;
197 if (set.has(item))
198 continue;
199 set.add(item);
200 result.push({title: item.substring(text.length - prefix.length), cla ssName: "additional"});
201 }
202 return result;
203 },
204
205 /**
206 * @override
207 */
208 focus: function()
209 {
210 if (this._editor)
211 this._editor.widget().focus();
212 else
213 this.element.focus();
214 },
215
216 /**
217 * @param {number} lineNumber
218 * @param {number} columnNumber
219 * @return {?WebInspector.TextRange}
220 */
221 _substituteRange: function(lineNumber, columnNumber)
222 {
223 var lineText = this._editor.line(lineNumber);
224 var index;
225 for (index = lineText.length - 1; index >= 0; index--) {
226 if (" =:[({;,!+-*/&|^<>.".indexOf(lineText.charAt(index)) !== -1)
227 break;
228 }
229 return new WebInspector.TextRange(lineNumber, index + 1, lineNumber, col umnNumber);
230 },
231
232 /**
233 * @param {!WebInspector.TextRange} prefixRange
234 * @param {!WebInspector.TextRange} substituteRange
235 * @return {!Promise.<!Array.<{title: string, className: (string|undefined)} >>}
236 */
237 _wordsWithPrefix: function(prefixRange, substituteRange)
238 {
239 var fulfill;
240 var promise = new Promise(x => fulfill = x);
241 var prefix = this._editor.text(prefixRange);
242 var before = this._editor.text(new WebInspector.TextRange(0, 0, prefixRa nge.startLine, prefixRange.startColumn));
243 var historyWords = this._historyCompletions(prefix);
244 WebInspector.ExecutionContextSelector.completionsForTextInCurrentContext (before, prefix, false /* Don't force */, innerWordsWithPrefix);
245 return promise;
246
247 /**
248 * @param {!Array.<string>} words
249 */
250 function innerWordsWithPrefix(words)
251 {
252 fulfill(words.map(item => ({title:item})).concat(historyWords));
253 }
254 },
255
256 __proto__: WebInspector.Widget.prototype
257 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698