Bug 940632 - Fixup findbar scroll positioning code and remove some text zoom cruft. r=mbrubeck

This commit is contained in:
Jim Mathies 2013-11-20 12:45:43 -06:00
parent c5cdf6d9d6
commit 4a188c217e
11 changed files with 50 additions and 270 deletions

View File

@ -1,124 +0,0 @@
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
/* 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/. */
/**
* Responsible for zooming in to a given view rectangle
*/
const AnimatedZoom = {
startScale: null,
/** Starts an animated zoom to zoomRect. */
animateTo: function(aZoomRect) {
if (!aZoomRect)
return;
this.zoomTo = aZoomRect.clone();
if (this.animationDuration === undefined)
this.animationDuration = Services.prefs.getIntPref("browser.ui.zoom.animationDuration");
Browser.forceChromeReflow();
this.start();
// Check if zooming animations were occuring before.
if (!this.zoomRect) {
this.updateTo(this.zoomFrom);
mozRequestAnimationFrame(this);
let event = document.createEvent("Events");
event.initEvent("AnimatedZoomBegin", true, true);
window.dispatchEvent(event);
}
},
start: function start() {
this.tab = Browser.selectedTab;
this.browser = this.tab.browser;
this.bcr = this.browser.getBoundingClientRect();
this.zoomFrom = this.zoomRect || this.getStartRect();
this.startScale = this.browser.scale;
this.beginTime = mozAnimationStartTime;
},
/** Get the visible rect, in device pixels relative to the content origin. */
getStartRect: function getStartRect() {
let browser = this.browser;
let scroll = browser.getRootView().getPosition();
return new Rect(scroll.x, scroll.y, this.bcr.width, this.bcr.height);
},
/** Update the visible rect, in device pixels relative to the content origin. */
updateTo: function(nextRect) {
// Stop animating if the browser has been destroyed
if (typeof this.browser.fuzzyZoom !== "function") {
this.reset();
return false;
}
let zoomRatio = this.bcr.width / nextRect.width;
let scale = this.startScale * zoomRatio;
let scrollX = nextRect.left * zoomRatio;
let scrollY = nextRect.top * zoomRatio;
this.browser.fuzzyZoom(scale, scrollX, scrollY);
this.zoomRect = nextRect;
return true;
},
/** Stop animation, zoom to point, and clean up. */
finish: function() {
if (!this.updateTo(this.zoomTo || this.zoomRect))
return;
// Check whether the zoom limits have changed since the animation started.
let browser = this.browser;
let finalScale = this.tab.clampZoomLevel(browser.scale);
if (browser.scale != finalScale)
browser.scale = finalScale; // scale= calls finishFuzzyZoom.
else
browser.finishFuzzyZoom();
this.reset();
browser._updateCSSViewport();
},
reset: function reset() {
this.beginTime = null;
this.zoomTo = null;
this.zoomFrom = null;
this.zoomRect = null;
this.startScale = null;
let event = document.createEvent("Events");
event.initEvent("AnimatedZoomEnd", true, true);
window.dispatchEvent(event);
},
isZooming: function isZooming() {
return this.beginTime != null;
},
sample: function(aTimeStamp) {
try {
let tdiff = aTimeStamp - this.beginTime;
let counter = tdiff / this.animationDuration;
if (counter < 1) {
// update browser to interpolated rectangle
let rect = this.zoomFrom.blend(this.zoomTo, counter);
if (this.updateTo(rect))
mozRequestAnimationFrame(this);
} else {
// last cycle already rendered final scaled image, now clean up
this.finish();
}
} catch(e) {
this.finish();
throw e;
}
}
};

View File

@ -99,7 +99,7 @@ var ContentAreaObserver = {
Services.obs.addObserver(this, "metro_softkeyboard_hidden", false);
// setup initial values for browser form repositioning
this._shiftBrowserDeck(0);
this.shiftBrowserDeck(0);
// initialize our custom width and height styles
this._initStyles();
@ -226,7 +226,7 @@ var ContentAreaObserver = {
this.updateViewableArea();
if (!aNewState) {
this._shiftBrowserDeck(0);
this.shiftBrowserDeck(0);
return;
}
@ -241,10 +241,10 @@ var ContentAreaObserver = {
_onRepositionResponse: function _onRepositionResponse(aJsonMsg) {
if (!aJsonMsg.reposition || !this.isKeyboardOpened) {
this._shiftBrowserDeck(0);
this.shiftBrowserDeck(0);
return;
}
this._shiftBrowserDeck(aJsonMsg.raiseContent);
this.shiftBrowserDeck(aJsonMsg.raiseContent);
},
observe: function cao_observe(aSubject, aTopic, aData) {
@ -300,7 +300,7 @@ var ContentAreaObserver = {
}
},
_shiftBrowserDeck: function _shiftBrowserDeck(aAmount) {
shiftBrowserDeck: function (aAmount) {
if (aAmount == 0) {
this._deckTransitioning = false;
this._dispatchWindowEvent("KeyboardChanged", this.isKeyboardOpened);

View File

@ -760,24 +760,6 @@
this.docShellIsActive = this._active;
]]></setter>
</property>
<!-- Transform the viewport without updating the displayport. -->
<method name="fuzzyZoom">
<parameter name="scale"/>
<parameter name="x"/>
<parameter name="y"/>
<body><![CDATA[
this.getRootView().scrollTo(x, y);
]]></body>
</method>
<!-- After fuzzy zoom, sync the displayport with the new viewport. -->
<method name="finishFuzzyZoom">
<body><![CDATA[
return;
]]></body>
</method>
</implementation>
</binding>
@ -1150,34 +1132,6 @@
]]>
</field>
<!-- Transform the viewport without updating the displayport. -->
<method name="fuzzyZoom">
<parameter name="scale"/>
<parameter name="x"/>
<parameter name="y"/>
<body><![CDATA[
let rootView = this.getRootView();
rootView._setScale(scale);
if ("_contentView" in rootView)
rootView._contentView.scrollTo(x, y);
]]></body>
</method>
<!-- After fuzzy zoom, sync the displayport with the new viewport. -->
<method name="finishFuzzyZoom">
<body><![CDATA[
let view = this.getRootView();
// ensure that we are scrolled within the page's viewable area
view.scrollBy(0,0);
view._updateCacheViewport();
let event = document.createEvent("Events");
event.initEvent("ZoomChanged", true, false);
this.dispatchEvent(event);
]]></body>
</method>
<!-- The ratio of CSS pixels to device pixels. -->
<property name="scale">
<getter><![CDATA[
@ -1189,7 +1143,6 @@
let rootView = this.getRootView();
rootView._setScale(val);
this.finishFuzzyZoom();
return val;
]]></setter>

View File

@ -102,7 +102,6 @@ let ScriptContexts = {};
["SelectionHelperUI", "chrome://browser/content/helperui/SelectionHelperUI.js"],
["SelectionPrototype", "chrome://browser/content/library/SelectionPrototype.js"],
["ChromeSelectionHandler", "chrome://browser/content/helperui/ChromeSelectionHandler.js"],
["AnimatedZoom", "chrome://browser/content/AnimatedZoom.js"],
["CommandUpdater", "chrome://browser/content/commandUtil.js"],
["ContextCommands", "chrome://browser/content/ContextCommands.js"],
["Bookmarks", "chrome://browser/content/bookmarks.js"],
@ -152,9 +151,3 @@ XPCOMUtils.defineLazyGetter(this, "ContentAreaUtils", function() {
Services.scriptloader.loadSubScript("chrome://global/content/contentAreaUtils.js", ContentAreaUtils);
return ContentAreaUtils;
});
XPCOMUtils.defineLazyGetter(this, "ZoomManager", function() {
let sandbox = {};
Services.scriptloader.loadSubScript("chrome://global/content/viewZoomOverlay.js", sandbox);
return sandbox.ZoomManager;
});

View File

@ -781,33 +781,6 @@ var Browser = {
Bookmarks.isURIBookmarked(uri, callback);
},
/** Rect should be in browser coordinates. */
_getZoomLevelForRect: function _getZoomLevelForRect(rect) {
const margin = 15;
return this.selectedTab.clampZoomLevel(ContentAreaObserver.width / (rect.width + margin * 2));
},
/**
* Find a good zoom rectangle for point that is specified in browser coordinates.
* @return Rect in viewport coordinates
*/
_getZoomRectForPoint: function _getZoomRectForPoint(x, y, zoomLevel) {
let browser = getBrowser();
x = x * browser.scale;
y = y * browser.scale;
zoomLevel = Math.min(ZoomManager.MAX, zoomLevel);
let oldScale = browser.scale;
let zoomRatio = zoomLevel / oldScale;
let browserRect = browser.getBoundingClientRect();
let newVisW = browserRect.width / zoomRatio, newVisH = browserRect.height / zoomRatio;
let result = new Rect(x - newVisW / 2, y - newVisH / 2, newVisW, newVisH);
// Make sure rectangle doesn't poke out of viewport
return result.translateInside(new Rect(0, 0, browser.contentDocumentWidth * oldScale,
browser.contentDocumentHeight * oldScale));
},
/**
* Convenience function for getting the scrollbox position off of a
* scrollBoxObject interface. Returns the actual values instead of the
@ -1496,14 +1469,6 @@ Tab.prototype = {
}
},
/**
* Takes a scale and restricts it based on this tab's zoom limits.
* @param aScale The original scale.
*/
clampZoomLevel: function clampZoomLevel(aScale) {
return Util.clamp(aScale, ZoomManager.MIN, ZoomManager.MAX);
},
updateThumbnail: function updateThumbnail() {
PageThumbs.captureToCanvas(this.browser.contentWindow, this._chromeTab.thumbnailCanvas);
},

View File

@ -36,7 +36,7 @@ var FindHandler = {
}
if (findResult == Ci.nsITypeAheadFind.FIND_NOTFOUND) {
sendAsyncMessage("FindAssist:Show", { rect: null , result: findResult });
sendAsyncMessage("FindAssist:Show", { rect: null, result: findResult });
return;
}
@ -57,30 +57,28 @@ var FindHandler = {
}
}
let scroll = ContentScroll.getScrollOffset(content);
// Return the bounding selection rect in content coordinates
// including the scroll offset.
let offset = ContentScroll.getScrollOffset(content);
for (let frame = this._fastFind.currentWindow; frame != content; frame = frame.parent) {
let rect = frame.frameElement.getBoundingClientRect();
let left = frame.getComputedStyle(frame.frameElement, "").borderLeftWidth;
let top = frame.getComputedStyle(frame.frameElement, "").borderTopWidth;
scroll.add(rect.left + parseInt(left), rect.top + parseInt(top));
offset.add(rect.left + parseInt(left), rect.top + parseInt(top));
}
let rangeRect = selection.getRangeAt(0).getBoundingClientRect();
let rect = new Rect(scroll.x + rangeRect.left, scroll.y + rangeRect.top, rangeRect.width, rangeRect.height);
let aNewViewHeight = content.innerHeight - Services.metro.keyboardHeight;
let position = Util.centerElementInView(aNewViewHeight, rangeRect);
if (position !== undefined) {
sendAsyncMessage("Content:RepositionInfoResponse", {
reposition: true,
raiseContent: position,
});
}
let rect = new Rect(offset.x + rangeRect.left, offset.y + rangeRect.top,
rangeRect.width, rangeRect.height);
// Ensure the potential "scroll" event fired during a search as already fired
let timer = new Util.Timeout(function() {
sendAsyncMessage("FindAssist:Show", { rect: rect.isEmpty() ? null: rect , result: findResult });
sendAsyncMessage("FindAssist:Show", {
rect: rect.isEmpty() ? null: rect,
contentHeight: content.document.documentElement.scrollHeight,
result: findResult
});
});
timer.once(0);
}

View File

@ -66,8 +66,10 @@ var FindHelperUI = {
case "FindAssist:Show":
ContextUI.dismiss();
this.status = json.result;
if (json.rect)
this._zoom(Rect.fromRect(json.rect));
// null rect implies nothing found
if (json.rect) {
this._zoom(Rect.fromRect(json.rect), json.contentHeight);
}
break;
case "FindAssist:Hide":
@ -118,9 +120,7 @@ var FindHelperUI = {
let findbar = this._container;
setTimeout(() => {
Elements.browsers.setAttribute("findbar", true);
findbar.show();
this.search(this._textbox.value);
this._textbox.select();
this._textbox.focus();
@ -136,6 +136,8 @@ var FindHelperUI = {
if (!this._open)
return;
ContentAreaObserver.shiftBrowserDeck(0);
let onTransitionEnd = () => {
this._container.removeEventListener("transitionend", onTransitionEnd, true);
this._textbox.value = "";
@ -149,7 +151,6 @@ var FindHelperUI = {
this._textbox.blur();
this._container.addEventListener("transitionend", onTransitionEnd, true);
this._container.dismiss();
Elements.browsers.removeAttribute("findbar");
},
goToPrevious: function findHelperGoToPrevious() {
@ -172,27 +173,33 @@ var FindHelperUI = {
this._cmdNext.setAttribute("disabled", disabled);
},
_zoom: function _findHelperZoom(aElementRect) {
let autozoomEnabled = Services.prefs.getBoolPref("findhelper.autozoom");
if (!aElementRect || !autozoomEnabled)
return;
_zoom: function _findHelperZoom(aElementRect, aContentHeight) {
// The rect we get here is the content rect including scroll offset
// in the page.
if (Browser.selectedTab.allowZoom) {
let zoomLevel = Browser._getZoomLevelForRect(aElementRect);
// Clamp the zoom level relatively to the default zoom level of the page
let defaultZoomLevel = Browser.selectedTab.getDefaultZoomLevel();
zoomLevel = Util.clamp(zoomLevel, (defaultZoomLevel * kBrowserFindZoomLevelMin),
(defaultZoomLevel * kBrowserFindZoomLevelMax));
zoomLevel = Browser.selectedTab.clampZoomLevel(zoomLevel);
let zoomRect = Browser._getZoomRectForPoint(aElementRect.center().x, aElementRect.y, zoomLevel);
AnimatedZoom.animateTo(zoomRect);
} else {
// Even if zooming is disabled we could need to reposition the view in
// order to keep the element on-screen
let zoomRect = Browser._getZoomRectForPoint(aElementRect.center().x, aElementRect.y, getBrowser().scale);
AnimatedZoom.animateTo(zoomRect);
// If the text falls below the find bar and keyboard shift content up.
let browserShift = 0;
// aElementRect.y is the top left origin of the selection rect.
if ((aElementRect.y + aElementRect.height) >
(aContentHeight - this._container.boxObject.height)) {
browserShift += this._container.boxObject.height;
}
browserShift += Services.metro.keyboardHeight;
ContentAreaObserver.shiftBrowserDeck(browserShift);
// Adjust for keyboad display and position the text selection rect in
// the middle of the viewable area.
let xPos = aElementRect.x;
let yPos = aElementRect.y;
let scrollAdjust = ((ContentAreaObserver.height - Services.metro.keyboardHeight) * .5) +
Services.metro.keyboardHeight;
yPos -= scrollAdjust;
if (yPos < 0) {
yPos = 0;
}
// TODO zoom via apzc, right now all we support is scroll
// positioning.
Browser.selectedBrowser.contentWindow.scrollTo(xPos, yPos);
}
};

View File

@ -587,7 +587,6 @@ var SelectionHelperUI = {
Elements.browsers.addEventListener("URLChanged", this, true);
Elements.browsers.addEventListener("SizeChanged", this, true);
Elements.browsers.addEventListener("ZoomChanged", this, true);
Elements.navbar.addEventListener("transitionend", this, true);
Elements.navbar.addEventListener("MozAppbarDismissing", this, true);
@ -615,7 +614,6 @@ var SelectionHelperUI = {
Elements.browsers.removeEventListener("URLChanged", this, true);
Elements.browsers.removeEventListener("SizeChanged", this, true);
Elements.browsers.removeEventListener("ZoomChanged", this, true);
Elements.navbar.removeEventListener("transitionend", this, true);
Elements.navbar.removeEventListener("MozAppbarDismissing", this, true);
@ -1080,7 +1078,6 @@ var SelectionHelperUI = {
this._shutdown();
break;
case "ZoomChanged":
case "MozPrecisePointer":
this.closeEditSession(true);
break;

View File

@ -80,7 +80,6 @@ chrome.jar:
content/Site.js (content/Site.js)
content/TopSites.js (content/TopSites.js)
content/console.js (content/console.js)
content/AnimatedZoom.js (content/AnimatedZoom.js)
content/dbg-metro-actors.js (content/dbg-metro-actors.js)
#ifdef MOZ_SERVICES_SYNC
content/flyoutpanels/SyncFlyoutPanel.js (content/flyoutpanels/SyncFlyoutPanel.js)

View File

@ -193,9 +193,6 @@ pref("browser.helperApps.deleteTempFileOnExit", false);
/* password manager */
pref("signon.rememberSignons", true);
/* find helper */
pref("findhelper.autozoom", true);
// this will automatically enable inline spellchecking (if it is available) for
// editable elements in HTML
// 0 = spellcheck nothing

View File

@ -252,11 +252,6 @@ documenttab[selected] .documenttab-selection {
transition-delay: 0s;
transition-property: padding-bottom;
}
#browsers[findbar] browser {
/* delay setting padding-bottom until the findbar has transitioned in */
transition-delay: @metro_animation_duration@;
padding-bottom: @findbar_height@;
}
/* Selection overlay and monocles */
#page,
.selection-overlay {