Diff
Modified: trunk/Source/WebCore/ChangeLog (134138 => 134139)
--- trunk/Source/WebCore/ChangeLog 2012-11-10 01:26:06 UTC (rev 134138)
+++ trunk/Source/WebCore/ChangeLog 2012-11-10 01:44:33 UTC (rev 134139)
@@ -1,3 +1,57 @@
+2012-11-09 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.
+
+ 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/MediaControlRootElement.cpp:
+ (WebCore::MediaControlRootElement::MediaControlRootElement):
+ (WebCore::MediaControlRootElement::create): New track container and list elements created.
+ (WebCore::MediaControlRootElement::setMediaController): Hook up the new elements to the controller..
+ (WebCore::MediaControlRootElement::hide):
+ (WebCore::MediaControlRootElement::makeTransparent):
+ (WebCore::MediaControlRootElement::reset):
+ (WebCore::MediaControlRootElement::reportedError):
+ (WebCore::MediaControlRootElement::toggleClosedCaptionTrackList): Shows or hides the popup with the list of tracks.
+ (WebCore):
+ * html/shadow/MediaControlRootElement.h:
+ (WebCore):
+ (MediaControlRootElement):
+ * html/shadow/MediaControlRootElementChromium.cpp:
+ (WebCore::MediaControlRootElementChromium::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):
+
2012-11-09 Noel Gordon <noel.gor...@gmail.com>
[chromium] Should pass fast/images/paletted-png-with-color-profile.html
Modified: trunk/Source/WebCore/css/mediaControls.css (134138 => 134139)
--- trunk/Source/WebCore/css/mediaControls.css 2012-11-10 01:26:06 UTC (rev 134138)
+++ trunk/Source/WebCore/css/mediaControls.css 2012-11-10 01:44:33 UTC (rev 134139)
@@ -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 (134138 => 134139)
--- trunk/Source/WebCore/css/mediaControlsQuickTime.css 2012-11-10 01:26:06 UTC (rev 134138)
+++ trunk/Source/WebCore/css/mediaControlsQuickTime.css 2012-11-10 01:44:33 UTC (rev 134139)
@@ -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 (134138 => 134139)
--- trunk/Source/WebCore/html/shadow/MediaControlElements.cpp 2012-11-10 01:26:06 UTC (rev 134138)
+++ trunk/Source/WebCore/html/shadow/MediaControlElements.cpp 2012-11-10 01:44:33 UTC (rev 134139)
@@ -43,6 +43,7 @@
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "HTMLVideoElement.h"
+#include "Language.h"
#include "LayoutRepainter.h"
#include "LocalizedStrings.h"
#include "MediaControlRootElement.h"
@@ -62,6 +63,9 @@
#include "Settings.h"
#include "StyleResolver.h"
#include "Text.h"
+#if ENABLE(VIDEO_TRACK)
+#include "TextTrackList.h"
+#endif
namespace WebCore {
@@ -114,6 +118,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)
@@ -851,25 +863,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();
}
@@ -877,17 +920,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 (134138 => 134139)
--- trunk/Source/WebCore/html/shadow/MediaControlElements.h 2012-11-10 01:26:06 UTC (rev 134138)
+++ trunk/Source/WebCore/html/shadow/MediaControlElements.h 2012-11-10 01:44:33 UTC (rev 134139)
@@ -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/MediaControlRootElement.cpp (134138 => 134139)
--- trunk/Source/WebCore/html/shadow/MediaControlRootElement.cpp 2012-11-10 01:26:06 UTC (rev 134138)
+++ trunk/Source/WebCore/html/shadow/MediaControlRootElement.cpp 2012-11-10 01:44:33 UTC (rev 134139)
@@ -62,6 +62,8 @@
, m_seekBackButton(0)
, m_seekForwardButton(0)
, m_toggleClosedCaptionsButton(0)
+ , m_closedCaptionsTrackList(0)
+ , m_closedCaptionsContainer(0)
, m_panelMuteButton(0)
, m_volumeSlider(0)
, m_volumeSliderMuteButton(0)
@@ -162,11 +164,25 @@
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>
@@ -266,6 +282,10 @@
m_seekForwardButton->setMediaController(controller);
if (m_toggleClosedCaptionsButton)
m_toggleClosedCaptionsButton->setMediaController(controller);
+ if (m_closedCaptionsTrackList)
+ m_closedCaptionsTrackList->setMediaController(controller);
+ if (m_closedCaptionsContainer)
+ m_closedCaptionsContainer->setMediaController(controller);
if (m_panelMuteButton)
m_panelMuteButton->setMediaController(controller);
if (m_volumeSlider)
@@ -302,6 +322,7 @@
m_panel->setIsDisplayed(false);
m_panel->hide();
m_volumeSliderContainer->hide();
+ m_closedCaptionsContainer->hide();
}
void MediaControlRootElement::makeOpaque()
@@ -313,6 +334,7 @@
{
m_panel->makeTransparent();
m_volumeSliderContainer->hide();
+ m_closedCaptionsContainer->hide();
}
void MediaControlRootElement::reset()
@@ -346,9 +368,10 @@
m_volumeSlider->setVolume(m_mediaController->volume());
if (m_toggleClosedCaptionsButton) {
- if (m_mediaController->hasClosedCaptions())
+ if (m_mediaController->hasClosedCaptions()) {
m_toggleClosedCaptionsButton->show();
- else
+ m_closedCaptionsTrackList->updateDisplay();
+ } else
m_toggleClosedCaptionsButton->hide();
}
@@ -447,6 +470,8 @@
m_volumeSliderContainer->hide();
if (m_toggleClosedCaptionsButton && !page->theme()->hasOwnDisabledStateHandlingFor(MediaToggleClosedCaptionsButtonPart))
m_toggleClosedCaptionsButton->hide();
+ if (m_closedCaptionsContainer)
+ m_closedCaptionsContainer->hide();
}
void MediaControlRootElement::updateStatusDisplay()
@@ -542,6 +567,19 @@
m_volumeSliderContainer->show();
}
+void MediaControlRootElement::toggleClosedCaptionTrackList()
+{
+ if (!m_mediaController->hasClosedCaptions())
+ return;
+
+ if (m_closedCaptionsContainer) {
+ if (m_closedCaptionsContainer->isShowing())
+ m_closedCaptionsContainer->hide();
+ else
+ m_closedCaptionsContainer->show();
+ }
+}
+
bool MediaControlRootElement::shouldHideControls()
{
return !m_panel->hovered();
Modified: trunk/Source/WebCore/html/shadow/MediaControlRootElement.h (134138 => 134139)
--- trunk/Source/WebCore/html/shadow/MediaControlRootElement.h 2012-11-10 01:26:06 UTC (rev 134138)
+++ trunk/Source/WebCore/html/shadow/MediaControlRootElement.h 2012-11-10 01:44:33 UTC (rev 134139)
@@ -42,7 +42,9 @@
class MediaControlSeekButtonElement;
class MediaControlRewindButtonElement;
class MediaControlReturnToRealtimeButtonElement;
+class MediaControlClosedCaptionsContainerElement;
class MediaControlToggleClosedCaptionsButtonElement;
+class MediaControlClosedCaptionsTrackListElement;
class MediaControlCurrentTimeDisplayElement;
class MediaControlTimelineElement;
class MediaControlTimeRemainingDisplayElement;
@@ -103,6 +105,8 @@
void updateTimeDisplay();
void updateStatusDisplay();
+ void toggleClosedCaptionTrackList();
+
#if ENABLE(VIDEO_TRACK)
void createTextTrackDisplay();
void showTextTrackDisplay();
@@ -141,6 +145,8 @@
MediaControlSeekBackButtonElement* m_seekBackButton;
MediaControlSeekForwardButtonElement* m_seekForwardButton;
MediaControlToggleClosedCaptionsButtonElement* m_toggleClosedCaptionsButton;
+ MediaControlClosedCaptionsTrackListElement* m_closedCaptionsTrackList;
+ MediaControlClosedCaptionsContainerElement* m_closedCaptionsContainer;
MediaControlPanelMuteButtonElement* m_panelMuteButton;
MediaControlVolumeSliderElement* m_volumeSlider;
MediaControlVolumeSliderMuteButtonElement* m_volumeSliderMuteButton;
Modified: trunk/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp (134138 => 134139)
--- trunk/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp 2012-11-10 01:26:06 UTC (rev 134138)
+++ trunk/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp 2012-11-10 01:44:33 UTC (rev 134139)
@@ -166,7 +166,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/html/shadow/MediaControls.h (134138 => 134139)
--- trunk/Source/WebCore/html/shadow/MediaControls.h 2012-11-10 01:26:06 UTC (rev 134138)
+++ trunk/Source/WebCore/html/shadow/MediaControls.h 2012-11-10 01:44:33 UTC (rev 134139)
@@ -70,6 +70,8 @@
virtual void updateTimeDisplay() = 0;
virtual void updateStatusDisplay() = 0;
+ virtual void toggleClosedCaptionTrackList() { }
+
virtual bool shouldHideControls() = 0;
#if ENABLE(VIDEO_TRACK)
Modified: trunk/Source/WebCore/platform/Language.cpp (134138 => 134139)
--- trunk/Source/WebCore/platform/Language.cpp 2012-11-10 01:26:06 UTC (rev 134138)
+++ trunk/Source/WebCore/platform/Language.cpp 2012-11-10 01:44:33 UTC (rev 134139)
@@ -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 (134138 => 134139)
--- trunk/Source/WebCore/platform/Language.h 2012-11-10 01:26:06 UTC (rev 134138)
+++ trunk/Source/WebCore/platform/Language.h 2012-11-10 01:44:33 UTC (rev 134139)
@@ -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();
}