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