Bug 1197824 - Support the browser.ui.zoom.force-user-scalable pref in the gecko zoom-constraints codepath. r=botond

The browser.ui.zoom.force-user-scalable pref can be modified by the user from
the Fennec settings screen, and allows them zoom pages despite the meta-viewport
tag that might otherwise restrict zooming. This effectively ignores the effect
of the user-scalable, minimum-scale, and maximum-scale meta-viewport tokens.
This commit is contained in:
Kartikaya Gupta 2015-09-03 10:30:41 -04:00
parent 0a73904dd8
commit e5382cb5a1
3 changed files with 38 additions and 4 deletions

View File

@ -8074,6 +8074,26 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
}
case Specified:
default:
LayoutDeviceToScreenScale effectiveMinScale = mScaleMinFloat;
LayoutDeviceToScreenScale effectiveMaxScale = mScaleMaxFloat;
bool effectiveValidMaxScale = mValidMaxScale;
bool effectiveAllowZoom = mAllowZoom;
bool effectiveAllowDoubleTapZoom = mAllowDoubleTapZoom;
if (gfxPrefs::ForceUserScalable()) {
// If the pref to force user-scalable is enabled, we ignore the values
// from the meta-viewport tag for these properties and just assume they
// allow the page to be scalable. Note in particular that this code is
// in the "Specified" branch of the enclosing switch statement, so that
// calls to GetViewportInfo always use the latest value of the
// ForceUserScalable pref. Other codepaths that return nsViewportInfo
// instances are all consistent with ForceUserScalable() already.
effectiveMinScale = kViewportMinScale;
effectiveMaxScale = kViewportMaxScale;
effectiveValidMaxScale = true;
effectiveAllowZoom = true;
effectiveAllowDoubleTapZoom = true;
}
CSSSize size = mViewportSize;
if (!mValidWidth) {
@ -8096,8 +8116,8 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
}
CSSToScreenScale scaleFloat = mScaleFloat * layoutDeviceScale;
CSSToScreenScale scaleMinFloat = mScaleMinFloat * layoutDeviceScale;
CSSToScreenScale scaleMaxFloat = mScaleMaxFloat * layoutDeviceScale;
CSSToScreenScale scaleMinFloat = effectiveMinScale * layoutDeviceScale;
CSSToScreenScale scaleMaxFloat = effectiveMaxScale * layoutDeviceScale;
if (mAutoSize) {
// aDisplaySize is in screen pixels; convert them to CSS pixels for the viewport size.
@ -8122,14 +8142,15 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
CSSSize displaySize = ScreenSize(aDisplaySize) / scaleFloat;
size.width = std::max(size.width, displaySize.width);
size.height = std::max(size.height, displaySize.height);
} else if (mValidMaxScale) {
} else if (effectiveValidMaxScale) {
CSSSize displaySize = ScreenSize(aDisplaySize) / scaleMaxFloat;
size.width = std::max(size.width, displaySize.width);
size.height = std::max(size.height, displaySize.height);
}
return nsViewportInfo(scaleFloat, scaleMinFloat, scaleMaxFloat, size,
mAutoSize, mAllowZoom, mAllowDoubleTapZoom);
mAutoSize, effectiveAllowZoom,
effectiveAllowDoubleTapZoom);
}
}

View File

@ -187,6 +187,7 @@ private:
DECL_GFX_PREF(Live, "apz.y_stationary_size_multiplier", APZYStationarySizeMultiplier, float, 3.5f);
DECL_GFX_PREF(Live, "apz.zoom_animation_duration_ms", APZZoomAnimationDuration, int32_t, 250);
DECL_GFX_PREF(Live, "browser.ui.zoom.force-user-scalable", ForceUserScalable, bool, false);
DECL_GFX_PREF(Live, "browser.viewport.desktopWidth", DesktopViewportWidth, int32_t, 980);
DECL_GFX_PREF(Live, "dom.meta-viewport.enabled", MetaViewportEnabled, bool, false);

View File

@ -27,6 +27,7 @@ NS_IMPL_ISUPPORTS(ZoomConstraintsClient, nsIDOMEventListener, nsIObserver)
static const nsLiteralString DOM_META_ADDED = NS_LITERAL_STRING("DOMMetaAdded");
static const nsLiteralString DOM_META_CHANGED = NS_LITERAL_STRING("DOMMetaChanged");
static const nsLiteralCString BEFORE_FIRST_PAINT = NS_LITERAL_CSTRING("before-first-paint");
static const nsLiteralCString NS_PREF_CHANGED = NS_LITERAL_CSTRING("nsPref:changed");
using namespace mozilla;
using namespace mozilla::layers;
@ -76,6 +77,8 @@ ZoomConstraintsClient::Destroy()
observerService->RemoveObserver(this, BEFORE_FIRST_PAINT.Data());
}
Preferences::RemoveObserver(this, "browser.ui.zoom.force-user-scalable");
if (mGuid) {
if (nsIWidget* widget = GetWidget(mPresShell)) {
ZCC_LOG("Sending null constraints in %p for { %u, %" PRIu64 " }\n",
@ -111,6 +114,8 @@ ZoomConstraintsClient::Init(nsIPresShell* aPresShell, nsIDocument* aDocument)
if (observerService) {
observerService->AddObserver(this, BEFORE_FIRST_PAINT.Data(), false);
}
Preferences::AddStrongObserver(this, "browser.ui.zoom.force-user-scalable");
}
NS_IMETHODIMP
@ -136,6 +141,13 @@ ZoomConstraintsClient::Observe(nsISupports* aSubject, const char* aTopic, const
if (SameCOMIdentity(aSubject, mDocument) && BEFORE_FIRST_PAINT.EqualsASCII(aTopic)) {
ZCC_LOG("Got a before-first-paint event in %p\n", this);
RefreshZoomConstraints();
} else if (NS_PREF_CHANGED.EqualsASCII(aTopic)) {
ZCC_LOG("Got a pref-change event in %p\n", this);
// We need to run this later because all the pref change listeners need
// to execute before we can be guaranteed that gfxPrefs::ForceUserScalable()
// returns the updated value.
NS_DispatchToMainThread(NS_NewRunnableMethod(
this, &ZoomConstraintsClient::RefreshZoomConstraints));
}
return NS_OK;
}