Bug 589436 patch 2: Allow string-valued SVG attributes to be SMIL-animated. r=dholbert a=blocking-b8+

This commit is contained in:
Robert Longson 2010-10-07 12:19:32 -07:00
parent f5d772cd80
commit eba2ec8bc5
32 changed files with 610 additions and 208 deletions

View File

@ -71,8 +71,8 @@ enum nsLinkState {
// IID for the nsIContent interface
#define NS_ICONTENT_IID \
{ 0xdd254504, 0xe273, 0x4923, \
{ 0x9e, 0xc1, 0xd8, 0x42, 0x1a, 0x66, 0x35, 0xf1 } }
{ 0x64ef8589, 0xbd19, 0x40f4, \
{ 0xa9, 0x61, 0x47, 0x89, 0xe0, 0x8d, 0xb0, 0x49 } }
/**
* A node of content in a document's content model. This interface
@ -895,7 +895,7 @@ public:
*
* The CALLER OWNS the result and is responsible for deleting it.
*/
virtual nsISMILAttr* GetAnimatedAttr(nsIAtom* aName) = 0;
virtual nsISMILAttr* GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName) = 0;
/**
* Get the SMIL override style for this content node. This is a style

View File

@ -230,7 +230,7 @@ public:
virtual void SaveSubtreeState();
#ifdef MOZ_SMIL
virtual nsISMILAttr* GetAnimatedAttr(nsIAtom* /*aName*/)
virtual nsISMILAttr* GetAnimatedAttr(PRInt32 /*aNamespaceID*/, nsIAtom* /*aName*/)
{
return nsnull;
}

View File

@ -430,7 +430,7 @@ public:
virtual void SaveSubtreeState();
#ifdef MOZ_SMIL
virtual nsISMILAttr* GetAnimatedAttr(nsIAtom* /*aName*/)
virtual nsISMILAttr* GetAnimatedAttr(PRInt32 /*aNamespaceID*/, nsIAtom* /*aName*/)
{
return nsnull;
}

View File

@ -76,6 +76,7 @@ CPPSRCS += \
SMILBoolType.cpp \
SMILEnumType.cpp \
SMILIntegerType.cpp \
SMILStringType.cpp \
$(NULL)
endif

View File

@ -0,0 +1,123 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla SVG project.
*
* The Initial Developer of the Original Code is Robert Longson.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "SMILStringType.h"
#include "nsSMILValue.h"
#include "nsDebug.h"
#include "nsString.h"
namespace mozilla {
/*static*/ SMILStringType SMILStringType::sSingleton;
void
SMILStringType::Init(nsSMILValue& aValue) const
{
NS_PRECONDITION(aValue.IsNull(), "Unexpected value type");
aValue.mU.mPtr = new nsString();
aValue.mType = this;
}
void
SMILStringType::Destroy(nsSMILValue& aValue) const
{
NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
delete static_cast<nsAString*>(aValue.mU.mPtr);
aValue.mU.mPtr = nsnull;
aValue.mType = &nsSMILNullType::sSingleton;
}
nsresult
SMILStringType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
{
NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
const nsAString* src = static_cast<const nsAString*>(aSrc.mU.mPtr);
nsAString* dst = static_cast<nsAString*>(aDest.mU.mPtr);
*dst = *src;
return NS_OK;
}
PRBool
SMILStringType::IsEqual(const nsSMILValue& aLeft,
const nsSMILValue& aRight) const
{
NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
const nsAString* leftString =
static_cast<const nsAString*>(aLeft.mU.mPtr);
const nsAString* rightString =
static_cast<nsAString*>(aRight.mU.mPtr);
return *leftString == *rightString;
}
nsresult
SMILStringType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
PRUint32 aCount) const
{
NS_PRECONDITION(aValueToAdd.mType == aDest.mType,
"Trying to add invalid types");
NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type");
return NS_ERROR_FAILURE; // string values can't be added to each other
}
nsresult
SMILStringType::ComputeDistance(const nsSMILValue& aFrom,
const nsSMILValue& aTo,
double& aDistance) const
{
NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
return NS_ERROR_FAILURE; // there is no concept of distance between string values
}
nsresult
SMILStringType::Interpolate(const nsSMILValue& aStartVal,
const nsSMILValue& aEndVal,
double aUnitDistance,
nsSMILValue& aResult) const
{
NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
"Trying to interpolate different types");
NS_PRECONDITION(aStartVal.mType == this,
"Unexpected types for interpolation");
NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
return NS_ERROR_FAILURE; // string values do not interpolate
}
} // namespace mozilla

View File

@ -0,0 +1,77 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla SVG project.
*
* The Initial Developer of the Original Code is Robert Longson.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_SMILSTRINGTYPE_H_
#define MOZILLA_SMILSTRINGTYPE_H_
#include "nsISMILType.h"
namespace mozilla {
class SMILStringType : public nsISMILType
{
public:
// Singleton for nsSMILValue objects to hold onto.
static SMILStringType sSingleton;
protected:
// nsISMILType Methods
// -------------------
virtual void Init(nsSMILValue& aValue) const;
virtual void Destroy(nsSMILValue&) const;
virtual nsresult Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const;
virtual PRBool IsEqual(const nsSMILValue& aLeft,
const nsSMILValue& aRight) const;
virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
PRUint32 aCount) const;
virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
const nsSMILValue& aTo,
double& aDistance) const;
virtual nsresult Interpolate(const nsSMILValue& aStartVal,
const nsSMILValue& aEndVal,
double aUnitDistance,
nsSMILValue& aResult) const;
private:
// Private constructor & destructor: prevent instances beyond my singleton,
// and prevent others from deleting my singleton.
SMILStringType() {}
~SMILStringType() {}
};
} // namespace mozilla
#endif // MOZILLA_SMILSTRINGTYPE_H_

View File

@ -46,8 +46,8 @@
// some property of another element, e.g. <animate>, <set>.
#define NS_ISMILANIMATIONELEMENT_IID \
{ 0x5c891601, 0x47aa, 0x4230, \
{ 0xb8, 0xdc, 0xb9, 0x26, 0xd1, 0xe7, 0xd7, 0xf4 } }
{ 0xaf92584b, 0x75b0, 0x4584, \
{ 0x87, 0xd2, 0xa8, 0x3, 0x34, 0xf0, 0x5, 0xaf } }
class nsISMILAttr;
class nsSMILAnimationFunction;
@ -120,7 +120,8 @@ public:
/*
* Returns the name of the target (animated) attribute or property.
*/
virtual nsIAtom* GetTargetAttributeName() const = 0;
virtual PRBool GetTargetAttributeName(PRInt32* aNamespaceID,
nsIAtom** aLocalName) const = 0;
/*
* Returns the type of the target (animated) attribute or property.

View File

@ -21,6 +21,7 @@
* Contributor(s):
* Brian Birtles <birtles@gmail.com>
* Daniel Holbert <dholbert@mozilla.com>
* Robert Longson <longsonr@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -720,12 +721,12 @@ nsSMILAnimationController::GetTargetIdentifierForAnimation(
return PR_FALSE;
// Look up target (animated) attribute
//
// XXXdholbert As mentioned in SMILANIM section 3.1, attributeName may
// have an XMLNS prefix to indicate the XML namespace. Need to parse
// that somewhere.
nsIAtom* attributeName = aAnimElem->GetTargetAttributeName();
if (!attributeName)
// SMILANIM section 3.1, attributeName may
// have an XMLNS prefix to indicate the XML namespace.
nsCOMPtr<nsIAtom> attributeName;
PRInt32 attributeNamespaceID;
if (!aAnimElem->GetTargetAttributeName(&attributeNamespaceID,
getter_AddRefs(attributeName)))
// Animation has no target attr -- skip it.
return PR_FALSE;
@ -735,11 +736,13 @@ nsSMILAnimationController::GetTargetIdentifierForAnimation(
// Check if an 'auto' attributeType refers to a CSS property or XML attribute.
// Note that SMIL requires we search for CSS properties first. So if they
// overlap, 'auto' = 'CSS'. (SMILANIM 3.1)
PRBool isCSS;
PRBool isCSS = PR_FALSE;
if (attributeType == eSMILTargetAttrType_auto) {
nsCSSProperty prop =
nsCSSProps::LookupProperty(nsDependentAtomString(attributeName));
isCSS = nsSMILCSSProperty::IsPropertyAnimatable(prop);
if (attributeNamespaceID == kNameSpaceID_None) {
nsCSSProperty prop =
nsCSSProps::LookupProperty(nsDependentAtomString(attributeName));
isCSS = nsSMILCSSProperty::IsPropertyAnimatable(prop);
}
} else {
isCSS = (attributeType == eSMILTargetAttrType_CSS);
}
@ -747,6 +750,7 @@ nsSMILAnimationController::GetTargetIdentifierForAnimation(
// Construct the key
aResult.mElement = targetElem;
aResult.mAttributeName = attributeName;
aResult.mAttributeNamespaceID = attributeNamespaceID;
aResult.mIsCSS = isCSS;
return PR_TRUE;

View File

@ -158,7 +158,8 @@ nsSMILCompositor::CreateSMILAttr()
return new nsSMILCSSProperty(propId, mKey.mElement.get());
}
} else {
return mKey.mElement->GetAnimatedAttr(mKey.mAttributeName);
return mKey.mElement->GetAnimatedAttr(mKey.mAttributeNamespaceID,
mKey.mAttributeName);
}
return nsnull;
}

View File

@ -58,17 +58,20 @@
struct nsSMILTargetIdentifier
{
nsSMILTargetIdentifier()
: mElement(nsnull), mAttributeName(nsnull), mIsCSS(PR_FALSE) {}
: mElement(nsnull), mAttributeName(nsnull),
mAttributeNamespaceID(kNameSpaceID_Unknown), mIsCSS(PR_FALSE) {}
inline PRBool Equals(const nsSMILTargetIdentifier& aOther) const
{
return (aOther.mElement == mElement &&
aOther.mAttributeName == mAttributeName &&
aOther.mIsCSS == mIsCSS);
return (aOther.mElement == mElement &&
aOther.mAttributeName == mAttributeName &&
aOther.mAttributeNamespaceID == mAttributeNamespaceID &&
aOther.mIsCSS == mIsCSS);
}
nsRefPtr<mozilla::dom::Element> mElement;
nsRefPtr<nsIAtom> mAttributeName; // XXX need to consider namespaces here
nsRefPtr<nsIAtom> mAttributeName;
PRInt32 mAttributeNamespaceID;
PRPackedBool mIsCSS;
};

View File

@ -47,8 +47,8 @@
nsSVGElement::StringInfo nsSVGAElement::sStringInfo[2] =
{
{ &nsGkAtoms::href, kNameSpaceID_XLink },
{ &nsGkAtoms::target, kNameSpaceID_None }
{ &nsGkAtoms::href, kNameSpaceID_XLink, PR_TRUE },
{ &nsGkAtoms::target, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(A)

View File

@ -85,7 +85,7 @@ protected:
nsSVGElement::StringInfo nsSVGAltGlyphElement::sStringInfo[1] =
{
{ &nsGkAtoms::href, kNameSpaceID_XLink }
{ &nsGkAtoms::href, kNameSpaceID_XLink, PR_FALSE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(AltGlyph)

View File

@ -80,13 +80,16 @@ nsSVGAnimateMotionElement::AnimationFunction()
return mAnimationFunction;
}
nsIAtom*
nsSVGAnimateMotionElement::GetTargetAttributeName() const
PRBool
nsSVGAnimateMotionElement::GetTargetAttributeName(PRInt32 *aNamespaceID,
nsIAtom **aLocalName) const
{
// <animateMotion> doesn't take an attributeName, since it doesn't target an
// 'attribute' per se. We'll use a unique dummy attribute-name so that our
// nsSMILTargetIdentifier logic (which requires a attribute name) still works.
return nsGkAtoms::mozAnimateMotionDummyAttr;
*aNamespaceID = kNameSpaceID_None;
*aLocalName = nsGkAtoms::mozAnimateMotionDummyAttr;
return PR_TRUE;
}
nsSMILTargetAttrType

View File

@ -70,7 +70,8 @@ public:
// nsISMILAnimationElement
virtual nsSMILAnimationFunction& AnimationFunction();
virtual nsIAtom* GetTargetAttributeName() const;
virtual PRBool GetTargetAttributeName(PRInt32 *aNamespaceID,
nsIAtom **aLocalName) const;
virtual nsSMILTargetAttrType GetTargetAttributeType() const;
// Utility method to let our <mpath> children tell us when they've changed,

View File

@ -151,18 +151,22 @@ nsSVGAnimationElement::GetTargetElementContent()
return nsSVGUtils::GetParentElement(this);
}
nsIAtom*
nsSVGAnimationElement::GetTargetAttributeName() const
PRBool
nsSVGAnimationElement::GetTargetAttributeName(PRInt32 *aNamespaceID,
nsIAtom **aLocalName) const
{
const nsAttrValue* nameAttr
= mAttrsAndChildren.GetAttr(nsGkAtoms::attributeName);
if (!nameAttr)
return nsnull;
return PR_FALSE;
NS_ASSERTION(nameAttr->Type() == nsAttrValue::eAtom,
"attributeName should have been parsed as an atom");
return nameAttr->GetAtomValue();
return NS_SUCCEEDED(nsContentUtils::SplitQName(
this, nsDependentAtomString(nameAttr->GetAtomValue()),
aNamespaceID, aLocalName));
}
nsSMILTargetAttrType

View File

@ -94,7 +94,8 @@ public:
virtual PRBool GetAnimAttr(nsIAtom* aAttName, nsAString& aResult) const;
virtual PRBool HasAnimAttr(nsIAtom* aAttName) const;
virtual Element* GetTargetElementContent();
virtual nsIAtom* GetTargetAttributeName() const;
virtual PRBool GetTargetAttributeName(PRInt32* aNamespaceID,
nsIAtom** aLocalName) const;
virtual nsSMILTargetAttrType GetTargetAttributeType() const;
virtual nsSMILTimedElement& TimedElement();
virtual nsSMILTimeContainer* GetTimeContainer();

View File

@ -1933,6 +1933,19 @@ void nsSVGElement::SetStringBaseValue(PRUint8 aAttrEnum, const nsAString& aValue
*info.mStringInfo[aAttrEnum].mName, aValue, PR_TRUE);
}
void
nsSVGElement::DidAnimateString(PRUint8 aAttrEnum)
{
nsIFrame* frame = GetPrimaryFrame();
if (frame) {
StringAttributesInfo info = GetStringInfo();
frame->AttributeChanged(info.mStringInfo[aAttrEnum].mNamespaceID,
*info.mStringInfo[aAttrEnum].mName,
nsIDOMMutationEvent::MODIFICATION);
}
}
nsresult
nsSVGElement::ParseNumberOptionalNumber(const nsAString& aValue,
PRUint32 aIndex1, PRUint32 aIndex2)
@ -2054,137 +2067,150 @@ nsSVGElement::RecompileScriptEventListeners()
#ifdef MOZ_SMIL
nsISMILAttr*
nsSVGElement::GetAnimatedAttr(nsIAtom* aName)
nsSVGElement::GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName)
{
// Transforms:
nsCOMPtr<nsIDOMSVGAnimatedTransformList> transformList;
if (aName == nsGkAtoms::transform) {
nsCOMPtr<nsIDOMSVGTransformable> transformable(
do_QueryInterface(static_cast<nsIContent*>(this)));
if (!transformable)
return nsnull;
nsresult rv = transformable->GetTransform(getter_AddRefs(transformList));
NS_ENSURE_SUCCESS(rv, nsnull);
}
if (aName == nsGkAtoms::gradientTransform) {
nsCOMPtr<nsIDOMSVGGradientElement> gradientElement(
do_QueryInterface(static_cast<nsIContent*>(this)));
if (!gradientElement)
return nsnull;
nsresult rv = gradientElement->GetGradientTransform(getter_AddRefs(transformList));
NS_ENSURE_SUCCESS(rv, nsnull);
}
if (aName == nsGkAtoms::patternTransform) {
nsCOMPtr<nsIDOMSVGPatternElement> patternElement(
do_QueryInterface(static_cast<nsIContent*>(this)));
if (!patternElement)
return nsnull;
nsresult rv = patternElement->GetPatternTransform(getter_AddRefs(transformList));
NS_ENSURE_SUCCESS(rv, nsnull);
}
if (transformList) {
nsSVGAnimatedTransformList* list
= static_cast<nsSVGAnimatedTransformList*>(transformList.get());
NS_ENSURE_TRUE(list, nsnull);
return new nsSVGTransformSMILAttr(list, this);
}
// Motion (fake 'attribute' for animateMotion)
if (aName == nsGkAtoms::mozAnimateMotionDummyAttr) {
return new SVGMotionSMILAttr(this);
}
// Lengths:
LengthAttributesInfo info = GetLengthInfo();
for (PRUint32 i = 0; i < info.mLengthCount; i++) {
if (aName == *info.mLengthInfo[i].mName) {
return info.mLengths[i].ToSMILAttr(this);
if (aNamespaceID == kNameSpaceID_None) {
// Transforms:
nsCOMPtr<nsIDOMSVGAnimatedTransformList> transformList;
if (aName == nsGkAtoms::transform) {
nsCOMPtr<nsIDOMSVGTransformable> transformable(
do_QueryInterface(static_cast<nsIContent*>(this)));
if (!transformable)
return nsnull;
nsresult rv = transformable->GetTransform(getter_AddRefs(transformList));
NS_ENSURE_SUCCESS(rv, nsnull);
}
}
if (aName == nsGkAtoms::gradientTransform) {
nsCOMPtr<nsIDOMSVGGradientElement> gradientElement(
do_QueryInterface(static_cast<nsIContent*>(this)));
if (!gradientElement)
return nsnull;
// Numbers:
{
NumberAttributesInfo info = GetNumberInfo();
for (PRUint32 i = 0; i < info.mNumberCount; i++) {
// XXX this isn't valid for either of the two properties corresponding to
// attributes of type <number-optional-number> - see filter,
// feConvolveMatrix, feDiffuseLighting, feGaussianBlur, feMorphology and
// feTurbulence.
// The way to fix this is probably to handle them as 2-item number lists
// once we implement number list animation, and put the number list loop
// *above* this one at that time to catch those properties before we get
// here. The separate properties should then point into the list.
if (aName == *info.mNumberInfo[i].mName) {
return info.mNumbers[i].ToSMILAttr(this);
nsresult rv = gradientElement->GetGradientTransform(getter_AddRefs(transformList));
NS_ENSURE_SUCCESS(rv, nsnull);
}
if (aName == nsGkAtoms::patternTransform) {
nsCOMPtr<nsIDOMSVGPatternElement> patternElement(
do_QueryInterface(static_cast<nsIContent*>(this)));
if (!patternElement)
return nsnull;
nsresult rv = patternElement->GetPatternTransform(getter_AddRefs(transformList));
NS_ENSURE_SUCCESS(rv, nsnull);
}
if (transformList) {
nsSVGAnimatedTransformList* list
= static_cast<nsSVGAnimatedTransformList*>(transformList.get());
NS_ENSURE_TRUE(list, nsnull);
return new nsSVGTransformSMILAttr(list, this);
}
// Motion (fake 'attribute' for animateMotion)
if (aName == nsGkAtoms::mozAnimateMotionDummyAttr) {
return new SVGMotionSMILAttr(this);
}
// Lengths:
LengthAttributesInfo info = GetLengthInfo();
for (PRUint32 i = 0; i < info.mLengthCount; i++) {
if (aName == *info.mLengthInfo[i].mName) {
return info.mLengths[i].ToSMILAttr(this);
}
}
// Numbers:
{
NumberAttributesInfo info = GetNumberInfo();
for (PRUint32 i = 0; i < info.mNumberCount; i++) {
// XXX this isn't valid for either of the two properties corresponding to
// attributes of type <number-optional-number> - see filter,
// feConvolveMatrix, feDiffuseLighting, feGaussianBlur, feMorphology and
// feTurbulence.
// The way to fix this is probably to handle them as 2-item number lists
// once we implement number list animation, and put the number list loop
// *above* this one at that time to catch those properties before we get
// here. The separate properties should then point into the list.
if (aName == *info.mNumberInfo[i].mName) {
return info.mNumbers[i].ToSMILAttr(this);
}
}
}
// Integers:
{
IntegerAttributesInfo info = GetIntegerInfo();
for (PRUint32 i = 0; i < info.mIntegerCount; i++) {
if (aName == *info.mIntegerInfo[i].mName) {
return info.mIntegers[i].ToSMILAttr(this);
}
}
}
// Enumerations:
{
EnumAttributesInfo info = GetEnumInfo();
for (PRUint32 i = 0; i < info.mEnumCount; i++) {
if (aName == *info.mEnumInfo[i].mName) {
return info.mEnums[i].ToSMILAttr(this);
}
}
}
// Booleans:
{
BooleanAttributesInfo info = GetBooleanInfo();
for (PRUint32 i = 0; i < info.mBooleanCount; i++) {
if (aName == *info.mBooleanInfo[i].mName) {
return info.mBooleans[i].ToSMILAttr(this);
}
}
}
// Angles:
{
AngleAttributesInfo info = GetAngleInfo();
for (PRUint32 i = 0; i < info.mAngleCount; i++) {
if (aName == *info.mAngleInfo[i].mName) {
return info.mAngles[i].ToSMILAttr(this);
}
}
}
// viewBox:
if (aName == nsGkAtoms::viewBox) {
nsSVGViewBox *viewBox = GetViewBox();
return viewBox ? viewBox->ToSMILAttr(this) : nsnull;
}
// preserveAspectRatio:
if (aName == nsGkAtoms::preserveAspectRatio) {
nsSVGPreserveAspectRatio *preserveAspectRatio = GetPreserveAspectRatio();
return preserveAspectRatio ? preserveAspectRatio->ToSMILAttr(this) : nsnull;
}
// LengthLists:
{
LengthListAttributesInfo info = GetLengthListInfo();
for (PRUint32 i = 0; i < info.mLengthListCount; i++) {
if (aName == *info.mLengthListInfo[i].mName) {
NS_ABORT_IF_FALSE(i <= UCHAR_MAX, "Too many attributes");
return info.mLengthLists[i].ToSMILAttr(this,
PRUint8(i),
info.mLengthListInfo[i].mAxis,
info.mLengthListInfo[i].mCouldZeroPadList);
}
}
}
}
// Integers:
// Strings
{
IntegerAttributesInfo info = GetIntegerInfo();
for (PRUint32 i = 0; i < info.mIntegerCount; i++) {
if (aName == *info.mIntegerInfo[i].mName) {
return info.mIntegers[i].ToSMILAttr(this);
}
}
}
// Enumerations:
{
EnumAttributesInfo info = GetEnumInfo();
for (PRUint32 i = 0; i < info.mEnumCount; i++) {
if (aName == *info.mEnumInfo[i].mName) {
return info.mEnums[i].ToSMILAttr(this);
}
}
}
// Booleans:
{
BooleanAttributesInfo info = GetBooleanInfo();
for (PRUint32 i = 0; i < info.mBooleanCount; i++) {
if (aName == *info.mBooleanInfo[i].mName) {
return info.mBooleans[i].ToSMILAttr(this);
}
}
}
// Angles:
{
AngleAttributesInfo info = GetAngleInfo();
for (PRUint32 i = 0; i < info.mAngleCount; i++) {
if (aName == *info.mAngleInfo[i].mName) {
return info.mAngles[i].ToSMILAttr(this);
}
}
}
// viewBox:
if (aName == nsGkAtoms::viewBox) {
nsSVGViewBox *viewBox = GetViewBox();
return viewBox ? viewBox->ToSMILAttr(this) : nsnull;
}
// preserveAspectRatio:
if (aName == nsGkAtoms::preserveAspectRatio) {
nsSVGPreserveAspectRatio *preserveAspectRatio = GetPreserveAspectRatio();
return preserveAspectRatio ? preserveAspectRatio->ToSMILAttr(this) : nsnull;
}
// LengthLists:
{
LengthListAttributesInfo info = GetLengthListInfo();
for (PRUint32 i = 0; i < info.mLengthListCount; i++) {
if (aName == *info.mLengthListInfo[i].mName) {
NS_ABORT_IF_FALSE(i <= UCHAR_MAX, "Too many attributes");
return info.mLengthLists[i].ToSMILAttr(this,
PRUint8(i),
info.mLengthListInfo[i].mAxis,
info.mLengthListInfo[i].mCouldZeroPadList);
StringAttributesInfo info = GetStringInfo();
for (PRUint32 i = 0; i < info.mStringCount; i++) {
if (aNamespaceID == info.mStringInfo[i].mNamespaceID &&
aName == *info.mStringInfo[i].mName) {
return info.mStrings[i].ToSMILAttr(this);
}
}
}

View File

@ -155,6 +155,9 @@ public:
// subclass has the useful implementation.
virtual void SetAnimateMotionTransform(const gfxMatrix* aMatrix) {/*no-op*/}
PRBool IsStringAnimatable(PRUint8 aAttrEnum) {
return GetStringInfo().mStringInfo[aAttrEnum].mIsAnimatable;
}
virtual void DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeNumber(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeInteger(PRUint8 aAttrEnum, PRBool aDoSetAttr);
@ -176,6 +179,7 @@ public:
virtual void DidAnimatePreserveAspectRatio();
virtual void DidAnimateLengthList(PRUint8 aAttrEnum);
virtual void DidAnimateTransform();
virtual void DidAnimateString(PRUint8 aAttrEnum);
void GetAnimatedLengthValues(float *aFirst, ...);
void GetAnimatedNumberValues(float *aFirst, ...);
@ -184,7 +188,7 @@ public:
mozilla::SVGAnimatedLengthList* GetAnimatedLengthList(PRUint8 aAttrEnum);
#ifdef MOZ_SMIL
virtual nsISMILAttr* GetAnimatedAttr(nsIAtom* aName);
virtual nsISMILAttr* GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName);
void AnimationNeedsResample();
void FlushAnimations();
#endif
@ -371,6 +375,7 @@ protected:
struct StringInfo {
nsIAtom** mName;
PRInt32 mNamespaceID;
PRPackedBool mIsAnimatable;
};
struct StringAttributesInfo {

View File

@ -67,7 +67,7 @@ nsSVGElement::EnumInfo nsSVGFilterElement::sEnumInfo[2] =
nsSVGElement::StringInfo nsSVGFilterElement::sStringInfo[1] =
{
{ &nsGkAtoms::href, kNameSpaceID_XLink }
{ &nsGkAtoms::href, kNameSpaceID_XLink, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(Filter)

View File

@ -345,6 +345,12 @@ nsSVGFE::DidAnimateBoolean(PRUint8 aAttrEnum)
DidAnimateAttr(this);
}
void
nsSVGFE::DidAnimateString(PRUint8 aAttrEnum)
{
DidAnimateAttr(this);
}
//---------------------Gaussian Blur------------------------
typedef nsSVGFE nsSVGFEGaussianBlurElementBase;
@ -418,8 +424,8 @@ nsSVGElement::NumberInfo nsSVGFEGaussianBlurElement::sNumberInfo[2] =
nsSVGElement::StringInfo nsSVGFEGaussianBlurElement::sStringInfo[2] =
{
{ &nsGkAtoms::result, kNameSpaceID_None },
{ &nsGkAtoms::in, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEGaussianBlur)
@ -898,9 +904,9 @@ nsSVGElement::EnumInfo nsSVGFEBlendElement::sEnumInfo[1] =
nsSVGElement::StringInfo nsSVGFEBlendElement::sStringInfo[3] =
{
{ &nsGkAtoms::result, kNameSpaceID_None },
{ &nsGkAtoms::in, kNameSpaceID_None },
{ &nsGkAtoms::in2, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in2, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEBlend)
@ -1103,8 +1109,8 @@ nsSVGElement::EnumInfo nsSVGFEColorMatrixElement::sEnumInfo[1] =
nsSVGElement::StringInfo nsSVGFEColorMatrixElement::sStringInfo[2] =
{
{ &nsGkAtoms::result, kNameSpaceID_None },
{ &nsGkAtoms::in, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEColorMatrix)
@ -1443,9 +1449,9 @@ nsSVGElement::EnumInfo nsSVGFECompositeElement::sEnumInfo[1] =
nsSVGElement::StringInfo nsSVGFECompositeElement::sStringInfo[3] =
{
{ &nsGkAtoms::result, kNameSpaceID_None },
{ &nsGkAtoms::in, kNameSpaceID_None },
{ &nsGkAtoms::in2, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in2, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEComposite)
@ -1706,8 +1712,8 @@ protected:
nsSVGElement::StringInfo nsSVGFEComponentTransferElement::sStringInfo[2] =
{
{ &nsGkAtoms::result, kNameSpaceID_None },
{ &nsGkAtoms::in, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEComponentTransfer)
@ -2347,7 +2353,7 @@ protected:
nsSVGElement::StringInfo nsSVGFEMergeElement::sStringInfo[1] =
{
{ &nsGkAtoms::result, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEMerge)
@ -2419,7 +2425,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsSVGFEMergeNodeElement, NS_SVG_FE_MERGE_NODE_CID)
nsSVGElement::StringInfo nsSVGFEMergeNodeElement::sStringInfo[1] =
{
{ &nsGkAtoms::in, kNameSpaceID_None }
{ &nsGkAtoms::in, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEMergeNode)
@ -2534,8 +2540,8 @@ nsSVGElement::NumberInfo nsSVGFEOffsetElement::sNumberInfo[2] =
nsSVGElement::StringInfo nsSVGFEOffsetElement::sStringInfo[2] =
{
{ &nsGkAtoms::result, kNameSpaceID_None },
{ &nsGkAtoms::in, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEOffset)
@ -2726,7 +2732,7 @@ protected:
nsSVGElement::StringInfo nsSVGFEFloodElement::sStringInfo[1] =
{
{ &nsGkAtoms::result, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEFlood)
@ -2867,8 +2873,8 @@ protected:
nsSVGElement::StringInfo nsSVGFETileElement::sStringInfo[2] =
{
{ &nsGkAtoms::result, kNameSpaceID_None },
{ &nsGkAtoms::in, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FETile)
@ -3175,7 +3181,7 @@ nsSVGElement::EnumInfo nsSVGFETurbulenceElement::sEnumInfo[2] =
nsSVGElement::StringInfo nsSVGFETurbulenceElement::sStringInfo[1] =
{
{ &nsGkAtoms::result, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FETurbulence)
@ -3613,8 +3619,8 @@ nsSVGElement::EnumInfo nsSVGFEMorphologyElement::sEnumInfo[1] =
nsSVGElement::StringInfo nsSVGFEMorphologyElement::sStringInfo[2] =
{
{ &nsGkAtoms::result, kNameSpaceID_None },
{ &nsGkAtoms::in, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEMorphology)
@ -3970,8 +3976,8 @@ nsSVGElement::EnumInfo nsSVGFEConvolveMatrixElement::sEnumInfo[1] =
nsSVGElement::StringInfo nsSVGFEConvolveMatrixElement::sStringInfo[2] =
{
{ &nsGkAtoms::result, kNameSpaceID_None },
{ &nsGkAtoms::in, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEConvolveMatrix)
@ -4709,8 +4715,8 @@ nsSVGElement::NumberInfo nsSVGFELightingElement::sNumberInfo[6] =
nsSVGElement::StringInfo nsSVGFELightingElement::sStringInfo[2] =
{
{ &nsGkAtoms::result, kNameSpaceID_None },
{ &nsGkAtoms::in, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in, kNameSpaceID_None, PR_TRUE }
};
//----------------------------------------------------------------------
@ -5358,6 +5364,7 @@ protected:
virtual nsSVGPreserveAspectRatio *GetPreserveAspectRatio();
virtual StringAttributesInfo GetStringInfo();
virtual void DidAnimateString(PRUint8 aAttrEnum);
enum { RESULT, HREF };
nsSVGString mStringAttributes[2];
@ -5368,8 +5375,8 @@ protected:
nsSVGElement::StringInfo nsSVGFEImageElement::sStringInfo[2] =
{
{ &nsGkAtoms::result, kNameSpaceID_None },
{ &nsGkAtoms::href, kNameSpaceID_XLink }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::href, kNameSpaceID_XLink, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEImage)
@ -5591,6 +5598,17 @@ nsSVGFEImageElement::GetStringInfo()
NS_ARRAY_LENGTH(sStringInfo));
}
void
nsSVGFEImageElement::DidAnimateString(PRUint8 aAttrEnum)
{
if (aAttrEnum == HREF) {
LoadSVGImage(PR_TRUE, PR_FALSE);
return;
}
nsSVGFEImageElementBase::DidAnimateString(aAttrEnum);
}
//----------------------------------------------------------------------
// imgIDecoderObserver methods
@ -5745,9 +5763,9 @@ nsSVGElement::EnumInfo nsSVGFEDisplacementMapElement::sEnumInfo[2] =
nsSVGElement::StringInfo nsSVGFEDisplacementMapElement::sStringInfo[3] =
{
{ &nsGkAtoms::result, kNameSpaceID_None },
{ &nsGkAtoms::in, kNameSpaceID_None },
{ &nsGkAtoms::in2, kNameSpaceID_None }
{ &nsGkAtoms::result, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in, kNameSpaceID_None, PR_TRUE },
{ &nsGkAtoms::in2, kNameSpaceID_None, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEDisplacementMap)

View File

@ -222,6 +222,7 @@ protected:
virtual void DidAnimateEnum(PRUint8 aAttrEnum);
virtual void DidAnimateBoolean(PRUint8 aAttrEnum);
virtual void DidAnimatePreserveAspectRatio();
virtual void DidAnimateString(PRUint8 aAttrEnum);
// nsIDOMSVGFitlerPrimitiveStandardAttributes values
enum { X, Y, WIDTH, HEIGHT };

View File

@ -71,7 +71,7 @@ nsSVGElement::EnumInfo nsSVGGradientElement::sEnumInfo[2] =
nsSVGElement::StringInfo nsSVGGradientElement::sStringInfo[1] =
{
{ &nsGkAtoms::href, kNameSpaceID_XLink }
{ &nsGkAtoms::href, kNameSpaceID_XLink, PR_TRUE }
};
//----------------------------------------------------------------------

View File

@ -54,7 +54,7 @@ nsSVGElement::LengthInfo nsSVGImageElement::sLengthInfo[4] =
nsSVGElement::StringInfo nsSVGImageElement::sStringInfo[1] =
{
{ &nsGkAtoms::href, kNameSpaceID_XLink }
{ &nsGkAtoms::href, kNameSpaceID_XLink, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(Image)
@ -271,6 +271,17 @@ nsSVGImageElement::GetStringInfo()
NS_ARRAY_LENGTH(sStringInfo));
}
void
nsSVGImageElement::DidAnimateString(PRUint8 aAttrEnum)
{
if (aAttrEnum == HREF) {
LoadSVGImage(PR_TRUE, PR_FALSE);
return;
}
nsSVGImageElementBase::DidAnimateString(aAttrEnum);
}
nsresult
nsSVGImageElement::CopyInnerTo(nsGenericElement* aDest) const
{

View File

@ -101,6 +101,7 @@ protected:
virtual LengthAttributesInfo GetLengthInfo();
virtual nsSVGPreserveAspectRatio *GetPreserveAspectRatio();
virtual StringAttributesInfo GetStringInfo();
virtual void DidAnimateString(PRUint8 aAttrEnum);
enum { X, Y, WIDTH, HEIGHT };
nsSVGLength2 mLengthAttributes[4];

View File

@ -45,7 +45,7 @@ using namespace mozilla::dom;
nsSVGElement::StringInfo nsSVGMpathElement::sStringInfo[1] =
{
{ &nsGkAtoms::href, kNameSpaceID_XLink },
{ &nsGkAtoms::href, kNameSpaceID_XLink, PR_FALSE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(Mpath)

View File

@ -68,7 +68,7 @@ nsSVGElement::EnumInfo nsSVGPatternElement::sEnumInfo[2] =
nsSVGElement::StringInfo nsSVGPatternElement::sStringInfo[1] =
{
{ &nsGkAtoms::href, kNameSpaceID_XLink }
{ &nsGkAtoms::href, kNameSpaceID_XLink, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(Pattern)

View File

@ -108,7 +108,7 @@ protected:
nsSVGElement::StringInfo nsSVGScriptElement::sStringInfo[1] =
{
{ &nsGkAtoms::href, kNameSpaceID_XLink }
{ &nsGkAtoms::href, kNameSpaceID_XLink, PR_FALSE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT_CHECK_PARSER(Script)

View File

@ -35,6 +35,12 @@
* ***** END LICENSE BLOCK ***** */
#include "nsSVGString.h"
#ifdef MOZ_SMIL
#include "nsSMILValue.h"
#include "SMILStringType.h"
#endif // MOZ_SMIL
using namespace mozilla;
NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGString::DOMAnimatedString, mSVGElement)
@ -58,24 +64,41 @@ nsSVGString::SetBaseValue(const nsAString& aValue,
{
NS_ASSERTION(aSVGElement, "Null element passed to SetBaseValue");
mAnimVal = nsnull;
if (aDoSetAttr) {
aSVGElement->SetStringBaseValue(mAttrEnum, aValue);
}
#ifdef MOZ_SMIL
if (mAnimVal) {
aSVGElement->AnimationNeedsResample();
}
#endif
aSVGElement->DidChangeString(mAttrEnum);
}
void
nsSVGString::GetAnimValue(nsAString& aResult, const nsSVGElement* aSVGElement) const
nsSVGString::GetAnimValue(nsAString& aResult, const nsSVGElement *aSVGElement) const
{
if (mAnimVal)
if (mAnimVal) {
aResult = *mAnimVal;
return;
}
aSVGElement->GetStringBaseValue(mAttrEnum, aResult);
}
void
nsSVGString::SetAnimValue(const nsAString& aValue, nsSVGElement *aSVGElement)
{
if (aSVGElement->IsStringAnimatable(mAttrEnum)) {
if (!mAnimVal) {
mAnimVal = new nsString();
}
*mAnimVal = aValue;
aSVGElement->DidAnimateString(mAttrEnum);
}
}
nsresult
nsSVGString::ToDOMAnimatedString(nsIDOMSVGAnimatedString **aResult,
nsSVGElement *aSVGElement)
@ -87,3 +110,53 @@ nsSVGString::ToDOMAnimatedString(nsIDOMSVGAnimatedString **aResult,
NS_ADDREF(*aResult);
return NS_OK;
}
#ifdef MOZ_SMIL
nsISMILAttr*
nsSVGString::ToSMILAttr(nsSVGElement *aSVGElement)
{
return new SMILString(this, aSVGElement);
}
nsresult
nsSVGString::SMILString::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* /*aSrcElement*/,
nsSMILValue& aValue,
PRBool& aPreventCachingOfSandwich) const
{
nsSMILValue val(&SMILStringType::sSingleton);
*static_cast<nsAString*>(val.mU.mPtr) = aStr;
aValue.Swap(val);
aPreventCachingOfSandwich = PR_FALSE;
return NS_OK;
}
nsSMILValue
nsSVGString::SMILString::GetBaseValue() const
{
nsSMILValue val(&SMILStringType::sSingleton);
mSVGElement->GetStringBaseValue(mVal->mAttrEnum, *static_cast<nsAString*>(val.mU.mPtr));
return val;
}
void
nsSVGString::SMILString::ClearAnimValue()
{
if (mVal->mAnimVal) {
mVal->mAnimVal = nsnull;
mSVGElement->DidAnimateString(mVal->mAttrEnum);
}
}
nsresult
nsSVGString::SMILString::SetAnimValue(const nsSMILValue& aValue)
{
NS_ASSERTION(aValue.mType == &SMILStringType::sSingleton,
"Unexpected type to assign animated value");
if (aValue.mType == &SMILStringType::sSingleton) {
mVal->SetAnimValue(*static_cast<nsAString*>(aValue.mU.mPtr), mSVGElement);
}
return NS_OK;
}
#endif // MOZ_SMIL

View File

@ -53,13 +53,18 @@ public:
void SetBaseValue(const nsAString& aValue,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr);
void GetBaseValue(nsAString& aValue, nsSVGElement* aSVGElement) const
void GetBaseValue(nsAString& aValue, nsSVGElement *aSVGElement) const
{ aSVGElement->GetStringBaseValue(mAttrEnum, aValue); }
void GetAnimValue(nsAString& aValue, const nsSVGElement* aSVGElement) const;
void SetAnimValue(const nsAString& aValue, nsSVGElement *aSVGElement);
void GetAnimValue(nsAString& aValue, const nsSVGElement *aSVGElement) const;
nsresult ToDOMAnimatedString(nsIDOMSVGAnimatedString **aResult,
nsSVGElement* aSVGElement);
nsSVGElement *aSVGElement);
#ifdef MOZ_SMIL
// Returns a new nsISMILAttr object that the caller must delete
nsISMILAttr* ToSMILAttr(nsSVGElement *aSVGElement);
#endif // MOZ_SMIL
private:
@ -72,7 +77,7 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(DOMAnimatedString)
DOMAnimatedString(nsSVGString* aVal, nsSVGElement *aSVGElement)
DOMAnimatedString(nsSVGString *aVal, nsSVGElement *aSVGElement)
: mVal(aVal), mSVGElement(aSVGElement) {}
nsSVGString* mVal; // kept alive because it belongs to content
@ -84,8 +89,36 @@ public:
{ mVal->SetBaseValue(aValue, mSVGElement, PR_TRUE); return NS_OK; }
NS_IMETHOD GetAnimVal(nsAString & aResult)
{ mVal->GetAnimValue(aResult, mSVGElement); return NS_OK; }
{
#ifdef MOZ_SMIL
mSVGElement->FlushAnimations();
#endif
mVal->GetAnimValue(aResult, mSVGElement); return NS_OK;
}
};
#ifdef MOZ_SMIL
struct SMILString : public nsISMILAttr
{
public:
SMILString(nsSVGString *aVal, nsSVGElement *aSVGElement)
: mVal(aVal), mSVGElement(aSVGElement) {}
// These will stay alive because a nsISMILAttr only lives as long
// as the Compositing step, and DOM elements don't get a chance to
// die during that.
nsSVGString* mVal;
nsSVGElement* mSVGElement;
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement *aSrcElement,
nsSMILValue& aValue,
PRBool& aPreventCachingOfSandwich) const;
virtual nsSMILValue GetBaseValue() const;
virtual void ClearAnimValue();
virtual nsresult SetAnimValue(const nsSMILValue& aValue);
};
#endif // MOZ_SMIL
};
#endif //__NS_SVGSTRING_H__

View File

@ -74,7 +74,7 @@ nsSVGElement::EnumInfo nsSVGTextPathElement::sEnumInfo[2] =
nsSVGElement::StringInfo nsSVGTextPathElement::sStringInfo[1] =
{
{ &nsGkAtoms::href, kNameSpaceID_XLink }
{ &nsGkAtoms::href, kNameSpaceID_XLink, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(TextPath)

View File

@ -59,7 +59,7 @@ nsSVGElement::LengthInfo nsSVGUseElement::sLengthInfo[4] =
nsSVGElement::StringInfo nsSVGUseElement::sStringInfo[1] =
{
{ &nsGkAtoms::href, kNameSpaceID_XLink }
{ &nsGkAtoms::href, kNameSpaceID_XLink, PR_TRUE }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(Use)
@ -516,6 +516,20 @@ nsSVGUseElement::DidChangeString(PRUint8 aAttrEnum)
}
}
void
nsSVGUseElement::DidAnimateString(PRUint8 aAttrEnum)
{
if (aAttrEnum == HREF) {
// we're changing our nature, clear out the clone information
mOriginal = nsnull;
UnlinkSource();
TriggerReclone();
return;
}
nsSVGUseElementBase::DidAnimateString(aAttrEnum);
}
nsSVGElement::StringAttributesInfo
nsSVGUseElement::GetStringInfo()
{

View File

@ -104,6 +104,7 @@ public:
virtual gfxMatrix PrependLocalTransformTo(const gfxMatrix &aMatrix);
virtual void DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeString(PRUint8 aAttrEnum);
virtual void DidAnimateString(PRUint8 aAttrEnum);
// nsIContent interface
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;