Skip to content

Commit

Permalink
Move off of UIKit SPI: -[UIScrollView _is(Vertical|Horizontal)Bouncing]
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=262013
rdar://112473874

Reviewed by Aditya Keerthi.

Stop using `-_isVerticalBouncing` and `-_isHorizontalBouncing` on `UIScrollView`; as an alternative,
add a new category helper method, `-[UIScrollView _wk_isScrolledBeyondExtents]`, that returns
whether or not the current content offset is scrolled beyond the minimum or maximum extents of the
scroll view, taking the `-adjustedContentInset` into account.

* Source/WebKit/Platform/spi/ios/UIKitSPI.h:
* Source/WebKit/UIProcess/ios/UIKitUtilities.h:
* Source/WebKit/UIProcess/ios/UIKitUtilities.mm:
(-[UIScrollView _wk_isScrolledBeyondExtents]):
* Source/WebKit/UIProcess/ios/WKScrollView.mm:
(-[WKScrollView _setContentSizePreservingContentOffsetDuringRubberband:]):
* Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
* Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
* Tools/WebKitTestRunner/ios/UIKitSPIForTesting.h: Copied from Source/WebKit/UIProcess/ios/UIKitUtilities.h.

Continue using `-_isVerticalBouncing` and `-_isHorizontalBouncing` in WebKitTestRunner harness logic
to determine when scrolling/zooming animations are complete. We also add an SPI header, specific to
WebKitTestRunner for now, to house these new forward declarations and SPI include points. I'll move
various existing testing-only declarations and includes in UIKitSPI.h into this header in a
subsequent patch.

Canonical link: https://commits.webkit.org/268376@main
  • Loading branch information
whsieh committed Sep 24, 2023
1 parent 207c7c9 commit 2f74816
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 4 deletions.
2 changes: 0 additions & 2 deletions Source/WebKit/Platform/spi/ios/UIKitSPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,8 +455,6 @@ typedef struct CGSVGDocument *CGSVGDocumentRef;
- (double)_verticalVelocity;
- (void)_flashScrollIndicatorsForAxes:(UIAxis)axes persistingPreviousFlashes:(BOOL)persisting;
@property (nonatomic, getter=isZoomEnabled) BOOL zoomEnabled;
@property (nonatomic, readonly, getter=_isVerticalBouncing) BOOL isVerticalBouncing;
@property (nonatomic, readonly, getter=_isHorizontalBouncing) BOOL isHorizontalBouncing;
@property (nonatomic, readonly, getter=_isAnimatingZoom) BOOL isAnimatingZoom;
@property (nonatomic, readonly, getter=_isAnimatingScroll) BOOL isAnimatingScroll;
@property (nonatomic, getter=_contentScrollInset, setter=_setContentScrollInset:) UIEdgeInsets contentScrollInset;
Expand Down
1 change: 1 addition & 0 deletions Source/WebKit/UIProcess/ios/UIKitUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

@interface UIScrollView (WebKitInternal)
@property (readonly, nonatomic) BOOL _wk_isInterruptingDeceleration;
@property (readonly, nonatomic) BOOL _wk_isScrolledBeyondExtents;
@end

@interface UIView (WebKitInternal)
Expand Down
16 changes: 16 additions & 0 deletions Source/WebKit/UIProcess/ios/UIKitUtilities.mm
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@ - (BOOL)_wk_isInterruptingDeceleration
return self.decelerating && self.tracking;
}

- (BOOL)_wk_isScrolledBeyondExtents
{
auto contentOffset = self.contentOffset;
auto inset = self.adjustedContentInset;
if (contentOffset.x < -inset.left || contentOffset.y < -inset.top)
return YES;

auto contentSize = self.contentSize;
auto boundsSize = self.bounds.size;
auto maxScrollExtent = CGPointMake(
contentSize.width + inset.right - std::min<CGFloat>(boundsSize.width, contentSize.width + inset.left + inset.right),
contentSize.height + inset.bottom - std::min<CGFloat>(boundsSize.height, contentSize.height + inset.top + inset.bottom)
);
return contentOffset.x > maxScrollExtent.x || contentOffset.y > maxScrollExtent.y;
}

@end

@implementation UIView (WebKitInternal)
Expand Down
4 changes: 2 additions & 2 deletions Source/WebKit/UIProcess/ios/WKScrollView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#import "Logging.h"
#import "UIKitSPI.h"
#import "UIKitUtilities.h"
#import "WKDeferringGestureRecognizer.h"
#import "WKWebViewIOS.h"
#import "WebPage.h"
Expand Down Expand Up @@ -415,8 +416,7 @@ - (void)_restoreContentOffsetWithRubberbandAmount:(CGSize)rubberbandAmount
- (void)_setContentSizePreservingContentOffsetDuringRubberband:(CGSize)contentSize
{
CGSize currentContentSize = [self contentSize];

BOOL mightBeRubberbanding = self.isDragging || self.isVerticalBouncing || self.isHorizontalBouncing || self.refreshControl;
BOOL mightBeRubberbanding = self.isDragging || (self.scrollEnabled && self._wk_isScrolledBeyondExtents) || self.refreshControl;
if (!mightBeRubberbanding || CGSizeEqualToSize(currentContentSize, CGSizeZero) || CGSizeEqualToSize(currentContentSize, contentSize) || ((self.zoomScale < self.minimumZoomScale) && !WebKit::scalesAreEssentiallyEqual(self.zoomScale, self.minimumZoomScale))) {
// FIXME: rdar://problem/65277759 Find out why iOS Mail needs this call even when the contentSize has not changed.
[self setContentSize:contentSize];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
F44A531821B899E500DBB99C /* InstanceMethodSwizzler.mm in Sources */ = {isa = PBXBuildFile; fileRef = F44A531621B899DA00DBB99C /* InstanceMethodSwizzler.mm */; };
F46240B1217013E500917B16 /* UIScriptControllerCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = F46240AF2170128300917B16 /* UIScriptControllerCocoa.mm */; };
F4C3578C20E8444600FA0748 /* LayoutTestSpellChecker.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4C3578A20E8444000FA0748 /* LayoutTestSpellChecker.mm */; };
F4C80D4E2ABFBCB500DEB820 /* UIKitSPIForTesting.h in Headers */ = {isa = PBXBuildFile; fileRef = F4C80D4D2ABFBCB500DEB820 /* UIKitSPIForTesting.h */; };
F4FED324235823A3003C139C /* NSPasteboardAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4FED3222358215E003C139C /* NSPasteboardAdditions.mm */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -450,6 +451,7 @@
F46240AF2170128300917B16 /* UIScriptControllerCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = UIScriptControllerCocoa.mm; sourceTree = "<group>"; };
F4C3578A20E8444000FA0748 /* LayoutTestSpellChecker.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = LayoutTestSpellChecker.mm; path = ../TestRunnerShared/cocoa/LayoutTestSpellChecker.mm; sourceTree = "<group>"; };
F4C3578B20E8444000FA0748 /* LayoutTestSpellChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LayoutTestSpellChecker.h; path = ../TestRunnerShared/cocoa/LayoutTestSpellChecker.h; sourceTree = "<group>"; };
F4C80D4D2ABFBCB500DEB820 /* UIKitSPIForTesting.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIKitSPIForTesting.h; sourceTree = "<group>"; };
F4FED3212358215E003C139C /* NSPasteboardAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSPasteboardAdditions.h; path = ../TestRunnerShared/mac/NSPasteboardAdditions.h; sourceTree = "<group>"; };
F4FED3222358215E003C139C /* NSPasteboardAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = NSPasteboardAdditions.mm; path = ../TestRunnerShared/mac/NSPasteboardAdditions.mm; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -756,6 +758,7 @@
0FEBF8591BB61DF20028722D /* HIDEventGenerator.mm */,
2EE52D131890A9FB0010ED21 /* PlatformWebViewIOS.mm */,
2EE52D141890A9FB0010ED21 /* TestControllerIOS.mm */,
F4C80D4D2ABFBCB500DEB820 /* UIKitSPIForTesting.h */,
F415C22A27AF52D30028F505 /* UIPasteboardConsistencyEnforcer.h */,
F415C22B27AF52D30028F505 /* UIPasteboardConsistencyEnforcer.mm */,
2D0BEE1722EAD1360092B738 /* UIScriptControllerIOS.h */,
Expand Down Expand Up @@ -1002,6 +1005,7 @@
0F73B5521BA78968004B3EF4 /* JSUIScriptController.h in Headers */,
2DFA98481D7F70CF00AFF2C9 /* SharedEventStreamsMac.h in Headers */,
2904FA1E265CC5D900A7EBC9 /* StringFunctionsCocoa.h in Headers */,
F4C80D4E2ABFBCB500DEB820 /* UIKitSPIForTesting.h in Headers */,
F415C22C27AF52D30028F505 /* UIPasteboardConsistencyEnforcer.h in Headers */,
2D058E0922E2EE2200E4C145 /* UIScriptControllerCocoa.h in Headers */,
2D058E0B22E2EF6D00E4C145 /* UIScriptControllerMac.h in Headers */,
Expand Down
1 change: 1 addition & 0 deletions Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#if PLATFORM(IOS_FAMILY)
#import "UIKitSPI.h"
#import "UIKitSPIForTesting.h"
#import <WebKit/WKWebViewPrivate.h>

@interface WKWebView ()
Expand Down
45 changes: 45 additions & 0 deletions Tools/WebKitTestRunner/ios/UIKitSPIForTesting.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2023 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#if PLATFORM(IOS_FAMILY)

#import <UIKit/UIKit.h>

#if USE(APPLE_INTERNAL_SDK)

#import <UIKit/UIScrollView_Private.h>

#else

@interface UIScrollView ()
@property (nonatomic, readonly, getter=_isVerticalBouncing) BOOL isVerticalBouncing;
@property (nonatomic, readonly, getter=_isHorizontalBouncing) BOOL isHorizontalBouncing;
@end

#endif

#endif // PLATFORM(IOS_FAMILY)

0 comments on commit 2f74816

Please sign in to comment.