Bug 798212 - social flyout may be horizontally misaligned after resizing. r=jaws
authorMark Hammond <mhammond@skippinet.com.au>
Mon, 08 Oct 2012 17:14:55 +1100
changeset 109629 24cf4069004206568643a94521ef722484225c78
parent 109628 ea218a65affb3b692791656ffc6156b02f885ba4
child 109630 d9e0325428315899a68e297bbc2ee856b2e3543b
push id23636
push usergsharp@mozilla.com
push dateMon, 08 Oct 2012 08:08:19 +0000
treeherdermozilla-central@24cf40690042 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs798212
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 798212 - social flyout may be horizontally misaligned after resizing. r=jaws
browser/base/content/browser-social.js
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -1,14 +1,14 @@
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 // The minimum sizes for the auto-resize panel code.
-const PANEL_MIN_HEIGHT = 300;
+const PANEL_MIN_HEIGHT = 100;
 const PANEL_MIN_WIDTH = 330;
 
 let SocialUI = {
   // Called on delayed startup to initialize UI
   init: function SocialUI_init() {
     Services.obs.addObserver(this, "social:pref-changed", false);
     Services.obs.addObserver(this, "social:ambient-notification-changed", false);
     Services.obs.addObserver(this, "social:profile-changed", false);
@@ -198,50 +198,58 @@ let SocialChatBar = {
       this.chatbar.openChat(aProvider, aURL, aCallback, aMode);
   },
   update: function() {
     if (!this.canShow)
       this.chatbar.removeAll();
   }
 }
 
-function sizeSocialPanelToContent(iframe) {
+function sizeSocialPanelToContent(panel, iframe) {
   // FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here?
   let doc = iframe.contentDocument;
   if (!doc || !doc.body) {
     return;
   }
   let body = doc.body;
   // offsetHeight/Width don't include margins, so account for that.
   let cs = doc.defaultView.getComputedStyle(body);
   let computedHeight = parseInt(cs.marginTop) + body.offsetHeight + parseInt(cs.marginBottom);
   let height = Math.max(computedHeight, PANEL_MIN_HEIGHT);
-  iframe.style.height = height + "px";
   let computedWidth = parseInt(cs.marginLeft) + body.offsetWidth + parseInt(cs.marginRight);
   let width = Math.max(computedWidth, PANEL_MIN_WIDTH);
+  let wDiff = width - iframe.getBoundingClientRect().width;
+  // A panel resize will move the right margin - if that is where the anchor
+  // arrow is, the arrow will be mis-aligned from the anchor.  So we move the
+  // popup to compensate for that.  See bug 799014.
+  if (wDiff !== 0 && panel.getAttribute("side") == "right") {
+    let box = panel.boxObject;
+    panel.moveTo(box.screenX - wDiff, box.screenY);
+  }
+  iframe.style.height = height + "px";
   iframe.style.width = width + "px";
 }
 
 function DynamicResizeWatcher() {
   this._mutationObserver = null;
 }
 
 DynamicResizeWatcher.prototype = {
-  start: function DynamicResizeWatcher_start(iframe) {
+  start: function DynamicResizeWatcher_start(panel, iframe) {
     this.stop(); // just in case...
     let doc = iframe.contentDocument;
     this._mutationObserver = new iframe.contentWindow.MutationObserver(function(mutations) {
-      sizeSocialPanelToContent(iframe);
+      sizeSocialPanelToContent(panel, iframe);
     });
     // Observe anything that causes the size to change.
     let config = {attributes: true, characterData: true, childList: true, subtree: true};
     this._mutationObserver.observe(doc, config);
     // and since this may be setup after the load event has fired we do an
     // initial resize now.
-    sizeSocialPanelToContent(iframe);
+    sizeSocialPanelToContent(panel, iframe);
   },
   stop: function DynamicResizeWatcher_stop() {
     if (this._mutationObserver) {
       try {
         this._mutationObserver.disconnect();
       } catch (ex) {
         // may get "TypeError: can't access dead object" which seems strange,
         // but doesn't seem to indicate a real problem, so ignore it...
@@ -304,29 +312,30 @@ let SocialFlyout = {
     let panel = this.panel;
     panel.hidePopup();
     if (!panel.firstChild)
       return
     panel.removeChild(panel.firstChild);
   },
 
   onShown: function(aEvent) {
-    let iframe = this.panel.firstChild;
+    let panel = this.panel;
+    let iframe = panel.firstChild;
     this._dynamicResizer = new DynamicResizeWatcher();
     iframe.docShell.isActive = true;
     iframe.docShell.isAppTab = true;
     if (iframe.contentDocument.readyState == "complete") {
-      this._dynamicResizer.start(iframe);
+      this._dynamicResizer.start(panel, iframe);
       this.dispatchPanelEvent("socialFrameShow");
     } else {
       // first time load, wait for load and dispatch after load
       iframe.addEventListener("load", function panelBrowserOnload(e) {
         iframe.removeEventListener("load", panelBrowserOnload, true);
         setTimeout(function() {
-          SocialFlyout._dynamicResizer.start(iframe);
+          SocialFlyout._dynamicResizer.start(panel, iframe);
           SocialFlyout.dispatchPanelEvent("socialFrameShow");
         }, 0);
       }, true);
     }
   },
 
   onHidden: function(aEvent) {
     this._dynamicResizer.stop();
@@ -361,17 +370,17 @@ let SocialFlyout = {
     else if (aCallback) {
       try {
         aCallback(iframe.contentWindow);
       } catch(e) {
         Cu.reportError(e);
       }
     }
 
-    sizeSocialPanelToContent(iframe);
+    sizeSocialPanelToContent(panel, iframe);
     let anchor = document.getElementById("social-sidebar-browser");
     if (panel.state == "open") {
       // this is painful - there is no way to say "move to a new anchor offset",
       // only "move to new screen pos".  So we remember the last yOffset,
       // calculate the adjustment needed to the new yOffset, then calc the
       // screen Y position.
       let yAdjust = yOffset - this.yOffset;
       let box = panel.boxObject;
@@ -787,23 +796,23 @@ var SocialToolbar = {
     });
 
     panel.addEventListener("popupshown", function onpopupshown() {
       panel.removeEventListener("popupshown", onpopupshown);
       aToolbarButtonBox.setAttribute("open", "true");
       notificationFrame.docShell.isActive = true;
       notificationFrame.docShell.isAppTab = true;
       if (notificationFrame.contentDocument.readyState == "complete") {
-        dynamicResizer.start(notificationFrame);
+        dynamicResizer.start(panel, notificationFrame);
         dispatchPanelEvent("socialFrameShow");
       } else {
         // first time load, wait for load and dispatch after load
         notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
           notificationFrame.removeEventListener("load", panelBrowserOnload, true);
-          dynamicResizer.start(notificationFrame);
+          dynamicResizer.start(panel, notificationFrame);
           setTimeout(function() {
             dispatchPanelEvent("socialFrameShow");
           }, 0);
         }, true);
       }
     });
 
     let imageId = aToolbarButtonBox.getAttribute("id") + "-image";