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