merge mozilla-central to fx-team. r=merge a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sat, 13 Aug 2016 13:53:42 +0200
changeset 400466 d33489bb88626f512cf7aa58d631f6875aa2d696
parent 400465 4cf5aa807f27376197743b62eff2b2c3c2891b44 (current diff)
parent 400444 6e191a55c3d23e83e6a2e72e4e80c1dc21516493 (diff)
child 400467 a81e69525dfc44b8eb0dd3d78a52a12d3c4f59dd
child 400469 f944299e1f561477b82861fdd70435b0dd8c4ac3
child 400477 e135af145a2eb0fb6b8a5f9a35cf21655e19ad7c
child 400481 c278206471e5f23287184de317827f3938b82621
child 400680 d3eaba631b4f3aca55e0edb037776c13a319934d
child 400735 d7218029d78d41639f23c32ebb8f75cd5a4173f5
child 400943 a0fe0bbac7ac2cbe5ee7e396ea07f3730b011868
child 400960 b6811515de2d44a68bc748671f75531e437ce624
child 400974 48fdf882c65343b887ebf539b2fe4be131c65d91
child 405252 980b7d618e13839ddcb64d7dcc3a75e9040dccce
push id26149
push userjwein@mozilla.com
push dateSat, 13 Aug 2016 20:25:08 +0000
reviewersmerge, merge
milestone51.0a1
merge mozilla-central to fx-team. r=merge a=merge
browser/base/content/browser.js
browser/components/customizableui/test/browser_no_mutationrecords_during_panel_opening.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -7191,18 +7191,16 @@ var gIdentityHandler = {
     // Now open the popup, anchored off the primary chrome element
     this._identityPopup.openPopup(this._identityIcon, "bottomcenter topleft");
   },
 
   onPopupShown(event) {
     if (event.target == this._identityPopup) {
       window.addEventListener("focus", this, true);
     }
-    this._identityPopupMultiView._mainView.style.height =
-      this._identityPopup.getBoundingClientRect().height + "px";
   },
 
   onPopupHidden(event) {
     if (event.target == this._identityPopup) {
       window.removeEventListener("focus", this, true);
       this._identityBox.removeAttribute("open");
     }
   },
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -147,17 +147,17 @@ const PanelUI = {
         let anchor;
         if (!aEvent ||
             aEvent.type == "command") {
           anchor = this.menuButton;
         } else {
           anchor = aEvent.target;
         }
 
-        this.panel.addEventListener("popupshown", function onPopupShown(event) {
+        this.panel.addEventListener("popupshown", function onPopupShown() {
           this.removeEventListener("popupshown", onPopupShown);
           resolve();
         });
 
         let iconAnchor =
           document.getAnonymousElementByAttribute(anchor, "class",
                                                   "toolbarbutton-icon");
         this.panel.openPopup(iconAnchor || anchor);
--- a/browser/components/customizableui/content/panelUI.xml
+++ b/browser/components/customizableui/content/panelUI.xml
@@ -53,26 +53,43 @@
       <field name="_panel" readonly="true">
         this.parentNode;
       </field>
 
       <field name="_currentSubView">null</field>
       <field name="_anchorElement">null</field>
       <field name="_mainViewHeight">0</field>
       <field name="_subViewObserver">null</field>
-      <field name="__transitioning">true</field>
+      <field name="__transitioning">false</field>
+      <field name="_ignoreMutations">false</field>
 
       <property name="showingSubView" readonly="true"
                 onget="return this._viewStack.getAttribute('viewtype') == 'subview'"/>
       <property name="_mainViewId" onget="return this.getAttribute('mainViewId');" onset="this.setAttribute('mainViewId', val); return val;"/>
       <property name="_mainView" readonly="true"
                 onget="return this._mainViewId ? document.getElementById(this._mainViewId) : null;"/>
       <property name="showingSubViewAsMainView" readonly="true"
                 onget="return this.getAttribute('mainViewIsSubView') == 'true'"/>
 
+      <property name="ignoreMutations">
+        <getter>
+          return this._ignoreMutations;
+        </getter>
+        <setter><![CDATA[
+          this._ignoreMutations = val;
+          if (!val && this._panel.state == "open") {
+            if (this.showingSubView) {
+              this._syncContainerWithSubView();
+            } else {
+              this._syncContainerWithMainView();
+            }
+          }
+        ]]></setter>
+      </property>
+
       <property name="_transitioning">
         <getter>
           return this.__transitioning;
         </getter>
         <setter><![CDATA[
           this.__transitioning = val;
           if (val) {
             this.setAttribute("transitioning", "true");
@@ -201,20 +218,17 @@
       </method>
 
       <method name="_setViewContainerHeight">
         <parameter name="aHeight"/>
         <body><![CDATA[
           let container = this._viewContainer;
           this._transitioning = true;
 
-          let onTransitionEnd = (event) => {
-            if (event.propertyName != "transform") {
-              return;
-            }
+          let onTransitionEnd = () => {
             container.removeEventListener("transitionend", onTransitionEnd);
             this._transitioning = false;
           };
 
           container.addEventListener("transitionend", onTransitionEnd);
           container.style.height = `${aHeight}px`;
         ]]></body>
       </method>
@@ -277,43 +291,35 @@
                 if (this.showingSubView) {
                   setTimeout(this._syncContainerWithSubView.bind(this), 0);
                 } else if (!this.transitioning) {
                   setTimeout(this._syncContainerWithMainView.bind(this), 0);
                 }
               }
               break;
             case "popupshowing":
+              this.setAttribute("panelopen", "true");
               // Bug 941196 - The panel can get taller when opening a subview. Disabling
               // autoPositioning means that the panel won't jump around if an opened
               // subview causes the panel to exceed the dimensions of the screen in the
               // direction that the panel originally opened in. This property resets
               // every time the popup closes, which is why we have to set it each time.
               this._panel.autoPosition = false;
               this._syncContainerWithMainView();
 
               this._mainViewObserver.observe(this._mainView, {
                 attributes: true,
                 characterData: true,
                 childList: true,
                 subtree: true
               });
 
-              let onTransitionEnd = (event) => {
-                if (event.propertyName != "transform") {
-                  return;
-                }
-                let panel = event.target;
-                panel.removeEventListener("tranitionend", onTransitionEnd);
-                // Needed in case the panel is closed before the transition ends.
-                if (panel.state == "open") {
-                  this.setAttribute("panelopen", "true");
-                }
-              };
-              this._panel.addEventListener("transitionend", onTransitionEnd);
+              break;
+            case "popupshown":
+              this._setMaxHeight();
               break;
             case "popuphidden":
               this.removeAttribute("panelopen");
               this._mainView.style.removeProperty("height");
               this.showMainView();
               this._mainViewObserver.disconnect();
               break;
           }
@@ -327,19 +333,32 @@
       </method>
 
       <method name="_shouldSetHeight">
         <body><![CDATA[
           return this.getAttribute("nosubviews") != "true";
         ]]></body>
       </method>
 
+      <method name="_setMaxHeight">
+        <body><![CDATA[
+          if (!this._shouldSetHeight())
+            return;
+
+          // Ignore the mutation that'll fire when we set the height of
+          // the main view.
+          this.ignoreMutations = true;
+          this._mainView.style.height =
+            this.getBoundingClientRect().height + "px";
+          this.ignoreMutations = false;
+        ]]></body>
+      </method>
       <method name="_adjustContainerHeight">
         <body><![CDATA[
-          if (!this.showingSubView && !this._transitioning) {
+          if (!this.ignoreMutations && !this.showingSubView && !this._transitioning) {
             let height;
             if (this.showingSubViewAsMainView) {
               height = this._heightOfSubview(this._mainView);
             } else {
               height = this._mainView.scrollHeight;
             }
             this._viewContainer.style.height = height + "px";
           }
@@ -347,17 +366,17 @@
       </method>
       <method name="_syncContainerWithSubView">
         <body><![CDATA[
           // Check that this panel is still alive:
           if (!this._panel || !this._panel.parentNode) {
             return;
           }
 
-          if (this.showingSubView) {
+          if (!this.ignoreMutations && this.showingSubView) {
             let newHeight = this._heightOfSubview(this._currentSubView, this._subViews);
             this._viewContainer.style.height = newHeight + "px";
           }
         ]]></body>
       </method>
       <method name="_syncContainerWithMainView">
         <body><![CDATA[
           // Check that this panel is still alive:
--- a/browser/components/customizableui/test/browser.ini
+++ b/browser/components/customizableui/test/browser.ini
@@ -144,13 +144,12 @@ skip-if = os == "linux" # crashing on Li
 [browser_1087303_button_fullscreen.js]
 tags = fullscreen
 skip-if = os == "mac"
 [browser_1087303_button_preferences.js]
 [browser_1089591_still_customizable_after_reset.js]
 [browser_1096763_seen_widgets_post_reset.js]
 [browser_1161838_inserted_new_default_buttons.js]
 [browser_bootstrapped_custom_toolbar.js]
-[browser_check_tooltips_in_navbar.js]
 [browser_customizemode_contextmenu_menubuttonstate.js]
-[browser_no_mutationrecords_during_panel_opening.js]
 [browser_panel_toggle.js]
 [browser_switch_to_customize_mode.js]
+[browser_check_tooltips_in_navbar.js]
deleted file mode 100644
--- a/browser/components/customizableui/test/browser_no_mutationrecords_during_panel_opening.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-/**
- * Test that we don't get unexpected mutations during the opening of the
- * browser menu.
- */
-
-add_task(function* test_setup() {
-  yield resetCustomization();
-  yield PanelUI.show();
-  let hiddenPromise = promisePanelHidden(window);
-  PanelUI.hide();
-  yield hiddenPromise;
-});
-
-add_task(function* no_mutation_events_during_opening() {
-  let panel = PanelUI.panel;
-  yield PanelUI.ensureReady();
-
-  let failures = 0;
-  let observer = new MutationObserver(function(mutations) {
-    for (let mutation of mutations) {
-      if (mutation.target.localName == "panel" &&
-          mutation.type == "attributes" &&
-          mutation.attributeName == "animate") {
-        // This mutation is allowed because it triggers the CSS transition.
-        continue;
-      }
-
-      if (mutation.type == "attributes" &&
-          mutation.attributeName == "panelopen") {
-        // This mutation is allowed because it is set after the panel has
-        // finished the transition.
-        continue;
-      }
-
-      let newValue = null;
-      if (mutation.type == "attributes") {
-        newValue = mutation.target.getAttribute(mutation.attributeName);
-      } else if (mutation.type == "characterData") {
-        newValue = mutation.target.textContent;
-      }
-
-      if (AppConstants.isPlatformAndVersionAtMost("win", "6.1") &&
-          mutation.target.className == "panel-arrowbox" &&
-          mutation.attributeName == "style" &&
-          newValue.startsWith("transform:")) {
-        // Windows 7 and earlier has an alignment offset on the arrowbox.
-        // This is allowed here as it is no longer used on newer platforms.
-        continue;
-      }
-
-      if (newValue == mutation.oldValue) {
-        // Mutations records are observed even when the new and old value are
-        // identical. This is unlikely to invalidate the panel, so ignore these.
-        continue;
-      }
-
-      let nodeIdentifier = `${mutation.target.localName}#${mutation.target.id}.${mutation.target.className};`;
-      ok(false, `Observed: ${mutation.type}; ${nodeIdentifier} ${mutation.attributeName}; oldValue: ${mutation.oldValue}; newValue: ${newValue}`);
-      failures++;
-    }
-  });
-  observer.observe(panel, {
-    childList: true,
-    attributes: true,
-    characterData: true,
-    subtree: true,
-    attributeOldValue: true,
-    characterDataOldValue: true,
-  });
-  let shownPromise = promisePanelShown(window);
-  PanelUI.show();
-  yield shownPromise;
-  observer.disconnect();
-
-  is(failures, 0, "There should be no unexpected mutation events during opening of the panel");
-});
-
-add_task(function* cleanup() {
-  let hiddenPromise = promisePanelHidden(window);
-  PanelUI.hide();
-  yield hiddenPromise;
-});
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_popup_resize.js
+++ b/browser/components/extensions/test/browser/browser_ext_browserAction_popup_resize.js
@@ -170,33 +170,27 @@ function* testPopupSize(standardsMode, b
 
   let {panel} = browserWin.PanelUI;
   let origPanelRect = panel.getBoundingClientRect();
 
   // Check that the panel is still positioned as expected.
   let checkPanelPosition = () => {
     is(panel.getAttribute("side"), arrowSide, "Panel arrow is positioned as expected");
 
-    function isGreaterThanOrWithinPixelRoundingError(a, b, message) {
-      let result = a + 1 >= b;
-      ok(result, `${a} should be greater than or within one pixel of ${b}: ${message}`);
-    }
-
     let panelRect = panel.getBoundingClientRect();
     if (arrowSide == "top") {
-      isGreaterThanOrWithinPixelRoundingError(panelRect.top, origPanelRect.top, "Panel has not moved downwards");
-      isGreaterThanOrWithinPixelRoundingError(panelRect.bottom, origPanelRect.bottom, "Panel has not shrunk from original size");
+      ok(panelRect.top, origPanelRect.top, "Panel has not moved downwards");
+      ok(panelRect.bottom >= origPanelRect.bottom, `Panel has not shrunk from original size (${panelRect.bottom} >= ${origPanelRect.bottom})`);
 
       let screenBottom = browserWin.screen.availTop + win.screen.availHeight;
       let panelBottom = browserWin.mozInnerScreenY + panelRect.bottom;
       ok(panelBottom <= screenBottom, `Bottom of popup should be on-screen. (${panelBottom} <= ${screenBottom})`);
     } else {
-      isGreaterThanOrWithinPixelRoundingError(panelRect.bottom, origPanelRect.bottom, "Panel has not moved upwards");
-      // The arguments here are reversed compared to the above calls due to the coordinate system.
-      isGreaterThanOrWithinPixelRoundingError(origPanelRect.top, panelRect.top, "Panel has not shrunk from original size");
+      ok(panelRect.bottom, origPanelRect.bottom, "Panel has not moved upwards");
+      ok(panelRect.top <= origPanelRect.top, `Panel has not shrunk from original size (${panelRect.top} <= ${origPanelRect.top})`);
 
       let panelTop = browserWin.mozInnerScreenY + panelRect.top;
       ok(panelTop >= browserWin.screen.availTop, `Top of popup should be on-screen. (${panelTop} >= ${browserWin.screen.availTop})`);
     }
   };
 
 
   let isStandards = win.document.compatMode != "BackCompat";
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -420,19 +420,17 @@
         if (position.indexOf("start_") == 0 || position.indexOf("end_") == 0) {
           container.orient = "horizontal";
           arrowbox.orient = "vertical";
           if (position.indexOf("_after") > 0) {
             arrowbox.pack = "end";
           } else {
             arrowbox.pack = "start";
           }
-          if (offset != "0") {
-            arrowbox.style.transform = "translate(0, " + -offset + "px)";
-          }
+          arrowbox.style.transform = "translate(0, " + -offset + "px)";
 
           // The assigned side stays the same regardless of direction.
           var isRTL = (window.getComputedStyle(this).direction == "rtl");
 
           if (position.indexOf("start_") == 0) {
             container.dir = "reverse";
             this.setAttribute("side", isRTL ? "left" : "right");
           }
@@ -444,19 +442,17 @@
         else if (position.indexOf("before_") == 0 || position.indexOf("after_") == 0) {
           container.orient = "";
           arrowbox.orient = "";
           if (position.indexOf("_end") > 0) {
             arrowbox.pack = "end";
           } else {
             arrowbox.pack = "start";
           }
-          if (offset != "0") {
-            arrowbox.style.transform = "translate(" + -offset + "px, 0)";
-          }
+          arrowbox.style.transform = "translate(" + -offset + "px, 0)";
 
           if (position.indexOf("before_") == 0) {
             container.dir = "reverse";
             this.setAttribute("side", "bottom");
           }
           else {
             container.dir = "";
             this.setAttribute("side", "top");