Bug 561870 - Enforce min/max limits on viewport values [r=mfinkle]
authorMatt Brubeck <mbrubeck@mozilla.com>
Thu, 29 Apr 2010 15:29:01 -0400
changeset 66187 ca56bfc3c5a130f50095ffcb01c4ead71e1942be
parent 66186 6b4a6e40214eb105477c864f4bffbabf4e90b19d
child 66188 23267cbaa936c20d9c1a7e069e2de1280e61f9c4
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)
reviewersmfinkle
bugs561870
Bug 561870 - Enforce min/max limits on viewport values [r=mfinkle]
mobile/chrome/content/Util.js
mobile/chrome/tests/Makefile.in
mobile/chrome/tests/browser_viewport.js
mobile/chrome/tests/browser_viewport_08.html
--- a/mobile/chrome/content/Util.js
+++ b/mobile/chrome/content/Util.js
@@ -36,16 +36,24 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 let Ci = Components.interfaces;
 
+// Blindly copied from Safari documentation for now.
+const kViewportMinScale  = 0;
+const kViewportMaxScale  = 10;
+const kViewportMinWidth  = 200;
+const kViewportMaxWidth  = 10000;
+const kViewportMinHeight = 223;
+const kViewportMaxHeight = 10000;
+
 // -----------------------------------------------------------
 // General util/convenience tools
 //
 
 let Util = {
   bind: function bind(f, thisObj) {
     return function() {
       return f.apply(thisObj, arguments);
@@ -128,28 +136,37 @@ let Util = {
 
     if (browser.contentDocument instanceof XULDocument)
       return { reason: "chrome", result: true, scale: 1.0, autoSize: true, allowZoom: false };
 
     // viewport details found here
     // http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html
     // http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html
     
+    // Note: These values will be NaN if parseFloat or parseInt doesn't find a number.
+    // Remember that NaN is contagious: Math.max(1, NaN) == Math.min(1, NaN) == NaN.
     let viewportScale = parseFloat(windowUtils.getDocumentMetadata("viewport-initial-scale"));
     let viewportMinScale = parseFloat(windowUtils.getDocumentMetadata("viewport-minimum-scale"));
     let viewportMaxScale = parseFloat(windowUtils.getDocumentMetadata("viewport-maximum-scale"));
     let viewportWidthStr = windowUtils.getDocumentMetadata("viewport-width");
     let viewportHeightStr = windowUtils.getDocumentMetadata("viewport-height");
 
+    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 viewportWidth = viewportWidthStr == "device-width" ? window.innerWidth : parseInt(viewportWidthStr);
     let viewportHeight = viewportHeightStr == "device-height" ? window.innerHeight : parseInt(viewportHeightStr);
+
+    viewportWidth  = Util.clamp(viewportWidth,  kViewportMinWidth,  kViewportMaxWidth);
+    viewportHeight = Util.clamp(viewportHeight, kViewportMinHeight, kViewportMaxHeight);
  
     // If (scale * width) < device-width, increase the width (bug 561413).
     let maxInitialScale = viewportScale || viewportMaxScale;
     if (maxInitialScale && viewportWidth)
       viewportWidth = Math.max(viewportWidth, window.innerWidth / maxInitialScale);
 
     if (viewportScale > 0 || viewportWidth > 0 || viewportHeight > 0 || viewportMinScale > 0 || viewportMaxScale > 0) {
       return {
@@ -163,16 +180,20 @@ let Util = {
         autoSize: viewportWidthStr == "device-width" || viewportHeightStr == "device-height",
         allowZoom: windowUtils.getDocumentMetadata("viewport-user-scalable") != "no"
       };
     }
 
     return { reason: "", result: false, allowZoom: true };
   },
 
+  clamp: function(num, min, max) {
+    return Math.max(min, Math.min(max, num));
+  },
+
   /**
    * Determines whether a home page override is needed.
    * Returns:
    *  "new profile" if this is the first run with a new profile.
    *  "new version" if this is the first run with a build with a different
    *                      Gecko milestone (i.e. right after an upgrade).
    *  "none" otherwise.
    */
--- a/mobile/chrome/tests/Makefile.in
+++ b/mobile/chrome/tests/Makefile.in
@@ -64,12 +64,13 @@ include $(topsrcdir)/config/rules.mk
   browser_viewport_00.html \
   browser_viewport_01.html \
   browser_viewport_02.html \
   browser_viewport_03.html \
   browser_viewport_04.html \
   browser_viewport_05.html \
   browser_viewport_06.html \
   browser_viewport_07.html \
+  browser_viewport_08.html \
   $(NULL)
 
 libs:: $(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
--- a/mobile/chrome/tests/browser_viewport.js
+++ b/mobile/chrome/tests/browser_viewport.js
@@ -52,17 +52,18 @@ let isLoading = function() { return !wor
 let testData = [
   { width: undefined,   scale: undefined },
   { width: deviceWidth, scale: 1 },
   { width: 320,         scale: 1 },
   { width: undefined,   scale: 1,        disableZoom: true },
   { width: 200,         scale: undefined },
   { width: 2000,        minScale: 0.75 },
   { width: 100,         maxScale: 2 },
-  { width: 2000,        scale: 0.75 }
+  { width: 2000,        scale: 0.75 },
+  { width: 10000,       scale: 10 }
 ];
 
 //------------------------------------------------------------------------------
 // Entry point (must be named "test")
 function test() {
   // This test is async
   waitForExplicitFinish();
 
new file mode 100644
--- /dev/null
+++ b/mobile/chrome/tests/browser_viewport_08.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+    <title>Browser Viewport Page 08</title>
+    <meta name="viewport" content="width=20000, initial-scale=100"/>
+</head>
+<body>
+    <p>Browser Viewport Page 08</p>
+    <p>width=20000, initial-scale=100</p>
+</body>
+</html>