зеркало из https://github.com/mozilla/pjs.git
Bug 706198 - Disable font inflation on sites optimized for mobile to avoid strangely inflated text. [r=mbrubeck,dbaron]
--HG-- extra : rebase_source : 60d764b0a76ae87515a3e669ba76adc61926c862
This commit is contained in:
Родитель
163e7715aa
Коммит
7faffa3598
|
@ -178,6 +178,48 @@ enum EventNameType {
|
|||
EventNameType_All = 0xFFFF
|
||||
};
|
||||
|
||||
/**
|
||||
* Information retrieved from the <meta name="viewport"> tag. See
|
||||
* GetViewportInfo for more information on this functionality.
|
||||
*/
|
||||
struct ViewportInfo
|
||||
{
|
||||
// Default zoom indicates the level at which the display is 'zoomed in'
|
||||
// initially for the user, upon loading of the page.
|
||||
double defaultZoom;
|
||||
|
||||
// The minimum zoom level permitted by the page.
|
||||
double minZoom;
|
||||
|
||||
// The maximum zoom level permitted by the page.
|
||||
double maxZoom;
|
||||
|
||||
// The width of the viewport, specified by the <meta name="viewport"> tag,
|
||||
// in CSS pixels.
|
||||
PRUint32 width;
|
||||
|
||||
// The height of the viewport, specified by the <meta name="viewport"> tag,
|
||||
// in CSS pixels.
|
||||
PRUint32 height;
|
||||
|
||||
// Whether or not we should automatically size the viewport to the device's
|
||||
// width. This is true if the document has been optimized for mobile, and
|
||||
// the width property of a specified <meta name="viewport"> tag is either
|
||||
// not specified, or is set to the special value 'device-width'.
|
||||
bool autoSize;
|
||||
|
||||
// Whether or not the user can zoom in and out on the page. Default is true.
|
||||
bool allowZoom;
|
||||
|
||||
// This is a holdover from e10s fennec, and might be removed in the future.
|
||||
// It's a hack to work around bugs that didn't allow zooming of documents
|
||||
// from within the parent process. It is still used in native Fennec for XUL
|
||||
// documents, but it should probably be removed.
|
||||
// Currently, from, within GetViewportInfo(), This is only set to false
|
||||
// if the document is a XUL document.
|
||||
bool autoScale;
|
||||
};
|
||||
|
||||
struct EventNameMapping
|
||||
{
|
||||
nsIAtom* mAtom;
|
||||
|
@ -1489,6 +1531,18 @@ public:
|
|||
return sScriptBlockerCount == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve information about the viewport as a data structure.
|
||||
* This will return information in the viewport META data section
|
||||
* of the document. This can be used in lieu of ProcessViewportInfo(),
|
||||
* which places the viewport information in the document header instead
|
||||
* of returning it directly.
|
||||
*
|
||||
* NOTE: If the site is optimized for mobile (via the doctype), this
|
||||
* will return viewport information that specifies default information.
|
||||
*/
|
||||
static ViewportInfo GetViewportInfo(nsIDocument* aDocument);
|
||||
|
||||
/* Process viewport META data. This gives us information for the scale
|
||||
* and zoom of a page on mobile devices. We stick the information in
|
||||
* the document header and use it later on after rendering.
|
||||
|
|
|
@ -211,6 +211,8 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
|
|||
#include "mozilla/Preferences.h"
|
||||
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
#include "nsIDOMDocumentType.h"
|
||||
#include "nsIDOMWindowUtils.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
|
||||
|
@ -221,6 +223,17 @@ using namespace mozilla;
|
|||
|
||||
const char kLoadAsData[] = "loadAsData";
|
||||
|
||||
/**
|
||||
* Default values for the ViewportInfo structure.
|
||||
*/
|
||||
static const float kViewportMinScale = 0.0;
|
||||
static const float kViewportMaxScale = 10.0;
|
||||
static const PRUint32 kViewportMinWidth = 200;
|
||||
static const PRUint32 kViewportMaxWidth = 10000;
|
||||
static const PRUint32 kViewportMinHeight = 223;
|
||||
static const PRUint32 kViewportMaxHeight = 10000;
|
||||
static const PRInt32 kViewportDefaultScreenWidth = 980;
|
||||
|
||||
static const char kJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1";
|
||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
|
||||
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
|
||||
|
@ -4554,6 +4567,198 @@ static void ProcessViewportToken(nsIDocument *aDocument,
|
|||
#define IS_SEPARATOR(c) ((c == '=') || (c == ',') || (c == ';') || \
|
||||
(c == '\t') || (c == '\n') || (c == '\r'))
|
||||
|
||||
/* static */
|
||||
ViewportInfo
|
||||
nsContentUtils::GetViewportInfo(nsIDocument *aDocument)
|
||||
{
|
||||
ViewportInfo ret;
|
||||
ret.defaultZoom = 1.0;
|
||||
ret.autoSize = true;
|
||||
ret.allowZoom = true;
|
||||
ret.autoScale = true;
|
||||
|
||||
// If the docType specifies that we are on a site optimized for mobile,
|
||||
// then we want to return specially crafted defaults for the viewport info.
|
||||
nsCOMPtr<nsIDOMDocument>
|
||||
domDoc(do_QueryInterface(aDocument));
|
||||
|
||||
nsCOMPtr<nsIDOMDocumentType> docType;
|
||||
nsresult rv = domDoc->GetDoctype(getter_AddRefs(docType));
|
||||
if (NS_SUCCEEDED(rv) && docType) {
|
||||
nsAutoString docId;
|
||||
rv = docType->GetPublicId(docId);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if ((docId.Find("WAP") != -1) ||
|
||||
(docId.Find("Mobile") != -1) ||
|
||||
(docId.Find("WML") != -1))
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aDocument->IsXUL()) {
|
||||
ret.autoScale = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsIDOMWindow* window = aDocument->GetWindow();
|
||||
nsCOMPtr<nsIDOMWindowUtils> windowUtils(do_GetInterface(window));
|
||||
|
||||
if (!windowUtils) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsAutoString handheldFriendly;
|
||||
aDocument->GetHeaderData(nsGkAtoms::handheldFriendly, handheldFriendly);
|
||||
|
||||
if (handheldFriendly.EqualsLiteral("true")) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
PRInt32 errorCode;
|
||||
|
||||
nsAutoString minScaleStr;
|
||||
aDocument->GetHeaderData(nsGkAtoms::minimum_scale, minScaleStr);
|
||||
|
||||
float scaleMinFloat = minScaleStr.ToFloat(&errorCode);
|
||||
|
||||
if (errorCode) {
|
||||
scaleMinFloat = kViewportMinScale;
|
||||
}
|
||||
|
||||
scaleMinFloat = NS_MIN(scaleMinFloat, kViewportMaxScale);
|
||||
scaleMinFloat = NS_MAX(scaleMinFloat, kViewportMinScale);
|
||||
|
||||
nsAutoString maxScaleStr;
|
||||
aDocument->GetHeaderData(nsGkAtoms::maximum_scale, maxScaleStr);
|
||||
|
||||
// We define a special error code variable for the scale and max scale,
|
||||
// because they are used later (see the width calculations).
|
||||
PRInt32 scaleMaxErrorCode;
|
||||
float scaleMaxFloat = maxScaleStr.ToFloat(&scaleMaxErrorCode);
|
||||
|
||||
if (scaleMaxErrorCode) {
|
||||
scaleMaxFloat = kViewportMaxScale;
|
||||
}
|
||||
|
||||
scaleMaxFloat = NS_MIN(scaleMaxFloat, kViewportMaxScale);
|
||||
scaleMaxFloat = NS_MAX(scaleMaxFloat, kViewportMinScale);
|
||||
|
||||
nsAutoString scaleStr;
|
||||
aDocument->GetHeaderData(nsGkAtoms::viewport_initial_scale, scaleStr);
|
||||
|
||||
PRInt32 scaleErrorCode;
|
||||
float scaleFloat = scaleStr.ToFloat(&scaleErrorCode);
|
||||
scaleFloat = NS_MIN(scaleFloat, scaleMaxFloat);
|
||||
scaleFloat = NS_MAX(scaleFloat, scaleMinFloat);
|
||||
|
||||
nsAutoString widthStr, heightStr;
|
||||
|
||||
aDocument->GetHeaderData(nsGkAtoms::viewport_height, heightStr);
|
||||
aDocument->GetHeaderData(nsGkAtoms::viewport_width, widthStr);
|
||||
|
||||
bool autoSize = false;
|
||||
|
||||
if (widthStr.EqualsLiteral("device-width")) {
|
||||
autoSize = true;
|
||||
}
|
||||
|
||||
if (widthStr.IsEmpty() &&
|
||||
(heightStr.EqualsLiteral("device-height") ||
|
||||
scaleFloat == 1.0))
|
||||
{
|
||||
autoSize = true;
|
||||
}
|
||||
|
||||
// XXXjwir3:
|
||||
// See bug 706918, comment 23 for more information on this particular section
|
||||
// of the code. We're using "screen size" in place of the size of the content
|
||||
// area, because on mobile, these are close or equal. This will work for our
|
||||
// purposes (bug 706198), but it will need to be changed in the future to be
|
||||
// more correct when we bring the rest of the viewport code into platform.
|
||||
// We actually want the size of the content area, in the event that we don't
|
||||
// have any metadata about the width and/or height. On mobile, the screen size
|
||||
// and the size of the content area are very close, or the same value.
|
||||
// In XUL fennec, the content area is the size of the <browser> widget, but
|
||||
// in native fennec, the content area is the size of the Gecko LayerView
|
||||
// object.
|
||||
|
||||
// TODO:
|
||||
// Once bug 716575 has been resolved, this code should be changed so that it
|
||||
// does the right thing on all platforms.
|
||||
nsresult result;
|
||||
PRInt32 screenLeft, screenTop, screenWidth, screenHeight;
|
||||
nsCOMPtr<nsIScreenManager> screenMgr =
|
||||
do_GetService("@mozilla.org/gfx/screenmanager;1", &result);
|
||||
|
||||
nsCOMPtr<nsIScreen> screen;
|
||||
screenMgr->GetPrimaryScreen(getter_AddRefs(screen));
|
||||
screen->GetRect(&screenLeft, &screenTop, &screenWidth, &screenHeight);
|
||||
|
||||
PRUint32 width = widthStr.ToInteger(&errorCode);
|
||||
if (errorCode) {
|
||||
if (autoSize) {
|
||||
width = screenWidth;
|
||||
} else {
|
||||
width = Preferences::GetInt("browser.viewport.desktopWidth", 0);
|
||||
}
|
||||
}
|
||||
|
||||
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)(screenWidth/width));
|
||||
}
|
||||
|
||||
PRUint32 height = heightStr.ToInteger(&errorCode);
|
||||
|
||||
if (errorCode) {
|
||||
height = width * ((float)screenHeight / screenWidth);
|
||||
}
|
||||
|
||||
// If height was provided by the user, but width wasn't, then we should
|
||||
// calculate the width.
|
||||
if (widthStr.IsEmpty() && !heightStr.IsEmpty()) {
|
||||
width = (PRUint32) ((height * screenWidth) / screenHeight);
|
||||
}
|
||||
|
||||
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() && !scaleErrorCode) {
|
||||
width = NS_MAX(width, (PRUint32)(screenWidth / scaleFloat));
|
||||
height = NS_MAX(height, (PRUint32)(screenHeight / scaleFloat));
|
||||
} else if (!maxScaleStr.IsEmpty() && !scaleMaxErrorCode) {
|
||||
width = NS_MAX(width, (PRUint32)(screenWidth / scaleMaxFloat));
|
||||
height = NS_MAX(height, (PRUint32)(screenHeight / scaleMaxFloat));
|
||||
}
|
||||
|
||||
bool allowZoom = true;
|
||||
nsAutoString userScalable;
|
||||
aDocument->GetHeaderData(nsGkAtoms::viewport_user_scalable, userScalable);
|
||||
|
||||
if ((userScalable.EqualsLiteral("0")) ||
|
||||
(userScalable.EqualsLiteral("no")) ||
|
||||
(userScalable.EqualsLiteral("false"))) {
|
||||
allowZoom = false;
|
||||
}
|
||||
|
||||
ret.allowZoom = allowZoom;
|
||||
ret.width = width;
|
||||
ret.height = height;
|
||||
ret.defaultZoom = scaleFloat;
|
||||
ret.minZoom = scaleMinFloat;
|
||||
ret.maxZoom = scaleMaxFloat;
|
||||
ret.autoSize = autoSize;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsContentUtils::ProcessViewportInfo(nsIDocument *aDocument,
|
||||
|
|
|
@ -4804,7 +4804,18 @@ nsLayoutUtils::FontSizeInflationFor(const nsIFrame *aFrame,
|
|||
/* static */ bool
|
||||
nsLayoutUtils::FontSizeInflationEnabled(nsPresContext *aPresContext)
|
||||
{
|
||||
return (sFontSizeInflationEmPerLine != 0 ||
|
||||
sFontSizeInflationMinTwips != 0) &&
|
||||
!aPresContext->IsChrome();
|
||||
if ((sFontSizeInflationEmPerLine == 0 &&
|
||||
sFontSizeInflationMinTwips == 0) ||
|
||||
aPresContext->IsChrome()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ViewportInfo vInf =
|
||||
nsContentUtils::GetViewportInfo(aPresContext->PresShell()->GetDocument());
|
||||
|
||||
if (vInf.defaultZoom >= 1.0 || vInf.autoSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<!--
|
||||
Without the patch for bug 706198, this website should not show up as inflated. That means
|
||||
that with a 450px container, the minimum font size with 15em per line should be 30px.
|
||||
So, we map 0px-45px into 30px-45px, and thus 12px gets mapped to 34px.
|
||||
|
||||
With the patch, the text should be uninflated, which means that 12px should still be
|
||||
12px.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta content='True' name='HandheldFriendly' />
|
||||
<style>
|
||||
p { font-size: 12px; line-height: 1.0;}
|
||||
</style>
|
||||
<body>
|
||||
<p>Some uninflated text.</p>
|
||||
</body>
|
||||
</head>
|
||||
</html>
|
|
@ -0,0 +1,20 @@
|
|||
<!--
|
||||
Without the patch for bug 706198, this website should not show up as inflated. That means
|
||||
that with a 450px container, the minimum font size with 15em per line should be 30px.
|
||||
So, we map 0px-45px into 30px-45px, and thus 12px gets mapped to 34px.
|
||||
|
||||
With the patch, the text should be uninflated, which means that 12px should still be
|
||||
12px.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
|
||||
<style>
|
||||
p { font-size: 12px; line-height: 1.0;}
|
||||
</style>
|
||||
<body>
|
||||
<p>Some uninflated text.</p>
|
||||
</body>
|
||||
</head>
|
||||
</html>
|
|
@ -0,0 +1,20 @@
|
|||
<!--
|
||||
Without the patch for bug 706198, this website should not show up as inflated. That means
|
||||
that with a 450px container, the minimum font size with 15em per line should be 30px.
|
||||
So, we map 0px-45px into 30px-45px, and thus 12px gets mapped to 34px.
|
||||
|
||||
With the patch, the text should be uninflated, which means that 12px should still be
|
||||
12px.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=320"/>
|
||||
<style>
|
||||
p { font-size: 12px; line-height: 1.0;}
|
||||
</style>
|
||||
<body>
|
||||
<p>Some uninflated text.</p>
|
||||
</body>
|
||||
</head>
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
<!--
|
||||
Without the patch for bug 706198, this website should not show up as inflated. That means
|
||||
that with a 450px container, the minimum font size with 15em per line should be 30px.
|
||||
So, we map 0px-45px into 30px-45px, and thus 12px gets mapped to 34px.
|
||||
|
||||
With the patch, the text should be uninflated, which means that 12px should still be
|
||||
12px.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
p { font-size: 12px; line-height: 1.0;}
|
||||
</style>
|
||||
<body>
|
||||
<p>Some uninflated text.</p>
|
||||
</body>
|
||||
</head>
|
||||
</html>
|
|
@ -0,0 +1,21 @@
|
|||
<?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">
|
||||
|
||||
<!--
|
||||
Without the patch for bug 706198, this website should not show up as inflated. That means
|
||||
that with a 450px container, the minimum font size with 15em per line should be 30px.
|
||||
So, we map 0px-45px into 30px-45px, and thus 12px gets mapped to 34px.
|
||||
|
||||
With the patch, the text should be uninflated, which means that 12px should still be
|
||||
12px.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
p { font-size: 12px; line-height: 1.0;}
|
||||
</style>
|
||||
<body>
|
||||
<p>Some uninflated text.</p>
|
||||
</body>
|
||||
</head>
|
||||
</html>
|
|
@ -61,6 +61,10 @@ var gTests = [
|
|||
"!= select-combobox-2.html select-combobox-2.html",
|
||||
"!= input-checkbox.html input-checkbox.html",
|
||||
"!= input-radio.html input-radio.html",
|
||||
"== disable-fontinfl-on-mobile.html disable-fontinfl-on-mobile-ref.html",
|
||||
"== disable-fontinfl-on-mobile-2.html disable-fontinfl-on-mobile-ref.html",
|
||||
"== disable-fontinfl-on-mobile-3.html disable-fontinfl-on-mobile-ref.html",
|
||||
"== disable-fontinfl-on-mobile-4.html disable-fontinfl-on-mobile-ref.html",
|
||||
];
|
||||
|
||||
// Maintain a reference count of how many things we're waiting for until
|
||||
|
|
Загрузка…
Ссылка в новой задаче