Backed out changeset f594e6f00208 (bug 1940883) for causing crashes in bug 1941164.
[gecko.git] / dom / media / webvtt / TextTrackList.cpp
blob9edccdd7de85ad9c9ab21d50c319831a69ce7835
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/dom/TextTrackList.h"
8 #include "mozilla/DebugOnly.h"
9 #include "mozilla/dom/Event.h"
10 #include "mozilla/dom/TextTrackListBinding.h"
11 #include "mozilla/dom/TrackEvent.h"
12 #include "nsThreadUtils.h"
13 #include "nsGlobalWindowInner.h"
14 #include "mozilla/dom/TextTrackCue.h"
15 #include "mozilla/dom/TextTrackManager.h"
17 namespace mozilla::dom {
19 NS_IMPL_CYCLE_COLLECTION_INHERITED(TextTrackList, DOMEventTargetHelper,
20 mTextTracks, mTextTrackManager)
22 NS_IMPL_ADDREF_INHERITED(TextTrackList, DOMEventTargetHelper)
23 NS_IMPL_RELEASE_INHERITED(TextTrackList, DOMEventTargetHelper)
24 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TextTrackList)
25 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
27 TextTrackList::TextTrackList(nsPIDOMWindowInner* aOwnerWindow)
28 : DOMEventTargetHelper(aOwnerWindow) {}
30 TextTrackList::TextTrackList(nsPIDOMWindowInner* aOwnerWindow,
31 TextTrackManager* aTextTrackManager)
32 : DOMEventTargetHelper(aOwnerWindow),
33 mTextTrackManager(aTextTrackManager) {}
35 TextTrackList::~TextTrackList() = default;
37 void TextTrackList::GetShowingCues(nsTArray<RefPtr<TextTrackCue>>& aCues) {
38 // Only Subtitles and Captions can show on the screen.
39 nsTArray<RefPtr<TextTrackCue>> cues;
40 for (uint32_t i = 0; i < Length(); i++) {
41 if (mTextTracks[i]->Mode() == TextTrackMode::Showing &&
42 (mTextTracks[i]->Kind() == TextTrackKind::Subtitles ||
43 mTextTracks[i]->Kind() == TextTrackKind::Captions)) {
44 mTextTracks[i]->GetActiveCueArray(cues);
45 aCues.AppendElements(cues);
50 JSObject* TextTrackList::WrapObject(JSContext* aCx,
51 JS::Handle<JSObject*> aGivenProto) {
52 return TextTrackList_Binding::Wrap(aCx, this, aGivenProto);
55 TextTrack* TextTrackList::IndexedGetter(uint32_t aIndex, bool& aFound) {
56 aFound = aIndex < mTextTracks.Length();
57 if (!aFound) {
58 return nullptr;
60 return mTextTracks[aIndex];
63 TextTrack* TextTrackList::operator[](uint32_t aIndex) {
64 return mTextTracks.SafeElementAt(aIndex, nullptr);
67 already_AddRefed<TextTrack> TextTrackList::AddTextTrack(
68 TextTrackKind aKind, const nsAString& aLabel, const nsAString& aLanguage,
69 TextTrackMode aMode, TextTrackReadyState aReadyState,
70 TextTrackSource aTextTrackSource, const CompareTextTracks& aCompareTT) {
71 RefPtr<TextTrack> track =
72 new TextTrack(GetOwnerWindow(), this, aKind, aLabel, aLanguage, aMode,
73 aReadyState, aTextTrackSource);
74 AddTextTrack(track, aCompareTT);
75 return track.forget();
78 void TextTrackList::AddTextTrack(TextTrack* aTextTrack,
79 const CompareTextTracks& aCompareTT) {
80 if (mTextTracks.Contains(aTextTrack)) {
81 return;
83 mTextTracks.InsertElementSorted(aTextTrack, aCompareTT);
84 aTextTrack->SetTextTrackList(this);
85 CreateAndDispatchTrackEventRunner(aTextTrack, u"addtrack"_ns);
88 TextTrack* TextTrackList::GetTrackById(const nsAString& aId) {
89 nsAutoString id;
90 for (uint32_t i = 0; i < Length(); i++) {
91 mTextTracks[i]->GetId(id);
92 if (aId.Equals(id)) {
93 return mTextTracks[i];
96 return nullptr;
99 void TextTrackList::RemoveTextTrack(TextTrack* aTrack) {
100 if (mTextTracks.RemoveElement(aTrack)) {
101 CreateAndDispatchTrackEventRunner(aTrack, u"removetrack"_ns);
105 class TrackEventRunner : public Runnable {
106 public:
107 TrackEventRunner(TextTrackList* aList, Event* aEvent)
108 : Runnable("dom::TrackEventRunner"), mList(aList), mEvent(aEvent) {}
110 NS_IMETHOD Run() override { return mList->DispatchTrackEvent(mEvent); }
112 RefPtr<TextTrackList> mList;
114 private:
115 RefPtr<Event> mEvent;
118 nsresult TextTrackList::DispatchTrackEvent(Event* aEvent) {
119 return DispatchTrustedEvent(aEvent);
122 void TextTrackList::CreateAndDispatchChangeEvent() {
123 MOZ_ASSERT(NS_IsMainThread());
124 nsPIDOMWindowInner* win = GetOwnerWindow();
125 if (!win) {
126 return;
129 RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
131 event->InitEvent(u"change"_ns, false, false);
132 event->SetTrusted(true);
134 nsCOMPtr<nsIRunnable> eventRunner = new TrackEventRunner(this, event);
135 nsGlobalWindowInner::Cast(win)->Dispatch(eventRunner.forget());
138 void TextTrackList::CreateAndDispatchTrackEventRunner(
139 TextTrack* aTrack, const nsAString& aEventName) {
140 nsCOMPtr<nsIEventTarget> target = GetMainThreadSerialEventTarget();
141 if (!target) {
142 // If we are not able to get the main-thread object we are shutting down.
143 return;
146 TrackEventInit eventInit;
147 eventInit.mTrack.SetValue().SetAsTextTrack() = aTrack;
148 RefPtr<TrackEvent> event =
149 TrackEvent::Constructor(this, aEventName, eventInit);
151 // Dispatch the TrackEvent asynchronously.
152 DebugOnly<nsresult> rv = target->Dispatch(
153 do_AddRef(new TrackEventRunner(this, event)), NS_DISPATCH_NORMAL);
155 // If we are shutting down this can file but it's still ok.
156 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Dispatch failed");
159 HTMLMediaElement* TextTrackList::GetMediaElement() {
160 if (mTextTrackManager) {
161 return mTextTrackManager->mMediaElement;
163 return nullptr;
166 void TextTrackList::SetTextTrackManager(TextTrackManager* aTextTrackManager) {
167 mTextTrackManager = aTextTrackManager;
170 void TextTrackList::SetCuesInactive() {
171 for (uint32_t i = 0; i < Length(); i++) {
172 mTextTracks[i]->SetCuesInactive();
176 bool TextTrackList::AreTextTracksLoaded() {
177 // Return false if any texttrack is not loaded.
178 for (uint32_t i = 0; i < Length(); i++) {
179 if (!mTextTracks[i]->IsLoaded()) {
180 return false;
183 return true;
186 nsTArray<RefPtr<TextTrack>>& TextTrackList::GetTextTrackArray() {
187 return mTextTracks;
190 } // namespace mozilla::dom