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

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: Copyright 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 (c) 2016 The Chromium Authors. All rights reserved.
dgozman 2016/09/14 21:20:17 http://dev.chromium.org/blink/coding-style#TOC-Lic
einbinder 2016/09/15 00:14:09 Done.
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 bracketMatchingFlag: "consoleBracketMatching",
33 mimeType: "javascript",
34 autoHeight: true
35 });
36
37 this._editor.configureAutocomplete({
38 substituteRangeCallback: this._substituteRange.bind(this),
39 suggestionsCallback: this._wordsWithPrefix.bind(this),
40 captureEnter: true
41 })
42 this._editor.widget().show(this.element);
43
44 this.setText(this._initialText);
45 delete this._initialText;
46 if (this.hasFocus())
47 this.focus();
48 this.element.tabIndex = -1;
49 }
50 }
51
52 WebInspector.ConsolePrompt.prototype = {
53 /**
54 * @return {!WebInspector.HistoryManager}
55 */
56 history: function()
57 {
58 return this._history;
59 },
60
61 clearAutocomplete: function()
62 {
63 if (this._editor)
64 this._editor.clearAutocomplete();
65 },
66
67 /**
68 * @return {boolean}
69 */
70 isCaretInsidePrompt: function()
71 {
72 return this.hasFocus();
73 },
74
75 /**
76 * @return {boolean}
77 */
78 isCaretAtEndOfPrompt: function()
79 {
80 return !!this._editor && this._editor.selection().collapseToEnd().equal( this._editor.fullRange().collapseToEnd());
81 },
82
83 /**
84 * @return {boolean}
85 */
86 isCaretOnLastLine: function()
87 {
88 return !!this._editor && this._editor.selection().endLine === this._edit or.fullRange().endLine;
89 },
90
91 /**
92 * @return {boolean}
93 */
94 isCaretOnFirstLine: function()
95 {
96 return !!this._editor && this._editor.selection().endLine === 0;
97 },
98
99 moveCaretToEndOfPrompt: function()
100 {
101 if (this._editor)
102 this._editor.setSelection(WebInspector.TextRange.createFromLocation( Infinity,Infinity));
103 },
104
105 moveCaretToEndOfFirstLine: function()
106 {
107 if (this._editor)
108 this._editor.setSelection(WebInspector.TextRange.createFromLocation( 0,Infinity));
109 },
110
111 /**
112 * @param {string} text
113 */
114 setText: function(text)
115 {
116 if (this._editor)
117 this._editor.setText(text);
118 else
119 this._initialText = text;
120 },
121
122 /**
123 * @return {string}
124 */
125 text: function()
126 {
127 return this._editor ? this._editor.text() : this._initialText;
128 },
129
130 /**
131 * @param {boolean} value
132 */
133 setAddCompletionsFromHistory: function(value)
134 {
135 this._addCompletionsFromHistory = value;
136 },
137
138 /**
139 * @param {!Event} event
140 */
141 _editorKeyDown: function(event)
142 {
143 var keyboardEvent = /** @type {!KeyboardEvent} */ (event);
144 var newText;
145 var isPrevious;
146
147 switch (keyboardEvent.keyCode) {
148 case WebInspector.KeyboardShortcut.Keys.Up.code:
149 if (!this.isCaretOnFirstLine())
150 break;
151 newText = this._history.previous(this.text());
152 isPrevious = true;
153 break;
154 case WebInspector.KeyboardShortcut.Keys.Down.code:
155 if (!this.isCaretOnLastLine())
156 break;
157 newText = this._history.next();
158 break;
159 case WebInspector.KeyboardShortcut.Keys.P.code: // Ctrl+P = Previous
160 if (WebInspector.isMac() && keyboardEvent.ctrlKey && !keyboardEvent. metaKey && !keyboardEvent.altKey && !keyboardEvent.shiftKey) {
161 newText = this._history.previous(this.text());
162 isPrevious = true;
163 }
164 break;
165 case WebInspector.KeyboardShortcut.Keys.N.code: // Ctrl+N = Next
166 if (WebInspector.isMac() && keyboardEvent.ctrlKey && !keyboardEvent. metaKey && !keyboardEvent.altKey && !keyboardEvent.shiftKey)
167 newText = this._history.next();
168 break;
169 }
170
171 if (newText === undefined)
172 return;
173 keyboardEvent.consume(true);
174 this.setText(newText);
175
176 if (isPrevious)
177 this.moveCaretToEndOfFirstLine();
178 else
179 this.moveCaretToEndOfPrompt();
180 },
181
182 /**
183 * @param {string} prefix
184 * @return {!WebInspector.SuggestBox.Suggestions}
185 */
186 _historyCompletions: function(prefix)
187 {
188 if (!this._addCompletionsFromHistory || !this.isCaretAtEndOfPrompt())
189 return [];
190 var result = [];
191 var text = this.text();
192 var set = new Set();
193 var data = this._history.historyData();
194 for (var i = data.length - 1; i >= 0 && result.length < 50; --i) {
195 var item = data[i];
196 if (!item.startsWith(text))
197 continue;
198 if (set.has(item))
199 continue;
200 set.add(item);
201 result.push({title: item.substring(text.length - prefix.length), cla ssName: "additional"});
202 }
203 return result;
204 },
205
206 /**
207 * @override
208 */
209 focus: function()
210 {
211 if (this._editor)
212 this._editor.widget().focus();
213 else
214 this.element.focus();
215 },
216
217 /**
218 * @param {number} lineNumber
219 * @param {number} columnNumber
220 * @return {?WebInspector.TextRange}
221 */
222 _substituteRange: function(lineNumber, columnNumber)
223 {
224 var lineText = this._editor.line(lineNumber);
225 var index;
226 for (index = lineText.length - 1; index >= 0; index--) {
227 if (" =:[({;,!+-*/&|^<>.".indexOf(lineText.charAt(index)) !== -1)
228 break;
229 }
230 return new WebInspector.TextRange(lineNumber, index + 1, lineNumber, col umnNumber);
231 },
232
233 /**
234 * @param {!WebInspector.TextRange} prefixRange
235 * @param {!WebInspector.TextRange} substituteRange
236 * @return {!Promise.<!Array.<{title: string, className: (string|undefined)} >>}
237 */
238 _wordsWithPrefix: function(prefixRange, substituteRange)
239 {
240 var resolve;
dgozman 2016/09/14 21:20:17 resolve -> fulfill
einbinder 2016/09/15 00:14:09 Done.
241 var promise = new Promise(fufill => resolve = fufill);
242 var prefix = this._editor.text(prefixRange);
243 var before = this._editor.text(new WebInspector.TextRange(0, 0, prefixRa nge.startLine, prefixRange.startColumn));
244 var historyWords = this._historyCompletions(prefix);
245 WebInspector.ExecutionContextSelector.completionsForTextInCurrentContext (before, prefix, false /* Don't force */, innerWordsWithPrefix);
246 return promise;
247
248 /**
249 * @param {!Array.<string>} words
250 */
251 function innerWordsWithPrefix(words)
252 {
253 resolve(words.map(item => ({title:item})).concat(historyWords));
254 }
255 },
256
257 __proto__: WebInspector.Widget.prototype
258 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698