Bug 617952 - Fire scroll events for pages coming from bfcache [r=mfinkle, a=blocking]
authorWes Johnston <wjohnston@mozilla.com>
Tue, 01 Mar 2011 09:11:18 -0800
changeset 67448 4ea3fa2f0947cd46beb424de1200e11082bd785c
parent 67447 b3d88ce1574c15da38293f709662f80295426921
child 67449 1cc782b4095cc4d6c68dfabe12bbe7c2372d6c0d
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, blocking
bugs617952
Bug 617952 - Fire scroll events for pages coming from bfcache [r=mfinkle, a=blocking]
mobile/chrome/content/bindings/browser.js
mobile/chrome/content/bindings/browser.xml
--- a/mobile/chrome/content/bindings/browser.js
+++ b/mobile/chrome/content/bindings/browser.js
@@ -189,16 +189,18 @@ let DOMEvents =  {
       case "DOMContentLoaded":
         if (document.documentURIObject.spec == "about:blank")
           return;
 
         sendAsyncMessage("DOMContentLoaded", { });
         break;
 
       case "pageshow":
+        if (aEvent.persisted)
+          ContentScroll.sendScroll();
       case "pagehide": {
         if (aEvent.target.defaultView != content)
           break;
 
         let util = aEvent.target.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
                                             .getInterface(Ci.nsIDOMWindowUtils);
 
         let json = {
@@ -348,22 +350,17 @@ let ContentScroll =  {
 
   handleEvent: function(aEvent) {
     switch (aEvent.type) {
       case "scroll": {
         let doc = aEvent.target;
         if (doc != content.document)
           break;
 
-        let scrollOffset = this.getScrollOffset(content);
-        if (this._scrollOffset.x == scrollOffset.x && this._scrollOffset.y == scrollOffset.y)
-          break;
-
-        this._scrollOffset = scrollOffset;
-        sendAsyncMessage("scroll", scrollOffset);
+        this.sendScroll();
         break;
       }
 
       case "MozScrolledAreaChanged": {
         let doc = aEvent.originalTarget;
         if (content != doc.defaultView) // We are only interested in root scroll pane changes
           return;
 
@@ -379,16 +376,25 @@ let ContentScroll =  {
         sendAsyncMessage("MozScrolledAreaChanged", {
           width: width,
           height: height
         });
 
         break;
       }
     }
+  },
+
+  sendScroll: function sendScroll() {
+    let scrollOffset = this.getScrollOffset(content);
+    if (this._scrollOffset.x == scrollOffset.x && this._scrollOffset.y == scrollOffset.y)
+      return;
+
+    this._scrollOffset = scrollOffset;
+    sendAsyncMessage("scroll", scrollOffset);
   }
 };
 
 ContentScroll.init();
 
 let ContentActive =  {
   init: function() {
     addMessageListener("Content:Activate", this);
--- a/mobile/chrome/content/bindings/browser.xml
+++ b/mobile/chrome/content/bindings/browser.xml
@@ -750,22 +750,34 @@
           receiveMessage: function receiveMessage(aMessage) {
             let self = this.self;
             let json = aMessage.json;
 
             switch (aMessage.name) {
               case "scroll":
                 if (!self.scrollSync)
                   return;
-
-                // Use floor so that we always guarantee top-left corner of content is visible.
-                let view = self.getRootView();
-                view.scrollTo(Math.floor(json.x * self.scale), Math.floor(json.y * self.scale));
+                this.doScroll(json.x, json.y, 0);
                 break;
            }
+         },
+
+         doScroll: function doScroll(aX, aY, aCount) {
+            let self = this.self;
+
+            // Use floor so that we always guarantee top-left corner of content is visible.
+            let view = self.getRootView();
+            view.scrollTo(Math.floor(aX * self.scale), Math.floor(aY * self.scale));
+
+            let position = view.getPosition();
+            if ((position.x != aX * self.scale || position.y != aY * self.scale) && aCount < 3) {
+              setTimeout((function() {
+                 this.doScroll(aX, aY, ++aCount);
+              }).bind(this), 0);
+            }
          }
        })
       ]]></field>
 
       <!-- Keep a store of temporary content views. -->
       <field name="_contentViews">({})</field>
 
       <!-- There is a point before a page has loaded where a root content view