Skip to content

Commit

Permalink
Cherry-pick 89bc7dd. rdar://122843511
Browse files Browse the repository at this point in the history
    Find in Note: Dark gray outline (shadow) appears behind gray/yellow highlights when matched text found in HTML note.
    https://bugs.webkit.org/show_bug.cgi?id=270666
    rdar://122843511

    Reviewed by Aditya Keerthi.

    In notes, the WKContentView is transparent, so our original solution of putting an additional
    grey layer behind the content view that filled up the empty parts of the scroll view would show
    through and make the find ui have a incorrect grey cast. So instead, we make four views that surround
    the WKContentView to fill in any part of the scrollView that isn't covered by the contentView.
    These are arranged around the content view like so:

    ----- -----------
    |    |          |
    |    |----------|
    |    |     |    |
    |    |     |    |
    ----- ------    |
    |          |    |
    |__________|____|

    Each view is expanded to reach the edges of the scroll view every time the view is scrolled or the bounds change.
    This means that no matter where the content view is scrolled to, there will be a view that gives the correct
    grey cast to the scroll view.

    * Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h:
    * Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm:
    (-[WKWebView scrollViewDidScroll:]):
    (-[WKWebView _frameOrBoundsMayHaveChanged]):
    (-[WKWebView _updateFindOverlayForOverflowScrollPositions]):
    (-[WKWebView _showFindOverlay]):
    (-[WKWebView _hideFindOverlay]):
    (-[WKWebView _didAddLayerForFindOverlay:]):
    (-[WKWebView _updateFindOverlayPosition]): Deleted.

    Canonical link: https://commits.webkit.org/275873@main

Identifier: 273664.1365@safari-7619.1.5.6-branch
  • Loading branch information
megangardner authored and MyahCobbs committed Mar 11, 2024
1 parent b1493cd commit 3a8dc20
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 24 deletions.
8 changes: 7 additions & 1 deletion Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,13 @@ struct PerWebProcessState {

BOOL _findInteractionEnabled;
#if HAVE(UIFINDINTERACTION)
RetainPtr<UIView> _findOverlay;
struct FindOverlays {
RetainPtr<UIView> top;
RetainPtr<UIView> right;
RetainPtr<UIView> bottom;
RetainPtr<UIView> left;
};
std::optional<FindOverlays> _findOverlaysOutsideContentView;
RetainPtr<UIFindInteraction> _findInteraction;
#endif

Expand Down
111 changes: 88 additions & 23 deletions Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3333,38 +3333,77 @@ - (CABasicAnimation *)_animationForFindOverlay:(BOOL)animateIn

- (void)_updateFindOverlayPosition
{
if (!_findOverlaysOutsideContentView)
return;

UIScrollView *scrollView = _scrollView.get();
[_findOverlay setBounds:CGRectMake(0, 0, scrollView.bounds.size.width, scrollView.bounds.size.height)];
[_findOverlay setCenter:CGPointMake(scrollView.center.x + scrollView.contentOffset.x, scrollView.center.y + scrollView.contentOffset.y)];
CGRect contentViewBounds = [_contentView bounds];
CGRect contentViewFrame = [_contentView frame];
CGFloat minX = std::min<CGFloat>(0, scrollView.contentOffset.x);
CGFloat minY = std::min<CGFloat>(0, scrollView.contentOffset.y);
CGFloat maxX = std::max<CGFloat>(scrollView.bounds.size.width + scrollView.contentOffset.x, contentViewBounds.size.width);
CGFloat maxY = std::max<CGFloat>(scrollView.bounds.size.height + scrollView.contentOffset.y, contentViewBounds.size.height);

[_findOverlaysOutsideContentView->top setFrame:CGRectMake(
CGRectGetMinX(contentViewFrame),
minY,
std::max<CGFloat>(maxX - CGRectGetMinX(contentViewFrame), 0),
std::max<CGFloat>(CGRectGetMinY(contentViewFrame) - minY, 0))];

[_findOverlaysOutsideContentView->right setFrame:CGRectMake(
CGRectGetMaxX(contentViewFrame),
CGRectGetMinY(contentViewFrame),
std::max<CGFloat>(maxX - CGRectGetMaxX(contentViewFrame), 0),
std::max<CGFloat>(maxY - CGRectGetMinY(contentViewFrame), 0))];

[_findOverlaysOutsideContentView->bottom setFrame:CGRectMake(
minX,
CGRectGetMaxY(contentViewFrame),
std::max<CGFloat>(CGRectGetMaxX(contentViewFrame) - minX, 0),
std::max<CGFloat>(maxY - CGRectGetMaxY(contentViewFrame), 0))];

[_findOverlaysOutsideContentView->left setFrame:CGRectMake(
minX,
minY,
std::max<CGFloat>(CGRectGetMinX(contentViewFrame) - minX, 0),
std::max<CGFloat>(CGRectGetMaxY(contentViewFrame) - minY, 0))];
}

- (void)_showFindOverlay
{
if (!_findOverlay) {
_findOverlay = adoptNS([[UIView alloc] init]);
UIColor *overlayColor = [UIColor colorWithRed:(26. / 255) green:(26. / 255) blue:(26. / 255) alpha:(64. / 255)];
[_findOverlay setBackgroundColor:overlayColor];
}
if (!_findOverlaysOutsideContentView) {
auto makeOverlay = [&]() {
UIColor *overlayColor = [UIColor colorWithRed:(26. / 255) green:(26. / 255) blue:(26. / 255) alpha:(64. / 255)];
auto newOverlay = adoptNS([[UIView alloc] init]);
[newOverlay setBackgroundColor:overlayColor];
[_scrollView insertSubview:newOverlay.get() belowSubview:_contentView.get()];

return newOverlay;
};
_findOverlaysOutsideContentView = { makeOverlay(), makeOverlay(), makeOverlay(), makeOverlay() };
}
[self _updateFindOverlayPosition];
[_scrollView insertSubview:_findOverlay.get() belowSubview:_contentView.get()];

if (CALayer *contentViewFindOverlayLayer = [self _layerForFindOverlay]) {
[[_findOverlay layer] removeAllAnimations];
[contentViewFindOverlayLayer removeAllAnimations];
[self _updateFindOverlaysOutsideContentView:^(UIView *view) {
[[view layer] removeAllAnimations];
[view setAlpha:1];
}];

[_findOverlay setAlpha:1];
[contentViewFindOverlayLayer removeAllAnimations];
[contentViewFindOverlayLayer setOpacity:1];
} else {
[_findOverlay setAlpha:0];
[self _updateFindOverlaysOutsideContentView:^(UIView *view) {
[view setAlpha:0];
}];
[self _addLayerForFindOverlay];
}
}

- (void)_hideFindOverlay
{
CALayer *contentViewFindOverlayLayer = [self _layerForFindOverlay];
CALayer *findOverlayLayer = [_findOverlay layer];
CALayer *findOverlayLayer = _findOverlaysOutsideContentView ? [_findOverlaysOutsideContentView->top layer] : nil;

if (!findOverlayLayer && !contentViewFindOverlayLayer)
return;
Expand All @@ -3373,7 +3412,9 @@ - (void)_hideFindOverlay
return;

[contentViewFindOverlayLayer removeAllAnimations];
[findOverlayLayer removeAllAnimations];
[self _updateFindOverlaysOutsideContentView:^(UIView *view) {
[[view layer] removeAllAnimations];
}];

[CATransaction begin];

Expand All @@ -3384,22 +3425,31 @@ - (void)_hideFindOverlay
if (!strongSelf)
return;

if ([strongSelf->_findOverlay alpha])
bool hasOverlaysOutsideContentView = strongSelf->_findOverlaysOutsideContentView.has_value();
if (hasOverlaysOutsideContentView && [strongSelf->_findOverlaysOutsideContentView->top alpha])
return;

[strongSelf->_findOverlay removeFromSuperview];
strongSelf->_findOverlay = nil;

[strongSelf _removeLayerForFindOverlay];

if (hasOverlaysOutsideContentView) {
[strongSelf _updateFindOverlaysOutsideContentView:^(UIView *view) {
[view removeFromSuperview];
}];
strongSelf->_findOverlaysOutsideContentView.reset();
}
}];

[contentViewFindOverlayLayer addAnimation:animation forKey:@"findOverlayFadeOut"];
[findOverlayLayer addAnimation:animation forKey:@"findOverlayFadeOut"];
[self _updateFindOverlaysOutsideContentView:^(UIView *view) {
[[view layer] addAnimation:animation forKey:@"findOverlayFadeOut"];
}];

[CATransaction commit];

contentViewFindOverlayLayer.opacity = 0;
findOverlayLayer.opacity = 0;
[self _updateFindOverlaysOutsideContentView:^(UIView *view) {
[view layer].opacity = 0;
}];
}

#endif // HAVE(UIFINDINTERACTION)
Expand Down Expand Up @@ -3539,20 +3589,35 @@ - (_UIDataOwner)_effectiveDataOwner:(_UIDataOwner)clientSuppliedDataOwner
return _UIDataOwnerUndefined;
}

#if HAVE(UIFINDINTERACTION)
- (void)_updateFindOverlaysOutsideContentView:(void(^)(UIView *))updateFindOverlay
{
if (!_findOverlaysOutsideContentView)
return;
updateFindOverlay(_findOverlaysOutsideContentView->top.get());
updateFindOverlay(_findOverlaysOutsideContentView->bottom.get());
updateFindOverlay(_findOverlaysOutsideContentView->left.get());
updateFindOverlay(_findOverlaysOutsideContentView->right.get());
}
#endif

- (void)_didAddLayerForFindOverlay:(CALayer *)layer
{
_perProcessState.committedFindLayerID = std::exchange(_perProcessState.pendingFindLayerID, { });
_page->findClient().didAddLayerForFindOverlay(_page.get(), layer);

#if HAVE(UIFINDINTERACTION)
CABasicAnimation *animation = [self _animationForFindOverlay:YES];
CALayer *findOverlayLayer = [_findOverlay layer];

[layer addAnimation:animation forKey:@"findOverlayFadeIn"];
[findOverlayLayer addAnimation:animation forKey:@"findOverlayFadeIn"];

[self _updateFindOverlaysOutsideContentView:^(UIView *view) {
CALayer *overlayLayer = [view layer];
[overlayLayer addAnimation:animation forKey:@"findOverlayFadeIn"];
overlayLayer.opacity = 1;
}];

layer.opacity = 1;
findOverlayLayer.opacity = 1;
#endif
}

Expand Down

0 comments on commit 3a8dc20

Please sign in to comment.