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

Unified Diff: Source/testing/runner/AccessibilityUIElementChromium.cpp

Issue 23983002: Expose InlineTextBoxes in the accessibility tree. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Address feedback Created 7 years, 2 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: Source/testing/runner/AccessibilityUIElementChromium.cpp
diff --git a/Source/testing/runner/AccessibilityUIElementChromium.cpp b/Source/testing/runner/AccessibilityUIElementChromium.cpp
index 9859ff2d2b9c395c0473514fffe93c5b4001534e..45989bffba45324ddab529f528638329be8528fd 100644
--- a/Source/testing/runner/AccessibilityUIElementChromium.cpp
+++ b/Source/testing/runner/AccessibilityUIElementChromium.cpp
@@ -132,6 +132,8 @@ string roleToString(WebAXRole role)
return result.append("Image");
case WebAXRoleIncrementor:
return result.append("Incrementor");
+ case WebAXRoleInlineTextBox:
+ return result.append("InlineTextBox");
case WebAXRoleLabel:
return result.append("Label");
case WebAXRoleLegend:
@@ -345,6 +347,108 @@ string getAttributes(const WebAXObject& object)
return attributes;
}
+WebRect boundsForCharacter(const WebAXObject& object, int characterIndex)
+{
+ BLINK_ASSERT(object.role() == WebAXRoleStaticText);
+ int end = 0;
+ for (unsigned i = 0; i < object.childCount(); i++) {
+ WebAXObject child = object.childAt(i);
aboxhall 2013/10/17 22:27:55 s/child/textBox/g ?
dmazzoni 2013/10/19 06:48:07 Done.
+ BLINK_ASSERT(child.role() == WebAXRoleInlineTextBox);
+ int start = end;
+ end += child.stringValue().length();
+ if (end <= characterIndex)
+ continue;
+ WebRect childRect = child.boundingBoxRect();
+ int localIndex = characterIndex - start;
+ WebVector<int> characterOffsets;
+ child.characterOffsets(characterOffsets);
+ BLINK_ASSERT(characterOffsets.size() > 0 && characterOffsets.size() == child.stringValue().length());
+ switch (child.textDirection()) {
+ case WebAXTextDirectionLR: {
+ if (localIndex) {
aboxhall 2013/10/17 22:27:55 I know it's not WebKit/Blink style, but I think ex
dmazzoni 2013/10/19 06:48:07 I agree with you, but the style checker actually d
+ int left = childRect.x + characterOffsets[localIndex - 1];
+ int width = characterOffsets[localIndex] - characterOffsets[localIndex - 1];
+ return WebRect(left, childRect.y, width, childRect.height);
+ }
+ return WebRect(childRect.x, childRect.y, characterOffsets[0], childRect.height);
+ }
+ case WebAXTextDirectionRL: {
+ int right = childRect.x + childRect.width;
+
+ if (localIndex) {
+ int left = right - characterOffsets[localIndex];
+ int width = characterOffsets[localIndex] - characterOffsets[localIndex - 1];
+ return WebRect(left, childRect.y, width, childRect.height);
+ }
+ int left = right - characterOffsets[0];
+ return WebRect(left, childRect.y, characterOffsets[0], childRect.height);
+ }
+ case WebAXTextDirectionTB: {
+ if (localIndex) {
+ int top = childRect.y + characterOffsets[localIndex - 1];
+ int height = characterOffsets[localIndex] - characterOffsets[localIndex - 1];
+ return WebRect(childRect.x, top, childRect.width, height);
+ }
+ return WebRect(childRect.x, childRect.y, childRect.width, characterOffsets[0]);
+ }
+ case WebAXTextDirectionBT: {
+ int bottom = childRect.y + childRect.height;
+
+ if (localIndex) {
+ int top = bottom - characterOffsets[localIndex];
+ int height = characterOffsets[localIndex] - characterOffsets[localIndex - 1];
+ return WebRect(childRect.x, top, childRect.width, height);
+ }
+ int top = bottom - characterOffsets[0];
+ return WebRect(childRect.x, top, childRect.width, characterOffsets[0]);
+ }
+ }
+ }
+
+ BLINK_ASSERT(false);
+ return WebRect();
+}
+
+void getWordBoundaries(const WebAXObject& object, int characterIndex, int& wordStart, int& wordEnd)
aboxhall 2013/10/17 22:27:55 This method name confuses me a bit - it's similar
dmazzoni 2013/10/19 06:48:07 Done.
+{
+ int end = 0;
+ for (unsigned i = 0; i < object.childCount(); i++) {
+ WebAXObject child = object.childAt(i);
aboxhall 2013/10/17 22:27:55 similarly, s/child/textBox/g ?
dmazzoni 2013/10/19 06:48:07 Done.
+ BLINK_ASSERT(child.role() == WebAXRoleInlineTextBox);
+ int start = end;
+ end += child.stringValue().length();
+ if (end <= characterIndex)
+ continue;
+ int localIndex = characterIndex - start;
+
+ WebVector<int> starts;
+ WebVector<int> ends;
+ child.wordBoundaries(starts, ends);
+ size_t wordCount = starts.size();
+ BLINK_ASSERT(ends.size() == wordCount);
+
+ // If there are no words, use the InlineTextBox boundaries.
+ if (!wordCount) {
+ wordStart = start;
+ wordEnd = end;
+ return;
+ }
+
+ // Look for a character within any word other than the last.
+ for (size_t j = 0; j < wordCount - 1; j++) {
+ if (localIndex <= ends[j]) {
+ wordStart = start + starts[j];
+ wordEnd = start + ends[j];
+ return;
+ }
+ }
+
+ // Return the last word by default.
+ wordStart = start + starts[wordCount - 1];
+ wordEnd = start + ends[wordCount - 1];
+ return;
+ }
+}
// Collects attributes into a string, delimited by dashes. Used by all methods
// that output lists of attributes: attributesOfLinkedUIElementsCallback,
@@ -458,6 +562,8 @@ AccessibilityUIElement::AccessibilityUIElement(const WebAXObject& object, Factor
bindMethod("scrollToMakeVisible", &AccessibilityUIElement::scrollToMakeVisibleCallback);
bindMethod("scrollToMakeVisibleWithSubFocus", &AccessibilityUIElement::scrollToMakeVisibleWithSubFocusCallback);
bindMethod("scrollToGlobalPoint", &AccessibilityUIElement::scrollToGlobalPointCallback);
+ bindMethod("wordStart", &AccessibilityUIElement::wordStartCallback);
+ bindMethod("wordEnd", &AccessibilityUIElement::wordEndCallback);
bindFallbackMethod(&AccessibilityUIElement::fallbackCallback);
}
@@ -747,9 +853,36 @@ void AccessibilityUIElement::lineForIndexCallback(const CppArgumentList& argumen
result->set(line);
}
-void AccessibilityUIElement::boundsForRangeCallback(const CppArgumentList&, CppVariant* result)
+void AccessibilityUIElement::boundsForRangeCallback(const CppArgumentList& arguments, CppVariant* result)
{
result->setNull();
+
+ if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
+ return;
+
+ if (accessibilityObject().role() != WebAXRoleStaticText)
+ return;
+
+ int start = arguments[0].toInt32();
+ int end = arguments[1].toInt32();
+ int len = end - start;
+
+ // Get the bounds for each character and union them into one large rectangle.
+ // This is just for testing so it doesn't need to be efficient.
+ WebRect bounds = boundsForCharacter(accessibilityObject(), start);
+ for (int i = 1; i < len; i++) {
+ WebRect next = boundsForCharacter(accessibilityObject(), start + i);
+ int right = std::max(bounds.x + bounds.width, next.x + next.width);
+ int bottom = std::max(bounds.y + bounds.height, next.y + next.height);
+ bounds.x = std::min(bounds.x, next.x);
+ bounds.y = std::min(bounds.y, next.y);
+ bounds.width = right - bounds.x;
+ bounds.height = bottom - bounds.y;
+ }
+
+ char buffer[100];
+ snprintf(buffer, sizeof(buffer), "{x: %d, y: %d, width: %d, height: %d}", bounds.x, bounds.y, bounds.width, bounds.height);
+ result->set(string(buffer));
}
void AccessibilityUIElement::stringForRangeCallback(const CppArgumentList&, CppVariant* result)
@@ -1035,6 +1168,38 @@ void AccessibilityUIElement::scrollToGlobalPointCallback(const CppArgumentList&
result->setNull();
}
+void AccessibilityUIElement::wordStartCallback(const CppArgumentList& arguments, CppVariant* result)
+{
+ result->setNull();
+
+ if (arguments.size() != 1 || !arguments[0].isNumber())
+ return;
+
+ if (accessibilityObject().role() != WebAXRoleStaticText)
+ return;
+
+ int characterIndex = arguments[0].toInt32();
+ int wordStart, wordEnd;
+ getWordBoundaries(accessibilityObject(), characterIndex, wordStart, wordEnd);
+ result->set(wordStart);
+}
+
+void AccessibilityUIElement::wordEndCallback(const CppArgumentList& arguments, CppVariant* result)
+{
+ result->setNull();
+
+ if (arguments.size() != 1 || !arguments[0].isNumber())
+ return;
+
+ if (accessibilityObject().role() != WebAXRoleStaticText)
+ return;
+
+ int characterIndex = arguments[0].toInt32();
+ int wordStart, wordEnd;
+ getWordBoundaries(accessibilityObject(), characterIndex, wordStart, wordEnd);
+ result->set(wordEnd);
+}
+
void AccessibilityUIElement::fallbackCallback(const CppArgumentList &, CppVariant* result)
{
// FIXME: Implement this.

Powered by Google App Engine
This is Rietveld 408576698