Bug 1292662 - Style XBL anonymous content after binding explicit children to insertion points. r=heycam
authorBobby Holley <bobbyholley@gmail.com>
Thu, 11 Aug 2016 16:31:57 -0700
changeset 311291 1ba090154f480d7afeea724d65b983a77bd6e7e9
parent 311290 4f13817111efea19ca9d0eb91979f7ee1e94f267
child 311292 1f1748ac77ef4c292612a08368577e5da817a4b3
push id81091
push userbholley@mozilla.com
push dateFri, 26 Aug 2016 04:37:35 +0000
treeherdermozilla-inbound@45d015eed45f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1292662
milestone51.0a1
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 1292662 - Style XBL anonymous content after binding explicit children to insertion points. r=heycam We're doing it too soon, which means that the subtree isn't fully set up.
dom/xbl/nsXBLBinding.cpp
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -201,20 +201,16 @@ nsXBLBinding::InstallAnonymousContent(ns
   // element's document, assuming that the bound element is in a document
   // Note that we don't change the current doc of aAnonParent here, since that
   // quite simply does not matter.  aAnonParent is just a way of keeping refs
   // to all its kids, which are anonymous content from the point of view of
   // aElement.
   // (2) The children's parent back pointer should not be to this synthetic root
   // but should instead point to the enclosing parent element.
   nsIDocument* doc = aElement->GetUncomposedDoc();
-  ServoStyleSet* servoStyleSet = nullptr;
-  if (nsIPresShell* presShell = aElement->OwnerDoc()->GetShell()) {
-    servoStyleSet = presShell->StyleSet()->GetAsServo();
-  }
   bool allowScripts = AllowScripts();
 
   nsAutoScriptBlocker scriptBlocker;
   for (nsIContent* child = aAnonParent->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
     child->UnbindFromTree();
     if (aChromeOnlyContent) {
@@ -235,20 +231,16 @@ nsXBLBinding::InstallAnonymousContent(ns
 #ifdef MOZ_XUL
     // To make XUL templates work (and other goodies that happen when
     // an element is added to a XUL document), we need to notify the
     // XUL document using its special API.
     nsCOMPtr<nsIXULDocument> xuldoc(do_QueryInterface(doc));
     if (xuldoc)
       xuldoc->AddSubtreeToDocument(child);
 #endif
-
-    if (servoStyleSet) {
-      servoStyleSet->StyleNewSubtree(child);
-    }
   }
 }
 
 void
 nsXBLBinding::UninstallAnonymousContent(nsIDocument* aDocument,
                                         nsIContent* aAnonParent)
 {
   nsAutoScriptBlocker scriptBlocker;
@@ -423,16 +415,25 @@ nsXBLBinding::GenerateAnonymousContent()
                                value2, false);
       }
     }
 
     // Conserve space by wiping the attributes off the clone.
     if (mContent)
       mContent->UnsetAttr(namespaceID, name, false);
   }
+
+  // Now that we've finished shuffling the tree around, go ahead and restyle it
+  // since frame construction is about to happen.
+  nsIPresShell* presShell = mBoundElement->OwnerDoc()->GetShell();
+  ServoStyleSet* servoSet = presShell->StyleSet()->GetAsServo();
+  if (servoSet) {
+    mBoundElement->SetHasDirtyDescendantsForServo();
+    servoSet->StyleNewChildren(mBoundElement);
+  }
 }
 
 XBLChildrenElement*
 nsXBLBinding::FindInsertionPointFor(nsIContent* aChild)
 {
   // XXX We should get rid of this function as it causes us to traverse the
   // binding chain multiple times
   if (mContent) {