Bug 562773 - Viewport is not resized on window resize / orientation change [r=mfinkle r=stechz]

This commit is contained in:
Matt Brubeck 2010-05-05 15:51:58 -04:00
parent fed9dd6753
commit 7f6fc000ba
4 changed files with 99 additions and 94 deletions

View File

@ -347,7 +347,7 @@ BrowserView.prototype = {
}
let rounded = Math.round(bounded * kBrowserViewZoomLevelPrecision) / kBrowserViewZoomLevelPrecision;
return (rounded) ? rounded : 1.0;
return rounded || 1.0;
},
beginOffscreenOperation: function beginOffscreenOperation(rect) {
@ -595,8 +595,6 @@ BrowserView.prototype = {
if (!bvs)
return false;
bvs.metaData = Util.getViewportMetadata(this._browser);
let isDefault = (bvs.zoomLevel == bvs.defaultZoomLevel);
bvs.defaultZoomLevel = this.getDefaultZoomLevel();
if (isDefault)
@ -626,7 +624,7 @@ BrowserView.prototype = {
let md = bvs.metaData;
if (md && md.defaultZoom)
pageZoom = Math.max(pageZoom, md.defaultZoom);
return Math.max(pageZoom, this.clampZoomLevel(md.defaultZoom));
return pageZoom;
},

View File

@ -125,23 +125,19 @@ let Util = {
getViewportMetadata: function getViewportMetadata(browser) {
let dpiScale = gPrefService.getIntPref("zoom.dpiScale") / 100;
// Device size in CSS pixels:
let deviceWidth = window.innerWidth / dpiScale;
let deviceHeight = window.innerHeight / dpiScale;
let doctype = browser.contentDocument.doctype;
if (doctype && /(WAP|WML|Mobile)/.test(doctype.publicId))
return { reason: "doctype", result: true, defaultZoom: dpiScale, width: deviceWidth };
return { defaultZoom: dpiScale, autoSize: true };
let windowUtils = browser.contentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let handheldFriendly = windowUtils.getDocumentMetadata("HandheldFriendly");
if (handheldFriendly == "true")
return { reason: "handheld", defaultZoom: dpiScale, width: deviceWidth };
return { defaultZoom: dpiScale, autoSize: true };
if (browser.contentDocument instanceof XULDocument)
return { reason: "chrome", defaultZoom: 1.0, autoSize: true, allowZoom: false };
return { defaultZoom: 1.0, autoSize: true, allowZoom: false };
// viewport details found here
// http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html
@ -155,18 +151,17 @@ let Util = {
let viewportWidthStr = windowUtils.getDocumentMetadata("viewport-width");
let viewportHeightStr = windowUtils.getDocumentMetadata("viewport-height");
viewportScale = Util.clamp(viewportScale, kViewportMinScale, kViewportMaxScale);
viewportScale = Util.clamp(viewportScale, kViewportMinScale, kViewportMaxScale);
viewportMinScale = Util.clamp(viewportMinScale, kViewportMinScale, kViewportMaxScale);
viewportMaxScale = Util.clamp(viewportMaxScale, kViewportMinScale, kViewportMaxScale);
// If initial scale is 1.0 and width is not set, assume width=device-width
if (viewportScale == 1.0 && !viewportWidthStr)
viewportWidthStr = "device-width";
let autoSize = (viewportWidthStr == "device-width" ||
viewportHeightStr == "device-height" ||
(viewportScale == 1.0 && !viewportWidthStr));
let viewportWidth = viewportWidthStr == "device-width" ? deviceWidth
: Util.clamp(parseInt(viewportWidthStr), kViewportMinWidth, kViewportMaxWidth);
let viewportHeight = viewportHeightStr == "device-height" ? deviceHeight
: Util.clamp(parseInt(viewportHeightStr), kViewportMinHeight, kViewportMaxHeight);
let viewportWidth = Util.clamp(parseInt(viewportWidthStr), kViewportMinWidth, kViewportMaxWidth);
let viewportHeight = Util.clamp(parseInt(viewportHeightStr), kViewportMinHeight, kViewportMaxHeight);
// Zoom level is the final (device pixel : CSS pixel) ratio for content.
// Since web content specifies scale as (reference pixel : CSS pixel) ratio,
@ -175,29 +170,19 @@ let Util = {
//
// See bug 561445 or any of the examples of chrome/tests/browser_viewport_XX.html
// for more information and examples.
let defaultZoom = viewportScale * dpiScale;
let minZoom = viewportMinScale * dpiScale;
let maxZoom = viewportMaxScale * dpiScale;
let defaultZoom = viewportScale * dpiScale;
let minZoom = viewportMinScale * dpiScale;
let maxZoom = viewportMaxScale * dpiScale;
// If (scale * width) < device-width, increase the width (bug 561413).
let maxInitialZoom = defaultZoom || maxZoom;
if (maxInitialZoom && viewportWidth)
viewportWidth = Math.max(viewportWidth, window.innerWidth / maxInitialZoom);
if (viewportScale > 0 || viewportWidth > 0 || viewportHeight > 0 || viewportMinScale > 0 || viewportMaxScale > 0) {
return {
reason: "viewport",
defaultZoom: defaultZoom,
minZoom: minZoom,
maxZoom: maxZoom,
width: viewportWidth,
height: viewportHeight,
autoSize: viewportWidthStr == "device-width" || viewportHeightStr == "device-height",
allowZoom: windowUtils.getDocumentMetadata("viewport-user-scalable") != "no"
};
}
return { reason: null, allowZoom: true };
return {
defaultZoom: defaultZoom,
minZoom: minZoom,
maxZoom: maxZoom,
width: viewportWidth,
height: viewportHeight,
autoSize: autoSize,
allowZoom: windowUtils.getDocumentMetadata("viewport-user-scalable") != "no"
};
},
clamp: function(num, min, max) {

View File

@ -380,7 +380,7 @@ var Browser = {
bv.beginBatchOperation();
let stylesheet = document.styleSheets[0];
for each (let style in ["viewport-width", "viewport-height", "window-width", "window-height", "toolbar-height", "browser", "browser-viewport"]) {
for each (let style in ["viewport-width", "viewport-height", "window-width", "window-height", "toolbar-height"]) {
let index = stylesheet.insertRule("." + style + " {}", stylesheet.cssRules.length);
this.styles[style] = stylesheet.cssRules[index].style;
}
@ -408,8 +408,6 @@ var Browser = {
Browser.styles["window-width"].width = w + "px";
Browser.styles["window-height"].height = h + "px";
Browser.styles["toolbar-height"].height = toolbarHeight + "px";
Browser.styles["browser"].width = kDefaultBrowserWidth + "px";
Browser.styles["browser"].height = scaledDefaultH + "px";
// Cause a resize of the viewport if the current browser holds a XUL document
let browser = Browser.selectedBrowser;
@ -434,6 +432,9 @@ var Browser = {
Browser.hideSidebars();
bv.onAfterVisibleMove();
for (let i = Browser._tabs.length - 1; i >= 0; i--)
Browser._tabs[i].updateViewportSize();
bv.commitBatchOperation();
let curEl = document.activeElement;
@ -2992,6 +2993,76 @@ Tab.prototype = {
Browser._browserView.commitBatchOperation();
},
/** Update browser styles when the viewport metadata changes. */
updateViewportMetadata: function updateViewportMetadata() {
let browser = this._browser;
if (!browser)
return;
let metaData = Util.getViewportMetadata(this._browser);
this._browserViewportState.metaData = metaData;
// Remove any previous styles.
browser.className = "";
browser.style.removeProperty("width");
browser.style.removeProperty("height");
// Add classes for auto-sizing viewports.
if (metaData.autoSize) {
if (metaData.defaultZoom == 1.0) {
browser.classList.add("window-width");
browser.classList.add("window-height");
} else {
browser.classList.add("viewport-width");
browser.classList.add("viewport-height");
}
}
this.updateViewportSize();
},
/** Update browser size when the metadata or the window size changes. */
updateViewportSize: function updateViewportSize() {
let browser = this._browser;
let metaData = this._browserViewportState.metaData
if (!browser || !metaData)
return;
if (!metaData.autoSize) {
let screenW = window.innerWidth;
let screenH = window.innerHeight;
let viewportW = metaData.width;
let viewportH = metaData.height;
// If (scale * width) < device-width, increase the width (bug 561413).
let maxInitialZoom = metaData.defaultZoom || metaData.maxZoom;
if (maxInitialZoom && viewportW)
viewportW = Math.max(viewportW, screenW / maxInitialZoom);
let validW = viewportW > 0;
let validH = viewportH > 0;
if (validW && !validH) {
viewportH = viewportW * (screenH / screenW);
} else if (!validW && validH) {
viewportW = viewportH * (screenW / screenH);
} else {
viewportW = kDefaultBrowserWidth;
viewportH = kDefaultBrowserWidth * (screenH / screenW);
}
browser.style.width = viewportW + "px";
browser.style.height = viewportH + "px";
}
// Some documents are not firing MozScrolledAreaChanged and/or fired it for
// sub-documents only
let doc = browser.contentDocument;
if (doc instanceof XULDocument || doc.body instanceof HTMLFrameSetElement) {
let [width, height] = BrowserView.Util.getBrowserDimensions(browser);
BrowserView.Util.ensureMozScrolledAreaEvent(browser, width, height);
}
},
/** Returns tab's identity state for updating security UI. */
getIdentityState: function getIdentityState() {
return this._listener.state;
@ -3020,55 +3091,8 @@ Tab.prototype = {
endLoading: function endLoading() {
if (!this._loading) throw "Not Loading!";
// Determine at what resolution the browser is rendered based on meta tag
let browser = this._browser;
let metaData = Util.getViewportMetadata(browser);
// Remove any fixed size properties
browser.style.removeProperty("width");
browser.style.removeProperty("height");
if (metaData.reason == "handheld" || metaData.reason == "doctype" || metaData.reason == "viewport") {
browser.className = "browser-viewport";
if (metaData.autoSize) {
browser.classList.add("viewport-width");
browser.classList.add("viewport-height");
}
else {
let screenW = window.innerWidth;
let screenH = window.innerHeight;
let viewportW = metaData.width;
let viewportH = metaData.height;
let validW = viewportW > 0;
let validH = viewportH > 0;
if (validW && !validH) {
viewportH = viewportW * (screenH / screenW);
} else if (!validW && validH) {
viewportW = viewportH * (screenW / screenH);
} else {
viewportW = kDefaultBrowserWidth;
viewportH = kDefaultBrowserWidth * (screenH / screenW);
}
browser.style.width = viewportW + "px";
browser.style.height = viewportH + "px";
}
} else if (metaData.reason == "chrome") {
browser.className = "browser-chrome window-width window-height";
} else {
browser.className = "browser";
}
// Some documents are not firing MozScrolledAreaChanged and/or fired it for
// sub-documents only
let doc = browser.contentDocument;
if (doc instanceof XULDocument || doc.body instanceof HTMLFrameSetElement) {
let [width, height] = BrowserView.Util.getBrowserDimensions(browser);
BrowserView.Util.ensureMozScrolledAreaEvent(browser, width, height);
}
this.setIcon(browser.mIconURL);
this.updateViewportMetadata();
this.setIcon(this._browser.mIconURL);
this._loading = false;
if (this == Browser.selectedTab) {
@ -3120,7 +3144,6 @@ Tab.prototype = {
// Create the browser using the current width the dynamically size the height
let browser = this._browser = document.createElement("browser");
browser.className = "browser";
browser.setAttribute("style", "overflow: -moz-hidden-unscrollable; visibility: hidden;");
browser.setAttribute("type", "content");

View File

@ -73,7 +73,6 @@ function verifyBlank(n) {
is(uri, testURL_blank, "URL Matches blank page "+n);
// Check viewport settings
ok(working_tab.browser.classList.contains("browser"), "Normal 'browser' class");
let style = window.getComputedStyle(working_tab.browser, null);
is(style.width, "800px", "Normal 'browser' width is 800 pixels");