Index: Source/core/html/track/TrackListBase.h |
diff --git a/Source/core/html/track/TrackListBase.h b/Source/core/html/track/TrackListBase.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..124ab6f5f2afe1048124e6af97d4f15c793fa789 |
--- /dev/null |
+++ b/Source/core/html/track/TrackListBase.h |
@@ -0,0 +1,124 @@ |
+// 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 RefCounted<TrackListBase<T> >, public EventTargetWithInlineData { |
+ REFCOUNTED_EVENT_TARGET(TrackListBase<T>); |
+ |
+public: |
+ explicit TrackListBase(HTMLMediaElement* mediaElement) |
+ : m_mediaElement(mediaElement) |
+ { |
+ } |
+ |
+ virtual ~TrackListBase() |
+ { |
+ ASSERT(m_tracks.isEmpty()); |
+ ASSERT(!m_mediaElement); |
+ } |
+ |
+ unsigned length() const { return m_tracks.size(); } |
+ PassRefPtr<T> anonymousIndexedGetter(unsigned index) const |
+ { |
+ if (index >= m_tracks.size()) |
+ return nullptr; |
+ return m_tracks[index]; |
+ } |
+ |
+ PassRefPtr<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]; |
+ } |
+ |
+ return nullptr; |
+ } |
+ |
+ 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; |
+ } |
+ |
+ void shutdown() |
+ { |
+ removeAll(); |
+ m_mediaElement = 0; |
+ } |
+ |
+ void add(PassRefPtr<T> track) |
+ { |
+ ASSERT(track); |
+ m_tracks.append(track.get()); |
+ scheduleTrackEvent(EventTypeNames::addtrack, track); |
+ } |
+ |
+ void remove(const String& id) |
+ { |
+ for (unsigned i = 0; i < m_tracks.size(); ++i) { |
+ if (m_tracks[i]->id() != id) |
+ continue; |
+ |
+ m_tracks[i]->setMediaElement(0); |
+ scheduleTrackEvent(EventTypeNames::removetrack, m_tracks[i]); |
+ m_tracks.remove(i); |
+ return; |
+ } |
+ } |
+ |
+ 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; |
+ RefPtr<Event> event = Event::create(EventTypeNames::change, initializer); |
+ event->setTarget(this); |
+ m_mediaElement->scheduleEvent(event); |
philipj_slow
2014/03/28 08:27:15
This isn't per spec but I think it should be: http
|
+ } |
+ |
+private: |
+ void scheduleTrackEvent(const AtomicString& eventName, PassRefPtr<T> track) |
+ { |
+ TrackEventInit initializer; |
+ initializer.track = track; |
+ initializer.bubbles = false; |
+ initializer.cancelable = false; |
+ RefPtr<Event> event = TrackEvent::create(eventName, initializer); |
+ event->setTarget(this); |
+ m_mediaElement->scheduleEvent(event); |
+ } |
+ |
+ |
+ Vector<RefPtr<T> > m_tracks; |
+ HTMLMediaElement* m_mediaElement; |
+}; |
+ |
+} |
+ |
+#endif |