summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/HTMLTrackElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/html/HTMLTrackElement.cpp')
-rw-r--r--Source/WebCore/html/HTMLTrackElement.cpp201
1 files changed, 91 insertions, 110 deletions
diff --git a/Source/WebCore/html/HTMLTrackElement.cpp b/Source/WebCore/html/HTMLTrackElement.cpp
index 449b63268..668b812b8 100644
--- a/Source/WebCore/html/HTMLTrackElement.cpp
+++ b/Source/WebCore/html/HTMLTrackElement.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011, 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +11,10 @@
* 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * 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 COMPUTER, INC. OR
+ * 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
@@ -24,11 +25,13 @@
*/
#include "config.h"
-#if ENABLE(VIDEO_TRACK)
#include "HTMLTrackElement.h"
+#if ENABLE(VIDEO_TRACK)
+
#include "ContentSecurityPolicy.h"
#include "Event.h"
+#include "EventNames.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "Logging.h"
@@ -40,6 +43,7 @@ namespace WebCore {
using namespace HTMLNames;
#if !LOG_DISABLED
+
static String urlForLoggingTrack(const URL& url)
{
static const unsigned maximumURLLengthForLogging = 128;
@@ -48,11 +52,12 @@ static String urlForLoggingTrack(const URL& url)
return url.string();
return url.string().substring(0, maximumURLLengthForLogging) + "...";
}
+
#endif
inline HTMLTrackElement::HTMLTrackElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
- , m_loadTimer(this, &HTMLTrackElement::loadTimerFired)
+ , m_loadTimer(*this, &HTMLTrackElement::loadTimerFired)
{
LOG(Media, "HTMLTrackElement::HTMLTrackElement - %p", this);
ASSERT(hasTagName(trackTag));
@@ -60,119 +65,101 @@ inline HTMLTrackElement::HTMLTrackElement(const QualifiedName& tagName, Document
HTMLTrackElement::~HTMLTrackElement()
{
- if (m_track)
+ if (m_track) {
+ m_track->clearElement();
m_track->clearClient();
+ }
}
-PassRefPtr<HTMLTrackElement> HTMLTrackElement::create(const QualifiedName& tagName, Document& document)
+Ref<HTMLTrackElement> HTMLTrackElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(new HTMLTrackElement(tagName, document));
+ return adoptRef(*new HTMLTrackElement(tagName, document));
}
Node::InsertionNotificationRequest HTMLTrackElement::insertedInto(ContainerNode& insertionPoint)
{
+ HTMLElement::insertedInto(insertionPoint);
+
+ if (is<HTMLMediaElement>(insertionPoint))
+ downcast<HTMLMediaElement>(insertionPoint).didAddTextTrack(*this);
+
// Since we've moved to a new parent, we may now be able to load.
scheduleLoad();
- HTMLElement::insertedInto(insertionPoint);
- HTMLMediaElement* parent = mediaElement();
- if (&insertionPoint == parent) {
- ensureTrack();
- parent->didAddTextTrack(this);
- }
return InsertionDone;
}
void HTMLTrackElement::removedFrom(ContainerNode& insertionPoint)
{
- if (!parentNode() && isHTMLMediaElement(insertionPoint))
- toHTMLMediaElement(insertionPoint).didRemoveTextTrack(this);
HTMLElement::removedFrom(insertionPoint);
+
+ if (is<HTMLMediaElement>(insertionPoint))
+ downcast<HTMLMediaElement>(insertionPoint).didRemoveTextTrack(*this);
}
void HTMLTrackElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- if (RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled()) {
- if (name == srcAttr) {
- if (!value.isEmpty())
- scheduleLoad();
- else if (m_track)
- m_track->removeAllCues();
-
- // 4.8.10.12.3 Sourcing out-of-band text tracks
- // As the kind, label, and srclang attributes are set, changed, or removed, the text track must update accordingly...
- } else if (name == kindAttr)
- track()->setKind(value.lower());
- else if (name == labelAttr)
- track()->setLabel(value);
- else if (name == srclangAttr)
- track()->setLanguage(value);
- else if (name == defaultAttr)
- track()->setIsDefault(!value.isNull());
- }
-
- HTMLElement::parseAttribute(name, value);
-}
+ if (name == srcAttr) {
+ if (!value.isEmpty())
+ scheduleLoad();
+ else if (m_track)
+ m_track->removeAllCues();
-String HTMLTrackElement::kind()
-{
- return track()->kind();
-}
+ // 4.8.10.12.3 Sourcing out-of-band text tracks
+ // As the kind, label, and srclang attributes are set, changed, or removed, the text track must update accordingly...
+ } else if (name == kindAttr)
+ track().setKindKeywordIgnoringASCIICase(value.string());
+ else if (name == labelAttr)
+ track().setLabel(value);
+ else if (name == srclangAttr)
+ track().setLanguage(value);
+ else if (name == defaultAttr)
+ track().setIsDefault(!value.isNull());
-void HTMLTrackElement::setKind(const String& kind)
-{
- setAttribute(kindAttr, kind);
+ HTMLElement::parseAttribute(name, value);
}
-String HTMLTrackElement::srclang() const
+const AtomicString& HTMLTrackElement::kind()
{
- return getAttribute(srclangAttr);
+ return track().kindKeyword();
}
-void HTMLTrackElement::setSrclang(const String& srclang)
+void HTMLTrackElement::setKind(const AtomicString& kind)
{
- setAttribute(srclangAttr, srclang);
+ setAttributeWithoutSynchronization(kindAttr, kind);
}
-String HTMLTrackElement::label() const
+const AtomicString& HTMLTrackElement::srclang() const
{
- return getAttribute(labelAttr);
+ return attributeWithoutSynchronization(srclangAttr);
}
-void HTMLTrackElement::setLabel(const String& label)
+const AtomicString& HTMLTrackElement::label() const
{
- setAttribute(labelAttr, label);
+ return attributeWithoutSynchronization(labelAttr);
}
bool HTMLTrackElement::isDefault() const
{
- return fastHasAttribute(defaultAttr);
+ return hasAttributeWithoutSynchronization(defaultAttr);
}
-void HTMLTrackElement::setIsDefault(bool isDefault)
-{
- setBooleanAttribute(defaultAttr, isDefault);
-}
-
-LoadableTextTrack& HTMLTrackElement::ensureTrack()
+LoadableTextTrack& HTMLTrackElement::track()
{
+ // FIXME: There is no practical value in lazily initializing this.
+ // Instead this should be created in the constructor.
if (!m_track) {
- // The kind attribute is an enumerated attribute, limited only to know values. It defaults to 'subtitles' if missing or invalid.
- String kind = getAttribute(kindAttr).lower();
+ // The kind attribute is an enumerated attribute, limited only to known values. It defaults to 'subtitles' if missing or invalid.
+ String kind = attributeWithoutSynchronization(kindAttr).convertToASCIILowercase();
if (!TextTrack::isValidKindKeyword(kind))
kind = TextTrack::subtitlesKeyword();
- m_track = LoadableTextTrack::create(this, kind, label(), srclang());
- } else
- m_track->setTrackElement(this);
+ m_track = LoadableTextTrack::create(*this, kind, label(), srclang());
+ }
+ ASSERT(m_track->trackElement() == this);
return *m_track;
}
-TextTrack* HTMLTrackElement::track()
-{
- return &ensureTrack();
-}
-
bool HTMLTrackElement::isURLAttribute(const Attribute& attribute) const
{
return attribute.name() == srcAttr || HTMLElement::isURLAttribute(attribute);
@@ -185,11 +172,8 @@ void HTMLTrackElement::scheduleLoad()
if (m_loadTimer.isActive())
return;
- if (!RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
- return;
-
// 2. If the text track's text track mode is not set to one of hidden or showing, abort these steps.
- if (ensureTrack().mode() != TextTrack::hiddenKeyword() && ensureTrack().mode() != TextTrack::showingKeyword())
+ if (track().mode() != TextTrack::Mode::Hidden && track().mode() != TextTrack::Mode::Showing)
return;
// 3. If the text track's track element does not have a media element as a parent, abort these steps.
@@ -200,9 +184,9 @@ void HTMLTrackElement::scheduleLoad()
m_loadTimer.startOneShot(0);
}
-void HTMLTrackElement::loadTimerFired(Timer<HTMLTrackElement>&)
+void HTMLTrackElement::loadTimerFired()
{
- if (!fastHasAttribute(srcAttr))
+ if (!hasAttributeWithoutSynchronization(srcAttr))
return;
// 6. Set the text track readiness state to loading.
@@ -218,14 +202,11 @@ void HTMLTrackElement::loadTimerFired(Timer<HTMLTrackElement>&)
return;
}
- ensureTrack().scheduleLoad(url);
+ track().scheduleLoad(url);
}
bool HTMLTrackElement::canLoadURL(const URL& url)
{
- if (!RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
- return false;
-
HTMLMediaElement* parent = mediaElement();
if (!parent)
return false;
@@ -238,11 +219,13 @@ bool HTMLTrackElement::canLoadURL(const URL& url)
if (url.isEmpty())
return false;
- if (!document().contentSecurityPolicy()->allowMediaFromSource(url)) {
+ ASSERT(document().contentSecurityPolicy());
+ // Elements in user agent show tree should load whatever the embedding document policy is.
+ if (!isInUserAgentShadowTree() && !document().contentSecurityPolicy()->allowMediaFromSource(url)) {
LOG(Media, "HTMLTrackElement::canLoadURL(%s) -> rejected by Content Security Policy", urlForLoggingTrack(url).utf8().data());
return false;
}
-
+
return dispatchBeforeLoadEvent(url.string());
}
@@ -260,7 +243,7 @@ void HTMLTrackElement::didCompleteLoad(LoadStatus status)
if (status == Failure) {
setReadyState(HTMLTrackElement::TRACK_ERROR);
- dispatchEvent(Event::create(eventNames().errorEvent, false, false), IGNORE_EXCEPTION);
+ dispatchEvent(Event::create(eventNames().errorEvent, false, false));
return;
}
@@ -271,7 +254,7 @@ void HTMLTrackElement::didCompleteLoad(LoadStatus status)
// 2. If the file was successfully processed, fire a simple event named load at the
// track element.
- dispatchEvent(Event::create(eventNames().loadEvent, false, false), IGNORE_EXCEPTION);
+ dispatchEvent(Event::create(eventNames().loadEvent, false, false));
}
// NOTE: The values in the TextTrack::ReadinessState enum must stay in sync with those in HTMLTrackElement::ReadyState.
@@ -282,71 +265,69 @@ COMPILE_ASSERT(HTMLTrackElement::TRACK_ERROR == static_cast<HTMLTrackElement::Re
void HTMLTrackElement::setReadyState(ReadyState state)
{
- ensureTrack().setReadinessState(static_cast<TextTrack::ReadinessState>(state));
+ track().setReadinessState(static_cast<TextTrack::ReadinessState>(state));
if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackReadyStateChanged(m_track.get());
+ parent->textTrackReadyStateChanged(m_track.get());
}
HTMLTrackElement::ReadyState HTMLTrackElement::readyState()
{
- return static_cast<ReadyState>(ensureTrack().readinessState());
+ return static_cast<ReadyState>(track().readinessState());
}
const AtomicString& HTMLTrackElement::mediaElementCrossOriginAttribute() const
{
if (HTMLMediaElement* parent = mediaElement())
- return parent->fastGetAttribute(HTMLNames::crossoriginAttr);
-
+ return parent->attributeWithoutSynchronization(HTMLNames::crossoriginAttr);
return nullAtom;
}
-void HTMLTrackElement::textTrackKindChanged(TextTrack* track)
+void HTMLTrackElement::textTrackKindChanged(TextTrack& track)
{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackKindChanged(track);
+ if (auto* parent = mediaElement())
+ parent->textTrackKindChanged(track);
}
-void HTMLTrackElement::textTrackModeChanged(TextTrack* track)
+void HTMLTrackElement::textTrackModeChanged(TextTrack& track)
{
// Since we've moved to a new parent, we may now be able to load.
if (readyState() == HTMLTrackElement::NONE)
scheduleLoad();
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackModeChanged(track);
+ if (auto* parent = mediaElement())
+ parent->textTrackModeChanged(track);
}
-void HTMLTrackElement::textTrackAddCues(TextTrack* track, const TextTrackCueList* cues)
+void HTMLTrackElement::textTrackAddCues(TextTrack& track, const TextTrackCueList& cues)
{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackAddCues(track, cues);
+ if (auto* parent = mediaElement())
+ parent->textTrackAddCues(track, cues);
}
-void HTMLTrackElement::textTrackRemoveCues(TextTrack* track, const TextTrackCueList* cues)
+void HTMLTrackElement::textTrackRemoveCues(TextTrack& track, const TextTrackCueList& cues)
{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackRemoveCues(track, cues);
+ if (auto* parent = mediaElement())
+ parent->textTrackRemoveCues(track, cues);
}
-void HTMLTrackElement::textTrackAddCue(TextTrack* track, PassRefPtr<TextTrackCue> cue)
+void HTMLTrackElement::textTrackAddCue(TextTrack& track, TextTrackCue& cue)
{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackAddCue(track, cue);
+ if (auto* parent = mediaElement())
+ parent->textTrackAddCue(track, cue);
}
-void HTMLTrackElement::textTrackRemoveCue(TextTrack* track, PassRefPtr<TextTrackCue> cue)
+void HTMLTrackElement::textTrackRemoveCue(TextTrack& track, TextTrackCue& cue)
{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackRemoveCue(track, cue);
+ if (auto* parent = mediaElement())
+ parent->textTrackRemoveCue(track, cue);
}
HTMLMediaElement* HTMLTrackElement::mediaElement() const
{
- Element* parent = parentElement();
- if (parent && parent->isMediaElement())
- return toHTMLMediaElement(parentNode());
-
- return 0;
+ auto* parent = parentElement();
+ if (!is<HTMLMediaElement>(parent))
+ return nullptr;
+ return downcast<HTMLMediaElement>(parent);
}
}