Backed out 2 changesets (bug 1137009)
authorWes Kocher <wkocher@mozilla.com>
Tue, 13 Oct 2015 18:36:12 -0700
changeset 606998 38cffa3439e4820205978f3218e087b122a95048
parent 606997 6ee2ce4e485f5ffcebd2573531cabe9d08c16b25
child 606999 72703ed7364a2a8445d68b7603a641739871289a
push id93006
push userjyavenard@mozilla.com
push dateThu, 15 Oct 2015 05:15:33 +0000
treeherdertry@45ea2a01301e [default view] [failures only]
bugs1137009
milestone43.0a2
backs out735ebc504963a025a007611bad8c9bf7f05c9ed7
7e06450a934c166a81645b56b1818f6e024e6397
Backed out 2 changesets (bug 1137009) Backed out changeset 735ebc504963 (bug 1137009) Backed out changeset 7e06450a934c (bug 1137009)
dom/xul/XULDocument.cpp
xpfe/appshell/nsWebShellWindow.cpp
xpfe/appshell/nsXULWindow.cpp
xpfe/appshell/nsXULWindow.h
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -915,33 +915,16 @@ XULDocument::AttributeWillChange(nsIDocu
     // See if we need to update our ref map.
     if (aAttribute == nsGkAtoms::ref) {
         // Might not need this, but be safe for now.
         nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
         RemoveElementFromRefMap(aElement);
     }
 }
 
-static bool
-ShouldPersistAttribute(nsIDocument* aDocument, Element* aElement)
-{
-    if (aElement->IsXULElement(nsGkAtoms::window)) {
-        if (nsCOMPtr<nsPIDOMWindow> window = aDocument->GetWindow()) {
-            bool isFullscreen;
-            window->GetFullScreen(&isFullscreen);
-            if (isFullscreen) {
-                // Don't persist attributes if it is window element and
-                // we are in fullscreen state.
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
 void
 XULDocument::AttributeChanged(nsIDocument* aDocument,
                               Element* aElement, int32_t aNameSpaceID,
                               nsIAtom* aAttribute, int32_t aModType,
                               const nsAttrValue* aOldValue)
 {
     NS_ASSERTION(aDocument == this, "unexpected doc");
 
@@ -1006,29 +989,28 @@ XULDocument::AttributeChanged(nsIDocumen
             }
         }
     }
 
     // checks for modifications in broadcasters
     bool listener, resolved;
     CheckBroadcasterHookup(aElement, &listener, &resolved);
 
-    if (ShouldPersistAttribute(aDocument, aElement)) {
-        // See if there is anything we need to persist in the localstore.
-        //
-        // XXX Namespace handling broken :-(
-        nsString persist;
-        aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::persist, persist);
-        if (!persist.IsEmpty() &&
-            // XXXldb This should check that it's a token, not just a substring.
-            persist.Find(nsDependentAtomString(aAttribute)) >= 0) {
+    // See if there is anything we need to persist in the localstore.
+    //
+    // XXX Namespace handling broken :-(
+    nsAutoString persist;
+    aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::persist, persist);
+    if (!persist.IsEmpty()) {
+        // XXXldb This should check that it's a token, not just a substring.
+        if (persist.Find(nsDependentAtomString(aAttribute)) >= 0) {
             nsContentUtils::AddScriptRunner(NS_NewRunnableMethodWithArgs
-                <nsIContent*, int32_t, nsIAtom*>
-                (this, &XULDocument::DoPersist, aElement,
-                 kNameSpaceID_None, aAttribute));
+              <nsIContent*, int32_t, nsIAtom*>
+              (this, &XULDocument::DoPersist, aElement, kNameSpaceID_None,
+               aAttribute));
         }
     }
 }
 
 void
 XULDocument::ContentAppended(nsIDocument* aDocument,
                              nsIContent* aContainer,
                              nsIContent* aFirstNewContent,
--- a/xpfe/appshell/nsWebShellWindow.cpp
+++ b/xpfe/appshell/nsWebShellWindow.cpp
@@ -414,18 +414,18 @@ nsWebShellWindow::WindowActivated()
 
   // focusing the window could cause it to close, so keep a reference to it
   nsCOMPtr<nsIDOMWindow> window = mDocShell ? mDocShell->GetWindow() : nullptr;
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   if (fm && window)
     fm->WindowRaised(window);
 
   if (mChromeLoaded) {
-    SetAttributesDirty(PAD_POSITION | PAD_SIZE | PAD_MISC);
-    SaveAttributes();
+    PersistentAttributesDirty(PAD_POSITION | PAD_SIZE | PAD_MISC);
+    SavePersistentAttributes();
    }
 }
 
 void
 nsWebShellWindow::WindowDeactivated()
 {
   nsCOMPtr<nsIXULWindow> xulWindow(this);
 
@@ -507,24 +507,24 @@ nsWebShellWindow::SetPersistenceTimer(ui
     }
   }
 
   nsRefPtr<WebShellWindowTimerCallback> callback =
     new WebShellWindowTimerCallback(this);
   mSPTimer->InitWithCallback(callback, SIZE_PERSISTENCE_TIMEOUT,
                              nsITimer::TYPE_ONE_SHOT);
 
-  SetAttributesDirty(aDirtyFlags);
+  PersistentAttributesDirty(aDirtyFlags);
 }
 
 void
 nsWebShellWindow::FirePersistenceTimer()
 {
   MutexAutoLock lock(mSPTimerLock);
-  SaveAttributes();
+  SavePersistentAttributes();
 }
 
 
 //----------------------------------------
 // nsIWebProgessListener implementation
 //----------------------------------------
 NS_IMETHODIMP
 nsWebShellWindow::OnProgressChange(nsIWebProgress *aProgress,
@@ -767,14 +767,14 @@ NS_IMETHODIMP nsWebShellWindow::Destroy(
     webProgress->RemoveProgressListener(this);
   }
 
   nsCOMPtr<nsIXULWindow> kungFuDeathGrip(this);
   {
     MutexAutoLock lock(mSPTimerLock);
     if (mSPTimer) {
       mSPTimer->Cancel();
-      SaveAttributes();
+      SavePersistentAttributes();
       mSPTimer = nullptr;
     }
   }
   return nsXULWindow::Destroy();
 }
--- a/xpfe/appshell/nsXULWindow.cpp
+++ b/xpfe/appshell/nsXULWindow.cpp
@@ -217,18 +217,18 @@ NS_IMETHODIMP nsXULWindow::SetZLevel(uin
     nsSizeMode sizeMode = mWindow->SizeMode();
     if (sizeMode == nsSizeMode_Maximized || sizeMode == nsSizeMode_Fullscreen) {
       return NS_ERROR_FAILURE;
     }
   }
 
   // do it
   mediator->SetZLevel(this, aLevel);
-  SetAttributesDirty(PAD_MISC);
-  SaveAttributes();
+  PersistentAttributesDirty(PAD_MISC);
+  SavePersistentAttributes();
 
   nsCOMPtr<nsIContentViewer> cv;
   mDocShell->GetContentViewer(getter_AddRefs(cv));
   if (cv) {
     nsCOMPtr<nsIDocument> doc = cv->GetDocument();
     if (doc) {
       ErrorResult rv;
       nsRefPtr<dom::Event> event =
@@ -541,18 +541,18 @@ NS_IMETHODIMP nsXULWindow::SetPosition(i
   nsresult rv = mWindow->Move(aX * invScale, aY * invScale);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
   if (!mChromeLoaded) {
     // If we're called before the chrome is loaded someone obviously wants this
     // window at this position. We don't persist this one-time position.
     mIgnoreXULPosition = true;
     return NS_OK;
   }
-  SetAttributesDirty(PAD_POSITION);
-  SaveAttributes();
+  PersistentAttributesDirty(PAD_POSITION);
+  SavePersistentAttributes();
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULWindow::GetPosition(int32_t* aX, int32_t* aY)
 {
   return GetPositionAndSize(aX, aY, nullptr, nullptr);
 }
 
@@ -573,18 +573,18 @@ NS_IMETHODIMP nsXULWindow::SetSize(int32
     // If we're called before the chrome is loaded someone obviously wants this
     // window at this size & in the normal size mode (since it is the only mode
     // in which setting dimensions makes sense). We don't persist this one-time
     // size.
     mIgnoreXULSize = true;
     mIgnoreXULSizeMode = true;
     return NS_OK;
   }
-  SetAttributesDirty(PAD_SIZE);
-  SaveAttributes();
+  PersistentAttributesDirty(PAD_SIZE);
+  SavePersistentAttributes();
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULWindow::GetSize(int32_t* aCX, int32_t* aCY)
 {
   return GetPositionAndSize(nullptr, nullptr, aCX, aCY);
 }
 
@@ -607,18 +607,18 @@ NS_IMETHODIMP nsXULWindow::SetPositionAn
   if (!mChromeLoaded) {
     // If we're called before the chrome is loaded someone obviously wants this
     // window at this size and position. We don't persist this one-time setting.
     mIgnoreXULPosition = true;
     mIgnoreXULSize = true;
     mIgnoreXULSizeMode = true;
     return NS_OK;
   }
-  SetAttributesDirty(PAD_POSITION | PAD_SIZE);
-  SaveAttributes();
+  PersistentAttributesDirty(PAD_POSITION | PAD_SIZE);
+  SavePersistentAttributes();
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULWindow::GetPositionAndSize(int32_t* x, int32_t* y, int32_t* cx,
    int32_t* cy)
 {
   nsIntRect rect;
 
@@ -1424,27 +1424,32 @@ void nsXULWindow::SyncAttributesToWidget
 
   // "macanimationtype" attribute
   windowElement->GetAttribute(NS_LITERAL_STRING("macanimationtype"), attr);
   if (attr.EqualsLiteral("document")) {
     mWindow->SetWindowAnimationType(nsIWidget::eDocumentWindowAnimation);
   }
 }
 
-void nsXULWindow::SaveAttributes()
+NS_IMETHODIMP nsXULWindow::SavePersistentAttributes()
 {
   // can happen when the persistence timer fires at an inopportune time
   // during window shutdown
-  if (!mDocShell) {
-    return;
-  }
+  if (!mDocShell)
+    return NS_ERROR_FAILURE;
 
   nsCOMPtr<dom::Element> docShellElement = GetWindowDOMElement();
-  if (!docShellElement) {
-    return;
+  if (!docShellElement)
+    return NS_ERROR_FAILURE;
+
+  nsAutoString   persistString;
+  docShellElement->GetAttribute(PERSIST_ATTRIBUTE, persistString);
+  if (persistString.IsEmpty()) { // quick check which sometimes helps
+    mPersistentAttributesDirty = 0;
+    return NS_OK;
   }
 
   // get our size, position and mode to persist
   nsIntRect rect;
   bool gotRestoredBounds = NS_SUCCEEDED(mWindow->GetRestoredBounds(rect));
 
   CSSToLayoutDeviceScale scale = mWindow->GetDefaultScale();
 
@@ -1455,63 +1460,90 @@ void nsXULWindow::SaveAttributes()
     if (NS_SUCCEEDED(parent->GetPosition(&parentX, &parentY))) {
       rect.x -= parentX;
       rect.y -= parentY;
     }
   }
 
   char                        sizeBuf[10];
   nsAutoString                sizeString;
+  nsAutoString                windowElementId;
+  nsCOMPtr<nsIDOMXULDocument> ownerXULDoc;
+
+  // fetch docShellElement's ID and XUL owner document
+  ownerXULDoc = do_QueryInterface(docShellElement->OwnerDoc());
+  if (docShellElement->IsXULElement()) {
+    docShellElement->GetId(windowElementId);
+  }
 
   ErrorResult rv;
   // (only for size elements which are persisted)
   if ((mPersistentAttributesDirty & PAD_POSITION) && gotRestoredBounds) {
-    PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.x / scale.scale));
-    sizeString.AssignWithConversion(sizeBuf);
-    docShellElement->SetAttribute(SCREENX_ATTRIBUTE, sizeString, rv);
-
-    PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.y / scale.scale));
-    sizeString.AssignWithConversion(sizeBuf);
-    docShellElement->SetAttribute(SCREENY_ATTRIBUTE, sizeString, rv);
+    if (persistString.Find("screenX") >= 0) {
+      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.x / scale.scale));
+      sizeString.AssignWithConversion(sizeBuf);
+      docShellElement->SetAttribute(SCREENX_ATTRIBUTE, sizeString, rv);
+      if (ownerXULDoc) // force persistence in case the value didn't change
+        ownerXULDoc->Persist(windowElementId, SCREENX_ATTRIBUTE);
+    }
+    if (persistString.Find("screenY") >= 0) {
+      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.y / scale.scale));
+      sizeString.AssignWithConversion(sizeBuf);
+      docShellElement->SetAttribute(SCREENY_ATTRIBUTE, sizeString, rv);
+      if (ownerXULDoc)
+        ownerXULDoc->Persist(windowElementId, SCREENY_ATTRIBUTE);
+    }
   }
 
   if ((mPersistentAttributesDirty & PAD_SIZE) && gotRestoredBounds) {
-    PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.width / scale.scale));
-    sizeString.AssignWithConversion(sizeBuf);
-    docShellElement->SetAttribute(WIDTH_ATTRIBUTE, sizeString, rv);
-
-    PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.height / scale.scale));
-    sizeString.AssignWithConversion(sizeBuf);
-    docShellElement->SetAttribute(HEIGHT_ATTRIBUTE, sizeString, rv);
+    if (persistString.Find("width") >= 0) {
+      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.width / scale.scale));
+      sizeString.AssignWithConversion(sizeBuf);
+      docShellElement->SetAttribute(WIDTH_ATTRIBUTE, sizeString, rv);
+      if (ownerXULDoc)
+        ownerXULDoc->Persist(windowElementId, WIDTH_ATTRIBUTE);
+    }
+    if (persistString.Find("height") >= 0) {
+      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.height / scale.scale));
+      sizeString.AssignWithConversion(sizeBuf);
+      docShellElement->SetAttribute(HEIGHT_ATTRIBUTE, sizeString, rv);
+      if (ownerXULDoc)
+        ownerXULDoc->Persist(windowElementId, HEIGHT_ATTRIBUTE);
+    }
   }
 
   if (mPersistentAttributesDirty & PAD_MISC) {
     nsSizeMode sizeMode = mWindow->SizeMode();
 
     if (sizeMode != nsSizeMode_Minimized) {
       if (sizeMode == nsSizeMode_Maximized)
         sizeString.Assign(SIZEMODE_MAXIMIZED);
       else if (sizeMode == nsSizeMode_Fullscreen)
         sizeString.Assign(SIZEMODE_FULLSCREEN);
       else
         sizeString.Assign(SIZEMODE_NORMAL);
       docShellElement->SetAttribute(MODE_ATTRIBUTE, sizeString, rv);
+      if (ownerXULDoc && persistString.Find("sizemode") >= 0)
+        ownerXULDoc->Persist(windowElementId, MODE_ATTRIBUTE);
     }
-
-    uint32_t zLevel;
-    nsCOMPtr<nsIWindowMediator> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
-    if (mediator) {
-      mediator->GetZLevel(this, &zLevel);
-      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%lu", (unsigned long)zLevel);
-      sizeString.AssignWithConversion(sizeBuf);
-      docShellElement->SetAttribute(ZLEVEL_ATTRIBUTE, sizeString, rv);
+    if (persistString.Find("zlevel") >= 0) {
+      uint32_t zLevel;
+      nsCOMPtr<nsIWindowMediator> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
+      if (mediator) {
+        mediator->GetZLevel(this, &zLevel);
+        PR_snprintf(sizeBuf, sizeof(sizeBuf), "%lu", (unsigned long)zLevel);
+        sizeString.AssignWithConversion(sizeBuf);
+        docShellElement->SetAttribute(ZLEVEL_ATTRIBUTE, sizeString, rv);
+        ownerXULDoc->Persist(windowElementId, ZLEVEL_ATTRIBUTE);
+      }
     }
   }
 
   mPersistentAttributesDirty = 0;
+  return NS_OK;
 }
 
 NS_IMETHODIMP nsXULWindow::GetWindowDOMWindow(nsIDOMWindow** aDOMWindow)
 {
   NS_ENSURE_STATE(mDocShell);
 
   if (!mDOMWindow)
     mDOMWindow = mDocShell->GetWindow();
@@ -1971,17 +2003,17 @@ bool nsXULWindow::GetContentScrollbarVis
     if (prefValue == nsIScrollable::Scrollbar_Never)
       return false;
   }
 
   return true;
 }
 
 // during spinup, attributes that haven't been loaded yet can't be dirty
-void nsXULWindow::SetAttributesDirty(uint32_t aDirtyFlags)
+void nsXULWindow::PersistentAttributesDirty(uint32_t aDirtyFlags)
 {
   mPersistentAttributesDirty |= aDirtyFlags & mPersistentAttributesMask;
 }
 
 NS_IMETHODIMP nsXULWindow::ApplyChromeFlags()
 {
   nsCOMPtr<dom::Element> window = GetWindowDOMElement();
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
--- a/xpfe/appshell/nsXULWindow.h
+++ b/xpfe/appshell/nsXULWindow.h
@@ -91,17 +91,17 @@ protected:
 
    void OnChromeLoaded();
    void StaggerPosition(int32_t &aRequestedX, int32_t &aRequestedY,
                         int32_t aSpecWidth, int32_t aSpecHeight);
    bool       LoadPositionFromXUL();
    bool       LoadSizeFromXUL();
    bool       LoadMiscPersistentAttributesFromXUL();
    void       SyncAttributesToWidget();
-   void       SaveAttributes();
+   NS_IMETHOD SavePersistentAttributes();
 
    NS_IMETHOD GetWindowDOMWindow(nsIDOMWindow** aDOMWindow);
    mozilla::dom::Element* GetWindowDOMElement() const;
 
    // See nsIDocShellTreeOwner for docs on next two methods
    nsresult ContentShellAdded(nsIDocShellTreeItem* aContentShell,
                                           bool aPrimary, bool aTargetable,
                                           const nsAString& aID);
@@ -114,17 +114,17 @@ protected:
 
    void       EnableParent(bool aEnable);
    bool       ConstrainToZLevel(bool aImmediate, nsWindowZ *aPlacement,
                                 nsIWidget *aReqBelow, nsIWidget **aActualBelow);
    void       PlaceWindowLayersBehind(uint32_t aLowLevel, uint32_t aHighLevel,
                                       nsIXULWindow *aBehind);
    void       SetContentScrollbarVisibility(bool aVisible);
    bool       GetContentScrollbarVisibility();
-   void       SetAttributesDirty(uint32_t aDirtyFlags);
+   void       PersistentAttributesDirty(uint32_t aDirtyFlags);
 
    nsChromeTreeOwner*      mChromeTreeOwner;
    nsContentTreeOwner*     mContentTreeOwner;
    nsContentTreeOwner*     mPrimaryContentTreeOwner;
    nsCOMPtr<nsIWidget>     mWindow;
    nsCOMPtr<nsIDocShell>   mDocShell;
    nsCOMPtr<nsIDOMWindow>  mDOMWindow;
    nsCOMPtr<nsIWeakReference> mParentWindow;