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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |