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