Bug 1358792 - Fix uninterruptible reflow at adjustSiteIconStart. r=mak draft
authorPaolo Amadini <paolo.mozmail@amadzone.org>
Mon, 21 Aug 2017 15:16:44 +0100
changeset 649913 a2d140d2906dba0858554c4cd7b9e97f05474518
parent 649622 7dddbd85047c6dc73ddbe1e423cd643a217845b3
child 727235 6c1bc715fe4ceb4bc97b93c10d580c684c3da6dd
push id75200
push userpaolo.mozmail@amadzone.org
push dateMon, 21 Aug 2017 14:17:22 +0000
reviewersmak
bugs1358792
milestone57.0a1
Bug 1358792 - Fix uninterruptible reflow at adjustSiteIconStart. r=mak This adds a spacer element before the type icon so we don't have to compute its initial margin. MozReview-Commit-ID: 7dJ38Iwistn
browser/base/content/test/performance/browser_urlbar_search_reflows.js
toolkit/content/widgets/autocomplete.xml
--- a/browser/base/content/test/performance/browser_urlbar_search_reflows.js
+++ b/browser/base/content/test/performance/browser_urlbar_search_reflows.js
@@ -33,38 +33,16 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
       "openPopup@chrome://global/content/bindings/autocomplete.xml",
       "set_popupOpen@chrome://global/content/bindings/autocomplete.xml"
     ],
     times: 1, // This number should only ever go down - never up.
   },
 
   {
     stack: [
-      "adjustSiteIconStart@chrome://global/content/bindings/autocomplete.xml",
-      "set_siteIconStart@chrome://global/content/bindings/autocomplete.xml",
-      "_openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
-      "openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
-      "openPopup@chrome://global/content/bindings/autocomplete.xml",
-      "set_popupOpen@chrome://global/content/bindings/autocomplete.xml",
-    ],
-  },
-
-  {
-    stack: [
-      "adjustSiteIconStart@chrome://global/content/bindings/autocomplete.xml",
-      "_reuseAcItem@chrome://global/content/bindings/autocomplete.xml",
-      "_appendCurrentResult@chrome://global/content/bindings/autocomplete.xml",
-      "_invalidate@chrome://global/content/bindings/autocomplete.xml",
-      "invalidate@chrome://global/content/bindings/autocomplete.xml",
-    ],
-    times: 9, // This number should only ever go down - never up.
-  },
-
-  {
-    stack: [
       "adjustHeight@chrome://global/content/bindings/autocomplete.xml",
       "onxblpopupshown@chrome://global/content/bindings/autocomplete.xml"
     ],
     times: 5, // This number should only ever go down - never up.
   },
 
   {
     stack: [
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -1493,16 +1493,17 @@ extends="chrome://global/content/binding
       </handler>
     </handlers>
   </binding>
 
   <binding id="autocomplete-richlistitem-insecure-field" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-richlistitem">
     <content align="center"
              onoverflow="this._onOverflow();"
              onunderflow="this._onUnderflow();">
+      <xul:spacer anonid="type-icon-spacer"/>
       <xul:image anonid="type-icon"
                  class="ac-type-icon"
                  xbl:inherits="selected,current,type"/>
       <xul:image anonid="site-icon"
                  class="ac-site-icon"
                  xbl:inherits="src=image,selected,type"/>
       <xul:vbox class="ac-title"
                 align="left"
@@ -1590,16 +1591,17 @@ extends="chrome://global/content/binding
     </implementation>
   </binding>
 
   <binding id="autocomplete-richlistitem" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
 
     <content align="center"
              onoverflow="this._onOverflow();"
              onunderflow="this._onUnderflow();">
+      <xul:spacer anonid="type-icon-spacer"/>
       <xul:image anonid="type-icon"
                  class="ac-type-icon"
                  xbl:inherits="selected,current,type"/>
       <xul:image anonid="site-icon"
                  class="ac-site-icon"
                  xbl:inherits="src=image,selected,type"/>
       <xul:hbox class="ac-title"
                 align="center"
@@ -1644,16 +1646,19 @@ extends="chrome://global/content/binding
                            xbl:inherits="selected"/>
         </xul:description>
       </xul:hbox>
     </content>
 
     <implementation implements="nsIDOMXULSelectControlItemElement">
       <constructor>
         <![CDATA[
+          this._typeIconSpacer = document.getAnonymousElementByAttribute(
+            this, "anonid", "type-icon-spacer"
+          );
           this._typeIcon = document.getAnonymousElementByAttribute(
             this, "anonid", "type-icon"
           );
           this._siteIcon = document.getAnonymousElementByAttribute(
             this, "anonid", "site-icon"
           );
           this._titleText = document.getAnonymousElementByAttribute(
             this, "anonid", "title-text"
@@ -2370,35 +2375,35 @@ extends="chrome://global/content/binding
                   the window.  Pass undefined to reset the icon's position to
                   whatever is specified in CSS.
            @return True if the icon's position changed, false if not. -->
       <method name="adjustSiteIconStart">
         <parameter name="newStart"/>
         <body>
           <![CDATA[
           if (typeof(newStart) != "number") {
-            this._typeIcon.style.removeProperty("margin-inline-start");
+            this._typeIconSpacer.style.removeProperty("width");
             return true;
           }
+
           let utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
                             .getInterface(Ci.nsIDOMWindowUtils);
           let rect = utils.getBoundsWithoutFlushing(this._siteIcon);
 
           let dir = this.getAttribute("dir");
-          let delta = dir == "rtl" ? rect.right - newStart
-                                   : newStart - rect.left;
-          let px = this._typeIcon.style.marginInlineStart;
-          if (!px) {
-            // Allow margin-inline-start not to be specified in CSS initially.
-            let style = window.getComputedStyle(this._typeIcon);
-            px = dir == "rtl" ? style.marginRight : style.marginLeft;
+          let delta = dir == "rtl" ? rect.right - Math.round(newStart)
+                                   : Math.round(newStart) - rect.left;
+          if (delta) {
+            let currentSpacerWidth = this._typeIconSpacer.style.width || "0px";
+            this._typeIconSpacer.style.width =
+              (parseInt(currentSpacerWidth, 10) + delta) + "px";
+            return true;
           }
-          let typeIconStart = Number(px.substr(0, px.length - 2));
-          this._typeIcon.style.marginInlineStart = (typeIconStart + delta) + "px";
-          return delta > 0;
+
+          return false;
           ]]>
         </body>
       </method>
 
       <!-- This method truncates the displayed strings as necessary. -->
       <method name="_handleOverflow">
         <body><![CDATA[
           let itemRect = this.parentNode.getBoundingClientRect();