diff options
Diffstat (limited to 'dom/media/TextTrackList.cpp')
-rw-r--r-- | dom/media/TextTrackList.cpp | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/dom/media/TextTrackList.cpp b/dom/media/TextTrackList.cpp new file mode 100644 index 000000000..e557d97f5 --- /dev/null +++ b/dom/media/TextTrackList.cpp @@ -0,0 +1,236 @@ +/* -*- 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/TextTrackList.h" +#include "mozilla/dom/TextTrackListBinding.h" +#include "mozilla/dom/TrackEvent.h" +#include "nsThreadUtils.h" +#include "mozilla/dom/TextTrackCue.h" +#include "mozilla/dom/TextTrackManager.h" + +namespace mozilla { +namespace dom { + +NS_IMPL_CYCLE_COLLECTION_INHERITED(TextTrackList, + DOMEventTargetHelper, + mTextTracks, + mTextTrackManager) + +NS_IMPL_ADDREF_INHERITED(TextTrackList, DOMEventTargetHelper) +NS_IMPL_RELEASE_INHERITED(TextTrackList, DOMEventTargetHelper) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrackList) +NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) + +TextTrackList::TextTrackList(nsPIDOMWindowInner* aOwnerWindow) + : DOMEventTargetHelper(aOwnerWindow) +{ +} + +TextTrackList::TextTrackList(nsPIDOMWindowInner* aOwnerWindow, + TextTrackManager* aTextTrackManager) + : DOMEventTargetHelper(aOwnerWindow) + , mTextTrackManager(aTextTrackManager) +{ +} + +TextTrackList::~TextTrackList() +{ +} + +void +TextTrackList::GetShowingCues(nsTArray<RefPtr<TextTrackCue> >& aCues) +{ + nsTArray< RefPtr<TextTrackCue> > cues; + for (uint32_t i = 0; i < Length(); i++) { + if (mTextTracks[i]->Mode() == TextTrackMode::Showing) { + mTextTracks[i]->GetActiveCueArray(cues); + aCues.AppendElements(cues); + } + } +} + +JSObject* +TextTrackList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) +{ + return TextTrackListBinding::Wrap(aCx, this, aGivenProto); +} + +TextTrack* +TextTrackList::IndexedGetter(uint32_t aIndex, bool& aFound) +{ + aFound = aIndex < mTextTracks.Length(); + if (!aFound) { + return nullptr; + } + return mTextTracks[aIndex]; +} + +TextTrack* +TextTrackList::operator[](uint32_t aIndex) +{ + return mTextTracks.SafeElementAt(aIndex, nullptr); +} + +already_AddRefed<TextTrack> +TextTrackList::AddTextTrack(TextTrackKind aKind, + const nsAString& aLabel, + const nsAString& aLanguage, + TextTrackMode aMode, + TextTrackReadyState aReadyState, + TextTrackSource aTextTrackSource, + const CompareTextTracks& aCompareTT) +{ + RefPtr<TextTrack> track = new TextTrack(GetOwner(), this, aKind, aLabel, + aLanguage, aMode, aReadyState, + aTextTrackSource); + AddTextTrack(track, aCompareTT); + return track.forget(); +} + +void +TextTrackList::AddTextTrack(TextTrack* aTextTrack, + const CompareTextTracks& aCompareTT) +{ + if (mTextTracks.Contains(aTextTrack)) { + return; + } + if (mTextTracks.InsertElementSorted(aTextTrack, aCompareTT)) { + aTextTrack->SetTextTrackList(this); + CreateAndDispatchTrackEventRunner(aTextTrack, NS_LITERAL_STRING("addtrack")); + } +} + +TextTrack* +TextTrackList::GetTrackById(const nsAString& aId) +{ + nsAutoString id; + for (uint32_t i = 0; i < Length(); i++) { + mTextTracks[i]->GetId(id); + if (aId.Equals(id)) { + return mTextTracks[i]; + } + } + return nullptr; +} + +void +TextTrackList::RemoveTextTrack(TextTrack* aTrack) +{ + if (mTextTracks.RemoveElement(aTrack)) { + CreateAndDispatchTrackEventRunner(aTrack, NS_LITERAL_STRING("removetrack")); + } +} + +void +TextTrackList::DidSeek() +{ + for (uint32_t i = 0; i < mTextTracks.Length(); i++) { + mTextTracks[i]->SetDirty(); + } +} + +class TrackEventRunner : public Runnable +{ +public: + TrackEventRunner(TextTrackList* aList, nsIDOMEvent* aEvent) + : mList(aList) + , mEvent(aEvent) + {} + + NS_IMETHOD Run() override + { + return mList->DispatchTrackEvent(mEvent); + } + + RefPtr<TextTrackList> mList; +private: + RefPtr<nsIDOMEvent> mEvent; +}; + +class ChangeEventRunner final : public TrackEventRunner +{ +public: + ChangeEventRunner(TextTrackList* aList, nsIDOMEvent* aEvent) + : TrackEventRunner(aList, aEvent) + {} + + NS_IMETHOD Run() override + { + mList->mPendingTextTrackChange = false; + return TrackEventRunner::Run(); + } +}; + +nsresult +TextTrackList::DispatchTrackEvent(nsIDOMEvent* aEvent) +{ + return DispatchTrustedEvent(aEvent); +} + +void +TextTrackList::CreateAndDispatchChangeEvent() +{ + MOZ_ASSERT(NS_IsMainThread()); + if (!mPendingTextTrackChange) { + mPendingTextTrackChange = true; + RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr); + + event->InitEvent(NS_LITERAL_STRING("change"), false, false); + event->SetTrusted(true); + + nsCOMPtr<nsIRunnable> eventRunner = new ChangeEventRunner(this, event); + NS_DispatchToMainThread(eventRunner); + } +} + +void +TextTrackList::CreateAndDispatchTrackEventRunner(TextTrack* aTrack, + const nsAString& aEventName) +{ + nsCOMPtr<nsIThread> thread; + nsresult rv = NS_GetMainThread(getter_AddRefs(thread)); + if (NS_FAILED(rv)) { + // If we are not able to get the main-thread object we are shutting down. + return; + } + + TrackEventInit eventInit; + eventInit.mTrack.SetValue().SetAsTextTrack() = aTrack; + RefPtr<TrackEvent> event = + TrackEvent::Constructor(this, aEventName, eventInit); + + // Dispatch the TrackEvent asynchronously. + rv = thread->Dispatch(do_AddRef(new TrackEventRunner(this, event)), + NS_DISPATCH_NORMAL); + + // If we are shutting down this can file but it's still ok. + NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Dispatch failed"); +} + +HTMLMediaElement* +TextTrackList::GetMediaElement() +{ + if (mTextTrackManager) { + return mTextTrackManager->mMediaElement; + } + return nullptr; +} + +void +TextTrackList::SetTextTrackManager(TextTrackManager* aTextTrackManager) +{ + mTextTrackManager = aTextTrackManager; +} + +void +TextTrackList::SetCuesInactive() +{ + for (uint32_t i = 0; i < Length(); i++) { + mTextTracks[i]->SetCuesInactive(); + } +} + +} // namespace dom +} // namespace mozilla |