| 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 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()); |
| 366 if (characterOffsets[characterOffsets.size() - 1] < 0) { |
| 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); |
| 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. |
| 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. |
| 410 for (size_t j = 0; j < wordCount - 1; j++) { |
| 411 if (characterIndex <= ends[j]) { |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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) |
| 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 Loading... |
| 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 } |
| OLD | NEW |