Changeset 245803 in webkit
- Timestamp:
- May 27, 2019 6:03:10 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r245801 r245803 1 2019-05-27 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [iOS] Dropping in an editable element should result in a ranged selection 4 https://bugs.webkit.org/show_bug.cgi?id=198267 5 <rdar://problem/51145977> 6 7 Reviewed by Tim Horton. 8 9 When drag and drop was first implemented for iOS in iOS 11, selection behavior when dropping into editable 10 elements matched that of macOS, by leaving the inserted content selected after performing the drop. However, in 11 other parts of the platform (e.g. Notes), both the keyboard and selection views are not shown after a drop. 12 13 Instead of matching macOS behavior, WebKit on iOS should match the rest of the platform. This is a little 14 tricky, since we use the selection range after a drop to create a TextIndicator snapshot when creating a drag 15 preview. To resolve this, we refactor some of the logic introduced in r245778 to remember the DOM range to 16 snapshot before collapsing the range to the end of the inserted content. 17 18 Tested by adjusting some existing API tests. 19 20 * UIProcess/ios/WKContentViewInteraction.mm: 21 (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:]): 22 23 Remove some logic that currently presents the keyboard while the user is performing a drop that focuses an 24 editable element. 25 26 * WebProcess/WebPage/WebPage.h: 27 28 Add a member variable to keep track of which range should be snapshotted when generating a drop preview. 29 30 * WebProcess/WebPage/ios/WebPageIOS.mm: 31 (WebKit::WebPage::didConcludeDrop): 32 (WebKit::WebPage::didConcludeEditDrag): 33 34 Collapse the selection range to the end after an edit drag (i.e., a drop in an editable area that inserted 35 content). 36 37 (WebKit::WebPage::computeAndSendEditDragSnapshot): 38 1 39 2019-05-27 Chris Dumez <cdumez@apple.com> 2 40 -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
r245778 r245803 5075 5075 return YES; 5076 5076 5077 #if ENABLE(DRAG_SUPPORT)5078 if (_dragDropInteractionState.isPerformingDrop())5079 return YES;5080 #endif5081 5082 5077 if (self.isFirstResponder || _becomingFirstResponder) { 5083 5078 // When the software keyboard is being used to enter an url, only the focus activity state is changing. -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.h
r245796 r245803 1781 1781 #if ENABLE(DRAG_SUPPORT) && PLATFORM(IOS_FAMILY) 1782 1782 HashSet<RefPtr<WebCore::HTMLImageElement>> m_pendingImageElementsForDropSnapshot; 1783 RefPtr<WebCore::Range> m_rangeForDropSnapshot; 1783 1784 #endif 1784 1785 -
trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
r245787 r245803 828 828 void WebPage::didConcludeDrop() 829 829 { 830 m_rangeForDropSnapshot = nullptr; 830 831 m_pendingImageElementsForDropSnapshot.clear(); 831 832 } … … 840 841 841 842 bool waitingForAnyImageToLoad = false; 842 auto & frame = m_page->focusController().focusedOrMainFrame();843 if (auto range = frame.selection().selection().toNormalizedRange()) {844 for (TextIterator iterator( range.get()); !iterator.atEnd(); iterator.advance()) {843 auto frame = makeRef(m_page->focusController().focusedOrMainFrame()); 844 if (auto selectionRange = frame->selection().selection().toNormalizedRange()) { 845 for (TextIterator iterator(selectionRange.get()); !iterator.atEnd(); iterator.advance()) { 845 846 auto* node = iterator.node(); 846 847 if (!is<HTMLImageElement>(node)) … … 854 855 } 855 856 } 857 auto collapsedRange = Range::create(selectionRange->ownerDocument(), selectionRange->endPosition(), selectionRange->endPosition()); 858 frame->selection().setSelectedRange(collapsedRange.ptr(), DOWNSTREAM, FrameSelection::ShouldCloseTyping::Yes, UserTriggered); 859 860 m_rangeForDropSnapshot = WTFMove(selectionRange); 856 861 } 857 862 … … 875 880 Optional<TextIndicatorData> textIndicatorData; 876 881 static auto defaultTextIndicatorOptionsForEditDrag = TextIndicatorOptionIncludeSnapshotOfAllVisibleContentWithoutSelection | TextIndicatorOptionExpandClipBeyondVisibleRect | TextIndicatorOptionPaintAllContent | TextIndicatorOptionIncludeMarginIfRangeMatchesSelection | TextIndicatorOptionPaintBackgrounds | TextIndicatorOptionComputeEstimatedBackgroundColor| TextIndicatorOptionUseSelectionRectForSizing | TextIndicatorOptionIncludeSnapshotWithSelectionHighlight; 877 auto& frame = m_page->focusController().focusedOrMainFrame(); 878 if (auto range = frame.selection().selection().toNormalizedRange()) { 882 if (auto range = std::exchange(m_rangeForDropSnapshot, nullptr)) { 879 883 if (auto textIndicator = TextIndicator::createWithRange(*range, defaultTextIndicatorOptionsForEditDrag, TextIndicatorPresentationTransition::None, { })) 880 884 textIndicatorData = textIndicator->data(); -
trunk/Tools/ChangeLog
r245798 r245803 1 2019-05-27 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [iOS] Dropping in an editable element should result in a ranged selection 4 https://bugs.webkit.org/show_bug.cgi?id=198267 5 <rdar://problem/51145977> 6 7 Reviewed by Tim Horton. 8 9 Adjust some existing API tests that currently check for selection rects after a drop. Instead of checking for 10 visible selection rects, simply check for the start caret rect, as determined by WKContentView's 11 -selectionRange. 12 13 * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm: 14 (TestWebKitAPI::TEST): 15 (makeCGRectValue): Deleted. 16 (checkSelectionRectsWithLogging): Deleted. 17 * TestWebKitAPI/cocoa/DragAndDropSimulator.h: 18 19 Replace finalSelectionRects with finalSelectionStartRect. 20 21 * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm: 22 (-[DragAndDropSimulator _resetSimulatedState]): 23 (-[DragAndDropSimulator runFrom:to:additionalItemRequestLocations:]): 24 (-[DragAndDropSimulator finalSelectionRects]): Deleted. 25 1 26 2019-05-27 Oriol Brufau <obrufau@igalia.com> 2 27 -
trunk/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm
r245778 r245803 118 118 } 119 119 120 static NSValue *makeCGRectValue(CGFloat x, CGFloat y, CGFloat width, CGFloat height)121 {122 return [NSValue valueWithCGRect:CGRectMake(x, y, width, height)];123 }124 125 120 static void checkCGRectIsEqualToCGRectWithLogging(CGRect expected, CGRect observed) 126 121 { … … 129 124 if (!isEqual) 130 125 NSLog(@"Expected: %@ but observed: %@", NSStringFromCGRect(expected), NSStringFromCGRect(observed)); 131 }132 133 static void checkSelectionRectsWithLogging(NSArray *expected, NSArray *observed)134 {135 if (![expected isEqualToArray:observed])136 NSLog(@"Expected selection rects: %@ but observed: %@", expected, observed);137 EXPECT_TRUE([expected isEqualToArray:observed]);138 126 } 139 127 … … 276 264 EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); 277 265 EXPECT_TRUE([observedEventNames containsObject:@"drop"]); 278 check SelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 215, 174) ], [simulator finalSelectionRects]);266 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(214, 201, 2, 174), [simulator finalSelectionStartRect]); 279 267 checkFirstTypeIsPresentAndSecondTypeIsMissing(simulator.get(), kUTTypePNG, kUTTypeFileURL); 280 268 checkEstimatedSize(simulator.get(), { 215, 174 }); … … 321 309 322 310 EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String); 323 check SelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 2057, 232) ], [simulator finalSelectionRects]);311 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(2156, 241, 2, 232), [simulator finalSelectionStartRect]); 324 312 checkSuggestedNameAndEstimatedSize(simulator.get(), @"icon.png", { 215, 174 }); 325 313 checkTypeIdentifierIsRegisteredAtIndex(simulator.get(), (__bridge NSString *)kUTTypePNG, 0); … … 391 379 EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); 392 380 EXPECT_TRUE([observedEventNames containsObject:@"drop"]); 393 check SelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 961, 227) ], [simulator finalSelectionRects]);381 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(960, 201, 2, 227), [simulator finalSelectionStartRect]); 394 382 checkRichTextTypePrecedesPlainTextType(simulator.get()); 395 383 EXPECT_TRUE([simulator lastKnownDropProposal].precise); … … 415 403 EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); 416 404 EXPECT_TRUE([observedEventNames containsObject:@"drop"]); 417 check SelectionRectsWithLogging(@[ makeCGRectValue(101, 203, 990, 232) ], [simulator finalSelectionRects]);405 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(1089, 203, 2, 232), [simulator finalSelectionStartRect]); 418 406 checkRichTextTypePrecedesPlainTextType(simulator.get()); 419 407 EXPECT_TRUE([simulator lastKnownDropProposal].precise); … … 472 460 EXPECT_FALSE(secondParagraphOffset == NSNotFound); 473 461 EXPECT_GT(firstParagraphOffset, secondParagraphOffset); 474 check SelectionRectsWithLogging(@[ makeCGRectValue(190, 100, 130, 20), makeCGRectValue(0, 120, 320, 100), makeCGRectValue(0, 220, 252, 20) ], [simulator finalSelectionRects]);462 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(251, 220, 2, 20), [simulator finalSelectionStartRect]); 475 463 EXPECT_TRUE([simulator lastKnownDropProposal].precise); 476 464 } … … 498 486 EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.value"].length, 0UL); 499 487 EXPECT_WK_STREQ("Hello world", [webView editorValue].UTF8String); 500 check SelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 990, 232) ], [simulator finalSelectionRects]);488 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(1089, 241, 2, 232), [simulator finalSelectionStartRect]); 501 489 } 502 490 … … 569 557 EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); 570 558 EXPECT_TRUE([observedEventNames containsObject:@"drop"]); 571 check SelectionRectsWithLogging(@[ makeCGRectValue(101, 273, 2057, 232) ], [simulator finalSelectionRects]);559 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(2156, 273, 2, 232), [simulator finalSelectionStartRect]); 572 560 checkTypeIdentifierIsRegisteredAtIndex(simulator.get(), (__bridge NSString *)kUTTypeURL, 0); 573 561 } … … 587 575 EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); 588 576 EXPECT_TRUE([observedEventNames containsObject:@"drop"]); 589 check SelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 2057, 232) ], [simulator finalSelectionRects]);577 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(2156, 241, 2, 232), [simulator finalSelectionStartRect]); 590 578 checkTypeIdentifierIsRegisteredAtIndex(simulator.get(), (__bridge NSString *)kUTTypeURL, 0); 591 579 } … … 605 593 EXPECT_FALSE([observedEventNames containsObject:@"dragenter"]); 606 594 EXPECT_FALSE([observedEventNames containsObject:@"dragover"]); 607 check SelectionRectsWithLogging(@[ ], [simulator finalSelectionRects]);595 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(0, 0, 0, 0), [simulator finalSelectionStartRect]); 608 596 } 609 597 … … 621 609 EXPECT_TRUE([observedEventNames containsObject:@"dragenter"]); 622 610 EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); 623 check SelectionRectsWithLogging(@[ ], [simulator finalSelectionRects]);611 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(0, 0, 0, 0), [simulator finalSelectionStartRect]); 624 612 } 625 613 … … 639 627 EXPECT_TRUE([observedEventNames containsObject:@"dragleave"]); 640 628 EXPECT_FALSE([observedEventNames containsObject:@"drop"]); 641 check SelectionRectsWithLogging(@[ ], [simulator finalSelectionRects]);629 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(0, 0, 0, 0), [simulator finalSelectionStartRect]); 642 630 } 643 631 … … 1026 1014 [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; 1027 1015 EXPECT_WK_STREQ(textPayload.UTF8String, [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String); 1028 check SelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 1936, 227) ], [simulator finalSelectionRects]);1016 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(1935, 201, 2, 227), [simulator finalSelectionStartRect]); 1029 1017 } 1030 1018 … … 1046 1034 [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; 1047 1035 EXPECT_TRUE([webView editorContainsImageElement]); 1048 check SelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 215, 174) ], [simulator finalSelectionRects]);1036 checkCGRectIsEqualToCGRectWithLogging(CGRectMake(214, 201, 2, 223), [simulator finalSelectionStartRect]); 1049 1037 } 1050 1038 -
trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h
r245778 r245803 109 109 @property (nonatomic, readonly) NSArray *sourceItemProviders; 110 110 @property (nonatomic, readonly) NSArray *observedEventNames; 111 @property (nonatomic, readonly) NSArray *finalSelectionRects;111 @property (nonatomic, readonly) CGRect finalSelectionStartRect; 112 112 @property (nonatomic, readonly) CGRect lastKnownDragCaretRect; 113 113 @property (nonatomic, readonly) NSArray<UITargetedDragPreview *> *liftPreviews; -
trunk/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm
r245778 r245803 304 304 RetainPtr<NSArray> _externalItemProviders; 305 305 RetainPtr<NSArray> _sourceItemProviders; 306 RetainPtr<NSArray> _finalSelectionRects;306 CGRect _finalSelectionStartRect; 307 307 CGPoint _startLocation; 308 308 CGPoint _endLocation; … … 382 382 _insertedAttachments = adoptNS([[NSMutableArray alloc] init]); 383 383 _removedAttachments = adoptNS([[NSMutableArray alloc] init]); 384 _finalSelection Rects = @[ ];384 _finalSelectionStartRect = CGRectNull; 385 385 _dragSession = nil; 386 386 _dropSession = nil; … … 464 464 Util::run(&_isDoneWaitingForDelayedDropPreviews); 465 465 [_webView clearMessageHandlers:dragAndDropEventNames()]; 466 _finalSelectionRects = [_webView selectionRectsAfterPresentationUpdate]; 466 [_webView waitForNextPresentationUpdate]; 467 468 auto contentView = [_webView textInputContentView]; 469 _finalSelectionStartRect = [contentView caretRectForPosition:contentView.selectedTextRange.start]; 467 470 468 471 [defaultCenter removeObserver:self]; 469 }470 471 - (NSArray *)finalSelectionRects472 {473 return _finalSelectionRects.get();474 472 } 475 473
Note: See TracChangeset
for help on using the changeset viewer.