[WTF] Clean up StringStatics.cpp by using LazyNeverDestroyed<> for Atoms
[WebKit-https.git] / Source / WebCore / accessibility / AccessibilityMediaControls.cpp
1 /*
2  * Copyright (C) 2009-2011 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29
30 #include "config.h"
31
32 #if ENABLE(VIDEO)
33
34 #include "AccessibilityMediaControls.h"
35
36 #include "AXObjectCache.h"
37 #include "HTMLInputElement.h"
38 #include "HTMLMediaElement.h"
39 #include "HTMLNames.h"
40 #include "LocalizedStrings.h"
41 #include "MediaControlElements.h"
42 #include "RenderObject.h"
43 #include "RenderSlider.h"
44 #include <wtf/NeverDestroyed.h>
45
46 namespace WebCore {
47
48 using namespace HTMLNames;
49
50
51 AccessibilityMediaControl::AccessibilityMediaControl(RenderObject* renderer)
52     : AccessibilityRenderObject(renderer)
53 {
54 }
55
56 Ref<AccessibilityObject> AccessibilityMediaControl::create(RenderObject* renderer)
57 {
58     ASSERT(renderer->node());
59
60     switch (mediaControlElementType(renderer->node())) {
61     case MediaSlider:
62         return AccessibilityMediaTimeline::create(renderer);
63
64     case MediaCurrentTimeDisplay:
65     case MediaTimeRemainingDisplay:
66         return AccessibilityMediaTimeDisplay::create(renderer);
67
68     case MediaControlsPanel:
69         return AccessibilityMediaControlsContainer::create(renderer);
70
71     default:
72         return adoptRef(*new AccessibilityMediaControl(renderer));
73     }
74 }
75
76 MediaControlElementType AccessibilityMediaControl::controlType() const
77 {
78     if (!renderer() || !renderer()->node())
79         return MediaTimelineContainer; // Timeline container is not accessible.
80
81     return mediaControlElementType(renderer()->node());
82 }
83
84 const String& AccessibilityMediaControl::controlTypeName() const
85 {
86     static NeverDestroyed<const String> mediaEnterFullscreenButtonName(MAKE_STATIC_STRING_IMPL("EnterFullscreenButton"));
87     static NeverDestroyed<const String> mediaExitFullscreenButtonName(MAKE_STATIC_STRING_IMPL("ExitFullscreenButton"));
88     static NeverDestroyed<const String> mediaMuteButtonName(MAKE_STATIC_STRING_IMPL("MuteButton"));
89     static NeverDestroyed<const String> mediaPlayButtonName(MAKE_STATIC_STRING_IMPL("PlayButton"));
90     static NeverDestroyed<const String> mediaSeekBackButtonName(MAKE_STATIC_STRING_IMPL("SeekBackButton"));
91     static NeverDestroyed<const String> mediaSeekForwardButtonName(MAKE_STATIC_STRING_IMPL("SeekForwardButton"));
92     static NeverDestroyed<const String> mediaRewindButtonName(MAKE_STATIC_STRING_IMPL("RewindButton"));
93     static NeverDestroyed<const String> mediaReturnToRealtimeButtonName(MAKE_STATIC_STRING_IMPL("ReturnToRealtimeButton"));
94     static NeverDestroyed<const String> mediaUnMuteButtonName(MAKE_STATIC_STRING_IMPL("UnMuteButton"));
95     static NeverDestroyed<const String> mediaPauseButtonName(MAKE_STATIC_STRING_IMPL("PauseButton"));
96     static NeverDestroyed<const String> mediaStatusDisplayName(MAKE_STATIC_STRING_IMPL("StatusDisplay"));
97     static NeverDestroyed<const String> mediaCurrentTimeDisplay(MAKE_STATIC_STRING_IMPL("CurrentTimeDisplay"));
98     static NeverDestroyed<const String> mediaTimeRemainingDisplay(MAKE_STATIC_STRING_IMPL("TimeRemainingDisplay"));
99     static NeverDestroyed<const String> mediaShowClosedCaptionsButtonName(MAKE_STATIC_STRING_IMPL("ShowClosedCaptionsButton"));
100     static NeverDestroyed<const String> mediaHideClosedCaptionsButtonName(MAKE_STATIC_STRING_IMPL("HideClosedCaptionsButton"));
101
102     switch (controlType()) {
103     case MediaEnterFullscreenButton:
104         return mediaEnterFullscreenButtonName;
105     case MediaExitFullscreenButton:
106         return mediaExitFullscreenButtonName;
107     case MediaMuteButton:
108         return mediaMuteButtonName;
109     case MediaPlayButton:
110         return mediaPlayButtonName;
111     case MediaSeekBackButton:
112         return mediaSeekBackButtonName;
113     case MediaSeekForwardButton:
114         return mediaSeekForwardButtonName;
115     case MediaRewindButton:
116         return mediaRewindButtonName;
117     case MediaReturnToRealtimeButton:
118         return mediaReturnToRealtimeButtonName;
119     case MediaUnMuteButton:
120         return mediaUnMuteButtonName;
121     case MediaPauseButton:
122         return mediaPauseButtonName;
123     case MediaStatusDisplay:
124         return mediaStatusDisplayName;
125     case MediaCurrentTimeDisplay:
126         return mediaCurrentTimeDisplay;
127     case MediaTimeRemainingDisplay:
128         return mediaTimeRemainingDisplay;
129     case MediaShowClosedCaptionsButton:
130         return mediaShowClosedCaptionsButtonName;
131     case MediaHideClosedCaptionsButton:
132         return mediaHideClosedCaptionsButtonName;
133
134     default:
135         break;
136     }
137
138     return nullAtom();
139 }
140
141 void AccessibilityMediaControl::accessibilityText(Vector<AccessibilityText>& textOrder)
142 {
143     String description = accessibilityDescription();
144     if (!description.isEmpty())
145         textOrder.append(AccessibilityText(description, AlternativeText));
146
147     String title = this->title();
148     if (!title.isEmpty())
149         textOrder.append(AccessibilityText(title, AlternativeText));
150
151     String helptext = helpText();
152     if (!helptext.isEmpty())
153         textOrder.append(AccessibilityText(helptext, HelpText));
154 }
155     
156
157 String AccessibilityMediaControl::title() const
158 {
159     static NeverDestroyed<const String> controlsPanel(MAKE_STATIC_STRING_IMPL("ControlsPanel"));
160
161     if (controlType() == MediaControlsPanel)
162         return localizedMediaControlElementString(controlsPanel);
163
164     return AccessibilityRenderObject::title();
165 }
166
167 String AccessibilityMediaControl::accessibilityDescription() const
168 {
169     return localizedMediaControlElementString(controlTypeName());
170 }
171
172 String AccessibilityMediaControl::helpText() const
173 {
174     return localizedMediaControlElementHelpText(controlTypeName());
175 }
176
177 bool AccessibilityMediaControl::computeAccessibilityIsIgnored() const
178 {
179     if (!m_renderer || m_renderer->style().visibility() != VISIBLE || controlType() == MediaTimelineContainer)
180         return true;
181
182     return accessibilityIsIgnoredByDefault();
183 }
184
185 AccessibilityRole AccessibilityMediaControl::roleValue() const
186 {
187     switch (controlType()) {
188     case MediaEnterFullscreenButton:
189     case MediaExitFullscreenButton:
190     case MediaMuteButton:
191     case MediaPlayButton:
192     case MediaSeekBackButton:
193     case MediaSeekForwardButton:
194     case MediaRewindButton:
195     case MediaReturnToRealtimeButton:
196     case MediaUnMuteButton:
197     case MediaPauseButton:
198     case MediaShowClosedCaptionsButton:
199     case MediaHideClosedCaptionsButton:
200         return ButtonRole;
201
202     case MediaStatusDisplay:
203         return StaticTextRole;
204
205     case MediaTimelineContainer:
206         return GroupRole;
207
208     default:
209         break;
210     }
211
212     return UnknownRole;
213 }
214
215
216
217 //
218 // AccessibilityMediaControlsContainer
219
220 AccessibilityMediaControlsContainer::AccessibilityMediaControlsContainer(RenderObject* renderer)
221     : AccessibilityMediaControl(renderer)
222 {
223 }
224
225 Ref<AccessibilityObject> AccessibilityMediaControlsContainer::create(RenderObject* renderer)
226 {
227     return adoptRef(*new AccessibilityMediaControlsContainer(renderer));
228 }
229
230 String AccessibilityMediaControlsContainer::accessibilityDescription() const
231 {
232     return localizedMediaControlElementString(elementTypeName());
233 }
234
235 String AccessibilityMediaControlsContainer::helpText() const
236 {
237     return localizedMediaControlElementHelpText(elementTypeName());
238 }
239
240 bool AccessibilityMediaControlsContainer::controllingVideoElement() const
241 {
242     auto element = parentMediaElement(*m_renderer);
243     return !element || element->isVideo();
244 }
245
246 const String& AccessibilityMediaControlsContainer::elementTypeName() const
247 {
248     static NeverDestroyed<const String> videoElement(MAKE_STATIC_STRING_IMPL("VideoElement"));
249     static NeverDestroyed<const String> audioElement(MAKE_STATIC_STRING_IMPL("AudioElement"));
250
251     if (controllingVideoElement())
252         return videoElement;
253     return audioElement;
254 }
255
256 bool AccessibilityMediaControlsContainer::computeAccessibilityIsIgnored() const
257 {
258     return accessibilityIsIgnoredByDefault();
259 }
260
261 //
262 // AccessibilityMediaTimeline
263
264 AccessibilityMediaTimeline::AccessibilityMediaTimeline(RenderObject* renderer)
265     : AccessibilitySlider(renderer)
266 {
267 }
268
269 Ref<AccessibilityObject> AccessibilityMediaTimeline::create(RenderObject* renderer)
270 {
271     return adoptRef(*new AccessibilityMediaTimeline(renderer));
272 }
273
274 String AccessibilityMediaTimeline::valueDescription() const
275 {
276     Node* node = m_renderer->node();
277     if (!is<HTMLInputElement>(*node))
278         return String();
279
280     float time = downcast<HTMLInputElement>(*node).value().toFloat();
281     return localizedMediaTimeDescription(time);
282 }
283
284 String AccessibilityMediaTimeline::helpText() const
285 {
286     static NeverDestroyed<const String> slider(MAKE_STATIC_STRING_IMPL("Slider"));
287     return localizedMediaControlElementHelpText(slider);
288 }
289
290
291 //
292 // AccessibilityMediaTimeDisplay
293
294 AccessibilityMediaTimeDisplay::AccessibilityMediaTimeDisplay(RenderObject* renderer)
295     : AccessibilityMediaControl(renderer)
296 {
297 }
298
299 Ref<AccessibilityObject> AccessibilityMediaTimeDisplay::create(RenderObject* renderer)
300 {
301     return adoptRef(*new AccessibilityMediaTimeDisplay(renderer));
302 }
303
304 bool AccessibilityMediaTimeDisplay::computeAccessibilityIsIgnored() const
305 {
306     if (!m_renderer || m_renderer->style().visibility() != VISIBLE)
307         return true;
308
309     if (!m_renderer->style().width().value())
310         return true;
311     
312     return accessibilityIsIgnoredByDefault();
313 }
314
315 String AccessibilityMediaTimeDisplay::accessibilityDescription() const
316 {
317     static NeverDestroyed<const String> currentTimeDisplay(MAKE_STATIC_STRING_IMPL("CurrentTimeDisplay"));
318     static NeverDestroyed<const String> timeRemainingDisplay(MAKE_STATIC_STRING_IMPL("TimeRemainingDisplay"));
319
320     if (controlType() == MediaCurrentTimeDisplay)
321         return localizedMediaControlElementString(currentTimeDisplay);
322
323     return localizedMediaControlElementString(timeRemainingDisplay);
324 }
325
326 String AccessibilityMediaTimeDisplay::stringValue() const
327 {
328     if (!m_renderer || !m_renderer->node())
329         return String();
330
331     MediaControlTimeDisplayElement* element = static_cast<MediaControlTimeDisplayElement*>(m_renderer->node());
332     float time = element->currentValue();
333     return localizedMediaTimeDescription(fabsf(time));
334 }
335
336 } // namespace WebCore
337
338 #endif // ENABLE(VIDEO)