michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef NS_SMILTIMEVALUESPEC_H_ michael@0: #define NS_SMILTIMEVALUESPEC_H_ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "nsSMILTimeValueSpecParams.h" michael@0: #include "nsReferencedElement.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsIDOMEventListener.h" michael@0: michael@0: class nsAString; michael@0: class nsSMILTimeValue; michael@0: class nsSMILTimedElement; michael@0: class nsSMILTimeContainer; michael@0: class nsSMILInstanceTime; michael@0: class nsSMILInterval; michael@0: michael@0: namespace mozilla { michael@0: class EventListenerManager; michael@0: } // namespace mozilla michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // nsSMILTimeValueSpec class michael@0: // michael@0: // An individual element of a 'begin' or 'end' attribute, e.g. '5s', 'a.end'. michael@0: // This class handles the parsing of such specifications and performs the michael@0: // necessary event handling (for event, repeat, and accesskey specifications) michael@0: // and synchronisation (for syncbase specifications). michael@0: // michael@0: // For an overview of how this class is related to other SMIL time classes see michael@0: // the documentation in nsSMILTimeValue.h michael@0: michael@0: class nsSMILTimeValueSpec michael@0: { michael@0: public: michael@0: typedef mozilla::dom::Element Element; michael@0: michael@0: nsSMILTimeValueSpec(nsSMILTimedElement& aOwner, bool aIsBegin); michael@0: ~nsSMILTimeValueSpec(); michael@0: michael@0: nsresult SetSpec(const nsAString& aStringSpec, Element* aContextNode); michael@0: void ResolveReferences(nsIContent* aContextNode); michael@0: bool IsEventBased() const; michael@0: michael@0: void HandleNewInterval(nsSMILInterval& aInterval, michael@0: const nsSMILTimeContainer* aSrcContainer); michael@0: void HandleTargetElementChange(Element* aNewTarget); michael@0: michael@0: // For created nsSMILInstanceTime objects michael@0: bool DependsOnBegin() const; michael@0: void HandleChangedInstanceTime(const nsSMILInstanceTime& aBaseTime, michael@0: const nsSMILTimeContainer* aSrcContainer, michael@0: nsSMILInstanceTime& aInstanceTimeToUpdate, michael@0: bool aObjectChanged); michael@0: void HandleDeletedInstanceTime(nsSMILInstanceTime& aInstanceTime); michael@0: michael@0: // Cycle-collection support michael@0: void Traverse(nsCycleCollectionTraversalCallback* aCallback); michael@0: void Unlink(); michael@0: michael@0: protected: michael@0: void UpdateReferencedElement(Element* aFrom, Element* aTo); michael@0: void UnregisterFromReferencedElement(Element* aElement); michael@0: nsSMILTimedElement* GetTimedElement(Element* aElement); michael@0: bool IsWhitelistedEvent(); michael@0: void RegisterEventListener(Element* aElement); michael@0: void UnregisterEventListener(Element* aElement); michael@0: mozilla::EventListenerManager* GetEventListenerManager(Element* aElement); michael@0: void HandleEvent(nsIDOMEvent* aEvent); michael@0: bool CheckEventDetail(nsIDOMEvent* aEvent); michael@0: bool CheckRepeatEventDetail(nsIDOMEvent* aEvent); michael@0: bool CheckAccessKeyEventDetail(nsIDOMEvent* aEvent); michael@0: nsSMILTimeValue ConvertBetweenTimeContainers(const nsSMILTimeValue& aSrcTime, michael@0: const nsSMILTimeContainer* aSrcContainer); michael@0: bool ApplyOffset(nsSMILTimeValue& aTime) const; michael@0: michael@0: nsSMILTimedElement* mOwner; michael@0: bool mIsBegin; // Indicates if *we* are a begin spec, michael@0: // not to be confused with michael@0: // mParams.mSyncBegin which indicates michael@0: // if we're synced with the begin of michael@0: // the target. michael@0: nsSMILTimeValueSpecParams mParams; michael@0: michael@0: class TimeReferenceElement : public nsReferencedElement michael@0: { michael@0: public: michael@0: TimeReferenceElement(nsSMILTimeValueSpec* aOwner) : mSpec(aOwner) { } michael@0: void ResetWithElement(Element* aTo) { michael@0: nsRefPtr from = get(); michael@0: Unlink(); michael@0: ElementChanged(from, aTo); michael@0: } michael@0: michael@0: protected: michael@0: virtual void ElementChanged(Element* aFrom, Element* aTo) MOZ_OVERRIDE michael@0: { michael@0: nsReferencedElement::ElementChanged(aFrom, aTo); michael@0: mSpec->UpdateReferencedElement(aFrom, aTo); michael@0: } michael@0: virtual bool IsPersistent() MOZ_OVERRIDE { return true; } michael@0: private: michael@0: nsSMILTimeValueSpec* mSpec; michael@0: }; michael@0: michael@0: TimeReferenceElement mReferencedElement; michael@0: michael@0: class EventListener MOZ_FINAL : public nsIDOMEventListener michael@0: { michael@0: public: michael@0: EventListener(nsSMILTimeValueSpec* aOwner) : mSpec(aOwner) { } michael@0: void Disconnect() michael@0: { michael@0: mSpec = nullptr; michael@0: } michael@0: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIDOMEVENTLISTENER michael@0: michael@0: private: michael@0: nsSMILTimeValueSpec* mSpec; michael@0: }; michael@0: nsRefPtr mEventListener; michael@0: }; michael@0: michael@0: #endif // NS_SMILTIMEVALUESPEC_H_