Add interfaces and stubs for audio and video tracks
[WebKit-https.git] / Source / WebCore / html / track / TextTrackList.cpp
1 /*
2  * Copyright (C) 2011, 2012 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27
28 #if ENABLE(VIDEO_TRACK)
29
30 #include "TextTrackList.h"
31
32 #include "EventNames.h"
33 #include "HTMLMediaElement.h"
34 #include "InbandTextTrack.h"
35 #include "InbandTextTrackPrivate.h"
36 #include "LoadableTextTrack.h"
37 #include "TextTrack.h"
38
39 using namespace WebCore;
40
41 TextTrackList::TextTrackList(HTMLMediaElement* element, ScriptExecutionContext* context)
42     : TrackListBase(element, context)
43 {
44 }
45
46 TextTrackList::~TextTrackList()
47 {
48 }
49
50 unsigned TextTrackList::length() const
51 {
52     return m_addTrackTracks.size() + m_elementTracks.size() + m_inbandTracks.size();
53 }
54
55 int TextTrackList::getTrackIndex(TextTrack *textTrack)
56 {
57     if (textTrack->trackType() == TextTrack::TrackElement)
58         return static_cast<LoadableTextTrack*>(textTrack)->trackElementIndex();
59
60     if (textTrack->trackType() == TextTrack::AddTrack)
61         return m_elementTracks.size() + m_addTrackTracks.find(textTrack);
62
63     if (textTrack->trackType() == TextTrack::InBand)
64         return m_elementTracks.size() + m_addTrackTracks.size() + m_inbandTracks.find(textTrack);
65
66     ASSERT_NOT_REACHED();
67
68     return -1;
69 }
70
71 int TextTrackList::getTrackIndexRelativeToRenderedTracks(TextTrack *textTrack)
72 {
73     // Calculate the "Let n be the number of text tracks whose text track mode is showing and that are in the media element's list of text tracks before track."
74     int trackIndex = 0;
75
76     for (size_t i = 0; i < m_elementTracks.size(); ++i) {
77         if (!toTextTrack(m_elementTracks[i].get())->isRendered())
78             continue;
79
80         if (m_elementTracks[i] == textTrack)
81             return trackIndex;
82         ++trackIndex;
83     }
84
85     for (size_t i = 0; i < m_addTrackTracks.size(); ++i) {
86         if (!toTextTrack(m_addTrackTracks[i].get())->isRendered())
87             continue;
88
89         if (m_addTrackTracks[i] == textTrack)
90             return trackIndex;
91         ++trackIndex;
92     }
93
94     for (size_t i = 0; i < m_inbandTracks.size(); ++i) {
95         if (!toTextTrack(m_inbandTracks[i].get())->isRendered())
96             continue;
97
98         if (m_inbandTracks[i] == textTrack)
99             return trackIndex;
100         ++trackIndex;
101     }
102
103     ASSERT_NOT_REACHED();
104
105     return -1;
106 }
107
108 TextTrack* TextTrackList::item(unsigned index)
109 {
110     // 4.8.10.12.1 Text track model
111     // The text tracks are sorted as follows:
112     // 1. The text tracks corresponding to track element children of the media element, in tree order.
113     // 2. Any text tracks added using the addTextTrack() method, in the order they were added, oldest first.
114     // 3. Any media-resource-specific text tracks (text tracks corresponding to data in the media
115     // resource), in the order defined by the media resource's format specification.
116
117     if (index < m_elementTracks.size())
118         return toTextTrack(m_elementTracks[index].get());
119
120     index -= m_elementTracks.size();
121     if (index < m_addTrackTracks.size())
122         return toTextTrack(m_addTrackTracks[index].get());
123
124     index -= m_addTrackTracks.size();
125     if (index < m_inbandTracks.size())
126         return toTextTrack(m_inbandTracks[index].get());
127
128     return 0;
129 }
130
131 void TextTrackList::invalidateTrackIndexesAfterTrack(TextTrack* track)
132 {
133     Vector<RefPtr<TrackBase> >* tracks = 0;
134
135     if (track->trackType() == TextTrack::TrackElement) {
136         tracks = &m_elementTracks;
137         for (size_t i = 0; i < m_addTrackTracks.size(); ++i)
138             toTextTrack(m_addTrackTracks[i].get())->invalidateTrackIndex();
139         for (size_t i = 0; i < m_inbandTracks.size(); ++i)
140             toTextTrack(m_inbandTracks[i].get())->invalidateTrackIndex();
141     } else if (track->trackType() == TextTrack::AddTrack) {
142         tracks = &m_addTrackTracks;
143         for (size_t i = 0; i < m_inbandTracks.size(); ++i)
144             toTextTrack(m_inbandTracks[i].get())->invalidateTrackIndex();
145     } else if (track->trackType() == TextTrack::InBand)
146         tracks = &m_inbandTracks;
147     else
148         ASSERT_NOT_REACHED();
149
150     size_t index = tracks->find(track);
151     if (index == notFound)
152         return;
153
154     for (size_t i = index; i < tracks->size(); ++i)
155         toTextTrack(tracks->at(index).get())->invalidateTrackIndex();
156 }
157
158 void TextTrackList::append(PassRefPtr<TextTrack> prpTrack)
159 {
160     RefPtr<TextTrack> track = prpTrack;
161
162     if (track->trackType() == TextTrack::AddTrack)
163         m_addTrackTracks.append(track);
164     else if (track->trackType() == TextTrack::TrackElement) {
165         // Insert tracks added for <track> element in tree order.
166         size_t index = static_cast<LoadableTextTrack*>(track.get())->trackElementIndex();
167         m_elementTracks.insert(index, track);
168     } else if (track->trackType() == TextTrack::InBand) {
169         // Insert tracks added for in-band in the media file order.
170         size_t index = static_cast<InbandTextTrack*>(track.get())->inbandTrackIndex();
171         m_inbandTracks.insert(index, track);
172     } else
173         ASSERT_NOT_REACHED();
174
175     invalidateTrackIndexesAfterTrack(track.get());
176
177     ASSERT(!track->mediaElement() || track->mediaElement() == mediaElement());
178     track->setMediaElement(mediaElement());
179
180     scheduleAddTrackEvent(track.release());
181 }
182
183 void TextTrackList::remove(TrackBase* track)
184 {
185     TextTrack* textTrack = toTextTrack(track);
186     Vector<RefPtr<TrackBase> >* tracks = 0;
187     if (textTrack->trackType() == TextTrack::TrackElement)
188         tracks = &m_elementTracks;
189     else if (textTrack->trackType() == TextTrack::AddTrack)
190         tracks = &m_addTrackTracks;
191     else if (textTrack->trackType() == TextTrack::InBand)
192         tracks = &m_inbandTracks;
193     else
194         ASSERT_NOT_REACHED();
195
196     size_t index = tracks->find(track);
197     if (index == notFound)
198         return;
199
200     invalidateTrackIndexesAfterTrack(textTrack);
201
202     ASSERT(!track->mediaElement() || track->mediaElement() == element());
203     track->setMediaElement(0);
204
205     RefPtr<TrackBase> trackRef = (*tracks)[index];
206     tracks->remove(index);
207     scheduleRemoveTrackEvent(trackRef.release());
208 }
209
210 bool TextTrackList::contains(TrackBase* track) const
211 {
212     const Vector<RefPtr<TrackBase> >* tracks = 0;
213     TextTrack::TextTrackType type = toTextTrack(track)->trackType();
214     if (type == TextTrack::TrackElement)
215         tracks = &m_elementTracks;
216     else if (type == TextTrack::AddTrack)
217         tracks = &m_addTrackTracks;
218     else if (type == TextTrack::InBand)
219         tracks = &m_inbandTracks;
220     else
221         ASSERT_NOT_REACHED();
222     
223     return tracks->find(track) != notFound;
224 }
225
226 const AtomicString& TextTrackList::interfaceName() const
227 {
228     return eventNames().interfaceForTextTrackList;
229 }
230
231 #endif