Changeset 244561 in webkit
- Timestamp:
- Apr 23, 2019, 1:31:51 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 15 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/accessibility/mac/bounds-for-range-expected.txt (modified) (1 diff)
-
LayoutTests/accessibility/mac/search-text (added)
-
LayoutTests/accessibility/mac/search-text/search-text-expected.txt (added)
-
LayoutTests/accessibility/mac/search-text/search-text.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/accessibility/AccessibilityObject.cpp (modified) (5 diffs)
-
Source/WebCore/accessibility/AccessibilityObject.h (modified) (2 diffs)
-
Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (modified) (5 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/DumpRenderTree/AccessibilityTextMarker.h (modified) (1 diff)
-
Tools/DumpRenderTree/AccessibilityUIElement.cpp (modified) (2 diffs)
-
Tools/DumpRenderTree/AccessibilityUIElement.h (modified) (1 diff)
-
Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm (modified) (15 diffs)
-
Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp (modified) (1 diff)
-
Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h (modified) (1 diff)
-
Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl (modified) (1 diff)
-
Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r244557 r244561 1 2019-04-23 Andres Gonzalez <andresg_22@apple.com> 2 3 Accessibility text search and selection API enhancements. 4 https://bugs.webkit.org/show_bug.cgi?id=197095 5 <rdar://problem/48181791> 6 7 Reviewed by Chris Fleizach. 8 9 - Added new test for AccessibilitySearchTextWithCriteria API. 10 - Updated bounds-for-range expected file that includes a list of available APIs. 11 12 * accessibility/mac/bounds-for-range-expected.txt: 13 * accessibility/mac/search-text/search-text-expected.txt: Added. 14 * accessibility/mac/search-text/search-text.html: Added. 15 1 16 2019-04-23 Guy Lewin <guy@lewin.co.il> 2 17 -
trunk/LayoutTests/accessibility/mac/bounds-for-range-expected.txt
r229080 r244561 66 66 AXLineTextMarkerRangeForTextMarker 67 67 AXSelectTextWithCriteria 68 AXSearchTextWithCriteria 69 AXTextOperation 68 70 69 71 ---------------------- -
trunk/Source/WebCore/ChangeLog
r244557 r244561 1 2019-04-23 Andres Gonzalez <andresg_22@apple.com> 2 3 Accessibility text search and selection API enhancements. 4 https://bugs.webkit.org/show_bug.cgi?id=197095 5 <rdar://problem/48181791> 6 7 Reviewed by Chris Fleizach. 8 9 - Split the existing SelectTextWithCriteria API into two: search text API (SearchTextWithCriteria) and a text operation API (TextOperation: select, replace, capitalize...). 10 - This allows for more flexibility and extensibility. 11 - Added the ability to retrieve text markers for multiple search hits. 12 - Various code clean up and consolidation. 13 - Added LayoutTest for search API. 14 - Previous API is marked with "To be deprecated", and is implemented with new implementation. May be removed in a future change. 15 16 Test: accessibility/mac/search-text/search-text.html 17 18 * accessibility/AccessibilityObject.cpp: 19 (WebCore::rangeClosestToRange): 20 (WebCore::AccessibilityObject::rangeOfStringClosestToRangeInDirection const): 21 (WebCore::AccessibilityObject::findTextRange const): 22 (WebCore::AccessibilityObject::findTextRanges const): 23 (WebCore::AccessibilityObject::performTextOperation): 24 (WebCore::AccessibilityObject::frame const): 25 (WebCore::AccessibilityObject::selectText): Deleted. 26 * accessibility/AccessibilityObject.h: 27 (WebCore::AccessibilitySearchTextCriteria::AccessibilitySearchTextCriteria): 28 (WebCore::AccessibilityTextOperation::AccessibilityTextOperation): 29 (WebCore::AccessibilitySelectTextCriteria::AccessibilitySelectTextCriteria): Deleted. 30 * accessibility/mac/WebAccessibilityObjectWrapperMac.mm: 31 (accessibilityTextCriteriaForParameterizedAttribute): 32 (accessibilitySearchTextCriteriaForParameterizedAttribute): 33 (accessibilityTextOperationForParameterizedAttribute): 34 (-[WebAccessibilityObjectWrapper IGNORE_WARNINGS_END]): 35 (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]): 36 (accessibilitySelectTextCriteriaForCriteriaParameterizedAttribute): Deleted. 37 1 38 2019-04-23 Guy Lewin <guy@lewin.co.il> 2 39 -
trunk/Source/WebCore/accessibility/AccessibilityObject.cpp
r244538 r244561 758 758 // NOTE: The after range is expected to ACTUALLY be after the reference range and the before 759 759 // range is expected to ACTUALLY be before. These are not checked for performance reasons. 760 static RefPtr<Range> rangeClosestToRange(R ange*referenceRange, RefPtr<Range>&& afterRange, RefPtr<Range>&& beforeRange)760 static RefPtr<Range> rangeClosestToRange(RefPtr<Range> const& referenceRange, RefPtr<Range>&& afterRange, RefPtr<Range>&& beforeRange) 761 761 { 762 762 if (!referenceRange) 763 763 return nullptr; 764 764 765 765 // The treeScope for shadow nodes may not be the same scope as another element in a document. 766 766 // Comparisons may fail in that case, which are expected behavior and should not assert. 767 767 if (afterRange && (referenceRange->endPosition().isNull() || ((afterRange->startPosition().anchorNode()->compareDocumentPosition(*referenceRange->endPosition().anchorNode()) & Node::DOCUMENT_POSITION_DISCONNECTED) == Node::DOCUMENT_POSITION_DISCONNECTED))) 768 768 return nullptr; 769 ASSERT(!afterRange || afterRange-> startPosition() >= referenceRange->endPosition());770 769 ASSERT(!afterRange || afterRange->compareBoundaryPoints(Range::START_TO_START, *referenceRange).releaseReturnValue() >= 0); 770 771 771 if (beforeRange && (referenceRange->startPosition().isNull() || ((beforeRange->endPosition().anchorNode()->compareDocumentPosition(*referenceRange->startPosition().anchorNode()) & Node::DOCUMENT_POSITION_DISCONNECTED) == Node::DOCUMENT_POSITION_DISCONNECTED))) 772 772 return nullptr; 773 ASSERT(!beforeRange || beforeRange-> endPosition() <= referenceRange->startPosition());774 773 ASSERT(!beforeRange || beforeRange->compareBoundaryPoints(Range::START_TO_START, *referenceRange).releaseReturnValue() <= 0); 774 775 775 if (!afterRange && !beforeRange) 776 776 return nullptr; … … 786 786 } 787 787 788 RefPtr<Range> AccessibilityObject::rangeOfStringClosestToRangeInDirection(Range* referenceRange, AccessibilitySearchDirection searchDirection, Vector<String> & searchStrings) const788 RefPtr<Range> AccessibilityObject::rangeOfStringClosestToRangeInDirection(Range* referenceRange, AccessibilitySearchDirection searchDirection, Vector<String> const& searchStrings) const 789 789 { 790 790 Frame* frame = this->frame(); … … 798 798 FindOptions findOptions { AtWordStarts, AtWordEnds, CaseInsensitive, StartInSelection }; 799 799 if (isBackwardSearch) 800 findOptions.add( Backwards);800 findOptions.add(FindOptionFlag::Backwards); 801 801 802 802 RefPtr<Range> closestStringRange = nullptr; … … 844 844 } 845 845 846 String AccessibilityObject::selectText(AccessibilitySelectTextCriteria* criteria) 847 { 848 ASSERT(criteria); 849 850 if (!criteria) 851 return String(); 852 846 RefPtr<Range> AccessibilityObject::findTextRange(Vector<String> const& searchStrings, RefPtr<Range> const& start, AccessibilitySearchTextDirection direction) const 847 { 848 RefPtr<Range> found; 849 if (direction == AccessibilitySearchTextDirection::Forward) 850 found = rangeOfStringClosestToRangeInDirection(start.get(), AccessibilitySearchDirection::Next, searchStrings); 851 else if (direction == AccessibilitySearchTextDirection::Backward) 852 found = rangeOfStringClosestToRangeInDirection(start.get(), AccessibilitySearchDirection::Previous, searchStrings); 853 else if (direction == AccessibilitySearchTextDirection::Closest) { 854 auto foundAfter = rangeOfStringClosestToRangeInDirection(start.get(), AccessibilitySearchDirection::Next, searchStrings); 855 auto foundBefore = rangeOfStringClosestToRangeInDirection(start.get(), AccessibilitySearchDirection::Previous, searchStrings); 856 found = rangeClosestToRange(start.get(), WTFMove(foundAfter), WTFMove(foundBefore)); 857 } 858 859 if (found) { 860 // If the search started within a text control, ensure that the result is inside that element. 861 if (element() && element()->isTextField()) { 862 if (!found->startContainer().isDescendantOrShadowDescendantOf(element()) 863 || !found->endContainer().isDescendantOrShadowDescendantOf(element())) 864 return nullptr; 865 } 866 } 867 return found; 868 } 869 870 Vector<RefPtr<Range>> AccessibilityObject::findTextRanges(AccessibilitySearchTextCriteria const& criteria) const 871 { 872 Vector<RefPtr<Range>> result; 873 874 // Determine start range. 875 RefPtr<Range> startRange; 876 if (criteria.start == AccessibilitySearchTextStartFrom::Selection) 877 startRange = selectionRange(); 878 else 879 startRange = elementRange(); 880 881 if (startRange) { 882 // Collapse the range to the start unless searching from the end of the doc or searching backwards. 883 if (criteria.start == AccessibilitySearchTextStartFrom::Begin) 884 startRange->collapse(true); 885 else if (criteria.start == AccessibilitySearchTextStartFrom::End) 886 startRange->collapse(false); 887 else 888 startRange->collapse(criteria.direction != AccessibilitySearchTextDirection::Backward); 889 } else 890 return result; 891 892 RefPtr<Range> found; 893 switch (criteria.direction) { 894 case AccessibilitySearchTextDirection::Forward: 895 case AccessibilitySearchTextDirection::Backward: 896 case AccessibilitySearchTextDirection::Closest: 897 found = findTextRange(criteria.searchStrings, startRange, criteria.direction); 898 if (found) 899 result.append(found); 900 break; 901 case AccessibilitySearchTextDirection::All: { 902 auto findAll = [&](AccessibilitySearchTextDirection dir) { 903 found = findTextRange(criteria.searchStrings, startRange, dir); 904 while (found) { 905 result.append(found); 906 found = findTextRange(criteria.searchStrings, found, dir); 907 } 908 }; 909 findAll(AccessibilitySearchTextDirection::Forward); 910 findAll(AccessibilitySearchTextDirection::Backward); 911 break; 912 } 913 } 914 915 return result; 916 } 917 918 Vector<String> AccessibilityObject::performTextOperation(AccessibilityTextOperation const& operation) 919 { 920 Vector<String> result; 921 922 if (operation.textRanges.isEmpty()) 923 return result; 924 853 925 Frame* frame = this->frame(); 854 926 if (!frame) 855 return String(); 856 857 AccessibilitySelectTextActivity& activity = criteria->activity; 858 AccessibilitySelectTextAmbiguityResolution& ambiguityResolution = criteria->ambiguityResolution; 859 String& replacementString = criteria->replacementString; 860 Vector<String>& searchStrings = criteria->searchStrings; 861 862 RefPtr<Range> selectedStringRange = selectionRange(); 863 // When starting our search again, make this a zero length range so that search forwards will find this selected range if its appropriate. 864 selectedStringRange->setEnd(selectedStringRange->startContainer(), selectedStringRange->startOffset()); 865 866 RefPtr<Range> closestAfterStringRange = nullptr; 867 RefPtr<Range> closestBeforeStringRange = nullptr; 868 // Search forward if necessary. 869 if (ambiguityResolution == AccessibilitySelectTextAmbiguityResolution::ClosestAfter || ambiguityResolution == AccessibilitySelectTextAmbiguityResolution::ClosestTo) 870 closestAfterStringRange = rangeOfStringClosestToRangeInDirection(selectedStringRange.get(), AccessibilitySearchDirection::Next, searchStrings); 871 // Search backward if necessary. 872 if (ambiguityResolution == AccessibilitySelectTextAmbiguityResolution::ClosestBefore || ambiguityResolution == AccessibilitySelectTextAmbiguityResolution::ClosestTo) 873 closestBeforeStringRange = rangeOfStringClosestToRangeInDirection(selectedStringRange.get(), AccessibilitySearchDirection::Previous, searchStrings); 874 875 // Determine which candidate is closest to the selection and perform the activity. 876 if (RefPtr<Range> closestStringRange = rangeClosestToRange(selectedStringRange.get(), WTFMove(closestAfterStringRange), WTFMove(closestBeforeStringRange))) { 877 // If the search started within a text control, ensure that the result is inside that element. 878 if (element() && element()->isTextField()) { 879 if (!closestStringRange->startContainer().isDescendantOrShadowDescendantOf(element()) || !closestStringRange->endContainer().isDescendantOrShadowDescendantOf(element())) 880 return String(); 927 return result; 928 929 for (auto textRange : operation.textRanges) { 930 if (!frame->selection().setSelectedRange(textRange.get(), DOWNSTREAM, FrameSelection::ShouldCloseTyping::Yes)) 931 continue; 932 933 String text = textRange->text(); 934 String replacementString = operation.replacementText; 935 bool replaceSelection = false; 936 switch (operation.type) { 937 case AccessibilityTextOperationType::Capitalize: 938 replacementString = capitalize(text, ' '); // FIXME: Needs to take locale into account to work correctly. 939 replaceSelection = true; 940 break; 941 case AccessibilityTextOperationType::Uppercase: 942 replacementString = text.convertToUppercaseWithoutLocale(); // FIXME: Needs locale to work correctly. 943 replaceSelection = true; 944 break; 945 case AccessibilityTextOperationType::Lowercase: 946 replacementString = text.convertToLowercaseWithoutLocale(); // FIXME: Needs locale to work correctly. 947 replaceSelection = true; 948 break; 949 case AccessibilityTextOperationType::Replace: { 950 replaceSelection = true; 951 // When applying find and replace activities, we want to match the capitalization of the replaced text, 952 // (unless we're replacing with an abbreviation.) 953 if (text.length() > 0 954 && replacementString.length() > 2 955 && replacementString != replacementString.convertToUppercaseWithoutLocale()) { 956 if (text[0] == u_toupper(text[0])) 957 replacementString = capitalize(replacementString, ' '); // FIXME: Needs to take locale into account to work correctly. 958 else 959 replacementString = replacementString.convertToLowercaseWithoutLocale(); // FIXME: Needs locale to work correctly. 960 } 961 break; 881 962 } 882 883 String closestString = closestStringRange->text(); 884 bool replaceSelection = false; 885 if (frame->selection().setSelectedRange(closestStringRange.get(), DOWNSTREAM, FrameSelection::ShouldCloseTyping::Yes)) { 886 switch (activity) { 887 case AccessibilitySelectTextActivity::FindAndCapitalize: 888 replacementString = capitalize(closestString, ' '); // FIXME: Needs to take locale into account to work correctly. 889 replaceSelection = true; 890 break; 891 case AccessibilitySelectTextActivity::FindAndUppercase: 892 replacementString = closestString.convertToUppercaseWithoutLocale(); // FIXME: Needs locale to work correctly. 893 replaceSelection = true; 894 break; 895 case AccessibilitySelectTextActivity::FindAndLowercase: 896 replacementString = closestString.convertToLowercaseWithoutLocale(); // FIXME: Needs locale to work correctly. 897 replaceSelection = true; 898 break; 899 case AccessibilitySelectTextActivity::FindAndReplace: { 900 replaceSelection = true; 901 // When applying find and replace activities, we want to match the capitalization of the replaced text, 902 // (unless we're replacing with an abbreviation.) 903 if (closestString.length() > 0 && replacementString.length() > 2 && replacementString != replacementString.convertToUppercaseWithoutLocale()) { 904 if (closestString[0] == u_toupper(closestString[0])) 905 replacementString = capitalize(replacementString, ' '); // FIXME: Needs to take locale into account to work correctly. 906 else 907 replacementString = replacementString.convertToLowercaseWithoutLocale(); // FIXME: Needs locale to work correctly. 908 } 909 break; 910 } 911 case AccessibilitySelectTextActivity::FindAndSelect: 912 break; 913 } 914 915 // A bit obvious, but worth noting the API contract for this method is that we should 916 // return the replacement string when replacing, but the selected string if not. 917 if (replaceSelection) { 918 frame->editor().replaceSelectionWithText(replacementString, Editor::SelectReplacement::Yes, Editor::SmartReplace::Yes); 919 return replacementString; 920 } 921 922 return closestString; 963 case AccessibilityTextOperationType::Select: 964 break; 923 965 } 924 } 925 926 return String(); 966 967 // A bit obvious, but worth noting the API contract for this method is that we should 968 // return the replacement string when replacing, but the selected string if not. 969 if (replaceSelection) { 970 frame->editor().replaceSelectionWithText(replacementString, Editor::SelectReplacement::Yes, Editor::SmartReplace::Yes); 971 result.append(replacementString); 972 } else 973 result.append(text); 974 } 975 976 return result; 927 977 } 928 978 … … 1077 1127 { 1078 1128 Node* node = this->node(); 1079 if (!node) 1080 return nullptr; 1081 1082 return node->document().frame(); 1129 return node ? node->document().frame() : nullptr; 1083 1130 } 1084 1131 -
trunk/Source/WebCore/accessibility/AccessibilityObject.h
r244538 r244561 306 306 }; 307 307 308 enum class AccessibilitySelectTextActivity { 309 FindAndReplace, 310 FindAndSelect, 311 FindAndCapitalize, 312 FindAndLowercase, 313 FindAndUppercase 314 }; 315 316 enum class AccessibilitySelectTextAmbiguityResolution { 317 ClosestAfter, 318 ClosestBefore, 319 ClosestTo 320 }; 321 322 struct AccessibilitySelectTextCriteria { 323 AccessibilitySelectTextActivity activity; 324 AccessibilitySelectTextAmbiguityResolution ambiguityResolution; 325 String replacementString; 326 Vector<String> searchStrings; 327 328 AccessibilitySelectTextCriteria(AccessibilitySelectTextActivity activity, AccessibilitySelectTextAmbiguityResolution ambiguityResolution, const String& replacementString) 329 : activity(activity) 330 , ambiguityResolution(ambiguityResolution) 331 , replacementString(replacementString) 308 enum class AccessibilitySearchTextStartFrom { 309 Begin, // Search from the beginning of the element. 310 Selection, // Search from the position of the current selection. 311 End // Search from the end of the element. 312 }; 313 314 enum class AccessibilitySearchTextDirection { 315 Forward, // Occurrence after the starting range. 316 Backward, // Occurrence before the starting range. 317 Closest, // Closest occurrence to the starting range, whether after or before. 318 All // All occurrences 319 }; 320 321 struct AccessibilitySearchTextCriteria { 322 Vector<String> searchStrings; // Text strings to search for. 323 AccessibilitySearchTextStartFrom start; 324 AccessibilitySearchTextDirection direction; 325 326 AccessibilitySearchTextCriteria() 327 : start(AccessibilitySearchTextStartFrom::Selection) 328 , direction(AccessibilitySearchTextDirection::Forward) 329 { } 330 }; 331 332 enum class AccessibilityTextOperationType { 333 Select, 334 Replace, 335 Capitalize, 336 Lowercase, 337 Uppercase 338 }; 339 340 struct AccessibilityTextOperation { 341 Vector<RefPtr<Range>> textRanges; // text on which perform the operation. 342 AccessibilityTextOperationType type; 343 String replacementText; // For type = replace. 344 345 AccessibilityTextOperation() 346 : type(AccessibilityTextOperationType::Select) 332 347 { } 333 348 }; … … 608 623 609 624 bool isDescendantOfRole(AccessibilityRole) const; 610 625 611 626 // Text selection 612 RefPtr<Range> rangeOfStringClosestToRangeInDirection(Range*, AccessibilitySearchDirection, Vector<String>&) const; 627 private: 628 RefPtr<Range> rangeOfStringClosestToRangeInDirection(Range*, AccessibilitySearchDirection, Vector<String> const&) const; 613 629 RefPtr<Range> selectionRange() const; 614 String selectText(AccessibilitySelectTextCriteria*); 615 630 RefPtr<Range> findTextRange(Vector<String> const& searchStrings, RefPtr<Range> const& start, AccessibilitySearchTextDirection) const; 631 public: 632 Vector<RefPtr<Range>> findTextRanges(AccessibilitySearchTextCriteria const&) const; 633 Vector<String> performTextOperation(AccessibilityTextOperation const&); 634 616 635 virtual AccessibilityObject* observableObject() const { return nullptr; } 617 636 virtual void linkedUIElements(AccessibilityChildrenVector&) const { } -
trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm
r244059 r244561 373 373 #endif 374 374 375 // Text search 376 377 #ifndef NSAccessibilitySearchTextWithCriteriaParameterizedAttribute 378 /* Performs a text search with the given parameters. 379 Returns an NSArray of text marker ranges of the search hits. 380 */ 381 #define NSAccessibilitySearchTextWithCriteriaParameterizedAttribute @"AXSearchTextWithCriteria" 382 #endif 383 384 #ifndef NSAccessibilitySearchTextSearchStrings 385 // NSArray of strings to search for. 386 #define NSAccessibilitySearchTextSearchStrings @"AXSearchTextSearchStrings" 387 #endif 388 389 #ifndef NSAccessibilitySearchTextStartFrom 390 // NSString specifying the start point of the search: selection, begin or end. 391 #define NSAccessibilitySearchTextStartFrom @"AXSearchTextStartFrom" 392 #endif 393 394 #ifndef NSAccessibilitySearchTextStartFromBegin 395 // Value for SearchTextStartFrom. 396 #define NSAccessibilitySearchTextStartFromBegin @"AXSearchTextStartFromBegin" 397 #endif 398 399 #ifndef NSAccessibilitySearchTextStartFromSelection 400 // Value for SearchTextStartFrom. 401 #define NSAccessibilitySearchTextStartFromSelection @"AXSearchTextStartFromSelection" 402 #endif 403 404 #ifndef NSAccessibilitySearchTextStartFromEnd 405 // Value for SearchTextStartFrom. 406 #define NSAccessibilitySearchTextStartFromEnd @"AXSearchTextStartFromEnd" 407 #endif 408 409 #ifndef NSAccessibilitySearchTextDirection 410 // NSString specifying the direction of the search: forward, backward, closest, all. 411 #define NSAccessibilitySearchTextDirection @"AXSearchTextDirection" 412 #endif 413 414 #ifndef NSAccessibilitySearchTextDirectionForward 415 // Value for SearchTextDirection. 416 #define NSAccessibilitySearchTextDirectionForward @"AXSearchTextDirectionForward" 417 #endif 418 419 #ifndef NSAccessibilitySearchTextDirectionBackward 420 // Value for SearchTextDirection. 421 #define NSAccessibilitySearchTextDirectionBackward @"AXSearchTextDirectionBackward" 422 #endif 423 424 #ifndef NSAccessibilitySearchTextDirectionClosest 425 // Value for SearchTextDirection. 426 #define NSAccessibilitySearchTextDirectionClosest @"AXSearchTextDirectionClosest" 427 #endif 428 429 #ifndef NSAccessibilitySearchTextDirectionAll 430 // Value for SearchTextDirection. 431 #define NSAccessibilitySearchTextDirectionAll @"AXSearchTextDirectionAll" 432 #endif 433 434 // Text operations 435 436 #ifndef NSAccessibilityTextOperationParameterizedAttribute 437 // Performs an operation on the given text. 438 #define NSAccessibilityTextOperationParameterizedAttribute @"AXTextOperation" 439 #endif 440 441 #ifndef NSAccessibilityTextOperationMarkerRanges 442 // Text on which to perform operation. 443 #define NSAccessibilityTextOperationMarkerRanges @"AXTextOperationMarkerRanges" 444 #endif 445 446 #ifndef NSAccessibilityTextOperationType 447 // The type of operation to be performed: select, replace, capitalize.... 448 #define NSAccessibilityTextOperationType @"AXTextOperationType" 449 #endif 450 451 #ifndef NSAccessibilityTextOperationSelect 452 // Value for TextOperationType. 453 #define NSAccessibilityTextOperationSelect @"TextOperationSelect" 454 #endif 455 456 #ifndef NSAccessibilityTextOperationReplace 457 // Value for TextOperationType. 458 #define NSAccessibilityTextOperationReplace @"TextOperationReplace" 459 #endif 460 461 #ifndef NSAccessibilityTextOperationCapitalize 462 // Value for TextOperationType. 463 #define NSAccessibilityTextOperationCapitalize @"Capitalize" 464 #endif 465 466 #ifndef NSAccessibilityTextOperationLowercase 467 // Value for TextOperationType. 468 #define NSAccessibilityTextOperationLowercase @"Lowercase" 469 #endif 470 471 #ifndef NSAccessibilityTextOperationUppercase 472 // Value for TextOperationType. 473 #define NSAccessibilityTextOperationUppercase @"Uppercase" 474 #endif 475 476 #ifndef NSAccessibilityTextOperationReplacementString 477 // Replacement text for operation replace. 478 #define NSAccessibilityTextOperationReplacementString @"AXTextOperationReplacementString" 479 #endif 480 375 481 // Math attributes 376 482 #define NSAccessibilityMathRootRadicandAttribute @"AXMathRootRadicand" … … 505 611 #pragma mark Select text helpers 506 612 507 static AccessibilitySelectTextCriteria accessibilitySelectTextCriteriaForCriteriaParameterizedAttribute(const NSDictionary *parameterizedAttribute) 508 { 613 // To be deprecated. 614 static std::pair<AccessibilitySearchTextCriteria, AccessibilityTextOperation> accessibilityTextCriteriaForParameterizedAttribute(const NSDictionary *parameterizedAttribute) 615 { 616 AccessibilitySearchTextCriteria criteria; 617 AccessibilityTextOperation operation; 618 509 619 NSString *activityParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextActivity]; 510 620 NSString *ambiguityResolutionParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextAmbiguityResolution]; 511 621 NSString *replacementStringParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextReplacementString]; 512 622 NSArray *searchStringsParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextSearchStrings]; 513 514 AccessibilitySelectTextActivity activity = AccessibilitySelectTextActivity::FindAndSelect; 623 515 624 if ([activityParameter isKindOfClass:[NSString class]]) { 516 625 if ([activityParameter isEqualToString:NSAccessibilitySelectTextActivityFindAndReplace]) 517 activity = AccessibilitySelectTextActivity::FindAndReplace;626 operation.type = AccessibilityTextOperationType::Replace; 518 627 else if ([activityParameter isEqualToString:kAXSelectTextActivityFindAndCapitalize]) 519 activity = AccessibilitySelectTextActivity::FindAndCapitalize;628 operation.type = AccessibilityTextOperationType::Capitalize; 520 629 else if ([activityParameter isEqualToString:kAXSelectTextActivityFindAndLowercase]) 521 activity = AccessibilitySelectTextActivity::FindAndLowercase;630 operation.type = AccessibilityTextOperationType::Lowercase; 522 631 else if ([activityParameter isEqualToString:kAXSelectTextActivityFindAndUppercase]) 523 activity = AccessibilitySelectTextActivity::FindAndUppercase;524 } 525 526 AccessibilitySelectTextAmbiguityResolution ambiguityResolution = AccessibilitySelectTextAmbiguityResolution::ClosestTo;632 operation.type = AccessibilityTextOperationType::Uppercase; 633 } 634 635 criteria.direction = AccessibilitySearchTextDirection::Closest; 527 636 if ([ambiguityResolutionParameter isKindOfClass:[NSString class]]) { 528 637 if ([ambiguityResolutionParameter isEqualToString:NSAccessibilitySelectTextAmbiguityResolutionClosestAfterSelection]) 529 ambiguityResolution = AccessibilitySelectTextAmbiguityResolution::ClosestAfter;638 criteria.direction = AccessibilitySearchTextDirection::Forward; 530 639 else if ([ambiguityResolutionParameter isEqualToString:NSAccessibilitySelectTextAmbiguityResolutionClosestBeforeSelection]) 531 ambiguityResolution = AccessibilitySelectTextAmbiguityResolution::ClosestBefore; 532 } 533 534 String replacementString; 640 criteria.direction = AccessibilitySearchTextDirection::Backward; 641 } 642 535 643 if ([replacementStringParameter isKindOfClass:[NSString class]]) 536 replacementString = replacementStringParameter; 537 538 AccessibilitySelectTextCriteria criteria(activity, ambiguityResolution, replacementString); 539 644 operation.replacementText = replacementStringParameter; 645 540 646 if ([searchStringsParameter isKindOfClass:[NSArray class]]) { 541 647 size_t searchStringsCount = static_cast<size_t>([searchStringsParameter count]); … … 546 652 } 547 653 } 548 654 655 return std::make_pair(criteria, operation); 656 } 657 658 static AccessibilitySearchTextCriteria accessibilitySearchTextCriteriaForParameterizedAttribute(const NSDictionary *params) 659 { 660 AccessibilitySearchTextCriteria criteria; 661 662 NSArray *searchStrings = [params objectForKey:NSAccessibilitySearchTextSearchStrings]; 663 NSString *start = [params objectForKey:NSAccessibilitySearchTextStartFrom]; 664 NSString *direction = [params objectForKey:NSAccessibilitySearchTextDirection]; 665 666 if ([searchStrings isKindOfClass:[NSArray class]]) { 667 size_t searchStringsCount = static_cast<size_t>([searchStrings count]); 668 criteria.searchStrings.reserveInitialCapacity(searchStringsCount); 669 for (NSString *searchString in searchStrings) { 670 if ([searchString isKindOfClass:[NSString class]]) 671 criteria.searchStrings.uncheckedAppend(searchString); 672 } 673 } 674 675 if ([start isKindOfClass:[NSString class]]) { 676 if ([start isEqualToString:NSAccessibilitySearchTextStartFromBegin]) 677 criteria.start = AccessibilitySearchTextStartFrom::Begin; 678 else if ([start isEqualToString:NSAccessibilitySearchTextStartFromEnd]) 679 criteria.start = AccessibilitySearchTextStartFrom::End; 680 } 681 682 if ([direction isKindOfClass:[NSString class]]) { 683 if ([direction isEqualToString:NSAccessibilitySearchTextDirectionBackward]) 684 criteria.direction = AccessibilitySearchTextDirection::Backward; 685 else if ([direction isEqualToString:NSAccessibilitySearchTextDirectionClosest]) 686 criteria.direction = AccessibilitySearchTextDirection::Closest; 687 else if ([direction isEqualToString:NSAccessibilitySearchTextDirectionAll]) 688 criteria.direction = AccessibilitySearchTextDirection::All; 689 } 690 549 691 return criteria; 692 } 693 694 static AccessibilityTextOperation accessibilityTextOperationForParameterizedAttribute(WebAccessibilityObjectWrapper *obj, const NSDictionary *parameterizedAttribute) 695 { 696 AccessibilityTextOperation operation; 697 698 NSArray *markerRanges = [parameterizedAttribute objectForKey:NSAccessibilityTextOperationMarkerRanges]; 699 NSString *operationType = [parameterizedAttribute objectForKey:NSAccessibilityTextOperationType]; 700 NSString *replacementString = [parameterizedAttribute objectForKey:NSAccessibilityTextOperationReplacementString]; 701 702 if ([markerRanges isKindOfClass:[NSArray class]]) { 703 size_t count = static_cast<size_t>(markerRanges.count); 704 operation.textRanges.reserveInitialCapacity(count); 705 for (id markerRange : markerRanges) 706 operation.textRanges.append([obj rangeForTextMarkerRange:markerRange]); 707 } 708 709 if ([operationType isKindOfClass:[NSString class]]) { 710 if ([operationType isEqualToString:NSAccessibilityTextOperationReplace]) 711 operation.type = AccessibilityTextOperationType::Replace; 712 else if ([operationType isEqualToString:NSAccessibilityTextOperationCapitalize]) 713 operation.type = AccessibilityTextOperationType::Capitalize; 714 else if ([operationType isEqualToString:NSAccessibilityTextOperationLowercase]) 715 operation.type = AccessibilityTextOperationType::Lowercase; 716 else if ([operationType isEqualToString:NSAccessibilityTextOperationUppercase]) 717 operation.type = AccessibilityTextOperationType::Uppercase; 718 } 719 720 if ([replacementString isKindOfClass:[NSString class]]) 721 operation.replacementText = replacementString; 722 723 return operation; 550 724 } 551 725 … … 3440 3614 NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute, 3441 3615 NSAccessibilitySelectTextWithCriteriaParameterizedAttribute, 3616 NSAccessibilitySearchTextWithCriteriaParameterizedAttribute, 3617 NSAccessibilityTextOperationParameterizedAttribute, 3442 3618 nil]; 3443 3619 } … … 3991 4167 // dispatch 3992 4168 if ([attribute isEqualToString:NSAccessibilitySelectTextWithCriteriaParameterizedAttribute]) { 3993 AccessibilitySelectTextCriteria criteria = accessibilitySelectTextCriteriaForCriteriaParameterizedAttribute(dictionary); 3994 return m_object->selectText(&criteria); 3995 } 3996 4169 // To be deprecated. 4170 auto criteria = accessibilityTextCriteriaForParameterizedAttribute(dictionary); 4171 criteria.second.textRanges = m_object->findTextRanges(criteria.first); 4172 ASSERT(criteria.second.textRanges.size() <= 1); 4173 Vector<String> result = m_object->performTextOperation(criteria.second); 4174 ASSERT(result.size() <= 1); 4175 if (result.size() > 0) 4176 return result[0]; 4177 return String(); 4178 } 4179 4180 if ([attribute isEqualToString:NSAccessibilitySearchTextWithCriteriaParameterizedAttribute]) { 4181 auto criteria = accessibilitySearchTextCriteriaForParameterizedAttribute(dictionary); 4182 auto ranges = m_object->findTextRanges(criteria); 4183 if (ranges.isEmpty()) 4184 return nil; 4185 NSMutableArray *markers = [NSMutableArray arrayWithCapacity:ranges.size()]; 4186 for (auto range : ranges) { 4187 if (id marker = [self textMarkerRangeFromRange:range]) 4188 [markers addObject:marker]; 4189 } 4190 return markers; 4191 } 4192 4193 if ([attribute isEqualToString:NSAccessibilityTextOperationParameterizedAttribute]) { 4194 auto textOperation = accessibilityTextOperationForParameterizedAttribute(self, dictionary); 4195 auto operationResult = m_object->performTextOperation(textOperation); 4196 if (operationResult.isEmpty()) 4197 return nil; 4198 NSMutableArray *result = [NSMutableArray arrayWithCapacity:operationResult.size()]; 4199 for (auto str : operationResult) 4200 [result addObject:str]; 4201 return result; 4202 } 4203 3997 4204 if ([attribute isEqualToString:NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute]) { 3998 4205 AccessibilitySearchCriteria criteria = accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute(dictionary); -
trunk/Tools/ChangeLog
r244557 r244561 1 2019-04-23 Andres Gonzalez <andresg_22@apple.com> 2 3 Accessibility text search and selection API enhancements. 4 https://bugs.webkit.org/show_bug.cgi?id=197095 5 <rdar://problem/48181791> 6 7 Reviewed by Chris Fleizach. 8 9 Added new API JS binding code for searchTextWithCriteria to both WTR and DRT. 10 11 * DumpRenderTree/AccessibilityTextMarker.h: 12 * DumpRenderTree/AccessibilityUIElement.cpp: 13 (searchTextWithCriteriaCallback): 14 (AccessibilityUIElement::getJSClass): 15 * DumpRenderTree/AccessibilityUIElement.h: 16 * DumpRenderTree/mac/AccessibilityUIElementMac.mm: 17 (convertVectorToObjectArray): 18 (convertNSArrayToVector): 19 (searchTextParameterizedAttributeForCriteria): 20 (AccessibilityUIElement::getLinkedUIElements): 21 (AccessibilityUIElement::getDocumentLinks): 22 (AccessibilityUIElement::getChildren): 23 (AccessibilityUIElement::getChildrenWithRange): 24 (AccessibilityUIElement::rowHeaders const): 25 (AccessibilityUIElement::columnHeaders const): 26 (AccessibilityUIElement::uiElementArrayAttributeValue const): 27 (AccessibilityUIElement::searchTextWithCriteria): 28 (AccessibilityUIElement::attributesOfColumnHeaders): 29 (AccessibilityUIElement::attributesOfRowHeaders): 30 (AccessibilityUIElement::attributesOfColumns): 31 (AccessibilityUIElement::attributesOfRows): 32 (AccessibilityUIElement::attributesOfVisibleCells): 33 * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h: 34 * WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl: 35 * WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm: 36 (WTR::convertVectorToObjectArray): 37 (WTR::convertNSArrayToVector): 38 (WTR::searchTextParameterizedAttributeForCriteria): 39 (WTR::AccessibilityUIElement::getLinkedUIElements): 40 (WTR::AccessibilityUIElement::getDocumentLinks): 41 (WTR::AccessibilityUIElement::getUIElementsWithAttribute const): 42 (WTR::AccessibilityUIElement::getChildren): 43 (WTR::AccessibilityUIElement::getChildrenWithRange): 44 (WTR::AccessibilityUIElement::rowHeaders const): 45 (WTR::AccessibilityUIElement::columnHeaders const): 46 (WTR::AccessibilityUIElement::uiElementArrayAttributeValue const): 47 (WTR::AccessibilityUIElement::searchTextWithCriteria): 48 (WTR::AccessibilityUIElement::attributesOfColumnHeaders): 49 (WTR::AccessibilityUIElement::attributesOfRowHeaders): 50 (WTR::AccessibilityUIElement::attributesOfColumns): 51 (WTR::AccessibilityUIElement::attributesOfRows): 52 (WTR::AccessibilityUIElement::attributesOfVisibleCells): 53 (WTR::convertElementsToObjectArray): Deleted. 54 1 55 2019-04-23 Guy Lewin <guy@lewin.co.il> 2 56 -
trunk/Tools/DumpRenderTree/AccessibilityTextMarker.h
r237266 r244561 76 76 static JSObjectRef makeJSAccessibilityTextMarkerRange(JSContextRef, const AccessibilityTextMarkerRange&); 77 77 bool isEqual(AccessibilityTextMarkerRange*); 78 78 79 static JSClassRef getJSClass(); 80 79 81 private: 80 static JSClassRef getJSClass();81 82 #if SUPPORTS_AX_TEXTMARKERS && PLATFORM(MAC) 82 83 RetainPtr<PlatformTextMarkerRange> m_textMarkerRange; -
trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp
r244062 r244561 279 279 return JSValueMakeString(context, result.get()); 280 280 } 281 282 #if PLATFORM(MAC) 283 static JSValueRef searchTextWithCriteriaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 284 { 285 if (argumentCount < 1) 286 return JSValueMakeUndefined(context); 287 288 JSValueRef searchStrings = arguments[0]; 289 JSRetainPtr<JSStringRef> startFrom; 290 if (argumentCount > 1) 291 startFrom = adopt(JSValueToStringCopy(context, arguments[1], exception)); 292 JSRetainPtr<JSStringRef> direction; 293 if (argumentCount > 2) 294 direction = adopt(JSValueToStringCopy(context, arguments[2], exception)); 295 296 return toAXElement(thisObject)->searchTextWithCriteria(context, searchStrings, startFrom.get(), direction.get()); 297 } 298 #endif 281 299 282 300 static JSValueRef indexOfChildCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) … … 1897 1915 { "uiElementForSearchPredicate", uiElementForSearchPredicateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1898 1916 { "selectTextWithCriteria", selectTextWithCriteriaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1917 #if PLATFORM(MAC) 1918 { "searchTextWithCriteria", searchTextWithCriteriaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1919 #endif 1899 1920 { "childAtIndex", childAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1900 1921 { "linkedUIElementAtIndex", linkedUIElementAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, -
trunk/Tools/DumpRenderTree/AccessibilityUIElement.h
r244059 r244561 219 219 AccessibilityUIElement uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly); 220 220 JSRetainPtr<JSStringRef> selectTextWithCriteria(JSContextRef, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity); 221 #if PLATFORM(MAC) 222 JSValueRef searchTextWithCriteria(JSContextRef, JSValueRef searchStrings, JSStringRef StartFrom, JSStringRef direction); 223 #endif 224 221 225 #if PLATFORM(IOS_FAMILY) 222 226 void elementsForRange(unsigned location, unsigned length, Vector<AccessibilityUIElement>& elements); -
trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
r244059 r244561 179 179 } 180 180 181 template<typename T> 182 static JSValueRef convertVectorToObjectArray(JSContextRef context, Vector<T> const& elements) 183 { 184 JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0); 185 JSObjectRef arrayObj = JSValueToObject(context, arrayResult, 0); 186 size_t elementCount = elements.size(); 187 for (size_t i = 0; i < elementCount; ++i) 188 JSObjectSetPropertyAtIndex(context, arrayObj, i, JSObjectMake(context, elements[i].getJSClass(), new T(elements[i])), 0); 189 190 return arrayResult; 191 } 192 181 193 static JSRetainPtr<JSStringRef> concatenateAttributeAndValue(NSString *attribute, NSString *value) 182 194 { … … 193 205 } 194 206 195 static void convertNSArrayToVector(NSArray* array, Vector<AccessibilityUIElement>& elementVector) 196 { 197 NSUInteger count = [array count]; 207 template<typename T> 208 static Vector<T> convertNSArrayToVector(NSArray *array) 209 { 210 Vector<T> v; 211 NSUInteger count = array.count; 212 v.reserveInitialCapacity(count); 198 213 for (NSUInteger i = 0; i < count; ++i) 199 elementVector.append(AccessibilityUIElement([array objectAtIndex:i])); 214 v.append([array objectAtIndex:i]); 215 return v; 200 216 } 201 217 … … 256 272 } 257 273 274 #if PLATFORM(MAC) 275 static NSDictionary *searchTextParameterizedAttributeForCriteria(JSContextRef context, JSValueRef searchStrings, JSStringRef startFrom, JSStringRef direction) 276 { 277 NSMutableDictionary *parameterizedAttribute = [NSMutableDictionary dictionary]; 278 279 if (searchStrings) { 280 NSMutableArray *searchStringsParameter = [NSMutableArray array]; 281 if (JSValueIsString(context, searchStrings)) { 282 auto searchStringsString = adopt(JSValueToStringCopy(context, searchStrings, nullptr)); 283 if (searchStringsString) 284 [searchStringsParameter addObject:[NSString stringWithJSStringRef:searchStringsString.get()]]; 285 } else if (JSValueIsObject(context, searchStrings)) { 286 JSObjectRef searchStringsArray = JSValueToObject(context, searchStrings, nullptr); 287 unsigned searchStringsArrayLength = 0; 288 289 auto lengthPropertyString = adopt(JSStringCreateWithUTF8CString("length")); 290 JSValueRef searchStringsArrayLengthValue = JSObjectGetProperty(context, searchStringsArray, lengthPropertyString.get(), nullptr); 291 if (searchStringsArrayLengthValue && JSValueIsNumber(context, searchStringsArrayLengthValue)) 292 searchStringsArrayLength = static_cast<unsigned>(JSValueToNumber(context, searchStringsArrayLengthValue, nullptr)); 293 294 for (unsigned i = 0; i < searchStringsArrayLength; ++i) { 295 auto searchStringsString = adopt(JSValueToStringCopy(context, JSObjectGetPropertyAtIndex(context, searchStringsArray, i, nullptr), nullptr)); 296 if (searchStringsString) 297 [searchStringsParameter addObject:[NSString stringWithJSStringRef:searchStringsString.get()]]; 298 } 299 } 300 [parameterizedAttribute setObject:searchStringsParameter forKey:@"AXSearchTextSearchStrings"]; 301 } 302 303 if (startFrom) 304 [parameterizedAttribute setObject:[NSString stringWithJSStringRef:startFrom] forKey:@"AXSearchTextStartFrom"]; 305 306 if (direction) 307 [parameterizedAttribute setObject:[NSString stringWithJSStringRef:direction] forKey:@"AXSearchTextDirection"]; 308 309 return parameterizedAttribute; 310 } 311 #endif 312 258 313 void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elementVector) 259 314 { 260 315 BEGIN_AX_OBJC_EXCEPTIONS 261 316 NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; 262 convertNSArrayToVector(linkedElements, elementVector);317 elementVector = convertNSArrayToVector<AccessibilityUIElement>(linkedElements); 263 318 END_AX_OBJC_EXCEPTIONS 264 319 } … … 268 323 BEGIN_AX_OBJC_EXCEPTIONS 269 324 NSArray* linkElements = [m_element accessibilityAttributeValue:@"AXLinkUIElements"]; 270 convertNSArrayToVector(linkElements, elementVector);325 elementVector = convertNSArrayToVector<AccessibilityUIElement>(linkElements); 271 326 END_AX_OBJC_EXCEPTIONS 272 327 } … … 276 331 BEGIN_AX_OBJC_EXCEPTIONS 277 332 NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute]; 278 convertNSArrayToVector(children, elementVector);333 elementVector = convertNSArrayToVector<AccessibilityUIElement>(children); 279 334 END_AX_OBJC_EXCEPTIONS 280 335 } … … 284 339 BEGIN_AX_OBJC_EXCEPTIONS 285 340 NSArray* children = [m_element accessibilityArrayAttributeValues:NSAccessibilityChildrenAttribute index:location maxCount:length]; 286 convertNSArrayToVector(children, elementVector);341 elementVector = convertNSArrayToVector<AccessibilityUIElement>(children); 287 342 END_AX_OBJC_EXCEPTIONS 288 343 } … … 493 548 id value = [m_element accessibilityAttributeValue:NSAccessibilityRowHeaderUIElementsAttribute]; 494 549 if ([value isKindOfClass:[NSArray class]]) 495 convertNSArrayToVector(value, elements);550 elements = convertNSArrayToVector<AccessibilityUIElement>(value); 496 551 END_AX_OBJC_EXCEPTIONS 497 552 } … … 502 557 id value = [m_element accessibilityAttributeValue:NSAccessibilityColumnHeaderUIElementsAttribute]; 503 558 if ([value isKindOfClass:[NSArray class]]) 504 convertNSArrayToVector(value, elements);559 elements = convertNSArrayToVector<AccessibilityUIElement>(value); 505 560 END_AX_OBJC_EXCEPTIONS 506 561 } … … 511 566 id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]]; 512 567 if ([value isKindOfClass:[NSArray class]]) 513 convertNSArrayToVector(value, elements);568 elements = convertNSArrayToVector<AccessibilityUIElement>(value); 514 569 END_AX_OBJC_EXCEPTIONS 515 570 } … … 1104 1159 } 1105 1160 1161 #if PLATFORM(MAC) 1162 JSValueRef AccessibilityUIElement::searchTextWithCriteria(JSContextRef context, JSValueRef searchStrings, JSStringRef startFrom, JSStringRef direction) 1163 { 1164 BEGIN_AX_OBJC_EXCEPTIONS 1165 NSDictionary *parameterizedAttribute = searchTextParameterizedAttributeForCriteria(context, searchStrings, startFrom, direction); 1166 id result = [m_element accessibilityAttributeValue:@"AXSearchTextWithCriteria" forParameter:parameterizedAttribute]; 1167 if ([result isKindOfClass:[NSArray class]]) 1168 return convertVectorToObjectArray<AccessibilityTextMarkerRange>(context, convertNSArrayToVector<AccessibilityTextMarkerRange>(result)); 1169 END_AX_OBJC_EXCEPTIONS 1170 return nullptr; 1171 } 1172 #endif 1173 1106 1174 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders() 1107 1175 { … … 1109 1177 BEGIN_AX_OBJC_EXCEPTIONS 1110 1178 NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"]; 1111 Vector<AccessibilityUIElement> columnHeadersVector; 1112 convertNSArrayToVector(columnHeadersArray, columnHeadersVector); 1179 auto columnHeadersVector = convertNSArrayToVector<AccessibilityUIElement>(columnHeadersArray); 1113 1180 return descriptionOfElements(columnHeadersVector); 1114 1181 END_AX_OBJC_EXCEPTIONS … … 1121 1188 BEGIN_AX_OBJC_EXCEPTIONS 1122 1189 NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"]; 1123 Vector<AccessibilityUIElement> rowHeadersVector; 1124 convertNSArrayToVector(rowHeadersArray, rowHeadersVector); 1190 auto rowHeadersVector = convertNSArrayToVector<AccessibilityUIElement>(rowHeadersArray); 1125 1191 return descriptionOfElements(rowHeadersVector); 1126 1192 END_AX_OBJC_EXCEPTIONS … … 1133 1199 BEGIN_AX_OBJC_EXCEPTIONS 1134 1200 NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute]; 1135 Vector<AccessibilityUIElement> columnsVector; 1136 convertNSArrayToVector(columnsArray, columnsVector); 1201 auto columnsVector = convertNSArrayToVector<AccessibilityUIElement>(columnsArray); 1137 1202 return descriptionOfElements(columnsVector); 1138 1203 END_AX_OBJC_EXCEPTIONS … … 1145 1210 BEGIN_AX_OBJC_EXCEPTIONS 1146 1211 NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute]; 1147 Vector<AccessibilityUIElement> rowsVector; 1148 convertNSArrayToVector(rowsArray, rowsVector); 1212 auto rowsVector = convertNSArrayToVector<AccessibilityUIElement>(rowsArray); 1149 1213 return descriptionOfElements(rowsVector); 1150 1214 END_AX_OBJC_EXCEPTIONS … … 1157 1221 BEGIN_AX_OBJC_EXCEPTIONS 1158 1222 NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"]; 1159 Vector<AccessibilityUIElement> cellsVector; 1160 convertNSArrayToVector(cellsArray, cellsVector); 1223 auto cellsVector = convertNSArrayToVector<AccessibilityUIElement>(cellsArray); 1161 1224 return descriptionOfElements(cellsVector); 1162 1225 END_AX_OBJC_EXCEPTIONS -
trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp
r238098 r244561 92 92 void AccessibilityUIElement::setBoolAttributeValue(JSStringRef, bool) { } 93 93 void AccessibilityUIElement::setValue(JSStringRef) { } 94 JSValueRef AccessibilityUIElement::searchTextWithCriteria(JSContextRef, JSValueRef, JSStringRef, JSStringRef) { return nullptr; } 94 95 #endif 95 96 -
trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h
r244059 r244561 256 256 RefPtr<AccessibilityUIElement> uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly); 257 257 JSRetainPtr<JSStringRef> selectTextWithCriteria(JSContextRef, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity); 258 JSValueRef searchTextWithCriteria(JSContextRef, JSValueRef searchStrings, JSStringRef startFrom, JSStringRef direction); 258 259 259 260 // Text-specific -
trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl
r244059 r244561 184 184 [PassContext] AccessibilityUIElement uiElementForSearchPredicate(AccessibilityUIElement startElement, boolean isDirectionNext, object searchKey, DOMString searchText, boolean visibleOnly, boolean immediateDescendantsOnly); 185 185 [PassContext] DOMString selectTextWithCriteria(DOMString ambiguityResolution, object searchStrings, DOMString replacementString, DOMString activity); 186 [PassContext] object searchTextWithCriteria(object searchStrings, DOMString startFrom, DOMString direction); 186 187 boolean setSelectedTextRange(unsigned long location, unsigned long length); 187 188 -
trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm
r244059 r244561 193 193 } 194 194 195 static JSValueRef convertElementsToObjectArray(JSContextRef context, Vector<RefPtr<AccessibilityUIElement>>& elements) 195 template<typename T> 196 static JSValueRef convertVectorToObjectArray(JSContextRef context, Vector<T> const& elements) 196 197 { 197 198 JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0); … … 200 201 for (size_t i = 0; i < elementCount; ++i) 201 202 JSObjectSetPropertyAtIndex(context, arrayObj, i, JSObjectMake(context, elements[i]->wrapperClass(), elements[i].get()), 0); 202 203 203 204 return arrayResult; 204 205 } … … 218 219 } 219 220 220 static void convertNSArrayToVector(NSArray* array, Vector<RefPtr<AccessibilityUIElement> >& elementVector) 221 { 222 NSUInteger count = [array count]; 221 template<typename T> 222 static Vector<T> convertNSArrayToVector(NSArray *array) 223 { 224 Vector<T> v; 225 NSUInteger count = array.count; 226 v.reserveInitialCapacity(count); 223 227 for (NSUInteger i = 0; i < count; ++i) 224 elementVector.append(AccessibilityUIElement::create([array objectAtIndex:i])); 228 v.append(T::ValueType::create([array objectAtIndex:i])); 229 return v; 225 230 } 226 231 … … 282 287 } 283 288 289 static NSDictionary *searchTextParameterizedAttributeForCriteria(JSContextRef context, JSValueRef searchStrings, JSStringRef startFrom, JSStringRef direction) 290 { 291 NSMutableDictionary *parameterizedAttribute = [NSMutableDictionary dictionary]; 292 293 if (searchStrings) { 294 NSMutableArray *searchStringsParameter = [NSMutableArray array]; 295 if (JSValueIsString(context, searchStrings)) { 296 auto searchStringsString = adopt(JSValueToStringCopy(context, searchStrings, nullptr)); 297 if (searchStringsString) 298 [searchStringsParameter addObject:[NSString stringWithJSStringRef:searchStringsString.get()]]; 299 } else if (JSValueIsObject(context, searchStrings)) { 300 JSObjectRef searchStringsArray = JSValueToObject(context, searchStrings, nullptr); 301 unsigned searchStringsArrayLength = 0; 302 303 auto lengthPropertyString = adopt(JSStringCreateWithUTF8CString("length")); 304 JSValueRef searchStringsArrayLengthValue = JSObjectGetProperty(context, searchStringsArray, lengthPropertyString.get(), nullptr); 305 if (searchStringsArrayLengthValue && JSValueIsNumber(context, searchStringsArrayLengthValue)) 306 searchStringsArrayLength = static_cast<unsigned>(JSValueToNumber(context, searchStringsArrayLengthValue, nullptr)); 307 308 for (unsigned i = 0; i < searchStringsArrayLength; ++i) { 309 auto searchStringsString = adopt(JSValueToStringCopy(context, JSObjectGetPropertyAtIndex(context, searchStringsArray, i, nullptr), nullptr)); 310 if (searchStringsString) 311 [searchStringsParameter addObject:[NSString stringWithJSStringRef:searchStringsString.get()]]; 312 } 313 } 314 [parameterizedAttribute setObject:searchStringsParameter forKey:@"AXSearchTextSearchStrings"]; 315 } 316 317 if (startFrom) 318 [parameterizedAttribute setObject:[NSString stringWithJSStringRef:startFrom] forKey:@"AXSearchTextStartFrom"]; 319 320 if (direction) 321 [parameterizedAttribute setObject:[NSString stringWithJSStringRef:direction] forKey:@"AXSearchTextDirection"]; 322 323 return parameterizedAttribute; 324 } 325 284 326 void AccessibilityUIElement::getLinkedUIElements(Vector<RefPtr<AccessibilityUIElement> >& elementVector) 285 327 { 286 328 BEGIN_AX_OBJC_EXCEPTIONS 287 329 NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; 288 convertNSArrayToVector(linkedElements, elementVector);330 elementVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(linkedElements); 289 331 END_AX_OBJC_EXCEPTIONS 290 332 } … … 294 336 BEGIN_AX_OBJC_EXCEPTIONS 295 337 NSArray* linkElements = [m_element accessibilityAttributeValue:@"AXLinkUIElements"]; 296 convertNSArrayToVector(linkElements, elementVector);338 elementVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(linkElements); 297 339 END_AX_OBJC_EXCEPTIONS 298 340 } … … 303 345 id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]]; 304 346 if ([value isKindOfClass:[NSArray class]]) 305 convertNSArrayToVector(value, elements);347 elements = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(value); 306 348 END_AX_OBJC_EXCEPTIONS 307 349 } … … 311 353 BEGIN_AX_OBJC_EXCEPTIONS 312 354 NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute]; 313 convertNSArrayToVector(children, elementVector);355 elementVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(children); 314 356 END_AX_OBJC_EXCEPTIONS 315 357 } … … 319 361 BEGIN_AX_OBJC_EXCEPTIONS 320 362 NSArray* children = [m_element accessibilityArrayAttributeValues:NSAccessibilityChildrenAttribute index:location maxCount:length]; 321 convertNSArrayToVector(children, elementVector);363 elementVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(children); 322 364 END_AX_OBJC_EXCEPTIONS 323 365 } … … 332 374 id value = [m_element accessibilityAttributeValue:NSAccessibilityRowHeaderUIElementsAttribute]; 333 375 if ([value isKindOfClass:[NSArray class]]) 334 convertNSArrayToVector(value, elements);335 return convert ElementsToObjectArray(context, elements);376 elements = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(value); 377 return convertVectorToObjectArray<RefPtr<AccessibilityUIElement>>(context, elements); 336 378 END_AX_OBJC_EXCEPTIONS 337 379 } … … 346 388 id value = [m_element accessibilityAttributeValue:NSAccessibilityColumnHeaderUIElementsAttribute]; 347 389 if ([value isKindOfClass:[NSArray class]]) 348 convertNSArrayToVector(value, elements);349 return convert ElementsToObjectArray(context, elements);390 elements = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(value); 391 return convertVectorToObjectArray<RefPtr<AccessibilityUIElement>>(context, elements); 350 392 END_AX_OBJC_EXCEPTIONS 351 393 } … … 597 639 Vector<RefPtr<AccessibilityUIElement>> elements; 598 640 getUIElementsWithAttribute(attribute, elements); 599 return convert ElementsToObjectArray(context, elements);641 return convertVectorToObjectArray<RefPtr<AccessibilityUIElement>>(context, elements); 600 642 } 601 643 … … 1200 1242 } 1201 1243 1244 #if PLATFORM(MAC) 1245 JSValueRef AccessibilityUIElement::searchTextWithCriteria(JSContextRef context, JSValueRef searchStrings, JSStringRef startFrom, JSStringRef direction) 1246 { 1247 BEGIN_AX_OBJC_EXCEPTIONS 1248 NSDictionary *parameterizedAttribute = searchTextParameterizedAttributeForCriteria(context, searchStrings, startFrom, direction); 1249 id result = [m_element accessibilityAttributeValue:@"AXSearchTextWithCriteria" forParameter:parameterizedAttribute]; 1250 if ([result isKindOfClass:[NSArray class]]) 1251 return convertVectorToObjectArray<RefPtr<AccessibilityTextMarkerRange>>(context, convertNSArrayToVector<RefPtr<AccessibilityTextMarkerRange>>(result)); 1252 END_AX_OBJC_EXCEPTIONS 1253 1254 return nullptr; 1255 } 1256 #endif 1257 1202 1258 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders() 1203 1259 { … … 1205 1261 BEGIN_AX_OBJC_EXCEPTIONS 1206 1262 NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"]; 1207 Vector<RefPtr<AccessibilityUIElement> > columnHeadersVector; 1208 convertNSArrayToVector(columnHeadersArray, columnHeadersVector); 1263 auto columnHeadersVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(columnHeadersArray); 1209 1264 return descriptionOfElements(columnHeadersVector); 1210 1265 END_AX_OBJC_EXCEPTIONS … … 1217 1272 BEGIN_AX_OBJC_EXCEPTIONS 1218 1273 NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"]; 1219 Vector<RefPtr<AccessibilityUIElement> > rowHeadersVector; 1220 convertNSArrayToVector(rowHeadersArray, rowHeadersVector); 1274 auto rowHeadersVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(rowHeadersArray); 1221 1275 return descriptionOfElements(rowHeadersVector); 1222 1276 END_AX_OBJC_EXCEPTIONS … … 1229 1283 BEGIN_AX_OBJC_EXCEPTIONS 1230 1284 NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute]; 1231 Vector<RefPtr<AccessibilityUIElement> > columnsVector; 1232 convertNSArrayToVector(columnsArray, columnsVector); 1285 auto columnsVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(columnsArray); 1233 1286 return descriptionOfElements(columnsVector); 1234 1287 END_AX_OBJC_EXCEPTIONS … … 1241 1294 BEGIN_AX_OBJC_EXCEPTIONS 1242 1295 NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute]; 1243 Vector<RefPtr<AccessibilityUIElement> > rowsVector; 1244 convertNSArrayToVector(rowsArray, rowsVector); 1296 auto rowsVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(rowsArray); 1245 1297 return descriptionOfElements(rowsVector); 1246 1298 END_AX_OBJC_EXCEPTIONS … … 1253 1305 BEGIN_AX_OBJC_EXCEPTIONS 1254 1306 NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"]; 1255 Vector<RefPtr<AccessibilityUIElement> > cellsVector; 1256 convertNSArrayToVector(cellsArray, cellsVector); 1307 auto cellsVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(cellsArray); 1257 1308 return descriptionOfElements(cellsVector); 1258 1309 END_AX_OBJC_EXCEPTIONS
Note:
See TracChangeset
for help on using the changeset viewer.