mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 436418, patch H: SVG/SMIL animateMotion - add support for <mpath> sub-element. r=roc
This commit is contained in:
parent
c121001886
commit
128f3eaa73
@ -129,6 +129,7 @@ CPPSRCS += nsSVGAnimateElement.cpp \
|
||||
nsSVGAnimateTransformElement.cpp \
|
||||
nsSVGAnimateMotionElement.cpp \
|
||||
nsSVGAnimationElement.cpp \
|
||||
nsSVGMpathElement.cpp \
|
||||
nsSVGSetElement.cpp \
|
||||
nsSVGTransformSMILType.cpp \
|
||||
nsSVGTransformSMILAttr.cpp \
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "nsSVGPathDataParser.h"
|
||||
#include "nsSVGPathSeg.h"
|
||||
#include "nsSVGPathElement.h" // for nsSVGPathList
|
||||
#include "nsSVGMpathElement.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -150,6 +151,25 @@ SVGMotionSMILAnimationFunction::GetCalcMode() const
|
||||
//----------------------------------------------------------------------
|
||||
// Helpers for GetValues
|
||||
|
||||
/*
|
||||
* Returns the first <mpath> child of the given element
|
||||
*/
|
||||
|
||||
static nsSVGMpathElement*
|
||||
GetFirstMpathChild(nsIContent* aElem)
|
||||
{
|
||||
PRUint32 childCount = aElem->GetChildCount();
|
||||
for (PRUint32 i = 0; i < childCount; ++i) {
|
||||
nsIContent* child = aElem->GetChildAt(i);
|
||||
if (child->Tag() == nsGkAtoms::mpath &&
|
||||
child->GetNameSpaceID() == kNameSpaceID_SVG) {
|
||||
return static_cast<nsSVGMpathElement*>(child);
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
SVGMotionSMILAnimationFunction::
|
||||
RebuildPathAndVerticesFromBasicAttrs(const nsIContent* aContextElem)
|
||||
@ -224,6 +244,27 @@ SVGMotionSMILAnimationFunction::
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SVGMotionSMILAnimationFunction::
|
||||
RebuildPathAndVerticesFromMpathElem(nsSVGMpathElement* aMpathElem)
|
||||
{
|
||||
mPathSourceType = ePathSourceType_Mpath;
|
||||
|
||||
// Use the path that's the target of our chosen <mpath> child.
|
||||
nsSVGPathElement* pathElem = aMpathElem->GetReferencedPath();
|
||||
if (pathElem) {
|
||||
if (pathElem->HasAttr(kNameSpaceID_None, nsGkAtoms::d)) {
|
||||
const nsAString& pathSpec =
|
||||
pathElem->GetParsedAttr(nsGkAtoms::d)->GetStringValue();
|
||||
nsresult rv = SetPathVerticesFromPathString(pathSpec);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mPath = pathElem->GetFlattenedPath(
|
||||
pathElem->PrependLocalTransformTo(gfxMatrix()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SVGMotionSMILAnimationFunction::RebuildPathAndVerticesFromPathAttr()
|
||||
{
|
||||
@ -304,9 +345,13 @@ SVGMotionSMILAnimationFunction::
|
||||
|
||||
// Do we have a mpath child? if so, it trumps everything. Otherwise, we look
|
||||
// through our list of path-defining attributes, in order of priority.
|
||||
// XXXdholbert This is where we should check for mpath, in <mpath> patch.
|
||||
// ...else, if no mpath child:
|
||||
if (HasAttr(nsGkAtoms::path)) {
|
||||
nsSVGMpathElement* firstMpathChild =
|
||||
GetFirstMpathChild(&mAnimationElement->Content());
|
||||
|
||||
if (firstMpathChild) {
|
||||
RebuildPathAndVerticesFromMpathElem(firstMpathChild);
|
||||
mValueNeedsReparsingEverySample = PR_FALSE;
|
||||
} else if (HasAttr(nsGkAtoms::path)) {
|
||||
RebuildPathAndVerticesFromPathAttr();
|
||||
mValueNeedsReparsingEverySample = PR_FALSE;
|
||||
} else {
|
||||
|
@ -42,6 +42,8 @@
|
||||
#include "SVGMotionSMILType.h" // for RotateType
|
||||
#include "gfxPath.h" // for gfxFlattenedPath
|
||||
|
||||
class nsSVGMpathElement;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -60,6 +62,13 @@ public:
|
||||
nsresult* aParseResult = nsnull);
|
||||
NS_OVERRIDE virtual PRBool UnsetAttr(nsIAtom* aAttribute);
|
||||
|
||||
// Method to allow our owner-element to signal us when our <mpath>
|
||||
// has changed or been added/removed. When that happens, we need to
|
||||
// mark ourselves as changed so we'll get recomposed, and mark our path data
|
||||
// as stale so it'll get regenerated (regardless of mPathSourceType, since
|
||||
// <mpath> trumps all the other sources of path data)
|
||||
void MpathChanged() { mIsPathStale = mHasChanged = PR_TRUE; }
|
||||
|
||||
protected:
|
||||
enum PathSourceType {
|
||||
// NOTE: Ordering matters here. Higher-priority path-descriptors should
|
||||
@ -88,6 +97,7 @@ protected:
|
||||
void MarkStaleIfAttributeAffectsPath(nsIAtom* aAttribute);
|
||||
nsresult SetPathVerticesFromPathString(const nsAString& aPathSpec);
|
||||
void RebuildPathAndVertices(const nsIContent* aContextElem);
|
||||
void RebuildPathAndVerticesFromMpathElem(nsSVGMpathElement* aMpathElem);
|
||||
void RebuildPathAndVerticesFromPathAttr();
|
||||
void RebuildPathAndVerticesFromBasicAttrs(const nsIContent* aContextElem);
|
||||
PRBool GenerateValuesForPathAndPoints(gfxFlattenedPath* aPath,
|
||||
|
@ -0,0 +1,4 @@
|
||||
<svg:mpath xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xlink:href="#foo">
|
||||
</svg:mpath>
|
After Width: | Height: | Size: 147 B |
@ -42,6 +42,7 @@ load 427325-1.svg
|
||||
load 428228-1.svg
|
||||
load 428841-1.svg
|
||||
load 435209-1.svg
|
||||
load 436418-mpathRoot-1.svg
|
||||
load 448244-1.svg
|
||||
load 466576-1.xhtml
|
||||
load 535691-1.svg
|
||||
|
@ -38,48 +38,7 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGAnimationElement.h"
|
||||
#include "nsIDOMSVGAnimateMotionElement.h"
|
||||
#include "nsSVGEnum.h"
|
||||
#include "SVGMotionSMILAnimationFunction.h"
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIDOMSVGPathSeg.h"
|
||||
#include "nsSVGPathSeg.h"
|
||||
#include "nsSVGPathDataParser.h"
|
||||
|
||||
|
||||
typedef nsSVGAnimationElement nsSVGAnimateMotionElementBase;
|
||||
|
||||
class nsSVGAnimateMotionElement : public nsSVGAnimateMotionElementBase,
|
||||
public nsIDOMSVGAnimateMotionElement
|
||||
{
|
||||
protected:
|
||||
friend nsresult NS_NewSVGAnimateMotionElement(nsIContent **aResult,
|
||||
nsINodeInfo *aNodeInfo);
|
||||
nsSVGAnimateMotionElement(nsINodeInfo* aNodeInfo);
|
||||
|
||||
mozilla::SVGMotionSMILAnimationFunction mAnimationFunction;
|
||||
|
||||
public:
|
||||
// interfaces:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOMSVGANIMATEMOTIONELEMENT
|
||||
|
||||
NS_FORWARD_NSIDOMNODE(nsSVGAnimateMotionElementBase::)
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGAnimateMotionElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAnimateMotionElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGANIMATIONELEMENT(nsSVGAnimateMotionElementBase::)
|
||||
|
||||
// nsIDOMNode specializations
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
// nsISMILAnimationElement
|
||||
virtual nsSMILAnimationFunction& AnimationFunction();
|
||||
virtual nsIAtom* GetTargetAttributeName() const;
|
||||
virtual nsSMILTargetAttrType GetTargetAttributeType() const;
|
||||
|
||||
};
|
||||
#include "nsSVGAnimateMotionElement.h"
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(AnimateMotion)
|
||||
|
||||
|
81
content/svg/content/src/nsSVGAnimateMotionElement.h
Normal file
81
content/svg/content/src/nsSVGAnimateMotionElement.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* -*- 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 the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Holbert <dholbert@mozilla.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"),
|
||||
* 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 NS_SVGANIMATEMOTIONELEMENT_H_
|
||||
#define NS_SVGANIMATEMOTIONELEMENT_H_
|
||||
|
||||
#include "nsSVGAnimationElement.h"
|
||||
#include "nsIDOMSVGAnimateMotionElement.h"
|
||||
#include "nsSVGEnum.h"
|
||||
#include "SVGMotionSMILAnimationFunction.h"
|
||||
|
||||
typedef nsSVGAnimationElement nsSVGAnimateMotionElementBase;
|
||||
|
||||
class nsSVGAnimateMotionElement : public nsSVGAnimateMotionElementBase,
|
||||
public nsIDOMSVGAnimateMotionElement
|
||||
{
|
||||
protected:
|
||||
friend nsresult NS_NewSVGAnimateMotionElement(nsIContent **aResult,
|
||||
nsINodeInfo *aNodeInfo);
|
||||
nsSVGAnimateMotionElement(nsINodeInfo* aNodeInfo);
|
||||
|
||||
mozilla::SVGMotionSMILAnimationFunction mAnimationFunction;
|
||||
|
||||
public:
|
||||
// interfaces:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOMSVGANIMATEMOTIONELEMENT
|
||||
|
||||
NS_FORWARD_NSIDOMNODE(nsSVGAnimateMotionElementBase::)
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGAnimateMotionElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAnimateMotionElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGANIMATIONELEMENT(nsSVGAnimateMotionElementBase::)
|
||||
|
||||
// nsIDOMNode specializations
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
// nsISMILAnimationElement
|
||||
virtual nsSMILAnimationFunction& AnimationFunction();
|
||||
virtual nsIAtom* GetTargetAttributeName() const;
|
||||
virtual nsSMILTargetAttrType GetTargetAttributeType() const;
|
||||
|
||||
// Utility method to let our <mpath> children tell us when they've changed,
|
||||
// so we can make sure our mAnimationFunction is marked as having changed.
|
||||
void MpathChanged() { mAnimationFunction.MpathChanged(); }
|
||||
};
|
||||
|
||||
#endif // NS_SVGANIMATEMOTIONELEMENT_H_
|
@ -172,6 +172,8 @@ NS_NewSVGAnimateTransformElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
||||
nsresult
|
||||
NS_NewSVGAnimateMotionElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
||||
nsresult
|
||||
NS_NewSVGMpathElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
||||
nsresult
|
||||
NS_NewSVGSetElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
@ -313,6 +315,8 @@ NS_NewSVGElement(nsIContent** aResult, nsINodeInfo *aNodeInfo,
|
||||
return NS_NewSVGAnimateTransformElement(aResult, aNodeInfo);
|
||||
if (name == nsGkAtoms::animateMotion)
|
||||
return NS_NewSVGAnimateMotionElement(aResult, aNodeInfo);
|
||||
if (name == nsGkAtoms::mpath)
|
||||
return NS_NewSVGMpathElement(aResult, aNodeInfo);
|
||||
if (name == nsGkAtoms::set)
|
||||
return NS_NewSVGSetElement(aResult, aNodeInfo);
|
||||
}
|
||||
|
296
content/svg/content/src/nsSVGMpathElement.cpp
Normal file
296
content/svg/content/src/nsSVGMpathElement.cpp
Normal file
@ -0,0 +1,296 @@
|
||||
/* -*- 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 the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Holbert <dholbert@mozilla.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"),
|
||||
* 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 "nsSVGMpathElement.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsSVGPathElement.h"
|
||||
#include "nsSVGAnimateMotionElement.h"
|
||||
|
||||
nsSVGElement::StringInfo nsSVGMpathElement::sStringInfo[1] =
|
||||
{
|
||||
{ &nsGkAtoms::href, kNameSpaceID_XLink },
|
||||
};
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(Mpath)
|
||||
|
||||
// Cycle collection magic -- based on nsSVGUseElement
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsSVGMpathElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsSVGMpathElement,
|
||||
nsSVGMpathElementBase)
|
||||
tmp->UnlinkHrefTarget(PR_FALSE);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsSVGMpathElement,
|
||||
nsSVGMpathElementBase)
|
||||
tmp->mHrefTarget.Traverse(&cb);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISupports methods
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsSVGMpathElement,nsSVGMpathElementBase)
|
||||
NS_IMPL_RELEASE_INHERITED(nsSVGMpathElement,nsSVGMpathElementBase)
|
||||
|
||||
DOMCI_DATA(SVGMpathElement, nsSVGMpathElement)
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsSVGMpathElement)
|
||||
NS_NODE_INTERFACE_TABLE6(nsSVGMpathElement, nsIDOMNode, nsIDOMElement,
|
||||
nsIDOMSVGElement, nsIDOMSVGURIReference,
|
||||
nsIDOMSVGMpathElement, nsIMutationObserver)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGMpathElement)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsSVGMpathElementBase)
|
||||
|
||||
// Constructor
|
||||
#ifdef _MSC_VER
|
||||
// Disable "warning C4355: 'this' : used in base member initializer list".
|
||||
// We can ignore that warning because we know that mHrefTarget's constructor
|
||||
// doesn't dereference the pointer passed to it.
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4355)
|
||||
#endif
|
||||
nsSVGMpathElement::nsSVGMpathElement(nsINodeInfo* aNodeInfo)
|
||||
: nsSVGMpathElementBase(aNodeInfo),
|
||||
mHrefTarget(this)
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
nsSVGMpathElement::~nsSVGMpathElement()
|
||||
{
|
||||
UnlinkHrefTarget(PR_FALSE);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMNode methods
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGMpathElement)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMSVGURIReference methods
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedString href; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGMpathElement::GetHref(nsIDOMSVGAnimatedString** aHref)
|
||||
{
|
||||
return mStringAttributes[HREF].ToDOMAnimatedString(aHref, this);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIContent methods
|
||||
|
||||
nsresult
|
||||
nsSVGMpathElement::BindToTree(nsIDocument* aDocument,
|
||||
nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!mHrefTarget.get(),
|
||||
"Shouldn't have href-target yet "
|
||||
"(or it should've been cleared)");
|
||||
nsresult rv = nsSVGMpathElementBase::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (aDocument) {
|
||||
const nsAttrValue* hrefAttrValue =
|
||||
mAttrsAndChildren.GetAttr(nsGkAtoms::href, kNameSpaceID_XLink);
|
||||
if (hrefAttrValue) {
|
||||
UpdateHrefTarget(aParent, hrefAttrValue->GetStringValue());
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGMpathElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
UnlinkHrefTarget(PR_TRUE);
|
||||
nsSVGMpathElementBase::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGMpathElement::ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
PRBool returnVal =
|
||||
nsSVGMpathElementBase::ParseAttribute(aNamespaceID, aAttribute,
|
||||
aValue, aResult);
|
||||
if (aNamespaceID == kNameSpaceID_XLink &&
|
||||
aAttribute == nsGkAtoms::href &&
|
||||
IsInDoc()) {
|
||||
// NOTE: If we fail the IsInDoc call, it's ok -- we'll update the target
|
||||
// on next BindToTree call.
|
||||
UpdateHrefTarget(GetParent(), aValue);
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGMpathElement::UnsetAttr(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute, PRBool aNotify)
|
||||
{
|
||||
nsresult rv = nsSVGMpathElementBase::UnsetAttr(aNamespaceID, aAttribute,
|
||||
aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_XLink &&
|
||||
aAttribute == nsGkAtoms::href) {
|
||||
UnlinkHrefTarget(PR_TRUE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGElement methods
|
||||
|
||||
nsSVGElement::StringAttributesInfo
|
||||
nsSVGMpathElement::GetStringInfo()
|
||||
{
|
||||
return StringAttributesInfo(mStringAttributes, sStringInfo,
|
||||
NS_ARRAY_LENGTH(sStringInfo));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIMutationObserver methods
|
||||
|
||||
void
|
||||
nsSVGMpathElement::AttributeChanged(nsIDocument *aDocument,
|
||||
nsIContent *aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom *aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aAttribute == nsGkAtoms::d) {
|
||||
NotifyParentOfMpathChange(GetParent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Public helper methods
|
||||
|
||||
nsSVGPathElement*
|
||||
nsSVGMpathElement::GetReferencedPath()
|
||||
{
|
||||
if (!HasAttr(kNameSpaceID_XLink, nsGkAtoms::href)) {
|
||||
NS_ABORT_IF_FALSE(!mHrefTarget.get(),
|
||||
"We shouldn't have an xlink:href target "
|
||||
"if we don't have an xlink:href attribute");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIContent* genericTarget = mHrefTarget.get();
|
||||
if (genericTarget &&
|
||||
genericTarget->Tag() == nsGkAtoms::path) {
|
||||
return static_cast<nsSVGPathElement*>(genericTarget);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Protected helper methods
|
||||
|
||||
void
|
||||
nsSVGMpathElement::UpdateHrefTarget(nsIContent* aParent,
|
||||
const nsAString& aHrefStr)
|
||||
{
|
||||
nsCOMPtr<nsIURI> targetURI;
|
||||
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI),
|
||||
aHrefStr, GetOwnerDoc(), baseURI);
|
||||
|
||||
// Stop observing old target (if any)
|
||||
if (mHrefTarget.get()) {
|
||||
mHrefTarget.get()->RemoveMutationObserver(this);
|
||||
}
|
||||
|
||||
if (aParent) {
|
||||
// Pass in |aParent| instead of |this| -- first argument is only used
|
||||
// for a call to GetCurrentDoc(), and |this| might not have a current
|
||||
// document yet (if our caller is BindToTree).
|
||||
mHrefTarget.Reset(aParent, targetURI);
|
||||
} else {
|
||||
// if we don't have a parent, then there's no animateMotion element
|
||||
// depending on our target, so there's no point tracking it right now.
|
||||
mHrefTarget.Unlink();
|
||||
}
|
||||
|
||||
// Start observing new target (if any)
|
||||
if (mHrefTarget.get()) {
|
||||
mHrefTarget.get()->AddMutationObserver(this);
|
||||
}
|
||||
|
||||
NotifyParentOfMpathChange(aParent);
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGMpathElement::UnlinkHrefTarget(PRBool aNotifyParent)
|
||||
{
|
||||
// Stop observing old target (if any)
|
||||
if (mHrefTarget.get()) {
|
||||
mHrefTarget.get()->RemoveMutationObserver(this);
|
||||
}
|
||||
mHrefTarget.Unlink();
|
||||
|
||||
if (aNotifyParent) {
|
||||
NotifyParentOfMpathChange(GetParent());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGMpathElement::NotifyParentOfMpathChange(nsIContent* aParent)
|
||||
{
|
||||
if (aParent &&
|
||||
aParent->GetNameSpaceID() == kNameSpaceID_SVG &&
|
||||
aParent->Tag() == nsGkAtoms::animateMotion) {
|
||||
|
||||
nsSVGAnimateMotionElement* animateMotionParent =
|
||||
static_cast<nsSVGAnimateMotionElement*>(aParent);
|
||||
|
||||
animateMotionParent->MpathChanged();
|
||||
AnimationNeedsResample();
|
||||
}
|
||||
}
|
139
content/svg/content/src/nsSVGMpathElement.h
Normal file
139
content/svg/content/src/nsSVGMpathElement.h
Normal file
@ -0,0 +1,139 @@
|
||||
/* -*- 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 the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Holbert <dholbert@mozilla.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"),
|
||||
* 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 NS_SVGMPATHELEMENT_H_
|
||||
#define NS_SVGMPATHELEMENT_H_
|
||||
|
||||
#include "nsIDOMSVGMpathElement.h"
|
||||
#include "nsIDOMSVGURIReference.h"
|
||||
#include "nsSVGElement.h"
|
||||
#include "nsStubMutationObserver.h"
|
||||
#include "nsSVGPathElement.h"
|
||||
#include "nsSVGString.h"
|
||||
#include "nsReferencedElement.h"
|
||||
|
||||
|
||||
typedef nsSVGElement nsSVGMpathElementBase;
|
||||
|
||||
class nsSVGMpathElement : public nsSVGMpathElementBase,
|
||||
public nsIDOMSVGMpathElement,
|
||||
public nsIDOMSVGURIReference,
|
||||
public nsStubMutationObserver
|
||||
{
|
||||
protected:
|
||||
friend nsresult NS_NewSVGMpathElement(nsIContent **aResult,
|
||||
nsINodeInfo *aNodeInfo);
|
||||
nsSVGMpathElement(nsINodeInfo* aNodeInfo);
|
||||
~nsSVGMpathElement();
|
||||
|
||||
|
||||
public:
|
||||
// interfaces:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOMSVGMPATHELEMENT
|
||||
NS_DECL_NSIDOMSVGURIREFERENCE
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsSVGMpathElement,
|
||||
nsSVGMpathElementBase)
|
||||
|
||||
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
|
||||
|
||||
// Forward interface implementations to base class
|
||||
NS_FORWARD_NSIDOMNODE(nsSVGMpathElementBase::)
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGMpathElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGMpathElementBase::)
|
||||
|
||||
// nsIContent interface
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep, PRBool aNullParent);
|
||||
|
||||
virtual nsresult UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify);
|
||||
// nsGenericElement specializations
|
||||
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
// Public helper method: If our xlink:href attribute links to a <path>
|
||||
// element, this method returns a pointer to that element. Otherwise,
|
||||
// this returns nsnull.
|
||||
nsSVGPathElement* GetReferencedPath();
|
||||
|
||||
protected:
|
||||
class PathReference : public nsReferencedElement {
|
||||
public:
|
||||
PathReference(nsSVGMpathElement* aMpathElement) :
|
||||
mMpathElement(aMpathElement) {}
|
||||
protected:
|
||||
// We need to be notified when target changes, in order to request a sample
|
||||
// (which will clear animation effects that used the old target-path
|
||||
// and recompute the animation effects using the new target-path).
|
||||
virtual void ContentChanged(nsIContent* aFrom, nsIContent* aTo) {
|
||||
nsReferencedElement::ContentChanged(aFrom, aTo);
|
||||
if (aFrom) {
|
||||
aFrom->RemoveMutationObserver(mMpathElement);
|
||||
}
|
||||
if (aTo) {
|
||||
aTo->AddMutationObserver(mMpathElement);
|
||||
}
|
||||
mMpathElement->NotifyParentOfMpathChange(mMpathElement->GetParent());
|
||||
}
|
||||
|
||||
// We need to override IsPersistent to get persistent tracking (beyond the
|
||||
// first time the target changes)
|
||||
virtual PRBool IsPersistent() { return PR_TRUE; }
|
||||
private:
|
||||
nsSVGMpathElement* const mMpathElement;
|
||||
};
|
||||
|
||||
virtual StringAttributesInfo GetStringInfo();
|
||||
|
||||
void UpdateHrefTarget(nsIContent* aParent, const nsAString& aHrefStr);
|
||||
void UnlinkHrefTarget(PRBool aNotifyParent);
|
||||
void NotifyParentOfMpathChange(nsIContent* aParent);
|
||||
|
||||
enum { HREF };
|
||||
nsSVGString mStringAttributes[1];
|
||||
static StringInfo sStringInfo[1];
|
||||
PathReference mHrefTarget;
|
||||
};
|
||||
|
||||
#endif // NS_SVGMPATHELEMENT_H_
|
@ -373,6 +373,7 @@
|
||||
#include "nsIDOMSVGAnimateElement.h"
|
||||
#include "nsIDOMSVGAnimateTransformElement.h"
|
||||
#include "nsIDOMSVGAnimateMotionElement.h"
|
||||
#include "nsIDOMSVGMpathElement.h"
|
||||
#include "nsIDOMSVGSetElement.h"
|
||||
#include "nsIDOMSVGAnimationElement.h"
|
||||
#include "nsIDOMElementTimeControl.h"
|
||||
@ -971,6 +972,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(SVGAnimateMotionElement, nsElementSH,
|
||||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(SVGMpathElement, nsElementSH,
|
||||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(SVGSetElement, nsElementSH,
|
||||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
#endif // MOZ_SMIL
|
||||
@ -2927,6 +2930,12 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementTimeControl)
|
||||
DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(SVGMpathElement, nsIDOMSVGMpathElement)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
|
||||
DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(SVGCircleElement, nsIDOMSVGCircleElement)
|
||||
|
@ -236,6 +236,7 @@ DOMCI_CLASS(SVGAltGlyphElement)
|
||||
DOMCI_CLASS(SVGAnimateElement)
|
||||
DOMCI_CLASS(SVGAnimateTransformElement)
|
||||
DOMCI_CLASS(SVGAnimateMotionElement)
|
||||
DOMCI_CLASS(SVGMpathElement)
|
||||
DOMCI_CLASS(SVGSetElement)
|
||||
#endif // MOZ_SMIL
|
||||
DOMCI_CLASS(SVGCircleElement)
|
||||
|
@ -135,6 +135,7 @@ XPIDLSRCS += \
|
||||
nsIDOMSVGAnimateTransformElement.idl \
|
||||
nsIDOMSVGAnimateMotionElement.idl \
|
||||
nsIDOMSVGAnimationElement.idl \
|
||||
nsIDOMSVGMpathElement.idl \
|
||||
nsIDOMSVGSetElement.idl \
|
||||
$(NULL)
|
||||
endif
|
||||
|
60
dom/interfaces/svg/nsIDOMSVGMpathElement.idl
Normal file
60
dom/interfaces/svg/nsIDOMSVGMpathElement.idl
Normal file
@ -0,0 +1,60 @@
|
||||
/* -*- Mode: IDL; 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
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Holbert <dholbert@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either 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 "nsIDOMSVGElement.idl"
|
||||
|
||||
/**
|
||||
* For more information on this interface please see
|
||||
* http://www.w3.org/TR/SVG/animate.html#mpathElement
|
||||
*/
|
||||
|
||||
[scriptable, uuid(752f5ec1-eaf6-4cfa-887b-96bc69ec36b8)]
|
||||
interface nsIDOMSVGMpathElement
|
||||
: nsIDOMSVGElement
|
||||
/*
|
||||
The SVG DOM makes use of multiple interface inheritance.
|
||||
Since XPCOM only supports single interface inheritance,
|
||||
the best thing that we can do is to promise that whenever
|
||||
an object implements _this_ interface it will also
|
||||
implement the following interfaces. (We then have to QI to
|
||||
hop between them.)
|
||||
nsIDOMSVGURIReference,
|
||||
nsIDOMSVGExternalResourcesRequired,
|
||||
*/
|
||||
{
|
||||
};
|
Loading…
Reference in New Issue
Block a user