This source file includes following definitions.
- m_asyncEventQueue
- length
- getTrackIndex
- getTrackIndexRelativeToRenderedTracks
- item
- getTrackById
- invalidateTrackIndexesAfterTrack
- append
- remove
- removeAllInbandTracks
- contains
- interfaceName
- executionContext
- clearOwner
- scheduleTrackEvent
- scheduleAddTrackEvent
- scheduleChangeEvent
- scheduleRemoveTrackEvent
- owner
#include "config.h"
#include "core/html/track/TextTrackList.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/events/GenericEventQueue.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/track/InbandTextTrack.h"
#include "core/html/track/LoadableTextTrack.h"
#include "core/html/track/TextTrack.h"
#include "core/html/track/TrackEvent.h"
using namespace WebCore;
TextTrackList::TextTrackList(HTMLMediaElement* owner)
: m_owner(owner)
, m_asyncEventQueue(GenericEventQueue::create(this))
{
ScriptWrappable::init(this);
}
TextTrackList::~TextTrackList()
{
ASSERT(!m_owner);
m_asyncEventQueue->close();
for (unsigned i = 0; i < length(); ++i) {
item(i)->setTrackList(0);
}
}
unsigned TextTrackList::length() const
{
return m_addTrackTracks.size() + m_elementTracks.size() + m_inbandTracks.size();
}
int TextTrackList::getTrackIndex(TextTrack *textTrack)
{
if (textTrack->trackType() == TextTrack::TrackElement)
return static_cast<LoadableTextTrack*>(textTrack)->trackElementIndex();
if (textTrack->trackType() == TextTrack::AddTrack)
return m_elementTracks.size() + m_addTrackTracks.find(textTrack);
if (textTrack->trackType() == TextTrack::InBand)
return m_elementTracks.size() + m_addTrackTracks.size() + m_inbandTracks.find(textTrack);
ASSERT_NOT_REACHED();
return -1;
}
int TextTrackList::getTrackIndexRelativeToRenderedTracks(TextTrack *textTrack)
{
int trackIndex = 0;
for (size_t i = 0; i < m_elementTracks.size(); ++i) {
if (!m_elementTracks[i]->isRendered())
continue;
if (m_elementTracks[i] == textTrack)
return trackIndex;
++trackIndex;
}
for (size_t i = 0; i < m_addTrackTracks.size(); ++i) {
if (!m_addTrackTracks[i]->isRendered())
continue;
if (m_addTrackTracks[i] == textTrack)
return trackIndex;
++trackIndex;
}
for (size_t i = 0; i < m_inbandTracks.size(); ++i) {
if (!m_inbandTracks[i]->isRendered())
continue;
if (m_inbandTracks[i] == textTrack)
return trackIndex;
++trackIndex;
}
ASSERT_NOT_REACHED();
return -1;
}
TextTrack* TextTrackList::item(unsigned index)
{
if (index < m_elementTracks.size())
return m_elementTracks[index].get();
index -= m_elementTracks.size();
if (index < m_addTrackTracks.size())
return m_addTrackTracks[index].get();
index -= m_addTrackTracks.size();
if (index < m_inbandTracks.size())
return m_inbandTracks[index].get();
return 0;
}
TextTrack* TextTrackList::getTrackById(const AtomicString& id)
{
for (unsigned i = 0; i < length(); ++i) {
TextTrack* track = item(i);
if (track->id() == id)
return track;
}
return 0;
}
void TextTrackList::invalidateTrackIndexesAfterTrack(TextTrack* track)
{
Vector<RefPtr<TextTrack> >* tracks = 0;
if (track->trackType() == TextTrack::TrackElement) {
tracks = &m_elementTracks;
for (size_t i = 0; i < m_addTrackTracks.size(); ++i)
m_addTrackTracks[i]->invalidateTrackIndex();
for (size_t i = 0; i < m_inbandTracks.size(); ++i)
m_inbandTracks[i]->invalidateTrackIndex();
} else if (track->trackType() == TextTrack::AddTrack) {
tracks = &m_addTrackTracks;
for (size_t i = 0; i < m_inbandTracks.size(); ++i)
m_inbandTracks[i]->invalidateTrackIndex();
} else if (track->trackType() == TextTrack::InBand)
tracks = &m_inbandTracks;
else
ASSERT_NOT_REACHED();
size_t index = tracks->find(track);
if (index == kNotFound)
return;
for (size_t i = index; i < tracks->size(); ++i)
tracks->at(index)->invalidateTrackIndex();
}
void TextTrackList::append(PassRefPtr<TextTrack> prpTrack)
{
RefPtr<TextTrack> track = prpTrack;
if (track->trackType() == TextTrack::AddTrack)
m_addTrackTracks.append(track);
else if (track->trackType() == TextTrack::TrackElement) {
size_t index = static_cast<LoadableTextTrack*>(track.get())->trackElementIndex();
m_elementTracks.insert(index, track);
} else if (track->trackType() == TextTrack::InBand) {
size_t index = static_cast<InbandTextTrack*>(track.get())->inbandTrackIndex();
m_inbandTracks.insert(index, track);
} else
ASSERT_NOT_REACHED();
invalidateTrackIndexesAfterTrack(track.get());
ASSERT(!track->trackList());
track->setTrackList(this);
scheduleAddTrackEvent(track.release());
}
void TextTrackList::remove(TextTrack* track)
{
Vector<RefPtr<TextTrack> >* tracks = 0;
if (track->trackType() == TextTrack::TrackElement) {
tracks = &m_elementTracks;
} else if (track->trackType() == TextTrack::AddTrack) {
tracks = &m_addTrackTracks;
} else if (track->trackType() == TextTrack::InBand) {
tracks = &m_inbandTracks;
} else {
ASSERT_NOT_REACHED();
}
size_t index = tracks->find(track);
if (index == kNotFound)
return;
invalidateTrackIndexesAfterTrack(track);
ASSERT(track->trackList() == this);
track->setTrackList(0);
tracks->remove(index);
scheduleRemoveTrackEvent(track);
}
void TextTrackList::removeAllInbandTracks()
{
for (unsigned i = 0; i < m_inbandTracks.size(); ++i) {
m_inbandTracks[i]->setTrackList(0);
}
m_inbandTracks.clear();
}
bool TextTrackList::contains(TextTrack* track) const
{
const Vector<RefPtr<TextTrack> >* tracks = 0;
if (track->trackType() == TextTrack::TrackElement)
tracks = &m_elementTracks;
else if (track->trackType() == TextTrack::AddTrack)
tracks = &m_addTrackTracks;
else if (track->trackType() == TextTrack::InBand)
tracks = &m_inbandTracks;
else
ASSERT_NOT_REACHED();
return tracks->find(track) != kNotFound;
}
const AtomicString& TextTrackList::interfaceName() const
{
return EventTargetNames::TextTrackList;
}
ExecutionContext* TextTrackList::executionContext() const
{
ASSERT(m_owner);
return m_owner->executionContext();
}
void TextTrackList::clearOwner()
{
m_owner = 0;
}
void TextTrackList::scheduleTrackEvent(const AtomicString& eventName, PassRefPtr<TextTrack> track)
{
TrackEventInit initializer;
initializer.track = track;
initializer.bubbles = false;
initializer.cancelable = false;
m_asyncEventQueue->enqueueEvent(TrackEvent::create(eventName, initializer));
}
void TextTrackList::scheduleAddTrackEvent(PassRefPtr<TextTrack> track)
{
scheduleTrackEvent(EventTypeNames::addtrack, track);
}
void TextTrackList::scheduleChangeEvent()
{
EventInit initializer;
initializer.bubbles = false;
initializer.cancelable = false;
m_asyncEventQueue->enqueueEvent(Event::create(EventTypeNames::change, initializer));
}
void TextTrackList::scheduleRemoveTrackEvent(PassRefPtr<TextTrack> track)
{
scheduleTrackEvent(EventTypeNames::removetrack, track);
}
HTMLMediaElement* TextTrackList::owner() const
{
return m_owner;
}