Fri, 16 Jan 2015 04:50:19 +0100
Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 et tw=78: */
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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/TextTrack.h"
8 #include "mozilla/dom/TextTrackBinding.h"
9 #include "mozilla/dom/TextTrackList.h"
10 #include "mozilla/dom/TextTrackCue.h"
11 #include "mozilla/dom/TextTrackCueList.h"
12 #include "mozilla/dom/TextTrackRegion.h"
13 #include "mozilla/dom/HTMLMediaElement.h"
14 #include "mozilla/dom/HTMLTrackElement.h"
16 namespace mozilla {
17 namespace dom {
19 NS_IMPL_CYCLE_COLLECTION_INHERITED(TextTrack,
20 DOMEventTargetHelper,
21 mCueList,
22 mActiveCueList,
23 mTextTrackList,
24 mTrackElement)
26 NS_IMPL_ADDREF_INHERITED(TextTrack, DOMEventTargetHelper)
27 NS_IMPL_RELEASE_INHERITED(TextTrack, DOMEventTargetHelper)
28 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrack)
29 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
31 TextTrack::TextTrack(nsPIDOMWindow* aOwnerWindow,
32 TextTrackKind aKind,
33 const nsAString& aLabel,
34 const nsAString& aLanguage,
35 TextTrackMode aMode,
36 TextTrackReadyState aReadyState,
37 TextTrackSource aTextTrackSource)
38 : DOMEventTargetHelper(aOwnerWindow)
39 , mKind(aKind)
40 , mLabel(aLabel)
41 , mLanguage(aLanguage)
42 , mMode(aMode)
43 , mReadyState(aReadyState)
44 , mTextTrackSource(aTextTrackSource)
45 {
46 SetDefaultSettings();
47 }
49 TextTrack::TextTrack(nsPIDOMWindow* aOwnerWindow,
50 TextTrackList* aTextTrackList,
51 TextTrackKind aKind,
52 const nsAString& aLabel,
53 const nsAString& aLanguage,
54 TextTrackMode aMode,
55 TextTrackReadyState aReadyState,
56 TextTrackSource aTextTrackSource)
57 : DOMEventTargetHelper(aOwnerWindow)
58 , mTextTrackList(aTextTrackList)
59 , mKind(aKind)
60 , mLabel(aLabel)
61 , mLanguage(aLanguage)
62 , mMode(aMode)
63 , mReadyState(aReadyState)
64 , mTextTrackSource(aTextTrackSource)
65 {
66 SetDefaultSettings();
67 }
69 void
70 TextTrack::SetDefaultSettings()
71 {
72 nsPIDOMWindow* ownerWindow = GetOwner();
73 mCueList = new TextTrackCueList(ownerWindow);
74 mActiveCueList = new TextTrackCueList(ownerWindow);
75 mCuePos = 0;
76 mDirty = false;
77 }
79 JSObject*
80 TextTrack::WrapObject(JSContext* aCx)
81 {
82 return TextTrackBinding::Wrap(aCx, this);
83 }
85 void
86 TextTrack::SetMode(TextTrackMode aValue)
87 {
88 if (mMode != aValue) {
89 mMode = aValue;
90 if (mTextTrackList) {
91 mTextTrackList->CreateAndDispatchChangeEvent();
92 }
93 }
94 }
96 void
97 TextTrack::GetId(nsAString& aId) const
98 {
99 // If the track has a track element then its id should be the same as the
100 // track element's id.
101 if (mTrackElement) {
102 mTrackElement->GetAttribute(NS_LITERAL_STRING("id"), aId);
103 }
104 }
106 void
107 TextTrack::AddCue(TextTrackCue& aCue)
108 {
109 mCueList->AddCue(aCue);
110 aCue.SetTrack(this);
111 if (mTextTrackList) {
112 HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
113 if (mediaElement) {
114 mediaElement->AddCue(aCue);
115 }
116 }
117 SetDirty();
118 }
120 void
121 TextTrack::RemoveCue(TextTrackCue& aCue, ErrorResult& aRv)
122 {
123 mCueList->RemoveCue(aCue, aRv);
124 SetDirty();
125 }
127 void
128 TextTrack::SetCuesDirty()
129 {
130 for (uint32_t i = 0; i < mCueList->Length(); i++) {
131 ((*mCueList)[i])->Reset();
132 }
133 }
135 void
136 TextTrack::UpdateActiveCueList()
137 {
138 if (!mTextTrackList) {
139 return;
140 }
142 HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
143 if (!mediaElement) {
144 return;
145 }
147 // If we are dirty, i.e. an event happened that may cause the sorted mCueList
148 // to have changed like a seek or an insert for a cue, than we need to rebuild
149 // the active cue list from scratch.
150 if (mDirty) {
151 mCuePos = 0;
152 mDirty = false;
153 mActiveCueList->RemoveAll();
154 }
156 double playbackTime = mediaElement->CurrentTime();
157 // Remove all the cues from the active cue list whose end times now occur
158 // earlier then the current playback time.
159 for (uint32_t i = mActiveCueList->Length(); i > 0; i--) {
160 if ((*mActiveCueList)[i - 1]->EndTime() < playbackTime) {
161 mActiveCueList->RemoveCueAt(i - 1);
162 }
163 }
164 // Add all the cues, starting from the position of the last cue that was
165 // added, that have valid start and end times for the current playback time.
166 // We can stop iterating safely once we encounter a cue that does not have
167 // a valid start time as the cue list is sorted.
168 for (; mCuePos < mCueList->Length() &&
169 (*mCueList)[mCuePos]->StartTime() <= playbackTime; mCuePos++) {
170 if ((*mCueList)[mCuePos]->EndTime() >= playbackTime) {
171 mActiveCueList->AddCue(*(*mCueList)[mCuePos]);
172 }
173 }
174 }
176 TextTrackCueList*
177 TextTrack::GetActiveCues() {
178 if (mMode != TextTrackMode::Disabled) {
179 UpdateActiveCueList();
180 return mActiveCueList;
181 }
182 return nullptr;
183 }
185 void
186 TextTrack::GetActiveCueArray(nsTArray<nsRefPtr<TextTrackCue> >& aCues)
187 {
188 if (mMode != TextTrackMode::Disabled) {
189 UpdateActiveCueList();
190 mActiveCueList->GetArray(aCues);
191 }
192 }
194 TextTrackReadyState
195 TextTrack::ReadyState() const
196 {
197 return mReadyState;
198 }
200 void
201 TextTrack::SetReadyState(uint32_t aReadyState)
202 {
203 if (aReadyState <= TextTrackReadyState::FailedToLoad) {
204 SetReadyState(static_cast<TextTrackReadyState>(aReadyState));
205 }
206 }
208 void
209 TextTrack::SetReadyState(TextTrackReadyState aState)
210 {
211 mReadyState = aState;
213 if (!mTextTrackList) {
214 return;
215 }
217 HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
218 if (mediaElement && (mReadyState == TextTrackReadyState::Loaded||
219 mReadyState == TextTrackReadyState::FailedToLoad)) {
220 mediaElement->RemoveTextTrack(this, true);
221 }
222 }
224 TextTrackList*
225 TextTrack::GetTextTrackList()
226 {
227 return mTextTrackList;
228 }
230 void
231 TextTrack::SetTextTrackList(TextTrackList* aTextTrackList)
232 {
233 mTextTrackList = aTextTrackList;
234 }
236 HTMLTrackElement*
237 TextTrack::GetTrackElement() {
238 return mTrackElement;
239 }
241 void
242 TextTrack::SetTrackElement(HTMLTrackElement* aTrackElement) {
243 mTrackElement = aTrackElement;
244 }
246 } // namespace dom
247 } // namespace mozilla