Title: [99867] trunk/Source/WebCore
Revision
99867
Author
[email protected]
Date
2011-11-10 09:07:02 -0800 (Thu, 10 Nov 2011)

Log Message

Web Inspector: [SuggestBox] Correctly position the box under the first character of the suggestion prefix.
https://bugs.webkit.org/show_bug.cgi?id=72022

Reviewed by Pavel Feldman.

On any suggest box position update (updateSuggestions invocation) an anchor is created at the beginning
of the user-entered word, and its box is ultimately passed into _updateBoxPosition to be used as the
actual anchor box (instead of the input element box).

* inspector/front-end/TextPrompt.js:
(WebInspector.TextPrompt.prototype._boxForAnchorAtStart):
(WebInspector.TextPrompt.prototype._completionsReady):
(WebInspector.TextPrompt.SuggestBox):
(WebInspector.TextPrompt.SuggestBox.prototype._onscrollresize):
(WebInspector.TextPrompt.SuggestBox.prototype._updateBoxPositionWithExistingAnchor):
(WebInspector.TextPrompt.SuggestBox.prototype._updateBoxPosition):
(WebInspector.TextPrompt.SuggestBox.prototype.updateSuggestions):
(WebInspector.TextPrompt.SuggestBox.prototype._completionsReady):
* inspector/front-end/utilities.js:
(AnchorBox):
(Element.prototype.offsetRelativeToWindow):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (99866 => 99867)


--- trunk/Source/WebCore/ChangeLog	2011-11-10 17:05:18 UTC (rev 99866)
+++ trunk/Source/WebCore/ChangeLog	2011-11-10 17:07:02 UTC (rev 99867)
@@ -1,3 +1,27 @@
+2011-11-10  Alexander Pavlov  <[email protected]>
+
+        Web Inspector: [SuggestBox] Correctly position the box under the first character of the suggestion prefix.
+        https://bugs.webkit.org/show_bug.cgi?id=72022
+
+        Reviewed by Pavel Feldman.
+
+        On any suggest box position update (updateSuggestions invocation) an anchor is created at the beginning
+        of the user-entered word, and its box is ultimately passed into _updateBoxPosition to be used as the
+        actual anchor box (instead of the input element box).
+
+        * inspector/front-end/TextPrompt.js:
+        (WebInspector.TextPrompt.prototype._boxForAnchorAtStart):
+        (WebInspector.TextPrompt.prototype._completionsReady):
+        (WebInspector.TextPrompt.SuggestBox):
+        (WebInspector.TextPrompt.SuggestBox.prototype._onscrollresize):
+        (WebInspector.TextPrompt.SuggestBox.prototype._updateBoxPositionWithExistingAnchor):
+        (WebInspector.TextPrompt.SuggestBox.prototype._updateBoxPosition):
+        (WebInspector.TextPrompt.SuggestBox.prototype.updateSuggestions):
+        (WebInspector.TextPrompt.SuggestBox.prototype._completionsReady):
+        * inspector/front-end/utilities.js:
+        (AnchorBox):
+        (Element.prototype.offsetRelativeToWindow):
+
 2011-11-10  Ryuan Choi  <[email protected]>
 
         [CMAKE] Refactoring CMakeLists${PORT}.txt to Platform${PORT}.cmake

Modified: trunk/Source/WebCore/inspector/front-end/TextPrompt.js (99866 => 99867)


--- trunk/Source/WebCore/inspector/front-end/TextPrompt.js	2011-11-10 17:05:18 UTC (rev 99866)
+++ trunk/Source/WebCore/inspector/front-end/TextPrompt.js	2011-11-10 17:07:02 UTC (rev 99867)
@@ -377,6 +377,19 @@
         this._loadCompletions(wordPrefixRange, force, this._completionsReady.bind(this, selection, auto, wordPrefixRange, reverse));
     },
 
+    _boxForAnchorAtStart: function(selection, textRange)
+    {
+        var rangeCopy = selection.getRangeAt(0).cloneRange();
+        var anchorElement = document.createElement("span");
+        anchorElement.textContent = "\u200B";
+        textRange.insertNode(anchorElement);
+        var box = anchorElement.boxInWindow(window, this._suggestBox._parentElement);
+        anchorElement.parentElement.removeChild(anchorElement);
+        selection.removeAllRanges();
+        selection.addRange(rangeCopy);
+        return box;
+    },
+
     /**
      * @param {Array.<string>=} completions
      */
@@ -401,7 +414,7 @@
         this._userEnteredText = fullWordRange.toString();
 
         if (this._suggestBox) {
-            this._suggestBox.updateSuggestions(completions);
+            this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selection, fullWordRange), completions);
             return; // Do nothing, the suggest box is driving us.
         }
 
@@ -830,8 +843,6 @@
     this._element.addEventListener("mousedown", this._onboxmousedown.bind(this), true);
     this.containerElement = this._element.createChild("div", "container");
     this.contentElement = this.containerElement.createChild("div", "content");
-
-    this._updateBoxPosition();
 }
 
 WebInspector.TextPrompt.SuggestBox.prototype = {
@@ -847,13 +858,21 @@
 
     _onscrollresize: function(isScroll, event)
     {
-        if (isScroll && this._element.isAncestor(event.target))
+        if (isScroll && this._element.isAncestor(event.target) || !this.visible)
             return;
-        this._updateBoxPosition();
+        this._updateBoxPositionWithExistingAnchor();
     },
 
-    _updateBoxPosition: function()
+    _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);
@@ -864,28 +883,39 @@
         this.containerElement.appendChild(this.contentElement);
 
         // Lay out the suggest-box relative to the anchorBox.
-        const anchorBox = this._inputElement.boxInWindow(window, this._parentElement);
+        this._anchorBox = anchorBox;
         const suggestBoxPaddingX = 21;
         const suggestBoxPaddingY = 2;
         const spacer = 6;
         const minHeight = 25;
-        const maxWidth = document.body.offsetWidth - anchorBox.x - spacer;
-        const width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
+        var maxWidth = document.body.offsetWidth - anchorBox.x - spacer;
+        var width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
 
         var maxHeight = document.body.offsetHeight - anchorBox.y - anchorBox.height - spacer;
+        var paddedWidth = contentWidth + suggestBoxPaddingX;
         var paddedHeight = contentHeight + suggestBoxPaddingY;
         var height = Math.min(paddedHeight, maxHeight);
+        var boxX = anchorBox.x;
+        var boxY;
         if (height >= minHeight || height === paddedHeight) {
             // Locate the suggest box under the anchorBox.
-            this._element.positionAt(anchorBox.x, anchorBox.y + anchorBox.height);
+            boxY = anchorBox.y + anchorBox.height;
             this._element.removeStyleClass("above-anchor");
         } else {
             // Locate the suggest box above the anchorBox.
             maxHeight = anchorBox.y - spacer;
             height = Math.min(contentHeight, maxHeight - suggestBoxPaddingY) + suggestBoxPaddingY;
-            this._element.positionAt(anchorBox.x, anchorBox.y - height);
+            boxY = anchorBox.y - height;
             this._element.addStyleClass("above-anchor");
         }
+
+        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;
+        }
+        this._element.positionAt(boxX, boxY);
         this._element.style.width = width + "px";
         this._element.style.height = height + "px";
     },
@@ -974,24 +1004,16 @@
     },
 
     /**
+     * @param {AnchorBox} anchorBox
      * @param {Array.<string>=} completions
      */
-    updateSuggestionsSoon: function(completions)
+    updateSuggestions: function(anchorBox, completions)
     {
-        if (!this._suggestTimeout)
-            this._suggestTimeout = setTimeout(this.updateSuggestions.bind(this, completions), 10);
-    },
-
-    /**
-     * @param {Array.<string>=} completions
-     */
-    updateSuggestions: function(completions)
-    {
         if (this._suggestTimeout) {
             clearTimeout(this._suggestTimeout);
             delete this._suggestTimeout;
         }
-        this._completionsReady(completions);
+        this._completionsReady(anchorBox, completions);
     },
 
     _onItemMouseDown: function(text, event)
@@ -1054,9 +1076,10 @@
     },
 
     /**
+     * @param {AnchorBox} anchorBox
      * @param {Array.<string>=} completions
      */
-    _completionsReady: function(completions)
+    _completionsReady: function(anchorBox, completions)
     {
         if (!completions || !completions.length) {
             this.hide()
@@ -1064,7 +1087,7 @@
         }
 
         this._updateItems(completions);
-        this._updateBoxPosition();
+        this._updateBoxPosition(anchorBox);
         if (this.contentElement.children.length && (this.contentElement.children.length > 1 || this.contentElement.children[0].textContent.length !== this._textPrompt._userEnteredText.length)) {
             // Will not be shown if a sole suggestion is equal to the user input.
             this._element.addStyleClass("visible");

Modified: trunk/Source/WebCore/inspector/front-end/utilities.js (99866 => 99867)


--- trunk/Source/WebCore/inspector/front-end/utilities.js	2011-11-10 17:05:18 UTC (rev 99866)
+++ trunk/Source/WebCore/inspector/front-end/utilities.js	2011-11-10 17:07:02 UTC (rev 99867)
@@ -29,8 +29,6 @@
  * http://ejohn.org/files/jsdiff.js (released under the MIT license).
  */
 
-function setupPrototypeUtilities() {
-
 Function.prototype.bind = function(thisObject)
 {
     var func = this;
@@ -283,9 +281,27 @@
     return total;
 }
 
+/**
+ * @constructor
+ * @param {number=} x
+ * @param {number=} y
+ * @param {number=} width
+ * @param {number=} height
+ */
+function AnchorBox(x, y, width, height)
+{
+    this.x = x || 0;
+    this.y = y || 0;
+    this.width = width || 0;
+    this.height = height || 0;
+}
+
+/**
+ * @return {AnchorBox}
+ */
 Element.prototype.offsetRelativeToWindow = function(targetWindow)
 {
-    var elementOffset = {x: 0, y: 0};
+    var elementOffset = new AnchorBox();
     var curElement = this;
     var curWindow = this.ownerDocument.defaultView;
     while (curWindow && curElement) {
@@ -301,6 +317,9 @@
     return elementOffset;
 }
 
+/**
+ * @return {AnchorBox}
+ */
 Element.prototype.boxInWindow = function(targetWindow, relativeParent)
 {
     targetWindow = targetWindow || this.ownerDocument.defaultView;
@@ -853,10 +872,6 @@
     return { formattedResult: result, unusedSubstitutions: unusedSubstitutions };
 }
 
-} // setupPrototypeUtilities()
-
-setupPrototypeUtilities();
-
 function isEnterKey(event) {
     // Check if in IME.
     return event.keyCode !== 229 && event.keyIdentifier === "Enter";
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to