Changeset 146380 in webkit


Ignore:
Timestamp:
Mar 20, 2013, 1:13:36 PM (13 years ago)
Author:
eric.carlson@apple.com
Message:

Allow ports specific text track menu
https://bugs.webkit.org/show_bug.cgi?id=112800

Reviewed by Dean Jackson.

Source/WebCore:

No new tests, existing tests updated for changes.

  • English.lproj/Localizable.strings: Add localizable strings for text track names.
  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::HTMLMediaElement): userPrefersCaptions -> shouldShowCaptions.
(WebCore::HTMLMediaElement::setSelectedTextTrack): toggleTrackAtIndex -> setSelectedTextTrack.
(WebCore::HTMLMediaElement::userPrefersCaptions): userPrefersCaptions -> shouldShowCaptions.
(WebCore::HTMLMediaElement::userIsInterestedInThisTrackKind): Get preferences from CaptionUserPreferences

instead of from Settings.

(WebCore::HTMLMediaElement::setSelectedTextTrack): Renamed from toggleTrackAtIndex. Now takes

a TextTrack* instead of an int.

(WebCore::HTMLMediaElement::captionPreferencesChanged): Don't force a recalculation unless

captions are enabled/disabled to avoid unnecessary thrash.

  • html/HTMLMediaElement.h:
  • html/shadow/MediaControlElements.cpp:

(WebCore::MediaControlClosedCaptionsTrackListElement::defaultEventHandler): Use the menu to track

map instead of just the track index.

(WebCore::MediaControlClosedCaptionsTrackListElement::updateDisplay): Build and configure the

menu from the menu to track map.

(WebCore::MediaControlClosedCaptionsTrackListElement::rebuildTrackListMenu): Start with a list

of tracks already sorted according to platform specific rules. Build a menu to track map
so tracks are retained while the menu is visible.

  • html/shadow/MediaControlElements.h:
  • html/shadow/MediaControls.cpp:

(WebCore::MediaControls::textTrackPreferencesChanged): Call closedCaptionTracksChanged so the

track menu will be rebuilt before it is shown again.

  • html/track/InbandTextTrack.cpp:

(WebCore::InbandTextTrack::containsOnlyForcedSubtitles): New, passthrough to the private track.
(WebCore::InbandTextTrack::isMainProgramContent): Ditto.
(WebCore::InbandTextTrack::isEasyToRead): Ditto.

  • html/track/InbandTextTrack.h:
  • html/track/TextTrack.h:
  • html/track/TextTrackList.cpp:

(WebCore::TextTrackList::contains): New.

  • html/track/TextTrackList.h:
  • page/CaptionUserPreferences.cpp:

(WebCore::CaptionUserPreferences::CaptionUserPreferences): Pull in from .h ditto.
(WebCore::CaptionUserPreferences::~CaptionUserPreferences): Ditto.
(WebCore::CaptionUserPreferences::shouldShowCaptions): Renamed from userPrefersCaptions.
(WebCore::CaptionUserPreferences::setShouldShowCaptions): New.
(WebCore::CaptionUserPreferences::userPrefersCaptions): Ditto.
(WebCore::CaptionUserPreferences::setUserPrefersCaptions): Ditto.
(WebCore::CaptionUserPreferences::userPrefersSubtitles): Ditto.
(WebCore::CaptionUserPreferences::setUserPrefersSubtitles): Ditto.
(WebCore::CaptionUserPreferences::userPrefersTextDescriptions): Ditto.
(WebCore::CaptionUserPreferences::setUserPrefersTextDescriptions): Ditto.
(WebCore::CaptionUserPreferences::displayNameForTrack): Ditto.
(WebCore::CaptionUserPreferences::sortedTrackListForMenu): Ditto.

  • page/CaptionUserPreferences.h:
  • page/CaptionUserPreferencesMac.h:
  • page/CaptionUserPreferencesMac.mm:

(WebCore::CaptionUserPreferencesMac::shouldShowCaptions): Renamed from userPrefersCaptions.
(WebCore::CaptionUserPreferencesMac::userPrefersCaptions): New.
(WebCore::CaptionUserPreferences::userPrefersSubtitles): Ditto.
(WebCore::trackDisplayName): Update logic used to build track title.
(WebCore::CaptionUserPreferencesMac::displayNameForTrack): Call trackDisplayName.
(WebCore::textTrackCompare): Text track title sort comparison function.
(WebCore::CaptionUserPreferencesMac::sortedTrackListForMenu): New. Sort the list of tracks

according to title, language, and user preferences.

  • platform/Language.cpp:

(WebCore::displayNameForLanguageLocale): Don't leak the CFLocale.

  • platform/LocalizedStrings.cpp:

(WebCore::textTrackCountryAndLanguageMenuItemText): New.
(WebCore::textTrackLanguageMenuItemText): Ditto.
(WebCore::closedCaptionTrackMenuItemText): Ditto.
(WebCore::sdhTrackMenuItemText): Ditto.
(WebCore::easyReaderTrackMenuItemText): Ditto.

  • platform/LocalizedStrings.h:
  • platform/graphics/InbandTextTrackPrivate.h:
  • platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.h:
  • platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.mm:

(WebCore::InbandTextTrackPrivateAVFObjC::containsOnlyForcedSubtitles): New, return AVFoundation property.
(WebCore::InbandTextTrackPrivateAVFObjC::isMainProgramContent): Ditto.
(WebCore::InbandTextTrackPrivateAVFObjC::isEasyToRead): Ditto.

  • testing/InternalSettings.cpp:

(WebCore::InternalSettings::setShouldDisplayTrackKind): Set setting via CaptionUserPreferences

instead of from Settings.

(WebCore::InternalSettings::shouldDisplayTrackKind): Get setting from CaptionUserPreferences

instead of from Settings.

Source/WebKit:

  • WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in: Add new exports.
  • win/WebKit.vcproj/WebKitExports.def.in: Ditto.

LayoutTests:

  • media/track/track-user-preferences-expected.txt:
  • media/track/track-user-preferences.html:
  • media/video-controls-captions-trackmenu-localized.html:
  • media/video-controls-captions-trackmenu-sorted.html:
  • media/video-controls-captions-trackmenu.html:
  • platform/mac/media/video-controls-captions-trackmenu-expected.txt:
  • platform/mac/media/video-controls-captions-trackmenu-localized-expected.txt:
  • platform/mac/media/video-controls-captions-trackmenu-sorted-expected.txt:
Location:
trunk
Files:
36 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r146371 r146380  
     12013-03-20  Eric Carlson  <eric.carlson@apple.com>
     2
     3        Allow ports specific text track menu
     4        https://bugs.webkit.org/show_bug.cgi?id=112800
     5
     6        Reviewed by Dean Jackson.
     7
     8        * media/track/track-user-preferences-expected.txt:
     9        * media/track/track-user-preferences.html:
     10        * media/video-controls-captions-trackmenu-localized.html:
     11        * media/video-controls-captions-trackmenu-sorted.html:
     12        * media/video-controls-captions-trackmenu.html:
     13        * platform/mac/media/video-controls-captions-trackmenu-expected.txt:
     14        * platform/mac/media/video-controls-captions-trackmenu-localized-expected.txt:
     15        * platform/mac/media/video-controls-captions-trackmenu-sorted-expected.txt:
     16
    1172013-03-20  Julien Chaffraix  <jchaffraix@webkit.org>
    218
  • trunk/LayoutTests/media/track/track-user-preferences-expected.txt

    r142809 r146380  
    1919Test 3: select 'fr' track from menu
    2020- show captions menu.
    21 EXPECTED (trackMenuItems[1].className == '') OK
    22 EXPECTED (trackMenuItems[2].className == '') OK
    23 EXPECTED (trackMenuItems[3].className == 'selected') OK
    24 - click on menu item 2.
     21EXPECTED (trackMenuItems[menuIndexForLanguage('French')].className == '') OK
     22EXPECTED (trackMenuItems[menuIndexForLanguage('English')].className == '') OK
     23EXPECTED (trackMenuItems[menuIndexForLanguage('Norwegian')].className == 'selected') OK
     24- click on 'French' menu item.
    2525EVENT(load)
    2626EXPECTED (event.target.srclang == 'fr') OK
     
    3939Test 5: turning captions off from menu disables caption selection
    4040- show captions menu.
    41 - click on menu item 0.
     41- click on 'Off' menu item.
    4242- creating tracks for: [ru,jp,en].
    4343EXPECTED (video.textTracks[0].mode == 'disabled') OK
  • trunk/LayoutTests/media/track/track-user-preferences.html

    r142809 r146380  
    4545            }
    4646
    47             function selectCaptionMenuItem(index)
     47            function menuIndexForLanguage(language)
    4848            {
    49                 consoleWrite("- click on menu item " + index + ".");
    5049                var trackMenuItems = trackMenuList();
     50                for (i = 0; i < trackMenuItems.length; ++i) {
     51                    if (trackMenuItems[i].textContent.indexOf(language) >= 0)
     52                        break;
     53                }
     54                return (i < trackMenuItems.length) ? i : -1;
     55            }
     56
     57            function selectCaptionMenuItem(language)
     58            {
     59                var trackMenuItems = trackMenuList();
     60                var index = menuIndexForLanguage(language);
     61                if (index < 0) {
     62                    failTest("Menu item " + language + " not found in track list menu.");
     63                    return;
     64                }
     65
     66                consoleWrite("- click on '" + language + "' menu item.");
    5167                var selectedTrackItem = trackMenuItems[index];
    5268                var boundingRect = selectedTrackItem.getBoundingClientRect();
     
    7187                var track = document.createElement('track');
    7288                track.setAttribute('kind', "captions");
    73                 track.src = 'data:text/vtt,'+encodeURIComponent("WEBVTT\n\n00:00:00.000 --> 00:00:01.000\nCaption 1\n");
     89                track.src = 'data:text/vtt,' + encodeURIComponent("WEBVTT\n\n00:00:00.000 --> 00:00:01.000\nCaption 1\n");
    7490                track.setAttribute('srclang', language);
    7591                track.setAttribute('onload', 'trackLoaded()');
     
    109125
    110126                case 3:
    111                     // Clear the debug setting so it isn't considered in the track selection logic
    112                     internals.settings.setShouldDisplayTrackKind('Captions', false);
    113 
    114127                    consoleWrite("<br>Test 3: select 'fr' track from menu");
    115128                    showCaptionMenu();
     
    118131                case 4:
    119132                    trackMenuItems = trackMenuList();
    120                     testExpected("trackMenuItems[1].className", "");
    121                     testExpected("trackMenuItems[2].className", "");
    122                     testExpected("trackMenuItems[3].className", "selected");
     133                    testExpected("trackMenuItems[menuIndexForLanguage('French')].className", "");
     134                    testExpected("trackMenuItems[menuIndexForLanguage('English')].className", "");
     135                    testExpected("trackMenuItems[menuIndexForLanguage('Norwegian')].className", "selected");
    123136
    124                     selectCaptionMenuItem(2);
     137                    selectCaptionMenuItem("French");
    125138                    expectedLanguage = 'fr';
    126139                    break;
     
    144157
    145158                case 7:
    146                     selectCaptionMenuItem(0);
     159                    selectCaptionMenuItem("Off");
    147160                    createTrackElements([ 'ru', 'jp', 'en']);
    148161                    timer = setTimeout(nextStep, 100);
  • trunk/LayoutTests/media/video-controls-captions-trackmenu-localized.html

    r142003 r146380  
    4545
    4646            item = captionsEntries[2];
    47             consoleWrite("<br>Third item in captions menu should be labelled 'Unknown'");
    48             testExpected("item.textContent", "Unknown");
     47            consoleWrite("<br>Third item in captions menu should be labelled 'Unknown SDH'");
     48            testExpected("item.textContent", "Unknown SDH");
    4949
    5050            item = captionsEntries[3];
  • trunk/LayoutTests/media/video-controls-captions-trackmenu-sorted.html

    r141864 r146380  
    88        <script src="trackmenu-test.js"></script>
    99        <script>
     10            var test = 0;
    1011            if (window.testRunner)
    1112                testRunner.dumpAsText();
    1213
    13             function testSortedMenu()
     14            function textTrackMenuItems()
    1415            {
     16                // Show and hide the menu to force a recalculation.
     17                clickCCButton();
     18                clickCCButton();
     19
    1520                var trackListElement = getTrackListElement();
    1621                if (!trackListElement)
     
    2126                    return;
    2227                }
    23                 var lastTrackLabel = null;
    24                 var trackListItems = trackListSection.querySelectorAll("li");
    25                 if (!trackListItems || trackListItems.length != 7) {
    26                     failTest("There should be seven li elements in the menu");
    27                     return;
     28                return trackListSection.querySelectorAll("li");
     29            }
     30
     31            function testSortedMenu()
     32            {
     33                switch (test)
     34                {
     35                case 0:
     36                    consoleWrite("<br><i>** Test with preferred language set to English, track type set to captions<" + "/i>");
     37                    run("internals.settings.setShouldDisplayTrackKind('Captions', true)");
     38                    window.setTimeout(testSortedMenu, 0);
     39                    break;
     40
     41                case 1:
     42                    trackMenuItems = textTrackMenuItems();
     43                    testExpected("trackMenuItems[0].textContent", "Off");
     44                    testExpected("trackMenuItems[1].textContent", "u (English) SDH");
     45                    testExpected("trackMenuItems[2].textContent", "y (English-Australia) SDH");
     46                    testExpected("trackMenuItems[3].textContent", "v (English)");
     47                    testExpected("trackMenuItems[4].textContent", "x (English-Australia)");
     48                    testExpected("trackMenuItems[5].textContent", "w (Japanese) SDH");
     49                    testExpected("trackMenuItems[6].textContent", "z (Japanese)");
     50                    testExpected("video.textTracks.length", 6);
     51                    testExpected("trackMenuItems.length", 7);
     52
     53                    consoleWrite("<br><i>** Change preferred language to Japanese, change preference to subtitles<" + "/i>");
     54                    run("internals.setUserPreferredLanguages(['ja'])");
     55                    run("internals.settings.setShouldDisplayTrackKind('Captions', false)");
     56                    run("internals.settings.setShouldDisplayTrackKind('Subtitles', true)");
     57
     58                    window.setTimeout(testSortedMenu, 0);
     59                break;
     60
     61                case 2:
     62                    trackMenuItems = textTrackMenuItems();
     63                    testExpected("trackMenuItems[0].textContent", "Off");
     64                    testExpected("trackMenuItems[1].textContent", "z (Japanese)");
     65                    testExpected("trackMenuItems[2].textContent", "v (English)");
     66                    testExpected("trackMenuItems[3].textContent", "x (English-Australia)");
     67                    testExpected("video.textTracks.length", 6);
     68                    testExpected("trackMenuItems.length", 4);
     69
     70                    consoleWrite("");
     71                    endTest();
     72                break;
    2873                }
    29                 for (var j = 0; j < trackListItems.length; j++) {
    30                     var item = trackListItems[j];
    31                     if (j == 0)
    32                         logResult(item.textContent == "Off", "First item should be labelled off");
    33                     else {
    34                         if (lastTrackLabel)
    35                             logResult(item.textContent > lastTrackLabel, lastTrackLabel + " comes before " + item.textContent);
    36                         else
    37                             logResult(true, item.textContent + " is the first real item in the list");
    38                         lastTrackLabel = item.textContent;
    39                     }
    40                 }
    41                 endTest();
     74
     75                ++test;
    4276            }
    4377
     
    5286
    5387    <body onload="start()">
    54         <p>Test that captions and subtitles are sorted in the menu.</p>
     88        <p>Test that captions and subtitles are sorted in the menu according to user preferences.</p>
    5589        <video width="500" height="300" controls>
    56             <track label="c" kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="ja">
    57             <track label="b" kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="en-au">
    58             <track label="a" kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="en">
    59             <track label="b" kind="subtitles" src="track/captions-webvtt/captions-fast.vtt" srclang="ja">
    60             <track label="a" kind="subtitles" src="track/captions-webvtt/captions-fast.vtt" srclang="en-au">
    61             <track label="c" kind="subtitles" src="track/captions-webvtt/captions-fast.vtt" srclang="en">
     90            <track label="z" kind="subtitles" src="track/captions-webvtt/captions-fast.vtt" srclang="ja">
     91            <track label="y" kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="en-au">
     92            <track label="x" kind="subtitles" src="track/captions-webvtt/captions-fast.vtt" srclang="en-au">
     93            <track label="w" kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="ja">
     94            <track label="v" kind="subtitles" src="track/captions-webvtt/captions-fast.vtt" srclang="en">
     95            <track label="u" kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="en">
    6296        </video>
    6397    </body>
  • trunk/LayoutTests/media/video-controls-captions-trackmenu.html

    r141864 r146380  
    1616                run('video.addTextTrack("captions", "Commentary", "ru")');
    1717                window.setTimeout(turnCaptionsOn, 100);
     18                consoleWrite("");
    1819            }
    1920
     
    4041            function testMenu()
    4142            {
    42                 var trackListItems = trackMenuList();
     43                trackListItems = trackMenuList();
    4344                var expectedItemCount = video.textTracks.length + 1;
    4445                consoleWrite("There should be " + expectedItemCount + " items in the menu.");
    45                 testExpected(trackListItems.length, expectedItemCount);
     46                testExpected("trackListItems.length", expectedItemCount);
    4647            }
    4748
     
    6364            {
    6465                consoleWrite("*** Turning captions on");
    65                 // Click on the third item, which is the second track (Off is the first item in the menu)
     66                // Click on the second item, which is the second track (Off is the first item in the menu)
    6667                selectCaptionMenuItem(2, testCaptionsVisible);
    6768            }
     
    118119        <p>Test that we are able to trigger the list of captions, and select from the list.</p>
    119120        <video width="500" height="300" controls>
     121            <track kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="fr">
    120122            <track kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="en">
    121             <track kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="en-au">
    122123            <track kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="ja">
    123124        </video>
  • trunk/LayoutTests/platform/mac/media/video-controls-captions-trackmenu-expected.txt

    r141864 r146380  
    88*** Add another text track.
    99RUN(video.addTextTrack("captions", "Commentary", "ru"))
     10
    1011*** Turning captions on
    1112There should be 5 items in the menu.
    12 EXPECTED (5 == '5') OK
     13EXPECTED (trackListItems.length == '5') OK
    1314EXPECTED (video.textTracks.length == '4') OK
    1415Track 0 should be showing
     
    2627*** Turning captions off
    2728There should be 4 items in the menu.
    28 EXPECTED (4 == '4') OK
     29EXPECTED (trackListItems.length == '4') OK
    2930EXPECTED (video.textTracks.length == '3') OK
    3031Track 0 should be disabled
  • trunk/LayoutTests/platform/mac/media/video-controls-captions-trackmenu-localized-expected.txt

    r142003 r146380  
    1212
    1313Second item in captions menu should be labelled 'English CC'
    14 EXPECTED (item.textContent == 'English CC'), OBSERVED 'Unknown' FAIL
     14EXPECTED (item.textContent == 'English CC'), OBSERVED 'Unknown SDH' FAIL
    1515
    16 Third item in captions menu should be labelled 'Unknown'
    17 EXPECTED (item.textContent == 'Unknown') OK
     16Third item in captions menu should be labelled 'Unknown SDH'
     17EXPECTED (item.textContent == 'Unknown SDH'), OBSERVED 'Unknown' FAIL
    1818
    1919Fourth item in captions menu should be labelled 'Unknown'
  • trunk/LayoutTests/platform/mac/media/video-controls-captions-trackmenu-sorted-expected.txt

    r141864 r146380  
    1 Test that captions and subtitles are sorted in the menu.
     1Test that captions and subtitles are sorted in the menu according to user preferences.
    22
    33EVENT(canplaythrough)
     
    55*** Set the user language preference.
    66RUN(internals.setUserPreferredLanguages(['en']))
    7 First item should be labelled off OK
    8 a English (Australia) is the first real item in the list OK
    9 a English (Australia) comes before a English SDH OK
    10 a English SDH comes before b English (Australia) SDH OK
    11 b English (Australia) SDH comes before b Japanese OK
    12 b Japanese comes before c English OK
    13 c English comes before c Japanese SDH OK
     7
     8** Test with preferred language set to English, track type set to captions
     9RUN(internals.settings.setShouldDisplayTrackKind('Captions', true))
     10EXPECTED (trackMenuItems[0].textContent == 'Off') OK
     11EXPECTED (trackMenuItems[1].textContent == 'u (English) SDH') OK
     12EXPECTED (trackMenuItems[2].textContent == 'y (English-Australia) SDH') OK
     13EXPECTED (trackMenuItems[3].textContent == 'v (English)') OK
     14EXPECTED (trackMenuItems[4].textContent == 'x (English-Australia)') OK
     15EXPECTED (trackMenuItems[5].textContent == 'w (Japanese) SDH') OK
     16EXPECTED (trackMenuItems[6].textContent == 'z (Japanese)') OK
     17EXPECTED (video.textTracks.length == '6') OK
     18EXPECTED (trackMenuItems.length == '7') OK
     19
     20** Change preferred language to Japanese, change preference to subtitles
     21RUN(internals.setUserPreferredLanguages(['ja']))
     22RUN(internals.settings.setShouldDisplayTrackKind('Captions', false))
     23RUN(internals.settings.setShouldDisplayTrackKind('Subtitles', true))
     24EXPECTED (trackMenuItems[0].textContent == 'Off') OK
     25EXPECTED (trackMenuItems[1].textContent == 'z (Japanese)') OK
     26EXPECTED (trackMenuItems[2].textContent == 'v (English)') OK
     27EXPECTED (trackMenuItems[3].textContent == 'x (English-Australia)') OK
     28EXPECTED (video.textTracks.length == '6') OK
     29EXPECTED (trackMenuItems.length == '4') OK
     30
    1431END OF TEST
    1532
  • trunk/Source/WebCore/ChangeLog

    r146379 r146380  
     12013-03-20  Eric Carlson  <eric.carlson@apple.com>
     2
     3        Allow ports specific text track menu
     4        https://bugs.webkit.org/show_bug.cgi?id=112800
     5
     6        Reviewed by Dean Jackson.
     7
     8        No new tests, existing tests updated for changes.
     9
     10        * English.lproj/Localizable.strings: Add localizable strings for text track names.
     11
     12        * html/HTMLMediaElement.cpp:
     13        (WebCore::HTMLMediaElement::HTMLMediaElement): userPrefersCaptions -> shouldShowCaptions.
     14        (WebCore::HTMLMediaElement::setSelectedTextTrack): toggleTrackAtIndex -> setSelectedTextTrack.
     15        (WebCore::HTMLMediaElement::userPrefersCaptions): userPrefersCaptions -> shouldShowCaptions.
     16        (WebCore::HTMLMediaElement::userIsInterestedInThisTrackKind): Get preferences from CaptionUserPreferences
     17            instead of from Settings.
     18        (WebCore::HTMLMediaElement::setSelectedTextTrack): Renamed from toggleTrackAtIndex. Now takes
     19            a TextTrack* instead of an int.
     20        (WebCore::HTMLMediaElement::captionPreferencesChanged): Don't force a recalculation unless
     21            captions are enabled/disabled to avoid unnecessary thrash.
     22        * html/HTMLMediaElement.h:
     23
     24        * html/shadow/MediaControlElements.cpp:
     25        (WebCore::MediaControlClosedCaptionsTrackListElement::defaultEventHandler): Use the menu to track
     26            map instead of just the track index.
     27        (WebCore::MediaControlClosedCaptionsTrackListElement::updateDisplay): Build and configure the
     28            menu from the menu to track map.
     29        (WebCore::MediaControlClosedCaptionsTrackListElement::rebuildTrackListMenu): Start with a list
     30            of tracks already sorted according to platform specific rules. Build a menu to track map
     31            so tracks are retained while the menu is visible.
     32        * html/shadow/MediaControlElements.h:
     33
     34        * html/shadow/MediaControls.cpp:
     35        (WebCore::MediaControls::textTrackPreferencesChanged): Call closedCaptionTracksChanged so the
     36            track menu will be rebuilt before it is shown again.
     37
     38        * html/track/InbandTextTrack.cpp:
     39        (WebCore::InbandTextTrack::containsOnlyForcedSubtitles): New, passthrough to the private track.
     40        (WebCore::InbandTextTrack::isMainProgramContent): Ditto.
     41        (WebCore::InbandTextTrack::isEasyToRead): Ditto.
     42        * html/track/InbandTextTrack.h:
     43        * html/track/TextTrack.h:
     44
     45        * html/track/TextTrackList.cpp:
     46        (WebCore::TextTrackList::contains): New.
     47        * html/track/TextTrackList.h:
     48
     49        * page/CaptionUserPreferences.cpp:
     50        (WebCore::CaptionUserPreferences::CaptionUserPreferences): Pull in from .h ditto.
     51        (WebCore::CaptionUserPreferences::~CaptionUserPreferences): Ditto.
     52        (WebCore::CaptionUserPreferences::shouldShowCaptions): Renamed from userPrefersCaptions.
     53        (WebCore::CaptionUserPreferences::setShouldShowCaptions): New.
     54        (WebCore::CaptionUserPreferences::userPrefersCaptions): Ditto.
     55        (WebCore::CaptionUserPreferences::setUserPrefersCaptions): Ditto.
     56        (WebCore::CaptionUserPreferences::userPrefersSubtitles): Ditto.
     57        (WebCore::CaptionUserPreferences::setUserPrefersSubtitles): Ditto.
     58        (WebCore::CaptionUserPreferences::userPrefersTextDescriptions): Ditto.
     59        (WebCore::CaptionUserPreferences::setUserPrefersTextDescriptions): Ditto.
     60        (WebCore::CaptionUserPreferences::displayNameForTrack): Ditto.
     61        (WebCore::CaptionUserPreferences::sortedTrackListForMenu): Ditto.
     62        * page/CaptionUserPreferences.h:
     63
     64        * page/CaptionUserPreferencesMac.h:
     65        * page/CaptionUserPreferencesMac.mm:
     66        (WebCore::CaptionUserPreferencesMac::shouldShowCaptions): Renamed from userPrefersCaptions.
     67        (WebCore::CaptionUserPreferencesMac::userPrefersCaptions): New.
     68        (WebCore::CaptionUserPreferences::userPrefersSubtitles): Ditto.
     69        (WebCore::trackDisplayName): Update logic used to build track title.
     70        (WebCore::CaptionUserPreferencesMac::displayNameForTrack): Call trackDisplayName.
     71        (WebCore::textTrackCompare): Text track title sort comparison function.
     72        (WebCore::CaptionUserPreferencesMac::sortedTrackListForMenu): New. Sort the list of tracks
     73            according to title, language, and user preferences.
     74
     75        * platform/Language.cpp:
     76        (WebCore::displayNameForLanguageLocale): Don't leak the CFLocale.
     77       
     78        * platform/LocalizedStrings.cpp:
     79        (WebCore::textTrackCountryAndLanguageMenuItemText): New.
     80        (WebCore::textTrackLanguageMenuItemText): Ditto.
     81        (WebCore::closedCaptionTrackMenuItemText): Ditto.
     82        (WebCore::sdhTrackMenuItemText): Ditto.
     83        (WebCore::easyReaderTrackMenuItemText): Ditto.
     84        * platform/LocalizedStrings.h:
     85
     86        * platform/graphics/InbandTextTrackPrivate.h:
     87        * platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.h:
     88        * platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.mm:
     89        (WebCore::InbandTextTrackPrivateAVFObjC::containsOnlyForcedSubtitles): New, return AVFoundation property.
     90        (WebCore::InbandTextTrackPrivateAVFObjC::isMainProgramContent): Ditto.
     91        (WebCore::InbandTextTrackPrivateAVFObjC::isEasyToRead): Ditto.
     92
     93        * testing/InternalSettings.cpp:
     94        (WebCore::InternalSettings::setShouldDisplayTrackKind): Set setting via CaptionUserPreferences
     95            instead of from Settings.
     96        (WebCore::InternalSettings::shouldDisplayTrackKind): Get setting from CaptionUserPreferences
     97            instead of from Settings.
     98
    1992013-03-20  Zan Dobersek  <zdobersek@igalia.com>
    2100
  • trunk/Source/WebCore/English.lproj/Localizable.strings

    r144769 r146380  
    2020"%@ (%@ Internet plug-in)" = "%@ (%@ Internet plug-in)";
    2121
     22/* Text track display name format that includes the language of the subtitle, in the form of 'Title (Language)' */
     23"%@ (%@)" = "%@ (%@)";
     24
     25/* Text track display name format that includes the country and language of the subtitle, in the form of 'Title (Language-Country)' */
     26"%@ (%@-%@)" = "%@ (%@-%@)";
     27
     28/* Text track contains closed captions */
     29"%@ CC" = "%@ CC";
     30
     31/* Text track contains simplified (3rd grade level) subtitles */
     32"%@ Easy Reader" = "%@ Easy Reader";
     33
    2234/* visible name of the network process. The argument is the application name. */
    2335"%@ Networking" = "%@ Networking";
     
    2638"%@ Offline Storage" = "%@ Offline Storage";
    2739
     40/* Text track contains subtitles for the deaf and hard of hearing */
     41"%@ SDH" = "%@ SDH";
     42
    2843/* Visible name of the shared worker process. The argument is the application name. */
    2944"%@ Shared Worker" = "%@ Shared Worker";
     
    518533"Underline (Undo action name)" = "Underline";
    519534
    520 /* Menu item label for a closed captions track that has no other name */
    521 "Unknown (closed captions track)" = "Unknown";
    522 
    523535/* Unknown filesize FTP directory listing item */
    524536"Unknown (filesize)" = "Unknown";
    525537
     538/* Menu item label for a text track that has no other name */
     539"Unknown (text track)" = "Unknown";
     540
    526541/* Undo action name */
    527542"Unlink (Undo action name)" = "Unlink";
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r145826 r146380  
    321321        CaptionUserPreferences* captionPreferences = document->page()->group().captionPreferences();
    322322        if (captionPreferences->userHasCaptionPreferences())
    323             m_disableCaptions = !captionPreferences->userPrefersCaptions();
     323            m_disableCaptions = !captionPreferences->shouldShowCaptions();
    324324    }
    325325#endif
     
    28632863
    28642864    if (!platformTrack) {
    2865         toggleTrackAtIndex(textTracksOffIndex(), true);
     2865        setSelectedTextTrack(0);
    28662866        return;
    28672867    }
     
    28782878    if (i == m_textTracks->length())
    28792879        return;
    2880     toggleTrackAtIndex(i, true);
     2880    setSelectedTextTrack(textTrack);
    28812881}
    28822882
     
    30773077
    30783078    CaptionUserPreferences* captionPreferences = page->group().captionPreferences();
    3079     return captionPreferences->userHasCaptionPreferences() && captionPreferences->userPrefersCaptions();
     3079    return captionPreferences->userHasCaptionPreferences() && captionPreferences->shouldShowCaptions();
    30803080}
    30813081
     
    30853085        return false;
    30863086
    3087     Settings* settings = document()->settings();
     3087    Page* page = document()->page();
     3088    if (!page)
     3089        return false;
     3090
     3091    CaptionUserPreferences* captionPreferences = page->group().captionPreferences();
    30883092    bool userPrefersCaptionsOrSubtitles = m_closedCaptionsVisible || userPrefersCaptions();
    30893093
    30903094    if (kind == TextTrack::subtitlesKeyword())
    3091         return (settings && settings->shouldDisplaySubtitles()) || userPrefersCaptionsOrSubtitles;
     3095        return captionPreferences->userPrefersSubtitles() || userPrefersCaptionsOrSubtitles;
    30923096    if (kind == TextTrack::captionsKeyword())
    3093         return (settings && settings->shouldDisplayCaptions()) || userPrefersCaptionsOrSubtitles;
     3097        return captionPreferences->userPrefersCaptions() || userPrefersCaptionsOrSubtitles;
    30943098    if (kind == TextTrack::descriptionsKeyword())
    3095         return settings && settings->shouldDisplayTextDescriptions();
     3099        return captionPreferences->userPrefersTextDescriptions() || userPrefersCaptionsOrSubtitles;
    30963100
    30973101    return false;
     
    31793183}
    31803184
    3181 void HTMLMediaElement::toggleTrackAtIndex(int index, bool exclusive)
     3185void HTMLMediaElement::setSelectedTextTrack(TextTrack* trackToSelect)
    31823186{
    31833187    TextTrackList* trackList = textTracks();
    31843188    if (!trackList || !trackList->length())
    31853189        return;
    3186 
    3187     CaptionUserPreferences* captionPreferences = document()->page() ? document()->page()->group().captionPreferences() : 0;
    3188     if (captionPreferences)
    3189         captionPreferences->setUserPrefersCaptions(index != textTracksOffIndex());
     3190    if (trackToSelect && !trackList->contains(trackToSelect))
     3191        return;
    31903192
    31913193    for (int i = 0, length = trackList->length(); i < length; ++i) {
    31923194        TextTrack* track = trackList->item(i);
    3193         if (i == index) {
     3195        if (!trackToSelect || track != trackToSelect)
     3196            track->setMode(TextTrack::disabledKeyword());
     3197        else
    31943198            track->setMode(TextTrack::showingKeyword());
    3195             if (captionPreferences && track->language().length())
    3196                 captionPreferences->setPreferredLanguage(track->language());
    3197         }
    3198         else if (exclusive || index == HTMLMediaElement::textTracksOffIndex())
    3199             track->setMode(TextTrack::disabledKeyword());
     3199    }
     3200
     3201    CaptionUserPreferences* captionPreferences = document()->page() ? document()->page()->group().captionPreferences() : 0;
     3202    if (captionPreferences) {
     3203        captionPreferences->setShouldShowCaptions(trackToSelect);
     3204        if (trackToSelect && trackToSelect->language().length())
     3205            captionPreferences->setPreferredLanguage(trackToSelect->language());
    32003206    }
    32013207}
     
    45214527        return;
    45224528
    4523     m_processingPreferenceChange = true;
    4524     setClosedCaptionsVisible(userPrefersCaptions());
    4525 
    45264529    if (hasMediaControls())
    45274530        mediaControls()->textTrackPreferencesChanged();
     4531
     4532    bool prefersCaptions = userPrefersCaptions();
     4533    if (m_disableCaptions == !prefersCaptions)
     4534        return;
     4535
     4536    m_processingPreferenceChange = true;
     4537    setClosedCaptionsVisible(prefersCaptions);
    45284538}
    45294539
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r145826 r146380  
    268268    void configureTextTrackGroup(const TrackGroup&);
    269269
    270     void toggleTrackAtIndex(int index, bool exclusive = true);
     270    void setSelectedTextTrack(TextTrack*);
    271271    static int textTracksOffIndex() { return -1; }
    272272    static int textTracksIndexNotFound() { return -2; }
  • trunk/Source/WebCore/html/shadow/MediaControlElements.cpp

    r146140 r146380  
    756756        // tell the HTMLMediaElement to enable that track.
    757757
     758        RefPtr<TextTrack> textTrack;
     759        MenuItemToTrackMap::iterator iter = m_menuToTrackMap.find(toElement(target));
     760        if (iter != m_menuToTrackMap.end())
     761            textTrack = iter->value;
     762        m_menuToTrackMap.clear();
     763        m_controls->toggleClosedCaptionTrackList();
     764
    758765        int trackIndex = trackListIndexForElement(toElement(target));
    759766        if (trackIndex == HTMLMediaElement::textTracksIndexNotFound())
     
    764771            return;
    765772
    766         mediaElement->toggleTrackAtIndex(trackIndex);
    767 
    768         // We've selected a track to display, so we can now close the menu.
    769         m_controls->toggleClosedCaptionTrackList();
     773        if (textTrack)
     774            mediaElement->setSelectedTextTrack(textTrack.get());
     775        else if (trackIndex == HTMLMediaElement::textTracksOffIndex())
     776            mediaElement->setSelectedTextTrack(0);
     777
    770778        updateDisplay();
    771779    }
     
    800808    if (m_trackListHasChanged)
    801809        rebuildTrackListMenu();
    802    
     810
    803811    bool captionsVisible = mediaElement->closedCaptionsVisible();
    804812    for (unsigned i = 0, length = m_menuItems.size(); i < length; ++i) {
    805813        RefPtr<Element> trackItem = m_menuItems[i];
     814
    806815        int trackIndex = trackListIndexForElement(trackItem.get());
    807         if (trackIndex != HTMLMediaElement::textTracksIndexNotFound()) {
    808             if (trackIndex == HTMLMediaElement::textTracksOffIndex()) {
    809                 if (captionsVisible)
    810                     trackItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION);
    811                 else
    812                     trackItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION);
    813             } else {
    814                 TextTrack* track = trackList->item(trackIndex);
    815                 if (!track)
    816                     continue;
    817                 if (track->mode() == TextTrack::showingKeyword())
    818                     trackItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION);
    819                 else
    820                     trackItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION);
    821             }
     816        if (trackIndex == HTMLMediaElement::textTracksIndexNotFound())
     817            continue;
     818
     819        if (trackIndex == HTMLMediaElement::textTracksOffIndex()) {
     820            if (captionsVisible)
     821                trackItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION);
     822            else
     823                trackItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION);
     824            continue;
    822825        }
     826
     827        RefPtr<TextTrack> textTrack;
     828        MenuItemToTrackMap::iterator iter = m_menuToTrackMap.find(trackItem.get());
     829        if (iter == m_menuToTrackMap.end())
     830            continue;
     831        textTrack = iter->value;
     832        if (!textTrack)
     833            continue;
     834        if (textTrack->mode() == TextTrack::showingKeyword())
     835            trackItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION);
     836        else
     837            trackItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION);
    823838    }
    824839#endif
    825840}
    826 
    827 #if ENABLE(VIDEO_TRACK)
    828 static void insertTextTrackMenuItemIntoSortedContainer(RefPtr<Element>& item, RefPtr<Element>& container)
    829 {
    830     // The container will always have the "Off" entry already present and it
    831     // should remain at the start of the list.
    832     ASSERT(container->childNodeCount() > 0);
    833     ASSERT(item->childNodeCount() == 1); // Each item should have a single text node child for the label.
    834     String itemLabel = toText(item->firstChild())->wholeText();
    835 
    836     // This is an insertion sort :( However, there shouldn't be a horrible number of text track items.
    837     for (int i = 1, numChildNodes = container->childNodeCount(); i < numChildNodes; ++i) {
    838         Node* child = container->childNode(i);
    839         ASSERT(child->childNodeCount() == 1); // Each item should have a single text node child for the label.
    840         String childLabel = toText(child->firstChild())->wholeText();
    841         if (codePointCompareLessThan(itemLabel, childLabel)) {
    842             container->insertBefore(item, child);
    843             return;
    844         }
    845     }
    846     container->appendChild(item);
    847 }
    848 #endif
    849841
    850842void MediaControlClosedCaptionsTrackListElement::rebuildTrackListMenu()
     
    856848
    857849    m_trackListHasChanged = false;
     850    m_menuToTrackMap.clear();
    858851
    859852    if (!mediaController()->hasClosedCaptions())
     
    865858
    866859    TextTrackList* trackList = mediaElement->textTracks();
    867 
    868860    if (!trackList || !trackList->length())
    869861        return;
     
    871863    Document* doc = document();
    872864    CaptionUserPreferences* captionsUserPreferences = doc->page()->group().captionPreferences();
     865    Vector<RefPtr<TextTrack> > tracksForMenu = captionsUserPreferences->sortedTrackListForMenu(trackList);
    873866
    874867    RefPtr<Element> captionsHeader = doc->createElement(h3Tag, ASSERT_NO_EXCEPTION);
     
    877870    RefPtr<Element> captionsMenuList = doc->createElement(ulTag, ASSERT_NO_EXCEPTION);
    878871
    879     RefPtr<Element> trackItem;
    880 
    881     trackItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION);
    882     trackItem->appendChild(doc->createTextNode(textTrackOffText()));
    883     trackItem->setAttribute(trackIndexAttributeName(), textTracksOffAttrValue, ASSERT_NO_EXCEPTION);
    884     captionsMenuList->appendChild(trackItem);
    885     m_menuItems.append(trackItem);
    886 
    887     for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
    888         TextTrack* track = trackList->item(i);
    889         trackItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION);
     872    RefPtr<Element> menuItem;
     873    menuItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION);
     874    menuItem->appendChild(doc->createTextNode(textTrackOffText()));
     875    menuItem->setAttribute(trackIndexAttributeName(), textTracksOffAttrValue, ASSERT_NO_EXCEPTION);
     876    captionsMenuList->appendChild(menuItem);
     877    m_menuItems.append(menuItem);
     878
     879    for (unsigned i = 0, length = tracksForMenu.size(); i < length; ++i) {
     880        RefPtr<TextTrack> textTrack = tracksForMenu[i];
     881        menuItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION);
    890882
    891883        // Add a custom attribute to the <li> element which will allow
     
    893885        // track. Since this list is rebuilt if the tracks change, we
    894886        // should always be in sync.
    895         trackItem->setAttribute(trackIndexAttributeName(), String::number(i), ASSERT_NO_EXCEPTION);
    896 
    897         if (captionsUserPreferences)
    898             trackItem->appendChild(doc->createTextNode(captionsUserPreferences->displayNameForTrack(track)));
    899         else
    900             trackItem->appendChild(doc->createTextNode(track->label()));
    901 
    902         insertTextTrackMenuItemIntoSortedContainer(trackItem, captionsMenuList);
    903         m_menuItems.append(trackItem);
     887        menuItem->setAttribute(trackIndexAttributeName(), String::number(i), ASSERT_NO_EXCEPTION);
     888
     889        menuItem->appendChild(doc->createTextNode(captionsUserPreferences->displayNameForTrack(textTrack.get())));
     890
     891        captionsMenuList->appendChild(menuItem);
     892        m_menuItems.append(menuItem);
     893        m_menuToTrackMap.add(menuItem, textTrack);
    904894    }
    905895
  • trunk/Source/WebCore/html/shadow/MediaControlElements.h

    r145397 r146380  
    316316    typedef Vector<RefPtr<Element> > TrackMenuItems;
    317317    TrackMenuItems m_menuItems;
     318#if ENABLE(VIDEO_TRACK)
     319    typedef HashMap<RefPtr<Element>, RefPtr<TextTrack> > MenuItemToTrackMap;
     320    MenuItemToTrackMap m_menuToTrackMap;
     321#endif
    318322    MediaControls* m_controls;
    319323    bool m_trackListHasChanged;
  • trunk/Source/WebCore/html/shadow/MediaControls.cpp

    r145403 r146380  
    412412    if (m_textDisplayContainer)
    413413        m_textDisplayContainer->updateSizes(true);
     414    closedCaptionTracksChanged();
    414415}
    415416#endif
  • trunk/Source/WebCore/html/track/InbandTextTrack.cpp

    r142349 r146380  
    104104}
    105105
     106bool InbandTextTrack::containsOnlyForcedSubtitles() const
     107{
     108    if (!m_private)
     109        return false;
     110   
     111    return m_private->containsOnlyForcedSubtitles();
     112}
     113
     114bool InbandTextTrack::isMainProgramContent() const
     115{
     116    if (!m_private)
     117        return false;
     118   
     119    return m_private->isMainProgramContent();
     120}
     121
     122bool InbandTextTrack::isEasyToRead() const
     123{
     124    if (!m_private)
     125        return false;
     126   
     127    return m_private->isEasyToRead();
     128}
     129   
    106130size_t InbandTextTrack::inbandTrackIndex()
    107131{
  • trunk/Source/WebCore/html/track/InbandTextTrack.h

    r145322 r146380  
    4747
    4848    virtual bool isClosedCaptions() const OVERRIDE;
     49    virtual bool containsOnlyForcedSubtitles() const OVERRIDE;
     50    virtual bool isMainProgramContent() const OVERRIDE;
     51    virtual bool isEasyToRead() const OVERRIDE;
    4952    virtual void setMode(const AtomicString&) OVERRIDE;
    5053    size_t inbandTrackIndex();
  • trunk/Source/WebCore/html/track/TextTrack.cpp

    r145322 r146380  
    430430#endif
    431431
     432bool TextTrack::isMainProgramContent() const
     433{
     434    // "Main program" content is intrinsic to the presentation of the media file, regardless of locale. Content such as
     435    // directors commentary is not "main program" because it is not essential for the presentation. HTML5 doesn't have
     436    // a way to express this in a machine-reable form, it is typically done with the track label, so we assume that caption
     437    // tracks are main content and all other track types are not.
     438    return m_kind == captionsKeyword();
     439}
     440
    432441} // namespace WebCore
    433442
  • trunk/Source/WebCore/html/track/TextTrack.h

    r145322 r146380  
    120120    virtual bool isClosedCaptions() const { return false; }
    121121
     122    virtual bool containsOnlyForcedSubtitles() const { return false; }
     123    virtual bool isMainProgramContent() const;
     124    virtual bool isEasyToRead() const { return false; }
     125
    122126    int trackIndex();
    123127    void invalidateTrackIndex();
  • trunk/Source/WebCore/html/track/TextTrackList.cpp

    r142375 r146380  
    212212}
    213213
     214bool TextTrackList::contains(TextTrack* track) const
     215{
     216    const Vector<RefPtr<TextTrack> >* tracks = 0;
     217   
     218    if (track->trackType() == TextTrack::TrackElement)
     219        tracks = &m_elementTracks;
     220    else if (track->trackType() == TextTrack::AddTrack)
     221        tracks = &m_addTrackTracks;
     222    else if (track->trackType() == TextTrack::InBand)
     223        tracks = &m_inbandTracks;
     224    else
     225        ASSERT_NOT_REACHED();
     226   
     227    return tracks->find(track) != notFound;
     228}
     229
    214230const AtomicString& TextTrackList::interfaceName() const
    215231{
  • trunk/Source/WebCore/html/track/TextTrackList.h

    r135410 r146380  
    5454    int getTrackIndex(TextTrack*);
    5555    int getTrackIndexRelativeToRenderedTracks(TextTrack*);
     56    bool contains(TextTrack*) const;
    5657
    5758    TextTrack* item(unsigned index);
  • trunk/Source/WebCore/page/CaptionUserPreferences.cpp

    r145826 r146380  
    2929
    3030#include "CaptionUserPreferences.h"
     31#include "Page.h"
    3132#include "PageGroup.h"
     33#include "Settings.h"
     34#include "TextTrackList.h"
     35#include <wtf/NonCopyingSort.h>
    3236
    3337namespace WebCore {
    3438
     39CaptionUserPreferences::CaptionUserPreferences(PageGroup* group)
     40    : m_pageGroup(group)
     41    , m_timer(this, &CaptionUserPreferences::timerFired)
     42    , m_testingMode(false)
     43    , m_havePreferences(false)
     44    , m_shouldShowCaptions(false)
     45{
     46}
     47
     48CaptionUserPreferences::~CaptionUserPreferences()
     49{
     50}
     51
     52bool CaptionUserPreferences::shouldShowCaptions() const
     53{
     54    return m_testingMode ? m_shouldShowCaptions : false;
     55}
     56
     57void CaptionUserPreferences::timerFired(Timer<CaptionUserPreferences>*)
     58{
     59    captionPreferencesChanged();
     60}
     61
     62void CaptionUserPreferences::notify()
     63{
     64    if (!m_testingMode)
     65        return;
     66
     67    m_havePreferences = true;
     68    if (!m_timer.isActive())
     69        m_timer.startOneShot(0);
     70}
     71
     72void CaptionUserPreferences::setShouldShowCaptions(bool preference)
     73{
     74    m_shouldShowCaptions = preference;
     75    notify();
     76}
     77
     78bool CaptionUserPreferences::userPrefersCaptions() const
     79{
     80    Page* page = *(pageGroup()->pages().begin());
     81    if (!page)
     82        return false;
     83
     84    return page->settings()->shouldDisplayCaptions();
     85}
     86
    3587void CaptionUserPreferences::setUserPrefersCaptions(bool preference)
    3688{
    37     m_userPrefersCaptions = preference;
    38     if (m_testingMode) {
    39         m_havePreferences = true;
    40         captionPreferencesChanged();
    41     }
     89    Page* page = *(pageGroup()->pages().begin());
     90    if (!page)
     91        return;
     92
     93    page->settings()->setShouldDisplayCaptions(preference);
     94    notify();
     95}
     96
     97bool CaptionUserPreferences::userPrefersSubtitles() const
     98{
     99    Page* page = *(pageGroup()->pages().begin());
     100    if (!page)
     101        return false;
     102
     103    return page->settings()->shouldDisplaySubtitles();
     104}
     105
     106void CaptionUserPreferences::setUserPrefersSubtitles(bool preference)
     107{
     108    Page* page = *(pageGroup()->pages().begin());
     109    if (!page)
     110        return;
     111
     112    page->settings()->setShouldDisplaySubtitles(preference);
     113    notify();
     114}
     115
     116bool CaptionUserPreferences::userPrefersTextDescriptions() const
     117{
     118    Page* page = *(pageGroup()->pages().begin());
     119    if (!page)
     120        return false;
     121   
     122    return page->settings()->shouldDisplayTextDescriptions();
     123}
     124
     125void CaptionUserPreferences::setUserPrefersTextDescriptions(bool preference)
     126{
     127    Page* page = *(pageGroup()->pages().begin());
     128    if (!page)
     129        return;
     130   
     131    page->settings()->setShouldDisplayTextDescriptions(preference);
     132    notify();
    42133}
    43134
     
    59150{
    60151    m_userPreferredLanguage = language;
    61     if (m_testingMode) {
    62         m_havePreferences = true;
    63         captionPreferencesChanged();
    64     }
     152    notify();
    65153}
    66154
    67 String CaptionUserPreferences::displayNameForTrack(TextTrack* track) const
     155static String trackDisplayName(TextTrack* track)
    68156{
    69157    if (track->label().isEmpty() && track->language().isEmpty())
     
    74162}
    75163
     164String CaptionUserPreferences::displayNameForTrack(TextTrack* track) const
     165{
     166    return trackDisplayName(track);
     167}
     168   
     169static bool textTrackCompare(const RefPtr<TextTrack>& a, const RefPtr<TextTrack>& b)
     170{
     171    return codePointCompare(trackDisplayName(a.get()), trackDisplayName(b.get())) < 0;
     172}
     173
     174Vector<RefPtr<TextTrack> > CaptionUserPreferences::sortedTrackListForMenu(TextTrackList* trackList)
     175{
     176    ASSERT(trackList);
     177
     178    Vector<RefPtr<TextTrack> > tracksForMenu;
     179
     180    for (unsigned i = 0, length = trackList->length(); i < length; ++i)
     181        tracksForMenu.append(trackList->item(i));
     182
     183    nonCopyingSort(tracksForMenu.begin(), tracksForMenu.end(), textTrackCompare);
     184
     185    return tracksForMenu;
     186}
     187
    76188}
    77189
  • trunk/Source/WebCore/page/CaptionUserPreferences.h

    r145826 r146380  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3232#include "LocalizedStrings.h"
    3333#include "TextTrack.h"
     34#include "Timer.h"
    3435#include <wtf/PassOwnPtr.h>
    3536#include <wtf/text/AtomicString.h>
     
    3839
    3940class PageGroup;
     41class TextTrackList;
    4042
    4143class CaptionUserPreferences {
    4244public:
    4345    static PassOwnPtr<CaptionUserPreferences> create(PageGroup* group) { return adoptPtr(new CaptionUserPreferences(group)); }
    44     virtual ~CaptionUserPreferences() { }
     46    virtual ~CaptionUserPreferences();
    4547
    4648    virtual bool userHasCaptionPreferences() const { return m_testingMode && m_havePreferences; }
    47     virtual bool userPrefersCaptions() const { return m_testingMode ? m_userPrefersCaptions : false; }
    48     virtual void setUserPrefersCaptions(bool preference);
     49    virtual bool shouldShowCaptions() const;
     50    virtual void setShouldShowCaptions(bool);
     51
     52    virtual bool userPrefersCaptions() const;
     53    virtual void setUserPrefersCaptions(bool);
     54
     55    virtual bool userPrefersSubtitles() const;
     56    virtual void setUserPrefersSubtitles(bool preference);
     57   
     58    virtual bool userPrefersTextDescriptions() const;
     59    virtual void setUserPrefersTextDescriptions(bool preference);
     60
    4961    virtual float captionFontSizeScale(bool& important) const { important = false; return 0.05f; }
    5062    virtual String captionsStyleSheetOverride() const { return emptyString(); }
     
    5870
    5971    virtual String displayNameForTrack(TextTrack*) const;
     72    virtual Vector<RefPtr<TextTrack> > sortedTrackListForMenu(TextTrackList*);
    6073
    6174    virtual bool testingMode() const { return m_testingMode; }
    6275    virtual void setTestingMode(bool override) { m_testingMode = override; }
    6376
    64     PageGroup* pageGroup() { return m_pageGroup; }
     77    PageGroup* pageGroup() const { return m_pageGroup; }
    6578
    6679protected:
    67     CaptionUserPreferences(PageGroup* group)
    68         : m_pageGroup(group)
    69         , m_testingMode(false)
    70         , m_havePreferences(false)
    71         , m_userPrefersCaptions(false)
    72     {
    73     }
     80    CaptionUserPreferences(PageGroup*);
    7481
    7582private:
     83    void timerFired(Timer<CaptionUserPreferences>*);
     84    void notify();
     85
    7686    PageGroup* m_pageGroup;
     87    Timer<CaptionUserPreferences> m_timer;
    7788    String m_userPreferredLanguage;
    7889    bool m_testingMode;
    7990    bool m_havePreferences;
    80     bool m_userPrefersCaptions;
     91    bool m_shouldShowCaptions;
    8192};
    8293   
  • trunk/Source/WebCore/page/CaptionUserPreferencesMac.h

    r145826 r146380  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4343#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
    4444    virtual bool userHasCaptionPreferences() const OVERRIDE;
     45    virtual bool shouldShowCaptions() const OVERRIDE;
     46    virtual void setShouldShowCaptions(bool) OVERRIDE;
     47
    4548    virtual bool userPrefersCaptions() const OVERRIDE;
    46     virtual void setUserPrefersCaptions(bool) OVERRIDE;
     49    virtual bool userPrefersSubtitles() const OVERRIDE;
     50   
    4751    virtual float captionFontSizeScale(bool&) const OVERRIDE;
    4852    virtual String captionsStyleSheetOverride() const OVERRIDE;
     
    5458
    5559    virtual void captionPreferencesChanged() OVERRIDE;
     60
    5661#endif
    5762
     63    virtual Vector<RefPtr<TextTrack> > sortedTrackListForMenu(TextTrackList*) OVERRIDE;
    5864    virtual String displayNameForTrack(TextTrack*) const OVERRIDE;
    5965
  • trunk/Source/WebCore/page/CaptionUserPreferencesMac.mm

    r145826 r146380  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4242#import "SoftLinking.h"
    4343#import "TextTrackCue.h"
     44#import "TextTrackList.h"
    4445#import "UserStyleSheetTypes.h"
     46#import <wtf/NonCopyingSort.h>
    4547#import <wtf/RetainPtr.h>
    4648#import <wtf/text/StringBuilder.h>
     
    7274SOFT_LINK(MediaAccessibility, MACaptionAppearanceAddSelectedLanguage, bool, (MACaptionAppearanceDomain domain, CFStringRef language), (domain, language));
    7375SOFT_LINK(MediaAccessibility, MACaptionAppearanceCopySelectedLanguages, CFArrayRef, (MACaptionAppearanceDomain domain), (domain));
     76SOFT_LINK(MediaAccessibility, MACaptionAppearanceCopyPreferredCaptioningMediaCharacteristics,  CFArrayRef, (MACaptionAppearanceDomain domain), (domain));
    7477
    7578SOFT_LINK_POINTER(MediaAccessibility, kMAXCaptionAppearanceSettingsChangedNotification, CFStringRef)
     
    112115
    113116#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
     117
     118bool CaptionUserPreferencesMac::shouldShowCaptions() const
     119{
     120    if (testingMode() || !MediaAccessibilityLibrary())
     121        return CaptionUserPreferences::shouldShowCaptions();
     122
     123    return MACaptionAppearanceGetShowCaptions(kMACaptionAppearanceDomainUser);
     124}
     125
     126void CaptionUserPreferencesMac::setShouldShowCaptions(bool preference)
     127{
     128    if (testingMode() || !MediaAccessibilityLibrary()) {
     129        CaptionUserPreferences::setShouldShowCaptions(preference);
     130        return;
     131    }
     132
     133    MACaptionAppearanceSetShowCaptions(kMACaptionAppearanceDomainUser, preference);
     134}
     135
    114136bool CaptionUserPreferencesMac::userPrefersCaptions() const
    115137{
    116     if (testingMode() || !MediaAccessibilityLibrary())
    117         return CaptionUserPreferences::userPrefersCaptions();
    118 
    119     return MACaptionAppearanceGetShowCaptions(kMACaptionAppearanceDomainUser);
    120 }
    121 
    122 void CaptionUserPreferencesMac::setUserPrefersCaptions(bool preference)
    123 {
    124     if (testingMode() || !MediaAccessibilityLibrary()) {
    125         CaptionUserPreferences::setUserPrefersCaptions(preference);
    126         return;
    127     }
    128 
    129     MACaptionAppearanceSetShowCaptions(kMACaptionAppearanceDomainUser, preference);
     138    bool captionSetting = CaptionUserPreferences::userPrefersCaptions();
     139    if (captionSetting || testingMode() || !MediaAccessibilityLibrary())
     140        return captionSetting;
     141   
     142    RetainPtr<CFArrayRef> captioningMediaCharacteristics(AdoptCF, MACaptionAppearanceCopyPreferredCaptioningMediaCharacteristics(kMACaptionAppearanceDomainUser));
     143    return captioningMediaCharacteristics && CFArrayGetCount(captioningMediaCharacteristics.get());
     144}
     145
     146bool CaptionUserPreferencesMac::userPrefersSubtitles() const
     147{
     148    bool subtitlesSetting = CaptionUserPreferences::userPrefersSubtitles();
     149    if (subtitlesSetting || testingMode() || !MediaAccessibilityLibrary())
     150        return subtitlesSetting;
     151   
     152    RetainPtr<CFArrayRef> captioningMediaCharacteristics(AdoptCF, MACaptionAppearanceCopyPreferredCaptioningMediaCharacteristics(kMACaptionAppearanceDomainUser));
     153    return !(captioningMediaCharacteristics && CFArrayGetCount(captioningMediaCharacteristics.get()));
    130154}
    131155
     
    500524    return userPreferredLanguages;
    501525}
    502 #endif
     526#endif  // HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
     527   
     528static String trackDisplayName(TextTrack* track)
     529{
     530    StringBuilder displayName;
     531    String label = track->label();
     532    String trackLanguageIdentifier = track->language();
     533
     534    RetainPtr<CFLocaleRef> currentLocale(AdoptCF, CFLocaleCopyCurrent());
     535    RetainPtr<CFStringRef> localeIdentifier(AdoptCF, CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorDefault, trackLanguageIdentifier.createCFString().get()));
     536    RetainPtr<CFStringRef> languageCF(AdoptCF, CFLocaleCopyDisplayNameForPropertyValue(currentLocale.get(), kCFLocaleLanguageCode, localeIdentifier.get()));
     537    String language = languageCF.get();
     538    if (!label.isEmpty()) {
     539        if (!language.isEmpty() && !label.contains(language)) {
     540            RetainPtr<CFDictionaryRef> localeDict(AdoptCF, CFLocaleCreateComponentsFromLocaleIdentifier(kCFAllocatorDefault, localeIdentifier.get()));
     541            if (localeDict) {
     542                CFStringRef countryCode = 0;
     543                String countryName;
     544               
     545                CFDictionaryGetValueIfPresent(localeDict.get(), kCFLocaleCountryCode, (const void **)&countryCode);
     546                if (countryCode) {
     547                    RetainPtr<CFStringRef> countryNameCF(AdoptCF, CFLocaleCopyDisplayNameForPropertyValue(currentLocale.get(), kCFLocaleCountryCode, countryCode));
     548                    countryName = countryNameCF.get();
     549                }
     550               
     551                if (!countryName.isEmpty())
     552                    displayName.append(textTrackCountryAndLanguageMenuItemText(label, countryName, language));
     553                else
     554                    displayName.append(textTrackLanguageMenuItemText(label, language));
     555            }
     556        }
     557    } else {
     558        String languageAndLocale = CFLocaleCopyDisplayNameForPropertyValue(currentLocale.get(), kCFLocaleIdentifier, trackLanguageIdentifier.createCFString().get());
     559        if (!languageAndLocale.isEmpty())
     560            displayName.append(languageAndLocale);
     561        else if (!language.isEmpty())
     562            displayName.append(language);
     563        else
     564            displayName.append(localeIdentifier.get());
     565    }
     566   
     567    if (displayName.isEmpty())
     568        displayName.append(textTrackNoLabelText());
     569   
     570    if (track->isEasyToRead())
     571        return easyReaderTrackMenuItemText(displayName.toString());
     572   
     573    if (track->kind() != track->captionsKeyword())
     574        return displayName.toString();
     575   
     576    if (track->isClosedCaptions())
     577        return closedCaptionTrackMenuItemText(displayName.toString());
     578   
     579    return sdhTrackMenuItemText(displayName.toString());
     580}
    503581
    504582String CaptionUserPreferencesMac::displayNameForTrack(TextTrack* track) const
    505583{
    506     String label = track->label();
    507     String language = track->language();
    508     String preferredLanguage = defaultLanguage();
    509     StringBuilder displayName;
    510 
    511     if (label.isEmpty() && language.isEmpty()) {
    512         displayName.append(textTrackNoLabelText());
    513         return displayName.toString();
    514     }
    515 
    516     if (!label.isEmpty())
    517         displayName.append(label);
    518 
    519     AtomicString localeDisplayName = displayNameForLanguageLocale(language);
    520     if (!label.contains(localeDisplayName)) {
    521         if (displayName.length() > 0)
    522             displayName.append(" ");
    523         displayName.append(localeDisplayName);
    524     }
    525 
    526     if (track->kind() == track->captionsKeyword()) {
    527         if (track->isClosedCaptions())
    528             displayName.append(" CC");
    529         else
    530             displayName.append(" SDH");
    531     }
    532 
    533     return displayName.toString();
    534 }
    535 
     584    return trackDisplayName(track);
     585}
     586
     587static String languageIdentifier(const String& languageCode)
     588{
     589    if (languageCode.isEmpty())
     590        return languageCode;
     591
     592    String lowercaseLanguageCode = languageCode.lower();
     593   
     594    if (lowercaseLanguageCode.length() >= 3 && (lowercaseLanguageCode[2] == '_' || lowercaseLanguageCode[2] == '-'))
     595        lowercaseLanguageCode.truncate(2);
     596   
     597    return lowercaseLanguageCode;
     598}
     599
     600static bool textTrackCompare(const RefPtr<TextTrack>& a, const RefPtr<TextTrack>& b)
     601{
     602    String preferredLanguageDisplayName = displayNameForLanguageLocale(languageIdentifier(defaultLanguage()));
     603    String aLanguageDisplayName = displayNameForLanguageLocale(languageIdentifier(a->language()));
     604    String bLanguageDisplayName = displayNameForLanguageLocale(languageIdentifier(b->language()));
     605
     606    // Tracks in the user's preferred language are always at the top of the menu.
     607    bool aIsPreferredLanguage = !codePointCompare(aLanguageDisplayName, preferredLanguageDisplayName);
     608    bool bIsPreferredLanguage = !codePointCompare(bLanguageDisplayName, preferredLanguageDisplayName);
     609    if ((aIsPreferredLanguage || bIsPreferredLanguage) && (aIsPreferredLanguage != bIsPreferredLanguage))
     610        return aIsPreferredLanguage;
     611
     612    // Tracks not in the user's preferred language sort first by language ...
     613    if (codePointCompare(aLanguageDisplayName, bLanguageDisplayName))
     614        return codePointCompare(aLanguageDisplayName, bLanguageDisplayName) < 0;
     615
     616    // ... but when tracks have the same language, main program content sorts next highest ...
     617    bool aIsMainContent = a->isMainProgramContent();
     618    bool bIsMainContent = b->isMainProgramContent();
     619    if ((aIsMainContent || bIsMainContent) && (aIsMainContent != bIsMainContent))
     620        return aIsMainContent;
     621
     622    // ... and main program trakcs sort higher than CC tracks ...
     623    bool aIsCC = a->isClosedCaptions();
     624    bool bIsCC = b->isClosedCaptions();
     625    if ((aIsCC || bIsCC) && (aIsCC != bIsCC)) {
     626        if (aIsCC)
     627            return aIsMainContent;
     628        return bIsMainContent;
     629    }
     630
     631    // ... and tracks of the same type and language sort by the menu item text.
     632    return codePointCompare(trackDisplayName(a.get()), trackDisplayName(b.get())) < 0;
     633}
     634
     635Vector<RefPtr<TextTrack> > CaptionUserPreferencesMac::sortedTrackListForMenu(TextTrackList* trackList)
     636{
     637    ASSERT(trackList);
     638
     639    Vector<RefPtr<TextTrack> > tracksForMenu;
     640    HashSet<String> languagesIncluded;
     641    bool prefersAccessibilityTracks = userPrefersCaptions();
     642
     643    for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
     644        TextTrack* track = trackList->item(i);
     645        String language = displayNameForLanguageLocale(track->language());
     646
     647        if (track->isEasyToRead()) {
     648            if (!language.isEmpty())
     649                languagesIncluded.add(language);
     650            tracksForMenu.append(track);
     651            continue;
     652        }
     653
     654        if (track->containsOnlyForcedSubtitles())
     655            continue;
     656
     657        if (!language.isEmpty() && track->isMainProgramContent()) {
     658            bool isAccessibilityTrack = track->kind() == track->captionsKeyword();
     659            if (prefersAccessibilityTracks) {
     660                // In the first pass, include only caption tracks if the user prefers accessibility tracks.
     661                if (!isAccessibilityTrack) {
     662                    LOG(Media, "CaptionUserPreferencesMac::sortedTrackListForMenu - skipping %s because it is NOT an accessibility track", language.utf8().data());
     663                    continue;
     664                }
     665            } else {
     666                // In the first pass, only include the first non-CC or SDH track with each language if the user prefers translation tracks.
     667                if (isAccessibilityTrack) {
     668                    LOG(Media, "CaptionUserPreferencesMac::sortedTrackListForMenu - skipping %s because it is an accessibility track", language.utf8().data());
     669                    continue;
     670                }
     671                if (languagesIncluded.contains(language)) {
     672                    LOG(Media, "CaptionUserPreferencesMac::sortedTrackListForMenu - skipping %s because it is not the first with this language", language.utf8().data());
     673                    continue;
     674                }
     675            }
     676        }
     677
     678        if (!language.isEmpty())
     679            languagesIncluded.add(language);
     680        tracksForMenu.append(track);
     681    }
     682
     683    // Now that we have filtered for the user's accessibility/translation preference, add  all tracks with a unique language without regard to track type.
     684    for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
     685        TextTrack* track = trackList->item(i);
     686        String language = displayNameForLanguageLocale(track->language());
     687
     688        // All candidates with no languge were added the first time through.
     689        if (language.isEmpty())
     690            continue;
     691
     692        if (track->containsOnlyForcedSubtitles())
     693            continue;
     694 
     695        if (!languagesIncluded.contains(language) && track->isMainProgramContent()) {
     696            languagesIncluded.add(language);
     697            tracksForMenu.append(track);
     698        }
     699    }
     700
     701    nonCopyingSort(tracksForMenu.begin(), tracksForMenu.end(), textTrackCompare);
     702
     703    return tracksForMenu;
     704}
     705   
    536706}
    537707
  • trunk/Source/WebCore/platform/Language.cpp

    r142580 r146380  
    155155{
    156156#if PLATFORM(MAC)
    157     if (!localeName.isNull() && !localeName.isEmpty())
    158         return CFLocaleCopyDisplayNameForPropertyValue(CFLocaleCopyCurrent(), kCFLocaleIdentifier, localeName.createCFString().get());
     157    if (!localeName.isNull() && !localeName.isEmpty()) {
     158        RetainPtr<CFLocaleRef> currentLocale(AdoptCF, CFLocaleCopyCurrent());
     159        return CFLocaleCopyDisplayNameForPropertyValue(currentLocale.get(), kCFLocaleIdentifier, localeName.createCFString().get());
     160    }
    159161#endif
    160162    return localeName;
  • trunk/Source/WebCore/platform/LocalizedStrings.cpp

    r143232 r146380  
    10281028String textTrackNoLabelText()
    10291029{
    1030     return WEB_UI_STRING_KEY("Unknown", "Unknown (closed captions track)", "Menu item label for a closed captions track that has no other name");
    1031 }
     1030    return WEB_UI_STRING_KEY("Unknown", "Unknown (text track)", "Menu item label for a text track that has no other name");
     1031}
     1032   
     1033#if PLATFORM(MAC)
     1034String textTrackCountryAndLanguageMenuItemText(const String& title, const String& country, const String& language)
     1035{
     1036    return formatLocalizedString(WEB_UI_STRING("%@ (%@-%@)", "Text track display name format that includes the country and language of the subtitle, in the form of 'Title (Language-Country)'"), title.createCFString().get(), language.createCFString().get(), country.createCFString().get());
     1037}
     1038
     1039String textTrackLanguageMenuItemText(const String& title, const String& language)
     1040{
     1041    return formatLocalizedString(WEB_UI_STRING("%@ (%@)", "Text track display name format that includes the language of the subtitle, in the form of 'Title (Language)'"), title.createCFString().get(), language.createCFString().get());
     1042}
     1043
     1044String closedCaptionTrackMenuItemText(const String& title)
     1045{
     1046    return formatLocalizedString(WEB_UI_STRING("%@ CC", "Text track contains closed captions"), title.createCFString().get());
     1047}
     1048
     1049String sdhTrackMenuItemText(const String& title)
     1050{
     1051    return formatLocalizedString(WEB_UI_STRING("%@ SDH", "Text track contains subtitles for the deaf and hard of hearing"), title.createCFString().get());
     1052}
     1053
     1054String easyReaderTrackMenuItemText(const String& title)
     1055{
     1056    return formatLocalizedString(WEB_UI_STRING("%@ Easy Reader", "Text track contains simplified (3rd grade level) subtitles"), title.createCFString().get());
     1057}
     1058#endif
     1059
    10321060#endif
    10331061
  • trunk/Source/WebCore/platform/LocalizedStrings.h

    r142507 r146380  
    269269    String textTrackOffText();
    270270    String textTrackNoLabelText();
     271#if PLATFORM(MAC)
     272    String textTrackCountryAndLanguageMenuItemText(const String& title, const String& country, const String& language);
     273    String textTrackLanguageMenuItemText(const String& title, const String& language);
     274    String closedCaptionTrackMenuItemText(const String&);
     275    String sdhTrackMenuItemText(const String&);
     276    String easyReaderTrackMenuItemText(const String&);
     277#endif
    271278#endif
    272279
  • trunk/Source/WebCore/platform/graphics/InbandTextTrackPrivate.h

    r141957 r146380  
    5757    virtual Kind kind() const { return Subtitles; }
    5858    virtual bool isClosedCaptions() const { return false; }
     59    virtual bool containsOnlyForcedSubtitles() const { return false; }
     60    virtual bool isMainProgramContent() const { return true; }
     61    virtual bool isEasyToRead() const { return false; }
    5962
    6063    virtual AtomicString label() const { return emptyAtom; }
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.h

    r141957 r146380  
    5050    virtual InbandTextTrackPrivate::Kind kind() const OVERRIDE;
    5151    virtual bool isClosedCaptions() const OVERRIDE;
     52    virtual bool containsOnlyForcedSubtitles() const OVERRIDE;
     53    virtual bool isMainProgramContent() const OVERRIDE;
     54    virtual bool isEasyToRead() const OVERRIDE;
    5255    virtual AtomicString label() const OVERRIDE;
    5356    virtual AtomicString language() const OVERRIDE;
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.mm

    r141957 r146380  
    5353#define AVMediaCharacteristicAudible getAVMediaCharacteristicAudible()
    5454#define AVMediaTypeClosedCaption getAVMediaTypeClosedCaption()
    55 #define AVMediaTypeVideo getAVMediaTypeVideo()
    56 #define AVMediaTypeAudio getAVMediaTypeAudio()
     55#define AVMediaCharacteristicContainsOnlyForcedSubtitles getAVMediaCharacteristicContainsOnlyForcedSubtitles()
     56#define AVMediaCharacteristicIsMainProgramContent getAVMediaCharacteristicIsMainProgramContent()
     57#define AVMediaCharacteristicEasyToRead getAVMediaCharacteristicEasyToRead()
    5758
    5859SOFT_LINK_POINTER(AVFoundation, AVMediaTypeClosedCaption, NSString *)
     
    6364SOFT_LINK_POINTER(AVFoundation, AVMediaCharacteristicTranscribesSpokenDialogForAccessibility, NSString *)
    6465SOFT_LINK_POINTER(AVFoundation, AVMediaCharacteristicDescribesMusicAndSoundForAccessibility, NSString *)
     66SOFT_LINK_POINTER(AVFoundation, AVMediaCharacteristicContainsOnlyForcedSubtitles, NSString *)
     67SOFT_LINK_POINTER(AVFoundation, AVMediaCharacteristicIsMainProgramContent, NSString *)
     68SOFT_LINK_POINTER(AVFoundation, AVMediaCharacteristicEasyToRead, NSString *)
     69
    6570#define AVMetadataItem getAVMetadataItemClass()
    6671#define AVPlayerItemLegibleOutput getAVPlayerItemLegibleOutputClass()
     
    120125}
    121126
     127bool InbandTextTrackPrivateAVFObjC::containsOnlyForcedSubtitles() const
     128{
     129    if (!m_mediaSelectionOption)
     130        return false;
     131   
     132    return [m_mediaSelectionOption hasMediaCharacteristic:AVMediaCharacteristicContainsOnlyForcedSubtitles];
     133}
     134
     135bool InbandTextTrackPrivateAVFObjC::isMainProgramContent() const
     136{
     137    if (!m_mediaSelectionOption)
     138        return false;
     139   
     140    return [m_mediaSelectionOption hasMediaCharacteristic:AVMediaCharacteristicIsMainProgramContent];
     141}
     142
     143bool InbandTextTrackPrivateAVFObjC::isEasyToRead() const
     144{
     145    if (!m_mediaSelectionOption)
     146        return false;
     147
     148    return [m_mediaSelectionOption hasMediaCharacteristic:AVMediaCharacteristicEasyToRead];
     149}
     150
    122151AtomicString InbandTextTrackPrivateAVFObjC::label() const
    123152{
  • trunk/Source/WebCore/testing/InternalSettings.cpp

    r145750 r146380  
    2828#include "InternalSettings.h"
    2929
     30#include "CaptionUserPreferences.h"
    3031#include "Document.h"
    3132#include "ExceptionCode.h"
     
    3536#include "LocaleToScriptMapping.h"
    3637#include "Page.h"
     38#include "PageGroup.h"
    3739#include "RuntimeEnabledFeatures.h"
    3840#include "Settings.h"
     
    427429
    428430#if ENABLE(VIDEO_TRACK)
     431    if (!page())
     432        return;
     433    CaptionUserPreferences* captionPreferences = page()->group().captionPreferences();
     434
    429435    if (equalIgnoringCase(kind, "Subtitles"))
    430         settings()->setShouldDisplaySubtitles(enabled);
     436        captionPreferences->setUserPrefersSubtitles(enabled);
    431437    else if (equalIgnoringCase(kind, "Captions"))
    432         settings()->setShouldDisplayCaptions(enabled);
     438        captionPreferences->setUserPrefersCaptions(enabled);
    433439    else if (equalIgnoringCase(kind, "TextDescriptions"))
    434         settings()->setShouldDisplayTextDescriptions(enabled);
     440        captionPreferences->setUserPrefersTextDescriptions(enabled);
    435441    else
    436442        ec = SYNTAX_ERR;
     
    446452
    447453#if ENABLE(VIDEO_TRACK)
     454    if (!page())
     455        return false;
     456    CaptionUserPreferences* captionPreferences = page()->group().captionPreferences();
     457
    448458    if (equalIgnoringCase(kind, "Subtitles"))
    449         return settings()->shouldDisplaySubtitles();
     459        return captionPreferences->userPrefersSubtitles();
    450460    if (equalIgnoringCase(kind, "Captions"))
    451         return settings()->shouldDisplayCaptions();
     461        return captionPreferences->userPrefersCaptions();
    452462    if (equalIgnoringCase(kind, "TextDescriptions"))
    453         return settings()->shouldDisplayTextDescriptions();
     463        return captionPreferences->userPrefersTextDescriptions();
    454464
    455465    ec = SYNTAX_ERR;
  • trunk/Source/WebKit/ChangeLog

    r146367 r146380  
     12013-03-20  Eric Carlson  <eric.carlson@apple.com>
     2
     3        Allow ports specific text track menu
     4        https://bugs.webkit.org/show_bug.cgi?id=112800
     5
     6        Reviewed by Dean Jackson.
     7
     8        * WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in: Add new exports.
     9        * win/WebKit.vcproj/WebKitExports.def.in: Ditto.
     10
    1112013-03-20  Roger Fong  <roger_fong@apple.com>
    212
  • trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in

    r146367 r146380  
    417417        ?setAcceleratedCompositingEnabled@Settings@WebCore@@QAEX_N@Z
    418418        ?setAutofilled@HTMLInputElement@WebCore@@QAEX_N@Z
     419        ?captionPreferences@PageGroup@WebCore@@QAEPAVCaptionUserPreferences@2@XZ
     420        ?initGroup@Page@WebCore@@AAEXXZ
    419421
    420422#if ENABLE(WORKERS)
  • trunk/Source/WebKit/win/WebKit.vcproj/WebKitExports.def.in

    r146361 r146380  
    417417        ?setAcceleratedCompositingEnabled@Settings@WebCore@@QAEX_N@Z
    418418        ?setAutofilled@HTMLInputElement@WebCore@@QAEX_N@Z
     419        ?captionPreferences@PageGroup@WebCore@@QAEPAVCaptionUserPreferences@2@XZ
     420        ?initGroup@Page@WebCore@@AAEXXZ
    419421
    420422#if ENABLE(WORKERS)
Note: See TracChangeset for help on using the changeset viewer.