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

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

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4
5 /** 4 /**
6 * @constructor 5 * @unrestricted
7 * @extends {WebInspector.Widget}
8 */ 6 */
9 WebInspector.ConsolePrompt = function() 7 WebInspector.ConsolePrompt = class extends WebInspector.Widget {
10 { 8 constructor() {
11 WebInspector.Widget.call(this); 9 super();
12 this._addCompletionsFromHistory = true; 10 this._addCompletionsFromHistory = true;
13 this._history = new WebInspector.ConsoleHistoryManager(); 11 this._history = new WebInspector.ConsoleHistoryManager();
14 12
15 this._initialText = ""; 13 this._initialText = '';
16 this._editor = null; 14 this._editor = null;
17 15
18 this.element.tabIndex = 0; 16 this.element.tabIndex = 0;
19 17
20 self.runtime.extension(WebInspector.TextEditorFactory).instance().then(gotFa ctory.bind(this)); 18 self.runtime.extension(WebInspector.TextEditorFactory).instance().then(gotFa ctory.bind(this));
21 19
22 /** 20 /**
23 * @param {!WebInspector.TextEditorFactory} factory 21 * @param {!WebInspector.TextEditorFactory} factory
24 * @this {WebInspector.ConsolePrompt} 22 * @this {WebInspector.ConsolePrompt}
25 */ 23 */
26 function gotFactory(factory) 24 function gotFactory(factory) {
27 { 25 this._editor =
28 this._editor = factory.createEditor({ 26 factory.createEditor({lineNumbers: false, lineWrapping: true, mimeType : 'javascript', autoHeight: true});
29 lineNumbers: false, 27
30 lineWrapping: true, 28 this._editor.configureAutocomplete({
31 mimeType: "javascript", 29 substituteRangeCallback: this._substituteRange.bind(this),
32 autoHeight: true 30 suggestionsCallback: this._wordsWithPrefix.bind(this),
33 }); 31 captureEnter: true
34 32 });
35 this._editor.configureAutocomplete({ 33 this._editor.widget().element.addEventListener('keydown', this._editorKeyD own.bind(this), true);
36 substituteRangeCallback: this._substituteRange.bind(this), 34 this._editor.widget().show(this.element);
37 suggestionsCallback: this._wordsWithPrefix.bind(this), 35
38 captureEnter: true 36 this.setText(this._initialText);
39 }); 37 delete this._initialText;
40 this._editor.widget().element.addEventListener("keydown", this._editorKe yDown.bind(this), true); 38 if (this.hasFocus())
41 this._editor.widget().show(this.element); 39 this.focus();
42 40 this.element.tabIndex = -1;
43 this.setText(this._initialText); 41
44 delete this._initialText; 42 this._editorSetForTest();
45 if (this.hasFocus()) 43 }
46 this.focus(); 44 }
47 this.element.tabIndex = -1; 45
48 46 /**
49 this._editorSetForTest(); 47 * @return {!WebInspector.ConsoleHistoryManager}
50 } 48 */
49 history() {
50 return this._history;
51 }
52
53 clearAutocomplete() {
54 if (this._editor)
55 this._editor.clearAutocomplete();
56 }
57
58 /**
59 * @return {boolean}
60 */
61 _isCaretAtEndOfPrompt() {
62 return !!this._editor && this._editor.selection().collapseToEnd().equal(this ._editor.fullRange().collapseToEnd());
63 }
64
65 moveCaretToEndOfPrompt() {
66 if (this._editor)
67 this._editor.setSelection(WebInspector.TextRange.createFromLocation(Infini ty, Infinity));
68 }
69
70 /**
71 * @param {string} text
72 */
73 setText(text) {
74 if (this._editor)
75 this._editor.setText(text);
76 else
77 this._initialText = text;
78 }
79
80 /**
81 * @return {string}
82 */
83 text() {
84 return this._editor ? this._editor.text() : this._initialText;
85 }
86
87 /**
88 * @param {boolean} value
89 */
90 setAddCompletionsFromHistory(value) {
91 this._addCompletionsFromHistory = value;
92 }
93
94 /**
95 * @param {!Event} event
96 */
97 _editorKeyDown(event) {
98 var keyboardEvent = /** @type {!KeyboardEvent} */ (event);
99 var newText;
100 var isPrevious;
101
102 switch (keyboardEvent.keyCode) {
103 case WebInspector.KeyboardShortcut.Keys.Up.code:
104 if (this._editor.selection().endLine > 0)
105 break;
106 newText = this._history.previous(this.text());
107 isPrevious = true;
108 break;
109 case WebInspector.KeyboardShortcut.Keys.Down.code:
110 if (this._editor.selection().endLine < this._editor.fullRange().endLine)
111 break;
112 newText = this._history.next();
113 break;
114 case WebInspector.KeyboardShortcut.Keys.P.code: // Ctrl+P = Previous
115 if (WebInspector.isMac() && keyboardEvent.ctrlKey && !keyboardEvent.meta Key && !keyboardEvent.altKey &&
116 !keyboardEvent.shiftKey) {
117 newText = this._history.previous(this.text());
118 isPrevious = true;
119 }
120 break;
121 case WebInspector.KeyboardShortcut.Keys.N.code: // Ctrl+N = Next
122 if (WebInspector.isMac() && keyboardEvent.ctrlKey && !keyboardEvent.meta Key && !keyboardEvent.altKey &&
123 !keyboardEvent.shiftKey)
124 newText = this._history.next();
125 break;
126 case WebInspector.KeyboardShortcut.Keys.Enter.code:
127 this._enterKeyPressed(keyboardEvent);
128 break;
129 }
130
131 if (newText === undefined)
132 return;
133 keyboardEvent.consume(true);
134 this.setText(newText);
135
136 if (isPrevious)
137 this._editor.setSelection(WebInspector.TextRange.createFromLocation(0, Inf inity));
138 else
139 this.moveCaretToEndOfPrompt();
140 }
141
142 /**
143 * @param {!KeyboardEvent} event
144 */
145 _enterKeyPressed(event) {
146 if (event.altKey || event.ctrlKey || event.shiftKey)
147 return;
148
149 event.consume(true);
150
151 this.clearAutocomplete();
152
153 var str = this.text();
154 if (!str.length)
155 return;
156
157 var currentExecutionContext = WebInspector.context.flavor(WebInspector.Execu tionContext);
158 if (!this._isCaretAtEndOfPrompt() || !currentExecutionContext) {
159 this._appendCommand(str, true);
160 return;
161 }
162 currentExecutionContext.target().runtimeModel.compileScript(
163 str, '', false, currentExecutionContext.id, compileCallback.bind(this));
164
165 /**
166 * @param {!RuntimeAgent.ScriptId=} scriptId
167 * @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
168 * @this {WebInspector.ConsolePrompt}
169 */
170 function compileCallback(scriptId, exceptionDetails) {
171 if (str !== this.text())
172 return;
173 if (exceptionDetails &&
174 (exceptionDetails.exception.description.startsWith('SyntaxError: Unexp ected end of input') ||
175 exceptionDetails.exception.description.startsWith('SyntaxError: Unter minated template literal'))) {
176 this._editor.newlineAndIndent();
177 this._enterProcessedForTest();
178 return;
179 }
180 this._appendCommand(str, true);
181 this._enterProcessedForTest();
182 }
183 }
184
185 /**
186 * @param {string} text
187 * @param {boolean} useCommandLineAPI
188 */
189 _appendCommand(text, useCommandLineAPI) {
190 this.setText('');
191 var currentExecutionContext = WebInspector.context.flavor(WebInspector.Execu tionContext);
192 if (currentExecutionContext) {
193 WebInspector.ConsoleModel.evaluateCommandInConsole(currentExecutionContext , text, useCommandLineAPI);
194 if (WebInspector.ConsolePanel.instance().isShowing())
195 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Com mandEvaluatedInConsolePanel);
196 }
197 }
198
199 _enterProcessedForTest() {
200 }
201
202 /**
203 * @param {string} prefix
204 * @return {!WebInspector.SuggestBox.Suggestions}
205 */
206 _historyCompletions(prefix) {
207 if (!this._addCompletionsFromHistory || !this._isCaretAtEndOfPrompt())
208 return [];
209 var result = [];
210 var text = this.text();
211 var set = new Set();
212 var data = this._history.historyData();
213 for (var i = data.length - 1; i >= 0 && result.length < 50; --i) {
214 var item = data[i];
215 if (!item.startsWith(text))
216 continue;
217 if (set.has(item))
218 continue;
219 set.add(item);
220 result.push({title: item.substring(text.length - prefix.length), className : 'additional'});
221 }
222 return result;
223 }
224
225 /**
226 * @override
227 */
228 focus() {
229 if (this._editor)
230 this._editor.widget().focus();
231 else
232 this.element.focus();
233 }
234
235 /**
236 * @param {number} lineNumber
237 * @param {number} columnNumber
238 * @return {?WebInspector.TextRange}
239 */
240 _substituteRange(lineNumber, columnNumber) {
241 var lineText = this._editor.line(lineNumber);
242 var index;
243 for (index = lineText.length - 1; index >= 0; index--) {
244 if (' =:[({;,!+-*/&|^<>.'.indexOf(lineText.charAt(index)) !== -1)
245 break;
246 }
247 return new WebInspector.TextRange(lineNumber, index + 1, lineNumber, columnN umber);
248 }
249
250 /**
251 * @param {!WebInspector.TextRange} prefixRange
252 * @param {!WebInspector.TextRange} substituteRange
253 * @return {!Promise<!WebInspector.SuggestBox.Suggestions>}
254 */
255 _wordsWithPrefix(prefixRange, substituteRange) {
256 var prefix = this._editor.text(prefixRange);
257 var before = this._editor.text(new WebInspector.TextRange(0, 0, prefixRange. startLine, prefixRange.startColumn));
258 var historyWords = this._historyCompletions(prefix);
259 return WebInspector.ExecutionContextSelector.completionsForTextInCurrentCont ext(before, prefix, true /* force */)
260 .then(innerWordsWithPrefix);
261
262 /**
263 * @param {!Array<string>} words
264 * @return {!WebInspector.SuggestBox.Suggestions}
265 */
266 function innerWordsWithPrefix(words) {
267 return words.map(item => ({title: item})).concat(historyWords);
268 }
269 }
270
271 _editorSetForTest() {
272 }
51 }; 273 };
52 274
53 WebInspector.ConsolePrompt.prototype = {
54 /**
55 * @return {!WebInspector.ConsoleHistoryManager}
56 */
57 history: function()
58 {
59 return this._history;
60 },
61
62 clearAutocomplete: function()
63 {
64 if (this._editor)
65 this._editor.clearAutocomplete();
66 },
67
68 /**
69 * @return {boolean}
70 */
71 _isCaretAtEndOfPrompt: function()
72 {
73 return !!this._editor && this._editor.selection().collapseToEnd().equal( this._editor.fullRange().collapseToEnd());
74 },
75
76 moveCaretToEndOfPrompt: function()
77 {
78 if (this._editor)
79 this._editor.setSelection(WebInspector.TextRange.createFromLocation( Infinity, Infinity));
80 },
81
82 /**
83 * @param {string} text
84 */
85 setText: function(text)
86 {
87 if (this._editor)
88 this._editor.setText(text);
89 else
90 this._initialText = text;
91 },
92
93 /**
94 * @return {string}
95 */
96 text: function()
97 {
98 return this._editor ? this._editor.text() : this._initialText;
99 },
100
101 /**
102 * @param {boolean} value
103 */
104 setAddCompletionsFromHistory: function(value)
105 {
106 this._addCompletionsFromHistory = value;
107 },
108
109 /**
110 * @param {!Event} event
111 */
112 _editorKeyDown: function(event)
113 {
114 var keyboardEvent = /** @type {!KeyboardEvent} */ (event);
115 var newText;
116 var isPrevious;
117
118 switch (keyboardEvent.keyCode) {
119 case WebInspector.KeyboardShortcut.Keys.Up.code:
120 if (this._editor.selection().endLine > 0)
121 break;
122 newText = this._history.previous(this.text());
123 isPrevious = true;
124 break;
125 case WebInspector.KeyboardShortcut.Keys.Down.code:
126 if (this._editor.selection().endLine < this._editor.fullRange().endL ine)
127 break;
128 newText = this._history.next();
129 break;
130 case WebInspector.KeyboardShortcut.Keys.P.code: // Ctrl+P = Previous
131 if (WebInspector.isMac() && keyboardEvent.ctrlKey && !keyboardEvent. metaKey && !keyboardEvent.altKey && !keyboardEvent.shiftKey) {
132 newText = this._history.previous(this.text());
133 isPrevious = true;
134 }
135 break;
136 case WebInspector.KeyboardShortcut.Keys.N.code: // Ctrl+N = Next
137 if (WebInspector.isMac() && keyboardEvent.ctrlKey && !keyboardEvent. metaKey && !keyboardEvent.altKey && !keyboardEvent.shiftKey)
138 newText = this._history.next();
139 break;
140 case WebInspector.KeyboardShortcut.Keys.Enter.code:
141 this._enterKeyPressed(keyboardEvent);
142 break;
143 }
144
145 if (newText === undefined)
146 return;
147 keyboardEvent.consume(true);
148 this.setText(newText);
149
150 if (isPrevious)
151 this._editor.setSelection(WebInspector.TextRange.createFromLocation( 0, Infinity));
152 else
153 this.moveCaretToEndOfPrompt();
154 },
155
156 /**
157 * @param {!KeyboardEvent} event
158 */
159 _enterKeyPressed: function(event)
160 {
161 if (event.altKey || event.ctrlKey || event.shiftKey)
162 return;
163
164 event.consume(true);
165
166 this.clearAutocomplete();
167
168 var str = this.text();
169 if (!str.length)
170 return;
171
172 var currentExecutionContext = WebInspector.context.flavor(WebInspector.E xecutionContext);
173 if (!this._isCaretAtEndOfPrompt() || !currentExecutionContext) {
174 this._appendCommand(str, true);
175 return;
176 }
177 currentExecutionContext.target().runtimeModel.compileScript(str, "", fal se, currentExecutionContext.id, compileCallback.bind(this));
178
179 /**
180 * @param {!RuntimeAgent.ScriptId=} scriptId
181 * @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
182 * @this {WebInspector.ConsolePrompt}
183 */
184 function compileCallback(scriptId, exceptionDetails)
185 {
186 if (str !== this.text())
187 return;
188 if (exceptionDetails && (exceptionDetails.exception.description.star tsWith("SyntaxError: Unexpected end of input")
189 || exceptionDetails.exception.description.startsWith("SyntaxErro r: Unterminated template literal"))) {
190 this._editor.newlineAndIndent();
191 this._enterProcessedForTest();
192 return;
193 }
194 this._appendCommand(str, true);
195 this._enterProcessedForTest();
196 }
197 },
198
199 /**
200 * @param {string} text
201 * @param {boolean} useCommandLineAPI
202 */
203 _appendCommand: function(text, useCommandLineAPI)
204 {
205 this.setText("");
206 var currentExecutionContext = WebInspector.context.flavor(WebInspector.E xecutionContext);
207 if (currentExecutionContext) {
208 WebInspector.ConsoleModel.evaluateCommandInConsole(currentExecutionC ontext, text, useCommandLineAPI);
209 if (WebInspector.ConsolePanel.instance().isShowing())
210 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Ac tion.CommandEvaluatedInConsolePanel);
211 }
212 },
213
214 _enterProcessedForTest: function() { },
215
216 /**
217 * @param {string} prefix
218 * @return {!WebInspector.SuggestBox.Suggestions}
219 */
220 _historyCompletions: function(prefix)
221 {
222 if (!this._addCompletionsFromHistory || !this._isCaretAtEndOfPrompt())
223 return [];
224 var result = [];
225 var text = this.text();
226 var set = new Set();
227 var data = this._history.historyData();
228 for (var i = data.length - 1; i >= 0 && result.length < 50; --i) {
229 var item = data[i];
230 if (!item.startsWith(text))
231 continue;
232 if (set.has(item))
233 continue;
234 set.add(item);
235 result.push({ title: item.substring(text.length - prefix.length), cl assName: "additional" });
236 }
237 return result;
238 },
239
240 /**
241 * @override
242 */
243 focus: function()
244 {
245 if (this._editor)
246 this._editor.widget().focus();
247 else
248 this.element.focus();
249 },
250
251 /**
252 * @param {number} lineNumber
253 * @param {number} columnNumber
254 * @return {?WebInspector.TextRange}
255 */
256 _substituteRange: function(lineNumber, columnNumber)
257 {
258 var lineText = this._editor.line(lineNumber);
259 var index;
260 for (index = lineText.length - 1; index >= 0; index--) {
261 if (" =:[({;,!+-*/&|^<>.".indexOf(lineText.charAt(index)) !== -1)
262 break;
263 }
264 return new WebInspector.TextRange(lineNumber, index + 1, lineNumber, col umnNumber);
265 },
266
267 /**
268 * @param {!WebInspector.TextRange} prefixRange
269 * @param {!WebInspector.TextRange} substituteRange
270 * @return {!Promise<!WebInspector.SuggestBox.Suggestions>}
271 */
272 _wordsWithPrefix: function(prefixRange, substituteRange)
273 {
274 var prefix = this._editor.text(prefixRange);
275 var before = this._editor.text(new WebInspector.TextRange(0, 0, prefixRa nge.startLine, prefixRange.startColumn));
276 var historyWords = this._historyCompletions(prefix);
277 return WebInspector.ExecutionContextSelector.completionsForTextInCurrent Context(before, prefix, true /* force */).then(innerWordsWithPrefix);
278
279 /**
280 * @param {!Array<string>} words
281 * @return {!WebInspector.SuggestBox.Suggestions}
282 */
283 function innerWordsWithPrefix(words)
284 {
285 return words.map(item => ({title:item})).concat(historyWords);
286 }
287 },
288
289 _editorSetForTest: function() { },
290
291 __proto__: WebInspector.Widget.prototype
292 };
293
294 /** 275 /**
295 * @constructor 276 * @unrestricted
296 */ 277 */
297 WebInspector.ConsoleHistoryManager = function() 278 WebInspector.ConsoleHistoryManager = class {
298 { 279 constructor() {
299 /** 280 /**
300 * @type {!Array.<string>} 281 * @type {!Array.<string>}
301 */ 282 */
302 this._data = []; 283 this._data = [];
303 284
304 /** 285 /**
305 * 1-based entry in the history stack. 286 * 1-based entry in the history stack.
306 * @type {number} 287 * @type {number}
307 */ 288 */
308 this._historyOffset = 1; 289 this._historyOffset = 1;
290 }
291
292 /**
293 * @return {!Array.<string>}
294 */
295 historyData() {
296 return this._data;
297 }
298
299 /**
300 * @param {!Array.<string>} data
301 */
302 setHistoryData(data) {
303 this._data = data.slice();
304 this._historyOffset = 1;
305 }
306
307 /**
308 * Pushes a committed text into the history.
309 * @param {string} text
310 */
311 pushHistoryItem(text) {
312 if (this._uncommittedIsTop) {
313 this._data.pop();
314 delete this._uncommittedIsTop;
315 }
316
317 this._historyOffset = 1;
318 if (text === this._currentHistoryItem())
319 return;
320 this._data.push(text);
321 }
322
323 /**
324 * Pushes the current (uncommitted) text into the history.
325 * @param {string} currentText
326 */
327 _pushCurrentText(currentText) {
328 if (this._uncommittedIsTop)
329 this._data.pop(); // Throw away obsolete uncommitted text.
330 this._uncommittedIsTop = true;
331 this._data.push(currentText);
332 }
333
334 /**
335 * @param {string} currentText
336 * @return {string|undefined}
337 */
338 previous(currentText) {
339 if (this._historyOffset > this._data.length)
340 return undefined;
341 if (this._historyOffset === 1)
342 this._pushCurrentText(currentText);
343 ++this._historyOffset;
344 return this._currentHistoryItem();
345 }
346
347 /**
348 * @return {string|undefined}
349 */
350 next() {
351 if (this._historyOffset === 1)
352 return undefined;
353 --this._historyOffset;
354 return this._currentHistoryItem();
355 }
356
357 /**
358 * @return {string|undefined}
359 */
360 _currentHistoryItem() {
361 return this._data[this._data.length - this._historyOffset];
362 }
309 }; 363 };
310
311 WebInspector.ConsoleHistoryManager.prototype = {
312 /**
313 * @return {!Array.<string>}
314 */
315 historyData: function()
316 {
317 return this._data;
318 },
319
320 /**
321 * @param {!Array.<string>} data
322 */
323 setHistoryData: function(data)
324 {
325 this._data = data.slice();
326 this._historyOffset = 1;
327 },
328
329 /**
330 * Pushes a committed text into the history.
331 * @param {string} text
332 */
333 pushHistoryItem: function(text)
334 {
335 if (this._uncommittedIsTop) {
336 this._data.pop();
337 delete this._uncommittedIsTop;
338 }
339
340 this._historyOffset = 1;
341 if (text === this._currentHistoryItem())
342 return;
343 this._data.push(text);
344 },
345
346 /**
347 * Pushes the current (uncommitted) text into the history.
348 * @param {string} currentText
349 */
350 _pushCurrentText: function(currentText)
351 {
352 if (this._uncommittedIsTop)
353 this._data.pop(); // Throw away obsolete uncommitted text.
354 this._uncommittedIsTop = true;
355 this._data.push(currentText);
356 },
357
358 /**
359 * @param {string} currentText
360 * @return {string|undefined}
361 */
362 previous: function(currentText)
363 {
364 if (this._historyOffset > this._data.length)
365 return undefined;
366 if (this._historyOffset === 1)
367 this._pushCurrentText(currentText);
368 ++this._historyOffset;
369 return this._currentHistoryItem();
370 },
371
372 /**
373 * @return {string|undefined}
374 */
375 next: function()
376 {
377 if (this._historyOffset === 1)
378 return undefined;
379 --this._historyOffset;
380 return this._currentHistoryItem();
381 },
382
383 /**
384 * @return {string|undefined}
385 */
386 _currentHistoryItem: function()
387 {
388 return this._data[this._data.length - this._historyOffset];
389 }
390 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698