Changeset 260865 in webkit
- Timestamp:
- Apr 28, 2020 10:16:23 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r260862 r260865 1 2020-04-28 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Text manipulation] Add a userInfo dictionary to _WKTextManipulationToken 4 https://bugs.webkit.org/show_bug.cgi?id=211151 5 <rdar://problem/62329534> 6 7 Reviewed by Darin Adler. 8 9 Add an extensible mechanism for the text manipulation controller to send additional 10 metadata for each text manipulation token through to the WebKit client, for debugging 11 purposes. 12 13 Test: TextManipulation.StartTextManipulationExtractsUserInfo 14 15 * editing/TextManipulationController.cpp: 16 (WebCore::tokenInfo): 17 (WebCore::TextManipulationController::observeParagraphs): 18 * editing/TextManipulationController.h: 19 20 Add TextManipulationTokenInfo, and add an optional TextManipulationTokenInfo member to 21 TextManipulationToken. For now, just send over the document URL, element tag name, and 22 the value of the role attribute. 23 24 (WebCore::TextManipulationController::ManipulationTokenInfo::encode const): 25 (WebCore::TextManipulationController::ManipulationTokenInfo::decode): 26 (WebCore::TextManipulationController::ManipulationToken::encode const): 27 (WebCore::TextManipulationController::ManipulationToken::decode): 28 1 29 2020-04-28 Simon Fraser <simon.fraser@apple.com> 2 30 -
trunk/Source/WebCore/editing/TextManipulationController.cpp
r260783 r260865 259 259 } 260 260 261 static Optional<TextManipulationController::ManipulationTokenInfo> tokenInfo(Node* node) 262 { 263 if (!node) 264 return WTF::nullopt; 265 266 TextManipulationController::ManipulationTokenInfo result; 267 result.documentURL = node->document().url(); 268 if (auto element = is<Element>(node) ? makeRefPtr(downcast<Element>(*node)) : makeRefPtr(node->parentElement())) { 269 result.tagName = element->tagName(); 270 if (element->hasAttributeWithoutSynchronization(HTMLNames::roleAttr)) 271 result.roleAttribute = element->attributeWithoutSynchronization(HTMLNames::roleAttr); 272 } 273 return result; 274 } 275 261 276 void TextManipulationController::observeParagraphs(const Position& start, const Position& end) 262 277 { … … 322 337 if (!content.isTextContent && canPerformTextManipulationByReplacingEntireTextContent(currentElement)) { 323 338 addItem(ManipulationItemData { Position(), Position(), makeWeakPtr(currentElement), nullQName(), 324 { ManipulationToken { m_tokenIdentifier.generate(), currentElement.textContent() } } });339 { ManipulationToken { m_tokenIdentifier.generate(), currentElement.textContent(), tokenInfo(¤tElement) } } }); 325 340 } 326 341 if (currentElement.hasAttributes()) { … … 328 343 if (isAttributeForTextManipulation(attribute.name())) { 329 344 addItem(ManipulationItemData { Position(), Position(), makeWeakPtr(currentElement), attribute.name(), 330 { ManipulationToken { m_tokenIdentifier.generate(), attribute.value() } } });345 { ManipulationToken { m_tokenIdentifier.generate(), attribute.value(), tokenInfo(¤tElement) } } }); 331 346 } 332 347 } … … 347 362 348 363 endOfCurrentParagraph = currentEndOfCurrentParagraph; 349 tokensInCurrentParagraph.append(ManipulationToken { m_tokenIdentifier.generate(), "[]", t rue });364 tokensInCurrentParagraph.append(ManipulationToken { m_tokenIdentifier.generate(), "[]", tokenInfo(content.node.get()), true }); 350 365 351 366 continue; … … 366 381 startOfCurrentParagraph = Position(&textNode, startOfCurrentLine); 367 382 368 tokensInCurrentParagraph.append(ManipulationToken { m_tokenIdentifier.generate(), stringUntilEndOfLine, exclusionRuleMatcher.isExcluded(content.node.get()) });383 tokensInCurrentParagraph.append(ManipulationToken { m_tokenIdentifier.generate(), stringUntilEndOfLine, tokenInfo(&textNode), exclusionRuleMatcher.isExcluded(content.node.get()) }); 369 384 } 370 385 … … 386 401 } 387 402 endOfCurrentParagraph = iterator.endPosition(); 388 tokensInCurrentParagraph.append(ManipulationToken { m_tokenIdentifier.generate(), remainingText.toString(), exclusionRuleMatcher.isExcluded(content.node.get()) });403 tokensInCurrentParagraph.append(ManipulationToken { m_tokenIdentifier.generate(), remainingText.toString(), tokenInfo(content.node.get()), exclusionRuleMatcher.isExcluded(content.node.get()) }); 389 404 } 390 405 } -
trunk/Source/WebCore/editing/TextManipulationController.h
r260609 r260865 49 49 using TokenIdentifier = ObjectIdentifier<TokenIdentifierType>; 50 50 51 struct ManipulationTokenInfo { 52 String tagName; 53 String roleAttribute; 54 URL documentURL; 55 56 template<class Encoder> void encode(Encoder&) const; 57 template<class Decoder> static Optional<ManipulationTokenInfo> decode(Decoder&); 58 }; 59 51 60 struct ManipulationToken { 52 61 TokenIdentifier identifier; 53 62 String content; 63 Optional<ManipulationTokenInfo> info; 54 64 bool isExcluded { false }; 55 65 … … 159 169 160 170 template<class Encoder> 171 void TextManipulationController::ManipulationTokenInfo::encode(Encoder& encoder) const 172 { 173 encoder << tagName; 174 encoder << roleAttribute; 175 encoder << documentURL; 176 } 177 178 template<class Decoder> 179 Optional<TextManipulationController::ManipulationTokenInfo> TextManipulationController::ManipulationTokenInfo::decode(Decoder& decoder) 180 { 181 ManipulationTokenInfo result; 182 if (!decoder.decode(result.tagName)) 183 return WTF::nullopt; 184 185 if (!decoder.decode(result.roleAttribute)) 186 return WTF::nullopt; 187 188 if (!decoder.decode(result.documentURL)) 189 return WTF::nullopt; 190 191 return result; 192 } 193 194 template<class Encoder> 161 195 void TextManipulationController::ManipulationToken::encode(Encoder& encoder) const 162 196 { 163 encoder << identifier << content << i sExcluded;197 encoder << identifier << content << info << isExcluded; 164 198 } 165 199 … … 171 205 return WTF::nullopt; 172 206 if (!decoder.decode(result.content)) 207 return WTF::nullopt; 208 if (!decoder.decode(result.info)) 173 209 return WTF::nullopt; 174 210 if (!decoder.decode(result.isExcluded)) -
trunk/Source/WebKit/ChangeLog
r260864 r260865 1 2020-04-28 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Text manipulation] Add a userInfo dictionary to _WKTextManipulationToken 4 https://bugs.webkit.org/show_bug.cgi?id=211151 5 <rdar://problem/62329534> 6 7 Reviewed by Darin Adler. 8 9 * UIProcess/API/Cocoa/WKWebView.mm: 10 (createUserInfo): 11 (-[WKWebView _startTextManipulationsWithConfiguration:completion:]): 12 (-[WKWebView _completeTextManipulation:completion:]): 13 (-[WKWebView _completeTextManipulationForItems:completion:]): 14 * UIProcess/API/Cocoa/_WKTextManipulationToken.h: 15 * UIProcess/API/Cocoa/_WKTextManipulationToken.mm: 16 (-[_WKTextManipulationToken setUserInfo:]): 17 (-[_WKTextManipulationToken userInfo]): 18 19 Add a new `userInfo` dictionary to `_WKTextManipulationToken`, which contains several named 20 `NSString` keys. 21 22 (-[_WKTextManipulationToken isEqualToTextManipulationToken:includingContentEquality:]): 23 (-[_WKTextManipulationToken _descriptionPreservingPrivacy:]): 24 1 25 2020-04-28 David Kilzer <ddkilzer@apple.com> 2 26 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
r260787 r260865 1607 1607 } 1608 1608 1609 static RetainPtr<NSDictionary<NSString *, id>> createUserInfo(const Optional<WebCore::TextManipulationController::ManipulationTokenInfo>& info) 1610 { 1611 if (!info) 1612 return { }; 1613 1614 auto result = adoptNS([[NSMutableDictionary alloc] initWithCapacity:3]); 1615 if (!info->documentURL.isNull()) 1616 [result setObject:(NSURL *)info->documentURL forKey:_WKTextManipulationTokenUserInfoDocumentURLKey]; 1617 if (!info->tagName.isNull()) 1618 [result setObject:(NSString *)info->tagName forKey:_WKTextManipulationTokenUserInfoTagNameKey]; 1619 if (!info->roleAttribute.isNull()) 1620 [result setObject:(NSString *)info->roleAttribute forKey:_WKTextManipulationTokenUserInfoRoleAttributeKey]; 1621 1622 return result; 1623 } 1624 1609 1625 - (void)_startTextManipulationsWithConfiguration:(_WKTextManipulationConfiguration *)configuration completion:(void(^)())completionHandler 1610 1626 { … … 1644 1660 [wkToken setContent:token.content]; 1645 1661 [wkToken setExcluded:token.isExcluded]; 1662 [wkToken setUserInfo:createUserInfo(token.info).get()]; 1646 1663 return wkToken; 1647 1664 }); … … 1681 1698 Vector<WebCore::TextManipulationController::ManipulationToken> tokens; 1682 1699 for (_WKTextManipulationToken *wkToken in item.tokens) 1683 tokens.append(WebCore::TextManipulationController::ManipulationToken { coreTextManipulationTokenIdentifierFromString(wkToken.identifier), wkToken.content });1700 tokens.append(WebCore::TextManipulationController::ManipulationToken { coreTextManipulationTokenIdentifierFromString(wkToken.identifier), wkToken.content, WTF::nullopt }); 1684 1701 1685 1702 Vector<WebCore::TextManipulationController::ManipulationItem> coreItems; … … 1740 1757 coreTokens.reserveInitialCapacity(wkItem.tokens.count); 1741 1758 for (_WKTextManipulationToken *wkToken in wkItem.tokens) 1742 coreTokens.uncheckedAppend(WebCore::TextManipulationController::ManipulationToken { coreTextManipulationTokenIdentifierFromString(wkToken.identifier), wkToken.content });1759 coreTokens.uncheckedAppend(WebCore::TextManipulationController::ManipulationToken { coreTextManipulationTokenIdentifierFromString(wkToken.identifier), wkToken.content, WTF::nullopt }); 1743 1760 coreItems.uncheckedAppend(WebCore::TextManipulationController::ManipulationItem { coreTextManipulationItemIdentifierFromString(wkItem.identifier), WTFMove(coreTokens) }); 1744 1761 } -
trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.h
r260334 r260865 29 29 NS_ASSUME_NONNULL_BEGIN 30 30 31 WK_EXTERN NSString * const _WKTextManipulationTokenUserInfoDocumentURLKey WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 32 WK_EXTERN NSString * const _WKTextManipulationTokenUserInfoTagNameKey WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 33 WK_EXTERN NSString * const _WKTextManipulationTokenUserInfoRoleAttributeKey WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 34 31 35 WK_CLASS_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)) 32 36 @interface _WKTextManipulationToken : NSObject … … 39 43 @property (nonatomic, copy, readonly) NSString *debugDescription; 40 44 45 @property (nonatomic, nullable, copy) NSDictionary<NSString *, id> *userInfo; 46 41 47 @end 42 48 -
trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm
r259280 r260865 27 27 #import "_WKTextManipulationToken.h" 28 28 29 @implementation _WKTextManipulationToken 29 #import <wtf/RetainPtr.h> 30 31 NSString * const _WKTextManipulationTokenUserInfoDocumentURLKey = @"_WKTextManipulationTokenUserInfoDocumentURLKey"; 32 NSString * const _WKTextManipulationTokenUserInfoTagNameKey = @"_WKTextManipulationTokenUserInfoTagNameKey"; 33 NSString * const _WKTextManipulationTokenUserInfoRoleAttributeKey = @"_WKTextManipulationTokenUserInfoRoleAttributeKey"; 34 35 @implementation _WKTextManipulationToken { 36 RetainPtr<NSDictionary<NSString *, id>> _userInfo; 37 } 30 38 31 39 - (void)dealloc … … 37 45 38 46 [super dealloc]; 47 } 48 49 - (void)setUserInfo:(NSDictionary<NSString *, id> *)userInfo 50 { 51 if (userInfo == _userInfo || [_userInfo isEqual:userInfo]) 52 return; 53 54 _userInfo = adoptNS(userInfo.copy); 55 } 56 57 - (NSDictionary<NSString *, id> *)userInfo 58 { 59 return _userInfo.get(); 39 60 } 40 61 … … 66 87 BOOL equalExclusion = self.isExcluded == otherToken.isExcluded; 67 88 BOOL equalContent = !includingContentEquality || isEqualOrBothNil(self.content, otherToken.content); 89 BOOL equalUserInfo = isEqualOrBothNil(self.userInfo, otherToken.userInfo); 68 90 69 return equalIdentifiers && equalExclusion && equalContent ;91 return equalIdentifiers && equalExclusion && equalContent && equalUserInfo; 70 92 } 71 93 … … 86 108 [description appendFormat:@"; content length = %lu", (unsigned long)self.content.length]; 87 109 else 88 [description appendFormat:@"; content = %@ ", self.content];110 [description appendFormat:@"; content = %@; user info = %@", self.content, self.userInfo]; 89 111 90 112 [description appendString:@">"]; -
trunk/Tools/ChangeLog
r260860 r260865 1 2020-04-28 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Text manipulation] Add a userInfo dictionary to _WKTextManipulationToken 4 https://bugs.webkit.org/show_bug.cgi?id=211151 5 <rdar://problem/62329534> 6 7 Reviewed by Darin Adler. 8 9 Add a new API test to check the userInfo dictionary on text manipulation tokens. 10 11 * TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm: 12 1 13 2020-04-28 David Kilzer <ddkilzer@apple.com> 2 14 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm
r260783 r260865 705 705 } 706 706 707 TEST(TextManipulation, StartTextManipulationExtractsUserInfo) 708 { 709 auto delegate = adoptNS([[TextManipulationDelegate alloc] init]); 710 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]); 711 [webView _setTextManipulationDelegate:delegate.get()]; 712 713 [webView synchronouslyLoadHTMLString:@"<!DOCTYPE html>" 714 "<body>" 715 " <title>This is a test</title>" 716 " <p>First</p>" 717 " <div role='button'>Second</div>" 718 " <span>Third</span>" 719 "</body>"]; 720 721 done = false; 722 [webView _startTextManipulationsWithConfiguration:nil completion:^{ 723 done = true; 724 }]; 725 TestWebKitAPI::Util::run(&done); 726 727 auto items = [delegate items]; 728 EXPECT_EQ(items.count, 4UL); 729 EXPECT_EQ(items[0].tokens.count, 1UL); 730 EXPECT_EQ(items[1].tokens.count, 1UL); 731 EXPECT_EQ(items[2].tokens.count, 1UL); 732 EXPECT_EQ(items[3].tokens.count, 1UL); 733 EXPECT_WK_STREQ("This is a test", items[0].tokens[0].content); 734 EXPECT_WK_STREQ("First", items[1].tokens[0].content); 735 EXPECT_WK_STREQ("Second", items[2].tokens[0].content); 736 EXPECT_WK_STREQ("Third", items[3].tokens[0].content); 737 { 738 auto userInfo = items[0].tokens[0].userInfo; 739 EXPECT_WK_STREQ("TestWebKitAPI.resources", [(NSURL *)userInfo[_WKTextManipulationTokenUserInfoDocumentURLKey] lastPathComponent]); 740 EXPECT_WK_STREQ("TITLE", (NSString *)userInfo[_WKTextManipulationTokenUserInfoTagNameKey]); 741 } 742 { 743 auto userInfo = items[1].tokens[0].userInfo; 744 EXPECT_WK_STREQ("TestWebKitAPI.resources", [(NSURL *)userInfo[_WKTextManipulationTokenUserInfoDocumentURLKey] lastPathComponent]); 745 EXPECT_WK_STREQ("P", (NSString *)userInfo[_WKTextManipulationTokenUserInfoTagNameKey]); 746 } 747 { 748 auto userInfo = items[2].tokens[0].userInfo; 749 EXPECT_WK_STREQ("TestWebKitAPI.resources", [(NSURL *)userInfo[_WKTextManipulationTokenUserInfoDocumentURLKey] lastPathComponent]); 750 EXPECT_WK_STREQ("DIV", (NSString *)userInfo[_WKTextManipulationTokenUserInfoTagNameKey]); 751 EXPECT_WK_STREQ("button", (NSString *)userInfo[_WKTextManipulationTokenUserInfoRoleAttributeKey]); 752 } 753 { 754 auto userInfo = items[3].tokens[0].userInfo; 755 EXPECT_WK_STREQ("TestWebKitAPI.resources", [(NSURL *)userInfo[_WKTextManipulationTokenUserInfoDocumentURLKey] lastPathComponent]); 756 EXPECT_WK_STREQ("SPAN", (NSString *)userInfo[_WKTextManipulationTokenUserInfoTagNameKey]); 757 } 758 } 759 707 760 struct Token { 708 761 NSString *identifier;
Note: See TracChangeset
for help on using the changeset viewer.