mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 14:25:52 +00:00
bug 793755 - Talos Regressions Trobopan, Tdhtml, tp4m_nochrome on Sept 22, cache information about the viewport r=jwir3
This commit is contained in:
parent
613983a388
commit
6cb0d7645f
@ -75,6 +75,7 @@ class nsTextNode;
|
||||
class nsWindowSizes;
|
||||
class nsSmallVoidArray;
|
||||
class nsDOMCaretPosition;
|
||||
class nsViewportInfo;
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
@ -562,6 +563,10 @@ public:
|
||||
*/
|
||||
Element* GetRootElement() const;
|
||||
|
||||
virtual nsViewportInfo GetViewportInfo(uint32_t aDisplayWidth,
|
||||
uint32_t aDisplayHeight) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
virtual Element *GetRootElementInternal() const = 0;
|
||||
|
||||
|
@ -5053,164 +5053,7 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
|
||||
uint32_t aDisplayWidth,
|
||||
uint32_t aDisplayHeight)
|
||||
{
|
||||
nsAutoString viewport;
|
||||
aDocument->GetHeaderData(nsGkAtoms::viewport, viewport);
|
||||
if (viewport.IsEmpty()) {
|
||||
// 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))
|
||||
{
|
||||
nsViewportInfo ret(aDisplayWidth, aDisplayHeight);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString handheldFriendly;
|
||||
aDocument->GetHeaderData(nsGkAtoms::handheldFriendly, handheldFriendly);
|
||||
if (handheldFriendly.EqualsLiteral("true")) {
|
||||
nsViewportInfo ret(aDisplayWidth, aDisplayHeight);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString minScaleStr;
|
||||
aDocument->GetHeaderData(nsGkAtoms::viewport_minimum_scale, minScaleStr);
|
||||
|
||||
nsresult errorCode;
|
||||
float scaleMinFloat = minScaleStr.ToFloat(&errorCode);
|
||||
|
||||
if (NS_FAILED(errorCode)) {
|
||||
scaleMinFloat = kViewportMinScale;
|
||||
}
|
||||
|
||||
scaleMinFloat = NS_MIN((double)scaleMinFloat, kViewportMaxScale);
|
||||
scaleMinFloat = NS_MAX((double)scaleMinFloat, kViewportMinScale);
|
||||
|
||||
nsAutoString maxScaleStr;
|
||||
aDocument->GetHeaderData(nsGkAtoms::viewport_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).
|
||||
nsresult scaleMaxErrorCode;
|
||||
float scaleMaxFloat = maxScaleStr.ToFloat(&scaleMaxErrorCode);
|
||||
|
||||
if (NS_FAILED(scaleMaxErrorCode)) {
|
||||
scaleMaxFloat = kViewportMaxScale;
|
||||
}
|
||||
|
||||
scaleMaxFloat = NS_MIN((double)scaleMaxFloat, kViewportMaxScale);
|
||||
scaleMaxFloat = NS_MAX((double)scaleMaxFloat, kViewportMinScale);
|
||||
|
||||
nsAutoString scaleStr;
|
||||
aDocument->GetHeaderData(nsGkAtoms::viewport_initial_scale, scaleStr);
|
||||
|
||||
nsresult scaleErrorCode;
|
||||
float scaleFloat = scaleStr.ToFloat(&scaleErrorCode);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Now convert the scale into device pixels per CSS pixel.
|
||||
nsIWidget *widget = WidgetForDocument(aDocument);
|
||||
double pixelRatio = widget ? GetDevicePixelsPerMetaViewportPixel(widget) : 1.0;
|
||||
scaleFloat *= pixelRatio;
|
||||
scaleMinFloat *= pixelRatio;
|
||||
scaleMaxFloat *= pixelRatio;
|
||||
|
||||
uint32_t width, height;
|
||||
if (autoSize) {
|
||||
// aDisplayWidth and aDisplayHeight are in device pixels; convert them to
|
||||
// CSS pixels for the viewport size.
|
||||
width = aDisplayWidth / pixelRatio;
|
||||
height = aDisplayHeight / pixelRatio;
|
||||
} else {
|
||||
nsresult widthErrorCode, heightErrorCode;
|
||||
width = widthStr.ToInteger(&widthErrorCode);
|
||||
height = heightStr.ToInteger(&heightErrorCode);
|
||||
|
||||
// If width or height has not been set to a valid number by this point,
|
||||
// fall back to a default value.
|
||||
bool validWidth = (!widthStr.IsEmpty() && NS_SUCCEEDED(widthErrorCode) && width > 0);
|
||||
bool validHeight = (!heightStr.IsEmpty() && NS_SUCCEEDED(heightErrorCode) && height > 0);
|
||||
|
||||
if (!validWidth) {
|
||||
if (validHeight && aDisplayWidth > 0 && aDisplayHeight > 0) {
|
||||
width = uint32_t((height * aDisplayWidth) / aDisplayHeight);
|
||||
} else {
|
||||
width = Preferences::GetInt("browser.viewport.desktopWidth",
|
||||
kViewportDefaultScreenWidth);
|
||||
}
|
||||
}
|
||||
|
||||
if (!validHeight) {
|
||||
if (aDisplayWidth > 0 && aDisplayHeight > 0) {
|
||||
height = uint32_t((width * aDisplayHeight) / aDisplayWidth);
|
||||
} else {
|
||||
height = width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
width = NS_MAX(width, (uint32_t)(aDisplayWidth / scaleFloat));
|
||||
height = NS_MAX(height, (uint32_t)(aDisplayHeight / scaleFloat));
|
||||
} else if (!maxScaleStr.IsEmpty() && NS_SUCCEEDED(scaleMaxErrorCode)) {
|
||||
width = NS_MAX(width, (uint32_t)(aDisplayWidth / scaleMaxFloat));
|
||||
height = NS_MAX(height, (uint32_t)(aDisplayHeight / 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;
|
||||
}
|
||||
|
||||
nsViewportInfo ret(scaleFloat, scaleMinFloat, scaleMaxFloat, width, height,
|
||||
autoSize, allowZoom);
|
||||
return ret;
|
||||
return aDocument->GetViewportInfo(aDisplayWidth, aDisplayHeight);
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -188,6 +188,7 @@
|
||||
#include "nsFrame.h"
|
||||
#include "nsDOMCaretPosition.h"
|
||||
#include "nsIDOMHTMLTextAreaElement.h"
|
||||
#include "nsViewportInfo.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -1326,6 +1327,7 @@ nsIDocument::nsIDocument()
|
||||
nsDocument::nsDocument(const char* aContentType)
|
||||
: nsIDocument()
|
||||
, mAnimatingImages(true)
|
||||
, mViewportType(Unknown)
|
||||
{
|
||||
SetContentTypeInternal(nsDependentCString(aContentType));
|
||||
|
||||
@ -3089,6 +3091,17 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAString& aData)
|
||||
// Chromium treats any value other than 'on' (case insensitive) as 'off'.
|
||||
mAllowDNSPrefetch = aData.IsEmpty() || aData.LowerCaseEqualsLiteral("on");
|
||||
}
|
||||
|
||||
if (aHeaderField == nsGkAtoms::viewport ||
|
||||
aHeaderField == nsGkAtoms::handheldFriendly ||
|
||||
aHeaderField == nsGkAtoms::viewport_minimum_scale ||
|
||||
aHeaderField == nsGkAtoms::viewport_maximum_scale ||
|
||||
aHeaderField == nsGkAtoms::viewport_initial_scale ||
|
||||
aHeaderField == nsGkAtoms::viewport_height ||
|
||||
aHeaderField == nsGkAtoms::viewport_width ||
|
||||
aHeaderField == nsGkAtoms::viewport_user_scalable) {
|
||||
mViewportType = Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@ -6376,6 +6389,186 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
|
||||
return adoptedNode;
|
||||
}
|
||||
|
||||
nsViewportInfo
|
||||
nsDocument::GetViewportInfo(uint32_t aDisplayWidth,
|
||||
uint32_t aDisplayHeight)
|
||||
{
|
||||
switch (mViewportType) {
|
||||
case DisplayWidthHeight:
|
||||
return nsViewportInfo(aDisplayWidth, aDisplayHeight);
|
||||
case Unknown:
|
||||
{
|
||||
nsAutoString viewport;
|
||||
GetHeaderData(nsGkAtoms::viewport, viewport);
|
||||
if (viewport.IsEmpty()) {
|
||||
// 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<nsIDOMDocumentType> docType;
|
||||
nsresult rv = 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))
|
||||
{
|
||||
mViewportType = DisplayWidthHeight;
|
||||
nsViewportInfo ret(aDisplayWidth, aDisplayHeight);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString handheldFriendly;
|
||||
GetHeaderData(nsGkAtoms::handheldFriendly, handheldFriendly);
|
||||
if (handheldFriendly.EqualsLiteral("true")) {
|
||||
mViewportType = DisplayWidthHeight;
|
||||
nsViewportInfo ret(aDisplayWidth, aDisplayHeight);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString minScaleStr;
|
||||
GetHeaderData(nsGkAtoms::viewport_minimum_scale, minScaleStr);
|
||||
|
||||
nsresult errorCode;
|
||||
mScaleMinFloat = minScaleStr.ToFloat(&errorCode);
|
||||
|
||||
if (NS_FAILED(errorCode)) {
|
||||
mScaleMinFloat = kViewportMinScale;
|
||||
}
|
||||
|
||||
mScaleMinFloat = NS_MIN((double)mScaleMinFloat, kViewportMaxScale);
|
||||
mScaleMinFloat = NS_MAX((double)mScaleMinFloat, kViewportMinScale);
|
||||
|
||||
nsAutoString maxScaleStr;
|
||||
GetHeaderData(nsGkAtoms::viewport_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).
|
||||
nsresult scaleMaxErrorCode;
|
||||
mScaleMaxFloat = maxScaleStr.ToFloat(&scaleMaxErrorCode);
|
||||
|
||||
if (NS_FAILED(scaleMaxErrorCode)) {
|
||||
mScaleMaxFloat = kViewportMaxScale;
|
||||
}
|
||||
|
||||
mScaleMaxFloat = NS_MIN((double)mScaleMaxFloat, kViewportMaxScale);
|
||||
mScaleMaxFloat = NS_MAX((double)mScaleMaxFloat, kViewportMinScale);
|
||||
|
||||
nsAutoString scaleStr;
|
||||
GetHeaderData(nsGkAtoms::viewport_initial_scale, scaleStr);
|
||||
|
||||
nsresult scaleErrorCode;
|
||||
mScaleFloat = scaleStr.ToFloat(&scaleErrorCode);
|
||||
|
||||
nsAutoString widthStr, heightStr;
|
||||
|
||||
GetHeaderData(nsGkAtoms::viewport_height, heightStr);
|
||||
GetHeaderData(nsGkAtoms::viewport_width, widthStr);
|
||||
|
||||
mAutoSize = false;
|
||||
|
||||
if (widthStr.EqualsLiteral("device-width")) {
|
||||
mAutoSize = true;
|
||||
}
|
||||
|
||||
if (widthStr.IsEmpty() && heightStr.EqualsLiteral("device-height")) {
|
||||
mAutoSize = true;
|
||||
}
|
||||
|
||||
nsresult widthErrorCode, heightErrorCode;
|
||||
mViewportWidth = widthStr.ToInteger(&widthErrorCode);
|
||||
mViewportHeight = heightStr.ToInteger(&heightErrorCode);
|
||||
|
||||
// If width or height has not been set to a valid number by this point,
|
||||
// fall back to a default value.
|
||||
bool validWidth = (!widthStr.IsEmpty() && NS_SUCCEEDED(widthErrorCode) && mViewportWidth > 0);
|
||||
bool validHeight = (!heightStr.IsEmpty() && NS_SUCCEEDED(heightErrorCode) && mViewportHeight > 0);
|
||||
|
||||
if (!validWidth) {
|
||||
if (validHeight && aDisplayWidth > 0 && aDisplayHeight > 0) {
|
||||
mViewportWidth = uint32_t((mViewportHeight * aDisplayWidth) / aDisplayHeight);
|
||||
} else {
|
||||
mViewportWidth = Preferences::GetInt("browser.viewport.desktopWidth",
|
||||
kViewportDefaultScreenWidth);
|
||||
}
|
||||
}
|
||||
|
||||
if (!validHeight) {
|
||||
if (aDisplayWidth > 0 && aDisplayHeight > 0) {
|
||||
mViewportHeight = uint32_t((mViewportWidth * aDisplayHeight) / aDisplayWidth);
|
||||
} else {
|
||||
mViewportHeight = mViewportWidth;
|
||||
}
|
||||
}
|
||||
|
||||
mAllowZoom = true;
|
||||
nsAutoString userScalable;
|
||||
GetHeaderData(nsGkAtoms::viewport_user_scalable, userScalable);
|
||||
|
||||
if ((userScalable.EqualsLiteral("0")) ||
|
||||
(userScalable.EqualsLiteral("no")) ||
|
||||
(userScalable.EqualsLiteral("false"))) {
|
||||
mAllowZoom = false;
|
||||
}
|
||||
|
||||
mScaleStrEmpty = scaleStr.IsEmpty();
|
||||
mWidthStrEmpty = widthStr.IsEmpty();
|
||||
mValidScaleFloat = !scaleStr.IsEmpty() && NS_SUCCEEDED(scaleErrorCode);
|
||||
mValidMaxScale = !maxScaleStr.IsEmpty() && NS_SUCCEEDED(scaleMaxErrorCode);
|
||||
|
||||
mViewportType = Specified;
|
||||
}
|
||||
case Specified:
|
||||
default:
|
||||
// Now convert the scale into device pixels per CSS pixel.
|
||||
nsIWidget *widget = nsContentUtils::WidgetForDocument(this);
|
||||
double pixelRatio = widget ? nsContentUtils::GetDevicePixelsPerMetaViewportPixel(widget) : 1.0;
|
||||
float scaleFloat = mScaleFloat * pixelRatio;
|
||||
float scaleMinFloat= mScaleMinFloat * pixelRatio;
|
||||
float scaleMaxFloat = mScaleMaxFloat * pixelRatio;
|
||||
|
||||
uint32_t width, height;
|
||||
if (mAutoSize) {
|
||||
// aDisplayWidth and aDisplayHeight are in device pixels; convert them to
|
||||
// CSS pixels for the viewport size.
|
||||
width = aDisplayWidth / pixelRatio;
|
||||
height = aDisplayHeight / pixelRatio;
|
||||
} else {
|
||||
width = mViewportWidth;
|
||||
height = mViewportHeight;
|
||||
}
|
||||
|
||||
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 (mScaleStrEmpty && !mWidthStrEmpty) {
|
||||
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 (mValidScaleFloat) {
|
||||
width = NS_MAX(width, (uint32_t)(aDisplayWidth / scaleFloat));
|
||||
height = NS_MAX(height, (uint32_t)(aDisplayHeight / scaleFloat));
|
||||
} else if (mValidMaxScale) {
|
||||
width = NS_MAX(width, (uint32_t)(aDisplayWidth / scaleMaxFloat));
|
||||
height = NS_MAX(height, (uint32_t)(aDisplayHeight / scaleMaxFloat));
|
||||
}
|
||||
|
||||
nsViewportInfo ret(scaleFloat, scaleMinFloat, scaleMaxFloat, width, height,
|
||||
mAutoSize || (mWidthStrEmpty && scaleFloat == 1.0), mAllowZoom);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
nsEventListenerManager*
|
||||
nsDocument::GetListenerManager(bool aCreateIfNotFound)
|
||||
{
|
||||
|
@ -738,6 +738,10 @@ public:
|
||||
nsRadioGroupStruct* GetRadioGroup(const nsAString& aName) const;
|
||||
nsRadioGroupStruct* GetOrCreateRadioGroup(const nsAString& aName);
|
||||
|
||||
virtual nsViewportInfo GetViewportInfo(uint32_t aDisplayWidth,
|
||||
uint32_t aDisplayHeight);
|
||||
|
||||
|
||||
private:
|
||||
nsRadioGroupStruct* GetRadioGroupInternal(const nsAString& aName) const;
|
||||
|
||||
@ -1359,6 +1363,20 @@ private:
|
||||
|
||||
nsRefPtr<mozilla::dom::UndoManager> mUndoManager;
|
||||
|
||||
enum ViewportType {
|
||||
DisplayWidthHeight,
|
||||
Specified,
|
||||
Unknown
|
||||
};
|
||||
|
||||
ViewportType mViewportType;
|
||||
|
||||
// These member variables cache information about the viewport so we don't have to
|
||||
// recalculate it each time.
|
||||
float mScaleMinFloat, mScaleMaxFloat, mScaleFloat, mPixelRatio;
|
||||
bool mAutoSize, mAllowZoom, mValidScaleFloat, mValidMaxScale, mScaleStrEmpty, mWidthStrEmpty;
|
||||
uint32_t mViewportWidth, mViewportHeight;
|
||||
|
||||
#ifdef DEBUG
|
||||
protected:
|
||||
bool mWillReparent;
|
||||
|
Loading…
Reference in New Issue
Block a user