Bug 710298: Support reflow-on-zoom by limiting the max line box width after zooming in on mobile. [r=blassey]

This commit is contained in:
Scott Johnson 2012-10-04 14:41:46 -05:00
parent 17af47564d
commit 9ce3aa84f3
2 changed files with 93 additions and 1 deletions

View File

@ -2661,6 +2661,19 @@ Tab.prototype = {
this.setScrollClampingSize(aViewport.zoom);
// Adjust the max line box width to be no more than the viewport width, but
// only if the reflow-on-zoom preference is enabled.
if (BrowserEventHandler.mReflozPref && BrowserEventHandler._mLastPinchData) {
let webNav = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation);
let docShell = webNav.QueryInterface(Ci.nsIDocShell);
let docViewer = docShell.contentViewer.QueryInterface(Ci.nsIMarkupDocumentViewer);
let viewportWidth = gScreenWidth / aViewport.zoom;
// We add in a bit of fudge just so that the end characters don't accidentally
// get clipped. 15px is an arbitrary choice.
docViewer.changeMaxLineBoxWidth(viewportWidth - 15);
BrowserEventHandler._mLastPinchData = null;
}
let win = this.browser.contentWindow;
win.scrollTo(x, y);
@ -3512,9 +3525,25 @@ var BrowserEventHandler = {
BrowserApp.deck.addEventListener("touchstart", this, true);
BrowserApp.deck.addEventListener("click", InputWidgetHelper, true);
BrowserApp.deck.addEventListener("click", SelectHelper, true);
document.addEventListener("MozMagnifyGestureStart", this, true);
document.addEventListener("MozMagnifyGestureUpdate", this, true);
document.addEventListener("MozMagnifyGesture", this, true);
Services.prefs.addObserver("browser.zoom.reflowOnZoom", this, false);
},
updateReflozPref: function() {
this.mReflozPref = Services.prefs.getBoolPref("browser.zoom.reflowOnZoom");
},
handleEvent: function(aEvent) {
if (aEvent.type && (aEvent.type === "MozMagnifyGesture" ||
aEvent.type === "MozMagnifyGestureUpdate" ||
aEvent.type === "MozMagnifyGestureStart")) {
this.observe(this, aEvent.type, JSON.stringify({x: aEvent.screenX, y: aEvent.screenY}));
return;
}
if (!BrowserApp.isBrowserContentDocumentDisplayed() || aEvent.touches.length > 1 || aEvent.defaultPrevented)
return;
@ -3653,9 +3682,20 @@ var BrowserEventHandler = {
} else if (aTopic == "Gesture:DoubleTap") {
this._cancelTapHighlight();
this.onDoubleTap(aData);
} else if (aTopic == "MozMagnifyGestureStart" ||
aTopic == "MozMagnifyGestureUpdate") {
this.onPinch(aData);
} else if (aTopic == "MozMagnifyGesture") {
this.onPinchFinish(aData,
this._mLastPinchPoint.x,
this._mLastPinchPoint.y);
} else if (aTopic == "nsPref:changed") {
if (aData == "browser.zoom.reflowOnZoom") {
this.updateReflozPref();
}
}
},
_zoomOut: function() {
sendMessageToJava({ gecko: { type: "Browser:ZoomToPageWidth"} });
},
@ -3745,6 +3785,43 @@ var BrowserEventHandler = {
}
},
_zoomInAndSnapToElement: function(aX, aY, aElement) {
let viewport = BrowserApp.selectedTab.getViewport();
if (viewport.zoom < 1.0) {
// We don't want to do this on zoom out.
return;
}
let fudge = 15; // Add a bit of fudge.
let win = BrowserApp.selectedBrowser.contentWindow;
let rect = ElementTouchHelper.getBoundingContentRect(aElement);
rect.type = "Browser:ZoomToRect";
rect.x = Math.max(viewport.cssPageLeft, rect.x - fudge);
rect.y = viewport.cssY;
rect.w = viewport.cssWidth;
rect.h = viewport.cssHeight;
sendMessageToJava({ gecko: rect });
},
onPinch: function(aData) {
let data = JSON.parse(aData);
this._mLastPinchPoint = {x: data.x, y: data.y};
},
onPinchFinish: function(aData, aX, aY) {
if (this.mReflozPref) {
let data = JSON.parse(aData);
let pinchElement = ElementTouchHelper.anyElementFromPoint(aX, aY);
data.element = pinchElement;
BrowserApp.selectedTab._mLastPinchElement = pinchElement;
this._mLastPinchData = data;
this._zoomInAndSnapToElement(data.x, data.y, data.element);
}
},
_shouldZoomToElement: function(aElement) {
let win = aElement.ownerDocument.defaultView;
if (win.getComputedStyle(aElement, null).display == "inline")
@ -3762,6 +3839,8 @@ var BrowserEventHandler = {
_highlightElement: null,
_mLastPinchData: null,
_doTapHighlight: function _doTapHighlight(aElement) {
DOMUtils.setContentState(aElement, kStateActive);
this._highlightElement = aElement;

View File

@ -3531,6 +3531,19 @@ pref("zoom.minPercent", 30);
pref("zoom.maxPercent", 300);
pref("toolkit.zoomManager.zoomValues", ".3,.5,.67,.8,.9,1,1.1,1.2,1.33,1.5,1.7,2,2.4,3");
/**
* Specify whether or not the browser should generate a reflow event on zoom.
* For a pan-and-zoom ui on mobile, it is sometimes desirable for a zoom event
* to limit the max line box width of text in order to enable easier reading
* of large amounts of text.
*
* If enabled, this will limit the max line box width of all text on a page to
* the viewport width (also generating a reflow), after a zoom event occurs.
*
* By default, this is not enabled.
*/
pref("browser.zoom.reflowOnZoom", false);
// Image-related prefs
// The maximum size, in bytes, of the decoded images we cache
pref("image.cache.size", 5242880);