Add browser binding comments, make some methods internal, and rename zoomLevel to scale
authorBenjamin Stover <bstover@mozilla.com>
Wed, 01 Sep 2010 13:35:05 -0700
changeset 1971 0a1a74ff1cd94e2f0a385121351a38257cb164ca
parent 1970 904ee5d6d6ff5112929116fb403a198a28913373
child 1972 18a0eaae44ce3e35a48fe30f2b9d2e6c76fdb21b
push id1714
push userdougt@mozilla.com
push dateThu, 16 Sep 2010 02:04:21 +0000
Add browser binding comments, make some methods internal, and rename zoomLevel to scale
chrome/content/bindings/browser.js
chrome/content/bindings/browser.xml
chrome/content/browser.js
--- a/chrome/content/bindings/browser.js
+++ b/chrome/content/bindings/browser.js
@@ -334,23 +334,21 @@ let DOMEvents =  {
         break;
     }
   }
 };
 
 DOMEvents.init();
 
 let ContentScroll =  {
-  _contentArea: new Rect(0, 0, 0, 0),
-
   init: function() {
     addMessageListener("Content:ScrollTo", this);
     addMessageListener("Content:ScrollBy", this);
     addMessageListener("Content:SetResolution", this);
-    addMessageListener("Content:SetDisplayportArea", this);
+    addMessageListener("Content:SetCacheViewport", this);
     addMessageListener("Content:SetCssViewportSize", this);
 
     addEventListener("scroll", this, false);
     addEventListener("MozScrolledAreaChanged", this, false);
   },
 
   receiveMessage: function(aMessage) {
     let json = aMessage.json;
@@ -358,30 +356,30 @@ let ContentScroll =  {
       case "Content:ScrollTo":
         content.scrollTo(json.x, json.y);
         break;
 
       case "Content:ScrollBy":
         content.scrollBy(json.dx, json.dy);
         break;
 
-      case "Content:SetResolution":
+      case "Content:SetResolution": {
         let cwu = Util.getWindowUtils(content);
         cwu.setResolution(json.zoomLevel, json.zoomLevel);
         sendAsyncMessage("Content:SetResolution:Return", { zoomLevel: json.zoomLevel });
         break;
+      }
 
-      case "Content:SetDisplayportArea": {
-        let displayport = new Rect(json.x, json.y, json.w, json.h).translateInside(this._contentArea);
+      case "Content:SetCacheViewport": {
+        let displayport = new Rect(json.x, json.y, json.w, json.h);
         if (displayport.isEmpty())
           break;
 
         let cwu = Util.getWindowUtils(content);
         cwu.setDisplayPort(displayport.x, displayport.y, displayport.width, displayport.height);
-        sendAsyncMessage("Content:SetDisplayportArea:Return");
         break;
       }
 
       case "Content:SetCssViewportSize": {
         let cwu = Util.getWindowUtils(content);
         cwu.setCSSViewport(json.width, json.height);
         break;
       }
@@ -405,19 +403,16 @@ let ContentScroll =  {
         // Adjust width and height from the incoming event properties so that we
         // ignore changes to width and height contributed by growth in page
         // quadrants other than x > 0 && y > 0.
         let x = aEvent.x + scrollOffset.x;
         let y = aEvent.y + scrollOffset.y;
         let width = aEvent.width + (x < 0 ? x : 0);
         let height = aEvent.height + (y < 0 ? y : 0);
 
-        this._contentArea.width = width;
-        this._contentArea.height = height;
-
         sendAsyncMessage("MozScrolledAreaChanged", {
           width: width,
           height: height,
           viewportWidth: content.innerWidth,
           viewportHeight: content.innerHeight
         });
 
         break;
--- a/chrome/content/bindings/browser.xml
+++ b/chrome/content/bindings/browser.xml
@@ -156,28 +156,22 @@
             case "Prompt:Prompt":
               return prompt(aMessage.json.text, aMessage.json.value);
 
             case "MozScrolledAreaChanged":
               this._widthInCSSPx = aMessage.json.width;
               this._heightInCSSPx = aMessage.json.height;
               this._viewportWidthInCSSPx = aMessage.json.viewportWidth;
               this._viewportHeightInCSSPx = aMessage.json.viewportHeight;
-              this._updateDisplayport();
-              break;
-
-            case "Content:SetDisplayportArea:Return":
-              // XXX explain behavior
-              this._flushingFastScroll = false;
-              this._pendingPixelsX = 0;
-              this._pendingPixelsY = 0;
+              this._updateCacheViewport();
               break;
 
             case "Content:SetResolution:Return":
               this._zoomLevel = aMessage.json.zoomLevel;
+              this._updateCacheViewport();
               break;
          }
         ]]></body>
       </method>
 
       <method name="_getLinkType">
         <parameter name="aLink" />
         <body><![CDATA[
@@ -282,18 +276,17 @@
 
                 if (this._browser.contentWindowId != json.windowId) {
                   this._browser.contentWindowId = json.windowId;
                   this._browser._documentURI = json.documentURI;
                   this._browser._searchEngines = [];
                 }
 
                 this._browser._zoomLevel = 1;
-
-                this._browser._updateDisplayport();
+                this._browser._updateCacheViewport();
 
                 this._notify(Components.interfaces.nsIWebProgress.NOTIFY_LOCATION,
                              "onLocationChange",
                              args);
 
                 break;
 
               case "WebProgress:StatusChange":
@@ -402,138 +395,128 @@
             this.pageReport.push(obj);
             this.pageReport.reported = false;
             this.updatePageReport();
           ]]>
         </body>
       </method>
 
       <field name="_frameLoader">null</field>
-      <field name="_cssViewportWidthInCSSPx">0</field>
-      <field name="_flushingFastScroll">false</field>
-      <field name="_widthInCSSPx">0</field>
-      <field name="_heightInCSSPx">0</field>
-      <field name="_zoomLevel">1</field>
-      <field name="_defaultZoomLevel">1</field>
-      <field name="_pendingPixelsX">0</field>
-      <field name="_pendingPixelsY">0</field>
 
-      <property name="widthInCSSPx"
-                onget="return this._widthInCSSPx;"
-                readonly="true"/>
-
-      <property name="heightInCSSPx"
-                onget="return this._heightInCSSPx;"
-                readonly="true"/>
-
-      <property name="widthInDevicePx"
-                onget="return this._widthInCSSPx * this._zoomLevel;"
-                readonly="true"/>
-
-      <property name="heightInDevicePx"
-                onget="return this._heightInCSSPx * this._zoomLevel;"
-                readonly="true"/>
-
-      <property name="zoomLevel"
-                onget="return this._zoomLevel;"
-                readonly="true"/>
-
-      <property name="defaultZoomLevel"
-                onget="return this._defaultZoomLevel;"
-                onset="return this._setDefaultZoomLevel(val);"/>
-
+      <!-- Dimensions of content window -->
       <property name="viewportWidthInCSSPx"
                 onget="return this._viewportWidthInCSSPx;"
                 readonly="true"/>
-
       <property name="viewportHeightInCSSPx"
                 onget="return this._viewportHeightInCSSPx;"
                 readonly="true"/>
 
-      <method name="_updateDisplayport">
+      <!-- Dimensions of content document -->
+      <field name="_widthInCSSPx">0</field>
+      <field name="_heightInCSSPx">0</field>
+      <property name="_widthInDevicePx"
+                onget="return this._widthInCSSPx * this._zoomLevel;"
+                readonly="true"/>
+      <property name="_heightInDevicePx"
+                onget="return this._heightInCSSPx * this._zoomLevel;"
+                readonly="true"/>
+
+      <!-- Zoom level is the ratio of device pixels to CSS pixels -->
+      <field name="_zoomLevel">1</field>
+      <property name="scale"
+                onget="return this._zoomLevel;"
+                readonly="true"/>
+
+      <!-- These counters are used to update the cached viewport after they reach a certain
+           threshold when scrolling -->
+      <field name="_pendingPixelsX">0</field>
+      <field name="_pendingPixelsY">0</field>
+
+      <!-- The cache viewport is what parts of content is cached in the parent process for
+           fast scrolling. This syncs that up with the current projection viewport. -->
+      <method name="_updateCacheViewport">
         <body>
           <![CDATA[
             let frameLoader = this._frameLoader;
-            this.messageManager.sendAsyncMessage("Content:SetDisplayportArea", {
-              x: frameLoader.viewportScrollX / this._zoomLevel - 200,
-              y: frameLoader.viewportScrollY / this._zoomLevel - 400,
-              w: this._viewportWidthInCSSPx + 400,
-              h: this._viewportHeightInCSSPx + 800
+            this.messageManager.sendAsyncMessage("Content:SetCacheViewport", {
+              x: (frameLoader.viewportScrollX - 200) / this._zoomLevel,
+              y: (frameLoader.viewportScrollY - 1250) / this._zoomLevel,
+              w: (this._viewportWidthInCSSPx + 400) / this._zoomLevel,
+              h: (this._viewportHeightInCSSPx + 2500) / this._zoomLevel
             });
+
+            this._pendingPixelsX = 0;
+            this._pendingPixelsY = 0;
           ]]>
         </body>
       </method>
 
+      <!-- Synchronize the CSS viewport with the projection viewport. -->
       <method name="_updateCSSViewport">
         <body>
           <![CDATA[
             let frameLoader = this._frameLoader;
             this.messageManager.sendAsyncMessage("Content:ScrollTo", {
               x: frameLoader.viewportScrollX / this._zoomLevel,
               y: frameLoader.viewportScrollY / this._zoomLevel
             });
           ]]>
         </body>
       </method>
 
-      <method name="setZoomLevel">
+      <!-- Sets the scale of CSS pixels to device pixels. Does not affect page layout. -->
+      <method name="setScale">
         <parameter name="zl"/>
         <body>
           <![CDATA[
             if (zl <= 0) throw "Bad zoom level given.";
 
             this._frameLoader.setViewportScale(zl, zl);
-            this.messageManager.sendAsyncMessage("Content:SetResolution", {
-              zoomLevel: zl
-            });
+            this.messageManager.sendAsyncMessage("Content:SetResolution", { zoomLevel: zl });
           ]]>
         </body>
       </method>
 
+      <!-- Sets size of CSS viewport, which affects how page is layout. -->
       <method name="setCssViewportSize">
         <parameter name="width"/>
         <parameter name="height"/>
         <body>
           <![CDATA[
             this.messageManager.sendAsyncMessage("Content:SetCssViewportSize", {
               width: width,
               height: height
             });
           ]]>
         </body>
       </method>
 
-      <method name="flushScroll">
-        <body>
-          <![CDATA[
-            this._updateDisplayport();
-          ]]>
-        </body>
-      </method>
-
+      <!-- Scroll viewport by (x, y) device pixels. -->
       <method name="scrollBy">
         <parameter name="x"/>
         <parameter name="y"/>
         <body>
           <![CDATA[
             this.contentWindow.scrollBy(x, y);
           ]]>
         </body>
       </method>
 
+      <!-- Scroll viewport to (x, y) offset of document in device pixels. -->
       <method name="scrollTo">
         <parameter name="x"/>
         <parameter name="y"/>
         <body>
           <![CDATA[
             this.contentWindow.scrollTo(x, y);
           ]]>
         </body>
       </method>
 
+      <!-- Get position of viewport in device pixels. -->
       <method name="getPosition">
         <parameter name="scrollX"/>
         <parameter name="scrollY"/>
         <body>
           <![CDATA[
             let cwu = this.contentWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
                       getInterface(Components.interfaces.nsIDOMWindowUtils);
             cwu.getScrollXY(false, scrollX, scrollY);
@@ -833,32 +816,30 @@
         <body>
           <![CDATA[
             let frameLoader = this._frameLoader;
 
             let bcr = this.getBoundingClientRect();
             let viewportWidth = bcr.width;
             let viewportHeight = bcr.height;
 
-            x = Math.floor(Math.max(0, Math.min(this.widthInDevicePx - viewportWidth, frameLoader.viewportScrollX + x)) - frameLoader.viewportScrollX);
-            y = Math.floor(Math.max(0, Math.min(this.heightInDevicePx - viewportHeight, frameLoader.viewportScrollY + y)) - frameLoader.viewportScrollY);
+            x = Math.floor(Math.max(0, Math.min(this._widthInDevicePx - viewportWidth, frameLoader.viewportScrollX + x)) - frameLoader.viewportScrollX);
+            y = Math.floor(Math.max(0, Math.min(this._heightInDevicePx - viewportHeight, frameLoader.viewportScrollY + y)) - frameLoader.viewportScrollY);
 
             if (x == 0 && y == 0)
               return;
 
             frameLoader.scrollViewportBy(x, y);
 
             // XXX comment this behavior
             this._pendingPixelsX += x;
             this._pendingPixelsY += y;
 
-            if (this._flushingFastScroll == false &&
-                (Math.abs(this._pendingPixelsX) >= 150 || Math.abs(this._pendingPixelsY) >= 250)) {
-              this._flushingFastScroll = true;
-              this._updateDisplayport();
+            if ((Math.abs(this._pendingPixelsX) >= 150 || Math.abs(this._pendingPixelsY) >= 1000)) {
+              this._updateCacheViewport();
             }
           ]]>
         </body>
       </method>
 
       <method name="scrollTo">
         <parameter name="x"/>
         <parameter name="y"/>
@@ -876,14 +857,13 @@
         <body>
           <![CDATA[
             let frameLoader = this._frameLoader;
             scrollX.value = frameLoader.viewportScrollX;
             scrollY.value = frameLoader.viewportScrollY;
           ]]>
         </body>
       </method>
-
     </implementation>
 
   </binding>
 
 </bindings>
--- a/chrome/content/browser.js
+++ b/chrome/content/browser.js
@@ -158,20 +158,16 @@ var Browser = {
     container.customKeySender = new ContentCustomKeySender();
     container.customDragger = new Browser.MainDragger();
 
     // Warning, total hack ahead. All of the real-browser related scrolling code
     // lies in a pretend scrollbox here. Let's not land this as-is. Maybe it's time
     // to redo all the dragging code.
     this.contentScrollbox = container;
     this.contentScrollboxScroller = {
-      flush: function() {
-        getBrowser().flushScroll();
-      },
-
       scrollBy: function(x, y) {
         getBrowser().scrollBy(x, y);
       },
 
       scrollTo: function(x, y) {
         getBrowser().scrollTo(x, y);
       },
 
@@ -843,17 +839,17 @@ var Browser = {
   },
 
   /** Zoom one step in (negative) or out (positive). */
   zoom: function zoom(aDirection) {
     let tab = this.selectedTab;
     if (!tab.allowZoom)
       return;
 
-    let zoomLevel = getBrowser().zoomLevel;
+    let zoomLevel = getBrowser().scale;
     let zoomValues = ZoomManager.zoomValues;
     let i = zoomValues.indexOf(ZoomManager.snap(zoomLevel)) + (aDirection < 0 ? 1 : -1);
     if (i >= 0 && i < zoomValues.length)
       zoomLevel = zoomValues[i];
 
     zoomLevel = tab.clampZoomLevel(zoomLevel);
 
     let centerX = getBrowser().viewportScrollX + window.innerWidth / 2;
@@ -867,17 +863,17 @@ var Browser = {
     return this.selectedTab.clampZoomLevel(window.innerWidth / (rect.width + margin * 2));
   },
 
   /**
    * Find an appropriate zoom rect for an element bounding rect, if it exists.
    * @return Rect in viewport coordinates
    * */
   _getZoomRectForRect: function _getZoomRectForRect(rect, y) {
-    let oldZoomLevel = getBrowser().zoomLevel;
+    let oldZoomLevel = getBrowser().scale;
     let zoomLevel = this._getZoomLevelForRect(rect);
     let zoomRatio = oldZoomLevel / zoomLevel;
 
     // Don't zoom in a marginal amount, but be more lenient for the first zoom.
     // > 2/3 means operation increases the zoom level by less than 1.5
     // > 9/10 means operation increases the zoom level by less than 1.1
     let zoomTolerance = (this.selectedTab.isDefaultZoomLevel()) ? .9 : .6666;
     if (zoomRatio >= zoomTolerance)
@@ -886,60 +882,60 @@ var Browser = {
       return this._getZoomRectForPoint(rect.center().x, y, zoomLevel);
   },
 
   /**
    * Find a good zoom rectangle for point that is specified in browser coordinates.
    * @return Rect in viewport coordinates
    */
   _getZoomRectForPoint: function _getZoomRectForPoint(x, y, zoomLevel) {
-    x = x * getBrowser().zoomLevel;
-    y = y * getBrowser().zoomLevel;
+    x = x * getBrowser().scale;
+    y = y * getBrowser().scale;
 
     zoomLevel = Math.min(ZoomManager.MAX, zoomLevel);
-    let zoomRatio = zoomLevel / getBrowser().zoomLevel;
+    let zoomRatio = zoomLevel / getBrowser().scale;
     let newVisW = window.innerWidth / zoomRatio, newVisH = window.innerHeight / zoomRatio;
     let result = new Rect(x - newVisW / 2, y - newVisH / 2, newVisW, newVisH);
 
     // Make sure rectangle doesn't poke out of viewport
-    return result.translateInside(new Rect(0, 0, getBrowser().widthInDevicePx, getBrowser().heightInDevicePx));
+    return result.translateInside(new Rect(0, 0, getBrowser()._widthInDevicePx, getBrowser()._heightInDevicePx));
   },
 
   animatedZoomTo: function animatedZoomTo(rect) {
     let zoom = new AnimatedZoom();
     zoom.animateTo(rect);
   },
 
   setVisibleRect: function setVisibleRect(rect) {
     let zoomRatio = window.innerWidth / rect.width;
-    let zoomLevel = getBrowser().zoomLevel * zoomRatio;
+    let zoomLevel = getBrowser().scale * zoomRatio;
     let scrollX = rect.left * zoomRatio;
     let scrollY = rect.top * zoomRatio;
 
     this.hideSidebars();
     this.hideTitlebar();
 
-    getBrowser().setZoomLevel(zoomLevel);
+    getBrowser().setScale(zoomLevel);
     // XXX
     setTimeout(function() {
       getBrowser().scrollTo(scrollX, scrollY);
     }, 500);
   },
 
   zoomToPoint: function zoomToPoint(cX, cY, aRect) {
     let tab = this.selectedTab;
     if (!tab.allowZoom)
       return null;
 
     let zoomRect = null;
     if (aRect)
       zoomRect = this._getZoomRectForRect(aRect, cY);
 
     if (!zoomRect && tab.isDefaultZoomLevel())
-      zoomRect = this._getZoomRectForPoint(cX, cY, getBrowser().zoomLevel * 2);
+      zoomRect = this._getZoomRectForPoint(cX, cY, getBrowser().scale * 2);
 
     if (zoomRect)
       this.animatedZoomTo(zoomRect);
 
     return zoomRect;
   },
 
   zoomFromPoint: function zoomFromPoint(cX, cY) {
@@ -986,17 +982,17 @@ var Browser = {
     return rect.clone().translate(Math.round(containerBCR.left), Math.round(containerBCR.top));
   },
 
   /**
    * turn client coordinates into page-relative ones (adjusted for
    * zoom and page position)
    */
   transformClientToBrowser: function transformClientToBrowser(cX, cY) {
-    return this.clientToBrowserView(cX, cY).map(function(val) { return val / getBrowser().zoomLevel });
+    return this.clientToBrowserView(cX, cY).map(function(val) { return val / getBrowser().scale });
   },
 
   /**
    * Convenience function for getting the scrollbox position off of a
    * scrollBoxObject interface.  Returns the actual values instead of the
    * wrapping objects.
    *
    * @param scroller a scrollBoxObject on which to call scroller.getPosition()
@@ -1056,19 +1052,17 @@ Browser.MainDragger.prototype = {
   },
 
   dragStart: function dragStart(clientX, clientY, target, scroller) {
   },
 
   dragStop: function dragStop(dx, dy, scroller) {
     this.draggedFrame = null;
     this.dragMove(Browser.snapSidebars(), 0, scroller);
-
     Browser.tryUnfloatToolbar();
-    Browser.contentScrollboxScroller.flush();
   },
 
   dragMove: function dragMove(dx, dy, scroller) {
     let doffset = new Point(dx, dy);
 
     if (!this._dragMoved) {
       this._dragMoved = true;
     }
@@ -1315,17 +1309,17 @@ ContentCustomClicker.prototype = {
 
   doubleClick: function doubleClick(aX1, aY1, aX2, aY2) {
     TapHighlightHelper.hide();
 
     this._dispatchMouseEvent("Browser:MouseCancel");
 
     const kDoubleClickRadius = 32;
 
-    let maxRadius = kDoubleClickRadius * getBrowser().zoomLevel;
+    let maxRadius = kDoubleClickRadius * getBrowser().scale;
     let isClickInRadius = (Math.abs(aX1 - aX2) < maxRadius && Math.abs(aY1 - aY2) < maxRadius);
     if (isClickInRadius)
       this._dispatchMouseEvent("Browser:ZoomToPoint", aX1, aY1);
   },
 
   toString: function toString() {
     return "[ContentCustomClicker] { }";
   }
@@ -2370,32 +2364,32 @@ Tab.prototype = {
     return rounded || 1.0;
   },
 
   /**
    * XXX document me
    */
   resetZoomLevel: function resetZoomLevel() {
     let browser = this._browser;
-    this._defaultZoomLevel = browser.zoomLevel;
+    this._defaultZoomLevel = browser.scale;
   },
 
   /**
    * XXX document me
    */
   updateDefaultZoomLevel: function updateDefaultZoomLevel() {
     let browser = this._browser;
-    let isDefault = (browser.zoomLevel == this._defaultZoomLevel);
+    let isDefault = (browser.scale == this._defaultZoomLevel);
     this._defaultZoomLevel = this.getDefaultZoomLevel();
     if (isDefault)
-      browser.setZoomLevel(this._defaultZoomLevel);
+      browser.setScale(this._defaultZoomLevel);
   },
 
   isDefaultZoomLevel: function isDefaultZoomLevel() {
-    return getBrowser().zoomLevel == this._defaultZoomLevel;
+    return getBrowser().scale == this._defaultZoomLevel;
   },
 
   getDefaultZoomLevel: function getDefaultZoomLevel() {
     let md = this.metaData;
     if (md && md.defaultZoom)
       return this.clampZoomLevel(md.defaultZoom);
 
     let pageZoom = this.getPageZoomLevel();