Title: [134507] trunk/Source/WebCore
Revision
134507
Author
d...@apple.com
Date
2012-11-13 16:36:06 -0800 (Tue, 13 Nov 2012)

Log Message

Support list of tracks in caption media controls
https://bugs.webkit.org/show_bug.cgi?id=101669

Reviewed by Eric Carlson.

Attempt four of commit. The first two times caused build failures on Chromium. The third time
crashed the Windows test bot. It's also been rebased since r134488.

Add some new elements to the media control shadow DOM that display the list of available
tracks on an audio/video element. The UI is hidden by default everywhere but on Mac,
where it is given a very basic design. At the moment only the list of available tracks
are displayed; The followup bug will make the UI active: https://bugs.webkit.org/show_bug.cgi?id=101670

No new tests - this doesn't expose any testable surface.

* css/mediaControls.css: Added default rules that hide the new elements.
* css/mediaControlsQuickTime.css: Specific rules that give a basic rendering of the new track list.
* html/shadow/MediaControlElements.cpp:
(WebCore::MediaControlElement::isShowing): Tests for the visibility of a control.
(WebCore::MediaControlClosedCaptionsContainerElement::MediaControlClosedCaptionsContainerElement):
(WebCore::MediaControlClosedCaptionsContainerElement::create):
(WebCore::MediaControlClosedCaptionsContainerElement::shadowPseudoId):
(WebCore::MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement):
(WebCore::MediaControlToggleClosedCaptionsButtonElement::create): Now takes a reference to the media controls as a parameter.
(WebCore::MediaControlToggleClosedCaptionsButtonElement::updateDisplayType):
(WebCore::MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler):
(WebCore::MediaControlToggleClosedCaptionsButtonElement::shadowPseudoId):
(WebCore::MediaControlClosedCaptionsTrackListElement::MediaControlClosedCaptionsTrackListElement): New element for holding a list of tracks to display.
* html/shadow/MediaControlElements.h:
(MediaControlElement):
(MediaControlToggleClosedCaptionsButtonElement):
(MediaControlClosedCaptionsContainerElement):
(MediaControlClosedCaptionsTrackListElement): Examines the media element to build a shadow DOM that lists all the tracks available.
* html/shadow/MediaControlsApple.cpp:
(WebCore::MediaControlsApple::MediaControlsApple):
(WebCore::MediaControlsApple::create): New track container and list elements created.
(WebCore::MediaControlsApple::setMediaController): Hook up the new elements to the controller..
(WebCore::MediaControlsApple::hide):
(WebCore::MediaControlsApple::makeTransparent):
(WebCore::MediaControlsApple::reset):
(WebCore::MediaControlsApple::reportedError):
(WebCore::MediaControlsApple::toggleClosedCaptionTrackList): Shows or hides the popup with the list of tracks.
(WebCore):
* html/shadow/MediaControlsApple.h:
(MediaControlsApple):
* html/shadow/MediaControlsChromium.cpp:
(WebCore::MediaControlsChromium::initializeControls): Pass in the controls as a parameter.
* html/shadow/MediaControls.h:
(MediaControls):
* platform/Language.cpp:
(WebCore::displayNameForLanguageLocale): New function to return a human-readable name for a locale, given the identifier input.
* platform/Language.h:
(WebCore):
* rendering/RenderMediaControls.cpp:
(WebCore::RenderMediaControls::paintMediaControlsPart): New enum values into switch.
* rendering/RenderMediaControlsChromium.cpp:
(WebCore::RenderMediaControlsChromium::paintMediaControlsPart): New enum values into switch.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (134506 => 134507)


--- trunk/Source/WebCore/ChangeLog	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/ChangeLog	2012-11-14 00:36:06 UTC (rev 134507)
@@ -1,3 +1,63 @@
+2012-11-13  Dean Jackson  <d...@apple.com>
+
+        Support list of tracks in caption media controls
+        https://bugs.webkit.org/show_bug.cgi?id=101669
+
+        Reviewed by Eric Carlson.
+
+        Attempt four of commit. The first two times caused build failures on Chromium. The third time
+        crashed the Windows test bot. It's also been rebased since r134488.
+
+        Add some new elements to the media control shadow DOM that display the list of available
+        tracks on an audio/video element. The UI is hidden by default everywhere but on Mac,
+        where it is given a very basic design. At the moment only the list of available tracks
+        are displayed; The followup bug will make the UI active: https://bugs.webkit.org/show_bug.cgi?id=101670
+
+        No new tests - this doesn't expose any testable surface.
+
+        * css/mediaControls.css: Added default rules that hide the new elements.
+        * css/mediaControlsQuickTime.css: Specific rules that give a basic rendering of the new track list.
+        * html/shadow/MediaControlElements.cpp:
+        (WebCore::MediaControlElement::isShowing): Tests for the visibility of a control.
+        (WebCore::MediaControlClosedCaptionsContainerElement::MediaControlClosedCaptionsContainerElement):
+        (WebCore::MediaControlClosedCaptionsContainerElement::create):
+        (WebCore::MediaControlClosedCaptionsContainerElement::shadowPseudoId):
+        (WebCore::MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement):
+        (WebCore::MediaControlToggleClosedCaptionsButtonElement::create): Now takes a reference to the media controls as a parameter.
+        (WebCore::MediaControlToggleClosedCaptionsButtonElement::updateDisplayType):
+        (WebCore::MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler):
+        (WebCore::MediaControlToggleClosedCaptionsButtonElement::shadowPseudoId):
+        (WebCore::MediaControlClosedCaptionsTrackListElement::MediaControlClosedCaptionsTrackListElement): New element for holding a list of tracks to display.
+        * html/shadow/MediaControlElements.h:
+        (MediaControlElement):
+        (MediaControlToggleClosedCaptionsButtonElement):
+        (MediaControlClosedCaptionsContainerElement):
+        (MediaControlClosedCaptionsTrackListElement): Examines the media element to build a shadow DOM that lists all the tracks available.
+        * html/shadow/MediaControlsApple.cpp:
+        (WebCore::MediaControlsApple::MediaControlsApple):
+        (WebCore::MediaControlsApple::create): New track container and list elements created.
+        (WebCore::MediaControlsApple::setMediaController): Hook up the new elements to the controller..
+        (WebCore::MediaControlsApple::hide):
+        (WebCore::MediaControlsApple::makeTransparent):
+        (WebCore::MediaControlsApple::reset):
+        (WebCore::MediaControlsApple::reportedError):
+        (WebCore::MediaControlsApple::toggleClosedCaptionTrackList): Shows or hides the popup with the list of tracks.
+        (WebCore):
+        * html/shadow/MediaControlsApple.h:
+        (MediaControlsApple):
+        * html/shadow/MediaControlsChromium.cpp:
+        (WebCore::MediaControlsChromium::initializeControls): Pass in the controls as a parameter.
+        * html/shadow/MediaControls.h:
+        (MediaControls):
+        * platform/Language.cpp:
+        (WebCore::displayNameForLanguageLocale): New function to return a human-readable name for a locale, given the identifier input.
+        * platform/Language.h:
+        (WebCore):
+        * rendering/RenderMediaControls.cpp:
+        (WebCore::RenderMediaControls::paintMediaControlsPart): New enum values into switch.
+        * rendering/RenderMediaControlsChromium.cpp:
+        (WebCore::RenderMediaControlsChromium::paintMediaControlsPart): New enum values into switch.
+
 2012-11-13  Dimitri Glazkov  <dglaz...@chromium.org>
 
         Unreviewed, rolling out r134377.

Modified: trunk/Source/WebCore/css/mediaControls.css (134506 => 134507)


--- trunk/Source/WebCore/css/mediaControls.css	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/css/mediaControls.css	2012-11-14 00:36:06 UTC (rev 134507)
@@ -187,6 +187,14 @@
     color: inherit;
 }
 
+audio::-webkit-media-controls-closed-captions-container, video::-webkit-media-controls-closed-captions-container {
+    display: none;
+}
+
+audio::-webkit-media-controls-closed-captions-track-list, video::-webkit-media-controls-closed-captions-track-list {
+    display: none;
+}
+
 audio::-webkit-media-controls-volume-slider-mute-button, video::-webkit-media-controls-volume-slider-mute-button {
     -webkit-appearance: media-volume-slider-mute-button;
     display: none;

Modified: trunk/Source/WebCore/css/mediaControlsQuickTime.css (134506 => 134507)


--- trunk/Source/WebCore/css/mediaControlsQuickTime.css	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/css/mediaControlsQuickTime.css	2012-11-14 00:36:06 UTC (rev 134507)
@@ -188,17 +188,6 @@
     text-decoration: none;
 }
 
-audio::-webkit-media-controls-toggle-closed-captions-button, video::-webkit-media-controls-toggle-closed-captions-button {
-    -webkit-appearance: media-toggle-closed-captions-button;
-    display: -webkit-box;
-    width: 16px;
-    height: 16px;
-    margin-left: 7px;
-    margin-right: 7px;
-    -webkit-box-ordinal-group: 3; /* between mute and fullscreen */
-    border: none !important;
-}
-
 audio::-webkit-media-controls-volume-slider-container, video::-webkit-media-controls-volume-slider-container {
     -webkit-appearance: media-volume-slider-container;
     position: absolute;
@@ -239,3 +228,104 @@
 
     border: none !important;
 }
+
+audio::-webkit-media-controls-toggle-closed-captions-button, video::-webkit-media-controls-toggle-closed-captions-button {
+    -webkit-appearance: media-toggle-closed-captions-button;
+    display: -webkit-box;
+    width: 16px;
+    height: 16px;
+    margin-left: 7px;
+    margin-right: 7px;
+    -webkit-box-ordinal-group: 3; /* between mute and fullscreen */
+    border: none !important;
+}
+
+audio::-webkit-media-controls-closed-captions-container, video::-webkit-media-controls-closed-captions-container {
+    -webkit-appearance: media-closed-captions-container;
+    position: absolute;
+    display: block;
+    bottom: 29px;
+    margin-left: -155px;
+    z-index: 2;
+    width: 200px;
+    height: 250px;
+    background-color: rgba(0, 0, 0, 0.85);
+    border: 1px solid rgb(66, 66, 66);
+    border-radius: 8px;
+}
+
+audio::-webkit-media-controls-closed-captions-track-list, video::-webkit-media-controls-closed-captions-track-list {
+    -webkit-appearance: media-closed-captions-track-list;
+    position: absolute;
+    display: block;
+    top: 5px;
+    left: 5px;
+    width: 190px;
+    height: 240px;
+    overflow-x: hidden;
+    overflow-y: scroll;
+    text-align: left;
+    font-family: "Helvetica Bold", "Helvetica";
+    font-weight: bold;
+    font-size: 9pt;
+}
+
+audio::-webkit-media-controls-closed-captions-track-list h3,
+video::-webkit-media-controls-closed-captions-track-list h3 {
+    margin: 0;
+    color: #bbb;
+    text-shadow: 0 1px 0 black;
+    padding-left: 4px;
+    padding-top: 4px;
+    padding-bottom: 4px;
+    border-bottom: 1px solid #555;
+    font-size: 9pt;
+}
+
+audio::-webkit-media-controls-closed-captions-track-list ul,
+video::-webkit-media-controls-closed-captions-track-list ul {
+    list-style-type: none;
+    margin: 0 0 8px 0;
+    padding: 0;
+}
+
+audio::-webkit-media-controls-closed-captions-track-list li,
+video::-webkit-media-controls-closed-captions-track-list li {
+    color: white;
+    text-shadow: 0 1px 0 black;
+    margin: 0;
+    padding-left: 24px;
+    padding-right: 10px;
+    padding-top: 0.35em;
+    padding-bottom: 0.3em;
+    width: 190px;
+    height: 2.0em;
+    border-bottom: 1px solid #555;
+    box-sizing: border-box;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    -webkit-text-overflow: ellipsis;
+}
+
+audio::-webkit-media-controls-closed-captions-track-list li:hover,
+video::-webkit-media-controls-closed-captions-track-list li:hover {
+    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(79, 112, 245)), color-stop(1, rgb(28, 66, 245)));
+    border-bottom: 1px solid rgb(28, 66, 245);
+}
+
+audio::-webkit-media-controls-closed-captions-track-list li.selected,
+video::-webkit-media-controls-closed-captions-track-list li.selected {
+    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA9CAYAAADmgpoeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RTBEQkI5QzgyMTc4MTFFMkJERDdBRjI3NEQwNzZERjAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RTBEQkI5QzkyMTc4MTFFMkJERDdBRjI3NEQwNzZERjAiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFMERCQjlDNjIxNzgxMUUyQkREN0FGMjc0RDA3NkRGMCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFMERCQjlDNzIxNzgxMUUyQkREN0FGMjc0RDA3NkRGMCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqpWz0UAAAHPSURBVHja7JqBbYQwDEXdDRghI7BBGSEjZARGyAaMwAg3AtcJMkJug4xAUymqTggVO1yJbZ0lCyGd0D3Z/Pw4fICAWNfV5IvN+Zmzz2k2P7mX61fOx9M9X6Ccy0qLOWfHGcqt9Ji4V6oGyr2hGkD1GqG6nFEVVAGbNEIN6qAKWKCsU1KgRgLUIgXqRzASEiqydhQbME+oVi8FyhCqNYKUKGZVz3v1VC1MpLJlUVetUWO1AkgKgnUaJEFh161ZWrW8OsEoYJhqeWlQDlmtThpY1FitQWu1bhqVELsgi1NCr65aBNEYrmibefNnQrFBpuJ5tum2pFgdjOOeKMqFFA33n1CUQWXAwJXnHko8B1dAgkNOn/wVLzkVbnnBrNBcpWBUOH9i7bpxHontjsWQm0nLeSaxO8hEiFFsubCGmpZEnnH5lmCU8fNvSyLbsK0vJB7vLMhK8xiAEsXEN3MalXDUby3aOI1Kc5xeAMZve1L5mYKMo6CTLRmBa5xsSd4HDMQzY1kzjYqWFHMoTm1JB1KCuHCLG4QGdvuuC72kBYlx4OYTSI2D7c0MkuOPtc2C9NgRkgQaYkdIJtASm5F2rwnMsHfyJ+V/0gjWcWjDbwEGAN9/NX8H7V/FAAAAAElFTkSuQmCC');
+    background-repeat: no-repeat;
+    background-position: 0.5em 0.5em;
+    background-size: 1em 1em;
+}
+
+audio::-webkit-media-controls-closed-captions-track-list li.selected:hover,
+video::-webkit-media-controls-closed-captions-track-list li.selected:hover {
+    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA9CAYAAADmgpoeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RTBEQkI5QzgyMTc4MTFFMkJERDdBRjI3NEQwNzZERjAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RTBEQkI5QzkyMTc4MTFFMkJERDdBRjI3NEQwNzZERjAiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFMERCQjlDNjIxNzgxMUUyQkREN0FGMjc0RDA3NkRGMCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFMERCQjlDNzIxNzgxMUUyQkREN0FGMjc0RDA3NkRGMCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqpWz0UAAAHPSURBVHja7JqBbYQwDEXdDRghI7BBGSEjZARGyAaMwAg3AtcJMkJug4xAUymqTggVO1yJbZ0lCyGd0D3Z/Pw4fICAWNfV5IvN+Zmzz2k2P7mX61fOx9M9X6Ccy0qLOWfHGcqt9Ji4V6oGyr2hGkD1GqG6nFEVVAGbNEIN6qAKWKCsU1KgRgLUIgXqRzASEiqydhQbME+oVi8FyhCqNYKUKGZVz3v1VC1MpLJlUVetUWO1AkgKgnUaJEFh161ZWrW8OsEoYJhqeWlQDlmtThpY1FitQWu1bhqVELsgi1NCr65aBNEYrmibefNnQrFBpuJ5tum2pFgdjOOeKMqFFA33n1CUQWXAwJXnHko8B1dAgkNOn/wVLzkVbnnBrNBcpWBUOH9i7bpxHontjsWQm0nLeSaxO8hEiFFsubCGmpZEnnH5lmCU8fNvSyLbsK0vJB7vLMhK8xiAEsXEN3MalXDUby3aOI1Kc5xeAMZve1L5mYKMo6CTLRmBa5xsSd4HDMQzY1kzjYqWFHMoTm1JB1KCuHCLG4QGdvuuC72kBYlx4OYTSI2D7c0MkuOPtc2C9NgRkgQaYkdIJtASm5F2rwnMsHfyJ+V/0gjWcWjDbwEGAN9/NX8H7V/FAAAAAElFTkSuQmCC'), -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(79, 112, 245)), color-stop(1, rgb(28, 66, 245)));
+    background-repeat: no-repeat, repeat;
+    background-position: 0.5em 0.5em, top left;
+    background-size: 1em 1em, 100% 100%;
+}

Modified: trunk/Source/WebCore/html/shadow/MediaControlElements.cpp (134506 => 134507)


--- trunk/Source/WebCore/html/shadow/MediaControlElements.cpp	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/html/shadow/MediaControlElements.cpp	2012-11-14 00:36:06 UTC (rev 134507)
@@ -43,6 +43,7 @@
 #include "HTMLMediaElement.h"
 #include "HTMLNames.h"
 #include "HTMLVideoElement.h"
+#include "Language.h"
 #include "LayoutRepainter.h"
 #include "LocalizedStrings.h"
 #include "MediaControls.h"
@@ -61,6 +62,9 @@
 #include "Settings.h"
 #include "StyleResolver.h"
 #include "Text.h"
+#if ENABLE(VIDEO_TRACK)
+#include "TextTrackList.h"
+#endif
 
 namespace WebCore {
 
@@ -113,6 +117,14 @@
     setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
 }
 
+bool MediaControlElement::isShowing() const
+{
+    const StylePropertySet* propertySet = inlineStyle();
+    // Following the code from show() and hide() above, we only have
+    // to check for the presense of inline display.
+    return (!propertySet || !propertySet->getPropertyCSSValue(CSSPropertyDisplay));
+}
+
 // ----------------------------
 
 inline MediaControlPanelElement::MediaControlPanelElement(Document* document)
@@ -850,25 +862,56 @@
 
 // ----------------------------
 
-inline MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document* document)
+inline MediaControlClosedCaptionsContainerElement::MediaControlClosedCaptionsContainerElement(Document* document)
+    : MediaControlElement(document)
+{
+}
+
+PassRefPtr<MediaControlClosedCaptionsContainerElement> MediaControlClosedCaptionsContainerElement::create(Document* document)
+{
+    RefPtr<MediaControlClosedCaptionsContainerElement> element = adoptRef(new MediaControlClosedCaptionsContainerElement(document));
+    element->hide();
+    return element.release();
+}
+
+const AtomicString& MediaControlClosedCaptionsContainerElement::shadowPseudoId() const
+{
+    DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-closed-captions-container", AtomicString::ConstructFromLiteral));
+    return id;
+}
+
+// ----------------------------
+
+inline MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document* document, MediaControls* controls)
     : MediaControlInputElement(document, MediaShowClosedCaptionsButton)
+    , m_controls(controls)
 {
 }
 
-PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(Document* document)
+PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(Document* document, MediaControls* controls)
 {
-    RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(document));
+    ASSERT(controls);
+
+    RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(document, controls));
     button->createShadowSubtree();
     button->setType("button");
     button->hide();
     return button.release();
 }
 
+void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
+{
+    setDisplayType(mediaController()->closedCaptionsVisible() ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton);
+}
+
 void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event)
 {
     if (event->type() == eventNames().clickEvent) {
+        // FIXME: This is now incorrectly doing two things at once: showing the list of captions and toggling display.
+        // https://bugs.webkit.org/show_bug.cgi?id=101670
         mediaController()->setClosedCaptionsVisible(!mediaController()->closedCaptionsVisible());
         setChecked(mediaController()->closedCaptionsVisible());
+        m_controls->toggleClosedCaptionTrackList();
         updateDisplayType();
         event->setDefaultHandled();
     }
@@ -876,17 +919,117 @@
     HTMLInputElement::defaultEventHandler(event);
 }
 
-void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
+const AtomicString& MediaControlToggleClosedCaptionsButtonElement::shadowPseudoId() const
 {
-    setDisplayType(mediaController()->closedCaptionsVisible() ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton);
+    DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-toggle-closed-captions-button", AtomicString::ConstructFromLiteral));
+    return id;
 }
 
-const AtomicString& MediaControlToggleClosedCaptionsButtonElement::shadowPseudoId() const
+// ----------------------------
+
+inline MediaControlClosedCaptionsTrackListElement::MediaControlClosedCaptionsTrackListElement(Document* document)
+    : MediaControlElement(document)
 {
-    DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-toggle-closed-captions-button", AtomicString::ConstructFromLiteral));
+}
+
+PassRefPtr<MediaControlClosedCaptionsTrackListElement> MediaControlClosedCaptionsTrackListElement::create(Document* document)
+{
+    RefPtr<MediaControlClosedCaptionsTrackListElement> element = adoptRef(new MediaControlClosedCaptionsTrackListElement(document));
+    return element.release();
+}
+
+void MediaControlClosedCaptionsTrackListElement::defaultEventHandler(Event* event)
+{
+    // FIXME: Hook this up to actual text tracks.
+    // https://bugs.webkit.org/show_bug.cgi?id=101670
+    UNUSED_PARAM(event);
+}
+
+const AtomicString& MediaControlClosedCaptionsTrackListElement::shadowPseudoId() const
+{
+    DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-closed-captions-track-list", AtomicString::ConstructFromLiteral));
     return id;
 }
 
+void MediaControlClosedCaptionsTrackListElement::updateDisplay()
+{
+#if ENABLE(VIDEO_TRACK)
+    // Remove any existing content.
+    removeChildren();
+
+    if (!mediaController()->hasClosedCaptions())
+        return;
+
+    HTMLMediaElement* mediaElement = toParentMediaElement(this);
+    if (!mediaElement)
+        return;
+
+    TextTrackList* trackList = mediaElement->textTracks();
+
+    if (!trackList || !trackList->length())
+        return;
+
+    Document* doc = document();
+
+    RefPtr<Element> captionsSection = doc->createElement(sectionTag, ASSERT_NO_EXCEPTION);
+    RefPtr<Element> captionsHeader = doc->createElement(h3Tag, ASSERT_NO_EXCEPTION);
+    captionsHeader->appendChild(doc->createTextNode("Closed Captions"));
+    captionsSection->appendChild(captionsHeader);
+    RefPtr<Element> captionsList = doc->createElement(ulTag, ASSERT_NO_EXCEPTION);
+
+    RefPtr<Element> subtitlesSection = doc->createElement(sectionTag, ASSERT_NO_EXCEPTION);
+    RefPtr<Element> subtitlesHeader = doc->createElement(h3Tag, ASSERT_NO_EXCEPTION);
+    subtitlesHeader->appendChild(doc->createTextNode("Subtitles"));
+    subtitlesSection->appendChild(subtitlesHeader);
+    RefPtr<Element> subtitlesList = doc->createElement(ulTag, ASSERT_NO_EXCEPTION);
+
+    RefPtr<Element> trackItem;
+
+    trackItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION);
+    trackItem->appendChild(doc->createTextNode("Off"));
+    // FIXME: These lists are not yet live. Mark the Off entry as the selected one for now.
+    trackItem->setAttribute(classAttr, "selected");
+    captionsList->appendChild(trackItem);
+
+    trackItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION);
+    trackItem->appendChild(doc->createTextNode("Off"));
+    // FIXME: These lists are not yet live. Mark the Off entry as the selected one for now.
+    trackItem->setAttribute(classAttr, "selected");
+    subtitlesList->appendChild(trackItem);
+
+    bool hasCaptions = false;
+    bool hasSubtitles = false;
+
+    for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
+        TextTrack* track = trackList->item(i);
+        trackItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION);
+        AtomicString labelText = track->label();
+        if (labelText.isNull() || labelText.isEmpty())
+            labelText = displayNameForLanguageLocale(track->language());
+        if (labelText.isNull() || labelText.isEmpty())
+            labelText = "No Label";
+
+        if (track->kind() == track->captionsKeyword()) {
+            hasCaptions = true;
+            captionsList->appendChild(trackItem);
+        }
+        if (track->kind() == track->subtitlesKeyword()) {
+            hasSubtitles = true;
+            subtitlesList->appendChild(trackItem);
+        }
+        trackItem->appendChild(doc->createTextNode(labelText));
+    }
+
+    captionsSection->appendChild(captionsList);
+    subtitlesSection->appendChild(subtitlesList);
+
+    if (hasCaptions)
+        appendChild(captionsSection);
+    if (hasSubtitles)
+        appendChild(subtitlesSection);
+#endif
+}
+
 // ----------------------------
 
 MediaControlTimelineElement::MediaControlTimelineElement(Document* document, MediaControls* controls)

Modified: trunk/Source/WebCore/html/shadow/MediaControlElements.h (134506 => 134507)


--- trunk/Source/WebCore/html/shadow/MediaControlElements.h	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/html/shadow/MediaControlElements.h	2012-11-14 00:36:06 UTC (rev 134507)
@@ -75,6 +75,8 @@
     MediaTextTrackDisplay,
     MediaExitFullscreenButton,
     MediaOverlayPlayButton,
+    MediaClosedCaptionsContainer,
+    MediaClosedCaptionsTrackList,
 };
 
 HTMLMediaElement* toParentMediaElement(Node*);
@@ -88,6 +90,7 @@
 public:
     void hide();
     void show();
+    bool isShowing() const;
 
     virtual MediaControlElementType displayType() const = 0;
 
@@ -380,20 +383,54 @@
 
 class MediaControlToggleClosedCaptionsButtonElement : public MediaControlInputElement {
 public:
-    static PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> create(Document*);
+    static PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> create(Document*, MediaControls*);
 
+    virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
     virtual void defaultEventHandler(Event*);
-    virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
     virtual void updateDisplayType();
 
 private:
-    MediaControlToggleClosedCaptionsButtonElement(Document*);
+    MediaControlToggleClosedCaptionsButtonElement(Document*, MediaControls*);
+    virtual const AtomicString& shadowPseudoId() const;
 
+    MediaControls* m_controls;
+};
+
+// ----------------------------
+
+class MediaControlClosedCaptionsContainerElement : public MediaControlElement {
+public:
+    static PassRefPtr<MediaControlClosedCaptionsContainerElement> create(Document*);
+
+    virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
+
+private:
+    MediaControlClosedCaptionsContainerElement(Document*);
+
+    virtual MediaControlElementType displayType() const { return MediaClosedCaptionsContainer; }
     virtual const AtomicString& shadowPseudoId() const;
-};    
+};
 
 // ----------------------------
 
+class MediaControlClosedCaptionsTrackListElement : public MediaControlElement {
+public:
+    static PassRefPtr<MediaControlClosedCaptionsTrackListElement> create(Document*);
+
+    virtual void defaultEventHandler(Event*);
+    virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
+
+    void updateDisplay();
+
+private:
+    MediaControlClosedCaptionsTrackListElement(Document*);
+
+    virtual MediaControlElementType displayType() const { return MediaClosedCaptionsTrackList; }
+    virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
 class MediaControlTimelineElement : public MediaControlInputElement {
 public:
     static PassRefPtr<MediaControlTimelineElement> create(Document*, MediaControls*);

Modified: trunk/Source/WebCore/html/shadow/MediaControls.h (134506 => 134507)


--- trunk/Source/WebCore/html/shadow/MediaControls.h	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/html/shadow/MediaControls.h	2012-11-14 00:36:06 UTC (rev 134507)
@@ -88,6 +88,7 @@
     virtual void changedVolume();
 
     virtual void changedClosedCaptionsVisibility();
+    virtual void toggleClosedCaptionTrackList() { }
 
     virtual void enteredFullscreen();
     virtual void exitedFullscreen();

Modified: trunk/Source/WebCore/html/shadow/MediaControlsApple.cpp (134506 => 134507)


--- trunk/Source/WebCore/html/shadow/MediaControlsApple.cpp	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/html/shadow/MediaControlsApple.cpp	2012-11-14 00:36:06 UTC (rev 134507)
@@ -55,6 +55,8 @@
     , m_timelineContainer(0)
     , m_seekBackButton(0)
     , m_seekForwardButton(0)
+    , m_closedCaptionsTrackList(0)
+    , m_closedCaptionsContainer(0)
     , m_volumeSliderMuteButton(0)
     , m_volumeSliderContainer(0)
     , m_fullScreenMinVolumeButton(0)
@@ -145,11 +147,24 @@
         return 0;
 
     if (document->page()->theme()->supportsClosedCaptioning()) {
-        RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document);
+        RefPtr<MediaControlClosedCaptionsContainerElement> closedCaptionsContainer = MediaControlClosedCaptionsContainerElement::create(document);
+
+        RefPtr<MediaControlClosedCaptionsTrackListElement> closedCaptionsTrackList = MediaControlClosedCaptionsTrackListElement::create(document);
+        controls->m_closedCaptionsTrackList = closedCaptionsTrackList.get();
+        closedCaptionsContainer->appendChild(closedCaptionsTrackList.release(), ec, true);
+        if (ec)
+            return 0;
+
+        RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document, controls.get());
         controls->m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
         panel->appendChild(toggleClosedCaptionsButton.release(), ec, true);
         if (ec)
             return 0;
+
+        controls->m_closedCaptionsContainer = closedCaptionsContainer.get();
+        panel->appendChild(closedCaptionsContainer.release(), ec, true);
+        if (ec)
+            return 0;
     }
 
     // FIXME: Only create when needed <http://webkit.org/b/57163>
@@ -252,18 +267,26 @@
         m_fullScreenVolumeSlider->setMediaController(controller);
     if (m_fullScreenMaxVolumeButton)
         m_fullScreenMaxVolumeButton->setMediaController(controller);
+    if (m_closedCaptionsTrackList)
+        m_closedCaptionsTrackList->setMediaController(controller);
+    if (m_closedCaptionsContainer)
+        m_closedCaptionsContainer->setMediaController(controller);
 }
 
 void MediaControlsApple::hide()
 {
     MediaControls::hide();
     m_volumeSliderContainer->hide();
+    if (m_closedCaptionsContainer)
+        m_closedCaptionsContainer->hide();
 }
 
 void MediaControlsApple::makeTransparent()
 {
     MediaControls::makeTransparent();
     m_volumeSliderContainer->hide();
+    if (m_closedCaptionsContainer)
+        m_closedCaptionsContainer->hide();
 }
 
 void MediaControlsApple::reset()
@@ -297,9 +320,11 @@
         m_volumeSlider->setVolume(m_mediaController->volume());
 
     if (m_toggleClosedCaptionsButton) {
-        if (m_mediaController->hasClosedCaptions())
+        if (m_mediaController->hasClosedCaptions()) {
             m_toggleClosedCaptionsButton->show();
-        else
+            if (m_closedCaptionsTrackList)
+                m_closedCaptionsTrackList->updateDisplay();
+        } else
             m_toggleClosedCaptionsButton->hide();
     }
 
@@ -370,6 +395,8 @@
         m_volumeSliderContainer->hide();
     if (m_toggleClosedCaptionsButton && !page->theme()->hasOwnDisabledStateHandlingFor(MediaToggleClosedCaptionsButtonPart))
         m_toggleClosedCaptionsButton->hide();
+    if (m_closedCaptionsContainer)
+        m_closedCaptionsContainer->hide();
 }
 
 void MediaControlsApple::updateStatusDisplay()
@@ -446,6 +473,19 @@
         m_volumeSliderContainer->show();
 }
 
+void MediaControlsApple::toggleClosedCaptionTrackList()
+{
+    if (!m_mediaController->hasClosedCaptions())
+        return;
+
+    if (m_closedCaptionsContainer) {
+        if (m_closedCaptionsContainer->isShowing())
+            m_closedCaptionsContainer->hide();
+        else
+            m_closedCaptionsContainer->show();
+    }
 }
 
+}
+
 #endif

Modified: trunk/Source/WebCore/html/shadow/MediaControlsApple.h (134506 => 134507)


--- trunk/Source/WebCore/html/shadow/MediaControlsApple.h	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/html/shadow/MediaControlsApple.h	2012-11-14 00:36:06 UTC (rev 134507)
@@ -58,6 +58,8 @@
     virtual void updateCurrentTimeDisplay() OVERRIDE;
     virtual void updateStatusDisplay() OVERRIDE;
 
+    void toggleClosedCaptionTrackList();
+
 private:
     MediaControlsApple(Document*);
 
@@ -69,6 +71,8 @@
     MediaControlTimelineContainerElement* m_timelineContainer;
     MediaControlSeekBackButtonElement* m_seekBackButton;
     MediaControlSeekForwardButtonElement* m_seekForwardButton;
+    MediaControlClosedCaptionsTrackListElement* m_closedCaptionsTrackList;
+    MediaControlClosedCaptionsContainerElement* m_closedCaptionsContainer;
     MediaControlVolumeSliderMuteButtonElement* m_volumeSliderMuteButton;
     MediaControlVolumeSliderContainerElement* m_volumeSliderContainer;
     MediaControlFullscreenVolumeMinButtonElement* m_fullScreenMinVolumeButton;

Modified: trunk/Source/WebCore/html/shadow/MediaControlsChromium.cpp (134506 => 134507)


--- trunk/Source/WebCore/html/shadow/MediaControlsChromium.cpp	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/html/shadow/MediaControlsChromium.cpp	2012-11-14 00:36:06 UTC (rev 134507)
@@ -136,7 +136,7 @@
         return false;
 
     if (document->page()->theme()->supportsClosedCaptioning()) {
-        RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document);
+        RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document, this);
         m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
         panel->appendChild(toggleClosedCaptionsButton.release(), ec, true);
         if (ec)

Modified: trunk/Source/WebCore/platform/Language.cpp (134506 => 134507)


--- trunk/Source/WebCore/platform/Language.cpp	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/platform/Language.cpp	2012-11-14 00:36:06 UTC (rev 134507)
@@ -27,8 +27,13 @@
 #include "Language.h"
 
 #include <wtf/HashMap.h>
+#include <wtf/RetainPtr.h>
 #include <wtf/text/WTFString.h>
 
+#if PLATFORM(MAC)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
 namespace WebCore {
 
 typedef HashMap<void*, LanguageChangeObserverFunction> ObserverMap;
@@ -142,5 +147,14 @@
 
     return emptyString();
 }
-    
+
+String displayNameForLanguageLocale(const String& localeName)
+{
+#if PLATFORM(MAC)
+    if (!localeName.isNull() && !localeName.isEmpty())
+        return CFLocaleCopyDisplayNameForPropertyValue(CFLocaleCopyCurrent(), kCFLocaleIdentifier, localeName.createCFString().get());
+#endif
+    return localeName;
 }
+
+}

Modified: trunk/Source/WebCore/platform/Language.h (134506 => 134507)


--- trunk/Source/WebCore/platform/Language.h	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/platform/Language.h	2012-11-14 00:36:06 UTC (rev 134507)
@@ -43,6 +43,8 @@
 
 Vector<String> platformUserPreferredLanguages();
 
+String displayNameForLanguageLocale(const String&);
+
 // Called from platform specific code when the user's preferred language(s) change.
 void languageDidChange();
 }

Modified: trunk/Source/WebCore/rendering/RenderMediaControls.cpp (134506 => 134507)


--- trunk/Source/WebCore/rendering/RenderMediaControls.cpp	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/rendering/RenderMediaControls.cpp	2012-11-14 00:36:06 UTC (rev 134507)
@@ -197,9 +197,11 @@
         ASSERT_NOT_REACHED();
     case MediaTextTrackDisplayContainer:
     case MediaTextTrackDisplay:
+    case MediaClosedCaptionsContainer:
+    case MediaClosedCaptionsTrackList:
         ASSERT_NOT_REACHED();
         break;
-}
+    }
 
     return false;
 }

Modified: trunk/Source/WebCore/rendering/RenderMediaControlsChromium.cpp (134506 => 134507)


--- trunk/Source/WebCore/rendering/RenderMediaControlsChromium.cpp	2012-11-14 00:33:45 UTC (rev 134506)
+++ trunk/Source/WebCore/rendering/RenderMediaControlsChromium.cpp	2012-11-14 00:36:06 UTC (rev 134507)
@@ -383,6 +383,8 @@
     case MediaTextTrackDisplay:
     case MediaFullScreenVolumeSlider:
     case MediaFullScreenVolumeSliderThumb:
+    case MediaClosedCaptionsContainer:
+    case MediaClosedCaptionsTrackList:
         ASSERT_NOT_REACHED();
         break;
     }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to