OLD | NEW |
| (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 * @unrestricted | |
6 */ | |
7 UI.CommandMenu = class { | |
8 constructor() { | |
9 this._commands = []; | |
10 this._loadCommands(); | |
11 } | |
12 | |
13 /** | |
14 * @param {string} category | |
15 * @param {string} keys | |
16 * @param {string} title | |
17 * @param {string} shortcut | |
18 * @param {function()} executeHandler | |
19 * @param {function()=} availableHandler | |
20 * @return {!UI.CommandMenu.Command} | |
21 */ | |
22 static createCommand(category, keys, title, shortcut, executeHandler, availabl
eHandler) { | |
23 // Separate keys by null character, to prevent fuzzy matching from matching
across them. | |
24 var key = keys.replace(/,/g, '\0'); | |
25 return new UI.CommandMenu.Command(category, title, key, shortcut, executeHan
dler, availableHandler); | |
26 } | |
27 | |
28 /** | |
29 * @param {!Runtime.Extension} extension | |
30 * @param {string} title | |
31 * @param {V} value | |
32 * @return {!UI.CommandMenu.Command} | |
33 * @template V | |
34 */ | |
35 static createSettingCommand(extension, title, value) { | |
36 var category = extension.descriptor()['category'] || ''; | |
37 var tags = extension.descriptor()['tags'] || ''; | |
38 var setting = Common.settings.moduleSetting(extension.descriptor()['settingN
ame']); | |
39 return UI.CommandMenu.createCommand(category, tags, title, '', setting.set.b
ind(setting, value), availableHandler); | |
40 | |
41 /** | |
42 * @return {boolean} | |
43 */ | |
44 function availableHandler() { | |
45 return setting.get() !== value; | |
46 } | |
47 } | |
48 | |
49 /** | |
50 * @param {!UI.Action} action | |
51 * @return {!UI.CommandMenu.Command} | |
52 */ | |
53 static createActionCommand(action) { | |
54 var shortcut = UI.shortcutRegistry.shortcutTitleForAction(action.id()) || ''
; | |
55 return UI.CommandMenu.createCommand( | |
56 action.category(), action.tags(), action.title(), shortcut, action.execu
te.bind(action)); | |
57 } | |
58 | |
59 /** | |
60 * @param {!Runtime.Extension} extension | |
61 * @return {!UI.CommandMenu.Command} | |
62 */ | |
63 static createRevealPanelCommand(extension) { | |
64 var panelName = extension.descriptor()['name']; | |
65 var tags = extension.descriptor()['tags'] || ''; | |
66 return UI.CommandMenu.createCommand( | |
67 Common.UIString('Panel'), tags, Common.UIString('Show %s', extension.tit
le()), '', executeHandler, | |
68 availableHandler); | |
69 | |
70 /** | |
71 * @return {boolean} | |
72 */ | |
73 function availableHandler() { | |
74 return true; | |
75 } | |
76 | |
77 function executeHandler() { | |
78 UI.viewManager.showView(panelName); | |
79 } | |
80 } | |
81 | |
82 /** | |
83 * @param {!Runtime.Extension} extension | |
84 * @return {!UI.CommandMenu.Command} | |
85 */ | |
86 static createRevealDrawerCommand(extension) { | |
87 var drawerId = extension.descriptor()['id']; | |
88 var executeHandler = UI.viewManager.showView.bind(UI.viewManager, drawerId); | |
89 var tags = extension.descriptor()['tags'] || ''; | |
90 return UI.CommandMenu.createCommand( | |
91 Common.UIString('Drawer'), tags, Common.UIString('Show %s', extension.ti
tle()), '', executeHandler); | |
92 } | |
93 | |
94 _loadCommands() { | |
95 // Populate panels. | |
96 var panelExtensions = self.runtime.extensions(UI.Panel); | |
97 for (var extension of panelExtensions) | |
98 this._commands.push(UI.CommandMenu.createRevealPanelCommand(extension)); | |
99 | |
100 // Populate drawers. | |
101 var drawerExtensions = self.runtime.extensions('view'); | |
102 for (var extension of drawerExtensions) { | |
103 if (extension.descriptor()['location'] !== 'drawer-view') | |
104 continue; | |
105 this._commands.push(UI.CommandMenu.createRevealDrawerCommand(extension)); | |
106 } | |
107 | |
108 // Populate whitelisted settings. | |
109 var settingExtensions = self.runtime.extensions('setting'); | |
110 for (var extension of settingExtensions) { | |
111 var options = extension.descriptor()['options']; | |
112 if (!options || !extension.descriptor()['category']) | |
113 continue; | |
114 for (var pair of options) | |
115 this._commands.push(UI.CommandMenu.createSettingCommand(extension, pair[
'title'], pair['value'])); | |
116 } | |
117 } | |
118 | |
119 /** | |
120 * @return {!Array.<!UI.CommandMenu.Command>} | |
121 */ | |
122 commands() { | |
123 return this._commands; | |
124 } | |
125 }; | |
126 | |
127 /** | |
128 * @unrestricted | |
129 */ | |
130 UI.CommandMenuDelegate = class extends UI.FilteredListWidget.Delegate { | |
131 constructor() { | |
132 super([]); | |
133 this._commands = []; | |
134 this._appendAvailableCommands(); | |
135 } | |
136 | |
137 _appendAvailableCommands() { | |
138 var allCommands = UI.commandMenu.commands(); | |
139 | |
140 // Populate whitelisted actions. | |
141 var actions = UI.actionRegistry.availableActions(); | |
142 for (var action of actions) { | |
143 if (action.category()) | |
144 this._commands.push(UI.CommandMenu.createActionCommand(action)); | |
145 } | |
146 | |
147 for (var command of allCommands) { | |
148 if (command.available()) | |
149 this._commands.push(command); | |
150 } | |
151 | |
152 this._commands = this._commands.sort(commandComparator); | |
153 | |
154 /** | |
155 * @param {!UI.CommandMenu.Command} left | |
156 * @param {!UI.CommandMenu.Command} right | |
157 * @return {number} | |
158 */ | |
159 function commandComparator(left, right) { | |
160 var cats = left.category().compareTo(right.category()); | |
161 return cats ? cats : left.title().compareTo(right.title()); | |
162 } | |
163 } | |
164 | |
165 /** | |
166 * @override | |
167 * @return {number} | |
168 */ | |
169 itemCount() { | |
170 return this._commands.length; | |
171 } | |
172 | |
173 /** | |
174 * @override | |
175 * @param {number} itemIndex | |
176 * @return {string} | |
177 */ | |
178 itemKeyAt(itemIndex) { | |
179 return this._commands[itemIndex].key(); | |
180 } | |
181 | |
182 /** | |
183 * @override | |
184 * @param {number} itemIndex | |
185 * @param {string} query | |
186 * @return {number} | |
187 */ | |
188 itemScoreAt(itemIndex, query) { | |
189 var command = this._commands[itemIndex]; | |
190 var opcodes = Diff.Diff.charDiff(query.toLowerCase(), command.title().toLowe
rCase()); | |
191 var score = 0; | |
192 // Score longer sequences higher. | |
193 for (var i = 0; i < opcodes.length; ++i) { | |
194 if (opcodes[i][0] === Diff.Diff.Operation.Equal) | |
195 score += opcodes[i][1].length * opcodes[i][1].length; | |
196 } | |
197 | |
198 // Score panel/drawer reveals above regular actions. | |
199 if (command.category().startsWith('Panel')) | |
200 score += 2; | |
201 else if (command.category().startsWith('Drawer')) | |
202 score += 1; | |
203 | |
204 return score; | |
205 } | |
206 | |
207 /** | |
208 * @override | |
209 * @param {number} itemIndex | |
210 * @param {string} query | |
211 * @param {!Element} titleElement | |
212 * @param {!Element} subtitleElement | |
213 */ | |
214 renderItem(itemIndex, query, titleElement, subtitleElement) { | |
215 var command = this._commands[itemIndex]; | |
216 titleElement.removeChildren(); | |
217 var tagElement = titleElement.createChild('span', 'tag'); | |
218 var index = String.hashCode(command.category()) % UI.CommandMenuDelegate.Mat
erialPaletteColors.length; | |
219 tagElement.style.backgroundColor = UI.CommandMenuDelegate.MaterialPaletteCol
ors[index]; | |
220 tagElement.textContent = command.category(); | |
221 titleElement.createTextChild(command.title()); | |
222 this.highlightRanges(titleElement, query); | |
223 subtitleElement.textContent = command.shortcut(); | |
224 } | |
225 | |
226 /** | |
227 * @override | |
228 * @param {?number} itemIndex | |
229 * @param {string} promptValue | |
230 */ | |
231 selectItem(itemIndex, promptValue) { | |
232 if (itemIndex === null) | |
233 return; | |
234 this._commands[itemIndex].execute(); | |
235 } | |
236 | |
237 /** | |
238 * @override | |
239 * @return {boolean} | |
240 */ | |
241 caseSensitive() { | |
242 return false; | |
243 } | |
244 | |
245 /** | |
246 * @override | |
247 * @return {boolean} | |
248 */ | |
249 renderMonospace() { | |
250 return false; | |
251 } | |
252 }; | |
253 | |
254 UI.CommandMenuDelegate.MaterialPaletteColors = [ | |
255 '#F44336', '#E91E63', '#9C27B0', '#673AB7', '#3F51B5', '#03A9F4', '#00BCD4', '
#009688', '#4CAF50', '#8BC34A', | |
256 '#CDDC39', '#FFC107', '#FF9800', '#FF5722', '#795548', '#9E9E9E', '#607D8B' | |
257 ]; | |
258 | |
259 /** | |
260 * @unrestricted | |
261 */ | |
262 UI.CommandMenu.Command = class { | |
263 /** | |
264 * @param {string} category | |
265 * @param {string} title | |
266 * @param {string} key | |
267 * @param {string} shortcut | |
268 * @param {function()} executeHandler | |
269 * @param {function()=} availableHandler | |
270 */ | |
271 constructor(category, title, key, shortcut, executeHandler, availableHandler)
{ | |
272 this._category = category; | |
273 this._title = title; | |
274 this._key = category + '\0' + title + '\0' + key; | |
275 this._shortcut = shortcut; | |
276 this._executeHandler = executeHandler; | |
277 this._availableHandler = availableHandler; | |
278 } | |
279 | |
280 /** | |
281 * @return {string} | |
282 */ | |
283 category() { | |
284 return this._category; | |
285 } | |
286 | |
287 /** | |
288 * @return {string} | |
289 */ | |
290 title() { | |
291 return this._title; | |
292 } | |
293 | |
294 /** | |
295 * @return {string} | |
296 */ | |
297 key() { | |
298 return this._key; | |
299 } | |
300 | |
301 /** | |
302 * @return {string} | |
303 */ | |
304 shortcut() { | |
305 return this._shortcut; | |
306 } | |
307 | |
308 /** | |
309 * @return {boolean} | |
310 */ | |
311 available() { | |
312 return this._availableHandler ? this._availableHandler() : true; | |
313 } | |
314 | |
315 execute() { | |
316 this._executeHandler(); | |
317 } | |
318 }; | |
319 | |
320 | |
321 /** @type {!UI.CommandMenu} */ | |
322 UI.commandMenu = new UI.CommandMenu(); | |
323 | |
324 /** | |
325 * @implements {UI.ActionDelegate} | |
326 * @unrestricted | |
327 */ | |
328 UI.CommandMenu.ShowActionDelegate = class { | |
329 /** | |
330 * @override | |
331 * @param {!UI.Context} context | |
332 * @param {string} actionId | |
333 * @return {boolean} | |
334 */ | |
335 handleAction(context, actionId) { | |
336 new UI.FilteredListWidget(new UI.CommandMenuDelegate()).showAsDialog(); | |
337 InspectorFrontendHost.bringToFront(); | |
338 return true; | |
339 } | |
340 }; | |
OLD | NEW |