[Mac] webkitClosedCaptionsVisible doesn't work
[WebKit-https.git] / Source / WebCore / page / CaptionUserPreferences.cpp
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27
28 #if ENABLE(VIDEO_TRACK)
29
30 #include "CaptionUserPreferences.h"
31 #include "Page.h"
32 #include "PageGroup.h"
33 #include "Settings.h"
34 #include "TextTrackList.h"
35 #include <wtf/NonCopyingSort.h>
36
37 namespace WebCore {
38
39 CaptionUserPreferences::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
48 CaptionUserPreferences::~CaptionUserPreferences()
49 {
50 }
51
52 bool CaptionUserPreferences::shouldShowCaptions() const
53 {
54     if (!m_testingMode)
55         return false;
56     
57     return m_shouldShowCaptions || userPrefersCaptions() || userPrefersSubtitles();
58 }
59
60 void CaptionUserPreferences::timerFired(Timer<CaptionUserPreferences>*)
61 {
62     captionPreferencesChanged();
63 }
64
65 void CaptionUserPreferences::notify()
66 {
67     if (!m_testingMode)
68         return;
69
70     m_havePreferences = true;
71     if (!m_timer.isActive())
72         m_timer.startOneShot(0);
73 }
74
75 void CaptionUserPreferences::setShouldShowCaptions(bool preference)
76 {
77     m_shouldShowCaptions = preference;
78     if (m_testingMode && !preference) {
79         setUserPrefersCaptions(false);
80         setUserPrefersSubtitles(false);
81     }
82     notify();
83 }
84
85 bool CaptionUserPreferences::userPrefersCaptions() const
86 {
87     Page* page = *(pageGroup()->pages().begin());
88     if (!page)
89         return false;
90
91     return page->settings()->shouldDisplayCaptions();
92 }
93
94 void CaptionUserPreferences::setUserPrefersCaptions(bool preference)
95 {
96     Page* page = *(pageGroup()->pages().begin());
97     if (!page)
98         return;
99
100     page->settings()->setShouldDisplayCaptions(preference);
101     notify();
102 }
103
104 bool CaptionUserPreferences::userPrefersSubtitles() const
105 {
106     Page* page = *(pageGroup()->pages().begin());
107     if (!page)
108         return false;
109
110     return page->settings()->shouldDisplaySubtitles();
111 }
112
113 void CaptionUserPreferences::setUserPrefersSubtitles(bool preference)
114 {
115     Page* page = *(pageGroup()->pages().begin());
116     if (!page)
117         return;
118
119     page->settings()->setShouldDisplaySubtitles(preference);
120     notify();
121 }
122
123 bool CaptionUserPreferences::userPrefersTextDescriptions() const
124 {
125     Page* page = *(pageGroup()->pages().begin());
126     if (!page)
127         return false;
128     
129     return page->settings()->shouldDisplayTextDescriptions();
130 }
131
132 void CaptionUserPreferences::setUserPrefersTextDescriptions(bool preference)
133 {
134     Page* page = *(pageGroup()->pages().begin());
135     if (!page)
136         return;
137     
138     page->settings()->setShouldDisplayTextDescriptions(preference);
139     notify();
140 }
141
142 void CaptionUserPreferences::captionPreferencesChanged()
143 {
144     m_pageGroup->captionPreferencesChanged();
145 }
146
147 Vector<String> CaptionUserPreferences::preferredLanguages() const
148 {
149     Vector<String> languages = userPreferredLanguages();
150     if (m_testingMode && !m_userPreferredLanguage.isEmpty())
151         languages.insert(0, m_userPreferredLanguage);
152
153     return languages;
154 }
155
156 void CaptionUserPreferences::setPreferredLanguage(String language)
157 {
158     m_userPreferredLanguage = language;
159     notify();
160 }
161
162 static String trackDisplayName(TextTrack* track)
163 {
164     if (track->label().isEmpty() && track->language().isEmpty())
165         return textTrackNoLabelText();
166     if (!track->label().isEmpty())
167         return track->label();
168     return track->language();
169 }
170
171 String CaptionUserPreferences::displayNameForTrack(TextTrack* track) const
172 {
173     return trackDisplayName(track);
174 }
175     
176 static bool textTrackCompare(const RefPtr<TextTrack>& a, const RefPtr<TextTrack>& b)
177 {
178     return codePointCompare(trackDisplayName(a.get()), trackDisplayName(b.get())) < 0;
179 }
180
181 Vector<RefPtr<TextTrack> > CaptionUserPreferences::sortedTrackListForMenu(TextTrackList* trackList)
182 {
183     ASSERT(trackList);
184
185     Vector<RefPtr<TextTrack> > tracksForMenu;
186
187     for (unsigned i = 0, length = trackList->length(); i < length; ++i)
188         tracksForMenu.append(trackList->item(i));
189
190     nonCopyingSort(tracksForMenu.begin(), tracksForMenu.end(), textTrackCompare);
191
192     return tracksForMenu;
193 }
194
195 int CaptionUserPreferences::textTrackSelectionScore(TextTrack* track, HTMLMediaElement*) const
196 {
197     int trackScore = 0;
198
199     if (track->kind() != TextTrack::captionsKeyword() && track->kind() != TextTrack::subtitlesKeyword())
200         return trackScore;
201
202     if (track->kind() == TextTrack::subtitlesKeyword() && userPrefersSubtitles())
203         trackScore = 1;
204     else if (track->kind() == TextTrack::captionsKeyword() && userPrefersCaptions())
205         trackScore = 1;
206     
207     return trackScore + textTrackLanguageSelectionScore(track);
208 }
209
210 int CaptionUserPreferences::textTrackLanguageSelectionScore(TextTrack* track) const
211 {
212     if (track->language().isEmpty())
213         return 0;
214
215     Vector<String> languages = preferredLanguages();
216     size_t languageMatchIndex = indexOfBestMatchingLanguageInList(track->language(), languages);
217     if (languageMatchIndex >= languages.size())
218         return 0;
219
220     // Matching a track language is more important than matching track type, so this multiplier must be
221     // greater than the maximum value returned by textTrackSelectionScore.
222     return (languages.size() - languageMatchIndex) * 10;
223 }
224
225 }
226
227 #endif // ENABLE(VIDEO_TRACK)