tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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