OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
3 * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved. | 3 * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 DEFINE_STATIC_LOCAL(const AtomicString, closed, ("hidden", AtomicString::Con
structFromLiteral)); | 88 DEFINE_STATIC_LOCAL(const AtomicString, closed, ("hidden", AtomicString::Con
structFromLiteral)); |
89 return closed; | 89 return closed; |
90 } | 90 } |
91 | 91 |
92 const AtomicString& TextTrack::showingKeyword() | 92 const AtomicString& TextTrack::showingKeyword() |
93 { | 93 { |
94 DEFINE_STATIC_LOCAL(const AtomicString, ended, ("showing", AtomicString::Con
structFromLiteral)); | 94 DEFINE_STATIC_LOCAL(const AtomicString, ended, ("showing", AtomicString::Con
structFromLiteral)); |
95 return ended; | 95 return ended; |
96 } | 96 } |
97 | 97 |
98 TextTrack::TextTrack(Document& document, TextTrackClient* client, const AtomicSt
ring& kind, const AtomicString& label, const AtomicString& language, const Atomi
cString& id, TextTrackType type) | 98 TextTrack::TextTrack(Document& document, const AtomicString& kind, const AtomicS
tring& label, const AtomicString& language, const AtomicString& id, TextTrackTyp
e type) |
99 : TrackBase(TrackBase::TextTrack, label, language, id) | 99 : TrackBase(TrackBase::TextTrack, label, language, id) |
100 , m_cues(nullptr) | 100 , m_cues(nullptr) |
101 , m_regions(nullptr) | 101 , m_regions(nullptr) |
102 , m_document(&document) | 102 , m_document(&document) |
103 , m_trackList(0) | 103 , m_trackList(0) |
104 , m_mode(disabledKeyword()) | 104 , m_mode(disabledKeyword()) |
105 , m_client(client) | |
106 , m_trackType(type) | 105 , m_trackType(type) |
107 , m_readinessState(NotLoaded) | 106 , m_readinessState(NotLoaded) |
108 , m_trackIndex(invalidTrackIndex) | 107 , m_trackIndex(invalidTrackIndex) |
109 , m_renderedTrackIndex(invalidTrackIndex) | 108 , m_renderedTrackIndex(invalidTrackIndex) |
110 , m_hasBeenConfigured(false) | 109 , m_hasBeenConfigured(false) |
111 { | 110 { |
112 ScriptWrappable::init(this); | 111 ScriptWrappable::init(this); |
113 setKind(kind); | 112 setKind(kind); |
114 } | 113 } |
115 | 114 |
116 TextTrack::~TextTrack() | 115 TextTrack::~TextTrack() |
117 { | 116 { |
| 117 ASSERT(!m_trackList); |
| 118 |
118 if (m_cues) { | 119 if (m_cues) { |
119 if (m_client) | |
120 m_client->textTrackRemoveCues(this, m_cues.get()); | |
121 | |
122 for (size_t i = 0; i < m_cues->length(); ++i) | 120 for (size_t i = 0; i < m_cues->length(); ++i) |
123 m_cues->item(i)->setTrack(0); | 121 m_cues->item(i)->setTrack(0); |
124 } | 122 } |
125 | 123 |
126 if (m_regions) { | 124 if (m_regions) { |
127 for (size_t i = 0; i < m_regions->length(); ++i) | 125 for (size_t i = 0; i < m_regions->length(); ++i) |
128 m_regions->item(i)->setTrack(0); | 126 m_regions->item(i)->setTrack(0); |
129 } | 127 } |
130 clearClient(); | |
131 } | 128 } |
132 | 129 |
133 bool TextTrack::isValidKindKeyword(const AtomicString& value) | 130 bool TextTrack::isValidKindKeyword(const AtomicString& value) |
134 { | 131 { |
135 if (value == subtitlesKeyword()) | 132 if (value == subtitlesKeyword()) |
136 return true; | 133 return true; |
137 if (value == captionsKeyword()) | 134 if (value == captionsKeyword()) |
138 return true; | 135 return true; |
139 if (value == descriptionsKeyword()) | 136 if (value == descriptionsKeyword()) |
140 return true; | 137 return true; |
141 if (value == chaptersKeyword()) | 138 if (value == chaptersKeyword()) |
142 return true; | 139 return true; |
143 if (value == metadataKeyword()) | 140 if (value == metadataKeyword()) |
144 return true; | 141 return true; |
145 | 142 |
146 return false; | 143 return false; |
147 } | 144 } |
148 | 145 |
149 void TextTrack::setTrackList(TextTrackList* trackList) | 146 void TextTrack::setTrackList(TextTrackList* trackList) |
150 { | 147 { |
151 // NOTE: We are using m_trackList->owner() instead of m_client here because | 148 if (!trackList && mediaElement() && m_cues) |
152 // when a HTMLTrackElement is reparented, HTMLTrackElement::textTrackRemoveC
ues() | 149 mediaElement()->textTrackRemoveCues(this, m_cues.get()); |
153 // will forward the call to the new parent instead of the element the track
is being | 150 |
154 // removed from. | |
155 if (!trackList && m_trackList && m_trackList->owner() && m_cues) | |
156 m_trackList->owner()->textTrackRemoveCues(this, m_cues.get()); | |
157 m_trackList = trackList; | 151 m_trackList = trackList; |
158 } | 152 } |
159 | 153 |
160 void TextTrack::setKind(const AtomicString& newKind) | 154 void TextTrack::setKind(const AtomicString& newKind) |
161 { | 155 { |
162 AtomicString oldKind = kind(); | 156 AtomicString oldKind = kind(); |
163 TrackBase::setKind(newKind); | 157 TrackBase::setKind(newKind); |
164 | 158 |
165 if (m_client && oldKind != kind()) | 159 if (mediaElement() && oldKind != kind()) |
166 m_client->textTrackKindChanged(this); | 160 mediaElement()->textTrackKindChanged(this); |
167 } | 161 } |
168 | 162 |
169 void TextTrack::setMode(const AtomicString& mode) | 163 void TextTrack::setMode(const AtomicString& mode) |
170 { | 164 { |
171 ASSERT(mode == disabledKeyword() || mode == hiddenKeyword() || mode == showi
ngKeyword()); | 165 ASSERT(mode == disabledKeyword() || mode == hiddenKeyword() || mode == showi
ngKeyword()); |
172 | 166 |
173 // On setting, if the new value isn't equal to what the attribute would curr
ently | 167 // On setting, if the new value isn't equal to what the attribute would curr
ently |
174 // return, the new value must be processed as follows ... | 168 // return, the new value must be processed as follows ... |
175 if (m_mode == mode) | 169 if (m_mode == mode) |
176 return; | 170 return; |
177 | 171 |
178 // If mode changes to disabled, remove this track's cues from the client | 172 // If mode changes to disabled, remove this track's cues from the client |
179 // because they will no longer be accessible from the cues() function. | 173 // because they will no longer be accessible from the cues() function. |
180 if (mode == disabledKeyword() && m_client && m_cues) | 174 if (mode == disabledKeyword() && mediaElement() && m_cues) |
181 m_client->textTrackRemoveCues(this, m_cues.get()); | 175 mediaElement()->textTrackRemoveCues(this, m_cues.get()); |
182 | 176 |
183 if (mode != showingKeyword() && m_cues) | 177 if (mode != showingKeyword() && m_cues) |
184 for (size_t i = 0; i < m_cues->length(); ++i) | 178 for (size_t i = 0; i < m_cues->length(); ++i) |
185 m_cues->item(i)->removeDisplayTree(); | 179 m_cues->item(i)->removeDisplayTree(); |
186 | 180 |
187 m_mode = mode; | 181 m_mode = mode; |
188 | 182 |
189 if (m_client) | 183 if (mediaElement()) |
190 m_client->textTrackModeChanged(this); | 184 mediaElement()->textTrackModeChanged(this); |
191 } | 185 } |
192 | 186 |
193 TextTrackCueList* TextTrack::cues() | 187 TextTrackCueList* TextTrack::cues() |
194 { | 188 { |
195 // 4.8.10.12.5 If the text track mode ... is not the text track disabled mod
e, | 189 // 4.8.10.12.5 If the text track mode ... is not the text track disabled mod
e, |
196 // then the cues attribute must return a live TextTrackCueList object ... | 190 // then the cues attribute must return a live TextTrackCueList object ... |
197 // Otherwise, it must return null. When an object is returned, the | 191 // Otherwise, it must return null. When an object is returned, the |
198 // same object must be returned each time. | 192 // same object must be returned each time. |
199 // http://www.whatwg.org/specs/web-apps/current-work/#dom-texttrack-cues | 193 // http://www.whatwg.org/specs/web-apps/current-work/#dom-texttrack-cues |
200 if (m_mode != disabledKeyword()) | 194 if (m_mode != disabledKeyword()) |
201 return ensureTextTrackCueList(); | 195 return ensureTextTrackCueList(); |
202 return 0; | 196 return 0; |
203 } | 197 } |
204 | 198 |
205 void TextTrack::removeAllCues() | 199 void TextTrack::removeAllCues() |
206 { | 200 { |
207 if (!m_cues) | 201 if (!m_cues) |
208 return; | 202 return; |
209 | 203 |
210 if (m_client) | 204 if (mediaElement()) |
211 m_client->textTrackRemoveCues(this, m_cues.get()); | 205 mediaElement()->textTrackRemoveCues(this, m_cues.get()); |
212 | 206 |
213 for (size_t i = 0; i < m_cues->length(); ++i) | 207 for (size_t i = 0; i < m_cues->length(); ++i) |
214 m_cues->item(i)->setTrack(0); | 208 m_cues->item(i)->setTrack(0); |
215 | 209 |
216 m_cues = nullptr; | 210 m_cues = nullptr; |
217 } | 211 } |
218 | 212 |
219 TextTrackCueList* TextTrack::activeCues() const | 213 TextTrackCueList* TextTrack::activeCues() const |
220 { | 214 { |
221 // 4.8.10.12.5 If the text track mode ... is not the text track disabled mod
e, | 215 // 4.8.10.12.5 If the text track mode ... is not the text track disabled mod
e, |
(...skipping 25 matching lines...) Expand all Loading... |
247 // 1. If the given cue is in a text track list of cues, then remove cue from
that text track | 241 // 1. If the given cue is in a text track list of cues, then remove cue from
that text track |
248 // list of cues. | 242 // list of cues. |
249 TextTrack* cueTrack = cue->track(); | 243 TextTrack* cueTrack = cue->track(); |
250 if (cueTrack && cueTrack != this) | 244 if (cueTrack && cueTrack != this) |
251 cueTrack->removeCue(cue.get(), ASSERT_NO_EXCEPTION); | 245 cueTrack->removeCue(cue.get(), ASSERT_NO_EXCEPTION); |
252 | 246 |
253 // 2. Add cue to the method's TextTrack object's text track's text track lis
t of cues. | 247 // 2. Add cue to the method's TextTrack object's text track's text track lis
t of cues. |
254 cue->setTrack(this); | 248 cue->setTrack(this); |
255 ensureTextTrackCueList()->add(cue); | 249 ensureTextTrackCueList()->add(cue); |
256 | 250 |
257 if (m_client) | 251 if (mediaElement()) |
258 m_client->textTrackAddCue(this, cue.get()); | 252 mediaElement()->textTrackAddCue(this, cue.get()); |
259 } | 253 } |
260 | 254 |
261 void TextTrack::removeCue(TextTrackCue* cue, ExceptionState& exceptionState) | 255 void TextTrack::removeCue(TextTrackCue* cue, ExceptionState& exceptionState) |
262 { | 256 { |
263 if (!cue) | 257 if (!cue) |
264 return; | 258 return; |
265 | 259 |
266 // 4.8.10.12.5 Text track API | 260 // 4.8.10.12.5 Text track API |
267 | 261 |
268 // The removeCue(cue) method of TextTrack objects, when invoked, must run th
e following steps: | 262 // The removeCue(cue) method of TextTrack objects, when invoked, must run th
e following steps: |
269 | 263 |
270 // 1. If the given cue is not currently listed in the method's TextTrack | 264 // 1. If the given cue is not currently listed in the method's TextTrack |
271 // object's text track's text track list of cues, then throw a NotFoundError
exception. | 265 // object's text track's text track list of cues, then throw a NotFoundError
exception. |
272 if (cue->track() != this) { | 266 if (cue->track() != this) { |
273 exceptionState.throwDOMException(NotFoundError, "The specified cue is no
t listed in the TextTrack's list of cues."); | 267 exceptionState.throwDOMException(NotFoundError, "The specified cue is no
t listed in the TextTrack's list of cues."); |
274 return; | 268 return; |
275 } | 269 } |
276 | 270 |
277 // 2. Remove cue from the method's TextTrack object's text track's text trac
k list of cues. | 271 // 2. Remove cue from the method's TextTrack object's text track's text trac
k list of cues. |
278 if (!m_cues || !m_cues->remove(cue)) { | 272 if (!m_cues || !m_cues->remove(cue)) { |
279 exceptionState.throwDOMException(InvalidStateError, "Failed to remove th
e specified cue."); | 273 exceptionState.throwDOMException(InvalidStateError, "Failed to remove th
e specified cue."); |
280 return; | 274 return; |
281 } | 275 } |
282 | 276 |
283 cue->setTrack(0); | 277 cue->setTrack(0); |
284 if (m_client) | 278 if (mediaElement()) |
285 m_client->textTrackRemoveCue(this, cue); | 279 mediaElement()->textTrackRemoveCue(this, cue); |
286 } | 280 } |
287 | 281 |
288 VTTRegionList* TextTrack::ensureVTTRegionList() | 282 VTTRegionList* TextTrack::ensureVTTRegionList() |
289 { | 283 { |
290 if (!m_regions) | 284 if (!m_regions) |
291 m_regions = VTTRegionList::create(); | 285 m_regions = VTTRegionList::create(); |
292 | 286 |
293 return m_regions.get(); | 287 return m_regions.get(); |
294 } | 288 } |
295 | 289 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 if (!m_regions || !m_regions->remove(region)) { | 345 if (!m_regions || !m_regions->remove(region)) { |
352 exceptionState.throwDOMException(InvalidStateError, "Failed to remove th
e specified region."); | 346 exceptionState.throwDOMException(InvalidStateError, "Failed to remove th
e specified region."); |
353 return; | 347 return; |
354 } | 348 } |
355 | 349 |
356 region->setTrack(0); | 350 region->setTrack(0); |
357 } | 351 } |
358 | 352 |
359 void TextTrack::cueWillChange(TextTrackCue* cue) | 353 void TextTrack::cueWillChange(TextTrackCue* cue) |
360 { | 354 { |
361 if (!m_client) | 355 if (!mediaElement()) |
362 return; | 356 return; |
363 | 357 |
364 // The cue may need to be repositioned in the media element's interval tree,
may need to | 358 // The cue may need to be repositioned in the media element's interval tree,
may need to |
365 // be re-rendered, etc, so remove it before the modification... | 359 // be re-rendered, etc, so remove it before the modification... |
366 m_client->textTrackRemoveCue(this, cue); | 360 mediaElement()->textTrackRemoveCue(this, cue); |
367 } | 361 } |
368 | 362 |
369 void TextTrack::cueDidChange(TextTrackCue* cue) | 363 void TextTrack::cueDidChange(TextTrackCue* cue) |
370 { | 364 { |
371 if (!m_client) | 365 if (!mediaElement()) |
372 return; | 366 return; |
373 | 367 |
374 // Make sure the TextTrackCueList order is up-to-date. | 368 // Make sure the TextTrackCueList order is up-to-date. |
375 ensureTextTrackCueList()->updateCueIndex(cue); | 369 ensureTextTrackCueList()->updateCueIndex(cue); |
376 | 370 |
377 // ... and add it back again. | 371 // ... and add it back again. |
378 m_client->textTrackAddCue(this, cue); | 372 mediaElement()->textTrackAddCue(this, cue); |
379 } | 373 } |
380 | 374 |
381 int TextTrack::trackIndex() | 375 int TextTrack::trackIndex() |
382 { | 376 { |
383 ASSERT(m_trackList); | 377 ASSERT(m_trackList); |
384 | 378 |
385 if (m_trackIndex == invalidTrackIndex) | 379 if (m_trackIndex == invalidTrackIndex) |
386 m_trackIndex = m_trackList->getTrackIndex(this); | 380 m_trackIndex = m_trackList->getTrackIndex(this); |
387 | 381 |
388 return m_trackIndex; | 382 return m_trackIndex; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 const AtomicString& TextTrack::interfaceName() const | 420 const AtomicString& TextTrack::interfaceName() const |
427 { | 421 { |
428 return EventTargetNames::TextTrack; | 422 return EventTargetNames::TextTrack; |
429 } | 423 } |
430 | 424 |
431 ExecutionContext* TextTrack::executionContext() const | 425 ExecutionContext* TextTrack::executionContext() const |
432 { | 426 { |
433 return m_document; | 427 return m_document; |
434 } | 428 } |
435 | 429 |
| 430 HTMLMediaElement* TextTrack::mediaElement() |
| 431 { |
| 432 return m_trackList ? m_trackList->owner() : 0; |
| 433 } |
| 434 |
436 } // namespace WebCore | 435 } // namespace WebCore |
OLD | NEW |