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

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

Powered by Google App Engine
This is Rietveld 408576698