Chromium Code Reviews| 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 bf47f5aa99208b6b3b7ecf3b5519d332ba05a3e4..34a6df5ad408a8ded3bab76365960292829f1678 100644 |
| --- a/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js |
| +++ b/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js |
| @@ -50,6 +50,7 @@ WebInspector.SuggestBoxDelegate.prototype = { |
| /** |
| * @constructor |
| + * @implements {WebInspector.StaticViewportControl.Provider} |
| * @param {!WebInspector.SuggestBoxDelegate} suggestBoxDelegate |
| * @param {number=} maxItemsHeight |
| * @param {boolean=} captureEnter |
| @@ -63,7 +64,10 @@ WebInspector.SuggestBox = function(suggestBoxDelegate, maxItemsHeight, captureEn |
| this._maxItemsHeight = maxItemsHeight; |
| this._maybeHideBound = this._maybeHide.bind(this); |
| this._container = createElementWithClass("div", "suggest-box-container"); |
| - this._element = this._container.createChild("div", "suggest-box"); |
| + this._viewport = new WebInspector.StaticViewportControl(this); |
| + this._element = this._viewport.element; |
| + 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"); |
| @@ -72,6 +76,10 @@ WebInspector.SuggestBox = function(suggestBoxDelegate, maxItemsHeight, captureEn |
| this._asyncDetailsPromises = new Map(); |
| this._userInteracted = false; |
| this._captureEnter = captureEnter; |
| + /** @type {!Array<!Element>} */ |
| + this._elementList = []; |
| + this._rowHeight = 17; |
| + this._viewportWidth = "100vw"; |
| } |
| /** |
| @@ -102,8 +110,9 @@ WebInspector.SuggestBox.prototype = { |
| _updateBoxPosition: function(anchorBox) |
| { |
| console.assert(this._overlay); |
| - if (this._lastAnchorBox && this._lastAnchorBox.equals(anchorBox)) |
| + 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. |
| @@ -121,10 +130,25 @@ WebInspector.SuggestBox.prototype = { |
| else |
| this._overlay.setVerticalOffset(totalHeight - anchorBox.y, false); |
| - /** const */ var rowHeight = 17; |
| - /** const */ var spacer = 6; |
| - var maxHeight = this._maxItemsHeight ? this._maxItemsHeight * rowHeight : Math.max(underHeight, aboveHeight) - spacer; |
| - this._element.style.maxHeight = maxHeight + "px"; |
| + var spacer = 6; |
| + var maxHeight = this._maxItemsHeight ? this._maxItemsHeight * this._rowHeight : Math.max(underHeight, aboveHeight) - spacer; |
| + var height = this._rowHeight * this._elementList.length; |
| + var hasScrollBars = height > maxHeight; |
| + this._element.style.height = Math.min(maxHeight, height) + "px"; |
| + }, |
| + |
| + _updateWidth: function() |
|
einbinder
2016/10/07 23:17:51
This is unfortunate, but I think it's necessary.
|
| + { |
| + if (this._element.offsetHeight + this._rowHeight <= this._rowHeight * this._elementList.length) { |
| + this._element.style.width = "100vw"; |
| + return; |
| + } |
| + // If there are no scrollbars, set the width to the width of the largest row. |
| + var width = 0; |
| + for (var i = 0; i < this._elementList.length; i++) { |
| + width = Math.max(width, WebInspector.measurePreferredSize(this._elementList[i], this._element).width); |
| + } |
| + this._element.style.width = width + "px"; |
| }, |
| /** |
| @@ -157,6 +181,10 @@ WebInspector.SuggestBox.prototype = { |
| 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() |
| @@ -256,10 +284,9 @@ WebInspector.SuggestBox.prototype = { |
| /** |
| * @param {string} prefix |
| * @param {string} text |
| - * @param {string|undefined} className |
| - * @param {number} index |
| + * @param {string=} className |
| */ |
| - _createItemElement: function(prefix, text, className, index) |
| + _createItemElement: function(prefix, text, className) |
| { |
| var element = createElementWithClass("div", "suggest-box-content-item source-code " + (className || "")); |
| element.tabIndex = -1; |
| @@ -285,14 +312,11 @@ WebInspector.SuggestBox.prototype = { |
| this._length = items.length; |
| this._asyncDetailsPromises.clear(); |
| this._asyncDetailsCallback = asyncDetails; |
| - this._element.removeChildren(); |
| + this._elementList = []; |
| delete this._selectedElement; |
| - for (var i = 0; i < items.length; ++i) { |
| - var item = items[i]; |
| - var currentItemElement = this._createItemElement(userEnteredText, item.title, item.className, i); |
| - this._element.appendChild(currentItemElement); |
| - } |
| + for (var i = 0; i < items.length; ++i) |
| + this._elementList.push(this._createItemElement(userEnteredText, items[i].title, items[i].className)); |
| }, |
| /** |
| @@ -334,14 +358,14 @@ WebInspector.SuggestBox.prototype = { |
| if (index < 0) |
| return; |
| - this._selectedElement = this._element.children[index]; |
| + this._selectedElement = this._elementList[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._selectedElement.scrollIntoViewIfNeeded(false); |
| + this._viewport.scrollItemIntoView(index); |
| /** |
| * @param {?{detail: string, description: string}} details |
| @@ -375,10 +399,10 @@ WebInspector.SuggestBox.prototype = { |
| { |
| if (this._rowCountPerViewport) |
| return; |
| - if (!this._element.firstChild) |
| + if (!this._elementList.length) |
| return; |
| - this._rowCountPerViewport = Math.floor(this._element.offsetHeight / this._element.firstChild.offsetHeight); |
| + this._rowCountPerViewport = Math.floor(this._element.getBoundingClientRect().height / this._rowHeight); |
| }, |
| /** |
| @@ -396,6 +420,8 @@ WebInspector.SuggestBox.prototype = { |
| this._updateItems(completions, userEnteredText, asyncDetails); |
| this._show(); |
| this._updateBoxPosition(anchorBox); |
| + this._updateWidth(); |
| + this._viewport.refresh(); |
| this._selectItem(selectedIndex, selectedIndex > 0); |
| delete this._rowCountPerViewport; |
| } else { |
| @@ -474,6 +500,35 @@ WebInspector.SuggestBox.prototype = { |
| // 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._elementList.length; |
| + }, |
| + |
| + /** |
| + * @override |
| + * @param {number} index |
| + * @return {?Element} |
| + */ |
| + itemElement: function(index) |
| + { |
| + return this._elementList[index]; |
| } |
| } |