TextTrackList.cpp (6007B)
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/. */ 5 6 #include "mozilla/dom/TextTrackList.h" 7 8 #include "mozilla/DebugOnly.h" 9 #include "mozilla/dom/Event.h" 10 #include "mozilla/dom/TextTrackCue.h" 11 #include "mozilla/dom/TextTrackListBinding.h" 12 #include "mozilla/dom/TextTrackManager.h" 13 #include "mozilla/dom/TrackEvent.h" 14 #include "nsGlobalWindowInner.h" 15 #include "nsThreadUtils.h" 16 17 namespace mozilla::dom { 18 19 NS_IMPL_CYCLE_COLLECTION_INHERITED(TextTrackList, DOMEventTargetHelper, 20 mTextTracks, mTextTrackManager) 21 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) 26 27 TextTrackList::TextTrackList(nsPIDOMWindowInner* aOwnerWindow) 28 : DOMEventTargetHelper(aOwnerWindow) {} 29 30 TextTrackList::TextTrackList(nsPIDOMWindowInner* aOwnerWindow, 31 TextTrackManager* aTextTrackManager) 32 : DOMEventTargetHelper(aOwnerWindow), 33 mTextTrackManager(aTextTrackManager) {} 34 35 TextTrackList::~TextTrackList() = default; 36 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); 46 } 47 } 48 } 49 50 JSObject* TextTrackList::WrapObject(JSContext* aCx, 51 JS::Handle<JSObject*> aGivenProto) { 52 return TextTrackList_Binding::Wrap(aCx, this, aGivenProto); 53 } 54 55 TextTrack* TextTrackList::IndexedGetter(uint32_t aIndex, bool& aFound) { 56 aFound = aIndex < mTextTracks.Length(); 57 if (!aFound) { 58 return nullptr; 59 } 60 return mTextTracks[aIndex]; 61 } 62 63 TextTrack* TextTrackList::operator[](uint32_t aIndex) { 64 return mTextTracks.SafeElementAt(aIndex, nullptr); 65 } 66 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(); 76 } 77 78 void TextTrackList::AddTextTrack(TextTrack* aTextTrack, 79 const CompareTextTracks& aCompareTT) { 80 if (mTextTracks.Contains(aTextTrack)) { 81 return; 82 } 83 mTextTracks.InsertElementSorted(aTextTrack, aCompareTT); 84 aTextTrack->SetTextTrackList(this); 85 CreateAndDispatchTrackEventRunner(aTextTrack, u"addtrack"_ns); 86 } 87 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]; 94 } 95 } 96 return nullptr; 97 } 98 99 void TextTrackList::RemoveTextTrack(TextTrack* aTrack) { 100 if (mTextTracks.RemoveElement(aTrack)) { 101 CreateAndDispatchTrackEventRunner(aTrack, u"removetrack"_ns); 102 } 103 } 104 105 class TrackEventRunner : public Runnable { 106 public: 107 TrackEventRunner(TextTrackList* aList, Event* aEvent) 108 : Runnable("dom::TrackEventRunner"), mList(aList), mEvent(aEvent) {} 109 110 NS_IMETHOD Run() override { return mList->DispatchTrackEvent(mEvent); } 111 112 RefPtr<TextTrackList> mList; 113 114 private: 115 RefPtr<Event> mEvent; 116 }; 117 118 nsresult TextTrackList::DispatchTrackEvent(Event* aEvent) { 119 return DispatchTrustedEvent(aEvent); 120 } 121 122 void TextTrackList::CreateAndDispatchChangeEvent() { 123 MOZ_ASSERT(NS_IsMainThread()); 124 nsPIDOMWindowInner* win = GetOwnerWindow(); 125 if (!win) { 126 return; 127 } 128 129 RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr); 130 131 event->InitEvent(u"change"_ns, false, false); 132 event->SetTrusted(true); 133 134 nsCOMPtr<nsIRunnable> eventRunner = new TrackEventRunner(this, event); 135 nsGlobalWindowInner::Cast(win)->Dispatch(eventRunner.forget()); 136 } 137 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; 144 } 145 146 TrackEventInit eventInit; 147 eventInit.mTrack.SetValue().SetAsTextTrack() = aTrack; 148 RefPtr<TrackEvent> event = 149 TrackEvent::Constructor(this, aEventName, eventInit); 150 151 // Dispatch the TrackEvent asynchronously. 152 DebugOnly<nsresult> rv = target->Dispatch( 153 do_AddRef(new TrackEventRunner(this, event)), NS_DISPATCH_NORMAL); 154 155 // If we are shutting down this can file but it's still ok. 156 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Dispatch failed"); 157 } 158 159 HTMLMediaElement* TextTrackList::GetMediaElement() { 160 if (mTextTrackManager) { 161 return mTextTrackManager->mMediaElement; 162 } 163 return nullptr; 164 } 165 166 void TextTrackList::SetTextTrackManager(TextTrackManager* aTextTrackManager) { 167 mTextTrackManager = aTextTrackManager; 168 } 169 170 void TextTrackList::SetCuesInactive() { 171 for (uint32_t i = 0; i < Length(); i++) { 172 mTextTracks[i]->SetCuesInactive(); 173 } 174 } 175 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; 181 } 182 } 183 return true; 184 } 185 186 nsTArray<RefPtr<TextTrack>>& TextTrackList::GetTextTrackArray() { 187 return mTextTracks; 188 } 189 190 } // namespace mozilla::dom