--- 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