Changeset 229641 in webkit
- Timestamp:
- Mar 15, 2018 1:50:03 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r229638 r229641 1 2018-03-15 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [iOS WK2] Hit-testing fails when specifying a large top content inset 4 https://bugs.webkit.org/show_bug.cgi?id=183648 5 <rdar://problem/38421894> 6 7 Reviewed by Tim Horton. 8 9 Currently, in the process of computing unobscured content rect in the UI process on iOS, we subtract away parts 10 of the view that are obscured by insets (e.g. MobileSafari's chrome). The helper method -[WKWebView 11 _computeContentInset] is intended to compute these obscuring insets around the view, but it takes scroll view 12 insets into account. This means that if WKWebView's inner scroll view has content insets, we'll end up shrinking 13 the unobscured content rect as if the insetted region obscures the viewport; this causes visible content on the 14 page to be uninteractible, since WKWebView erroneously thinks it's obscured. 15 16 To address this, we rename _computeContentInset to _computeObscuredInset, and make it _not_ affected by the 17 scroll view's content insets. From code inspection and testing, all but one of the former call sites of 18 _computeContentInset really need the obscured inset instead (see below). The one exception, -[WKWebView 19 _adjustedContentOffset:], takes a scroll position from the page and maps it to a content offset in the inner 20 UIScrollView (see below for more details). 21 22 Tests: ScrollViewInsetTests.InnerHeightWithLargeTopContentInset 23 ScrollViewInsetTests.InnerHeightWithLargeBottomContentInset 24 ScrollViewInsetTests.RestoreInitialContentOffsetAfterCrash 25 ScrollViewInsetTests.RestoreInitialContentOffsetAfterNavigation 26 27 * UIProcess/API/Cocoa/WKWebView.mm: 28 (-[WKWebView _setHasCustomContentView:loadedMIMEType:]): 29 (-[WKWebView _initialContentOffsetForScrollView]): 30 31 See -_contentOffsetAdjustedForObscuredInset: below. 32 33 (-[WKWebView _contentOffsetAdjustedForObscuredInset:]): 34 35 Formerly -_adjustedContentOffset:. -_contentOffsetAdjustedForObscuredInset: no longer takes scroll view content 36 inset into account, and only cares about insets that obscure the view. This means that the scroll position 37 (0, 0) in the document now maps to the content offset in the inner UIScrollView, such that the top of the page 38 is aligned with the top of the viewport. 39 40 However, many call sites of -_adjustedContentOffset: were intended to compute the initial, top-left-most content 41 offset in the scroll view to scroll to when resetting the web view (i.e., they pass in CGPointZero for the 42 scroll position). An example of this is the scroll position to jump to after web content process termination, or 43 the scroll position after main frame navigation. In these cases, we actually want to jump to the top of the 44 scroll view, so we do want to use the version of the computed content insets that accounts for scroll view 45 insets. 46 47 Since these cases are limited to finding the top-left-most scroll position, we pull this out into a separate 48 helper method (-_initialContentOffsetForScrollView) and replace calls to 49 `-[self _adjustedContentOffset:CGPointZero]` with this instead. 50 51 (-[WKWebView _computedObscuredInset]): 52 53 A version of -_computeContentInset that doesn't care about scroll view insets. Used whereever we need to account 54 for obscured insets rather than the combination of content insets and unobscured insets (e.g. 55 -_initialContentOffsetForScrollView). 56 57 (-[WKWebView _processDidExit]): 58 (-[WKWebView _didCommitLayerTree:]): 59 (-[WKWebView _dynamicViewportUpdateChangedTargetToScale:position:nextValidLayerTreeTransactionID:]): 60 (-[WKWebView _scrollToContentScrollPosition:scrollOrigin:]): 61 (-[WKWebView scrollViewWillEndDragging:withVelocity:targetContentOffset:]): 62 (-[WKWebView _updateVisibleContentRects]): 63 (-[WKWebView _navigationGestureDidBegin]): 64 65 In all these places where we inset the view bounds to compute the unobscured region of the viewport, it doesn't 66 make sense to additionally inset by the scroll view's content insets, since (1) the scroll view's content insets 67 don't obscure the viewport, and (2) it's perfectly valid for the inner scroll view to have arbitrarily large 68 content insets. 69 70 (-[WKWebView _adjustedContentOffset:]): Deleted. 71 72 Renamed to -_contentOffsetAdjustedForObscuredInset:. 73 74 * UIProcess/API/Cocoa/WKWebViewInternal.h: 75 * UIProcess/ios/WKPDFView.mm: 76 (-[WKPDFView _offsetForPageNumberIndicator]): 77 78 Similar to -_scrollToFragment: (see below). 79 80 (-[WKPDFView _scrollToFragment:]): 81 82 This helper figures out which content offset to scroll to, given the y-origin of a page in a PDF document. If 83 insets are added to the scroll view, we end up scrolling to the wrong content offset since we'll add the height 84 of the top content inset (imagine that the top content inset is enormous — then we'll scroll an amount equal to 85 the top content inset _past_ the point where the y-origin of the page is at the top of the viewport). 86 1 87 2018-03-15 Brent Fulgham <bfulgham@apple.com> 2 88 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
r229511 r229641 1462 1462 1463 1463 _scrollViewBackgroundColor = WebCore::Color(); 1464 [_scrollView setContentOffset:[self _ adjustedContentOffset:CGPointZero]];1464 [_scrollView setContentOffset:[self _initialContentOffsetForScrollView]]; 1465 1465 1466 1466 [self _setAvoidsUnsafeArea:NO]; … … 1582 1582 } 1583 1583 1584 - (CGPoint)_adjustedContentOffset:(CGPoint)point 1584 - (CGPoint)_initialContentOffsetForScrollView 1585 { 1586 auto combinedUnobscuredAndScrollViewInset = [self _computedContentInset]; 1587 return CGPointMake(-combinedUnobscuredAndScrollViewInset.left, -combinedUnobscuredAndScrollViewInset.top); 1588 } 1589 1590 - (CGPoint)_contentOffsetAdjustedForObscuredInset:(CGPoint)point 1585 1591 { 1586 1592 CGPoint result = point; 1587 UIEdgeInsets contentInset = [self _computed ContentInset];1593 UIEdgeInsets contentInset = [self _computedObscuredInset]; 1588 1594 1589 1595 result.x -= contentInset.left; … … 1598 1604 return UIRectEdgeAll; 1599 1605 return _obscuredInsetEdgesAffectedBySafeArea; 1606 } 1607 1608 - (UIEdgeInsets)_computedObscuredInset 1609 { 1610 if (_haveSetObscuredInsets) 1611 return _obscuredInsets; 1612 1613 #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000 1614 if (self._safeAreaShouldAffectObscuredInsets) 1615 return UIEdgeInsetsAdd(UIEdgeInsetsZero, self._scrollViewSystemContentInset, self._effectiveObscuredInsetEdgesAffectedBySafeArea); 1616 #endif 1617 1618 return UIEdgeInsetsZero; 1600 1619 } 1601 1620 … … 1642 1661 [_contentView setFrame:self.bounds]; 1643 1662 [_scrollView setBackgroundColor:[UIColor whiteColor]]; 1644 [_scrollView setContentOffset:[self _ adjustedContentOffset:CGPointZero]];1663 [_scrollView setContentOffset:[self _initialContentOffsetForScrollView]]; 1645 1664 [_scrollView setZoomScale:1]; 1646 1665 … … 1779 1798 if (_needsResetViewStateAfterCommitLoadForMainFrame && layerTreeTransaction.transactionID() >= _firstPaintAfterCommitLoadTransactionID) { 1780 1799 _needsResetViewStateAfterCommitLoadForMainFrame = NO; 1781 [_scrollView setContentOffset:[self _ adjustedContentOffset:CGPointZero]];1800 [_scrollView setContentOffset:[self _initialContentOffsetForScrollView]]; 1782 1801 if (_observedRenderingProgressEvents & _WKRenderingProgressEventFirstPaint) 1783 1802 _navigationState->didFirstPaint(); … … 1848 1867 _resizeAnimationTransformAdjustments = CATransform3DMakeScale(scale, scale, 1); 1849 1868 1850 CGPoint newContentOffset = [self _ adjustedContentOffset:CGPointMake(newScrollPosition.x * newScale, newScrollPosition.y * newScale)];1869 CGPoint newContentOffset = [self _contentOffsetAdjustedForObscuredInset:CGPointMake(newScrollPosition.x * newScale, newScrollPosition.y * newScale)]; 1851 1870 CGPoint currentContentOffset = [_scrollView contentOffset]; 1852 1871 … … 2007 2026 scaledOffset.scale(zoomScale); 2008 2027 2009 CGPoint contentOffsetInScrollViewCoordinates = [self _ adjustedContentOffset:scaledOffset];2028 CGPoint contentOffsetInScrollViewCoordinates = [self _contentOffsetAdjustedForObscuredInset:scaledOffset]; 2010 2029 contentOffsetInScrollViewCoordinates = contentOffsetBoundedInValidRange(_scrollView.get(), contentOffsetInScrollViewCoordinates); 2011 2030 … … 2374 2393 CGSize maxScrollOffsets = CGSizeMake(scrollView.contentSize.width - scrollView.bounds.size.width, scrollView.contentSize.height - scrollView.bounds.size.height); 2375 2394 2376 CGRect fullViewRect = self.bounds; 2377 2378 UIEdgeInsets contentInset; 2395 UIEdgeInsets obscuredInset; 2379 2396 2380 2397 id<WKUIDelegatePrivate> uiDelegatePrivate = static_cast<id <WKUIDelegatePrivate>>([self UIDelegate]); 2381 2398 if ([uiDelegatePrivate respondsToSelector:@selector(_webView:finalObscuredInsetsForScrollView:withVelocity:targetContentOffset:)]) 2382 contentInset = [uiDelegatePrivate _webView:self finalObscuredInsetsForScrollView:scrollView withVelocity:velocity targetContentOffset:targetContentOffset];2399 obscuredInset = [uiDelegatePrivate _webView:self finalObscuredInsetsForScrollView:scrollView withVelocity:velocity targetContentOffset:targetContentOffset]; 2383 2400 else 2384 contentInset = [self _computedContentInset];2385 2386 CGRect unobscuredRect = UIEdgeInsetsInsetRect( fullViewRect, contentInset);2401 obscuredInset = [self _computedObscuredInset]; 2402 2403 CGRect unobscuredRect = UIEdgeInsetsInsetRect(self.bounds, obscuredInset); 2387 2404 2388 2405 coordinator->adjustTargetContentOffsetForSnapping(maxScrollOffsets, velocity, unobscuredRect.origin.y, targetContentOffset); … … 2751 2768 return; 2752 2769 2753 CGRect fullViewRect = self.bounds;2754 2770 CGRect visibleRectInContentCoordinates = [self _visibleContentRect]; 2755 2771 2756 UIEdgeInsets computedContentInsetUnadjustedForKeyboard = [self _computed ContentInset];2772 UIEdgeInsets computedContentInsetUnadjustedForKeyboard = [self _computedObscuredInset]; 2757 2773 if (!_haveSetObscuredInsets) 2758 2774 computedContentInsetUnadjustedForKeyboard.bottom -= _totalScrollViewBottomInsetAdjustmentForKeyboard; … … 2760 2776 CGFloat scaleFactor = contentZoomScale(self); 2761 2777 2762 CGRect unobscuredRect = UIEdgeInsetsInsetRect( fullViewRect, computedContentInsetUnadjustedForKeyboard);2778 CGRect unobscuredRect = UIEdgeInsetsInsetRect(self.bounds, computedContentInsetUnadjustedForKeyboard); 2763 2779 CGRect unobscuredRectInContentCoordinates = _frozenUnobscuredContentRect ? _frozenUnobscuredContentRect.value() : [self convertRect:unobscuredRect toView:_contentView.get()]; 2764 2780 unobscuredRectInContentCoordinates = CGRectIntersection(unobscuredRectInContentCoordinates, [self _contentBoundsExtendedForRubberbandingWithScale:scaleFactor]); … … 2768 2784 WebKit::RemoteScrollingCoordinatorProxy* coordinator = _page->scrollingCoordinatorProxy(); 2769 2785 if (coordinator && coordinator->hasActiveSnapPoint()) { 2770 CGRect unobscuredRect = UIEdgeInsetsInsetRect(fullViewRect, computedContentInsetUnadjustedForKeyboard);2771 2772 2786 CGPoint currentPoint = [_scrollView contentOffset]; 2773 2787 CGPoint activePoint = coordinator->nearestActiveContentInsetAdjustedSnapPoint(unobscuredRect.origin.y, currentPoint); … … 2949 2963 // frozen rects during swipes. 2950 2964 CGRect fullViewRect = self.bounds; 2951 CGRect unobscuredRect = UIEdgeInsetsInsetRect(fullViewRect, [self _computed ContentInset]);2965 CGRect unobscuredRect = UIEdgeInsetsInsetRect(fullViewRect, [self _computedObscuredInset]); 2952 2966 2953 2967 _frozenVisibleContentRect = [self convertRect:fullViewRect toView:_contentView.get()]; -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h
r229485 r229641 146 146 147 147 @property (nonatomic, readonly) BOOL _allowsDoubleTapGestures; 148 @property (nonatomic, readonly) UIEdgeInsets _computed ContentInset;148 @property (nonatomic, readonly) UIEdgeInsets _computedObscuredInset; 149 149 @property (nonatomic, readonly) UIEdgeInsets _computedUnobscuredSafeAreaInset; 150 150 #endif -
trunk/Source/WebKit/UIProcess/ios/WKPDFView.mm
r229182 r229641 309 309 - (CGPoint)_offsetForPageNumberIndicator 310 310 { 311 UIEdgeInsets insets = UIEdgeInsetsAdd(_webView._computedUnobscuredSafeAreaInset, _webView._computed ContentInset, UIRectEdgeAll);311 UIEdgeInsets insets = UIEdgeInsetsAdd(_webView._computedUnobscuredSafeAreaInset, _webView._computedObscuredInset, UIRectEdgeAll); 312 312 return CGPointMake(insets.left, insets.top + _overlaidAccessoryViewsInset.height); 313 313 } … … 367 367 368 368 // Ensure that the page margin is visible below the content inset. 369 const CGFloat verticalOffset = _pages[pageIndex].frame.origin.y - _webView._computed ContentInset.top - pdfPageMargin;369 const CGFloat verticalOffset = _pages[pageIndex].frame.origin.y - _webView._computedObscuredInset.top - pdfPageMargin; 370 370 [_scrollView setContentOffset:CGPointMake(_scrollView.contentOffset.x, verticalOffset) animated:NO]; 371 371 -
trunk/Tools/ChangeLog
r229630 r229641 1 2018-03-15 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [iOS WK2] Hit-testing fails when specifying a large top content inset 4 https://bugs.webkit.org/show_bug.cgi?id=183648 5 <rdar://problem/38421894> 6 7 Reviewed by Tim Horton. 8 9 Adds four new API tests to verify that adding top or bottom content insets to the WKWebView's scroll view does 10 not cause the DOMWindow's innerHeight to shrink. Currently, doing so would cause the innerHeight to be reported 11 as (viewHeight - inset.top) or (viewHeight - inset.bottom). 12 13 See WebKit ChangeLog for more details. 14 15 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: 16 * TestWebKitAPI/Tests/ios/ScrollViewInsetTests.mm: Added. 17 (TestWebKitAPI::TEST): 18 1 19 2018-03-15 Aakash Jain <aakash_jain@apple.com> 2 20 -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r229589 r229641 769 769 F4BFA68E1E4AD08000154298 /* DragAndDropPasteboardTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4BFA68C1E4AD08000154298 /* DragAndDropPasteboardTests.mm */; }; 770 770 F4C2AB221DD6D95E00E06D5B /* enormous-video-with-sound.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4C2AB211DD6D94100E06D5B /* enormous-video-with-sound.html */; }; 771 F4C8797F2059D8D3009CD00B /* ScrollViewInsetTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4C8797E2059D8D3009CD00B /* ScrollViewInsetTests.mm */; }; 771 772 F4D4F3B61E4E2BCB00BB2767 /* DataInteractionSimulator.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D4F3B41E4E2BCB00BB2767 /* DataInteractionSimulator.mm */; }; 772 773 F4D4F3B91E4E36E400BB2767 /* DataInteractionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D4F3B71E4E36E400BB2767 /* DataInteractionTests.mm */; }; … … 854 855 dstSubfolderSpec = 7; 855 856 files = ( 856 CD758A6F20572EA00071834A /* video-with-paused-audio-and-playing-muted.html in Copy Resources */,857 857 1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */, 858 858 379028B914FAC24C007E6B43 /* acceptsFirstMouse.html in Copy Resources */, … … 1089 1089 CD321B041E3A85FA00EB21C8 /* video-with-muted-audio-and-webaudio.html in Copy Resources */, 1090 1090 CDB4115A1E0B00DB00EAD352 /* video-with-muted-audio.html in Copy Resources */, 1091 CD758A6F20572EA00071834A /* video-with-paused-audio-and-playing-muted.html in Copy Resources */, 1091 1092 CDC8E4961BC6F10800594FEC /* video-without-audio.html in Copy Resources */, 1092 1093 CDC8E4971BC6F10800594FEC /* video-without-audio.mp4 in Copy Resources */, … … 1908 1909 F4BFA68C1E4AD08000154298 /* DragAndDropPasteboardTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DragAndDropPasteboardTests.mm; sourceTree = "<group>"; }; 1909 1910 F4C2AB211DD6D94100E06D5B /* enormous-video-with-sound.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "enormous-video-with-sound.html"; sourceTree = "<group>"; }; 1911 F4C8797E2059D8D3009CD00B /* ScrollViewInsetTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollViewInsetTests.mm; sourceTree = "<group>"; }; 1910 1912 F4D4F3B41E4E2BCB00BB2767 /* DataInteractionSimulator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataInteractionSimulator.mm; sourceTree = "<group>"; }; 1911 1913 F4D4F3B51E4E2BCB00BB2767 /* DataInteractionSimulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataInteractionSimulator.h; sourceTree = "<group>"; }; … … 2320 2322 F4D4F3B71E4E36E400BB2767 /* DataInteractionTests.mm */, 2321 2323 7560917719259C59009EF06E /* MemoryCacheAddImageToCacheIOS.mm */, 2324 F4C8797E2059D8D3009CD00B /* ScrollViewInsetTests.mm */, 2322 2325 F46849BD1EEF58E400B937FE /* UIPasteboardTests.mm */, 2323 2326 2E1B881E2040EE5300FFF6A9 /* ViewportSizingTests.mm */, … … 3108 3111 CDC8E48A1BC5C96200594FEC /* video-with-audio.mp4 */, 3109 3112 CD321B031E3A84B700EB21C8 /* video-with-muted-audio-and-webaudio.html */, 3113 CDB411591E09DA8E00EAD352 /* video-with-muted-audio.html */, 3110 3114 CD758A6E20572D540071834A /* video-with-paused-audio-and-playing-muted.html */, 3111 CDB411591E09DA8E00EAD352 /* video-with-muted-audio.html */,3112 3115 CDC8E48B1BC5C96200594FEC /* video-without-audio.html */, 3113 3116 CDC8E48C1BC5C96200594FEC /* video-without-audio.mp4 */, … … 3638 3641 CDCFA7AA1E45183200C2433D /* SampleMap.cpp in Sources */, 3639 3642 7CCE7F121A411AE600447C4C /* ScrollPinningBehaviors.cpp in Sources */, 3643 F4C8797F2059D8D3009CD00B /* ScrollViewInsetTests.mm in Sources */, 3640 3644 CE06DF9B1E1851F200E570C9 /* SecurityOrigin.cpp in Sources */, 3641 3645 5769C50B1D9B0002000847FB /* SerializedCryptoKeyWrap.mm in Sources */,
Note: See TracChangeset
for help on using the changeset viewer.