diff options
Diffstat (limited to 'Source/WebCore/page/CaptionUserPreferences.cpp')
-rw-r--r-- | Source/WebCore/page/CaptionUserPreferences.cpp | 147 |
1 files changed, 104 insertions, 43 deletions
diff --git a/Source/WebCore/page/CaptionUserPreferences.cpp b/Source/WebCore/page/CaptionUserPreferences.cpp index adb570ea7..d2c391a5d 100644 --- a/Source/WebCore/page/CaptionUserPreferences.cpp +++ b/Source/WebCore/page/CaptionUserPreferences.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2013-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,25 +24,31 @@ */ #include "config.h" +#include "CaptionUserPreferences.h" #if ENABLE(VIDEO_TRACK) -#include "CaptionUserPreferences.h" +#include "AudioTrackList.h" #include "DOMWrapperWorld.h" #include "Page.h" #include "PageGroup.h" #include "Settings.h" #include "TextTrackList.h" +#include "UserContentController.h" +#include "UserContentTypes.h" +#include "UserStyleSheet.h" #include "UserStyleSheetTypes.h" +#include <heap/HeapInlines.h> +#include <runtime/JSCellInlines.h> +#include <runtime/StructureInlines.h> +#include <wtf/NeverDestroyed.h> namespace WebCore { CaptionUserPreferences::CaptionUserPreferences(PageGroup& group) : m_pageGroup(group) , m_displayMode(ForcedOnly) - , m_timer(this, &CaptionUserPreferences::timerFired) - , m_testingMode(false) - , m_havePreferences(false) + , m_timer(*this, &CaptionUserPreferences::timerFired) { } @@ -50,13 +56,27 @@ CaptionUserPreferences::~CaptionUserPreferences() { } -void CaptionUserPreferences::timerFired(Timer<CaptionUserPreferences>&) +void CaptionUserPreferences::timerFired() { captionPreferencesChanged(); } +void CaptionUserPreferences::beginBlockingNotifications() +{ + ++m_blockNotificationsCounter; +} + +void CaptionUserPreferences::endBlockingNotifications() +{ + ASSERT(m_blockNotificationsCounter); + --m_blockNotificationsCounter; +} + void CaptionUserPreferences::notify() { + if (m_blockNotificationsCounter) + return; + m_havePreferences = true; if (!m_timer.isActive()) m_timer.startOneShot(0); @@ -77,9 +97,17 @@ void CaptionUserPreferences::setCaptionDisplayMode(CaptionUserPreferences::Capti notify(); } +Page* CaptionUserPreferences::currentPage() const +{ + if (m_pageGroup.pages().isEmpty()) + return nullptr; + + return *(m_pageGroup.pages().begin()); +} + bool CaptionUserPreferences::userPrefersCaptions() const { - Page* page = *(m_pageGroup.pages().begin()); + Page* page = currentPage(); if (!page) return false; @@ -88,7 +116,7 @@ bool CaptionUserPreferences::userPrefersCaptions() const void CaptionUserPreferences::setUserPrefersCaptions(bool preference) { - Page* page = *(m_pageGroup.pages().begin()); + Page* page = currentPage(); if (!page) return; @@ -98,7 +126,7 @@ void CaptionUserPreferences::setUserPrefersCaptions(bool preference) bool CaptionUserPreferences::userPrefersSubtitles() const { - Page* page = *(pageGroup().pages().begin()); + Page* page = currentPage(); if (!page) return false; @@ -107,7 +135,7 @@ bool CaptionUserPreferences::userPrefersSubtitles() const void CaptionUserPreferences::setUserPrefersSubtitles(bool preference) { - Page* page = *(m_pageGroup.pages().begin()); + Page* page = currentPage(); if (!page) return; @@ -117,7 +145,7 @@ void CaptionUserPreferences::setUserPrefersSubtitles(bool preference) bool CaptionUserPreferences::userPrefersTextDescriptions() const { - Page* page = *(m_pageGroup.pages().begin()); + Page* page = currentPage(); if (!page) return false; @@ -126,7 +154,7 @@ bool CaptionUserPreferences::userPrefersTextDescriptions() const void CaptionUserPreferences::setUserPrefersTextDescriptions(bool preference) { - Page* page = *(m_pageGroup.pages().begin()); + Page* page = currentPage(); if (!page) return; @@ -154,6 +182,20 @@ void CaptionUserPreferences::setPreferredLanguage(const String& language) notify(); } +void CaptionUserPreferences::setPreferredAudioCharacteristic(const String& characteristic) +{ + m_userPreferredAudioCharacteristic = characteristic; + notify(); +} + +Vector<String> CaptionUserPreferences::preferredAudioCharacteristics() const +{ + Vector<String> characteristics; + if (!m_userPreferredAudioCharacteristic.isEmpty()) + characteristics.append(m_userPreferredAudioCharacteristic); + return characteristics; +} + static String trackDisplayName(TextTrack* track) { if (track == TextTrack::captionMenuOffItem()) @@ -161,11 +203,11 @@ static String trackDisplayName(TextTrack* track) if (track == TextTrack::captionMenuAutomaticItem()) return textTrackAutomaticMenuItemText(); - if (track->label().isEmpty() && track->language().isEmpty()) + if (track->label().isEmpty() && track->validBCP47Language().isEmpty()) return textTrackNoLabelText(); if (!track->label().isEmpty()) return track->label(); - return track->language(); + return track->validBCP47Language(); } String CaptionUserPreferences::displayNameForTrack(TextTrack* track) const @@ -181,12 +223,12 @@ Vector<RefPtr<TextTrack>> CaptionUserPreferences::sortedTrackListForMenu(TextTra for (unsigned i = 0, length = trackList->length(); i < length; ++i) { TextTrack* track = trackList->item(i); - const AtomicString& kind = track->kind(); - if (kind == TextTrack::captionsKeyword() || kind == TextTrack::descriptionsKeyword() || kind == TextTrack::subtitlesKeyword()) + auto kind = track->kind(); + if (kind == TextTrack::Kind::Captions || kind == TextTrack::Kind::Descriptions || kind == TextTrack::Kind::Subtitles) tracksForMenu.append(track); } - std::sort(tracksForMenu.begin(), tracksForMenu.end(), [](const RefPtr<TextTrack>& a, const RefPtr<TextTrack>& b) { + std::sort(tracksForMenu.begin(), tracksForMenu.end(), [](auto& a, auto& b) { return codePointCompare(trackDisplayName(a.get()), trackDisplayName(b.get())) < 0; }); @@ -196,57 +238,76 @@ Vector<RefPtr<TextTrack>> CaptionUserPreferences::sortedTrackListForMenu(TextTra return tracksForMenu; } -int CaptionUserPreferences::textTrackSelectionScore(TextTrack* track, HTMLMediaElement*) const +static String trackDisplayName(AudioTrack* track) { - int trackScore = 0; + if (track->label().isEmpty() && track->validBCP47Language().isEmpty()) + return audioTrackNoLabelText(); + if (!track->label().isEmpty()) + return track->label(); + return track->validBCP47Language(); +} - if (track->kind() != TextTrack::captionsKeyword() && track->kind() != TextTrack::subtitlesKeyword()) - return trackScore; +String CaptionUserPreferences::displayNameForTrack(AudioTrack* track) const +{ + return trackDisplayName(track); +} + +Vector<RefPtr<AudioTrack>> CaptionUserPreferences::sortedTrackListForMenu(AudioTrackList* trackList) +{ + ASSERT(trackList); + + Vector<RefPtr<AudioTrack>> tracksForMenu; + + for (unsigned i = 0, length = trackList->length(); i < length; ++i) { + AudioTrack* track = trackList->item(i); + tracksForMenu.append(track); + } + + std::sort(tracksForMenu.begin(), tracksForMenu.end(), [](auto& a, auto& b) { + return codePointCompare(trackDisplayName(a.get()), trackDisplayName(b.get())) < 0; + }); + + return tracksForMenu; +} + +int CaptionUserPreferences::textTrackSelectionScore(TextTrack* track, HTMLMediaElement*) const +{ + if (track->kind() != TextTrack::Kind::Captions && track->kind() != TextTrack::Kind::Subtitles) + return 0; if (!userPrefersSubtitles() && !userPrefersCaptions()) - return trackScore; - - if (track->kind() == TextTrack::subtitlesKeyword() && userPrefersSubtitles()) - trackScore = 1; - else if (track->kind() == TextTrack::captionsKeyword() && userPrefersCaptions()) - trackScore = 1; + return 0; - return trackScore + textTrackLanguageSelectionScore(track, preferredLanguages()); + return textTrackLanguageSelectionScore(track, preferredLanguages()) + 1; } int CaptionUserPreferences::textTrackLanguageSelectionScore(TextTrack* track, const Vector<String>& preferredLanguages) const { - if (track->language().isEmpty()) + if (track->validBCP47Language().isEmpty()) return 0; - size_t languageMatchIndex = indexOfBestMatchingLanguageInList(track->language(), preferredLanguages); + bool exactMatch; + size_t languageMatchIndex = indexOfBestMatchingLanguageInList(track->validBCP47Language(), preferredLanguages, exactMatch); if (languageMatchIndex >= preferredLanguages.size()) return 0; // Matching a track language is more important than matching track type, so this multiplier must be // greater than the maximum value returned by textTrackSelectionScore. - return (preferredLanguages.size() - languageMatchIndex) * 10; + int bonus = exactMatch ? 1 : 0; + return (preferredLanguages.size() + bonus - languageMatchIndex) * 10; } void CaptionUserPreferences::setCaptionsStyleSheetOverride(const String& override) { m_captionsStyleSheetOverride = override; - updateCaptionStyleSheetOveride(); + updateCaptionStyleSheetOverride(); } -void CaptionUserPreferences::updateCaptionStyleSheetOveride() +void CaptionUserPreferences::updateCaptionStyleSheetOverride() { - // Identify our override style sheet with a unique URL - a new scheme and a UUID. - DEFINE_STATIC_LOCAL(URL, captionsStyleSheetURL, (ParsedURLString, "user-captions-override:01F6AF12-C3B0-4F70-AF5E-A3E00234DC23")); - - m_pageGroup.removeUserStyleSheetFromWorld(mainThreadNormalWorld(), captionsStyleSheetURL); - String captionsOverrideStyleSheet = captionsStyleSheetOverride(); - if (captionsOverrideStyleSheet.isEmpty()) - return; - - m_pageGroup.addUserStyleSheetToWorld(mainThreadNormalWorld(), captionsOverrideStyleSheet, captionsStyleSheetURL, Vector<String>(), - Vector<String>(), InjectInAllFrames, UserStyleAuthorLevel, InjectInExistingDocuments); + for (auto& page : m_pageGroup.pages()) + page->setCaptionUserPreferencesStyleSheet(captionsOverrideStyleSheet); } String CaptionUserPreferences::primaryAudioTrackLanguageOverride() const |