| Index: third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
|
| diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js b/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
|
| index 45f89fe95ff8d9a888d80c661bec638bbab2bfd0..983a0e56fb3e591d64d26db67590540caaee32bf 100644
|
| --- a/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
|
| +++ b/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
|
| @@ -27,50 +27,49 @@
|
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| */
|
| -
|
| /**
|
| * @interface
|
| */
|
| -WebInspector.SuggestBoxDelegate = function()
|
| -{
|
| -};
|
| +WebInspector.SuggestBoxDelegate = function() {};
|
|
|
| WebInspector.SuggestBoxDelegate.prototype = {
|
| - /**
|
| - * @param {string} suggestion
|
| - * @param {boolean=} isIntermediateSuggestion
|
| - */
|
| - applySuggestion: function(suggestion, isIntermediateSuggestion) { },
|
| -
|
| - /**
|
| - * acceptSuggestion will be always called after call to applySuggestion with isIntermediateSuggestion being equal to false.
|
| - */
|
| - acceptSuggestion: function() { },
|
| + /**
|
| + * @param {string} suggestion
|
| + * @param {boolean=} isIntermediateSuggestion
|
| + */
|
| + applySuggestion: function(suggestion, isIntermediateSuggestion) {},
|
| +
|
| + /**
|
| + * acceptSuggestion will be always called after call to applySuggestion with isIntermediateSuggestion being equal to false.
|
| + */
|
| + acceptSuggestion: function() {},
|
| };
|
|
|
| /**
|
| - * @constructor
|
| * @implements {WebInspector.StaticViewportControl.Provider}
|
| - * @param {!WebInspector.SuggestBoxDelegate} suggestBoxDelegate
|
| - * @param {number=} maxItemsHeight
|
| - * @param {boolean=} captureEnter
|
| + * @unrestricted
|
| */
|
| -WebInspector.SuggestBox = function(suggestBoxDelegate, maxItemsHeight, captureEnter)
|
| -{
|
| +WebInspector.SuggestBox = class {
|
| + /**
|
| + * @param {!WebInspector.SuggestBoxDelegate} suggestBoxDelegate
|
| + * @param {number=} maxItemsHeight
|
| + * @param {boolean=} captureEnter
|
| + */
|
| + constructor(suggestBoxDelegate, maxItemsHeight, captureEnter) {
|
| this._suggestBoxDelegate = suggestBoxDelegate;
|
| this._length = 0;
|
| this._selectedIndex = -1;
|
| this._selectedElement = null;
|
| this._maxItemsHeight = maxItemsHeight;
|
| this._maybeHideBound = this._maybeHide.bind(this);
|
| - this._container = createElementWithClass("div", "suggest-box-container");
|
| + this._container = createElementWithClass('div', 'suggest-box-container');
|
| this._viewport = new WebInspector.StaticViewportControl(this);
|
| this._element = this._viewport.element;
|
| - this._element.classList.add("suggest-box");
|
| + this._element.classList.add('suggest-box');
|
| this._container.appendChild(this._element);
|
| - this._element.addEventListener("mousedown", this._onBoxMouseDown.bind(this), true);
|
| - this._detailsPopup = this._container.createChild("div", "suggest-box details-popup monospace");
|
| - this._detailsPopup.classList.add("hidden");
|
| + this._element.addEventListener('mousedown', this._onBoxMouseDown.bind(this), true);
|
| + this._detailsPopup = this._container.createChild('div', 'suggest-box details-popup monospace');
|
| + this._detailsPopup.classList.add('hidden');
|
| this._asyncDetailsCallback = null;
|
| /** @type {!Map<number, !Promise<{detail: string, description: string}>>} */
|
| this._asyncDetailsPromises = new Map();
|
| @@ -79,534 +78,500 @@ WebInspector.SuggestBox = function(suggestBoxDelegate, maxItemsHeight, captureEn
|
| /** @type {!Array<!Element>} */
|
| this._elementList = [];
|
| this._rowHeight = 17;
|
| - this._viewportWidth = "100vw";
|
| + this._viewportWidth = '100vw';
|
| this._hasVerticalScroll = false;
|
| - this._userEnteredText = "";
|
| + this._userEnteredText = '';
|
| /** @type {!WebInspector.SuggestBox.Suggestions} */
|
| this._items = [];
|
| -};
|
| -
|
| -/**
|
| - * @typedef {!Array.<{title: string, className: (string|undefined)}>}
|
| - */
|
| -WebInspector.SuggestBox.Suggestions;
|
| -
|
| -WebInspector.SuggestBox.prototype = {
|
| - /**
|
| - * @return {boolean}
|
| - */
|
| - visible: function()
|
| - {
|
| - return !!this._container.parentElement;
|
| - },
|
| -
|
| - /**
|
| - * @param {!AnchorBox} anchorBox
|
| - */
|
| - setPosition: function(anchorBox)
|
| - {
|
| - this._updateBoxPosition(anchorBox);
|
| - },
|
| -
|
| - /**
|
| - * @param {!AnchorBox} anchorBox
|
| - */
|
| - _updateBoxPosition: function(anchorBox)
|
| - {
|
| - console.assert(this._overlay);
|
| - if (this._lastAnchorBox && this._lastAnchorBox.equals(anchorBox) && this._lastItemCount === this.itemCount())
|
| - return;
|
| - this._lastItemCount = this.itemCount();
|
| - this._lastAnchorBox = anchorBox;
|
| -
|
| - // Position relative to main DevTools element.
|
| - var container = WebInspector.Dialog.modalHostView().element;
|
| - anchorBox = anchorBox.relativeToElement(container);
|
| - var totalHeight = container.offsetHeight;
|
| - var aboveHeight = anchorBox.y;
|
| - var underHeight = totalHeight - anchorBox.y - anchorBox.height;
|
| -
|
| - this._overlay.setLeftOffset(anchorBox.x);
|
| -
|
| - var under = underHeight >= aboveHeight;
|
| - if (under)
|
| - this._overlay.setVerticalOffset(anchorBox.y + anchorBox.height, true);
|
| - else
|
| - this._overlay.setVerticalOffset(totalHeight - anchorBox.y, false);
|
| -
|
| - var spacer = 6;
|
| - var maxHeight = Math.min(Math.max(underHeight, aboveHeight) - spacer, this._maxItemsHeight ? this._maxItemsHeight * this._rowHeight : 0);
|
| - var height = this._rowHeight * this._items.length;
|
| - this._hasVerticalScroll = height > maxHeight;
|
| - this._element.style.height = Math.min(maxHeight, height) + "px";
|
| - },
|
| -
|
| - _updateWidth: function()
|
| - {
|
| - if (this._hasVerticalScroll) {
|
| - this._element.style.width = "100vw";
|
| - return;
|
| - }
|
| - // If there are no scrollbars, set the width to the width of the largest row.
|
| - var maxIndex = 0;
|
| - for (var i = 0; i < this._items.length; i++) {
|
| - if (this._items[i].title.length > this._items[maxIndex].title.length)
|
| - maxIndex = i;
|
| - }
|
| - var element = /** @type {!Element} */ (this.itemElement(maxIndex));
|
| - this._element.style.width = WebInspector.measurePreferredSize(element, this._element).width + "px";
|
| - },
|
| -
|
| - /**
|
| - * @param {!Event} event
|
| - */
|
| - _onBoxMouseDown: function(event)
|
| - {
|
| - if (this._hideTimeoutId) {
|
| - window.clearTimeout(this._hideTimeoutId);
|
| - delete this._hideTimeoutId;
|
| - }
|
| - event.preventDefault();
|
| - },
|
| -
|
| - _maybeHide: function()
|
| - {
|
| - if (!this._hideTimeoutId)
|
| - this._hideTimeoutId = window.setTimeout(this.hide.bind(this), 0);
|
| - },
|
| -
|
| - /**
|
| - * // FIXME: make SuggestBox work for multiple documents.
|
| - * @suppressGlobalPropertiesCheck
|
| - */
|
| - _show: function()
|
| - {
|
| - if (this.visible())
|
| - return;
|
| - this._bodyElement = document.body;
|
| - this._bodyElement.addEventListener("mousedown", this._maybeHideBound, true);
|
| - this._overlay = new WebInspector.SuggestBox.Overlay();
|
| - this._overlay.setContentElement(this._container);
|
| - var measuringElement = this._createItemElement("1", "12");
|
| - this._viewport.element.appendChild(measuringElement);
|
| - this._rowHeight = measuringElement.getBoundingClientRect().height;
|
| - measuringElement.remove();
|
| - },
|
| -
|
| - hide: function()
|
| - {
|
| - if (!this.visible())
|
| - return;
|
| -
|
| - this._userInteracted = false;
|
| - this._bodyElement.removeEventListener("mousedown", this._maybeHideBound, true);
|
| - delete this._bodyElement;
|
| - this._container.remove();
|
| - this._overlay.dispose();
|
| - delete this._overlay;
|
| - delete this._selectedElement;
|
| - this._selectedIndex = -1;
|
| - delete this._lastAnchorBox;
|
| - },
|
| -
|
| - removeFromElement: function()
|
| - {
|
| - this.hide();
|
| - },
|
| -
|
| - /**
|
| - * @param {boolean=} isIntermediateSuggestion
|
| - * @return {boolean}
|
| - */
|
| - _applySuggestion: function(isIntermediateSuggestion)
|
| - {
|
| - if (this._onlyCompletion) {
|
| - this._suggestBoxDelegate.applySuggestion(this._onlyCompletion, isIntermediateSuggestion);
|
| - return true;
|
| - }
|
| -
|
| - if (!this.visible() || !this._selectedElement)
|
| - return false;
|
| -
|
| - var suggestion = this._selectedElement.__fullValue;
|
| - if (!suggestion)
|
| - return false;
|
| -
|
| - this._suggestBoxDelegate.applySuggestion(suggestion, isIntermediateSuggestion);
|
| - return true;
|
| - },
|
| -
|
| - /**
|
| - * @return {boolean}
|
| - */
|
| - acceptSuggestion: function()
|
| - {
|
| - var result = this._applySuggestion();
|
| - this.hide();
|
| - if (!result)
|
| - return false;
|
| -
|
| - this._suggestBoxDelegate.acceptSuggestion();
|
| -
|
| - return true;
|
| - },
|
| -
|
| - /**
|
| - * @param {number} shift
|
| - * @param {boolean=} isCircular
|
| - * @return {boolean} is changed
|
| - */
|
| - _selectClosest: function(shift, isCircular)
|
| - {
|
| - if (!this._length)
|
| - return false;
|
| -
|
| - this._userInteracted = true;
|
| -
|
| - if (this._selectedIndex === -1 && shift < 0)
|
| - shift += 1;
|
| -
|
| - var index = this._selectedIndex + shift;
|
| -
|
| - if (isCircular)
|
| - index = (this._length + index) % this._length;
|
| - else
|
| - index = Number.constrain(index, 0, this._length - 1);
|
| -
|
| - this._selectItem(index, true);
|
| - this._applySuggestion(true);
|
| - return true;
|
| - },
|
| -
|
| - /**
|
| - * @param {!Event} event
|
| - */
|
| - _onItemMouseDown: function(event)
|
| - {
|
| - this._selectedElement = event.currentTarget;
|
| - this.acceptSuggestion();
|
| - event.consume(true);
|
| - },
|
| -
|
| - /**
|
| - * @param {string} prefix
|
| - * @param {string} text
|
| - * @param {string=} className
|
| - * @return {!Element}
|
| - */
|
| - _createItemElement: function(prefix, text, className)
|
| - {
|
| - var element = createElementWithClass("div", "suggest-box-content-item source-code " + (className || ""));
|
| - element.tabIndex = -1;
|
| - if (prefix && prefix.length && !text.indexOf(prefix)) {
|
| - element.createChild("span", "prefix").textContent = prefix;
|
| - element.createChild("span", "suffix").textContent = text.substring(prefix.length).trimEnd(50);
|
| - } else {
|
| - element.createChild("span", "suffix").textContent = text.trimEnd(50);
|
| - }
|
| - element.__fullValue = text;
|
| - element.createChild("span", "spacer");
|
| - element.addEventListener("mousedown", this._onItemMouseDown.bind(this), false);
|
| - return element;
|
| - },
|
| + }
|
| +
|
| + /**
|
| + * @return {boolean}
|
| + */
|
| + visible() {
|
| + return !!this._container.parentElement;
|
| + }
|
| +
|
| + /**
|
| + * @param {!AnchorBox} anchorBox
|
| + */
|
| + setPosition(anchorBox) {
|
| + this._updateBoxPosition(anchorBox);
|
| + }
|
| +
|
| + /**
|
| + * @param {!AnchorBox} anchorBox
|
| + */
|
| + _updateBoxPosition(anchorBox) {
|
| + console.assert(this._overlay);
|
| + if (this._lastAnchorBox && this._lastAnchorBox.equals(anchorBox) && this._lastItemCount === this.itemCount())
|
| + return;
|
| + this._lastItemCount = this.itemCount();
|
| + this._lastAnchorBox = anchorBox;
|
| +
|
| + // Position relative to main DevTools element.
|
| + var container = WebInspector.Dialog.modalHostView().element;
|
| + anchorBox = anchorBox.relativeToElement(container);
|
| + var totalHeight = container.offsetHeight;
|
| + var aboveHeight = anchorBox.y;
|
| + var underHeight = totalHeight - anchorBox.y - anchorBox.height;
|
| +
|
| + this._overlay.setLeftOffset(anchorBox.x);
|
| +
|
| + var under = underHeight >= aboveHeight;
|
| + if (under)
|
| + this._overlay.setVerticalOffset(anchorBox.y + anchorBox.height, true);
|
| + else
|
| + this._overlay.setVerticalOffset(totalHeight - anchorBox.y, false);
|
| +
|
| + var spacer = 6;
|
| + var maxHeight = Math.min(
|
| + Math.max(underHeight, aboveHeight) - spacer, this._maxItemsHeight ? this._maxItemsHeight * this._rowHeight : 0);
|
| + var height = this._rowHeight * this._items.length;
|
| + this._hasVerticalScroll = height > maxHeight;
|
| + this._element.style.height = Math.min(maxHeight, height) + 'px';
|
| + }
|
| +
|
| + _updateWidth() {
|
| + if (this._hasVerticalScroll) {
|
| + this._element.style.width = '100vw';
|
| + return;
|
| + }
|
| + // If there are no scrollbars, set the width to the width of the largest row.
|
| + var maxIndex = 0;
|
| + for (var i = 0; i < this._items.length; i++) {
|
| + if (this._items[i].title.length > this._items[maxIndex].title.length)
|
| + maxIndex = i;
|
| + }
|
| + var element = /** @type {!Element} */ (this.itemElement(maxIndex));
|
| + this._element.style.width = WebInspector.measurePreferredSize(element, this._element).width + 'px';
|
| + }
|
| +
|
| + /**
|
| + * @param {!Event} event
|
| + */
|
| + _onBoxMouseDown(event) {
|
| + if (this._hideTimeoutId) {
|
| + window.clearTimeout(this._hideTimeoutId);
|
| + delete this._hideTimeoutId;
|
| + }
|
| + event.preventDefault();
|
| + }
|
| +
|
| + _maybeHide() {
|
| + if (!this._hideTimeoutId)
|
| + this._hideTimeoutId = window.setTimeout(this.hide.bind(this), 0);
|
| + }
|
| +
|
| + /**
|
| + * // FIXME: make SuggestBox work for multiple documents.
|
| + * @suppressGlobalPropertiesCheck
|
| + */
|
| + _show() {
|
| + if (this.visible())
|
| + return;
|
| + this._bodyElement = document.body;
|
| + this._bodyElement.addEventListener('mousedown', this._maybeHideBound, true);
|
| + this._overlay = new WebInspector.SuggestBox.Overlay();
|
| + this._overlay.setContentElement(this._container);
|
| + var measuringElement = this._createItemElement('1', '12');
|
| + this._viewport.element.appendChild(measuringElement);
|
| + this._rowHeight = measuringElement.getBoundingClientRect().height;
|
| + measuringElement.remove();
|
| + }
|
| +
|
| + hide() {
|
| + if (!this.visible())
|
| + return;
|
|
|
| - /**
|
| - * @param {!WebInspector.SuggestBox.Suggestions} items
|
| - * @param {string} userEnteredText
|
| - * @param {function(number): !Promise<{detail:string, description:string}>=} asyncDetails
|
| - */
|
| - _updateItems: function(items, userEnteredText, asyncDetails)
|
| - {
|
| - this._length = items.length;
|
| - this._asyncDetailsPromises.clear();
|
| - this._asyncDetailsCallback = asyncDetails;
|
| - this._elementList = [];
|
| - delete this._selectedElement;
|
| -
|
| - this._userEnteredText = userEnteredText;
|
| - this._items = items;
|
| - },
|
| + this._userInteracted = false;
|
| + this._bodyElement.removeEventListener('mousedown', this._maybeHideBound, true);
|
| + delete this._bodyElement;
|
| + this._container.remove();
|
| + this._overlay.dispose();
|
| + delete this._overlay;
|
| + delete this._selectedElement;
|
| + this._selectedIndex = -1;
|
| + delete this._lastAnchorBox;
|
| + }
|
| +
|
| + removeFromElement() {
|
| + this.hide();
|
| + }
|
| +
|
| + /**
|
| + * @param {boolean=} isIntermediateSuggestion
|
| + * @return {boolean}
|
| + */
|
| + _applySuggestion(isIntermediateSuggestion) {
|
| + if (this._onlyCompletion) {
|
| + this._suggestBoxDelegate.applySuggestion(this._onlyCompletion, isIntermediateSuggestion);
|
| + return true;
|
| + }
|
|
|
| - /**
|
| - * @param {number} index
|
| - * @return {!Promise<?{detail: string, description: string}>}
|
| - */
|
| - _asyncDetails: function(index)
|
| - {
|
| - if (!this._asyncDetailsCallback)
|
| - return Promise.resolve(/** @type {?{description: string, detail: string}} */(null));
|
| - if (!this._asyncDetailsPromises.has(index))
|
| - this._asyncDetailsPromises.set(index, this._asyncDetailsCallback(index));
|
| - return /** @type {!Promise<?{detail: string, description: string}>} */(this._asyncDetailsPromises.get(index));
|
| - },
|
| + if (!this.visible() || !this._selectedElement)
|
| + return false;
|
| +
|
| + var suggestion = this._selectedElement.__fullValue;
|
| + if (!suggestion)
|
| + return false;
|
| +
|
| + this._suggestBoxDelegate.applySuggestion(suggestion, isIntermediateSuggestion);
|
| + return true;
|
| + }
|
| +
|
| + /**
|
| + * @return {boolean}
|
| + */
|
| + acceptSuggestion() {
|
| + var result = this._applySuggestion();
|
| + this.hide();
|
| + if (!result)
|
| + return false;
|
| +
|
| + this._suggestBoxDelegate.acceptSuggestion();
|
| +
|
| + return true;
|
| + }
|
| +
|
| + /**
|
| + * @param {number} shift
|
| + * @param {boolean=} isCircular
|
| + * @return {boolean} is changed
|
| + */
|
| + _selectClosest(shift, isCircular) {
|
| + if (!this._length)
|
| + return false;
|
| +
|
| + this._userInteracted = true;
|
| +
|
| + if (this._selectedIndex === -1 && shift < 0)
|
| + shift += 1;
|
| +
|
| + var index = this._selectedIndex + shift;
|
| +
|
| + if (isCircular)
|
| + index = (this._length + index) % this._length;
|
| + else
|
| + index = Number.constrain(index, 0, this._length - 1);
|
| +
|
| + this._selectItem(index, true);
|
| + this._applySuggestion(true);
|
| + return true;
|
| + }
|
| +
|
| + /**
|
| + * @param {!Event} event
|
| + */
|
| + _onItemMouseDown(event) {
|
| + this._selectedElement = event.currentTarget;
|
| + this.acceptSuggestion();
|
| + event.consume(true);
|
| + }
|
| +
|
| + /**
|
| + * @param {string} prefix
|
| + * @param {string} text
|
| + * @param {string=} className
|
| + * @return {!Element}
|
| + */
|
| + _createItemElement(prefix, text, className) {
|
| + var element = createElementWithClass('div', 'suggest-box-content-item source-code ' + (className || ''));
|
| + element.tabIndex = -1;
|
| + if (prefix && prefix.length && !text.indexOf(prefix)) {
|
| + element.createChild('span', 'prefix').textContent = prefix;
|
| + element.createChild('span', 'suffix').textContent = text.substring(prefix.length).trimEnd(50);
|
| + } else {
|
| + element.createChild('span', 'suffix').textContent = text.trimEnd(50);
|
| + }
|
| + element.__fullValue = text;
|
| + element.createChild('span', 'spacer');
|
| + element.addEventListener('mousedown', this._onItemMouseDown.bind(this), false);
|
| + return element;
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.SuggestBox.Suggestions} items
|
| + * @param {string} userEnteredText
|
| + * @param {function(number): !Promise<{detail:string, description:string}>=} asyncDetails
|
| + */
|
| + _updateItems(items, userEnteredText, asyncDetails) {
|
| + this._length = items.length;
|
| + this._asyncDetailsPromises.clear();
|
| + this._asyncDetailsCallback = asyncDetails;
|
| + this._elementList = [];
|
| + delete this._selectedElement;
|
| +
|
| + this._userEnteredText = userEnteredText;
|
| + this._items = items;
|
| + }
|
| +
|
| + /**
|
| + * @param {number} index
|
| + * @return {!Promise<?{detail: string, description: string}>}
|
| + */
|
| + _asyncDetails(index) {
|
| + if (!this._asyncDetailsCallback)
|
| + return Promise.resolve(/** @type {?{description: string, detail: string}} */ (null));
|
| + if (!this._asyncDetailsPromises.has(index))
|
| + this._asyncDetailsPromises.set(index, this._asyncDetailsCallback(index));
|
| + return /** @type {!Promise<?{detail: string, description: string}>} */ (this._asyncDetailsPromises.get(index));
|
| + }
|
| +
|
| + /**
|
| + * @param {?{detail: string, description: string}} details
|
| + */
|
| + _showDetailsPopup(details) {
|
| + this._detailsPopup.removeChildren();
|
| + if (!details)
|
| + return;
|
| + this._detailsPopup.createChild('section', 'detail').createTextChild(details.detail);
|
| + this._detailsPopup.createChild('section', 'description').createTextChild(details.description);
|
| + this._detailsPopup.classList.remove('hidden');
|
| + }
|
| +
|
| + /**
|
| + * @param {number} index
|
| + * @param {boolean} scrollIntoView
|
| + */
|
| + _selectItem(index, scrollIntoView) {
|
| + if (this._selectedElement)
|
| + this._selectedElement.classList.remove('selected');
|
| +
|
| + this._selectedIndex = index;
|
| + if (index < 0)
|
| + return;
|
| +
|
| + this._selectedElement = this.itemElement(index);
|
| + this._selectedElement.classList.add('selected');
|
| + this._detailsPopup.classList.add('hidden');
|
| + var elem = this._selectedElement;
|
| + this._asyncDetails(index).then(showDetails.bind(this), function() {});
|
| +
|
| + if (scrollIntoView)
|
| + this._viewport.scrollItemIntoView(index);
|
|
|
| /**
|
| * @param {?{detail: string, description: string}} details
|
| + * @this {WebInspector.SuggestBox}
|
| */
|
| - _showDetailsPopup: function(details)
|
| - {
|
| - this._detailsPopup.removeChildren();
|
| - if (!details)
|
| - return;
|
| - this._detailsPopup.createChild("section", "detail").createTextChild(details.detail);
|
| - this._detailsPopup.createChild("section", "description").createTextChild(details.description);
|
| - this._detailsPopup.classList.remove("hidden");
|
| - },
|
| -
|
| - /**
|
| - * @param {number} index
|
| - * @param {boolean} scrollIntoView
|
| - */
|
| - _selectItem: function(index, scrollIntoView)
|
| - {
|
| - if (this._selectedElement)
|
| - this._selectedElement.classList.remove("selected");
|
| -
|
| - this._selectedIndex = index;
|
| - if (index < 0)
|
| - return;
|
| -
|
| - this._selectedElement = this.itemElement(index);
|
| - this._selectedElement.classList.add("selected");
|
| - this._detailsPopup.classList.add("hidden");
|
| - var elem = this._selectedElement;
|
| - this._asyncDetails(index).then(showDetails.bind(this), function(){});
|
| -
|
| - if (scrollIntoView)
|
| - this._viewport.scrollItemIntoView(index);
|
| -
|
| - /**
|
| - * @param {?{detail: string, description: string}} details
|
| - * @this {WebInspector.SuggestBox}
|
| - */
|
| - function showDetails(details)
|
| - {
|
| - if (elem === this._selectedElement)
|
| - this._showDetailsPopup(details);
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * @param {!WebInspector.SuggestBox.Suggestions} completions
|
| - * @param {boolean} canShowForSingleItem
|
| - * @param {string} userEnteredText
|
| - * @return {boolean}
|
| - */
|
| - _canShowBox: function(completions, canShowForSingleItem, userEnteredText)
|
| - {
|
| - if (!completions || !completions.length)
|
| - return false;
|
| -
|
| - if (completions.length > 1)
|
| - return true;
|
| -
|
| - // Do not show a single suggestion if it is the same as user-entered prefix, even if allowed to show single-item suggest boxes.
|
| - return canShowForSingleItem && completions[0].title !== userEnteredText;
|
| - },
|
| -
|
| - _ensureRowCountPerViewport: function()
|
| - {
|
| - if (this._rowCountPerViewport)
|
| - return;
|
| - if (!this._items.length)
|
| - return;
|
| -
|
| - this._rowCountPerViewport = Math.floor(this._element.getBoundingClientRect().height / this._rowHeight);
|
| - },
|
| -
|
| - /**
|
| - * @param {!AnchorBox} anchorBox
|
| - * @param {!WebInspector.SuggestBox.Suggestions} completions
|
| - * @param {number} selectedIndex
|
| - * @param {boolean} canShowForSingleItem
|
| - * @param {string} userEnteredText
|
| - * @param {function(number): !Promise<{detail:string, description:string}>=} asyncDetails
|
| - */
|
| - updateSuggestions: function(anchorBox, completions, selectedIndex, canShowForSingleItem, userEnteredText, asyncDetails)
|
| - {
|
| - delete this._onlyCompletion;
|
| - if (this._canShowBox(completions, canShowForSingleItem, userEnteredText)) {
|
| - this._updateItems(completions, userEnteredText, asyncDetails);
|
| - this._show();
|
| - this._updateBoxPosition(anchorBox);
|
| - this._updateWidth();
|
| - this._viewport.refresh();
|
| - this._selectItem(selectedIndex, selectedIndex > 0);
|
| - delete this._rowCountPerViewport;
|
| - } else {
|
| - if (completions.length === 1)
|
| - this._onlyCompletion = completions[0].title;
|
| - this.hide();
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * @param {!KeyboardEvent} event
|
| - * @return {boolean}
|
| - */
|
| - keyPressed: function(event)
|
| - {
|
| - switch (event.key) {
|
| - case "ArrowUp":
|
| - return this.upKeyPressed();
|
| - case "ArrowDown":
|
| - return this.downKeyPressed();
|
| - case "PageUp":
|
| - return this.pageUpKeyPressed();
|
| - case "PageDown":
|
| - return this.pageDownKeyPressed();
|
| - case "Enter":
|
| - return this.enterKeyPressed();
|
| - }
|
| - return false;
|
| - },
|
| -
|
| - /**
|
| - * @return {boolean}
|
| - */
|
| - upKeyPressed: function()
|
| - {
|
| - return this._selectClosest(-1, true);
|
| - },
|
| -
|
| - /**
|
| - * @return {boolean}
|
| - */
|
| - downKeyPressed: function()
|
| - {
|
| - return this._selectClosest(1, true);
|
| - },
|
| -
|
| - /**
|
| - * @return {boolean}
|
| - */
|
| - pageUpKeyPressed: function()
|
| - {
|
| - this._ensureRowCountPerViewport();
|
| - return this._selectClosest(-this._rowCountPerViewport, false);
|
| - },
|
| -
|
| - /**
|
| - * @return {boolean}
|
| - */
|
| - pageDownKeyPressed: function()
|
| - {
|
| - this._ensureRowCountPerViewport();
|
| - return this._selectClosest(this._rowCountPerViewport, false);
|
| - },
|
| -
|
| - /**
|
| - * @return {boolean}
|
| - */
|
| - enterKeyPressed: function()
|
| - {
|
| - if (!this._userInteracted && this._captureEnter)
|
| - return false;
|
| -
|
| - var hasSelectedItem = !!this._selectedElement || this._onlyCompletion;
|
| - this.acceptSuggestion();
|
| -
|
| - // Report the event as non-handled if there is no selected item,
|
| - // to commit the input or handle it otherwise.
|
| - return hasSelectedItem;
|
| - },
|
| -
|
| - /**
|
| - * @override
|
| - * @param {number} index
|
| - * @return {number}
|
| - */
|
| - fastItemHeight: function(index)
|
| - {
|
| - return this._rowHeight;
|
| - },
|
| -
|
| - /**
|
| - * @override
|
| - * @return {number}
|
| - */
|
| - itemCount: function()
|
| - {
|
| - return this._items.length;
|
| - },
|
| -
|
| - /**
|
| - * @override
|
| - * @param {number} index
|
| - * @return {?Element}
|
| - */
|
| - itemElement: function(index)
|
| - {
|
| - if (!this._elementList[index])
|
| - this._elementList[index] = this._createItemElement(this._userEnteredText, this._items[index].title, this._items[index].className);
|
| - return this._elementList[index];
|
| + function showDetails(details) {
|
| + if (elem === this._selectedElement)
|
| + this._showDetailsPopup(details);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.SuggestBox.Suggestions} completions
|
| + * @param {boolean} canShowForSingleItem
|
| + * @param {string} userEnteredText
|
| + * @return {boolean}
|
| + */
|
| + _canShowBox(completions, canShowForSingleItem, userEnteredText) {
|
| + if (!completions || !completions.length)
|
| + return false;
|
| +
|
| + if (completions.length > 1)
|
| + return true;
|
| +
|
| + // Do not show a single suggestion if it is the same as user-entered prefix, even if allowed to show single-item suggest boxes.
|
| + return canShowForSingleItem && completions[0].title !== userEnteredText;
|
| + }
|
| +
|
| + _ensureRowCountPerViewport() {
|
| + if (this._rowCountPerViewport)
|
| + return;
|
| + if (!this._items.length)
|
| + return;
|
| +
|
| + this._rowCountPerViewport = Math.floor(this._element.getBoundingClientRect().height / this._rowHeight);
|
| + }
|
| +
|
| + /**
|
| + * @param {!AnchorBox} anchorBox
|
| + * @param {!WebInspector.SuggestBox.Suggestions} completions
|
| + * @param {number} selectedIndex
|
| + * @param {boolean} canShowForSingleItem
|
| + * @param {string} userEnteredText
|
| + * @param {function(number): !Promise<{detail:string, description:string}>=} asyncDetails
|
| + */
|
| + updateSuggestions(anchorBox, completions, selectedIndex, canShowForSingleItem, userEnteredText, asyncDetails) {
|
| + delete this._onlyCompletion;
|
| + if (this._canShowBox(completions, canShowForSingleItem, userEnteredText)) {
|
| + this._updateItems(completions, userEnteredText, asyncDetails);
|
| + this._show();
|
| + this._updateBoxPosition(anchorBox);
|
| + this._updateWidth();
|
| + this._viewport.refresh();
|
| + this._selectItem(selectedIndex, selectedIndex > 0);
|
| + delete this._rowCountPerViewport;
|
| + } else {
|
| + if (completions.length === 1)
|
| + this._onlyCompletion = completions[0].title;
|
| + this.hide();
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @param {!KeyboardEvent} event
|
| + * @return {boolean}
|
| + */
|
| + keyPressed(event) {
|
| + switch (event.key) {
|
| + case 'ArrowUp':
|
| + return this.upKeyPressed();
|
| + case 'ArrowDown':
|
| + return this.downKeyPressed();
|
| + case 'PageUp':
|
| + return this.pageUpKeyPressed();
|
| + case 'PageDown':
|
| + return this.pageDownKeyPressed();
|
| + case 'Enter':
|
| + return this.enterKeyPressed();
|
| }
|
| + return false;
|
| + }
|
| +
|
| + /**
|
| + * @return {boolean}
|
| + */
|
| + upKeyPressed() {
|
| + return this._selectClosest(-1, true);
|
| + }
|
| +
|
| + /**
|
| + * @return {boolean}
|
| + */
|
| + downKeyPressed() {
|
| + return this._selectClosest(1, true);
|
| + }
|
| +
|
| + /**
|
| + * @return {boolean}
|
| + */
|
| + pageUpKeyPressed() {
|
| + this._ensureRowCountPerViewport();
|
| + return this._selectClosest(-this._rowCountPerViewport, false);
|
| + }
|
| +
|
| + /**
|
| + * @return {boolean}
|
| + */
|
| + pageDownKeyPressed() {
|
| + this._ensureRowCountPerViewport();
|
| + return this._selectClosest(this._rowCountPerViewport, false);
|
| + }
|
| +
|
| + /**
|
| + * @return {boolean}
|
| + */
|
| + enterKeyPressed() {
|
| + if (!this._userInteracted && this._captureEnter)
|
| + return false;
|
| +
|
| + var hasSelectedItem = !!this._selectedElement || this._onlyCompletion;
|
| + this.acceptSuggestion();
|
| +
|
| + // Report the event as non-handled if there is no selected item,
|
| + // to commit the input or handle it otherwise.
|
| + return hasSelectedItem;
|
| + }
|
| +
|
| + /**
|
| + * @override
|
| + * @param {number} index
|
| + * @return {number}
|
| + */
|
| + fastItemHeight(index) {
|
| + return this._rowHeight;
|
| + }
|
| +
|
| + /**
|
| + * @override
|
| + * @return {number}
|
| + */
|
| + itemCount() {
|
| + return this._items.length;
|
| + }
|
| +
|
| + /**
|
| + * @override
|
| + * @param {number} index
|
| + * @return {?Element}
|
| + */
|
| + itemElement(index) {
|
| + if (!this._elementList[index])
|
| + this._elementList[index] =
|
| + this._createItemElement(this._userEnteredText, this._items[index].title, this._items[index].className);
|
| + return this._elementList[index];
|
| + }
|
| };
|
|
|
| /**
|
| - * @constructor
|
| - * // FIXME: make SuggestBox work for multiple documents.
|
| - * @suppressGlobalPropertiesCheck
|
| + * @typedef {!Array.<{title: string, className: (string|undefined)}>}
|
| + */
|
| +WebInspector.SuggestBox.Suggestions;
|
| +
|
| +/**
|
| + * @unrestricted
|
| */
|
| -WebInspector.SuggestBox.Overlay = function()
|
| -{
|
| - this.element = createElementWithClass("div", "suggest-box-overlay");
|
| - var root = WebInspector.createShadowRootWithCoreStyles(this.element, "ui/suggestBox.css");
|
| - this._leftSpacerElement = root.createChild("div", "suggest-box-left-spacer");
|
| - this._horizontalElement = root.createChild("div", "suggest-box-horizontal");
|
| - this._topSpacerElement = this._horizontalElement.createChild("div", "suggest-box-top-spacer");
|
| - this._bottomSpacerElement = this._horizontalElement.createChild("div", "suggest-box-bottom-spacer");
|
| +WebInspector.SuggestBox.Overlay = class {
|
| + /**
|
| + * // FIXME: make SuggestBox work for multiple documents.
|
| + * @suppressGlobalPropertiesCheck
|
| + */
|
| + constructor() {
|
| + this.element = createElementWithClass('div', 'suggest-box-overlay');
|
| + var root = WebInspector.createShadowRootWithCoreStyles(this.element, 'ui/suggestBox.css');
|
| + this._leftSpacerElement = root.createChild('div', 'suggest-box-left-spacer');
|
| + this._horizontalElement = root.createChild('div', 'suggest-box-horizontal');
|
| + this._topSpacerElement = this._horizontalElement.createChild('div', 'suggest-box-top-spacer');
|
| + this._bottomSpacerElement = this._horizontalElement.createChild('div', 'suggest-box-bottom-spacer');
|
| this._resize();
|
| document.body.appendChild(this.element);
|
| -};
|
| -
|
| -WebInspector.SuggestBox.Overlay.prototype = {
|
| - /**
|
| - * @param {number} offset
|
| - */
|
| - setLeftOffset: function(offset)
|
| - {
|
| - this._leftSpacerElement.style.flexBasis = offset + "px";
|
| - },
|
| -
|
| - /**
|
| - * @param {number} offset
|
| - * @param {boolean} isTopOffset
|
| - */
|
| - setVerticalOffset: function(offset, isTopOffset)
|
| - {
|
| - this.element.classList.toggle("under-anchor", isTopOffset);
|
| -
|
| - if (isTopOffset) {
|
| - this._bottomSpacerElement.style.flexBasis = "auto";
|
| - this._topSpacerElement.style.flexBasis = offset + "px";
|
| - } else {
|
| - this._bottomSpacerElement.style.flexBasis = offset + "px";
|
| - this._topSpacerElement.style.flexBasis = "auto";
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * @param {!Element} element
|
| - */
|
| - setContentElement: function(element)
|
| - {
|
| - this._horizontalElement.insertBefore(element, this._bottomSpacerElement);
|
| - },
|
| -
|
| - _resize: function()
|
| - {
|
| - var container = WebInspector.Dialog.modalHostView().element;
|
| - var containerBox = container.boxInWindow(container.ownerDocument.defaultView);
|
| -
|
| - this.element.style.left = containerBox.x + "px";
|
| - this.element.style.top = containerBox.y + "px";
|
| - this.element.style.height = containerBox.height + "px";
|
| - this.element.style.width = containerBox.width + "px";
|
| - },
|
| -
|
| - dispose: function()
|
| - {
|
| - this.element.remove();
|
| + }
|
| +
|
| + /**
|
| + * @param {number} offset
|
| + */
|
| + setLeftOffset(offset) {
|
| + this._leftSpacerElement.style.flexBasis = offset + 'px';
|
| + }
|
| +
|
| + /**
|
| + * @param {number} offset
|
| + * @param {boolean} isTopOffset
|
| + */
|
| + setVerticalOffset(offset, isTopOffset) {
|
| + this.element.classList.toggle('under-anchor', isTopOffset);
|
| +
|
| + if (isTopOffset) {
|
| + this._bottomSpacerElement.style.flexBasis = 'auto';
|
| + this._topSpacerElement.style.flexBasis = offset + 'px';
|
| + } else {
|
| + this._bottomSpacerElement.style.flexBasis = offset + 'px';
|
| + this._topSpacerElement.style.flexBasis = 'auto';
|
| }
|
| + }
|
| +
|
| + /**
|
| + * @param {!Element} element
|
| + */
|
| + setContentElement(element) {
|
| + this._horizontalElement.insertBefore(element, this._bottomSpacerElement);
|
| + }
|
| +
|
| + _resize() {
|
| + var container = WebInspector.Dialog.modalHostView().element;
|
| + var containerBox = container.boxInWindow(container.ownerDocument.defaultView);
|
| +
|
| + this.element.style.left = containerBox.x + 'px';
|
| + this.element.style.top = containerBox.y + 'px';
|
| + this.element.style.height = containerBox.height + 'px';
|
| + this.element.style.width = containerBox.width + 'px';
|
| + }
|
| +
|
| + dispose() {
|
| + this.element.remove();
|
| + }
|
| };
|
|
|