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
Родитель d4123b08f8
Коммит dfd208bb19
11 изменённых файлов: 155 добавлений и 2 удалений

Просмотреть файл

@ -171,6 +171,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();
@ -208,6 +214,8 @@ ResponsiveUI.prototype = {
return;
this.closing = true;
this.docShell.deviceSizeIsPageSize = false;
if (this._floatingScrollbars)
switchToNativeScrollbars(this.tab);
@ -241,6 +249,7 @@ ResponsiveUI.prototype = {
this.container.removeAttribute("responsivemode");
this.stack.removeAttribute("responsivemode");
delete this.docShell;
delete this.tab.__responsiveUI;
this._telemetry.toolClosed("responsive");
ResponsiveUIManager.emit("off", this.tab, this);

Просмотреть файл

@ -16,6 +16,7 @@ MOCHITEST_BROWSER_FILES := \
browser_responsiveruleview.js \
browser_responsive_cmd.js \
browser_responsivecomputedview.js \
browser_responsive_devicewidth.js \
head.js \
$(NULL)

Просмотреть файл

@ -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();
}
}

Просмотреть файл

@ -771,6 +771,7 @@ nsDocShell::nsDocShell():
mIsAppTab(false),
mUseGlobalHistory(false),
mInPrivateBrowsing(false),
mDeviceSizeIsPageSize(false),
mFiredUnloadEvent(false),
mEODForCurrentDocument(false),
mURIResultedInDocument(false),
@ -3930,6 +3931,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)
{

Просмотреть файл

@ -824,6 +824,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

Просмотреть файл

@ -873,4 +873,12 @@ interface nsIDocShell : nsIDocShellTreeItem
* Returns false for mLSHE, true for mOSHE
*/
boolean getCurrentSHEntry(out nsISHEntry aEntry);
/**
* 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;
};

Просмотреть файл

@ -387,6 +387,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)

Просмотреть файл

@ -56,6 +56,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;
}
@ -63,6 +72,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;
}
@ -145,6 +163,8 @@ private:
LockPermission GetLockOrientationPermission() const;
bool IsDeviceSizePageSize();
nsRefPtr<FullScreenEventListener> mEventListener;
};

Просмотреть файл

@ -2586,6 +2586,17 @@ nsPresContext::IsCrossProcessRootContentDocument()
return (tabChild && tabChild->IsRootContentDocument());
}
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),

Просмотреть файл

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

Просмотреть файл

@ -109,14 +109,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;
}