1 /* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 24 */ 25 26 #include "config.h" 27 #include "core/html/track/LoadableTextTrack.h" 28 29 #include "core/dom/ElementTraversal.h" 30 #include "core/html/HTMLMediaElement.h" 31 #include "core/html/HTMLTrackElement.h" 32 #include "core/html/track/TextTrackCueList.h" 33 #include "core/html/track/vtt/VTTRegionList.h" 34 35 namespace WebCore { 36 37 using namespace HTMLNames; 38 39 LoadableTextTrack::LoadableTextTrack(HTMLTrackElement* track) 40 : TextTrack(track->document(), emptyAtom, emptyAtom, emptyAtom, emptyAtom, TrackElement) 41 , m_trackElement(track) 42 , m_loadTimer(this, &LoadableTextTrack::loadTimerFired) 43 , m_isDefault(false) 44 { 45 } 46 47 LoadableTextTrack::~LoadableTextTrack() 48 { 49 #if !ENABLE(OILPAN) 50 ASSERT(!m_trackElement); 51 #endif 52 } 53 54 #if !ENABLE(OILPAN) 55 void LoadableTextTrack::clearTrackElement() 56 { 57 m_trackElement = nullptr; 58 } 59 #endif 60 61 void LoadableTextTrack::setMode(const AtomicString& mode) 62 { 63 TextTrack::setMode(mode); 64 if (!m_trackElement) 65 return; 66 67 if (m_trackElement->readyState() == HTMLTrackElement::NONE) 68 m_trackElement->scheduleLoad(); 69 } 70 71 void LoadableTextTrack::scheduleLoad(const KURL& url) 72 { 73 if (url == m_url) { 74 // If loading of the resource from this URL is in progress, return early. 75 ASSERT(m_loader && m_trackElement); 76 if (m_loader->loadState() < TextTrackLoader::Finished) 77 return; 78 79 // The track element might have changed its state to HTMLTrackElement::Loading 80 // waiting for a call to didCompleteLoad to continue. 81 cueLoadingCompleted(m_loader.get(), m_loader->loadState() == TextTrackLoader::Failed); 82 return; 83 } 84 85 // 4.8.10.12.3 Sourcing out-of-band text tracks (continued) 86 87 // 2. Let URL be the track URL of the track element. 88 m_url = url; 89 90 // 3. Asynchronously run the remaining steps, while continuing with whatever task 91 // was responsible for creating the text track or changing the text track mode. 92 if (!m_loadTimer.isActive()) 93 m_loadTimer.startOneShot(0, FROM_HERE); 94 } 95 96 void LoadableTextTrack::loadTimerFired(Timer<LoadableTextTrack>*) 97 { 98 if (m_loader) 99 m_loader->cancelLoad(); 100 101 if (!m_trackElement) 102 return; 103 104 // 4.8.10.12.3 Sourcing out-of-band text tracks (continued) 105 106 // 4. Download: If URL is not the empty string, perform a potentially CORS-enabled fetch of URL, with the 107 // mode being the state of the media element's crossorigin content attribute, the origin being the 108 // origin of the media element's Document, and the default origin behaviour set to fail. 109 m_loader = TextTrackLoader::create(*this, m_trackElement->document()); 110 if (!m_loader->load(m_url, m_trackElement->mediaElementCrossOriginAttribute())) 111 m_trackElement->didCompleteLoad(HTMLTrackElement::Failure); 112 } 113 114 void LoadableTextTrack::newCuesAvailable(TextTrackLoader* loader) 115 { 116 ASSERT_UNUSED(loader, m_loader == loader); 117 118 WillBeHeapVector<RefPtrWillBeMember<VTTCue> > newCues; 119 m_loader->getNewCues(newCues); 120 121 if (!m_cues) 122 m_cues = TextTrackCueList::create(); 123 124 for (size_t i = 0; i < newCues.size(); ++i) { 125 newCues[i]->setTrack(this); 126 m_cues->add(newCues[i].release()); 127 } 128 129 if (mediaElement()) 130 mediaElement()->textTrackAddCues(this, m_cues.get()); 131 } 132 133 void LoadableTextTrack::cueLoadingCompleted(TextTrackLoader* loader, bool loadingFailed) 134 { 135 ASSERT_UNUSED(loader, m_loader == loader); 136 137 if (!m_trackElement) 138 return; 139 140 m_trackElement->didCompleteLoad(loadingFailed ? HTMLTrackElement::Failure : HTMLTrackElement::Success); 141 } 142 143 void LoadableTextTrack::newRegionsAvailable(TextTrackLoader* loader) 144 { 145 ASSERT_UNUSED(loader, m_loader == loader); 146 147 WillBeHeapVector<RefPtrWillBeMember<VTTRegion> > newRegions; 148 m_loader->getNewRegions(newRegions); 149 150 for (size_t i = 0; i < newRegions.size(); ++i) { 151 newRegions[i]->setTrack(this); 152 regions()->add(newRegions[i]); 153 } 154 } 155 156 size_t LoadableTextTrack::trackElementIndex() 157 { 158 ASSERT(m_trackElement); 159 ASSERT(m_trackElement->parentNode()); 160 161 size_t index = 0; 162 for (HTMLTrackElement* track = Traversal<HTMLTrackElement>::firstChild(*m_trackElement->parentNode()); track; track = Traversal<HTMLTrackElement>::nextSibling(*track)) { 163 if (!track->parentNode()) 164 continue; 165 if (track == m_trackElement) 166 return index; 167 ++index; 168 } 169 ASSERT_NOT_REACHED(); 170 171 return 0; 172 } 173 174 void LoadableTextTrack::trace(Visitor* visitor) 175 { 176 visitor->trace(m_trackElement); 177 visitor->trace(m_loader); 178 TextTrack::trace(visitor); 179 } 180 181 } // namespace WebCore 182