Merge mozilla-central to mozilla-inbound
authorEd Morley <emorley@mozilla.com>
Mon, 01 Oct 2012 14:04:36 +0100
changeset 108864 94526a90222e6c46c25723cda44d04625e8c4c2e
parent 108863 86cc9c289960e869d047a72372f060c919879c66 (current diff)
parent 108836 d4355e045ea76e8bd1f473bdae0e52194e11a4f3 (diff)
child 108865 4a83e0291d581cc077b9296fc6cbcf72323737d6
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
milestone18.0a1
Merge mozilla-central to mozilla-inbound
--- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
+++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
@@ -56,17 +56,16 @@ const STATE_RESTORE_FINISHED = 3;
 function PrivateBrowsingService() {
   this._obs = Cc["@mozilla.org/observer-service;1"].
               getService(Ci.nsIObserverService);
   this._obs.addObserver(this, "profile-after-change", true);
   this._obs.addObserver(this, "quit-application-granted", true);
   this._obs.addObserver(this, "private-browsing", true);
   this._obs.addObserver(this, "command-line-startup", true);
   this._obs.addObserver(this, "sessionstore-browser-state-restored", true);
-  this._obs.addObserver(this, "domwindowopened", true);
 
   // List of nsIXULWindows we are going to be closing during the transition
   this._windowsToClose = [];
 }
 
 PrivateBrowsingService.prototype = {
   // Preferences Service
   get _prefs() {
@@ -492,28 +491,16 @@ PrivateBrowsingService.prototype = {
         }
         break;
       case "sessionstore-browser-state-restored":
         if (this._currentStatus == STATE_WAITING_FOR_RESTORE) {
           this._currentStatus = STATE_RESTORE_FINISHED;
           this._notifyIfTransitionComplete();
         }
         break;
-      case "domwindowopened":
-        let aWindow = aSubject;
-        let self = this;
-        aWindow.addEventListener("load", function PBS__onWindowLoad(aEvent) {
-          aWindow.removeEventListener("load", arguments.callee);
-          if (aWindow.document
-                     .documentElement
-                     .getAttribute("windowtype") == "navigator:browser") {
-            self._setPerWindowPBFlag(aWindow, self._inPrivateBrowsing);
-          }
-        }, false);
-        break;
     }
   },
 
   // nsICommandLineHandler
 
   handle: function PBS_handle(aCmdLine) {
     if (aCmdLine.handleFlag("private", false))
       aCmdLine.preventDefault = true; // It has already been handled
--- a/browser/devtools/debugger/debugger-controller.js
+++ b/browser/devtools/debugger/debugger-controller.js
@@ -55,18 +55,17 @@ let DebuggerController = {
     DebuggerView.initializeKeys();
     DebuggerView.initializePanes();
     DebuggerView.initializeEditor(function() {
       DebuggerView.GlobalSearch.initialize();
       DebuggerView.Scripts.initialize();
       DebuggerView.StackFrames.initialize();
       DebuggerView.Breakpoints.initialize();
       DebuggerView.Properties.initialize();
-      DebuggerView.toggleCloseButton(!this._isRemoteDebugger &&
-                                     !this._isChromeDebugger);
+      DebuggerView.showCloseButton(!this._isRemoteDebugger && !this._isChromeDebugger);
 
       this.dispatchEvent("Debugger:Loaded");
       this._connect();
     }.bind(this));
   },
 
   /**
    * Destroys the debugger view, disconnects the debugger client and cleans up
--- a/browser/devtools/debugger/debugger-view.js
+++ b/browser/devtools/debugger/debugger-view.js
@@ -1,17 +1,16 @@
 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 const BREAKPOINT_LINE_TOOLTIP_MAX_SIZE = 1000; // chars
-const PANES_APPEARANCE_DELAY = 50; // ms
 const PROPERTY_VIEW_FLASH_DURATION = 400; // ms
 const GLOBAL_SEARCH_MATCH_FLASH_DURATION = 100; // ms
 const GLOBAL_SEARCH_URL_MAX_SIZE = 100; // chars
 const GLOBAL_SEARCH_LINE_MAX_SIZE = 300; // chars
 const GLOBAL_SEARCH_ACTION_DELAY = 150; // ms
 
 const SEARCH_GLOBAL_FLAG = "!";
 const SEARCH_LINE_FLAG = ":";
@@ -99,18 +98,18 @@ let DebuggerView = {
    * Initializes UI properties for all the displayed panes.
    */
   initializePanes: function DV_initializePanes() {
     this._togglePanesButton.addEventListener("click", this._onTogglePanesButtonPressed);
 
     this._stackframesAndBreakpoints.setAttribute("width", Prefs.stackframesWidth);
     this._variables.setAttribute("width", Prefs.variablesWidth);
 
-    this.toggleStackframesAndBreakpointsPane({ silent: true });
-    this.toggleVariablesPane({ silent: true });
+    this.showStackframesAndBreakpointsPane(Prefs.stackframesPaneVisible);
+    this.showVariablesPane(Prefs.variablesPaneVisible);
   },
 
   /**
    * Initializes the SourceEditor instance.
    *
    * @param function aCallback
    *        Called after the editor finishes initializing.
    */
@@ -169,140 +168,79 @@ let DebuggerView = {
     DebuggerController.Breakpoints.initialize();
     this.editor.focus();
   },
 
   /**
    * Called when the panes toggle button is clicked.
    */
   _onTogglePanesButtonPressed: function DV__onTogglePanesButtonPressed() {
-    this.toggleStackframesAndBreakpointsPane({
-      visible: !!this._togglePanesButton.getAttribute("stackframesAndBreakpointsHidden"),
-      animated: true
-    });
-    this.toggleVariablesPane({
-      visible: !!this._togglePanesButton.getAttribute("variablesHidden"),
-      animated: true
-    });
-    this._onPanesToggle();
+    this.showStackframesAndBreakpointsPane(
+      this._togglePanesButton.getAttribute("stackframesAndBreakpointsHidden"), true);
+
+    this.showVariablesPane(
+      this._togglePanesButton.getAttribute("variablesHidden"), true);
   },
 
   /**
    * Sets the close button hidden or visible. It's hidden by default.
    * @param boolean aVisibleFlag
    */
-  toggleCloseButton: function DV_toggleCloseButton(aVisibleFlag) {
+  showCloseButton: function DV_showCloseButton(aVisibleFlag) {
     document.getElementById("close").setAttribute("hidden", !aVisibleFlag);
   },
 
   /**
    * Sets the stackframes and breakpoints pane hidden or visible.
-   *
-   * @param object aFlags [optional]
-   *        An object containing some of the following booleans:
-   *        - visible: true if the pane should be shown, false for hidden
-   *        - animated: true to display an animation on toggle
-   *        - silent: true to not update any designated prefs
+   * @param boolean aVisibleFlag
+   * @param boolean aAnimatedFlag
    */
-  toggleStackframesAndBreakpointsPane:
-  function DV_toggleStackframesAndBreakpointsPane(aFlags = {}) {
-    if (aFlags.animated) {
+  showStackframesAndBreakpointsPane:
+  function DV_showStackframesAndBreakpointsPane(aVisibleFlag, aAnimatedFlag) {
+    if (aAnimatedFlag) {
       this._stackframesAndBreakpoints.setAttribute("animated", "");
     } else {
       this._stackframesAndBreakpoints.removeAttribute("animated");
     }
-    if (aFlags.visible) {
+    if (aVisibleFlag) {
       this._stackframesAndBreakpoints.style.marginLeft = "0";
       this._togglePanesButton.removeAttribute("stackframesAndBreakpointsHidden");
       this._togglePanesButton.setAttribute("tooltiptext", L10N.getStr("collapsePanes"));
     } else {
       let margin = parseInt(this._stackframesAndBreakpoints.getAttribute("width")) + 1;
       this._stackframesAndBreakpoints.style.marginLeft = -margin + "px";
       this._togglePanesButton.setAttribute("stackframesAndBreakpointsHidden", "true");
       this._togglePanesButton.setAttribute("tooltiptext", L10N.getStr("expandPanes"));
     }
-    if (!aFlags.silent) {
-      Prefs.stackframesPaneVisible = !!aFlags.visible;
-    }
+    Prefs.stackframesPaneVisible = aVisibleFlag;
   },
 
   /**
    * Sets the variable spane hidden or visible.
-   *
-   * @param object aFlags [optional]
-   *        An object containing some of the following booleans:
-   *        - visible: true if the pane should be shown, false for hidden
-   *        - animated: true to display an animation on toggle
-   *        - silent: true to not update any designated prefs
+   * @param boolean aVisibleFlag
+   * @param boolean aAnimatedFlag
    */
-  toggleVariablesPane:
-  function DV_toggleVariablesPane(aFlags = {}) {
-    if (aFlags.animated) {
+  showVariablesPane:
+  function DV_showVariablesPane(aVisibleFlag, aAnimatedFlag) {
+    if (aAnimatedFlag) {
       this._variables.setAttribute("animated", "");
     } else {
       this._variables.removeAttribute("animated");
     }
-    if (aFlags.visible) {
+    if (aVisibleFlag) {
       this._variables.style.marginRight = "0";
       this._togglePanesButton.removeAttribute("variablesHidden");
       this._togglePanesButton.setAttribute("tooltiptext", L10N.getStr("collapsePanes"));
     } else {
       let margin = parseInt(this._variables.getAttribute("width")) + 1;
       this._variables.style.marginRight = -margin + "px";
       this._togglePanesButton.setAttribute("variablesHidden", "true");
       this._togglePanesButton.setAttribute("tooltiptext", L10N.getStr("expandPanes"));
     }
-    if (!aFlags.silent) {
-      Prefs.variablesPaneVisible = !!aFlags.visible;
-    }
-  },
-
-  /**
-   * Shows the stackframes, breakpoints and variable panes if currently hidden
-   * and the preferences dictate otherwise.
-   */
-  showPanesIfAllowed: function DV_showPanesIfAllowed() {
-    // Try to keep animations as smooth as possible, so wait a few cycles.
-    window.setTimeout(function() {
-      let shown;
-
-      if (Prefs.stackframesPaneVisible &&
-          this._togglePanesButton.getAttribute("stackframesAndBreakpointsHidden")) {
-        this.toggleStackframesAndBreakpointsPane({
-          visible: true,
-          animated: true,
-          silent: true
-        });
-        shown = true;
-      }
-      if (Prefs.variablesPaneVisible &&
-          this._togglePanesButton.getAttribute("variablesHidden")) {
-        this.toggleVariablesPane({
-          visible: true,
-          animated: true,
-          silent: true
-        });
-        shown = true;
-      }
-      if (shown) {
-        this._onPanesToggle();
-      }
-    }.bind(this), PANES_APPEARANCE_DELAY);
-  },
-
-  /**
-   * Displaying the panes may have the effect of triggering scrollbars to
-   * appear in the source editor, which would render the currently highlighted
-   * line to appear behind them in some cases.
-   */
-  _onPanesToggle: function DV__onPanesToggle() {
-    document.addEventListener("transitionend", function onEvent() {
-      document.removeEventListener("transitionend", onEvent);
-      DebuggerController.StackFrames.updateEditorLocation();
-    });
+    Prefs.variablesPaneVisible = aVisibleFlag;
   },
 
   /**
    * The cached global view elements.
    */
   _togglePanesButton: null,
   _stackframesAndBreakpoints: null,
   _stackframes: null,
@@ -1682,18 +1620,16 @@ StackFramesView.prototype = {
    * @return object
    *         The newly created html node representing the added frame.
    */
   addFrame: function DVF_addFrame(aDepth, aFrameNameText, aFrameDetailsText) {
     // Make sure we don't duplicate anything.
     if (document.getElementById("stackframe-" + aDepth)) {
       return null;
     }
-    // Stackframes are UI elements which benefit from visible panes.
-    DebuggerView.showPanesIfAllowed();
 
     let frame = document.createElement("box");
     let frameName = document.createElement("label");
     let frameDetails = document.createElement("label");
 
     // Create a list item to be added to the stackframes container.
     frame.id = "stackframe-" + aDepth;
     frame.className = "dbg-stackframe list-item";
--- a/browser/devtools/debugger/test/browser_dbg_pane-collapse.js
+++ b/browser/devtools/debugger/test/browser_dbg_pane-collapse.js
@@ -14,62 +14,42 @@ var gView = null;
 function test() {
   debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPane = aPane;
     gDebugger = gPane.contentWindow;
     gView = gDebugger.DebuggerView;
 
-    testPanesState();
-
-    gView.toggleStackframesAndBreakpointsPane({ visible: true });
-    gView.toggleVariablesPane({ visible: true });
     testPaneCollapse1();
     testPaneCollapse2();
-
     closeDebuggerAndFinish();
   });
 }
 
-function testPanesState() {
-  let togglePanesButton =
-    gDebugger.document.getElementById("toggle-panes");
-
-  ok(togglePanesButton.getAttribute("stackframesAndBreakpointsHidden"),
-    "The stackframes and breakpoints pane should initially be invisible.");
-  is(gDebugger.Prefs.stackframesPaneVisible, true,
-    "The stackframes and breakpoints pane should initially be preffed as visible.");
-
-  ok(togglePanesButton.getAttribute("variablesHidden"),
-    "The stackframes and breakpoints pane should initially be invisible.");
-  is(gDebugger.Prefs.variablesPaneVisible, true,
-    "The stackframes and breakpoints pane should initially be preffed as visible.");
-}
-
 function testPaneCollapse1() {
   let stackframesAndBrekpoints =
     gDebugger.document.getElementById("stackframes+breakpoints");
   let togglePanesButton =
     gDebugger.document.getElementById("toggle-panes");
 
   let width = parseInt(stackframesAndBrekpoints.getAttribute("width"));
   is(width, gDebugger.Prefs.stackframesWidth,
     "The stackframes and breakpoints pane has an incorrect width.");
   is(stackframesAndBrekpoints.style.marginLeft, "0px",
-    "The stackframes and breakpoints pane has an incorrect left margin.");
+    "The stackframes and breakpoints pane has an incorrect initial left margin.");
   ok(!stackframesAndBrekpoints.hasAttribute("animated"),
-    "The stackframes and breakpoints pane has an incorrect animated attribute.");
+    "The stackframes and breakpoints pane has an incorrect initial animated attribute.");
   ok(!togglePanesButton.getAttribute("stackframesAndBreakpointsHidden"),
-    "The stackframes and breakpoints pane should at this point be visible.");
+    "The stackframes and breakpoints pane should initially be visible.");
 
   is(gDebugger.Prefs.stackframesPaneVisible, true,
-    "The stackframes and breakpoints pane should at this point be visible.");
+    "The stackframes and breakpoints pane should initially be visible.");
 
-  gView.toggleStackframesAndBreakpointsPane({ visible: false, animated: true });
+  gView.showStackframesAndBreakpointsPane(false, true);
 
   is(gDebugger.Prefs.stackframesPaneVisible, false,
     "The stackframes and breakpoints pane should be hidden after collapsing.");
 
   let margin = -(width + 1) + "px";
   is(width, gDebugger.Prefs.stackframesWidth,
     "The stackframes and breakpoints pane has an incorrect width after collapsing.");
   is(stackframesAndBrekpoints.style.marginLeft, margin,
@@ -77,17 +57,17 @@ function testPaneCollapse1() {
   ok(stackframesAndBrekpoints.hasAttribute("animated"),
     "The stackframes and breakpoints pane has an incorrect attribute after an animated collapsing.");
   ok(togglePanesButton.hasAttribute("stackframesAndBreakpointsHidden"),
     "The stackframes and breakpoints pane should not be visible after collapsing.");
 
   is(gDebugger.Prefs.stackframesPaneVisible, false,
     "The stackframes and breakpoints pane should be hidden before uncollapsing.");
 
-  gView.toggleStackframesAndBreakpointsPane({ visible: true, animated: false });
+  gView.showStackframesAndBreakpointsPane(true, false);
 
   is(gDebugger.Prefs.stackframesPaneVisible, true,
     "The stackframes and breakpoints pane should be visible after uncollapsing.");
 
   is(width, gDebugger.Prefs.stackframesWidth,
     "The stackframes and breakpoints pane has an incorrect width after uncollapsing.");
   is(stackframesAndBrekpoints.style.marginLeft, "0px",
     "The stackframes and breakpoints pane has an incorrect left margin after uncollapsing.");
@@ -102,26 +82,26 @@ function testPaneCollapse2() {
     gDebugger.document.getElementById("variables");
   let togglePanesButton =
     gDebugger.document.getElementById("toggle-panes");
 
   let width = parseInt(variables.getAttribute("width"));
   is(width, gDebugger.Prefs.variablesWidth,
     "The variables pane has an incorrect width.");
   is(variables.style.marginRight, "0px",
-    "The variables pane has an incorrect right margin.");
+    "The variables pane has an incorrect initial right margin.");
   ok(!variables.hasAttribute("animated"),
-    "The variables pane has an incorrect animated attribute.");
+    "The variables pane has an incorrect initial animated attribute.");
   ok(!togglePanesButton.getAttribute("variablesHidden"),
-    "The variables pane should at this point be visible.");
+    "The variables pane should initially be visible.");
 
   is(gDebugger.Prefs.variablesPaneVisible, true,
-    "The variables pane should at this point be visible.");
+    "The variables pane should initially be visible.");
 
-  gView.toggleVariablesPane({ visible: false, animated: true });
+  gView.showVariablesPane(false, true);
 
   is(gDebugger.Prefs.variablesPaneVisible, false,
     "The variables pane should be hidden after collapsing.");
 
   let margin = -(width + 1) + "px";
   is(width, gDebugger.Prefs.variablesWidth,
     "The variables pane has an incorrect width after collapsing.");
   is(variables.style.marginRight, margin,
@@ -129,17 +109,17 @@ function testPaneCollapse2() {
   ok(variables.hasAttribute("animated"),
     "The variables pane has an incorrect attribute after an animated collapsing.");
   ok(togglePanesButton.hasAttribute("variablesHidden"),
     "The variables pane should not be visible after collapsing.");
 
   is(gDebugger.Prefs.variablesPaneVisible, false,
     "The variables pane should be hidden before uncollapsing.");
 
-  gView.toggleVariablesPane({ visible: true, animated: false });
+  gView.showVariablesPane(true, false);
 
   is(gDebugger.Prefs.variablesPaneVisible, true,
     "The variables pane should be visible after uncollapsing.");
 
   is(width, gDebugger.Prefs.variablesWidth,
     "The variables pane has an incorrect width after uncollapsing.");
   is(variables.style.marginRight, "0px",
     "The variables pane has an incorrect right margin after uncollapsing.");
--- a/browser/themes/gnomestripe/devtools/debugger.css
+++ b/browser/themes/gnomestripe/devtools/debugger.css
@@ -1,16 +1,16 @@
 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #body {
-  background-color: white;
+  background: -moz-dialog;
 }
 
 /**
  * Debugger content
  */
 
 #dbg-content {
   padding: 0;
--- a/browser/themes/pinstripe/devtools/debugger.css
+++ b/browser/themes/pinstripe/devtools/debugger.css
@@ -2,17 +2,17 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 %include ../shared.inc
 
 #body {
-  background-color: white;
+  background: -moz-dialog;
 }
 
 /**
  * Debugger content
  */
 
 #dbg-content {
   padding: 0;
--- a/browser/themes/winstripe/devtools/debugger.css
+++ b/browser/themes/winstripe/devtools/debugger.css
@@ -1,16 +1,16 @@
 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #body {
-  background-color: white;
+  background: -moz-dialog;
 }
 
 /**
  * Debugger content
  */
 
 #dbg-content {
   padding: 0;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -188,16 +188,20 @@
 
 #include "nsDOMNavigationTiming.h"
 #include "nsITimedChannel.h"
 #include "mozilla/StartupTimeline.h"
 
 #include "mozilla/Telemetry.h"
 #include "nsISecurityUITelemetry.h"
 
+#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
+#include "nsIPrivateBrowsingService.h"
+#endif
+
 static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
                      NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 #if defined(DEBUG_bryner) || defined(DEBUG_chb)
 //#define DEBUG_DOCSHELL_FOCUS
 #define DEBUG_PAGE_CACHE
 #endif
@@ -2717,22 +2721,33 @@ nsDocShell::SetDocLoaderParent(nsDocLoad
         {
             SetIsActive(value);
         }
         if (NS_FAILED(parentAsDocShell->GetAllowDNSPrefetch(&value))) {
             value = false;
         }
         SetAllowDNSPrefetch(value);
     }
+#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
+    // Set the PB flag on the docshell based on the global PB mode for now
+    nsCOMPtr<nsIPrivateBrowsingService> pbs =
+        do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
+    if (pbs) {
+        bool inPrivateBrowsing = false;
+        pbs->GetPrivateBrowsingEnabled(&inPrivateBrowsing);
+        SetUsePrivateBrowsing(inPrivateBrowsing);
+    }
+#else
     nsCOMPtr<nsILoadContext> parentAsLoadContext(do_QueryInterface(parent));
     if (parentAsLoadContext &&
         NS_SUCCEEDED(parentAsLoadContext->GetUsePrivateBrowsing(&value)))
     {
         SetUsePrivateBrowsing(value);
     }
+#endif
 
     nsCOMPtr<nsIURIContentListener> parentURIListener(do_GetInterface(parent));
     if (parentURIListener)
         mContentListener->SetParentContentListener(parentURIListener);
     return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -59,17 +59,17 @@ NotifySubdocumentInvalidationRecursive(L
   aCallback(container, container->GetVisibleRegion());
 }
 
 struct LayerPropertiesBase : public LayerProperties
 {
   LayerPropertiesBase(Layer* aLayer)
     : mLayer(aLayer)
     , mMaskLayer(nullptr)
-    , mVisibleBounds(aLayer->GetVisibleRegion().GetBounds())
+    , mVisibleRegion(aLayer->GetVisibleRegion())
     , mTransform(aLayer->GetTransform())
     , mOpacity(aLayer->GetOpacity())
     , mUseClipRect(!!aLayer->GetClipRect())
   {
     MOZ_COUNT_CTOR(LayerPropertiesBase);
     if (aLayer->GetMaskLayer()) {
       mMaskLayer = CloneLayerTreePropertiesInternal(aLayer->GetMaskLayer());
     }
@@ -113,16 +113,20 @@ struct LayerPropertiesBase : public Laye
       // layers then we can just stop here since we've already invalidated the entire
       // old and new bounds.
       if (!aCallback) {
         ClearInvalidations(mLayer);
         return result;
       }
     }
 
+    nsIntRegion visible;
+    visible.Xor(mVisibleRegion, mLayer->GetVisibleRegion());
+    result = result.Union(TransformRect(visible.GetBounds(), mTransform));
+
     result = result.Union(ComputeChangeInternal(aCallback));
     result = result.Union(TransformRect(mLayer->GetInvalidRegion().GetBounds(), mTransform));
 
     if (mMaskLayer && otherMask) {
       nsIntRect maskDiff = mMaskLayer->ComputeChange(aCallback);
       result = result.Union(TransformRect(maskDiff, mTransform));
     }
 
@@ -140,24 +144,24 @@ struct LayerPropertiesBase : public Laye
 
   nsIntRect NewTransformedBounds()
   {
     return TransformRect(mLayer->GetVisibleRegion().GetBounds(), mLayer->GetTransform());
   }
 
   nsIntRect OldTransformedBounds()
   {
-    return TransformRect(mVisibleBounds, mTransform);
+    return TransformRect(mVisibleRegion.GetBounds(), mTransform);
   }
 
   virtual nsIntRect ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback) { return nsIntRect(); }
 
   nsRefPtr<Layer> mLayer;
   nsAutoPtr<LayerPropertiesBase> mMaskLayer;
-  nsIntRect mVisibleBounds;
+  nsIntRegion mVisibleRegion;
   gfx3DMatrix mTransform;
   float mOpacity;
   nsIntRect mClipRect;
   bool mUseClipRect;
 };
 
 struct ContainerLayerProperties : public LayerPropertiesBase
 {
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -2260,19 +2260,20 @@ public:
    * invalid areas in the layer tree and schedule a layer tree
    * composite operation to display the layer tree.
    *
    * @param aFlags PAINT_COMPOSITE_ONLY : No changes have been made
    * that require a layer tree update, so only schedule a layer
    * tree composite.
    */
   enum {
-    PAINT_COMPOSITE_ONLY
+    PAINT_DEFAULT = 0,
+    PAINT_COMPOSITE_ONLY = 1 << 0
   };
-  void SchedulePaint(uint32_t aFlags = 0);
+  void SchedulePaint(uint32_t aFlags = PAINT_DEFAULT);
 
   /**
    * Checks if the layer tree includes a dedicated layer for this 
    * frame/display item key pair, and invalidates at least aDamageRect
    * area within that layer.
    *
    * If no layer is found, calls InvalidateFrame() instead.
    *