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 blink { 36 37 using namespace HTMLNames; 38 39 LoadableTextTrack::LoadableTextTrack(HTMLTrackElement* track) 40 : TextTrack(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 !ENABLE(OILPAN) 65 if (!m_trackElement) 66 return; 67 #endif 68 69 if (m_trackElement->readyState() == HTMLTrackElement::NONE) 70 m_trackElement->scheduleLoad(); 71 } 72 73 void LoadableTextTrack::scheduleLoad(const KURL& url) 74 { 75 if (url == m_url) { 76 // If loading of the resource from this URL is in progress, return early. 77 ASSERT(m_loader && m_trackElement); 78 if (m_loader->loadState() < TextTrackLoader::Finished) 79 return; 80 81 // The track element might have changed its state to HTMLTrackElement::Loading 82 // waiting for a call to didCompleteLoad to continue. 83 cueLoadingCompleted(m_loader.get(), m_loader->loadState() == TextTrackLoader::Failed); 84 return; 85 } 86 87 // 4.8.10.12.3 Sourcing out-of-band text tracks (continued) 88 89 // 2. Let URL be the track URL of the track element. 90 m_url = url; 91 92 // 3. Asynchronously run the remaining steps, while continuing with whatever task 93 // was responsible for creating the text track or changing the text track mode. 94 if (!m_loadTimer.isActive()) 95 m_loadTimer.startOneShot(0, FROM_HERE); 96 } 97 98 void LoadableTextTrack::loadTimerFired(Timer<LoadableTextTrack>*) 99 { 100 if (m_loader) 101 m_loader->cancelLoad(); 102 103 #if !ENABLE(OILPAN) 104 if (!m_trackElement) 105 return; 106 #endif 107 108 // 4.8.10.12.3 Sourcing out-of-band text tracks (continued) 109 110 // 4. Download: If URL is not the empty string, perform a potentially CORS-enabled fetch of URL, with the 111 // mode being the state of the media element's crossorigin content attribute, the origin being the 112 // origin of the media element's Document, and the default origin behaviour set to fail. 113 m_loader = TextTrackLoader::create(*this, m_trackElement->document()); 114 if (!m_loader->load(m_url, m_trackElement->mediaElementCrossOriginAttribute())) 115 m_trackElement->didCompleteLoad(HTMLTrackElement::Failure); 116 } 117 118 void LoadableTextTrack::newCuesAvailable(TextTrackLoader* loader) 119 { 120 ASSERT_UNUSED(loader, m_loader == loader); 121 122 WillBeHeapVector<RefPtrWillBeMember<VTTCue> > newCues; 123 m_loader->getNewCues(newCues); 124 125 if (!m_cues) 126 m_cues = TextTrackCueList::create(); 127 128 for (size_t i = 0; i < newCues.size(); ++i) { 129 newCues[i]->setTrack(this); 130 m_cues->add(newCues[i].release()); 131 } 132 133 if (mediaElement()) 134 mediaElement()->textTrackAddCues(this, m_cues.get()); 135 } 136 137 void LoadableTextTrack::cueLoadingCompleted(TextTrackLoader* loader, bool loadingFailed) 138 { 139 ASSERT_UNUSED(loader, m_loader == loader); 140 141 #if !ENABLE(OILPAN) 142 if (!m_trackElement) 143 return; 144 #endif 145 146 m_trackElement->didCompleteLoad(loadingFailed ? HTMLTrackElement::Failure : HTMLTrackElement::Success); 147 } 148 149 void LoadableTextTrack::newRegionsAvailable(TextTrackLoader* loader) 150 { 151 ASSERT_UNUSED(loader, m_loader == loader); 152 153 WillBeHeapVector<RefPtrWillBeMember<VTTRegion> > newRegions; 154 m_loader->getNewRegions(newRegions); 155 156 for (size_t i = 0; i < newRegions.size(); ++i) { 157 newRegions[i]->setTrack(this); 158 regions()->add(newRegions[i]); 159 } 160 } 161 162 size_t LoadableTextTrack::trackElementIndex() 163 { 164 ASSERT(m_trackElement); 165 ASSERT(m_trackElement->parentNode()); 166 167 size_t index = 0; 168 for (HTMLTrackElement* track = Traversal<HTMLTrackElement>::firstChild(*m_trackElement->parentNode()); track; track = Traversal<HTMLTrackElement>::nextSibling(*track)) { 169 if (!track->parentNode()) 170 continue; 171 if (track == m_trackElement) 172 return index; 173 ++index; 174 } 175 ASSERT_NOT_REACHED(); 176 177 return 0; 178 } 179 180 void LoadableTextTrack::trace(Visitor* visitor) 181 { 182 visitor->trace(m_trackElement); 183 visitor->trace(m_loader); 184 TextTrack::trace(visitor); 185 } 186 187 } // namespace blink 188