.: Replace "Apple Computer, Inc." with "Apple Inc." in copyright headers
[WebKit-https.git] / Source / WebCore / accessibility / AccessibilityListBoxOption.cpp
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 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 "HTMLOptGroupElement.h"
38 #include "HTMLOptionElement.h"
39 #include "HTMLSelectElement.h"
40 #include "IntRect.h"
41 #include "RenderListBox.h"
42 #include "RenderObject.h"
43
44 namespace WebCore {
45
46 using namespace HTMLNames;
47     
48 AccessibilityListBoxOption::AccessibilityListBoxOption()
49     : m_optionElement(0)
50 {
51 }
52
53 AccessibilityListBoxOption::~AccessibilityListBoxOption()
54 {
55 }    
56     
57 PassRefPtr<AccessibilityListBoxOption> AccessibilityListBoxOption::create()
58 {
59     return adoptRef(new AccessibilityListBoxOption());
60 }
61     
62 bool AccessibilityListBoxOption::isEnabled() const
63 {
64     if (!m_optionElement)
65         return false;
66     
67     if (isHTMLOptGroupElement(m_optionElement))
68         return false;
69
70     if (equalIgnoringCase(getAttribute(aria_disabledAttr), "true"))
71         return false;
72
73     if (m_optionElement->hasAttribute(disabledAttr))
74         return false;
75     
76     return true;
77 }
78     
79 bool AccessibilityListBoxOption::isSelected() const
80 {
81     if (!m_optionElement)
82         return false;
83
84     if (!isHTMLOptionElement(m_optionElement))
85         return false;
86
87     return toHTMLOptionElement(m_optionElement)->selected();
88 }
89
90 bool AccessibilityListBoxOption::isSelectedOptionActive() const
91 {
92     HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode();
93     if (!listBoxParentNode)
94         return false;
95
96     return listBoxParentNode->activeSelectionEndListIndex() == listBoxOptionIndex();
97 }
98
99 LayoutRect AccessibilityListBoxOption::elementRect() const
100 {
101     LayoutRect rect;
102     if (!m_optionElement)
103         return rect;
104     
105     HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode();
106     if (!listBoxParentNode)
107         return rect;
108     
109     RenderObject* listBoxRenderer = listBoxParentNode->renderer();
110     if (!listBoxRenderer)
111         return rect;
112     
113     LayoutRect parentRect = listBoxRenderer->document().axObjectCache()->getOrCreate(listBoxRenderer)->boundingBoxRect();
114     int index = listBoxOptionIndex();
115     if (index != -1)
116         rect = toRenderListBox(listBoxRenderer)->itemBoundingBoxRect(parentRect.location(), index);
117     
118     return rect;
119 }
120
121 bool AccessibilityListBoxOption::computeAccessibilityIsIgnored() const
122 {
123     if (!m_optionElement)
124         return true;
125
126     if (accessibilityIsIgnoredByDefault())
127         return true;
128     
129     return parentObject()->accessibilityIsIgnored();
130 }
131     
132 bool AccessibilityListBoxOption::canSetSelectedAttribute() const
133 {
134     if (!m_optionElement)
135         return false;
136     
137     if (!isHTMLOptionElement(m_optionElement))
138         return false;
139     
140     if (m_optionElement->isDisabledFormControl())
141         return false;
142     
143     HTMLSelectElement* selectElement = listBoxOptionParentNode();
144     if (selectElement && selectElement->isDisabledFormControl())
145         return false;
146     
147     return true;
148 }
149     
150 String AccessibilityListBoxOption::stringValue() const
151 {
152     if (!m_optionElement)
153         return String();
154     
155     const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
156     if (!ariaLabel.isNull())
157         return ariaLabel;
158     
159     if (isHTMLOptionElement(m_optionElement))
160         return toHTMLOptionElement(m_optionElement)->text();
161     
162     if (isHTMLOptGroupElement(m_optionElement))
163         return toHTMLOptGroupElement(m_optionElement)->groupLabelText();
164     
165     return String();
166 }
167
168 Element* AccessibilityListBoxOption::actionElement() const
169 {
170     return m_optionElement;
171 }
172
173 AccessibilityObject* AccessibilityListBoxOption::parentObject() const
174 {
175     HTMLSelectElement* parentNode = listBoxOptionParentNode();
176     if (!parentNode)
177         return 0;
178     
179     return m_optionElement->document().axObjectCache()->getOrCreate(parentNode);
180 }
181
182 void AccessibilityListBoxOption::setSelected(bool selected)
183 {
184     HTMLSelectElement* selectElement = listBoxOptionParentNode();
185     if (!selectElement)
186         return;
187     
188     if (!canSetSelectedAttribute())
189         return;
190     
191     bool isOptionSelected = isSelected();
192     if ((isOptionSelected && selected) || (!isOptionSelected && !selected))
193         return;
194     
195     // Convert from the entire list index to the option index.
196     int optionIndex = selectElement->listToOptionIndex(listBoxOptionIndex());
197     selectElement->accessKeySetSelectedIndex(optionIndex);
198 }
199
200 HTMLSelectElement* AccessibilityListBoxOption::listBoxOptionParentNode() const
201 {
202     if (!m_optionElement)
203         return 0;
204
205     if (isHTMLOptionElement(m_optionElement))
206         return toHTMLOptionElement(m_optionElement)->ownerSelectElement();
207
208     if (isHTMLOptGroupElement(m_optionElement))
209         return toHTMLOptGroupElement(m_optionElement)->ownerSelectElement();
210
211     return 0;
212 }
213
214 int AccessibilityListBoxOption::listBoxOptionIndex() const
215 {
216     if (!m_optionElement)
217         return -1;
218     
219     HTMLSelectElement* selectElement = listBoxOptionParentNode();
220     if (!selectElement) 
221         return -1;
222     
223     const auto& listItems = selectElement->listItems();
224     unsigned length = listItems.size();
225     for (unsigned i = 0; i < length; i++)
226         if (listItems[i] == m_optionElement)
227             return i;
228
229     return -1;
230 }
231
232 } // namespace WebCore