1/* 2 * Copyright (C) 2010 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 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "AccessibilityMenuListPopup.h" 28 29#include "AXObjectCache.h" 30#include "AccessibilityMenuList.h" 31#include "AccessibilityMenuListOption.h" 32#include "HTMLNames.h" 33#include "HTMLOptionElement.h" 34#include "HTMLSelectElement.h" 35#include "RenderMenuList.h" 36 37namespace WebCore { 38 39using namespace HTMLNames; 40 41AccessibilityMenuListPopup::AccessibilityMenuListPopup() 42{ 43} 44 45bool AccessibilityMenuListPopup::isVisible() const 46{ 47 return false; 48} 49 50bool AccessibilityMenuListPopup::isOffScreen() const 51{ 52 if (!m_parent) 53 return true; 54 55 return m_parent->isCollapsed(); 56} 57 58bool AccessibilityMenuListPopup::isEnabled() const 59{ 60 if (!m_parent) 61 return false; 62 63 return m_parent->isEnabled(); 64} 65 66bool AccessibilityMenuListPopup::computeAccessibilityIsIgnored() const 67{ 68 return accessibilityIsIgnoredByDefault(); 69} 70 71AccessibilityMenuListOption* AccessibilityMenuListPopup::menuListOptionAccessibilityObject(HTMLElement* element) const 72{ 73 if (!element || !isHTMLOptionElement(element) || !element->inRenderedDocument()) 74 return 0; 75 76 AccessibilityObject* object = document()->axObjectCache()->getOrCreate(MenuListOptionRole); 77 ASSERT_WITH_SECURITY_IMPLICATION(object->isMenuListOption()); 78 79 AccessibilityMenuListOption* option = toAccessibilityMenuListOption(object); 80 option->setElement(element); 81 82 return option; 83} 84 85bool AccessibilityMenuListPopup::press() 86{ 87 if (!m_parent) 88 return false; 89 90 m_parent->press(); 91 return true; 92} 93 94void AccessibilityMenuListPopup::addChildren() 95{ 96 if (!m_parent) 97 return; 98 99 Node* selectNode = m_parent->node(); 100 if (!selectNode) 101 return; 102 103 m_haveChildren = true; 104 105 for (const auto& listItem : toHTMLSelectElement(selectNode)->listItems()) { 106 AccessibilityMenuListOption* option = menuListOptionAccessibilityObject(listItem); 107 if (option) { 108 option->setParent(this); 109 m_children.append(option); 110 } 111 } 112} 113 114void AccessibilityMenuListPopup::childrenChanged() 115{ 116 AXObjectCache* cache = axObjectCache(); 117 for (size_t i = m_children.size(); i > 0 ; --i) { 118 AccessibilityObject* child = m_children[i - 1].get(); 119 if (child->actionElement() && !child->actionElement()->inRenderedDocument()) { 120 child->detachFromParent(); 121 cache->remove(child->axObjectID()); 122 } 123 } 124 125 m_children.clear(); 126 m_haveChildren = false; 127 addChildren(); 128} 129 130void AccessibilityMenuListPopup::didUpdateActiveOption(int optionIndex) 131{ 132 ASSERT_ARG(optionIndex, optionIndex >= 0); 133 ASSERT_ARG(optionIndex, optionIndex < static_cast<int>(m_children.size())); 134 135 AXObjectCache* cache = axObjectCache(); 136 RefPtr<AccessibilityObject> child = m_children[optionIndex].get(); 137 138 cache->postNotification(child.get(), document(), AXObjectCache::AXFocusedUIElementChanged, TargetElement, PostSynchronously); 139 cache->postNotification(child.get(), document(), AXObjectCache::AXMenuListItemSelected, TargetElement, PostSynchronously); 140} 141 142} // namespace WebCore 143