2 * Copyright (C) 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
30 #include "AccessibilityListBox.h"
32 #include "AXObjectCache.h"
33 #include "AccessibilityListBoxOption.h"
34 #include "HTMLNames.h"
35 #include "HTMLSelectElement.h"
36 #include "HitTestResult.h"
37 #include "RenderListBox.h"
38 #include "RenderObject.h"
44 using namespace HTMLNames;
46 AccessibilityListBox::AccessibilityListBox(RenderObject* renderer)
47 : AccessibilityRenderObject(renderer)
51 AccessibilityListBox::~AccessibilityListBox()
55 PassRefPtr<AccessibilityListBox> AccessibilityListBox::create(RenderObject* renderer)
57 AccessibilityListBox* obj = new AccessibilityListBox(renderer);
62 bool AccessibilityListBox::canSetSelectedChildrenAttribute() const
64 Node* selectNode = m_renderer->node();
68 return !toHTMLSelectElement(selectNode)->disabled();
71 void AccessibilityListBox::addChildren()
73 Node* selectNode = m_renderer->node();
77 m_haveChildren = true;
79 const Vector<HTMLElement*>& listItems = toHTMLSelectElement(selectNode)->listItems();
80 unsigned length = listItems.size();
81 for (unsigned i = 0; i < length; i++) {
82 // The cast to HTMLElement below is safe because the only other possible listItem type
83 // would be a WMLElement, but WML builds don't use accessibility features at all.
84 AccessibilityObject* listOption = listBoxOptionAccessibilityObject(listItems[i]);
85 if (listOption && !listOption->accessibilityIsIgnored())
86 m_children.append(listOption);
90 void AccessibilityListBox::setSelectedChildren(AccessibilityChildrenVector& children)
92 if (!canSetSelectedChildrenAttribute())
95 Node* selectNode = m_renderer->node();
99 // disable any selected options
100 unsigned length = m_children.size();
101 for (unsigned i = 0; i < length; i++) {
102 AccessibilityListBoxOption* listBoxOption = static_cast<AccessibilityListBoxOption*>(m_children[i].get());
103 if (listBoxOption->isSelected())
104 listBoxOption->setSelected(false);
107 length = children.size();
108 for (unsigned i = 0; i < length; i++) {
109 AccessibilityObject* obj = children[i].get();
110 if (obj->roleValue() != ListBoxOptionRole)
113 static_cast<AccessibilityListBoxOption*>(obj)->setSelected(true);
117 void AccessibilityListBox::selectedChildren(AccessibilityChildrenVector& result)
119 ASSERT(result.isEmpty());
124 unsigned length = m_children.size();
125 for (unsigned i = 0; i < length; i++) {
126 if (static_cast<AccessibilityListBoxOption*>(m_children[i].get())->isSelected())
127 result.append(m_children[i]);
131 void AccessibilityListBox::visibleChildren(AccessibilityChildrenVector& result)
133 ASSERT(result.isEmpty());
138 unsigned length = m_children.size();
139 for (unsigned i = 0; i < length; i++) {
140 if (toRenderListBox(m_renderer)->listIndexIsVisible(i))
141 result.append(m_children[i]);
145 AccessibilityObject* AccessibilityListBox::listBoxOptionAccessibilityObject(HTMLElement* element) const
148 if (!element || element->hasTagName(hrTag))
151 AccessibilityObject* listBoxObject = m_renderer->document()->axObjectCache()->getOrCreate(ListBoxOptionRole);
152 static_cast<AccessibilityListBoxOption*>(listBoxObject)->setHTMLElement(element);
154 return listBoxObject;
157 bool AccessibilityListBox::accessibilityIsIgnored() const
159 AccessibilityObjectInclusion decision = accessibilityIsIgnoredBase();
160 if (decision == IncludeObject)
162 if (decision == IgnoreObject)
168 AccessibilityObject* AccessibilityListBox::elementAccessibilityHitTest(const IntPoint& point) const
170 // the internal HTMLSelectElement methods for returning a listbox option at a point
171 // ignore optgroup elements.
175 Node* node = m_renderer->node();
179 LayoutRect parentRect = boundingBoxRect();
181 AccessibilityObject* listBoxOption = 0;
182 unsigned length = m_children.size();
183 for (unsigned i = 0; i < length; i++) {
184 LayoutRect rect = toRenderListBox(m_renderer)->itemBoundingBoxRect(parentRect.location(), i);
185 // The cast to HTMLElement below is safe because the only other possible listItem type
186 // would be a WMLElement, but WML builds don't use accessibility features at all.
187 if (rect.contains(point)) {
188 listBoxOption = m_children[i].get();
193 if (listBoxOption && !listBoxOption->accessibilityIsIgnored())
194 return listBoxOption;
196 return axObjectCache()->getOrCreate(m_renderer);
199 } // namespace WebCore