diff options
Diffstat (limited to 'dom/media/webvtt/TextTrackCue.h')
-rw-r--r-- | dom/media/webvtt/TextTrackCue.h | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/dom/media/webvtt/TextTrackCue.h b/dom/media/webvtt/TextTrackCue.h new file mode 100644 index 0000000000..90ce0a571d --- /dev/null +++ b/dom/media/webvtt/TextTrackCue.h @@ -0,0 +1,342 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 et tw=78: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_TextTrackCue_h +#define mozilla_dom_TextTrackCue_h + +#include "mozilla/DOMEventTargetHelper.h" +#include "mozilla/dom/DocumentFragment.h" +#include "mozilla/dom/VTTCueBinding.h" +#include "nsCycleCollectionParticipant.h" +#include "nsIWebVTTParserWrapper.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/dom/HTMLDivElement.h" +#include "mozilla/dom/TextTrack.h" +#include "mozilla/StateWatching.h" + +namespace mozilla::dom { + +class Document; +class HTMLTrackElement; +class TextTrackRegion; + +class TextTrackCue final : public DOMEventTargetHelper { + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TextTrackCue, DOMEventTargetHelper) + + // TextTrackCue WebIDL + // See bug 868509 about splitting out the WebVTT-specific interfaces. + static already_AddRefed<TextTrackCue> Constructor(GlobalObject& aGlobal, + double aStartTime, + double aEndTime, + const nsAString& aText, + ErrorResult& aRv) { + nsCOMPtr<nsPIDOMWindowInner> window = + do_QueryInterface(aGlobal.GetAsSupports()); + RefPtr<TextTrackCue> ttcue = + new TextTrackCue(window, aStartTime, aEndTime, aText, aRv); + return ttcue.forget(); + } + TextTrackCue(nsPIDOMWindowInner* aGlobal, double aStartTime, double aEndTime, + const nsAString& aText, ErrorResult& aRv); + + TextTrackCue(nsPIDOMWindowInner* aGlobal, double aStartTime, double aEndTime, + const nsAString& aText, HTMLTrackElement* aTrackElement, + ErrorResult& aRv); + + JSObject* WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) override; + + TextTrack* GetTrack() const { return mTrack; } + + void GetId(nsAString& aId) const { aId = mId; } + + void SetId(const nsAString& aId) { + if (mId == aId) { + return; + } + + mId = aId; + } + + double StartTime() const { return mStartTime; } + + void SetStartTime(double aStartTime) { + if (mStartTime == aStartTime) { + return; + } + + mStartTime = aStartTime; + mReset = true; + NotifyCueUpdated(this); + } + + double EndTime() const { return mEndTime; } + + void SetEndTime(double aEndTime) { + if (mEndTime == aEndTime) { + return; + } + + mEndTime = aEndTime; + mReset = true; + NotifyCueUpdated(this); + } + + bool PauseOnExit() { return mPauseOnExit; } + + void SetPauseOnExit(bool aPauseOnExit) { + if (mPauseOnExit == aPauseOnExit) { + return; + } + + mPauseOnExit = aPauseOnExit; + NotifyCueUpdated(nullptr); + } + + TextTrackRegion* GetRegion(); + void SetRegion(TextTrackRegion* aRegion); + + DirectionSetting Vertical() const { return mVertical; } + + void SetVertical(const DirectionSetting& aVertical) { + if (mVertical == aVertical) { + return; + } + + mReset = true; + mVertical = aVertical; + } + + bool SnapToLines() { return mSnapToLines; } + + void SetSnapToLines(bool aSnapToLines) { + if (mSnapToLines == aSnapToLines) { + return; + } + + mReset = true; + mSnapToLines = aSnapToLines; + } + + void GetLine(OwningDoubleOrAutoKeyword& aLine) const { + if (mLineIsAutoKeyword) { + aLine.SetAsAutoKeyword() = AutoKeyword::Auto; + return; + } + aLine.SetAsDouble() = mLine; + } + + void SetLine(const DoubleOrAutoKeyword& aLine) { + if (aLine.IsDouble() && + (mLineIsAutoKeyword || (aLine.GetAsDouble() != mLine))) { + mLineIsAutoKeyword = false; + mLine = aLine.GetAsDouble(); + mReset = true; + return; + } + if (aLine.IsAutoKeyword() && !mLineIsAutoKeyword) { + mLineIsAutoKeyword = true; + mReset = true; + } + } + + LineAlignSetting LineAlign() const { return mLineAlign; } + + void SetLineAlign(LineAlignSetting& aLineAlign, ErrorResult& aRv) { + if (mLineAlign == aLineAlign) { + return; + } + + mReset = true; + mLineAlign = aLineAlign; + } + + void GetPosition(OwningDoubleOrAutoKeyword& aPosition) const { + if (mPositionIsAutoKeyword) { + aPosition.SetAsAutoKeyword() = AutoKeyword::Auto; + return; + } + aPosition.SetAsDouble() = mPosition; + } + + void SetPosition(const DoubleOrAutoKeyword& aPosition, ErrorResult& aRv) { + if (!aPosition.IsAutoKeyword() && + (aPosition.GetAsDouble() > 100.0 || aPosition.GetAsDouble() < 0.0)) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return; + } + + if (aPosition.IsDouble() && + (mPositionIsAutoKeyword || (aPosition.GetAsDouble() != mPosition))) { + mPositionIsAutoKeyword = false; + mPosition = aPosition.GetAsDouble(); + mReset = true; + return; + } + + if (aPosition.IsAutoKeyword() && !mPositionIsAutoKeyword) { + mPositionIsAutoKeyword = true; + mReset = true; + } + } + + PositionAlignSetting PositionAlign() const { return mPositionAlign; } + + void SetPositionAlign(PositionAlignSetting aPositionAlign, ErrorResult& aRv) { + if (mPositionAlign == aPositionAlign) { + return; + } + + mReset = true; + mPositionAlign = aPositionAlign; + } + + double Size() const { return mSize; } + + void SetSize(double aSize, ErrorResult& aRv) { + if (mSize == aSize) { + return; + } + + if (aSize < 0.0 || aSize > 100.0) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return; + } + + mReset = true; + mSize = aSize; + } + + AlignSetting Align() const { return mAlign; } + + void SetAlign(AlignSetting& aAlign) { + if (mAlign == aAlign) { + return; + } + + mReset = true; + mAlign = aAlign; + } + + void GetText(nsAString& aText) const { aText = mText; } + + void SetText(const nsAString& aText) { + if (mText == aText) { + return; + } + + mReset = true; + mText = aText; + } + + IMPL_EVENT_HANDLER(enter) + IMPL_EVENT_HANDLER(exit) + + HTMLDivElement* GetDisplayState() { + return static_cast<HTMLDivElement*>(mDisplayState.get()); + } + + void SetDisplayState(HTMLDivElement* aDisplayState) { + mDisplayState = aDisplayState; + mReset = false; + } + + void Reset() { mReset = true; } + + bool HasBeenReset() { return mReset; } + + double ComputedLine(); + double ComputedPosition(); + PositionAlignSetting ComputedPositionAlign(); + + // Helper functions for implementation. + const nsAString& Id() const { return mId; } + + void SetTrack(TextTrack* aTextTrack) { + mTrack = aTextTrack; + if (!mHaveStartedWatcher && aTextTrack) { + mHaveStartedWatcher = true; + mWatchManager.Watch(mReset, &TextTrackCue::NotifyDisplayStatesChanged); + } else if (mHaveStartedWatcher && !aTextTrack) { + mHaveStartedWatcher = false; + mWatchManager.Unwatch(mReset, &TextTrackCue::NotifyDisplayStatesChanged); + } + } + + /** + * Produces a tree of anonymous content based on the tree of the processed + * cue text. + * + * Returns a DocumentFragment that is the head of the tree of anonymous + * content. + */ + already_AddRefed<DocumentFragment> GetCueAsHTML(); + + void SetTrackElement(HTMLTrackElement* aTrackElement); + + void SetActive(bool aActive); + + bool GetActive() { return mActive; } + + private: + ~TextTrackCue(); + + void NotifyCueUpdated(TextTrackCue* aCue) { + if (mTrack) { + mTrack->NotifyCueUpdated(aCue); + } + } + + void NotifyDisplayStatesChanged(); + + void SetDefaultCueSettings(); + nsresult StashDocument(); + + bool IsTextBaseDirectionLTR() const; + + RefPtr<Document> mDocument; + nsString mText; + double mStartTime; + double mEndTime; + + RefPtr<TextTrack> mTrack; + RefPtr<HTMLTrackElement> mTrackElement; + nsString mId; + double mPosition; + bool mPositionIsAutoKeyword; + PositionAlignSetting mPositionAlign; + double mSize; + bool mPauseOnExit; + bool mSnapToLines; + RefPtr<TextTrackRegion> mRegion; + DirectionSetting mVertical; + bool mLineIsAutoKeyword; + double mLine; + AlignSetting mAlign; + LineAlignSetting mLineAlign; + + // Holds the computed DOM elements that represent the parsed cue text. + // http://www.whatwg.org/specs/web-apps/current-work/#text-track-cue-display-state + RefPtr<nsGenericHTMLElement> mDisplayState; + // Tells whether or not we need to recompute mDisplayState. This is set + // anytime a property that relates to the display of the TextTrackCue is + // changed. + Watchable<bool> mReset; + + bool mActive; + + static StaticRefPtr<nsIWebVTTParserWrapper> sParserWrapper; + + // Only start watcher after the cue has text track. + bool mHaveStartedWatcher; + WatchManager<TextTrackCue> mWatchManager; +}; + +} // namespace mozilla::dom + +#endif // mozilla_dom_TextTrackCue_h |