- Revision
- 271828
- Author
- [email protected]
- Date
- 2021-01-25 14:11:34 -0800 (Mon, 25 Jan 2021)
Log Message
Cherry-pick r271543. rdar://problem/73469576
[iOS] Emoji keyboard covers text field on twitter.com/messages
https://bugs.webkit.org/show_bug.cgi?id=220664
<rdar://problem/68400471>
Reviewed by Devin Rousso.
Source/WebKit:
After iOS 14, the emoji software keyboard layout now includes a search field that can be used to filter for
specific emojis. This slightly increases the overall height of the software keyboard when the emoji keyplane is
active; in turn, this means that if the selection or caret is positioned right above the top of the software
keyboard when the normal (alphabetic) keyplane is active, switching to the emoji keyplane will cause the
keyboard to overlap the selection, making it difficult to see inserted text.
To address this, add a mechanism to detect when a change in the bounds of the software keyboard causes a visible
selection or caret rect to become overlapped, and react by scrolling to keep the selection visible. This has the
effect of fixing this bug by scrolling to reveal the text field after switching to the emoji keyboard, but it
also has the effect of scrolling to keep the selection visible after detaching a connected hardware keyboard,
in the case where it would've otherwise been overlapped by the (much taller) software keyboard that appears.
Test: editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard.html
* UIProcess/API/ios/WKWebViewIOS.h:
* UIProcess/API/ios/WKWebViewIOS.mm:
(-[WKWebView _selectionRectIsFullyVisibleAndNonEmpty]):
Add an internal helper to check whether the selection bounds are fully visible.
(-[WKWebView _scrollToRevealSelectionIfNeeded]):
(-[WKWebView _zoomToFocusRect:selectionRect:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]):
(-[WKWebView _keyboardChangedWithInfo:adjustScrollView:]):
In the case where changing input view bounds causes a previously visible selection to become overlapped, call
`-_scrollToRevealSelectionIfNeeded` to make the selection visible again.
(-[WKWebView _zoomToFocusRect:selectionRect:insideFixed:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]): Deleted.
* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentView.h:
* UIProcess/ios/WKContentView.mm:
(-[WKContentView _zoomToFocusRect:selectionRect:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]):
(-[WKContentView _zoomToFocusRect:selectionRect:insideFixed:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]): Deleted.
Drive-by fix: remove the unused `insideFixed:` parameter from this adjacent method.
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView rectToRevealWhenZoomingToFocusedElement]):
(-[WKContentView _zoomToRevealFocusedElement]):
(rectToRevealWhenZoomingToFocusedElement): Deleted.
Pull this into the `-rectToRevealWhenZoomingToFocusedElement` internal helper method instead, and use the new
`selectionBoundingRectInRootViewCoordinates` method below.
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::selectionBoundingRectInRootViewCoordinates const):
Pull out code to compute the selection bounding rect (for both ranged and caret selections) into a method on
`WebPageProxy`, so that it can be used in `WKContentView` and `WKWebView`.
LayoutTests:
Add a test to verify that after disconnecting a hardware keyboard and showing the software keyboard, we scroll
up to reveal the caret in a focused text field.
* editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard-expected.txt: Added.
* editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard.html: Added.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271543 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Modified Paths
Added Paths
Diff
Modified: branches/safari-611-branch/LayoutTests/ChangeLog (271827 => 271828)
--- branches/safari-611-branch/LayoutTests/ChangeLog 2021-01-25 22:11:27 UTC (rev 271827)
+++ branches/safari-611-branch/LayoutTests/ChangeLog 2021-01-25 22:11:34 UTC (rev 271828)
@@ -1,5 +1,92 @@
2021-01-25 Alan Coon <[email protected]>
+ Cherry-pick r271543. rdar://problem/73469576
+
+ [iOS] Emoji keyboard covers text field on twitter.com/messages
+ https://bugs.webkit.org/show_bug.cgi?id=220664
+ <rdar://problem/68400471>
+
+ Reviewed by Devin Rousso.
+
+ Source/WebKit:
+
+ After iOS 14, the emoji software keyboard layout now includes a search field that can be used to filter for
+ specific emojis. This slightly increases the overall height of the software keyboard when the emoji keyplane is
+ active; in turn, this means that if the selection or caret is positioned right above the top of the software
+ keyboard when the normal (alphabetic) keyplane is active, switching to the emoji keyplane will cause the
+ keyboard to overlap the selection, making it difficult to see inserted text.
+
+ To address this, add a mechanism to detect when a change in the bounds of the software keyboard causes a visible
+ selection or caret rect to become overlapped, and react by scrolling to keep the selection visible. This has the
+ effect of fixing this bug by scrolling to reveal the text field after switching to the emoji keyboard, but it
+ also has the effect of scrolling to keep the selection visible after detaching a connected hardware keyboard,
+ in the case where it would've otherwise been overlapped by the (much taller) software keyboard that appears.
+
+ Test: editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard.html
+
+ * UIProcess/API/ios/WKWebViewIOS.h:
+ * UIProcess/API/ios/WKWebViewIOS.mm:
+ (-[WKWebView _selectionRectIsFullyVisibleAndNonEmpty]):
+
+ Add an internal helper to check whether the selection bounds are fully visible.
+
+ (-[WKWebView _scrollToRevealSelectionIfNeeded]):
+ (-[WKWebView _zoomToFocusRect:selectionRect:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]):
+ (-[WKWebView _keyboardChangedWithInfo:adjustScrollView:]):
+
+ In the case where changing input view bounds causes a previously visible selection to become overlapped, call
+ `-_scrollToRevealSelectionIfNeeded` to make the selection visible again.
+
+ (-[WKWebView _zoomToFocusRect:selectionRect:insideFixed:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]): Deleted.
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/WKContentView.h:
+ * UIProcess/ios/WKContentView.mm:
+ (-[WKContentView _zoomToFocusRect:selectionRect:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]):
+ (-[WKContentView _zoomToFocusRect:selectionRect:insideFixed:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]): Deleted.
+
+ Drive-by fix: remove the unused `insideFixed:` parameter from this adjacent method.
+
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView rectToRevealWhenZoomingToFocusedElement]):
+ (-[WKContentView _zoomToRevealFocusedElement]):
+ (rectToRevealWhenZoomingToFocusedElement): Deleted.
+
+ Pull this into the `-rectToRevealWhenZoomingToFocusedElement` internal helper method instead, and use the new
+ `selectionBoundingRectInRootViewCoordinates` method below.
+
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::selectionBoundingRectInRootViewCoordinates const):
+
+ Pull out code to compute the selection bounding rect (for both ranged and caret selections) into a method on
+ `WebPageProxy`, so that it can be used in `WKContentView` and `WKWebView`.
+
+ LayoutTests:
+
+ Add a test to verify that after disconnecting a hardware keyboard and showing the software keyboard, we scroll
+ up to reveal the caret in a focused text field.
+
+ * editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard-expected.txt: Added.
+ * editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard.html: Added.
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271543 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2021-01-15 Wenson Hsieh <[email protected]>
+
+ [iOS] Emoji keyboard covers text field on twitter.com/messages
+ https://bugs.webkit.org/show_bug.cgi?id=220664
+ <rdar://problem/68400471>
+
+ Reviewed by Devin Rousso.
+
+ Add a test to verify that after disconnecting a hardware keyboard and showing the software keyboard, we scroll
+ up to reveal the caret in a focused text field.
+
+ * editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard-expected.txt: Added.
+ * editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard.html: Added.
+
+2021-01-25 Alan Coon <[email protected]>
+
Cherry-pick r271524. rdar://problem/73473371
Reversed transform animation not applied alongside other transform animations
Added: branches/safari-611-branch/LayoutTests/editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard-expected.txt (0 => 271828)
--- branches/safari-611-branch/LayoutTests/editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard-expected.txt (rev 0)
+++ branches/safari-611-branch/LayoutTests/editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard-expected.txt 2021-01-25 22:11:34 UTC (rev 271828)
@@ -0,0 +1,9 @@
+Verifies that after disconnecting a hardware keyboard and showing the software keyboard, we scroll to reveal the caret in the focused text field.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS Scrolled in response to showing software keyboard
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: branches/safari-611-branch/LayoutTests/editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard.html (0 => 271828)
--- branches/safari-611-branch/LayoutTests/editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard.html (rev 0)
+++ branches/safari-611-branch/LayoutTests/editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard.html 2021-01-25 22:11:34 UTC (rev 271828)
@@ -0,0 +1,56 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1, width=device-width">
+<script src=""
+<script src=""
+<script>
+jsTestIsAsync = true;
+
+addEventListener("load", async () => {
+ let editor = document.querySelector("div[contenteditable]");
+ description("Verifies that after disconnecting a hardware keyboard and showing the software keyboard, we scroll to reveal the caret in the focused text field.");
+
+ if (!window.testRunner)
+ return;
+
+ await UIHelper.activateElementAndWaitForInputSession(editor);
+ let initialContentOffset = await UIHelper.contentOffset();
+
+ await UIHelper.setHardwareKeyboardAttached(false);
+
+ let contentOffset = initialContentOffset;
+ while (contentOffset.y <= initialContentOffset.y) {
+ await UIHelper.delayFor(200);
+ contentOffset = await UIHelper.contentOffset();
+ }
+
+ testPassed("Scrolled in response to showing software keyboard");
+
+ editor.blur();
+ await UIHelper.waitForKeyboardToHide();
+
+ finishJSTest();
+});
+</script>
+<style>
+html, body {
+ width: 100%;
+ height: 100%;
+}
+
+div[contenteditable] {
+ position: fixed;
+ width: calc(100% - 16px);
+ bottom: 1em;
+ border: tomato solid 1px;
+ outline: none;
+}
+</style>
+</head>
+<body>
+ <div contenteditable></div>
+ <div id="description"></div>
+ <div id="console"></div>
+</body>
+</html>
\ No newline at end of file
Modified: branches/safari-611-branch/Source/WebKit/ChangeLog (271827 => 271828)
--- branches/safari-611-branch/Source/WebKit/ChangeLog 2021-01-25 22:11:27 UTC (rev 271827)
+++ branches/safari-611-branch/Source/WebKit/ChangeLog 2021-01-25 22:11:34 UTC (rev 271828)
@@ -1,5 +1,136 @@
2021-01-25 Alan Coon <[email protected]>
+ Cherry-pick r271543. rdar://problem/73469576
+
+ [iOS] Emoji keyboard covers text field on twitter.com/messages
+ https://bugs.webkit.org/show_bug.cgi?id=220664
+ <rdar://problem/68400471>
+
+ Reviewed by Devin Rousso.
+
+ Source/WebKit:
+
+ After iOS 14, the emoji software keyboard layout now includes a search field that can be used to filter for
+ specific emojis. This slightly increases the overall height of the software keyboard when the emoji keyplane is
+ active; in turn, this means that if the selection or caret is positioned right above the top of the software
+ keyboard when the normal (alphabetic) keyplane is active, switching to the emoji keyplane will cause the
+ keyboard to overlap the selection, making it difficult to see inserted text.
+
+ To address this, add a mechanism to detect when a change in the bounds of the software keyboard causes a visible
+ selection or caret rect to become overlapped, and react by scrolling to keep the selection visible. This has the
+ effect of fixing this bug by scrolling to reveal the text field after switching to the emoji keyboard, but it
+ also has the effect of scrolling to keep the selection visible after detaching a connected hardware keyboard,
+ in the case where it would've otherwise been overlapped by the (much taller) software keyboard that appears.
+
+ Test: editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard.html
+
+ * UIProcess/API/ios/WKWebViewIOS.h:
+ * UIProcess/API/ios/WKWebViewIOS.mm:
+ (-[WKWebView _selectionRectIsFullyVisibleAndNonEmpty]):
+
+ Add an internal helper to check whether the selection bounds are fully visible.
+
+ (-[WKWebView _scrollToRevealSelectionIfNeeded]):
+ (-[WKWebView _zoomToFocusRect:selectionRect:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]):
+ (-[WKWebView _keyboardChangedWithInfo:adjustScrollView:]):
+
+ In the case where changing input view bounds causes a previously visible selection to become overlapped, call
+ `-_scrollToRevealSelectionIfNeeded` to make the selection visible again.
+
+ (-[WKWebView _zoomToFocusRect:selectionRect:insideFixed:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]): Deleted.
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/WKContentView.h:
+ * UIProcess/ios/WKContentView.mm:
+ (-[WKContentView _zoomToFocusRect:selectionRect:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]):
+ (-[WKContentView _zoomToFocusRect:selectionRect:insideFixed:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]): Deleted.
+
+ Drive-by fix: remove the unused `insideFixed:` parameter from this adjacent method.
+
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView rectToRevealWhenZoomingToFocusedElement]):
+ (-[WKContentView _zoomToRevealFocusedElement]):
+ (rectToRevealWhenZoomingToFocusedElement): Deleted.
+
+ Pull this into the `-rectToRevealWhenZoomingToFocusedElement` internal helper method instead, and use the new
+ `selectionBoundingRectInRootViewCoordinates` method below.
+
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::selectionBoundingRectInRootViewCoordinates const):
+
+ Pull out code to compute the selection bounding rect (for both ranged and caret selections) into a method on
+ `WebPageProxy`, so that it can be used in `WKContentView` and `WKWebView`.
+
+ LayoutTests:
+
+ Add a test to verify that after disconnecting a hardware keyboard and showing the software keyboard, we scroll
+ up to reveal the caret in a focused text field.
+
+ * editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard-expected.txt: Added.
+ * editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard.html: Added.
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271543 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2021-01-15 Wenson Hsieh <[email protected]>
+
+ [iOS] Emoji keyboard covers text field on twitter.com/messages
+ https://bugs.webkit.org/show_bug.cgi?id=220664
+ <rdar://problem/68400471>
+
+ Reviewed by Devin Rousso.
+
+ After iOS 14, the emoji software keyboard layout now includes a search field that can be used to filter for
+ specific emojis. This slightly increases the overall height of the software keyboard when the emoji keyplane is
+ active; in turn, this means that if the selection or caret is positioned right above the top of the software
+ keyboard when the normal (alphabetic) keyplane is active, switching to the emoji keyplane will cause the
+ keyboard to overlap the selection, making it difficult to see inserted text.
+
+ To address this, add a mechanism to detect when a change in the bounds of the software keyboard causes a visible
+ selection or caret rect to become overlapped, and react by scrolling to keep the selection visible. This has the
+ effect of fixing this bug by scrolling to reveal the text field after switching to the emoji keyboard, but it
+ also has the effect of scrolling to keep the selection visible after detaching a connected hardware keyboard,
+ in the case where it would've otherwise been overlapped by the (much taller) software keyboard that appears.
+
+ Test: editing/selection/ios/scroll-to-reveal-selection-when-showing-software-keyboard.html
+
+ * UIProcess/API/ios/WKWebViewIOS.h:
+ * UIProcess/API/ios/WKWebViewIOS.mm:
+ (-[WKWebView _selectionRectIsFullyVisibleAndNonEmpty]):
+
+ Add an internal helper to check whether the selection bounds are fully visible.
+
+ (-[WKWebView _scrollToRevealSelectionIfNeeded]):
+ (-[WKWebView _zoomToFocusRect:selectionRect:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]):
+ (-[WKWebView _keyboardChangedWithInfo:adjustScrollView:]):
+
+ In the case where changing input view bounds causes a previously visible selection to become overlapped, call
+ `-_scrollToRevealSelectionIfNeeded` to make the selection visible again.
+
+ (-[WKWebView _zoomToFocusRect:selectionRect:insideFixed:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]): Deleted.
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/WKContentView.h:
+ * UIProcess/ios/WKContentView.mm:
+ (-[WKContentView _zoomToFocusRect:selectionRect:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]):
+ (-[WKContentView _zoomToFocusRect:selectionRect:insideFixed:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]): Deleted.
+
+ Drive-by fix: remove the unused `insideFixed:` parameter from this adjacent method.
+
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView rectToRevealWhenZoomingToFocusedElement]):
+ (-[WKContentView _zoomToRevealFocusedElement]):
+ (rectToRevealWhenZoomingToFocusedElement): Deleted.
+
+ Pull this into the `-rectToRevealWhenZoomingToFocusedElement` internal helper method instead, and use the new
+ `selectionBoundingRectInRootViewCoordinates` method below.
+
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::selectionBoundingRectInRootViewCoordinates const):
+
+ Pull out code to compute the selection bounding rect (for both ranged and caret selections) into a method on
+ `WebPageProxy`, so that it can be used in `WKContentView` and `WKWebView`.
+
+2021-01-25 Alan Coon <[email protected]>
+
Cherry-pick r271497. rdar://problem/73469623
Exceptions thrown when invoking a <select> on an iPhone-idiom app running on macOS
Modified: branches/safari-611-branch/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h (271827 => 271828)
--- branches/safari-611-branch/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h 2021-01-25 22:11:27 UTC (rev 271827)
+++ branches/safari-611-branch/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h 2021-01-25 22:11:34 UTC (rev 271828)
@@ -69,7 +69,7 @@
- (double)_contentZoomScale;
- (double)_targetContentZoomScaleForRect:(const WebCore::FloatRect&)targetRect currentScale:(double)currentScale fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale;
-- (void)_zoomToFocusRect:(const WebCore::FloatRect&)focusedElementRect selectionRect:(const WebCore::FloatRect&)selectionRectInDocumentCoordinates insideFixed:(BOOL)insideFixed fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll;
+- (void)_zoomToFocusRect:(const WebCore::FloatRect&)focusedElementRect selectionRect:(const WebCore::FloatRect&)selectionRectInDocumentCoordinates fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll;
- (BOOL)_zoomToRect:(WebCore::FloatRect)targetRect withOrigin:(WebCore::FloatPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(float)minimumScrollDistance;
- (void)_zoomOutWithOrigin:(WebCore::FloatPoint)origin animated:(BOOL)animated;
- (void)_zoomToInitialScaleWithOrigin:(WebCore::FloatPoint)origin animated:(BOOL)animated;
Modified: branches/safari-611-branch/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm (271827 => 271828)
--- branches/safari-611-branch/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2021-01-25 22:11:27 UTC (rev 271827)
+++ branches/safari-611-branch/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2021-01-25 22:11:34 UTC (rev 271828)
@@ -1187,12 +1187,51 @@
[self _zoomToPoint:origin atScale:_initialScaleFactor animated:animated];
}
-// focusedElementRect and selectionRect are both in document coordinates.
-- (void)_zoomToFocusRect:(const WebCore::FloatRect&)focusedElementRectInDocumentCoordinates selectionRect:(const WebCore::FloatRect&)selectionRectInDocumentCoordinates insideFixed:(BOOL)insideFixed
+- (BOOL)_selectionRectIsFullyVisibleAndNonEmpty
+{
+ auto rect = _page->selectionBoundingRectInRootViewCoordinates();
+ return !rect.isEmpty() && CGRectContainsRect(self._contentRectForUserInteraction, rect);
+}
+
+- (void)_scrollToAndRevealSelectionIfNeeded
+{
+ if (![_scrollView isScrollEnabled])
+ return;
+
+ auto selectionRect = _page->selectionBoundingRectInRootViewCoordinates();
+ constexpr CGFloat selectionRectPadding = 4;
+ selectionRect.inflate(selectionRectPadding);
+ selectionRect.intersect([_contentView bounds]);
+ if (selectionRect.isEmpty())
+ return;
+
+ WebCore::FloatRect userInteractionContentRect = self._contentRectForUserInteraction;
+ auto scrollDeltaInContentCoordinates = CGSizeZero;
+
+ if (userInteractionContentRect.maxY() < selectionRect.maxY())
+ scrollDeltaInContentCoordinates.height = selectionRect.maxY() - userInteractionContentRect.maxY();
+ else if (userInteractionContentRect.y() > selectionRect.y())
+ scrollDeltaInContentCoordinates.height = selectionRect.y() - userInteractionContentRect.y();
+
+ if (userInteractionContentRect.maxX() < selectionRect.maxX())
+ scrollDeltaInContentCoordinates.width = selectionRect.maxX() - userInteractionContentRect.maxX();
+ else if (userInteractionContentRect.x() > selectionRect.x())
+ scrollDeltaInContentCoordinates.width = selectionRect.x() - userInteractionContentRect.x();
+
+ if (CGSizeEqualToSize(scrollDeltaInContentCoordinates, CGSizeZero))
+ return;
+
+ auto scale = contentZoomScale(self);
+ auto newContentOffset = [_scrollView contentOffset];
+ newContentOffset.x += scrollDeltaInContentCoordinates.width * scale;
+ newContentOffset.y += scrollDeltaInContentCoordinates.height * scale;
+ [_scrollView setContentOffset:newContentOffset animated:YES];
+}
+
+- (void)_zoomToFocusRect:(const WebCore::FloatRect&)focusedElementRectInDocumentCoordinates selectionRect:(const WebCore::FloatRect&)selectionRectInDocumentCoordinates
fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll
{
LOG_WITH_STREAM(VisibleRects, stream << "_zoomToFocusRect:" << focusedElementRectInDocumentCoordinates << " selectionRect:" << selectionRectInDocumentCoordinates);
- UNUSED_PARAM(insideFixed);
const double minimumHeightToShowContentAboveKeyboard = 106;
const CFTimeInterval formControlZoomAnimationDuration = 0.25;
@@ -2249,6 +2288,9 @@
if (!endFrameValue)
return;
+ auto previousInputViewBounds = _inputViewBounds;
+ BOOL selectionWasVisible = self._selectionRectIsFullyVisibleAndNonEmpty;
+
// The keyboard rect is always in screen coordinates. In the view services case the window does not
// have the interface orientation rotation transformation; its host does. So, it makes no sense to
// clip the keyboard rect against its screen.
@@ -2272,6 +2314,9 @@
_totalScrollViewBottomInsetAdjustmentForKeyboard += bottomInsetAfterAdjustment - bottomInsetBeforeAdjustment;
}
+ if (selectionWasVisible && [_contentView _hasFocusedElement] && !CGRectIsEmpty(previousInputViewBounds) && !CGRectIsEmpty(_inputViewBounds) && !CGRectEqualToRect(previousInputViewBounds, _inputViewBounds))
+ [self _scrollToAndRevealSelectionIfNeeded];
+
[self _scheduleVisibleContentRectUpdate];
}
Modified: branches/safari-611-branch/Source/WebKit/UIProcess/WebPageProxy.h (271827 => 271828)
--- branches/safari-611-branch/Source/WebKit/UIProcess/WebPageProxy.h 2021-01-25 22:11:27 UTC (rev 271827)
+++ branches/safari-611-branch/Source/WebKit/UIProcess/WebPageProxy.h 2021-01-25 22:11:34 UTC (rev 271828)
@@ -818,6 +818,7 @@
bool isScrollingOrZooming() const { return m_isScrollingOrZooming; }
void requestEvasionRectsAboveSelection(CompletionHandler<void(const Vector<WebCore::FloatRect>&)>&&);
void updateSelectionWithDelta(int64_t locationDelta, int64_t lengthDelta, CompletionHandler<void()>&&);
+ WebCore::FloatRect selectionBoundingRectInRootViewCoordinates() const;
void requestDocumentEditingContext(WebKit::DocumentEditingContextRequest, CompletionHandler<void(WebKit::DocumentEditingContext)>&&);
void generateSyntheticEditingCommand(SyntheticEditingCommandType);
void showDataDetectorsUIForPositionInformation(const InteractionInformationAtPosition&);
Modified: branches/safari-611-branch/Source/WebKit/UIProcess/ios/WKContentView.h (271827 => 271828)
--- branches/safari-611-branch/Source/WebKit/UIProcess/ios/WKContentView.h 2021-01-25 22:11:27 UTC (rev 271827)
+++ branches/safari-611-branch/Source/WebKit/UIProcess/ios/WKContentView.h 2021-01-25 22:11:34 UTC (rev 271828)
@@ -117,7 +117,7 @@
- (void)_setAccessibilityWebProcessToken:(NSData *)data;
- (BOOL)_scrollToRect:(CGRect)targetRect withOrigin:(CGPoint)origin minimumScrollDistance:(CGFloat)minimumScrollDistance;
-- (void)_zoomToFocusRect:(CGRect)rectToFocus selectionRect:(CGRect)selectionRect insideFixed:(BOOL)insideFixed fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll;
+- (void)_zoomToFocusRect:(CGRect)rectToFocus selectionRect:(CGRect)selectionRect fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll;
- (BOOL)_zoomToRect:(CGRect)targetRect withOrigin:(CGPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(CGFloat)minimumScrollDistance;
- (void)_zoomOutWithOrigin:(CGPoint)origin;
- (void)_zoomToInitialScaleWithOrigin:(CGPoint)origin;
Modified: branches/safari-611-branch/Source/WebKit/UIProcess/ios/WKContentView.mm (271827 => 271828)
--- branches/safari-611-branch/Source/WebKit/UIProcess/ios/WKContentView.mm 2021-01-25 22:11:27 UTC (rev 271827)
+++ branches/safari-611-branch/Source/WebKit/UIProcess/ios/WKContentView.mm 2021-01-25 22:11:34 UTC (rev 271828)
@@ -713,11 +713,10 @@
return [_webView _scrollToRect:targetRect origin:origin minimumScrollDistance:minimumScrollDistance];
}
-- (void)_zoomToFocusRect:(CGRect)rectToFocus selectionRect:(CGRect)selectionRect insideFixed:(BOOL)insideFixed fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll
+- (void)_zoomToFocusRect:(CGRect)rectToFocus selectionRect:(CGRect)selectionRect fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll
{
[_webView _zoomToFocusRect:rectToFocus
selectionRect:selectionRect
- insideFixed:insideFixed
fontSize:fontSize
minimumScale:minimumScale
maximumScale:maximumScale
Modified: branches/safari-611-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (271827 => 271828)
--- branches/safari-611-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2021-01-25 22:11:27 UTC (rev 271827)
+++ branches/safari-611-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2021-01-25 22:11:34 UTC (rev 271828)
@@ -2021,6 +2021,23 @@
return YES;
}
+- (WebCore::FloatRect)rectToRevealWhenZoomingToFocusedElement
+{
+ WebCore::IntRect elementInteractionRect;
+ if (_focusedElementInformation.interactionRect.contains(_focusedElementInformation.lastInteractionLocation))
+ elementInteractionRect = { _focusedElementInformation.lastInteractionLocation, { 1, 1 } };
+
+ if (!mayContainSelectableText(_focusedElementInformation.elementType))
+ return elementInteractionRect;
+
+ if (_page->editorState().isMissingPostLayoutData)
+ return elementInteractionRect;
+
+ auto boundingRect = _page->selectionBoundingRectInRootViewCoordinates();
+ boundingRect.intersect(_focusedElementInformation.interactionRect);
+ return boundingRect;
+}
+
- (void)_zoomToRevealFocusedElement
{
if (_suppressSelectionAssistantReasons || _textInteractionIsHappening)
@@ -2029,8 +2046,7 @@
// In case user scaling is force enabled, do not use that scaling when zooming in with an input field.
// Zooming above the page's default scale factor should only happen when the user performs it.
[self _zoomToFocusRect:_focusedElementInformation.interactionRect
- selectionRect:_didAccessoryTabInitiateFocus ? WebCore::FloatRect() : rectToRevealWhenZoomingToFocusedElement(_focusedElementInformation, _page->editorState())
- insideFixed:_focusedElementInformation.insideFixedPosition
+ selectionRect:_didAccessoryTabInitiateFocus ? WebCore::FloatRect() : self.rectToRevealWhenZoomingToFocusedElement
fontSize:_focusedElementInformation.nodeFontSize
minimumScale:_focusedElementInformation.minimumScaleFactor
maximumScale:_focusedElementInformation.maximumScaleFactorIgnoringAlwaysScalable
@@ -5909,35 +5925,6 @@
return elementTypeRequiresAccessoryView(information.elementType);
}
-static WebCore::FloatRect rectToRevealWhenZoomingToFocusedElement(const WebKit::FocusedElementInformation& elementInfo, const WebKit::EditorState& editorState)
-{
- WebCore::IntRect elementInteractionRect;
- if (elementInfo.interactionRect.contains(elementInfo.lastInteractionLocation))
- elementInteractionRect = { elementInfo.lastInteractionLocation, { 1, 1 } };
-
- if (!mayContainSelectableText(elementInfo.elementType))
- return elementInteractionRect;
-
- if (editorState.isMissingPostLayoutData) {
- ASSERT_NOT_REACHED();
- return elementInteractionRect;
- }
-
- if (editorState.selectionIsNone)
- return { };
-
- WebCore::FloatRect selectionBoundingRect;
- auto& postLayoutData = editorState.postLayoutData();
- if (editorState.selectionIsRange) {
- for (auto& rect : postLayoutData.selectionRects)
- selectionBoundingRect.unite(rect.rect());
- } else
- selectionBoundingRect = postLayoutData.caretRectAtStart;
-
- selectionBoundingRect.intersect(elementInfo.interactionRect);
- return selectionBoundingRect;
-}
-
static RetainPtr<NSObject <WKFormPeripheral>> createInputPeripheralWithView(WebKit::InputType type, WKContentView *view)
{
#if PLATFORM(WATCHOS)
Modified: branches/safari-611-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (271827 => 271828)
--- branches/safari-611-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2021-01-25 22:11:27 UTC (rev 271827)
+++ branches/safari-611-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2021-01-25 22:11:34 UTC (rev 271828)
@@ -1146,6 +1146,25 @@
sendWithAsyncReply(Messages::WebPage::UpdateSelectionWithDelta(locationDelta, lengthDelta), WTFMove(completionHandler));
}
+WebCore::FloatRect WebPageProxy::selectionBoundingRectInRootViewCoordinates() const
+{
+ if (m_editorState.selectionIsNone)
+ return { };
+
+ if (m_editorState.isMissingPostLayoutData)
+ return { };
+
+ WebCore::FloatRect bounds;
+ auto& postLayoutData = m_editorState.postLayoutData();
+ if (m_editorState.selectionIsRange) {
+ for (auto& rect : postLayoutData.selectionRects)
+ bounds.unite(rect.rect());
+ } else
+ bounds = postLayoutData.caretRectAtStart;
+
+ return bounds;
+}
+
void WebPageProxy::requestDocumentEditingContext(WebKit::DocumentEditingContextRequest request, CompletionHandler<void(WebKit::DocumentEditingContext)>&& completionHandler)
{
if (!hasRunningProcess()) {