Diff
Modified: trunk/LayoutTests/ChangeLog (250314 => 250315)
--- trunk/LayoutTests/ChangeLog 2019-09-24 19:22:22 UTC (rev 250314)
+++ trunk/LayoutTests/ChangeLog 2019-09-24 20:06:48 UTC (rev 250315)
@@ -1,3 +1,22 @@
+2019-09-24 Zalan Bujtas <za...@apple.com>
+
+ [iPadOs] The second click event is missing on double tap when dblclick handler is not present
+ https://bugs.webkit.org/show_bug.cgi?id=202006
+ <rdar://problem/51706828>
+
+ Reviewed by Wenson Hsieh.
+
+ * fast/events/touch/ios/double-tap-for-two-clicks1-expected.txt: Added.
+ * fast/events/touch/ios/double-tap-for-two-clicks1.html: Added.
+ * fast/events/touch/ios/double-tap-for-two-clicks2-expected.txt: Added.
+ * fast/events/touch/ios/double-tap-for-two-clicks2.html: Added.
+ * fast/events/touch/ios/double-tap-for-two-clicks3-expected.txt: Added.
+ * fast/events/touch/ios/double-tap-for-two-clicks3.html: Added.
+ * fast/events/touch/ios/double-tap-for-two-clicks4-expected.txt: Added.
+ * fast/events/touch/ios/double-tap-for-two-clicks4.html: Added.
+ * fast/events/touch/ios/doubleclick.html: Added.
+ * fast/events/touch/resources/doubleClickContent.html: Added.
+
2019-09-24 Antoine Quint <grao...@apple.com>
[Web Animations] Unflake web-animations/timing-model/animations/updating-the-finished-state.html WPT test
Added: trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks1-expected.txt (0 => 250315)
--- trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks1-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks1-expected.txt 2019-09-24 20:06:48 UTC (rev 250315)
@@ -0,0 +1,2 @@
+PASS if '[click][click]' text is shown below.
+[click][click]
Added: trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks1.html (0 => 250315)
--- trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks1.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks1.html 2019-09-24 20:06:48 UTC (rev 250315)
@@ -0,0 +1,40 @@
+<!DOCTYPE html><!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="width=device-width initial-scale=1 user-scalable=no">
+<title>This tests that we fire two click events on double tap when dblclick handler is not present.</title>
+<script src=""
+<style>
+#doubleTapthis {
+ width: 400px;
+ height: 400px;
+ border: 1px solid green;
+}
+</style>
+<script>
+async function test() {
+ if (!window.testRunner || !testRunner.runUIScript)
+ return;
+
+ testRunner.waitUntilDone();
+ testRunner.dumpAsText();
+
+ await UIHelper.humanSpeedDoubleTapAt(doubleTapthis.offsetLeft, doubleTapthis.offsetTop);
+}
+</script>
+</head>
+<body _onload_="test()">
+<div id=doubleTapthis>PASS if '[click][click]' text is shown below.</div>
+<pre id=result></pre>
+<script>
+let numberOfClicks = 0;
+
+doubleTapthis.addEventListener("click", function( event ) {
+ result.innerHTML = result.innerHTML + "[click]";
+ if (++numberOfClicks == 2 && window.testRunner)
+ setTimeout("testRunner.notifyDone()", 0);
+}, false);
+
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks2-expected.txt (0 => 250315)
--- trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks2-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks2-expected.txt 2019-09-24 20:06:48 UTC (rev 250315)
@@ -0,0 +1,2 @@
+PASS if '[click][click]' text is shown below.
+[click][click]
Added: trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks2.html (0 => 250315)
--- trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks2.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks2.html 2019-09-24 20:06:48 UTC (rev 250315)
@@ -0,0 +1,46 @@
+<!DOCTYPE html><!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="width=device-width initial-scale=1 user-scalable=no">
+<title>This tests that we fire two click events on double tap when dblclick handler is removed dynamically.</title>
+<script src=""
+<style>
+#doubleTapthis {
+ width: 400px;
+ height: 400px;
+ border: 1px solid green;
+}
+</style>
+</head>
+<body _onload_="test()">
+<div id=doubleTapthis>PASS if '[click][click]' text is shown below.</div>
+<pre id=result></pre>
+<script>
+
+function dblclickHandler(event) {
+ result.innerHTML = result.innerHTML + "[should not double click]";
+}
+
+doubleTapthis.addEventListener("dblclick", dblclickHandler, false);
+
+let numberOfClicks = 0;
+doubleTapthis.addEventListener("click", function( event ) {
+ result.innerHTML = result.innerHTML + "[click]";
+ if (++numberOfClicks == 2 && window.testRunner)
+ setTimeout("testRunner.notifyDone()", 0);
+}, false);
+
+async function test() {
+ doubleTapthis.removeEventListener("dblclick", dblclickHandler, false);
+
+ if (!window.testRunner || !testRunner.runUIScript)
+ return;
+
+ testRunner.waitUntilDone();
+ testRunner.dumpAsText();
+
+ await UIHelper.humanSpeedDoubleTapAt(doubleTapthis.offsetLeft, doubleTapthis.offsetTop);
+}
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks3-expected.txt (0 => 250315)
--- trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks3-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks3-expected.txt 2019-09-24 20:06:48 UTC (rev 250315)
@@ -0,0 +1,2 @@
+PASS if '[click][click][double click]' text is shown below.
+[click][click][double click]
Added: trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks3.html (0 => 250315)
--- trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks3.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks3.html 2019-09-24 20:06:48 UTC (rev 250315)
@@ -0,0 +1,50 @@
+<!DOCTYPE html><!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="width=device-width initial-scale=1 user-scalable=no">
+<title>This tests that we fire two click events on double tap when multiple dblclick handlers are present.</title>
+<script src=""
+<style>
+#doubleTapthis {
+ width: 400px;
+ height: 400px;
+ border: 1px solid green;
+}
+</style>
+</head>
+<body _onload_="test()">
+<div id=doubleTapthis>PASS if '[click][click][double click]' text is shown below.</div>
+<pre id=result></pre>
+<script>
+
+doubleTapthis.addEventListener("click", function( event ) {
+ result.innerHTML = result.innerHTML + "[click]";
+}, false);
+
+function dblclickHandler(event) {
+ result.innerHTML = result.innerHTML + "[double click]";
+ if (window.testRunner)
+ setTimeout("testRunner.notifyDone()", 0);
+}
+
+function dblclickHandlerForResult(event) {
+ result.innerHTML = result.innerHTML + "[should not double click]";
+}
+
+doubleTapthis.addEventListener("dblclick", dblclickHandler, false);
+result.addEventListener("dblclick", dblclickHandlerForResult, false);
+
+async function test() {
+ doubleTapthis.removeEventListener("result", dblclickHandler, false);
+
+ if (!window.testRunner || !testRunner.runUIScript)
+ return;
+
+ testRunner.waitUntilDone();
+ testRunner.dumpAsText();
+
+ await UIHelper.humanSpeedDoubleTapAt(doubleTapthis.offsetLeft, doubleTapthis.offsetTop);
+}
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks4-expected.txt (0 => 250315)
--- trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks4-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks4-expected.txt 2019-09-24 20:06:48 UTC (rev 250315)
@@ -0,0 +1,2 @@
+PASS if '[click][click][double click]' text is shown below.
+ [click][click][double click]
Added: trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks4.html (0 => 250315)
--- trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks4.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/double-tap-for-two-clicks4.html 2019-09-24 20:06:48 UTC (rev 250315)
@@ -0,0 +1,46 @@
+<!DOCTYPE html><!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="width=device-width initial-scale=1 user-scalable=no">
+<title>This tests that we fire two click events on double tap when dblclick handler is in an iframe.</title>
+<script src=""
+<style>
+#doubleTapthis {
+ width: 400px;
+ height: 400px;
+ border: 1px solid green;
+}
+</style>
+</head>
+<body _onload_="test()">
+<div id=doubleTapthis>PASS if '[click][click][double click]' text is shown below.</div>
+<iframe id=removeMe src=""
+<pre id=result></pre>
+<script>
+
+doubleTapthis.addEventListener("click", function( event ) {
+ result.innerHTML = result.innerHTML + "[click]";
+}, false);
+
+function dblclickHandler(event) {
+ result.innerHTML = result.innerHTML + "[double click]";
+ if (window.testRunner)
+ setTimeout("testRunner.notifyDone()", 0);
+}
+
+doubleTapthis.addEventListener("dblclick", dblclickHandler, false);
+
+async function test() {
+ removeMe.remove();
+
+ if (!window.testRunner || !testRunner.runUIScript)
+ return;
+
+ testRunner.waitUntilDone();
+ testRunner.dumpAsText();
+
+ await UIHelper.humanSpeedDoubleTapAt(doubleTapthis.offsetLeft, doubleTapthis.offsetTop);
+}
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/resources/doubleClickContent.html (0 => 250315)
--- trunk/LayoutTests/fast/events/touch/resources/doubleClickContent.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/resources/doubleClickContent.html 2019-09-24 20:06:48 UTC (rev 250315)
@@ -0,0 +1,8 @@
+<div id=doubleTap1>some text</div>
+<div id=doubleTap2>some text</div>
+<script>
+function dblclickHandler(event) {
+}
+doubleTap1.addEventListener("dblclick", dblclickHandler, false);
+doubleTap2.addEventListener("dblclick", dblclickHandler, false);
+</script>
Modified: trunk/Source/WebKit/ChangeLog (250314 => 250315)
--- trunk/Source/WebKit/ChangeLog 2019-09-24 19:22:22 UTC (rev 250314)
+++ trunk/Source/WebKit/ChangeLog 2019-09-24 20:06:48 UTC (rev 250315)
@@ -1,3 +1,31 @@
+2019-09-24 Zalan Bujtas <za...@apple.com>
+
+ [iPadOs] The second click event is missing on double tap when dblclick handler is not present
+ https://bugs.webkit.org/show_bug.cgi?id=202006
+ <rdar://problem/51706828>
+
+ Reviewed by Wenson Hsieh.
+
+ While double tapping,
+ 1. the first tap triggers a click event through the normal _singleTapIdentified/_singleTapRecognized codepath.
+ 2. and the second tap should trigger either
+ a second single click event or
+ a second single click followed by a dblclick event when dblclick handler is present.
+ However the second click is dropped on the floor when the node under the cursor does not have a dblclick handler (see handleDoubleTapForDoubleClickAtPoint()) -so we end up sending one click event.
+
+ This patch fixes this case by sending the second tap through the normal single tap flow when the dblclick handler is not present.
+
+ * Shared/ios/InteractionInformationAtPosition.h:
+ * Shared/ios/InteractionInformationAtPosition.mm:
+ (WebKit::InteractionInformationAtPosition::encode const):
+ (WebKit::InteractionInformationAtPosition::decode):
+ * UIProcess/ios/WKContentViewInteraction.h:
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView setupInteraction]):
+ (-[WKContentView gestureRecognizerShouldBegin:]):
+ (WebKit::WebPage::positionInformation):
+ (WebKit::WebPage::requestPositionInformation):
+
2019-09-24 Alex Christensen <achristen...@webkit.org>
Move HSTS storage directory to LegacyGlobalSettings
Modified: trunk/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h (250314 => 250315)
--- trunk/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h 2019-09-24 19:22:22 UTC (rev 250314)
+++ trunk/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h 2019-09-24 20:06:48 UTC (rev 250315)
@@ -51,6 +51,7 @@
bool canBeValid { true };
bool nodeAtPositionIsFocusedElement { false };
+ bool nodeAtPositionHasDoubleClickHandler { false };
#if ENABLE(DATA_INTERACTION)
bool hasSelectionAtPosition { false };
#endif
Modified: trunk/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm (250314 => 250315)
--- trunk/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm 2019-09-24 19:22:22 UTC (rev 250314)
+++ trunk/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm 2019-09-24 20:06:48 UTC (rev 250315)
@@ -45,6 +45,7 @@
encoder << canBeValid;
encoder << nodeAtPositionIsFocusedElement;
+ encoder << nodeAtPositionHasDoubleClickHandler;
#if ENABLE(DATA_INTERACTION)
encoder << hasSelectionAtPosition;
#endif
@@ -97,6 +98,9 @@
if (!decoder.decode(result.nodeAtPositionIsFocusedElement))
return false;
+ if (!decoder.decode(result.nodeAtPositionHasDoubleClickHandler))
+ return false;
+
#if ENABLE(DATA_INTERACTION)
if (!decoder.decode(result.hasSelectionAtPosition))
return false;
Modified: trunk/Source/WebKit/Shared/ios/InteractionInformationRequest.cpp (250314 => 250315)
--- trunk/Source/WebKit/Shared/ios/InteractionInformationRequest.cpp 2019-09-24 19:22:22 UTC (rev 250314)
+++ trunk/Source/WebKit/Shared/ios/InteractionInformationRequest.cpp 2019-09-24 20:06:48 UTC (rev 250315)
@@ -58,11 +58,8 @@
return true;
}
-bool InteractionInformationRequest::isValidForRequest(const InteractionInformationRequest& other)
+bool InteractionInformationRequest::isValidForRequest(const InteractionInformationRequest& other, int radius)
{
- if (other.point != point)
- return false;
-
if (other.includeSnapshot && !includeSnapshot)
return false;
@@ -72,21 +69,12 @@
if (other.linkIndicatorShouldHaveLegacyMargins != linkIndicatorShouldHaveLegacyMargins)
return false;
- return true;
+ return (other.point - point).diagonalLengthSquared() <= radius * radius;
}
-bool InteractionInformationRequest::isApproximatelyValidForRequest(const InteractionInformationRequest& other)
+bool InteractionInformationRequest::isApproximatelyValidForRequest(const InteractionInformationRequest& other, int radius)
{
- if (other.includeSnapshot && !includeSnapshot)
- return false;
-
- if (other.includeLinkIndicator && !includeLinkIndicator)
- return false;
-
- if (other.linkIndicatorShouldHaveLegacyMargins != linkIndicatorShouldHaveLegacyMargins)
- return false;
-
- return (other.point - point).diagonalLengthSquared() <= 4;
+ return isValidForRequest(other, radius);
}
#endif // PLATFORM(IOS_FAMILY)
Modified: trunk/Source/WebKit/Shared/ios/InteractionInformationRequest.h (250314 => 250315)
--- trunk/Source/WebKit/Shared/ios/InteractionInformationRequest.h 2019-09-24 19:22:22 UTC (rev 250314)
+++ trunk/Source/WebKit/Shared/ios/InteractionInformationRequest.h 2019-09-24 20:06:48 UTC (rev 250315)
@@ -50,8 +50,8 @@
this->point = point;
}
- bool isValidForRequest(const InteractionInformationRequest&);
- bool isApproximatelyValidForRequest(const InteractionInformationRequest& other);
+ bool isValidForRequest(const InteractionInformationRequest&, int radius = 0);
+ bool isApproximatelyValidForRequest(const InteractionInformationRequest&, int radius);
void encode(IPC::Encoder&) const;
static bool decode(IPC::Decoder&, InteractionInformationRequest&);
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (250314 => 250315)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2019-09-24 19:22:22 UTC (rev 250314)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2019-09-24 20:06:48 UTC (rev 250315)
@@ -2112,9 +2112,9 @@
return _outstandingPositionInformationRequest && _outstandingPositionInformationRequest->isValidForRequest(request);
}
-- (BOOL)_currentPositionInformationIsApproximatelyValidForRequest:(const WebKit::InteractionInformationRequest&)request
+- (BOOL)_currentPositionInformationIsApproximatelyValidForRequest:(const WebKit::InteractionInformationRequest&)request radiusForApproximation:(int)radius
{
- return _hasValidPositionInformation && _positionInformation.request.isApproximatelyValidForRequest(request);
+ return _hasValidPositionInformation && _positionInformation.request.isApproximatelyValidForRequest(request, radius);
}
- (void)_invokeAndRemovePendingHandlersValidForCurrentPositionInformation
@@ -2191,10 +2191,19 @@
if (gestureRecognizer == _singleTapGestureRecognizer)
return !isInterruptingDecelerationForScrollViewOrAncestor([_singleTapGestureRecognizer lastTouchedScrollView]);
+ if (gestureRecognizer == _doubleTapGestureRecognizerForDoubleClick) {
+ // Do not start the double-tap-for-double-click gesture recognizer unless we've got a dblclick event handler on the node at the tap location.
+ WebKit::InteractionInformationRequest request(WebCore::roundedIntPoint(point));
+ if ([self _currentPositionInformationIsApproximatelyValidForRequest:request radiusForApproximation:[_doubleTapGestureRecognizerForDoubleClick allowableMovement]])
+ return _positionInformation.nodeAtPositionHasDoubleClickHandler;
+ if (![self ensurePositionInformationIsUpToDate:request])
+ return NO;
+ return _positionInformation.nodeAtPositionHasDoubleClickHandler;
+ }
+
if (gestureRecognizer == _highlightLongPressGestureRecognizer
|| gestureRecognizer == _doubleTapGestureRecognizer
|| gestureRecognizer == _nonBlockingDoubleTapGestureRecognizer
- || gestureRecognizer == _doubleTapGestureRecognizerForDoubleClick
|| gestureRecognizer == _twoFingerDoubleTapGestureRecognizer) {
if (hasFocusedElement(_focusedElementInformation)) {
@@ -4471,7 +4480,7 @@
#if PLATFORM(MACCATALYST)
WebKit::InteractionInformationRequest request(WebCore::roundedIntPoint(point));
[self requestAsynchronousPositionInformationUpdate:request];
- if ([self _currentPositionInformationIsApproximatelyValidForRequest:request] && _positionInformation.isSelectable)
+ if ([self _currentPositionInformationIsApproximatelyValidForRequest:request radiusForApproximation:2] && _positionInformation.isSelectable)
return [WKTextPosition textPositionWithRect:_positionInformation.caretRect];
#endif
return nil;
Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (250314 => 250315)
--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2019-09-24 19:22:22 UTC (rev 250314)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2019-09-24 20:06:48 UTC (rev 250315)
@@ -2767,10 +2767,11 @@
info.request = request;
FloatPoint adjustedPoint;
- Node* hitNode = m_page->mainFrame().nodeRespondingToClickEvents(request.point, adjustedPoint);
+ auto* nodeRespondingToClickEvents = m_page->mainFrame().nodeRespondingToClickEvents(request.point, adjustedPoint);
- info.nodeAtPositionIsFocusedElement = hitNode == m_focusedElement;
+ info.nodeAtPositionIsFocusedElement = nodeRespondingToClickEvents == m_focusedElement;
info.adjustedPointForNodeRespondingToClickEvents = adjustedPoint;
+ info.nodeAtPositionHasDoubleClickHandler = m_page->mainFrame().nodeRespondingToDoubleClickEvent(request.point, adjustedPoint);
#if ENABLE(DATA_INTERACTION)
info.hasSelectionAtPosition = m_page->hasSelectionAtPosition(adjustedPoint);
@@ -2779,8 +2780,8 @@
if (m_focusedElement)
focusedElementPositionInformation(*this, *m_focusedElement, request, info);
- if (is<Element>(hitNode)) {
- Element& element = downcast<Element>(*hitNode);
+ if (is<Element>(nodeRespondingToClickEvents)) {
+ auto& element = downcast<Element>(*nodeRespondingToClickEvents);
elementPositionInformation(*this, element, request, info);
if (info.isLink && !info.isImage && request.includeSnapshot)
@@ -2792,10 +2793,8 @@
// Prevent the callout bar from showing when tapping on the datalist button.
#if ENABLE(DATALIST_ELEMENT)
- if (is<HTMLInputElement>(hitNode)) {
- const HTMLInputElement& input = downcast<HTMLInputElement>(*hitNode);
- textInteractionPositionInformation(*this, input, request, info);
- }
+ if (is<HTMLInputElement>(nodeRespondingToClickEvents))
+ textInteractionPositionInformation(*this, downcast<HTMLInputElement>(*nodeRespondingToClickEvents), request, info);
#endif
return info;