diff options
Diffstat (limited to 'dom/media/TextTrackCue.cpp')
-rw-r--r-- | dom/media/TextTrackCue.cpp | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/dom/media/TextTrackCue.cpp b/dom/media/TextTrackCue.cpp new file mode 100644 index 000000000..5ca70f84e --- /dev/null +++ b/dom/media/TextTrackCue.cpp @@ -0,0 +1,256 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "mozilla/dom/HTMLTrackElement.h" +#include "mozilla/dom/TextTrackCue.h" +#include "mozilla/dom/TextTrackList.h" +#include "mozilla/dom/TextTrackRegion.h" +#include "nsComponentManagerUtils.h" +#include "mozilla/ClearOnShutdown.h" + +namespace mozilla { +namespace dom { + +NS_IMPL_CYCLE_COLLECTION_INHERITED(TextTrackCue, + DOMEventTargetHelper, + mDocument, + mTrack, + mTrackElement, + mDisplayState, + mRegion) + +NS_IMPL_ADDREF_INHERITED(TextTrackCue, DOMEventTargetHelper) +NS_IMPL_RELEASE_INHERITED(TextTrackCue, DOMEventTargetHelper) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrackCue) +NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) + +StaticRefPtr<nsIWebVTTParserWrapper> TextTrackCue::sParserWrapper; + +// Set cue setting defaults based on step 19 & seq. +// in http://dev.w3.org/html5/webvtt/#parsing +void +TextTrackCue::SetDefaultCueSettings() +{ + mPositionIsAutoKeyword = true; + mPositionAlign = PositionAlignSetting::Center; + mSize = 100.0; + mPauseOnExit = false; + mSnapToLines = true; + mLineIsAutoKeyword = true; + mAlign = AlignSetting::Center; + mLineAlign = LineAlignSetting::Start; + mVertical = DirectionSetting::_empty; + mActive = false; +} + +TextTrackCue::TextTrackCue(nsPIDOMWindowInner* aOwnerWindow, + double aStartTime, + double aEndTime, + const nsAString& aText, + ErrorResult& aRv) + : DOMEventTargetHelper(aOwnerWindow) + , mText(aText) + , mStartTime(aStartTime) + , mEndTime(aEndTime) + , mReset(false, "TextTrackCue::mReset") + , mHaveStartedWatcher(false) + , mWatchManager(this, AbstractThread::MainThread()) +{ + SetDefaultCueSettings(); + MOZ_ASSERT(aOwnerWindow); + if (NS_FAILED(StashDocument())) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } +} + +TextTrackCue::TextTrackCue(nsPIDOMWindowInner* aOwnerWindow, + double aStartTime, + double aEndTime, + const nsAString& aText, + HTMLTrackElement* aTrackElement, + ErrorResult& aRv) + : DOMEventTargetHelper(aOwnerWindow) + , mText(aText) + , mStartTime(aStartTime) + , mEndTime(aEndTime) + , mTrackElement(aTrackElement) + , mReset(false, "TextTrackCue::mReset") + , mHaveStartedWatcher(false) + , mWatchManager(this, AbstractThread::MainThread()) +{ + SetDefaultCueSettings(); + MOZ_ASSERT(aOwnerWindow); + if (NS_FAILED(StashDocument())) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } +} + +TextTrackCue::~TextTrackCue() +{ +} + +/** Save a reference to our creating document so we don't have to + * keep getting it from our window. + */ +nsresult +TextTrackCue::StashDocument() +{ + nsPIDOMWindowInner* window = GetOwner(); + if (!window) { + return NS_ERROR_NO_INTERFACE; + } + mDocument = window->GetDoc(); + if (!mDocument) { + return NS_ERROR_NOT_AVAILABLE; + } + return NS_OK; +} + +already_AddRefed<DocumentFragment> +TextTrackCue::GetCueAsHTML() +{ + // mDocument may be null during cycle collector shutdown. + // See bug 941701. + if (!mDocument) { + return nullptr; + } + + if (!sParserWrapper) { + nsresult rv; + nsCOMPtr<nsIWebVTTParserWrapper> parserWrapper = + do_CreateInstance(NS_WEBVTTPARSERWRAPPER_CONTRACTID, &rv); + if (NS_FAILED(rv)) { + return mDocument->CreateDocumentFragment(); + } + sParserWrapper = parserWrapper; + ClearOnShutdown(&sParserWrapper); + } + + nsPIDOMWindowInner* window = mDocument->GetInnerWindow(); + if (!window) { + return mDocument->CreateDocumentFragment(); + } + + nsCOMPtr<nsIDOMHTMLElement> div; + sParserWrapper->ConvertCueToDOMTree(window, this, + getter_AddRefs(div)); + if (!div) { + return mDocument->CreateDocumentFragment(); + } + RefPtr<DocumentFragment> docFrag = mDocument->CreateDocumentFragment(); + nsCOMPtr<nsIDOMNode> throwAway; + docFrag->AppendChild(div, getter_AddRefs(throwAway)); + + return docFrag.forget(); +} + +void +TextTrackCue::SetTrackElement(HTMLTrackElement* aTrackElement) +{ + mTrackElement = aTrackElement; +} + +JSObject* +TextTrackCue::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) +{ + return VTTCueBinding::Wrap(aCx, this, aGivenProto); +} + +TextTrackRegion* +TextTrackCue::GetRegion() +{ + return mRegion; +} + +void +TextTrackCue::SetRegion(TextTrackRegion* aRegion) +{ + if (mRegion == aRegion) { + return; + } + mRegion = aRegion; + mReset = true; +} + +double +TextTrackCue::ComputedLine() +{ + // See spec https://w3c.github.io/webvtt/#cue-computed-line + if (!mLineIsAutoKeyword && !mSnapToLines && + (mLine < 0.0 || mLine > 100.0)) { + return 100.0; + } else if (!mLineIsAutoKeyword) { + return mLine; + } else if (mLineIsAutoKeyword && !mSnapToLines) { + return 100.0; + } else if (!mTrack || + !mTrack->GetTextTrackList() || + !mTrack->GetTextTrackList()->GetMediaElement()) { + return -1.0; + } + + RefPtr<TextTrackList> trackList = mTrack->GetTextTrackList(); + bool dummy; + uint32_t showingTracksNum = 0; + for (uint32_t idx = 0; idx < trackList->Length(); idx++) { + RefPtr<TextTrack> track = trackList->IndexedGetter(idx, dummy); + if (track->Mode() == TextTrackMode::Showing) { + showingTracksNum++; + } + + if (mTrack == track) { + break; + } + } + + return (-1.0) * showingTracksNum; +} + +double +TextTrackCue::ComputedPosition() +{ + // See spec https://w3c.github.io/webvtt/#cue-computed-position + if (!mPositionIsAutoKeyword) { + return mPosition; + } else if (mAlign == AlignSetting::Left) { + return 0.0; + } else if (mAlign == AlignSetting::Right) { + return 100.0; + } + return 50.0; +} + +PositionAlignSetting +TextTrackCue::ComputedPositionAlign() +{ + // See spec https://w3c.github.io/webvtt/#cue-computed-position-alignment + if (mPositionAlign != PositionAlignSetting::Auto) { + return mPositionAlign; + } else if (mAlign == AlignSetting::Left) { + return PositionAlignSetting::Line_left; + } else if (mAlign == AlignSetting::Right) { + return PositionAlignSetting::Line_right; + } + return PositionAlignSetting::Center; +} + +void +TextTrackCue::NotifyDisplayStatesChanged() +{ + if (!mReset) { + return; + } + + if (!mTrack || + !mTrack->GetTextTrackList() || + !mTrack->GetTextTrackList()->GetMediaElement()) { + return; + } + + mTrack->GetTextTrackList()->GetMediaElement()->NotifyCueDisplayStatesChanged(); +} + +} // namespace dom +} // namespace mozilla |