Bug 716575 (1/4) - Add a scriptable interface to GetViewportInfo [r=dbaron]

This commit is contained in:
Matt Brubeck 2012-08-22 13:17:20 -07:00
parent 5e5744a41b
commit 7eeb4d9731
5 changed files with 89 additions and 41 deletions

View File

@ -1537,10 +1537,17 @@ public:
* which places the viewport information in the document header instead
* of returning it directly.
*
* @param aDisplayWidth width of the on-screen display area for this
* document, in device pixels.
* @param aDisplayHeight height of the on-screen display area for this
* document, in device pixels.
*
* 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);
static ViewportInfo GetViewportInfo(nsIDocument* aDocument,
uint32_t aDisplayWidth,
uint32_t aDisplayHeight);
// Call EnterMicroTask when you're entering JS execution.
// Usually the best way to do this is to use nsAutoMicroTask.

View File

@ -5083,7 +5083,9 @@ static void ProcessViewportToken(nsIDocument *aDocument,
/* static */
ViewportInfo
nsContentUtils::GetViewportInfo(nsIDocument *aDocument)
nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
uint32_t aDisplayWidth,
uint32_t aDisplayHeight)
{
ViewportInfo ret;
ret.defaultZoom = 1.0;
@ -5172,35 +5174,10 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument)
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;
int32_t 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);
uint32_t width = widthStr.ToInteger(&errorCode);
if (NS_FAILED(errorCode)) {
if (autoSize) {
width = screenWidth;
width = aDisplayWidth;
} else {
width = Preferences::GetInt("browser.viewport.desktopWidth", 0);
}
@ -5212,19 +5189,19 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument)
// 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));
scaleFloat = NS_MAX(scaleFloat, (float)(aDisplayWidth/width));
}
uint32_t height = heightStr.ToInteger(&errorCode);
if (NS_FAILED(errorCode)) {
height = width * ((float)screenHeight / screenWidth);
height = width * ((float)aDisplayHeight / aDisplayWidth);
}
// If height was provided by the user, but width wasn't, then we should
// calculate the width.
if (widthStr.IsEmpty() && !heightStr.IsEmpty()) {
width = (uint32_t) ((height * screenWidth) / screenHeight);
width = (uint32_t) ((height * aDisplayWidth) / aDisplayHeight);
}
height = NS_MIN(height, kViewportMaxHeight);
@ -5233,11 +5210,11 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument)
// 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)(screenWidth / scaleFloat));
height = NS_MAX(height, (uint32_t)(screenHeight / scaleFloat));
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)(screenWidth / scaleMaxFloat));
height = NS_MAX(height, (uint32_t)(screenHeight / scaleMaxFloat));
width = NS_MAX(width, (uint32_t)(aDisplayWidth / scaleMaxFloat));
height = NS_MAX(height, (uint32_t)(aDisplayHeight / scaleMaxFloat));
}
bool allowZoom = true;

View File

@ -177,7 +177,7 @@ nsDOMWindowUtils::GetDocCharsetIsForced(bool *aIsForced)
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
if (window) {
nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
*aIsForced = doc &&
doc->GetDocumentCharacterSetSource() >= kCharsetFromParentForced;
}
@ -263,6 +263,31 @@ nsDOMWindowUtils::SetCSSViewport(float aWidthPx, float aHeightPx)
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::GetViewportInfo(uint32_t aDisplayWidth,
uint32_t aDisplayHeight,
double *aDefaultZoom, bool *aAllowZoom,
double *aMinZoom, double *aMaxZoom,
uint32_t *aWidth, uint32_t *aHeight,
bool *aAutoSize)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
NS_ENSURE_STATE(doc);
ViewportInfo info = nsContentUtils::GetViewportInfo(doc, aDisplayWidth, aDisplayHeight);
*aDefaultZoom = info.defaultZoom;
*aAllowZoom = info.allowZoom;
*aMinZoom = info.minZoom;
*aMaxZoom = info.maxZoom;
*aWidth = info.width;
*aHeight = info.height;
*aAutoSize = info.autoSize;
return NS_OK;
}
static void DestroyNsRect(void* aObject, nsIAtom* aPropertyName,
void* aPropertyValue, void* aData)
{

View File

@ -40,7 +40,7 @@ interface nsIDOMTouch;
interface nsIDOMClientRect;
interface nsIURI;
[scriptable, uuid(6cf3e8f0-fb82-11e1-a21f-0800200c9a66)]
[scriptable, uuid(90d8e97b-2c61-4c05-9f1c-e568d22f5bdc)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -103,6 +103,16 @@ interface nsIDOMWindowUtils : nsISupports {
*/
void setCSSViewport(in float aWidthPx, in float aHeightPx);
/**
* Information retrieved from the <meta name="viewport"> tag.
* See nsContentUtils::GetViewportInfo for more information.
*/
void getViewportInfo(in uint32_t aDisplayWidth, in uint32_t aDisplayHeight,
out double aDefaultZoom, out boolean aAllowZoom,
out double aMinZoom, out double aMaxZoom,
out uint32_t aWidth, out uint32_t aHeight,
out boolean aAutoSize);
/**
* For any scrollable element, this allows you to override the
* visible region and draw more than what is visible, which is

View File

@ -5066,11 +5066,40 @@ nsLayoutUtils::FontSizeInflationEnabled(nsPresContext *aPresContext)
return false;
}
ViewportInfo vInf =
nsContentUtils::GetViewportInfo(aPresContext->PresShell()->GetDocument());
// 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.
if (vInf.defaultZoom >= 1.0 || vInf.autoSize) {
return false;
// TODO:
// Once bug 716575 has been resolved, this code should be changed so that it
// does the right thing on all platforms.
nsresult rv;
nsCOMPtr<nsIScreenManager> screenMgr =
do_GetService("@mozilla.org/gfx/screenmanager;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIScreen> screen;
screenMgr->GetPrimaryScreen(getter_AddRefs(screen));
if (screen) {
int32_t screenLeft, screenTop, screenWidth, screenHeight;
screen->GetRect(&screenLeft, &screenTop, &screenWidth, &screenHeight);
ViewportInfo vInf =
nsContentUtils::GetViewportInfo(aPresContext->PresShell()->GetDocument(),
screenWidth, screenHeight);
if (vInf.defaultZoom >= 1.0 || vInf.autoSize) {
return false;
}
}
return true;