Bug 1455108: Don't reparent first-line stuff in display: none subtrees. r?heycam draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 19 Apr 2018 18:18:35 +0200
changeset 785084 35b5239882e70270aec7f5af3c4e9a63f05acef9
parent 785083 0c64902054644e9bccceb948a586c0f495936783
child 785142 5365c19f75b10caca0278b721224a64f07bcbfeb
push id107129
push userbmo:emilio@crisal.io
push dateThu, 19 Apr 2018 16:20:55 +0000
reviewersheycam
bugs1455108
milestone61.0a1
Bug 1455108: Don't reparent first-line stuff in display: none subtrees. r?heycam We may no longer know what the right parent style is, and it's not like it matters anyway, the frame tree under us is dead, including placeholders and such holding from us. MozReview-Commit-ID: 1RHTwvKy0zQ
layout/base/RestyleManager.cpp
layout/style/crashtests/1455108.html
layout/style/crashtests/crashtests.list
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -3517,24 +3517,30 @@ RestyleManager::DoReparentComputedStyleF
   // updated as a child).  And given how this method ends up getting called, if
   // we reach here for a table frame, we are already in the middle of
   // reparenting the table wrapper frame.  So no need to
   // UpdateStyleOfOwnedAnonBoxes() here.
 
   ReparentFrameDescendants(aFrame, providerChild, aStyleSet);
 
   // We do not need to do the equivalent of UpdateFramePseudoElementStyles,
-  // because those are hadled by our descendant walk.
+  // because those are handled by our descendant walk.
 }
 
 void
 RestyleManager::ReparentFrameDescendants(nsIFrame* aFrame,
                                          nsIFrame* aProviderChild,
                                          ServoStyleSet& aStyleSet)
 {
+  if (aFrame->GetContent()->IsElement() &&
+      !aFrame->GetContent()->AsElement()->HasServoData()) {
+    // We're getting into a display: none subtree, avoid reparenting into stuff
+    // that is going to go away anyway in seconds.
+    return;
+  }
   nsIFrame::ChildListIterator lists(aFrame);
   for (; !lists.IsDone(); lists.Next()) {
     for (nsIFrame* child : lists.CurrentList()) {
       // only do frames that are in flow
       if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
           child != aProviderChild) {
         DoReparentComputedStyleForFirstLine(child, aStyleSet);
       }
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1455108.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<style>
+  div::first-line {
+    color: yellow:
+  }
+  .foo span {
+    display: none;
+  }
+  .foo::first-line {
+    color: red;
+  }
+</style>
+<div><span>Yo, I'm a first-line<span> really</span></span>
+<script>
+  document.body.offsetTop;
+  document.querySelector('div').classList.add('foo');
+</script>
--- a/layout/style/crashtests/crashtests.list
+++ b/layout/style/crashtests/crashtests.list
@@ -268,8 +268,9 @@ test-pref(dom.animations-api.core.enable
 pref(dom.webcomponents.shadowdom.enabled,true) load 1419554.html
 load 1426312.html
 load 1439793.html
 load 1409183.html
 pref(dom.webcomponents.shadowdom.enabled,true) load 1445682.html
 load 1450691.html
 pref(dom.webcomponents.shadowdom.enabled,true) load 1453206.html
 load 1454140.html
+load 1455108.html