| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008, 2009, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008, 2009, 2011 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 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 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 return false; | 634 return false; |
| 635 | 635 |
| 636 if (parent->supportsActiveDescendant() && | 636 if (parent->supportsActiveDescendant() && |
| 637 !parent->getAttribute(aria_activedescendantAttr).isEmpty()) { | 637 !parent->getAttribute(aria_activedescendantAttr).isEmpty()) { |
| 638 return true; | 638 return true; |
| 639 } | 639 } |
| 640 | 640 |
| 641 return parent->ancestorExposesActiveDescendant(); | 641 return parent->ancestorExposesActiveDescendant(); |
| 642 } | 642 } |
| 643 | 643 |
| 644 // Simplify whitespace, but preserve a single leading and trailing whitespace ch
aracter if it's present. | 644 // Simplify whitespace, but preserve a single leading and trailing whitespace |
| 645 // character if it's present. |
| 645 // static | 646 // static |
| 646 String AXObject::collapseWhitespace(const String& str) { | 647 String AXObject::collapseWhitespace(const String& str) { |
| 647 StringBuilder result; | 648 StringBuilder result; |
| 648 if (!str.isEmpty() && isHTMLSpace<UChar>(str[0])) | 649 if (!str.isEmpty() && isHTMLSpace<UChar>(str[0])) |
| 649 result.append(' '); | 650 result.append(' '); |
| 650 result.append(str.simplifyWhiteSpace(isHTMLSpace<UChar>)); | 651 result.append(str.simplifyWhiteSpace(isHTMLSpace<UChar>)); |
| 651 if (!str.isEmpty() && isHTMLSpace<UChar>(str[str.length() - 1])) | 652 if (!str.isEmpty() && isHTMLSpace<UChar>(str[str.length() - 1])) |
| 652 result.append(' '); | 653 result.append(' '); |
| 653 return result.toString(); | 654 return result.toString(); |
| 654 } | 655 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 tmpNameFrom, nullptr, nullptr); | 702 tmpNameFrom, nullptr, nullptr); |
| 702 } | 703 } |
| 703 | 704 |
| 704 bool AXObject::isHiddenForTextAlternativeCalculation() const { | 705 bool AXObject::isHiddenForTextAlternativeCalculation() const { |
| 705 if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) | 706 if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) |
| 706 return false; | 707 return false; |
| 707 | 708 |
| 708 if (getLayoutObject()) | 709 if (getLayoutObject()) |
| 709 return getLayoutObject()->style()->visibility() != EVisibility::Visible; | 710 return getLayoutObject()->style()->visibility() != EVisibility::Visible; |
| 710 | 711 |
| 711 // This is an obscure corner case: if a node has no LayoutObject, that means i
t's not rendered, | 712 // This is an obscure corner case: if a node has no LayoutObject, that means |
| 712 // but we still may be exploring it as part of a text alternative calculation,
for example if it | 713 // it's not rendered, but we still may be exploring it as part of a text |
| 713 // was explicitly referenced by aria-labelledby. So we need to explicitly call
the style resolver | 714 // alternative calculation, for example if it was explicitly referenced by |
| 714 // to check whether it's invisible or display:none, rather than relying on the
style cached in the | 715 // aria-labelledby. So we need to explicitly call the style resolver to check |
| 715 // LayoutObject. | 716 // whether it's invisible or display:none, rather than relying on the style |
| 717 // cached in the LayoutObject. |
| 716 Document* doc = getDocument(); | 718 Document* doc = getDocument(); |
| 717 if (doc && doc->frame() && getNode() && getNode()->isElementNode()) { | 719 if (doc && doc->frame() && getNode() && getNode()->isElementNode()) { |
| 718 RefPtr<ComputedStyle> style = | 720 RefPtr<ComputedStyle> style = |
| 719 doc->ensureStyleResolver().styleForElement(toElement(getNode())); | 721 doc->ensureStyleResolver().styleForElement(toElement(getNode())); |
| 720 return style->display() == EDisplay::None || | 722 return style->display() == EDisplay::None || |
| 721 style->visibility() != EVisibility::Visible; | 723 style->visibility() != EVisibility::Visible; |
| 722 } | 724 } |
| 723 | 725 |
| 724 return false; | 726 return false; |
| 725 } | 727 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 754 nameSources->append(NameSource(*foundTextAlternative, attr)); | 756 nameSources->append(NameSource(*foundTextAlternative, attr)); |
| 755 nameSources->last().type = nameFrom; | 757 nameSources->last().type = nameFrom; |
| 756 } | 758 } |
| 757 | 759 |
| 758 const AtomicString& ariaLabelledby = getAttribute(attr); | 760 const AtomicString& ariaLabelledby = getAttribute(attr); |
| 759 if (!ariaLabelledby.isNull()) { | 761 if (!ariaLabelledby.isNull()) { |
| 760 if (nameSources) | 762 if (nameSources) |
| 761 nameSources->last().attributeValue = ariaLabelledby; | 763 nameSources->last().attributeValue = ariaLabelledby; |
| 762 | 764 |
| 763 // Operate on a copy of |visited| so that if |nameSources| is not null, | 765 // Operate on a copy of |visited| so that if |nameSources| is not null, |
| 764 // the set of visited objects is preserved unmodified for future calculati
ons. | 766 // the set of visited objects is preserved unmodified for future |
| 767 // calculations. |
| 765 AXObjectSet visitedCopy = visited; | 768 AXObjectSet visitedCopy = visited; |
| 766 textAlternative = textFromAriaLabelledby(visitedCopy, relatedObjects); | 769 textAlternative = textFromAriaLabelledby(visitedCopy, relatedObjects); |
| 767 if (!textAlternative.isNull()) { | 770 if (!textAlternative.isNull()) { |
| 768 if (nameSources) { | 771 if (nameSources) { |
| 769 NameSource& source = nameSources->last(); | 772 NameSource& source = nameSources->last(); |
| 770 source.type = nameFrom; | 773 source.type = nameFrom; |
| 771 source.relatedObjects = *relatedObjects; | 774 source.relatedObjects = *relatedObjects; |
| 772 source.text = textAlternative; | 775 source.text = textAlternative; |
| 773 *foundTextAlternative = true; | 776 *foundTextAlternative = true; |
| 774 } else { | 777 } else { |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1153 return object->documentFrameView(); | 1156 return object->documentFrameView(); |
| 1154 } | 1157 } |
| 1155 | 1158 |
| 1156 String AXObject::language() const { | 1159 String AXObject::language() const { |
| 1157 const AtomicString& lang = getAttribute(langAttr); | 1160 const AtomicString& lang = getAttribute(langAttr); |
| 1158 if (!lang.isEmpty()) | 1161 if (!lang.isEmpty()) |
| 1159 return lang; | 1162 return lang; |
| 1160 | 1163 |
| 1161 AXObject* parent = parentObject(); | 1164 AXObject* parent = parentObject(); |
| 1162 | 1165 |
| 1163 // as a last resort, fall back to the content language specified in the meta t
ag | 1166 // As a last resort, fall back to the content language specified in the meta |
| 1167 // tag. |
| 1164 if (!parent) { | 1168 if (!parent) { |
| 1165 Document* doc = getDocument(); | 1169 Document* doc = getDocument(); |
| 1166 if (doc) | 1170 if (doc) |
| 1167 return doc->contentLanguage(); | 1171 return doc->contentLanguage(); |
| 1168 return nullAtom; | 1172 return nullAtom; |
| 1169 } | 1173 } |
| 1170 | 1174 |
| 1171 return parent->language(); | 1175 return parent->language(); |
| 1172 } | 1176 } |
| 1173 | 1177 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1240 ProgrammaticScroll); | 1244 ProgrammaticScroll); |
| 1241 } | 1245 } |
| 1242 | 1246 |
| 1243 void AXObject::getRelativeBounds(AXObject** outContainer, | 1247 void AXObject::getRelativeBounds(AXObject** outContainer, |
| 1244 FloatRect& outBoundsInContainer, | 1248 FloatRect& outBoundsInContainer, |
| 1245 SkMatrix44& outContainerTransform) const { | 1249 SkMatrix44& outContainerTransform) const { |
| 1246 *outContainer = nullptr; | 1250 *outContainer = nullptr; |
| 1247 outBoundsInContainer = FloatRect(); | 1251 outBoundsInContainer = FloatRect(); |
| 1248 outContainerTransform.setIdentity(); | 1252 outContainerTransform.setIdentity(); |
| 1249 | 1253 |
| 1250 // First check if it has explicit bounds, for example if this element is tied
to a | 1254 // First check if it has explicit bounds, for example if this element is tied |
| 1251 // canvas path. When explicit coordinates are provided, the ID of the explicit
container | 1255 // to a canvas path. When explicit coordinates are provided, the ID of the |
| 1252 // element that the coordinates are relative to must be provided too. | 1256 // explicit container element that the coordinates are relative to must be |
| 1257 // provided too. |
| 1253 if (!m_explicitElementRect.isEmpty()) { | 1258 if (!m_explicitElementRect.isEmpty()) { |
| 1254 *outContainer = axObjectCache().objectFromAXID(m_explicitContainerID); | 1259 *outContainer = axObjectCache().objectFromAXID(m_explicitContainerID); |
| 1255 if (*outContainer) { | 1260 if (*outContainer) { |
| 1256 outBoundsInContainer = FloatRect(m_explicitElementRect); | 1261 outBoundsInContainer = FloatRect(m_explicitElementRect); |
| 1257 return; | 1262 return; |
| 1258 } | 1263 } |
| 1259 } | 1264 } |
| 1260 | 1265 |
| 1261 LayoutObject* layoutObject = layoutObjectForRelativeBounds(); | 1266 LayoutObject* layoutObject = layoutObjectForRelativeBounds(); |
| 1262 if (!layoutObject) | 1267 if (!layoutObject) |
| 1263 return; | 1268 return; |
| 1264 | 1269 |
| 1265 if (isWebArea()) { | 1270 if (isWebArea()) { |
| 1266 if (layoutObject->frame()->view()) | 1271 if (layoutObject->frame()->view()) |
| 1267 outBoundsInContainer.setSize( | 1272 outBoundsInContainer.setSize( |
| 1268 FloatSize(layoutObject->frame()->view()->contentsSize())); | 1273 FloatSize(layoutObject->frame()->view()->contentsSize())); |
| 1269 return; | 1274 return; |
| 1270 } | 1275 } |
| 1271 | 1276 |
| 1272 // First compute the container. The container must be an ancestor in the acces
sibility tree, and | 1277 // First compute the container. The container must be an ancestor in the |
| 1273 // its LayoutObject must be an ancestor in the layout tree. Get the first such
ancestor that's | 1278 // accessibility tree, and its LayoutObject must be an ancestor in the layout |
| 1274 // either scrollable or has a paint layer. | 1279 // tree. Get the first such ancestor that's either scrollable or has a paint |
| 1280 // layer. |
| 1275 AXObject* container = parentObjectUnignored(); | 1281 AXObject* container = parentObjectUnignored(); |
| 1276 LayoutObject* containerLayoutObject = nullptr; | 1282 LayoutObject* containerLayoutObject = nullptr; |
| 1277 while (container) { | 1283 while (container) { |
| 1278 containerLayoutObject = container->getLayoutObject(); | 1284 containerLayoutObject = container->getLayoutObject(); |
| 1279 if (containerLayoutObject && containerLayoutObject->isBoxModelObject() && | 1285 if (containerLayoutObject && containerLayoutObject->isBoxModelObject() && |
| 1280 layoutObject->isDescendantOf(containerLayoutObject)) { | 1286 layoutObject->isDescendantOf(containerLayoutObject)) { |
| 1281 if (container->isScrollableContainer() || | 1287 if (container->isScrollableContainer() || |
| 1282 containerLayoutObject->hasLayer()) | 1288 containerLayoutObject->hasLayer()) |
| 1283 break; | 1289 break; |
| 1284 } | 1290 } |
| 1285 | 1291 |
| 1286 container = container->parentObjectUnignored(); | 1292 container = container->parentObjectUnignored(); |
| 1287 } | 1293 } |
| 1288 | 1294 |
| 1289 if (!container) | 1295 if (!container) |
| 1290 return; | 1296 return; |
| 1291 *outContainer = container; | 1297 *outContainer = container; |
| 1292 outBoundsInContainer = layoutObject->localBoundingBoxRectForAccessibility(); | 1298 outBoundsInContainer = layoutObject->localBoundingBoxRectForAccessibility(); |
| 1293 | 1299 |
| 1294 // If the container has a scroll offset, subtract that out because we want our | 1300 // If the container has a scroll offset, subtract that out because we want our |
| 1295 // bounds to be relative to the *unscrolled* position of the container object. | 1301 // bounds to be relative to the *unscrolled* position of the container object. |
| 1296 ScrollableArea* scrollableArea = container->getScrollableAreaIfScrollable(); | 1302 ScrollableArea* scrollableArea = container->getScrollableAreaIfScrollable(); |
| 1297 if (scrollableArea && !container->isWebArea()) { | 1303 if (scrollableArea && !container->isWebArea()) { |
| 1298 IntPoint scrollPosition = scrollableArea->scrollPosition(); | 1304 IntPoint scrollPosition = scrollableArea->scrollPosition(); |
| 1299 outBoundsInContainer.move( | 1305 outBoundsInContainer.move( |
| 1300 FloatSize(scrollPosition.x(), scrollPosition.y())); | 1306 FloatSize(scrollPosition.x(), scrollPosition.y())); |
| 1301 } | 1307 } |
| 1302 | 1308 |
| 1303 // Compute the transform between the container's coordinate space and this obj
ect. | 1309 // Compute the transform between the container's coordinate space and this |
| 1304 // If the transform is just a simple translation, apply that to the bounding b
ox, but | 1310 // object. If the transform is just a simple translation, apply that to the |
| 1305 // if it's a non-trivial transformation like a rotation, scaling, etc. then re
turn | 1311 // bounding box, but if it's a non-trivial transformation like a rotation, |
| 1306 // the full matrix instead. | 1312 // scaling, etc. then return the full matrix instead. |
| 1307 TransformationMatrix transform = layoutObject->localToAncestorTransform( | 1313 TransformationMatrix transform = layoutObject->localToAncestorTransform( |
| 1308 toLayoutBoxModelObject(containerLayoutObject)); | 1314 toLayoutBoxModelObject(containerLayoutObject)); |
| 1309 if (transform.isIdentityOr2DTranslation()) { | 1315 if (transform.isIdentityOr2DTranslation()) { |
| 1310 outBoundsInContainer.move(transform.to2DTranslation()); | 1316 outBoundsInContainer.move(transform.to2DTranslation()); |
| 1311 } else { | 1317 } else { |
| 1312 outContainerTransform = TransformationMatrix::toSkMatrix44(transform); | 1318 outContainerTransform = TransformationMatrix::toSkMatrix44(transform); |
| 1313 } | 1319 } |
| 1314 } | 1320 } |
| 1315 | 1321 |
| 1316 LayoutRect AXObject::getBoundsInFrameCoordinates() const { | 1322 LayoutRect AXObject::getBoundsInFrameCoordinates() const { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1424 return currentScrollOffset; | 1430 return currentScrollOffset; |
| 1425 | 1431 |
| 1426 // Subfocus must be within focus. | 1432 // Subfocus must be within focus. |
| 1427 subfocusMin = std::max(subfocusMin, objectMin); | 1433 subfocusMin = std::max(subfocusMin, objectMin); |
| 1428 subfocusMax = std::min(subfocusMax, objectMax); | 1434 subfocusMax = std::min(subfocusMax, objectMax); |
| 1429 | 1435 |
| 1430 // Subfocus must be no larger than the viewport size; favor top/left. | 1436 // Subfocus must be no larger than the viewport size; favor top/left. |
| 1431 if (subfocusMax - subfocusMin > viewportSize) | 1437 if (subfocusMax - subfocusMin > viewportSize) |
| 1432 subfocusMax = subfocusMin + viewportSize; | 1438 subfocusMax = subfocusMin + viewportSize; |
| 1433 | 1439 |
| 1434 // Compute the size of an object centered on the subfocus, the size of the v
iewport. | 1440 // Compute the size of an object centered on the subfocus, the size of the |
| 1441 // viewport. |
| 1435 int centeredObjectMin = (subfocusMin + subfocusMax - viewportSize) / 2; | 1442 int centeredObjectMin = (subfocusMin + subfocusMax - viewportSize) / 2; |
| 1436 int centeredObjectMax = centeredObjectMin + viewportSize; | 1443 int centeredObjectMax = centeredObjectMin + viewportSize; |
| 1437 | 1444 |
| 1438 objectMin = std::max(objectMin, centeredObjectMin); | 1445 objectMin = std::max(objectMin, centeredObjectMin); |
| 1439 objectMax = std::min(objectMax, centeredObjectMax); | 1446 objectMax = std::min(objectMax, centeredObjectMax); |
| 1440 } | 1447 } |
| 1441 | 1448 |
| 1442 // Exit now if the focus is already within the viewport. | 1449 // Exit now if the focus is already within the viewport. |
| 1443 if (objectMin - currentScrollOffset >= viewportMin && | 1450 if (objectMin - currentScrollOffset >= viewportMin && |
| 1444 objectMax - currentScrollOffset <= viewportMax) | 1451 objectMax - currentScrollOffset <= viewportMax) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1491 pixelSnappedIntRect(scrollParent->getBoundsInFrameCoordinates()); | 1498 pixelSnappedIntRect(scrollParent->getBoundsInFrameCoordinates()); |
| 1492 newSubfocus.move(newElementRect.x(), newElementRect.y()); | 1499 newSubfocus.move(newElementRect.x(), newElementRect.y()); |
| 1493 newSubfocus.move(-scrollParentRect.x(), -scrollParentRect.y()); | 1500 newSubfocus.move(-scrollParentRect.x(), -scrollParentRect.y()); |
| 1494 | 1501 |
| 1495 // Recursively make sure the scroll parent itself is visible. | 1502 // Recursively make sure the scroll parent itself is visible. |
| 1496 if (scrollParent->parentObject()) | 1503 if (scrollParent->parentObject()) |
| 1497 scrollParent->scrollToMakeVisibleWithSubFocus(newSubfocus); | 1504 scrollParent->scrollToMakeVisibleWithSubFocus(newSubfocus); |
| 1498 } | 1505 } |
| 1499 | 1506 |
| 1500 void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const { | 1507 void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const { |
| 1501 // Search up the parent chain and create a vector of all scrollable parent obj
ects | 1508 // Search up the parent chain and create a vector of all scrollable parent |
| 1502 // and ending with this object itself. | 1509 // objects and ending with this object itself. |
| 1503 HeapVector<Member<const AXObject>> objects; | 1510 HeapVector<Member<const AXObject>> objects; |
| 1504 AXObject* parentObject; | 1511 AXObject* parentObject; |
| 1505 for (parentObject = this->parentObject(); parentObject; | 1512 for (parentObject = this->parentObject(); parentObject; |
| 1506 parentObject = parentObject->parentObject()) { | 1513 parentObject = parentObject->parentObject()) { |
| 1507 if (parentObject->getScrollableAreaIfScrollable()) | 1514 if (parentObject->getScrollableAreaIfScrollable()) |
| 1508 objects.prepend(parentObject); | 1515 objects.prepend(parentObject); |
| 1509 } | 1516 } |
| 1510 objects.append(this); | 1517 objects.append(this); |
| 1511 | 1518 |
| 1512 // Start with the outermost scrollable (the main window) and try to scroll the | 1519 // Start with the outermost scrollable (the main window) and try to scroll the |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1534 | 1541 |
| 1535 int desiredX = computeBestScrollOffset(0, objectRect.x(), objectRect.maxX(), | 1542 int desiredX = computeBestScrollOffset(0, objectRect.x(), objectRect.maxX(), |
| 1536 objectRect.x(), objectRect.maxX(), | 1543 objectRect.x(), objectRect.maxX(), |
| 1537 point.x(), point.x()); | 1544 point.x(), point.x()); |
| 1538 int desiredY = computeBestScrollOffset(0, objectRect.y(), objectRect.maxY(), | 1545 int desiredY = computeBestScrollOffset(0, objectRect.y(), objectRect.maxY(), |
| 1539 objectRect.y(), objectRect.maxY(), | 1546 objectRect.y(), objectRect.maxY(), |
| 1540 point.y(), point.y()); | 1547 point.y(), point.y()); |
| 1541 outer->setScrollOffset(IntPoint(desiredX, desiredY)); | 1548 outer->setScrollOffset(IntPoint(desiredX, desiredY)); |
| 1542 | 1549 |
| 1543 if (outer->isWebArea() && !inner->isWebArea()) { | 1550 if (outer->isWebArea() && !inner->isWebArea()) { |
| 1544 // If outer object we just scrolled is a web area (frame) but the inner ob
ject | 1551 // If outer object we just scrolled is a web area (frame) but the inner |
| 1545 // is not, keep track of the coordinate transformation to apply to | 1552 // object is not, keep track of the coordinate transformation to apply to |
| 1546 // future nested calculations. | 1553 // future nested calculations. |
| 1547 scrollPosition = scrollableArea->scrollPosition(); | 1554 scrollPosition = scrollableArea->scrollPosition(); |
| 1548 offsetX -= (scrollPosition.x() + point.x()); | 1555 offsetX -= (scrollPosition.x() + point.x()); |
| 1549 offsetY -= (scrollPosition.y() + point.y()); | 1556 offsetY -= (scrollPosition.y() + point.y()); |
| 1550 point.move(scrollPosition.x() - innerRect.x(), | 1557 point.move(scrollPosition.x() - innerRect.x(), |
| 1551 scrollPosition.y() - innerRect.y()); | 1558 scrollPosition.y() - innerRect.y()); |
| 1552 } else if (inner->isWebArea()) { | 1559 } else if (inner->isWebArea()) { |
| 1553 // Otherwise, if the inner object is a web area, reset the coordinate tran
sformation. | 1560 // Otherwise, if the inner object is a web area, reset the coordinate |
| 1561 // transformation. |
| 1554 offsetX = 0; | 1562 offsetX = 0; |
| 1555 offsetY = 0; | 1563 offsetY = 0; |
| 1556 } | 1564 } |
| 1557 } | 1565 } |
| 1558 } | 1566 } |
| 1559 | 1567 |
| 1560 void AXObject::notifyIfIgnoredValueChanged() { | 1568 void AXObject::notifyIfIgnoredValueChanged() { |
| 1561 bool isIgnored = accessibilityIsIgnored(); | 1569 bool isIgnored = accessibilityIsIgnored(); |
| 1562 if (lastKnownIsIgnoredValue() != isIgnored) { | 1570 if (lastKnownIsIgnoredValue() != isIgnored) { |
| 1563 axObjectCache().childrenChanged(parentObject()); | 1571 axObjectCache().childrenChanged(parentObject()); |
| 1564 setLastKnownIsIgnoredValue(isIgnored); | 1572 setLastKnownIsIgnoredValue(isIgnored); |
| 1565 } | 1573 } |
| 1566 } | 1574 } |
| 1567 | 1575 |
| 1568 void AXObject::selectionChanged() { | 1576 void AXObject::selectionChanged() { |
| 1569 if (AXObject* parent = parentObjectIfExists()) | 1577 if (AXObject* parent = parentObjectIfExists()) |
| 1570 parent->selectionChanged(); | 1578 parent->selectionChanged(); |
| 1571 } | 1579 } |
| 1572 | 1580 |
| 1573 int AXObject::lineForPosition(const VisiblePosition& position) const { | 1581 int AXObject::lineForPosition(const VisiblePosition& position) const { |
| 1574 if (position.isNull() || !getNode()) | 1582 if (position.isNull() || !getNode()) |
| 1575 return -1; | 1583 return -1; |
| 1576 | 1584 |
| 1577 // If the position is not in the same editable region as this AX object, retur
n -1. | 1585 // If the position is not in the same editable region as this AX object, |
| 1586 // return -1. |
| 1578 Node* containerNode = position.deepEquivalent().computeContainerNode(); | 1587 Node* containerNode = position.deepEquivalent().computeContainerNode(); |
| 1579 if (!containerNode->isShadowIncludingInclusiveAncestorOf(getNode()) && | 1588 if (!containerNode->isShadowIncludingInclusiveAncestorOf(getNode()) && |
| 1580 !getNode()->isShadowIncludingInclusiveAncestorOf(containerNode)) | 1589 !getNode()->isShadowIncludingInclusiveAncestorOf(containerNode)) |
| 1581 return -1; | 1590 return -1; |
| 1582 | 1591 |
| 1583 int lineCount = -1; | 1592 int lineCount = -1; |
| 1584 VisiblePosition currentPosition = position; | 1593 VisiblePosition currentPosition = position; |
| 1585 VisiblePosition previousPosition; | 1594 VisiblePosition previousPosition; |
| 1586 | 1595 |
| 1587 // move up until we get to the top | 1596 // Move up until we get to the top. |
| 1588 // FIXME: This only takes us to the top of the rootEditableElement, not the to
p of the | 1597 // FIXME: This only takes us to the top of the rootEditableElement, not the |
| 1589 // top document. | 1598 // top of the top document. |
| 1590 do { | 1599 do { |
| 1591 previousPosition = currentPosition; | 1600 previousPosition = currentPosition; |
| 1592 currentPosition = | 1601 currentPosition = |
| 1593 previousLinePosition(currentPosition, LayoutUnit(), HasEditableAXRole); | 1602 previousLinePosition(currentPosition, LayoutUnit(), HasEditableAXRole); |
| 1594 ++lineCount; | 1603 ++lineCount; |
| 1595 } while (currentPosition.isNotNull() && | 1604 } while (currentPosition.isNotNull() && |
| 1596 !inSameLine(currentPosition, previousPosition)); | 1605 !inSameLine(currentPosition, previousPosition)); |
| 1597 | 1606 |
| 1598 return lineCount; | 1607 return lineCount; |
| 1599 } | 1608 } |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1724 } | 1733 } |
| 1725 | 1734 |
| 1726 DEFINE_TRACE(AXObject) { | 1735 DEFINE_TRACE(AXObject) { |
| 1727 visitor->trace(m_children); | 1736 visitor->trace(m_children); |
| 1728 visitor->trace(m_parent); | 1737 visitor->trace(m_parent); |
| 1729 visitor->trace(m_cachedLiveRegionRoot); | 1738 visitor->trace(m_cachedLiveRegionRoot); |
| 1730 visitor->trace(m_axObjectCache); | 1739 visitor->trace(m_axObjectCache); |
| 1731 } | 1740 } |
| 1732 | 1741 |
| 1733 } // namespace blink | 1742 } // namespace blink |
| OLD | NEW |