Diff
Modified: trunk/LayoutTests/ChangeLog (127034 => 127035)
--- trunk/LayoutTests/ChangeLog 2012-08-29 19:53:47 UTC (rev 127034)
+++ trunk/LayoutTests/ChangeLog 2012-08-29 20:03:11 UTC (rev 127035)
@@ -1,3 +1,15 @@
+2012-08-29 Anna Cavender <ann...@chromium.org>
+
+ Create a toggle button for closed captions.
+ https://bugs.webkit.org/show_bug.cgi?id=94395
+
+ Reviewed by Eric Carlson.
+
+ This patch will create a button that toggles any captions or subtitles on or off.
+
+ * media/video-controls-captions-expected.txt: Added.
+ * media/video-controls-captions.html: Added.
+
2012-08-29 Zhenyao Mo <z...@google.com>
Unreviewed, chromium test expectations cleanup.
Added: trunk/LayoutTests/media/video-controls-captions-expected.txt (0 => 127035)
--- trunk/LayoutTests/media/video-controls-captions-expected.txt (rev 0)
+++ trunk/LayoutTests/media/video-controls-captions-expected.txt 2012-08-29 20:03:11 UTC (rev 127035)
@@ -0,0 +1,25 @@
+Tests that the closed captions button, when toggled, updates the text track display area.
+
+Set the user language preference so that the track will be chosen when the CC button is clicked.
+RUN(internals.setUserPreferredLanguages(['en']))
+EVENT(canplaythrough)
+
+** Caption button should be visible and enabled because we have a captions track.
+EXPECTED (captionsButtonCoordinates[0] > '0') OK
+EXPECTED (captionsButtonCoordinates[1] > '0') OK
+EXPECTED (captionsButtonElement.disabled == 'false') OK
+
+** The captions track should be listed in textTracks, but not yet loaded. **
+EXPECTED (video.textTracks.length == '1') OK
+EXPECTED (video.textTracks[0].mode == 'disabled') OK
+Failed to find text track container element
+
+** Captions track should load and captions should become visible after button is clicked **
+*** Click the CC button.
+EXPECTED (textTrackDisplayElement(video, 'display').innerText == 'Lorem') OK
+
+** Captions should not be visible after button is clicked again **
+*** Click the CC button.
+No text track cue with display id '-webkit-media-text-track-display' is currently visible
+END OF TEST
+
Added: trunk/LayoutTests/media/video-controls-captions.html (0 => 127035)
--- trunk/LayoutTests/media/video-controls-captions.html (rev 0)
+++ trunk/LayoutTests/media/video-controls-captions.html 2012-08-29 20:03:11 UTC (rev 127035)
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Test closed caption button toggling.</title>
+ <script src=""
+ <script src=""
+ <script src=""
+ <script>
+ var captionsButtonElement;
+ var captionsButtonCoordinates;
+
+ function startTest()
+ {
+ if (!window.eventSender) {
+ consoleWrite("No eventSender found.");
+ failTest();
+ }
+
+ try {
+ captionsButtonElement = mediaControlsElement(internals.shadowRoot(video).firstChild, "-webkit-media-controls-toggle-closed-captions-button");
+ captionsButtonCoordinates = mediaControlsButtonCoordinates(video, "toggle-closed-captions-button");
+ } catch (exception) {
+ consoleWrite("Failed to find a closed captions button or its coordinates: " + exception);
+ failTest();
+ return;
+ }
+
+ consoleWrite("");
+ consoleWrite("** Caption button should be visible and enabled because we have a captions track.");
+ testExpected("captionsButtonCoordinates[0]", 0, ">");
+ testExpected("captionsButtonCoordinates[1]", 0, ">");
+ testExpected("captionsButtonElement.disabled", false);
+
+ consoleWrite("");
+ consoleWrite("** The captions track should be listed in textTracks, but not yet loaded. **");
+ testExpected("video.textTracks.length", 1);
+ testExpected("video.textTracks[0].mode", "disabled");
+ checkCaptionsDisplay();
+
+ consoleWrite("");
+ consoleWrite("** Captions track should load and captions should become visible after button is clicked **");
+ clickCCButton();
+ }
+
+ function clickCCButton()
+ {
+ consoleWrite("*** Click the CC button.");
+ eventSender.mouseMoveTo(captionsButtonCoordinates[0], captionsButtonCoordinates[1]);
+ eventSender.mouseDown();
+ eventSender.mouseUp();
+ }
+
+ function checkCaptionsDisplay()
+ {
+ // When no tracks are loaded, this should report no text track container,
+ // when tracks are loaded but not visible, should report no cues visible,
+ // when tracks are loaded and visible, should properly check the text.
+ testExpected("textTrackDisplayElement(video, 'display').innerText", "Lorem");
+ }
+
+ function trackLoaded()
+ {
+ checkCaptionsDisplay();
+
+ consoleWrite("");
+ consoleWrite("** Captions should not be visible after button is clicked again **");
+ clickCCButton();
+ checkCaptionsDisplay();
+
+ endTest();
+ }
+
+ function loaded()
+ {
+ findMediaElement();
+ consoleWrite("Set the user language preference so that the track will be chosen when the CC button is clicked.");
+ run("internals.setUserPreferredLanguages(['en'])");
+
+ waitForEvent('canplaythrough', startTest);
+
+ video.src = "" 'content/counting');
+ }
+ </script>
+</head>
+<body _onload_="loaded()">
+ <p>Tests that the closed captions button, when toggled, updates the text track display area.</p>
+ <video controls >
+ <track src="" kind="captions" srclang="en" _onload_="trackLoaded()">
+ </video>
+
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (127034 => 127035)
--- trunk/Source/WebCore/ChangeLog 2012-08-29 19:53:47 UTC (rev 127034)
+++ trunk/Source/WebCore/ChangeLog 2012-08-29 20:03:11 UTC (rev 127035)
@@ -1,3 +1,77 @@
+2012-08-29 Anna Cavender <ann...@chromium.org>
+
+ Create a toggle button for closed captions.
+ https://bugs.webkit.org/show_bug.cgi?id=94395
+
+ Reviewed by Eric Carlson.
+
+ This patch will create a button that toggles any captions or subtitles on or off.
+
+ Test: media/video-controls-captions.html
+
+ * css/mediaControlsChromium.css:
+ (audio::-webkit-media-controls-toggle-closed-captions-button, video::-webkit-media-controls-toggle-closed-captions-button):
+ New style for new button.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement):
+ Initialize new variable for keeping track of user (button) disabled captions.
+
+ (WebCore::HTMLMediaElement::loadTimerFired):
+ Rename configureNewTextTracks() to configureTextTracks().
+
+ (WebCore::HTMLMediaElement::prepareForLoad):
+ Do not set closedCaptionsVisible to false, we should instead honor the
+ checks for default out-of-band tracks.
+
+ (WebCore::HTMLMediaElement::textTrackModeChanged):
+ Rename configureNewTextTracks() to configureTextTracks().
+
+ (WebCore::HTMLMediaElement::userIsInterestedInThisTrackKind):
+ Add checks for when user has requested to see or not see captions.
+
+ (WebCore::HTMLMediaElement::configureTextTracks):
+ Rename configureNewTextTracks() to configureTextTracks().
+
+ (WebCore::HTMLMediaElement::hasClosedCaptions):
+ Return true if we have any caption or subtitle text tracks.
+
+ (WebCore::HTMLMediaElement::setClosedCaptionsVisible):
+ Update the text track display and the closed captions button when the
+ closed captions button is toggled.
+
+ (WebCore::HTMLMediaElement::configureTextTrackDisplay):
+ If the visibility of any text tracks has changed, update the display and
+ the controls.
+
+ (WebCore::HTMLMediaElement::updateClosedCaptionsControls):
+ New function that updates both the text track display and the closed
+ captions button.
+
+ * html/HTMLMediaElement.h:
+ (HTMLMediaElement):
+ New function updateClosedCaptionsControls()
+
+ Adding the button:
+ * html/shadow/MediaControlRootElementChromium.cpp:
+ (WebCore::MediaControlRootElementChromium::MediaControlRootElementChromium):
+ (WebCore::MediaControlRootElementChromium::initializeControls):
+ (WebCore::MediaControlRootElementChromium::setMediaController):
+ (WebCore::MediaControlRootElementChromium::reset):
+ (WebCore::MediaControlRootElementChromium::reportedError):
+ (WebCore::MediaControlRootElementChromium::changedClosedCaptionsVisibility):
+ (WebCore::MediaControlRootElementChromium::createTextTrackDisplay):
+ * html/shadow/MediaControlRootElementChromium.h:
+ (WebCore):
+ (MediaControlRootElementChromium):
+
+ Ensure that Linux and Windows render themes will support closed captions:
+ * rendering/RenderThemeChromiumSkia.cpp:
+ (WebCore):
+ (WebCore::supportsClosedCaptioning):
+ * rendering/RenderThemeChromiumSkia.h:
+ (RenderThemeChromiumSkia):
+
2012-08-29 Jessie Berlin <jber...@apple.com>
run-bindings-tests failing on Apple Mountain Lion Testers.
Modified: trunk/Source/WebCore/css/mediaControlsChromium.css (127034 => 127035)
--- trunk/Source/WebCore/css/mediaControlsChromium.css 2012-08-29 19:53:47 UTC (rev 127034)
+++ trunk/Source/WebCore/css/mediaControlsChromium.css 2012-08-29 20:03:11 UTC (rev 127035)
@@ -178,6 +178,19 @@
margin-right: -7px;
}
+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;
+ border: none;
+ box-sizing: border-box;
+ width: 25px;
+ height: 25px;
+ line-height: 25px;
+ margin-left: -5px;
+ margin-right: 9px;
+ padding: 0;
+}
+
audio::-webkit-media-controls-fullscreen-button, video::-webkit-media-controls-fullscreen-button {
-webkit-appearance: media-enter-fullscreen-button;
display: -webkit-box;
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (127034 => 127035)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2012-08-29 19:53:47 UTC (rev 127034)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2012-08-29 20:03:11 UTC (rev 127035)
@@ -259,6 +259,7 @@
, m_lastTextTrackUpdateTime(-1)
, m_textTracks(0)
, m_ignoreTrackDisplayUpdate(0)
+ , m_disableCaptions(false)
#endif
#if ENABLE(WEB_AUDIO)
, m_audioSourceNode(0)
@@ -594,7 +595,7 @@
#if ENABLE(VIDEO_TRACK)
if (RuntimeEnabledFeatures::webkitVideoTrackEnabled() && (m_pendingLoadFlags & TextTrackResource))
- configureNewTextTracks();
+ configureTextTracks();
#endif
if (m_pendingLoadFlags & MediaResource) {
@@ -741,7 +742,6 @@
m_playedTimeRanges = TimeRanges::create();
m_lastSeekTime = 0;
- m_closedCaptionsVisible = false;
// The spec doesn't say to block the load event until we actually run the asynchronous section
// algorithm, but do it now because we won't start that until after the timer fires and the
@@ -1298,7 +1298,7 @@
if (trackElement->track() != track)
continue;
- // Mark this track as "configured" so configureNewTextTracks won't change the mode again.
+ // Mark this track as "configured" so configureTextTracks won't change the mode again.
trackElement->setHasBeenConfigured(true);
if (track->mode() != TextTrack::disabledKeyword()) {
if (trackElement->readyState() == HTMLTrackElement::LOADED)
@@ -2790,16 +2790,19 @@
bool HTMLMediaElement::userIsInterestedInThisTrackKind(String kind) const
{
// If ... the user has indicated an interest in having a track with this text track kind, text track language, ...
+ if (m_disableCaptions)
+ return false;
+
Settings* settings = document()->settings();
if (!settings)
return false;
if (kind == TextTrack::subtitlesKeyword())
- return settings->shouldDisplaySubtitles();
+ return settings->shouldDisplaySubtitles() || m_closedCaptionsVisible;
if (kind == TextTrack::captionsKeyword())
- return settings->shouldDisplayCaptions();
+ return settings->shouldDisplayCaptions() || m_closedCaptionsVisible;
if (kind == TextTrack::descriptionsKeyword())
- return settings->shouldDisplayTextDescriptions();
+ return settings->shouldDisplayTextDescriptions() || m_closedCaptionsVisible;
return false;
}
@@ -2895,7 +2898,7 @@
}
}
-void HTMLMediaElement::configureNewTextTracks()
+void HTMLMediaElement::configureTextTracks()
{
TrackGroup captionAndSubtitleTracks(TrackGroup::CaptionsAndSubtitles);
TrackGroup descriptionTracks(TrackGroup::Description);
@@ -3923,7 +3926,18 @@
bool HTMLMediaElement::hasClosedCaptions() const
{
- return m_player && m_player->hasClosedCaptions();
+ if (m_player && m_player->hasClosedCaptions())
+ return true;
+
+#if ENABLE(VIDEO_TRACK)
+ if (RuntimeEnabledFeatures::webkitVideoTrackEnabled() && m_textTracks)
+ for (unsigned i = 0; i < m_textTracks->length(); ++i) {
+ if (m_textTracks->item(i)->kind() == TextTrack::captionsKeyword()
+ || m_textTracks->item(i)->kind() == TextTrack::subtitlesKeyword())
+ return true;
+ }
+#endif
+ return false;
}
bool HTMLMediaElement::closedCaptionsVisible() const
@@ -3935,13 +3949,36 @@
{
LOG(Media, "HTMLMediaElement::setClosedCaptionsVisible(%s)", boolString(closedCaptionVisible));
- if (!m_player ||!hasClosedCaptions())
+ if (!m_player || !hasClosedCaptions())
return;
m_closedCaptionsVisible = closedCaptionVisible;
m_player->setClosedCaptionsVisible(closedCaptionVisible);
+
+#if ENABLE(VIDEO_TRACK)
+ if (RuntimeEnabledFeatures::webkitVideoTrackEnabled()) {
+ m_disableCaptions = !m_closedCaptionsVisible;
+
+ // Mark all track elements as not "configured" so that configureTextTracks()
+ // will reconsider which tracks to display in light of new user preferences
+ // (e.g. default tracks should not be displayed if the user has turned off
+ // captions and non-default tracks should be displayed based on language
+ // preferences if the user has turned captions on).
+ for (Node* node = firstChild(); node; node = node->nextSibling()) {
+ if (!node->hasTagName(trackTag))
+ continue;
+ HTMLTrackElement* trackElement = static_cast<HTMLTrackElement*>(node);
+ if (trackElement->kind() == TextTrack::captionsKeyword()
+ || trackElement->kind() == TextTrack::subtitlesKeyword())
+ trackElement->setHasBeenConfigured(false);
+ }
+
+ configureTextTracks();
+ }
+#else
if (hasMediaControls())
mediaControls()->changedClosedCaptionsVisibility();
+#endif
}
void HTMLMediaElement::setWebkitClosedCaptionsVisible(bool visible)
@@ -4105,13 +4142,25 @@
if (m_haveVisibleTextTrack == haveVisibleTextTrack)
return;
m_haveVisibleTextTrack = haveVisibleTextTrack;
+ m_closedCaptionsVisible = m_haveVisibleTextTrack;
if (!m_haveVisibleTextTrack && !hasMediaControls())
return;
if (!hasMediaControls() && !createMediaControls())
return;
- mediaControls()->updateTextTrackDisplay();
+
+ updateClosedCaptionsControls();
}
+
+void HTMLMediaElement::updateClosedCaptionsControls()
+{
+ if (hasMediaControls()) {
+ mediaControls()->changedClosedCaptionsVisibility();
+
+ if (RuntimeEnabledFeatures::webkitVideoTrackEnabled())
+ mediaControls()->updateTextTrackDisplay();
+ }
+}
#endif
void* HTMLMediaElement::preDispatchEventHandler(Event* event)
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (127034 => 127035)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2012-08-29 19:53:47 UTC (rev 127034)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2012-08-29 20:03:11 UTC (rev 127035)
@@ -236,12 +236,13 @@
};
void configureTextTrackGroupForLanguage(const TrackGroup&) const;
- void configureNewTextTracks();
+ void configureTextTracks();
void configureTextTrackGroup(const TrackGroup&) const;
bool userIsInterestedInThisTrackKind(String) const;
bool textTracksAreReady() const;
void configureTextTrackDisplay();
+ void updateClosedCaptionsControls();
// TextTrackClient
virtual void textTrackReadyStateChanged(TextTrack*);
@@ -654,6 +655,7 @@
CueList m_currentlyActiveCues;
int m_ignoreTrackDisplayUpdate;
+ bool m_disableCaptions;
#endif
#if ENABLE(WEB_AUDIO)
Modified: trunk/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp (127034 => 127035)
--- trunk/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp 2012-08-29 19:53:47 UTC (rev 127034)
+++ trunk/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp 2012-08-29 20:03:11 UTC (rev 127035)
@@ -84,6 +84,7 @@
, m_timeline(0)
, m_panelMuteButton(0)
, m_volumeSlider(0)
+ , m_toggleClosedCaptionsButton(0)
, m_fullscreenButton(0)
, m_panel(0)
, m_enclosure(0)
@@ -164,6 +165,14 @@
if (ec)
return false;
+ if (document->page()->theme()->supportsClosedCaptioning()) {
+ RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document);
+ m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
+ panel->appendChild(toggleClosedCaptionsButton.release(), ec, true);
+ if (ec)
+ return false;
+ }
+
RefPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(document, this);
m_fullscreenButton = fullscreenButton.get();
panel->appendChild(fullscreenButton.release(), ec, true);
@@ -201,6 +210,8 @@
m_panelMuteButton->setMediaController(controller);
if (m_volumeSlider)
m_volumeSlider->setMediaController(controller);
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->setMediaController(controller);
if (m_fullscreenButton)
m_fullscreenButton->setMediaController(controller);
if (m_panel)
@@ -265,6 +276,13 @@
}
}
+ if (m_toggleClosedCaptionsButton) {
+ if (m_mediaController->hasClosedCaptions())
+ m_toggleClosedCaptionsButton->show();
+ else
+ m_toggleClosedCaptionsButton->hide();
+ }
+
if (m_mediaController->supportsFullscreen() && m_mediaController->hasVideo())
m_fullscreenButton->show();
else
@@ -332,6 +350,8 @@
m_panelMuteButton->hide();
m_volumeSlider->hide();
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->hide();
m_fullscreenButton->hide();
}
@@ -417,6 +437,8 @@
void MediaControlRootElementChromium::changedClosedCaptionsVisibility()
{
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->updateDisplayType();
}
void MediaControlRootElementChromium::changedMute()
@@ -465,6 +487,9 @@
RefPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(document());
m_textDisplayContainer = textDisplayContainer.get();
+ if (m_mediaController)
+ m_textDisplayContainer->setMediaController(m_mediaController);
+
// Insert it before the first controller element so it always displays behind the controls.
insertBefore(textDisplayContainer.release(), m_enclosure, ASSERT_NO_EXCEPTION, true);
}
Modified: trunk/Source/WebCore/html/shadow/MediaControlRootElementChromium.h (127034 => 127035)
--- trunk/Source/WebCore/html/shadow/MediaControlRootElementChromium.h 2012-08-29 19:53:47 UTC (rev 127034)
+++ trunk/Source/WebCore/html/shadow/MediaControlRootElementChromium.h 2012-08-29 20:03:11 UTC (rev 127035)
@@ -44,6 +44,7 @@
class MediaControlTimeRemainingDisplayElement;
class MediaControlTimelineElement;
class MediaControlVolumeSliderElement;
+class MediaControlToggleClosedCaptionsButtonElement;
class MediaControlFullscreenButtonElement;
class MediaControlTimeDisplayElement;
class MediaControlTimelineContainerElement;
@@ -146,6 +147,7 @@
MediaControlTimelineElement* m_timeline;
MediaControlPanelMuteButtonElement* m_panelMuteButton;
MediaControlVolumeSliderElement* m_volumeSlider;
+ MediaControlToggleClosedCaptionsButtonElement* m_toggleClosedCaptionsButton;
MediaControlFullscreenButtonElement* m_fullscreenButton;
MediaControlPanelElement* m_panel;
MediaControlPanelEnclosureElement* m_enclosure;
Modified: trunk/Source/WebCore/rendering/RenderThemeChromiumSkia.cpp (127034 => 127035)
--- trunk/Source/WebCore/rendering/RenderThemeChromiumSkia.cpp 2012-08-29 19:53:47 UTC (rev 127034)
+++ trunk/Source/WebCore/rendering/RenderThemeChromiumSkia.cpp 2012-08-29 20:03:11 UTC (rev 127035)
@@ -131,6 +131,13 @@
return RenderThemeChromiumCommon::supportsDataListUI(type);
}
+#if ENABLE(VIDEO_TRACK)
+bool RenderThemeChromiumSkia::supportsClosedCaptioning() const
+{
+ return true;
+}
+#endif
+
Color RenderThemeChromiumSkia::platformActiveSelectionBackgroundColor() const
{
return Color(0x1e, 0x90, 0xff);
Modified: trunk/Source/WebCore/rendering/RenderThemeChromiumSkia.h (127034 => 127035)
--- trunk/Source/WebCore/rendering/RenderThemeChromiumSkia.h 2012-08-29 19:53:47 UTC (rev 127034)
+++ trunk/Source/WebCore/rendering/RenderThemeChromiumSkia.h 2012-08-29 20:03:11 UTC (rev 127035)
@@ -54,6 +54,9 @@
virtual bool supportsDataListUI(const AtomicString& type) const OVERRIDE;
+#if ENABLE(VIDEO_TRACK)
+ virtual bool supportsClosedCaptioning() const OVERRIDE;
+#endif
// The platform selection color.
virtual Color platformActiveSelectionBackgroundColor() const;
virtual Color platformInactiveSelectionBackgroundColor() const;