| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| 11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
| 12 * | 12 * |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 #include "core/html/track/TextTrackList.h" | 27 #include "core/html/track/TextTrackList.h" |
| 28 | 28 |
| 29 #include "bindings/v8/ExceptionStatePlaceholder.h" | 29 #include "bindings/v8/ExceptionStatePlaceholder.h" |
| 30 #include "core/events/GenericEventQueue.h" |
| 30 #include "core/events/ThreadLocalEventNames.h" | 31 #include "core/events/ThreadLocalEventNames.h" |
| 31 #include "core/html/HTMLMediaElement.h" | 32 #include "core/html/HTMLMediaElement.h" |
| 32 #include "core/html/track/InbandTextTrack.h" | 33 #include "core/html/track/InbandTextTrack.h" |
| 33 #include "core/html/track/LoadableTextTrack.h" | 34 #include "core/html/track/LoadableTextTrack.h" |
| 34 #include "core/html/track/TextTrack.h" | 35 #include "core/html/track/TextTrack.h" |
| 35 #include "core/html/track/TrackEvent.h" | 36 #include "core/html/track/TrackEvent.h" |
| 36 | 37 |
| 37 using namespace WebCore; | 38 using namespace WebCore; |
| 38 | 39 |
| 39 TextTrackList::TextTrackList(HTMLMediaElement* owner) | 40 TextTrackList::TextTrackList(HTMLMediaElement* owner) |
| 40 : m_owner(owner) | 41 : m_owner(owner) |
| 41 , m_pendingEventTimer(this, &TextTrackList::asyncEventTimerFired) | 42 , m_asyncEventQueue(GenericEventQueue::create(this)) |
| 42 , m_dispatchingEvents(0) | |
| 43 { | 43 { |
| 44 ScriptWrappable::init(this); | 44 ScriptWrappable::init(this); |
| 45 } | 45 } |
| 46 | 46 |
| 47 TextTrackList::~TextTrackList() | 47 TextTrackList::~TextTrackList() |
| 48 { | 48 { |
| 49 m_asyncEventQueue->close(); |
| 49 } | 50 } |
| 50 | 51 |
| 51 unsigned TextTrackList::length() const | 52 unsigned TextTrackList::length() const |
| 52 { | 53 { |
| 53 return m_addTrackTracks.size() + m_elementTracks.size() + m_inbandTracks.siz
e(); | 54 return m_addTrackTracks.size() + m_elementTracks.size() + m_inbandTracks.siz
e(); |
| 54 } | 55 } |
| 55 | 56 |
| 56 int TextTrackList::getTrackIndex(TextTrack *textTrack) | 57 int TextTrackList::getTrackIndex(TextTrack *textTrack) |
| 57 { | 58 { |
| 58 if (textTrack->trackType() == TextTrack::TrackElement) | 59 if (textTrack->trackType() == TextTrack::TrackElement) |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 | 220 |
| 220 invalidateTrackIndexesAfterTrack(track); | 221 invalidateTrackIndexesAfterTrack(track); |
| 221 | 222 |
| 222 ASSERT(track->mediaElement() == m_owner); | 223 ASSERT(track->mediaElement() == m_owner); |
| 223 track->setMediaElement(0); | 224 track->setMediaElement(0); |
| 224 | 225 |
| 225 tracks->remove(index); | 226 tracks->remove(index); |
| 226 | 227 |
| 227 if (inbandTrack) | 228 if (inbandTrack) |
| 228 inbandTrack->trackRemoved(); | 229 inbandTrack->trackRemoved(); |
| 230 |
| 231 scheduleRemoveTrackEvent(track); |
| 229 } | 232 } |
| 230 | 233 |
| 231 bool TextTrackList::contains(TextTrack* track) const | 234 bool TextTrackList::contains(TextTrack* track) const |
| 232 { | 235 { |
| 233 const Vector<RefPtr<TextTrack> >* tracks = 0; | 236 const Vector<RefPtr<TextTrack> >* tracks = 0; |
| 234 | 237 |
| 235 if (track->trackType() == TextTrack::TrackElement) | 238 if (track->trackType() == TextTrack::TrackElement) |
| 236 tracks = &m_elementTracks; | 239 tracks = &m_elementTracks; |
| 237 else if (track->trackType() == TextTrack::AddTrack) | 240 else if (track->trackType() == TextTrack::AddTrack) |
| 238 tracks = &m_addTrackTracks; | 241 tracks = &m_addTrackTracks; |
| 239 else if (track->trackType() == TextTrack::InBand) | 242 else if (track->trackType() == TextTrack::InBand) |
| 240 tracks = &m_inbandTracks; | 243 tracks = &m_inbandTracks; |
| 241 else | 244 else |
| 242 ASSERT_NOT_REACHED(); | 245 ASSERT_NOT_REACHED(); |
| 243 | 246 |
| 244 return tracks->find(track) != kNotFound; | 247 return tracks->find(track) != kNotFound; |
| 245 } | 248 } |
| 246 | 249 |
| 247 const AtomicString& TextTrackList::interfaceName() const | 250 const AtomicString& TextTrackList::interfaceName() const |
| 248 { | 251 { |
| 249 return EventTargetNames::TextTrackList; | 252 return EventTargetNames::TextTrackList; |
| 250 } | 253 } |
| 251 | 254 |
| 252 ExecutionContext* TextTrackList::executionContext() const | 255 ExecutionContext* TextTrackList::executionContext() const |
| 253 { | 256 { |
| 254 ASSERT(m_owner); | 257 ASSERT(m_owner); |
| 255 return m_owner->executionContext(); | 258 return m_owner->executionContext(); |
| 256 } | 259 } |
| 257 | 260 |
| 261 void TextTrackList::scheduleTrackEvent(const AtomicString& eventName, PassRefPtr
<TextTrack> track) |
| 262 { |
| 263 TrackEventInit initializer; |
| 264 initializer.track = track; |
| 265 initializer.bubbles = false; |
| 266 initializer.cancelable = false; |
| 267 |
| 268 m_asyncEventQueue->enqueueEvent(TrackEvent::create(eventName, initializer)); |
| 269 } |
| 270 |
| 258 void TextTrackList::scheduleAddTrackEvent(PassRefPtr<TextTrack> track) | 271 void TextTrackList::scheduleAddTrackEvent(PassRefPtr<TextTrack> track) |
| 259 { | 272 { |
| 260 // 4.8.10.12.3 Sourcing out-of-band text tracks | 273 // 4.8.10.12.3 Sourcing out-of-band text tracks |
| 261 // 4.8.10.12.4 Text track API | 274 // 4.8.10.12.4 Text track API |
| 262 // ... then queue a task to fire an event with the name addtrack, that does
not | 275 // ... then queue a task to fire an event with the name addtrack, that does
not |
| 263 // bubble and is not cancelable, and that uses the TrackEvent interface, wit
h | 276 // bubble and is not cancelable, and that uses the TrackEvent interface, wit
h |
| 264 // the track attribute initialized to the text track's TextTrack object, at | 277 // the track attribute initialized to the text track's TextTrack object, at |
| 265 // the media element's textTracks attribute's TextTrackList object. | 278 // the media element's textTracks attribute's TextTrackList object. |
| 279 scheduleTrackEvent(EventTypeNames::addtrack, track); |
| 280 } |
| 266 | 281 |
| 267 RefPtr<TextTrack> trackRef = track; | 282 void TextTrackList::scheduleChangeEvent() |
| 268 TrackEventInit initializer; | 283 { |
| 269 initializer.track = trackRef; | 284 // 4.8.10.12.1 Text track model |
| 285 // Whenever a text track that is in a media element's list of text tracks |
| 286 // has its text track mode change value, the user agent must run the |
| 287 // following steps for the media element: |
| 288 // ... |
| 289 // Fire a simple event named change at the media element's textTracks |
| 290 // attribute's TextTrackList object. |
| 291 |
| 292 EventInit initializer; |
| 270 initializer.bubbles = false; | 293 initializer.bubbles = false; |
| 271 initializer.cancelable = false; | 294 initializer.cancelable = false; |
| 272 | 295 |
| 273 m_pendingEvents.append(TrackEvent::create(EventTypeNames::addtrack, initiali
zer)); | 296 m_asyncEventQueue->enqueueEvent(Event::create(EventTypeNames::change, initia
lizer)); |
| 274 if (!m_pendingEventTimer.isActive()) | |
| 275 m_pendingEventTimer.startOneShot(0); | |
| 276 } | 297 } |
| 277 | 298 |
| 278 void TextTrackList::asyncEventTimerFired(Timer<TextTrackList>*) | 299 void TextTrackList::scheduleRemoveTrackEvent(PassRefPtr<TextTrack> track) |
| 279 { | 300 { |
| 280 Vector<RefPtr<Event> > pendingEvents; | 301 // 4.8.10.12.3 Sourcing out-of-band text tracks |
| 281 | 302 // When a track element's parent element changes and the old parent was a |
| 282 ++m_dispatchingEvents; | 303 // media element, then the user agent must remove the track element's |
| 283 m_pendingEvents.swap(pendingEvents); | 304 // corresponding text track from the media element's list of text tracks, |
| 284 size_t count = pendingEvents.size(); | 305 // and then queue a task to fire a trusted event with the name removetrack, |
| 285 for (size_t index = 0; index < count; ++index) | 306 // that does not bubble and is not cancelable, and that uses the TrackEvent |
| 286 dispatchEvent(pendingEvents[index].release(), IGNORE_EXCEPTION); | 307 // interface, with the track attribute initialized to the text track's |
| 287 --m_dispatchingEvents; | 308 // TextTrack object, at the media element's textTracks attribute's |
| 309 // TextTrackList object. |
| 310 scheduleTrackEvent(EventTypeNames::removetrack, track); |
| 288 } | 311 } |
| 289 | 312 |
| 290 Node* TextTrackList::owner() const | 313 Node* TextTrackList::owner() const |
| 291 { | 314 { |
| 292 return m_owner; | 315 return m_owner; |
| 293 } | 316 } |
| OLD | NEW |