Bug 436083: Viewport meta tag [r=mark.finkle r=gavin.sharp]
authorBrad Lassey <blassey@mozilla.com>
Tue, 03 Nov 2009 16:20:03 -0500
changeset 65753 32fa65b56b567410f5714875e9ff8e23d15f6a8d
parent 65752 206ce90fa9cc64fc3deb8edc3bd2f1cf1cd83f40
child 65754 6d1c8c13bdd0a384bb5a686606ce5e03881a5fa9
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmark.finkle, gavin.sharp
bugs436083
Bug 436083: Viewport meta tag [r=mark.finkle r=gavin.sharp]
mobile/chrome/content/BrowserView.js
mobile/chrome/content/Util.js
mobile/chrome/content/browser.js
--- a/mobile/chrome/content/BrowserView.js
+++ b/mobile/chrome/content/BrowserView.js
@@ -570,18 +570,21 @@ BrowserView.prototype = {
       this.setZoomLevel(this.getZoomForPage());
   },
 
   getZoomForPage: function getZoomForPage() {
     let browser = this._browser;
     if (!browser)
       return 0;
 
-    if (Util.contentIsHandheld(browser))
+    let metaData = Util.contentIsHandheld(browser);
+    if (metaData.reason == "handheld" || metaData.reason == "doctype")
       return 1;
+    else if (metaData.reason == "viewport" && metaData.scale > 0)
+      return metaData.scale;
 
     let bvs = this._browserViewportState;  // browser exists, so bvs must as well
     let w = this.viewportToBrowser(bvs.viewportRect.right);
     let h = this.viewportToBrowser(bvs.viewportRect.bottom);
     return BrowserView.Util.pageZoomLevel(this.getVisibleRect(), w, h);
   },
 
   zoom: function zoom(aDirection) {
--- a/mobile/chrome/content/Util.js
+++ b/mobile/chrome/content/Util.js
@@ -107,26 +107,37 @@ let Util = {
       return link.href;
     else
       return null;
   },
 
   contentIsHandheld: function contentIsHandheld(browser) {
     let doctype = browser.contentDocument.doctype;
     if (doctype && /(WAP|WML|Mobile)/.test(doctype.publicId))
-      return true;
+      return {reason: "doctype", result: true};
 
     let windowUtils = browser.contentWindow
                              .QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIDOMWindowUtils);
     let handheldFriendly = windowUtils.getDocumentMetadata("HandheldFriendly");
     if (handheldFriendly == "true")
-      return true;
+      return {reason: "handheld", result: true};
 
-    return false;
+    let viewportScale = parseFloat(windowUtils.getDocumentMetadata("viewport-initial-scale"));
+    if (viewportScale > 0) {
+      return {
+        reason: "viewport",
+        result: true,
+        scale: viewportScale,
+        width: parseInt(windowUtils.getDocumentMetadata("viewport-width")),
+        height: parseInt(windowUtils.getDocumentMetadata("viewport-height"))
+      }
+    }
+
+    return {reason: "", result: false};
   }
 };
 
 
 /**
  * Simple Point class.
  *
  * Any method that takes an x and y may also take a point.
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -367,17 +367,17 @@ var Browser = {
     let pageScrollbox = this.pageScrollbox = document.getElementById("page-scrollbox");
     this.pageScrollboxScroller = pageScrollbox.boxObject.QueryInterface(Ci.nsIScrollBoxObject);
     pageScrollbox.customDragger = controlsScrollbox.customDragger;
 
     // during startup a lot of viewportHandler calls happen due to content and window resizes
     bv.beginBatchOperation();
 
     let stylesheet = document.styleSheets[0];
-    for each (let style in ['window-width', 'window-height', 'toolbar-height', 'browser', 'browser-handheld']) {
+    for each (let style in ["window-width", "window-height", "toolbar-height", "browser", "browser-handheld", "browser-viewport"]) {
       let index = stylesheet.insertRule("." + style + " {}", stylesheet.cssRules.length);
       this.styles[style] = stylesheet.cssRules[index].style;
     }
 
     function resizeHandler(e) {
 
       if (e.target != window)
         return;
@@ -2484,18 +2484,39 @@ Tab.prototype = {
       Browser._browserView.invalidateEntireView();
       this._loadingTimeout = setTimeout(Util.bind(this._resizeAndPaint, this), 2000);
     }
   },
 
   endLoading: function() {
     // Determine at what resolution the browser is rendered based on meta tag
     let browser = this._browser;
-    if (Util.contentIsHandheld(browser)) {
+    let metaData = Util.contentIsHandheld(browser);
+
+    if (metaData.reason == "handheld" || metaData.reason == "doctype") {
       browser.className = "browser-handheld";
+    } else if (metaData.reason == "viewport") {
+      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.className = "browser-viewport";
+      browser.style.width = viewportW + "px";
+      browser.style.height = viewportH + "px";
     } else {
       browser.className = "browser";
     }
 
     //if (!this._loading)
     //  dump("!!! Already finished loading this tab, please file a bug\n");
     this.setIcon(browser.mIconURL);