| 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; |
| 152 invalidateTrackIndex(); |
| 158 } | 153 } |
| 159 | 154 |
| 160 void TextTrack::setKind(const AtomicString& newKind) | 155 void TextTrack::setKind(const AtomicString& newKind) |
| 161 { | 156 { |
| 162 AtomicString oldKind = kind(); | 157 AtomicString oldKind = kind(); |
| 163 TrackBase::setKind(newKind); | 158 TrackBase::setKind(newKind); |
| 164 | 159 |
| 165 if (m_client && oldKind != kind()) | 160 if (mediaElement() && oldKind != kind()) |
| 166 m_client->textTrackKindChanged(this); | 161 mediaElement()->textTrackKindChanged(this); |
| 167 } | 162 } |
| 168 | 163 |
| 169 void TextTrack::setMode(const AtomicString& mode) | 164 void TextTrack::setMode(const AtomicString& mode) |
| 170 { | 165 { |
| 171 ASSERT(mode == disabledKeyword() || mode == hiddenKeyword() || mode == showi
ngKeyword()); | 166 ASSERT(mode == disabledKeyword() || mode == hiddenKeyword() || mode == showi
ngKeyword()); |
| 172 | 167 |
| 173 // On setting, if the new value isn't equal to what the attribute would curr
ently | 168 // 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 ... | 169 // return, the new value must be processed as follows ... |
| 175 if (m_mode == mode) | 170 if (m_mode == mode) |
| 176 return; | 171 return; |
| 177 | 172 |
| 178 // If mode changes to disabled, remove this track's cues from the client | 173 // 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. | 174 // because they will no longer be accessible from the cues() function. |
| 180 if (mode == disabledKeyword() && m_client && m_cues) | 175 if (mode == disabledKeyword() && mediaElement() && m_cues) |
| 181 m_client->textTrackRemoveCues(this, m_cues.get()); | 176 mediaElement()->textTrackRemoveCues(this, m_cues.get()); |
| 182 | 177 |
| 183 if (mode != showingKeyword() && m_cues) | 178 if (mode != showingKeyword() && m_cues) |
| 184 for (size_t i = 0; i < m_cues->length(); ++i) | 179 for (size_t i = 0; i < m_cues->length(); ++i) |
| 185 m_cues->item(i)->removeDisplayTree(); | 180 m_cues->item(i)->removeDisplayTree(); |
| 186 | 181 |
| 187 m_mode = mode; | 182 m_mode = mode; |
| 188 | 183 |
| 189 if (m_client) | 184 if (mediaElement()) |
| 190 m_client->textTrackModeChanged(this); | 185 mediaElement()->textTrackModeChanged(this); |
| 191 } | 186 } |
| 192 | 187 |
| 193 TextTrackCueList* TextTrack::cues() | 188 TextTrackCueList* TextTrack::cues() |
| 194 { | 189 { |
| 195 // 4.8.10.12.5 If the text track mode ... is not the text track disabled mod
e, | 190 // 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 ... | 191 // then the cues attribute must return a live TextTrackCueList object ... |
| 197 // Otherwise, it must return null. When an object is returned, the | 192 // Otherwise, it must return null. When an object is returned, the |
| 198 // same object must be returned each time. | 193 // same object must be returned each time. |
| 199 // http://www.whatwg.org/specs/web-apps/current-work/#dom-texttrack-cues | 194 // http://www.whatwg.org/specs/web-apps/current-work/#dom-texttrack-cues |
| 200 if (m_mode != disabledKeyword()) | 195 if (m_mode != disabledKeyword()) |
| 201 return ensureTextTrackCueList(); | 196 return ensureTextTrackCueList(); |
| 202 return 0; | 197 return 0; |
| 203 } | 198 } |
| 204 | 199 |
| 205 void TextTrack::removeAllCues() | 200 void TextTrack::removeAllCues() |
| 206 { | 201 { |
| 207 if (!m_cues) | 202 if (!m_cues) |
| 208 return; | 203 return; |
| 209 | 204 |
| 210 if (m_client) | 205 if (mediaElement()) |
| 211 m_client->textTrackRemoveCues(this, m_cues.get()); | 206 mediaElement()->textTrackRemoveCues(this, m_cues.get()); |
| 212 | 207 |
| 213 for (size_t i = 0; i < m_cues->length(); ++i) | 208 for (size_t i = 0; i < m_cues->length(); ++i) |
| 214 m_cues->item(i)->setTrack(0); | 209 m_cues->item(i)->setTrack(0); |
| 215 | 210 |
| 216 m_cues = nullptr; | 211 m_cues = nullptr; |
| 217 } | 212 } |
| 218 | 213 |
| 219 TextTrackCueList* TextTrack::activeCues() const | 214 TextTrackCueList* TextTrack::activeCues() const |
| 220 { | 215 { |
| 221 // 4.8.10.12.5 If the text track mode ... is not the text track disabled mod
e, | 216 // 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 | 242 // 1. If the given cue is in a text track list of cues, then remove cue from
that text track |
| 248 // list of cues. | 243 // list of cues. |
| 249 TextTrack* cueTrack = cue->track(); | 244 TextTrack* cueTrack = cue->track(); |
| 250 if (cueTrack && cueTrack != this) | 245 if (cueTrack && cueTrack != this) |
| 251 cueTrack->removeCue(cue.get(), ASSERT_NO_EXCEPTION); | 246 cueTrack->removeCue(cue.get(), ASSERT_NO_EXCEPTION); |
| 252 | 247 |
| 253 // 2. Add cue to the method's TextTrack object's text track's text track lis
t of cues. | 248 // 2. Add cue to the method's TextTrack object's text track's text track lis
t of cues. |
| 254 cue->setTrack(this); | 249 cue->setTrack(this); |
| 255 ensureTextTrackCueList()->add(cue); | 250 ensureTextTrackCueList()->add(cue); |
| 256 | 251 |
| 257 if (m_client) | 252 if (mediaElement()) |
| 258 m_client->textTrackAddCue(this, cue.get()); | 253 mediaElement()->textTrackAddCue(this, cue.get()); |
| 259 } | 254 } |
| 260 | 255 |
| 261 void TextTrack::removeCue(TextTrackCue* cue, ExceptionState& exceptionState) | 256 void TextTrack::removeCue(TextTrackCue* cue, ExceptionState& exceptionState) |
| 262 { | 257 { |
| 263 if (!cue) | 258 if (!cue) |
| 264 return; | 259 return; |
| 265 | 260 |
| 266 // 4.8.10.12.5 Text track API | 261 // 4.8.10.12.5 Text track API |
| 267 | 262 |
| 268 // The removeCue(cue) method of TextTrack objects, when invoked, must run th
e following steps: | 263 // The removeCue(cue) method of TextTrack objects, when invoked, must run th
e following steps: |
| 269 | 264 |
| 270 // 1. If the given cue is not currently listed in the method's TextTrack | 265 // 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. | 266 // object's text track's text track list of cues, then throw a NotFoundError
exception. |
| 272 if (cue->track() != this) { | 267 if (cue->track() != this) { |
| 273 exceptionState.throwDOMException(NotFoundError, "The specified cue is no
t listed in the TextTrack's list of cues."); | 268 exceptionState.throwDOMException(NotFoundError, "The specified cue is no
t listed in the TextTrack's list of cues."); |
| 274 return; | 269 return; |
| 275 } | 270 } |
| 276 | 271 |
| 277 // 2. Remove cue from the method's TextTrack object's text track's text trac
k list of cues. | 272 // 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)) { | 273 if (!m_cues || !m_cues->remove(cue)) { |
| 279 exceptionState.throwDOMException(InvalidStateError, "Failed to remove th
e specified cue."); | 274 exceptionState.throwDOMException(InvalidStateError, "Failed to remove th
e specified cue."); |
| 280 return; | 275 return; |
| 281 } | 276 } |
| 282 | 277 |
| 283 cue->setTrack(0); | 278 cue->setTrack(0); |
| 284 if (m_client) | 279 if (mediaElement()) |
| 285 m_client->textTrackRemoveCue(this, cue); | 280 mediaElement()->textTrackRemoveCue(this, cue); |
| 286 } | 281 } |
| 287 | 282 |
| 288 VTTRegionList* TextTrack::ensureVTTRegionList() | 283 VTTRegionList* TextTrack::ensureVTTRegionList() |
| 289 { | 284 { |
| 290 if (!m_regions) | 285 if (!m_regions) |
| 291 m_regions = VTTRegionList::create(); | 286 m_regions = VTTRegionList::create(); |
| 292 | 287 |
| 293 return m_regions.get(); | 288 return m_regions.get(); |
| 294 } | 289 } |
| 295 | 290 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 if (!m_regions || !m_regions->remove(region)) { | 346 if (!m_regions || !m_regions->remove(region)) { |
| 352 exceptionState.throwDOMException(InvalidStateError, "Failed to remove th
e specified region."); | 347 exceptionState.throwDOMException(InvalidStateError, "Failed to remove th
e specified region."); |
| 353 return; | 348 return; |
| 354 } | 349 } |
| 355 | 350 |
| 356 region->setTrack(0); | 351 region->setTrack(0); |
| 357 } | 352 } |
| 358 | 353 |
| 359 void TextTrack::cueWillChange(TextTrackCue* cue) | 354 void TextTrack::cueWillChange(TextTrackCue* cue) |
| 360 { | 355 { |
| 361 if (!m_client) | 356 if (!mediaElement()) |
| 362 return; | 357 return; |
| 363 | 358 |
| 364 // The cue may need to be repositioned in the media element's interval tree,
may need to | 359 // 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... | 360 // be re-rendered, etc, so remove it before the modification... |
| 366 m_client->textTrackRemoveCue(this, cue); | 361 mediaElement()->textTrackRemoveCue(this, cue); |
| 367 } | 362 } |
| 368 | 363 |
| 369 void TextTrack::cueDidChange(TextTrackCue* cue) | 364 void TextTrack::cueDidChange(TextTrackCue* cue) |
| 370 { | 365 { |
| 371 if (!m_client) | 366 if (!mediaElement()) |
| 372 return; | 367 return; |
| 373 | 368 |
| 374 // Make sure the TextTrackCueList order is up-to-date. | 369 // Make sure the TextTrackCueList order is up-to-date. |
| 375 ensureTextTrackCueList()->updateCueIndex(cue); | 370 ensureTextTrackCueList()->updateCueIndex(cue); |
| 376 | 371 |
| 377 // ... and add it back again. | 372 // ... and add it back again. |
| 378 m_client->textTrackAddCue(this, cue); | 373 mediaElement()->textTrackAddCue(this, cue); |
| 379 } | 374 } |
| 380 | 375 |
| 381 int TextTrack::trackIndex() | 376 int TextTrack::trackIndex() |
| 382 { | 377 { |
| 383 ASSERT(m_trackList); | 378 ASSERT(m_trackList); |
| 384 | 379 |
| 385 if (m_trackIndex == invalidTrackIndex) | 380 if (m_trackIndex == invalidTrackIndex) |
| 386 m_trackIndex = m_trackList->getTrackIndex(this); | 381 m_trackIndex = m_trackList->getTrackIndex(this); |
| 387 | 382 |
| 388 return m_trackIndex; | 383 return m_trackIndex; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 const AtomicString& TextTrack::interfaceName() const | 421 const AtomicString& TextTrack::interfaceName() const |
| 427 { | 422 { |
| 428 return EventTargetNames::TextTrack; | 423 return EventTargetNames::TextTrack; |
| 429 } | 424 } |
| 430 | 425 |
| 431 ExecutionContext* TextTrack::executionContext() const | 426 ExecutionContext* TextTrack::executionContext() const |
| 432 { | 427 { |
| 433 return m_document; | 428 return m_document; |
| 434 } | 429 } |
| 435 | 430 |
| 431 HTMLMediaElement* TextTrack::mediaElement() |
| 432 { |
| 433 return m_trackList ? m_trackList->owner() : 0; |
| 434 } |
| 435 |
| 436 } // namespace WebCore | 436 } // namespace WebCore |
| OLD | NEW |