AccessibilityMediaControls.cpp [plain text]
#include "config.h"
#if ENABLE(VIDEO)
#include "AccessibilityMediaControls.h"
#include "AXObjectCache.h"
#include "HTMLInputElement.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "LocalizedStrings.h"
#include "MediaControlElements.h"
#include "RenderObject.h"
#include "RenderSlider.h"
#include <wtf/NeverDestroyed.h>
namespace WebCore {
using namespace HTMLNames;
AccessibilityMediaControl::AccessibilityMediaControl(RenderObject* renderer)
: AccessibilityRenderObject(renderer)
{
}
PassRefPtr<AccessibilityObject> AccessibilityMediaControl::create(RenderObject* renderer)
{
ASSERT(renderer->node());
switch (mediaControlElementType(renderer->node())) {
case MediaSlider:
return AccessibilityMediaTimeline::create(renderer);
case MediaCurrentTimeDisplay:
case MediaTimeRemainingDisplay:
return AccessibilityMediaTimeDisplay::create(renderer);
case MediaControlsPanel:
return AccessibilityMediaControlsContainer::create(renderer);
default:
return adoptRef(new AccessibilityMediaControl(renderer));
}
}
MediaControlElementType AccessibilityMediaControl::controlType() const
{
if (!renderer() || !renderer()->node())
return MediaTimelineContainer;
return mediaControlElementType(renderer()->node());
}
const String& AccessibilityMediaControl::controlTypeName() const
{
static NeverDestroyed<const String> mediaEnterFullscreenButtonName(ASCIILiteral("EnterFullscreenButton"));
static NeverDestroyed<const String> mediaExitFullscreenButtonName(ASCIILiteral("ExitFullscreenButton"));
static NeverDestroyed<const String> mediaMuteButtonName(ASCIILiteral("MuteButton"));
static NeverDestroyed<const String> mediaPlayButtonName(ASCIILiteral("PlayButton"));
static NeverDestroyed<const String> mediaSeekBackButtonName(ASCIILiteral("SeekBackButton"));
static NeverDestroyed<const String> mediaSeekForwardButtonName(ASCIILiteral("SeekForwardButton"));
static NeverDestroyed<const String> mediaRewindButtonName(ASCIILiteral("RewindButton"));
static NeverDestroyed<const String> mediaReturnToRealtimeButtonName(ASCIILiteral("ReturnToRealtimeButton"));
static NeverDestroyed<const String> mediaUnMuteButtonName(ASCIILiteral("UnMuteButton"));
static NeverDestroyed<const String> mediaPauseButtonName(ASCIILiteral("PauseButton"));
static NeverDestroyed<const String> mediaStatusDisplayName(ASCIILiteral("StatusDisplay"));
static NeverDestroyed<const String> mediaCurrentTimeDisplay(ASCIILiteral("CurrentTimeDisplay"));
static NeverDestroyed<const String> mediaTimeRemainingDisplay(ASCIILiteral("TimeRemainingDisplay"));
static NeverDestroyed<const String> mediaShowClosedCaptionsButtonName(ASCIILiteral("ShowClosedCaptionsButton"));
static NeverDestroyed<const String> mediaHideClosedCaptionsButtonName(ASCIILiteral("HideClosedCaptionsButton"));
switch (controlType()) {
case MediaEnterFullscreenButton:
return mediaEnterFullscreenButtonName;
case MediaExitFullscreenButton:
return mediaExitFullscreenButtonName;
case MediaMuteButton:
return mediaMuteButtonName;
case MediaPlayButton:
return mediaPlayButtonName;
case MediaSeekBackButton:
return mediaSeekBackButtonName;
case MediaSeekForwardButton:
return mediaSeekForwardButtonName;
case MediaRewindButton:
return mediaRewindButtonName;
case MediaReturnToRealtimeButton:
return mediaReturnToRealtimeButtonName;
case MediaUnMuteButton:
return mediaUnMuteButtonName;
case MediaPauseButton:
return mediaPauseButtonName;
case MediaStatusDisplay:
return mediaStatusDisplayName;
case MediaCurrentTimeDisplay:
return mediaCurrentTimeDisplay;
case MediaTimeRemainingDisplay:
return mediaTimeRemainingDisplay;
case MediaShowClosedCaptionsButton:
return mediaShowClosedCaptionsButtonName;
case MediaHideClosedCaptionsButton:
return mediaHideClosedCaptionsButtonName;
default:
break;
}
return nullAtom;
}
void AccessibilityMediaControl::accessibilityText(Vector<AccessibilityText>& textOrder)
{
String description = accessibilityDescription();
if (!description.isEmpty())
textOrder.append(AccessibilityText(description, AlternativeText));
String title = this->title();
if (!title.isEmpty())
textOrder.append(AccessibilityText(title, AlternativeText));
String helptext = helpText();
if (!helptext.isEmpty())
textOrder.append(AccessibilityText(helptext, HelpText));
}
String AccessibilityMediaControl::title() const
{
static NeverDestroyed<const String> controlsPanel(ASCIILiteral("ControlsPanel"));
if (controlType() == MediaControlsPanel)
return localizedMediaControlElementString(controlsPanel);
return AccessibilityRenderObject::title();
}
String AccessibilityMediaControl::accessibilityDescription() const
{
return localizedMediaControlElementString(controlTypeName());
}
String AccessibilityMediaControl::helpText() const
{
return localizedMediaControlElementHelpText(controlTypeName());
}
bool AccessibilityMediaControl::computeAccessibilityIsIgnored() const
{
if (!m_renderer || m_renderer->style().visibility() != VISIBLE || controlType() == MediaTimelineContainer)
return true;
return accessibilityIsIgnoredByDefault();
}
AccessibilityRole AccessibilityMediaControl::roleValue() const
{
switch (controlType()) {
case MediaEnterFullscreenButton:
case MediaExitFullscreenButton:
case MediaMuteButton:
case MediaPlayButton:
case MediaSeekBackButton:
case MediaSeekForwardButton:
case MediaRewindButton:
case MediaReturnToRealtimeButton:
case MediaUnMuteButton:
case MediaPauseButton:
case MediaShowClosedCaptionsButton:
case MediaHideClosedCaptionsButton:
return ButtonRole;
case MediaStatusDisplay:
return StaticTextRole;
case MediaTimelineContainer:
return GroupRole;
default:
break;
}
return UnknownRole;
}
AccessibilityMediaControlsContainer::AccessibilityMediaControlsContainer(RenderObject* renderer)
: AccessibilityMediaControl(renderer)
{
}
PassRefPtr<AccessibilityObject> AccessibilityMediaControlsContainer::create(RenderObject* renderer)
{
return adoptRef(new AccessibilityMediaControlsContainer(renderer));
}
String AccessibilityMediaControlsContainer::accessibilityDescription() const
{
return localizedMediaControlElementString(elementTypeName());
}
String AccessibilityMediaControlsContainer::helpText() const
{
return localizedMediaControlElementHelpText(elementTypeName());
}
bool AccessibilityMediaControlsContainer::controllingVideoElement() const
{
auto element = parentMediaElement(*m_renderer);
return !element || element->isVideo();
}
const String& AccessibilityMediaControlsContainer::elementTypeName() const
{
static NeverDestroyed<const String> videoElement(ASCIILiteral("VideoElement"));
static NeverDestroyed<const String> audioElement(ASCIILiteral("AudioElement"));
if (controllingVideoElement())
return videoElement;
return audioElement;
}
bool AccessibilityMediaControlsContainer::computeAccessibilityIsIgnored() const
{
return accessibilityIsIgnoredByDefault();
}
AccessibilityMediaTimeline::AccessibilityMediaTimeline(RenderObject* renderer)
: AccessibilitySlider(renderer)
{
}
PassRefPtr<AccessibilityObject> AccessibilityMediaTimeline::create(RenderObject* renderer)
{
return adoptRef(new AccessibilityMediaTimeline(renderer));
}
String AccessibilityMediaTimeline::valueDescription() const
{
Node* node = m_renderer->node();
if (!isHTMLInputElement(node))
return String();
float time = toHTMLInputElement(node)->value().toFloat();
return localizedMediaTimeDescription(time);
}
String AccessibilityMediaTimeline::helpText() const
{
static NeverDestroyed<const String> slider(ASCIILiteral("Slider"));
return localizedMediaControlElementHelpText(slider);
}
AccessibilityMediaTimeDisplay::AccessibilityMediaTimeDisplay(RenderObject* renderer)
: AccessibilityMediaControl(renderer)
{
}
PassRefPtr<AccessibilityObject> AccessibilityMediaTimeDisplay::create(RenderObject* renderer)
{
return adoptRef(new AccessibilityMediaTimeDisplay(renderer));
}
bool AccessibilityMediaTimeDisplay::computeAccessibilityIsIgnored() const
{
if (!m_renderer || m_renderer->style().visibility() != VISIBLE)
return true;
if (!m_renderer->style().width().value())
return true;
return accessibilityIsIgnoredByDefault();
}
String AccessibilityMediaTimeDisplay::accessibilityDescription() const
{
static NeverDestroyed<const String> currentTimeDisplay(ASCIILiteral("CurrentTimeDisplay"));
static NeverDestroyed<const String> timeRemainingDisplay(ASCIILiteral("TimeRemainingDisplay"));
if (controlType() == MediaCurrentTimeDisplay)
return localizedMediaControlElementString(currentTimeDisplay);
return localizedMediaControlElementString(timeRemainingDisplay);
}
String AccessibilityMediaTimeDisplay::stringValue() const
{
if (!m_renderer || !m_renderer->node())
return String();
MediaControlTimeDisplayElement* element = static_cast<MediaControlTimeDisplayElement*>(m_renderer->node());
float time = element->currentValue();
return localizedMediaTimeDescription(fabsf(time));
}
}
#endif // ENABLE(VIDEO)