1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_TextTrackManager_h 8 #define mozilla_dom_TextTrackManager_h 9 10 #include "mozilla/dom/TextTrack.h" 11 #include "mozilla/dom/TextTrackList.h" 12 #include "mozilla/dom/TextTrackCueList.h" 13 #include "mozilla/StaticPtr.h" 14 #include "nsContentUtils.h" 15 #include "nsIDOMEventListener.h" 16 #include "TimeUnits.h" 17 18 class nsIWebVTTParserWrapper; 19 20 namespace mozilla { 21 namespace dom { 22 23 class HTMLMediaElement; 24 25 class CompareTextTracks { 26 private: 27 HTMLMediaElement* mMediaElement; 28 int32_t TrackChildPosition(TextTrack* aTrack) const; 29 30 public: 31 explicit CompareTextTracks(HTMLMediaElement* aMediaElement); 32 bool Equals(TextTrack* aOne, TextTrack* aTwo) const; 33 bool LessThan(TextTrack* aOne, TextTrack* aTwo) const; 34 }; 35 36 class TextTrack; 37 class TextTrackCue; 38 39 class TextTrackManager final : public nsIDOMEventListener { 40 ~TextTrackManager(); 41 42 public: 43 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 44 NS_DECL_CYCLE_COLLECTION_CLASS(TextTrackManager) 45 46 NS_DECL_NSIDOMEVENTLISTENER 47 48 explicit TextTrackManager(HTMLMediaElement* aMediaElement); 49 50 TextTrackList* GetTextTracks() const; 51 already_AddRefed<TextTrack> AddTextTrack(TextTrackKind aKind, 52 const nsAString& aLabel, 53 const nsAString& aLanguage, 54 TextTrackMode aMode, 55 TextTrackReadyState aReadyState, 56 TextTrackSource aTextTrackSource); 57 void AddTextTrack(TextTrack* aTextTrack); 58 void RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly); 59 void DidSeek(); 60 61 void NotifyCueAdded(TextTrackCue& aCue); 62 void AddCues(TextTrack* aTextTrack); 63 void NotifyCueRemoved(TextTrackCue& aCue); 64 /** 65 * Overview of WebVTT cuetext and anonymous content setup. 66 * 67 * WebVTT nodes are the parsed version of WebVTT cuetext. WebVTT cuetext is 68 * the portion of a WebVTT cue that specifies what the caption will actually 69 * show up as on screen. 70 * 71 * WebVTT cuetext can contain markup that loosely relates to HTML markup. It 72 * can contain tags like <b>, <u>, <i>, <c>, <v>, <ruby>, <rt>, <lang>, 73 * including timestamp tags. 74 * 75 * When the caption is ready to be displayed the WebVTT nodes are converted 76 * over to anonymous DOM content. <i>, <u>, <b>, <ruby>, and <rt> all become 77 * HTMLElements of their corresponding HTML markup tags. <c> and <v> are 78 * converted to <span> tags. Timestamp tags are converted to XML processing 79 * instructions. Additionally, all cuetext tags support specifying of classes. 80 * This takes the form of <foo.class.subclass>. These classes are then parsed 81 * and set as the anonymous content's class attribute. 82 * 83 * Rules on constructing DOM objects from WebVTT nodes can be found here 84 * http://dev.w3.org/html5/webvtt/#webvtt-cue-text-dom-construction-rules. 85 * Current rules are taken from revision on April 15, 2013. 86 */ 87 88 void PopulatePendingList(); 89 90 void AddListeners(); 91 92 // The HTMLMediaElement that this TextTrackManager manages the TextTracks of. 93 RefPtr<HTMLMediaElement> mMediaElement; 94 95 void DispatchTimeMarchesOn(); 96 void TimeMarchesOn(); 97 void DispatchUpdateCueDisplay(); 98 NotifyShutdown()99 void NotifyShutdown() { mShutdown = true; } 100 101 void NotifyCueUpdated(TextTrackCue* aCue); 102 103 void NotifyReset(); 104 105 bool IsLoaded(); 106 107 private: 108 /** 109 * Converts the TextTrackCue's cuetext into a tree of DOM objects 110 * and attaches it to a div on its owning TrackElement's 111 * MediaElement's caption overlay. 112 */ 113 void UpdateCueDisplay(); 114 115 // List of the TextTrackManager's owning HTMLMediaElement's TextTracks. 116 RefPtr<TextTrackList> mTextTracks; 117 // List of text track objects awaiting loading. 118 RefPtr<TextTrackList> mPendingTextTracks; 119 // List of newly introduced Text Track cues. 120 121 // Contain all cues for a MediaElement. Not sorted. 122 RefPtr<TextTrackCueList> mNewCues; 123 124 // True if the media player playback changed due to seeking prior to and 125 // during running the "Time Marches On" algorithm. 126 bool mHasSeeked; 127 // Playback position at the time of last "Time Marches On" call 128 media::TimeUnit mLastTimeMarchesOnCalled; 129 130 bool mTimeMarchesOnDispatched; 131 bool mUpdateCueDisplayDispatched; 132 133 static StaticRefPtr<nsIWebVTTParserWrapper> sParserWrapper; 134 135 bool performedTrackSelection; 136 137 // Runs the algorithm for performing automatic track selection. 138 void HonorUserPreferencesForTrackSelection(); 139 // Performs track selection for a single TextTrackKind. 140 void PerformTrackSelection(TextTrackKind aTextTrackKind); 141 // Performs track selection for a set of TextTrackKinds, for example, 142 // 'subtitles' and 'captions' should be selected together. 143 void PerformTrackSelection(TextTrackKind aTextTrackKinds[], uint32_t size); 144 void GetTextTracksOfKinds(TextTrackKind aTextTrackKinds[], uint32_t size, 145 nsTArray<TextTrack*>& aTextTracks); 146 void GetTextTracksOfKind(TextTrackKind aTextTrackKind, 147 nsTArray<TextTrack*>& aTextTracks); 148 bool TrackIsDefault(TextTrack* aTextTrack); 149 150 void ReportTelemetryForTrack(TextTrack* aTextTrack) const; 151 152 bool IsShutdown() const; 153 154 // This function will check media element's show poster flag to decide whether 155 // we need to run `TimeMarchesOn`. 156 void MaybeRunTimeMarchesOn(); 157 158 class ShutdownObserverProxy final : public nsIObserver { 159 NS_DECL_ISUPPORTS 160 161 public: ShutdownObserverProxy(TextTrackManager * aManager)162 explicit ShutdownObserverProxy(TextTrackManager* aManager) 163 : mManager(aManager) { 164 nsContentUtils::RegisterShutdownObserver(this); 165 } 166 Observe(nsISupports * aSubject,const char * aTopic,const char16_t * aData)167 NS_IMETHODIMP Observe(nsISupports* aSubject, const char* aTopic, 168 const char16_t* aData) override { 169 MOZ_ASSERT(NS_IsMainThread()); 170 if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { 171 if (mManager) { 172 mManager->NotifyShutdown(); 173 } 174 Unregister(); 175 } 176 return NS_OK; 177 } 178 179 void Unregister(); 180 181 private: 182 ~ShutdownObserverProxy() = default; 183 184 TextTrackManager* mManager; 185 }; 186 187 RefPtr<ShutdownObserverProxy> mShutdownProxy; 188 bool mShutdown; 189 }; 190 191 } // namespace dom 192 } // namespace mozilla 193 194 #endif // mozilla_dom_TextTrackManager_h 195