Bug 1346052 - Part 3: Implement AnimationValue::FromString.
AnimationValue::FromString compute the AnimationValue from a string.
MozReview-Commit-ID: CX8wairpnfN
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -182,16 +182,22 @@ SERVO_BINDING_FUNC(Servo_AnimationValue_
RawServoAnimationValueBorrowed value,
RefPtr<nsCSSValueSharedList>* list)
SERVO_BINDING_FUNC(Servo_AnimationValue_DeepEqual, bool,
RawServoAnimationValueBorrowed,
RawServoAnimationValueBorrowed)
SERVO_BINDING_FUNC(Servo_AnimationValue_Uncompute,
RawServoDeclarationBlockStrong,
RawServoAnimationValueBorrowed value)
+SERVO_BINDING_FUNC(Servo_AnimationValue_Compute,
+ RawServoAnimationValueStrong,
+ RawServoDeclarationBlockBorrowed declarations,
+ ServoComputedValuesBorrowed style,
+ ServoComputedValuesBorrowedOrNull parent_style,
+ RawServoStyleSetBorrowed raw_data)
// Style attribute
SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, RawServoDeclarationBlockStrong,
const nsACString* data,
RawGeckoURLExtraData* extra_data)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_CreateEmpty,
RawServoDeclarationBlockStrong)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_Clone, RawServoDeclarationBlockStrong,
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -892,16 +892,27 @@ already_AddRefed<ServoComputedValues>
ServoStyleSet::GetBaseComputedValuesForElement(Element* aElement,
nsIAtom* aPseudoTag)
{
return Servo_StyleSet_GetBaseComputedValuesForElement(mRawSet.get(),
aElement,
aPseudoTag).Consume();
}
+already_AddRefed<RawServoAnimationValue>
+ServoStyleSet::ComputeAnimationValue(
+ RawServoDeclarationBlock* aDeclarations,
+ const ServoComputedValuesWithParent& aComputedValues)
+{
+ return Servo_AnimationValue_Compute(aDeclarations,
+ aComputedValues.mCurrentStyle,
+ aComputedValues.mParentStyle,
+ mRawSet.get()).Consume();
+}
+
void
ServoStyleSet::RebuildData()
{
ClearNonInheritingStyleContexts();
Servo_StyleSet_RebuildData(mRawSet.get());
}
already_AddRefed<ServoComputedValues>
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -299,16 +299,20 @@ public:
* Resolve style for a given declaration block with/without the parent style.
* If the parent style is not specified, the document default computed values
* is used.
*/
already_AddRefed<ServoComputedValues>
ResolveForDeclarations(ServoComputedValuesBorrowedOrNull aParentOrNull,
RawServoDeclarationBlockBorrowed aDeclarations);
+ already_AddRefed<RawServoAnimationValue>
+ ComputeAnimationValue(RawServoDeclarationBlock* aDeclaration,
+ const ServoComputedValuesWithParent& aComputedValues);
+
private:
already_AddRefed<nsStyleContext> GetContext(already_AddRefed<ServoComputedValues>,
nsStyleContext* aParentContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
dom::Element* aElementForAnimation);
already_AddRefed<nsStyleContext> GetContext(nsIContent* aContent,
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -19,21 +19,24 @@
#include "nsAutoPtr.h"
#include "nsCOMArray.h"
#include "nsIStyleRule.h"
#include "mozilla/css/StyleRule.h"
#include "nsString.h"
#include "nsStyleContext.h"
#include "nsStyleSet.h"
#include "nsComputedDOMStyle.h"
+#include "nsContentUtils.h"
#include "nsCSSParser.h"
#include "nsCSSPseudoElements.h"
#include "mozilla/css/Declaration.h"
#include "mozilla/dom/Element.h"
#include "mozilla/FloatingPoint.h"
+#include "mozilla/ServoComputedValuesWithParent.h"
+#include "mozilla/KeyframeUtils.h" // KeyframeUtils::ParseProperty
#include "mozilla/Likely.h"
#include "mozilla/ServoBindings.h" // RawServoDeclarationBlock
#include "gfxMatrix.h"
#include "gfxQuaternion.h"
#include "nsIDocument.h"
#include "nsIFrame.h"
#include "gfx2DGlue.h"
@@ -5190,16 +5193,17 @@ StyleAnimationValue::operator==(const St
case eUnit_ComplexColor:
return *mValue.mComplexColor == *aOther.mValue.mComplexColor;
}
NS_NOTREACHED("incomplete case");
return false;
}
+
// AnimationValue Implementation
bool
AnimationValue::operator==(const AnimationValue& aOther) const
{
// It is possible to compare an empty AnimationValue with others, so both
// mServo and mGecko could be null while comparing.
MOZ_ASSERT(!mServo || mGecko.IsNull());
@@ -5297,8 +5301,70 @@ AnimationValue::ComputeDistance(nsCSSPro
return StyleAnimationValue::ComputeDistance(aProperty,
mGecko,
aOther.mGecko,
aStyleContext,
distance)
? distance
: 0.0;
}
+
+/* static */ AnimationValue
+AnimationValue::FromString(nsCSSPropertyID aProperty,
+ const nsAString& aValue,
+ Element* aElement)
+{
+ MOZ_ASSERT(aElement);
+
+ AnimationValue result;
+
+ nsCOMPtr<nsIDocument> doc = aElement->GetComposedDoc();
+ if (!doc) {
+ return result;
+ }
+
+ nsCOMPtr<nsIPresShell> shell = doc->GetShell();
+ if (!shell) {
+ return result;
+ }
+
+ // GetStyleContext() flushes style, so we shouldn't assume that any
+ // non-owning references we have are still valid.
+ RefPtr<nsStyleContext> styleContext =
+ nsComputedDOMStyle::GetStyleContext(aElement, nullptr, shell);
+
+ if (styleContext->StyleSource().IsServoComputedValues()) {
+ nsPresContext* presContext = shell->GetPresContext();
+ if (!presContext) {
+ return result;
+ }
+
+ RefPtr<RawServoDeclarationBlock> declarations =
+ KeyframeUtils::ParseProperty(aProperty, aValue, doc);
+
+ if (!declarations) {
+ return result;
+ }
+
+ // We use the current ServoComputeValues and its parent ServoComputeValues
+ // to reconstruct the Context and then compute the AnimationValue. However,
+ // nsStyleContext::GetParentAllowServo() is going away, so if possible, we
+ // should find another way to get the parent ServoComputedValues.
+ RefPtr<nsStyleContext> parentContext = styleContext->GetParentAllowServo();
+ const ServoComputedValuesWithParent styles = {
+ styleContext->StyleSource().AsServoComputedValues(),
+ parentContext ? parentContext->StyleSource().AsServoComputedValues()
+ : nullptr
+ };
+
+ result.mServo = presContext->StyleSet()
+ ->AsServo()
+ ->ComputeAnimationValue(declarations, styles);
+ return result;
+ }
+
+ if (!StyleAnimationValue::ComputeValue(aProperty, aElement, styleContext,
+ aValue, false /* |aUseSVGMode| */,
+ result.mGecko)) {
+ MOZ_ASSERT(result.IsNull());
+ }
+ return result;
+}
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -571,23 +571,38 @@ private:
struct AnimationValue
{
explicit AnimationValue(const StyleAnimationValue& aValue)
: mGecko(aValue) { }
explicit AnimationValue(const RefPtr<RawServoAnimationValue>& aValue)
: mServo(aValue) { }
AnimationValue() = default;
- // mGecko and mServo are mutually exclusive: only one or the other should
- // ever be set.
- // FIXME: After obsoleting StyleAnimationValue, we should remove mGecko, and
- // make AnimationValue a wrapper of RawServoAnimationValue to hide these
- // FFIs.
- StyleAnimationValue mGecko;
- RefPtr<RawServoAnimationValue> mServo;
+ AnimationValue(const AnimationValue& aOther)
+ : mGecko(aOther.mGecko), mServo(aOther.mServo) { }
+ AnimationValue(AnimationValue&& aOther)
+ : mGecko(Move(aOther.mGecko)), mServo(Move(aOther.mServo)) { }
+
+ AnimationValue& operator=(const AnimationValue& aOther)
+ {
+ if (this != &aOther) {
+ mGecko = aOther.mGecko;
+ mServo = aOther.mServo;
+ }
+ return *this;
+ }
+ AnimationValue& operator=(AnimationValue&& aOther)
+ {
+ MOZ_ASSERT(this != &aOther, "Do not move itself");
+ if (this != &aOther) {
+ mGecko = Move(aOther.mGecko);
+ mServo = Move(aOther.mServo);
+ }
+ return *this;
+ }
bool operator==(const AnimationValue& aOther) const;
bool operator!=(const AnimationValue& aOther) const;
bool IsNull() const { return mGecko.IsNull() && !mServo; }
float GetOpacity() const;
@@ -604,16 +619,31 @@ struct AnimationValue
const AnimationValue& aToValue) const;
// Compute the distance between *this and aOther.
// If |aStyleContext| is nullptr, we will return 0.0 if we have mismatched
// transform lists.
double ComputeDistance(nsCSSPropertyID aProperty,
const AnimationValue& aOther,
nsStyleContext* aStyleContext) const;
+
+ // Create an AnimaitonValue from a string. This method flushes style, so we
+ // should use this carefully. Now, it is only used by
+ // nsDOMWindowUtils::ComputeAnimationDistance.
+ static AnimationValue FromString(nsCSSPropertyID aProperty,
+ const nsAString& aValue,
+ dom::Element* aElement);
+
+ // mGecko and mServo are mutually exclusive: only one or the other should
+ // ever be set.
+ // FIXME: After obsoleting StyleAnimationValue, we should remove mGecko, and
+ // make AnimationValue a wrapper of RawServoAnimationValue to hide these
+ // FFIs.
+ StyleAnimationValue mGecko;
+ RefPtr<RawServoAnimationValue> mServo;
};
struct PropertyStyleAnimationValuePair
{
nsCSSPropertyID mProperty;
AnimationValue mValue;
};
} // namespace mozilla