From e366563d7bd5a83830e4b245bbb2ac8c83dfcb88 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Tue, 16 Jul 2013 11:57:20 +0200 Subject: [PATCH] Bug 893446 - Try to avoid moving the page contents when the find bar appears. r=dao --- toolkit/content/jar.mn | 1 + toolkit/content/widgets/findbar.css | 41 +++++++++++ toolkit/content/widgets/findbar.xml | 83 +++++++++++++++++++++++ toolkit/themes/linux/global/findBar.css | 18 ----- toolkit/themes/osx/global/findBar.css | 18 ----- toolkit/themes/windows/global/findBar.css | 18 ----- 6 files changed, 125 insertions(+), 54 deletions(-) create mode 100644 toolkit/content/widgets/findbar.css diff --git a/toolkit/content/jar.mn b/toolkit/content/jar.mn index 9e9bb1cfd81..5c011ed6ac7 100644 --- a/toolkit/content/jar.mn +++ b/toolkit/content/jar.mn @@ -62,6 +62,7 @@ toolkit.jar: 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) diff --git a/toolkit/content/widgets/findbar.css b/toolkit/content/widgets/findbar.css new file mode 100644 index 00000000000..de083ee3396 --- /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); +} diff --git a/toolkit/content/widgets/findbar.xml b/toolkit/content/widgets/findbar.xml index 8f5965dd1b0..c8e4c8f36ab 100644 --- a/toolkit/content/widgets/findbar.xml +++ b/toolkit/content/widgets/findbar.xml @@ -173,6 +173,7 @@ + @@ -241,6 +242,8 @@ 0 6 + 0 + @@ -1134,8 +1137,30 @@ 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"); @@ -1178,6 +1203,16 @@ } 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); @@ -1479,10 +1514,58 @@ 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; } ]]> + + + + + + + + + +