#include "core/html/track/TextTrack.h"
#include "RuntimeEnabledFeatures.h"
+#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/track/TextTrackCueList.h"
#include "core/html/track/TextTrackList.h"
-#include "core/html/track/VTTRegion.h"
-#include "core/html/track/VTTRegionList.h"
+#include "core/html/track/vtt/VTTRegion.h"
+#include "core/html/track/vtt/VTTRegionList.h"
namespace WebCore {
return ended;
}
-TextTrack::TextTrack(Document& document, TextTrackClient* client, const AtomicString& kind, const AtomicString& label, const AtomicString& language, TextTrackType type)
- : TrackBase(TrackBase::TextTrack)
- , m_cues(0)
- , m_regions(0)
- , m_document(&document)
- , m_mediaElement(0)
- , m_label(label)
- , m_language(language)
- , m_mode(disabledKeyword().string())
- , m_client(client)
+TextTrack::TextTrack(Document& document, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType type)
+ : TrackBase(TrackBase::TextTrack, label, language, id)
+ , m_cues(nullptr)
+ , m_regions(nullptr)
+ , m_trackList(nullptr)
+ , m_mode(disabledKeyword())
, m_trackType(type)
, m_readinessState(NotLoaded)
, m_trackIndex(invalidTrackIndex)
TextTrack::~TextTrack()
{
- if (m_cues) {
- if (m_client)
- m_client->textTrackRemoveCues(this, m_cues.get());
+#if !ENABLE(OILPAN)
+ ASSERT(!m_trackList);
+ if (m_cues) {
for (size_t i = 0; i < m_cues->length(); ++i)
m_cues->item(i)->setTrack(0);
}
-
if (m_regions) {
for (size_t i = 0; i < m_regions->length(); ++i)
m_regions->item(i)->setTrack(0);
}
- clearClient();
+#endif
}
bool TextTrack::isValidKindKeyword(const AtomicString& value)
return false;
}
-void TextTrack::setKind(const AtomicString& kind)
+void TextTrack::setTrackList(TextTrackList* trackList)
{
- String oldKind = m_kind;
+ if (!trackList && mediaElement() && m_cues)
+ mediaElement()->textTrackRemoveCues(this, m_cues.get());
- if (isValidKindKeyword(kind))
- m_kind = kind;
- else
- m_kind = subtitlesKeyword();
+ m_trackList = trackList;
+ invalidateTrackIndex();
+}
+
+void TextTrack::setKind(const AtomicString& newKind)
+{
+ AtomicString oldKind = kind();
+ TrackBase::setKind(newKind);
- if (m_client && oldKind != m_kind)
- m_client->textTrackKindChanged(this);
+ if (mediaElement() && oldKind != kind())
+ mediaElement()->textTrackKindChanged(this);
}
void TextTrack::setMode(const AtomicString& mode)
// If mode changes to disabled, remove this track's cues from the client
// because they will no longer be accessible from the cues() function.
- if (mode == disabledKeyword() && m_client && m_cues)
- m_client->textTrackRemoveCues(this, m_cues.get());
+ if (mode == disabledKeyword() && mediaElement() && m_cues)
+ mediaElement()->textTrackRemoveCues(this, m_cues.get());
if (mode != showingKeyword() && m_cues)
for (size_t i = 0; i < m_cues->length(); ++i)
m_mode = mode;
- if (m_client)
- m_client->textTrackModeChanged(this);
+ if (mediaElement())
+ mediaElement()->textTrackModeChanged(this);
}
TextTrackCueList* TextTrack::cues()
if (!m_cues)
return;
- if (m_client)
- m_client->textTrackRemoveCues(this, m_cues.get());
+ if (mediaElement())
+ mediaElement()->textTrackRemoveCues(this, m_cues.get());
for (size_t i = 0; i < m_cues->length(); ++i)
m_cues->item(i)->setTrack(0);
- m_cues = 0;
+ m_cues = nullptr;
}
TextTrackCueList* TextTrack::activeCues() const
return 0;
}
-void TextTrack::addCue(PassRefPtr<TextTrackCue> prpCue)
+void TextTrack::addCue(PassRefPtrWillBeRawPtr<TextTrackCue> prpCue)
{
if (!prpCue)
return;
- RefPtr<TextTrackCue> cue = prpCue;
+ RefPtrWillBeRawPtr<TextTrackCue> cue = prpCue;
// TODO(93143): Add spec-compliant behavior for negative time values.
if (std::isnan(cue->startTime()) || std::isnan(cue->endTime()) || cue->startTime() < 0 || cue->endTime() < 0)
cue->setTrack(this);
ensureTextTrackCueList()->add(cue);
- if (m_client)
- m_client->textTrackAddCue(this, cue.get());
+ if (mediaElement())
+ mediaElement()->textTrackAddCue(this, cue.get());
}
-void TextTrack::removeCue(TextTrackCue* cue, ExceptionState& es)
+void TextTrack::removeCue(TextTrackCue* cue, ExceptionState& exceptionState)
{
if (!cue)
return;
// 1. If the given cue is not currently listed in the method's TextTrack
// object's text track's text track list of cues, then throw a NotFoundError exception.
if (cue->track() != this) {
- es.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The specified cue is not listed in the TextTrack's list of cues.");
return;
}
// 2. Remove cue from the method's TextTrack object's text track's text track list of cues.
if (!m_cues || !m_cues->remove(cue)) {
- es.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "Failed to remove the specified cue.");
return;
}
cue->setTrack(0);
- if (m_client)
- m_client->textTrackRemoveCue(this, cue);
+ if (mediaElement())
+ mediaElement()->textTrackRemoveCue(this, cue);
}
VTTRegionList* TextTrack::ensureVTTRegionList()
return 0;
}
-void TextTrack::addRegion(PassRefPtr<VTTRegion> prpRegion)
+void TextTrack::addRegion(PassRefPtrWillBeRawPtr<VTTRegion> prpRegion)
{
if (!prpRegion)
return;
- RefPtr<VTTRegion> region = prpRegion;
+ RefPtrWillBeRawPtr<VTTRegion> region = prpRegion;
VTTRegionList* regionList = ensureVTTRegionList();
// 1. If the given region is in a text track list of regions, then remove
regionList->add(region);
}
-void TextTrack::removeRegion(VTTRegion* region, ExceptionState &es)
+void TextTrack::removeRegion(VTTRegion* region, ExceptionState &exceptionState)
{
if (!region)
return;
// 1. If the given region is not currently listed in the method's TextTrack
// object's text track list of regions, then throw a NotFoundError exception.
if (region->track() != this) {
- es.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The specified region is not listed in the TextTrack's list of regions.");
return;
}
if (!m_regions || !m_regions->remove(region)) {
- es.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "Failed to remove the specified region.");
return;
}
void TextTrack::cueWillChange(TextTrackCue* cue)
{
- if (!m_client)
+ if (!mediaElement())
return;
// The cue may need to be repositioned in the media element's interval tree, may need to
// be re-rendered, etc, so remove it before the modification...
- m_client->textTrackRemoveCue(this, cue);
+ mediaElement()->textTrackRemoveCue(this, cue);
}
void TextTrack::cueDidChange(TextTrackCue* cue)
{
- if (!m_client)
+ if (!mediaElement())
return;
// Make sure the TextTrackCueList order is up-to-date.
ensureTextTrackCueList()->updateCueIndex(cue);
// ... and add it back again.
- m_client->textTrackAddCue(this, cue);
+ mediaElement()->textTrackAddCue(this, cue);
}
int TextTrack::trackIndex()
{
- ASSERT(m_mediaElement);
+ ASSERT(m_trackList);
if (m_trackIndex == invalidTrackIndex)
- m_trackIndex = m_mediaElement->textTracks()->getTrackIndex(this);
+ m_trackIndex = m_trackList->getTrackIndex(this);
return m_trackIndex;
}
bool TextTrack::isRendered()
{
- if (m_kind != captionsKeyword() && m_kind != subtitlesKeyword())
+ if (kind() != captionsKeyword() && kind() != subtitlesKeyword())
return false;
if (m_mode != showingKeyword())
int TextTrack::trackIndexRelativeToRenderedTracks()
{
- ASSERT(m_mediaElement);
+ ASSERT(m_trackList);
if (m_renderedTrackIndex == invalidTrackIndex)
- m_renderedTrackIndex = m_mediaElement->textTracks()->getTrackIndexRelativeToRenderedTracks(this);
+ m_renderedTrackIndex = m_trackList->getTrackIndexRelativeToRenderedTracks(this);
return m_renderedTrackIndex;
}
-bool TextTrack::hasCue(TextTrackCue* cue)
+const AtomicString& TextTrack::interfaceName() const
{
- if (cue->startTime() < 0 || cue->endTime() < 0)
- return false;
-
- if (!m_cues || !m_cues->length())
- return false;
-
- size_t searchStart = 0;
- size_t searchEnd = m_cues->length();
-
- while (1) {
- ASSERT(searchStart <= m_cues->length());
- ASSERT(searchEnd <= m_cues->length());
-
- TextTrackCue* existingCue;
-
- // Cues in the TextTrackCueList are maintained in start time order.
- if (searchStart == searchEnd) {
- if (!searchStart)
- return false;
-
- // If there is more than one cue with the same start time, back up to first one so we
- // consider all of them.
- while (searchStart >= 2 && cue->startTime() == m_cues->item(searchStart - 2)->startTime())
- --searchStart;
-
- bool firstCompare = true;
- while (1) {
- if (!firstCompare)
- ++searchStart;
- firstCompare = false;
- if (searchStart > m_cues->length())
- return false;
-
- existingCue = m_cues->item(searchStart - 1);
- if (!existingCue || cue->startTime() > existingCue->startTime())
- return false;
-
- if (*existingCue != *cue)
- continue;
-
- return true;
- }
- }
-
- size_t index = (searchStart + searchEnd) / 2;
- existingCue = m_cues->item(index);
- if (cue->startTime() < existingCue->startTime() || (cue->startTime() == existingCue->startTime() && cue->endTime() > existingCue->endTime()))
- searchEnd = index;
- else
- searchStart = index + 1;
- }
+ return EventTargetNames::TextTrack;
+}
- ASSERT_NOT_REACHED();
- return false;
+ExecutionContext* TextTrack::executionContext() const
+{
+ HTMLMediaElement* owner = mediaElement();
+ return owner ? owner->executionContext() : 0;
}
-bool TextTrack::isMainProgramContent() const
+HTMLMediaElement* TextTrack::mediaElement() const
{
- // "Main program" content is intrinsic to the presentation of the media file, regardless of locale. Content such as
- // directors commentary is not "main program" because it is not essential for the presentation. HTML5 doesn't have
- // a way to express this in a machine-reable form, it is typically done with the track label, so we assume that caption
- // tracks are main content and all other track types are not.
- return m_kind == captionsKeyword();
+ return m_trackList ? m_trackList->owner() : 0;
}
-const AtomicString& TextTrack::interfaceName() const
+Node* TextTrack::owner() const
{
- return EventTargetNames::TextTrack;
+ return mediaElement();
}
-ExecutionContext* TextTrack::executionContext() const
+void TextTrack::trace(Visitor* visitor)
{
- return m_document;
+ visitor->trace(m_cues);
+ visitor->trace(m_regions);
+ visitor->trace(m_trackList);
+ TrackBase::trace(visitor);
}
} // namespace WebCore
-