1 /*
2 * Copyright (C) 2008 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 #include "config.h"
30 #include "AccessibilityListBoxOption.h"
31
32 #include "AXObjectCache.h"
33 #include "AccessibilityListBox.h"
34 #include "Element.h"
35 #include "HTMLElement.h"
36 #include "HTMLNames.h"
37 #include "HTMLOptionElement.h"
38 #include "HTMLOptGroupElement.h"
39 #include "HTMLSelectElement.h"
40 #include "IntRect.h"
41 #include "RenderObject.h"
42 #include "RenderListBox.h"
43
44 using namespace std;
45
46 namespace WebCore {
47
48 using namespace HTMLNames;
49
AccessibilityListBoxOption()50 AccessibilityListBoxOption::AccessibilityListBoxOption()
51 : m_optionElement(0)
52 {
53 }
54
~AccessibilityListBoxOption()55 AccessibilityListBoxOption::~AccessibilityListBoxOption()
56 {
57 }
58
create()59 PassRefPtr<AccessibilityListBoxOption> AccessibilityListBoxOption::create()
60 {
61 return adoptRef(new AccessibilityListBoxOption());
62 }
63
isEnabled() const64 bool AccessibilityListBoxOption::isEnabled() const
65 {
66 if (!m_optionElement)
67 return false;
68
69 if (m_optionElement->hasTagName(optgroupTag))
70 return false;
71
72 return true;
73 }
74
isSelected() const75 bool AccessibilityListBoxOption::isSelected() const
76 {
77 if (!m_optionElement)
78 return false;
79
80 if (!m_optionElement->hasTagName(optionTag))
81 return false;
82
83 return static_cast<HTMLOptionElement*>(m_optionElement)->selected();
84 }
85
elementRect() const86 IntRect AccessibilityListBoxOption::elementRect() const
87 {
88 IntRect rect;
89 if (!m_optionElement)
90 return rect;
91
92 HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode();
93 if (!listBoxParentNode)
94 return rect;
95
96 RenderObject* listBoxRenderer = listBoxParentNode->renderer();
97 if (!listBoxRenderer)
98 return rect;
99
100 IntRect parentRect = listBoxRenderer->document()->axObjectCache()->getOrCreate(listBoxRenderer)->boundingBoxRect();
101 int index = listBoxOptionIndex();
102 if (index != -1)
103 rect = toRenderListBox(listBoxRenderer)->itemBoundingBoxRect(parentRect.x(), parentRect.y(), index);
104
105 return rect;
106 }
107
canSetSelectedAttribute() const108 bool AccessibilityListBoxOption::canSetSelectedAttribute() const
109 {
110 if (!m_optionElement)
111 return false;
112
113 if (!m_optionElement->hasTagName(optionTag))
114 return false;
115
116 if (m_optionElement->disabled())
117 return false;
118
119 HTMLSelectElement* selectElement = listBoxOptionParentNode();
120 if (selectElement && selectElement->disabled())
121 return false;
122
123 return true;
124 }
125
stringValue() const126 String AccessibilityListBoxOption::stringValue() const
127 {
128 if (!m_optionElement)
129 return String();
130
131 if (m_optionElement->hasTagName(optionTag))
132 return static_cast<HTMLOptionElement*>(m_optionElement)->text();
133
134 if (m_optionElement->hasTagName(optgroupTag))
135 return static_cast<HTMLOptGroupElement*>(m_optionElement)->groupLabelText();
136
137 return String();
138 }
139
size() const140 IntSize AccessibilityListBoxOption::size() const
141 {
142 return elementRect().size();
143 }
144
actionElement() const145 Element* AccessibilityListBoxOption::actionElement() const
146 {
147 return m_optionElement;
148 }
149
parentObject() const150 AccessibilityObject* AccessibilityListBoxOption::parentObject() const
151 {
152 HTMLSelectElement* parentNode = listBoxOptionParentNode();
153 if (!parentNode)
154 return 0;
155
156 return m_optionElement->document()->axObjectCache()->getOrCreate(parentNode->renderer());
157 }
158
setSelected(bool selected)159 void AccessibilityListBoxOption::setSelected(bool selected)
160 {
161 HTMLSelectElement* selectElement = listBoxOptionParentNode();
162 if (!selectElement)
163 return;
164
165 if (!canSetSelectedAttribute())
166 return;
167
168 bool isOptionSelected = isSelected();
169 if ((isOptionSelected && selected) || (!isOptionSelected && !selected))
170 return;
171
172 selectElement->accessKeySetSelectedIndex(listBoxOptionIndex());
173 }
174
listBoxOptionParentNode() const175 HTMLSelectElement* AccessibilityListBoxOption::listBoxOptionParentNode() const
176 {
177 if (!m_optionElement)
178 return 0;
179
180 if (m_optionElement->hasTagName(optionTag))
181 return static_cast<HTMLOptionElement*>(m_optionElement)->ownerSelectElement();
182
183 if (m_optionElement->hasTagName(optgroupTag))
184 return static_cast<HTMLOptGroupElement*>(m_optionElement)->ownerSelectElement();
185
186 return 0;
187 }
188
listBoxOptionIndex() const189 int AccessibilityListBoxOption::listBoxOptionIndex() const
190 {
191 if (!m_optionElement)
192 return -1;
193
194 HTMLSelectElement* selectElement = listBoxOptionParentNode();
195 if (!selectElement)
196 return -1;
197
198 const Vector<Element*>& listItems = selectElement->listItems();
199 unsigned length = listItems.size();
200 for (unsigned i = 0; i < length; i++)
201 if (listItems[i] == m_optionElement)
202 return i;
203
204 return -1;
205 }
206
207 } // namespace WebCore
208