SVGAnimationElement.h (5457B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef DOM_SVG_SVGANIMATIONELEMENT_H_ 8 #define DOM_SVG_SVGANIMATIONELEMENT_H_ 9 10 #include "mozilla/SMILTimedElement.h" 11 #include "mozilla/dom/IDTracker.h" 12 #include "mozilla/dom/SVGElement.h" 13 #include "mozilla/dom/SVGTests.h" 14 15 namespace mozilla::dom { 16 17 using SVGAnimationElementBase = SVGElement; 18 19 class SVGAnimationElement : public SVGAnimationElementBase, public SVGTests { 20 protected: 21 explicit SVGAnimationElement( 22 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo); 23 nsresult Init(); 24 virtual ~SVGAnimationElement() = default; 25 26 public: 27 // interfaces: 28 NS_DECL_ISUPPORTS_INHERITED 29 30 NS_IMPL_FROMNODE_HELPER(SVGAnimationElement, IsSVGAnimationElement()) 31 32 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGAnimationElement, 33 SVGAnimationElementBase) 34 35 bool IsSVGAnimationElement() const final { return true; } 36 bool PassesConditionalProcessingTests() const final { 37 return SVGTests::PassesConditionalProcessingTests(); 38 } 39 nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override = 0; 40 41 // nsIContent specializations 42 nsresult BindToTree(BindContext&, nsINode& aParent) override; 43 void UnbindFromTree(UnbindContext&) override; 44 45 // Element specializations 46 bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute, 47 const nsAString& aValue, 48 nsIPrincipal* aMaybeScriptedPrincipal, 49 nsAttrValue& aResult) override; 50 void AfterSetAttr(int32_t aNamespaceID, nsAtom* aName, 51 const nsAttrValue* aValue, const nsAttrValue* aOldValue, 52 nsIPrincipal* aSubjectPrincipal, bool aNotify) override; 53 54 Element* GetTargetElementContent(); 55 virtual bool GetTargetAttributeName(int32_t* aNamespaceID, 56 nsAtom** aLocalName) const; 57 mozilla::SMILTimedElement& TimedElement(); 58 mozilla::SMILTimeContainer* GetTimeContainer(); 59 virtual SMILAnimationFunction& AnimationFunction() = 0; 60 61 bool IsEventAttributeNameInternal(nsAtom* aName) override; 62 63 // Utility methods for within SVG 64 void ActivateByHyperlink(); 65 66 bool IsDisabled(); 67 68 // WebIDL 69 SVGElement* GetTargetElement(); 70 float GetStartTime(ErrorResult& rv); 71 float GetCurrentTimeAsFloat(); 72 float GetSimpleDuration(ErrorResult& aRv); 73 void BeginElement(ErrorResult& aRv) { BeginElementAt(0.f, aRv); } 74 void BeginElementAt(float offset, ErrorResult& aRv); 75 void EndElement(ErrorResult& aRv) { EndElementAt(0.f, aRv); } 76 void EndElementAt(float offset, ErrorResult& aRv); 77 78 // Manually implement onbegin/onrepeat/onend IDL property getters/setters. 79 // We don't autogenerate these methods because the property name differs 80 // from the event type atom - the event type atom has an extra 'Event' tacked 81 // on at the end. (i.e. 'onbegin' corresponds to an event whose name is 82 // literally 'beginEvent' rather than 'begin') 83 84 EventHandlerNonNull* GetOnbegin() { 85 return GetEventHandler(nsGkAtoms::onbeginEvent); 86 } 87 void SetOnbegin(EventHandlerNonNull* handler) { 88 EventTarget::SetEventHandler(nsGkAtoms::onbeginEvent, handler); 89 } 90 91 EventHandlerNonNull* GetOnrepeat() { 92 return GetEventHandler(nsGkAtoms::onrepeatEvent); 93 } 94 void SetOnrepeat(EventHandlerNonNull* handler) { 95 EventTarget::SetEventHandler(nsGkAtoms::onrepeatEvent, handler); 96 } 97 98 EventHandlerNonNull* GetOnend() { 99 return GetEventHandler(nsGkAtoms::onendEvent); 100 } 101 void SetOnend(EventHandlerNonNull* handler) { 102 EventTarget::SetEventHandler(nsGkAtoms::onendEvent, handler); 103 } 104 105 // SVGTests 106 SVGElement* AsSVGElement() final { return this; } 107 108 protected: 109 // SVGElement overrides 110 111 void UpdateHrefTarget(const nsAString& aHrefStr); 112 void AnimationTargetChanged(); 113 114 /** 115 * Helper that provides a reference to the element with the ID that is 116 * referenced by the animation element's 'href' attribute, if any, and that 117 * will notify the animation element if the element that that ID identifies 118 * changes to a different element (or none). (If the 'href' attribute is not 119 * specified, then the animation target is the parent element and this helper 120 * is not used.) 121 */ 122 class HrefTargetTracker final : public IDTracker { 123 public: 124 explicit HrefTargetTracker(SVGAnimationElement* aAnimationElement) 125 : mAnimationElement(aAnimationElement) {} 126 127 protected: 128 // We need to be notified when target changes, in order to request a 129 // sample (which will clear animation effects from old target and apply 130 // them to the new target) and update any event registrations. 131 void ElementChanged(Element* aFrom, Element* aTo) override { 132 IDTracker::ElementChanged(aFrom, aTo); 133 mAnimationElement->AnimationTargetChanged(); 134 } 135 136 // We need to override IsPersistent to get persistent tracking (beyond the 137 // first time the target changes) 138 bool IsPersistent() override { return true; } 139 140 private: 141 SVGAnimationElement* const mAnimationElement; 142 }; 143 144 HrefTargetTracker mHrefTarget; 145 mozilla::SMILTimedElement mTimedElement; 146 }; 147 148 } // namespace mozilla::dom 149 150 #endif // DOM_SVG_SVGANIMATIONELEMENT_H_