Bug 602962 - Undo close tab thumbnail disappears when rotating screen orientation [r=smaug r=roc a=blocking-fennecb3]
authorVivien Nicolas <21@vingtetun.org>
Wed, 17 Nov 2010 08:46:00 -0500
changeset 57661 2cd50afa5a00164d43cbabc7d7bd1e843cbaf2ed
parent 57660 6cfd43067a07e1e7d818c02b6a7b1ea62e8ace02
child 57662 dc021bc9929f6a93abc1aac7867600d90c3ba2cc
push id17030
push usermfinkle@mozilla.com
push dateWed, 17 Nov 2010 20:59:29 +0000
treeherdermozilla-central@2cd50afa5a00 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, roc, blocking-fennecb3
bugs602962
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 602962 - Undo close tab thumbnail disappears when rotating screen orientation [r=smaug r=roc a=blocking-fennecb3]
content/base/src/nsContentUtils.cpp
content/base/src/nsGkAtomList.h
content/events/src/nsDOMEvent.cpp
content/events/src/nsDOMEvent.h
content/events/test/Makefile.in
content/events/test/bug602962.xul
content/events/test/test_bug602962.xul
layout/base/nsPresShell.cpp
widget/public/nsGUIEvent.h
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -587,16 +587,17 @@ nsContentUtils::InitializeEventTable() {
     { nsGkAtoms::onDOMFocusOut,                 NS_UI_FOCUSOUT, EventNameType_HTMLXUL, NS_UI_EVENT },
     { nsGkAtoms::oninput,                       NS_FORM_INPUT, EventNameType_HTMLXUL, NS_UI_EVENT },
                                                 
     { nsGkAtoms::onDOMMouseScroll,              NS_MOUSE_SCROLL, EventNameType_HTMLXUL, NS_MOUSE_SCROLL_EVENT },
     { nsGkAtoms::onMozMousePixelScroll,         NS_MOUSE_PIXEL_SCROLL, EventNameType_HTMLXUL, NS_MOUSE_SCROLL_EVENT },
                                                 
     { nsGkAtoms::onpageshow,                    NS_PAGE_SHOW, EventNameType_HTML, NS_EVENT },
     { nsGkAtoms::onpagehide,                    NS_PAGE_HIDE, EventNameType_HTML, NS_EVENT },
+    { nsGkAtoms::onMozBeforeResize,             NS_BEFORERESIZE_EVENT, EventNameType_None, NS_EVENT },
     { nsGkAtoms::onresize,                      NS_RESIZE_EVENT,
                                                 (EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT },
     { nsGkAtoms::onscroll,                      NS_SCROLL_EVENT,
                                                 (EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT_NULL },
     { nsGkAtoms::oncopy,                        NS_COPY, EventNameType_HTMLXUL, NS_EVENT },
     { nsGkAtoms::oncut,                         NS_CUT, EventNameType_HTMLXUL, NS_EVENT },
     { nsGkAtoms::onpaste,                       NS_PASTE, EventNameType_HTMLXUL, NS_EVENT },
     // XUL specific events
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -704,16 +704,17 @@ GK_ATOM(onpaint, "onpaint")
 GK_ATOM(onpaste, "onpaste")
 GK_ATOM(onpopuphidden, "onpopuphidden")
 GK_ATOM(onpopuphiding, "onpopuphiding")
 GK_ATOM(onpopupshowing, "onpopupshowing")
 GK_ATOM(onpopupshown, "onpopupshown")
 GK_ATOM(onreadystatechange, "onreadystatechange")
 GK_ATOM(onRequest, "onRequest")
 GK_ATOM(onreset, "onreset")
+GK_ATOM(onMozBeforeResize, "onMozBeforeResize")
 GK_ATOM(onresize, "onresize")
 GK_ATOM(onscroll, "onscroll")
 GK_ATOM(onselect, "onselect")
 GK_ATOM(onset, "onset")
 GK_ATOM(onsubmit, "onsubmit")
 GK_ATOM(ontext, "ontext")
 GK_ATOM(ontransitionend, "ontransitionend")
 GK_ATOM(onunderflow, "onunderflow")
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -88,16 +88,17 @@ static const char* const sEventNames[] =
 #ifdef MOZ_MEDIA
   "loadstart", "progress", "suspend", "emptied", "stalled", "play", "pause",
   "loadedmetadata", "loadeddata", "waiting", "playing", "canplay",
   "canplaythrough", "seeking", "seeked", "timeupdate", "ended", "ratechange",
   "durationchange", "volumechange", "MozAudioAvailable",
 #endif // MOZ_MEDIA
   "MozAfterPaint",
   "MozBeforePaint",
+  "MozBeforeResize",
   "MozSwipeGesture",
   "MozMagnifyGestureStart",
   "MozMagnifyGestureUpdate",
   "MozMagnifyGesture",
   "MozRotateGestureStart",
   "MozRotateGestureUpdate",
   "MozRotateGesture",
   "MozTapGesture",
@@ -1311,16 +1312,18 @@ const char* nsDOMEvent::GetEventName(PRU
     return sEventNames[eDOMEvents_volumechange];
   case NS_MOZAUDIOAVAILABLE:
     return sEventNames[eDOMEvents_mozaudioavailable];
 #endif
   case NS_AFTERPAINT:
     return sEventNames[eDOMEvents_afterpaint];
   case NS_BEFOREPAINT:
     return sEventNames[eDOMEvents_beforepaint];
+  case NS_BEFORERESIZE_EVENT:
+    return sEventNames[eDOMEvents_beforeresize];
   case NS_SIMPLE_GESTURE_SWIPE:
     return sEventNames[eDOMEvents_MozSwipeGesture];
   case NS_SIMPLE_GESTURE_MAGNIFY_START:
     return sEventNames[eDOMEvents_MozMagnifyGestureStart];
   case NS_SIMPLE_GESTURE_MAGNIFY_UPDATE:
     return sEventNames[eDOMEvents_MozMagnifyGestureUpdate];
   case NS_SIMPLE_GESTURE_MAGNIFY:
     return sEventNames[eDOMEvents_MozMagnifyGesture];
--- a/content/events/src/nsDOMEvent.h
+++ b/content/events/src/nsDOMEvent.h
@@ -170,16 +170,17 @@ public:
     eDOMEvents_ended,
     eDOMEvents_ratechange,
     eDOMEvents_durationchange,
     eDOMEvents_volumechange,
     eDOMEvents_mozaudioavailable,
 #endif
     eDOMEvents_afterpaint,
     eDOMEvents_beforepaint,
+    eDOMEvents_beforeresize,
     eDOMEvents_MozSwipeGesture,
     eDOMEvents_MozMagnifyGestureStart,
     eDOMEvents_MozMagnifyGestureUpdate,
     eDOMEvents_MozMagnifyGesture,
     eDOMEvents_MozRotateGestureStart,
     eDOMEvents_MozRotateGestureUpdate,
     eDOMEvents_MozRotateGesture,
     eDOMEvents_MozTapGesture,
--- a/content/events/test/Makefile.in
+++ b/content/events/test/Makefile.in
@@ -105,15 +105,17 @@ ifneq (mobile,$(MOZ_BUILD_APP))
 		test_dragstart.html \
 		$(NULL)
 endif
 
 _CHROME_FILES = \
 		test_bug415498.xul \
 		bug415498-doc1.html \
 		bug415498-doc2.html \
+		bug602962.xul \
+		test_bug602962.xul \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
 libs:: $(_CHROME_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/events/test/bug602962.xul
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window onload="window.opener.doTest()" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <scrollbox id="page-scrollbox" style="border: 1px solid red; background-color: black;overflow: auto" flex="1">
+    <box id="page-box" style="border: 1px solid green;"/>
+  </scrollbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/content/events/test/test_bug602962.xul
@@ -0,0 +1,94 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=602962
+-->
+<window title="Mozilla Bug 602962" onload="openWindow()"
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <title>Test for Bug 602962</title>
+  <script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"/>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+<body  xmlns="http://www.w3.org/1999/xhtml">
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=602962">Mozilla Bug 602962</a>
+  <p id="display"></p>
+<div id="content" style="display: none">
+</div>
+</body>
+
+<script class="testbody" type="application/javascript;version=1.8"><![CDATA[
+/** Test for Bug 602962 **/
+var scrollbox, sbo, content;
+var scrollX = 0, scrollY = 0;
+
+var mozBeforeResizeHasFired = false;
+var oldWidth = 0, oldHeight = 0;
+var win = null;
+
+function openWindow() {
+  win = window.open("chrome://mochitests/content/chrome/content/events/test/bug602962.xul", "_blank", "width=600,height=600");
+}
+
+function doTest() {
+  scrollbox = win.document.getElementById("page-scrollbox");
+  sbo = scrollbox.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
+  content = win.document.getElementById("page-box");
+  content.style.width = 400 + "px";
+  
+  win.addEventListener("resize", function() {
+    win.removeEventListener("resize", arguments.callee, false);
+
+    sbo.scrollBy(200, 0);
+    setTimeout(function() { resize(); }, 0);
+  }, false);
+
+  oldWidth = win.outerWidth;
+  oldHeight = win.outerHeight;
+  win.resizeTo(200, 400);
+}
+
+function resize() {
+  win.addEventListener("MozBeforeResize", function() {
+    win.removeEventListener("MozBeforeResize", arguments.callee, false);
+    mozBeforeResizeHasFired = true;
+
+    let x = {}, y = {};
+    sbo.getPosition(x, y);
+    scrollX = x.value, scrollY = y.value;
+    is(scrollX, 200, "Scroll X should not have changed yet");
+    is(scrollY, 0, "Scroll Y should not have changed yet");
+  }, false);
+
+  win.addEventListener("resize", function() {
+    content.style.width = (oldWidth + 400) + "px";
+    win.removeEventListener("resize", arguments.callee, true);
+    
+    setTimeout(function() {
+      finish();
+    }, 0);
+  }, true);
+
+  win.resizeTo(oldWidth, oldHeight);
+}
+
+function finish() {
+  is(mozBeforeResizeHasFired, true, "The MozBeforeResize event should already have fired");
+  sbo.scrollBy(scrollX, scrollY);
+
+  let x = {}, y = {};
+  sbo.getPosition(x, y);
+  is(x.value, 200, "Scroll X should have been restored to the value before the resize");
+  is(y.value, 0, "Scroll Y should have been restored to the value before the resize");
+
+  is(win.outerWidth, oldWidth, "Width should be resized");
+  is(win.outerHeight, oldHeight, "Height should be resized");
+  win.close();
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+]]></script>
+
+</window>
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -1350,16 +1350,17 @@ private:
   // Get the selected item and coordinates in device pixels relative to root
   // document's root view for element, first ensuring the element is onscreen
   void GetCurrentItemAndPositionForElement(nsIDOMElement *aCurrentEl,
                                            nsIContent **aTargetToUse,
                                            nsIntPoint& aTargetPt,
                                            nsIWidget *aRootWidget);
 
   void FireResizeEvent();
+  void FireBeforeResizeEvent();
   static void AsyncResizeEventCallback(nsITimer* aTimer, void* aPresShell);
   nsRevocableEventPtr<nsRunnableMethod<PresShell> > mResizeEvent;
   nsCOMPtr<nsITimer> mAsyncResizeEventTimer;
   PRPackedBool mAsyncResizeTimerIsActive;
   PRPackedBool mInResize;
 
 private:
 #ifdef DEBUG
@@ -2825,16 +2826,21 @@ PresShell::ResizeReflowIgnoreOverride(ns
   nsIFrame* rootFrame = FrameManager()->GetRootFrame();
 
   if (!rootFrame && aHeight == NS_UNCONSTRAINEDSIZE) {
     // We can't do the work needed for SizeToContent without a root
     // frame, and we want to return before setting the visible area.
     return NS_ERROR_NOT_AVAILABLE;
   }
 
+  if (!mIsDestroying && !mResizeEvent.IsPending() &&
+      !mAsyncResizeTimerIsActive) {
+    FireBeforeResizeEvent();
+  }
+
   mPresContext->SetVisibleArea(nsRect(0, 0, aWidth, aHeight));
 
   // There isn't anything useful we can do if the initial reflow hasn't happened
   if (!rootFrame)
     return NS_OK;
 
   NS_ASSERTION(mViewManager, "Must have view manager");
   nsCOMPtr<nsIViewManager> viewManagerDeathGrip = mViewManager;
@@ -2901,16 +2907,32 @@ PresShell::ResizeReflowIgnoreOverride(ns
       }
     }
   }
 
   return NS_OK; //XXX this needs to be real. MMP
 }
 
 void
+PresShell::FireBeforeResizeEvent()
+{
+  if (mIsDocumentGone)
+    return;
+
+  // Send beforeresize event from here.
+  nsEvent event(PR_TRUE, NS_BEFORERESIZE_EVENT);
+
+  nsPIDOMWindow *window = mDocument->GetWindow();
+  if (window) {
+    nsCOMPtr<nsIPresShell> kungFuDeathGrip(this);
+    nsEventDispatcher::Dispatch(window, mPresContext, &event);
+  }
+}
+
+void
 PresShell::FireResizeEvent()
 {
   if (mAsyncResizeTimerIsActive) {
     mAsyncResizeTimerIsActive = PR_FALSE;
     mAsyncResizeEventTimer->Cancel();
   }
   mResizeEvent.Revoke();
 
--- a/widget/public/nsGUIEvent.h
+++ b/widget/public/nsGUIEvent.h
@@ -231,16 +231,19 @@ class nsHashKey;
 // the window is active. In the latter case, the dispatcher of the event
 // is expected to ensure that the plugin's widget is focused beforehand.
 #define NS_PLUGIN_ACTIVATE               (NS_WINDOW_START + 62)
 #define NS_PLUGIN_FOCUS                  (NS_WINDOW_START + 63)
 
 #define NS_OFFLINE                       (NS_WINDOW_START + 64)
 #define NS_ONLINE                        (NS_WINDOW_START + 65)
 
+// Indicates a resize will occur
+#define NS_BEFORERESIZE_EVENT            (NS_WINDOW_START + 66)
+
 #define NS_MOUSE_MESSAGE_START          300
 #define NS_MOUSE_MOVE                   (NS_MOUSE_MESSAGE_START)
 #define NS_MOUSE_BUTTON_UP              (NS_MOUSE_MESSAGE_START + 1)
 #define NS_MOUSE_BUTTON_DOWN            (NS_MOUSE_MESSAGE_START + 2)
 #define NS_MOUSE_ENTER                  (NS_MOUSE_MESSAGE_START + 22)
 #define NS_MOUSE_EXIT                   (NS_MOUSE_MESSAGE_START + 23)
 #define NS_MOUSE_DOUBLECLICK            (NS_MOUSE_MESSAGE_START + 24)
 #define NS_MOUSE_CLICK                  (NS_MOUSE_MESSAGE_START + 27)