Bug 533291 Patch E: Add another outparam to nsISMILAttr::ValueFromString, to let us know whether we can re-use the parsed result in the future. r=roc

This commit is contained in:
Daniel Holbert 2010-02-20 13:13:11 -08:00
Родитель 1cd94792dd
Коммит f62ad5a1f6
25 изменённых файлов: 120 добавлений и 42 удалений

Просмотреть файл

@ -67,12 +67,17 @@ public:
* provided additional context data such as for
* animateTransform where the 'type' attribute is needed to
* parse the value.
* @param aValue Outparam for storing the parsed value.
* @param[out] aValue Outparam for storing the parsed value.
* @param[out] aCanCache Outparam for indicating whether the parsed value
* can be reused in future samples -- i.e. whether the
* given string is always guaranteed to compute
* to the same nsSMILValue.
* @return NS_OK on success or an error code if creation failed.
*/
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue) const = 0;
nsSMILValue& aValue,
PRBool& aCanCache) const = 0;
/**
* Gets the underlying value of this attribute.

Просмотреть файл

@ -104,6 +104,7 @@ nsSMILAnimationFunction::nsSMILAnimationFunction()
mRepeatIteration(0),
mLastValue(PR_FALSE),
mHasChanged(PR_TRUE),
mValueNeedsReparsingEverySample(PR_FALSE),
mBeginTime(LL_MININT),
mAnimationElement(nsnull),
mErrorFlags(0)
@ -358,7 +359,7 @@ nsSMILAnimationFunction::WillReplace() const
PRBool
nsSMILAnimationFunction::HasChanged() const
{
return mHasChanged;
return mHasChanged || mValueNeedsReparsingEverySample;
}
PRBool
@ -684,23 +685,33 @@ nsSMILAnimationFunction::GetAttr(nsIAtom* aAttName, nsAString& aResult) const
* A utility function to make querying an attribute that corresponds to an
* nsSMILValue a little neater.
*
* @param aAttName The attribute name (in the global namespace)
* @param aSMILAttr The SMIL attribute to perform the parsing
* @param aResult The resulting nsSMILValue
* @param aAttName The attribute name (in the global namespace).
* @param aSMILAttr The SMIL attribute to perform the parsing.
* @param[out] aResult The resulting nsSMILValue.
* @param[out] aCanCacheSoFar If |aResult| cannot be cached (as reported by
* nsISMILAttr::ValueFromString), then this outparam
* will be set to PR_FALSE. Otherwise, this outparam
* won't be modified.
*
* Returns PR_FALSE if a parse error occurred, otherwise returns PR_TRUE.
*/
PRBool
nsSMILAnimationFunction::ParseAttr(nsIAtom* aAttName,
const nsISMILAttr& aSMILAttr,
nsSMILValue& aResult) const
nsSMILValue& aResult,
PRBool& aCanCacheSoFar) const
{
nsAutoString attValue;
if (GetAttr(aAttName, attValue)) {
nsresult rv =
aSMILAttr.ValueFromString(attValue, mAnimationElement, aResult);
PRBool canCache;
nsresult rv = aSMILAttr.ValueFromString(attValue, mAnimationElement,
aResult, canCache);
if (NS_FAILED(rv))
return PR_FALSE;
if (!canCache) {
aCanCacheSoFar = PR_FALSE;
}
}
return PR_TRUE;
}
@ -726,25 +737,34 @@ nsSMILAnimationFunction::GetValues(const nsISMILAttr& aSMILAttr,
if (!mAnimationElement)
return NS_ERROR_FAILURE;
mValueNeedsReparsingEverySample = PR_FALSE;
nsSMILValueArray result;
// If "values" is set, use it
if (HasAttr(nsGkAtoms::values)) {
nsAutoString attValue;
GetAttr(nsGkAtoms::values, attValue);
PRBool canCache;
nsresult rv = nsSMILParserUtils::ParseValues(attValue, mAnimationElement,
aSMILAttr, result);
aSMILAttr, result, canCache);
if (NS_FAILED(rv))
return rv;
if (!canCache) {
mValueNeedsReparsingEverySample = PR_TRUE;
}
// Else try to/from/by
} else {
PRBool canCacheSoFar = PR_TRUE;
PRBool parseOk = PR_TRUE;
nsSMILValue to, from, by;
parseOk &= ParseAttr(nsGkAtoms::to, aSMILAttr, to);
parseOk &= ParseAttr(nsGkAtoms::from, aSMILAttr, from);
parseOk &= ParseAttr(nsGkAtoms::by, aSMILAttr, by);
parseOk &= ParseAttr(nsGkAtoms::to, aSMILAttr, to, canCacheSoFar);
parseOk &= ParseAttr(nsGkAtoms::from, aSMILAttr, from, canCacheSoFar);
parseOk &= ParseAttr(nsGkAtoms::by, aSMILAttr, by, canCacheSoFar);
if (!canCacheSoFar) {
mValueNeedsReparsingEverySample = PR_TRUE;
}
if (!parseOk)
return NS_ERROR_FAILURE;

Просмотреть файл

@ -321,7 +321,7 @@ protected:
nsAString& aResult) const;
PRBool ParseAttr(nsIAtom* aAttName, const nsISMILAttr& aSMILAttr,
nsSMILValue& aResult) const;
nsSMILValue& aResult, PRBool& aCanCacheSoFar) const;
nsresult GetValues(const nsISMILAttr& aSMILAttr,
nsSMILValueArray& aResult);
void UpdateValuesArray();
@ -372,6 +372,7 @@ protected:
PRUint32 mRepeatIteration;
PRPackedBool mLastValue;
PRPackedBool mHasChanged;
PRPackedBool mValueNeedsReparsingEverySample;
nsSMILTime mBeginTime; // document time

Просмотреть файл

@ -146,12 +146,26 @@ nsSMILCSSProperty::GetBaseValue() const
nsresult
nsSMILCSSProperty::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue) const
nsSMILValue& aValue,
PRBool& aCanCache) const
{
NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
nsSMILCSSValueType::ValueFromString(mPropID, mElement, aStr, aValue);
return aValue.IsNull() ? NS_ERROR_FAILURE : NS_OK;
if (aValue.IsNull()) {
return NS_ERROR_FAILURE;
}
// XXXdholbert: For simplicity, just assume that all CSS values have to
// reparsed every sample. This prevents us from doing the "nothing's changed
// so don't recompose" optimization (bug 533291) for CSS properties & mapped
// attributes. If it ends up being expensive to always recompose those, we
// can be a little smarter here. We really only need to disable aCanCache
// for "inherit" & "currentColor" (whose values could change at any time), as
// well as for length-valued types (particularly those with em/ex/percent
// units, since their conversion ratios can change at any time).
aCanCache = PR_FALSE;
return NS_OK;
}
nsresult

Просмотреть файл

@ -66,7 +66,8 @@ public:
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue) const;
nsSMILValue& aValue,
PRBool& aCanCache) const;
virtual nsSMILValue GetBaseValue() const;
virtual nsresult SetAnimValue(const nsSMILValue& aValue);
virtual void ClearAnimValue();

Просмотреть файл

@ -542,7 +542,8 @@ nsresult
nsSMILParserUtils::ParseValues(const nsAString& aSpec,
const nsISMILAnimationElement* aSrcElement,
const nsISMILAttr& aAttribute,
nsTArray<nsSMILValue>& aValuesArray)
nsTArray<nsSMILValue>& aValuesArray,
PRBool& aCanCache)
{
nsresult rv = NS_ERROR_FAILURE;
@ -551,6 +552,9 @@ nsSMILParserUtils::ParseValues(const nsAString& aSpec,
const PRUnichar* substrEnd = nsnull;
const PRUnichar* next = nsnull;
// Assume all results can be cached, until we find one that can't.
aCanCache = PR_TRUE;
while (start != end) {
rv = NS_ERROR_FAILURE;
@ -576,8 +580,9 @@ nsSMILParserUtils::ParseValues(const nsAString& aSpec,
--substrEnd;
nsSMILValue newValue;
PRBool tmpCanCache;
rv = aAttribute.ValueFromString(Substring(start, substrEnd),
aSrcElement, newValue);
aSrcElement, newValue, tmpCanCache);
if (NS_FAILED(rv))
break;
@ -585,8 +590,10 @@ nsSMILParserUtils::ParseValues(const nsAString& aSpec,
rv = NS_ERROR_OUT_OF_MEMORY;
break;
}
if (!tmpCanCache) {
aCanCache = PR_FALSE;
}
rv = NS_OK;
start = next;
}

Просмотреть файл

@ -66,7 +66,8 @@ public:
static nsresult ParseValues(const nsAString& aSpec,
const nsISMILAnimationElement* aSrcElement,
const nsISMILAttr& aAttribute,
nsTArray<nsSMILValue>& aValuesArray);
nsTArray<nsSMILValue>& aValuesArray,
PRBool& aCanCache);
static nsresult ParseRepeatCount(const nsAString& aSpec,
nsSMILRepeatCount& aResult);

Просмотреть файл

@ -436,7 +436,8 @@ nsSVGAngle::ToSMILAttr(nsSVGElement *aSVGElement)
nsresult
nsSVGAngle::SMILOrient::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* /*aSrcElement*/,
nsSMILValue& aValue) const
nsSMILValue& aValue,
PRBool& aCanCache) const
{
nsSMILValue val(&SVGOrientSMILType::sSingleton);
if (aStr.EqualsLiteral("auto")) {
@ -453,6 +454,7 @@ nsSVGAngle::SMILOrient::ValueFromString(const nsAString& aStr,
val.mU.mOrient.mOrientType = nsIDOMSVGMarkerElement::SVG_MARKER_ORIENT_ANGLE;
}
aValue = val;
aCanCache = PR_TRUE;
return NS_OK;
}

Просмотреть файл

@ -224,7 +224,8 @@ private:
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue) const;
nsSMILValue& aValue,
PRBool& aCanCache) const;
virtual nsSMILValue GetBaseValue() const;
virtual void ClearAnimValue();
virtual nsresult SetAnimValue(const nsSMILValue& aValue);

Просмотреть файл

@ -143,7 +143,8 @@ nsSVGBoolean::ToSMILAttr(nsSVGElement *aSVGElement)
nsresult
nsSVGBoolean::SMILBool::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* /*aSrcElement*/,
nsSMILValue& aValue) const
nsSMILValue& aValue,
PRBool& aCanCache) const
{
nsSMILValue val(&SMILBoolType::sSingleton);
@ -155,6 +156,7 @@ nsSVGBoolean::SMILBool::ValueFromString(const nsAString& aStr,
return NS_ERROR_FAILURE;
aValue = val;
aCanCache = PR_TRUE;
return NS_OK;
}

Просмотреть файл

@ -119,7 +119,8 @@ private:
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue) const;
nsSMILValue& aValue,
PRBool& aCanCache) const;
virtual nsSMILValue GetBaseValue() const;
virtual void ClearAnimValue();
virtual nsresult SetAnimValue(const nsSMILValue& aValue);

Просмотреть файл

@ -174,7 +174,8 @@ nsSVGEnum::ToSMILAttr(nsSVGElement *aSVGElement)
nsresult
nsSVGEnum::SMILEnum::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* /*aSrcElement*/,
nsSMILValue& aValue) const
nsSMILValue& aValue,
PRBool& aCanCache) const
{
nsCOMPtr<nsIAtom> valAtom = do_GetAtom(aStr);
nsSVGEnumMapping *mapping = mVal->GetMapping(mSVGElement);
@ -184,6 +185,7 @@ nsSVGEnum::SMILEnum::ValueFromString(const nsAString& aStr,
nsSMILValue val(&SMILEnumType::sSingleton);
val.mU.mUint = mapping->mVal;
aValue = val;
aCanCache = PR_TRUE;
return NS_OK;
}
mapping++;

Просмотреть файл

@ -128,7 +128,8 @@ private:
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue) const;
nsSMILValue& aValue,
PRBool& aCanCache) const;
virtual nsSMILValue GetBaseValue() const;
virtual void ClearAnimValue();
virtual nsresult SetAnimValue(const nsSMILValue& aValue);

Просмотреть файл

@ -137,7 +137,8 @@ nsSVGInteger::ToSMILAttr(nsSVGElement *aSVGElement)
nsresult
nsSVGInteger::SMILInteger::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* /*aSrcElement*/,
nsSMILValue& aValue) const
nsSMILValue& aValue,
PRBool& aCanCache) const
{
NS_ConvertUTF16toUTF8 value(aStr);
const char *str = value.get();
@ -154,6 +155,7 @@ nsSVGInteger::SMILInteger::ValueFromString(const nsAString& aStr,
nsSMILValue smilVal(&SMILIntegerType::sSingleton);
smilVal.mU.mInt = val;
aValue = smilVal;
aCanCache = PR_TRUE;
return NS_OK;
}

Просмотреть файл

@ -119,7 +119,8 @@ private:
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue) const;
nsSMILValue& aValue,
PRBool& aCanCache) const;
virtual nsSMILValue GetBaseValue() const;
virtual void ClearAnimValue();
virtual nsresult SetAnimValue(const nsSMILValue& aValue);

Просмотреть файл

@ -519,7 +519,8 @@ nsSVGLength2::ToSMILAttr(nsSVGElement *aSVGElement)
nsresult
nsSVGLength2::SMILLength::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* /*aSrcElement*/,
nsSMILValue& aValue) const
nsSMILValue& aValue,
PRBool& aCanCache) const
{
float value;
PRUint16 unitType;
@ -532,6 +533,9 @@ nsSVGLength2::SMILLength::ValueFromString(const nsAString& aStr,
nsSMILValue val(&nsSMILFloatType::sSingleton);
val.mU.mDouble = value / mVal->GetUnitScaleFactor(mSVGElement, unitType);
aValue = val;
aCanCache = (unitType != nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE &&
unitType != nsIDOMSVGLength::SVG_LENGTHTYPE_EMS &&
unitType != nsIDOMSVGLength::SVG_LENGTHTYPE_EXS);
return NS_OK;
}

Просмотреть файл

@ -283,7 +283,8 @@ private:
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue &aValue) const;
nsSMILValue &aValue,
PRBool& aCanCache) const;
virtual nsSMILValue GetBaseValue() const;
virtual void ClearAnimValue();
virtual nsresult SetAnimValue(const nsSMILValue& aValue);

Просмотреть файл

@ -172,7 +172,8 @@ nsSVGNumber2::ToSMILAttr(nsSVGElement *aSVGElement)
nsresult
nsSVGNumber2::SMILNumber::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* /*aSrcElement*/,
nsSMILValue& aValue) const
nsSMILValue& aValue,
PRBool& aCanCache) const
{
float value;
@ -184,6 +185,7 @@ nsSVGNumber2::SMILNumber::ValueFromString(const nsAString& aStr,
nsSMILValue val(&nsSMILFloatType::sSingleton);
val.mU.mDouble = value;
aValue = val;
aCanCache = PR_TRUE;
return NS_OK;
}

Просмотреть файл

@ -129,7 +129,8 @@ private:
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue) const;
nsSMILValue& aValue,
PRBool& aCanCache) const;
virtual nsSMILValue GetBaseValue() const;
virtual void ClearAnimValue();
virtual nsresult SetAnimValue(const nsSMILValue& aValue);

Просмотреть файл

@ -345,7 +345,8 @@ nsresult
nsSVGPreserveAspectRatio::SMILPreserveAspectRatio
::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* /*aSrcElement*/,
nsSMILValue& aValue) const
nsSMILValue& aValue,
PRBool& aCanCache) const
{
PreserveAspectRatio par;
nsresult res = ToPreserveAspectRatio(aStr, &par);
@ -354,6 +355,7 @@ nsSVGPreserveAspectRatio::SMILPreserveAspectRatio
nsSMILValue val(&SMILEnumType::sSingleton);
val.mU.mUint = PackPreserveAspectRatio(par);
aValue = val;
aCanCache = PR_TRUE;
return NS_OK;
}

Просмотреть файл

@ -214,7 +214,8 @@ private:
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue) const;
nsSMILValue& aValue,
PRBool& aCanCache) const;
virtual nsSMILValue GetBaseValue() const;
virtual void ClearAnimValue();
virtual nsresult SetAnimValue(const nsSMILValue& aValue);

Просмотреть файл

@ -54,7 +54,8 @@
nsresult
nsSVGTransformSMILAttr::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue) const
nsSMILValue& aValue,
PRBool& aCanCache) const
{
NS_ENSURE_TRUE(aSrcElement, NS_ERROR_FAILURE);
NS_ASSERTION(aValue.IsNull(),
@ -66,6 +67,7 @@ nsSVGTransformSMILAttr::ValueFromString(const nsAString& aStr,
: nsGkAtoms::translate;
ParseValue(aStr, transformType, aValue);
aCanCache = PR_TRUE;
return aValue.IsNull() ? NS_ERROR_FAILURE : NS_OK;
}

Просмотреть файл

@ -57,9 +57,10 @@ public:
: mVal(aTransform) {}
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue) const;
nsSMILValue& aValue,
PRBool& aCanCache) const;
virtual nsSMILValue GetBaseValue() const;
virtual void ClearAnimValue();
virtual nsresult SetAnimValue(const nsSMILValue& aValue);

Просмотреть файл

@ -284,7 +284,8 @@ nsresult
nsSVGViewBox::SMILViewBox
::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* /*aSrcElement*/,
nsSMILValue& aValue) const
nsSMILValue& aValue,
PRBool& aCanCache) const
{
nsSVGViewBoxRect viewBox;
nsresult res = ToSVGViewBoxRect(aStr, &viewBox);
@ -298,6 +299,7 @@ nsSVGViewBox::SMILViewBox
}
*static_cast<nsSVGViewBoxRect*>(val.mU.mPtr) = viewBox;
aValue = val;
aCanCache = PR_TRUE;
return NS_OK;
}

Просмотреть файл

@ -182,7 +182,8 @@ private:
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue) const;
nsSMILValue& aValue,
PRBool& aCanCache) const;
virtual nsSMILValue GetBaseValue() const;
virtual void ClearAnimValue();
virtual nsresult SetAnimValue(const nsSMILValue& aValue);