Implement load notification and events for <track>.
authorannacc@chromium.org <annacc@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Oct 2011 17:54:32 +0000 (17:54 +0000)
committerannacc@chromium.org <annacc@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Oct 2011 17:54:32 +0000 (17:54 +0000)
https://bugs.webkit.org/show_bug.cgi?id=71054

Reviewed by Eric Carlson.

Source/WebCore:

Tests: media/track/track-load-error-readyState.html
       media/track/track-load-from-element-readyState.html
       media/track/track-load-from-src-readyState.html

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::loadTextTracks):
(WebCore::HTMLMediaElement::loadNextTextTrack):
(WebCore::HTMLMediaElement::trackWasAdded):
(WebCore::HTMLMediaElement::trackWillBeRemoved):
(WebCore::HTMLMediaElement::trackSourceChanged):
* html/HTMLMediaElement.h:
* html/HTMLTrackElement.cpp:
(WebCore::HTMLTrackElement::insertedIntoTree):
(WebCore::HTMLTrackElement::willRemove):
(WebCore::HTMLTrackElement::parseMappedAttribute):
(WebCore::HTMLTrackElement::attributeChanged):
* html/HTMLTrackElement.h:
* html/LoadableTextTrack.cpp:
(WebCore::LoadableTextTrack::cueLoadingCompleted):

LayoutTests:

* media/track/track-load-error-readyState-expected.txt: Added.
* media/track/track-load-error-readyState.html: Added.
* media/track/track-load-from-element-readyState-expected.txt: Added.
* media/track/track-load-from-element-readyState.html: Added.
* media/track/track-load-from-src-readyState-expected.txt: Added.
* media/track/track-load-from-src-readyState.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@98736 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
LayoutTests/ChangeLog
LayoutTests/media/track/track-load-error-readyState-expected.txt [new file with mode: 0644]
LayoutTests/media/track/track-load-error-readyState.html [new file with mode: 0644]
LayoutTests/media/track/track-load-from-element-readyState-expected.txt [new file with mode: 0644]
LayoutTests/media/track/track-load-from-element-readyState.html [new file with mode: 0644]
LayoutTests/media/track/track-load-from-src-readyState-expected.txt [new file with mode: 0644]
LayoutTests/media/track/track-load-from-src-readyState.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/HTMLTrackElement.cpp
Source/WebCore/html/HTMLTrackElement.h
Source/WebCore/html/LoadableTextTrack.cpp

index fa67a75..0825dba 100755 (executable)
@@ -1,3 +1,17 @@
+2011-10-28  Anna Cavender  <annacc@chromium.org>
+
+        Implement load notification and events for <track>.
+        https://bugs.webkit.org/show_bug.cgi?id=71054
+
+        Reviewed by Eric Carlson.
+
+        * media/track/track-load-error-readyState-expected.txt: Added.
+        * media/track/track-load-error-readyState.html: Added.
+        * media/track/track-load-from-element-readyState-expected.txt: Added.
+        * media/track/track-load-from-element-readyState.html: Added.
+        * media/track/track-load-from-src-readyState-expected.txt: Added.
+        * media/track/track-load-from-src-readyState.html: Added.
+
 2011-10-28  Simon Fraser  <simon.fraser@apple.com>
 
         The HTML5 video element in Safari does not respect "visibility:hidden" CSS property
diff --git a/LayoutTests/media/track/track-load-error-readyState-expected.txt b/LayoutTests/media/track/track-load-error-readyState-expected.txt
new file mode 100644 (file)
index 0000000..9e2d00e
--- /dev/null
@@ -0,0 +1,6 @@
+Tests the error event on HTMLTrackElement and ERROR readyState on TextTrack.
+
+EVENT(error)
+EXPECTED (track.track.readyState == '3') OK
+END OF TEST
+
diff --git a/LayoutTests/media/track/track-load-error-readyState.html b/LayoutTests/media/track/track-load-error-readyState.html
new file mode 100644 (file)
index 0000000..80e4719
--- /dev/null
@@ -0,0 +1,26 @@
+<!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>
+
+            function trackError()
+            {
+                consoleWrite("EVENT(error)");
+                track = document.getElementById('testTrackError'); 
+                testExpected("track.track.readyState", TextTrack.Error);
+                endTest();
+            }
+
+        </script>
+    </head>
+    <body>
+        <p>Tests the error event on HTMLTrackElement and ERROR readyState on TextTrack.</p>
+        <video id="videotests">
+            <track id="testTrackError" src="junk" onerror="trackError()">
+        </video>
+    </body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/media/track/track-load-from-element-readyState-expected.txt b/LayoutTests/media/track/track-load-from-element-readyState-expected.txt
new file mode 100644 (file)
index 0000000..3a6e71c
--- /dev/null
@@ -0,0 +1,6 @@
+Tests the load event on HTMLTrackElement and LOADED readyState on TextTrack when src is set on the element.
+
+EVENT(load)
+EXPECTED (track.track.readyState == '2') OK
+END OF TEST
+
diff --git a/LayoutTests/media/track/track-load-from-element-readyState.html b/LayoutTests/media/track/track-load-from-element-readyState.html
new file mode 100644 (file)
index 0000000..b16dd4c
--- /dev/null
@@ -0,0 +1,26 @@
+<!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>
+
+            function trackLoaded()
+            {
+                consoleWrite("EVENT(load)");
+                track = document.getElementById('testTrackSrc'); 
+                testExpected("track.track.readyState", TextTrack.Loaded);
+                endTest();
+            }
+
+        </script>
+    </head>
+    <body>
+        <p>Tests the load event on HTMLTrackElement and LOADED readyState on TextTrack when src is set on the element.</p>
+        <video>
+            <track id="testTrackSrc" src="captions-webvtt/tc004-webvtt-file.vtt" onload="trackLoaded()">
+        </video>
+    </body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/media/track/track-load-from-src-readyState-expected.txt b/LayoutTests/media/track/track-load-from-src-readyState-expected.txt
new file mode 100644 (file)
index 0000000..4c405af
--- /dev/null
@@ -0,0 +1,7 @@
+Tests the load event on HTMLTrackElement and LOADED readyState on TextTrack when src is set from JavaScript.
+
+EXPECTED (track.track.readyState == '0') OK
+EVENT(load)
+EXPECTED (track.track.readyState == '2') OK
+END OF TEST
+
diff --git a/LayoutTests/media/track/track-load-from-src-readyState.html b/LayoutTests/media/track/track-load-from-src-readyState.html
new file mode 100644 (file)
index 0000000..f8b9fa7
--- /dev/null
@@ -0,0 +1,30 @@
+<!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>
+    </head>
+    <body>
+        <p>Tests the load event on HTMLTrackElement and LOADED readyState on TextTrack when src is set from JavaScript.</p>
+        <video>
+            <track id="testTrackEmpty">
+        </video>
+        <script>
+
+            function trackLoaded()
+            {
+                consoleWrite("EVENT(load)");
+                testExpected("track.track.readyState", TextTrack.Loaded);
+                endTest();
+            }
+
+            track = document.getElementById('testTrackEmpty');
+            testExpected("track.track.readyState", TextTrack.None);
+            track.addEventListener("load", function () { trackLoaded(); }, true);
+            track.src = "captions-webvtt/tc004-webvtt-file.vtt";    
+
+        </script>
+    </body>
+</html>
\ No newline at end of file
index c105acd..60905c2 100755 (executable)
@@ -1,3 +1,30 @@
+2011-10-28  Anna Cavender  <annacc@chromium.org>
+
+        Implement load notification and events for <track>.
+        https://bugs.webkit.org/show_bug.cgi?id=71054
+
+        Reviewed by Eric Carlson.
+
+        Tests: media/track/track-load-error-readyState.html
+               media/track/track-load-from-element-readyState.html
+               media/track/track-load-from-src-readyState.html
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::loadTextTracks):
+        (WebCore::HTMLMediaElement::loadNextTextTrack):
+        (WebCore::HTMLMediaElement::trackWasAdded):
+        (WebCore::HTMLMediaElement::trackWillBeRemoved):
+        (WebCore::HTMLMediaElement::trackSourceChanged):
+        * html/HTMLMediaElement.h:
+        * html/HTMLTrackElement.cpp:
+        (WebCore::HTMLTrackElement::insertedIntoTree):
+        (WebCore::HTMLTrackElement::willRemove):
+        (WebCore::HTMLTrackElement::parseMappedAttribute):
+        (WebCore::HTMLTrackElement::attributeChanged):
+        * html/HTMLTrackElement.h:
+        * html/LoadableTextTrack.cpp:
+        (WebCore::LoadableTextTrack::cueLoadingCompleted):
+
 2011-10-28  Simon Fraser  <simon.fraser@apple.com>
 
         The HTML5 video element in Safari does not respect "visibility:hidden" CSS property
index db534ee..3d62834 100644 (file)
@@ -839,13 +839,19 @@ void HTMLMediaElement::loadTextTracks()
         return;
 
     for (Node* node = firstChild(); node; node = node->nextSibling()) {
-        if (node->hasTagName(trackTag)) {
-            HTMLTrackElement* track = static_cast<HTMLTrackElement*>(node);
-            track->load(ActiveDOMObject::scriptExecutionContext(), this);
-        }
+        if (node->hasTagName(trackTag))
+            loadNextTextTrack(static_cast<HTMLTrackElement*>(node));
     }
 }
 
+void HTMLMediaElement::loadNextTextTrack(HTMLTrackElement* track)
+{
+    // FIXME(71124): This should schedule an *asynchronous* load.
+    track->load(ActiveDOMObject::scriptExecutionContext(), this);
+
+    // FIXME(71123): Add new track to list of text tracks and set the text track mode.
+}
+
 void HTMLMediaElement::textTrackReadyStateChanged(TextTrack*)
 {
     // FIXME(62885): Implement.
@@ -1978,6 +1984,38 @@ PassRefPtr<TextTrack> HTMLMediaElement::addTrack(const String& kind, const Strin
 {
     return TextTrack::create(this, kind, label, language);
 }
+
+void HTMLMediaElement::trackWasAdded(HTMLTrackElement* track)
+{
+#if !LOG_DISABLED
+    if (track->hasTagName(trackTag)) {
+        KURL url = track->getNonEmptyURLAttribute(srcAttr);
+        LOG(Media, "HTMLMediaElement::trackWasAdded - 'src' is %s", urlForLogging(url).utf8().data());
+    }
+#endif
+    loadNextTextTrack(track);
+}
+void HTMLMediaElement::trackWillBeRemoved(HTMLTrackElement* track)
+{
+#if !LOG_DISABLED
+    if (track->hasTagName(trackTag)) {
+        KURL url = track->getNonEmptyURLAttribute(srcAttr);
+        LOG(Media, "HTMLMediaElement::trackWillBeRemoved - 'src' is %s", urlForLogging(url).utf8().data());
+    }
+#endif
+}
+
+void HTMLMediaElement::trackSourceChanged(HTMLTrackElement* track)
+{
+#if !LOG_DISABLED
+    if (track->hasTagName(trackTag)) {
+        KURL url = track->getNonEmptyURLAttribute(srcAttr);
+        LOG(Media, "HTMLMediaElement::trackSourceChanged - 'src' is %s", urlForLogging(url).utf8().data());
+    }
+#endif
+    loadNextTextTrack(track);
+}
 #endif
 
 bool HTMLMediaElement::havePotentialSourceChild()
index fce32fa..820e8aa 100644 (file)
@@ -57,6 +57,9 @@ class Uint8Array;
 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
 class Widget;
 #endif
+#if ENABLE(VIDEO_TRACK)
+class HTMLTrackElement;
+#endif
 
 // FIXME: The inheritance from MediaPlayerClient here should be private inheritance.
 // But it can't be until the Chromium WebMediaPlayerClientImpl class is fixed so it
@@ -180,6 +183,9 @@ public:
 
 #if ENABLE(VIDEO_TRACK)
     PassRefPtr<TextTrack> addTrack(const String& kind, const String& label = "", const String& language = "");
+    virtual void trackWasAdded(HTMLTrackElement*);
+    virtual void trackWillBeRemoved(HTMLTrackElement*);
+    virtual void trackSourceChanged(HTMLTrackElement*);
 #endif
 
 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
@@ -352,6 +358,7 @@ private:
 
 #if ENABLE(VIDEO_TRACK)
     void loadTextTracks();
+    void loadNextTextTrack(HTMLTrackElement*);
 
     // TextTrackClient
     virtual void textTrackReadyStateChanged(TextTrack*);
index 9207d7a..35ade5f 100644 (file)
@@ -32,6 +32,7 @@
 #include "HTMLMediaElement.h"
 #include "HTMLNames.h"
 #include "Logging.h"
+#include "ScriptEventListener.h"
 
 using namespace std;
 
@@ -59,22 +60,41 @@ void HTMLTrackElement::insertedIntoTree(bool deep)
 {
     HTMLElement::insertedIntoTree(deep);
     Element* parent = parentElement();
-    if (parent && parent->isMediaElement()) {
-        // TODO(annacc):
-        // static_cast<HTMLMediaElement*>(parentNode())->trackWasAdded(this);
-    }
+    if (parent && parent->isMediaElement())
+        static_cast<HTMLMediaElement*>(parentNode())->trackWasAdded(this);
 }
 
 void HTMLTrackElement::willRemove()
 {
     Element* parent = parentElement();
-    if (parent && parent->isMediaElement()) {
-        // TODO(annacc):
-        // static_cast<HTMLMediaElement*>(parentNode())->trackWillBeRemoved(this);
-    }
+    if (parent && parent->isMediaElement())
+        static_cast<HTMLMediaElement*>(parentNode())->trackWillBeRemoved(this);
     HTMLElement::willRemove();
 }
 
+void HTMLTrackElement::parseMappedAttribute(Attribute* attribute)
+{
+    const QualifiedName& attrName = attribute->name();
+    
+    if (attrName == onloadAttr)
+        setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attribute));
+    else if (attrName == onerrorAttr)
+        setAttributeEventListener(eventNames().errorEvent, createAttributeEventListener(this, attribute));
+    else
+        HTMLElement::parseMappedAttribute(attribute);
+}
+
+void HTMLTrackElement::attributeChanged(Attribute* attr, bool preserveDecls)
+{
+    HTMLElement::attributeChanged(attr, preserveDecls);
+
+    const QualifiedName& attrName = attr->name();
+    if (attrName == srcAttr) {
+        if (!getAttribute(srcAttr).isEmpty() && parentNode())
+            static_cast<HTMLMediaElement*>(parentNode())->trackSourceChanged(this);
+    }
+}
+
 KURL HTMLTrackElement::src() const
 {
     return document()->completeURL(getAttribute(srcAttr));
index 5b3002c..dd41180 100644 (file)
@@ -60,6 +60,9 @@ private:
     HTMLTrackElement(const QualifiedName&, Document*);
     virtual ~HTMLTrackElement();
 
+    virtual void parseMappedAttribute(Attribute*);
+    virtual void attributeChanged(Attribute*, bool preserveDecls);
+
     virtual void insertedIntoTree(bool);
     virtual void willRemove();
     virtual bool isURLAttribute(Attribute*) const;
index 154e4e0..3d6f8c3 100644 (file)
@@ -63,11 +63,14 @@ void LoadableTextTrack::cueLoadingStarted(TextTrackLoader* loader)
     setReadyState(TextTrack::Loading);
 }
 
-void LoadableTextTrack::cueLoadingCompleted(TextTrackLoader* loader, bool)
+void LoadableTextTrack::cueLoadingCompleted(TextTrackLoader* loader, bool loadingFailed)
 {
     ASSERT_UNUSED(loader, m_loader == loader);
 
-    // FIXME(62885): Implement.
+    loadingFailed ? setReadyState(TextTrack::Error) : setReadyState(TextTrack::Loaded);
+
+    if (m_loadingClient)
+        m_loadingClient->textTrackLoadingCompleted(this, loadingFailed);
 }
 
 } // namespace WebCore