X-Git-Url: https://git.webkit.org/?p=WebKit-https.git;a=blobdiff_plain;f=Source%2FWebCore%2Finspector%2Ffront-end%2FTextPrompt.js;h=6ef8dfddf3f216b072bc81d95ffd29321171b1c6;hp=2b5b2d5aa8ddf3c4d2330c4a0c64303712924c7b;hb=386a412a5668b6a48086a4415d8b8db850ba4f65;hpb=07ba4ccc0031841b704094e596bfe65d2ad020ee diff --git a/Source/WebCore/inspector/front-end/TextPrompt.js b/Source/WebCore/inspector/front-end/TextPrompt.js index 2b5b2d5aa8dd..6ef8dfddf3f2 100644 --- a/Source/WebCore/inspector/front-end/TextPrompt.js +++ b/Source/WebCore/inspector/front-end/TextPrompt.js @@ -30,6 +30,7 @@ /** * @constructor * @extends WebInspector.Object + * @implements {WebInspector.SuggestBoxDelegate} * @param {function(Element, Range, boolean, function(Array., number=))} completions * @param {string=} stopCharacters */ @@ -51,6 +52,11 @@ WebInspector.TextPrompt.Events = { }; WebInspector.TextPrompt.prototype = { + userEnteredText: function() + { + return this._userEnteredText; + }, + get proxyElement() { return this._proxyElement; @@ -117,7 +123,7 @@ WebInspector.TextPrompt.prototype = { this._element.addEventListener("selectstart", this._boundSelectStart, false); if (typeof this._suggestBoxClassName === "string") - this._suggestBox = new WebInspector.TextPrompt.SuggestBox(this, this._element, this._suggestBoxClassName); + this._suggestBox = new WebInspector.SuggestBox(this, this._element, this._suggestBoxClassName); return this.proxyElement; }, @@ -520,7 +526,7 @@ WebInspector.TextPrompt.prototype = { selection.addRange(finalSelectionRange); } } else - this.applySuggestion(completionText, completions.length > 1, originalWordPrefixRange); + this._applySuggestion(completionText, completions.length > 1, originalWordPrefixRange); }, _completeCommonPrefix: function() @@ -538,9 +544,20 @@ WebInspector.TextPrompt.prototype = { }, /** - * @param {Range=} originalPrefixRange + * @param {string} completionText + * @param {boolean=} isIntermediateSuggestion + */ + applySuggestion: function(completionText, isIntermediateSuggestion) + { + this._applySuggestion(completionText, isIntermediateSuggestion); + }, + + /** + * @param {string} completionText + * @param {boolean=} isIntermediateSuggestion + * @param {Range} originalPrefixRange */ - applySuggestion: function(completionText, isIntermediateSuggestion, originalPrefixRange) + _applySuggestion: function(completionText, isIntermediateSuggestion, originalPrefixRange) { var wordPrefixLength; if (originalPrefixRange) @@ -717,7 +734,7 @@ WebInspector.TextPrompt.prototype = { enterKeyPressed: function(event) { if (this.isSuggestBoxVisible()) - return this._suggestBox.enterKeyPressed(event); + return this._suggestBox.enterKeyPressed(); return false; }, @@ -725,7 +742,7 @@ WebInspector.TextPrompt.prototype = { upKeyPressed: function(event) { if (this.isSuggestBoxVisible()) - return this._suggestBox.upKeyPressed(event); + return this._suggestBox.upKeyPressed(); return false; }, @@ -733,7 +750,7 @@ WebInspector.TextPrompt.prototype = { downKeyPressed: function(event) { if (this.isSuggestBoxVisible()) - return this._suggestBox.downKeyPressed(event); + return this._suggestBox.downKeyPressed(); return false; }, @@ -741,7 +758,7 @@ WebInspector.TextPrompt.prototype = { pageUpKeyPressed: function(event) { if (this.isSuggestBoxVisible()) - return this._suggestBox.pageUpKeyPressed(event); + return this._suggestBox.pageUpKeyPressed(); return false; }, @@ -749,7 +766,7 @@ WebInspector.TextPrompt.prototype = { pageDownKeyPressed: function(event) { if (this.isSuggestBoxVisible()) - return this._suggestBox.pageDownKeyPressed(event); + return this._suggestBox.pageDownKeyPressed(); return false; }, @@ -926,329 +943,3 @@ WebInspector.TextPromptWithHistory.prototype = { __proto__: WebInspector.TextPrompt.prototype } -/** - * @constructor - */ -WebInspector.TextPrompt.SuggestBox = function(textPrompt, inputElement, className) -{ - this._textPrompt = textPrompt; - this._inputElement = inputElement; - this._length = 0; - this._selectedIndex = -1; - this._selectedElement = null; - this._boundOnScroll = this._onscrollresize.bind(this, true); - this._boundOnResize = this._onscrollresize.bind(this, false); - window.addEventListener("scroll", this._boundOnScroll, true); - window.addEventListener("resize", this._boundOnResize, true); - - this._bodyElement = inputElement.ownerDocument.body; - this._element = inputElement.ownerDocument.createElement("div"); - this._element.className = "suggest-box " + (className || ""); - this._element.addEventListener("mousedown", this._onboxmousedown.bind(this), true); - this.containerElement = this._element.createChild("div", "container"); - this.contentElement = this.containerElement.createChild("div", "content"); -} - -WebInspector.TextPrompt.SuggestBox.prototype = { - get visible() - { - return !!this._element.parentElement; - }, - - get hasSelection() - { - return !!this._selectedElement; - }, - - _onscrollresize: function(isScroll, event) - { - if (isScroll && this._element.isAncestor(event.target) || !this.visible) - return; - this._updateBoxPositionWithExistingAnchor(); - }, - - _updateBoxPositionWithExistingAnchor: function() - { - this._updateBoxPosition(this._anchorBox); - }, - - /** - * @param {AnchorBox} anchorBox - */ - _updateBoxPosition: function(anchorBox) - { - // Measure the content element box. - this.contentElement.style.display = "inline-block"; - document.body.appendChild(this.contentElement); - this.contentElement.positionAt(0, 0); - var contentWidth = this.contentElement.offsetWidth; - var contentHeight = this.contentElement.offsetHeight; - this.contentElement.style.display = "block"; - this.containerElement.appendChild(this.contentElement); - - // Lay out the suggest-box relative to the anchorBox. - this._anchorBox = anchorBox; - const spacer = 6; - - const suggestBoxPaddingX = 21; - var maxWidth = document.body.offsetWidth - anchorBox.x - spacer; - var width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX; - var paddedWidth = contentWidth + suggestBoxPaddingX; - var boxX = anchorBox.x; - if (width < paddedWidth) { - // Shift the suggest box to the left to accommodate the content without trimming to the BODY edge. - maxWidth = document.body.offsetWidth - spacer; - width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX; - boxX = document.body.offsetWidth - width; - } - - const suggestBoxPaddingY = 2; - var boxY; - var aboveHeight = anchorBox.y; - var underHeight = document.body.offsetHeight - anchorBox.y - anchorBox.height; - var maxHeight = Math.max(underHeight, aboveHeight) - spacer; - var height = Math.min(contentHeight, maxHeight - suggestBoxPaddingY) + suggestBoxPaddingY; - if (underHeight >= aboveHeight) { - // Locate the suggest box under the anchorBox. - boxY = anchorBox.y + anchorBox.height; - this._element.removeStyleClass("above-anchor"); - this._element.addStyleClass("under-anchor"); - } else { - // Locate the suggest box above the anchorBox. - boxY = anchorBox.y - height; - this._element.removeStyleClass("under-anchor"); - this._element.addStyleClass("above-anchor"); - } - - this._element.positionAt(boxX, boxY); - this._element.style.width = width + "px"; - this._element.style.height = height + "px"; - }, - - _onboxmousedown: function(event) - { - event.preventDefault(); - }, - - hide: function() - { - if (!this.visible) - return; - - this._element.parentElement.removeChild(this._element); - delete this._selectedElement; - }, - - removeFromElement: function() - { - window.removeEventListener("scroll", this._boundOnScroll, true); - window.removeEventListener("resize", this._boundOnResize, true); - this.hide(); - }, - - /** - * @param {string=} text - * @param {boolean=} isIntermediateSuggestion - */ - _applySuggestion: function(text, isIntermediateSuggestion) - { - if (!this.visible || !(text || this._selectedElement)) - return false; - - var suggestion = text || this._selectedElement.textContent; - if (!suggestion) - return false; - - this._textPrompt.applySuggestion(suggestion, isIntermediateSuggestion); - return true; - }, - - /** - * @param {string=} text - */ - acceptSuggestion: function(text) - { - var result = this._applySuggestion(text, false); - this.hide(); - if (!result) - return false; - - this._textPrompt.acceptSuggestion(); - - return true; - }, - - /** - * @param {number} shift - * @param {boolean=} isCircular - * @return {boolean} is changed - */ - _selectClosest: function(shift, isCircular) - { - if (!this._length) - return false; - - 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); - this._applySuggestion(undefined, true); - return true; - }, - - /** - * @param {AnchorBox} anchorBox - * @param {Array.=} completions - * @param {number=} selectedIndex - * @param {boolean=} canShowForSingleItem - */ - updateSuggestions: function(anchorBox, completions, selectedIndex, canShowForSingleItem) - { - if (this._suggestTimeout) { - clearTimeout(this._suggestTimeout); - delete this._suggestTimeout; - } - this._completionsReady(anchorBox, completions, selectedIndex, canShowForSingleItem); - }, - - _onItemMouseDown: function(text, event) - { - this.acceptSuggestion(text); - event.consume(true); - }, - - _createItemElement: function(prefix, text) - { - var element = document.createElement("div"); - element.className = "suggest-box-content-item source-code"; - element.tabIndex = -1; - if (prefix && prefix.length && !text.indexOf(prefix)) { - var prefixElement = element.createChild("span", "prefix"); - prefixElement.textContent = prefix; - var suffixElement = element.createChild("span", "suffix"); - suffixElement.textContent = text.substring(prefix.length); - } else { - var suffixElement = element.createChild("span", "suffix"); - suffixElement.textContent = text; - } - element.addEventListener("mousedown", this._onItemMouseDown.bind(this, text), false); - return element; - }, - - /** - * @param {Array.=} items - * @param {number=} selectedIndex - */ - _updateItems: function(items, selectedIndex) - { - this._length = items.length; - this.contentElement.removeChildren(); - - var userEnteredText = this._textPrompt._userEnteredText; - for (var i = 0; i < items.length; ++i) { - var item = items[i]; - var currentItemElement = this._createItemElement(userEnteredText, item); - this.contentElement.appendChild(currentItemElement); - } - - this._selectedElement = null; - if (typeof selectedIndex === "number") - this._selectItem(selectedIndex); - }, - - /** - * @param {number} index - */ - _selectItem: function(index) - { - if (this._selectedElement) - this._selectedElement.classList.remove("selected"); - - this._selectedIndex = index; - this._selectedElement = this.contentElement.children[index]; - this._selectedElement.classList.add("selected"); - - this._selectedElement.scrollIntoViewIfNeeded(false); - }, - - /** - * @param {Array.=} completions - * @param {boolean=} canShowForSingleItem - */ - _canShowBox: function(completions, canShowForSingleItem) - { - 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] !== this._textPrompt._userEnteredText; - }, - - _rememberRowCountPerViewport: function() - { - if (!this.contentElement.firstChild) - return; - - this._rowCountPerViewport = Math.floor(this.containerElement.offsetHeight / this.contentElement.firstChild.offsetHeight); - }, - - /** - * @param {AnchorBox} anchorBox - * @param {Array.=} completions - * @param {number=} selectedIndex - * @param {boolean=} canShowForSingleItem - */ - _completionsReady: function(anchorBox, completions, selectedIndex, canShowForSingleItem) - { - if (this._canShowBox(completions, canShowForSingleItem)) { - this._updateItems(completions, selectedIndex); - this._updateBoxPosition(anchorBox); - if (!this.visible) - this._bodyElement.appendChild(this._element); - this._rememberRowCountPerViewport(); - } else - this.hide(); - }, - - upKeyPressed: function(event) - { - return this._selectClosest(-1, true); - }, - - downKeyPressed: function(event) - { - return this._selectClosest(1, true); - }, - - pageUpKeyPressed: function(event) - { - return this._selectClosest(-this._rowCountPerViewport, false); - }, - - pageDownKeyPressed: function(event) - { - return this._selectClosest(this._rowCountPerViewport, false); - }, - - enterKeyPressed: function(event) - { - var hasSelectedItem = !!this._selectedElement; - this.acceptSuggestion(); - - // Report the event as non-handled if there is no selected item, - // to commit the input or handle it otherwise. - return hasSelectedItem; - }, - - tabKeyPressed: function(event) - { - return this.enterKeyPressed(event); - } -}