5636691324fab446a91efe3e3067307b5751f149
[WebKit-https.git] / Source / WebCore / accessibility / AccessibilityMediaControls.cpp
1 /*
2  * Copyright (C) 2009 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 Computer, 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
45 namespace WebCore {
46
47 using namespace HTMLNames;
48
49
50 AccessibilityMediaControl::AccessibilityMediaControl(RenderObject* renderer)
51     : AccessibilityRenderObject(renderer)
52 {
53 }
54
55 PassRefPtr<AccessibilityObject> AccessibilityMediaControl::create(RenderObject* renderer)
56 {
57     ASSERT(renderer->node());
58
59     switch (mediaControlElementType(renderer->node())) {
60     case MediaSlider:
61         return AccessibilityMediaTimeline::create(renderer);
62
63     case MediaCurrentTimeDisplay:
64     case MediaTimeRemainingDisplay:
65         return AccessibilityMediaTimeDisplay::create(renderer);
66
67     case MediaControlsPanel:
68         return AccessibilityMediaControlsContainer::create(renderer);
69
70     default:
71         return adoptRef(new AccessibilityMediaControl(renderer));
72     }
73 }
74
75 MediaControlElementType AccessibilityMediaControl::controlType() const
76 {
77     if (!renderer() || !renderer()->node())
78         return MediaTimelineContainer; // Timeline container is not accessible.
79
80     return mediaControlElementType(renderer()->node());
81 }
82
83 String AccessibilityMediaControl::controlTypeName() const
84 {
85     DEFINE_STATIC_LOCAL(const String, mediaEnterFullscreenButtonName, ("EnterFullscreenButton"));
86     DEFINE_STATIC_LOCAL(const String, mediaExitFullscreenButtonName, ("ExitFullscreenButton"));
87     DEFINE_STATIC_LOCAL(const String, mediaMuteButtonName, ("MuteButton"));
88     DEFINE_STATIC_LOCAL(const String, mediaPlayButtonName, ("PlayButton"));
89     DEFINE_STATIC_LOCAL(const String, mediaSeekBackButtonName, ("SeekBackButton"));
90     DEFINE_STATIC_LOCAL(const String, mediaSeekForwardButtonName, ("SeekForwardButton"));
91     DEFINE_STATIC_LOCAL(const String, mediaRewindButtonName, ("RewindButton"));
92     DEFINE_STATIC_LOCAL(const String, mediaReturnToRealtimeButtonName, ("ReturnToRealtimeButton"));
93     DEFINE_STATIC_LOCAL(const String, mediaUnMuteButtonName, ("UnMuteButton"));
94     DEFINE_STATIC_LOCAL(const String, mediaPauseButtonName, ("PauseButton"));
95     DEFINE_STATIC_LOCAL(const String, mediaStatusDisplayName, ("StatusDisplay"));
96     DEFINE_STATIC_LOCAL(const String, mediaCurrentTimeDisplay, ("CurrentTimeDisplay"));
97     DEFINE_STATIC_LOCAL(const String, mediaTimeRemainingDisplay, ("TimeRemainingDisplay"));
98     DEFINE_STATIC_LOCAL(const String, mediaShowClosedCaptionsButtonName, ("ShowClosedCaptionsButton"));
99     DEFINE_STATIC_LOCAL(const String, mediaHideClosedCaptionsButtonName, ("HideClosedCaptionsButton"));
100
101     switch (controlType()) {
102     case MediaEnterFullscreenButton:
103         return mediaEnterFullscreenButtonName;
104     case MediaExitFullscreenButton:
105         return mediaExitFullscreenButtonName;
106     case MediaMuteButton:
107         return mediaMuteButtonName;
108     case MediaPlayButton:
109         return mediaPlayButtonName;
110     case MediaSeekBackButton:
111         return mediaSeekBackButtonName;
112     case MediaSeekForwardButton:
113         return mediaSeekForwardButtonName;
114     case MediaRewindButton:
115         return mediaRewindButtonName;
116     case MediaReturnToRealtimeButton:
117         return mediaReturnToRealtimeButtonName;
118     case MediaUnMuteButton:
119         return mediaUnMuteButtonName;
120     case MediaPauseButton:
121         return mediaPauseButtonName;
122     case MediaStatusDisplay:
123         return mediaStatusDisplayName;
124     case MediaCurrentTimeDisplay:
125         return mediaCurrentTimeDisplay;
126     case MediaTimeRemainingDisplay:
127         return mediaTimeRemainingDisplay;
128     case MediaShowClosedCaptionsButton:
129         return mediaShowClosedCaptionsButtonName;
130     case MediaHideClosedCaptionsButton:
131         return mediaHideClosedCaptionsButtonName;
132
133     default:
134         break;
135     }
136
137     return String();
138 }
139
140 String AccessibilityMediaControl::title() const
141 {
142     DEFINE_STATIC_LOCAL(const String, controlsPanel, ("ControlsPanel"));
143
144     if (controlType() == MediaControlsPanel)
145         return localizedMediaControlElementString(controlsPanel);
146
147     return AccessibilityRenderObject::title();
148 }
149
150 String AccessibilityMediaControl::accessibilityDescription() const
151 {
152     return localizedMediaControlElementString(controlTypeName());
153 }
154
155 String AccessibilityMediaControl::helpText() const
156 {
157     return localizedMediaControlElementHelpText(controlTypeName());
158 }
159
160 bool AccessibilityMediaControl::accessibilityIsIgnored() const
161 {
162     if (!m_renderer || !m_renderer->style() || m_renderer->style()->visibility() != VISIBLE || controlType() == MediaTimelineContainer)
163         return true;
164
165     return false;
166 }
167
168 AccessibilityRole AccessibilityMediaControl::roleValue() const
169 {
170     switch (controlType()) {
171     case MediaEnterFullscreenButton:
172     case MediaExitFullscreenButton:
173     case MediaMuteButton:
174     case MediaPlayButton:
175     case MediaSeekBackButton:
176     case MediaSeekForwardButton:
177     case MediaRewindButton:
178     case MediaReturnToRealtimeButton:
179     case MediaUnMuteButton:
180     case MediaPauseButton:
181     case MediaShowClosedCaptionsButton:
182     case MediaHideClosedCaptionsButton:
183         return ButtonRole;
184
185     case MediaStatusDisplay:
186         return StaticTextRole;
187
188     case MediaTimelineContainer:
189         return GroupRole;
190
191     default:
192         break;
193     }
194
195     return UnknownRole;
196 }
197
198
199
200 //
201 // AccessibilityMediaControlsContainer
202
203 AccessibilityMediaControlsContainer::AccessibilityMediaControlsContainer(RenderObject* renderer)
204     : AccessibilityMediaControl(renderer)
205 {
206 }
207
208 PassRefPtr<AccessibilityObject> AccessibilityMediaControlsContainer::create(RenderObject* renderer)
209 {
210     return adoptRef(new AccessibilityMediaControlsContainer(renderer));
211 }
212
213 String AccessibilityMediaControlsContainer::accessibilityDescription() const
214 {
215     return localizedMediaControlElementString(elementTypeName());
216 }
217
218 String AccessibilityMediaControlsContainer::helpText() const
219 {
220     return localizedMediaControlElementHelpText(elementTypeName());
221 }
222
223 bool AccessibilityMediaControlsContainer::controllingVideoElement() const
224 {
225     if (!m_renderer->node())
226         return true;
227
228     MediaControlTimeDisplayElement* element = static_cast<MediaControlTimeDisplayElement*>(m_renderer->node());
229
230     return toParentMediaElement(element)->isVideo();
231 }
232
233 const String AccessibilityMediaControlsContainer::elementTypeName() const
234 {
235     DEFINE_STATIC_LOCAL(const String, videoElement, ("VideoElement"));
236     DEFINE_STATIC_LOCAL(const String, audioElement, ("AudioElement"));
237
238     if (controllingVideoElement())
239         return videoElement;
240     return audioElement;
241 }
242
243
244 //
245 // AccessibilityMediaTimeline
246
247 AccessibilityMediaTimeline::AccessibilityMediaTimeline(RenderObject* renderer)
248     : AccessibilitySlider(renderer)
249 {
250 }
251
252 PassRefPtr<AccessibilityObject> AccessibilityMediaTimeline::create(RenderObject* renderer)
253 {
254     return adoptRef(new AccessibilityMediaTimeline(renderer));
255 }
256
257 String AccessibilityMediaTimeline::valueDescription() const
258 {
259     Node* node = m_renderer->node();
260     if (!node->hasTagName(inputTag))
261         return String();
262
263     float time = static_cast<HTMLInputElement*>(node)->value().toFloat();
264     return localizedMediaTimeDescription(time);
265 }
266
267 String AccessibilityMediaTimeline::helpText() const
268 {
269     DEFINE_STATIC_LOCAL(const String, slider, ("Slider"));
270     return localizedMediaControlElementHelpText(slider);
271 }
272
273
274 //
275 // AccessibilityMediaTimeDisplay
276
277 AccessibilityMediaTimeDisplay::AccessibilityMediaTimeDisplay(RenderObject* renderer)
278     : AccessibilityMediaControl(renderer)
279 {
280 }
281
282 PassRefPtr<AccessibilityObject> AccessibilityMediaTimeDisplay::create(RenderObject* renderer)
283 {
284     return adoptRef(new AccessibilityMediaTimeDisplay(renderer));
285 }
286
287 bool AccessibilityMediaTimeDisplay::accessibilityIsIgnored() const
288 {
289     if (!m_renderer || !m_renderer->style() || m_renderer->style()->visibility() != VISIBLE)
290         return true;
291
292     return !m_renderer->style()->width().value();
293 }
294
295 String AccessibilityMediaTimeDisplay::accessibilityDescription() const
296 {
297     DEFINE_STATIC_LOCAL(const String, currentTimeDisplay, ("CurrentTimeDisplay"));
298     DEFINE_STATIC_LOCAL(const String, timeRemainingDisplay, ("TimeRemainingDisplay"));
299
300     if (controlType() == MediaCurrentTimeDisplay)
301         return localizedMediaControlElementString(currentTimeDisplay);
302
303     return localizedMediaControlElementString(timeRemainingDisplay);
304 }
305
306 String AccessibilityMediaTimeDisplay::stringValue() const
307 {
308     if (!m_renderer || !m_renderer->node())
309         return String();
310
311     MediaControlTimeDisplayElement* element = static_cast<MediaControlTimeDisplayElement*>(m_renderer->node());
312     float time = element->currentValue();
313     return localizedMediaTimeDescription(fabsf(time));
314 }
315
316 } // namespace WebCore
317
318 #endif // ENABLE(VIDEO)