Bug 707571 (part 2) - Disable zooming for pages with user-scalable=no [r=kats]

This commit is contained in:
Matt Brubeck 2012-05-18 08:24:27 -07:00
parent a76f21a033
commit d3c53ac15c
6 changed files with 100 additions and 15 deletions

View File

@ -675,6 +675,8 @@ abstract public class GeckoApp
tab.updateFaviconURL(null);
tab.updateIdentityData(null);
tab.removeTransientDoorHangers();
tab.setAllowZoom(true);
tab.setDefaultZoom(0);
tab.setHasTouchListeners(false);
tab.setCheckerboardColor(Color.WHITE);
@ -1001,6 +1003,19 @@ abstract public class GeckoApp
}
} else if (event.equals("Update:Restart")) {
doRestart("org.mozilla.gecko.restart_update");
} else if (event.equals("Tab:ViewportMetadata")) {
int tabId = message.getInt("tabID");
Tab tab = Tabs.getInstance().getTab(tabId);
if (tab == null)
return;
tab.setAllowZoom(message.getBoolean("allowZoom"));
tab.setDefaultZoom((float) message.getDouble("defaultZoom"));
// Sync up the LayerController and the tab if the tab's currently displayed.
LayerController controller = getLayerController();
if (controller != null && Tabs.getInstance().isSelectedTab(tab)) {
controller.setAllowZoom(tab.getAllowZoom());
controller.setDefaultZoom(tab.getDefaultZoom());
}
} else if (event.equals("Tab:HasTouchListener")) {
int tabId = message.getInt("tabID");
Tab tab = Tabs.getInstance().getTab(tabId);
@ -1720,6 +1735,7 @@ abstract public class GeckoApp
GeckoAppShell.registerGeckoEventListener("CharEncoding:State", GeckoApp.mAppContext);
GeckoAppShell.registerGeckoEventListener("Update:Restart", GeckoApp.mAppContext);
GeckoAppShell.registerGeckoEventListener("Tab:HasTouchListener", GeckoApp.mAppContext);
GeckoAppShell.registerGeckoEventListener("Tab:ViewportMetadata", GeckoApp.mAppContext);
GeckoAppShell.registerGeckoEventListener("Session:StatePurged", GeckoApp.mAppContext);
GeckoAppShell.registerGeckoEventListener("Bookmark:Insert", GeckoApp.mAppContext);
GeckoAppShell.registerGeckoEventListener("Accessibility:Event", GeckoApp.mAppContext);

View File

@ -86,6 +86,8 @@ public final class Tab {
private String mDocumentURI;
private String mContentType;
private boolean mHasTouchListeners;
private boolean mAllowZoom;
private float mDefaultZoom;
private ArrayList<View> mPluginViews;
private HashMap<Object, Layer> mPluginLayers;
private ContentResolver mContentResolver;
@ -284,6 +286,22 @@ public final class Tab {
return mState;
}
public void setAllowZoom(boolean aValue) {
mAllowZoom = aValue;
}
public boolean getAllowZoom() {
return mAllowZoom;
}
public void setDefaultZoom(float aValue) {
mDefaultZoom = aValue;
}
public float getDefaultZoom() {
return mDefaultZoom;
}
public void setHasTouchListeners(boolean aValue) {
mHasTouchListeners = aValue;
}

View File

@ -43,6 +43,7 @@ import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.GeckoEventResponder;
import org.mozilla.gecko.Tab;
import org.mozilla.gecko.Tabs;
import org.json.JSONArray;
import org.json.JSONException;
@ -59,7 +60,6 @@ import android.util.Log;
import android.view.View;
import java.util.Map;
import java.util.HashMap;
import org.mozilla.gecko.Tabs;
public class GeckoLayerClient implements GeckoEventResponder,
LayerView.Listener {
@ -350,7 +350,12 @@ public class GeckoLayerClient implements GeckoEventResponder,
}
});
mLayerController.setViewportMetrics(currentMetrics);
mLayerController.setCheckerboardColor(Tabs.getInstance().getSelectedTab().getCheckerboardColor());
Tab tab = Tabs.getInstance().getSelectedTab();
mLayerController.setCheckerboardColor(tab.getCheckerboardColor());
mLayerController.setAllowZoom(tab.getAllowZoom());
mLayerController.setDefaultZoom(tab.getDefaultZoom());
// At this point, we have just switched to displaying a different document than we
// we previously displaying. This means we need to abort any panning/zooming animations
// that are in progress and send an updated display port request to browser.js as soon

View File

@ -41,7 +41,6 @@ package org.mozilla.gecko.gfx;
import org.mozilla.gecko.gfx.Layer;
import org.mozilla.gecko.ui.PanZoomController;
import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
import org.mozilla.gecko.GeckoApp;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
@ -92,6 +91,9 @@ public class LayerController {
private int mCheckerboardColor = Color.WHITE;
private boolean mCheckerboardShouldShowChecks;
private boolean mAllowZoom;
private float mDefaultZoom;
private boolean mForceRedraw;
public LayerController(Context context) {
@ -346,4 +348,20 @@ public class LayerController {
mCheckerboardColor = newColor;
mView.requestRender();
}
public void setAllowZoom(boolean aValue) {
mAllowZoom = aValue;
}
public boolean getAllowZoom() {
return mAllowZoom;
}
public void setDefaultZoom(float aValue) {
mDefaultZoom = aValue;
}
public float getDefaultZoom() {
return mDefaultZoom;
}
}

View File

@ -813,19 +813,32 @@ public class PanZoomController
float focusX = viewport.width() / 2.0f;
float focusY = viewport.height() / 2.0f;
float minZoomFactor = 0.0f;
if (viewport.width() > pageSize.width && pageSize.width > 0) {
float scaleFactor = viewport.width() / pageSize.width;
minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
focusX = 0.0f;
}
if (viewport.height() > pageSize.height && pageSize.height > 0) {
float scaleFactor = viewport.height() / pageSize.height;
minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
focusY = 0.0f;
float maxZoomFactor = MAX_ZOOM;
if (!mController.getAllowZoom()) {
// If allowZoom is false, clamp to the default zoom level.
maxZoomFactor = minZoomFactor = mController.getDefaultZoom();
}
if (!FloatUtils.fuzzyEquals(minZoomFactor, 0.0f)) {
// Ensure minZoomFactor keeps the page at least as big as the viewport.
if (pageSize.width > 0) {
float scaleFactor = viewport.width() / pageSize.width;
minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
if (viewport.width() > pageSize.width)
focusX = 0.0f;
}
if (pageSize.height > 0) {
float scaleFactor = viewport.height() / pageSize.height;
minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
if (viewport.height() > pageSize.height)
focusY = 0.0f;
}
maxZoomFactor = Math.max(maxZoomFactor, minZoomFactor);
if (zoomFactor < minZoomFactor) {
// if one (or both) of the page dimensions is smaller than the viewport,
// zoom using the top/left as the focus on that axis. this prevents the
// scenario where, if both dimensions are smaller than the viewport, but
@ -833,9 +846,9 @@ public class PanZoomController
// after applying the scale
PointF center = new PointF(focusX, focusY);
viewportMetrics.scaleTo(minZoomFactor, center);
} else if (zoomFactor > MAX_ZOOM) {
} else if (zoomFactor > maxZoomFactor) {
PointF center = new PointF(viewport.width() / 2.0f, viewport.height() / 2.0f);
viewportMetrics.scaleTo(MAX_ZOOM, center);
viewportMetrics.scaleTo(maxZoomFactor, center);
}
/* Now we pan to the right origin. */
@ -875,6 +888,9 @@ public class PanZoomController
if (mState == PanZoomState.ANIMATED_ZOOM)
return false;
if (!mController.getAllowZoom())
return false;
mState = PanZoomState.PINCHING;
mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY());
cancelTouch();
@ -992,6 +1008,8 @@ public class PanZoomController
@Override
public boolean onDoubleTap(MotionEvent motionEvent) {
if (!mController.getAllowZoom())
return false;
sendPointToGecko("Gesture:DoubleTap", motionEvent);
return true;
}

View File

@ -2362,6 +2362,7 @@ Tab.prototype = {
}
ViewportHandler.setMetadataForDocument(this.browser.contentDocument, aMetadata);
this.updateViewportSize(gScreenWidth);
this.sendViewportMetadata();
},
/** Update viewport when the metadata or the window size changes. */
@ -2449,6 +2450,15 @@ Tab.prototype = {
this.sendViewportUpdate();
},
sendViewportMetadata: function sendViewportMetadata() {
sendMessageToJava({ gecko: {
type: "Tab:ViewportMetadata",
allowZoom: this.metadata.allowZoom,
defaultZoom: this.metadata.defaultZoom || 0,
tabID: this.id
}});
},
setBrowserSize: function(aWidth, aHeight) {
this.browserWidth = aWidth;