OLD | NEW |
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 Loading... |
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 Loading... |
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 WebAXObject& object, int characterIndex) |
| 351 { |
| 352 BLINK_ASSERT(object.role() == WebAXRoleStaticText); |
| 353 int end = 0; |
| 354 for (unsigned i = 0; i < object.childCount(); i++) { |
| 355 WebAXObject child = object.childAt(i); |
| 356 BLINK_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 BLINK_ASSERT(characterOffsets.size() > 0 && characterOffsets.size() == c
hild.stringValue().length()); |
| 366 switch (child.textDirection()) { |
| 367 case WebAXTextDirectionLR: { |
| 368 if (localIndex) { |
| 369 int left = childRect.x + characterOffsets[localIndex - 1]; |
| 370 int width = characterOffsets[localIndex] - characterOffsets[loca
lIndex - 1]; |
| 371 return WebRect(left, childRect.y, width, childRect.height); |
| 372 } |
| 373 return WebRect(childRect.x, childRect.y, characterOffsets[0], childR
ect.height); |
| 374 } |
| 375 case WebAXTextDirectionRL: { |
| 376 int right = childRect.x + childRect.width; |
| 377 |
| 378 if (localIndex) { |
| 379 int left = right - characterOffsets[localIndex]; |
| 380 int width = characterOffsets[localIndex] - characterOffsets[loca
lIndex - 1]; |
| 381 return WebRect(left, childRect.y, width, childRect.height); |
| 382 } |
| 383 int left = right - characterOffsets[0]; |
| 384 return WebRect(left, childRect.y, characterOffsets[0], childRect.hei
ght); |
| 385 } |
| 386 case WebAXTextDirectionTB: { |
| 387 if (localIndex) { |
| 388 int top = childRect.y + characterOffsets[localIndex - 1]; |
| 389 int height = characterOffsets[localIndex] - characterOffsets[loc
alIndex - 1]; |
| 390 return WebRect(childRect.x, top, childRect.width, height); |
| 391 } |
| 392 return WebRect(childRect.x, childRect.y, childRect.width, characterO
ffsets[0]); |
| 393 } |
| 394 case WebAXTextDirectionBT: { |
| 395 int bottom = childRect.y + childRect.height; |
| 396 |
| 397 if (localIndex) { |
| 398 int top = bottom - characterOffsets[localIndex]; |
| 399 int height = characterOffsets[localIndex] - characterOffsets[loc
alIndex - 1]; |
| 400 return WebRect(childRect.x, top, childRect.width, height); |
| 401 } |
| 402 int top = bottom - characterOffsets[0]; |
| 403 return WebRect(childRect.x, top, childRect.width, characterOffsets[0
]); |
| 404 } |
| 405 } |
| 406 } |
| 407 |
| 408 BLINK_ASSERT(false); |
| 409 return WebRect(); |
| 410 } |
| 411 |
| 412 void getWordBoundaries(const WebAXObject& object, int characterIndex, int& wordS
tart, int& wordEnd) |
| 413 { |
| 414 int end = 0; |
| 415 for (unsigned i = 0; i < object.childCount(); i++) { |
| 416 WebAXObject child = object.childAt(i); |
| 417 BLINK_ASSERT(child.role() == WebAXRoleInlineTextBox); |
| 418 int start = end; |
| 419 end += child.stringValue().length(); |
| 420 if (end <= characterIndex) |
| 421 continue; |
| 422 int localIndex = characterIndex - start; |
| 423 |
| 424 WebVector<int> starts; |
| 425 WebVector<int> ends; |
| 426 child.wordBoundaries(starts, ends); |
| 427 size_t wordCount = starts.size(); |
| 428 BLINK_ASSERT(ends.size() == wordCount); |
| 429 |
| 430 // If there are no words, use the InlineTextBox boundaries. |
| 431 if (!wordCount) { |
| 432 wordStart = start; |
| 433 wordEnd = end; |
| 434 return; |
| 435 } |
| 436 |
| 437 // Look for a character within any word other than the last. |
| 438 for (size_t j = 0; j < wordCount - 1; j++) { |
| 439 if (localIndex <= ends[j]) { |
| 440 wordStart = start + starts[j]; |
| 441 wordEnd = start + ends[j]; |
| 442 return; |
| 443 } |
| 444 } |
| 445 |
| 446 // Return the last word by default. |
| 447 wordStart = start + starts[wordCount - 1]; |
| 448 wordEnd = start + ends[wordCount - 1]; |
| 449 return; |
| 450 } |
| 451 } |
348 | 452 |
349 // Collects attributes into a string, delimited by dashes. Used by all methods | 453 // Collects attributes into a string, delimited by dashes. Used by all methods |
350 // that output lists of attributes: attributesOfLinkedUIElementsCallback, | 454 // that output lists of attributes: attributesOfLinkedUIElementsCallback, |
351 // AttributesOfChildrenCallback, etc. | 455 // AttributesOfChildrenCallback, etc. |
352 class AttributesCollector { | 456 class AttributesCollector { |
353 public: | 457 public: |
354 void collectAttributes(const WebAXObject& object) | 458 void collectAttributes(const WebAXObject& object) |
355 { | 459 { |
356 m_attributes.append("\n------------\n"); | 460 m_attributes.append("\n------------\n"); |
357 m_attributes.append(getAttributes(object)); | 461 m_attributes.append(getAttributes(object)); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 bindMethod("decrement", &AccessibilityUIElement::decrementCallback); | 555 bindMethod("decrement", &AccessibilityUIElement::decrementCallback); |
452 bindMethod("showMenu", &AccessibilityUIElement::showMenuCallback); | 556 bindMethod("showMenu", &AccessibilityUIElement::showMenuCallback); |
453 bindMethod("press", &AccessibilityUIElement::pressCallback); | 557 bindMethod("press", &AccessibilityUIElement::pressCallback); |
454 bindMethod("isEqual", &AccessibilityUIElement::isEqualCallback); | 558 bindMethod("isEqual", &AccessibilityUIElement::isEqualCallback); |
455 bindMethod("addNotificationListener", &AccessibilityUIElement::addNotificati
onListenerCallback); | 559 bindMethod("addNotificationListener", &AccessibilityUIElement::addNotificati
onListenerCallback); |
456 bindMethod("removeNotificationListener", &AccessibilityUIElement::removeNoti
ficationListenerCallback); | 560 bindMethod("removeNotificationListener", &AccessibilityUIElement::removeNoti
ficationListenerCallback); |
457 bindMethod("takeFocus", &AccessibilityUIElement::takeFocusCallback); | 561 bindMethod("takeFocus", &AccessibilityUIElement::takeFocusCallback); |
458 bindMethod("scrollToMakeVisible", &AccessibilityUIElement::scrollToMakeVisib
leCallback); | 562 bindMethod("scrollToMakeVisible", &AccessibilityUIElement::scrollToMakeVisib
leCallback); |
459 bindMethod("scrollToMakeVisibleWithSubFocus", &AccessibilityUIElement::scrol
lToMakeVisibleWithSubFocusCallback); | 563 bindMethod("scrollToMakeVisibleWithSubFocus", &AccessibilityUIElement::scrol
lToMakeVisibleWithSubFocusCallback); |
460 bindMethod("scrollToGlobalPoint", &AccessibilityUIElement::scrollToGlobalPoi
ntCallback); | 564 bindMethod("scrollToGlobalPoint", &AccessibilityUIElement::scrollToGlobalPoi
ntCallback); |
| 565 bindMethod("wordStart", &AccessibilityUIElement::wordStartCallback); |
| 566 bindMethod("wordEnd", &AccessibilityUIElement::wordEndCallback); |
461 | 567 |
462 bindFallbackMethod(&AccessibilityUIElement::fallbackCallback); | 568 bindFallbackMethod(&AccessibilityUIElement::fallbackCallback); |
463 } | 569 } |
464 | 570 |
465 AccessibilityUIElement* AccessibilityUIElement::getChildAtIndex(unsigned index) | 571 AccessibilityUIElement* AccessibilityUIElement::getChildAtIndex(unsigned index) |
466 { | 572 { |
467 return m_factory->getOrCreate(accessibilityObject().childAt(index)); | 573 return m_factory->getOrCreate(accessibilityObject().childAt(index)); |
468 } | 574 } |
469 | 575 |
470 bool AccessibilityUIElement::isEqual(const WebKit::WebAXObject& other) | 576 bool AccessibilityUIElement::isEqual(const WebKit::WebAXObject& other) |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 | 846 |
741 WebVector<int> lineBreaks; | 847 WebVector<int> lineBreaks; |
742 accessibilityObject().lineBreaks(lineBreaks); | 848 accessibilityObject().lineBreaks(lineBreaks); |
743 int line = 0; | 849 int line = 0; |
744 int vectorSize = static_cast<int>(lineBreaks.size()); | 850 int vectorSize = static_cast<int>(lineBreaks.size()); |
745 while (line < vectorSize && lineBreaks[line] <= index) | 851 while (line < vectorSize && lineBreaks[line] <= index) |
746 line++; | 852 line++; |
747 result->set(line); | 853 result->set(line); |
748 } | 854 } |
749 | 855 |
750 void AccessibilityUIElement::boundsForRangeCallback(const CppArgumentList&, CppV
ariant* result) | 856 void AccessibilityUIElement::boundsForRangeCallback(const CppArgumentList& argum
ents, CppVariant* result) |
751 { | 857 { |
752 result->setNull(); | 858 result->setNull(); |
| 859 |
| 860 if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNum
ber()) |
| 861 return; |
| 862 |
| 863 if (accessibilityObject().role() != WebAXRoleStaticText) |
| 864 return; |
| 865 |
| 866 int start = arguments[0].toInt32(); |
| 867 int end = arguments[1].toInt32(); |
| 868 int len = end - start; |
| 869 |
| 870 // Get the bounds for each character and union them into one large rectangle
. |
| 871 // This is just for testing so it doesn't need to be efficient. |
| 872 WebRect bounds = boundsForCharacter(accessibilityObject(), start); |
| 873 for (int i = 1; i < len; i++) { |
| 874 WebRect next = boundsForCharacter(accessibilityObject(), start + i); |
| 875 int right = std::max(bounds.x + bounds.width, next.x + next.width); |
| 876 int bottom = std::max(bounds.y + bounds.height, next.y + next.height); |
| 877 bounds.x = std::min(bounds.x, next.x); |
| 878 bounds.y = std::min(bounds.y, next.y); |
| 879 bounds.width = right - bounds.x; |
| 880 bounds.height = bottom - bounds.y; |
| 881 } |
| 882 |
| 883 char buffer[100]; |
| 884 snprintf(buffer, sizeof(buffer), "{x: %d, y: %d, width: %d, height: %d}", bo
unds.x, bounds.y, bounds.width, bounds.height); |
| 885 result->set(string(buffer)); |
753 } | 886 } |
754 | 887 |
755 void AccessibilityUIElement::stringForRangeCallback(const CppArgumentList&, CppV
ariant* result) | 888 void AccessibilityUIElement::stringForRangeCallback(const CppArgumentList&, CppV
ariant* result) |
756 { | 889 { |
757 result->setNull(); | 890 result->setNull(); |
758 } | 891 } |
759 | 892 |
760 void AccessibilityUIElement::childAtIndexCallback(const CppArgumentList& argumen
ts, CppVariant* result) | 893 void AccessibilityUIElement::childAtIndexCallback(const CppArgumentList& argumen
ts, CppVariant* result) |
761 { | 894 { |
762 if (!arguments.size() || !arguments[0].isNumber()) { | 895 if (!arguments.size() || !arguments[0].isNumber()) { |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 || !arguments[1].isNumber()) | 1161 || !arguments[1].isNumber()) |
1029 return; | 1162 return; |
1030 | 1163 |
1031 int x = arguments[0].toInt32(); | 1164 int x = arguments[0].toInt32(); |
1032 int y = arguments[1].toInt32(); | 1165 int y = arguments[1].toInt32(); |
1033 | 1166 |
1034 accessibilityObject().scrollToGlobalPoint(WebPoint(x, y)); | 1167 accessibilityObject().scrollToGlobalPoint(WebPoint(x, y)); |
1035 result->setNull(); | 1168 result->setNull(); |
1036 } | 1169 } |
1037 | 1170 |
| 1171 void AccessibilityUIElement::wordStartCallback(const CppArgumentList& arguments,
CppVariant* result) |
| 1172 { |
| 1173 result->setNull(); |
| 1174 |
| 1175 if (arguments.size() != 1 || !arguments[0].isNumber()) |
| 1176 return; |
| 1177 |
| 1178 if (accessibilityObject().role() != WebAXRoleStaticText) |
| 1179 return; |
| 1180 |
| 1181 int characterIndex = arguments[0].toInt32(); |
| 1182 int wordStart, wordEnd; |
| 1183 getWordBoundaries(accessibilityObject(), characterIndex, wordStart, wordEnd)
; |
| 1184 result->set(wordStart); |
| 1185 } |
| 1186 |
| 1187 void AccessibilityUIElement::wordEndCallback(const CppArgumentList& arguments, C
ppVariant* result) |
| 1188 { |
| 1189 result->setNull(); |
| 1190 |
| 1191 if (arguments.size() != 1 || !arguments[0].isNumber()) |
| 1192 return; |
| 1193 |
| 1194 if (accessibilityObject().role() != WebAXRoleStaticText) |
| 1195 return; |
| 1196 |
| 1197 int characterIndex = arguments[0].toInt32(); |
| 1198 int wordStart, wordEnd; |
| 1199 getWordBoundaries(accessibilityObject(), characterIndex, wordStart, wordEnd)
; |
| 1200 result->set(wordEnd); |
| 1201 } |
| 1202 |
1038 void AccessibilityUIElement::fallbackCallback(const CppArgumentList &, CppVarian
t* result) | 1203 void AccessibilityUIElement::fallbackCallback(const CppArgumentList &, CppVarian
t* result) |
1039 { | 1204 { |
1040 // FIXME: Implement this. | 1205 // FIXME: Implement this. |
1041 result->setNull(); | 1206 result->setNull(); |
1042 } | 1207 } |
1043 | 1208 |
1044 RootAccessibilityUIElement::RootAccessibilityUIElement(const WebAXObject &object
, Factory *factory) | 1209 RootAccessibilityUIElement::RootAccessibilityUIElement(const WebAXObject &object
, Factory *factory) |
1045 : AccessibilityUIElement(object, factory) { } | 1210 : AccessibilityUIElement(object, factory) { } |
1046 | 1211 |
1047 AccessibilityUIElement* RootAccessibilityUIElement::getChildAtIndex(unsigned ind
ex) | 1212 AccessibilityUIElement* RootAccessibilityUIElement::getChildAtIndex(unsigned ind
ex) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1082 } | 1247 } |
1083 | 1248 |
1084 AccessibilityUIElement* AccessibilityUIElementList::createRoot(const WebAXObject
& object) | 1249 AccessibilityUIElement* AccessibilityUIElementList::createRoot(const WebAXObject
& object) |
1085 { | 1250 { |
1086 AccessibilityUIElement* element = new RootAccessibilityUIElement(object, thi
s); | 1251 AccessibilityUIElement* element = new RootAccessibilityUIElement(object, thi
s); |
1087 m_elements.push_back(element); | 1252 m_elements.push_back(element); |
1088 return element; | 1253 return element; |
1089 } | 1254 } |
1090 | 1255 |
1091 } | 1256 } |
OLD | NEW |