Bug 798068: Return sane values for min/max zoom when handheldFriendly, WAP, Mobile, or WML is set in the viewport metadata. [r=mbrubeck,bent]

This commit is contained in:
Scott Johnson 2012-10-05 18:24:16 -05:00
parent f5ee191e63
commit 57550822fb
5 changed files with 80 additions and 16 deletions

View File

@ -1570,6 +1570,13 @@ public:
uint32_t aDisplayWidth,
uint32_t aDisplayHeight);
/**
* Constrain the viewport calculations from the GetViewportInfo() function
* in order to always return sane minimum/maximum values. This modifies the
* ViewportInfo struct passed as an input parameter, in place.
*/
static void ConstrainViewportValues(ViewportInfo& aViewInfo);
/**
* The device-pixel-to-CSS-px ratio used to adjust meta viewport values.
*/

View File

@ -250,8 +250,8 @@ namespace {
/**
* Default values for the ViewportInfo structure.
*/
static const float kViewportMinScale = 0.0;
static const float kViewportMaxScale = 10.0;
static const double kViewportMinScale = 0.0;
static const double kViewportMaxScale = 10.0;
static const uint32_t kViewportMinWidth = 200;
static const uint32_t kViewportMaxWidth = 10000;
static const uint32_t kViewportMinHeight = 223;
@ -5101,6 +5101,29 @@ static void ProcessViewportToken(nsIDocument *aDocument,
#define IS_SEPARATOR(c) ((c == '=') || (c == ',') || (c == ';') || \
(c == '\t') || (c == '\n') || (c == '\r'))
/* static */
void
nsContentUtils::ConstrainViewportValues(ViewportInfo& aViewInfo)
{
aViewInfo.maxZoom = NS_MIN(aViewInfo.maxZoom, kViewportMaxScale);
aViewInfo.maxZoom = NS_MAX(aViewInfo.maxZoom, kViewportMinScale);
aViewInfo.minZoom = NS_MIN(aViewInfo.minZoom, kViewportMaxScale);
aViewInfo.minZoom = NS_MAX(aViewInfo.minZoom, kViewportMinScale);
// Constrain the min/max zoom as specified at:
// dev.w3.org/csswg/css-device-adapt section 6.2
aViewInfo.maxZoom = NS_MAX(aViewInfo.minZoom, aViewInfo.maxZoom);
aViewInfo.defaultZoom = NS_MIN(aViewInfo.defaultZoom, aViewInfo.maxZoom);
aViewInfo.defaultZoom = NS_MAX(aViewInfo.defaultZoom, aViewInfo.minZoom);
aViewInfo.width = NS_MIN(aViewInfo.width, kViewportMaxWidth);
aViewInfo.width = NS_MAX(aViewInfo.width, kViewportMinWidth);
aViewInfo.height = NS_MIN(aViewInfo.height, kViewportMaxHeight);
aViewInfo.height = NS_MAX(aViewInfo.height, kViewportMinHeight);
}
/* static */
ViewportInfo
nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
@ -5111,6 +5134,10 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
ret.defaultZoom = 1.0;
ret.autoSize = true;
ret.allowZoom = true;
ret.width = aDisplayWidth;
ret.height = aDisplayHeight;
ret.minZoom = kViewportMinScale;
ret.maxZoom = kViewportMaxScale;
nsAutoString viewport;
aDocument->GetHeaderData(nsGkAtoms::viewport, viewport);
@ -5128,6 +5155,7 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
(docId.Find("Mobile") != -1) ||
(docId.Find("WML") != -1))
{
nsContentUtils::ConstrainViewportValues(ret);
return ret;
}
}
@ -5136,6 +5164,7 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
nsAutoString handheldFriendly;
aDocument->GetHeaderData(nsGkAtoms::handheldFriendly, handheldFriendly);
if (handheldFriendly.EqualsLiteral("true")) {
nsContentUtils::ConstrainViewportValues(ret);
return ret;
}
}
@ -5150,9 +5179,6 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
scaleMinFloat = kViewportMinScale;
}
scaleMinFloat = NS_MIN(scaleMinFloat, kViewportMaxScale);
scaleMinFloat = NS_MAX(scaleMinFloat, kViewportMinScale);
nsAutoString maxScaleStr;
aDocument->GetHeaderData(nsGkAtoms::viewport_maximum_scale, maxScaleStr);
@ -5165,16 +5191,11 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
scaleMaxFloat = kViewportMaxScale;
}
scaleMaxFloat = NS_MIN(scaleMaxFloat, kViewportMaxScale);
scaleMaxFloat = NS_MAX(scaleMaxFloat, kViewportMinScale);
nsAutoString scaleStr;
aDocument->GetHeaderData(nsGkAtoms::viewport_initial_scale, scaleStr);
nsresult scaleErrorCode;
float scaleFloat = scaleStr.ToFloat(&scaleErrorCode);
scaleFloat = NS_MIN(scaleFloat, scaleMaxFloat);
scaleFloat = NS_MAX(scaleFloat, scaleMinFloat);
nsAutoString widthStr, heightStr;
@ -5235,18 +5256,12 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
}
}
width = NS_MIN(width, kViewportMaxWidth);
width = NS_MAX(width, kViewportMinWidth);
// Also recalculate the default zoom, if it wasn't specified in the metadata,
// and the width is specified.
if (scaleStr.IsEmpty() && !widthStr.IsEmpty()) {
scaleFloat = NS_MAX(scaleFloat, float(aDisplayWidth) / float(width));
}
height = NS_MIN(height, kViewportMaxHeight);
height = NS_MAX(height, kViewportMinHeight);
// We need to perform a conversion, but only if the initial or maximum
// scale were set explicitly by the user.
if (!scaleStr.IsEmpty() && NS_SUCCEEDED(scaleErrorCode)) {
@ -5274,6 +5289,8 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
ret.minZoom = scaleMinFloat;
ret.maxZoom = scaleMaxFloat;
ret.autoSize = autoSize;
nsContentUtils::ConstrainViewportValues(ret);
return ret;
}

View File

@ -0,0 +1,19 @@
<?xml version = '1.0' encoding = 'utf-8'?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
function doTest() {
var Ci = Components.interfaces;
var defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom ={}, width = {}, height = {}, autoSize = {};
var windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
windowUtils.getViewportInfo(1, 1, defaultZoom, allowZoom, minZoom, maxZoom, width, height, autoSize);
document.getElementById("minZoom").innerHTML = minZoom.value.toPrecision(10);
document.getElementById("maxZoom").innerHTML = maxZoom.value.toPrecision(10);
}
</script>
</head>
<body onload="doTest();">
MinZoom: <span id="minZoom"></span><br />
MaxZoom: <span id="maxZoom"></span>
</body>
</html>

View File

@ -0,0 +1,20 @@
<?xml version = '1.0' encoding = 'utf-8'?>
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
function doTest() {
var Ci = Components.interfaces;
var defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom ={}, width = {}, height = {}, autoSize = {};
var windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
windowUtils.getViewportInfo(1, 1, defaultZoom, allowZoom, minZoom, maxZoom, width, height, autoSize);
document.getElementById("minZoom").innerHTML = minZoom.value.toPrecision(10);
document.getElementById("maxZoom").innerHTML = maxZoom.value.toPrecision(10);
}
</script>
</head>
<body onload="doTest();">
MinZoom: <span id="minZoom"></span><br />
MaxZoom: <span id="maxZoom"></span>
</body>
</html>

View File

@ -15,3 +15,4 @@ skip-if(xulFennec) include ../../canvas/test/reftest/reftest.list
== bug592366-2.html bug592366-ref.html
== bug592366-1.xhtml bug592366-ref.xhtml
== bug592366-2.xhtml bug592366-ref.xhtml
== bug798068.xhtml bug798068-ref.xhtml