OLD | NEW |
---|---|
(Empty) | |
1 /** | |
pfeldman
2016/09/14 00:31:52
Where is my copyright?
einbinder
2016/09/14 20:21:06
Done.
| |
2 * @constructor | |
3 * @extends {WebInspector.Widget} | |
4 */ | |
5 WebInspector.ConsolePrompt = function() | |
6 { | |
7 WebInspector.Widget.call(this); | |
pfeldman
2016/09/14 00:31:53
There is no point in making something a widget unl
einbinder
2016/09/14 20:21:06
Even if it needs a public .element and needs .focu
| |
8 this._addCompletionsFromHistory = true; | |
9 this._history = new WebInspector.HistoryManager(); | |
10 | |
11 this._initialText = ""; | |
12 this._needsFocus = false; | |
13 this._editor = null; | |
14 | |
15 this.element.addEventListener("keydown", this._editorKeyDown.bind(this), tru e); | |
16 | |
17 self.runtime.extension(WebInspector.TextEditorFactory).instance().then(gotFa ctory.bind(this)); | |
18 | |
19 /** | |
20 * @param {!WebInspector.TextEditorFactory} factory | |
21 * @this {!WebInspector.ConsolePrompt} | |
pfeldman
2016/09/14 00:31:52
drop !
einbinder
2016/09/14 20:21:05
Done.
| |
22 */ | |
23 function gotFactory(factory) | |
24 { | |
25 this._editor = factory.createEditor({ | |
26 lineNumbers: false, | |
27 lineWrapping: true, | |
28 bracketMatchingFlag: "consoleBracketMatching", | |
29 mimeType: "javascript", | |
30 autoHeight: true | |
31 }); | |
32 | |
33 this._editor.configureAutocomplete({ | |
34 substituteRangeCallback: this._substituteRange.bind(this), | |
35 suggestionsCallback: this._wordsWithPrefix.bind(this), | |
36 captureEnter: true | |
37 }) | |
38 this._editor.widget().show(this.element); | |
39 | |
40 this.setText(this._initialText) | |
dgozman
2016/09/14 04:26:17
semicolon
einbinder
2016/09/14 20:21:06
Done.
| |
41 if (this._needsFocus) | |
pfeldman
2016/09/14 00:31:52
What if I already clicked away? Might need to set
dgozman
2016/09/14 04:26:17
delete this._initialText;
einbinder
2016/09/14 20:21:06
I thought it was acceptable losses. I can make it
| |
42 this.focus(); | |
43 this._needsFocus = false; | |
44 } | |
45 } | |
46 | |
47 WebInspector.ConsolePrompt.prototype = { | |
48 | |
lushnikov
2016/09/14 01:11:21
nit: stray line
einbinder
2016/09/14 20:21:06
Done.
| |
49 /** | |
50 * @return {!WebInspector.HistoryManager} | |
51 */ | |
52 history: function() | |
53 { | |
54 return this._history; | |
55 }, | |
56 | |
57 clearAutocomplete: function() | |
58 { | |
59 if (this._editor) | |
60 this._editor.clearAutocomplete(); | |
61 }, | |
62 | |
63 /** | |
64 * @return {boolean} | |
65 */ | |
66 isCaretInsidePrompt: function() | |
67 { | |
68 return this.hasFocus(); | |
69 }, | |
70 | |
71 /** | |
72 * @return {boolean} | |
73 */ | |
74 isCaretAtEndOfPrompt: function() | |
75 { | |
76 return !!this._editor && this._editor.selection().collapseToEnd().compar eTo(this._editor.fullRange().collapseToEnd()) === 0; | |
lushnikov
2016/09/14 01:11:21
nit: compareTo -> .equal
einbinder
2016/09/14 20:21:06
Done.
| |
77 }, | |
78 | |
79 /** | |
80 * @return {boolean} | |
81 */ | |
82 isCaretOnLastLine: function() | |
83 { | |
84 return !!this._editor && this._editor.selection().endLine === this._edit or.fullRange().endLine; | |
85 }, | |
86 | |
87 /** | |
88 * @return {boolean} | |
89 */ | |
90 isCaretOnFirstLine: function() | |
91 { | |
92 return !!this._editor && this._editor.selection().endLine === 0; | |
93 }, | |
94 | |
95 moveCaretToEndOfPrompt: function() | |
96 { | |
97 if (this._editor) | |
98 this._editor.setSelection(WebInspector.TextRange.createFromLocation( Infinity,Infinity)); | |
99 }, | |
100 | |
101 moveCaretToEndOfFirstLine: function() | |
102 { | |
103 if (this._editor) | |
104 this._editor.setSelection(WebInspector.TextRange.createFromLocation( 0,Infinity)); | |
105 }, | |
106 | |
107 /** | |
108 * @param {string} text | |
109 */ | |
110 setText: function(text) | |
111 { | |
112 if (this._editor) | |
113 this._editor.setText(text); | |
114 else | |
115 this._initialText = text; | |
116 }, | |
117 | |
118 /** | |
119 * @return {string} | |
120 */ | |
121 text: function() | |
122 { | |
123 return this._editor ? this._editor.text() : this._initialText; | |
124 }, | |
125 | |
126 /** | |
127 * @param {boolean} value | |
128 */ | |
129 setAddCompletionsFromHistory: function(value) | |
130 { | |
131 this._addCompletionsFromHistory = value; | |
132 }, | |
133 | |
134 /** | |
135 * @param {!Event} event | |
136 */ | |
137 _editorKeyDown: function(event) | |
138 { | |
139 var keyboardEvent = /** @type {!KeyboardEvent} */ (event); | |
140 var newText; | |
141 var isPrevious; | |
142 | |
143 switch (keyboardEvent.keyCode) { | |
lushnikov
2016/09/14 01:11:21
You probably will simplify key handling if you use
einbinder
2016/09/14 20:21:06
I stole this code from TextPrompt. How about I cle
| |
144 case WebInspector.KeyboardShortcut.Keys.Up.code: | |
145 if (!this.isCaretOnFirstLine()) | |
146 break; | |
147 newText = this._history.previous(this.text()); | |
148 isPrevious = true; | |
149 break; | |
150 case WebInspector.KeyboardShortcut.Keys.Down.code: | |
151 if (!this.isCaretOnLastLine()) | |
152 break; | |
153 newText = this._history.next(); | |
154 break; | |
155 case WebInspector.KeyboardShortcut.Keys.P.code: // Ctrl+P = Previous | |
156 if (WebInspector.isMac() && keyboardEvent.ctrlKey && !keyboardEvent. metaKey && !keyboardEvent.altKey && !keyboardEvent.shiftKey) { | |
157 newText = this._history.previous(this.text()); | |
158 isPrevious = true; | |
159 } | |
160 break; | |
161 case WebInspector.KeyboardShortcut.Keys.N.code: // Ctrl+N = Next | |
162 if (WebInspector.isMac() && keyboardEvent.ctrlKey && !keyboardEvent. metaKey && !keyboardEvent.altKey && !keyboardEvent.shiftKey) | |
163 newText = this._history.next(); | |
164 break; | |
165 } | |
166 | |
167 if (newText !== undefined) { | |
lushnikov
2016/09/14 01:11:21
fast-return?
einbinder
2016/09/14 20:21:06
Done.
| |
168 keyboardEvent.consume(true); | |
169 this.setText(newText); | |
170 | |
171 if (isPrevious) | |
172 this.moveCaretToEndOfFirstLine(); | |
173 else | |
174 this.moveCaretToEndOfPrompt(); | |
175 } | |
176 }, | |
177 | |
178 /** | |
179 * @param {string} prefix | |
180 * @return {!WebInspector.SuggestBox.Suggestions} | |
181 */ | |
182 _historyCompletions: function(prefix) | |
183 { | |
184 if (!this._addCompletionsFromHistory || !this.isCaretAtEndOfPrompt()) | |
185 return []; | |
186 var result = []; | |
187 var text = this.text(); | |
188 var set = new Set(); | |
189 var data = this._history.historyData(); | |
190 for (var i = data.length - 1; i >= 0 && result.length < 50; --i) { | |
191 var item = data[i]; | |
192 if (!item.startsWith(text)) | |
193 continue; | |
194 if (set.has(item)) | |
195 continue; | |
196 set.add(item); | |
197 result.push({title: item.substring(text.length - prefix.length), cla ssName: "additional"}); | |
198 } | |
199 return result; | |
200 }, | |
201 | |
202 /** | |
203 * @override | |
204 */ | |
205 focus: function() | |
206 { | |
207 if (this._editor) | |
208 this._editor.widget().focus(); | |
209 else | |
210 this._needsFocus = true; | |
dgozman
2016/09/14 04:26:17
Let's instead focus this.element here, and switch
einbinder
2016/09/14 20:21:05
Done.
| |
211 }, | |
212 | |
213 /** | |
214 * @param {number} lineNumber | |
215 * @param {number} columnNumber | |
216 * @return {?WebInspector.TextRange} | |
217 */ | |
218 _substituteRange: function(lineNumber, columnNumber) | |
219 { | |
220 if (!this._editor) | |
221 return null; | |
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 if (!this._editor) | |
lushnikov
2016/09/14 01:11:21
how could there be no editor?
| |
240 return Promise.resolve([]); | |
241 | |
242 var resolve; | |
243 var promise = new Promise(fufill => resolve = fufill); | |
244 var prefix = this._editor.text(prefixRange); | |
245 var before = this._editor.text(new WebInspector.TextRange(0,0,prefixRang e.startLine,prefixRange.startColumn)); | |
dgozman
2016/09/14 04:26:18
spaces
einbinder
2016/09/14 20:21:06
Done.
| |
246 var historyWords = this._historyCompletions(prefix); | |
247 WebInspector.ExecutionContextSelector.completionsForTextInCurrentContext (before, prefix, false, innerWordsWithPrefix); | |
dgozman
2016/09/14 04:26:17
Let's annotate false /* doSomething */
einbinder
2016/09/14 20:21:06
Done.
| |
248 return promise; | |
249 /** | |
dgozman
2016/09/14 04:26:17
empty line please
einbinder
2016/09/14 20:21:05
Done.
| |
250 * @param {!Array.<string>} words | |
251 */ | |
252 function innerWordsWithPrefix(words) | |
253 { | |
254 resolve(words.map(item => ({title:item})).concat(historyWords)); | |
255 } | |
256 }, | |
257 | |
258 __proto__: WebInspector.Widget.prototype | |
259 } | |
OLD | NEW |