Backed out changeset 6dcc6fc612e4 (bug 914180) for it was intended for Aurora only.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 13 Sep 2013 14:53:00 -0400
changeset 160051 bfed29c24ac571c163cac349b24a15970497f7c9
parent 160050 7d0fc78efe598acfc40182c6f0664ec55561527a
child 160052 3de581c2760b6260e97be319ec7be384a48db84b
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs914180
milestone26.0a1
backs out6dcc6fc612e449c61fbd83f05d251fe174adbe00
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
Backed out changeset 6dcc6fc612e4 (bug 914180) for it was intended for Aurora only.
browser/base/content/tabbrowser.xml
browser/themes/osx/browser.css
toolkit/components/viewsource/content/viewSource.xul
toolkit/content/jar.mn
toolkit/content/widgets/findbar.css
toolkit/content/widgets/findbar.xml
toolkit/themes/linux/global/findBar.css
toolkit/themes/osx/global/findBar.css
toolkit/themes/windows/global/findBar.css
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -158,17 +158,18 @@
             aTab = this.selectedTab;
 
           if (aTab._findBar)
             return aTab._findBar;
 
           let findBar = document.createElementNS(this.namespaceURI, "findbar");
           let browser = this.getBrowserForTab(aTab);
           let browserContainer = this.getBrowserContainer(browser);
-          browserContainer.appendChild(findBar);
+          findBar.setAttribute("position", "top");
+          browserContainer.insertBefore(findBar, browserContainer.firstChild);
 
           // Force a style flush to ensure that our binding is attached.
           findBar.clientTop;
 
           findBar.browser = browser;
           findBar._findField.value = this._lastFindValue;
 
           aTab._findBar = findBar;
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -2154,17 +2154,17 @@ sidebarheader {
 sidebarheader > .tabs-closebutton > .toolbarbutton-text {
   display: none;
 }
 
 /* ----- CONTENT ----- */
 
 .browserContainer > findbar {
   background: @scopeBarBackground@;
-  border-top: @scopeBarSeparatorBorder@;
+  border-bottom: @scopeBarSeparatorBorder@;
   color: -moz-DialogText;
   text-shadow: none;
 }
 
 /* ----- THROBBER ----- */
 
 #navigator-throbber {
   width: 17px;
--- a/toolkit/components/viewsource/content/viewSource.xul
+++ b/toolkit/components/viewsource/content/viewSource.xul
@@ -202,19 +202,18 @@
           <menuitem type="checkbox" id="menu_highlightSyntax" command="cmd_highlightSyntax"
                     label="&menu_highlightSyntax.label;" accesskey="&menu_highlightSyntax.accesskey;"/>
         </menupopup>
       </menu>
     </menubar>  
   </toolbox>
 
   <vbox id="appcontent" flex="1">
-
+    <findbar id="FindToolbar" browserid="content" position="top"/>
     <browser id="content" type="content-primary" name="content" src="about:blank" flex="1"
              context="viewSourceContextMenu" showcaret="true" tooltip="aHTMLTooltip"/>
-    <findbar id="FindToolbar" browserid="content"/>
   </vbox> 
 
   <statusbar id="status-bar" class="chromeclass-status">
     <statusbarpanel id="statusbar-line-col" label="" flex="1"/>
   </statusbar>
 
 </window>
--- a/toolkit/content/jar.mn
+++ b/toolkit/content/jar.mn
@@ -57,16 +57,17 @@ toolkit.jar:
    content/global/bindings/checkbox.xml        (widgets/checkbox.xml)
    content/global/bindings/colorpicker.xml     (widgets/colorpicker.xml)
    content/global/bindings/datetimepicker.xml  (widgets/datetimepicker.xml)
 *+ content/global/bindings/dialog.xml          (widgets/dialog.xml)
    content/global/bindings/editor.xml          (widgets/editor.xml)
    content/global/bindings/expander.xml        (widgets/expander.xml)
 *  content/global/bindings/filefield.xml       (widgets/filefield.xml)
 *+ content/global/bindings/findbar.xml         (widgets/findbar.xml)
+   content/global/bindings/findbar.css         (widgets/findbar.css)
    content/global/bindings/general.xml         (widgets/general.xml)
    content/global/bindings/groupbox.xml        (widgets/groupbox.xml)
 *+ content/global/bindings/listbox.xml         (widgets/listbox.xml)
    content/global/bindings/menu.xml            (widgets/menu.xml)
    content/global/bindings/menulist.xml        (widgets/menulist.xml)
    content/global/bindings/notification.xml    (widgets/notification.xml)
    content/global/bindings/numberbox.xml       (widgets/numberbox.xml)
    content/global/bindings/popup.xml           (widgets/popup.xml)
new file mode 100644
--- /dev/null
+++ b/toolkit/content/widgets/findbar.css
@@ -0,0 +1,41 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+findbar {
+  transition-property: transform, opacity, visibility;
+  transition-duration: 120ms, 120ms, 0s;
+  transition-timing-function: ease-in-out, ease-in-out, linear;
+
+  /* The following positioning properties only take an effect during findbar
+   * transitions. The findbar binding sets position:absolute during that time
+   * on the findbar.
+   */
+  left: 0;
+  right: 0;
+  bottom: 0;
+}
+
+findbar[position="top"] {
+  top: 0;
+  bottom: auto;
+}
+
+findbar > hbox {
+  width: 100%;
+}
+
+findbar[hidden] {
+  /* Override display:none to make the transition work. */
+  display: -moz-box;
+  visibility: collapse;
+  opacity: 0;
+  transition-delay: 0s, 0s, 120ms;
+  transform: translateY(2em);
+}
+
+findbar[position="top"][hidden] {
+  transform: translateY(-2em);
+}
--- a/toolkit/content/widgets/findbar.xml
+++ b/toolkit/content/widgets/findbar.xml
@@ -168,16 +168,17 @@
         event.preventDefault();
       ]]></handler>
     </handlers>
   </binding>
 
   <binding id="findbar"
            extends="chrome://global/content/bindings/toolbar.xml#toolbar">
     <resources>
+      <stylesheet src="chrome://global/content/bindings/findbar.css"/>
       <stylesheet src="chrome://global/skin/findBar.css"/>
     </resources>
 
     <content hidden="true">
     <xul:hbox anonid="findbar-container" class="findbar-container" flex="1" align="center">
       <xul:hbox anonid="findbar-textbox-wrapper" align="stretch">
         <xul:textbox anonid="findbar-textbox"
                      class="findbar-textbox findbar-find-fast"
@@ -236,16 +237,18 @@
       <field name="_tmpOutlineOffset">"0"</field>
       <field name="_drawOutline">false</field>
       <field name="_editors">null</field>
       <field name="_stateListeners">null</field>
 
       <field name="_flashFindBar">0</field>
       <field name="_initialFlashFindBarCount">6</field>
 
+      <field name="_contentScrollOffset">0</field>
+
       <property name="_foundLink"
                 onget="return this._foundLinkRef.get();"
                 onset="this._foundLinkRef = Components.utils.getWeakReference(val); return val;"/>
       <property name="_foundEditable"
                 onget="return this._foundEditableRef.get();"
                 onset="this._foundEditableRef = Components.utils.getWeakReference(val); return val;"/>
       <property name="_currentWindow"
                 onget="return this._currentWindowRef.get();"
@@ -1153,18 +1156,40 @@
             this._caseSensitiveStr =
               stringsBundle.GetStringFromName("CaseSensitive");
           }
 
           this._findFailedString = null;
 
           this._updateFindUI();
           if (this.hidden) {
+            // Use position:absolute during the transition.
+            this.style.position = "absolute";
+            this.parentNode.style.position = "relative";
+
+            // Apparently a flush is necessary after setting position:relative
+            // on our parentNode, otherwise setting hidden to false won't
+            // animate the transform change.
+            this.getBoundingClientRect();
+
             this.hidden = false;
 
+            // Set a height on the findbar that's at least as much as the
+            // current height, but guaranteed to be an integer number of
+            // screen pixels.
+            // This way, reapplying position:static on the findbar after the
+            // fade in animation won't cause the browser contents to wiggle.
+            let [chromeOffset, contentScrollOffset] = this._findOffsets();
+            this.style.height = chromeOffset + "px";
+            this._contentScrollOffset = contentScrollOffset;
+
+            // Wait for the findbar appearance animation to end before
+            // changing the browser size.
+            this.addEventListener("transitionend", this);
+
             this._updateStatusUI(this.nsITypeAheadFind.FIND_FOUND);
 
             let event = document.createEvent("Events");
             event.initEvent("findbaropen", true, false);
             this.dispatchEvent(event);
 
             return true;
           }
@@ -1197,16 +1222,26 @@
                     this._currentWindow.focus();
                 else
                   this.browser.contentWindow.focus();
               }
             }
           }
 
           this.hidden = true;
+
+          this.addEventListener("transitionend", this);
+
+          // Revert browser scroll shift + findbar static positioning.
+          if (this.getAttribute("position") == "top" &&
+              this.style.position != "absolute") {
+            this._browser.contentWindow.scrollBy(0, -this._contentScrollOffset);
+          }
+          this.style.position = "absolute";
+
           var fastFind = this.browser.fastFind;
           fastFind.setSelectionModeAndRepaint
             (this.nsISelectionController.SELECTION_ON);
           this._setFoundLink(null);
           this._cancelTimers();
           this._foundEditable = null;
           this._currentWindow = null;
 
@@ -1495,20 +1530,68 @@
             case "mouseup":
               if (!this.hidden && this._findMode != this.FIND_NORMAL)
                 this.close();
 
               break;
             case "keypress":
               this._onBrowserKeypress(aEvent);
               break;
+            case "transitionend":
+              if (aEvent.target == this &&
+                  aEvent.propertyName == "transform") {
+                this.removeEventListener("transitionend", this);
+
+                // Change the browser size in such a way that the region that's
+                // overlapped by the findbar can be scrolled to, but try to
+                // avoid a visual shift of the browser contents.
+                this.style.removeProperty("position");
+                if (this.getAttribute("position") == "top" &&
+                    !this.hidden) {
+                  this._browser.contentWindow.scrollBy(0, this._contentScrollOffset);
+                }
+
+                // We'd like to remove position:relative from this.parentNode,
+                // but that unfortunately causes unnecessary repainting.
+              }
+              break;
           }
         ]]></body>
       </method>
 
+      <method name="_screenPixelsPerCSSPixel">
+        <parameter name="aWindow"/>
+        <body><![CDATA[
+          return aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                        .getInterface(Components.interfaces.nsIDOMWindowUtils)
+                        .screenPixelsPerCSSPixel;
+        ]]></body>
+      </method>
+
+      <!--
+        - Find two numbers, one in chrome CSS pixels and one in integer
+        - content CSS pixels, that are about the same as (but not less than)
+        - the height of the findbar. These two numbers hopefully map to the
+        - same number of integer screen pixels.
+        - We want to avoid shifting of the page even when chrome and content
+        - have different zoom factors, and scrollBy() only accepts integers.
+        -->
+      <method name="_findOffsets">
+        <body><![CDATA[
+          let chromeFactor = this._screenPixelsPerCSSPixel(window);
+          let contentFactor = this._screenPixelsPerCSSPixel(this._browser.contentWindow);
+
+          let findbarHeightScreen = this.getBoundingClientRect().height * chromeFactor;
+          let contentScrollOffset = Math.ceil(findbarHeightScreen / contentFactor);
+          let estimatedScrollOffsetInScreenPixels = Math.round(contentScrollOffset * contentFactor);
+          let chromeOffset = estimatedScrollOffsetInScreenPixels / chromeFactor;
+          return [chromeOffset, contentScrollOffset];
+        ]]></body>
+      </method>
+
       <method name="_enableFindButtons">
         <parameter name="aEnable"/>
         <body><![CDATA[
           this.getElement("find-next").disabled =
             this.getElement("find-previous").disabled = !aEnable;
         ]]></body>
       </method>
 
--- a/toolkit/themes/linux/global/findBar.css
+++ b/toolkit/themes/linux/global/findBar.css
@@ -4,28 +4,21 @@
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
 findbar {
   padding: 4px 8px;
   border-top: 2px solid;
   -moz-border-top-colors: ThreeDShadow ThreeDHighlight;
   min-width: 1px;
-  transition-property: margin-bottom, opacity, visibility;
-  transition-duration: 150ms, 150ms, 0s;
-  transition-timing-function: ease-in-out, ease-in-out, linear;
 }
 
-findbar[hidden] {
-  /* Override display:none to make the transition work. */
-  display: -moz-box;
-  visibility: collapse;
-  margin-bottom: -1em;
-  opacity: 0;
-  transition-delay: 0s, 0s, 150ms;
+findbar[position="top"] {
+  border-top-style: none;
+  border-bottom: 1px solid ThreeDShadow;
 }
 
 .findbar-closebutton {
   -moz-margin-start: 4px;
   list-style-image: url("moz-icon://stock/gtk-close?size=menu");
 }
 
 /* Search field */
--- a/toolkit/themes/osx/global/findBar.css
+++ b/toolkit/themes/osx/global/findBar.css
@@ -5,28 +5,21 @@
 %include shared.inc
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
 findbar {
   background: @scopeBarBackground@;
   border-top: @scopeBarSeparatorBorder@;
   min-width: 1px;
   padding: 4px 2px;
-  transition-property: margin-bottom, opacity, visibility;
-  transition-duration: 150ms, 150ms, 0s;
-  transition-timing-function: ease-in-out, ease-in-out, linear;
 }
 
-findbar[hidden] {
-  /* Override display:none to make the transition work. */
-  display: -moz-box;
-  visibility: collapse;
-  margin-bottom: -1em;
-  opacity: 0;
-  transition-delay: 0s, 0s, 150ms;
+findbar[position="top"] {
+  border-top: none;
+  border-bottom: @scopeBarSeparatorBorder@;
 }
 
 findbar:-moz-lwtheme {
   -moz-appearance: none;
   background: none;
   border-style: none;
 }
 
--- a/toolkit/themes/windows/global/findBar.css
+++ b/toolkit/themes/windows/global/findBar.css
@@ -6,28 +6,21 @@
 
 findbar {
   padding: 4px 8px;
   box-shadow: 0 1px 1px rgba(0,0,0,.1) inset;
   background-image: linear-gradient(rgba(0,0,0,.15) 1px, rgba(255,255,255,.15) 1px);
   background-size: 100% 2px;
   background-repeat: no-repeat;
   min-width: 1px;
-  transition-property: margin-bottom, opacity, visibility;
-  transition-duration: 150ms, 150ms, 0s;
-  transition-timing-function: ease-in-out, ease-in-out, linear;
 }
 
-findbar[hidden] {
-  /* Override display:none to make the transition work. */
-  display: -moz-box;
-  visibility: collapse;
-  margin-bottom: -1em;
-  opacity: 0;
-  transition-delay: 0s, 0s, 150ms;
+findbar[position="top"] {
+  background-image: none;
+  box-shadow: 0 -1px 0 rgba(0,0,0,.1) inset;
 }
 
 .findbar-closebutton {
   -moz-margin-start: 4px;
   border: none;
   padding: 0;
   list-style-image: url("chrome://global/skin/icons/close.png");
   -moz-appearance: none;