blob: 24405a482d787507b6db05e9ae3ded83a501857b [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TrackListBase_h
#define TrackListBase_h
#include "core/events/EventTarget.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/track/TrackEvent.h"
namespace WebCore {
template<class T>
class TrackListBase : public RefCountedWillBeRefCountedGarbageCollected<TrackListBase<T> >, public EventTargetWithInlineData {
REFCOUNTED_EVENT_TARGET(TrackListBase);
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TrackListBase);
public:
explicit TrackListBase(HTMLMediaElement* mediaElement)
: m_mediaElement(mediaElement)
{
}
virtual ~TrackListBase()
{
#if !ENABLE(OILPAN)
ASSERT(m_tracks.isEmpty());
ASSERT(!m_mediaElement);
#endif
}
unsigned length() const { return m_tracks.size(); }
T* anonymousIndexedGetter(unsigned index) const
{
if (index >= m_tracks.size())
return 0;
return m_tracks[index].get();
}
T* getTrackById(const String& id) const
{
for (unsigned i = 0; i < m_tracks.size(); ++i) {
if (m_tracks[i]->id() == id)
return m_tracks[i].get();
}
return 0;
}
DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack);
DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack);
// EventTarget interface
virtual ExecutionContext* executionContext() const OVERRIDE
{
if (m_mediaElement)
return m_mediaElement->executionContext();
return 0;
}
#if !ENABLE(OILPAN)
void shutdown()
{
removeAll();
m_mediaElement = nullptr;
}
#endif
void add(PassRefPtrWillBeRawPtr<T> prpTrack)
{
RefPtrWillBeRawPtr<T> track = prpTrack;
track->setMediaElement(m_mediaElement);
m_tracks.append(track);
scheduleTrackEvent(EventTypeNames::addtrack, track.release());
}
void remove(blink::WebMediaPlayer::TrackId trackId)
{
for (unsigned i = 0; i < m_tracks.size(); ++i) {
if (m_tracks[i]->trackId() != trackId)
continue;
m_tracks[i]->setMediaElement(0);
scheduleTrackEvent(EventTypeNames::removetrack, m_tracks[i]);
m_tracks.remove(i);
return;
}
ASSERT_NOT_REACHED();
}
void removeAll()
{
for (unsigned i = 0; i < m_tracks.size(); ++i)
m_tracks[i]->setMediaElement(0);
m_tracks.clear();
}
void scheduleChangeEvent()
{
EventInit initializer;
initializer.bubbles = false;
initializer.cancelable = false;
RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::change, initializer);
event->setTarget(this);
m_mediaElement->scheduleEvent(event);
}
Node* owner() const { return m_mediaElement; }
void trace(Visitor* visitor)
{
visitor->trace(m_tracks);
visitor->trace(m_mediaElement);
EventTargetWithInlineData::trace(visitor);
}
private:
void scheduleTrackEvent(const AtomicString& eventName, PassRefPtrWillBeRawPtr<T> track)
{
TrackEventInit initializer;
initializer.track = track;
initializer.bubbles = false;
initializer.cancelable = false;
RefPtrWillBeRawPtr<Event> event = TrackEvent::create(eventName, initializer);
event->setTarget(this);
m_mediaElement->scheduleEvent(event);
}
WillBeHeapVector<RefPtrWillBeMember<T> > m_tracks;
RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
};
}
#endif