Changeset 238728 in webkit
- Timestamp:
- Nov 29, 2018 11:22:00 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r238726 r238728 1 2018-11-29 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 REGRESSION (r238635): Dragging a text selection within WKWebView causes the selection highlight to get into a bad state 4 https://bugs.webkit.org/show_bug.cgi?id=192165 5 <rdar://problem/46346682> 6 7 Reviewed by Daniel Bates. 8 9 Fixes a bug in PageClientImpl::isViewFocused. Consider the following scenario: 10 1. WKWebView is hosted within the view hierarchy 11 2. First responder is *not* WKContentView 12 3. The active focus retain count is nonzero 13 14 Before r238635, we would return true, due to condition (3). However, after r238635, we only consider whether the 15 first responder is WKContentView, since the web view is in the view hierarchy. This breaks scenarios where 16 WebKit or UIKit attempts to retain focus and later restore the content view to be the first responder (an 17 example of this is dragging a text selection between editable elements in the same web view). 18 19 To fix this, simply bail early and return true if focus is being retained. 20 21 * UIProcess/ios/PageClientImplIOS.mm: 22 (WebKit::PageClientImpl::isViewFocused): 23 1 24 2018-11-29 Tim Horton <timothy_horton@apple.com> 2 25 -
trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
r238635 r238728 167 167 bool PageClientImpl::isViewFocused() 168 168 { 169 if (isViewInWindow() && ![m_webView _isBackground]) 170 return [m_webView _contentViewIsFirstResponder]; 171 return [m_webView _isRetainingActiveFocusedState]; 169 return (isViewInWindow() && ![m_webView _isBackground] && [m_webView _contentViewIsFirstResponder]) || [m_webView _isRetainingActiveFocusedState]; 172 170 } 173 171 -
trunk/Tools/ChangeLog
r238726 r238728 1 2018-11-29 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 REGRESSION (r238635): Dragging a text selection within WKWebView causes the selection highlight to get into a bad state 4 https://bugs.webkit.org/show_bug.cgi?id=192165 5 <rdar://problem/46346682> 6 7 Reviewed by Daniel Bates. 8 9 Fixes 11 API tests that started failing or timing out after r238635. See below for more details. 10 11 * TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEditActions.mm: 12 (TestWebKitAPI::webViewForEditActionTesting): 13 (TestWebKitAPI::webViewForEditActionTestingWithPageNamed): 14 15 Ensure that the web view becomes first responder before executing edit actions. 16 17 * TestWebKitAPI/Tests/WebKitCocoa/autofocus-contenteditable.html: 18 * TestWebKitAPI/Tests/WebKitCocoa/contenteditable-and-textarea.html: 19 20 Tweak these tests to allow selected content to overflow the width of the web view. Without this change, 21 ContentEditableToContentEditable and ContentEditableToTextarea will sometimes fail because the content causes 22 the body to scroll horizontally, so we miss the drop destination. 23 24 * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm: 25 (loadTestPageAndEnsureInputSession): 26 27 Add a new helper to load a test page with a given name, become first responder, and wait until an input session 28 starts. Use this in various drag and drop tests to reduce code duplication. 29 30 * TestWebKitAPI/cocoa/DragAndDropSimulator.h: 31 * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm: 32 (-[DragAndDropSimulator initWithWebView:]): 33 (-[DragAndDropSimulator _resetSimulatedState]): 34 (-[DragAndDropSimulator _concludeDropAndPerformOperationIfNecessary]): 35 (-[DragAndDropSimulator _advanceProgress]): 36 37 To more accurately emulate UIKit behavior, begin focus preservation when starting a drag, and attempt to clear 38 the focus preservation token when the drag session ends. This allows us to simulate and test the scenario that 39 regressed with r238635. 40 41 (-[DragAndDropSimulator ensureInputSession]): 42 (-[DragAndDropSimulator _webView:didStartInputSession:]): 43 (-[DragAndDropSimulator waitForInputSession]): Deleted. 44 45 Refactored into -ensureInputSession. Instead of assuming that an input session has not yet been started, simply 46 wait for an input session to start if needed. 47 48 * TestWebKitAPI/ios/UIKitSPI.h: 49 50 Add a new SPI declaration. 51 1 52 2018-11-29 Tim Horton <timothy_horton@apple.com> 2 53 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEditActions.mm
r238186 r238728 79 79 [webView synchronouslyLoadHTMLString:markup]; 80 80 [webView _setEditable:YES]; 81 [webView becomeFirstResponder]; 81 82 [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.body, 1)"]; 82 83 return webView; … … 88 89 [webView synchronouslyLoadTestPageNamed:testPageName]; 89 90 [webView _setEditable:YES]; 91 [webView becomeFirstResponder]; 90 92 [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.body, 1)"]; 91 93 return webView; … … 244 246 { 245 247 auto source = webViewForEditActionTesting(); 246 auto destination = webViewForEditActionTesting(@"<div><br></div>");247 248 248 [source selectAll:nil]; 249 249 [source evaluateJavaScript:@"document.execCommand('bold'); document.execCommand('underline'); document.execCommand('italic')" completionHandler:nil]; 250 250 [source _synchronouslyExecuteEditCommand:@"Copy" argument:nil]; 251 251 252 auto destination = webViewForEditActionTesting(@"<div><br></div>"); 252 253 [destination _pasteAndMatchStyle:nil]; 253 254 [destination selectAll:nil]; -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/autofocus-contenteditable.html
r218433 r238728 13 13 font-size: 200px; 14 14 white-space: nowrap; 15 } 16 17 #source { 18 overflow: hidden; 15 19 } 16 20 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/contenteditable-and-textarea.html
r218433 r238728 13 13 font-size: 200px; 14 14 white-space: nowrap; 15 } 16 17 #source { 18 overflow: hidden; 15 19 } 16 20 -
trunk/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm
r238360 r238728 99 99 @end 100 100 101 static void loadTestPageAndEnsureInputSession(DragAndDropSimulator *simulator, NSString *testPageName) 102 { 103 TestWKWebView *webView = [simulator webView]; 104 simulator.allowsFocusToStartInputSession = YES; 105 [webView becomeFirstResponder]; 106 [webView synchronouslyLoadTestPageNamed:testPageName]; 107 [simulator ensureInputSession]; 108 } 109 101 110 static NSValue *makeCGRectValue(CGFloat x, CGFloat y, CGFloat width, CGFloat height) 102 111 { … … 342 351 auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]); 343 352 344 [webView loadTestPageNamed:@"autofocus-contenteditable"]; 345 [simulator waitForInputSession]; 353 loadTestPageAndEnsureInputSession(simulator.get(), @"autofocus-contenteditable"); 346 354 [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; 347 355 … … 363 371 auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]); 364 372 365 [webView loadTestPageNamed:@"contenteditable-and-textarea"]; 366 [simulator waitForInputSession]; 373 loadTestPageAndEnsureInputSession(simulator.get(), @"contenteditable-and-textarea"); 367 374 [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; 368 375 … … 395 402 auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]); 396 403 397 [webView loadTestPageNamed:@"two-paragraph-contenteditable"]; 398 [simulator waitForInputSession]; 404 loadTestPageAndEnsureInputSession(simulator.get(), @"two-paragraph-contenteditable"); 399 405 [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(250, 450)]; 400 406 … … 426 432 auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]); 427 433 428 [webView loadTestPageNamed:@"textarea-to-input"]; 429 [simulator waitForInputSession]; 434 loadTestPageAndEnsureInputSession(simulator.get(), @"textarea-to-input"); 430 435 [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; 431 436 … … 441 446 auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]); 442 447 443 [webView loadTestPageNamed:@"textarea-to-input"]; 444 [simulator waitForInputSession]; 448 loadTestPageAndEnsureInputSession(simulator.get(), @"textarea-to-input"); 445 449 [webView stringByEvaluatingJavaScript:@"source.value = 'pneumonoultramicroscopicsilicovolcanoconiosis'"]; 446 450 [webView stringByEvaluatingJavaScript:@"source.selectionStart = 0"]; … … 464 468 auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]); 465 469 466 [webView loadTestPageNamed:@"textarea-to-input"]; 467 [simulator waitForInputSession]; 470 loadTestPageAndEnsureInputSession(simulator.get(), @"textarea-to-input"); 468 471 [webView stringByEvaluatingJavaScript:@"source.value = 'https://webkit.org/'"]; 469 472 [webView stringByEvaluatingJavaScript:@"source.selectionStart = 0"]; -
trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h
r238360 r238728 90 90 - (instancetype)initWithWebView:(TestWKWebView *)webView; 91 91 - (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation additionalItemRequestLocations:(ProgressToCGPointValueMap)additionalItemRequestLocations; 92 - (void) waitForInputSession;92 - (void)ensureInputSession; 93 93 94 94 @property (nonatomic, readonly) DragAndDropPhase phase; -
trunk/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm
r238360 r238728 311 311 RetainPtr<NSMutableArray<_WKAttachment *>> _removedAttachments; 312 312 313 bool _ isDoneWaitingForInputSession;313 bool _hasStartedInputSession; 314 314 double _currentProgress; 315 315 bool _isDoneWithCurrentRun; … … 339 339 _shouldEnsureUIApplication = NO; 340 340 _shouldAllowMoveOperation = YES; 341 _isDoneWaitingForInputSession = true;342 341 [_webView setUIDelegate:self]; 343 342 [_webView _setInputDelegate:self]; … … 374 373 _queuedAdditionalItemRequestLocations = adoptNS([[NSMutableArray alloc] init]); 375 374 _liftPreviews = adoptNS([[NSMutableArray alloc] init]); 375 _hasStartedInputSession = false; 376 376 } 377 377 … … 460 460 [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] sessionDidEnd:_dropSession.get()]; 461 461 462 if (_dragSession) 463 [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] session:_dragSession.get() didEndWithOperation:operation]; 462 if (_dragSession) { 463 auto delegate = [_webView dragInteractionDelegate]; 464 [delegate dragInteraction:[_webView dragInteraction] session:_dragSession.get() didEndWithOperation:operation]; 465 if ([delegate respondsToSelector:@selector(_clearToken:)]) 466 [(id <UITextInputMultiDocument>)delegate _clearToken:nil]; 467 [_webView becomeFirstResponder]; 468 } 464 469 } 465 470 … … 544 549 } 545 550 546 [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] sessionWillBegin:_dragSession.get()]; 551 auto delegate = [_webView dragInteractionDelegate]; 552 if ([delegate respondsToSelector:@selector(_preserveFocusWithToken:destructively:)]) 553 [(id <UITextInputMultiDocument>)delegate _preserveFocusWithToken:nil destructively:NO]; 554 555 [_webView resignFirstResponder]; 556 557 [delegate dragInteraction:[_webView dragInteraction] sessionWillBegin:_dragSession.get()]; 547 558 548 559 RetainPtr<WKWebView> retainedWebView = _webView; … … 619 630 } 620 631 621 - (void)waitForInputSession 622 { 623 _isDoneWaitingForInputSession = false; 624 625 // Waiting for an input session implies that we should allow input sessions to begin. 626 self.allowsFocusToStartInputSession = YES; 627 628 Util::run(&_isDoneWaitingForInputSession); 632 - (void)ensureInputSession 633 { 634 Util::run(&_hasStartedInputSession); 629 635 } 630 636 … … 708 714 - (void)_webView:(WKWebView *)webView didStartInputSession:(id <_WKFormInputSession>)inputSession 709 715 { 710 _ isDoneWaitingForInputSession = true;716 _hasStartedInputSession = true; 711 717 } 712 718 -
trunk/Tools/TestWebKitAPI/ios/UIKitSPI.h
r238383 r238728 84 84 - (void)_preserveFocusWithToken:(id <NSCopying, NSSecureCoding>)token destructively:(BOOL)destructively; 85 85 - (BOOL)_restoreFocusWithToken:(id <NSCopying, NSSecureCoding>)token; 86 - (void)_clearToken:(id <NSCopying, NSSecureCoding>)token; 86 87 @end 87 88
Note: See TracChangeset
for help on using the changeset viewer.