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..fc73d95cc3d573eb51788c367a5d63d3a2369715 |
--- /dev/null |
+++ b/third_party/WebKit/Source/devtools/front_end/quick_open/QuickOpen.js |
@@ -0,0 +1,129 @@ |
+// 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 { |
+ /** |
+ * @param {!QuickOpen.FilteredListWidget} filtedListWidget |
+ */ |
+ constructor(filtedListWidget) { |
+ super(); |
+ /** @type {!Array<{ |
+ * prefix: string, |
+ * instance: function():!Promise<!QuickOpen.FilteredListWidget.Delegate>, |
+ * delegate: ?QuickOpen.FilteredListWidget.Delegate |
+ * }>} */ |
+ this._descriptors = []; |
+ self.runtime.extensions(QuickOpen.FilteredListWidget.Delegate).forEach(this._addProvider.bind(this)); |
+ this._delegate = this._loadingDelegate = new QuickOpen.QuickOpen.Loading(); |
+ this._prefix = null; |
pfeldman
2017/03/06 18:37:18
It is funny how you have this in both places - is
|
+ this._query = ''; |
+ this._disposed = false; |
+ this._filteredListWidget = filtedListWidget; |
+ this._filteredListWidget.on(QuickOpen.FilteredListWidget.QueryChangedEvent, this._queryChanged, this); |
+ this._filteredListWidget.on(QuickOpen.FilteredListWidget.DisposeEvent, this._dispose, this); |
pfeldman
2017/03/06 18:37:18
Ah, so you kind-of have both, a lifetime-long dele
einbinder
2017/03/08 22:39:56
Removed dispose, queryChange is a callback.
|
+ this._filteredListWidget.setDelegate(this._delegate); |
+ } |
+ |
+ /** |
+ * @param {string} query |
+ */ |
+ static show(query) { |
+ var filteredListWidget = new QuickOpen.FilteredListWidget(null, this._history); |
+ new this(filteredListWidget); |
+ filteredListWidget.showAsDialog(); |
+ filteredListWidget.setQuery(query); |
+ } |
+ |
+ /** |
+ * @param {!Runtime.Extension} extension |
+ */ |
+ _addProvider(extension) { |
+ var descriptor = { |
+ prefix: extension.descriptor().prefix, |
pfeldman
2017/03/06 18:37:18
Everything not defined in the jsdoc should be acce
einbinder
2017/03/08 22:39:56
Done.
|
+ delegate: null, |
+ instance: extension.instance.bind(extension) |
+ }; |
+ var index = this._descriptors.lowerBound(descriptor, (a, b) => b.prefix.length - a.prefix.length); |
+ this._descriptors.splice(index, 0, descriptor); |
pfeldman
2017/03/06 18:37:18
How is it better than array of extension.descripto
einbinder
2017/03/08 22:39:56
Replaced with a map.
|
+ } |
+ |
+ _updateProvider() { |
+ var descriptor = this._descriptors.find(descriptor => this._query.startsWith(descriptor.prefix)); |
+ if (!descriptor || this._prefix === descriptor.prefix) |
+ return; |
+ |
+ this._prefix = descriptor.prefix; |
+ this._filteredListWidget.setPrefix(this._prefix); |
+ if (descriptor.delegate) { |
pfeldman
2017/03/06 18:37:18
There is no reason to split promise and sync behav
einbinder
2017/03/08 22:39:57
Done.
|
+ this._filteredListWidget.setDelegate(descriptor.delegate); |
+ return; |
+ } |
+ descriptor.instance().then(instance => { |
+ if (this._disposed) |
+ instance.dispose(); |
pfeldman
2017/03/06 18:37:18
return after?
einbinder
2017/03/08 22:39:57
n/a
|
+ descriptor.delegate = instance; |
+ if (this._prefix !== descriptor.prefix) |
+ return; |
+ this._filteredListWidget.setDelegate(instance); |
+ this._delegateLoadedForTest(instance); |
+ }); |
+ this._filteredListWidget.setDelegate(this._loadingDelegate); |
pfeldman
2017/03/06 18:37:18
This is going to be instantaneous in most of the c
einbinder
2017/03/08 22:39:56
For the cases where it is not instantaneous.
|
+ } |
+ |
+ /** |
+ * @param {!QuickOpen.FilteredListWidget.QueryChangedEvent} event |
+ */ |
+ _queryChanged(event) { |
+ this._query = event.query; |
+ this._updateProvider(); |
+ } |
+ |
+ /** |
+ * @param {!QuickOpen.FilteredListWidget.Delegate} delegate |
+ */ |
+ _delegateLoadedForTest(delegate) { |
+ } |
+ |
+ _dispose() { |
+ this._disposed = true; |
+ this._filteredListWidget.off(QuickOpen.FilteredListWidget.QueryChangedEvent, this._queryChanged, this); |
+ this._filteredListWidget.off(QuickOpen.FilteredListWidget.DisposeEvent, this._dispose, this); |
+ for (var descriptor of this._descriptors) { |
+ if (descriptor.delegate) |
+ descriptor.delegate.dispose(); |
+ } |
+ this._filteredListWidget.setDelegate(null); |
+ } |
+}; |
+ |
+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.QuickOpen.Loading = class extends QuickOpen.FilteredListWidget.Delegate { |
+ /** |
+ * @override |
+ */ |
+ notFoundText() { |
+ return Common.UIString('Loading...'); |
+ } |
+}; |