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

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

Issue 23983002: Expose InlineTextBoxes in the accessibility tree. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase 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
« no previous file with comments | « Source/testing/runner/WebAXObjectProxy.h ('k') | Source/web/AssertMatchingEnums.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/testing/runner/WebAXObjectProxy.cpp
diff --git a/Source/testing/runner/WebAXObjectProxy.cpp b/Source/testing/runner/WebAXObjectProxy.cpp
index aa866300c20a10c027d5ad1071df1d368de30655..b154e0f16ad416fa2a874f0e8030853cc92c45d5 100644
--- a/Source/testing/runner/WebAXObjectProxy.cpp
+++ b/Source/testing/runner/WebAXObjectProxy.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:
@@ -346,6 +348,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 inlineTextBox = object.childAt(i);
+ BLINK_ASSERT(inlineTextBox.role() == WebAXRoleInlineTextBox);
+ int start = end;
+ end += inlineTextBox.stringValue().length();
+ if (end <= characterIndex)
+ continue;
+ WebRect inlineTextBoxRect = inlineTextBox.boundingBoxRect();
+ int localIndex = characterIndex - start;
+ WebVector<int> characterOffsets;
+ inlineTextBox.characterOffsets(characterOffsets);
+ BLINK_ASSERT(characterOffsets.size() > 0 && characterOffsets.size() == inlineTextBox.stringValue().length());
+ switch (inlineTextBox.textDirection()) {
+ case WebAXTextDirectionLR: {
+ if (localIndex) {
+ int left = inlineTextBoxRect.x + characterOffsets[localIndex - 1];
+ int width = characterOffsets[localIndex] - characterOffsets[localIndex - 1];
+ return WebRect(left, inlineTextBoxRect.y, width, inlineTextBoxRect.height);
+ }
+ return WebRect(inlineTextBoxRect.x, inlineTextBoxRect.y, characterOffsets[0], inlineTextBoxRect.height);
+ }
+ case WebAXTextDirectionRL: {
+ int right = inlineTextBoxRect.x + inlineTextBoxRect.width;
+
+ if (localIndex) {
+ int left = right - characterOffsets[localIndex];
+ int width = characterOffsets[localIndex] - characterOffsets[localIndex - 1];
+ return WebRect(left, inlineTextBoxRect.y, width, inlineTextBoxRect.height);
+ }
+ int left = right - characterOffsets[0];
+ return WebRect(left, inlineTextBoxRect.y, characterOffsets[0], inlineTextBoxRect.height);
+ }
+ case WebAXTextDirectionTB: {
+ if (localIndex) {
+ int top = inlineTextBoxRect.y + characterOffsets[localIndex - 1];
+ int height = characterOffsets[localIndex] - characterOffsets[localIndex - 1];
+ return WebRect(inlineTextBoxRect.x, top, inlineTextBoxRect.width, height);
+ }
+ return WebRect(inlineTextBoxRect.x, inlineTextBoxRect.y, inlineTextBoxRect.width, characterOffsets[0]);
+ }
+ case WebAXTextDirectionBT: {
+ int bottom = inlineTextBoxRect.y + inlineTextBoxRect.height;
+
+ if (localIndex) {
+ int top = bottom - characterOffsets[localIndex];
+ int height = characterOffsets[localIndex] - characterOffsets[localIndex - 1];
+ return WebRect(inlineTextBoxRect.x, top, inlineTextBoxRect.width, height);
+ }
+ int top = bottom - characterOffsets[0];
+ return WebRect(inlineTextBoxRect.x, top, inlineTextBoxRect.width, characterOffsets[0]);
+ }
+ }
+ }
+
+ BLINK_ASSERT(false);
+ return WebRect();
+}
+
+void getBoundariesForOneWord(const WebAXObject& object, int characterIndex, int& wordStart, int& wordEnd)
+{
+ int end = 0;
+ for (unsigned i = 0; i < object.childCount(); i++) {
+ WebAXObject inlineTextBox = object.childAt(i);
+ BLINK_ASSERT(inlineTextBox.role() == WebAXRoleInlineTextBox);
+ int start = end;
+ end += inlineTextBox.stringValue().length();
+ if (end <= characterIndex)
+ continue;
+ int localIndex = characterIndex - start;
+
+ WebVector<int> starts;
+ WebVector<int> ends;
+ inlineTextBox.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,
@@ -459,6 +563,8 @@ WebAXObjectProxy::WebAXObjectProxy(const WebAXObject& object, Factory* factory)
bindMethod("scrollToMakeVisible", &WebAXObjectProxy::scrollToMakeVisibleCallback);
bindMethod("scrollToMakeVisibleWithSubFocus", &WebAXObjectProxy::scrollToMakeVisibleWithSubFocusCallback);
bindMethod("scrollToGlobalPoint", &WebAXObjectProxy::scrollToGlobalPointCallback);
+ bindMethod("wordStart", &WebAXObjectProxy::wordStartCallback);
+ bindMethod("wordEnd", &WebAXObjectProxy::wordEndCallback);
bindFallbackMethod(&WebAXObjectProxy::fallbackCallback);
}
@@ -748,9 +854,36 @@ void WebAXObjectProxy::lineForIndexCallback(const CppArgumentList& arguments, Cp
result->set(line);
}
-void WebAXObjectProxy::boundsForRangeCallback(const CppArgumentList&, CppVariant* result)
+void WebAXObjectProxy::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 WebAXObjectProxy::stringForRangeCallback(const CppArgumentList&, CppVariant* result)
@@ -1036,6 +1169,38 @@ void WebAXObjectProxy::scrollToGlobalPointCallback(const CppArgumentList& argume
result->setNull();
}
+void WebAXObjectProxy::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;
+ getBoundariesForOneWord(accessibilityObject(), characterIndex, wordStart, wordEnd);
+ result->set(wordStart);
+}
+
+void WebAXObjectProxy::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;
+ getBoundariesForOneWord(accessibilityObject(), characterIndex, wordStart, wordEnd);
+ result->set(wordEnd);
+}
+
void WebAXObjectProxy::fallbackCallback(const CppArgumentList &, CppVariant* result)
{
// FIXME: Implement this.
« no previous file with comments | « Source/testing/runner/WebAXObjectProxy.h ('k') | Source/web/AssertMatchingEnums.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698