TextTrackList not sorted correctly

https://bugs.webkit.org/show_bug.cgi?id=72545

Reviewed by Darin Adler.

Source/WebCore: 

Test: media/track/track-texttracks.html

* WebCore.xcodeproj/project.pbxproj: Add TextTrack.h to WebCore private headers because 
    it is included by HTMLMediaElement.h.
* html/LoadableTextTrack.cpp:
(WebCore::LoadableTextTrack::LoadableTextTrack): Pass track type to base class constructor.
(WebCore::LoadableTextTrack::trackElementIndex): New, return the <track> element's tree order
    for sorting.
* html/LoadableTextTrack.h:

* html/TextTrack.cpp:
(WebCore::TextTrack::TextTrack): Set track type.
* html/TextTrack.h:
(WebCore::TextTrack::create): Ditto.
(WebCore::TextTrack::trackType): Ditto.

* html/track/TextTrackList.cpp:
(TextTrackList::length): Update to deal with two TextTrack vectors.
(TextTrackList::item): Ditto.
(TextTrackList::append): Ditto.
(TextTrackList::remove): Ditto
* html/track/TextTrackList.h: Store the two types of TextTracks in separate Vectors to make
    it simpler to keep them in the correct order.

LayoutTests: 

* media/track/track-texttracks-expected.txt: Added.
* media/track/track-texttracks.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@100616 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 526edbb0
2011-11-17 Eric Carlson <eric.carlson@apple.com>
TextTrackList not sorted correctly
https://bugs.webkit.org/show_bug.cgi?id=72545
Reviewed by Darin Adler.
* media/track/track-texttracks-expected.txt: Added.
* media/track/track-texttracks.html: Added.
2011-11-17 Steve Block <steveblock@google.com>
[Chromium] Layout test failures under Snow Leopard
Tests that TextTracks in a TextTrackList are kept in the correct order.
** Add a track with video.addTrack().
RUN(video.addTrack('descriptions', 'Descriptions Track', 'en'))
** Add a <track> element with DOM API.
RUN(trackElement = document.createElement('track'))
RUN(trackElement.setAttribute('kind', 'chapters'))
RUN(video.appendChild(trackElement))
** Verify track order.
EXPECTED (video.textTracks.length == '3') OK
EXPECTED (video.textTracks[0].kind == 'captions') OK
EXPECTED (video.textTracks[1].kind == 'chapters') OK
EXPECTED (video.textTracks[2].kind == 'descriptions') OK
** Add another <track> element, is should insert before the addTrack() track.
RUN(trackElement = document.createElement('track'))
RUN(trackElement.setAttribute('kind', 'metadata'))
RUN(video.appendChild(trackElement))
EXPECTED (video.textTracks.length == '4') OK
EXPECTED (video.textTracks[0].kind == 'captions') OK
EXPECTED (video.textTracks[1].kind == 'chapters') OK
EXPECTED (video.textTracks[2].kind == 'metadata') OK
EXPECTED (video.textTracks[3].kind == 'descriptions') OK
END OF TEST
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src=../media-file.js></script>
<script src=../video-test.js></script>
<script>
var trackElement;
function start()
{
findMediaElement();
consoleWrite("** Add a track with video.addTrack().");
run("video.addTrack('descriptions', 'Descriptions Track', 'en')");
consoleWrite("<br>** Add a &lt;track&gt; element with DOM API.");
run("trackElement = document.createElement('track')");
run("trackElement.setAttribute('kind', 'chapters')");
run("video.appendChild(trackElement)");
consoleWrite("<br>** Verify track order.");
testExpected("video.textTracks.length", 3);
testExpected("video.textTracks[0].kind", "captions");
testExpected("video.textTracks[1].kind", "chapters");
testExpected("video.textTracks[2].kind", "descriptions");
consoleWrite("<br>** Add another &lt;track&gt; element, is should insert before the addTrack() track.");
run("trackElement = document.createElement('track')");
run("trackElement.setAttribute('kind', 'metadata')");
run("video.appendChild(trackElement)");
testExpected("video.textTracks.length", 4);
testExpected("video.textTracks[0].kind", "captions");
testExpected("video.textTracks[1].kind", "chapters");
testExpected("video.textTracks[2].kind", "metadata");
testExpected("video.textTracks[3].kind", "descriptions");
consoleWrite("");
endTest();
}
</script>
</head>
<body onload="start()">
<p>Tests that TextTracks in a TextTrackList are kept in the correct order.</p>
<video>
<track id="track_1" kind="captions" src="captions-webvtt/tc004-webvtt-file.vtt" >
</video>
</body>
</html>
2011-11-17 Eric Carlson <eric.carlson@apple.com>
TextTrackList not sorted correctly
https://bugs.webkit.org/show_bug.cgi?id=72545
Reviewed by Darin Adler.
Test: media/track/track-texttracks.html
* WebCore.xcodeproj/project.pbxproj: Add TextTrack.h to WebCore private headers because
it is included by HTMLMediaElement.h.
* html/LoadableTextTrack.cpp:
(WebCore::LoadableTextTrack::LoadableTextTrack): Pass track type to base class constructor.
(WebCore::LoadableTextTrack::trackElementIndex): New, return the <track> element's tree order
for sorting.
* html/LoadableTextTrack.h:
* html/TextTrack.cpp:
(WebCore::TextTrack::TextTrack): Set track type.
* html/TextTrack.h:
(WebCore::TextTrack::create): Ditto.
(WebCore::TextTrack::trackType): Ditto.
* html/track/TextTrackList.cpp:
(TextTrackList::length): Update to deal with two TextTrack vectors.
(TextTrackList::item): Ditto.
(TextTrackList::append): Ditto.
(TextTrackList::remove): Ditto
* html/track/TextTrackList.h: Store the two types of TextTracks in separate Vectors to make
it simpler to keep them in the correct order.
2011-11-17 Simon Hausmann <simon.hausmann@nokia.com>
[Qt] Layer violation: WebCore::dnsPrefetch uses QWebSettings::globalSettings()
......@@ -4181,7 +4181,7 @@
B1AD4E6613A12A0B00846B27 /* TextTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1AD4E5513A12A0B00846B27 /* TextTrack.cpp */; };
B1AD4E6713A12A0B00846B27 /* TextTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = B1AD4E5613A12A0B00846B27 /* TextTrack.h */; settings = {ATTRIBUTES = (Private, ); }; };
B1AD4E6813A12A0B00846B27 /* TextTrackCue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1AD4E5713A12A0B00846B27 /* TextTrackCue.cpp */; };
B1AD4E6913A12A0B00846B27 /* TextTrackCue.h in Headers */ = {isa = PBXBuildFile; fileRef = B1AD4E5813A12A0B00846B27 /* TextTrackCue.h */; };
B1AD4E6913A12A0B00846B27 /* TextTrackCue.h in Headers */ = {isa = PBXBuildFile; fileRef = B1AD4E5813A12A0B00846B27 /* TextTrackCue.h */; settings = {ATTRIBUTES = (Private, ); }; };
B1AD4E6A13A12A0B00846B27 /* TextTrackCueList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1AD4E5913A12A0B00846B27 /* TextTrackCueList.cpp */; };
B1AD4E6B13A12A0B00846B27 /* TextTrackCueList.h in Headers */ = {isa = PBXBuildFile; fileRef = B1AD4E5A13A12A0B00846B27 /* TextTrackCueList.h */; };
B1AD4E7313A12A4600846B27 /* TextTrackLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1AD4E7113A12A4600846B27 /* TextTrackLoader.cpp */; };
......@@ -38,7 +38,7 @@
namespace WebCore {
LoadableTextTrack::LoadableTextTrack(HTMLTrackElement* track, const String& kind, const String& label, const String& language, bool isDefault)
: TextTrack(track->document(), track, kind, label, language)
: TextTrack(track->document(), track, kind, label, language, TrackElement)
, m_trackElement(track)
, m_loadTimer(this, &LoadableTextTrack::loadTimerFired)
, m_isDefault(isDefault)
......@@ -120,6 +120,24 @@ void LoadableTextTrack::fireCueChangeEvent()
m_trackElement->dispatchEvent(Event::create(eventNames().cuechangeEvent, false, false), ec);
}
size_t LoadableTextTrack::trackElementIndex()
{
ASSERT(m_trackElement);
ASSERT(m_trackElement->parentNode());
size_t index = 0;
for (Node* node = m_trackElement->parentNode()->firstChild(); node; node = node->nextSibling()) {
if (!node->hasTagName(trackTag))
continue;
if (node == m_trackElement)
return index;
++index;
}
ASSERT_NOT_REACHED();
return 0;
}
} // namespace WebCore
#endif
......@@ -57,6 +57,8 @@ public:
void scheduleLoad(const KURL&);
virtual void clearClient();
size_t trackElementIndex();
private:
// TextTrackLoaderClient
......
......@@ -71,13 +71,14 @@ const AtomicString& TextTrack::metadataKeyword()
return metadata;
}
TextTrack::TextTrack(ScriptExecutionContext* context, TextTrackClient* client, const String& kind, const String& label, const String& language)
TextTrack::TextTrack(ScriptExecutionContext* context, TextTrackClient* client, const String& kind, const String& label, const String& language, TextTrackType type)
: TrackBase(context, TrackBase::TextTrack)
, m_label(label)
, m_language(language)
, m_readyState(TextTrack::NONE)
, m_mode(TextTrack::HIDDEN)
, m_client(client)
, m_trackType(type)
{
setKind(kind);
}
......
......@@ -56,7 +56,7 @@ class TextTrack : public TrackBase {
public:
static PassRefPtr<TextTrack> create(ScriptExecutionContext* context, TextTrackClient* client, const String& kind, const String& label, const String& language)
{
return adoptRef(new TextTrack(context, client, kind, label, language));
return adoptRef(new TextTrack(context, client, kind, label, language, AddTrack));
}
virtual ~TextTrack();
......@@ -101,8 +101,11 @@ public:
virtual void fireCueChangeEvent();
DEFINE_ATTRIBUTE_EVENT_LISTENER(cuechange);
enum TextTrackType { TrackElement, AddTrack, InBand };
TextTrackType trackType() const { return m_trackType; }
protected:
TextTrack(ScriptExecutionContext*, TextTrackClient*, const String& kind, const String& label, const String& language);
TextTrack(ScriptExecutionContext*, TextTrackClient*, const String& kind, const String& label, const String& language, TextTrackType);
void setReadyState(ReadyState);
......@@ -115,6 +118,7 @@ private:
TextTrack::ReadyState m_readyState;
TextTrack::Mode m_mode;
TextTrackClient* m_client;
TextTrackType m_trackType;
};
} // namespace WebCore
......
......@@ -30,6 +30,7 @@
#include "TextTrackList.h"
#include "EventNames.h"
#include "LoadableTextTrack.h"
#include "ScriptExecutionContext.h"
#include "TextTrack.h"
#include "TrackEvent.h"
......@@ -51,29 +52,60 @@ TextTrackList::~TextTrackList()
unsigned TextTrackList::length() const
{
return m_tracks.size();
return m_addTrackTracks.size() + m_elementTracks.size();
}
TextTrack* TextTrackList::item(unsigned index)
{
if (index < m_tracks.size())
return m_tracks[index].get();
// 4.8.10.12.1 Text track model
// The text tracks are sorted as follows:
// 1. The text tracks corresponding to track element children of the media element, in tree order.
// 2. Any text tracks added using the addTextTrack() method, in the order they were added, oldest first.
// 3. Any media-resource-specific text tracks (text tracks corresponding to data in the media
// resource), in the order defined by the media resource's format specification.
if (index < m_elementTracks.size())
return m_elementTracks[index].get();
index -= m_elementTracks.size();
if (index < m_addTrackTracks.size())
return m_addTrackTracks[index].get();
return 0;
}
void TextTrackList::append(PassRefPtr<TextTrack> track)
{
RefPtr<TextTrack> trackRef = track;
m_tracks.append(trackRef);
if (trackRef->trackType() == TextTrack::AddTrack)
m_addTrackTracks.append(trackRef);
else if (trackRef->trackType() == TextTrack::TrackElement) {
// Insert tracks added for <track> element in tree order.
size_t index = static_cast<LoadableTextTrack*>(trackRef.get())->trackElementIndex();
m_elementTracks.insert(index, trackRef);
} else
ASSERT_NOT_REACHED();
scheduleAddTrackEvent(trackRef);
}
void TextTrackList::remove(PassRefPtr<TextTrack> track)
{
size_t index = m_tracks.find(track);
Vector<RefPtr<TextTrack> >* tracks = 0;
if (track->trackType() == TextTrack::TrackElement)
tracks = &m_elementTracks;
else if (track->trackType() == TextTrack::AddTrack)
tracks = &m_addTrackTracks;
else
ASSERT_NOT_REACHED();
size_t index = tracks->find(track);
if (index == notFound)
return;
m_tracks.remove(index);
tracks->remove(index);
}
const AtomicString& TextTrackList::interfaceName() const
......
......@@ -87,7 +87,8 @@ private:
Timer<TextTrackList> m_pendingEventTimer;
EventTargetData m_eventTargetData;
Vector<RefPtr<TextTrack> > m_tracks;
Vector<RefPtr<TextTrack> > m_addTrackTracks;
Vector<RefPtr<TextTrack> > m_elementTracks;
int m_dispatchingEvents;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment