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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/testing/runner/WebAXObjectProxy.h ('k') | Source/web/AssertMatchingEnums.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 { 341 {
340 // FIXME: Concatenate all attributes of the AXObject. 342 // FIXME: Concatenate all attributes of the AXObject.
341 string attributes(getTitle(object)); 343 string attributes(getTitle(object));
342 attributes.append("\n"); 344 attributes.append("\n");
343 attributes.append(getRole(object)); 345 attributes.append(getRole(object));
344 attributes.append("\n"); 346 attributes.append("\n");
345 attributes.append(getDescription(object)); 347 attributes.append(getDescription(object));
346 return attributes; 348 return attributes;
347 } 349 }
348 350
351 WebRect boundsForCharacter(const WebAXObject& object, int characterIndex)
352 {
353 BLINK_ASSERT(object.role() == WebAXRoleStaticText);
354 int end = 0;
355 for (unsigned i = 0; i < object.childCount(); i++) {
356 WebAXObject inlineTextBox = object.childAt(i);
357 BLINK_ASSERT(inlineTextBox.role() == WebAXRoleInlineTextBox);
358 int start = end;
359 end += inlineTextBox.stringValue().length();
360 if (end <= characterIndex)
361 continue;
362 WebRect inlineTextBoxRect = inlineTextBox.boundingBoxRect();
363 int localIndex = characterIndex - start;
364 WebVector<int> characterOffsets;
365 inlineTextBox.characterOffsets(characterOffsets);
366 BLINK_ASSERT(characterOffsets.size() > 0 && characterOffsets.size() == i nlineTextBox.stringValue().length());
367 switch (inlineTextBox.textDirection()) {
368 case WebAXTextDirectionLR: {
369 if (localIndex) {
370 int left = inlineTextBoxRect.x + characterOffsets[localIndex - 1 ];
371 int width = characterOffsets[localIndex] - characterOffsets[loca lIndex - 1];
372 return WebRect(left, inlineTextBoxRect.y, width, inlineTextBoxRe ct.height);
373 }
374 return WebRect(inlineTextBoxRect.x, inlineTextBoxRect.y, characterOf fsets[0], inlineTextBoxRect.height);
375 }
376 case WebAXTextDirectionRL: {
377 int right = inlineTextBoxRect.x + inlineTextBoxRect.width;
378
379 if (localIndex) {
380 int left = right - characterOffsets[localIndex];
381 int width = characterOffsets[localIndex] - characterOffsets[loca lIndex - 1];
382 return WebRect(left, inlineTextBoxRect.y, width, inlineTextBoxRe ct.height);
383 }
384 int left = right - characterOffsets[0];
385 return WebRect(left, inlineTextBoxRect.y, characterOffsets[0], inlin eTextBoxRect.height);
386 }
387 case WebAXTextDirectionTB: {
388 if (localIndex) {
389 int top = inlineTextBoxRect.y + characterOffsets[localIndex - 1] ;
390 int height = characterOffsets[localIndex] - characterOffsets[loc alIndex - 1];
391 return WebRect(inlineTextBoxRect.x, top, inlineTextBoxRect.width , height);
392 }
393 return WebRect(inlineTextBoxRect.x, inlineTextBoxRect.y, inlineTextB oxRect.width, characterOffsets[0]);
394 }
395 case WebAXTextDirectionBT: {
396 int bottom = inlineTextBoxRect.y + inlineTextBoxRect.height;
397
398 if (localIndex) {
399 int top = bottom - characterOffsets[localIndex];
400 int height = characterOffsets[localIndex] - characterOffsets[loc alIndex - 1];
401 return WebRect(inlineTextBoxRect.x, top, inlineTextBoxRect.width , height);
402 }
403 int top = bottom - characterOffsets[0];
404 return WebRect(inlineTextBoxRect.x, top, inlineTextBoxRect.width, ch aracterOffsets[0]);
405 }
406 }
407 }
408
409 BLINK_ASSERT(false);
410 return WebRect();
411 }
412
413 void getBoundariesForOneWord(const WebAXObject& object, int characterIndex, int& wordStart, int& wordEnd)
414 {
415 int end = 0;
416 for (unsigned i = 0; i < object.childCount(); i++) {
417 WebAXObject inlineTextBox = object.childAt(i);
418 BLINK_ASSERT(inlineTextBox.role() == WebAXRoleInlineTextBox);
419 int start = end;
420 end += inlineTextBox.stringValue().length();
421 if (end <= characterIndex)
422 continue;
423 int localIndex = characterIndex - start;
424
425 WebVector<int> starts;
426 WebVector<int> ends;
427 inlineTextBox.wordBoundaries(starts, ends);
428 size_t wordCount = starts.size();
429 BLINK_ASSERT(ends.size() == wordCount);
430
431 // If there are no words, use the InlineTextBox boundaries.
432 if (!wordCount) {
433 wordStart = start;
434 wordEnd = end;
435 return;
436 }
437
438 // Look for a character within any word other than the last.
439 for (size_t j = 0; j < wordCount - 1; j++) {
440 if (localIndex <= ends[j]) {
441 wordStart = start + starts[j];
442 wordEnd = start + ends[j];
443 return;
444 }
445 }
446
447 // Return the last word by default.
448 wordStart = start + starts[wordCount - 1];
449 wordEnd = start + ends[wordCount - 1];
450 return;
451 }
452 }
349 453
350 // Collects attributes into a string, delimited by dashes. Used by all methods 454 // Collects attributes into a string, delimited by dashes. Used by all methods
351 // that output lists of attributes: attributesOfLinkedUIElementsCallback, 455 // that output lists of attributes: attributesOfLinkedUIElementsCallback,
352 // AttributesOfChildrenCallback, etc. 456 // AttributesOfChildrenCallback, etc.
353 class AttributesCollector { 457 class AttributesCollector {
354 public: 458 public:
355 void collectAttributes(const WebAXObject& object) 459 void collectAttributes(const WebAXObject& object)
356 { 460 {
357 m_attributes.append("\n------------\n"); 461 m_attributes.append("\n------------\n");
358 m_attributes.append(getAttributes(object)); 462 m_attributes.append(getAttributes(object));
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 bindMethod("decrement", &WebAXObjectProxy::decrementCallback); 556 bindMethod("decrement", &WebAXObjectProxy::decrementCallback);
453 bindMethod("showMenu", &WebAXObjectProxy::showMenuCallback); 557 bindMethod("showMenu", &WebAXObjectProxy::showMenuCallback);
454 bindMethod("press", &WebAXObjectProxy::pressCallback); 558 bindMethod("press", &WebAXObjectProxy::pressCallback);
455 bindMethod("isEqual", &WebAXObjectProxy::isEqualCallback); 559 bindMethod("isEqual", &WebAXObjectProxy::isEqualCallback);
456 bindMethod("addNotificationListener", &WebAXObjectProxy::addNotificationList enerCallback); 560 bindMethod("addNotificationListener", &WebAXObjectProxy::addNotificationList enerCallback);
457 bindMethod("removeNotificationListener", &WebAXObjectProxy::removeNotificati onListenerCallback); 561 bindMethod("removeNotificationListener", &WebAXObjectProxy::removeNotificati onListenerCallback);
458 bindMethod("takeFocus", &WebAXObjectProxy::takeFocusCallback); 562 bindMethod("takeFocus", &WebAXObjectProxy::takeFocusCallback);
459 bindMethod("scrollToMakeVisible", &WebAXObjectProxy::scrollToMakeVisibleCall back); 563 bindMethod("scrollToMakeVisible", &WebAXObjectProxy::scrollToMakeVisibleCall back);
460 bindMethod("scrollToMakeVisibleWithSubFocus", &WebAXObjectProxy::scrollToMak eVisibleWithSubFocusCallback); 564 bindMethod("scrollToMakeVisibleWithSubFocus", &WebAXObjectProxy::scrollToMak eVisibleWithSubFocusCallback);
461 bindMethod("scrollToGlobalPoint", &WebAXObjectProxy::scrollToGlobalPointCall back); 565 bindMethod("scrollToGlobalPoint", &WebAXObjectProxy::scrollToGlobalPointCall back);
566 bindMethod("wordStart", &WebAXObjectProxy::wordStartCallback);
567 bindMethod("wordEnd", &WebAXObjectProxy::wordEndCallback);
462 568
463 bindFallbackMethod(&WebAXObjectProxy::fallbackCallback); 569 bindFallbackMethod(&WebAXObjectProxy::fallbackCallback);
464 } 570 }
465 571
466 WebAXObjectProxy* WebAXObjectProxy::getChildAtIndex(unsigned index) 572 WebAXObjectProxy* WebAXObjectProxy::getChildAtIndex(unsigned index)
467 { 573 {
468 return m_factory->getOrCreate(accessibilityObject().childAt(index)); 574 return m_factory->getOrCreate(accessibilityObject().childAt(index));
469 } 575 }
470 576
471 bool WebAXObjectProxy::isEqual(const WebKit::WebAXObject& other) 577 bool WebAXObjectProxy::isEqual(const WebKit::WebAXObject& other)
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 847
742 WebVector<int> lineBreaks; 848 WebVector<int> lineBreaks;
743 accessibilityObject().lineBreaks(lineBreaks); 849 accessibilityObject().lineBreaks(lineBreaks);
744 int line = 0; 850 int line = 0;
745 int vectorSize = static_cast<int>(lineBreaks.size()); 851 int vectorSize = static_cast<int>(lineBreaks.size());
746 while (line < vectorSize && lineBreaks[line] <= index) 852 while (line < vectorSize && lineBreaks[line] <= index)
747 line++; 853 line++;
748 result->set(line); 854 result->set(line);
749 } 855 }
750 856
751 void WebAXObjectProxy::boundsForRangeCallback(const CppArgumentList&, CppVariant * result) 857 void WebAXObjectProxy::boundsForRangeCallback(const CppArgumentList& arguments, CppVariant* result)
752 { 858 {
753 result->setNull(); 859 result->setNull();
860
861 if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNum ber())
862 return;
863
864 if (accessibilityObject().role() != WebAXRoleStaticText)
865 return;
866
867 int start = arguments[0].toInt32();
868 int end = arguments[1].toInt32();
869 int len = end - start;
870
871 // Get the bounds for each character and union them into one large rectangle .
872 // This is just for testing so it doesn't need to be efficient.
873 WebRect bounds = boundsForCharacter(accessibilityObject(), start);
874 for (int i = 1; i < len; i++) {
875 WebRect next = boundsForCharacter(accessibilityObject(), start + i);
876 int right = std::max(bounds.x + bounds.width, next.x + next.width);
877 int bottom = std::max(bounds.y + bounds.height, next.y + next.height);
878 bounds.x = std::min(bounds.x, next.x);
879 bounds.y = std::min(bounds.y, next.y);
880 bounds.width = right - bounds.x;
881 bounds.height = bottom - bounds.y;
882 }
883
884 char buffer[100];
885 snprintf(buffer, sizeof(buffer), "{x: %d, y: %d, width: %d, height: %d}", bo unds.x, bounds.y, bounds.width, bounds.height);
886 result->set(string(buffer));
754 } 887 }
755 888
756 void WebAXObjectProxy::stringForRangeCallback(const CppArgumentList&, CppVariant * result) 889 void WebAXObjectProxy::stringForRangeCallback(const CppArgumentList&, CppVariant * result)
757 { 890 {
758 result->setNull(); 891 result->setNull();
759 } 892 }
760 893
761 void WebAXObjectProxy::childAtIndexCallback(const CppArgumentList& arguments, Cp pVariant* result) 894 void WebAXObjectProxy::childAtIndexCallback(const CppArgumentList& arguments, Cp pVariant* result)
762 { 895 {
763 if (!arguments.size() || !arguments[0].isNumber()) { 896 if (!arguments.size() || !arguments[0].isNumber()) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 || !arguments[1].isNumber()) 1162 || !arguments[1].isNumber())
1030 return; 1163 return;
1031 1164
1032 int x = arguments[0].toInt32(); 1165 int x = arguments[0].toInt32();
1033 int y = arguments[1].toInt32(); 1166 int y = arguments[1].toInt32();
1034 1167
1035 accessibilityObject().scrollToGlobalPoint(WebPoint(x, y)); 1168 accessibilityObject().scrollToGlobalPoint(WebPoint(x, y));
1036 result->setNull(); 1169 result->setNull();
1037 } 1170 }
1038 1171
1172 void WebAXObjectProxy::wordStartCallback(const CppArgumentList& arguments, CppVa riant* result)
1173 {
1174 result->setNull();
1175
1176 if (arguments.size() != 1 || !arguments[0].isNumber())
1177 return;
1178
1179 if (accessibilityObject().role() != WebAXRoleStaticText)
1180 return;
1181
1182 int characterIndex = arguments[0].toInt32();
1183 int wordStart, wordEnd;
1184 getBoundariesForOneWord(accessibilityObject(), characterIndex, wordStart, wo rdEnd);
1185 result->set(wordStart);
1186 }
1187
1188 void WebAXObjectProxy::wordEndCallback(const CppArgumentList& arguments, CppVari ant* result)
1189 {
1190 result->setNull();
1191
1192 if (arguments.size() != 1 || !arguments[0].isNumber())
1193 return;
1194
1195 if (accessibilityObject().role() != WebAXRoleStaticText)
1196 return;
1197
1198 int characterIndex = arguments[0].toInt32();
1199 int wordStart, wordEnd;
1200 getBoundariesForOneWord(accessibilityObject(), characterIndex, wordStart, wo rdEnd);
1201 result->set(wordEnd);
1202 }
1203
1039 void WebAXObjectProxy::fallbackCallback(const CppArgumentList &, CppVariant* res ult) 1204 void WebAXObjectProxy::fallbackCallback(const CppArgumentList &, CppVariant* res ult)
1040 { 1205 {
1041 // FIXME: Implement this. 1206 // FIXME: Implement this.
1042 result->setNull(); 1207 result->setNull();
1043 } 1208 }
1044 1209
1045 RootWebAXObjectProxy::RootWebAXObjectProxy(const WebAXObject &object, Factory *f actory) 1210 RootWebAXObjectProxy::RootWebAXObjectProxy(const WebAXObject &object, Factory *f actory)
1046 : WebAXObjectProxy(object, factory) { } 1211 : WebAXObjectProxy(object, factory) { }
1047 1212
1048 WebAXObjectProxy* RootWebAXObjectProxy::getChildAtIndex(unsigned index) 1213 WebAXObjectProxy* RootWebAXObjectProxy::getChildAtIndex(unsigned index)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 } 1248 }
1084 1249
1085 WebAXObjectProxy* WebAXObjectProxyList::createRoot(const WebAXObject& object) 1250 WebAXObjectProxy* WebAXObjectProxyList::createRoot(const WebAXObject& object)
1086 { 1251 {
1087 WebAXObjectProxy* element = new RootWebAXObjectProxy(object, this); 1252 WebAXObjectProxy* element = new RootWebAXObjectProxy(object, this);
1088 m_elements.push_back(element); 1253 m_elements.push_back(element);
1089 return element; 1254 return element;
1090 } 1255 }
1091 1256
1092 } 1257 }
OLDNEW
« 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