OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012, Google Inc. All rights reserved. | 2 * Copyright (C) 2012, 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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 { | 133 { |
134 if (roleValue() != SliderRole) | 134 if (roleValue() != SliderRole) |
135 return; | 135 return; |
136 | 136 |
137 float value = valueForRange(); | 137 float value = valueForRange(); |
138 float step = stepValueForRange(); | 138 float step = stepValueForRange(); |
139 | 139 |
140 value += increase ? step : -step; | 140 value += increase ? step : -step; |
141 | 141 |
142 setValue(String::number(value)); | 142 setValue(String::number(value)); |
143 axObjectCache().postNotification(node(), AXObjectCacheImpl::AXValueChanged); | 143 axObjectCache().postNotification(getNode(), AXObjectCacheImpl::AXValueChange
d); |
144 } | 144 } |
145 | 145 |
146 String AXNodeObject::ariaAccessibilityDescription() const | 146 String AXNodeObject::ariaAccessibilityDescription() const |
147 { | 147 { |
148 String ariaLabelledby = ariaLabelledbyAttribute(); | 148 String ariaLabelledby = ariaLabelledbyAttribute(); |
149 if (!ariaLabelledby.isEmpty()) | 149 if (!ariaLabelledby.isEmpty()) |
150 return ariaLabelledby; | 150 return ariaLabelledby; |
151 | 151 |
152 const AtomicString& ariaLabel = getAttribute(aria_labelAttr); | 152 const AtomicString& ariaLabel = getAttribute(aria_labelAttr); |
153 if (!ariaLabel.isEmpty()) | 153 if (!ariaLabel.isEmpty()) |
(...skipping 15 matching lines...) Expand all Loading... |
169 if (ignoredReasons) | 169 if (ignoredReasons) |
170 ignoredReasons->append(IgnoredReason(AXAncestorIsLeafNode, leafNodeA
ncestor())); | 170 ignoredReasons->append(IgnoredReason(AXAncestorIsLeafNode, leafNodeA
ncestor())); |
171 return true; | 171 return true; |
172 } | 172 } |
173 | 173 |
174 // Ignore labels that are already referenced by a control. | 174 // Ignore labels that are already referenced by a control. |
175 AXObject* controlObject = correspondingControlForLabelElement(); | 175 AXObject* controlObject = correspondingControlForLabelElement(); |
176 if (controlObject && controlObject->isCheckboxOrRadio() && controlObject->na
meFromLabelElement()) { | 176 if (controlObject && controlObject->isCheckboxOrRadio() && controlObject->na
meFromLabelElement()) { |
177 if (ignoredReasons) { | 177 if (ignoredReasons) { |
178 HTMLLabelElement* label = labelElementContainer(); | 178 HTMLLabelElement* label = labelElementContainer(); |
179 if (label && label != node()) { | 179 if (label && label != getNode()) { |
180 AXObject* labelAXObject = axObjectCache().getOrCreate(label); | 180 AXObject* labelAXObject = axObjectCache().getOrCreate(label); |
181 ignoredReasons->append(IgnoredReason(AXLabelContainer, labelAXOb
ject)); | 181 ignoredReasons->append(IgnoredReason(AXLabelContainer, labelAXOb
ject)); |
182 } | 182 } |
183 | 183 |
184 ignoredReasons->append(IgnoredReason(AXLabelFor, controlObject)); | 184 ignoredReasons->append(IgnoredReason(AXLabelFor, controlObject)); |
185 } | 185 } |
186 return true; | 186 return true; |
187 } | 187 } |
188 | 188 |
189 Element* element = node()->isElementNode() ? toElement(node()) : node()->par
entElement(); | 189 Element* element = getNode()->isElementNode() ? toElement(getNode()) : getNo
de()->parentElement(); |
190 if (!layoutObject() | 190 if (!getLayoutObject() |
191 && (!element || !element->isInCanvasSubtree()) | 191 && (!element || !element->isInCanvasSubtree()) |
192 && !equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) { | 192 && !equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) { |
193 if (ignoredReasons) | 193 if (ignoredReasons) |
194 ignoredReasons->append(IgnoredReason(AXNotRendered)); | 194 ignoredReasons->append(IgnoredReason(AXNotRendered)); |
195 return true; | 195 return true; |
196 } | 196 } |
197 | 197 |
198 if (m_role == UnknownRole) { | 198 if (m_role == UnknownRole) { |
199 if (ignoredReasons) | 199 if (ignoredReasons) |
200 ignoredReasons->append(IgnoredReason(AXUninteresting)); | 200 ignoredReasons->append(IgnoredReason(AXUninteresting)); |
201 return true; | 201 return true; |
202 } | 202 } |
203 return false; | 203 return false; |
204 } | 204 } |
205 | 205 |
206 static bool isListElement(Node* node) | 206 static bool isListElement(Node* node) |
207 { | 207 { |
208 return isHTMLUListElement(*node) || isHTMLOListElement(*node) || isHTMLDList
Element(*node); | 208 return isHTMLUListElement(*node) || isHTMLOListElement(*node) || isHTMLDList
Element(*node); |
209 } | 209 } |
210 | 210 |
211 static bool isPresentationalInTable(AXObject* parent, HTMLElement* currentElemen
t) | 211 static bool isPresentationalInTable(AXObject* parent, HTMLElement* currentElemen
t) |
212 { | 212 { |
213 if (!currentElement) | 213 if (!currentElement) |
214 return false; | 214 return false; |
215 | 215 |
216 Node* parentNode = parent->node(); | 216 Node* parentNode = parent->getNode(); |
217 if (!parentNode || !parentNode->isHTMLElement()) | 217 if (!parentNode || !parentNode->isHTMLElement()) |
218 return false; | 218 return false; |
219 | 219 |
220 // AXTable determines the role as checking isTableXXX. | 220 // AXTable determines the role as checking isTableXXX. |
221 // If Table has explicit role including presentation, AXTable doesn't assign
implicit Role | 221 // If Table has explicit role including presentation, AXTable doesn't assign
implicit Role |
222 // to a whole Table. That's why we should check it based on node. | 222 // to a whole Table. That's why we should check it based on node. |
223 // Normal Table Tree is that | 223 // Normal Table Tree is that |
224 // cell(its role)-> tr(tr role)-> tfoot, tbody, thead(ignored role) -> table
(table role). | 224 // cell(its role)-> tr(tr role)-> tfoot, tbody, thead(ignored role) -> table
(table role). |
225 // If table has presentation role, it will be like | 225 // If table has presentation role, it will be like |
226 // cell(group)-> tr(unknown) -> tfoot, tbody, thead(ignored) -> table(presen
tation). | 226 // cell(group)-> tr(unknown) -> tfoot, tbody, thead(ignored) -> table(presen
tation). |
227 if (isHTMLTableCellElement(*currentElement) && isHTMLTableRowElement(*parent
Node)) | 227 if (isHTMLTableCellElement(*currentElement) && isHTMLTableRowElement(*parent
Node)) |
228 return parent->hasInheritedPresentationalRole(); | 228 return parent->hasInheritedPresentationalRole(); |
229 | 229 |
230 if (isHTMLTableRowElement(*currentElement) && isHTMLTableSectionElement(toHT
MLElement(*parentNode))) { | 230 if (isHTMLTableRowElement(*currentElement) && isHTMLTableSectionElement(toHT
MLElement(*parentNode))) { |
231 // Because TableSections have ignored role, presentation should be check
ed with its parent node | 231 // Because TableSections have ignored role, presentation should be check
ed with its parent node |
232 AXObject* tableObject = parent->parentObject(); | 232 AXObject* tableObject = parent->parentObject(); |
233 Node* tableNode = tableObject ? tableObject->node() : 0; | 233 Node* tableNode = tableObject ? tableObject->getNode() : 0; |
234 return isHTMLTableElement(tableNode) && tableObject->hasInheritedPresent
ationalRole(); | 234 return isHTMLTableElement(tableNode) && tableObject->hasInheritedPresent
ationalRole(); |
235 } | 235 } |
236 return false; | 236 return false; |
237 } | 237 } |
238 | 238 |
239 static bool isRequiredOwnedElement(AXObject* parent, AccessibilityRole currentRo
le, HTMLElement* currentElement) | 239 static bool isRequiredOwnedElement(AXObject* parent, AccessibilityRole currentRo
le, HTMLElement* currentElement) |
240 { | 240 { |
241 Node* parentNode = parent->node(); | 241 Node* parentNode = parent->getNode(); |
242 if (!parentNode || !parentNode->isHTMLElement()) | 242 if (!parentNode || !parentNode->isHTMLElement()) |
243 return false; | 243 return false; |
244 | 244 |
245 if (currentRole == ListItemRole) | 245 if (currentRole == ListItemRole) |
246 return isListElement(parentNode); | 246 return isListElement(parentNode); |
247 if (currentRole == ListMarkerRole) | 247 if (currentRole == ListMarkerRole) |
248 return isHTMLLIElement(*parentNode); | 248 return isHTMLLIElement(*parentNode); |
249 if (currentRole == MenuItemCheckBoxRole || currentRole == MenuItemRole || cu
rrentRole == MenuItemRadioRole) | 249 if (currentRole == MenuItemCheckBoxRole || currentRole == MenuItemRole || cu
rrentRole == MenuItemRadioRole) |
250 return isHTMLMenuElement(*parentNode); | 250 return isHTMLMenuElement(*parentNode); |
251 | 251 |
(...skipping 24 matching lines...) Expand all Loading... |
276 // ARIA spec says that the user agent MUST apply an inherited role of presen
tation | 276 // ARIA spec says that the user agent MUST apply an inherited role of presen
tation |
277 // to any owned elements that do not have an explicit role defined. | 277 // to any owned elements that do not have an explicit role defined. |
278 if (ariaRoleAttribute() != UnknownRole) | 278 if (ariaRoleAttribute() != UnknownRole) |
279 return 0; | 279 return 0; |
280 | 280 |
281 AXObject* parent = parentObject(); | 281 AXObject* parent = parentObject(); |
282 if (!parent) | 282 if (!parent) |
283 return 0; | 283 return 0; |
284 | 284 |
285 HTMLElement* element = nullptr; | 285 HTMLElement* element = nullptr; |
286 if (node() && node()->isHTMLElement()) | 286 if (getNode() && getNode()->isHTMLElement()) |
287 element = toHTMLElement(node()); | 287 element = toHTMLElement(getNode()); |
288 if (!parent->hasInheritedPresentationalRole()) { | 288 if (!parent->hasInheritedPresentationalRole()) { |
289 if (!layoutObject() || !layoutObject()->isBoxModelObject()) | 289 if (!getLayoutObject() || !getLayoutObject()->isBoxModelObject()) |
290 return 0; | 290 return 0; |
291 | 291 |
292 LayoutBoxModelObject* cssBox = toLayoutBoxModelObject(layoutObject()); | 292 LayoutBoxModelObject* cssBox = toLayoutBoxModelObject(getLayoutObject())
; |
293 if (!cssBox->isTableCell() && !cssBox->isTableRow()) | 293 if (!cssBox->isTableCell() && !cssBox->isTableRow()) |
294 return 0; | 294 return 0; |
295 | 295 |
296 if (!isPresentationalInTable(parent, element)) | 296 if (!isPresentationalInTable(parent, element)) |
297 return 0; | 297 return 0; |
298 } | 298 } |
299 // ARIA spec says that when a parent object is presentational and this objec
t | 299 // ARIA spec says that when a parent object is presentational and this objec
t |
300 // is a required owned element of that parent, then this object is also pres
entational. | 300 // is a required owned element of that parent, then this object is also pres
entational. |
301 if (isRequiredOwnedElement(parent, roleValue(), element)) | 301 if (isRequiredOwnedElement(parent, roleValue(), element)) |
302 return parent; | 302 return parent; |
303 return 0; | 303 return 0; |
304 } | 304 } |
305 | 305 |
306 bool AXNodeObject::isDescendantOfElementType(const HTMLQualifiedName& tagName) c
onst | 306 bool AXNodeObject::isDescendantOfElementType(const HTMLQualifiedName& tagName) c
onst |
307 { | 307 { |
308 if (!node()) | 308 if (!getNode()) |
309 return false; | 309 return false; |
310 | 310 |
311 for (Element* parent = node()->parentElement(); parent; parent = parent->par
entElement()) { | 311 for (Element* parent = getNode()->parentElement(); parent; parent = parent->
parentElement()) { |
312 if (parent->hasTagName(tagName)) | 312 if (parent->hasTagName(tagName)) |
313 return true; | 313 return true; |
314 } | 314 } |
315 return false; | 315 return false; |
316 } | 316 } |
317 | 317 |
318 AccessibilityRole AXNodeObject::nativeAccessibilityRoleIgnoringAria() const | 318 AccessibilityRole AXNodeObject::nativeAccessibilityRoleIgnoringAria() const |
319 { | 319 { |
320 if (!node()) | 320 if (!getNode()) |
321 return UnknownRole; | 321 return UnknownRole; |
322 | 322 |
323 // HTMLAnchorElement sets isLink only when it has hrefAttr. | 323 // HTMLAnchorElement sets isLink only when it has hrefAttr. |
324 // We assume that it is also LinkRole if it has event listners even though i
t doesn't have hrefAttr. | 324 // We assume that it is also LinkRole if it has event listners even though i
t doesn't have hrefAttr. |
325 if (node()->isLink() || (isHTMLAnchorElement(*node()) && isClickable())) | 325 if (getNode()->isLink() || (isHTMLAnchorElement(*getNode()) && isClickable()
)) |
326 return LinkRole; | 326 return LinkRole; |
327 | 327 |
328 if (isHTMLButtonElement(*node())) | 328 if (isHTMLButtonElement(*getNode())) |
329 return buttonRoleType(); | 329 return buttonRoleType(); |
330 | 330 |
331 if (isHTMLDetailsElement(*node())) | 331 if (isHTMLDetailsElement(*getNode())) |
332 return DetailsRole; | 332 return DetailsRole; |
333 | 333 |
334 if (isHTMLSummaryElement(*node())) { | 334 if (isHTMLSummaryElement(*getNode())) { |
335 ContainerNode* parent = FlatTreeTraversal::parent(*node()); | 335 ContainerNode* parent = FlatTreeTraversal::parent(*getNode()); |
336 if (parent && isHTMLDetailsElement(parent)) | 336 if (parent && isHTMLDetailsElement(parent)) |
337 return DisclosureTriangleRole; | 337 return DisclosureTriangleRole; |
338 return UnknownRole; | 338 return UnknownRole; |
339 } | 339 } |
340 | 340 |
341 if (isHTMLInputElement(*node())) { | 341 if (isHTMLInputElement(*getNode())) { |
342 HTMLInputElement& input = toHTMLInputElement(*node()); | 342 HTMLInputElement& input = toHTMLInputElement(*getNode()); |
343 const AtomicString& type = input.type(); | 343 const AtomicString& type = input.type(); |
344 if (input.dataList()) | 344 if (input.dataList()) |
345 return ComboBoxRole; | 345 return ComboBoxRole; |
346 if (type == InputTypeNames::button) { | 346 if (type == InputTypeNames::button) { |
347 if ((node()->parentNode() && isHTMLMenuElement(node()->parentNode())
) || (parentObject() && parentObject()->roleValue() == MenuRole)) | 347 if ((getNode()->parentNode() && isHTMLMenuElement(getNode()->parentN
ode())) || (parentObject() && parentObject()->roleValue() == MenuRole)) |
348 return MenuItemRole; | 348 return MenuItemRole; |
349 return buttonRoleType(); | 349 return buttonRoleType(); |
350 } | 350 } |
351 if (type == InputTypeNames::checkbox) { | 351 if (type == InputTypeNames::checkbox) { |
352 if ((node()->parentNode() && isHTMLMenuElement(node()->parentNode())
) || (parentObject() && parentObject()->roleValue() == MenuRole)) | 352 if ((getNode()->parentNode() && isHTMLMenuElement(getNode()->parentN
ode())) || (parentObject() && parentObject()->roleValue() == MenuRole)) |
353 return MenuItemCheckBoxRole; | 353 return MenuItemCheckBoxRole; |
354 return CheckBoxRole; | 354 return CheckBoxRole; |
355 } | 355 } |
356 if (type == InputTypeNames::date) | 356 if (type == InputTypeNames::date) |
357 return DateRole; | 357 return DateRole; |
358 if (type == InputTypeNames::datetime | 358 if (type == InputTypeNames::datetime |
359 || type == InputTypeNames::datetime_local | 359 || type == InputTypeNames::datetime_local |
360 || type == InputTypeNames::month | 360 || type == InputTypeNames::month |
361 || type == InputTypeNames::week) | 361 || type == InputTypeNames::week) |
362 return DateTimeRole; | 362 return DateTimeRole; |
363 if (type == InputTypeNames::file) | 363 if (type == InputTypeNames::file) |
364 return ButtonRole; | 364 return ButtonRole; |
365 if (type == InputTypeNames::radio) { | 365 if (type == InputTypeNames::radio) { |
366 if ((node()->parentNode() && isHTMLMenuElement(node()->parentNode())
) || (parentObject() && parentObject()->roleValue() == MenuRole)) | 366 if ((getNode()->parentNode() && isHTMLMenuElement(getNode()->parentN
ode())) || (parentObject() && parentObject()->roleValue() == MenuRole)) |
367 return MenuItemRadioRole; | 367 return MenuItemRadioRole; |
368 return RadioButtonRole; | 368 return RadioButtonRole; |
369 } | 369 } |
370 if (type == InputTypeNames::number) | 370 if (type == InputTypeNames::number) |
371 return SpinButtonRole; | 371 return SpinButtonRole; |
372 if (input.isTextButton()) | 372 if (input.isTextButton()) |
373 return buttonRoleType(); | 373 return buttonRoleType(); |
374 if (type == InputTypeNames::range) | 374 if (type == InputTypeNames::range) |
375 return SliderRole; | 375 return SliderRole; |
376 if (type == InputTypeNames::color) | 376 if (type == InputTypeNames::color) |
377 return ColorWellRole; | 377 return ColorWellRole; |
378 if (type == InputTypeNames::time) | 378 if (type == InputTypeNames::time) |
379 return InputTimeRole; | 379 return InputTimeRole; |
380 return TextFieldRole; | 380 return TextFieldRole; |
381 } | 381 } |
382 | 382 |
383 if (isHTMLSelectElement(*node())) { | 383 if (isHTMLSelectElement(*getNode())) { |
384 HTMLSelectElement& selectElement = toHTMLSelectElement(*node()); | 384 HTMLSelectElement& selectElement = toHTMLSelectElement(*getNode()); |
385 return selectElement.multiple() ? ListBoxRole : PopUpButtonRole; | 385 return selectElement.multiple() ? ListBoxRole : PopUpButtonRole; |
386 } | 386 } |
387 | 387 |
388 if (isHTMLTextAreaElement(*node())) | 388 if (isHTMLTextAreaElement(*getNode())) |
389 return TextFieldRole; | 389 return TextFieldRole; |
390 | 390 |
391 if (headingLevel()) | 391 if (headingLevel()) |
392 return HeadingRole; | 392 return HeadingRole; |
393 | 393 |
394 if (isHTMLDivElement(*node())) | 394 if (isHTMLDivElement(*getNode())) |
395 return DivRole; | 395 return DivRole; |
396 | 396 |
397 if (isHTMLMeterElement(*node())) | 397 if (isHTMLMeterElement(*getNode())) |
398 return MeterRole; | 398 return MeterRole; |
399 | 399 |
400 if (isHTMLOutputElement(*node())) | 400 if (isHTMLOutputElement(*getNode())) |
401 return StatusRole; | 401 return StatusRole; |
402 | 402 |
403 if (isHTMLParagraphElement(*node())) | 403 if (isHTMLParagraphElement(*getNode())) |
404 return ParagraphRole; | 404 return ParagraphRole; |
405 | 405 |
406 if (isHTMLLabelElement(*node())) | 406 if (isHTMLLabelElement(*getNode())) |
407 return LabelRole; | 407 return LabelRole; |
408 | 408 |
409 if (isHTMLLegendElement(*node())) | 409 if (isHTMLLegendElement(*getNode())) |
410 return LegendRole; | 410 return LegendRole; |
411 | 411 |
412 if (isHTMLRubyElement(*node())) | 412 if (isHTMLRubyElement(*getNode())) |
413 return RubyRole; | 413 return RubyRole; |
414 | 414 |
415 if (isHTMLDListElement(*node())) | 415 if (isHTMLDListElement(*getNode())) |
416 return DescriptionListRole; | 416 return DescriptionListRole; |
417 | 417 |
418 if (node()->hasTagName(ddTag)) | 418 if (getNode()->hasTagName(ddTag)) |
419 return DescriptionListDetailRole; | 419 return DescriptionListDetailRole; |
420 | 420 |
421 if (node()->hasTagName(dtTag)) | 421 if (getNode()->hasTagName(dtTag)) |
422 return DescriptionListTermRole; | 422 return DescriptionListTermRole; |
423 | 423 |
424 if (node()->nodeName() == "math") | 424 if (getNode()->nodeName() == "math") |
425 return MathRole; | 425 return MathRole; |
426 | 426 |
427 if (node()->hasTagName(rpTag) || node()->hasTagName(rtTag)) | 427 if (getNode()->hasTagName(rpTag) || getNode()->hasTagName(rtTag)) |
428 return AnnotationRole; | 428 return AnnotationRole; |
429 | 429 |
430 if (isHTMLFormElement(*node())) | 430 if (isHTMLFormElement(*getNode())) |
431 return FormRole; | 431 return FormRole; |
432 | 432 |
433 if (node()->hasTagName(abbrTag)) | 433 if (getNode()->hasTagName(abbrTag)) |
434 return AbbrRole; | 434 return AbbrRole; |
435 | 435 |
436 if (node()->hasTagName(articleTag)) | 436 if (getNode()->hasTagName(articleTag)) |
437 return ArticleRole; | 437 return ArticleRole; |
438 | 438 |
439 if (node()->hasTagName(mainTag)) | 439 if (getNode()->hasTagName(mainTag)) |
440 return MainRole; | 440 return MainRole; |
441 | 441 |
442 if (node()->hasTagName(markTag)) | 442 if (getNode()->hasTagName(markTag)) |
443 return MarkRole; | 443 return MarkRole; |
444 | 444 |
445 if (node()->hasTagName(navTag)) | 445 if (getNode()->hasTagName(navTag)) |
446 return NavigationRole; | 446 return NavigationRole; |
447 | 447 |
448 if (node()->hasTagName(asideTag)) | 448 if (getNode()->hasTagName(asideTag)) |
449 return ComplementaryRole; | 449 return ComplementaryRole; |
450 | 450 |
451 if (node()->hasTagName(preTag)) | 451 if (getNode()->hasTagName(preTag)) |
452 return PreRole; | 452 return PreRole; |
453 | 453 |
454 if (node()->hasTagName(sectionTag)) | 454 if (getNode()->hasTagName(sectionTag)) |
455 return RegionRole; | 455 return RegionRole; |
456 | 456 |
457 if (node()->hasTagName(addressTag)) | 457 if (getNode()->hasTagName(addressTag)) |
458 return ContentInfoRole; | 458 return ContentInfoRole; |
459 | 459 |
460 if (isHTMLDialogElement(*node())) | 460 if (isHTMLDialogElement(*getNode())) |
461 return DialogRole; | 461 return DialogRole; |
462 | 462 |
463 // The HTML element should not be exposed as an element. That's what the Lay
outView element does. | 463 // The HTML element should not be exposed as an element. That's what the Lay
outView element does. |
464 if (isHTMLHtmlElement(*node())) | 464 if (isHTMLHtmlElement(*getNode())) |
465 return IgnoredRole; | 465 return IgnoredRole; |
466 | 466 |
467 if (isHTMLIFrameElement(*node())) { | 467 if (isHTMLIFrameElement(*getNode())) { |
468 const AtomicString& ariaRole = getAttribute(roleAttr); | 468 const AtomicString& ariaRole = getAttribute(roleAttr); |
469 if (ariaRole == "none" || ariaRole == "presentation") | 469 if (ariaRole == "none" || ariaRole == "presentation") |
470 return IframePresentationalRole; | 470 return IframePresentationalRole; |
471 return IframeRole; | 471 return IframeRole; |
472 } | 472 } |
473 | 473 |
474 // There should only be one banner/contentInfo per page. If header/footer ar
e being used within an article or section | 474 // There should only be one banner/contentInfo per page. If header/footer ar
e being used within an article or section |
475 // then it should not be exposed as whole page's banner/contentInfo | 475 // then it should not be exposed as whole page's banner/contentInfo |
476 if (node()->hasTagName(headerTag) && !isDescendantOfElementType(articleTag)
&& !isDescendantOfElementType(sectionTag)) | 476 if (getNode()->hasTagName(headerTag) && !isDescendantOfElementType(articleTa
g) && !isDescendantOfElementType(sectionTag)) |
477 return BannerRole; | 477 return BannerRole; |
478 | 478 |
479 if (node()->hasTagName(footerTag) && !isDescendantOfElementType(articleTag)
&& !isDescendantOfElementType(sectionTag)) | 479 if (getNode()->hasTagName(footerTag) && !isDescendantOfElementType(articleTa
g) && !isDescendantOfElementType(sectionTag)) |
480 return FooterRole; | 480 return FooterRole; |
481 | 481 |
482 if (node()->hasTagName(blockquoteTag)) | 482 if (getNode()->hasTagName(blockquoteTag)) |
483 return BlockquoteRole; | 483 return BlockquoteRole; |
484 | 484 |
485 if (node()->hasTagName(captionTag)) | 485 if (getNode()->hasTagName(captionTag)) |
486 return CaptionRole; | 486 return CaptionRole; |
487 | 487 |
488 if (node()->hasTagName(figcaptionTag)) | 488 if (getNode()->hasTagName(figcaptionTag)) |
489 return FigcaptionRole; | 489 return FigcaptionRole; |
490 | 490 |
491 if (node()->hasTagName(figureTag)) | 491 if (getNode()->hasTagName(figureTag)) |
492 return FigureRole; | 492 return FigureRole; |
493 | 493 |
494 if (node()->nodeName() == "TIME") | 494 if (getNode()->nodeName() == "TIME") |
495 return TimeRole; | 495 return TimeRole; |
496 | 496 |
497 if (isEmbeddedObject()) | 497 if (isEmbeddedObject()) |
498 return EmbeddedObjectRole; | 498 return EmbeddedObjectRole; |
499 | 499 |
500 if (isHTMLHRElement(*node())) | 500 if (isHTMLHRElement(*getNode())) |
501 return SplitterRole; | 501 return SplitterRole; |
502 | 502 |
503 return UnknownRole; | 503 return UnknownRole; |
504 } | 504 } |
505 | 505 |
506 AccessibilityRole AXNodeObject::determineAccessibilityRole() | 506 AccessibilityRole AXNodeObject::determineAccessibilityRole() |
507 { | 507 { |
508 if (!node()) | 508 if (!getNode()) |
509 return UnknownRole; | 509 return UnknownRole; |
510 | 510 |
511 if ((m_ariaRole = determineAriaRoleAttribute()) != UnknownRole) | 511 if ((m_ariaRole = determineAriaRoleAttribute()) != UnknownRole) |
512 return m_ariaRole; | 512 return m_ariaRole; |
513 if (node()->isTextNode()) | 513 if (getNode()->isTextNode()) |
514 return StaticTextRole; | 514 return StaticTextRole; |
515 | 515 |
516 AccessibilityRole role = nativeAccessibilityRoleIgnoringAria(); | 516 AccessibilityRole role = nativeAccessibilityRoleIgnoringAria(); |
517 if (role != UnknownRole) | 517 if (role != UnknownRole) |
518 return role; | 518 return role; |
519 if (node()->isElementNode()) { | 519 if (getNode()->isElementNode()) { |
520 Element* element = toElement(node()); | 520 Element* element = toElement(getNode()); |
521 if (element->isInCanvasSubtree()) { | 521 if (element->isInCanvasSubtree()) { |
522 document()->updateLayoutTreeForNode(element); | 522 getDocument()->updateLayoutTreeForNode(element); |
523 if (element->isFocusable()) | 523 if (element->isFocusable()) |
524 return GroupRole; | 524 return GroupRole; |
525 } | 525 } |
526 } | 526 } |
527 return UnknownRole; | 527 return UnknownRole; |
528 } | 528 } |
529 | 529 |
530 AccessibilityRole AXNodeObject::determineAriaRoleAttribute() const | 530 AccessibilityRole AXNodeObject::determineAriaRoleAttribute() const |
531 { | 531 { |
532 const AtomicString& ariaRole = getAttribute(roleAttr); | 532 const AtomicString& ariaRole = getAttribute(roleAttr); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 // it's focusable, and existing logic should handle this case already - so i
t's not a | 607 // it's focusable, and existing logic should handle this case already - so i
t's not a |
608 // generic focusable element. | 608 // generic focusable element. |
609 | 609 |
610 if (hasContentEditableAttributeSet()) | 610 if (hasContentEditableAttributeSet()) |
611 return false; | 611 return false; |
612 | 612 |
613 // The web area and body element are both focusable, but existing logic hand
les these | 613 // The web area and body element are both focusable, but existing logic hand
les these |
614 // cases already, so we don't need to include them here. | 614 // cases already, so we don't need to include them here. |
615 if (roleValue() == WebAreaRole) | 615 if (roleValue() == WebAreaRole) |
616 return false; | 616 return false; |
617 if (isHTMLBodyElement(node())) | 617 if (isHTMLBodyElement(getNode())) |
618 return false; | 618 return false; |
619 | 619 |
620 // An SVG root is focusable by default, but it's probably not interactive, s
o don't | 620 // An SVG root is focusable by default, but it's probably not interactive, s
o don't |
621 // include it. It can still be made accessible by giving it an ARIA role. | 621 // include it. It can still be made accessible by giving it an ARIA role. |
622 if (roleValue() == SVGRootRole) | 622 if (roleValue() == SVGRootRole) |
623 return false; | 623 return false; |
624 | 624 |
625 return true; | 625 return true; |
626 } | 626 } |
627 | 627 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 } | 669 } |
670 | 670 |
671 return 0; | 671 return 0; |
672 } | 672 } |
673 | 673 |
674 Element* AXNodeObject::menuItemElementForMenu() const | 674 Element* AXNodeObject::menuItemElementForMenu() const |
675 { | 675 { |
676 if (ariaRoleAttribute() != MenuRole) | 676 if (ariaRoleAttribute() != MenuRole) |
677 return 0; | 677 return 0; |
678 | 678 |
679 return siblingWithAriaRole("menuitem", node()); | 679 return siblingWithAriaRole("menuitem", getNode()); |
680 } | 680 } |
681 | 681 |
682 Element* AXNodeObject::mouseButtonListener() const | 682 Element* AXNodeObject::mouseButtonListener() const |
683 { | 683 { |
684 Node* node = this->node(); | 684 Node* node = this->getNode(); |
685 if (!node) | 685 if (!node) |
686 return 0; | 686 return 0; |
687 | 687 |
688 // check if our parent is a mouse button listener | 688 // check if our parent is a mouse button listener |
689 if (!node->isElementNode()) | 689 if (!node->isElementNode()) |
690 node = node->parentElement(); | 690 node = node->parentElement(); |
691 | 691 |
692 if (!node) | 692 if (!node) |
693 return 0; | 693 return 0; |
694 | 694 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 m_node = nullptr; | 744 m_node = nullptr; |
745 } | 745 } |
746 | 746 |
747 bool AXNodeObject::isAnchor() const | 747 bool AXNodeObject::isAnchor() const |
748 { | 748 { |
749 return !isNativeImage() && isLink(); | 749 return !isNativeImage() && isLink(); |
750 } | 750 } |
751 | 751 |
752 bool AXNodeObject::isControl() const | 752 bool AXNodeObject::isControl() const |
753 { | 753 { |
754 Node* node = this->node(); | 754 Node* node = this->getNode(); |
755 if (!node) | 755 if (!node) |
756 return false; | 756 return false; |
757 | 757 |
758 return ((node->isElementNode() && toElement(node)->isFormControlElement()) | 758 return ((node->isElementNode() && toElement(node)->isFormControlElement()) |
759 || AXObject::isARIAControl(ariaRoleAttribute())); | 759 || AXObject::isARIAControl(ariaRoleAttribute())); |
760 } | 760 } |
761 | 761 |
762 bool AXNodeObject::isControllingVideoElement() const | 762 bool AXNodeObject::isControllingVideoElement() const |
763 { | 763 { |
764 Node* node = this->node(); | 764 Node* node = this->getNode(); |
765 if (!node) | 765 if (!node) |
766 return true; | 766 return true; |
767 | 767 |
768 return isHTMLVideoElement(toParentMediaElement(node)); | 768 return isHTMLVideoElement(toParentMediaElement(node)); |
769 } | 769 } |
770 | 770 |
771 bool AXNodeObject::isEmbeddedObject() const | 771 bool AXNodeObject::isEmbeddedObject() const |
772 { | 772 { |
773 return isHTMLPlugInElement(node()); | 773 return isHTMLPlugInElement(getNode()); |
774 } | 774 } |
775 | 775 |
776 bool AXNodeObject::isFieldset() const | 776 bool AXNodeObject::isFieldset() const |
777 { | 777 { |
778 return isHTMLFieldSetElement(node()); | 778 return isHTMLFieldSetElement(getNode()); |
779 } | 779 } |
780 | 780 |
781 bool AXNodeObject::isHeading() const | 781 bool AXNodeObject::isHeading() const |
782 { | 782 { |
783 return roleValue() == HeadingRole; | 783 return roleValue() == HeadingRole; |
784 } | 784 } |
785 | 785 |
786 bool AXNodeObject::isHovered() const | 786 bool AXNodeObject::isHovered() const |
787 { | 787 { |
788 Node* node = this->node(); | 788 Node* node = this->getNode(); |
789 if (!node) | 789 if (!node) |
790 return false; | 790 return false; |
791 | 791 |
792 return node->hovered(); | 792 return node->hovered(); |
793 } | 793 } |
794 | 794 |
795 bool AXNodeObject::isImage() const | 795 bool AXNodeObject::isImage() const |
796 { | 796 { |
797 return roleValue() == ImageRole; | 797 return roleValue() == ImageRole; |
798 } | 798 } |
799 | 799 |
800 bool AXNodeObject::isImageButton() const | 800 bool AXNodeObject::isImageButton() const |
801 { | 801 { |
802 return isNativeImage() && isButton(); | 802 return isNativeImage() && isButton(); |
803 } | 803 } |
804 | 804 |
805 bool AXNodeObject::isInputImage() const | 805 bool AXNodeObject::isInputImage() const |
806 { | 806 { |
807 Node* node = this->node(); | 807 Node* node = this->getNode(); |
808 if (roleValue() == ButtonRole && isHTMLInputElement(node)) | 808 if (roleValue() == ButtonRole && isHTMLInputElement(node)) |
809 return toHTMLInputElement(*node).type() == InputTypeNames::image; | 809 return toHTMLInputElement(*node).type() == InputTypeNames::image; |
810 | 810 |
811 return false; | 811 return false; |
812 } | 812 } |
813 | 813 |
814 bool AXNodeObject::isLink() const | 814 bool AXNodeObject::isLink() const |
815 { | 815 { |
816 return roleValue() == LinkRole; | 816 return roleValue() == LinkRole; |
817 } | 817 } |
(...skipping 14 matching lines...) Expand all Loading... |
832 } | 832 } |
833 | 833 |
834 bool AXNodeObject::isMultiSelectable() const | 834 bool AXNodeObject::isMultiSelectable() const |
835 { | 835 { |
836 const AtomicString& ariaMultiSelectable = getAttribute(aria_multiselectableA
ttr); | 836 const AtomicString& ariaMultiSelectable = getAttribute(aria_multiselectableA
ttr); |
837 if (equalIgnoringCase(ariaMultiSelectable, "true")) | 837 if (equalIgnoringCase(ariaMultiSelectable, "true")) |
838 return true; | 838 return true; |
839 if (equalIgnoringCase(ariaMultiSelectable, "false")) | 839 if (equalIgnoringCase(ariaMultiSelectable, "false")) |
840 return false; | 840 return false; |
841 | 841 |
842 return isHTMLSelectElement(node()) && toHTMLSelectElement(*node()).multiple(
); | 842 return isHTMLSelectElement(getNode()) && toHTMLSelectElement(*getNode()).mul
tiple(); |
843 } | 843 } |
844 | 844 |
845 bool AXNodeObject::isNativeCheckboxOrRadio() const | 845 bool AXNodeObject::isNativeCheckboxOrRadio() const |
846 { | 846 { |
847 Node* node = this->node(); | 847 Node* node = this->getNode(); |
848 if (!isHTMLInputElement(node)) | 848 if (!isHTMLInputElement(node)) |
849 return false; | 849 return false; |
850 | 850 |
851 HTMLInputElement* input = toHTMLInputElement(node); | 851 HTMLInputElement* input = toHTMLInputElement(node); |
852 return input->type() == InputTypeNames::checkbox || input->type() == InputTy
peNames::radio; | 852 return input->type() == InputTypeNames::checkbox || input->type() == InputTy
peNames::radio; |
853 } | 853 } |
854 | 854 |
855 bool AXNodeObject::isNativeImage() const | 855 bool AXNodeObject::isNativeImage() const |
856 { | 856 { |
857 Node* node = this->node(); | 857 Node* node = this->getNode(); |
858 if (!node) | 858 if (!node) |
859 return false; | 859 return false; |
860 | 860 |
861 if (isHTMLImageElement(*node)) | 861 if (isHTMLImageElement(*node)) |
862 return true; | 862 return true; |
863 | 863 |
864 if (isHTMLPlugInElement(*node)) | 864 if (isHTMLPlugInElement(*node)) |
865 return true; | 865 return true; |
866 | 866 |
867 if (isHTMLInputElement(*node)) | 867 if (isHTMLInputElement(*node)) |
868 return toHTMLInputElement(*node).type() == InputTypeNames::image; | 868 return toHTMLInputElement(*node).type() == InputTypeNames::image; |
869 | 869 |
870 return false; | 870 return false; |
871 } | 871 } |
872 | 872 |
873 bool AXNodeObject::isNativeTextControl() const | 873 bool AXNodeObject::isNativeTextControl() const |
874 { | 874 { |
875 Node* node = this->node(); | 875 Node* node = this->getNode(); |
876 if (!node) | 876 if (!node) |
877 return false; | 877 return false; |
878 | 878 |
879 if (isHTMLTextAreaElement(*node)) | 879 if (isHTMLTextAreaElement(*node)) |
880 return true; | 880 return true; |
881 | 881 |
882 if (isHTMLInputElement(*node)) | 882 if (isHTMLInputElement(*node)) |
883 return toHTMLInputElement(node)->isTextField(); | 883 return toHTMLInputElement(node)->isTextField(); |
884 | 884 |
885 return false; | 885 return false; |
886 } | 886 } |
887 | 887 |
888 bool AXNodeObject::isNonNativeTextControl() const | 888 bool AXNodeObject::isNonNativeTextControl() const |
889 { | 889 { |
890 if (isNativeTextControl()) | 890 if (isNativeTextControl()) |
891 return false; | 891 return false; |
892 | 892 |
893 if (hasContentEditableAttributeSet()) | 893 if (hasContentEditableAttributeSet()) |
894 return true; | 894 return true; |
895 | 895 |
896 if (isARIATextControl()) | 896 if (isARIATextControl()) |
897 return true; | 897 return true; |
898 | 898 |
899 return false; | 899 return false; |
900 } | 900 } |
901 | 901 |
902 bool AXNodeObject::isPasswordField() const | 902 bool AXNodeObject::isPasswordField() const |
903 { | 903 { |
904 Node* node = this->node(); | 904 Node* node = this->getNode(); |
905 if (!isHTMLInputElement(node)) | 905 if (!isHTMLInputElement(node)) |
906 return false; | 906 return false; |
907 | 907 |
908 AccessibilityRole ariaRole = ariaRoleAttribute(); | 908 AccessibilityRole ariaRole = ariaRoleAttribute(); |
909 if (ariaRole != TextFieldRole && ariaRole != UnknownRole) | 909 if (ariaRole != TextFieldRole && ariaRole != UnknownRole) |
910 return false; | 910 return false; |
911 | 911 |
912 return toHTMLInputElement(node)->type() == InputTypeNames::password; | 912 return toHTMLInputElement(node)->type() == InputTypeNames::password; |
913 } | 913 } |
914 | 914 |
915 bool AXNodeObject::isProgressIndicator() const | 915 bool AXNodeObject::isProgressIndicator() const |
916 { | 916 { |
917 return roleValue() == ProgressIndicatorRole; | 917 return roleValue() == ProgressIndicatorRole; |
918 } | 918 } |
919 | 919 |
920 bool AXNodeObject::isRichlyEditable() const | 920 bool AXNodeObject::isRichlyEditable() const |
921 { | 921 { |
922 return hasContentEditableAttributeSet() && !isARIATextControl(); | 922 return hasContentEditableAttributeSet() && !isARIATextControl(); |
923 } | 923 } |
924 | 924 |
925 bool AXNodeObject::isSlider() const | 925 bool AXNodeObject::isSlider() const |
926 { | 926 { |
927 return roleValue() == SliderRole; | 927 return roleValue() == SliderRole; |
928 } | 928 } |
929 | 929 |
930 bool AXNodeObject::isNativeSlider() const | 930 bool AXNodeObject::isNativeSlider() const |
931 { | 931 { |
932 Node* node = this->node(); | 932 Node* node = this->getNode(); |
933 if (!node) | 933 if (!node) |
934 return false; | 934 return false; |
935 | 935 |
936 if (!isHTMLInputElement(node)) | 936 if (!isHTMLInputElement(node)) |
937 return false; | 937 return false; |
938 | 938 |
939 return toHTMLInputElement(node)->type() == InputTypeNames::range; | 939 return toHTMLInputElement(node)->type() == InputTypeNames::range; |
940 } | 940 } |
941 | 941 |
942 bool AXNodeObject::isChecked() const | 942 bool AXNodeObject::isChecked() const |
943 { | 943 { |
944 Node* node = this->node(); | 944 Node* node = this->getNode(); |
945 if (!node) | 945 if (!node) |
946 return false; | 946 return false; |
947 | 947 |
948 // First test for native checkedness semantics | 948 // First test for native checkedness semantics |
949 if (isHTMLInputElement(*node)) | 949 if (isHTMLInputElement(*node)) |
950 return toHTMLInputElement(*node).shouldAppearChecked(); | 950 return toHTMLInputElement(*node).shouldAppearChecked(); |
951 | 951 |
952 // Else, if this is an ARIA role checkbox or radio or menuitemcheckbox | 952 // Else, if this is an ARIA role checkbox or radio or menuitemcheckbox |
953 // or menuitemradio or switch, respect the aria-checked attribute | 953 // or menuitemradio or switch, respect the aria-checked attribute |
954 switch (ariaRoleAttribute()) { | 954 switch (ariaRoleAttribute()) { |
955 case CheckBoxRole: | 955 case CheckBoxRole: |
956 case MenuItemCheckBoxRole: | 956 case MenuItemCheckBoxRole: |
957 case MenuItemRadioRole: | 957 case MenuItemRadioRole: |
958 case RadioButtonRole: | 958 case RadioButtonRole: |
959 case SwitchRole: | 959 case SwitchRole: |
960 if (equalIgnoringCase(getAttribute(aria_checkedAttr), "true")) | 960 if (equalIgnoringCase(getAttribute(aria_checkedAttr), "true")) |
961 return true; | 961 return true; |
962 return false; | 962 return false; |
963 default: | 963 default: |
964 break; | 964 break; |
965 } | 965 } |
966 | 966 |
967 // Otherwise it's not checked | 967 // Otherwise it's not checked |
968 return false; | 968 return false; |
969 } | 969 } |
970 | 970 |
971 bool AXNodeObject::isClickable() const | 971 bool AXNodeObject::isClickable() const |
972 { | 972 { |
973 if (node()) { | 973 if (getNode()) { |
974 if (node()->isElementNode() && toElement(node())->isDisabledFormControl(
)) | 974 if (getNode()->isElementNode() && toElement(getNode())->isDisabledFormCo
ntrol()) |
975 return false; | 975 return false; |
976 | 976 |
977 // Note: we can't call node()->willRespondToMouseClickEvents() because t
hat triggers a style recalc and can delete this. | 977 // Note: we can't call getNode()->willRespondToMouseClickEvents() becaus
e that triggers a style recalc and can delete this. |
978 if (node()->hasEventListeners(EventTypeNames::mouseup) || node()->hasEve
ntListeners(EventTypeNames::mousedown) || node()->hasEventListeners(EventTypeNam
es::click) || node()->hasEventListeners(EventTypeNames::DOMActivate)) | 978 if (getNode()->hasEventListeners(EventTypeNames::mouseup) || getNode()->
hasEventListeners(EventTypeNames::mousedown) || getNode()->hasEventListeners(Eve
ntTypeNames::click) || getNode()->hasEventListeners(EventTypeNames::DOMActivate)
) |
979 return true; | 979 return true; |
980 } | 980 } |
981 | 981 |
982 return AXObject::isClickable(); | 982 return AXObject::isClickable(); |
983 } | 983 } |
984 | 984 |
985 bool AXNodeObject::isEnabled() const | 985 bool AXNodeObject::isEnabled() const |
986 { | 986 { |
987 if (isDescendantOfDisabledNode()) | 987 if (isDescendantOfDisabledNode()) |
988 return false; | 988 return false; |
989 | 989 |
990 Node* node = this->node(); | 990 Node* node = this->getNode(); |
991 if (!node || !node->isElementNode()) | 991 if (!node || !node->isElementNode()) |
992 return true; | 992 return true; |
993 | 993 |
994 return !toElement(node)->isDisabledFormControl(); | 994 return !toElement(node)->isDisabledFormControl(); |
995 } | 995 } |
996 | 996 |
997 AccessibilityExpanded AXNodeObject::isExpanded() const | 997 AccessibilityExpanded AXNodeObject::isExpanded() const |
998 { | 998 { |
999 if (node() && isHTMLSummaryElement(*node())) { | 999 if (getNode() && isHTMLSummaryElement(*getNode())) { |
1000 if (node()->parentNode() && isHTMLDetailsElement(node()->parentNode())) | 1000 if (getNode()->parentNode() && isHTMLDetailsElement(getNode()->parentNod
e())) |
1001 return toElement(node()->parentNode())->hasAttribute(openAttr) ? Exp
andedExpanded : ExpandedCollapsed; | 1001 return toElement(getNode()->parentNode())->hasAttribute(openAttr) ?
ExpandedExpanded : ExpandedCollapsed; |
1002 } | 1002 } |
1003 | 1003 |
1004 const AtomicString& expanded = getAttribute(aria_expandedAttr); | 1004 const AtomicString& expanded = getAttribute(aria_expandedAttr); |
1005 if (equalIgnoringCase(expanded, "true")) | 1005 if (equalIgnoringCase(expanded, "true")) |
1006 return ExpandedExpanded; | 1006 return ExpandedExpanded; |
1007 if (equalIgnoringCase(expanded, "false")) | 1007 if (equalIgnoringCase(expanded, "false")) |
1008 return ExpandedCollapsed; | 1008 return ExpandedCollapsed; |
1009 | 1009 |
1010 return ExpandedUndefined; | 1010 return ExpandedUndefined; |
1011 } | 1011 } |
1012 | 1012 |
1013 bool AXNodeObject::isPressed() const | 1013 bool AXNodeObject::isPressed() const |
1014 { | 1014 { |
1015 if (!isButton()) | 1015 if (!isButton()) |
1016 return false; | 1016 return false; |
1017 | 1017 |
1018 Node* node = this->node(); | 1018 Node* node = this->getNode(); |
1019 if (!node) | 1019 if (!node) |
1020 return false; | 1020 return false; |
1021 | 1021 |
1022 // ARIA button with aria-pressed not undefined, then check for aria-pressed
attribute rather than node()->active() | 1022 // ARIA button with aria-pressed not undefined, then check for aria-pressed
attribute rather than getNode()->active() |
1023 if (ariaRoleAttribute() == ToggleButtonRole) { | 1023 if (ariaRoleAttribute() == ToggleButtonRole) { |
1024 if (equalIgnoringCase(getAttribute(aria_pressedAttr), "true") | 1024 if (equalIgnoringCase(getAttribute(aria_pressedAttr), "true") |
1025 || equalIgnoringCase(getAttribute(aria_pressedAttr), "mixed")) | 1025 || equalIgnoringCase(getAttribute(aria_pressedAttr), "mixed")) |
1026 return true; | 1026 return true; |
1027 return false; | 1027 return false; |
1028 } | 1028 } |
1029 | 1029 |
1030 return node->active(); | 1030 return node->active(); |
1031 } | 1031 } |
1032 | 1032 |
1033 bool AXNodeObject::isReadOnly() const | 1033 bool AXNodeObject::isReadOnly() const |
1034 { | 1034 { |
1035 Node* node = this->node(); | 1035 Node* node = this->getNode(); |
1036 if (!node) | 1036 if (!node) |
1037 return true; | 1037 return true; |
1038 | 1038 |
1039 if (isHTMLTextAreaElement(*node)) | 1039 if (isHTMLTextAreaElement(*node)) |
1040 return toHTMLTextAreaElement(*node).isReadOnly(); | 1040 return toHTMLTextAreaElement(*node).isReadOnly(); |
1041 | 1041 |
1042 if (isHTMLInputElement(*node)) { | 1042 if (isHTMLInputElement(*node)) { |
1043 HTMLInputElement& input = toHTMLInputElement(*node); | 1043 HTMLInputElement& input = toHTMLInputElement(*node); |
1044 if (input.isTextField()) | 1044 if (input.isTextField()) |
1045 return input.isReadOnly(); | 1045 return input.isReadOnly(); |
1046 } | 1046 } |
1047 | 1047 |
1048 return !node->hasEditableStyle(); | 1048 return !node->hasEditableStyle(); |
1049 } | 1049 } |
1050 | 1050 |
1051 bool AXNodeObject::isRequired() const | 1051 bool AXNodeObject::isRequired() const |
1052 { | 1052 { |
1053 Node* n = this->node(); | 1053 Node* n = this->getNode(); |
1054 if (n && (n->isElementNode() && toElement(n)->isFormControlElement()) && has
Attribute(requiredAttr)) | 1054 if (n && (n->isElementNode() && toElement(n)->isFormControlElement()) && has
Attribute(requiredAttr)) |
1055 return toHTMLFormControlElement(n)->isRequired(); | 1055 return toHTMLFormControlElement(n)->isRequired(); |
1056 | 1056 |
1057 if (equalIgnoringCase(getAttribute(aria_requiredAttr), "true")) | 1057 if (equalIgnoringCase(getAttribute(aria_requiredAttr), "true")) |
1058 return true; | 1058 return true; |
1059 | 1059 |
1060 return false; | 1060 return false; |
1061 } | 1061 } |
1062 | 1062 |
1063 bool AXNodeObject::canSetFocusAttribute() const | 1063 bool AXNodeObject::canSetFocusAttribute() const |
1064 { | 1064 { |
1065 Node* node = this->node(); | 1065 Node* node = this->getNode(); |
1066 if (!node) | 1066 if (!node) |
1067 return false; | 1067 return false; |
1068 | 1068 |
1069 if (isWebArea()) | 1069 if (isWebArea()) |
1070 return true; | 1070 return true; |
1071 | 1071 |
1072 // NOTE: It would be more accurate to ask the document whether setFocusedNod
e() would | 1072 // NOTE: It would be more accurate to ask the document whether setFocusedNod
e() would |
1073 // do anything. For example, setFocusedNode() will do nothing if the current
focused | 1073 // do anything. For example, setFocusedNode() will do nothing if the current
focused |
1074 // node will not relinquish the focus. | 1074 // node will not relinquish the focus. |
1075 if (!node) | 1075 if (!node) |
(...skipping 16 matching lines...) Expand all Loading... |
1092 if (isTextControl() && !isNativeTextControl()) | 1092 if (isTextControl() && !isNativeTextControl()) |
1093 return true; | 1093 return true; |
1094 | 1094 |
1095 // Any node could be contenteditable, so isReadOnly should be relied upon | 1095 // Any node could be contenteditable, so isReadOnly should be relied upon |
1096 // for this information for all elements. | 1096 // for this information for all elements. |
1097 return !isReadOnly(); | 1097 return !isReadOnly(); |
1098 } | 1098 } |
1099 | 1099 |
1100 bool AXNodeObject::canvasHasFallbackContent() const | 1100 bool AXNodeObject::canvasHasFallbackContent() const |
1101 { | 1101 { |
1102 Node* node = this->node(); | 1102 Node* node = this->getNode(); |
1103 if (!isHTMLCanvasElement(node)) | 1103 if (!isHTMLCanvasElement(node)) |
1104 return false; | 1104 return false; |
1105 | 1105 |
1106 // If it has any children that are elements, we'll assume it might be fallba
ck | 1106 // If it has any children that are elements, we'll assume it might be fallba
ck |
1107 // content. If it has no children or its only children are not elements | 1107 // content. If it has no children or its only children are not elements |
1108 // (e.g. just text nodes), it doesn't have fallback content. | 1108 // (e.g. just text nodes), it doesn't have fallback content. |
1109 return ElementTraversal::firstChild(*node); | 1109 return ElementTraversal::firstChild(*node); |
1110 } | 1110 } |
1111 | 1111 |
1112 int AXNodeObject::headingLevel() const | 1112 int AXNodeObject::headingLevel() const |
1113 { | 1113 { |
1114 // headings can be in block flow and non-block flow | 1114 // headings can be in block flow and non-block flow |
1115 Node* node = this->node(); | 1115 Node* node = this->getNode(); |
1116 if (!node) | 1116 if (!node) |
1117 return 0; | 1117 return 0; |
1118 | 1118 |
1119 if (roleValue() == HeadingRole && hasAttribute(aria_levelAttr)) { | 1119 if (roleValue() == HeadingRole && hasAttribute(aria_levelAttr)) { |
1120 int level = getAttribute(aria_levelAttr).toInt(); | 1120 int level = getAttribute(aria_levelAttr).toInt(); |
1121 if (level >= 1 && level <= 9) | 1121 if (level >= 1 && level <= 9) |
1122 return level; | 1122 return level; |
1123 } | 1123 } |
1124 | 1124 |
1125 if (!node->isHTMLElement()) | 1125 if (!node->isHTMLElement()) |
(...skipping 16 matching lines...) Expand all Loading... |
1142 return 5; | 1142 return 5; |
1143 | 1143 |
1144 if (element.hasTagName(h6Tag)) | 1144 if (element.hasTagName(h6Tag)) |
1145 return 6; | 1145 return 6; |
1146 | 1146 |
1147 return 0; | 1147 return 0; |
1148 } | 1148 } |
1149 | 1149 |
1150 unsigned AXNodeObject::hierarchicalLevel() const | 1150 unsigned AXNodeObject::hierarchicalLevel() const |
1151 { | 1151 { |
1152 Node* node = this->node(); | 1152 Node* node = this->getNode(); |
1153 if (!node || !node->isElementNode()) | 1153 if (!node || !node->isElementNode()) |
1154 return 0; | 1154 return 0; |
1155 Element* element = toElement(node); | 1155 Element* element = toElement(node); |
1156 String ariaLevel = element->getAttribute(aria_levelAttr); | 1156 String ariaLevel = element->getAttribute(aria_levelAttr); |
1157 if (!ariaLevel.isEmpty()) | 1157 if (!ariaLevel.isEmpty()) |
1158 return ariaLevel.toInt(); | 1158 return ariaLevel.toInt(); |
1159 | 1159 |
1160 // Only tree item will calculate its level through the DOM currently. | 1160 // Only tree item will calculate its level through the DOM currently. |
1161 if (roleValue() != TreeItemRole) | 1161 if (roleValue() != TreeItemRole) |
1162 return 0; | 1162 return 0; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 | 1229 |
1230 String AXNodeObject::text() const | 1230 String AXNodeObject::text() const |
1231 { | 1231 { |
1232 // If this is a user defined static text, use the accessible name computatio
n. | 1232 // If this is a user defined static text, use the accessible name computatio
n. |
1233 if (ariaRoleAttribute() == StaticTextRole) | 1233 if (ariaRoleAttribute() == StaticTextRole) |
1234 return ariaAccessibilityDescription(); | 1234 return ariaAccessibilityDescription(); |
1235 | 1235 |
1236 if (!isTextControl()) | 1236 if (!isTextControl()) |
1237 return String(); | 1237 return String(); |
1238 | 1238 |
1239 Node* node = this->node(); | 1239 Node* node = this->getNode(); |
1240 if (!node) | 1240 if (!node) |
1241 return String(); | 1241 return String(); |
1242 | 1242 |
1243 if (isNativeTextControl() && (isHTMLTextAreaElement(*node) || isHTMLInputEle
ment(*node))) | 1243 if (isNativeTextControl() && (isHTMLTextAreaElement(*node) || isHTMLInputEle
ment(*node))) |
1244 return toHTMLTextFormControlElement(*node).value(); | 1244 return toHTMLTextFormControlElement(*node).value(); |
1245 | 1245 |
1246 if (!node->isElementNode()) | 1246 if (!node->isElementNode()) |
1247 return String(); | 1247 return String(); |
1248 | 1248 |
1249 return toElement(node)->innerText(); | 1249 return toElement(node)->innerText(); |
1250 } | 1250 } |
1251 | 1251 |
1252 AccessibilityButtonState AXNodeObject::checkboxOrRadioValue() const | 1252 AccessibilityButtonState AXNodeObject::checkboxOrRadioValue() const |
1253 { | 1253 { |
1254 if (isNativeCheckboxInMixedState()) | 1254 if (isNativeCheckboxInMixedState()) |
1255 return ButtonStateMixed; | 1255 return ButtonStateMixed; |
1256 | 1256 |
1257 if (isNativeCheckboxOrRadio()) | 1257 if (isNativeCheckboxOrRadio()) |
1258 return isChecked() ? ButtonStateOn : ButtonStateOff; | 1258 return isChecked() ? ButtonStateOn : ButtonStateOff; |
1259 | 1259 |
1260 return AXObject::checkboxOrRadioValue(); | 1260 return AXObject::checkboxOrRadioValue(); |
1261 } | 1261 } |
1262 | 1262 |
1263 RGBA32 AXNodeObject::colorValue() const | 1263 RGBA32 AXNodeObject::colorValue() const |
1264 { | 1264 { |
1265 if (!isHTMLInputElement(node()) || !isColorWell()) | 1265 if (!isHTMLInputElement(getNode()) || !isColorWell()) |
1266 return AXObject::colorValue(); | 1266 return AXObject::colorValue(); |
1267 | 1267 |
1268 HTMLInputElement* input = toHTMLInputElement(node()); | 1268 HTMLInputElement* input = toHTMLInputElement(getNode()); |
1269 const AtomicString& type = input->getAttribute(typeAttr); | 1269 const AtomicString& type = input->getAttribute(typeAttr); |
1270 if (!equalIgnoringCase(type, "color")) | 1270 if (!equalIgnoringCase(type, "color")) |
1271 return AXObject::colorValue(); | 1271 return AXObject::colorValue(); |
1272 | 1272 |
1273 // HTMLInputElement::value always returns a string parseable by Color. | 1273 // HTMLInputElement::value always returns a string parseable by Color. |
1274 Color color; | 1274 Color color; |
1275 bool success = color.setFromString(input->value()); | 1275 bool success = color.setFromString(input->value()); |
1276 ASSERT_UNUSED(success, success); | 1276 ASSERT_UNUSED(success, success); |
1277 return color.rgb(); | 1277 return color.rgb(); |
1278 } | 1278 } |
1279 | 1279 |
1280 InvalidState AXNodeObject::getInvalidState() const | 1280 InvalidState AXNodeObject::getInvalidState() const |
1281 { | 1281 { |
1282 if (hasAttribute(aria_invalidAttr)) { | 1282 if (hasAttribute(aria_invalidAttr)) { |
1283 const AtomicString& attributeValue = getAttribute(aria_invalidAttr); | 1283 const AtomicString& attributeValue = getAttribute(aria_invalidAttr); |
1284 if (equalIgnoringCase(attributeValue, "false")) | 1284 if (equalIgnoringCase(attributeValue, "false")) |
1285 return InvalidStateFalse; | 1285 return InvalidStateFalse; |
1286 if (equalIgnoringCase(attributeValue, "true")) | 1286 if (equalIgnoringCase(attributeValue, "true")) |
1287 return InvalidStateTrue; | 1287 return InvalidStateTrue; |
1288 if (equalIgnoringCase(attributeValue, "spelling")) | 1288 if (equalIgnoringCase(attributeValue, "spelling")) |
1289 return InvalidStateSpelling; | 1289 return InvalidStateSpelling; |
1290 if (equalIgnoringCase(attributeValue, "grammar")) | 1290 if (equalIgnoringCase(attributeValue, "grammar")) |
1291 return InvalidStateGrammar; | 1291 return InvalidStateGrammar; |
1292 // A yet unknown value. | 1292 // A yet unknown value. |
1293 if (!attributeValue.isEmpty()) | 1293 if (!attributeValue.isEmpty()) |
1294 return InvalidStateOther; | 1294 return InvalidStateOther; |
1295 } | 1295 } |
1296 | 1296 |
1297 if (node() && node()->isElementNode() | 1297 if (getNode() && getNode()->isElementNode() |
1298 && toElement(node())->isFormControlElement()) { | 1298 && toElement(getNode())->isFormControlElement()) { |
1299 HTMLFormControlElement* element = toHTMLFormControlElement(node()); | 1299 HTMLFormControlElement* element = toHTMLFormControlElement(getNode()); |
1300 WillBeHeapVector<RefPtrWillBeMember<HTMLFormControlElement>> | 1300 WillBeHeapVector<RefPtrWillBeMember<HTMLFormControlElement>> |
1301 invalidControls; | 1301 invalidControls; |
1302 bool isInvalid = !element->checkValidity( | 1302 bool isInvalid = !element->checkValidity( |
1303 &invalidControls, CheckValidityDispatchNoEvent); | 1303 &invalidControls, CheckValidityDispatchNoEvent); |
1304 return isInvalid ? InvalidStateTrue : InvalidStateFalse; | 1304 return isInvalid ? InvalidStateTrue : InvalidStateFalse; |
1305 } | 1305 } |
1306 | 1306 |
1307 return InvalidStateUndefined; | 1307 return InvalidStateUndefined; |
1308 } | 1308 } |
1309 | 1309 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1348 | 1348 |
1349 return getAttribute(aria_valuetextAttr).string(); | 1349 return getAttribute(aria_valuetextAttr).string(); |
1350 } | 1350 } |
1351 | 1351 |
1352 float AXNodeObject::valueForRange() const | 1352 float AXNodeObject::valueForRange() const |
1353 { | 1353 { |
1354 if (hasAttribute(aria_valuenowAttr)) | 1354 if (hasAttribute(aria_valuenowAttr)) |
1355 return getAttribute(aria_valuenowAttr).toFloat(); | 1355 return getAttribute(aria_valuenowAttr).toFloat(); |
1356 | 1356 |
1357 if (isNativeSlider()) | 1357 if (isNativeSlider()) |
1358 return toHTMLInputElement(*node()).valueAsNumber(); | 1358 return toHTMLInputElement(*getNode()).valueAsNumber(); |
1359 | 1359 |
1360 if (isHTMLMeterElement(node())) | 1360 if (isHTMLMeterElement(getNode())) |
1361 return toHTMLMeterElement(*node()).value(); | 1361 return toHTMLMeterElement(*getNode()).value(); |
1362 | 1362 |
1363 return 0.0; | 1363 return 0.0; |
1364 } | 1364 } |
1365 | 1365 |
1366 float AXNodeObject::maxValueForRange() const | 1366 float AXNodeObject::maxValueForRange() const |
1367 { | 1367 { |
1368 if (hasAttribute(aria_valuemaxAttr)) | 1368 if (hasAttribute(aria_valuemaxAttr)) |
1369 return getAttribute(aria_valuemaxAttr).toFloat(); | 1369 return getAttribute(aria_valuemaxAttr).toFloat(); |
1370 | 1370 |
1371 if (isNativeSlider()) | 1371 if (isNativeSlider()) |
1372 return toHTMLInputElement(*node()).maximum(); | 1372 return toHTMLInputElement(*getNode()).maximum(); |
1373 | 1373 |
1374 if (isHTMLMeterElement(node())) | 1374 if (isHTMLMeterElement(getNode())) |
1375 return toHTMLMeterElement(*node()).max(); | 1375 return toHTMLMeterElement(*getNode()).max(); |
1376 | 1376 |
1377 return 0.0; | 1377 return 0.0; |
1378 } | 1378 } |
1379 | 1379 |
1380 float AXNodeObject::minValueForRange() const | 1380 float AXNodeObject::minValueForRange() const |
1381 { | 1381 { |
1382 if (hasAttribute(aria_valueminAttr)) | 1382 if (hasAttribute(aria_valueminAttr)) |
1383 return getAttribute(aria_valueminAttr).toFloat(); | 1383 return getAttribute(aria_valueminAttr).toFloat(); |
1384 | 1384 |
1385 if (isNativeSlider()) | 1385 if (isNativeSlider()) |
1386 return toHTMLInputElement(*node()).minimum(); | 1386 return toHTMLInputElement(*getNode()).minimum(); |
1387 | 1387 |
1388 if (isHTMLMeterElement(node())) | 1388 if (isHTMLMeterElement(getNode())) |
1389 return toHTMLMeterElement(*node()).min(); | 1389 return toHTMLMeterElement(*getNode()).min(); |
1390 | 1390 |
1391 return 0.0; | 1391 return 0.0; |
1392 } | 1392 } |
1393 | 1393 |
1394 float AXNodeObject::stepValueForRange() const | 1394 float AXNodeObject::stepValueForRange() const |
1395 { | 1395 { |
1396 if (!isNativeSlider()) | 1396 if (!isNativeSlider()) |
1397 return 0.0; | 1397 return 0.0; |
1398 | 1398 |
1399 Decimal step = toHTMLInputElement(*node()).createStepRange(RejectAny).step()
; | 1399 Decimal step = toHTMLInputElement(*getNode()).createStepRange(RejectAny).ste
p(); |
1400 return step.toString().toFloat(); | 1400 return step.toString().toFloat(); |
1401 } | 1401 } |
1402 | 1402 |
1403 String AXNodeObject::stringValue() const | 1403 String AXNodeObject::stringValue() const |
1404 { | 1404 { |
1405 Node* node = this->node(); | 1405 Node* node = this->getNode(); |
1406 if (!node) | 1406 if (!node) |
1407 return String(); | 1407 return String(); |
1408 | 1408 |
1409 if (isHTMLSelectElement(*node)) { | 1409 if (isHTMLSelectElement(*node)) { |
1410 HTMLSelectElement& selectElement = toHTMLSelectElement(*node); | 1410 HTMLSelectElement& selectElement = toHTMLSelectElement(*node); |
1411 int selectedIndex = selectElement.selectedIndex(); | 1411 int selectedIndex = selectElement.selectedIndex(); |
1412 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = sel
ectElement.listItems(); | 1412 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = sel
ectElement.listItems(); |
1413 if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems
.size()) { | 1413 if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems
.size()) { |
1414 const AtomicString& overriddenDescription = listItems[selectedIndex]
->fastGetAttribute(aria_labelAttr); | 1414 const AtomicString& overriddenDescription = listItems[selectedIndex]
->fastGetAttribute(aria_labelAttr); |
1415 if (!overriddenDescription.isNull()) | 1415 if (!overriddenDescription.isNull()) |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1502 // | 1502 // |
1503 | 1503 |
1504 String AXNodeObject::textAlternative(bool recursive, bool inAriaLabelledByTraver
sal, AXObjectSet& visited, AXNameFrom& nameFrom, AXRelatedObjectVector* relatedO
bjects, NameSources* nameSources) const | 1504 String AXNodeObject::textAlternative(bool recursive, bool inAriaLabelledByTraver
sal, AXObjectSet& visited, AXNameFrom& nameFrom, AXRelatedObjectVector* relatedO
bjects, NameSources* nameSources) const |
1505 { | 1505 { |
1506 // If nameSources is non-null, relatedObjects is used in filling it in, so i
t must be non-null as well. | 1506 // If nameSources is non-null, relatedObjects is used in filling it in, so i
t must be non-null as well. |
1507 if (nameSources) | 1507 if (nameSources) |
1508 ASSERT(relatedObjects); | 1508 ASSERT(relatedObjects); |
1509 | 1509 |
1510 bool foundTextAlternative = false; | 1510 bool foundTextAlternative = false; |
1511 | 1511 |
1512 if (!node() && !layoutObject()) | 1512 if (!getNode() && !getLayoutObject()) |
1513 return String(); | 1513 return String(); |
1514 | 1514 |
1515 String textAlternative = ariaTextAlternative(recursive, inAriaLabelledByTrav
ersal, visited, nameFrom, relatedObjects, nameSources, &foundTextAlternative); | 1515 String textAlternative = ariaTextAlternative(recursive, inAriaLabelledByTrav
ersal, visited, nameFrom, relatedObjects, nameSources, &foundTextAlternative); |
1516 if (foundTextAlternative && !nameSources) | 1516 if (foundTextAlternative && !nameSources) |
1517 return textAlternative; | 1517 return textAlternative; |
1518 | 1518 |
1519 // Step 2E from: http://www.w3.org/TR/accname-aam-1.1 | 1519 // Step 2E from: http://www.w3.org/TR/accname-aam-1.1 |
1520 if (recursive && !inAriaLabelledByTraversal && isControl() && !isButton()) { | 1520 if (recursive && !inAriaLabelledByTraversal && isControl() && !isButton()) { |
1521 // No need to set any name source info in a recursive call. | 1521 // No need to set any name source info in a recursive call. |
1522 if (isTextControl()) | 1522 if (isTextControl()) |
(...skipping 15 matching lines...) Expand all Loading... |
1538 return textAlternative; | 1538 return textAlternative; |
1539 | 1539 |
1540 // Step 2F / 2G from: http://www.w3.org/TR/accname-aam-1.1 | 1540 // Step 2F / 2G from: http://www.w3.org/TR/accname-aam-1.1 |
1541 if (recursive || nameFromContents()) { | 1541 if (recursive || nameFromContents()) { |
1542 nameFrom = AXNameFromContents; | 1542 nameFrom = AXNameFromContents; |
1543 if (nameSources) { | 1543 if (nameSources) { |
1544 nameSources->append(NameSource(foundTextAlternative)); | 1544 nameSources->append(NameSource(foundTextAlternative)); |
1545 nameSources->last().type = nameFrom; | 1545 nameSources->last().type = nameFrom; |
1546 } | 1546 } |
1547 | 1547 |
1548 Node* node = this->node(); | 1548 Node* node = this->getNode(); |
1549 if (node && node->isTextNode()) | 1549 if (node && node->isTextNode()) |
1550 textAlternative = toText(node)->wholeText(); | 1550 textAlternative = toText(node)->wholeText(); |
1551 else if (isHTMLBRElement(node)) | 1551 else if (isHTMLBRElement(node)) |
1552 textAlternative = String("\n"); | 1552 textAlternative = String("\n"); |
1553 else | 1553 else |
1554 textAlternative = textFromDescendants(visited, false); | 1554 textAlternative = textFromDescendants(visited, false); |
1555 | 1555 |
1556 if (!textAlternative.isEmpty()) { | 1556 if (!textAlternative.isEmpty()) { |
1557 if (nameSources) { | 1557 if (nameSources) { |
1558 foundTextAlternative = true; | 1558 foundTextAlternative = true; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1620 // Skip hidden children | 1620 // Skip hidden children |
1621 if (child->isInertOrAriaHidden()) | 1621 if (child->isInertOrAriaHidden()) |
1622 continue; | 1622 continue; |
1623 | 1623 |
1624 // If we're going between two layoutObjects that are in separate LayoutB
oxes, add | 1624 // If we're going between two layoutObjects that are in separate LayoutB
oxes, add |
1625 // whitespace if it wasn't there already. Intuitively if you have | 1625 // whitespace if it wasn't there already. Intuitively if you have |
1626 // <span>Hello</span><span>World</span>, those are part of the same Layo
utBox | 1626 // <span>Hello</span><span>World</span>, those are part of the same Layo
utBox |
1627 // so we should return "HelloWorld", but given <div>Hello</div><div>Worl
d</div> the | 1627 // so we should return "HelloWorld", but given <div>Hello</div><div>Worl
d</div> the |
1628 // strings are in separate boxes so we should return "Hello World". | 1628 // strings are in separate boxes so we should return "Hello World". |
1629 if (previous && accumulatedText.length() && !isHTMLSpace(accumulatedText
[accumulatedText.length() - 1])) { | 1629 if (previous && accumulatedText.length() && !isHTMLSpace(accumulatedText
[accumulatedText.length() - 1])) { |
1630 if (!isInSameNonInlineBlockFlow(child->layoutObject(), previous->lay
outObject())) | 1630 if (!isInSameNonInlineBlockFlow(child->getLayoutObject(), previous->
getLayoutObject())) |
1631 accumulatedText.append(' '); | 1631 accumulatedText.append(' '); |
1632 } | 1632 } |
1633 | 1633 |
1634 String result; | 1634 String result; |
1635 if (child->isPresentational()) | 1635 if (child->isPresentational()) |
1636 result = child->textFromDescendants(visited, true); | 1636 result = child->textFromDescendants(visited, true); |
1637 else | 1637 else |
1638 result = recursiveTextAlternative(*child, false, visited); | 1638 result = recursiveTextAlternative(*child, false, visited); |
1639 accumulatedText.append(result); | 1639 accumulatedText.append(result); |
1640 previous = child; | 1640 previous = child; |
1641 } | 1641 } |
1642 | 1642 |
1643 return accumulatedText.toString(); | 1643 return accumulatedText.toString(); |
1644 } | 1644 } |
1645 | 1645 |
1646 bool AXNodeObject::nameFromLabelElement() const | 1646 bool AXNodeObject::nameFromLabelElement() const |
1647 { | 1647 { |
1648 // This unfortunately duplicates a bit of logic from textAlternative and nat
iveTextAlternative, | 1648 // This unfortunately duplicates a bit of logic from textAlternative and nat
iveTextAlternative, |
1649 // but it's necessary because nameFromLabelElement needs to be called from | 1649 // but it's necessary because nameFromLabelElement needs to be called from |
1650 // computeAccessibilityIsIgnored, which isn't allowed to call axObjectCache-
>getOrCreate. | 1650 // computeAccessibilityIsIgnored, which isn't allowed to call axObjectCache-
>getOrCreate. |
1651 | 1651 |
1652 if (!node() && !layoutObject()) | 1652 if (!getNode() && !getLayoutObject()) |
1653 return false; | 1653 return false; |
1654 | 1654 |
1655 // Step 2A from: http://www.w3.org/TR/accname-aam-1.1 | 1655 // Step 2A from: http://www.w3.org/TR/accname-aam-1.1 |
1656 if (isHiddenForTextAlternativeCalculation()) | 1656 if (isHiddenForTextAlternativeCalculation()) |
1657 return false; | 1657 return false; |
1658 | 1658 |
1659 // Step 2B from: http://www.w3.org/TR/accname-aam-1.1 | 1659 // Step 2B from: http://www.w3.org/TR/accname-aam-1.1 |
1660 WillBeHeapVector<RawPtrWillBeMember<Element>> elements; | 1660 WillBeHeapVector<RawPtrWillBeMember<Element>> elements; |
1661 ariaLabelledbyElementVector(elements); | 1661 ariaLabelledbyElementVector(elements); |
1662 if (elements.size() > 0) | 1662 if (elements.size() > 0) |
1663 return false; | 1663 return false; |
1664 | 1664 |
1665 // Step 2C from: http://www.w3.org/TR/accname-aam-1.1 | 1665 // Step 2C from: http://www.w3.org/TR/accname-aam-1.1 |
1666 const AtomicString& ariaLabel = getAttribute(aria_labelAttr); | 1666 const AtomicString& ariaLabel = getAttribute(aria_labelAttr); |
1667 if (!ariaLabel.isEmpty()) | 1667 if (!ariaLabel.isEmpty()) |
1668 return false; | 1668 return false; |
1669 | 1669 |
1670 // Based on http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessi
ble-name-and-description-calculation | 1670 // Based on http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessi
ble-name-and-description-calculation |
1671 // 5.1/5.5 Text inputs, Other labelable Elements | 1671 // 5.1/5.5 Text inputs, Other labelable Elements |
1672 HTMLElement* htmlElement = nullptr; | 1672 HTMLElement* htmlElement = nullptr; |
1673 if (node()->isHTMLElement()) | 1673 if (getNode()->isHTMLElement()) |
1674 htmlElement = toHTMLElement(node()); | 1674 htmlElement = toHTMLElement(getNode()); |
1675 if (htmlElement && htmlElement->isLabelable()) { | 1675 if (htmlElement && htmlElement->isLabelable()) { |
1676 HTMLLabelElement* label = labelForElement(htmlElement); | 1676 HTMLLabelElement* label = labelForElement(htmlElement); |
1677 if (label) | 1677 if (label) |
1678 return true; | 1678 return true; |
1679 } | 1679 } |
1680 | 1680 |
1681 return false; | 1681 return false; |
1682 } | 1682 } |
1683 | 1683 |
1684 LayoutRect AXNodeObject::elementRect() const | 1684 LayoutRect AXNodeObject::elementRect() const |
1685 { | 1685 { |
1686 // First check if it has a custom rect, for example if this element is tied
to a canvas path. | 1686 // First check if it has a custom rect, for example if this element is tied
to a canvas path. |
1687 if (!m_explicitElementRect.isEmpty()) | 1687 if (!m_explicitElementRect.isEmpty()) |
1688 return m_explicitElementRect; | 1688 return m_explicitElementRect; |
1689 | 1689 |
1690 // FIXME: If there are a lot of elements in the canvas, it will be inefficie
nt. | 1690 // FIXME: If there are a lot of elements in the canvas, it will be inefficie
nt. |
1691 // We can avoid the inefficient calculations by using AXComputedObjectAttrib
uteCache. | 1691 // We can avoid the inefficient calculations by using AXComputedObjectAttrib
uteCache. |
1692 if (node()->parentElement()->isInCanvasSubtree()) { | 1692 if (getNode()->parentElement()->isInCanvasSubtree()) { |
1693 LayoutRect rect; | 1693 LayoutRect rect; |
1694 | 1694 |
1695 for (Node& child : NodeTraversal::childrenOf(*node())) { | 1695 for (Node& child : NodeTraversal::childrenOf(*getNode())) { |
1696 if (child.isHTMLElement()) { | 1696 if (child.isHTMLElement()) { |
1697 if (AXObject* obj = axObjectCache().get(&child)) { | 1697 if (AXObject* obj = axObjectCache().get(&child)) { |
1698 if (rect.isEmpty()) | 1698 if (rect.isEmpty()) |
1699 rect = obj->elementRect(); | 1699 rect = obj->elementRect(); |
1700 else | 1700 else |
1701 rect.unite(obj->elementRect()); | 1701 rect.unite(obj->elementRect()); |
1702 } | 1702 } |
1703 } | 1703 } |
1704 } | 1704 } |
1705 | 1705 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1738 | 1738 |
1739 if (!parentNode) | 1739 if (!parentNode) |
1740 parentNode = node->parentNode(); | 1740 parentNode = node->parentNode(); |
1741 | 1741 |
1742 return parentNode; | 1742 return parentNode; |
1743 } | 1743 } |
1744 | 1744 |
1745 AXObject* AXNodeObject::computeParent() const | 1745 AXObject* AXNodeObject::computeParent() const |
1746 { | 1746 { |
1747 ASSERT(!isDetached()); | 1747 ASSERT(!isDetached()); |
1748 if (Node* parentNode = getParentNodeForComputeParent(node())) | 1748 if (Node* parentNode = getParentNodeForComputeParent(getNode())) |
1749 return axObjectCache().getOrCreate(parentNode); | 1749 return axObjectCache().getOrCreate(parentNode); |
1750 | 1750 |
1751 return nullptr; | 1751 return nullptr; |
1752 } | 1752 } |
1753 | 1753 |
1754 AXObject* AXNodeObject::computeParentIfExists() const | 1754 AXObject* AXNodeObject::computeParentIfExists() const |
1755 { | 1755 { |
1756 if (Node* parentNode = getParentNodeForComputeParent(node())) | 1756 if (Node* parentNode = getParentNodeForComputeParent(getNode())) |
1757 return axObjectCache().get(parentNode); | 1757 return axObjectCache().get(parentNode); |
1758 | 1758 |
1759 return nullptr; | 1759 return nullptr; |
1760 } | 1760 } |
1761 | 1761 |
1762 AXObject* AXNodeObject::rawFirstChild() const | 1762 AXObject* AXNodeObject::rawFirstChild() const |
1763 { | 1763 { |
1764 if (!node()) | 1764 if (!getNode()) |
1765 return 0; | 1765 return 0; |
1766 | 1766 |
1767 Node* firstChild = node()->firstChild(); | 1767 Node* firstChild = getNode()->firstChild(); |
1768 | 1768 |
1769 if (!firstChild) | 1769 if (!firstChild) |
1770 return 0; | 1770 return 0; |
1771 | 1771 |
1772 return axObjectCache().getOrCreate(firstChild); | 1772 return axObjectCache().getOrCreate(firstChild); |
1773 } | 1773 } |
1774 | 1774 |
1775 AXObject* AXNodeObject::rawNextSibling() const | 1775 AXObject* AXNodeObject::rawNextSibling() const |
1776 { | 1776 { |
1777 if (!node()) | 1777 if (!getNode()) |
1778 return 0; | 1778 return 0; |
1779 | 1779 |
1780 Node* nextSibling = node()->nextSibling(); | 1780 Node* nextSibling = getNode()->nextSibling(); |
1781 if (!nextSibling) | 1781 if (!nextSibling) |
1782 return 0; | 1782 return 0; |
1783 | 1783 |
1784 return axObjectCache().getOrCreate(nextSibling); | 1784 return axObjectCache().getOrCreate(nextSibling); |
1785 } | 1785 } |
1786 | 1786 |
1787 void AXNodeObject::addChildren() | 1787 void AXNodeObject::addChildren() |
1788 { | 1788 { |
1789 ASSERT(!isDetached()); | 1789 ASSERT(!isDetached()); |
1790 // If the need to add more children in addition to existing children arises, | 1790 // If the need to add more children in addition to existing children arises, |
1791 // childrenChanged should have been called, leaving the object with no child
ren. | 1791 // childrenChanged should have been called, leaving the object with no child
ren. |
1792 ASSERT(!m_haveChildren); | 1792 ASSERT(!m_haveChildren); |
1793 | 1793 |
1794 if (!m_node) | 1794 if (!m_node) |
1795 return; | 1795 return; |
1796 | 1796 |
1797 m_haveChildren = true; | 1797 m_haveChildren = true; |
1798 | 1798 |
1799 // The only time we add children from the DOM tree to a node with a layoutOb
ject is when it's a canvas. | 1799 // The only time we add children from the DOM tree to a node with a layoutOb
ject is when it's a canvas. |
1800 if (layoutObject() && !isHTMLCanvasElement(*m_node)) | 1800 if (getLayoutObject() && !isHTMLCanvasElement(*m_node)) |
1801 return; | 1801 return; |
1802 | 1802 |
1803 HeapVector<Member<AXObject>> ownedChildren; | 1803 HeapVector<Member<AXObject>> ownedChildren; |
1804 computeAriaOwnsChildren(ownedChildren); | 1804 computeAriaOwnsChildren(ownedChildren); |
1805 | 1805 |
1806 for (Node& child : NodeTraversal::childrenOf(*m_node)) { | 1806 for (Node& child : NodeTraversal::childrenOf(*m_node)) { |
1807 AXObject* childObj = axObjectCache().getOrCreate(&child); | 1807 AXObject* childObj = axObjectCache().getOrCreate(&child); |
1808 if (!axObjectCache().isAriaOwned(childObj)) | 1808 if (!axObjectCache().isAriaOwned(childObj)) |
1809 addChild(childObj); | 1809 addChild(childObj); |
1810 } | 1810 } |
(...skipping 29 matching lines...) Expand all Loading... |
1840 ASSERT(child->parentObject() == this); | 1840 ASSERT(child->parentObject() == this); |
1841 m_children.insert(index, child); | 1841 m_children.insert(index, child); |
1842 } | 1842 } |
1843 } | 1843 } |
1844 | 1844 |
1845 bool AXNodeObject::canHaveChildren() const | 1845 bool AXNodeObject::canHaveChildren() const |
1846 { | 1846 { |
1847 // If this is an AXLayoutObject, then it's okay if this object | 1847 // If this is an AXLayoutObject, then it's okay if this object |
1848 // doesn't have a node - there are some layoutObjects that don't have associ
ated | 1848 // doesn't have a node - there are some layoutObjects that don't have associ
ated |
1849 // nodes, like scroll areas and css-generated text. | 1849 // nodes, like scroll areas and css-generated text. |
1850 if (!node() && !isAXLayoutObject()) | 1850 if (!getNode() && !isAXLayoutObject()) |
1851 return false; | 1851 return false; |
1852 | 1852 |
1853 if (node() && isHTMLMapElement(node())) | 1853 if (getNode() && isHTMLMapElement(getNode())) |
1854 return false; | 1854 return false; |
1855 | 1855 |
1856 AccessibilityRole role = roleValue(); | 1856 AccessibilityRole role = roleValue(); |
1857 | 1857 |
1858 // If an element has an ARIA role of presentation, we need to consider the n
ative | 1858 // If an element has an ARIA role of presentation, we need to consider the n
ative |
1859 // role when deciding whether it can have children or not - otherwise giving
something | 1859 // role when deciding whether it can have children or not - otherwise giving
something |
1860 // a role of presentation could expose inner implementation details. | 1860 // a role of presentation could expose inner implementation details. |
1861 if (isPresentational()) | 1861 if (isPresentational()) |
1862 role = nativeAccessibilityRoleIgnoringAria(); | 1862 role = nativeAccessibilityRoleIgnoringAria(); |
1863 | 1863 |
(...skipping 12 matching lines...) Expand all Loading... |
1876 case StaticTextRole: | 1876 case StaticTextRole: |
1877 if (!axObjectCache().inlineTextBoxAccessibilityEnabled()) | 1877 if (!axObjectCache().inlineTextBoxAccessibilityEnabled()) |
1878 return false; | 1878 return false; |
1879 default: | 1879 default: |
1880 return true; | 1880 return true; |
1881 } | 1881 } |
1882 } | 1882 } |
1883 | 1883 |
1884 Element* AXNodeObject::actionElement() const | 1884 Element* AXNodeObject::actionElement() const |
1885 { | 1885 { |
1886 Node* node = this->node(); | 1886 Node* node = this->getNode(); |
1887 if (!node) | 1887 if (!node) |
1888 return 0; | 1888 return 0; |
1889 | 1889 |
1890 if (isHTMLInputElement(*node)) { | 1890 if (isHTMLInputElement(*node)) { |
1891 HTMLInputElement& input = toHTMLInputElement(*node); | 1891 HTMLInputElement& input = toHTMLInputElement(*node); |
1892 if (!input.isDisabledFormControl() && (isCheckboxOrRadio() || input.isTe
xtButton() || input.type() == InputTypeNames::file)) | 1892 if (!input.isDisabledFormControl() && (isCheckboxOrRadio() || input.isTe
xtButton() || input.type() == InputTypeNames::file)) |
1893 return &input; | 1893 return &input; |
1894 } else if (isHTMLButtonElement(*node)) { | 1894 } else if (isHTMLButtonElement(*node)) { |
1895 return toElement(node); | 1895 return toElement(node); |
1896 } | 1896 } |
(...skipping 22 matching lines...) Expand all Loading... |
1919 } | 1919 } |
1920 | 1920 |
1921 Element* elt = anchorElement(); | 1921 Element* elt = anchorElement(); |
1922 if (!elt) | 1922 if (!elt) |
1923 elt = mouseButtonListener(); | 1923 elt = mouseButtonListener(); |
1924 return elt; | 1924 return elt; |
1925 } | 1925 } |
1926 | 1926 |
1927 Element* AXNodeObject::anchorElement() const | 1927 Element* AXNodeObject::anchorElement() const |
1928 { | 1928 { |
1929 Node* node = this->node(); | 1929 Node* node = this->getNode(); |
1930 if (!node) | 1930 if (!node) |
1931 return 0; | 1931 return 0; |
1932 | 1932 |
1933 AXObjectCacheImpl& cache = axObjectCache(); | 1933 AXObjectCacheImpl& cache = axObjectCache(); |
1934 | 1934 |
1935 // search up the DOM tree for an anchor element | 1935 // search up the DOM tree for an anchor element |
1936 // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElem
ent | 1936 // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElem
ent |
1937 for (; node; node = node->parentNode()) { | 1937 for (; node; node = node->parentNode()) { |
1938 if (isHTMLAnchorElement(*node) || (node->layoutObject() && cache.getOrCr
eate(node->layoutObject())->isAnchor())) | 1938 if (isHTMLAnchorElement(*node) || (node->layoutObject() && cache.getOrCr
eate(node->layoutObject())->isAnchor())) |
1939 return toElement(node); | 1939 return toElement(node); |
1940 } | 1940 } |
1941 | 1941 |
1942 return 0; | 1942 return 0; |
1943 } | 1943 } |
1944 | 1944 |
1945 Document* AXNodeObject::document() const | 1945 Document* AXNodeObject::getDocument() const |
1946 { | 1946 { |
1947 if (!node()) | 1947 if (!getNode()) |
1948 return 0; | 1948 return 0; |
1949 return &node()->document(); | 1949 return &getNode()->document(); |
1950 } | 1950 } |
1951 | 1951 |
1952 void AXNodeObject::setNode(Node* node) | 1952 void AXNodeObject::setNode(Node* node) |
1953 { | 1953 { |
1954 m_node = node; | 1954 m_node = node; |
1955 } | 1955 } |
1956 | 1956 |
1957 AXObject* AXNodeObject::correspondingControlForLabelElement() const | 1957 AXObject* AXNodeObject::correspondingControlForLabelElement() const |
1958 { | 1958 { |
1959 HTMLLabelElement* labelElement = labelElementContainer(); | 1959 HTMLLabelElement* labelElement = labelElementContainer(); |
1960 if (!labelElement) | 1960 if (!labelElement) |
1961 return 0; | 1961 return 0; |
1962 | 1962 |
1963 HTMLElement* correspondingControl = labelElement->control(); | 1963 HTMLElement* correspondingControl = labelElement->control(); |
1964 if (!correspondingControl) | 1964 if (!correspondingControl) |
1965 return 0; | 1965 return 0; |
1966 | 1966 |
1967 // Make sure the corresponding control isn't a descendant of this label | 1967 // Make sure the corresponding control isn't a descendant of this label |
1968 // that's in the middle of being destroyed. | 1968 // that's in the middle of being destroyed. |
1969 if (correspondingControl->layoutObject() && !correspondingControl->layoutObj
ect()->parent()) | 1969 if (correspondingControl->layoutObject() && !correspondingControl->layoutObj
ect()->parent()) |
1970 return 0; | 1970 return 0; |
1971 | 1971 |
1972 return axObjectCache().getOrCreate(correspondingControl); | 1972 return axObjectCache().getOrCreate(correspondingControl); |
1973 } | 1973 } |
1974 | 1974 |
1975 HTMLLabelElement* AXNodeObject::labelElementContainer() const | 1975 HTMLLabelElement* AXNodeObject::labelElementContainer() const |
1976 { | 1976 { |
1977 if (!node()) | 1977 if (!getNode()) |
1978 return 0; | 1978 return 0; |
1979 | 1979 |
1980 // the control element should not be considered part of the label | 1980 // the control element should not be considered part of the label |
1981 if (isControl()) | 1981 if (isControl()) |
1982 return 0; | 1982 return 0; |
1983 | 1983 |
1984 // the link element should not be considered part of the label | 1984 // the link element should not be considered part of the label |
1985 if (isLink()) | 1985 if (isLink()) |
1986 return 0; | 1986 return 0; |
1987 | 1987 |
1988 // find if this has a ancestor that is a label | 1988 // find if this has a ancestor that is a label |
1989 return Traversal<HTMLLabelElement>::firstAncestorOrSelf(*node()); | 1989 return Traversal<HTMLLabelElement>::firstAncestorOrSelf(*getNode()); |
1990 } | 1990 } |
1991 | 1991 |
1992 void AXNodeObject::setFocused(bool on) | 1992 void AXNodeObject::setFocused(bool on) |
1993 { | 1993 { |
1994 if (!canSetFocusAttribute()) | 1994 if (!canSetFocusAttribute()) |
1995 return; | 1995 return; |
1996 | 1996 |
1997 Document* document = this->document(); | 1997 Document* document = this->getDocument(); |
1998 if (!on) { | 1998 if (!on) { |
1999 document->clearFocusedElement(); | 1999 document->clearFocusedElement(); |
2000 } else { | 2000 } else { |
2001 Node* node = this->node(); | 2001 Node* node = this->getNode(); |
2002 if (node && node->isElementNode()) { | 2002 if (node && node->isElementNode()) { |
2003 // If this node is already the currently focused node, then calling
focus() won't do anything. | 2003 // If this node is already the currently focused node, then calling
focus() won't do anything. |
2004 // That is a problem when focus is removed from the webpage to chrom
e, and then returns. | 2004 // That is a problem when focus is removed from the webpage to chrom
e, and then returns. |
2005 // In these cases, we need to do what keyboard and mouse focus do, w
hich is reset focus first. | 2005 // In these cases, we need to do what keyboard and mouse focus do, w
hich is reset focus first. |
2006 if (document->focusedElement() == node) | 2006 if (document->focusedElement() == node) |
2007 document->clearFocusedElement(); | 2007 document->clearFocusedElement(); |
2008 | 2008 |
2009 toElement(node)->focus(); | 2009 toElement(node)->focus(); |
2010 } else { | 2010 } else { |
2011 document->clearFocusedElement(); | 2011 document->clearFocusedElement(); |
2012 } | 2012 } |
2013 } | 2013 } |
2014 } | 2014 } |
2015 | 2015 |
2016 void AXNodeObject::increment() | 2016 void AXNodeObject::increment() |
2017 { | 2017 { |
2018 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture); | 2018 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture); |
2019 alterSliderValue(true); | 2019 alterSliderValue(true); |
2020 } | 2020 } |
2021 | 2021 |
2022 void AXNodeObject::decrement() | 2022 void AXNodeObject::decrement() |
2023 { | 2023 { |
2024 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture); | 2024 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture); |
2025 alterSliderValue(false); | 2025 alterSliderValue(false); |
2026 } | 2026 } |
2027 | 2027 |
2028 void AXNodeObject::childrenChanged() | 2028 void AXNodeObject::childrenChanged() |
2029 { | 2029 { |
2030 // This method is meant as a quick way of marking a portion of the accessibi
lity tree dirty. | 2030 // This method is meant as a quick way of marking a portion of the accessibi
lity tree dirty. |
2031 if (!node() && !layoutObject()) | 2031 if (!getNode() && !getLayoutObject()) |
2032 return; | 2032 return; |
2033 | 2033 |
2034 // If this is not part of the accessibility tree because an ancestor | 2034 // If this is not part of the accessibility tree because an ancestor |
2035 // has only presentational children, invalidate this object's children but | 2035 // has only presentational children, invalidate this object's children but |
2036 // skip sending a notification and skip walking up the ancestors. | 2036 // skip sending a notification and skip walking up the ancestors. |
2037 if (ancestorForWhichThisIsAPresentationalChild()) { | 2037 if (ancestorForWhichThisIsAPresentationalChild()) { |
2038 setNeedsToUpdateChildren(); | 2038 setNeedsToUpdateChildren(); |
2039 return; | 2039 return; |
2040 } | 2040 } |
2041 | 2041 |
(...skipping 20 matching lines...) Expand all Loading... |
2062 } | 2062 } |
2063 } | 2063 } |
2064 | 2064 |
2065 void AXNodeObject::selectionChanged() | 2065 void AXNodeObject::selectionChanged() |
2066 { | 2066 { |
2067 // Post the selected text changed event on the first ancestor that's | 2067 // Post the selected text changed event on the first ancestor that's |
2068 // focused (to handle form controls, ARIA text boxes and contentEditable), | 2068 // focused (to handle form controls, ARIA text boxes and contentEditable), |
2069 // or the web area if the selection is just in the document somewhere. | 2069 // or the web area if the selection is just in the document somewhere. |
2070 if (isFocused() || isWebArea()) { | 2070 if (isFocused() || isWebArea()) { |
2071 axObjectCache().postNotification(this, AXObjectCacheImpl::AXSelectedText
Changed); | 2071 axObjectCache().postNotification(this, AXObjectCacheImpl::AXSelectedText
Changed); |
2072 if (document()) { | 2072 if (getDocument()) { |
2073 AXObject* documentObject = axObjectCache().getOrCreate(document()); | 2073 AXObject* documentObject = axObjectCache().getOrCreate(getDocument()
); |
2074 axObjectCache().postNotification(documentObject, AXObjectCacheImpl::
AXDocumentSelectionChanged); | 2074 axObjectCache().postNotification(documentObject, AXObjectCacheImpl::
AXDocumentSelectionChanged); |
2075 } | 2075 } |
2076 } else { | 2076 } else { |
2077 AXObject::selectionChanged(); // Calls selectionChanged on parent. | 2077 AXObject::selectionChanged(); // Calls selectionChanged on parent. |
2078 } | 2078 } |
2079 } | 2079 } |
2080 | 2080 |
2081 void AXNodeObject::textChanged() | 2081 void AXNodeObject::textChanged() |
2082 { | 2082 { |
2083 // If this element supports ARIA live regions, or is part of a region with a
n ARIA editable role, | 2083 // If this element supports ARIA live regions, or is part of a region with a
n ARIA editable role, |
2084 // then notify the AT of changes. | 2084 // then notify the AT of changes. |
2085 AXObjectCacheImpl& cache = axObjectCache(); | 2085 AXObjectCacheImpl& cache = axObjectCache(); |
2086 for (Node* parentNode = node(); parentNode; parentNode = parentNode->parentN
ode()) { | 2086 for (Node* parentNode = getNode(); parentNode; parentNode = parentNode->pare
ntNode()) { |
2087 AXObject* parent = cache.get(parentNode); | 2087 AXObject* parent = cache.get(parentNode); |
2088 if (!parent) | 2088 if (!parent) |
2089 continue; | 2089 continue; |
2090 | 2090 |
2091 if (parent->isLiveRegion()) | 2091 if (parent->isLiveRegion()) |
2092 cache.postNotification(parentNode, AXObjectCacheImpl::AXLiveRegionCh
anged); | 2092 cache.postNotification(parentNode, AXObjectCacheImpl::AXLiveRegionCh
anged); |
2093 | 2093 |
2094 // If this element is an ARIA text box or content editable, post a "valu
e changed" notification on it | 2094 // If this element is an ARIA text box or content editable, post a "valu
e changed" notification on it |
2095 // so that it behaves just like a native input element or textarea. | 2095 // so that it behaves just like a native input element or textarea. |
2096 if (parent->isNonNativeTextControl()) | 2096 if (parent->isNonNativeTextControl()) |
(...skipping 18 matching lines...) Expand all Loading... |
2115 | 2115 |
2116 Vector<String> idVector; | 2116 Vector<String> idVector; |
2117 tokenVectorFromAttribute(idVector, aria_ownsAttr); | 2117 tokenVectorFromAttribute(idVector, aria_ownsAttr); |
2118 | 2118 |
2119 axObjectCache().updateAriaOwns(this, idVector, ownedChildren); | 2119 axObjectCache().updateAriaOwns(this, idVector, ownedChildren); |
2120 } | 2120 } |
2121 | 2121 |
2122 // Based on http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-
name-and-description-calculation | 2122 // Based on http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-
name-and-description-calculation |
2123 String AXNodeObject::nativeTextAlternative(AXObjectSet& visited, AXNameFrom& nam
eFrom, AXRelatedObjectVector* relatedObjects, NameSources* nameSources, bool* fo
undTextAlternative) const | 2123 String AXNodeObject::nativeTextAlternative(AXObjectSet& visited, AXNameFrom& nam
eFrom, AXRelatedObjectVector* relatedObjects, NameSources* nameSources, bool* fo
undTextAlternative) const |
2124 { | 2124 { |
2125 if (!node()) | 2125 if (!getNode()) |
2126 return String(); | 2126 return String(); |
2127 | 2127 |
2128 // If nameSources is non-null, relatedObjects is used in filling it in, so i
t must be non-null as well. | 2128 // If nameSources is non-null, relatedObjects is used in filling it in, so i
t must be non-null as well. |
2129 if (nameSources) | 2129 if (nameSources) |
2130 ASSERT(relatedObjects); | 2130 ASSERT(relatedObjects); |
2131 | 2131 |
2132 String textAlternative; | 2132 String textAlternative; |
2133 AXRelatedObjectVector localRelatedObjects; | 2133 AXRelatedObjectVector localRelatedObjects; |
2134 | 2134 |
2135 const HTMLInputElement* inputElement = nullptr; | 2135 const HTMLInputElement* inputElement = nullptr; |
2136 if (isHTMLInputElement(node())) | 2136 if (isHTMLInputElement(getNode())) |
2137 inputElement = toHTMLInputElement(node()); | 2137 inputElement = toHTMLInputElement(getNode()); |
2138 | 2138 |
2139 // 5.1/5.5 Text inputs, Other labelable Elements | 2139 // 5.1/5.5 Text inputs, Other labelable Elements |
2140 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. | 2140 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. |
2141 HTMLElement* htmlElement = nullptr; | 2141 HTMLElement* htmlElement = nullptr; |
2142 if (node()->isHTMLElement()) | 2142 if (getNode()->isHTMLElement()) |
2143 htmlElement = toHTMLElement(node()); | 2143 htmlElement = toHTMLElement(getNode()); |
2144 if (htmlElement && htmlElement->isLabelable()) { | 2144 if (htmlElement && htmlElement->isLabelable()) { |
2145 // label | 2145 // label |
2146 nameFrom = AXNameFromRelatedElement; | 2146 nameFrom = AXNameFromRelatedElement; |
2147 if (nameSources) { | 2147 if (nameSources) { |
2148 nameSources->append(NameSource(*foundTextAlternative)); | 2148 nameSources->append(NameSource(*foundTextAlternative)); |
2149 nameSources->last().type = nameFrom; | 2149 nameSources->last().type = nameFrom; |
2150 nameSources->last().nativeSource = AXTextFromNativeHTMLLabel; | 2150 nameSources->last().nativeSource = AXTextFromNativeHTMLLabel; |
2151 } | 2151 } |
2152 HTMLLabelElement* label = labelForElement(htmlElement); | 2152 HTMLLabelElement* label = labelForElement(htmlElement); |
2153 if (label) { | 2153 if (label) { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2256 } | 2256 } |
2257 | 2257 |
2258 // 5.1 Text inputs - step 3 (placeholder attribute) | 2258 // 5.1 Text inputs - step 3 (placeholder attribute) |
2259 if (htmlElement && htmlElement->isTextFormControl()) { | 2259 if (htmlElement && htmlElement->isTextFormControl()) { |
2260 nameFrom = AXNameFromPlaceholder; | 2260 nameFrom = AXNameFromPlaceholder; |
2261 if (nameSources) { | 2261 if (nameSources) { |
2262 nameSources->append(NameSource(*foundTextAlternative, placeholderAtt
r)); | 2262 nameSources->append(NameSource(*foundTextAlternative, placeholderAtt
r)); |
2263 NameSource& source = nameSources->last(); | 2263 NameSource& source = nameSources->last(); |
2264 source.type = nameFrom; | 2264 source.type = nameFrom; |
2265 } | 2265 } |
2266 HTMLElement* element = toHTMLElement(node()); | 2266 HTMLElement* element = toHTMLElement(getNode()); |
2267 const AtomicString& placeholder = element->fastGetAttribute(placeholderA
ttr); | 2267 const AtomicString& placeholder = element->fastGetAttribute(placeholderA
ttr); |
2268 if (!placeholder.isEmpty()) { | 2268 if (!placeholder.isEmpty()) { |
2269 textAlternative = placeholder; | 2269 textAlternative = placeholder; |
2270 if (nameSources) { | 2270 if (nameSources) { |
2271 NameSource& source = nameSources->last(); | 2271 NameSource& source = nameSources->last(); |
2272 source.text = textAlternative; | 2272 source.text = textAlternative; |
2273 source.attributeValue = placeholder; | 2273 source.attributeValue = placeholder; |
2274 } else { | 2274 } else { |
2275 return textAlternative; | 2275 return textAlternative; |
2276 } | 2276 } |
2277 } | 2277 } |
2278 return textAlternative; | 2278 return textAlternative; |
2279 } | 2279 } |
2280 | 2280 |
2281 // 5.7 figure and figcaption Elements | 2281 // 5.7 figure and figcaption Elements |
2282 if (node()->hasTagName(figureTag)) { | 2282 if (getNode()->hasTagName(figureTag)) { |
2283 // figcaption | 2283 // figcaption |
2284 nameFrom = AXNameFromRelatedElement; | 2284 nameFrom = AXNameFromRelatedElement; |
2285 if (nameSources) { | 2285 if (nameSources) { |
2286 nameSources->append(NameSource(*foundTextAlternative)); | 2286 nameSources->append(NameSource(*foundTextAlternative)); |
2287 nameSources->last().type = nameFrom; | 2287 nameSources->last().type = nameFrom; |
2288 nameSources->last().nativeSource = AXTextFromNativeHTMLFigcaption; | 2288 nameSources->last().nativeSource = AXTextFromNativeHTMLFigcaption; |
2289 } | 2289 } |
2290 Element* figcaption = nullptr; | 2290 Element* figcaption = nullptr; |
2291 for (Element& element : ElementTraversal::descendantsOf(*(node()))) { | 2291 for (Element& element : ElementTraversal::descendantsOf(*(getNode()))) { |
2292 if (element.hasTagName(figcaptionTag)) { | 2292 if (element.hasTagName(figcaptionTag)) { |
2293 figcaption = &element; | 2293 figcaption = &element; |
2294 break; | 2294 break; |
2295 } | 2295 } |
2296 } | 2296 } |
2297 if (figcaption) { | 2297 if (figcaption) { |
2298 AXObject* figcaptionAXObject = axObjectCache().getOrCreate(figcaptio
n); | 2298 AXObject* figcaptionAXObject = axObjectCache().getOrCreate(figcaptio
n); |
2299 if (figcaptionAXObject) { | 2299 if (figcaptionAXObject) { |
2300 textAlternative = recursiveTextAlternative(*figcaptionAXObject,
false, visited); | 2300 textAlternative = recursiveTextAlternative(*figcaptionAXObject,
false, visited); |
2301 | 2301 |
(...skipping 10 matching lines...) Expand all Loading... |
2312 *foundTextAlternative = true; | 2312 *foundTextAlternative = true; |
2313 } else { | 2313 } else { |
2314 return textAlternative; | 2314 return textAlternative; |
2315 } | 2315 } |
2316 } | 2316 } |
2317 } | 2317 } |
2318 return textAlternative; | 2318 return textAlternative; |
2319 } | 2319 } |
2320 | 2320 |
2321 // 5.8 img or area Element | 2321 // 5.8 img or area Element |
2322 if (isHTMLImageElement(node()) || isHTMLAreaElement(node()) || (layoutObject
() && layoutObject()->isSVGImage())) { | 2322 if (isHTMLImageElement(getNode()) || isHTMLAreaElement(getNode()) || (getLay
outObject() && getLayoutObject()->isSVGImage())) { |
2323 // alt | 2323 // alt |
2324 nameFrom = AXNameFromAttribute; | 2324 nameFrom = AXNameFromAttribute; |
2325 if (nameSources) { | 2325 if (nameSources) { |
2326 nameSources->append(NameSource(*foundTextAlternative, altAttr)); | 2326 nameSources->append(NameSource(*foundTextAlternative, altAttr)); |
2327 nameSources->last().type = nameFrom; | 2327 nameSources->last().type = nameFrom; |
2328 } | 2328 } |
2329 const AtomicString& alt = getAttribute(altAttr); | 2329 const AtomicString& alt = getAttribute(altAttr); |
2330 if (!alt.isNull()) { | 2330 if (!alt.isNull()) { |
2331 textAlternative = alt; | 2331 textAlternative = alt; |
2332 if (nameSources) { | 2332 if (nameSources) { |
2333 NameSource& source = nameSources->last(); | 2333 NameSource& source = nameSources->last(); |
2334 source.attributeValue = alt; | 2334 source.attributeValue = alt; |
2335 source.text = textAlternative; | 2335 source.text = textAlternative; |
2336 *foundTextAlternative = true; | 2336 *foundTextAlternative = true; |
2337 } else { | 2337 } else { |
2338 return textAlternative; | 2338 return textAlternative; |
2339 } | 2339 } |
2340 } | 2340 } |
2341 return textAlternative; | 2341 return textAlternative; |
2342 } | 2342 } |
2343 | 2343 |
2344 // 5.9 table Element | 2344 // 5.9 table Element |
2345 if (isHTMLTableElement(node())) { | 2345 if (isHTMLTableElement(getNode())) { |
2346 HTMLTableElement* tableElement = toHTMLTableElement(node()); | 2346 HTMLTableElement* tableElement = toHTMLTableElement(getNode()); |
2347 | 2347 |
2348 // caption | 2348 // caption |
2349 nameFrom = AXNameFromCaption; | 2349 nameFrom = AXNameFromCaption; |
2350 if (nameSources) { | 2350 if (nameSources) { |
2351 nameSources->append(NameSource(*foundTextAlternative)); | 2351 nameSources->append(NameSource(*foundTextAlternative)); |
2352 nameSources->last().type = nameFrom; | 2352 nameSources->last().type = nameFrom; |
2353 nameSources->last().nativeSource = AXTextFromNativeHTMLTableCaption; | 2353 nameSources->last().nativeSource = AXTextFromNativeHTMLTableCaption; |
2354 } | 2354 } |
2355 HTMLTableCaptionElement* caption = tableElement->caption(); | 2355 HTMLTableCaptionElement* caption = tableElement->caption(); |
2356 if (caption) { | 2356 if (caption) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2390 *foundTextAlternative = true; | 2390 *foundTextAlternative = true; |
2391 } else { | 2391 } else { |
2392 return textAlternative; | 2392 return textAlternative; |
2393 } | 2393 } |
2394 } | 2394 } |
2395 | 2395 |
2396 return textAlternative; | 2396 return textAlternative; |
2397 } | 2397 } |
2398 | 2398 |
2399 // Per SVG AAM 1.0's modifications to 2D of this algorithm. | 2399 // Per SVG AAM 1.0's modifications to 2D of this algorithm. |
2400 if (node()->isSVGElement()) { | 2400 if (getNode()->isSVGElement()) { |
2401 nameFrom = AXNameFromRelatedElement; | 2401 nameFrom = AXNameFromRelatedElement; |
2402 if (nameSources) { | 2402 if (nameSources) { |
2403 nameSources->append(NameSource(*foundTextAlternative)); | 2403 nameSources->append(NameSource(*foundTextAlternative)); |
2404 nameSources->last().type = nameFrom; | 2404 nameSources->last().type = nameFrom; |
2405 nameSources->last().nativeSource = AXTextFromNativeHTMLTitleElement; | 2405 nameSources->last().nativeSource = AXTextFromNativeHTMLTitleElement; |
2406 } | 2406 } |
2407 ASSERT(node()->isContainerNode()); | 2407 ASSERT(getNode()->isContainerNode()); |
2408 Element* title = ElementTraversal::firstChild( | 2408 Element* title = ElementTraversal::firstChild( |
2409 toContainerNode(*(node())), | 2409 toContainerNode(*(getNode())), |
2410 HasTagName(SVGNames::titleTag)); | 2410 HasTagName(SVGNames::titleTag)); |
2411 | 2411 |
2412 if (title) { | 2412 if (title) { |
2413 AXObject* titleAXObject = axObjectCache().getOrCreate(title); | 2413 AXObject* titleAXObject = axObjectCache().getOrCreate(title); |
2414 if (titleAXObject && !visited.contains(titleAXObject)) { | 2414 if (titleAXObject && !visited.contains(titleAXObject)) { |
2415 textAlternative = recursiveTextAlternative(*titleAXObject, false
, visited); | 2415 textAlternative = recursiveTextAlternative(*titleAXObject, false
, visited); |
2416 if (relatedObjects) { | 2416 if (relatedObjects) { |
2417 localRelatedObjects.append(new NameSourceRelatedObject( | 2417 localRelatedObjects.append(new NameSourceRelatedObject( |
2418 titleAXObject, textAlternative)); | 2418 titleAXObject, textAlternative)); |
2419 *relatedObjects = localRelatedObjects; | 2419 *relatedObjects = localRelatedObjects; |
2420 localRelatedObjects.clear(); | 2420 localRelatedObjects.clear(); |
2421 } | 2421 } |
2422 } | 2422 } |
2423 if (nameSources) { | 2423 if (nameSources) { |
2424 NameSource& source = nameSources->last(); | 2424 NameSource& source = nameSources->last(); |
2425 source.text = textAlternative; | 2425 source.text = textAlternative; |
2426 source.relatedObjects = *relatedObjects; | 2426 source.relatedObjects = *relatedObjects; |
2427 *foundTextAlternative = true; | 2427 *foundTextAlternative = true; |
2428 } else { | 2428 } else { |
2429 return textAlternative; | 2429 return textAlternative; |
2430 } | 2430 } |
2431 } | 2431 } |
2432 } | 2432 } |
2433 | 2433 |
2434 // Fieldset / legend. | 2434 // Fieldset / legend. |
2435 if (isHTMLFieldSetElement(node())) { | 2435 if (isHTMLFieldSetElement(getNode())) { |
2436 nameFrom = AXNameFromRelatedElement; | 2436 nameFrom = AXNameFromRelatedElement; |
2437 if (nameSources) { | 2437 if (nameSources) { |
2438 nameSources->append(NameSource(*foundTextAlternative)); | 2438 nameSources->append(NameSource(*foundTextAlternative)); |
2439 nameSources->last().type = nameFrom; | 2439 nameSources->last().type = nameFrom; |
2440 nameSources->last().nativeSource = AXTextFromNativeHTMLLegend; | 2440 nameSources->last().nativeSource = AXTextFromNativeHTMLLegend; |
2441 } | 2441 } |
2442 HTMLElement* legend = toHTMLFieldSetElement(node())->legend(); | 2442 HTMLElement* legend = toHTMLFieldSetElement(getNode())->legend(); |
2443 if (legend) { | 2443 if (legend) { |
2444 AXObject* legendAXObject = axObjectCache().getOrCreate(legend); | 2444 AXObject* legendAXObject = axObjectCache().getOrCreate(legend); |
2445 // Avoid an infinite loop | 2445 // Avoid an infinite loop |
2446 if (legendAXObject && !visited.contains(legendAXObject)) { | 2446 if (legendAXObject && !visited.contains(legendAXObject)) { |
2447 textAlternative = recursiveTextAlternative(*legendAXObject, fals
e, visited); | 2447 textAlternative = recursiveTextAlternative(*legendAXObject, fals
e, visited); |
2448 | 2448 |
2449 if (relatedObjects) { | 2449 if (relatedObjects) { |
2450 localRelatedObjects.append(new NameSourceRelatedObject(legen
dAXObject, textAlternative)); | 2450 localRelatedObjects.append(new NameSourceRelatedObject(legen
dAXObject, textAlternative)); |
2451 *relatedObjects = localRelatedObjects; | 2451 *relatedObjects = localRelatedObjects; |
2452 localRelatedObjects.clear(); | 2452 localRelatedObjects.clear(); |
2453 } | 2453 } |
2454 | 2454 |
2455 if (nameSources) { | 2455 if (nameSources) { |
2456 NameSource& source = nameSources->last(); | 2456 NameSource& source = nameSources->last(); |
2457 source.relatedObjects = *relatedObjects; | 2457 source.relatedObjects = *relatedObjects; |
2458 source.text = textAlternative; | 2458 source.text = textAlternative; |
2459 *foundTextAlternative = true; | 2459 *foundTextAlternative = true; |
2460 } else { | 2460 } else { |
2461 return textAlternative; | 2461 return textAlternative; |
2462 } | 2462 } |
2463 } | 2463 } |
2464 } | 2464 } |
2465 } | 2465 } |
2466 | 2466 |
2467 // Document. | 2467 // Document. |
2468 if (isWebArea()) { | 2468 if (isWebArea()) { |
2469 Document* document = this->document(); | 2469 Document* document = this->getDocument(); |
2470 if (document) { | 2470 if (document) { |
2471 nameFrom = AXNameFromAttribute; | 2471 nameFrom = AXNameFromAttribute; |
2472 if (nameSources) { | 2472 if (nameSources) { |
2473 nameSources->append(NameSource(foundTextAlternative, aria_labelA
ttr)); | 2473 nameSources->append(NameSource(foundTextAlternative, aria_labelA
ttr)); |
2474 nameSources->last().type = nameFrom; | 2474 nameSources->last().type = nameFrom; |
2475 } | 2475 } |
2476 if (Element* documentElement = document->documentElement()) { | 2476 if (Element* documentElement = document->documentElement()) { |
2477 const AtomicString& ariaLabel = documentElement->getAttribute(ar
ia_labelAttr); | 2477 const AtomicString& ariaLabel = documentElement->getAttribute(ar
ia_labelAttr); |
2478 if (!ariaLabel.isEmpty()) { | 2478 if (!ariaLabel.isEmpty()) { |
2479 textAlternative = ariaLabel; | 2479 textAlternative = ariaLabel; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2535 return collapseWhitespace(result); | 2535 return collapseWhitespace(result); |
2536 } | 2536 } |
2537 | 2537 |
2538 // Based on http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-
name-and-description-calculation | 2538 // Based on http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-
name-and-description-calculation |
2539 String AXNodeObject::description(AXNameFrom nameFrom, AXDescriptionFrom& descrip
tionFrom, DescriptionSources* descriptionSources, AXRelatedObjectVector* related
Objects) const | 2539 String AXNodeObject::description(AXNameFrom nameFrom, AXDescriptionFrom& descrip
tionFrom, DescriptionSources* descriptionSources, AXRelatedObjectVector* related
Objects) const |
2540 { | 2540 { |
2541 // If descriptionSources is non-null, relatedObjects is used in filling it i
n, so it must be non-null as well. | 2541 // If descriptionSources is non-null, relatedObjects is used in filling it i
n, so it must be non-null as well. |
2542 if (descriptionSources) | 2542 if (descriptionSources) |
2543 ASSERT(relatedObjects); | 2543 ASSERT(relatedObjects); |
2544 | 2544 |
2545 if (!node()) | 2545 if (!getNode()) |
2546 return String(); | 2546 return String(); |
2547 | 2547 |
2548 String description; | 2548 String description; |
2549 bool foundDescription = false; | 2549 bool foundDescription = false; |
2550 | 2550 |
2551 descriptionFrom = AXDescriptionFromRelatedElement; | 2551 descriptionFrom = AXDescriptionFromRelatedElement; |
2552 if (descriptionSources) { | 2552 if (descriptionSources) { |
2553 descriptionSources->append(DescriptionSource(foundDescription, aria_desc
ribedbyAttr)); | 2553 descriptionSources->append(DescriptionSource(foundDescription, aria_desc
ribedbyAttr)); |
2554 descriptionSources->last().type = descriptionFrom; | 2554 descriptionSources->last().type = descriptionFrom; |
2555 } | 2555 } |
(...skipping 15 matching lines...) Expand all Loading... |
2571 foundDescription = true; | 2571 foundDescription = true; |
2572 } else { | 2572 } else { |
2573 return description; | 2573 return description; |
2574 } | 2574 } |
2575 } else if (descriptionSources) { | 2575 } else if (descriptionSources) { |
2576 descriptionSources->last().invalid = true; | 2576 descriptionSources->last().invalid = true; |
2577 } | 2577 } |
2578 } | 2578 } |
2579 | 2579 |
2580 HTMLElement* htmlElement = nullptr; | 2580 HTMLElement* htmlElement = nullptr; |
2581 if (node()->isHTMLElement()) | 2581 if (getNode()->isHTMLElement()) |
2582 htmlElement = toHTMLElement(node()); | 2582 htmlElement = toHTMLElement(getNode()); |
2583 | 2583 |
2584 // placeholder, 5.1.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-
aam.html | 2584 // placeholder, 5.1.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-
aam.html |
2585 if (nameFrom != AXNameFromPlaceholder && htmlElement && htmlElement->isTextF
ormControl()) { | 2585 if (nameFrom != AXNameFromPlaceholder && htmlElement && htmlElement->isTextF
ormControl()) { |
2586 descriptionFrom = AXDescriptionFromPlaceholder; | 2586 descriptionFrom = AXDescriptionFromPlaceholder; |
2587 if (descriptionSources) { | 2587 if (descriptionSources) { |
2588 descriptionSources->append(DescriptionSource(foundDescription, place
holderAttr)); | 2588 descriptionSources->append(DescriptionSource(foundDescription, place
holderAttr)); |
2589 DescriptionSource& source = descriptionSources->last(); | 2589 DescriptionSource& source = descriptionSources->last(); |
2590 source.type = descriptionFrom; | 2590 source.type = descriptionFrom; |
2591 } | 2591 } |
2592 HTMLElement* element = toHTMLElement(node()); | 2592 HTMLElement* element = toHTMLElement(getNode()); |
2593 const AtomicString& placeholder = element->fastGetAttribute(placeholderA
ttr); | 2593 const AtomicString& placeholder = element->fastGetAttribute(placeholderA
ttr); |
2594 if (!placeholder.isEmpty()) { | 2594 if (!placeholder.isEmpty()) { |
2595 description = placeholder; | 2595 description = placeholder; |
2596 if (descriptionSources) { | 2596 if (descriptionSources) { |
2597 DescriptionSource& source = descriptionSources->last(); | 2597 DescriptionSource& source = descriptionSources->last(); |
2598 source.text = description; | 2598 source.text = description; |
2599 source.attributeValue = placeholder; | 2599 source.attributeValue = placeholder; |
2600 foundDescription = true; | 2600 foundDescription = true; |
2601 } else { | 2601 } else { |
2602 return description; | 2602 return description; |
2603 } | 2603 } |
2604 } | 2604 } |
2605 } | 2605 } |
2606 | 2606 |
2607 const HTMLInputElement* inputElement = nullptr; | 2607 const HTMLInputElement* inputElement = nullptr; |
2608 if (isHTMLInputElement(node())) | 2608 if (isHTMLInputElement(getNode())) |
2609 inputElement = toHTMLInputElement(node()); | 2609 inputElement = toHTMLInputElement(getNode()); |
2610 | 2610 |
2611 // value, 5.2.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam.ht
ml | 2611 // value, 5.2.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam.ht
ml |
2612 if (nameFrom != AXNameFromValue && inputElement && inputElement->isTextButto
n()) { | 2612 if (nameFrom != AXNameFromValue && inputElement && inputElement->isTextButto
n()) { |
2613 descriptionFrom = AXDescriptionFromAttribute; | 2613 descriptionFrom = AXDescriptionFromAttribute; |
2614 if (descriptionSources) { | 2614 if (descriptionSources) { |
2615 descriptionSources->append(DescriptionSource(foundDescription, value
Attr)); | 2615 descriptionSources->append(DescriptionSource(foundDescription, value
Attr)); |
2616 descriptionSources->last().type = descriptionFrom; | 2616 descriptionSources->last().type = descriptionFrom; |
2617 } | 2617 } |
2618 String value = inputElement->value(); | 2618 String value = inputElement->value(); |
2619 if (!value.isNull()) { | 2619 if (!value.isNull()) { |
2620 description = value; | 2620 description = value; |
2621 if (descriptionSources) { | 2621 if (descriptionSources) { |
2622 DescriptionSource& source = descriptionSources->last(); | 2622 DescriptionSource& source = descriptionSources->last(); |
2623 source.text = description; | 2623 source.text = description; |
2624 foundDescription = true; | 2624 foundDescription = true; |
2625 } else { | 2625 } else { |
2626 return description; | 2626 return description; |
2627 } | 2627 } |
2628 } | 2628 } |
2629 } | 2629 } |
2630 | 2630 |
2631 // table caption, 5.9.2 from: http://rawgit.com/w3c/aria/master/html-aam/htm
l-aam.html | 2631 // table caption, 5.9.2 from: http://rawgit.com/w3c/aria/master/html-aam/htm
l-aam.html |
2632 if (nameFrom != AXNameFromCaption && isHTMLTableElement(node())) { | 2632 if (nameFrom != AXNameFromCaption && isHTMLTableElement(getNode())) { |
2633 HTMLTableElement* tableElement = toHTMLTableElement(node()); | 2633 HTMLTableElement* tableElement = toHTMLTableElement(getNode()); |
2634 | 2634 |
2635 descriptionFrom = AXDescriptionFromRelatedElement; | 2635 descriptionFrom = AXDescriptionFromRelatedElement; |
2636 if (descriptionSources) { | 2636 if (descriptionSources) { |
2637 descriptionSources->append(DescriptionSource(foundDescription)); | 2637 descriptionSources->append(DescriptionSource(foundDescription)); |
2638 descriptionSources->last().type = descriptionFrom; | 2638 descriptionSources->last().type = descriptionFrom; |
2639 descriptionSources->last().nativeSource = AXTextFromNativeHTMLTableC
aption; | 2639 descriptionSources->last().nativeSource = AXTextFromNativeHTMLTableC
aption; |
2640 } | 2640 } |
2641 HTMLTableCaptionElement* caption = tableElement->caption(); | 2641 HTMLTableCaptionElement* caption = tableElement->caption(); |
2642 if (caption) { | 2642 if (caption) { |
2643 AXObject* captionAXObject = axObjectCache().getOrCreate(caption); | 2643 AXObject* captionAXObject = axObjectCache().getOrCreate(caption); |
2644 if (captionAXObject) { | 2644 if (captionAXObject) { |
2645 AXObjectSet visited; | 2645 AXObjectSet visited; |
2646 description = recursiveTextAlternative(*captionAXObject, false,
visited); | 2646 description = recursiveTextAlternative(*captionAXObject, false,
visited); |
2647 if (relatedObjects) | 2647 if (relatedObjects) |
2648 relatedObjects->append(new NameSourceRelatedObject(captionAX
Object, description)); | 2648 relatedObjects->append(new NameSourceRelatedObject(captionAX
Object, description)); |
2649 | 2649 |
2650 if (descriptionSources) { | 2650 if (descriptionSources) { |
2651 DescriptionSource& source = descriptionSources->last(); | 2651 DescriptionSource& source = descriptionSources->last(); |
2652 source.relatedObjects = *relatedObjects; | 2652 source.relatedObjects = *relatedObjects; |
2653 source.text = description; | 2653 source.text = description; |
2654 foundDescription = true; | 2654 foundDescription = true; |
2655 } else { | 2655 } else { |
2656 return description; | 2656 return description; |
2657 } | 2657 } |
2658 } | 2658 } |
2659 } | 2659 } |
2660 } | 2660 } |
2661 | 2661 |
2662 // summary, 5.6.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam.
html | 2662 // summary, 5.6.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam.
html |
2663 if (nameFrom != AXNameFromContents && isHTMLSummaryElement(node())) { | 2663 if (nameFrom != AXNameFromContents && isHTMLSummaryElement(getNode())) { |
2664 descriptionFrom = AXDescriptionFromContents; | 2664 descriptionFrom = AXDescriptionFromContents; |
2665 if (descriptionSources) { | 2665 if (descriptionSources) { |
2666 descriptionSources->append(DescriptionSource(foundDescription)); | 2666 descriptionSources->append(DescriptionSource(foundDescription)); |
2667 descriptionSources->last().type = descriptionFrom; | 2667 descriptionSources->last().type = descriptionFrom; |
2668 } | 2668 } |
2669 | 2669 |
2670 AXObjectSet visited; | 2670 AXObjectSet visited; |
2671 description = textFromDescendants(visited, false); | 2671 description = textFromDescendants(visited, false); |
2672 | 2672 |
2673 if (!description.isEmpty()) { | 2673 if (!description.isEmpty()) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2735 } | 2735 } |
2736 | 2736 |
2737 String AXNodeObject::placeholder(AXNameFrom nameFrom, AXDescriptionFrom descript
ionFrom) const | 2737 String AXNodeObject::placeholder(AXNameFrom nameFrom, AXDescriptionFrom descript
ionFrom) const |
2738 { | 2738 { |
2739 if (nameFrom == AXNameFromPlaceholder) | 2739 if (nameFrom == AXNameFromPlaceholder) |
2740 return String(); | 2740 return String(); |
2741 | 2741 |
2742 if (descriptionFrom == AXDescriptionFromPlaceholder) | 2742 if (descriptionFrom == AXDescriptionFromPlaceholder) |
2743 return String(); | 2743 return String(); |
2744 | 2744 |
2745 if (!node()) | 2745 if (!getNode()) |
2746 return String(); | 2746 return String(); |
2747 | 2747 |
2748 String placeholder; | 2748 String placeholder; |
2749 if (isHTMLInputElement(*node())) { | 2749 if (isHTMLInputElement(*getNode())) { |
2750 HTMLInputElement* inputElement = toHTMLInputElement(node()); | 2750 HTMLInputElement* inputElement = toHTMLInputElement(getNode()); |
2751 placeholder = inputElement->strippedPlaceholder(); | 2751 placeholder = inputElement->strippedPlaceholder(); |
2752 } else if (isHTMLTextAreaElement(*node())) { | 2752 } else if (isHTMLTextAreaElement(*getNode())) { |
2753 HTMLTextAreaElement* textAreaElement = toHTMLTextAreaElement(node()); | 2753 HTMLTextAreaElement* textAreaElement = toHTMLTextAreaElement(getNode()); |
2754 placeholder = textAreaElement->strippedPlaceholder(); | 2754 placeholder = textAreaElement->strippedPlaceholder(); |
2755 } | 2755 } |
2756 return placeholder; | 2756 return placeholder; |
2757 } | 2757 } |
2758 | 2758 |
2759 DEFINE_TRACE(AXNodeObject) | 2759 DEFINE_TRACE(AXNodeObject) |
2760 { | 2760 { |
2761 visitor->trace(m_node); | 2761 visitor->trace(m_node); |
2762 AXObject::trace(visitor); | 2762 AXObject::trace(visitor); |
2763 } | 2763 } |
2764 | 2764 |
2765 } // namespace blink | 2765 } // namespace blink |
OLD | NEW |