[Mac] Caption menu should have only one item selected

https://bugs.webkit.org/show_bug.cgi?id=109730

Reviewed by Dean Jackson.

Source/WebCore: 

No new tests, media/track/track-user-preferences.html was modified to test the changes.

* CMakeLists.txt: Add CaptionUserPreferences.cpp.
* GNUmakefile.list.am: Ditto.
* Target.pri: Ditto.
* WebCore.gypi: Ditto.
* WebCore.vcproj/WebCore.vcproj: Ditto.
* WebCore.vcxproj/WebCore.vcxproj: Ditto.
* WebCore.xcodeproj/project.pbxproj: Ditto.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement): Initialize m_processingPreferenceChange.
(WebCore::HTMLMediaElement::configureTextTrackGroup): Only end up with one selected track when
    called because of a preferences change.
(WebCore::HTMLMediaElement::captionPreferencesChanged): Call setClosedCaptionsVisible instead
    of calling markCaptionAndSubtitleTracksAsUnconfigured directly.
(WebCore::HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured): Process all tracks, 
    not just track elements.
* html/HTMLMediaElement.h:

* page/CaptionUserPreferences.cpp: Added so the functionality can be tested in DRT.
(WebCore::CaptionUserPreferences::registerForPreferencesChangedCallbacks):
(WebCore::CaptionUserPreferences::unregisterForPreferencesChangedCallbacks):
(WebCore::CaptionUserPreferences::setUserPrefersCaptions):
(WebCore::CaptionUserPreferences::captionPreferencesChanged):
(WebCore::CaptionUserPreferences::preferredLanguages):
(WebCore::CaptionUserPreferences::setPreferredLanguage):
(WebCore::CaptionUserPreferences::displayNameForTrack):
* page/CaptionUserPreferences.h:

* page/CaptionUserPreferencesMac.h:
* page/CaptionUserPreferencesMac.mm:
(WebCore::CaptionUserPreferencesMac::registerForPreferencesChangedCallbacks): Moved some logic
    to base class.
(WebCore::CaptionUserPreferencesMac::captionPreferencesChanged): Ditto.

LayoutTests: 

* media/track/track-user-preferences-expected.txt:
* media/track/track-user-preferences.html: Update test to check for reactions to preferences.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@142809 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent c225a4dc
2013-02-13 Eric Carlson <eric.carlson@apple.com>
[Mac] Caption menu should have only one item selected
https://bugs.webkit.org/show_bug.cgi?id=109730
Reviewed by Dean Jackson.
* media/track/track-user-preferences-expected.txt:
* media/track/track-user-preferences.html: Update test to check for reactions to preferences.
2013-02-13 Hans Muller <hmuller@adobe.com>
[CSS Exclusions] ExclusionPolygon reflex vertices should constrain the first fit location.
......@@ -3,29 +3,40 @@ Test track user preferences.
Set user languages to: ['no', 'es-ES', 'en', 'fr'].
Test 1: track selected because of 'default' attribute
Test 1: 'no' track selected because of user preferred language
- creating tracks for: [en,fr,no].
EVENT(load)
EXPECTED (event.target.srclang == 'fr') OK
EXPECTED (event.target.srclang == 'no') OK
EXPECTED (event.target.readyState == '2') OK
Test 2: track selected because of original user preferred language
Test 2: 'no' track still selected because of language, overriding 'default' attribute
- creating tracks for: [fr,en,no].
-- 'en' track marked as default.
EVENT(load)
EXPECTED (event.target.srclang == 'no') OK
EXPECTED (event.target.readyState == '2') OK
Test 3: preferred language changed by selecting track from menu
Test 3: select 'fr' track from menu
- show captions menu.
EXPECTED (trackMenuItems[1].className == '') OK
EXPECTED (trackMenuItems[2].className == '') OK
EXPECTED (trackMenuItems[3].className == 'selected') OK
- click on menu item 2.
EVENT(load)
EXPECTED (event.target.srclang == 'fr') OK
EXPECTED (event.target.readyState == '2') OK
EXPECTED (video.textTracks[0].mode == 'showing') OK
EXPECTED (video.textTracks[0].language == 'fr') OK
- creating tracks for: [no,fr,en].
Test 4: preferred language was changed to 'fr' by selecting track from menu
- creating tracks for: [ru,en,fr].
EVENT(load)
EXPECTED (event.target.srclang == 'fr') OK
EXPECTED (event.target.readyState == '2') OK
EXPECTED (video.textTracks[2].mode == 'showing') OK
EXPECTED (video.textTracks[2].language == 'fr') OK
Test 4: turning captions off from menu disables captions
Test 5: turning captions off from menu disables caption selection
- show captions menu.
- click on menu item 0.
- creating tracks for: [ru,jp,en].
......
......@@ -11,6 +11,7 @@
var expectedLanguage;
var testStage = 0;
var captionsButtonCoordinates;
var trackMenuItems;
function showCaptionMenu()
{
......@@ -24,7 +25,7 @@
function trackMenuList()
{
var trackListElement = getTrackListElement();
trackListElement = getTrackListElement();
if (!trackListElement)
return;
......@@ -46,8 +47,8 @@
function selectCaptionMenuItem(index)
{
consoleWrite("- click on menu item " + index + ".");
var trackListItems = trackMenuList();
var selectedTrackItem = trackListItems[index];
var trackMenuItems = trackMenuList();
var selectedTrackItem = trackMenuItems[index];
var boundingRect = selectedTrackItem.getBoundingClientRect();
var x = boundingRect.left + boundingRect.width / 2;
var y = boundingRect.top + boundingRect.height / 2;
......@@ -72,8 +73,10 @@
track.src = 'data:text/vtt,'+encodeURIComponent("WEBVTT\n\n00:00:00.000 --> 00:00:01.000\nCaption 1\n");
track.setAttribute('srclang', language);
track.setAttribute('onload', 'trackLoaded()');
if (isDefault)
if (isDefault) {
consoleWrite("-- '" + language + "' track marked as default.");
track.setAttribute('default', 'default');
}
video.appendChild(track);
}
......@@ -93,42 +96,59 @@
++testStage;
switch (testStage) {
case 1:
consoleWrite("<br>Test 1: track selected because of 'default' attribute");
createTrackElements(['en', 'fr', 'no'], 1);
expectedLanguage = 'fr';
consoleWrite("<br>Test 1: 'no' track selected because of user preferred language");
createTrackElements(['en', 'fr', 'no']);
expectedLanguage = 'no';
break;
case 2:
consoleWrite("<br>Test 2: track selected because of original user preferred language");
createTrackElements(['fr', 'en', 'no']);
consoleWrite("<br>Test 2: 'no' track still selected because of language, overriding 'default' attribute");
createTrackElements(['fr', 'en', 'no'], 1);
expectedLanguage = 'no';
break;
case 3:
consoleWrite("<br>Test 3: preferred language changed by selecting track from menu");
// Clear the debug setting so it isn't considered in the track selection logic
internals.settings.setShouldDisplayTrackKind('Captions', false);
consoleWrite("<br>Test 3: select 'fr' track from menu");
showCaptionMenu();
break;
case 4:
trackMenuItems = trackMenuList();
testExpected("trackMenuItems[1].className", "");
testExpected("trackMenuItems[2].className", "");
testExpected("trackMenuItems[3].className", "selected");
selectCaptionMenuItem(2);
expectedLanguage = 'fr';
break;
case 5:
testExpected("video.textTracks[0].mode", "showing");
testExpected("video.textTracks[0].language", "fr");
consoleWrite("<br>Test 4: preferred language was changed to 'fr' by selecting track from menu");
createTrackElements(['ru', 'en', 'fr']);
expectedLanguage = 'fr';
createTrackElements([ 'no', 'fr', 'en']);
break;
case 5:
consoleWrite("<br>Test 4: turning captions off from menu disables captions");
case 6:
testExpected("video.textTracks[2].mode", "showing");
testExpected("video.textTracks[2].language", "fr");
consoleWrite("<br>Test 5: turning captions off from menu disables caption selection");
showCaptionMenu();
break;
case 6:
case 7:
selectCaptionMenuItem(0);
createTrackElements([ 'ru', 'jp', 'en']);
timer = setTimeout(nextStep, 250);
timer = setTimeout(nextStep, 100);
break;
case 7:
case 8:
for (var ndx = 0; ndx < video.textTracks.length; ++ndx)
testExpected("video.textTracks[" + ndx + "].mode", "disabled");
......@@ -145,6 +165,7 @@
video.addEventListener('canplaythrough', nextStep);
consoleWrite("<br>Set user languages to: ['no', 'es-ES', 'en', 'fr'].");
internals.setUserPreferredLanguages(['no', 'es-ES', 'en', 'fr']);
internals.settings.setShouldDisplayTrackKind('Captions', true);
}
</script>
</head>
......
......@@ -1747,6 +1747,7 @@ set(WebCore_SOURCES
page/AutoscrollController.cpp
page/BarInfo.cpp
page/CaptionUserPreferences.cpp
page/Chrome.cpp
page/Console.cpp
page/ContentSecurityPolicy.cpp
......
2013-02-13 Eric Carlson <eric.carlson@apple.com>
[Mac] Caption menu should have only one item selected
https://bugs.webkit.org/show_bug.cgi?id=109730
Reviewed by Dean Jackson.
No new tests, media/track/track-user-preferences.html was modified to test the changes.
* CMakeLists.txt: Add CaptionUserPreferences.cpp.
* GNUmakefile.list.am: Ditto.
* Target.pri: Ditto.
* WebCore.gypi: Ditto.
* WebCore.vcproj/WebCore.vcproj: Ditto.
* WebCore.vcxproj/WebCore.vcxproj: Ditto.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement): Initialize m_processingPreferenceChange.
(WebCore::HTMLMediaElement::configureTextTrackGroup): Only end up with one selected track when
called because of a preferences change.
(WebCore::HTMLMediaElement::captionPreferencesChanged): Call setClosedCaptionsVisible instead
of calling markCaptionAndSubtitleTracksAsUnconfigured directly.
(WebCore::HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured): Process all tracks,
not just track elements.
* html/HTMLMediaElement.h:
* page/CaptionUserPreferences.cpp: Added so the functionality can be tested in DRT.
(WebCore::CaptionUserPreferences::registerForPreferencesChangedCallbacks):
(WebCore::CaptionUserPreferences::unregisterForPreferencesChangedCallbacks):
(WebCore::CaptionUserPreferences::setUserPrefersCaptions):
(WebCore::CaptionUserPreferences::captionPreferencesChanged):
(WebCore::CaptionUserPreferences::preferredLanguages):
(WebCore::CaptionUserPreferences::setPreferredLanguage):
(WebCore::CaptionUserPreferences::displayNameForTrack):
* page/CaptionUserPreferences.h:
* page/CaptionUserPreferencesMac.h:
* page/CaptionUserPreferencesMac.mm:
(WebCore::CaptionUserPreferencesMac::registerForPreferencesChangedCallbacks): Moved some logic
to base class.
(WebCore::CaptionUserPreferencesMac::captionPreferencesChanged): Ditto.
2013-02-13 Hans Muller <hmuller@adobe.com>
[CSS Exclusions] ExclusionPolygon reflex vertices should constrain the first fit location.
......@@ -4102,6 +4102,7 @@ webcore_sources += \
Source/WebCore/page/AutoscrollController.h \
Source/WebCore/page/BarInfo.cpp \
Source/WebCore/page/BarInfo.h \
Source/WebCore/page/CaptionUserPreferences.cpp \
Source/WebCore/page/CaptionUserPreferences.h \
Source/WebCore/page/Chrome.cpp \
Source/WebCore/page/Chrome.h \
......
......@@ -907,6 +907,7 @@ SOURCES += \
page/animation/KeyframeAnimation.cpp \
page/AutoscrollController.cpp \
page/BarInfo.cpp \
page/CaptionUserPreferences.cpp \
page/Chrome.cpp \
page/Console.cpp \
page/ContentSecurityPolicy.cpp \
......@@ -2091,6 +2092,7 @@ HEADERS += \
page/AdjustViewSizeOrNot.h \
page/AutoscrollController.h \
page/BarInfo.h \
page/CaptionUserPreferences.h \
page/Chrome.h \
page/Console.h \
page/ConsoleTypes.h \
......
......@@ -2074,6 +2074,7 @@
'page/AutoscrollController.h',
'page/BarInfo.cpp',
'page/BarInfo.h',
'page/CaptionUserPreferences.cpp',
'page/Chrome.cpp',
'page/Console.cpp',
'page/ContentSecurityPolicy.cpp',
......
......@@ -27110,6 +27110,14 @@
RelativePath="..\page\BarInfo.h"
>
</File>
<File
RelativePath="..\page\CaptionUserPreferences.cpp"
>
</File>
<File
RelativePath="..\page\CaptionUserPreferences.h"
>
</File>
<File
RelativePath="..\page\Chrome.cpp"
>
......@@ -1996,6 +1996,7 @@
<ClCompile Include="..\page\animation\AnimationController.cpp" />
<ClCompile Include="..\page\AutoscrollController.cpp" />
<ClCompile Include="..\page\BarInfo.cpp" />
<ClCompile Include="..\page\CaptionUserPreferences.cpp" />
<ClCompile Include="..\page\Chrome.cpp" />
<ClCompile Include="..\page\animation\CompositeAnimation.cpp" />
<ClCompile Include="..\page\Console.cpp" />
......
......@@ -103,6 +103,7 @@
0720B0A114D3323500642955 /* GenericEventQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0720B09F14D3323500642955 /* GenericEventQueue.h */; settings = {ATTRIBUTES = (Private, ); }; };
0720B0A114D3323500642957 /* GestureEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 0720B09F14D3323500642957 /* GestureEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
072C8B11131C518600A4FCE9 /* MediaPlayerPrivateAVFoundation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 076F0D0912B8192700C26AA4 /* MediaPlayerPrivateAVFoundation.cpp */; };
072CA86116CB4DC3008AE131 /* CaptionUserPreferences.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 072CA86016CB4DC3008AE131 /* CaptionUserPreferences.cpp */; };
0735EE6A0F40C5E4004A2604 /* MediaPlayerProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 0735EE690F40C5E4004A2604 /* MediaPlayerProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
0753860214489E9800B78452 /* CachedTextTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0753860014489E9800B78452 /* CachedTextTrack.cpp */; };
0753860314489E9800B78452 /* CachedTextTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = 0753860114489E9800B78452 /* CachedTextTrack.h */; };
......@@ -7357,6 +7358,7 @@
0720B09F14D3323500642955 /* GenericEventQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericEventQueue.h; sourceTree = "<group>"; };
0720B09F14D3323500642956 /* GestureEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GestureEvent.cpp; sourceTree = "<group>"; };
0720B09F14D3323500642957 /* GestureEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GestureEvent.h; sourceTree = "<group>"; };
072CA86016CB4DC3008AE131 /* CaptionUserPreferences.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CaptionUserPreferences.cpp; sourceTree = "<group>"; };
0735EE690F40C5E4004A2604 /* MediaPlayerProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlayerProxy.h; sourceTree = "<group>"; };
0753860014489E9800B78452 /* CachedTextTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedTextTrack.cpp; sourceTree = "<group>"; };
0753860114489E9800B78452 /* CachedTextTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedTextTrack.h; sourceTree = "<group>"; };
......@@ -16301,6 +16303,7 @@
BC124EE40C2641CD009E2349 /* BarInfo.cpp */,
BC124EE50C2641CD009E2349 /* BarInfo.h */,
BC124EE60C2641CD009E2349 /* BarInfo.idl */,
072CA86016CB4DC3008AE131 /* CaptionUserPreferences.cpp */,
079D0867162F20E800DB8658 /* CaptionUserPreferences.h */,
079D0869162F21F900DB8658 /* CaptionUserPreferencesMac.h */,
079D086A162F21F900DB8658 /* CaptionUserPreferencesMac.mm */,
......@@ -29384,6 +29387,7 @@
08F859D41463F9CD0067D933 /* SVGImageCache.cpp in Sources */,
08F859D41463F9CD0067D934 /* SVGImageForContainer.cpp in Sources */,
B2227A2C0D00BF220071B782 /* SVGImageElement.cpp in Sources */,
072CA86116CB4DC3008AE131 /* CaptionUserPreferences.cpp in Sources */,
B28C6A290D00C44800334AA4 /* SVGImageLoader.cpp in Sources */,
B2227A2F0D00BF220071B782 /* SVGLangSpace.cpp in Sources */,
B2227A320D00BF220071B782 /* SVGLength.cpp in Sources */,
......@@ -289,6 +289,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* docum
#if ENABLE(VIDEO_TRACK)
, m_tracksAreReady(true)
, m_haveVisibleTextTrack(false)
, m_processingPreferenceChange(false)
, m_lastTextTrackUpdateTime(-1)
, m_textTracks(0)
, m_ignoreTrackDisplayUpdate(0)
......@@ -3014,7 +3015,7 @@ bool HTMLMediaElement::userIsInterestedInThisTrackKind(String kind) const
return false;
}
void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group) const
void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
{
ASSERT(group.tracks.size());
......@@ -3031,12 +3032,19 @@ void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group) const
}
// First, find the track in the group that should be enabled (if any).
Vector<RefPtr<TextTrack> > currentlyEnabledTracks;
RefPtr<TextTrack> trackToEnable;
RefPtr<TextTrack> defaultTrack;
RefPtr<TextTrack> fallbackTrack;
for (size_t i = 0; !trackToEnable && i < group.tracks.size(); ++i) {
for (size_t i = 0; i < group.tracks.size(); ++i) {
RefPtr<TextTrack> textTrack = group.tracks[i];
if (m_processingPreferenceChange && textTrack->mode() == TextTrack::showingKeyword())
currentlyEnabledTracks.append(textTrack);
if (trackToEnable)
continue;
if (userIsInterestedInThisTrackKind(textTrack->kind())) {
// * If the text track kind is { [subtitles or captions] [descriptions] } and the user has indicated an interest in having a
// track with this text track kind, text track language, and text track label enabled, and there is no
......@@ -3075,6 +3083,15 @@ void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group) const
if (!trackToEnable && fallbackTrack)
trackToEnable = fallbackTrack;
if (currentlyEnabledTracks.size()) {
m_processingPreferenceChange = false;
for (size_t i = 0; i < currentlyEnabledTracks.size(); ++i) {
RefPtr<TextTrack> textTrack = currentlyEnabledTracks[i];
if (textTrack != trackToEnable)
textTrack->setMode(TextTrack::disabledKeyword());
}
}
if (trackToEnable)
trackToEnable->setMode(TextTrack::showingKeyword());
}
......@@ -4413,28 +4430,23 @@ void HTMLMediaElement::captionPreferencesChanged()
if (!isVideo())
return;
m_processingPreferenceChange = true;
setClosedCaptionsVisible(userPrefersCaptions());
if (hasMediaControls())
mediaControls()->textTrackPreferencesChanged();
markCaptionAndSubtitleTracksAsUnconfigured();
}
void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured()
{
// Mark all track elements as not "configured" so that configureTextTracks()
// Mark all tracks 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 (RefPtr<Node> node = firstChild(); node; node = node->nextSibling()) {
if (!node->hasTagName(trackTag))
continue;
HTMLTrackElement* trackElement = static_cast<HTMLTrackElement*>(node.get());
RefPtr<TextTrack> textTrack = trackElement->track();
if (!textTrack)
continue;
for (unsigned i = 0; i < m_textTracks->length(); ++i) {
RefPtr<TextTrack> textTrack = m_textTracks->item(i);
String kind = textTrack->kind();
if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captionsKeyword())
......
......@@ -253,7 +253,7 @@ public:
void configureTextTrackGroupForLanguage(const TrackGroup&) const;
void configureTextTracks();
void configureTextTrackGroup(const TrackGroup&) const;
void configureTextTrackGroup(const TrackGroup&);
void toggleTrackAtIndex(int index, bool exclusive = true);
static int textTracksOffIndex() { return -1; }
......@@ -691,6 +691,7 @@ private:
#if ENABLE(VIDEO_TRACK)
bool m_tracksAreReady : 1;
bool m_haveVisibleTextTrack : 1;
bool m_processingPreferenceChange : 1;
float m_lastTextTrackUpdateTime;
RefPtr<TextTrackList> m_textTracks;
......
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#if ENABLE(VIDEO_TRACK)
#include "CaptionUserPreferences.h"
namespace WebCore {
void CaptionUserPreferences::registerForPreferencesChangedCallbacks(CaptionPreferencesChangedListener* listener)
{
m_captionPreferenceChangeListeners.add(listener);
}
void CaptionUserPreferences::unregisterForPreferencesChangedCallbacks(CaptionPreferencesChangedListener* listener)
{
if (m_captionPreferenceChangeListeners.isEmpty())
return;
m_captionPreferenceChangeListeners.remove(listener);
}
void CaptionUserPreferences::setUserPrefersCaptions(bool preference)
{
m_userPrefersCaptions = preference;
if (m_testingMode) {
m_havePreferences = true;
captionPreferencesChanged();
}
}
void CaptionUserPreferences::captionPreferencesChanged()
{
if (m_captionPreferenceChangeListeners.isEmpty())
return;
for (HashSet<CaptionPreferencesChangedListener*>::iterator i = m_captionPreferenceChangeListeners.begin(); i != m_captionPreferenceChangeListeners.end(); ++i)
(*i)->captionPreferencesChanged();
}
Vector<String> CaptionUserPreferences::preferredLanguages() const
{
Vector<String> languages = userPreferredLanguages();
if (m_testingMode && !m_userPreferredLanguage.isEmpty())
languages.insert(0, m_userPreferredLanguage);
return languages;
}
void CaptionUserPreferences::setPreferredLanguage(String language)
{
m_userPreferredLanguage = language;
if (m_testingMode) {
m_havePreferences = true;
captionPreferencesChanged();
}
}
String CaptionUserPreferences::displayNameForTrack(TextTrack* track) const
{
if (track->label().isEmpty() && track->language().isEmpty())
return textTrackNoLabelText();
if (!track->label().isEmpty())
return track->label();
return track->language();
}
}
#endif // ENABLE(VIDEO_TRACK)
......@@ -50,31 +50,21 @@ public:
static PassOwnPtr<CaptionUserPreferences> create(PageGroup* group) { return adoptPtr(new CaptionUserPreferences(group)); }
virtual ~CaptionUserPreferences() { }
virtual bool userHasCaptionPreferences() const { return false; }
virtual bool userHasCaptionPreferences() const { return m_testingMode && m_havePreferences; }
virtual bool userPrefersCaptions() const { return m_testingMode ? m_userPrefersCaptions : false; }
virtual void setUserPrefersCaptions(bool preference) { m_userPrefersCaptions = preference; }
virtual void setUserPrefersCaptions(bool preference);
virtual float captionFontSizeScale(bool& important) const { important = false; return 0.05f; }
virtual String captionsStyleSheetOverride() const { return emptyString(); }
virtual void registerForPreferencesChangedCallbacks(CaptionPreferencesChangedListener*) { }
virtual void unregisterForPreferencesChangedCallbacks(CaptionPreferencesChangedListener*) { }
virtual void setPreferredLanguage(String language) { m_userPreferredLanguage = language; }
virtual Vector<String> preferredLanguages() const
{
Vector<String> languages = userPreferredLanguages();
if (m_testingMode && !m_userPreferredLanguage.isEmpty())
languages.insert(0, m_userPreferredLanguage);
return languages;
}
virtual void registerForPreferencesChangedCallbacks(CaptionPreferencesChangedListener*);
virtual void unregisterForPreferencesChangedCallbacks(CaptionPreferencesChangedListener*);
virtual void captionPreferencesChanged();
bool havePreferenceChangeListeners() const { return !m_captionPreferenceChangeListeners.isEmpty(); }
virtual String displayNameForTrack(TextTrack* track) const
{
if (track->label().isEmpty() && track->language().isEmpty())
return textTrackNoLabelText();
if (!track->label().isEmpty())
return track->label();
return track->language();
}
virtual void setPreferredLanguage(String);
virtual Vector<String> preferredLanguages() const;
virtual String displayNameForTrack(TextTrack*) const;
virtual bool testingMode() const { return m_testingMode; }
virtual void setTestingMode(bool override) { m_testingMode = override; }
......@@ -85,14 +75,17 @@ protected:
CaptionUserPreferences(PageGroup* group)
: m_pageGroup(group)
, m_testingMode(false)
, m_havePreferences(false)
, m_userPrefersCaptions(false)
{
}
private:
HashSet<CaptionPreferencesChangedListener*> m_captionPreferenceChangeListeners;
PageGroup* m_pageGroup;
String m_userPreferredLanguage;
bool m_testingMode;
bool m_havePreferences;
bool m_userPrefersCaptions;
};
......
......@@ -46,13 +46,13 @@ public:
virtual void setUserPrefersCaptions(bool) OVERRIDE;
virtual float captionFontSizeScale(bool&) const OVERRIDE;
virtual String captionsStyleSheetOverride() const OVERRIDE;
virtual void registerForPreferencesChangedCallbacks(CaptionPreferencesChangedListener*) OVERRIDE;
virtual void unregisterForPreferencesChangedCallbacks(CaptionPreferencesChangedListener*) OVERRIDE;
virtual void setPreferredLanguage(String) OVERRIDE;
virtual Vector<String> preferredLanguages() const OVERRIDE;
void captionPreferencesChanged();
virtual void captionPreferencesChanged() OVERRIDE;
#endif
virtual String displayNameForTrack(TextTrack*) const OVERRIDE;
......@@ -74,7 +74,6 @@ private:
void updateCaptionStyleSheetOveride();
HashSet<CaptionPreferencesChangedListener*> m_captionPreferenceChangeListeners;
bool m_listeningForPreferenceChanges;
#endif
};
......
......@@ -128,34 +128,28 @@ bool CaptionUserPreferencesMac::userHasCaptionPreferences() const
void CaptionUserPreferencesMac::registerForPreferencesChangedCallbacks(CaptionPreferencesChangedListener* listener)
{
if (!MediaAccessibilityLibrary()) {
CaptionUserPreferences::registerForPreferencesChangedCallbacks(listener);
return;
}
CaptionUserPreferences::registerForPreferencesChangedCallbacks(listener);
ASSERT(!m_captionPreferenceChangeListeners.contains(listener));
if (!MediaAccessibilityLibrary())
return;
if (!kMAXCaptionAppearanceSettingsChangedNotification)
return;
if (!m_listeningForPreferenceChanges) {
m_listeningForPreferenceChanges = true;
CFNotificationCenterAddObserver (CFNotificationCenterGetLocalCenter(), this, userCaptionPreferencesChangedNotificationCallback, kMAXCaptionAppearanceSettingsChangedNotification, NULL, CFNotificationSuspensionBehaviorCoalesce);
CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), this, userCaptionPreferencesChangedNotificationCallback, kMAXCaptionAppearanceSettingsChangedNotification, NULL, CFNotificationSuspensionBehaviorCoalesce);
}
updateCaptionStyleSheetOveride();
m_captionPreferenceChangeListeners.add(listener);
}
void CaptionUserPreferencesMac::unregisterForPreferencesChangedCallbacks(CaptionPreferencesChangedListener* listener)
void CaptionUserPreferencesMac::captionPreferencesChanged()
{
if (!MediaAccessibilityLibrary()) {
CaptionUserPreferences::unregisterForPreferencesChangedCallbacks(listener);
return;
}
if (havePreferenceChangeListeners())
updateCaptionStyleSheetOveride();
if (kMAXCaptionAppearanceSettingsChangedNotification)
m_captionPreferenceChangeListeners.remove(listener);
CaptionUserPreferences::captionPreferencesChanged();
}
String CaptionUserPreferencesMac::captionsWindowCSS() const
......@@ -421,17 +415,6 @@ float CaptionUserPreferencesMac::captionFontSizeScale(bool& important) const
#endif
}
void CaptionUserPreferencesMac::captionPreferencesChanged()
{
if (m_captionPreferenceChangeListeners.isEmpty())
return;
updateCaptionStyleSheetOveride();
for (HashSet<CaptionPreferencesChangedListener*>::iterator i = m_captionPreferenceChangeListeners.begin(); i != m_captionPreferenceChangeListeners.end(); ++i)
(*i)->captionPreferencesChanged();
}
void CaptionUserPreferencesMac::updateCaptionStyleSheetOveride()