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 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#include "config.h"
30#include "AccessibilitySlider.h"
31
32#include "AXObjectCache.h"
33#include "HTMLInputElement.h"
34#include "HTMLNames.h"
35#include "RenderObject.h"
36#include "RenderSlider.h"
37#include "SliderThumbElement.h"
38
39namespace WebCore {
40
41using namespace HTMLNames;
42
43AccessibilitySlider::AccessibilitySlider(RenderObject* renderer)
44 : AccessibilityRenderObject(renderer)
45{
46}
47
48Ref<AccessibilitySlider> AccessibilitySlider::create(RenderObject* renderer)
49{
50 return adoptRef(*new AccessibilitySlider(renderer));
51}
52
53AccessibilityOrientation AccessibilitySlider::orientation() const
54{
55 // Default to horizontal in the unknown case.
56 if (!m_renderer)
57 return AccessibilityOrientation::Horizontal;
58
59 const RenderStyle& style = m_renderer->style();
60
61 ControlPart styleAppearance = style.appearance();
62 switch (styleAppearance) {
63 case SliderThumbHorizontalPart:
64 case SliderHorizontalPart:
65 case MediaSliderPart:
66 case MediaFullScreenVolumeSliderPart:
67 return AccessibilityOrientation::Horizontal;
68
69 case SliderThumbVerticalPart:
70 case SliderVerticalPart:
71 case MediaVolumeSliderPart:
72 return AccessibilityOrientation::Vertical;
73
74 default:
75 return AccessibilityOrientation::Horizontal;
76 }
77}
78
79void AccessibilitySlider::addChildren()
80{
81 ASSERT(!m_haveChildren);
82
83 m_haveChildren = true;
84
85 AXObjectCache* cache = m_renderer->document().axObjectCache();
86
87 auto& thumb = downcast<AccessibilitySliderThumb>(*cache->getOrCreate(AccessibilityRole::SliderThumb));
88 thumb.setParent(this);
89
90 // Before actually adding the value indicator to the hierarchy,
91 // allow the platform to make a final decision about it.
92 if (thumb.accessibilityIsIgnored())
93 cache->remove(thumb.axObjectID());
94 else
95 m_children.append(&thumb);
96}
97
98const AtomicString& AccessibilitySlider::getAttribute(const QualifiedName& attribute) const
99{
100 return inputElement()->getAttribute(attribute);
101}
102
103AccessibilityObject* AccessibilitySlider::elementAccessibilityHitTest(const IntPoint& point) const
104{
105 if (m_children.size()) {
106 ASSERT(m_children.size() == 1);
107 if (m_children[0]->elementRect().contains(point))
108 return m_children[0].get();
109 }
110
111 return axObjectCache()->getOrCreate(renderer());
112}
113
114float AccessibilitySlider::valueForRange() const
115{
116 return inputElement()->value().toFloat();
117}
118
119float AccessibilitySlider::maxValueForRange() const
120{
121 return static_cast<float>(inputElement()->maximum());
122}
123
124float AccessibilitySlider::minValueForRange() const
125{
126 return static_cast<float>(inputElement()->minimum());
127}
128
129void AccessibilitySlider::setValue(const String& value)
130{
131 HTMLInputElement* input = inputElement();
132
133 if (input->value() == value)
134 return;
135
136 input->setValue(value, DispatchChangeEvent);
137}
138
139HTMLInputElement* AccessibilitySlider::inputElement() const
140{
141 return downcast<HTMLInputElement>(m_renderer->node());
142}
143
144
145AccessibilitySliderThumb::AccessibilitySliderThumb()
146{
147}
148
149Ref<AccessibilitySliderThumb> AccessibilitySliderThumb::create()
150{
151 return adoptRef(*new AccessibilitySliderThumb());
152}
153
154LayoutRect AccessibilitySliderThumb::elementRect() const
155{
156 if (!m_parent)
157 return LayoutRect();
158
159 RenderObject* sliderRenderer = m_parent->renderer();
160 if (!sliderRenderer || !sliderRenderer->isSlider())
161 return LayoutRect();
162 if (auto* thumbRenderer = downcast<RenderSlider>(*sliderRenderer).element().sliderThumbElement()->renderer())
163 return thumbRenderer->absoluteBoundingBoxRect();
164 return LayoutRect();
165}
166
167bool AccessibilitySliderThumb::computeAccessibilityIsIgnored() const
168{
169 return accessibilityIsIgnoredByDefault();
170}
171
172} // namespace WebCore
173