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()); | |
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 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) | |
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 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 |