SMILTimeValueSpec.h (4944B)
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_SMIL_SMILTIMEVALUESPEC_H_ 8 #define DOM_SMIL_SMILTIMEVALUESPEC_H_ 9 10 #include "mozilla/SMILTimeValueSpecParams.h" 11 #include "mozilla/dom/IDTracker.h" 12 #include "nsIDOMEventListener.h" 13 #include "nsStringFwd.h" 14 15 // XXX Avoid including this here by moving function bodies to the cpp file 16 #include "mozilla/dom/Element.h" 17 18 namespace mozilla { 19 20 class EventListenerManager; 21 class SMILInstanceTime; 22 class SMILInterval; 23 class SMILTimeContainer; 24 class SMILTimedElement; 25 class SMILTimeValue; 26 27 namespace dom { 28 class Event; 29 } // namespace dom 30 31 //---------------------------------------------------------------------- 32 // SMILTimeValueSpec class 33 // 34 // An individual element of a 'begin' or 'end' attribute, e.g. '5s', 'a.end'. 35 // This class handles the parsing of such specifications and performs the 36 // necessary event handling (for event and repeat specifications) 37 // and synchronisation (for syncbase specifications). 38 // 39 // For an overview of how this class is related to other SMIL time classes see 40 // the documentation in SMILTimeValue.h 41 42 class SMILTimeValueSpec { 43 public: 44 using Element = dom::Element; 45 using Event = dom::Event; 46 using IDTracker = dom::IDTracker; 47 48 SMILTimeValueSpec(SMILTimedElement& aOwner, bool aIsBegin); 49 ~SMILTimeValueSpec(); 50 51 nsresult SetSpec(const nsAString& aStringSpec, Element& aContextElement); 52 void ResolveReferences(Element& aContextElement); 53 bool IsEventBased() const; 54 55 void HandleNewInterval(SMILInterval& aInterval, 56 const SMILTimeContainer* aSrcContainer); 57 void HandleTargetElementChange(Element* aNewTarget); 58 59 // For created SMILInstanceTime objects 60 bool DependsOnBegin() const; 61 void HandleChangedInstanceTime(const SMILInstanceTime& aBaseTime, 62 const SMILTimeContainer* aSrcContainer, 63 SMILInstanceTime& aInstanceTimeToUpdate, 64 bool aObjectChanged); 65 void HandleDeletedInstanceTime(SMILInstanceTime& aInstanceTime); 66 67 // Cycle-collection support 68 void Traverse(nsCycleCollectionTraversalCallback* aCallback); 69 void Unlink(); 70 71 protected: 72 void UpdateReferencedElement(Element* aFrom, Element* aTo); 73 void UnregisterFromReferencedElement(Element* aElement); 74 SMILTimedElement* GetTimedElement(Element* aElement); 75 bool IsEventAllowedWhenScriptingIsDisabled(); 76 void RegisterEventListener(Element* aTarget); 77 void UnregisterEventListener(Element* aTarget); 78 void HandleEvent(Event* aEvent); 79 bool CheckRepeatEventDetail(Event* aEvent); 80 SMILTimeValue ConvertBetweenTimeContainers( 81 const SMILTimeValue& aSrcTime, const SMILTimeContainer* aSrcContainer); 82 bool ApplyOffset(SMILTimeValue& aTime) const; 83 84 SMILTimedElement* mOwner; 85 bool mIsBegin; // Indicates if *we* are a begin spec, 86 // not to be confused with 87 // mParams.mSyncBegin which indicates 88 // if we're synced with the begin of 89 // the target. 90 SMILTimeValueSpecParams mParams; 91 92 /** 93 * If our SMILTimeValueSpec exists for a 'begin' or 'end' attribute with a 94 * value that specifies a time that is relative to the animation of some 95 * other element, it will create an instance of this class to reference and 96 * track that other element. For example, if the SMILTimeValueSpec is for 97 * end='a.end+2s', an instance of this class will be created to track the 98 * element associated with the element ID "a". This class will notify the 99 * SMILTimeValueSpec if the element that that ID identifies changes to a 100 * different element (or none). 101 */ 102 class TimeReferenceTracker final : public IDTracker { 103 public: 104 explicit TimeReferenceTracker(SMILTimeValueSpec* aOwner) : mSpec(aOwner) {} 105 void ResetWithElement(Element* aTo) { 106 RefPtr<Element> from = get(); 107 Unlink(); 108 ElementChanged(from, aTo); 109 } 110 111 protected: 112 void ElementChanged(Element* aFrom, Element* aTo) override { 113 IDTracker::ElementChanged(aFrom, aTo); 114 mSpec->UpdateReferencedElement(aFrom, aTo); 115 } 116 bool IsPersistent() override { return true; } 117 118 private: 119 SMILTimeValueSpec* mSpec; 120 }; 121 122 TimeReferenceTracker mReferencedElement; 123 124 class EventListener final : public nsIDOMEventListener { 125 ~EventListener() {} 126 127 public: 128 explicit EventListener(SMILTimeValueSpec* aOwner) : mSpec(aOwner) {} 129 void Disconnect() { mSpec = nullptr; } 130 131 NS_DECL_ISUPPORTS 132 NS_DECL_NSIDOMEVENTLISTENER 133 134 private: 135 SMILTimeValueSpec* mSpec; 136 }; 137 RefPtr<EventListener> mEventListener; 138 }; 139 140 } // namespace mozilla 141 142 #endif // DOM_SMIL_SMILTIMEVALUESPEC_H_