Bug 1352785 - stylo: Ensure children of elements with invalid -moz-binding URLs get styled. r?bholley draft
authorCameron McCormack <cam@mcc.id.au>
Sun, 02 Apr 2017 15:15:44 +0800
changeset 554738 e10c430d32dc9d3377483c86f305d5c1e60182f4
parent 554736 f3ee408e757ff3397ef1215fd8103edbe5fe6fa4
child 622426 6507f6af54a8c4ea3c9760da5894189e6dbf2b8a
push id52039
push userbmo:cam@mcc.id.au
push dateSun, 02 Apr 2017 07:16:17 +0000
reviewersbholley
bugs1352785
milestone55.0a1
Bug 1352785 - stylo: Ensure children of elements with invalid -moz-binding URLs get styled. r?bholley MozReview-Commit-ID: 2zot13HgjWU
layout/base/nsCSSFrameConstructor.cpp
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -5762,54 +5762,65 @@ nsCSSFrameConstructor::AddFrameConstruct
              aContent->NodeInfo()->NameAtom() == nsGkAtoms::area);
 
   // The following code allows the user to specify the base tag
   // of an element using XBL.  XUL and HTML objects (like boxes, menus, etc.)
   // can then be extended arbitrarily.
   const nsStyleDisplay* display = aStyleContext->StyleDisplay();
   RefPtr<nsStyleContext> styleContext(aStyleContext);
   PendingBinding* pendingBinding = nullptr;
-  if ((aFlags & ITEM_ALLOW_XBL_BASE) && display->mBinding)
-  {
-    // Ensure that our XBL bindings are installed.
-
-    nsXBLService* xblService = nsXBLService::GetInstance();
-    if (!xblService)
-      return;
-
-    bool resolveStyle;
-
-    nsAutoPtr<PendingBinding> newPendingBinding(new PendingBinding());
-
-    nsresult rv = xblService->LoadBindings(aContent, display->mBinding->GetURI(),
-                                           display->mBinding->mOriginPrincipal,
-                                           getter_AddRefs(newPendingBinding->mBinding),
-                                           &resolveStyle);
-    if (NS_FAILED(rv) && rv != NS_ERROR_XBL_BLOCKED)
-      return;
-
-    if (newPendingBinding->mBinding) {
-      pendingBinding = newPendingBinding;
-      // aState takes over owning newPendingBinding
-      aState.AddPendingBinding(newPendingBinding.forget());
-    }
-
-    if (aContent->IsStyledByServo()) {
-      NS_WARNING("stylo: Skipping Unsupported binding re-resolve. This needs fixing.");
-      resolveStyle = false;
-    }
-
-    if (resolveStyle) {
-      styleContext =
-        ResolveStyleContext(styleContext->GetParent(), aContent, &aState);
-      display = styleContext->StyleDisplay();
-      aStyleContext = styleContext;
-    }
-
-    aTag = mDocument->BindingManager()->ResolveTag(aContent, &aNameSpaceID);
+  if (aFlags & ITEM_ALLOW_XBL_BASE) {
+    if (display->mBinding) {
+      // Ensure that our XBL bindings are installed.
+
+      nsXBLService* xblService = nsXBLService::GetInstance();
+      if (!xblService)
+        return;
+
+      bool resolveStyle;
+
+      nsAutoPtr<PendingBinding> newPendingBinding(new PendingBinding());
+
+      nsresult rv = xblService->LoadBindings(aContent, display->mBinding->GetURI(),
+                                             display->mBinding->mOriginPrincipal,
+                                             getter_AddRefs(newPendingBinding->mBinding),
+                                             &resolveStyle);
+      if (NS_FAILED(rv) && rv != NS_ERROR_XBL_BLOCKED)
+        return;
+
+      if (newPendingBinding->mBinding) {
+        pendingBinding = newPendingBinding;
+        // aState takes over owning newPendingBinding
+        aState.AddPendingBinding(newPendingBinding.forget());
+      }
+
+      if (aContent->IsStyledByServo()) {
+        NS_WARNING("stylo: Skipping Unsupported binding re-resolve. This needs fixing.");
+        resolveStyle = false;
+      }
+
+      if (resolveStyle) {
+        styleContext =
+          ResolveStyleContext(styleContext->GetParent(), aContent, &aState);
+        display = styleContext->StyleDisplay();
+        aStyleContext = styleContext;
+      }
+
+      aTag = mDocument->BindingManager()->ResolveTag(aContent, &aNameSpaceID);
+    } else if (display->mBinding.ForceGet()) {
+      if (aContent->IsStyledByServo()) {
+        // Servo's should_traverse_children skips styling descendants of
+        // elements with a -moz-binding value.  For -moz-binding URLs that can
+        // be resolved, we will load the binding above, which will style the
+        // children after they have been rearranged in the flattened tree.
+        // If the URL couldn't be resolved, we still need to style the children,
+        // so we do that here.
+        mPresShell->StyleSet()->AsServo()->StyleNewChildren(aContent->AsElement());
+      }
+    }
   }
 
   bool isGeneratedContent = ((aFlags & ITEM_IS_GENERATED_CONTENT) != 0);
 
   // Pre-check for display "none" - if we find that, don't create
   // any frame at all
   if (StyleDisplay::None == display->mDisplay) {
     SetAsUndisplayedContent(aState, aItems, aContent, styleContext, isGeneratedContent);