Bug 1356765 - Avoid flushing layout when showing menus with accel shortcuts. r?Gijs draft
authorMike Conley <mconley@mozilla.com>
Thu, 08 Mar 2018 17:57:33 -0500
changeset 765065 d6b353def57e896d2d31c4f26b72399c9afc3ece
parent 764992 cb460424b72c2b0383fd9023b0e489b88bd19c84
push id101955
push usermconley@mozilla.com
push dateThu, 08 Mar 2018 22:58:21 +0000
reviewersGijs
bugs1356765
milestone60.0a1
Bug 1356765 - Avoid flushing layout when showing menus with accel shortcuts. r?Gijs MozReview-Commit-ID: KZYmbX7kwUm
toolkit/content/widgets/popup.xml
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -265,30 +265,39 @@
       <field name="scrollBox" readonly="true">
         document.getAnonymousElementByAttribute(this, "class", "popup-internal-box");
       </field>
     </implementation>
 
     <handlers>
       <handler event="popupshowing" phase="target">
         <![CDATA[
-          var array = [];
-          var width = 0;
-          for (var menuitem = this.firstChild; menuitem; menuitem = menuitem.nextSibling) {
+          let array = [];
+          let maxWidth = 0;
+          let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                          .getInterface(Ci.nsIDOMWindowUtils);
+          for (let menuitem = this.firstChild; menuitem; menuitem = menuitem.nextSibling) {
             if (menuitem.localName == "menuitem" && menuitem.hasAttribute("acceltext")) {
-              var accel = document.getAnonymousElementByAttribute(menuitem, "anonid", "accel");
+              let accel = document.getAnonymousElementByAttribute(menuitem, "anonid", "accel");
               if (accel && accel.boxObject) {
                 array.push(accel);
-                if (accel.boxObject.width > width)
-                  width = accel.boxObject.width;
+                // The popup is showing, which means it has already been laid
+                // out, so these bounds should still be accurate.
+                let itemWidth = dwu.getBoundsWithoutFlushing(accel);
+                if (itemWidth > maxWidth) {
+                  maxWidth = itemWidth
+                }
               }
             }
           }
-          for (var i = 0; i < array.length; i++)
-            array[i].width = width;
+          window.requestAnimationFrame(() => {
+            for (let i = 0; i < array.length; i++) {
+              array[i].width = width;
+            }
+          });
         ]]>
       </handler>
     </handlers>
   </binding>
 
   <binding id="panel"
            extends="chrome://global/content/bindings/popup.xml#popup-base">
     <implementation>