Changeset 273191 in webkit


Ignore:
Timestamp:
Feb 19, 2021 9:29:42 PM (3 years ago)
Author:
Devin Rousso
Message:

Allow track lists other than Subtitles/Captions/Descriptions to be sorted
https://bugs.webkit.org/show_bug.cgi?id=222207
<rdar://problem/74539660>

Reviewed by Eric Carlson.

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

(WebCore::CaptionUserPreferences::sortedTrackListForMenu):

  • page/CaptionUserPreferencesMediaAF.h:
  • platform/cocoa/PlaybackSessionModelMediaElement.mm:

(WebCore::PlaybackSessionModelMediaElement::updateMediaSelectionOptions):

  • page/CaptionUserPreferencesMediaAF.cpp:

(WebCore::CaptionUserPreferencesMediaAF::sortedTrackListForMenu):

  • Modules/modern-media-controls/media/overflow-support.js:

(OverflowSupport.prototype.get tracksToMonitor):

  • Modules/mediacontrols/MediaControlsHost.cpp:

(WebCore::MediaControlsHost::sortedTrackListForMenu):
(WebCore::MediaControlsHost::showMediaControlsContextMenu):

Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r273185 r273191  
     12021-02-19  Devin Rousso  <drousso@apple.com>
     2
     3        Allow track lists other than Subtitles/Captions/Descriptions to be sorted
     4        https://bugs.webkit.org/show_bug.cgi?id=222207
     5        <rdar://problem/74539660>
     6
     7        Reviewed by Eric Carlson.
     8
     9        * html/track/TextTrac.h:
     10        * page/CaptionUserPreferences.h:
     11        * page/CaptionUserPreferences.cpp:
     12        (WebCore::CaptionUserPreferences::sortedTrackListForMenu):
     13        * page/CaptionUserPreferencesMediaAF.h:
     14        * platform/cocoa/PlaybackSessionModelMediaElement.mm:
     15        (WebCore::PlaybackSessionModelMediaElement::updateMediaSelectionOptions):
     16        * page/CaptionUserPreferencesMediaAF.cpp:
     17        (WebCore::CaptionUserPreferencesMediaAF::sortedTrackListForMenu):
     18
     19        * Modules/modern-media-controls/media/overflow-support.js:
     20        (OverflowSupport.prototype.get tracksToMonitor):
     21        * Modules/mediacontrols/MediaControlsHost.cpp:
     22        (WebCore::MediaControlsHost::sortedTrackListForMenu):
     23        (WebCore::MediaControlsHost::showMediaControlsContextMenu):
     24
    1252021-02-19  Patrick Angle  <pangle@apple.com>
    226
  • trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.cpp

    r273024 r273191  
    5252#include <wtf/Variant.h>
    5353
    54 namespace WebCore {
    55 
    5654#if USE(APPLE_INTERNAL_SDK)
    5755#include <WebKitAdditions/MediaControlsHostAdditions.cpp>
     56#endif
     57
     58namespace WebCore {
     59
     60#if defined(MediaControlsHostAdditions_members)
     61MediaControlsHostAdditions_members
    5862#endif
    5963
     
    109113        return { };
    110114
    111     return page->group().captionPreferences().sortedTrackListForMenu(&trackList);
     115    return page->group().captionPreferences().sortedTrackListForMenu(&trackList, { TextTrack::Kind::Subtitles, TextTrack::Kind::Captions, TextTrack::Kind::Descriptions });
    112116}
    113117
     
    403407
    404408            auto& captionPreferences = page->group().captionPreferences();
    405             auto sortedTextTracks = captionPreferences.sortedTrackListForMenu(textTracks);
     409            auto sortedTextTracks = captionPreferences.sortedTrackListForMenu(textTracks, { TextTrack::Kind::Subtitles, TextTrack::Kind::Captions, TextTrack::Kind::Descriptions });
    406410            bool allTracksDisabled = notFound == sortedTextTracks.findMatching([] (const auto& textTrack) {
    407411                return textTrack->mode() == TextTrack::Mode::Showing;
  • trunk/Source/WebCore/Modules/modern-media-controls/media/overflow-support.js

    r273024 r273191  
    3636    }
    3737
     38    get tracksToMonitor()
     39    {
     40        let tracksToMonitor = [];
     41        window["WebKitAdditions.OverflowSupport.prototype.get_tracksToMonitor"]?.(this, tracksToMonitor);
     42        return tracksToMonitor;
     43    }
     44
    3845    get control()
    3946    {
  • trunk/Source/WebCore/html/track/TextTrack.h

    r262695 r273191  
    234234};
    235235
    236 };
     236template<> struct DefaultHash<WebCore::TextTrack::Kind> : IntHash<WebCore::TextTrack::Kind> { };
     237template<> struct HashTraits<WebCore::TextTrack::Kind> : StrongEnumHashTraits<WebCore::TextTrack::Kind> { };
     238
     239} // namespace WTF
    237240
    238241SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::TextTrack)
  • trunk/Source/WebCore/page/CaptionUserPreferences.cpp

    r271153 r273191  
    226226}
    227227   
    228 Vector<RefPtr<TextTrack>> CaptionUserPreferences::sortedTrackListForMenu(TextTrackList* trackList)
     228Vector<RefPtr<TextTrack>> CaptionUserPreferences::sortedTrackListForMenu(TextTrackList* trackList, HashSet<TextTrack::Kind> kinds)
    229229{
    230230    ASSERT(trackList);
     
    234234    for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
    235235        TextTrack* track = trackList->item(i);
    236         auto kind = track->kind();
    237         if (kind == TextTrack::Kind::Captions || kind == TextTrack::Kind::Descriptions || kind == TextTrack::Kind::Subtitles)
     236        if (kinds.contains(track->kind()))
    238237            tracksForMenu.append(track);
    239238    }
     
    243242    });
    244243
    245     tracksForMenu.insert(0, &TextTrack::captionMenuOffItem());
    246     tracksForMenu.insert(1, &TextTrack::captionMenuAutomaticItem());
     244    if (kinds.contains(TextTrack::Kind::Subtitles) || kinds.contains(TextTrack::Kind::Captions) || kinds.contains(TextTrack::Kind::Descriptions)) {
     245        tracksForMenu.insert(0, &TextTrack::captionMenuOffItem());
     246        tracksForMenu.insert(1, &TextTrack::captionMenuAutomaticItem());
     247    }
    247248
    248249    return tracksForMenu;
  • trunk/Source/WebCore/page/CaptionUserPreferences.h

    r262695 r273191  
    3131#include "TextTrack.h"
    3232#include "Timer.h"
     33#include <wtf/HashSet.h>
    3334
    3435namespace WebCore {
     
    8687    virtual String displayNameForTrack(TextTrack*) const;
    8788    MediaSelectionOption mediaSelectionOptionForTrack(TextTrack*) const;
    88     virtual Vector<RefPtr<TextTrack>> sortedTrackListForMenu(TextTrackList*);
     89    virtual Vector<RefPtr<TextTrack>> sortedTrackListForMenu(TextTrackList*, HashSet<TextTrack::Kind>);
    8990
    9091    virtual String displayNameForTrack(AudioTrack*) const;
  • trunk/Source/WebCore/page/CaptionUserPreferencesMediaAF.cpp

    r264585 r273191  
    780780}
    781781
    782 Vector<RefPtr<TextTrack>> CaptionUserPreferencesMediaAF::sortedTrackListForMenu(TextTrackList* trackList)
     782Vector<RefPtr<TextTrack>> CaptionUserPreferencesMediaAF::sortedTrackListForMenu(TextTrackList* trackList, HashSet<TextTrack::Kind> kinds)
    783783{
    784784    ASSERT(trackList);
     
    789789    bool prefersAccessibilityTracks = userPrefersCaptions();
    790790    bool filterTrackList = shouldFilterTrackMenu();
     791    bool requestingCaptionsOrDescriptionsOrSubtitles = kinds.contains(TextTrack::Kind::Subtitles) || kinds.contains(TextTrack::Kind::Captions) || kinds.contains(TextTrack::Kind::Descriptions);
    791792
    792793    for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
     
    800801        }
    801802
    802         auto kind = track->kind();
    803         if (kind != TextTrack::Kind::Captions && kind != TextTrack::Kind::Descriptions && kind != TextTrack::Kind::Subtitles)
     803        if (!kinds.contains(track->kind()))
    804804            continue;
    805805
    806         if (track->containsOnlyForcedSubtitles()) {
    807             LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - skipping '%s' track with language '%s' because it contains only forced subtitles", track->kindKeyword().string().utf8().data(), language.utf8().data());
    808             continue;
    809         }
    810        
    811         if (track->isEasyToRead()) {
    812             LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s' because it is 'easy to read'", track->kindKeyword().string().utf8().data(), language.utf8().data());
     806        if (requestingCaptionsOrDescriptionsOrSubtitles) {
     807            if (track->containsOnlyForcedSubtitles()) {
     808                LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - skipping '%s' track with language '%s' because it contains only forced subtitles", track->kindKeyword().string().utf8().data(), language.utf8().data());
     809                continue;
     810            }
     811
     812            if (track->isEasyToRead()) {
     813                LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s' because it is 'easy to read'", track->kindKeyword().string().utf8().data(), language.utf8().data());
     814                if (!language.isEmpty())
     815                    languagesIncluded.add(language);
     816                tracksForMenu.append(track);
     817                continue;
     818            }
     819
     820            if (track->mode() == TextTrack::Mode::Showing) {
     821                LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s' because it is already visible", track->kindKeyword().string().utf8().data(), language.utf8().data());
     822                if (!language.isEmpty())
     823                    languagesIncluded.add(language);
     824                tracksForMenu.append(track);
     825                continue;
     826            }
     827
     828            if (!language.isEmpty() && track->isMainProgramContent()) {
     829                bool isAccessibilityTrack = track->kind() == TextTrack::Kind::Captions;
     830                if (prefersAccessibilityTracks) {
     831                    // In the first pass, include only caption tracks if the user prefers accessibility tracks.
     832                    if (!isAccessibilityTrack && filterTrackList) {
     833                        LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - skipping '%s' track with language '%s' because it is NOT an accessibility track", track->kindKeyword().string().utf8().data(), language.utf8().data());
     834                        continue;
     835                    }
     836                } else {
     837                    // In the first pass, only include the first non-CC or SDH track with each language if the user prefers translation tracks.
     838                    if (isAccessibilityTrack && filterTrackList) {
     839                        LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - skipping '%s' track with language '%s' because it is an accessibility track", track->kindKeyword().string().utf8().data(), language.utf8().data());
     840                        continue;
     841                    }
     842                    if (languagesIncluded.contains(language) && filterTrackList) {
     843                        LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - skipping '%s' track with language '%s' because it is not the first with this language", track->kindKeyword().string().utf8().data(), language.utf8().data());
     844                        continue;
     845                    }
     846                }
     847            }
     848
    813849            if (!language.isEmpty())
    814850                languagesIncluded.add(language);
    815             tracksForMenu.append(track);
    816             continue;
    817851        }
    818852
    819         if (track->mode() == TextTrack::Mode::Showing) {
    820             LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s' because it is already visible", track->kindKeyword().string().utf8().data(), language.utf8().data());
    821             if (!language.isEmpty())
     853        tracksForMenu.append(track);
     854
     855        LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s', is%s main program content", track->kindKeyword().string().utf8().data(), language.utf8().data(), track->isMainProgramContent() ? "" : " NOT");
     856    }
     857
     858    if (requestingCaptionsOrDescriptionsOrSubtitles) {
     859        // Now that we have filtered for the user's accessibility/translation preference, add  all tracks with a unique language without regard to track type.
     860        for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
     861            TextTrack* track = trackList->item(i);
     862            String language = displayNameForLanguageLocale(track->language());
     863
     864            if (tracksForMenu.contains(track))
     865                continue;
     866
     867            if (!kinds.contains(track->kind()))
     868                continue;
     869
     870            // All candidates with no languge were added the first time through.
     871            if (language.isEmpty())
     872                continue;
     873
     874            if (track->containsOnlyForcedSubtitles())
     875                continue;
     876
     877            if (!languagesIncluded.contains(language) && track->isMainProgramContent()) {
    822878                languagesIncluded.add(language);
    823             tracksForMenu.append(track);
    824             continue;
    825         }
    826 
    827         if (!language.isEmpty() && track->isMainProgramContent()) {
    828             bool isAccessibilityTrack = track->kind() == TextTrack::Kind::Captions;
    829             if (prefersAccessibilityTracks) {
    830                 // In the first pass, include only caption tracks if the user prefers accessibility tracks.
    831                 if (!isAccessibilityTrack && filterTrackList) {
    832                     LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - skipping '%s' track with language '%s' because it is NOT an accessibility track", track->kindKeyword().string().utf8().data(), language.utf8().data());
    833                     continue;
    834                 }
    835             } else {
    836                 // In the first pass, only include the first non-CC or SDH track with each language if the user prefers translation tracks.
    837                 if (isAccessibilityTrack && filterTrackList) {
    838                     LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - skipping '%s' track with language '%s' because it is an accessibility track", track->kindKeyword().string().utf8().data(), language.utf8().data());
    839                     continue;
    840                 }
    841                 if (languagesIncluded.contains(language) && filterTrackList) {
    842                     LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - skipping '%s' track with language '%s' because it is not the first with this language", track->kindKeyword().string().utf8().data(), language.utf8().data());
    843                     continue;
    844                 }
     879                tracksForMenu.append(track);
     880                LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s' because it is the only track with this language", track->kindKeyword().string().utf8().data(), language.utf8().data());
    845881            }
    846882        }
    847 
    848         if (!language.isEmpty())
    849             languagesIncluded.add(language);
    850         tracksForMenu.append(track);
    851 
    852         LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s', is%s main program content", track->kindKeyword().string().utf8().data(), language.utf8().data(), track->isMainProgramContent() ? "" : " NOT");
    853     }
    854 
    855     // Now that we have filtered for the user's accessibility/translation preference, add  all tracks with a unique language without regard to track type.
    856     for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
    857         TextTrack* track = trackList->item(i);
    858         String language = displayNameForLanguageLocale(track->language());
    859 
    860         if (tracksForMenu.contains(track))
    861             continue;
    862 
    863         auto kind = track->kind();
    864         if (kind != TextTrack::Kind::Captions && kind != TextTrack::Kind::Descriptions && kind != TextTrack::Kind::Subtitles)
    865             continue;
    866 
    867         // All candidates with no languge were added the first time through.
    868         if (language.isEmpty())
    869             continue;
    870 
    871         if (track->containsOnlyForcedSubtitles())
    872             continue;
    873 
    874         if (!languagesIncluded.contains(language) && track->isMainProgramContent()) {
    875             languagesIncluded.add(language);
    876             tracksForMenu.append(track);
    877             LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s' because it is the only track with this language", track->kindKeyword().string().utf8().data(), language.utf8().data());
    878         }
    879883    }
    880884
     
    884888    std::sort(tracksForMenu.begin(), tracksForMenu.end(), textTrackCompare);
    885889
    886     tracksForMenu.insert(0, &TextTrack::captionMenuOffItem());
    887     tracksForMenu.insert(1, &TextTrack::captionMenuAutomaticItem());
     890    if (requestingCaptionsOrDescriptionsOrSubtitles) {
     891        tracksForMenu.insert(0, &TextTrack::captionMenuOffItem());
     892        tracksForMenu.insert(1, &TextTrack::captionMenuAutomaticItem());
     893    }
    888894
    889895    return tracksForMenu;
  • trunk/Source/WebCore/page/CaptionUserPreferencesMediaAF.h

    r262695 r273191  
    6767    String captionsStyleSheetOverride() const override;
    6868    Vector<RefPtr<AudioTrack>> sortedTrackListForMenu(AudioTrackList*) override;
    69     Vector<RefPtr<TextTrack>> sortedTrackListForMenu(TextTrackList*) override;
     69    Vector<RefPtr<TextTrack>> sortedTrackListForMenu(TextTrackList*, HashSet<TextTrack::Kind>) override;
    7070    String displayNameForTrack(AudioTrack*) const override;
    7171    String displayNameForTrack(TextTrack*) const override;
  • trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm

    r272890 r273191  
    380380    auto* textTracks = m_mediaElement->textTracks();
    381381    if (textTracks && textTracks->length())
    382         m_legibleTracksForMenu = captionPreferences.sortedTrackListForMenu(textTracks);
     382        m_legibleTracksForMenu = captionPreferences.sortedTrackListForMenu(textTracks, { TextTrack::Kind::Subtitles, TextTrack::Kind::Captions, TextTrack::Kind::Descriptions });
    383383    else
    384384        m_legibleTracksForMenu.clear();
Note: See TracChangeset for help on using the changeset viewer.