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

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: Remove platform differences from inline-text-textarea output 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 index = characterIndex - start;
363 WebVector<int> characterOffsets;
364 child.characterOffsets(characterOffsets);
365 WEBKIT_ASSERT(characterOffsets.size() > 0 && characterOffsets.size() == child.stringValue().length());
aboxhall 2013/09/06 17:19:21 Is checking characterOffsets.size() > 0 redundant?
dmazzoni 2013/09/06 20:25:27 I want to assert that they're both not zero. It'd
366 if (characterOffsets[characterOffsets.size() - 1] < 0) {
aboxhall 2013/09/06 17:19:21 Why last offset rather than first?
dmazzoni 2013/09/06 20:25:27 I was worried about a corner case where the first
367 // RTL.
368 int right = childRect.x + childRect.width;
369
370 if (index)
371 return WebRect(right + characterOffsets[index], childRect.y, cha racterOffsets[index - 1] - characterOffsets[index], childRect.height);
aboxhall 2013/09/06 17:19:21 This is breaking my brain... would it be a problem
aboxhall 2013/09/06 20:51:12 Ping? No worries if this isn't worth the effort fo
dmazzoni 2013/09/09 07:03:14 Sorry, meant to do this. Done - I like your idea,
372 return WebRect(right + characterOffsets[0], childRect.y, -characterO ffsets[0], childRect.height);
373 }
374
375 if (index)
376 return WebRect(childRect.x + characterOffsets[index - 1], childRect. y, characterOffsets[index] - characterOffsets[index - 1], childRect.height);
377 return WebRect(childRect.x, childRect.y, characterOffsets[0], childRect. height);
378 }
379
380 WEBKIT_ASSERT(false);
381 return WebRect();
382 }
383
384 void getWordBoundaries(const WebAccessibilityObject& object, int characterIndex, int& wordStart, int& wordEnd)
385 {
386 int end = 0;
387 for (unsigned i = 0; i < object.childCount(); i++) {
388 WebAccessibilityObject child = object.childAt(i);
389 WEBKIT_ASSERT(child.role() == WebAXRoleInlineTextBox);
390 int start = end;
391 end += child.stringValue().length();
392 if (end <= characterIndex)
393 continue;
394 int index = characterIndex - start;
395
396 WebVector<int> starts;
397 WebVector<int> ends;
398 child.wordBoundaries(starts, ends);
399 size_t wordCount = starts.size();
400 WEBKIT_ASSERT(ends.size() == wordCount);
401
402 // If there are no words, use the InlineTextBox boundaries.
aboxhall 2013/09/06 17:19:21 Why would there be no words?
dmazzoni 2013/09/06 20:25:27 An inline text box could have just whitespace, for
403 if (!wordCount) {
404 wordStart = start;
405 wordEnd = end;
406 return;
407 }
408
409 // Look for a character within any word other than the last.
aboxhall 2013/09/06 17:19:21 Why not the last?
dmazzoni 2013/09/06 20:25:27 Only because that case is handled below - any char
410 for (size_t j = 0; j < wordCount - 1; j++) {
411 if (characterIndex <= ends[j]) {
aboxhall 2013/09/06 17:19:21 Should this be index?
dmazzoni 2013/09/06 20:25:27 You're totally right. Fixed. I renamed it inlineB
aboxhall 2013/09/06 20:51:12 I'm curious why this wasn't caught by the layout t
dmazzoni 2013/09/09 07:03:14 Totally fair point. It wasn't caught because I did
412 wordStart = start + starts[j];
413 wordEnd = start + ends[j];
414 return;
415 }
416 }
417
418 // Return the last word by default.
419 wordStart = start + starts[wordCount - 1];
420 wordEnd = start + ends[wordCount - 1];
421 return;
422 }
423 }
348 424
349 // Collects attributes into a string, delimited by dashes. Used by all methods 425 // Collects attributes into a string, delimited by dashes. Used by all methods
350 // that output lists of attributes: attributesOfLinkedUIElementsCallback, 426 // that output lists of attributes: attributesOfLinkedUIElementsCallback,
351 // AttributesOfChildrenCallback, etc. 427 // AttributesOfChildrenCallback, etc.
352 class AttributesCollector { 428 class AttributesCollector {
353 public: 429 public:
354 void collectAttributes(const WebAccessibilityObject& object) 430 void collectAttributes(const WebAccessibilityObject& object)
355 { 431 {
356 m_attributes.append("\n------------\n"); 432 m_attributes.append("\n------------\n");
357 m_attributes.append(getAttributes(object)); 433 m_attributes.append(getAttributes(object));
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 bindMethod("decrement", &AccessibilityUIElement::decrementCallback); 527 bindMethod("decrement", &AccessibilityUIElement::decrementCallback);
452 bindMethod("showMenu", &AccessibilityUIElement::showMenuCallback); 528 bindMethod("showMenu", &AccessibilityUIElement::showMenuCallback);
453 bindMethod("press", &AccessibilityUIElement::pressCallback); 529 bindMethod("press", &AccessibilityUIElement::pressCallback);
454 bindMethod("isEqual", &AccessibilityUIElement::isEqualCallback); 530 bindMethod("isEqual", &AccessibilityUIElement::isEqualCallback);
455 bindMethod("addNotificationListener", &AccessibilityUIElement::addNotificati onListenerCallback); 531 bindMethod("addNotificationListener", &AccessibilityUIElement::addNotificati onListenerCallback);
456 bindMethod("removeNotificationListener", &AccessibilityUIElement::removeNoti ficationListenerCallback); 532 bindMethod("removeNotificationListener", &AccessibilityUIElement::removeNoti ficationListenerCallback);
457 bindMethod("takeFocus", &AccessibilityUIElement::takeFocusCallback); 533 bindMethod("takeFocus", &AccessibilityUIElement::takeFocusCallback);
458 bindMethod("scrollToMakeVisible", &AccessibilityUIElement::scrollToMakeVisib leCallback); 534 bindMethod("scrollToMakeVisible", &AccessibilityUIElement::scrollToMakeVisib leCallback);
459 bindMethod("scrollToMakeVisibleWithSubFocus", &AccessibilityUIElement::scrol lToMakeVisibleWithSubFocusCallback); 535 bindMethod("scrollToMakeVisibleWithSubFocus", &AccessibilityUIElement::scrol lToMakeVisibleWithSubFocusCallback);
460 bindMethod("scrollToGlobalPoint", &AccessibilityUIElement::scrollToGlobalPoi ntCallback); 536 bindMethod("scrollToGlobalPoint", &AccessibilityUIElement::scrollToGlobalPoi ntCallback);
537 bindMethod("wordStart", &AccessibilityUIElement::wordStartCallback);
538 bindMethod("wordEnd", &AccessibilityUIElement::wordEndCallback);
461 539
462 bindFallbackMethod(&AccessibilityUIElement::fallbackCallback); 540 bindFallbackMethod(&AccessibilityUIElement::fallbackCallback);
463 } 541 }
464 542
465 AccessibilityUIElement* AccessibilityUIElement::getChildAtIndex(unsigned index) 543 AccessibilityUIElement* AccessibilityUIElement::getChildAtIndex(unsigned index)
466 { 544 {
467 return m_factory->getOrCreate(accessibilityObject().childAt(index)); 545 return m_factory->getOrCreate(accessibilityObject().childAt(index));
468 } 546 }
469 547
470 bool AccessibilityUIElement::isEqual(const WebKit::WebAccessibilityObject& other ) 548 bool AccessibilityUIElement::isEqual(const WebKit::WebAccessibilityObject& other )
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 818
741 WebVector<int> lineBreaks; 819 WebVector<int> lineBreaks;
742 accessibilityObject().lineBreaks(lineBreaks); 820 accessibilityObject().lineBreaks(lineBreaks);
743 int line = 0; 821 int line = 0;
744 int vectorSize = static_cast<int>(lineBreaks.size()); 822 int vectorSize = static_cast<int>(lineBreaks.size());
745 while (line < vectorSize && lineBreaks[line] <= index) 823 while (line < vectorSize && lineBreaks[line] <= index)
746 line++; 824 line++;
747 result->set(line); 825 result->set(line);
748 } 826 }
749 827
750 void AccessibilityUIElement::boundsForRangeCallback(const CppArgumentList&, CppV ariant* result) 828 void AccessibilityUIElement::boundsForRangeCallback(const CppArgumentList& argum ents, CppVariant* result)
751 { 829 {
752 result->setNull(); 830 result->setNull();
831
832 if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNum ber())
833 return;
834
835 if (accessibilityObject().role() != WebAXRoleStaticText)
836 return;
837
838 int start = arguments[0].toInt32();
839 int end = arguments[1].toInt32();
840 int len = end - start;
841
842 // Get the bounds for each character and union them into one large rectangle .
843 // This is just for testing so it doesn't need to be efficient.
844 WebRect bounds = boundsForCharacter(accessibilityObject(), start);
845 for (int i = 1; i < len; i++) {
846 WebRect next = boundsForCharacter(accessibilityObject(), start + i);
847 int right = std::max(bounds.x + bounds.width, next.x + next.width);
848 int bottom = std::max(bounds.y + bounds.height, next.y + next.height);
849 bounds.x = std::min(bounds.x, next.x);
850 bounds.y = std::min(bounds.y, next.y);
851 bounds.width = right - bounds.x;
852 bounds.height = bottom - bounds.y;
853 }
854
855 char buffer[100];
856 snprintf(buffer, sizeof(buffer), "{x: %d, y: %d, width: %d, height: %d}", bo unds.x, bounds.y, bounds.width, bounds.height);
857 result->set(string(buffer));
753 } 858 }
754 859
755 void AccessibilityUIElement::stringForRangeCallback(const CppArgumentList&, CppV ariant* result) 860 void AccessibilityUIElement::stringForRangeCallback(const CppArgumentList&, CppV ariant* result)
756 { 861 {
757 result->setNull(); 862 result->setNull();
758 } 863 }
759 864
760 void AccessibilityUIElement::childAtIndexCallback(const CppArgumentList& argumen ts, CppVariant* result) 865 void AccessibilityUIElement::childAtIndexCallback(const CppArgumentList& argumen ts, CppVariant* result)
761 { 866 {
762 if (!arguments.size() || !arguments[0].isNumber()) { 867 if (!arguments.size() || !arguments[0].isNumber()) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 || !arguments[1].isNumber()) 1133 || !arguments[1].isNumber())
1029 return; 1134 return;
1030 1135
1031 int x = arguments[0].toInt32(); 1136 int x = arguments[0].toInt32();
1032 int y = arguments[1].toInt32(); 1137 int y = arguments[1].toInt32();
1033 1138
1034 accessibilityObject().scrollToGlobalPoint(WebPoint(x, y)); 1139 accessibilityObject().scrollToGlobalPoint(WebPoint(x, y));
1035 result->setNull(); 1140 result->setNull();
1036 } 1141 }
1037 1142
1143 void AccessibilityUIElement::wordStartCallback(const CppArgumentList& arguments, CppVariant* result)
aboxhall 2013/09/06 17:19:21 Are we likely to mostly be calling this and wordEn
dmazzoni 2013/09/06 20:25:27 This code is only for enabling layout tests, so th
aboxhall 2013/09/06 20:51:12 Makes sense.
1144 {
1145 result->setNull();
1146
1147 if (arguments.size() != 1 || !arguments[0].isNumber())
1148 return;
1149
1150 if (accessibilityObject().role() != WebAXRoleStaticText)
1151 return;
1152
1153 int characterIndex = arguments[0].toInt32();
1154 int wordStart, wordEnd;
1155 getWordBoundaries(accessibilityObject(), characterIndex, wordStart, wordEnd) ;
1156 result->set(wordStart);
1157 }
1158
1159 void AccessibilityUIElement::wordEndCallback(const CppArgumentList& arguments, C ppVariant* result)
1160 {
1161 result->setNull();
1162
1163 if (arguments.size() != 1 || !arguments[0].isNumber())
1164 return;
1165
1166 if (accessibilityObject().role() != WebAXRoleStaticText)
1167 return;
1168
1169 int characterIndex = arguments[0].toInt32();
1170 int wordStart, wordEnd;
1171 getWordBoundaries(accessibilityObject(), characterIndex, wordStart, wordEnd) ;
1172 result->set(wordEnd);
1173 }
1174
1038 void AccessibilityUIElement::fallbackCallback(const CppArgumentList &, CppVarian t* result) 1175 void AccessibilityUIElement::fallbackCallback(const CppArgumentList &, CppVarian t* result)
1039 { 1176 {
1040 // FIXME: Implement this. 1177 // FIXME: Implement this.
1041 result->setNull(); 1178 result->setNull();
1042 } 1179 }
1043 1180
1044 RootAccessibilityUIElement::RootAccessibilityUIElement(const WebAccessibilityObj ect &object, Factory *factory) 1181 RootAccessibilityUIElement::RootAccessibilityUIElement(const WebAccessibilityObj ect &object, Factory *factory)
1045 : AccessibilityUIElement(object, factory) { } 1182 : AccessibilityUIElement(object, factory) { }
1046 1183
1047 AccessibilityUIElement* RootAccessibilityUIElement::getChildAtIndex(unsigned ind ex) 1184 AccessibilityUIElement* RootAccessibilityUIElement::getChildAtIndex(unsigned ind ex)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 } 1219 }
1083 1220
1084 AccessibilityUIElement* AccessibilityUIElementList::createRoot(const WebAccessib ilityObject& object) 1221 AccessibilityUIElement* AccessibilityUIElementList::createRoot(const WebAccessib ilityObject& object)
1085 { 1222 {
1086 AccessibilityUIElement* element = new RootAccessibilityUIElement(object, thi s); 1223 AccessibilityUIElement* element = new RootAccessibilityUIElement(object, thi s);
1087 m_elements.push_back(element); 1224 m_elements.push_back(element);
1088 return element; 1225 return element;
1089 } 1226 }
1090 1227
1091 } 1228 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698