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(MenuListOptionRole); | 74 AXObject* object = axObjectCache()->getOrCreate(element); |
| 75 if (!object) |
| 76 return 0; |
| 77 |
75 ASSERT_WITH_SECURITY_IMPLICATION(object->isMenuListOption()); | 78 ASSERT_WITH_SECURITY_IMPLICATION(object->isMenuListOption()); |
76 | 79 return toAXMenuListOption(object); |
77 AXMenuListOption* option = toAXMenuListOption(object); | |
78 option->setElement(element); | |
79 | |
80 return option; | |
81 } | 80 } |
82 | 81 |
83 int AXMenuListPopup::getSelectedIndex() const | 82 int AXMenuListPopup::getSelectedIndex() const |
84 { | 83 { |
| 84 if (!m_parent) |
| 85 return -1; |
| 86 |
85 Node* selectNode = m_parent->node(); | 87 Node* selectNode = m_parent->node(); |
86 if (!selectNode) | 88 if (!selectNode) |
87 return -1; | 89 return -1; |
88 | 90 |
89 HTMLSelectElement* htmlSelectElement = toHTMLSelectElement(selectNode); | 91 HTMLSelectElement* htmlSelectElement = toHTMLSelectElement(selectNode); |
90 return htmlSelectElement->selectedIndex(); | 92 return htmlSelectElement->selectedIndex(); |
91 } | 93 } |
92 | 94 |
93 bool AXMenuListPopup::press() const | 95 bool AXMenuListPopup::press() const |
94 { | 96 { |
95 if (!m_parent) | 97 if (!m_parent) |
96 return false; | 98 return false; |
97 | 99 |
98 m_parent->press(); | 100 m_parent->press(); |
99 return true; | 101 return true; |
100 } | 102 } |
101 | 103 |
102 void AXMenuListPopup::addChildren() | 104 void AXMenuListPopup::addChildren() |
103 { | 105 { |
104 if (!m_parent) | 106 if (!m_parent) |
105 return; | 107 return; |
106 | 108 |
107 Node* selectNode = m_parent->node(); | 109 Node* selectNode = m_parent->node(); |
108 if (!selectNode) | 110 if (!selectNode) |
109 return; | 111 return; |
110 | 112 |
111 HTMLSelectElement* htmlSelectElement = toHTMLSelectElement(selectNode); | 113 HTMLSelectElement* htmlSelectElement = toHTMLSelectElement(selectNode); |
112 m_haveChildren = true; | 114 m_haveChildren = true; |
113 | 115 |
114 m_activeIndex = getSelectedIndex(); | 116 if (m_activeIndex == -1) |
| 117 m_activeIndex = getSelectedIndex(); |
| 118 |
115 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = htmlSel
ectElement->listItems(); | 119 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = htmlSel
ectElement->listItems(); |
116 unsigned length = listItems.size(); | 120 unsigned length = listItems.size(); |
117 for (unsigned i = 0; i < length; i++) { | 121 for (unsigned i = 0; i < length; i++) { |
118 AXMenuListOption* option = menuListOptionAXObject(listItems[i]); | 122 AXMenuListOption* option = menuListOptionAXObject(listItems[i]); |
119 if (option) { | 123 if (option) { |
120 option->setParent(this); | 124 option->setParent(this); |
121 m_children.append(option); | 125 m_children.append(option); |
122 } | 126 } |
123 } | 127 } |
124 } | 128 } |
125 | 129 |
126 void AXMenuListPopup::childrenChanged() | 130 void AXMenuListPopup::updateChildrenIfNecessary() |
127 { | 131 { |
128 AXObjectCacheImpl* cache = axObjectCache(); | 132 if (m_haveChildren && m_parent && m_parent->needsToUpdateChildren()) |
129 if (!cache) | 133 clearChildren(); |
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 } | |
140 | 134 |
141 m_children.clear(); | 135 if (!m_haveChildren) |
142 m_haveChildren = false; | 136 addChildren(); |
143 } | 137 } |
144 | 138 |
145 void AXMenuListPopup::didUpdateActiveOption(int optionIndex) | 139 void AXMenuListPopup::didUpdateActiveOption(int optionIndex) |
146 { | 140 { |
147 // We defer creation of the children until updating the active option so tha
t we don't | 141 updateChildrenIfNecessary(); |
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())); | |
154 | 142 |
155 AXObjectCacheImpl* cache = axObjectCache(); | 143 AXObjectCacheImpl* cache = axObjectCache(); |
156 if (m_activeIndex != optionIndex && m_activeIndex >= 0 && m_activeIndex < st
atic_cast<int>(m_children.size())) { | 144 if (m_activeIndex != optionIndex && m_activeIndex >= 0 && m_activeIndex < st
atic_cast<int>(m_children.size())) { |
157 RefPtr<AXObject> previousChild = m_children[m_activeIndex].get(); | 145 RefPtr<AXObject> previousChild = m_children[m_activeIndex].get(); |
158 cache->postNotification(previousChild.get(), AXObjectCacheImpl::AXMenuLi
stItemUnselected); | 146 cache->postNotification(previousChild.get(), AXObjectCacheImpl::AXMenuLi
stItemUnselected); |
159 } | 147 } |
160 | 148 |
161 RefPtr<AXObject> child = m_children[optionIndex].get(); | 149 if (optionIndex >= 0 && optionIndex < static_cast<int>(m_children.size())) { |
162 cache->postNotification(child.get(), AXObjectCacheImpl::AXFocusedUIElementCh
anged); | 150 RefPtr<AXObject> child = m_children[optionIndex].get(); |
163 cache->postNotification(child.get(), AXObjectCacheImpl::AXMenuListItemSelect
ed); | 151 cache->postNotification(child.get(), AXObjectCacheImpl::AXFocusedUIEleme
ntChanged); |
| 152 cache->postNotification(child.get(), AXObjectCacheImpl::AXMenuListItemSe
lected); |
| 153 } |
| 154 |
164 m_activeIndex = optionIndex; | 155 m_activeIndex = optionIndex; |
165 } | 156 } |
166 | 157 |
167 void AXMenuListPopup::didHide() | 158 void AXMenuListPopup::didHide() |
168 { | 159 { |
169 AXObjectCacheImpl* cache = axObjectCache(); | 160 AXObjectCacheImpl* cache = axObjectCache(); |
170 cache->postNotification(this, AXObjectCacheImpl::AXHide); | 161 cache->postNotification(this, AXObjectCacheImpl::AXHide); |
171 if (activeChild()) | 162 if (activeChild()) |
172 cache->postNotification(activeChild(), AXObjectCacheImpl::AXMenuListItem
Unselected); | 163 cache->postNotification(activeChild(), AXObjectCacheImpl::AXMenuListItem
Unselected); |
173 } | 164 } |
(...skipping 14 matching lines...) Expand all Loading... |
188 | 179 |
189 AXObject* AXMenuListPopup::activeChild() | 180 AXObject* AXMenuListPopup::activeChild() |
190 { | 181 { |
191 if (m_activeIndex < 0 || m_activeIndex >= static_cast<int>(children().size()
)) | 182 if (m_activeIndex < 0 || m_activeIndex >= static_cast<int>(children().size()
)) |
192 return nullptr; | 183 return nullptr; |
193 | 184 |
194 return m_children[m_activeIndex].get(); | 185 return m_children[m_activeIndex].get(); |
195 } | 186 } |
196 | 187 |
197 } // namespace blink | 188 } // namespace blink |
OLD | NEW |