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 #include "core/accessibility/AXMediaControls.h" 32 33 #include "core/html/HTMLMediaElement.h" 34 #include "platform/text/PlatformLocale.h" 35 36 namespace WebCore { 37 38 using blink::WebLocalizedString; 39 using namespace HTMLNames; 40 41 42 static inline String queryString(WebLocalizedString::Name name) 43 { 44 return Locale::defaultLocale().queryString(name); 45 } 46 47 AccessibilityMediaControl::AccessibilityMediaControl(RenderObject* renderer) 48 : AXRenderObject(renderer) 49 { 50 } 51 52 PassRefPtr<AXObject> AccessibilityMediaControl::create(RenderObject* renderer) 53 { 54 ASSERT(renderer->node()); 55 56 switch (mediaControlElementType(renderer->node())) { 57 case MediaSlider: 58 return AccessibilityMediaTimeline::create(renderer); 59 60 case MediaCurrentTimeDisplay: 61 case MediaTimeRemainingDisplay: 62 return AccessibilityMediaTimeDisplay::create(renderer); 63 64 case MediaControlsPanel: 65 return AXMediaControlsContainer::create(renderer); 66 67 default: 68 return adoptRef(new AccessibilityMediaControl(renderer)); 69 } 70 } 71 72 MediaControlElementType AccessibilityMediaControl::controlType() const 73 { 74 if (!renderer() || !renderer()->node()) 75 return MediaTimelineContainer; // Timeline container is not accessible. 76 77 return mediaControlElementType(renderer()->node()); 78 } 79 80 String AccessibilityMediaControl::title() const 81 { 82 // FIXME: the ControlsPanel container should never be visible in the 83 // accessibility hierarchy. 84 if (controlType() == MediaControlsPanel) 85 return queryString(WebLocalizedString::AXMediaDefault); 86 87 return AXRenderObject::title(); 88 } 89 90 String AccessibilityMediaControl::accessibilityDescription() const 91 { 92 switch (controlType()) { 93 case MediaEnterFullscreenButton: 94 return queryString(WebLocalizedString::AXMediaEnterFullscreenButton); 95 case MediaExitFullscreenButton: 96 return queryString(WebLocalizedString::AXMediaExitFullscreenButton); 97 case MediaMuteButton: 98 return queryString(WebLocalizedString::AXMediaMuteButton); 99 case MediaPlayButton: 100 return queryString(WebLocalizedString::AXMediaPlayButton); 101 case MediaUnMuteButton: 102 return queryString(WebLocalizedString::AXMediaUnMuteButton); 103 case MediaPauseButton: 104 return queryString(WebLocalizedString::AXMediaPauseButton); 105 case MediaStatusDisplay: 106 return queryString(WebLocalizedString::AXMediaStatusDisplay); 107 case MediaCurrentTimeDisplay: 108 return queryString(WebLocalizedString::AXMediaCurrentTimeDisplay); 109 case MediaTimeRemainingDisplay: 110 return queryString(WebLocalizedString::AXMediaTimeRemainingDisplay); 111 case MediaShowClosedCaptionsButton: 112 return queryString(WebLocalizedString::AXMediaShowClosedCaptionsButton); 113 case MediaHideClosedCaptionsButton: 114 return queryString(WebLocalizedString::AXMediaHideClosedCaptionsButton); 115 default: 116 return queryString(WebLocalizedString::AXMediaDefault); 117 } 118 } 119 120 String AccessibilityMediaControl::helpText() const 121 { 122 switch (controlType()) { 123 case MediaEnterFullscreenButton: 124 return queryString(WebLocalizedString::AXMediaEnterFullscreenButtonHelp); 125 case MediaExitFullscreenButton: 126 return queryString(WebLocalizedString::AXMediaExitFullscreenButtonHelp); 127 case MediaMuteButton: 128 return queryString(WebLocalizedString::AXMediaMuteButtonHelp); 129 case MediaPlayButton: 130 return queryString(WebLocalizedString::AXMediaPlayButtonHelp); 131 case MediaUnMuteButton: 132 return queryString(WebLocalizedString::AXMediaUnMuteButtonHelp); 133 case MediaPauseButton: 134 return queryString(WebLocalizedString::AXMediaPauseButtonHelp); 135 case MediaStatusDisplay: 136 return queryString(WebLocalizedString::AXMediaStatusDisplayHelp); 137 case MediaCurrentTimeDisplay: 138 return queryString(WebLocalizedString::AXMediaCurrentTimeDisplayHelp); 139 case MediaTimeRemainingDisplay: 140 return queryString(WebLocalizedString::AXMediaTimeRemainingDisplayHelp); 141 case MediaShowClosedCaptionsButton: 142 return queryString(WebLocalizedString::AXMediaShowClosedCaptionsButtonHelp); 143 case MediaHideClosedCaptionsButton: 144 return queryString(WebLocalizedString::AXMediaHideClosedCaptionsButtonHelp); 145 default: 146 return queryString(WebLocalizedString::AXMediaDefault); 147 } 148 } 149 150 bool AccessibilityMediaControl::computeAccessibilityIsIgnored() const 151 { 152 if (!m_renderer || !m_renderer->style() || m_renderer->style()->visibility() != VISIBLE || controlType() == MediaTimelineContainer) 153 return true; 154 155 return accessibilityIsIgnoredByDefault(); 156 } 157 158 AccessibilityRole AccessibilityMediaControl::roleValue() const 159 { 160 switch (controlType()) { 161 case MediaEnterFullscreenButton: 162 case MediaExitFullscreenButton: 163 case MediaMuteButton: 164 case MediaPlayButton: 165 case MediaUnMuteButton: 166 case MediaPauseButton: 167 case MediaShowClosedCaptionsButton: 168 case MediaHideClosedCaptionsButton: 169 return ButtonRole; 170 171 case MediaStatusDisplay: 172 return StaticTextRole; 173 174 case MediaTimelineContainer: 175 return GroupRole; 176 177 default: 178 break; 179 } 180 181 return UnknownRole; 182 } 183 184 185 186 // 187 // AXMediaControlsContainer 188 189 AXMediaControlsContainer::AXMediaControlsContainer(RenderObject* renderer) 190 : AccessibilityMediaControl(renderer) 191 { 192 } 193 194 PassRefPtr<AXObject> AXMediaControlsContainer::create(RenderObject* renderer) 195 { 196 return adoptRef(new AXMediaControlsContainer(renderer)); 197 } 198 199 String AXMediaControlsContainer::accessibilityDescription() const 200 { 201 return queryString(controllingVideoElement() ? WebLocalizedString::AXMediaVideoElement : WebLocalizedString::AXMediaAudioElement); 202 } 203 204 String AXMediaControlsContainer::helpText() const 205 { 206 return queryString(controllingVideoElement() ? WebLocalizedString::AXMediaVideoElementHelp : WebLocalizedString::AXMediaAudioElementHelp); 207 } 208 209 bool AXMediaControlsContainer::controllingVideoElement() const 210 { 211 if (!m_renderer->node()) 212 return true; 213 214 MediaControlTimeDisplayElement* element = static_cast<MediaControlTimeDisplayElement*>(m_renderer->node()); 215 216 return isHTMLVideoElement(toParentMediaElement(element)); 217 } 218 219 bool AXMediaControlsContainer::computeAccessibilityIsIgnored() const 220 { 221 return accessibilityIsIgnoredByDefault(); 222 } 223 224 // 225 // AccessibilityMediaTimeline 226 227 static String localizedMediaTimeDescription(float /*time*/) 228 { 229 // FIXME: To be fixed. See 230 // http://trac.webkit.org/browser/trunk/Source/WebCore/platform/LocalizedStrings.cpp#L928 231 return String(); 232 } 233 234 AccessibilityMediaTimeline::AccessibilityMediaTimeline(RenderObject* renderer) 235 : AXSlider(renderer) 236 { 237 } 238 239 PassRefPtr<AXObject> AccessibilityMediaTimeline::create(RenderObject* renderer) 240 { 241 return adoptRef(new AccessibilityMediaTimeline(renderer)); 242 } 243 244 String AccessibilityMediaTimeline::valueDescription() const 245 { 246 Node* node = m_renderer->node(); 247 if (!isHTMLInputElement(node)) 248 return String(); 249 250 return localizedMediaTimeDescription(toHTMLInputElement(node)->value().toFloat()); 251 } 252 253 String AccessibilityMediaTimeline::helpText() const 254 { 255 return queryString(WebLocalizedString::AXMediaSliderHelp); 256 } 257 258 259 // 260 // AccessibilityMediaTimeDisplay 261 262 AccessibilityMediaTimeDisplay::AccessibilityMediaTimeDisplay(RenderObject* renderer) 263 : AccessibilityMediaControl(renderer) 264 { 265 } 266 267 PassRefPtr<AXObject> AccessibilityMediaTimeDisplay::create(RenderObject* renderer) 268 { 269 return adoptRef(new AccessibilityMediaTimeDisplay(renderer)); 270 } 271 272 bool AccessibilityMediaTimeDisplay::computeAccessibilityIsIgnored() const 273 { 274 if (!m_renderer || !m_renderer->style() || m_renderer->style()->visibility() != VISIBLE) 275 return true; 276 277 if (!m_renderer->style()->width().value()) 278 return true; 279 280 return accessibilityIsIgnoredByDefault(); 281 } 282 283 String AccessibilityMediaTimeDisplay::accessibilityDescription() const 284 { 285 if (controlType() == MediaCurrentTimeDisplay) 286 return queryString(WebLocalizedString::AXMediaCurrentTimeDisplay); 287 return queryString(WebLocalizedString::AXMediaTimeRemainingDisplay); 288 } 289 290 String AccessibilityMediaTimeDisplay::stringValue() const 291 { 292 if (!m_renderer || !m_renderer->node()) 293 return String(); 294 295 MediaControlTimeDisplayElement* element = static_cast<MediaControlTimeDisplayElement*>(m_renderer->node()); 296 float time = element->currentValue(); 297 return localizedMediaTimeDescription(fabsf(time)); 298 } 299 300 } // namespace WebCore 301