Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(712)

Side by Side Diff: third_party/WebKit/Source/modules/accessibility/AXObject.cpp

Issue 2287433003: Get rid of remaining uses of AXObject::elementRect (Closed)
Patch Set: Rebase Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 10 matching lines...) Expand all
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29 #include "modules/accessibility/AXObject.h" 29 #include "modules/accessibility/AXObject.h"
30 30
31 #include "SkMatrix44.h"
31 #include "core/editing/EditingUtilities.h" 32 #include "core/editing/EditingUtilities.h"
32 #include "core/editing/VisibleUnits.h" 33 #include "core/editing/VisibleUnits.h"
33 #include "core/frame/FrameView.h" 34 #include "core/frame/FrameView.h"
34 #include "core/frame/LocalFrame.h" 35 #include "core/frame/LocalFrame.h"
35 #include "core/frame/Settings.h" 36 #include "core/frame/Settings.h"
36 #include "core/html/HTMLDialogElement.h" 37 #include "core/html/HTMLDialogElement.h"
37 #include "core/html/HTMLFrameOwnerElement.h" 38 #include "core/html/HTMLFrameOwnerElement.h"
38 #include "core/html/parser/HTMLParserIdioms.h" 39 #include "core/html/parser/HTMLParserIdioms.h"
40 #include "core/layout/LayoutInline.h"
39 #include "core/layout/LayoutTheme.h" 41 #include "core/layout/LayoutTheme.h"
40 #include "modules/accessibility/AXObjectCacheImpl.h" 42 #include "modules/accessibility/AXObjectCacheImpl.h"
41 #include "platform/UserGestureIndicator.h" 43 #include "platform/UserGestureIndicator.h"
42 #include "platform/text/PlatformLocale.h" 44 #include "platform/text/PlatformLocale.h"
43 #include "wtf/HashSet.h" 45 #include "wtf/HashSet.h"
44 #include "wtf/StdLibExtras.h" 46 #include "wtf/StdLibExtras.h"
45 #include "wtf/text/WTFString.h" 47 #include "wtf/text/WTFString.h"
46 48
47 using blink::WebLocalizedString; 49 using blink::WebLocalizedString;
48 50
(...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 updateCachedAttributeValuesIfNeeded(); 1127 updateCachedAttributeValuesIfNeeded();
1126 return m_cachedLiveRegionRoot && m_cachedLiveRegionRoot->liveRegionAtomic(); 1128 return m_cachedLiveRegionRoot && m_cachedLiveRegionRoot->liveRegionAtomic();
1127 } 1129 }
1128 1130
1129 bool AXObject::containerLiveRegionBusy() const 1131 bool AXObject::containerLiveRegionBusy() const
1130 { 1132 {
1131 updateCachedAttributeValuesIfNeeded(); 1133 updateCachedAttributeValuesIfNeeded();
1132 return m_cachedLiveRegionRoot && m_cachedLiveRegionRoot->liveRegionBusy(); 1134 return m_cachedLiveRegionRoot && m_cachedLiveRegionRoot->liveRegionBusy();
1133 } 1135 }
1134 1136
1135 void AXObject::markCachedElementRectDirty() const
1136 {
1137 for (const auto& child : m_children)
1138 child->markCachedElementRectDirty();
1139 }
1140
1141 IntPoint AXObject::clickPoint()
1142 {
1143 LayoutRect rect = elementRect();
1144 return roundedIntPoint(LayoutPoint(rect.x() + rect.width() / 2, rect.y() + r ect.height() / 2));
1145 }
1146
1147 SkMatrix44 AXObject::transformFromLocalParentFrame() const
1148 {
1149 return SkMatrix44();
1150 }
1151
1152 IntRect AXObject::boundingBoxForQuads(LayoutObject* obj, const Vector<FloatQuad> & quads)
1153 {
1154 ASSERT(obj);
1155 if (!obj)
1156 return IntRect();
1157
1158 size_t count = quads.size();
1159 if (!count)
1160 return IntRect();
1161
1162 IntRect result;
1163 for (size_t i = 0; i < count; ++i) {
1164 IntRect r = quads[i].enclosingBoundingBox();
1165 if (!r.isEmpty()) {
1166 // TODO(pdr): Should this be using visualOverflowRect?
1167 if (obj->style()->hasAppearance())
1168 LayoutTheme::theme().addVisualOverflow(*obj, r);
1169 result.unite(r);
1170 }
1171 }
1172 return result;
1173 }
1174
1175 AXObject* AXObject::elementAccessibilityHitTest(const IntPoint& point) const 1137 AXObject* AXObject::elementAccessibilityHitTest(const IntPoint& point) const
1176 { 1138 {
1177 // Check if there are any mock elements that need to be handled. 1139 // Check if there are any mock elements that need to be handled.
1178 for (const auto& child : m_children) { 1140 for (const auto& child : m_children) {
1179 if (child->isMockObject() && child->elementRect().contains(point)) 1141 if (child->isMockObject() && child->getBoundsInFrameCoordinates().contai ns(point))
1180 return child->elementAccessibilityHitTest(point); 1142 return child->elementAccessibilityHitTest(point);
1181 } 1143 }
1182 1144
1183 return const_cast<AXObject*>(this); 1145 return const_cast<AXObject*>(this);
1184 } 1146 }
1185 1147
1186 const AXObject::AXObjectVector& AXObject::children() 1148 const AXObject::AXObjectVector& AXObject::children()
1187 { 1149 {
1188 updateChildrenIfNecessary(); 1150 updateChildrenIfNecessary();
1189 1151
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1345 void AXObject::setScrollOffset(const IntPoint& offset) const 1307 void AXObject::setScrollOffset(const IntPoint& offset) const
1346 { 1308 {
1347 ScrollableArea* area = getScrollableAreaIfScrollable(); 1309 ScrollableArea* area = getScrollableAreaIfScrollable();
1348 if (!area) 1310 if (!area)
1349 return; 1311 return;
1350 1312
1351 // TODO(bokan): This should potentially be a UserScroll. 1313 // TODO(bokan): This should potentially be a UserScroll.
1352 area->setScrollPosition(DoublePoint(offset.x(), offset.y()), ProgrammaticScr oll); 1314 area->setScrollPosition(DoublePoint(offset.x(), offset.y()), ProgrammaticScr oll);
1353 } 1315 }
1354 1316
1355 void AXObject::getRelativeBounds(AXObject** container, FloatRect& boundsInContai ner, SkMatrix44& containerTransform) const 1317 void AXObject::getRelativeBounds(AXObject** outContainer, FloatRect& outBoundsIn Container, SkMatrix44& outContainerTransform) const
1356 { 1318 {
1357 *container = nullptr; 1319 *outContainer = nullptr;
1358 boundsInContainer = FloatRect(); 1320 outBoundsInContainer = FloatRect();
1359 containerTransform.setIdentity(); 1321 outContainerTransform.setIdentity();
1322
1323 // First check if it has explicit bounds, for example if this element is tie d to a
1324 // canvas path. When explicit coordinates are provided, the ID of the explic it container
1325 // element that the coordinates are relative to must be provided too.
1326 if (!m_explicitElementRect.isEmpty()) {
1327 *outContainer = axObjectCache().objectFromAXID(m_explicitContainerID);
1328 if (*outContainer) {
1329 outBoundsInContainer = FloatRect(m_explicitElementRect);
1330 return;
1331 }
1332 }
1333
1334 LayoutObject* layoutObject = layoutObjectForRelativeBounds();
1335 if (!layoutObject)
1336 return;
1337
1338 if (isWebArea()) {
1339 if (layoutObject->frame()->view())
1340 outBoundsInContainer.setSize(FloatSize(layoutObject->frame()->view() ->contentsSize()));
1341 return;
1342 }
1343
1344 // First compute the container. The container must be an ancestor in the acc essibility tree, and
1345 // its LayoutObject must be an ancestor in the layout tree. Get the first su ch ancestor that's
1346 // either scrollable or has a paint layer.
1347 AXObject* container = parentObjectUnignored();
1348 LayoutObject* containerLayoutObject = nullptr;
1349 while (container) {
1350 containerLayoutObject = container->getLayoutObject();
1351 if (containerLayoutObject && containerLayoutObject->isBoxModelObject() & & layoutObject->isDescendantOf(containerLayoutObject)) {
1352 if (container->isScrollableContainer() || containerLayoutObject->has Layer())
1353 break;
1354 }
1355
1356 container = container->parentObjectUnignored();
1357 }
1358
1359 if (!container)
1360 return;
1361 *outContainer = container;
1362
1363 // Next get the local bounds of this LayoutObject, which is typically
1364 // a rect at point (0, 0) with the width and height of the LayoutObject.
1365 LayoutRect localBounds;
1366 if (layoutObject->isText()) {
1367 Vector<FloatQuad> quads;
1368 toLayoutText(layoutObject)->quads(quads, LayoutText::ClipToEllipsis, Lay outText::LocalQuads);
1369 for (const FloatQuad& quad : quads)
1370 localBounds.unite(LayoutRect(quad.boundingBox()));
1371 } else if (layoutObject->isLayoutInline()) {
1372 Vector<LayoutRect> rects;
1373 toLayoutInline(layoutObject)->addOutlineRects(rects, LayoutPoint(), Layo utObject::IncludeBlockVisualOverflow);
1374 localBounds = unionRect(rects);
1375 } else if (layoutObject->isBox()) {
1376 localBounds = LayoutRect(LayoutPoint(), toLayoutBox(layoutObject)->size( ));
1377 } else if (layoutObject->isSVG()) {
1378 localBounds = LayoutRect(layoutObject->strokeBoundingBox());
1379 } else {
1380 DCHECK(false);
1381 }
1382 outBoundsInContainer = FloatRect(localBounds);
1383
1384 // If the container has a scroll offset, subtract that out because we want o ur
1385 // bounds to be relative to the *unscrolled* position of the container objec t.
1386 ScrollableArea* scrollableArea = container->getScrollableAreaIfScrollable();
1387 if (scrollableArea && !container->isWebArea()) {
1388 IntPoint scrollPosition = scrollableArea->scrollPosition();
1389 outBoundsInContainer.move(FloatSize(scrollPosition.x(), scrollPosition.y ()));
1390 }
1391
1392 // Compute the transform between the container's coordinate space and this o bject.
1393 // If the transform is just a simple translation, apply that to the bounding box, but
1394 // if it's a non-trivial transformation like a rotation, scaling, etc. then return
1395 // the full matrix instead.
1396 TransformationMatrix transform = layoutObject->localToAncestorTransform(toLa youtBoxModelObject(containerLayoutObject));
1397 if (transform.isIdentityOr2DTranslation()) {
1398 outBoundsInContainer.move(transform.to2DTranslation());
1399 } else {
1400 outContainerTransform = TransformationMatrix::toSkMatrix44(transform);
1401 }
1402 }
1403
1404 LayoutRect AXObject::getBoundsInFrameCoordinates() const
1405 {
1406 AXObject* container = nullptr;
1407 FloatRect bounds;
1408 SkMatrix44 transform;
1409 getRelativeBounds(&container, bounds, transform);
1410 FloatRect computedBounds(0, 0, bounds.width(), bounds.height());
1411 while (container && container != this) {
1412 computedBounds.move(bounds.x(), bounds.y());
1413 if (!container->isWebArea())
1414 computedBounds.move(-container->scrollOffset().x(), -container->scro llOffset().y());
1415 if (!transform.isIdentity()) {
1416 TransformationMatrix transformationMatrix(transform);
1417 transformationMatrix.mapRect(computedBounds);
1418 }
1419 container->getRelativeBounds(&container, bounds, transform);
1420 }
1421 return LayoutRect(computedBounds);
1360 } 1422 }
1361 1423
1362 // 1424 //
1363 // Modify or take an action on an object. 1425 // Modify or take an action on an object.
1364 // 1426 //
1365 1427
1366 bool AXObject::press() const 1428 bool AXObject::press() const
1367 { 1429 {
1368 Element* actionElem = actionElement(); 1430 Element* actionElem = actionElement();
1369 if (!actionElem) 1431 if (!actionElem)
1370 return false; 1432 return false;
1371 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture); 1433 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
1372 actionElem->accessKeyAction(true); 1434 actionElem->accessKeyAction(true);
1373 return true; 1435 return true;
1374 } 1436 }
1375 1437
1376 void AXObject::scrollToMakeVisible() const 1438 void AXObject::scrollToMakeVisible() const
1377 { 1439 {
1378 IntRect objectRect = pixelSnappedIntRect(elementRect()); 1440 IntRect objectRect = pixelSnappedIntRect(getBoundsInFrameCoordinates());
1379 objectRect.setLocation(IntPoint()); 1441 objectRect.setLocation(IntPoint());
1380 scrollToMakeVisibleWithSubFocus(objectRect); 1442 scrollToMakeVisibleWithSubFocus(objectRect);
1381 } 1443 }
1382 1444
1383 // This is a 1-dimensional scroll offset helper function that's applied 1445 // This is a 1-dimensional scroll offset helper function that's applied
1384 // separately in the horizontal and vertical directions, because the 1446 // separately in the horizontal and vertical directions, because the
1385 // logic is the same. The goal is to compute the best scroll offset 1447 // logic is the same. The goal is to compute the best scroll offset
1386 // in order to make an object visible within a viewport. 1448 // in order to make an object visible within a viewport.
1387 // 1449 //
1388 // If the object is already fully visible, returns the same scroll 1450 // If the object is already fully visible, returns the same scroll
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 ScrollableArea* scrollableArea = 0; 1540 ScrollableArea* scrollableArea = 0;
1479 while (scrollParent) { 1541 while (scrollParent) {
1480 scrollableArea = scrollParent->getScrollableAreaIfScrollable(); 1542 scrollableArea = scrollParent->getScrollableAreaIfScrollable();
1481 if (scrollableArea) 1543 if (scrollableArea)
1482 break; 1544 break;
1483 scrollParent = scrollParent->parentObject(); 1545 scrollParent = scrollParent->parentObject();
1484 } 1546 }
1485 if (!scrollParent || !scrollableArea) 1547 if (!scrollParent || !scrollableArea)
1486 return; 1548 return;
1487 1549
1488 IntRect objectRect = pixelSnappedIntRect(elementRect()); 1550 IntRect objectRect = pixelSnappedIntRect(getBoundsInFrameCoordinates());
1489 IntPoint scrollPosition = scrollableArea->scrollPosition(); 1551 IntPoint scrollPosition = scrollableArea->scrollPosition();
1490 IntRect scrollVisibleRect = scrollableArea->visibleContentRect(); 1552 IntRect scrollVisibleRect = scrollableArea->visibleContentRect();
1491 1553
1492 // Convert the object rect into local coordinates. 1554 // Convert the object rect into local coordinates.
1493 if (!scrollParent->isWebArea()) { 1555 if (!scrollParent->isWebArea()) {
1494 objectRect.moveBy(scrollPosition); 1556 objectRect.moveBy(scrollPosition);
1495 objectRect.moveBy(-pixelSnappedIntRect(scrollParent->elementRect()).loca tion()); 1557 objectRect.moveBy(-pixelSnappedIntRect(scrollParent->getBoundsInFrameCoo rdinates()).location());
1496 } 1558 }
1497 1559
1498 int desiredX = computeBestScrollOffset( 1560 int desiredX = computeBestScrollOffset(
1499 scrollPosition.x(), 1561 scrollPosition.x(),
1500 objectRect.x() + subfocus.x(), objectRect.x() + subfocus.maxX(), 1562 objectRect.x() + subfocus.x(), objectRect.x() + subfocus.maxX(),
1501 objectRect.x(), objectRect.maxX(), 1563 objectRect.x(), objectRect.maxX(),
1502 0, scrollVisibleRect.width()); 1564 0, scrollVisibleRect.width());
1503 int desiredY = computeBestScrollOffset( 1565 int desiredY = computeBestScrollOffset(
1504 scrollPosition.y(), 1566 scrollPosition.y(),
1505 objectRect.y() + subfocus.y(), objectRect.y() + subfocus.maxY(), 1567 objectRect.y() + subfocus.y(), objectRect.y() + subfocus.maxY(),
1506 objectRect.y(), objectRect.maxY(), 1568 objectRect.y(), objectRect.maxY(),
1507 0, scrollVisibleRect.height()); 1569 0, scrollVisibleRect.height());
1508 1570
1509 scrollParent->setScrollOffset(IntPoint(desiredX, desiredY)); 1571 scrollParent->setScrollOffset(IntPoint(desiredX, desiredY));
1510 1572
1511 // Convert the subfocus into the coordinates of the scroll parent. 1573 // Convert the subfocus into the coordinates of the scroll parent.
1512 IntRect newSubfocus = subfocus; 1574 IntRect newSubfocus = subfocus;
1513 IntRect newElementRect = pixelSnappedIntRect(elementRect()); 1575 IntRect newElementRect = pixelSnappedIntRect(getBoundsInFrameCoordinates());
1514 IntRect scrollParentRect = pixelSnappedIntRect(scrollParent->elementRect()); 1576 IntRect scrollParentRect = pixelSnappedIntRect(scrollParent->getBoundsInFram eCoordinates());
1515 newSubfocus.move(newElementRect.x(), newElementRect.y()); 1577 newSubfocus.move(newElementRect.x(), newElementRect.y());
1516 newSubfocus.move(-scrollParentRect.x(), -scrollParentRect.y()); 1578 newSubfocus.move(-scrollParentRect.x(), -scrollParentRect.y());
1517 1579
1518 // Recursively make sure the scroll parent itself is visible. 1580 // Recursively make sure the scroll parent itself is visible.
1519 if (scrollParent->parentObject()) 1581 if (scrollParent->parentObject())
1520 scrollParent->scrollToMakeVisibleWithSubFocus(newSubfocus); 1582 scrollParent->scrollToMakeVisibleWithSubFocus(newSubfocus);
1521 } 1583 }
1522 1584
1523 void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const 1585 void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const
1524 { 1586 {
(...skipping 10 matching lines...) Expand all
1535 // Start with the outermost scrollable (the main window) and try to scroll t he 1597 // Start with the outermost scrollable (the main window) and try to scroll t he
1536 // next innermost object to the given point. 1598 // next innermost object to the given point.
1537 int offsetX = 0, offsetY = 0; 1599 int offsetX = 0, offsetY = 0;
1538 IntPoint point = globalPoint; 1600 IntPoint point = globalPoint;
1539 size_t levels = objects.size() - 1; 1601 size_t levels = objects.size() - 1;
1540 for (size_t i = 0; i < levels; i++) { 1602 for (size_t i = 0; i < levels; i++) {
1541 const AXObject* outer = objects[i]; 1603 const AXObject* outer = objects[i];
1542 const AXObject* inner = objects[i + 1]; 1604 const AXObject* inner = objects[i + 1];
1543 ScrollableArea* scrollableArea = outer->getScrollableAreaIfScrollable(); 1605 ScrollableArea* scrollableArea = outer->getScrollableAreaIfScrollable();
1544 1606
1545 IntRect innerRect = inner->isWebArea() ? pixelSnappedIntRect(inner->pare ntObject()->elementRect()) : pixelSnappedIntRect(inner->elementRect()); 1607 IntRect innerRect = inner->isWebArea() ? pixelSnappedIntRect(inner->pare ntObject()->getBoundsInFrameCoordinates()) : pixelSnappedIntRect(inner->getBound sInFrameCoordinates());
1546 IntRect objectRect = innerRect; 1608 IntRect objectRect = innerRect;
1547 IntPoint scrollPosition = scrollableArea->scrollPosition(); 1609 IntPoint scrollPosition = scrollableArea->scrollPosition();
1548 1610
1549 // Convert the object rect into local coordinates. 1611 // Convert the object rect into local coordinates.
1550 objectRect.move(offsetX, offsetY); 1612 objectRect.move(offsetX, offsetY);
1551 if (!outer->isWebArea()) 1613 if (!outer->isWebArea())
1552 objectRect.move(scrollPosition.x(), scrollPosition.y()); 1614 objectRect.move(scrollPosition.x(), scrollPosition.y());
1553 1615
1554 int desiredX = computeBestScrollOffset( 1616 int desiredX = computeBestScrollOffset(
1555 0, 1617 0,
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1754 1816
1755 DEFINE_TRACE(AXObject) 1817 DEFINE_TRACE(AXObject)
1756 { 1818 {
1757 visitor->trace(m_children); 1819 visitor->trace(m_children);
1758 visitor->trace(m_parent); 1820 visitor->trace(m_parent);
1759 visitor->trace(m_cachedLiveRegionRoot); 1821 visitor->trace(m_cachedLiveRegionRoot);
1760 visitor->trace(m_axObjectCache); 1822 visitor->trace(m_axObjectCache);
1761 } 1823 }
1762 1824
1763 } // namespace blink 1825 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/accessibility/AXObject.h ('k') | third_party/WebKit/Source/modules/accessibility/AXSlider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698