Bug 611555 (1/2) - Use code from Easy Reading to reflow text on zoom [r=mfinkle]

--HG--
extra : rebase_source : 920f1317cd758db43105840196f47ea30b9803b9
This commit is contained in:
Matt Brubeck 2010-12-27 21:23:14 -08:00
parent 7911ded033
commit 6d8e43b46a
2 changed files with 72 additions and 48 deletions

View File

@ -66,7 +66,7 @@ const kDefaultMetadata = { autoSize: false, allowZoom: true, autoScale: true };
// Override sizeToContent in the main window. It breaks things (bug 565887)
window.sizeToContent = function() {
Components.utils.reportError("window.sizeToContent is not allowed in this window");
Cu.reportError("window.sizeToContent is not allowed in this window");
}
#ifdef MOZ_CRASH_REPORTER
@ -492,7 +492,7 @@ var Browser = {
window.controllers.removeController(BrowserUI);
},
getHomePage: function (aOptions) {
getHomePage: function getHomePage(aOptions) {
aOptions = aOptions || { useDefault: false };
let url = "about:home";
@ -993,17 +993,15 @@ var Browser = {
/**
* Find an appropriate zoom rect for an element bounding rect, if it exists.
* @return Rect in viewport coordinates
* */
* @return Rect in viewport coordinates, or null
*/
_getZoomRectForRect: function _getZoomRectForRect(rect, y) {
let oldZoomLevel = getBrowser().scale;
let zoomLevel = this._getZoomLevelForRect(rect);
let zoomRatio = oldZoomLevel / zoomLevel;
// Don't zoom in a marginal amount, but be more lenient for the first zoom.
// > 2/3 means operation increases the zoom level by less than 1.5
// > 9/10 means operation increases the zoom level by less than 1.1
let zoomTolerance = (this.selectedTab.isDefaultZoomLevel()) ? .9 : .6666;
// Don't zoom in a marginal amount.
let zoomTolerance = .95;
if (zoomRatio >= zoomTolerance)
return null;
else
@ -1078,6 +1076,23 @@ var Browser = {
}
},
// The device-pixel-to-CSS-px ratio used to adjust meta viewport values.
// This is higher on higher-dpi displays, so pages stay about the same physical size.
getScaleRatio: function getScaleRatio() {
let prefValue = Services.prefs.getIntPref("browser.viewport.scaleRatio");
if (prefValue > 0)
return prefValue / 100;
let dpi = this.windowUtils.displayDPI;
if (dpi < 200) // Includes desktop displays, and LDPI and MDPI Android devices
return 1;
else if (dpi < 300) // Includes Nokia N900, and HDPI Android devices
return 1.5;
// For very high-density displays like the iPhone 4, calculate an integer ratio.
return Math.floor(dpi / 150);
},
/**
* Convenience function for getting the scrollbox position off of a
* scrollBoxObject interface. Returns the actual values instead of the
@ -1124,8 +1139,10 @@ var Browser = {
case "Browser:ZoomToPoint:Return":
// JSON-ified rect needs to be recreated so the methods exist
let rect = Rect.fromRect(json.rect);
if (!this.zoomToPoint(json.x, json.y, rect))
if (!this.zoomToPoint(json.x, json.y, rect)) {
browser.messageManager.sendAsyncMessage("Browser:ResetZoom", {});
this.zoomFromPoint(json.x, json.y);
}
break;
case "scroll":
@ -1295,7 +1312,7 @@ nsBrowserAccess.prototype = {
QueryInterface: function(aIID) {
if (aIID.equals(Ci.nsIBrowserDOMWindow) || aIID.equals(Ci.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
throw Cr.NS_NOINTERFACE;
},
_getBrowser: function _getBrowser(aURI, aOpener, aWhere, aContext) {
@ -1608,17 +1625,15 @@ const ContentTouchHandler = {
return target && ("classList" in target && target.classList.contains("inputHandler"));
},
_dispatchMouseEvent: function _dispatchMouseEvent(aName, aX, aY, aModifiers) {
let aX = aX || 0;
let aY = aY || 0;
_dispatchMouseEvent: function _dispatchMouseEvent(aName, aX, aY, aOptions) {
let browser = getBrowser();
let pos = browser.transformClientToBrowser(aX, aY);
browser.messageManager.sendAsyncMessage(aName, {
x: pos.x,
y: pos.y,
modifiers: aModifiers || null,
messageId: this._messageId
});
let pos = browser.transformClientToBrowser(aX || 0, aY || 0);
let json = aOptions || {};
json.x = pos.x;
json.y = pos.y;
json.messageId = this._messageId;
browser.messageManager.sendAsyncMessage(aName, json);
},
tapDown: function tapDown(aX, aY) {
@ -1648,12 +1663,18 @@ const ContentTouchHandler = {
// Cancel the mouse click if we are showing a context menu
if (!ContextHelper.popupState)
this._dispatchMouseEvent("Browser:MouseUp", aX, aY, aModifiers);
this._dispatchMouseEvent("Browser:MouseUp", aX, aY, { modifiers: aModifiers });
},
tapDouble: function tapDouble(aX, aY, aModifiers) {
this._clearPendingMessages();
this._dispatchMouseEvent("Browser:ZoomToPoint", aX, aY);
let tab = Browser.selectedTab;
if (!tab.allowZoom)
return;
let width = window.innerWidth / Browser.getScaleRatio();
this._dispatchMouseEvent("Browser:ZoomToPoint", aX, aY, { width: width });
},
tapLong: function tapLong() {
@ -1698,7 +1719,7 @@ ContentCustomKeySender.prototype = {
},
_parseModifiers: function _parseModifiers(aEvent) {
const masks = Components.interfaces.nsIDOMNSEvent;
const masks = Ci.nsIDOMNSEvent;
var mval = 0;
if (aEvent.shiftKey)
mval |= masks.SHIFT_MASK;
@ -2275,7 +2296,7 @@ var MemoryObserver = {
observe: function mo_observe() {
window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils).garbageCollect();
Components.utils.forceGC();
Cu.forceGC();
}
};
@ -2512,7 +2533,7 @@ ProgressController.prototype = {
aIID.equals(Ci.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
throw Cr.NS_ERROR_NO_INTERFACE;
},
_networkStart: function _networkStart() {
@ -2676,7 +2697,7 @@ Tab.prototype = {
/** Update browser styles when the viewport metadata changes. */
updateViewportMetadata: function updateViewportMetadata(aMetadata) {
if (aMetadata && aMetadata.autoScale) {
let scaleRatio = aMetadata.scaleRatio = this.getScaleRatio();
let scaleRatio = aMetadata.scaleRatio = Browser.getScaleRatio();
if ("defaultZoom" in aMetadata && aMetadata.defaultZoom > 0)
aMetadata.defaultZoom *= scaleRatio;
@ -2735,23 +2756,6 @@ Tab.prototype = {
browser.setWindowSize(viewportW, viewportH);
},
// The device-pixel-to-CSS-px ratio used to adjust meta viewport values.
// This is higher on higher-dpi displays, so pages stay about the same physical size.
getScaleRatio: function getScaleRatio() {
let prefValue = Services.prefs.getIntPref("browser.viewport.scaleRatio");
if (prefValue > 0)
return prefValue / 100;
let dpi = Browser.windowUtils.displayDPI;
if (dpi < 200) // Includes desktop displays, and LDPI and MDPI Android devices
return 1;
else if (dpi < 300) // Includes Nokia N900, and HDPI Android devices
return 1.5;
// For very high-density displays like the iPhone 4, calculate an integer ratio.
return Math.floor(dpi / 150);
},
restoreViewportPosition: function restoreViewportPosition(aOldWidth, aNewWidth) {
let browser = this._browser;
let pos = browser.getPosition();

View File

@ -4,6 +4,7 @@ dump("###################################### content loaded\n");
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
let Cr = Components.results;
Cu.import("resource://gre/modules/Services.jsm");
@ -270,7 +271,7 @@ ProgressController.prototype = {
return this;
}
throw Components.results.NS_ERROR_NO_INTERFACE;
throw Cr.NS_ERROR_NO_INTERFACE;
},
start: function start() {
@ -297,6 +298,7 @@ function Content() {
addMessageListener("Browser:MouseUp", this);
addMessageListener("Browser:SaveAs", this);
addMessageListener("Browser:ZoomToPoint", this);
addMessageListener("Browser:ResetZoom", this);
addMessageListener("Browser:MozApplicationCache:Fetch", this);
if (Util.isParentProcess())
@ -304,6 +306,7 @@ function Content() {
addEventListener("MozApplicationManifest", this, false);
addEventListener("command", this, false);
addEventListener("pagehide", this, false);
this._progressController = new ProgressController(this);
this._progressController.start();
@ -336,14 +339,15 @@ Content.prototype = {
});
break;
}
case "command": {
// Don't trust synthetic events
if (!aEvent.isTrusted)
return;
let ot = aEvent.originalTarget;
let errorDoc = ot.ownerDocument;
// If the event came from an ssl error page, it is probably either the "Add
// Exception…" or "Get me out of here!" button
if (/^about:certerror\?e=nssBadCert/.test(errorDoc.documentURI)) {
@ -365,6 +369,11 @@ Content.prototype = {
}
break;
}
case "pagehide":
if (aEvent.target == content.document)
this._setTextZoom(1);
break;
}
},
@ -497,12 +506,18 @@ Content.prototype = {
let win = element.ownerDocument.defaultView;
while (element && win.getComputedStyle(element,null).display == "inline")
element = element.parentNode;
if (element)
if (element) {
rect = getBoundingContentRect(element);
this._setTextZoom(Math.max(1, rect.width / json.width));
}
sendAsyncMessage("Browser:ZoomToPoint:Return", { x: x, y: y, rect: rect });
break;
}
case "Browser:ResetZoom":
this._setTextZoom(1);
break;
case "Browser:MozApplicationCache:Fetch": {
let currentURI = Services.io.newURI(json.location, json.charset, null);
let manifestURI = Services.io.newURI(json.manifest, json.charset, currentURI);
@ -541,6 +556,11 @@ Content.prototype = {
windowUtils.sendMouseEventToWindow(aName, aX - scrollOffset.x, aY - scrollOffset.y, 0, 1, 0, true);
},
_setTextZoom: function _setTextZoom(aZoom) {
let viewer = docShell.contentViewer.QueryInterface(Ci.nsIMarkupDocumentViewer);
viewer.textZoom = aZoom;
},
startLoading: function startLoading() {
this._loading = true;
},
@ -885,7 +905,7 @@ var FormSubmitObserver = {
if (!aIID.equals(Ci.nsIFormSubmitObserver) &&
!aIID.equals(Ci.nsISupportsWeakReference) &&
!aIID.equals(Ci.nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
throw Cr.NS_ERROR_NO_INTERFACE;
return this;
}
};