OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2014, Google Inc. All rights reserved. | 2 * Copyright (C) 2014, Google 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 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 AXObjectCacheImpl::~AXObjectCacheImpl() { | 102 AXObjectCacheImpl::~AXObjectCacheImpl() { |
103 #if DCHECK_IS_ON() | 103 #if DCHECK_IS_ON() |
104 DCHECK(has_been_disposed_); | 104 DCHECK(has_been_disposed_); |
105 #endif | 105 #endif |
106 } | 106 } |
107 | 107 |
108 void AXObjectCacheImpl::Dispose() { | 108 void AXObjectCacheImpl::Dispose() { |
109 notification_post_timer_.Stop(); | 109 notification_post_timer_.Stop(); |
110 | 110 |
111 for (auto& entry : objects_) { | 111 for (auto& entry : objects_) { |
112 AXObjectImpl* obj = entry.value; | 112 AXObject* obj = entry.value; |
113 obj->Detach(); | 113 obj->Detach(); |
114 RemoveAXID(obj); | 114 RemoveAXID(obj); |
115 } | 115 } |
116 | 116 |
117 #if DCHECK_IS_ON() | 117 #if DCHECK_IS_ON() |
118 has_been_disposed_ = true; | 118 has_been_disposed_ = true; |
119 #endif | 119 #endif |
120 } | 120 } |
121 | 121 |
122 AXObjectImpl* AXObjectCacheImpl::Root() { | 122 AXObject* AXObjectCacheImpl::Root() { |
123 return GetOrCreate(document_); | 123 return GetOrCreate(document_); |
124 } | 124 } |
125 | 125 |
126 AXObjectImpl* AXObjectCacheImpl::FocusedImageMapUIElement( | 126 AXObject* AXObjectCacheImpl::FocusedImageMapUIElement( |
127 HTMLAreaElement* area_element) { | 127 HTMLAreaElement* area_element) { |
128 // Find the corresponding accessibility object for the HTMLAreaElement. This | 128 // Find the corresponding accessibility object for the HTMLAreaElement. This |
129 // should be in the list of children for its corresponding image. | 129 // should be in the list of children for its corresponding image. |
130 if (!area_element) | 130 if (!area_element) |
131 return 0; | 131 return 0; |
132 | 132 |
133 HTMLImageElement* image_element = area_element->ImageElement(); | 133 HTMLImageElement* image_element = area_element->ImageElement(); |
134 if (!image_element) | 134 if (!image_element) |
135 return 0; | 135 return 0; |
136 | 136 |
137 AXObjectImpl* ax_layout_image = GetOrCreate(image_element); | 137 AXObject* ax_layout_image = GetOrCreate(image_element); |
138 if (!ax_layout_image) | 138 if (!ax_layout_image) |
139 return 0; | 139 return 0; |
140 | 140 |
141 const AXObjectImpl::AXObjectVector& image_children = | 141 const AXObject::AXObjectVector& image_children = ax_layout_image->Children(); |
142 ax_layout_image->Children(); | |
143 unsigned count = image_children.size(); | 142 unsigned count = image_children.size(); |
144 for (unsigned k = 0; k < count; ++k) { | 143 for (unsigned k = 0; k < count; ++k) { |
145 AXObjectImpl* child = image_children[k]; | 144 AXObject* child = image_children[k]; |
146 if (!child->IsImageMapLink()) | 145 if (!child->IsImageMapLink()) |
147 continue; | 146 continue; |
148 | 147 |
149 if (ToAXImageMapLink(child)->AreaElement() == area_element) | 148 if (ToAXImageMapLink(child)->AreaElement() == area_element) |
150 return child; | 149 return child; |
151 } | 150 } |
152 | 151 |
153 return 0; | 152 return 0; |
154 } | 153 } |
155 | 154 |
156 AXObjectImpl* AXObjectCacheImpl::FocusedObject() { | 155 AXObject* AXObjectCacheImpl::FocusedObject() { |
157 if (!AccessibilityEnabled()) | 156 if (!AccessibilityEnabled()) |
158 return nullptr; | 157 return nullptr; |
159 | 158 |
160 Node* focused_node = document_->FocusedElement(); | 159 Node* focused_node = document_->FocusedElement(); |
161 if (!focused_node) | 160 if (!focused_node) |
162 focused_node = document_; | 161 focused_node = document_; |
163 | 162 |
164 // If it's an image map, get the focused link within the image map. | 163 // If it's an image map, get the focused link within the image map. |
165 if (isHTMLAreaElement(focused_node)) | 164 if (isHTMLAreaElement(focused_node)) |
166 return FocusedImageMapUIElement(toHTMLAreaElement(focused_node)); | 165 return FocusedImageMapUIElement(toHTMLAreaElement(focused_node)); |
167 | 166 |
168 // See if there's a page popup, for example a calendar picker. | 167 // See if there's a page popup, for example a calendar picker. |
169 Element* adjusted_focused_element = document_->AdjustedFocusedElement(); | 168 Element* adjusted_focused_element = document_->AdjustedFocusedElement(); |
170 if (isHTMLInputElement(adjusted_focused_element)) { | 169 if (isHTMLInputElement(adjusted_focused_element)) { |
171 if (AXObjectImpl* ax_popup = | 170 if (AXObject* ax_popup = |
172 toHTMLInputElement(adjusted_focused_element)->PopupRootAXObject()) { | 171 toHTMLInputElement(adjusted_focused_element)->PopupRootAXObject()) { |
173 if (Element* focused_element_in_popup = | 172 if (Element* focused_element_in_popup = |
174 ax_popup->GetDocument()->FocusedElement()) | 173 ax_popup->GetDocument()->FocusedElement()) |
175 focused_node = focused_element_in_popup; | 174 focused_node = focused_element_in_popup; |
176 } | 175 } |
177 } | 176 } |
178 | 177 |
179 AXObjectImpl* obj = GetOrCreate(focused_node); | 178 AXObject* obj = GetOrCreate(focused_node); |
180 if (!obj) | 179 if (!obj) |
181 return nullptr; | 180 return nullptr; |
182 | 181 |
183 // the HTML element, for example, is focusable but has an AX object that is | 182 // the HTML element, for example, is focusable but has an AX object that is |
184 // ignored | 183 // ignored |
185 if (obj->AccessibilityIsIgnored()) | 184 if (obj->AccessibilityIsIgnored()) |
186 obj = obj->ParentObjectUnignored(); | 185 obj = obj->ParentObjectUnignored(); |
187 | 186 |
188 return obj; | 187 return obj; |
189 } | 188 } |
190 | 189 |
191 AXObjectImpl* AXObjectCacheImpl::Get(LayoutObject* layout_object) { | 190 AXObject* AXObjectCacheImpl::Get(LayoutObject* layout_object) { |
192 if (!layout_object) | 191 if (!layout_object) |
193 return 0; | 192 return 0; |
194 | 193 |
195 AXID ax_id = layout_object_mapping_.at(layout_object); | 194 AXID ax_id = layout_object_mapping_.at(layout_object); |
196 DCHECK(!HashTraits<AXID>::IsDeletedValue(ax_id)); | 195 DCHECK(!HashTraits<AXID>::IsDeletedValue(ax_id)); |
197 if (!ax_id) | 196 if (!ax_id) |
198 return 0; | 197 return 0; |
199 | 198 |
200 return objects_.at(ax_id); | 199 return objects_.at(ax_id); |
201 } | 200 } |
202 | 201 |
203 // Returns true if |node| is an <option> element and its parent <select> | 202 // Returns true if |node| is an <option> element and its parent <select> |
204 // is a menu list (not a list box). | 203 // is a menu list (not a list box). |
205 static bool IsMenuListOption(Node* node) { | 204 static bool IsMenuListOption(Node* node) { |
206 if (!isHTMLOptionElement(node)) | 205 if (!isHTMLOptionElement(node)) |
207 return false; | 206 return false; |
208 HTMLSelectElement* select = toHTMLOptionElement(node)->OwnerSelectElement(); | 207 HTMLSelectElement* select = toHTMLOptionElement(node)->OwnerSelectElement(); |
209 if (!select) | 208 if (!select) |
210 return false; | 209 return false; |
211 LayoutObject* layout_object = select->GetLayoutObject(); | 210 LayoutObject* layout_object = select->GetLayoutObject(); |
212 return layout_object && layout_object->IsMenuList(); | 211 return layout_object && layout_object->IsMenuList(); |
213 } | 212 } |
214 | 213 |
215 AXObjectImpl* AXObjectCacheImpl::Get(Node* node) { | 214 AXObject* AXObjectCacheImpl::Get(Node* node) { |
216 if (!node) | 215 if (!node) |
217 return 0; | 216 return 0; |
218 | 217 |
219 // Menu list option and HTML area elements are indexed by DOM node, never by | 218 // Menu list option and HTML area elements are indexed by DOM node, never by |
220 // layout object. | 219 // layout object. |
221 LayoutObject* layout_object = node->GetLayoutObject(); | 220 LayoutObject* layout_object = node->GetLayoutObject(); |
222 if (IsMenuListOption(node) || isHTMLAreaElement(node)) | 221 if (IsMenuListOption(node) || isHTMLAreaElement(node)) |
223 layout_object = nullptr; | 222 layout_object = nullptr; |
224 | 223 |
225 AXID layout_id = layout_object ? layout_object_mapping_.at(layout_object) : 0; | 224 AXID layout_id = layout_object ? layout_object_mapping_.at(layout_object) : 0; |
(...skipping 12 matching lines...) Expand all Loading... |
238 | 237 |
239 if (layout_id) | 238 if (layout_id) |
240 return objects_.at(layout_id); | 239 return objects_.at(layout_id); |
241 | 240 |
242 if (!node_id) | 241 if (!node_id) |
243 return 0; | 242 return 0; |
244 | 243 |
245 return objects_.at(node_id); | 244 return objects_.at(node_id); |
246 } | 245 } |
247 | 246 |
248 AXObjectImpl* AXObjectCacheImpl::Get(AbstractInlineTextBox* inline_text_box) { | 247 AXObject* AXObjectCacheImpl::Get(AbstractInlineTextBox* inline_text_box) { |
249 if (!inline_text_box) | 248 if (!inline_text_box) |
250 return 0; | 249 return 0; |
251 | 250 |
252 AXID ax_id = inline_text_box_object_mapping_.at(inline_text_box); | 251 AXID ax_id = inline_text_box_object_mapping_.at(inline_text_box); |
253 DCHECK(!HashTraits<AXID>::IsDeletedValue(ax_id)); | 252 DCHECK(!HashTraits<AXID>::IsDeletedValue(ax_id)); |
254 if (!ax_id) | 253 if (!ax_id) |
255 return 0; | 254 return 0; |
256 | 255 |
257 return objects_.at(ax_id); | 256 return objects_.at(ax_id); |
258 } | 257 } |
259 | 258 |
260 // FIXME: This probably belongs on Node. | 259 // FIXME: This probably belongs on Node. |
261 // FIXME: This should take a const char*, but one caller passes nullAtom. | 260 // FIXME: This should take a const char*, but one caller passes nullAtom. |
262 bool NodeHasRole(Node* node, const String& role) { | 261 bool NodeHasRole(Node* node, const String& role) { |
263 if (!node || !node->IsElementNode()) | 262 if (!node || !node->IsElementNode()) |
264 return false; | 263 return false; |
265 | 264 |
266 return EqualIgnoringASCIICase(ToElement(node)->getAttribute(roleAttr), role); | 265 return EqualIgnoringASCIICase(ToElement(node)->getAttribute(roleAttr), role); |
267 } | 266 } |
268 | 267 |
269 AXObjectImpl* AXObjectCacheImpl::CreateFromRenderer( | 268 AXObject* AXObjectCacheImpl::CreateFromRenderer(LayoutObject* layout_object) { |
270 LayoutObject* layout_object) { | |
271 // FIXME: How could layoutObject->node() ever not be an Element? | 269 // FIXME: How could layoutObject->node() ever not be an Element? |
272 Node* node = layout_object->GetNode(); | 270 Node* node = layout_object->GetNode(); |
273 | 271 |
274 // If the node is aria role="list" or the aria role is empty and its a | 272 // If the node is aria role="list" or the aria role is empty and its a |
275 // ul/ol/dl type (it shouldn't be a list if aria says otherwise). | 273 // ul/ol/dl type (it shouldn't be a list if aria says otherwise). |
276 if (NodeHasRole(node, "list") || NodeHasRole(node, "directory") || | 274 if (NodeHasRole(node, "list") || NodeHasRole(node, "directory") || |
277 (NodeHasRole(node, g_null_atom) && | 275 (NodeHasRole(node, g_null_atom) && |
278 (isHTMLUListElement(node) || isHTMLOListElement(node) || | 276 (isHTMLUListElement(node) || isHTMLOListElement(node) || |
279 isHTMLDListElement(node)))) | 277 isHTMLDListElement(node)))) |
280 return AXList::Create(layout_object, *this); | 278 return AXList::Create(layout_object, *this); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 return AXProgressIndicator::Create(ToLayoutProgress(css_box), *this); | 320 return AXProgressIndicator::Create(ToLayoutProgress(css_box), *this); |
323 | 321 |
324 // input type=range | 322 // input type=range |
325 if (css_box->IsSlider()) | 323 if (css_box->IsSlider()) |
326 return AXSlider::Create(ToLayoutSlider(css_box), *this); | 324 return AXSlider::Create(ToLayoutSlider(css_box), *this); |
327 } | 325 } |
328 | 326 |
329 return AXLayoutObject::Create(layout_object, *this); | 327 return AXLayoutObject::Create(layout_object, *this); |
330 } | 328 } |
331 | 329 |
332 AXObjectImpl* AXObjectCacheImpl::CreateFromNode(Node* node) { | 330 AXObject* AXObjectCacheImpl::CreateFromNode(Node* node) { |
333 if (IsMenuListOption(node)) | 331 if (IsMenuListOption(node)) |
334 return AXMenuListOption::Create(toHTMLOptionElement(node), *this); | 332 return AXMenuListOption::Create(toHTMLOptionElement(node), *this); |
335 | 333 |
336 if (isHTMLAreaElement(node)) | 334 if (isHTMLAreaElement(node)) |
337 return AXImageMapLink::Create(toHTMLAreaElement(node), *this); | 335 return AXImageMapLink::Create(toHTMLAreaElement(node), *this); |
338 | 336 |
339 return AXNodeObject::Create(node, *this); | 337 return AXNodeObject::Create(node, *this); |
340 } | 338 } |
341 | 339 |
342 AXObjectImpl* AXObjectCacheImpl::CreateFromInlineTextBox( | 340 AXObject* AXObjectCacheImpl::CreateFromInlineTextBox( |
343 AbstractInlineTextBox* inline_text_box) { | 341 AbstractInlineTextBox* inline_text_box) { |
344 return AXInlineTextBox::Create(inline_text_box, *this); | 342 return AXInlineTextBox::Create(inline_text_box, *this); |
345 } | 343 } |
346 | 344 |
347 AXObjectImpl* AXObjectCacheImpl::GetOrCreate(Node* node) { | 345 AXObject* AXObjectCacheImpl::GetOrCreate(Node* node) { |
348 if (!node) | 346 if (!node) |
349 return 0; | 347 return 0; |
350 | 348 |
351 if (AXObjectImpl* obj = Get(node)) | 349 if (AXObject* obj = Get(node)) |
352 return obj; | 350 return obj; |
353 | 351 |
354 // If the node has a layout object, prefer using that as the primary key for | 352 // If the node has a layout object, prefer using that as the primary key for |
355 // the AXObjectImpl, with the exception of an HTMLAreaElement, which is | 353 // the AXObject, with the exception of an HTMLAreaElement, which is created |
356 // created based on its node. | 354 // based on its node. |
357 if (node->GetLayoutObject() && !isHTMLAreaElement(node)) | 355 if (node->GetLayoutObject() && !isHTMLAreaElement(node)) |
358 return GetOrCreate(node->GetLayoutObject()); | 356 return GetOrCreate(node->GetLayoutObject()); |
359 | 357 |
360 if (!node->parentElement()) | 358 if (!node->parentElement()) |
361 return 0; | 359 return 0; |
362 | 360 |
363 if (isHTMLHeadElement(node)) | 361 if (isHTMLHeadElement(node)) |
364 return 0; | 362 return 0; |
365 | 363 |
366 AXObjectImpl* new_obj = CreateFromNode(node); | 364 AXObject* new_obj = CreateFromNode(node); |
367 | 365 |
368 // Will crash later if we have two objects for the same node. | 366 // Will crash later if we have two objects for the same node. |
369 DCHECK(!Get(node)); | 367 DCHECK(!Get(node)); |
370 | 368 |
371 const AXID ax_id = GetOrCreateAXID(new_obj); | 369 const AXID ax_id = GetOrCreateAXID(new_obj); |
372 | 370 |
373 node_object_mapping_.Set(node, ax_id); | 371 node_object_mapping_.Set(node, ax_id); |
374 new_obj->Init(); | 372 new_obj->Init(); |
375 new_obj->SetLastKnownIsIgnoredValue(new_obj->AccessibilityIsIgnored()); | 373 new_obj->SetLastKnownIsIgnoredValue(new_obj->AccessibilityIsIgnored()); |
376 | 374 |
377 if (node->IsElementNode()) | 375 if (node->IsElementNode()) |
378 UpdateTreeIfElementIdIsAriaOwned(ToElement(node)); | 376 UpdateTreeIfElementIdIsAriaOwned(ToElement(node)); |
379 | 377 |
380 return new_obj; | 378 return new_obj; |
381 } | 379 } |
382 | 380 |
383 AXObjectImpl* AXObjectCacheImpl::GetOrCreate(LayoutObject* layout_object) { | 381 AXObject* AXObjectCacheImpl::GetOrCreate(LayoutObject* layout_object) { |
384 if (!layout_object) | 382 if (!layout_object) |
385 return 0; | 383 return 0; |
386 | 384 |
387 if (AXObjectImpl* obj = Get(layout_object)) | 385 if (AXObject* obj = Get(layout_object)) |
388 return obj; | 386 return obj; |
389 | 387 |
390 AXObjectImpl* new_obj = CreateFromRenderer(layout_object); | 388 AXObject* new_obj = CreateFromRenderer(layout_object); |
391 | 389 |
392 // Will crash later if we have two objects for the same layoutObject. | 390 // Will crash later if we have two objects for the same layoutObject. |
393 DCHECK(!Get(layout_object)); | 391 DCHECK(!Get(layout_object)); |
394 | 392 |
395 const AXID axid = GetOrCreateAXID(new_obj); | 393 const AXID axid = GetOrCreateAXID(new_obj); |
396 | 394 |
397 layout_object_mapping_.Set(layout_object, axid); | 395 layout_object_mapping_.Set(layout_object, axid); |
398 new_obj->Init(); | 396 new_obj->Init(); |
399 new_obj->SetLastKnownIsIgnoredValue(new_obj->AccessibilityIsIgnored()); | 397 new_obj->SetLastKnownIsIgnoredValue(new_obj->AccessibilityIsIgnored()); |
400 | 398 |
401 return new_obj; | 399 return new_obj; |
402 } | 400 } |
403 | 401 |
404 AXObjectImpl* AXObjectCacheImpl::GetOrCreate( | 402 AXObject* AXObjectCacheImpl::GetOrCreate( |
405 AbstractInlineTextBox* inline_text_box) { | 403 AbstractInlineTextBox* inline_text_box) { |
406 if (!inline_text_box) | 404 if (!inline_text_box) |
407 return 0; | 405 return 0; |
408 | 406 |
409 if (AXObjectImpl* obj = Get(inline_text_box)) | 407 if (AXObject* obj = Get(inline_text_box)) |
410 return obj; | 408 return obj; |
411 | 409 |
412 AXObjectImpl* new_obj = CreateFromInlineTextBox(inline_text_box); | 410 AXObject* new_obj = CreateFromInlineTextBox(inline_text_box); |
413 | 411 |
414 // Will crash later if we have two objects for the same inlineTextBox. | 412 // Will crash later if we have two objects for the same inlineTextBox. |
415 DCHECK(!Get(inline_text_box)); | 413 DCHECK(!Get(inline_text_box)); |
416 | 414 |
417 const AXID axid = GetOrCreateAXID(new_obj); | 415 const AXID axid = GetOrCreateAXID(new_obj); |
418 | 416 |
419 inline_text_box_object_mapping_.Set(inline_text_box, axid); | 417 inline_text_box_object_mapping_.Set(inline_text_box, axid); |
420 new_obj->Init(); | 418 new_obj->Init(); |
421 new_obj->SetLastKnownIsIgnoredValue(new_obj->AccessibilityIsIgnored()); | 419 new_obj->SetLastKnownIsIgnoredValue(new_obj->AccessibilityIsIgnored()); |
422 | 420 |
423 return new_obj; | 421 return new_obj; |
424 } | 422 } |
425 | 423 |
426 AXObjectImpl* AXObjectCacheImpl::GetOrCreate(AccessibilityRole role) { | 424 AXObject* AXObjectCacheImpl::GetOrCreate(AccessibilityRole role) { |
427 AXObjectImpl* obj = nullptr; | 425 AXObject* obj = nullptr; |
428 | 426 |
429 // will be filled in... | 427 // will be filled in... |
430 switch (role) { | 428 switch (role) { |
431 case kColumnRole: | 429 case kColumnRole: |
432 obj = AXTableColumn::Create(*this); | 430 obj = AXTableColumn::Create(*this); |
433 break; | 431 break; |
434 case kTableHeaderContainerRole: | 432 case kTableHeaderContainerRole: |
435 obj = AXTableHeaderContainer::Create(*this); | 433 obj = AXTableHeaderContainer::Create(*this); |
436 break; | 434 break; |
437 case kSliderThumbRole: | 435 case kSliderThumbRole: |
(...skipping 19 matching lines...) Expand all Loading... |
457 | 455 |
458 obj->Init(); | 456 obj->Init(); |
459 return obj; | 457 return obj; |
460 } | 458 } |
461 | 459 |
462 void AXObjectCacheImpl::Remove(AXID ax_id) { | 460 void AXObjectCacheImpl::Remove(AXID ax_id) { |
463 if (!ax_id) | 461 if (!ax_id) |
464 return; | 462 return; |
465 | 463 |
466 // first fetch object to operate some cleanup functions on it | 464 // first fetch object to operate some cleanup functions on it |
467 AXObjectImpl* obj = objects_.at(ax_id); | 465 AXObject* obj = objects_.at(ax_id); |
468 if (!obj) | 466 if (!obj) |
469 return; | 467 return; |
470 | 468 |
471 obj->Detach(); | 469 obj->Detach(); |
472 RemoveAXID(obj); | 470 RemoveAXID(obj); |
473 | 471 |
474 // finally remove the object | 472 // finally remove the object |
475 if (!objects_.Take(ax_id)) | 473 if (!objects_.Take(ax_id)) |
476 return; | 474 return; |
477 | 475 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 do { | 517 do { |
520 ++obj_id; | 518 ++obj_id; |
521 } while (!obj_id || HashTraits<AXID>::IsDeletedValue(obj_id) || | 519 } while (!obj_id || HashTraits<AXID>::IsDeletedValue(obj_id) || |
522 ids_in_use_.Contains(obj_id)); | 520 ids_in_use_.Contains(obj_id)); |
523 | 521 |
524 last_used_id = obj_id; | 522 last_used_id = obj_id; |
525 | 523 |
526 return obj_id; | 524 return obj_id; |
527 } | 525 } |
528 | 526 |
529 AXID AXObjectCacheImpl::GetOrCreateAXID(AXObjectImpl* obj) { | 527 AXID AXObjectCacheImpl::GetOrCreateAXID(AXObject* obj) { |
530 // check for already-assigned ID | 528 // check for already-assigned ID |
531 const AXID existing_axid = obj->AxObjectID(); | 529 const AXID existing_axid = obj->AxObjectID(); |
532 if (existing_axid) { | 530 if (existing_axid) { |
533 DCHECK(ids_in_use_.Contains(existing_axid)); | 531 DCHECK(ids_in_use_.Contains(existing_axid)); |
534 return existing_axid; | 532 return existing_axid; |
535 } | 533 } |
536 | 534 |
537 const AXID new_axid = GenerateAXID(); | 535 const AXID new_axid = GenerateAXID(); |
538 | 536 |
539 ids_in_use_.insert(new_axid); | 537 ids_in_use_.insert(new_axid); |
540 obj->SetAXObjectID(new_axid); | 538 obj->SetAXObjectID(new_axid); |
541 objects_.Set(new_axid, obj); | 539 objects_.Set(new_axid, obj); |
542 | 540 |
543 return new_axid; | 541 return new_axid; |
544 } | 542 } |
545 | 543 |
546 void AXObjectCacheImpl::RemoveAXID(AXObjectImpl* object) { | 544 void AXObjectCacheImpl::RemoveAXID(AXObject* object) { |
547 if (!object) | 545 if (!object) |
548 return; | 546 return; |
549 | 547 |
550 AXID obj_id = object->AxObjectID(); | 548 AXID obj_id = object->AxObjectID(); |
551 if (!obj_id) | 549 if (!obj_id) |
552 return; | 550 return; |
553 DCHECK(!HashTraits<AXID>::IsDeletedValue(obj_id)); | 551 DCHECK(!HashTraits<AXID>::IsDeletedValue(obj_id)); |
554 DCHECK(ids_in_use_.Contains(obj_id)); | 552 DCHECK(ids_in_use_.Contains(obj_id)); |
555 object->SetAXObjectID(0); | 553 object->SetAXObjectID(0); |
556 ids_in_use_.erase(obj_id); | 554 ids_in_use_.erase(obj_id); |
557 | 555 |
558 if (aria_owner_to_children_mapping_.Contains(obj_id)) { | 556 if (aria_owner_to_children_mapping_.Contains(obj_id)) { |
559 Vector<AXID> child_axi_ds = aria_owner_to_children_mapping_.at(obj_id); | 557 Vector<AXID> child_axi_ds = aria_owner_to_children_mapping_.at(obj_id); |
560 for (size_t i = 0; i < child_axi_ds.size(); ++i) | 558 for (size_t i = 0; i < child_axi_ds.size(); ++i) |
561 aria_owned_child_to_owner_mapping_.erase(child_axi_ds[i]); | 559 aria_owned_child_to_owner_mapping_.erase(child_axi_ds[i]); |
562 aria_owner_to_children_mapping_.erase(obj_id); | 560 aria_owner_to_children_mapping_.erase(obj_id); |
563 } | 561 } |
564 aria_owned_child_to_owner_mapping_.erase(obj_id); | 562 aria_owned_child_to_owner_mapping_.erase(obj_id); |
565 aria_owned_child_to_real_parent_mapping_.erase(obj_id); | 563 aria_owned_child_to_real_parent_mapping_.erase(obj_id); |
566 aria_owner_to_ids_mapping_.erase(obj_id); | 564 aria_owner_to_ids_mapping_.erase(obj_id); |
567 } | 565 } |
568 | 566 |
569 void AXObjectCacheImpl::SelectionChanged(Node* node) { | 567 void AXObjectCacheImpl::SelectionChanged(Node* node) { |
570 // Find the nearest ancestor that already has an accessibility object, since | 568 // Find the nearest ancestor that already has an accessibility object, since |
571 // we might be in the middle of a layout. | 569 // we might be in the middle of a layout. |
572 while (node) { | 570 while (node) { |
573 if (AXObjectImpl* obj = Get(node)) { | 571 if (AXObject* obj = Get(node)) { |
574 obj->SelectionChanged(); | 572 obj->SelectionChanged(); |
575 return; | 573 return; |
576 } | 574 } |
577 node = node->parentNode(); | 575 node = node->parentNode(); |
578 } | 576 } |
579 } | 577 } |
580 | 578 |
581 void AXObjectCacheImpl::TextChanged(Node* node) { | 579 void AXObjectCacheImpl::TextChanged(Node* node) { |
582 TextChanged(GetOrCreate(node)); | 580 TextChanged(GetOrCreate(node)); |
583 } | 581 } |
584 | 582 |
585 void AXObjectCacheImpl::TextChanged(LayoutObject* layout_object) { | 583 void AXObjectCacheImpl::TextChanged(LayoutObject* layout_object) { |
586 TextChanged(GetOrCreate(layout_object)); | 584 TextChanged(GetOrCreate(layout_object)); |
587 } | 585 } |
588 | 586 |
589 void AXObjectCacheImpl::TextChanged(AXObjectImpl* obj) { | 587 void AXObjectCacheImpl::TextChanged(AXObject* obj) { |
590 if (!obj) | 588 if (!obj) |
591 return; | 589 return; |
592 | 590 |
593 bool parent_already_exists = obj->ParentObjectIfExists(); | 591 bool parent_already_exists = obj->ParentObjectIfExists(); |
594 obj->TextChanged(); | 592 obj->TextChanged(); |
595 PostNotification(obj, AXObjectCacheImpl::kAXTextChanged); | 593 PostNotification(obj, AXObjectCacheImpl::kAXTextChanged); |
596 if (parent_already_exists) | 594 if (parent_already_exists) |
597 obj->NotifyIfIgnoredValueChanged(); | 595 obj->NotifyIfIgnoredValueChanged(); |
598 } | 596 } |
599 | 597 |
600 void AXObjectCacheImpl::UpdateCacheAfterNodeIsAttached(Node* node) { | 598 void AXObjectCacheImpl::UpdateCacheAfterNodeIsAttached(Node* node) { |
601 // Calling get() will update the AX object if we had an AXNodeObject but now | 599 // Calling get() will update the AX object if we had an AXNodeObject but now |
602 // we need an AXLayoutObject, because it was reparented to a location outside | 600 // we need an AXLayoutObject, because it was reparented to a location outside |
603 // of a canvas. | 601 // of a canvas. |
604 Get(node); | 602 Get(node); |
605 if (node->IsElementNode()) | 603 if (node->IsElementNode()) |
606 UpdateTreeIfElementIdIsAriaOwned(ToElement(node)); | 604 UpdateTreeIfElementIdIsAriaOwned(ToElement(node)); |
607 } | 605 } |
608 | 606 |
609 void AXObjectCacheImpl::ChildrenChanged(Node* node) { | 607 void AXObjectCacheImpl::ChildrenChanged(Node* node) { |
610 ChildrenChanged(Get(node)); | 608 ChildrenChanged(Get(node)); |
611 } | 609 } |
612 | 610 |
613 void AXObjectCacheImpl::ChildrenChanged(LayoutObject* layout_object) { | 611 void AXObjectCacheImpl::ChildrenChanged(LayoutObject* layout_object) { |
614 ChildrenChanged(Get(layout_object)); | 612 ChildrenChanged(Get(layout_object)); |
615 } | 613 } |
616 | 614 |
617 void AXObjectCacheImpl::ChildrenChanged(AXObjectImpl* obj) { | 615 void AXObjectCacheImpl::ChildrenChanged(AXObject* obj) { |
618 if (!obj) | 616 if (!obj) |
619 return; | 617 return; |
620 | 618 |
621 obj->ChildrenChanged(); | 619 obj->ChildrenChanged(); |
622 } | 620 } |
623 | 621 |
624 void AXObjectCacheImpl::NotificationPostTimerFired(TimerBase*) { | 622 void AXObjectCacheImpl::NotificationPostTimerFired(TimerBase*) { |
625 notification_post_timer_.Stop(); | 623 notification_post_timer_.Stop(); |
626 | 624 |
627 unsigned i = 0, count = notifications_to_post_.size(); | 625 unsigned i = 0, count = notifications_to_post_.size(); |
628 for (i = 0; i < count; ++i) { | 626 for (i = 0; i < count; ++i) { |
629 AXObjectImpl* obj = notifications_to_post_[i].first; | 627 AXObject* obj = notifications_to_post_[i].first; |
630 | 628 |
631 if (!obj->AxObjectID()) | 629 if (!obj->AxObjectID()) |
632 continue; | 630 continue; |
633 | 631 |
634 if (obj->IsDetached()) | 632 if (obj->IsDetached()) |
635 continue; | 633 continue; |
636 | 634 |
637 #if DCHECK_IS_ON() | 635 #if DCHECK_IS_ON() |
638 // Make sure none of the layout views are in the process of being layed out. | 636 // Make sure none of the layout views are in the process of being layed out. |
639 // Notifications should only be sent after the layoutObject has finished | 637 // Notifications should only be sent after the layoutObject has finished |
(...skipping 23 matching lines...) Expand all Loading... |
663 PostNotification(Get(layout_object), notification); | 661 PostNotification(Get(layout_object), notification); |
664 } | 662 } |
665 | 663 |
666 void AXObjectCacheImpl::PostNotification(Node* node, | 664 void AXObjectCacheImpl::PostNotification(Node* node, |
667 AXNotification notification) { | 665 AXNotification notification) { |
668 if (!node) | 666 if (!node) |
669 return; | 667 return; |
670 PostNotification(Get(node), notification); | 668 PostNotification(Get(node), notification); |
671 } | 669 } |
672 | 670 |
673 void AXObjectCacheImpl::PostNotification(AXObjectImpl* object, | 671 void AXObjectCacheImpl::PostNotification(AXObject* object, |
674 AXNotification notification) { | 672 AXNotification notification) { |
675 if (!object) | 673 if (!object) |
676 return; | 674 return; |
677 | 675 |
678 modification_count_++; | 676 modification_count_++; |
679 notifications_to_post_.push_back(std::make_pair(object, notification)); | 677 notifications_to_post_.push_back(std::make_pair(object, notification)); |
680 if (!notification_post_timer_.IsActive()) | 678 if (!notification_post_timer_.IsActive()) |
681 notification_post_timer_.StartOneShot(0, BLINK_FROM_HERE); | 679 notification_post_timer_.StartOneShot(0, BLINK_FROM_HERE); |
682 } | 680 } |
683 | 681 |
684 bool AXObjectCacheImpl::IsAriaOwned(const AXObjectImpl* child) const { | 682 bool AXObjectCacheImpl::IsAriaOwned(const AXObject* child) const { |
685 return aria_owned_child_to_owner_mapping_.Contains(child->AxObjectID()); | 683 return aria_owned_child_to_owner_mapping_.Contains(child->AxObjectID()); |
686 } | 684 } |
687 | 685 |
688 AXObjectImpl* AXObjectCacheImpl::GetAriaOwnedParent( | 686 AXObject* AXObjectCacheImpl::GetAriaOwnedParent(const AXObject* child) const { |
689 const AXObjectImpl* child) const { | |
690 return ObjectFromAXID( | 687 return ObjectFromAXID( |
691 aria_owned_child_to_owner_mapping_.at(child->AxObjectID())); | 688 aria_owned_child_to_owner_mapping_.at(child->AxObjectID())); |
692 } | 689 } |
693 | 690 |
694 void AXObjectCacheImpl::UpdateAriaOwns( | 691 void AXObjectCacheImpl::UpdateAriaOwns( |
695 const AXObjectImpl* owner, | 692 const AXObject* owner, |
696 const Vector<String>& id_vector, | 693 const Vector<String>& id_vector, |
697 HeapVector<Member<AXObjectImpl>>& owned_children) { | 694 HeapVector<Member<AXObject>>& owned_children) { |
698 // | 695 // |
699 // Update the map from the AXID of this element to the ids of the owned | 696 // Update the map from the AXID of this element to the ids of the owned |
700 // children, and the reverse map from ids to possible AXID owners. | 697 // children, and the reverse map from ids to possible AXID owners. |
701 // | 698 // |
702 | 699 |
703 HashSet<String> current_ids = | 700 HashSet<String> current_ids = |
704 aria_owner_to_ids_mapping_.at(owner->AxObjectID()); | 701 aria_owner_to_ids_mapping_.at(owner->AxObjectID()); |
705 HashSet<String> new_ids; | 702 HashSet<String> new_ids; |
706 bool ids_changed = false; | 703 bool ids_changed = false; |
707 for (const String& id : id_vector) { | 704 for (const String& id : id_vector) { |
(...skipping 29 matching lines...) Expand all Loading... |
737 // | 734 // |
738 | 735 |
739 // Figure out the children that are owned by this object and are in the tree. | 736 // Figure out the children that are owned by this object and are in the tree. |
740 TreeScope& scope = owner->GetNode()->GetTreeScope(); | 737 TreeScope& scope = owner->GetNode()->GetTreeScope(); |
741 Vector<AXID> new_child_axi_ds; | 738 Vector<AXID> new_child_axi_ds; |
742 for (const String& id_name : id_vector) { | 739 for (const String& id_name : id_vector) { |
743 Element* element = scope.getElementById(AtomicString(id_name)); | 740 Element* element = scope.getElementById(AtomicString(id_name)); |
744 if (!element) | 741 if (!element) |
745 continue; | 742 continue; |
746 | 743 |
747 AXObjectImpl* child = GetOrCreate(element); | 744 AXObject* child = GetOrCreate(element); |
748 if (!child) | 745 if (!child) |
749 continue; | 746 continue; |
750 | 747 |
751 // If this child is already aria-owned by a different owner, continue. | 748 // If this child is already aria-owned by a different owner, continue. |
752 // It's an author error if this happens and we don't worry about which of | 749 // It's an author error if this happens and we don't worry about which of |
753 // the two owners wins ownership of the child, as long as only one of them | 750 // the two owners wins ownership of the child, as long as only one of them |
754 // does. | 751 // does. |
755 if (IsAriaOwned(child) && GetAriaOwnedParent(child) != owner) | 752 if (IsAriaOwned(child) && GetAriaOwnedParent(child) != owner) |
756 continue; | 753 continue; |
757 | 754 |
758 // You can't own yourself! | 755 // You can't own yourself! |
759 if (child == owner) | 756 if (child == owner) |
760 continue; | 757 continue; |
761 | 758 |
762 // Walk up the parents of the owner object, make sure that this child | 759 // Walk up the parents of the owner object, make sure that this child |
763 // doesn't appear there, as that would create a cycle. | 760 // doesn't appear there, as that would create a cycle. |
764 bool found_cycle = false; | 761 bool found_cycle = false; |
765 for (AXObjectImpl* parent = owner->ParentObject(); parent && !found_cycle; | 762 for (AXObject* parent = owner->ParentObject(); parent && !found_cycle; |
766 parent = parent->ParentObject()) { | 763 parent = parent->ParentObject()) { |
767 if (parent == child) | 764 if (parent == child) |
768 found_cycle = true; | 765 found_cycle = true; |
769 } | 766 } |
770 if (found_cycle) | 767 if (found_cycle) |
771 continue; | 768 continue; |
772 | 769 |
773 new_child_axi_ds.push_back(child->AxObjectID()); | 770 new_child_axi_ds.push_back(child->AxObjectID()); |
774 owned_children.push_back(child); | 771 owned_children.push_back(child); |
775 } | 772 } |
(...skipping 11 matching lines...) Expand all Loading... |
787 same = false; | 784 same = false; |
788 } | 785 } |
789 } | 786 } |
790 if (same) | 787 if (same) |
791 return; | 788 return; |
792 | 789 |
793 // The list of owned children has changed. Even if they were just reordered, | 790 // The list of owned children has changed. Even if they were just reordered, |
794 // to be safe and handle all cases we remove all of the current owned children | 791 // to be safe and handle all cases we remove all of the current owned children |
795 // and add the new list of owned children. | 792 // and add the new list of owned children. |
796 for (size_t i = 0; i < current_child_axi_ds.size(); ++i) { | 793 for (size_t i = 0; i < current_child_axi_ds.size(); ++i) { |
797 // Find the AXObjectImpl for the child that this owner no longer owns. | 794 // Find the AXObject for the child that this owner no longer owns. |
798 AXID removed_child_id = current_child_axi_ds[i]; | 795 AXID removed_child_id = current_child_axi_ds[i]; |
799 AXObjectImpl* removed_child = ObjectFromAXID(removed_child_id); | 796 AXObject* removed_child = ObjectFromAXID(removed_child_id); |
800 | 797 |
801 // It's possible that this child has already been owned by some other owner, | 798 // It's possible that this child has already been owned by some other owner, |
802 // in which case we don't need to do anything. | 799 // in which case we don't need to do anything. |
803 if (removed_child && GetAriaOwnedParent(removed_child) != owner) | 800 if (removed_child && GetAriaOwnedParent(removed_child) != owner) |
804 continue; | 801 continue; |
805 | 802 |
806 // Remove it from the child -> owner mapping so it's not owned by this owner | 803 // Remove it from the child -> owner mapping so it's not owned by this owner |
807 // anymore. | 804 // anymore. |
808 aria_owned_child_to_owner_mapping_.erase(removed_child_id); | 805 aria_owned_child_to_owner_mapping_.erase(removed_child_id); |
809 | 806 |
810 if (removed_child) { | 807 if (removed_child) { |
811 // If the child still exists, find its "real" parent, and reparent it back | 808 // If the child still exists, find its "real" parent, and reparent it back |
812 // to its real parent in the tree by detaching it from its current parent | 809 // to its real parent in the tree by detaching it from its current parent |
813 // and calling childrenChanged on its real parent. | 810 // and calling childrenChanged on its real parent. |
814 removed_child->DetachFromParent(); | 811 removed_child->DetachFromParent(); |
815 AXID real_parent_id = | 812 AXID real_parent_id = |
816 aria_owned_child_to_real_parent_mapping_.at(removed_child_id); | 813 aria_owned_child_to_real_parent_mapping_.at(removed_child_id); |
817 AXObjectImpl* real_parent = ObjectFromAXID(real_parent_id); | 814 AXObject* real_parent = ObjectFromAXID(real_parent_id); |
818 ChildrenChanged(real_parent); | 815 ChildrenChanged(real_parent); |
819 } | 816 } |
820 | 817 |
821 // Remove the child -> original parent mapping too since this object has now | 818 // Remove the child -> original parent mapping too since this object has now |
822 // been reparented back to its original parent. | 819 // been reparented back to its original parent. |
823 aria_owned_child_to_real_parent_mapping_.erase(removed_child_id); | 820 aria_owned_child_to_real_parent_mapping_.erase(removed_child_id); |
824 } | 821 } |
825 | 822 |
826 for (size_t i = 0; i < new_child_axi_ds.size(); ++i) { | 823 for (size_t i = 0; i < new_child_axi_ds.size(); ++i) { |
827 // Find the AXObjectImpl for the child that will now be a child of this | 824 // Find the AXObject for the child that will now be a child of this owner. |
828 // owner. | |
829 AXID added_child_id = new_child_axi_ds[i]; | 825 AXID added_child_id = new_child_axi_ds[i]; |
830 AXObjectImpl* added_child = ObjectFromAXID(added_child_id); | 826 AXObject* added_child = ObjectFromAXID(added_child_id); |
831 | 827 |
832 // Add this child to the mapping from child to owner. | 828 // Add this child to the mapping from child to owner. |
833 aria_owned_child_to_owner_mapping_.Set(added_child_id, owner->AxObjectID()); | 829 aria_owned_child_to_owner_mapping_.Set(added_child_id, owner->AxObjectID()); |
834 | 830 |
835 // Add its parent object to a mapping from child to real parent. If later | 831 // Add its parent object to a mapping from child to real parent. If later |
836 // this owner doesn't own this child anymore, we need to return it to its | 832 // this owner doesn't own this child anymore, we need to return it to its |
837 // original parent. | 833 // original parent. |
838 AXObjectImpl* original_parent = added_child->ParentObject(); | 834 AXObject* original_parent = added_child->ParentObject(); |
839 aria_owned_child_to_real_parent_mapping_.Set(added_child_id, | 835 aria_owned_child_to_real_parent_mapping_.Set(added_child_id, |
840 original_parent->AxObjectID()); | 836 original_parent->AxObjectID()); |
841 | 837 |
842 // Now detach the object from its original parent and call childrenChanged | 838 // Now detach the object from its original parent and call childrenChanged |
843 // on the original parent so that it can recompute its list of children. | 839 // on the original parent so that it can recompute its list of children. |
844 added_child->DetachFromParent(); | 840 added_child->DetachFromParent(); |
845 ChildrenChanged(original_parent); | 841 ChildrenChanged(original_parent); |
846 } | 842 } |
847 | 843 |
848 // Finally, update the mapping from the owner to the list of child IDs. | 844 // Finally, update the mapping from the owner to the list of child IDs. |
849 aria_owner_to_children_mapping_.Set(owner->AxObjectID(), new_child_axi_ds); | 845 aria_owner_to_children_mapping_.Set(owner->AxObjectID(), new_child_axi_ds); |
850 } | 846 } |
851 | 847 |
852 void AXObjectCacheImpl::UpdateTreeIfElementIdIsAriaOwned(Element* element) { | 848 void AXObjectCacheImpl::UpdateTreeIfElementIdIsAriaOwned(Element* element) { |
853 if (!element->HasID()) | 849 if (!element->HasID()) |
854 return; | 850 return; |
855 | 851 |
856 String id = element->GetIdAttribute(); | 852 String id = element->GetIdAttribute(); |
857 HashSet<AXID>* owners = id_to_aria_owners_mapping_.at(id); | 853 HashSet<AXID>* owners = id_to_aria_owners_mapping_.at(id); |
858 if (!owners) | 854 if (!owners) |
859 return; | 855 return; |
860 | 856 |
861 AXObjectImpl* ax_element = GetOrCreate(element); | 857 AXObject* ax_element = GetOrCreate(element); |
862 if (!ax_element) | 858 if (!ax_element) |
863 return; | 859 return; |
864 | 860 |
865 // If it's already owned, call childrenChanged on the owner to make sure it's | 861 // If it's already owned, call childrenChanged on the owner to make sure it's |
866 // still an owner. | 862 // still an owner. |
867 if (IsAriaOwned(ax_element)) { | 863 if (IsAriaOwned(ax_element)) { |
868 AXObjectImpl* owned_parent = GetAriaOwnedParent(ax_element); | 864 AXObject* owned_parent = GetAriaOwnedParent(ax_element); |
869 DCHECK(owned_parent); | 865 DCHECK(owned_parent); |
870 ChildrenChanged(owned_parent); | 866 ChildrenChanged(owned_parent); |
871 return; | 867 return; |
872 } | 868 } |
873 | 869 |
874 // If it's not already owned, check the possible owners based on our mapping | 870 // If it's not already owned, check the possible owners based on our mapping |
875 // from ids to elements that have that id listed in their aria-owns attribute. | 871 // from ids to elements that have that id listed in their aria-owns attribute. |
876 for (const auto& ax_id : *owners) { | 872 for (const auto& ax_id : *owners) { |
877 AXObjectImpl* owner = ObjectFromAXID(ax_id); | 873 AXObject* owner = ObjectFromAXID(ax_id); |
878 if (owner) | 874 if (owner) |
879 ChildrenChanged(owner); | 875 ChildrenChanged(owner); |
880 } | 876 } |
881 } | 877 } |
882 | 878 |
883 void AXObjectCacheImpl::CheckedStateChanged(Node* node) { | 879 void AXObjectCacheImpl::CheckedStateChanged(Node* node) { |
884 PostNotification(node, AXObjectCacheImpl::kAXCheckedStateChanged); | 880 PostNotification(node, AXObjectCacheImpl::kAXCheckedStateChanged); |
885 } | 881 } |
886 | 882 |
887 void AXObjectCacheImpl::ListboxOptionStateChanged(HTMLOptionElement* option) { | 883 void AXObjectCacheImpl::ListboxOptionStateChanged(HTMLOptionElement* option) { |
888 PostNotification(option, kAXCheckedStateChanged); | 884 PostNotification(option, kAXCheckedStateChanged); |
889 } | 885 } |
890 | 886 |
891 void AXObjectCacheImpl::ListboxSelectedChildrenChanged( | 887 void AXObjectCacheImpl::ListboxSelectedChildrenChanged( |
892 HTMLSelectElement* select) { | 888 HTMLSelectElement* select) { |
893 PostNotification(select, kAXSelectedChildrenChanged); | 889 PostNotification(select, kAXSelectedChildrenChanged); |
894 } | 890 } |
895 | 891 |
896 void AXObjectCacheImpl::ListboxActiveIndexChanged(HTMLSelectElement* select) { | 892 void AXObjectCacheImpl::ListboxActiveIndexChanged(HTMLSelectElement* select) { |
897 AXObjectImpl* obj = Get(select); | 893 AXObject* obj = Get(select); |
898 if (!obj || !obj->IsAXListBox()) | 894 if (!obj || !obj->IsAXListBox()) |
899 return; | 895 return; |
900 | 896 |
901 ToAXListBox(obj)->ActiveIndexChanged(); | 897 ToAXListBox(obj)->ActiveIndexChanged(); |
902 } | 898 } |
903 | 899 |
904 void AXObjectCacheImpl::RadiobuttonRemovedFromGroup( | 900 void AXObjectCacheImpl::RadiobuttonRemovedFromGroup( |
905 HTMLInputElement* group_member) { | 901 HTMLInputElement* group_member) { |
906 AXObjectImpl* obj = Get(group_member); | 902 AXObject* obj = Get(group_member); |
907 if (!obj || !obj->IsAXRadioInput()) | 903 if (!obj || !obj->IsAXRadioInput()) |
908 return; | 904 return; |
909 | 905 |
910 // The 'posInSet' and 'setSize' attributes should be updated from the first | 906 // The 'posInSet' and 'setSize' attributes should be updated from the first |
911 // node, as the removed node is already detached from tree. | 907 // node, as the removed node is already detached from tree. |
912 HTMLInputElement* first_radio = | 908 HTMLInputElement* first_radio = |
913 ToAXRadioInput(obj)->FindFirstRadioButtonInGroup(group_member); | 909 ToAXRadioInput(obj)->FindFirstRadioButtonInGroup(group_member); |
914 AXObjectImpl* first_obj = Get(first_radio); | 910 AXObject* first_obj = Get(first_radio); |
915 if (!first_obj || !first_obj->IsAXRadioInput()) | 911 if (!first_obj || !first_obj->IsAXRadioInput()) |
916 return; | 912 return; |
917 | 913 |
918 ToAXRadioInput(first_obj)->UpdatePosAndSetSize(1); | 914 ToAXRadioInput(first_obj)->UpdatePosAndSetSize(1); |
919 PostNotification(first_obj, kAXAriaAttributeChanged); | 915 PostNotification(first_obj, kAXAriaAttributeChanged); |
920 ToAXRadioInput(first_obj)->RequestUpdateToNextNode(true); | 916 ToAXRadioInput(first_obj)->RequestUpdateToNextNode(true); |
921 } | 917 } |
922 | 918 |
923 void AXObjectCacheImpl::HandleLayoutComplete(LayoutObject* layout_object) { | 919 void AXObjectCacheImpl::HandleLayoutComplete(LayoutObject* layout_object) { |
924 if (!layout_object) | 920 if (!layout_object) |
925 return; | 921 return; |
926 | 922 |
927 modification_count_++; | 923 modification_count_++; |
928 | 924 |
929 // Create the AXObjectImpl if it didn't yet exist - that's always safe at the | 925 // Create the AXObject if it didn't yet exist - that's always safe at the end |
930 // end of a layout, and it allows an AX notification to be sent when a page | 926 // of a layout, and it allows an AX notification to be sent when a page has |
931 // has its first layout, rather than when the document first loads. | 927 // its first layout, rather than when the document first loads. |
932 if (AXObjectImpl* obj = GetOrCreate(layout_object)) | 928 if (AXObject* obj = GetOrCreate(layout_object)) |
933 PostNotification(obj, kAXLayoutComplete); | 929 PostNotification(obj, kAXLayoutComplete); |
934 } | 930 } |
935 | 931 |
936 void AXObjectCacheImpl::HandleClicked(Node* node) { | 932 void AXObjectCacheImpl::HandleClicked(Node* node) { |
937 if (AXObjectImpl* obj = GetOrCreate(node)) | 933 if (AXObject* obj = GetOrCreate(node)) |
938 PostNotification(obj, kAXClicked); | 934 PostNotification(obj, kAXClicked); |
939 } | 935 } |
940 | 936 |
941 void AXObjectCacheImpl::HandleAriaExpandedChange(Node* node) { | 937 void AXObjectCacheImpl::HandleAriaExpandedChange(Node* node) { |
942 if (AXObjectImpl* obj = GetOrCreate(node)) | 938 if (AXObject* obj = GetOrCreate(node)) |
943 obj->HandleAriaExpandedChanged(); | 939 obj->HandleAriaExpandedChanged(); |
944 } | 940 } |
945 | 941 |
946 void AXObjectCacheImpl::HandleAriaSelectedChanged(Node* node) { | 942 void AXObjectCacheImpl::HandleAriaSelectedChanged(Node* node) { |
947 AXObjectImpl* obj = Get(node); | 943 AXObject* obj = Get(node); |
948 if (!obj) | 944 if (!obj) |
949 return; | 945 return; |
950 | 946 |
951 PostNotification(obj, kAXCheckedStateChanged); | 947 PostNotification(obj, kAXCheckedStateChanged); |
952 | 948 |
953 AXObjectImpl* listbox = obj->ParentObjectUnignored(); | 949 AXObject* listbox = obj->ParentObjectUnignored(); |
954 if (listbox && listbox->RoleValue() == kListBoxRole) | 950 if (listbox && listbox->RoleValue() == kListBoxRole) |
955 PostNotification(listbox, kAXSelectedChildrenChanged); | 951 PostNotification(listbox, kAXSelectedChildrenChanged); |
956 } | 952 } |
957 | 953 |
958 void AXObjectCacheImpl::HandleActiveDescendantChanged(Node* node) { | 954 void AXObjectCacheImpl::HandleActiveDescendantChanged(Node* node) { |
959 // Changing the active descendant should trigger recomputing all | 955 // Changing the active descendant should trigger recomputing all |
960 // cached values even if it doesn't result in a notification, because | 956 // cached values even if it doesn't result in a notification, because |
961 // it can affect what's focusable or not. | 957 // it can affect what's focusable or not. |
962 modification_count_++; | 958 modification_count_++; |
963 | 959 |
964 if (AXObjectImpl* obj = GetOrCreate(node)) | 960 if (AXObject* obj = GetOrCreate(node)) |
965 obj->HandleActiveDescendantChanged(); | 961 obj->HandleActiveDescendantChanged(); |
966 } | 962 } |
967 | 963 |
968 void AXObjectCacheImpl::HandleAriaRoleChanged(Node* node) { | 964 void AXObjectCacheImpl::HandleAriaRoleChanged(Node* node) { |
969 if (AXObjectImpl* obj = GetOrCreate(node)) { | 965 if (AXObject* obj = GetOrCreate(node)) { |
970 obj->UpdateAccessibilityRole(); | 966 obj->UpdateAccessibilityRole(); |
971 modification_count_++; | 967 modification_count_++; |
972 obj->NotifyIfIgnoredValueChanged(); | 968 obj->NotifyIfIgnoredValueChanged(); |
973 } | 969 } |
974 } | 970 } |
975 | 971 |
976 void AXObjectCacheImpl::HandleAttributeChanged(const QualifiedName& attr_name, | 972 void AXObjectCacheImpl::HandleAttributeChanged(const QualifiedName& attr_name, |
977 Element* element) { | 973 Element* element) { |
978 if (attr_name == roleAttr) | 974 if (attr_name == roleAttr) |
979 HandleAriaRoleChanged(element); | 975 HandleAriaRoleChanged(element); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 void AXObjectCacheImpl::InlineTextBoxesUpdated( | 1013 void AXObjectCacheImpl::InlineTextBoxesUpdated( |
1018 LineLayoutItem line_layout_item) { | 1014 LineLayoutItem line_layout_item) { |
1019 if (!InlineTextBoxAccessibilityEnabled()) | 1015 if (!InlineTextBoxAccessibilityEnabled()) |
1020 return; | 1016 return; |
1021 | 1017 |
1022 LayoutObject* layout_object = | 1018 LayoutObject* layout_object = |
1023 LineLayoutAPIShim::LayoutObjectFrom(line_layout_item); | 1019 LineLayoutAPIShim::LayoutObjectFrom(line_layout_item); |
1024 | 1020 |
1025 // Only update if the accessibility object already exists and it's | 1021 // Only update if the accessibility object already exists and it's |
1026 // not already marked as dirty. | 1022 // not already marked as dirty. |
1027 if (AXObjectImpl* obj = Get(layout_object)) { | 1023 if (AXObject* obj = Get(layout_object)) { |
1028 if (!obj->NeedsToUpdateChildren()) { | 1024 if (!obj->NeedsToUpdateChildren()) { |
1029 obj->SetNeedsToUpdateChildren(); | 1025 obj->SetNeedsToUpdateChildren(); |
1030 PostNotification(layout_object, kAXChildrenChanged); | 1026 PostNotification(layout_object, kAXChildrenChanged); |
1031 } | 1027 } |
1032 } | 1028 } |
1033 } | 1029 } |
1034 | 1030 |
1035 Settings* AXObjectCacheImpl::GetSettings() { | 1031 Settings* AXObjectCacheImpl::GetSettings() { |
1036 return document_->GetSettings(); | 1032 return document_->GetSettings(); |
1037 } | 1033 } |
(...skipping 18 matching lines...) Expand all Loading... |
1056 node->IsElementNode() ? ToElement(node) : node->parentElement(); | 1052 node->IsElementNode() ? ToElement(node) : node->parentElement(); |
1057 | 1053 |
1058 for (; element; element = element->parentElement()) { | 1054 for (; element; element = element->parentElement()) { |
1059 if (NodeIsTextControl(element)) | 1055 if (NodeIsTextControl(element)) |
1060 result = element; | 1056 result = element; |
1061 } | 1057 } |
1062 | 1058 |
1063 return result; | 1059 return result; |
1064 } | 1060 } |
1065 | 1061 |
1066 AXObjectImpl* AXObjectCacheImpl::FirstAccessibleObjectFromNode( | 1062 AXObject* AXObjectCacheImpl::FirstAccessibleObjectFromNode(const Node* node) { |
1067 const Node* node) { | |
1068 if (!node) | 1063 if (!node) |
1069 return 0; | 1064 return 0; |
1070 | 1065 |
1071 AXObjectImpl* accessible_object = GetOrCreate(node->GetLayoutObject()); | 1066 AXObject* accessible_object = GetOrCreate(node->GetLayoutObject()); |
1072 while (accessible_object && accessible_object->AccessibilityIsIgnored()) { | 1067 while (accessible_object && accessible_object->AccessibilityIsIgnored()) { |
1073 node = NodeTraversal::Next(*node); | 1068 node = NodeTraversal::Next(*node); |
1074 | 1069 |
1075 while (node && !node->GetLayoutObject()) | 1070 while (node && !node->GetLayoutObject()) |
1076 node = NodeTraversal::NextSkippingChildren(*node); | 1071 node = NodeTraversal::NextSkippingChildren(*node); |
1077 | 1072 |
1078 if (!node) | 1073 if (!node) |
1079 return 0; | 1074 return 0; |
1080 | 1075 |
1081 accessible_object = GetOrCreate(node->GetLayoutObject()); | 1076 accessible_object = GetOrCreate(node->GetLayoutObject()); |
1082 } | 1077 } |
1083 | 1078 |
1084 return accessible_object; | 1079 return accessible_object; |
1085 } | 1080 } |
1086 | 1081 |
1087 bool AXObjectCacheImpl::NodeIsTextControl(const Node* node) { | 1082 bool AXObjectCacheImpl::NodeIsTextControl(const Node* node) { |
1088 if (!node) | 1083 if (!node) |
1089 return false; | 1084 return false; |
1090 | 1085 |
1091 const AXObjectImpl* ax_object = GetOrCreate(const_cast<Node*>(node)); | 1086 const AXObject* ax_object = GetOrCreate(const_cast<Node*>(node)); |
1092 return ax_object && ax_object->IsTextControl(); | 1087 return ax_object && ax_object->IsTextControl(); |
1093 } | 1088 } |
1094 | 1089 |
1095 bool IsNodeAriaVisible(Node* node) { | 1090 bool IsNodeAriaVisible(Node* node) { |
1096 if (!node) | 1091 if (!node) |
1097 return false; | 1092 return false; |
1098 | 1093 |
1099 if (!node->IsElementNode()) | 1094 if (!node->IsElementNode()) |
1100 return false; | 1095 return false; |
1101 | 1096 |
1102 return EqualIgnoringASCIICase(ToElement(node)->getAttribute(aria_hiddenAttr), | 1097 return EqualIgnoringASCIICase(ToElement(node)->getAttribute(aria_hiddenAttr), |
1103 "false"); | 1098 "false"); |
1104 } | 1099 } |
1105 | 1100 |
1106 void AXObjectCacheImpl::PostPlatformNotification(AXObjectImpl* obj, | 1101 void AXObjectCacheImpl::PostPlatformNotification(AXObject* obj, |
1107 AXNotification notification) { | 1102 AXNotification notification) { |
1108 if (!obj || !obj->GetDocument() || !obj->DocumentFrameView() || | 1103 if (!obj || !obj->GetDocument() || !obj->DocumentFrameView() || |
1109 !obj->DocumentFrameView()->GetFrame().GetPage()) | 1104 !obj->DocumentFrameView()->GetFrame().GetPage()) |
1110 return; | 1105 return; |
1111 | 1106 |
1112 ChromeClient& client = | 1107 ChromeClient& client = |
1113 obj->GetDocument()->AxObjectCacheOwner().GetPage()->GetChromeClient(); | 1108 obj->GetDocument()->AxObjectCacheOwner().GetPage()->GetChromeClient(); |
1114 client.PostAccessibilityNotification(obj, notification); | 1109 client.PostAccessibilityNotification(obj, notification); |
1115 } | 1110 } |
1116 | 1111 |
1117 void AXObjectCacheImpl::HandleFocusedUIElementChanged(Node* old_focused_node, | 1112 void AXObjectCacheImpl::HandleFocusedUIElementChanged(Node* old_focused_node, |
1118 Node* new_focused_node) { | 1113 Node* new_focused_node) { |
1119 if (!new_focused_node) | 1114 if (!new_focused_node) |
1120 return; | 1115 return; |
1121 | 1116 |
1122 Page* page = new_focused_node->GetDocument().GetPage(); | 1117 Page* page = new_focused_node->GetDocument().GetPage(); |
1123 if (!page) | 1118 if (!page) |
1124 return; | 1119 return; |
1125 | 1120 |
1126 AXObjectImpl* focused_object = this->FocusedObject(); | 1121 AXObject* focused_object = this->FocusedObject(); |
1127 if (!focused_object) | 1122 if (!focused_object) |
1128 return; | 1123 return; |
1129 | 1124 |
1130 AXObjectImpl* old_focused_object = Get(old_focused_node); | 1125 AXObject* old_focused_object = Get(old_focused_node); |
1131 | 1126 |
1132 PostPlatformNotification(old_focused_object, kAXBlur); | 1127 PostPlatformNotification(old_focused_object, kAXBlur); |
1133 PostPlatformNotification(focused_object, kAXFocusedUIElementChanged); | 1128 PostPlatformNotification(focused_object, kAXFocusedUIElementChanged); |
1134 } | 1129 } |
1135 | 1130 |
1136 void AXObjectCacheImpl::HandleInitialFocus() { | 1131 void AXObjectCacheImpl::HandleInitialFocus() { |
1137 PostNotification(document_, AXObjectCache::kAXFocusedUIElementChanged); | 1132 PostNotification(document_, AXObjectCache::kAXFocusedUIElementChanged); |
1138 } | 1133 } |
1139 | 1134 |
1140 void AXObjectCacheImpl::HandleEditableTextContentChanged(Node* node) { | 1135 void AXObjectCacheImpl::HandleEditableTextContentChanged(Node* node) { |
1141 AXObjectImpl* obj = Get(node); | 1136 AXObject* obj = Get(node); |
1142 while (obj && !obj->IsNativeTextControl() && !obj->IsNonNativeTextControl()) | 1137 while (obj && !obj->IsNativeTextControl() && !obj->IsNonNativeTextControl()) |
1143 obj = obj->ParentObject(); | 1138 obj = obj->ParentObject(); |
1144 PostNotification(obj, AXObjectCache::kAXValueChanged); | 1139 PostNotification(obj, AXObjectCache::kAXValueChanged); |
1145 } | 1140 } |
1146 | 1141 |
1147 void AXObjectCacheImpl::HandleTextFormControlChanged(Node* node) { | 1142 void AXObjectCacheImpl::HandleTextFormControlChanged(Node* node) { |
1148 HandleEditableTextContentChanged(node); | 1143 HandleEditableTextContentChanged(node); |
1149 } | 1144 } |
1150 | 1145 |
1151 void AXObjectCacheImpl::HandleValueChanged(Node* node) { | 1146 void AXObjectCacheImpl::HandleValueChanged(Node* node) { |
1152 PostNotification(node, AXObjectCache::kAXValueChanged); | 1147 PostNotification(node, AXObjectCache::kAXValueChanged); |
1153 } | 1148 } |
1154 | 1149 |
1155 void AXObjectCacheImpl::HandleUpdateActiveMenuOption(LayoutMenuList* menu_list, | 1150 void AXObjectCacheImpl::HandleUpdateActiveMenuOption(LayoutMenuList* menu_list, |
1156 int option_index) { | 1151 int option_index) { |
1157 AXObjectImpl* obj = Get(menu_list); | 1152 AXObject* obj = Get(menu_list); |
1158 if (!obj || !obj->IsMenuList()) | 1153 if (!obj || !obj->IsMenuList()) |
1159 return; | 1154 return; |
1160 | 1155 |
1161 ToAXMenuList(obj)->DidUpdateActiveOption(option_index); | 1156 ToAXMenuList(obj)->DidUpdateActiveOption(option_index); |
1162 } | 1157 } |
1163 | 1158 |
1164 void AXObjectCacheImpl::DidShowMenuListPopup(LayoutMenuList* menu_list) { | 1159 void AXObjectCacheImpl::DidShowMenuListPopup(LayoutMenuList* menu_list) { |
1165 AXObjectImpl* obj = Get(menu_list); | 1160 AXObject* obj = Get(menu_list); |
1166 if (!obj || !obj->IsMenuList()) | 1161 if (!obj || !obj->IsMenuList()) |
1167 return; | 1162 return; |
1168 | 1163 |
1169 ToAXMenuList(obj)->DidShowPopup(); | 1164 ToAXMenuList(obj)->DidShowPopup(); |
1170 } | 1165 } |
1171 | 1166 |
1172 void AXObjectCacheImpl::DidHideMenuListPopup(LayoutMenuList* menu_list) { | 1167 void AXObjectCacheImpl::DidHideMenuListPopup(LayoutMenuList* menu_list) { |
1173 AXObjectImpl* obj = Get(menu_list); | 1168 AXObject* obj = Get(menu_list); |
1174 if (!obj || !obj->IsMenuList()) | 1169 if (!obj || !obj->IsMenuList()) |
1175 return; | 1170 return; |
1176 | 1171 |
1177 ToAXMenuList(obj)->DidHidePopup(); | 1172 ToAXMenuList(obj)->DidHidePopup(); |
1178 } | 1173 } |
1179 | 1174 |
1180 void AXObjectCacheImpl::HandleLoadComplete(Document* document) { | 1175 void AXObjectCacheImpl::HandleLoadComplete(Document* document) { |
1181 PostNotification(GetOrCreate(document), AXObjectCache::kAXLoadComplete); | 1176 PostNotification(GetOrCreate(document), AXObjectCache::kAXLoadComplete); |
1182 } | 1177 } |
1183 | 1178 |
1184 void AXObjectCacheImpl::HandleLayoutComplete(Document* document) { | 1179 void AXObjectCacheImpl::HandleLayoutComplete(Document* document) { |
1185 PostNotification(GetOrCreate(document), AXObjectCache::kAXLayoutComplete); | 1180 PostNotification(GetOrCreate(document), AXObjectCache::kAXLayoutComplete); |
1186 } | 1181 } |
1187 | 1182 |
1188 void AXObjectCacheImpl::HandleScrolledToAnchor(const Node* anchor_node) { | 1183 void AXObjectCacheImpl::HandleScrolledToAnchor(const Node* anchor_node) { |
1189 if (!anchor_node) | 1184 if (!anchor_node) |
1190 return; | 1185 return; |
1191 AXObjectImpl* obj = GetOrCreate(anchor_node->GetLayoutObject()); | 1186 AXObject* obj = GetOrCreate(anchor_node->GetLayoutObject()); |
1192 if (!obj) | 1187 if (!obj) |
1193 return; | 1188 return; |
1194 if (obj->AccessibilityIsIgnored()) | 1189 if (obj->AccessibilityIsIgnored()) |
1195 obj = obj->ParentObjectUnignored(); | 1190 obj = obj->ParentObjectUnignored(); |
1196 PostPlatformNotification(obj, kAXScrolledToAnchor); | 1191 PostPlatformNotification(obj, kAXScrolledToAnchor); |
1197 } | 1192 } |
1198 | 1193 |
1199 void AXObjectCacheImpl::HandleScrollPositionChanged(FrameView* frame_view) { | 1194 void AXObjectCacheImpl::HandleScrollPositionChanged(FrameView* frame_view) { |
1200 AXObjectImpl* target_ax_object = | 1195 AXObject* target_ax_object = |
1201 GetOrCreate(frame_view->GetFrame().GetDocument()); | 1196 GetOrCreate(frame_view->GetFrame().GetDocument()); |
1202 PostPlatformNotification(target_ax_object, kAXScrollPositionChanged); | 1197 PostPlatformNotification(target_ax_object, kAXScrollPositionChanged); |
1203 } | 1198 } |
1204 | 1199 |
1205 void AXObjectCacheImpl::HandleScrollPositionChanged( | 1200 void AXObjectCacheImpl::HandleScrollPositionChanged( |
1206 LayoutObject* layout_object) { | 1201 LayoutObject* layout_object) { |
1207 PostPlatformNotification(GetOrCreate(layout_object), | 1202 PostPlatformNotification(GetOrCreate(layout_object), |
1208 kAXScrollPositionChanged); | 1203 kAXScrollPositionChanged); |
1209 } | 1204 } |
1210 | 1205 |
1211 const AtomicString& AXObjectCacheImpl::ComputedRoleForNode(Node* node) { | 1206 const AtomicString& AXObjectCacheImpl::ComputedRoleForNode(Node* node) { |
1212 AXObjectImpl* obj = GetOrCreate(node); | 1207 AXObject* obj = GetOrCreate(node); |
1213 if (!obj) | 1208 if (!obj) |
1214 return AXObjectImpl::RoleName(kUnknownRole); | 1209 return AXObject::RoleName(kUnknownRole); |
1215 return AXObjectImpl::RoleName(obj->RoleValue()); | 1210 return AXObject::RoleName(obj->RoleValue()); |
1216 } | 1211 } |
1217 | 1212 |
1218 String AXObjectCacheImpl::ComputedNameForNode(Node* node) { | 1213 String AXObjectCacheImpl::ComputedNameForNode(Node* node) { |
1219 AXObjectImpl* obj = GetOrCreate(node); | 1214 AXObject* obj = GetOrCreate(node); |
1220 if (!obj) | 1215 if (!obj) |
1221 return ""; | 1216 return ""; |
1222 | 1217 |
1223 return obj->ComputedName(); | 1218 return obj->ComputedName(); |
1224 } | 1219 } |
1225 | 1220 |
1226 void AXObjectCacheImpl::OnTouchAccessibilityHover(const IntPoint& location) { | 1221 void AXObjectCacheImpl::OnTouchAccessibilityHover(const IntPoint& location) { |
1227 AXObjectImpl* hit = Root()->AccessibilityHitTest(location); | 1222 AXObject* hit = Root()->AccessibilityHitTest(location); |
1228 if (hit) { | 1223 if (hit) { |
1229 // Ignore events on a frame or plug-in, because the touch events | 1224 // Ignore events on a frame or plug-in, because the touch events |
1230 // will be re-targeted there and we don't want to fire duplicate | 1225 // will be re-targeted there and we don't want to fire duplicate |
1231 // accessibility events. | 1226 // accessibility events. |
1232 if (hit->GetLayoutObject() && hit->GetLayoutObject()->IsLayoutPart()) | 1227 if (hit->GetLayoutObject() && hit->GetLayoutObject()->IsLayoutPart()) |
1233 return; | 1228 return; |
1234 | 1229 |
1235 PostPlatformNotification(hit, kAXHover); | 1230 PostPlatformNotification(hit, kAXHover); |
1236 } | 1231 } |
1237 } | 1232 } |
1238 | 1233 |
1239 void AXObjectCacheImpl::SetCanvasObjectBounds(HTMLCanvasElement* canvas, | 1234 void AXObjectCacheImpl::SetCanvasObjectBounds(HTMLCanvasElement* canvas, |
1240 Element* element, | 1235 Element* element, |
1241 const LayoutRect& rect) { | 1236 const LayoutRect& rect) { |
1242 AXObjectImpl* obj = GetOrCreate(element); | 1237 AXObject* obj = GetOrCreate(element); |
1243 if (!obj) | 1238 if (!obj) |
1244 return; | 1239 return; |
1245 | 1240 |
1246 AXObjectImpl* ax_canvas = GetOrCreate(canvas); | 1241 AXObject* ax_canvas = GetOrCreate(canvas); |
1247 if (!ax_canvas) | 1242 if (!ax_canvas) |
1248 return; | 1243 return; |
1249 | 1244 |
1250 obj->SetElementRect(rect, ax_canvas); | 1245 obj->SetElementRect(rect, ax_canvas); |
1251 } | 1246 } |
1252 | 1247 |
1253 DEFINE_TRACE(AXObjectCacheImpl) { | 1248 DEFINE_TRACE(AXObjectCacheImpl) { |
1254 visitor->Trace(document_); | 1249 visitor->Trace(document_); |
1255 visitor->Trace(node_object_mapping_); | 1250 visitor->Trace(node_object_mapping_); |
1256 | 1251 |
1257 visitor->Trace(objects_); | 1252 visitor->Trace(objects_); |
1258 visitor->Trace(notifications_to_post_); | 1253 visitor->Trace(notifications_to_post_); |
1259 | 1254 |
1260 AXObjectCache::Trace(visitor); | 1255 AXObjectCache::Trace(visitor); |
1261 } | 1256 } |
1262 | 1257 |
1263 } // namespace blink | 1258 } // namespace blink |
OLD | NEW |