Bug 1309752 - Part 4: Physicalize logical properties at building CSS Transitions. r?birtles draft
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Wed, 26 Apr 2017 17:46:59 +0900
changeset 568591 f00929df4c31b8c7e1d2d935046efac477d15a83
parent 568590 6fd5b07c042e2d1f10162b5f5cd6c079a0184b1f
child 568592 31b6126e97f38834f571e07f7ff7a253b466ba4c
push id55908
push userbmo:dakatsuka@mozilla.com
push dateWed, 26 Apr 2017 09:58:37 +0000
reviewersbirtles
bugs1309752
milestone55.0a1
Bug 1309752 - Part 4: Physicalize logical properties at building CSS Transitions. r?birtles The logical properties of CSS Transition should physicalize same to CSS properties. Also, if user set 'all' as transition property, prevent to extract logical properties. MozReview-Commit-ID: 2LqePHtjMfm
layout/style/nsTransitionManager.cpp
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -636,16 +636,52 @@ nsTransitionManager::UpdateTransitions(
     CSSTransitionCollection::GetAnimationCollection(aElement, aPseudoType);
   const nsStyleDisplay *disp = Servo_GetStyleDisplay(aNewStyle.mCurrentStyle);
   return DoUpdateTransitions(disp,
                              aElement, aPseudoType,
                              collection,
                              aOldStyle, aNewStyle);
 }
 
+static inline nsCSSPropertyID
+PhysicalProperty(nsCSSPropertyID aProperty, nsStyleContext* aStyleContext)
+{
+  MOZ_ASSERT(nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL),
+             "aProperty should be a logical longhand property");
+  return nsCSSProps::PhysicalProperty(
+           aProperty,
+           aStyleContext->StyleVisibility()->mWritingMode,
+           aStyleContext->StyleVisibility()->mTextOrientation,
+           aStyleContext->StyleVisibility()->mDirection);
+}
+
+static inline nsCSSPropertyID
+PhysicalProperty(nsCSSPropertyID aProperty,
+                 const ServoComputedValuesWithParent& aComputedStyle)
+{
+  MOZ_ASSERT(false, "PhysicalProperty() does not support for Servo yet");
+  return eCSSProperty_UNKNOWN;
+}
+
+
+static bool
+HasAnimaition(const nsCSSPropertyID aProperty,
+              nsTransitionManager::CSSTransitionCollection* aElementTransitions)
+{
+  if (!aElementTransitions) {
+    return false;
+  }
+  for (CSSTransition* transition : aElementTransitions->mAnimations) {
+    if (transition->TransitionProperty() == aProperty) {
+      return true;
+    }
+  }
+  return false;
+}
+
 template<typename StyleType>
 bool
 nsTransitionManager::DoUpdateTransitions(
   const nsStyleDisplay* aDisp,
   dom::Element* aElement,
   CSSPseudoElementType aPseudoType,
   CSSTransitionCollection*& aElementTransitions,
   StyleType aOldStyle,
@@ -656,16 +692,17 @@ nsTransitionManager::DoUpdateTransitions
              aElementTransitions->mElement == aElement, "Element mismatch");
 
   // Per http://lists.w3.org/Archives/Public/www-style/2009Aug/0109.html
   // I'll consider only the transitions from the number of items in
   // 'transition-property' on down, and later ones will override earlier
   // ones (tracked using |whichStarted|).
   bool startedAny = false;
   nsCSSPropertyIDSet whichStarted;
+  nsDataHashtable<nsUint32HashKey, uint32_t> logicalProperties;
   for (uint32_t i = aDisp->mTransitionPropertyCount; i-- != 0; ) {
     const StyleTransition& t = aDisp->mTransitions[i];
     // Check the combined duration (combination of delay and duration)
     // first, since it defaults to zero, which means we can ignore the
     // transition.
     if (t.GetCombinedDuration() > 0.0f) {
       // We might have something to transition.  See if any of the
       // properties in question changed and are animatable.
@@ -675,39 +712,69 @@ nsTransitionManager::DoUpdateTransitions
       if (property == eCSSPropertyExtra_no_properties ||
           property == eCSSPropertyExtra_variable ||
           property == eCSSProperty_UNKNOWN) {
         // Nothing to do, but need to exclude this from cases below.
       } else if (property == eCSSPropertyExtra_all_properties) {
         for (nsCSSPropertyID p = nsCSSPropertyID(0);
              p < eCSSProperty_COUNT_no_shorthands;
              p = nsCSSPropertyID(p + 1)) {
+          if (nsCSSProps::PropHasFlags(p, CSS_PROPERTY_LOGICAL)) {
+            // We don't need to extract any logical properties
+            // since we extract all physical properties.
+            continue;
+          }
           ConsiderInitiatingTransition(p, t, aElement, aPseudoType,
                                        aElementTransitions,
                                        aOldStyle, aNewStyle,
                                        &startedAny, &whichStarted);
         }
       } else if (nsCSSProps::IsShorthand(property)) {
         CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(subprop, property,
                                              CSSEnabledState::eForAllContent)
         {
+          if (nsCSSProps::PropHasFlags(*subprop, CSS_PROPERTY_LOGICAL)) {
+            logicalProperties.Put(*subprop, i);
+            continue;
+          }
           ConsiderInitiatingTransition(*subprop, t, aElement, aPseudoType,
                                        aElementTransitions,
                                        aOldStyle, aNewStyle,
                                        &startedAny, &whichStarted);
         }
       } else {
+        if (nsCSSProps::PropHasFlags(property, CSS_PROPERTY_LOGICAL)) {
+          logicalProperties.Put(property, i);
+          continue;
+        }
         ConsiderInitiatingTransition(property, t, aElement, aPseudoType,
                                      aElementTransitions,
                                      aOldStyle, aNewStyle,
                                      &startedAny, &whichStarted);
       }
     }
   }
 
+  // Extract logical properties to physical.
+  for (auto iterator = logicalProperties.ConstIter();
+       !iterator.Done(); iterator.Next()) {
+    nsCSSPropertyID logicalProperty =
+      static_cast<nsCSSPropertyID>(iterator.Key());
+    nsCSSPropertyID physicalProperty =
+      PhysicalProperty(logicalProperty, aNewStyle);
+    if (!HasAnimaition(physicalProperty, aElementTransitions)) {
+      uint32_t index = logicalProperties.Get(logicalProperty);
+      const StyleTransition& t = aDisp->mTransitions[index];
+      ConsiderInitiatingTransition(physicalProperty, t, aElement, aPseudoType,
+                                   aElementTransitions,
+                                   aOldStyle, aNewStyle,
+                                   &startedAny, &whichStarted);
+    }
+  }
+
   // Stop any transitions for properties that are no longer in
   // 'transition-property', including finished transitions.
   // Also stop any transitions (and remove any finished transitions)
   // for properties that just changed (and are still in the set of
   // properties to transition), but for which we didn't just start the
   // transition.  This can happen delay and duration are both zero, or
   // because the new value is not interpolable.
   // Note that we also do the latter set of work in