Bug 1364799 - Add a new TraversalRestyleBehavior that represents the traversal is triggered by CSS rule changes. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Sun, 21 May 2017 08:16:26 +0900
changeset 582079 beddff56532b2a5225a47440fcc0c3c06e41cf9c
parent 582078 ac11cc0303b8ab3b64031ad540afa00ff6b43442
child 582080 6f2b5d3368cdb09b7d422ef5753b1d585541e4a5
child 582081 a36ee516cdf1957a8cb928daff3d7c86562b2f76
push id59961
push userhikezoe@mozilla.com
push dateSun, 21 May 2017 00:19:28 +0000
reviewersbirtles
bugs1364799
milestone55.0a1
Bug 1364799 - Add a new TraversalRestyleBehavior that represents the traversal is triggered by CSS rule changes. r?birtles And propagate the new flag to servo if mRestyleForCSSRuleChanges is set. MozReview-Commit-ID: HRZ5duYgciF
layout/base/ServoRestyleManager.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
layout/style/ServoTypes.h
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -559,18 +559,21 @@ ServoRestyleManager::DoProcessPendingRes
   // Perform the Servo traversal, and the post-traversal if required. We do this
   // in a loop because certain rare paths in the frame constructor (like
   // uninstalling XBL bindings) can trigger additional style validations.
   mInStyleRefresh = true;
   if (mHaveNonAnimationRestyles && !animationOnly) {
     ++mAnimationGeneration;
   }
 
+  TraversalRestyleBehavior restyleBehavior = mRestyleForCSSRuleChanges
+    ? TraversalRestyleBehavior::ForCSSRuleChanges
+    : TraversalRestyleBehavior::Normal;
   while (animationOnly ? styleSet->StyleDocumentForAnimationOnly()
-                       : styleSet->StyleDocument()) {
+                       : styleSet->StyleDocument(restyleBehavior)) {
     if (!animationOnly) {
       ClearSnapshots();
     }
 
     // Recreate style contexts, and queue up change hints (which also handle
     // lazy frame construction).
     nsStyleChangeList currentChanges(StyleBackendType::Servo);
     DocumentStyleRootIterator iter(doc);
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -2532,17 +2532,17 @@ nsCSSFrameConstructor::ConstructDocEleme
                                                              LazyComputeBehavior::Allow);
       display = styleContext->StyleDisplay();
     }
   }
 
   // We delay traversing the entire document until here, since we per above we
   // may invalidate the root style when we load doc stylesheets.
   if (ServoStyleSet* set = mPresShell->StyleSet()->GetAsServo()) {
-    set->StyleDocument();
+    set->StyleDocument(TraversalRestyleBehavior::Normal);
   }
 
   // --------- IF SCROLLABLE WRAP IN SCROLLFRAME --------
 
   NS_ASSERTION(!display->IsScrollableOverflow() ||
                state.mPresContext->IsPaginated() ||
                propagatedScrollFrom == aDocElement,
                "Scrollbars should have been propagated to the viewport");
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -820,28 +820,34 @@ ServoStyleSet::HasStateDependentStyle(do
                                      dom::Element* aPseudoElement,
                                      EventStates aStateMask)
 {
   NS_WARNING("stylo: HasStateDependentStyle always returns zero!");
   return nsRestyleHint(0);
 }
 
 bool
-ServoStyleSet::StyleDocument()
+ServoStyleSet::StyleDocument(TraversalRestyleBehavior aRestyleBehavior)
 {
+  MOZ_ASSERT(
+    aRestyleBehavior == TraversalRestyleBehavior::Normal ||
+    aRestyleBehavior == TraversalRestyleBehavior::ForCSSRuleChanges,
+    "StyleDocument() should be only called for normal traversal or CSS rule "
+    "changes");
+
   PreTraverse();
 
   // Restyle the document from the root element and each of the document level
   // NAC subtree roots.
   bool postTraversalRequired = false;
   DocumentStyleRootIterator iter(mPresContext->Document());
   while (Element* root = iter.GetNextStyleRoot()) {
     if (PrepareAndTraverseSubtree(root,
                                   TraversalRootBehavior::Normal,
-                                  TraversalRestyleBehavior::Normal)) {
+                                  aRestyleBehavior)) {
       postTraversalRequired = true;
     }
   }
   return postTraversalRequired;
 }
 
 bool
 ServoStyleSet::StyleDocumentForAnimationOnly()
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -225,19 +225,24 @@ public:
 
   /**
    * Performs a Servo traversal to compute style for all dirty nodes in the
    * document.
    *
    * This will traverse all of the document's style roots (that is, its document
    * element, and the roots of the document-level native anonymous content).
    *
+   * |aRestyleBehavior| should be `Normal` or `ForCSSRuleChanges`.
+   * We need to specify |ForCSSRuleChanges| to try to update all CSS animations
+   * when we call this function due to CSS rule changes since @keyframes rules
+   * may have changed.
+   *
    * Returns true if a post-traversal is required.
    */
-  bool StyleDocument();
+  bool StyleDocument(TraversalRestyleBehavior aRestyleBehavior);
 
   /**
    * Performs a Servo animation-only traversal to compute style for all nodes
    * with the animation-only dirty bit in the document.
    *
    * This will traverse all of the document's style roots (that is, its document
    * element, and the roots of the document-level native anonymous content).
    */
--- a/layout/style/ServoTypes.h
+++ b/layout/style/ServoTypes.h
@@ -54,20 +54,28 @@ enum class TraversalRootBehavior {
 };
 
 // Indicates whether the Servo style system should perform normal processing,
 // animation-only processing (so we can flush any throttled animation styles),
 // or whether it should traverse in a mode that doesn't generate any change
 // hints, which is what's required when handling frame reconstruction.
 // The change hints in this case are unneeded, since the old frames have
 // already been destroyed.
+// Indicates how the Servo style system should perform.
 enum class TraversalRestyleBehavior {
+  // Normal processing.
   Normal,
+  // Traverses in a mode that doesn't generate any change hints, which is what's
+  // required when handling frame reconstruction.  The change hints in this case
+  // are unneeded, since the old frames have already been destroyed.
   ForReconstruct,
+  // Processes animation-only restyle.
   ForAnimationOnly,
+  // Traverses as normal mode but tries to update all CSS animations.
+  ForCSSRuleChanges,
 };
 
 // Represents which tasks are performed in a SequentialTask of UpdateAnimations.
 enum class UpdateAnimationsTasks : uint8_t {
   CSSAnimations    = 1 << 0,
   CSSTransitions   = 1 << 1,
   EffectProperties = 1 << 2,
   CascadeResults   = 1 << 3,