| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2010 Apple Inc. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 { | 64 { |
| 65 return accessibilityIsIgnoredByDefault(); | 65 return accessibilityIsIgnoredByDefault(); |
| 66 } | 66 } |
| 67 | 67 |
| 68 AXMenuListOption* AXMenuListPopup::menuListOptionAXObject(HTMLElement* element)
const | 68 AXMenuListOption* AXMenuListPopup::menuListOptionAXObject(HTMLElement* element)
const |
| 69 { | 69 { |
| 70 ASSERT(element); | 70 ASSERT(element); |
| 71 if (!isHTMLOptionElement(*element)) | 71 if (!isHTMLOptionElement(*element)) |
| 72 return 0; | 72 return 0; |
| 73 | 73 |
| 74 AXObject* object = axObjectCache()->getOrCreate(element); | 74 AXObject* object = axObjectCache()->getOrCreate(MenuListOptionRole); |
| 75 if (!object) | 75 ASSERT_WITH_SECURITY_IMPLICATION(object->isMenuListOption()); |
| 76 return 0; | |
| 77 | 76 |
| 78 ASSERT_WITH_SECURITY_IMPLICATION(object->isMenuListOption()); | 77 AXMenuListOption* option = toAXMenuListOption(object); |
| 79 return toAXMenuListOption(object); | 78 option->setElement(element); |
| 79 |
| 80 return option; |
| 80 } | 81 } |
| 81 | 82 |
| 82 int AXMenuListPopup::getSelectedIndex() const | 83 int AXMenuListPopup::getSelectedIndex() const |
| 83 { | 84 { |
| 84 if (!m_parent) | |
| 85 return -1; | |
| 86 | |
| 87 Node* selectNode = m_parent->node(); | 85 Node* selectNode = m_parent->node(); |
| 88 if (!selectNode) | 86 if (!selectNode) |
| 89 return -1; | 87 return -1; |
| 90 | 88 |
| 91 HTMLSelectElement* htmlSelectElement = toHTMLSelectElement(selectNode); | 89 HTMLSelectElement* htmlSelectElement = toHTMLSelectElement(selectNode); |
| 92 return htmlSelectElement->selectedIndex(); | 90 return htmlSelectElement->selectedIndex(); |
| 93 } | 91 } |
| 94 | 92 |
| 95 bool AXMenuListPopup::press() const | 93 bool AXMenuListPopup::press() const |
| 96 { | 94 { |
| 97 if (!m_parent) | 95 if (!m_parent) |
| 98 return false; | 96 return false; |
| 99 | 97 |
| 100 m_parent->press(); | 98 m_parent->press(); |
| 101 return true; | 99 return true; |
| 102 } | 100 } |
| 103 | 101 |
| 104 void AXMenuListPopup::addChildren() | 102 void AXMenuListPopup::addChildren() |
| 105 { | 103 { |
| 106 if (!m_parent) | 104 if (!m_parent) |
| 107 return; | 105 return; |
| 108 | 106 |
| 109 Node* selectNode = m_parent->node(); | 107 Node* selectNode = m_parent->node(); |
| 110 if (!selectNode) | 108 if (!selectNode) |
| 111 return; | 109 return; |
| 112 | 110 |
| 113 HTMLSelectElement* htmlSelectElement = toHTMLSelectElement(selectNode); | 111 HTMLSelectElement* htmlSelectElement = toHTMLSelectElement(selectNode); |
| 114 m_haveChildren = true; | 112 m_haveChildren = true; |
| 115 | 113 |
| 116 if (m_activeIndex == -1) | 114 m_activeIndex = getSelectedIndex(); |
| 117 m_activeIndex = getSelectedIndex(); | |
| 118 | |
| 119 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = htmlSel
ectElement->listItems(); | 115 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = htmlSel
ectElement->listItems(); |
| 120 unsigned length = listItems.size(); | 116 unsigned length = listItems.size(); |
| 121 for (unsigned i = 0; i < length; i++) { | 117 for (unsigned i = 0; i < length; i++) { |
| 122 AXMenuListOption* option = menuListOptionAXObject(listItems[i]); | 118 AXMenuListOption* option = menuListOptionAXObject(listItems[i]); |
| 123 if (option) { | 119 if (option) { |
| 124 option->setParent(this); | 120 option->setParent(this); |
| 125 m_children.append(option); | 121 m_children.append(option); |
| 126 } | 122 } |
| 127 } | 123 } |
| 128 } | 124 } |
| 129 | 125 |
| 130 void AXMenuListPopup::updateChildrenIfNecessary() | 126 void AXMenuListPopup::childrenChanged() |
| 131 { | 127 { |
| 132 if (m_haveChildren && m_parent && m_parent->needsToUpdateChildren()) | 128 AXObjectCacheImpl* cache = axObjectCache(); |
| 133 clearChildren(); | 129 if (!cache) |
| 130 return; |
| 131 for (size_t i = m_children.size(); i > 0 ; --i) { |
| 132 AXObject* child = m_children[i - 1].get(); |
| 133 // FIXME: How could children end up in here that have no actionElement()
, the check |
| 134 // in menuListOptionAXObject would seem to prevent that. |
| 135 if (child->actionElement()) { |
| 136 child->detachFromParent(); |
| 137 cache->remove(child->axObjectID()); |
| 138 } |
| 139 } |
| 134 | 140 |
| 135 if (!m_haveChildren) | 141 m_children.clear(); |
| 136 addChildren(); | 142 m_haveChildren = false; |
| 137 } | 143 } |
| 138 | 144 |
| 139 void AXMenuListPopup::didUpdateActiveOption(int optionIndex) | 145 void AXMenuListPopup::didUpdateActiveOption(int optionIndex) |
| 140 { | 146 { |
| 141 updateChildrenIfNecessary(); | 147 // We defer creation of the children until updating the active option so tha
t we don't |
| 148 // create AXObjects for <option> elements while they're in the middle of rem
oval. |
| 149 if (!m_haveChildren) |
| 150 addChildren(); |
| 151 |
| 152 ASSERT_ARG(optionIndex, optionIndex >= 0); |
| 153 ASSERT_ARG(optionIndex, optionIndex < static_cast<int>(m_children.size())); |
| 142 | 154 |
| 143 AXObjectCacheImpl* cache = axObjectCache(); | 155 AXObjectCacheImpl* cache = axObjectCache(); |
| 144 if (m_activeIndex != optionIndex && m_activeIndex >= 0 && m_activeIndex < st
atic_cast<int>(m_children.size())) { | 156 if (m_activeIndex != optionIndex && m_activeIndex >= 0 && m_activeIndex < st
atic_cast<int>(m_children.size())) { |
| 145 RefPtr<AXObject> previousChild = m_children[m_activeIndex].get(); | 157 RefPtr<AXObject> previousChild = m_children[m_activeIndex].get(); |
| 146 cache->postNotification(previousChild.get(), AXObjectCacheImpl::AXMenuLi
stItemUnselected); | 158 cache->postNotification(previousChild.get(), AXObjectCacheImpl::AXMenuLi
stItemUnselected); |
| 147 } | 159 } |
| 148 | 160 |
| 149 if (optionIndex >= 0 && optionIndex < static_cast<int>(m_children.size())) { | 161 RefPtr<AXObject> child = m_children[optionIndex].get(); |
| 150 RefPtr<AXObject> child = m_children[optionIndex].get(); | 162 cache->postNotification(child.get(), AXObjectCacheImpl::AXFocusedUIElementCh
anged); |
| 151 cache->postNotification(child.get(), AXObjectCacheImpl::AXFocusedUIEleme
ntChanged); | 163 cache->postNotification(child.get(), AXObjectCacheImpl::AXMenuListItemSelect
ed); |
| 152 cache->postNotification(child.get(), AXObjectCacheImpl::AXMenuListItemSe
lected); | |
| 153 } | |
| 154 | |
| 155 m_activeIndex = optionIndex; | 164 m_activeIndex = optionIndex; |
| 156 } | 165 } |
| 157 | 166 |
| 158 void AXMenuListPopup::didHide() | 167 void AXMenuListPopup::didHide() |
| 159 { | 168 { |
| 160 AXObjectCacheImpl* cache = axObjectCache(); | 169 AXObjectCacheImpl* cache = axObjectCache(); |
| 161 cache->postNotification(this, AXObjectCacheImpl::AXHide); | 170 cache->postNotification(this, AXObjectCacheImpl::AXHide); |
| 162 if (activeChild()) | 171 if (activeChild()) |
| 163 cache->postNotification(activeChild(), AXObjectCacheImpl::AXMenuListItem
Unselected); | 172 cache->postNotification(activeChild(), AXObjectCacheImpl::AXMenuListItem
Unselected); |
| 164 } | 173 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 179 | 188 |
| 180 AXObject* AXMenuListPopup::activeChild() | 189 AXObject* AXMenuListPopup::activeChild() |
| 181 { | 190 { |
| 182 if (m_activeIndex < 0 || m_activeIndex >= static_cast<int>(children().size()
)) | 191 if (m_activeIndex < 0 || m_activeIndex >= static_cast<int>(children().size()
)) |
| 183 return nullptr; | 192 return nullptr; |
| 184 | 193 |
| 185 return m_children[m_activeIndex].get(); | 194 return m_children[m_activeIndex].get(); |
| 186 } | 195 } |
| 187 | 196 |
| 188 } // namespace blink | 197 } // namespace blink |
| OLD | NEW |