Bug 1353317 - stylo: For newly added content, note dirty descendants in the lazy frame construction case through the flattened tree parent. r?bholley draft
authorCameron McCormack <cam@mcc.id.au>
Tue, 04 Apr 2017 18:28:05 +0800
changeset 559672 66ee1a718792b67e11464a750ff97295219b5c41
parent 559671 8c88be8e7f0527f73e106459ab7dd82e1845d73c
child 623457 593e815ea424cfa547608689a17e1bcf8490060e
push id53158
push userbmo:cam@mcc.id.au
push dateMon, 10 Apr 2017 09:58:23 +0000
reviewersbholley
bugs1353317
milestone55.0a1
Bug 1353317 - stylo: For newly added content, note dirty descendants in the lazy frame construction case through the flattened tree parent. r?bholley MozReview-Commit-ID: L6MhRK3zmSc
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/reftests/bugs/reftest-stylo.list
layout/reftests/dom/reftest-stylo.list
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -7396,16 +7396,30 @@ nsCSSFrameConstructor::MaybeRecreateForF
         return true;
       }
     }
   }
   return false;
 }
 
 void
+nsCSSFrameConstructor::LazilyStyleNewChildRange(nsIContent* aStartChild,
+                                                nsIContent* aEndChild)
+{
+  for (nsIContent* child = aStartChild; child != aEndChild;
+       child = child->GetNextSibling()) {
+    nsINode* parent = child->GetFlattenedTreeParent();
+    if (parent->IsElement()) {
+      MOZ_ASSERT(parent);
+      parent->AsElement()->NoteDirtyDescendantsForServo();
+    }
+  }
+}
+
+void
 nsCSSFrameConstructor::StyleNewChildRange(nsIContent* aStartChild,
                                           nsIContent* aEndChild)
 {
   ServoStyleSet* styleSet = mPresShell->StyleSet()->AsServo();
 
   for (nsIContent* child = aStartChild; child != aEndChild;
        child = child->GetNextSibling()) {
     // Calling StyleNewChildren on one child will end up styling another child,
@@ -7511,25 +7525,25 @@ nsCSSFrameConstructor::ContentAppended(n
   if (!isNewShadowTreeContent) {
     // See comment in ContentRangeInserted for why this is necessary.
     if (!GetContentInsertionFrameFor(aContainer) &&
         !aContainer->IsActiveChildrenElement()) {
       // We're punting on frame construction because there's no container frame.
       // The Servo-backed style system handles this case like the lazy frame
       // construction case.
       if (isNewlyAddedContentForServo) {
-        aContainer->AsElement()->NoteDirtyDescendantsForServo();
+        LazilyStyleNewChildRange(aFirstNewContent, nullptr);
       }
       return;
     }
 
     if (aAllowLazyConstruction &&
         MaybeConstructLazily(CONTENTAPPEND, aContainer, aFirstNewContent)) {
       if (isNewlyAddedContentForServo) {
-        aContainer->AsElement()->NoteDirtyDescendantsForServo();
+        LazilyStyleNewChildRange(aFirstNewContent, nullptr);
       }
       return;
     }
   }
 
   // We couldn't construct lazily. Make Servo eagerly traverse the new content.
   if (aContainer->IsStyledByServo()) {
     if (aForReconstruction) {
@@ -7992,29 +8006,29 @@ nsCSSFrameConstructor::ContentRangeInser
     // The xbl:children element won't have a frame, but default content can have the children as
     // a parent. While its uncommon to change the structure of the default content itself, a label,
     // for example, can be reframed by having its value attribute set or removed.
     if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
       // We're punting on frame construction because there's no container frame.
       // The Servo-backed style system handles this case like the lazy frame
       // construction case.
       if (isNewlyAddedContentForServo) {
-        aContainer->AsElement()->NoteDirtyDescendantsForServo();
+        LazilyStyleNewChildRange(aStartChild, aEndChild);
       }
       return;
     }
 
     // Otherwise, we've got parent content. Find its frame.
     NS_ASSERTION(!parentFrame || parentFrame->GetContent() == aContainer ||
                  GetDisplayContentsStyleFor(aContainer), "New XBL code is possibly wrong!");
 
     if (aAllowLazyConstruction &&
         MaybeConstructLazily(CONTENTINSERT, aContainer, aStartChild)) {
       if (isNewlyAddedContentForServo) {
-        aContainer->AsElement()->NoteDirtyDescendantsForServo();
+        LazilyStyleNewChildRange(aStartChild, aEndChild);
       }
       return;
     }
   }
 
   // We couldn't construct lazily. Make Servo eagerly traverse the new content.
   if (aContainer->IsStyledByServo()) {
     if (aForReconstruction) {
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -154,21 +154,32 @@ private:
                                         bool aForReconstruction);
 
   // Returns true if parent was recreated due to frameset child, false otherwise.
   bool MaybeRecreateForFrameset(nsIFrame* aParentFrame,
                                   nsIContent* aStartChild,
                                   nsIContent* aEndChild);
 
   /**
+   * For each child in the aStartChild/aEndChild range, calls
+   * NoteDirtyDescendantsForServo on their flattened tree parents.  This is
+   * used when content is inserted into the document and we decide that
+   * we can do lazy frame construction.  It handles children being rebound to
+   * different insertion points by calling NoteDirtyDescendantsForServo on each
+   * child's flattened tree parent.  Only used when we are styled by Servo.
+   */
+  void LazilyStyleNewChildRange(nsIContent* aStartChild, nsIContent* aEndChild);
+
+  /**
    * For each child in the aStartChild/aEndChild range, calls StyleNewChildren
    * on their flattened tree parents.  This is used when content is inserted
-   * into the document.  It handles children being rebound to different
-   * insertion points by calling StyleNewChildren on each child's flattened
-   * tree parent.  Only used when we are styled by Servo.
+   * into the document and we decide that we cannot do lazy frame construction.
+   * It handles children being rebound to different insertion points by calling
+   * StyleNewChildren on each child's flattened tree parent.  Only used when we
+   * are styled by Servo.
    */
   void StyleNewChildRange(nsIContent* aStartChild, nsIContent* aEndChild);
 
   /**
    * Calls StyleSubtreeForReconstruct on each child in the aStartChild/aEndChild
    * range. Only used when we are styled by Servo.
    */
   void StyleChildRangeForReconstruct(nsIContent* aStartChild,
--- a/layout/reftests/bugs/reftest-stylo.list
+++ b/layout/reftests/bugs/reftest-stylo.list
@@ -436,18 +436,18 @@ random == 328829-1.xhtml 328829-1.xhtml
 fails == 331809-1.html 331809-1.html
 == 332360.html 332360.html
 == 332360-ltr.html 332360-ltr.html
 == 332360-width.html 332360-width.html
 == 332360-width-ltr.html 332360-width-ltr.html
 fails == 332557-1.html 332557-1.html
 == 332975-1.html 332975-1.html
 == 333970-1.html 333970-1.html
-fails == 334829-1a.xhtml 334829-1a.xhtml
-fails == 334829-1b.xhtml 334829-1b.xhtml
+== 334829-1a.xhtml 334829-1a.xhtml
+== 334829-1b.xhtml 334829-1b.xhtml
 fails == 335628-1.html 335628-1.html
 == 335628-2.xul 335628-2.xul
 == 336096-1.xul 336096-1.xul
 fails == 336147-1.html 336147-1.html
 fails == 336153-1.html 336153-1.html
 fails == 338251-p.html 338251-p.html
 fails == 338251-p-oh.html 338251-p-oh.html
 fails == 338251-pre.html 338251-pre.html
@@ -883,17 +883,17 @@ fails == 403519-1.html 403519-1.html
 == 403519-2.html 403519-2.html
 == 403656-1.html 403656-1.html
 == 403656-2.html 403656-2.html
 == 403656-3.html 403656-3.html
 == 403656-4.html 403656-4.html
 == 403656-5.html 403656-5.html
 == 403657-1.html 403657-1.html
 == 403733-1.html 403733-1.html
-fails == 403962-1.xhtml 403962-1.xhtml # Bug 1290276
+== 403962-1.xhtml 403962-1.xhtml
 == 404030-1.html 404030-1.html
 == 404030-1-notref.html 404030-1-notref.html
 == 404030-1-notref2.html 404030-1-notref2.html
 fails == 404123-1.html 404123-1.html
 fails == 404123-2.html 404123-2.html
 == 404123-3.html 404123-3.html
 # may fail "randomly" on OS X, doesn't seem to be rendering usefully anyhow - bug 602469
 random-if(cocoaWidget) HTTP(..) == 404149-1.xul 404149-1.xul
--- a/layout/reftests/dom/reftest-stylo.list
+++ b/layout/reftests/dom/reftest-stylo.list
@@ -29,25 +29,25 @@
 # a range insert and an append
 == insertmultiplemultiple-2.html insertmultiplemultiple-2.html
 # multiple range inserts and an append
 == insertmultiplemultiple-2.html insertmultiplemultiple-2.html
 
 # testing bindings that have multiple insertion points
 == multipleinsertionpoints-ref2.xhtml multipleinsertionpoints-ref2.xhtml
 # append a single element
-fails == multipleinsertionpoints-appendsingle-1.xhtml multipleinsertionpoints-appendsingle-1.xhtml
-fails == multipleinsertionpoints-appendsingle-2.xhtml multipleinsertionpoints-appendsingle-2.xhtml
+== multipleinsertionpoints-appendsingle-1.xhtml multipleinsertionpoints-appendsingle-1.xhtml
+== multipleinsertionpoints-appendsingle-2.xhtml multipleinsertionpoints-appendsingle-2.xhtml
 # append several elements
-fails == multipleinsertionpoints-appendmultiple.xhtml multipleinsertionpoints-appendmultiple.xhtml
+== multipleinsertionpoints-appendmultiple.xhtml multipleinsertionpoints-appendmultiple.xhtml
 # insert a single element
-fails == multipleinsertionpoints-insertsingle-1.xhtml multipleinsertionpoints-insertsingle-1.xhtml
-fails == multipleinsertionpoints-insertsingle-2.xhtml multipleinsertionpoints-insertsingle-2.xhtml
+== multipleinsertionpoints-insertsingle-1.xhtml multipleinsertionpoints-insertsingle-1.xhtml
+== multipleinsertionpoints-insertsingle-2.xhtml multipleinsertionpoints-insertsingle-2.xhtml
 # insert several elements
-fails == multipleinsertionpoints-insertmultiple.xhtml multipleinsertionpoints-insertmultiple.xhtml
+== multipleinsertionpoints-insertmultiple.xhtml multipleinsertionpoints-insertmultiple.xhtml
 
 # test appending some nodes whose frame construction should be done lazily
 # followed by appending a node that might not be done lazily
 == multipleappendwithxul.xhtml multipleappendwithxul.xhtml
 fails == multipleappendwithinput.xhtml multipleappendwithinput.xhtml
 == multipleappendwitheditable.xhtml multipleappendwitheditable.xhtml
 
 fails == xbl-children-1.xhtml xbl-children-1.xhtml