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

Side by Side 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 review feedback Created 7 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 Google 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 are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * 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 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 case WebAXRoleIgnored: 125 case WebAXRoleIgnored:
126 return result.append("Ignored"); 126 return result.append("Ignored");
127 case WebAXRoleImageMapLink: 127 case WebAXRoleImageMapLink:
128 return result.append("ImageMapLink"); 128 return result.append("ImageMapLink");
129 case WebAXRoleImageMap: 129 case WebAXRoleImageMap:
130 return result.append("ImageMap"); 130 return result.append("ImageMap");
131 case WebAXRoleImage: 131 case WebAXRoleImage:
132 return result.append("Image"); 132 return result.append("Image");
133 case WebAXRoleIncrementor: 133 case WebAXRoleIncrementor:
134 return result.append("Incrementor"); 134 return result.append("Incrementor");
135 case WebAXRoleInlineTextBox:
136 return result.append("InlineTextBox");
135 case WebAXRoleLabel: 137 case WebAXRoleLabel:
136 return result.append("Label"); 138 return result.append("Label");
137 case WebAXRoleLegend: 139 case WebAXRoleLegend:
138 return result.append("Legend"); 140 return result.append("Legend");
139 case WebAXRoleLink: 141 case WebAXRoleLink:
140 return result.append("Link"); 142 return result.append("Link");
141 case WebAXRoleListBoxOption: 143 case WebAXRoleListBoxOption:
142 return result.append("ListBoxOption"); 144 return result.append("ListBoxOption");
143 case WebAXRoleListBox: 145 case WebAXRoleListBox:
144 return result.append("ListBox"); 146 return result.append("ListBox");
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 { 340 {
339 // FIXME: Concatenate all attributes of the AccessibilityObject. 341 // FIXME: Concatenate all attributes of the AccessibilityObject.
340 string attributes(getTitle(object)); 342 string attributes(getTitle(object));
341 attributes.append("\n"); 343 attributes.append("\n");
342 attributes.append(getRole(object)); 344 attributes.append(getRole(object));
343 attributes.append("\n"); 345 attributes.append("\n");
344 attributes.append(getDescription(object)); 346 attributes.append(getDescription(object));
345 return attributes; 347 return attributes;
346 } 348 }
347 349
350 WebRect boundsForCharacter(const WebAccessibilityObject& object, int characterIn dex)
351 {
352 WEBKIT_ASSERT(object.role() == WebAXRoleStaticText);
353 int end = 0;
354 for (unsigned i = 0; i < object.childCount(); i++) {
355 WebAccessibilityObject child = object.childAt(i);
356 WEBKIT_ASSERT(child.role() == WebAXRoleInlineTextBox);
357 int start = end;
358 end += child.stringValue().length();
359 if (end <= characterIndex)
360 continue;
361 WebRect childRect = child.boundingBoxRect();
362 int localIndex = characterIndex - start;
363 WebVector<int> characterOffsets;
364 child.characterOffsets(characterOffsets);
365 WEBKIT_ASSERT(characterOffsets.size() > 0 && characterOffsets.size() == child.stringValue().length());
366 if (characterOffsets[characterOffsets.size() - 1] < 0) {
367 // RTL.
368 int right = childRect.x + childRect.width;
369
370 if (localIndex) {
371 int left = right + characterOffsets[localIndex];
372 int width = characterOffsets[localIndex - 1] - characterOffsets[ localIndex];
373 return WebRect(left, childRect.y, width, childRect.height);
374 }
375 int left = right + characterOffsets[0];
376 return WebRect(left, childRect.y, -characterOffsets[0], childRect.he ight);
377 }
378
379 if (localIndex) {
380 int left = childRect.x + characterOffsets[localIndex - 1];
381 int width = characterOffsets[localIndex] - characterOffsets[localInd ex - 1];
382 return WebRect(left, childRect.y, width, childRect.height);
383 }
384 return WebRect(childRect.x, childRect.y, characterOffsets[0], childRect. height);
385 }
386
387 WEBKIT_ASSERT(false);
388 return WebRect();
389 }
390
391 void getWordBoundaries(const WebAccessibilityObject& object, int characterIndex, int& wordStart, int& wordEnd)
392 {
393 int end = 0;
394 for (unsigned i = 0; i < object.childCount(); i++) {
395 WebAccessibilityObject child = object.childAt(i);
396 WEBKIT_ASSERT(child.role() == WebAXRoleInlineTextBox);
397 int start = end;
398 end += child.stringValue().length();
399 if (end <= characterIndex)
400 continue;
401 int localIndex = characterIndex - start;
402
403 WebVector<int> starts;
404 WebVector<int> ends;
405 child.wordBoundaries(starts, ends);
406 size_t wordCount = starts.size();
407 WEBKIT_ASSERT(ends.size() == wordCount);
408
409 // If there are no words, use the InlineTextBox boundaries.
410 if (!wordCount) {
411 wordStart = start;
412 wordEnd = end;
413 return;
414 }
415
416 // Look for a character within any word other than the last.
417 for (size_t j = 0; j < wordCount - 1; j++) {
418 if (localIndex <= ends[j]) {
419 wordStart = start + starts[j];
420 wordEnd = start + ends[j];
421 return;
422 }
423 }
424
425 // Return the last word by default.
426 wordStart = start + starts[wordCount - 1];
427 wordEnd = start + ends[wordCount - 1];
428 return;
429 }
430 }
348 431
349 // Collects attributes into a string, delimited by dashes. Used by all methods 432 // Collects attributes into a string, delimited by dashes. Used by all methods
350 // that output lists of attributes: attributesOfLinkedUIElementsCallback, 433 // that output lists of attributes: attributesOfLinkedUIElementsCallback,
351 // AttributesOfChildrenCallback, etc. 434 // AttributesOfChildrenCallback, etc.
352 class AttributesCollector { 435 class AttributesCollector {
353 public: 436 public:
354 void collectAttributes(const WebAccessibilityObject& object) 437 void collectAttributes(const WebAccessibilityObject& object)
355 { 438 {
356 m_attributes.append("\n------------\n"); 439 m_attributes.append("\n------------\n");
357 m_attributes.append(getAttributes(object)); 440 m_attributes.append(getAttributes(object));
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 bindMethod("decrement", &AccessibilityUIElement::decrementCallback); 534 bindMethod("decrement", &AccessibilityUIElement::decrementCallback);
452 bindMethod("showMenu", &AccessibilityUIElement::showMenuCallback); 535 bindMethod("showMenu", &AccessibilityUIElement::showMenuCallback);
453 bindMethod("press", &AccessibilityUIElement::pressCallback); 536 bindMethod("press", &AccessibilityUIElement::pressCallback);
454 bindMethod("isEqual", &AccessibilityUIElement::isEqualCallback); 537 bindMethod("isEqual", &AccessibilityUIElement::isEqualCallback);
455 bindMethod("addNotificationListener", &AccessibilityUIElement::addNotificati onListenerCallback); 538 bindMethod("addNotificationListener", &AccessibilityUIElement::addNotificati onListenerCallback);
456 bindMethod("removeNotificationListener", &AccessibilityUIElement::removeNoti ficationListenerCallback); 539 bindMethod("removeNotificationListener", &AccessibilityUIElement::removeNoti ficationListenerCallback);
457 bindMethod("takeFocus", &AccessibilityUIElement::takeFocusCallback); 540 bindMethod("takeFocus", &AccessibilityUIElement::takeFocusCallback);
458 bindMethod("scrollToMakeVisible", &AccessibilityUIElement::scrollToMakeVisib leCallback); 541 bindMethod("scrollToMakeVisible", &AccessibilityUIElement::scrollToMakeVisib leCallback);
459 bindMethod("scrollToMakeVisibleWithSubFocus", &AccessibilityUIElement::scrol lToMakeVisibleWithSubFocusCallback); 542 bindMethod("scrollToMakeVisibleWithSubFocus", &AccessibilityUIElement::scrol lToMakeVisibleWithSubFocusCallback);
460 bindMethod("scrollToGlobalPoint", &AccessibilityUIElement::scrollToGlobalPoi ntCallback); 543 bindMethod("scrollToGlobalPoint", &AccessibilityUIElement::scrollToGlobalPoi ntCallback);
544 bindMethod("wordStart", &AccessibilityUIElement::wordStartCallback);
545 bindMethod("wordEnd", &AccessibilityUIElement::wordEndCallback);
461 546
462 bindFallbackMethod(&AccessibilityUIElement::fallbackCallback); 547 bindFallbackMethod(&AccessibilityUIElement::fallbackCallback);
463 } 548 }
464 549
465 AccessibilityUIElement* AccessibilityUIElement::getChildAtIndex(unsigned index) 550 AccessibilityUIElement* AccessibilityUIElement::getChildAtIndex(unsigned index)
466 { 551 {
467 return m_factory->getOrCreate(accessibilityObject().childAt(index)); 552 return m_factory->getOrCreate(accessibilityObject().childAt(index));
468 } 553 }
469 554
470 bool AccessibilityUIElement::isEqual(const WebKit::WebAccessibilityObject& other ) 555 bool AccessibilityUIElement::isEqual(const WebKit::WebAccessibilityObject& other )
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 825
741 WebVector<int> lineBreaks; 826 WebVector<int> lineBreaks;
742 accessibilityObject().lineBreaks(lineBreaks); 827 accessibilityObject().lineBreaks(lineBreaks);
743 int line = 0; 828 int line = 0;
744 int vectorSize = static_cast<int>(lineBreaks.size()); 829 int vectorSize = static_cast<int>(lineBreaks.size());
745 while (line < vectorSize && lineBreaks[line] <= index) 830 while (line < vectorSize && lineBreaks[line] <= index)
746 line++; 831 line++;
747 result->set(line); 832 result->set(line);
748 } 833 }
749 834
750 void AccessibilityUIElement::boundsForRangeCallback(const CppArgumentList&, CppV ariant* result) 835 void AccessibilityUIElement::boundsForRangeCallback(const CppArgumentList& argum ents, CppVariant* result)
751 { 836 {
752 result->setNull(); 837 result->setNull();
838
839 if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNum ber())
840 return;
841
842 if (accessibilityObject().role() != WebAXRoleStaticText)
843 return;
844
845 int start = arguments[0].toInt32();
846 int end = arguments[1].toInt32();
847 int len = end - start;
848
849 // Get the bounds for each character and union them into one large rectangle .
850 // This is just for testing so it doesn't need to be efficient.
851 WebRect bounds = boundsForCharacter(accessibilityObject(), start);
852 for (int i = 1; i < len; i++) {
853 WebRect next = boundsForCharacter(accessibilityObject(), start + i);
854 int right = std::max(bounds.x + bounds.width, next.x + next.width);
855 int bottom = std::max(bounds.y + bounds.height, next.y + next.height);
856 bounds.x = std::min(bounds.x, next.x);
857 bounds.y = std::min(bounds.y, next.y);
858 bounds.width = right - bounds.x;
859 bounds.height = bottom - bounds.y;
860 }
861
862 char buffer[100];
863 snprintf(buffer, sizeof(buffer), "{x: %d, y: %d, width: %d, height: %d}", bo unds.x, bounds.y, bounds.width, bounds.height);
864 result->set(string(buffer));
753 } 865 }
754 866
755 void AccessibilityUIElement::stringForRangeCallback(const CppArgumentList&, CppV ariant* result) 867 void AccessibilityUIElement::stringForRangeCallback(const CppArgumentList&, CppV ariant* result)
756 { 868 {
757 result->setNull(); 869 result->setNull();
758 } 870 }
759 871
760 void AccessibilityUIElement::childAtIndexCallback(const CppArgumentList& argumen ts, CppVariant* result) 872 void AccessibilityUIElement::childAtIndexCallback(const CppArgumentList& argumen ts, CppVariant* result)
761 { 873 {
762 if (!arguments.size() || !arguments[0].isNumber()) { 874 if (!arguments.size() || !arguments[0].isNumber()) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 || !arguments[1].isNumber()) 1140 || !arguments[1].isNumber())
1029 return; 1141 return;
1030 1142
1031 int x = arguments[0].toInt32(); 1143 int x = arguments[0].toInt32();
1032 int y = arguments[1].toInt32(); 1144 int y = arguments[1].toInt32();
1033 1145
1034 accessibilityObject().scrollToGlobalPoint(WebPoint(x, y)); 1146 accessibilityObject().scrollToGlobalPoint(WebPoint(x, y));
1035 result->setNull(); 1147 result->setNull();
1036 } 1148 }
1037 1149
1150 void AccessibilityUIElement::wordStartCallback(const CppArgumentList& arguments, CppVariant* result)
1151 {
1152 result->setNull();
1153
1154 if (arguments.size() != 1 || !arguments[0].isNumber())
1155 return;
1156
1157 if (accessibilityObject().role() != WebAXRoleStaticText)
1158 return;
1159
1160 int characterIndex = arguments[0].toInt32();
1161 int wordStart, wordEnd;
1162 getWordBoundaries(accessibilityObject(), characterIndex, wordStart, wordEnd) ;
1163 result->set(wordStart);
1164 }
1165
1166 void AccessibilityUIElement::wordEndCallback(const CppArgumentList& arguments, C ppVariant* result)
1167 {
1168 result->setNull();
1169
1170 if (arguments.size() != 1 || !arguments[0].isNumber())
1171 return;
1172
1173 if (accessibilityObject().role() != WebAXRoleStaticText)
1174 return;
1175
1176 int characterIndex = arguments[0].toInt32();
1177 int wordStart, wordEnd;
1178 getWordBoundaries(accessibilityObject(), characterIndex, wordStart, wordEnd) ;
1179 result->set(wordEnd);
1180 }
1181
1038 void AccessibilityUIElement::fallbackCallback(const CppArgumentList &, CppVarian t* result) 1182 void AccessibilityUIElement::fallbackCallback(const CppArgumentList &, CppVarian t* result)
1039 { 1183 {
1040 // FIXME: Implement this. 1184 // FIXME: Implement this.
1041 result->setNull(); 1185 result->setNull();
1042 } 1186 }
1043 1187
1044 RootAccessibilityUIElement::RootAccessibilityUIElement(const WebAccessibilityObj ect &object, Factory *factory) 1188 RootAccessibilityUIElement::RootAccessibilityUIElement(const WebAccessibilityObj ect &object, Factory *factory)
1045 : AccessibilityUIElement(object, factory) { } 1189 : AccessibilityUIElement(object, factory) { }
1046 1190
1047 AccessibilityUIElement* RootAccessibilityUIElement::getChildAtIndex(unsigned ind ex) 1191 AccessibilityUIElement* RootAccessibilityUIElement::getChildAtIndex(unsigned ind ex)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 } 1226 }
1083 1227
1084 AccessibilityUIElement* AccessibilityUIElementList::createRoot(const WebAccessib ilityObject& object) 1228 AccessibilityUIElement* AccessibilityUIElementList::createRoot(const WebAccessib ilityObject& object)
1085 { 1229 {
1086 AccessibilityUIElement* element = new RootAccessibilityUIElement(object, thi s); 1230 AccessibilityUIElement* element = new RootAccessibilityUIElement(object, thi s);
1087 m_elements.push_back(element); 1231 m_elements.push_back(element);
1088 return element; 1232 return element;
1089 } 1233 }
1090 1234
1091 } 1235 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698