Chromium Code Reviews| Index: third_party/WebKit/Source/devtools/front_end/quick_open/QuickOpen.js |
| diff --git a/third_party/WebKit/Source/devtools/front_end/quick_open/QuickOpen.js b/third_party/WebKit/Source/devtools/front_end/quick_open/QuickOpen.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..92d9bb687f76ac815c40bb06aef4215f8b265573 |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/devtools/front_end/quick_open/QuickOpen.js |
| @@ -0,0 +1,209 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +QuickOpen.QuickOpen = class extends QuickOpen.FilteredListWidget.Delegate { |
| + constructor() { |
| + super(); |
| + this._prefix = []; |
| + self.runtime.extensions('quick-open').forEach(this._addPrefix.bind(this)); |
| + this._currentDelegate = new QuickOpen.Loading(); |
|
pfeldman
2017/02/07 02:10:03
nit: here and below, remove _current prefix - I do
einbinder
2017/02/28 23:59:07
Done.
|
| + this._currentPrefix = ''; |
| + this._currentQuery = ''; |
| + } |
| + |
| + /** |
| + * @param {!Runtime.Extension} extension |
| + */ |
| + _addPrefix(extension) { |
| + this._prefix.push( |
| + {prefix: extension.descriptor().prefix, delegate: null, instance: extension.instance.bind(extension)}); |
| + this._prefix.sort((a, b) => b.prefix.length - a.prefix.length); |
|
pfeldman
2017/02/07 02:10:02
They are already sorter by "order" extension prope
einbinder
2017/02/28 23:59:07
This is important so that longer prefix go first.
|
| + } |
| + |
| + /** |
| + * @param {string} query |
| + * @return {!QuickOpen.FilteredListWidget.Delegate} |
| + */ |
| + _delegate(query) { |
| + for (var i = 0; i < this._prefix.length; i++) { |
|
pfeldman
2017/02/07 02:10:02
for (var provider of this._providers)
einbinder
2017/02/28 23:59:07
Done.
|
| + if (query.startsWith(this._prefix[i].prefix)) { |
| + this._currentPrefix = this._prefix[i].prefix; |
| + var delegate = this._prefix[i].delegate; |
| + if (!delegate) { |
| + delegate = new QuickOpen.Loading(); |
| + this._prefix[i].instance().then(instance => { |
| + instance.setRefreshCallback(this.refresh.bind(this)); |
| + this._prefix[i].delegate = instance; |
|
pfeldman
2017/02/07 02:10:02
Store extension in this._providers and simply chai
einbinder
2017/02/28 23:59:07
It is much easier if this method is synchronous. O
|
| + this.queryChanged(this._currentQuery); |
| + }); |
| + } |
| + return delegate; |
| + } |
| + } |
| + this._currentPrefix = ''; |
| + return this._currentDelegate || new QuickOpen.FilteredListWidget.Delegate(); |
|
pfeldman
2017/02/07 02:10:02
Oh, so QuickOpen.Loading() is not the same!
einbinder
2017/02/28 23:59:07
There was no path to get to the blank delegate, I
|
| + } |
| + |
| + /** |
| + * @param {string} query |
| + * @return {string} |
| + */ |
| + _cleanQuery(query) { |
| + return query.substring(this._currentPrefix.length); |
| + } |
| + |
| + /** |
| + * @override |
| + * @param {string} query |
| + */ |
| + queryChanged(query) { |
| + this._currentQuery = query; |
| + var lastDelegate = this._currentDelegate; |
| + this._currentDelegate = this._delegate(query); |
| + this._currentDelegate.queryChanged(this._cleanQuery(query)); |
| + if (this._currentDelegate !== lastDelegate) |
| + this.refresh(); |
| + if (!(this._currentDelegate instanceof QuickOpen.Loading)) |
| + this._delegateLoadedForTest(this._currentDelegate); |
| + } |
| + |
| + /** |
| + * @param {!QuickOpen.FilteredListWidget.Delegate} delegate |
| + */ |
| + _delegateLoadedForTest(delegate) { |
| + } |
| + |
| + /** |
| + * @override |
| + * @param {string} query |
| + * @return {string} |
| + */ |
| + notFoundText(query) { |
| + return this._currentDelegate.notFoundText(this._cleanQuery(query)); |
| + } |
| + |
| + /** |
| + * @override |
| + * @param {function():void} refreshCallback |
| + */ |
| + setRefreshCallback(refreshCallback) { |
|
pfeldman
2017/02/07 02:10:02
Is this to make sure that JavaScript works?
einbinder
2017/02/28 23:59:07
I was suspicious.
|
| + super.setRefreshCallback(refreshCallback); |
| + } |
| + |
| + /** |
| + * @override |
| + * @return {number} |
| + */ |
| + itemCount() { |
| + return this._currentDelegate.itemCount(); |
| + } |
| + |
| + /** |
| + * @override |
| + * @param {number} itemIndex |
| + * @return {string} |
| + */ |
| + itemKeyAt(itemIndex) { |
| + return this._currentDelegate.itemKeyAt(itemIndex); |
| + } |
| + |
| + /** |
| + * @override |
| + * @param {number} itemIndex |
| + * @param {string} query |
| + * @return {number} |
| + */ |
| + itemScoreAt(itemIndex, query) { |
| + return this._currentDelegate.itemScoreAt(itemIndex, query); |
| + } |
| + |
| + /** |
| + * @override |
| + * @param {number} itemIndex |
| + * @param {string} query |
| + * @param {!Element} titleElement |
| + * @param {!Element} subtitleElement |
| + */ |
| + renderItem(itemIndex, query, titleElement, subtitleElement) { |
| + this._delegate(query).renderItem(itemIndex, this._cleanQuery(query), titleElement, subtitleElement); |
| + } |
| + |
| + /** |
| + * @override |
| + * @return {boolean} |
| + */ |
| + renderAsTwoRows() { |
| + return this._currentDelegate.renderAsTwoRows(); |
| + } |
| + |
| + /** |
| + * @override |
| + * @param {null|number} itemIndex |
| + * @param {string} promptValue |
| + */ |
| + selectItem(itemIndex, promptValue) { |
| + this._currentDelegate.selectItem(itemIndex, this._cleanQuery(promptValue)); |
| + } |
| + |
| + /** |
| + * @override |
| + * @param {string} query |
| + * @return {string} |
| + */ |
| + rewriteQuery(query) { |
| + return this._delegate(query).rewriteQuery(this._cleanQuery(query)); |
| + } |
| + |
| + /** |
| + * @override |
| + */ |
| + dispose() { |
| + for (var i = 0; i < this._prefix.length; i++) { |
|
pfeldman
2017/02/07 02:10:02
I now see why you need delegates, but I'd manage s
einbinder
2017/02/28 23:59:07
Dispose is to remove the event listeners on Filter
|
| + if (this._prefix[i].delegate) |
| + this._prefix[i].delegate.dispose(); |
| + } |
| + super.dispose(); |
| + } |
| + |
| + /** |
| + * @param {string} query |
| + */ |
| + static show(query) { |
|
pfeldman
2017/02/07 02:10:03
move up.
einbinder
2017/02/28 23:59:07
Done.
|
| + var filteredItemSelectionDialog = |
| + new QuickOpen.FilteredListWidget(new QuickOpen.QuickOpen(), QuickOpen.QuickOpen._history); |
|
pfeldman
2017/02/07 02:10:03
QuickOpen.QuickOpen again - why do you need to spe
einbinder
2017/02/28 23:59:07
Fixed :)
|
| + filteredItemSelectionDialog.showAsDialog(); |
| + filteredItemSelectionDialog.setQuery(query); |
| + } |
| +}; |
| + |
| +QuickOpen.QuickOpen._history = []; |
| + |
| +/** |
| + * @implements {UI.ActionDelegate} |
| + */ |
| +QuickOpen.QuickOpen.ShowActionDelegate = class { |
| + /** |
| + * @override |
| + * @param {!UI.Context} context |
| + * @param {string} actionId |
| + * @return {boolean} |
| + */ |
| + handleAction(context, actionId) { |
| + switch (actionId) { |
| + case 'quickOpen.show': |
| + QuickOpen.QuickOpen.show(''); |
| + return true; |
| + } |
| + return false; |
| + } |
| +}; |
| + |
| +QuickOpen.Loading = class extends QuickOpen.FilteredListWidget.Delegate { |
|
pfeldman
2017/02/07 02:10:02
QuickOpen.QuickOpen.Loading :)
einbinder
2017/02/28 23:59:07
Done.
|
| + /** |
| + * @override |
| + */ |
| + notFoundText() { |
| + return Common.UIString('Loading...'); |
| + } |
| +}; |