Bug 890195 - device-width media queries should use the page width, not the actual device width. r=bz

This commit is contained in:
Paul Rouget 2013-07-17 05:08:00 +02:00
parent fc4f06aac5
commit b042dc9c82
11 changed files with 155 additions and 2 deletions

View File

@ -180,6 +180,12 @@ function ResponsiveUI(aWindow, aTab)
this.buildUI();
this.checkMenus();
this.docShell = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
this.docShell.deviceSizeIsPageSize = true;
try {
if (Services.prefs.getBoolPref("devtools.responsiveUI.rotate")) {
this.rotate();
@ -252,6 +258,8 @@ ResponsiveUI.prototype = {
this.browser.removeEventListener("load", this.bound_onPageLoad, true);
this.browser.removeEventListener("unload", this.bound_onPageUnload, true);
this.docShell.deviceSizeIsPageSize = false;
if (this._floatingScrollbars)
switchToNativeScrollbars(this.tab);
@ -288,6 +296,7 @@ ResponsiveUI.prototype = {
this.container.removeAttribute("responsivemode");
this.stack.removeAttribute("responsivemode");
delete this.docShell;
delete this.tab.__responsiveUI;
if (this.touchEventHandler)
this.touchEventHandler.stop();

View File

@ -9,6 +9,7 @@ MOCHITEST_BROWSER_FILES := \
browser_responsive_cmd.js \
browser_responsivecomputedview.js \
browser_responsiveui_touch.js \
browser_responsive_devicewidth.js \
touch.html \
head.js \
$(NULL)

View File

@ -0,0 +1,61 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let instance;
let mgr = ResponsiveUI.ResponsiveUIManager;
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
waitForFocus(startTest, content);
}, true);
content.location = "data:text/html,mop";
function startTest() {
mgr.once("on", function() {executeSoon(onUIOpen)});
document.getElementById("Tools:ResponsiveUI").doCommand();
}
function onUIOpen() {
instance = gBrowser.selectedTab.__responsiveUI;
instance.stack.setAttribute("notransition", "true");
ok(instance, "instance of the module is attached to the tab.");
let mql = content.matchMedia("(max-device-width:100px)")
ok(!mql.matches, "media query doesn't match.");
mql.addListener(onMediaChange);
instance.setSize(90, 500);
}
function onMediaChange(mql) {
mql.removeListener(onMediaChange);
ok(mql.matches, "media query matches.");
ok(window.screen.width != content.screen.width, "screen.width is not the size of the screen.");
is(content.screen.width, 90, "screen.width is the width of the page.");
is(content.screen.height, 500, "screen.height is the height of the page.");
let docShell = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
mql.addListener(onMediaChange2);
docShell.deviceSizeIsPageSize = false;
}
function onMediaChange2(mql) {
mql.removeListener(onMediaChange);
ok(!mql.matches, "media query has been re-evaluated.");
ok(window.screen.width == content.screen.width, "screen.width is not the size of the screen.");
instance.stack.removeAttribute("notransition");
document.getElementById("Tools:ResponsiveUI").doCommand();
gBrowser.removeCurrentTab();
finish();
}
}

View File

@ -752,6 +752,7 @@ nsDocShell::nsDocShell():
mIsAppTab(false),
mUseGlobalHistory(false),
mInPrivateBrowsing(false),
mDeviceSizeIsPageSize(false),
mFiredUnloadEvent(false),
mEODForCurrentDocument(false),
mURIResultedInDocument(false),
@ -3934,6 +3935,27 @@ nsDocShell::GetCurrentSHEntry(nsISHEntry** aEntry, bool* aOSHE)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetDeviceSizeIsPageSize(bool aValue)
{
if (mDeviceSizeIsPageSize != aValue) {
mDeviceSizeIsPageSize = aValue;
nsRefPtr<nsPresContext> presContext;
GetPresContext(getter_AddRefs(presContext));
if (presContext) {
presContext->MediaFeatureValuesChanged(presContext->eAlwaysRebuildStyle);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetDeviceSizeIsPageSize(bool* aValue)
{
*aValue = mDeviceSizeIsPageSize;
return NS_OK;
}
void
nsDocShell::ClearFrameHistory(nsISHEntry* aEntry)
{

View File

@ -809,6 +809,7 @@ protected:
bool mIsAppTab;
bool mUseGlobalHistory;
bool mInPrivateBrowsing;
bool mDeviceSizeIsPageSize;
// This boolean is set to true right before we fire pagehide and generally
// unset when we embed a new content viewer. While it's true no navigation

View File

@ -916,4 +916,12 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
boolean isCommandEnabled(in string command);
void doCommand(in string command);
/**
* If deviceSizeIsPageSize is set to true, device-width/height media queries
* will be calculated from the page size, not the device size.
*
* Used by the Responsive Design View.
*/
[infallible] attribute boolean deviceSizeIsPageSize;
};

View File

@ -385,6 +385,19 @@ nsScreen::SlowMozUnlockOrientation()
return NS_OK;
}
bool
nsScreen::IsDeviceSizePageSize()
{
nsPIDOMWindow* owner = GetOwner();
if (owner) {
nsIDocShell* docShell = owner->GetDocShell();
if (docShell) {
return docShell->GetDeviceSizeIsPageSize();
}
}
return false;
}
/* virtual */
JSObject*
nsScreen::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)

View File

@ -51,6 +51,15 @@ public:
int32_t GetWidth(ErrorResult& aRv)
{
nsRect rect;
if (IsDeviceSizePageSize()) {
nsCOMPtr<nsPIDOMWindow> owner = GetOwner();
if (owner) {
int32_t innerWidth = 0;
aRv = owner->GetInnerWidth(&innerWidth);
return innerWidth;
}
}
aRv = GetRect(rect);
return rect.width;
}
@ -58,6 +67,15 @@ public:
int32_t GetHeight(ErrorResult& aRv)
{
nsRect rect;
if (IsDeviceSizePageSize()) {
nsCOMPtr<nsPIDOMWindow> owner = GetOwner();
if (owner) {
int32_t innerHeight = 0;
aRv = owner->GetInnerHeight(&innerHeight);
return innerHeight;
}
}
aRv = GetRect(rect);
return rect.height;
}
@ -137,6 +155,8 @@ private:
LockPermission GetLockOrientationPermission() const;
bool IsDeviceSizePageSize();
nsRefPtr<FullScreenEventListener> mEventListener;
};

View File

@ -2672,6 +2672,17 @@ bool nsPresContext::GetPaintFlashing() const
return mPaintFlashing;
}
bool
nsPresContext::IsDeviceSizePageSize()
{
bool isDeviceSizePageSize = false;
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
if (docShell) {
isDeviceSizePageSize = docShell->GetDeviceSizeIsPageSize();
}
return isDeviceSizePageSize;
}
nsRootPresContext::nsRootPresContext(nsIDocument* aDocument,
nsPresContextType aType)
: nsPresContext(aDocument, aType),

View File

@ -1003,6 +1003,8 @@ public:
mExistThrottledUpdates = aExistThrottledUpdates;
}
bool IsDeviceSizePageSize();
protected:
friend class nsRunnableMethod<nsPresContext>;
NS_HIDDEN_(void) ThemeChangedInternal();

View File

@ -111,14 +111,19 @@ static nsSize
GetDeviceSize(nsPresContext* aPresContext)
{
nsSize size;
if (aPresContext->IsRootPaginatedDocument())
if (aPresContext->IsDeviceSizePageSize()) {
size = GetSize(aPresContext);
} else if (aPresContext->IsRootPaginatedDocument()) {
// We want the page size, including unprintable areas and margins.
// XXX The spec actually says we want the "page sheet size", but
// how is that different?
size = aPresContext->GetPageSize();
else
} else {
GetDeviceContextFor(aPresContext)->
GetDeviceSurfaceDimensions(size.width, size.height);
}
return size;
}