Backed out changeset d7623fd1ad70
authorMark Finkle <mfinkle@mozilla.com>
Wed, 21 Oct 2009 15:41:09 -0400
changeset 65693 48e9b919986c58d90e6d1a3b08777ccbe12172a4
parent 65692 d1a5f2580838c5055f002912054861581799a8c2
child 65694 9616b3974169b3d4a1a9971a6af72bfb35855d01
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)
Backed out changeset d7623fd1ad70
mobile/chrome/content/BrowserView.js
mobile/chrome/content/TileManager.js.in
mobile/chrome/content/browser.js
--- a/mobile/chrome/content/BrowserView.js
+++ b/mobile/chrome/content/BrowserView.js
@@ -164,20 +164,16 @@ BrowserView.Util = {
   createBrowserViewportState: function createBrowserViewportState() {
     return new BrowserView.BrowserViewportState(new Rect(0, 0, 1, 1), 0, 0, 1);
   },
 
   getViewportStateFromBrowser: function getViewportStateFromBrowser(browser) {
     return browser.__BrowserView__vps;
   },
 
-  /**
-   * Calling this is likely to cause a reflow of the browser's document.  Use
-   * wisely.
-   */
   getBrowserDimensions: function getBrowserDimensions(browser) {
     let cdoc = browser.contentDocument;
     if (cdoc instanceof SVGDocument) {
       let rect = cdoc.rootElement.getBoundingClientRect();
       return [Math.ceil(rect.width), Math.ceil(rect.height)];
     }
 
     // These might not exist yet depending on page load state
@@ -243,73 +239,57 @@ BrowserView.prototype = {
     } catch(e) {}
     this._tileManager = new TileManager(this._appendTile, this._removeTile, this, cacheSize);
     this._visibleRectFactory = visibleRectFactory;
 
     this._idleServiceObserver = new BrowserView.IdleServiceObserver(this);
     this._idleService = Cc["@mozilla.org/widget/idleservice;1"].getService(Ci.nsIIdleService);
     this._idleService.addIdleObserver(this._idleServiceObserver, kBrowserViewPrefetchBeginIdleWait);
   },
-
+  
   uninit: function uninit() {
     this.setBrowser(null, null, false);
     this._idleService.removeIdleObserver(this._idleServiceObserver, kBrowserViewPrefetchBeginIdleWait);
   },
 
   getVisibleRect: function getVisibleRect() {
     return this._visibleRectFactory();
   },
 
   setViewportDimensions: function setViewportDimensions(width, height, causedByZoom) {
     let bvs = this._browserViewportState;
 
     if (!bvs)
       return;
 
-    let oldwidth  = bvs.viewportRect.right;
-    let oldheight = bvs.viewportRect.bottom;
     bvs.viewportRect.right  = width;
     bvs.viewportRect.bottom = height;
 
-    let sizeChanged = (oldwidth != width || oldheight != height);
-
     // XXX we might not want the user's page to disappear from under them
     // at this point, which could happen if the container gets resized such
     // that visible rect becomes entirely outside of viewport rect.  might
     // be wise to define what UX should be in this case, like a move occurs.
     // then again, we could also argue this is the responsibility of the
     // caller who would do such a thing...
 
-    this._viewportChanged(sizeChanged, sizeChanged && !!causedByZoom);
+    this._viewportChanged(true, !!causedByZoom);
   },
 
-  /**
-   * @return [width, height]
-   */
-  getViewportDimensions: function getViewportDimensions() {
-    let bvs = this._browserViewportState;
-
-    if (!bvs)
-      throw "Cannot get viewport dimensions when no browser is set";
-
-    return [bvs.viewportRect.right, bvs.viewportRect.bottom];
-  },
-
-  setZoomLevel: function setZoomLevel(zoomLevel) {
+  setZoomLevel: function setZoomLevel(zl) {
     let bvs = this._browserViewportState;
 
     if (!bvs)
       return;
 
-    let newZoomLevel = BrowserView.Util.clampZoomLevel(zoomLevel);
+    let newZL = BrowserView.Util.clampZoomLevel(zl);
 
-    if (newZoomLevel != bvs.zoomLevel) {
+    if (newZL != bvs.zoomLevel) {
       let browserW = this.viewportToBrowser(bvs.viewportRect.right);
       let browserH = this.viewportToBrowser(bvs.viewportRect.bottom);
-      bvs.zoomLevel = newZoomLevel; // side-effect: now scale factor in transformations is newZoomLevel
+      bvs.zoomLevel = newZL; // side-effect: now scale factor in transformations is newZL
       this.setViewportDimensions(this.browserToViewport(browserW),
                                  this.browserToViewport(browserH),
                                  true);
       this.zoomChanged = true;
     }
   },
 
   getZoomLevel: function getZoomLevel() {
@@ -410,41 +390,47 @@ BrowserView.prototype = {
   /**
    * Swap out the current browser and browser viewport state with a new pair.
    */
   setBrowser: function setBrowser(browser, browserViewportState, doZoom) {
     if (browser && !browserViewportState) {
       throw "Cannot set non-null browser with null BrowserViewportState";
     }
 
-    let oldBrowser = this._browser;
+    let browserChanged = (this._browser !== browser);
 
-    let browserChanged = (oldBrowser !== browser);
+    if (this._browser) {
+      this._browser.removeEventListener("MozAfterPaint", this.handleMozAfterPaint, false);
+      this._browser.removeEventListener("scroll", this.handlePageScroll, false);
 
-    if (oldBrowser) {
-      oldBrowser.removeEventListener("MozAfterPaint", this.handleMozAfterPaint, false);
-      oldBrowser.removeEventListener("scroll", this.handlePageScroll, false);
-      oldBrowser.removeEventListener("MozScrolledAreaChanged", this.handleMozScrolledAreaChanged, false);
+      // !!! --- RESIZE HACK BEGIN -----
+      // change to the real event type and perhaps refactor the handler function name
+      this._browser.removeEventListener("FakeMozAfterSizeChange", this.handleMozAfterSizeChange, false);
+      // !!! --- RESIZE HACK END -------
 
-      oldBrowser.setAttribute("type", "content");
-      oldBrowser.docShell.isOffScreenBrowser = false;
+      this._browser.setAttribute("type", "content");
+      this._browser.docShell.isOffScreenBrowser = false;
     }
 
     this._browser = browser;
     this._contentWindow = (browser) ? browser.contentWindow : null;
     this._browserViewportState = browserViewportState;
 
     if (browser) {
       browser.setAttribute("type", "content-primary");
 
       this.beginBatchOperation();
 
       browser.addEventListener("MozAfterPaint", this.handleMozAfterPaint, false);
       browser.addEventListener("scroll", this.handlePageScroll, false);
-      browser.addEventListener("MozScrolledAreaChanged", this.handleMozScrolledAreaChanged, false);
+
+      // !!! --- RESIZE HACK BEGIN -----
+      // change to the real event type and perhaps refactor the handler function name
+      browser.addEventListener("FakeMozAfterSizeChange", this.handleMozAfterSizeChange, false);
+      // !!! --- RESIZE HACK END -------
 
       if (doZoom) {
         browser.docShell.isOffScreenBrowser = true;
         this.zoomToPage();
       }
 
       this._viewportChanged(browserChanged, browserChanged);
 
@@ -487,62 +473,59 @@ BrowserView.prototype = {
   },
 
   /** If browser scrolls, pan content to new scroll area. */
   handlePageScroll: function handlePageScroll(aEvent) {
     if (aEvent.target != this._browser.contentDocument)
       return;
 
     let { x: scrollX, y: scrollY } = BrowserView.Util.getContentScrollOffset(this._browser);
-    Browser.contentScrollboxScroller.scrollTo(this.browserToViewport(scrollX),
+    Browser.contentScrollboxScroller.scrollTo(this.browserToViewport(scrollX), 
                                               this.browserToViewport(scrollY));
     this.onAfterVisibleMove();
   },
 
-  handleMozScrolledAreaChanged: function handleMozScrolledAreaChanged(ev) {
-    if (ev.target != this._browser.contentDocument)
-      return;
-
-    let { x: scrollX, y: scrollY } = BrowserView.Util.getContentScrollOffset(this._browser);
+  // !!! --- RESIZE HACK BEGIN -----
+  simulateMozAfterSizeChange: function simulateMozAfterSizeChange() {
+    let [w, h] = BrowserView.Util.getBrowserDimensions(this._browser);
+    let ev = document.createEvent("MouseEvents");
+    ev.initMouseEvent("FakeMozAfterSizeChange", false, false, window, 0, w, h, 0, 0, false, false, false, false, 0, null);
+    this._browser.dispatchEvent(ev);
+  },
+  // !!! --- RESIZE HACK END -------
 
-    let x = ev.x + scrollX;
-    let y = ev.y + scrollY;
-    let w = ev.width;
-    let h = ev.height;
-
-    /* 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. */
-    if (x < 0) w += x;
-    if (y < 0) h += y;
-
-    this.setViewportDimensions(this.browserToViewport(w),
-                               this.browserToViewport(h));
+  handleMozAfterSizeChange: function handleMozAfterSizeChange(ev) {
+    // !!! --- RESIZE HACK BEGIN -----
+    // get the correct properties off of the event, these are wrong because
+    // we're using a MouseEvent, as it has an X and Y prop of some sort and
+    // we piggyback on that.
+    let w = ev.screenX;
+    let h = ev.screenY;
+    // !!! --- RESIZE HACK END -------
+    this.setViewportDimensions(this.browserToViewport(w), this.browserToViewport(h));
   },
 
   zoomToPage: function zoomToPage() {
     let browser = this._browser;
 
     if (!browser)
       return;
 
     var windowUtils = browser.contentWindow
                              .QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIDOMWindowUtils);
     var handheldFriendly = windowUtils.getDocumentMetadata("HandheldFriendly");
-
+    
     if (handheldFriendly == "true") {
       browser.className = "browser-handheld";
       this.setZoomLevel(1);
       browser.markupDocumentViewer.textZoom = 1;
     } else {
       browser.className = "browser";
-      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);
+      let [w, h] = BrowserView.Util.getBrowserDimensions(browser);
       this.setZoomLevel(BrowserView.Util.pageZoomLevel(this.getVisibleRect(), w, h));
     }
   },
 
   zoom: function zoom(aDirection) {
     let bvs = this._browserViewportState;
 
     if (!bvs)
@@ -553,59 +536,16 @@ BrowserView.prototype = {
 
     var zoomDelta = 0.05; // 1/20
     if (aDirection >= 0)
       zoomDelta *= -1;
 
     this.setZoomLevel(bvs.zoomLevel + zoomDelta);
   },
 
-  //
-  // XXXrf  This method is used as a workaround for the fact that
-  // MozAfterPaint events do not guarantee to inform us of all
-  // invalidated paints (See
-  // https://developer.mozilla.org/en/Gecko-Specific_DOM_Events#Important_notes
-  // for details on what the event *does* guarantee).  This is only an
-  // issue when the same current <browser> is used to navigate to a
-  // new page.  Unless a zoom was issued during the page transition
-  // (e.g. a call to zoomToPage() or something of that nature), we
-  // aren't guaranteed that we've actually invalidated the entire
-  // page.  We don't want to leave bits of the previous page in the
-  // view of the new one, so this method exists as a way for Browser
-  // to inform us that the page is changing, and that we really ought
-  // to invalidate everything.  Ideally, we wouldn't have to rely on
-  // this being called, and we would get proper invalidates for the
-  // whole page no matter what is or is not visible.
-  //
-  // Note that this workaround isn't necessary in almost all cases.
-  // Most of the time, one of the following two conditions is
-  // satisfied.  Either
-  //   (1) Pages have different widths so the Browser calls a
-  //       zoomToPage() which forces a dirtyAll, or
-  //   (2) MozAfterPaint does indeed inform us of dirtyRects covering
-  //       the entire page (everything that could possibly become
-  //       visible).
-  //
-  // An example where the workaround is necessary is in going from the
-  // firstrun page to a Twitter feed.  Condition (1) isn't satisfied
-  // because both pages have the same in-browser width.  Condition (2)
-  // isn't satisfied for all of the page because of what appears to be
-  // some kind of overflowing container div.  To see this, place some
-  // dumps of the rectangles incoming in the HandleMozAfterPaint
-  // method, and navigate to someone's Twitter feed.  Only sidebar on
-  // the right-hand side of the feed is invalidated across the page,
-  // and otherwise, the 500x800 visible region is invalidated as well.
-  //
-  // See browser.js for where this is invoked.
-  //
-  invalidateEntireView: function invalidateEntireView() {
-    if (this._browserViewportState)
-      this._viewportChanged(false, true);
-  },
-
   /**
    * Render a rectangle within the browser viewport to the destination canvas
    * under the given scale.
    *
    * @param destCanvas The destination canvas into which the image is rendered.
    * @param destWidth Destination width
    * @param destHeight Destination height
    * @param srcRect [optional] The source rectangle in BrowserView coordinates.
--- a/mobile/chrome/content/TileManager.js.in
+++ b/mobile/chrome/content/TileManager.js.in
@@ -146,102 +146,27 @@ TileManager.prototype = {
    * critical rect.
    */
   viewportChangeHandler: function viewportChangeHandler(viewportRect,
                                                         criticalRect,
                                                         boundsSizeChanged,
                                                         dirtyAll) {
     let tc = this._tileCache;
 
-    let iBoundOld = tc.iBound;
-    let jBoundOld = tc.jBound;
-    let iBound = tc.iBound = Math.ceil(viewportRect.right / kTileWidth) - 1;
-    let jBound = tc.jBound = Math.ceil(viewportRect.bottom / kTileHeight) - 1;
+    tc.iBound = Math.ceil(viewportRect.right / kTileWidth);
+    tc.jBound = Math.ceil(viewportRect.bottom / kTileHeight);
 
     if (criticalRect.isEmpty() || !criticalRect.equals(this._criticalRect)) {
       this.beginCriticalMove(criticalRect);
-      this.endCriticalMove(criticalRect, !(dirtyAll || boundsSizeChanged));
+      this.endCriticalMove(criticalRect, !boundsSizeChanged);
     }
 
-    if (dirtyAll) {
+    if (boundsSizeChanged) {
+      // TODO fastpath if !dirtyAll
       this.dirtyRects([viewportRect.clone()], true);
-    } else if (boundsSizeChanged) {
-
-      //
-      // This is a special case.  The bounds size changed, but we are
-      // told that not everything is dirty (so mayhap content grew or
-      // shrank vertically or horizontally).  We might have old tiles
-      // around in those areas just due to the fact that they haven't
-      // been yet evicted, so we patrol the new regions in search of
-      // any such leftover tiles and mark those we find as dirty.
-      //
-      // The two dirty rects below mark dirty any renegade tiles in
-      // the newly annexed grid regions as per the following diagram
-      // of the "new" viewport.
-      //
-      //   +------------+------+
-      //   |old         | A    |
-      //   |viewport    |      |
-      //   |            |      |
-      //   |            |      |
-      //   |            |      |
-      //   +------------+      |
-      //   | B          |      |
-      //   |            |      |
-      //   +------------+------+
-      //
-      // The first rectangle covers annexed region A, the second
-      // rectangle covers annexed region B.
-      //
-      // XXXrf If the tiles are large, then we are creating some
-      // redundant work here by invalidating the entire tile that
-      // the old viewport boundary crossed (note markDirty() being
-      // called with no rectangle parameter).  The rectangular area
-      // within the tile lying beyond the old boundary is certainly
-      // dirty, but not the area before.  Moreover, since we mark
-      // dirty entire tiles that may cross into the old viewport,
-      // they might, in particular, cross into the critical rect
-      // (which is anyhwere in the old viewport), so we call a
-      // criticalRectPaint() for such cleanup. We do all this more
-      // or less because we don't have much of a notion of "the old
-      // viewport" here except for in the sense that we know the
-      // index bounds on the tilecache grid from before (and the new
-      // index bounds now).
-      //
-
-      let t, l, b, r, rect;
-      let rects = [];
-
-      if (iBoundOld <= iBound) {
-        l = iBoundOld * kTileWidth;
-        t = 0;
-        r = (iBound + 1) * kTileWidth;
-        b = (jBound + 1) * kTileHeight;
-
-        rect = new Rect(l, t, r - l, b - t);
-        rect.restrictTo(viewportRect);
-
-        if (!rect.isEmpty())
-          rects.push(rect);
-      }
-
-      if (jBoundOld <= jBound) {
-        l = 0;
-        t = jBoundOld * kTileHeight;
-        r = (iBound + 1) * kTileWidth;
-        b = (jBound + 1) * kTileHeight;
-
-        rect = new Rect(l, t, r - l, b - t);
-        rect.restrictTo(viewportRect);
-
-        if (!rect.isEmpty())
-          rects.push(rect);
-      }
-
-      this.dirtyRects(rects, true);
     }
   },
 
   dirtyRects: function dirtyRects(rects, doCriticalRender) {
     let criticalIsDirty = false;
     let criticalRect = this._criticalRect;
     let tc = this._tileCache;
     let crawler = this._crawler;
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -537,17 +537,17 @@ var Browser = {
     bv.commitBatchOperation();
 
     // If some add-ons were disabled during during an application update, alert user
     if (gPrefService.prefHasUserValue("extensions.disabledAddons")) {
       let addons = gPrefService.getCharPref("extensions.disabledAddons").split(",");
       if (addons.length > 0) {
         let disabledStrings = document.getElementById("bundle_browser").getString("alertAddonsDisabled");
         let label = PluralForm.get(addons.length, disabledStrings).replace("#1", addons.length);
-
+  
         let alerts = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
         alerts.showAlertNotification(URI_GENERIC_ICON_XPINSTALL, strings.getString("alertAddons"),
                                      label, false, "", null);
       }
       gPrefService.clearUserPref("extensions.disabledAddons");
     }
 
     // Re-enable plugins if we had previously disabled them. We should get rid of
@@ -1269,17 +1269,17 @@ Browser.MainDragger.prototype = {
     let windowUtils = frame.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
 
     windowUtils.getScrollXY(false, origX, origY);
     frame.scrollBy(doffset.x, doffset.y);
     windowUtils.getScrollXY(false, newX, newY);
 
     doffset.subtract(newX.value - origX.value, newY.value - origY.value);
   }
-
+  
 };
 
 function nsBrowserAccess()
 {
 }
 
 nsBrowserAccess.prototype = {
   QueryInterface: function(aIID) {
@@ -1382,17 +1382,17 @@ const BrowserSearch = {
   get searchService() {
     delete this.searchService;
     return this.searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService);
   },
 
   get engines() {
     if (this._engines)
       return this._engines;
-    return this._engines = this.searchService.getVisibleEngines({ });
+    return this._engines = this.searchService.getVisibleEngines({ });    
   },
 
   addPageSearchEngine: function (aEngine, aDocument) {
     // Clean the engine referenced for document that didn't exist anymore
     let browsers = Browser.browsers;
     this._allEngines = this._allEngines.filter(function(element) {
        return browsers.some(function (browser) browser.contentDocument == element.doc);
     }, this);
@@ -1420,17 +1420,17 @@ const BrowserSearch = {
       return;
     }
 
     // XXX limit to the first search engine for now
     for (let i = 0; i<1; i++) {
       let button = document.createElement("button");
       button.className = "search-engine-button button-dark";
       button.setAttribute("oncommand", "BrowserSearch.addPermanentSearchEngine(this.engine);this.parentNode.hidden=true;");
-
+      
       let engine = newEngines[i];
       button.engine = engine.engine;
       button.setAttribute("label", engine.engine.title);
       button.setAttribute("image", BrowserUI._favicon.src);
 
       container.appendChild(button);
     }
 
@@ -1587,17 +1587,17 @@ IdentityHandler.prototype = {
   /**
    * Determine the identity of the page being displayed by examining its SSL cert
    * (if available) and, if necessary, update the UI to reflect this.
    */
   checkIdentity: function() {
     let state = Browser.selectedTab.getIdentityState();
     let location = getBrowser().contentWindow.location;
     let currentStatus = getBrowser().securityUI.QueryInterface(Ci.nsISSLStatusProvider).SSLStatus;
-
+    
     this._lastStatus = currentStatus;
     this._lastLocation = {};
     try {
       // make a copy of the passed in location to avoid cycles
       this._lastLocation = { host: location.host, hostname: location.hostname, port: location.port };
     } catch (ex) { }
 
     if (state & Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL)
@@ -1761,17 +1761,17 @@ IdentityHandler.prototype = {
 
     BrowserUI.pushPopup(this, [this._identityPopup, this._identityBox]);
     BrowserUI.lockToolbar();
   },
 
   hide: function ih_hide() {
     this._identityPopup.hidden = true;
     this._identityBox.removeAttribute("open");
-
+    
     BrowserUI.popPopup();
     BrowserUI.unlockToolbar();
   },
 
   /**
    * Click handler for the identity-box element in primary chrome.
    */
   handleIdentityButtonEvent: function(event) {
@@ -1992,17 +1992,17 @@ const gSessionHistoryObserver = {
     }
   }
 };
 
 var MemoryObserver = {
   observe: function() {
     let memory = Cc["@mozilla.org/xpcom/memory-service;1"].getService(Ci.nsIMemory);
     do {
-      Browser.windowUtils.garbageCollect();
+      Browser.windowUtils.garbageCollect();      
     } while (memory.isLowMemory() && Browser.sacrificeTab());
   }
 };
 
 #ifdef WINCE
 // Windows Mobile does not resize the window automatically when the soft
 // keyboard is displayed. Maemo does resize the window.
 var SoftKeyboardObserver = {
@@ -2030,37 +2030,37 @@ function getNotificationBox(aWindow) {
 function importDialog(parent, src, arguments) {
   // load the dialog with a synchronous XHR
   let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
   xhr.open("GET", src, false);
   xhr.overrideMimeType("text/xml");
   xhr.send(null);
   if (!xhr.responseXML)
     return null;
-
+  
   let doc = xhr.responseXML.documentElement;
-
+ 
   var dialog  = null;
-
+  
   // we need to insert before select-container if we want it to show correctly
   let selectContainer = document.getElementById("select-container");
   let parent = selectContainer.parentNode;
-
+  
   // emit DOMWillOpenModalDialog event
   let event = document.createEvent("Events");
   event.initEvent("DOMWillOpenModalDialog", true, false);
   let dispatcher = parent || getBrowser();
   dispatcher.dispatchEvent(event);
 
-  // create a full-screen semi-opaque box as a background
+  // create a full-screen semi-opaque box as a background 
   let back = document.createElement("box");
   back.setAttribute("class", "modal-block");
   dialog = back.appendChild(document.importNode(doc, true));
   parent.insertBefore(back, selectContainer);
-
+  
   dialog.arguments = arguments;
   dialog.parent = parent;
   return dialog;
 }
 
 function showDownloadManager(aWindowContext, aID, aReason) {
   BrowserUI.showPanel("downloads-container");
   // TODO: select the download with aID
@@ -2396,16 +2396,20 @@ Tab.prototype = {
   /**
    * Throttles redraws to once every second while loading the page, zooming to fit page if
    * user hasn't started zooming.
    */
   _resizeAndPaint: function() {
     let bv = Browser._browserView;
 
     if (this == Browser.selectedTab) {
+      // !!! --- RESIZE HACK BEGIN -----
+      bv.simulateMozAfterSizeChange();
+      // !!! --- RESIZE HACK END -----
+
       let restoringPage = (this._state != null);
 
       if (!this._browserViewportState.zoomChanged && !restoringPage) {
         // Only fit page if user hasn't started zooming around and this is a page that
         // isn't being restored.
         bv.zoomToPage();
       }
 
@@ -2431,20 +2435,16 @@ Tab.prototype = {
     //  dump("!!! Already loading this tab, please file a bug\n");
 
     this._loading = true;
     this._browserViewportState.zoomChanged = false;
 
     if (!this._loadingTimeout) {
       if (this == Browser.selectedTab) {
         Browser._browserView.beginBatchOperation();
-
-        // XXXrf  This is a workaround.  See the comment at the top of
-        // this method's definition in BrowserView.js for details.
-        Browser._browserView.invalidateEntireView();
       }
       this._loadingTimeout = setTimeout(Util.bind(this._resizeAndPaint, this), 2000);
     }
   },
 
   endLoading: function() {
     //if (!this._loading)
     //  dump("!!! Already finished loading this tab, please file a bug\n");