blob: b93297e3a4228d00cc3452545436f039c79aa9df [file] [log] [blame]
/*
* Copyright (C) 2011, 2013 Google Inc. All rights reserved.
* Copyright (C) 2011-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "LoadableTextTrack.h"
#if ENABLE(VIDEO)
#include "Document.h"
#include "ElementInlines.h"
#include "HTMLTrackElement.h"
#include "TextTrackCueList.h"
#include "VTTCue.h"
#include "VTTRegionList.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/SetForScope.h>
namespace WebCore {
WTF_MAKE_ISO_ALLOCATED_IMPL(LoadableTextTrack);
LoadableTextTrack::LoadableTextTrack(HTMLTrackElement& track, const String& kind, const String& label, const String& language)
: TextTrack(&track.document(), kind, emptyString(), label, language, TrackElement)
, m_trackElement(&track)
{
}
Ref<LoadableTextTrack> LoadableTextTrack::create(HTMLTrackElement& track, const String& kind, const String& label, const String& language)
{
auto textTrack = adoptRef(*new LoadableTextTrack(track, kind, label, language));
textTrack->suspendIfNeeded();
return textTrack;
}
void LoadableTextTrack::scheduleLoad(const URL& url)
{
ASSERT(!url.isEmpty());
if (url == m_url)
return;
// When src attribute is changed we need to flush all collected track data
removeAllCues();
if (!m_trackElement)
return;
// 4.8.10.12.3 Sourcing out-of-band text tracks (continued)
// 2. Let URL be the track URL of the track element.
m_url = url;
if (m_loadPending)
return;
// 3. Asynchronously run the remaining steps, while continuing with whatever task
// was responsible for creating the text track or changing the text track mode.
m_trackElement->scheduleTask([this]() mutable {
SetForScope<bool> loadPending { m_loadPending, true, false };
if (m_loader)
m_loader->cancelLoad();
if (!m_trackElement)
return;
// 4.8.10.12.3 Sourcing out-of-band text tracks (continued)
// 4. Download: If URL is not the empty string, perform a potentially CORS-enabled fetch of URL, with the
// mode being the state of the media element's crossorigin content attribute, the origin being the
// origin of the media element's Document, and the default origin behaviour set to fail.
m_loader = makeUnique<TextTrackLoader>(static_cast<TextTrackLoaderClient&>(*this), m_trackElement->document());
if (!m_loader->load(m_url, *m_trackElement))
m_trackElement->didCompleteLoad(HTMLTrackElement::Failure);
});
}
void LoadableTextTrack::newCuesAvailable(TextTrackLoader& loader)
{
ASSERT_UNUSED(loader, m_loader.get() == &loader);
if (!m_cues)
m_cues = TextTrackCueList::create();
for (auto& newCue : m_loader->getNewCues()) {
newCue->setTrack(this);
INFO_LOG(LOGIDENTIFIER, newCue.get());
m_cues->add(WTFMove(newCue));
}
TextTrack::newCuesAvailable(*m_cues);
}
void LoadableTextTrack::cueLoadingCompleted(TextTrackLoader& loader, bool loadingFailed)
{
ASSERT_UNUSED(loader, m_loader.get() == &loader);
if (!m_trackElement)
return;
INFO_LOG(LOGIDENTIFIER);
m_trackElement->didCompleteLoad(loadingFailed ? HTMLTrackElement::Failure : HTMLTrackElement::Success);
}
void LoadableTextTrack::newRegionsAvailable(TextTrackLoader& loader)
{
ASSERT_UNUSED(loader, m_loader.get() == &loader);
for (auto& newRegion : m_loader->getNewRegions()) {
newRegion->setTrack(this);
regions()->add(WTFMove(newRegion));
}
}
void LoadableTextTrack::newStyleSheetsAvailable(TextTrackLoader& loader)
{
ASSERT_UNUSED(loader, m_loader.get() == &loader);
m_styleSheets = m_loader->getNewStyleSheets();
}
AtomString LoadableTextTrack::id() const
{
if (!m_trackElement)
return emptyAtom();
return m_trackElement->attributeWithoutSynchronization(idAttr);
}
size_t LoadableTextTrack::trackElementIndex()
{
ASSERT(m_trackElement);
ASSERT(m_trackElement->parentNode());
size_t index = 0;
for (RefPtr<Node> node = m_trackElement->parentNode()->firstChild(); node; node = node->nextSibling()) {
if (!node->hasTagName(trackTag) || !node->parentNode())
continue;
if (node == m_trackElement)
return index;
++index;
}
ASSERT_NOT_REACHED();
return 0;
}
bool LoadableTextTrack::isDefault() const
{
return m_trackElement && m_trackElement->hasAttributeWithoutSynchronization(defaultAttr);
}
} // namespace WebCore
#endif