Bug 1417354 - Clear pending restyle requests for the element and its pseudos where the element is detached from the document. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Wed, 21 Feb 2018 06:16:23 +0900
changeset 757581 2dc4fab73096e5c904cac0a6baeed5a5d53bf2d7
parent 757580 1bb1396535b046a7dc76801a0ebc61bcd5967b11
push id99784
push userhikezoe@mozilla.com
push dateTue, 20 Feb 2018 21:16:55 +0000
reviewersbirtles
bugs1417354
milestone60.0a1
Bug 1417354 - Clear pending restyle requests for the element and its pseudos where the element is detached from the document. r?birtles MozReview-Commit-ID: GLHjtHNusuB
dom/animation/test/mozilla/file_restyles.html
dom/base/Element.cpp
--- a/dom/animation/test/mozilla/file_restyles.html
+++ b/dom/animation/test/mozilla/file_restyles.html
@@ -1270,21 +1270,16 @@ waitForAllPaints(() => {
     var div = addDiv(null);
     var animation = div.animate({ marginLeft: [ '0px', '100px' ] },
                                 100 * MS_PER_SEC);
 
     await animation.ready;
 
     div.remove();
 
-    // It's possible that the animation begins at this moment.  If this is the
-    // case, an additional superfluous restyle request that we will check later
-    // can't be observed.
-    const superfluousRestyle = startsRightNow(animation) ? 0 : 1;
-
     var markers = await observeStyling(5);
     is(markers.length, 0,
        'Animation on orphaned element should not cause restyles');
 
     document.body.appendChild(div);
 
     markers = await observeStyling(1);
     if (isServo) {
@@ -1294,21 +1289,17 @@ waitForAllPaints(() => {
       // CascadeResults which ends up calling RequestRestyle(Standard). As a
       // result, the animation is restyled during a second animation restyle in
       // the first frame. If we fix the behavior when we attach an orphaned
       // element with script animations to a document so that it requests a
       // layer restyle (bug 1388557) before fixing important_rules_change in
       // compute_style() so that it no longer dispatches a needless standard
       // restyle (bug 1388560), we should add a test case that fails if we
       // continue to unnecessarily request a standard restyle.
-      //
-      // Bug 1417354: There will be an additional superfluous restyle request
-      // which results when we detach an element from the document between
-      // the Animation tick and styling, and then re-attach it.
-      is(markers.length, 1 + superfluousRestyle,
+      is(markers.length, 1,
          'We should observe one restyle in the first frame right after ' +
          're-attaching to the document');
     } else {
       // Bug 1388557: We should call RequestRestyle(Layer) when an element which
       // has running script animations is attached to a document.
       todo_is(markers.length, 1,
               'Bug 1388557 We should observe one restyle in the first frame ' +
               'right after re-attaching to the document');
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1971,16 +1971,24 @@ Element::UnbindFromTree(bool aDeep, bool
   // FIXME (Bug 522599): Need a test for this.
   if (MayHaveAnimations()) {
     DeleteProperty(nsGkAtoms::transitionsOfBeforeProperty);
     DeleteProperty(nsGkAtoms::transitionsOfAfterProperty);
     DeleteProperty(nsGkAtoms::transitionsProperty);
     DeleteProperty(nsGkAtoms::animationsOfBeforeProperty);
     DeleteProperty(nsGkAtoms::animationsOfAfterProperty);
     DeleteProperty(nsGkAtoms::animationsProperty);
+    if (document) {
+      if (nsPresContext* presContext = document->GetPresContext()) {
+        // We have to clear all pending restyle requests for the animations on
+        // this element to avoid unnecessary restyles when we re-attached this
+        // element.
+        presContext->EffectCompositor()->ClearRestyleRequestsFor(this);
+      }
+    }
   }
 
   // Computed style data isn't useful for detached nodes, and we'll need to
   // recompute it anyway if we ever insert the nodes back into a document.
   if (IsStyledByServo()) {
     if (document) {
       ClearServoData(document);
     } else {