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

Unified Diff: third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp

Issue 2339093003: Support child-based node offsets when setting accessible selections (Closed)
Patch Set: More tests. 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
index 53f06146bff17b7a26e867933cf7a84d34990354..dd55c690d7328fe78d0b948ca9ca54552743de47 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
@@ -1817,21 +1817,44 @@ AXLayoutObject* AXLayoutObject::getUnignoredObjectFromNode(Node& node) const
// Convert from an accessible object and offset to a VisiblePosition.
static VisiblePosition toVisiblePosition(AXObject* obj, int offset)
{
- // First walk up until we find an accessible object with an associated node.
- AXObject* runner = obj;
- Node* node = nullptr;
- while (runner && !node) {
- node = runner->getNode();
- runner = runner->parentObject();
- }
-
- if (!node)
+ if (!obj->getNode())
return VisiblePosition();
- // If it's not a text node, no conversion is necessary, just create a VisiblePosition
- // with this node and offset.
- if (!node->isTextNode())
- return createVisiblePosition(Position(node, offset));
+ Node* node = obj->getNode();
+ if (!node->isTextNode()) {
dmazzoni 2016/09/15 16:32:36 It's possible to call AXObject::setSelection on an
+ // The offsets are child offsets over the AX tree. Note that we allow
+ // for the offset to equal the number of children as |Range| does.
+ if (offset < 0 || static_cast<unsigned>(offset) > obj->children().size())
+ return VisiblePosition();
+
+ // Clamp to between 0 and child count - 1.
+ int clampedOffset =
+ static_cast<unsigned>(offset) > (obj->children().size() - 1) ? offset - 1 : offset;
dmazzoni 2016/09/15 16:32:36 Clearer using std::min?
+ AXObject* childObj = obj->children()[clampedOffset];
+ Node* childNode = childObj->getNode();
+ if (!childNode || !childNode->parentNode())
+ return VisiblePosition();
+
+ // The index in parent.
+ int adjustedOffset = -1;
+ NodeList* childNodes = childNode->parentNode()->childNodes();
+ for (unsigned i = 0; i < childNodes->length(); ++i) {
+ if (childNodes->item(i) == childNode) {
+ adjustedOffset = i;
+ break;
+ }
+ }
+
+ if (adjustedOffset == -1)
+ return VisiblePosition();
+
+ // If we had to clamp the offset above, the client wants to select the
+ // end of the node.
+ if (clampedOffset != offset)
+ adjustedOffset++;
+
+ return createVisiblePosition(Position::editingPositionOf(childNode->parentNode(), adjustedOffset));
dmazzoni 2016/09/15 16:32:36 Instead of computing the index in parent in the DO
+ }
// If it is a text node, we need to call some utility functions that use a TextIterator
// to walk the characters of the node and figure out the position corresponding to the
@@ -1860,6 +1883,7 @@ void AXLayoutObject::setSelection(const AXRange& selection)
return;
}
+ // The selection offsets are offsets into the accessible value.
if (anchorObject == focusObject
&& anchorObject->getLayoutObject()->isTextControl()) {
HTMLTextFormControlElement* textControl = toLayoutTextControl(

Powered by Google App Engine
This is Rietveld 408576698