Bug 638552 Form Assistant suggestions should not reach into side pane [r=mbrubeck]
authorVivien Nicolas <21@vingtetun.org>
Fri, 04 Mar 2011 12:56:51 +0100
changeset 67468 fa30dde17d49b6b6b35f376c4932898aa287af20
parent 67467 5f90d630749b654ba5df9e7e3202bc03f99e2b29
child 67469 c15cd15090b71c1163036b42c5068d7cc2d4f571
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmbrubeck
bugs638552
Bug 638552 Form Assistant suggestions should not reach into side pane [r=mbrubeck]
mobile/chrome/content/common-ui.js
--- a/mobile/chrome/content/common-ui.js
+++ b/mobile/chrome/content/common-ui.js
@@ -713,18 +713,24 @@ var FormHelperUI = {
         // operation but not doing a zoom operation since this happen on both
         // manual dblClick and navigation between the fields by clicking the
         // buttons
         this._container.style.visibility = "hidden";
 
       case "AnimatedZoomBegin":
         // Changing the hidden attribute here create bugs with the scrollbox
         // arrows because the binding will miss some underflow events
-        if (this._hasSuggestions)
+        if (this._hasSuggestions) {
+          // Because the suggestions container could be big in terms of width
+          // (but never bigger than the screen) it's position needs to be
+          // resetted to the left to ensure it does not push the content to
+          // the right and misplaced sidebars as a result
+          this._suggestionsContainer.left = 0;
           this._suggestionsContainer.style.visibility = "hidden";
+        }
         break;
 
       case "PanFinished":
         this._container.style.visibility = "visible";
 
       case "AnimatedZoomEnd":
         if (this._hasSuggestions) {
           this._suggestionsContainer.style.visibility = "visible";
@@ -857,31 +863,33 @@ var FormHelperUI = {
   _updateSuggestionsFor: function _formHelperUpdateAutocompleteFor(aElement) {
     let suggestions = this._getAutocompleteSuggestions(aElement);
     if (!suggestions.length) {
       this._resetSuggestions();
       return;
     }
     // Keeps the suggestions element hidden while is it not positionned to the
     // correct place
-    this._suggestionsContainer.style.visibility = "hidden";
-    this._suggestionsContainer.hidden = false;
+    let suggestionsContainer = this._suggestionsContainer;
+    suggestionsContainer.style.visibility = "hidden";
+    suggestionsContainer.hidden = false;
+    suggestionsContainer.left = 0;
 
     // the scrollX/scrollY position can change because of the animated zoom so
     // delay the suggestions positioning
     if (AnimatedZoom.isZooming()) {
       let self = this;
       window.addEventListener("AnimatedZoomEnd", function() {
         window.removeEventListener("AnimatedZoomEnd", arguments.callee, true);
           self._updateSuggestionsFor(aElement);
       }, true);
       return;
     }
 
-    let container = this._suggestionsContainer.firstChild;
+    let container = suggestionsContainer.firstChild;
     while (container.hasChildNodes())
       container.removeChild(container.lastChild);
 
     let fragment = document.createDocumentFragment();
     for (let i = 0; i < suggestions.length; i++) {
       let value = suggestions[i];
       let button = document.createElement("label");
       button.setAttribute("value", value);
@@ -926,52 +934,57 @@ var FormHelperUI = {
   /**
    * This method positionned the list of suggestions on the screen using
    * a 'virtual' element as referrer that match the real content element
    * This method called element.getBoundingClientRect() many times and can be
    * expensive, do not called it too many times.
    */
   _ensureSuggestionsVisible: function _formHelperEnsureSuggestionsVisible() {
     let container = this._suggestionsContainer;
-    container.firstChild.style.maxWidth = (window.innerWidth * 0.75) + "px";
+
+    // Calculate the maximum size of the arrowpanel by allowing it to live only
+    // on the visible browser area
+    let [leftVis, rightVis, leftW, rightW] = Browser.computeSidebarVisibility();
+    let leftOffset = leftVis * leftW;
+    let rightOffset = rightVis * rightW;
+    let visibleAreaWidth = window.innerWidth - leftOffset - rightOffset;
+    container.firstChild.style.maxWidth = (visibleAreaWidth * 0.75) + "px";
 
     let browser = getBrowser();
     let rect = this._currentElementRect.clone().scale(browser.scale, browser.scale);
     let scroll = browser.getRootView().getPosition();
 
     // The sidebars scroll needs to be taken into account, otherwise the arrows
     // can be misplaced if the sidebars are open
-    let [leftVis, rightVis, leftW, rightW] = Browser.computeSidebarVisibility();
-    let leftOffset = leftVis * leftW;
-    let rightOffset = rightVis * rightW;
     let topOffset = (BrowserUI.toolbarH - Browser.getScrollboxPosition(Browser.pageScrollboxScroller).y);
     let virtualContentRect = {
       width: rect.width,
       height: rect.height,
       left: Math.ceil(rect.left - scroll.x + leftOffset - rightOffset),
       right: Math.floor(rect.left + rect.width - scroll.x + leftOffset - rightOffset),
       top: Math.ceil(rect.top - scroll.y + topOffset),
       bottom: Math.floor(rect.top + rect.height - scroll.y + topOffset)
     };
 
     // Translate the virtual rect inside the bounds of the viewable area if it
     // overflow
-    if (virtualContentRect.left + virtualContentRect.width > window.innerWidth) {
-      let offsetX = window.innerWidth - (virtualContentRect.left + virtualContentRect.width);
+    if (virtualContentRect.left + virtualContentRect.width > visibleAreaWidth) {
+      let offsetX = visibleAreaWidth - (virtualContentRect.left + virtualContentRect.width);
       virtualContentRect.width += offsetX;
       virtualContentRect.right -= offsetX;
     }
 
     // If the suggestions are out of view there is no need to display it
     let browserRect = Rect.fromRect(browser.getBoundingClientRect());
     if (BrowserUI.isToolbarLocked()) {
       // If the toolbar is locked, it can appear over the field in such a way
       // that the field is hidden
-      browserRect = new Rect(browserRect.left + leftOffset - rightOffset, browserRect.top + BrowserUI.toolbarH,
-                             browserRect.width + leftOffset - rightOffset, browserRect.height - BrowserUI.toolbarH);
+      let toolbarH = BrowserUI.toolbarH;
+      browserRect = new Rect(leftOffset - rightOffset, Math.max(0, browserRect.top - toolbarH) + toolbarH,
+                             browserRect.width + leftOffset - rightOffset, browserRect.height - toolbarH);
     }
 
     if (browserRect.intersect(Rect.fromRect(virtualContentRect)).isEmpty()) {
       container.style.visibility = "hidden";
       return;
     }
 
     // Adding rect.height to the top moves the arrowbox below the virtual field