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;
}