[ContentChangeObserver] Start observing for content change between touchEnd and mouse...
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 10 Mar 2019 00:09:05 +0000 (00:09 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 10 Mar 2019 00:09:05 +0000 (00:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195510
<rdar://problem/48735695>

Reviewed by Simon Fraser.

Source/WebCore:

This patch covers the observation of async changes triggered by touchStart/touchEnd (animations, timers, style recalcs).

Test: fast/events/touch/ios/content-observation/visibility-change-after-touch-end.html

* page/ios/ContentChangeObserver.cpp:
(WebCore::ContentChangeObserver::didCancelTouchEvent):
(WebCore::ContentChangeObserver::adjustObservedState):
* page/ios/ContentChangeObserver.h:
(WebCore::ContentChangeObserver::setIsInBetweenTouchEndAndMouseMoved):
(WebCore::ContentChangeObserver::isInBetweenTouchEndAndMouseMoved const):
(WebCore::ContentChangeObserver::isObservingContentChanges const):

Source/WebKit:

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::cancelPotentialTapInFrame):

LayoutTests:

* fast/events/touch/ios/content-observation/visibility-change-after-touch-end-expected.txt: Added.
* fast/events/touch/ios/content-observation/visibility-change-after-touch-end.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242675 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/events/touch/ios/content-observation/visibility-change-after-touch-end-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/content-observation/visibility-change-after-touch-end.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/ios/ContentChangeObserver.cpp
Source/WebCore/page/ios/ContentChangeObserver.h
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

index 4c12731..4d6cac7 100644 (file)
@@ -1,3 +1,14 @@
+2019-03-09  Zalan Bujtas  <zalan@apple.com>
+
+        [ContentChangeObserver] Start observing for content change between touchEnd and mouseMoved start
+        https://bugs.webkit.org/show_bug.cgi?id=195510
+        <rdar://problem/48735695>
+
+        Reviewed by Simon Fraser.
+
+        * fast/events/touch/ios/content-observation/visibility-change-after-touch-end-expected.txt: Added.
+        * fast/events/touch/ios/content-observation/visibility-change-after-touch-end.html: Added.
+
 2019-03-08  Ryan Haddad  <ryanhaddad@apple.com>
 
         [ iOS Simulator ] REGRESSION (r237087) Layout Test fast/viewport/ios/*-width-viewport-after-changing-view-scale.html is a flaky failure
diff --git a/LayoutTests/fast/events/touch/ios/content-observation/visibility-change-after-touch-end-expected.txt b/LayoutTests/fast/events/touch/ios/content-observation/visibility-change-after-touch-end-expected.txt
new file mode 100644 (file)
index 0000000..66db4c9
--- /dev/null
@@ -0,0 +1,2 @@
+PASS if 'clicked' text is not shown below.
+
diff --git a/LayoutTests/fast/events/touch/ios/content-observation/visibility-change-after-touch-end.html b/LayoutTests/fast/events/touch/ios/content-observation/visibility-change-after-touch-end.html
new file mode 100644 (file)
index 0000000..50498eb
--- /dev/null
@@ -0,0 +1,59 @@
+<html>
+<head>
+<title>This tests the case when visible content change happens after touchend but before mouseMoved.</title>
+<script src="../../../../../resources/basic-gestures.js"></script>
+<style>
+#tapthis {
+    width: 400px;
+    height: 400px;
+    border: 1px solid green;
+}
+
+#becomesVisible {
+    visibility: hidden;
+    width: 100px;
+    height: 100px;
+    background-color: green;
+}
+</style>
+<script>
+async function test() {
+    if (!window.testRunner || !testRunner.runUIScript)
+        return;
+    if (window.internals)
+        internals.settings.setContentChangeObserverEnabled(true);
+
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+
+    let rect = tapthis.getBoundingClientRect();
+    let x = rect.left + rect.width / 2;
+    let y = rect.top + rect.height / 2;
+
+    await tapAtPoint(x, y);
+}
+</script>
+</head>
+<body onload="test()">
+<div id=tapthis>PASS if 'clicked' text is not shown below.</div>
+<div id=becomesVisible></div>
+<pre id=result></pre>
+<script>
+tapthis.addEventListener("touchend", function( event ) {
+    setTimeout(function() {
+        becomesVisible.style.visibility = "visible";
+         if (window.testRunner)
+             testRunner.notifyDone();
+    }, 0);
+}, false);
+
+becomesVisible.addEventListener("click", function( event ) {   
+    result.innerHTML = "clicked hidden";
+}, false);
+
+tapthis.addEventListener("click", function( event ) {   
+    result.innerHTML = "clicked";
+}, false);
+</script>
+</body>
+</html>
index 793cb70..5eb1d8d 100644 (file)
@@ -1,3 +1,23 @@
+2019-03-09  Zalan Bujtas  <zalan@apple.com>
+
+        [ContentChangeObserver] Start observing for content change between touchEnd and mouseMoved start
+        https://bugs.webkit.org/show_bug.cgi?id=195510
+        <rdar://problem/48735695>
+
+        Reviewed by Simon Fraser.
+
+        This patch covers the observation of async changes triggered by touchStart/touchEnd (animations, timers, style recalcs).
+
+        Test: fast/events/touch/ios/content-observation/visibility-change-after-touch-end.html
+
+        * page/ios/ContentChangeObserver.cpp:
+        (WebCore::ContentChangeObserver::didCancelTouchEvent):
+        (WebCore::ContentChangeObserver::adjustObservedState):
+        * page/ios/ContentChangeObserver.h:
+        (WebCore::ContentChangeObserver::setIsInBetweenTouchEndAndMouseMoved):
+        (WebCore::ContentChangeObserver::isInBetweenTouchEndAndMouseMoved const):
+        (WebCore::ContentChangeObserver::isObservingContentChanges const):
+
 2019-03-08  Simon Fraser  <simon.fraser@apple.com>
 
         Make it clearer which data is protected by the two locks in ScrollingTree
index bda8258..56a158e 100644 (file)
@@ -88,6 +88,13 @@ void ContentChangeObserver::didRemoveDOMTimer(const DOMTimer& timer)
     adjustObservedState(Event::RemovedDOMTimer);
 }
 
+void ContentChangeObserver::willNotProceedWithClick()
+{
+    LOG(ContentObservation, "willNotProceedWithClick: click will not happen.");
+    setIsBetweenTouchEndAndMouseMoved(false);
+    // FIXME: Add support for preventDefault() and long press.
+}
+
 void ContentChangeObserver::domTimerExecuteDidStart(const DOMTimer& timer)
 {
     if (!containsObservedDOMTimer(timer))
@@ -247,20 +254,20 @@ void ContentChangeObserver::adjustObservedState(Event event)
     case Event::StartedTouchStartEventDispatching:
         setHasNoChangeState();
         clearObservedDOMTimers();
-        m_isMouseMovedPrecededByTouch = true;
         setShouldObserveDOMTimerScheduling(true);
         break;
     case Event::EndedTouchStartEventDispatching:
         setShouldObserveDOMTimerScheduling(false);
+        setIsBetweenTouchEndAndMouseMoved(true);
         break;
     case Event::StartedMouseMovedEventDispatching:
         ASSERT(!m_document.hasPendingStyleRecalc());
-        if (!m_isMouseMovedPrecededByTouch) {
+        if (!isBetweenTouchEndAndMouseMoved()) {
             setHasNoChangeState();
             clearObservedDOMTimers();
         }
+        setIsBetweenTouchEndAndMouseMoved(false);
         setShouldObserveDOMTimerScheduling(true);
-        m_isMouseMovedPrecededByTouch = false;
         break;
     case Event::EndedMouseMovedEventDispatching:
         setShouldObserveDOMTimerScheduling(false);
index dc25bed..59c6341 100644 (file)
@@ -49,6 +49,7 @@ public:
 
     void didInstallDOMTimer(const DOMTimer&, Seconds timeout, bool singleShot);
     void didRemoveDOMTimer(const DOMTimer&);
+    WEBCORE_EXPORT void willNotProceedWithClick();
     void didSuspendActiveDOMObjects();
     void willDetachPage();
 
@@ -123,7 +124,7 @@ private:
     void setShouldObserveNextStyleRecalc(bool);
     bool isWaitingForStyleRecalc() const { return m_isWaitingForStyleRecalc; }
 
-    bool isObservingContentChanges() const { return m_mouseMovedEventIsBeingDispatched || m_touchEventIsBeingDispatched || m_observedDomTimerIsBeingExecuted || m_isInObservedStyleRecalc || m_contentObservationTimer.isActive(); }
+    bool isObservingContentChanges() const;
 
     void cancelPendingActivities();
 
@@ -135,6 +136,9 @@ private:
     bool hasObservedDOMTimer() const { return !m_DOMTimerList.isEmpty(); }
     bool hasDeterminateState() const;
 
+    void setIsBetweenTouchEndAndMouseMoved(bool isBetween) { m_isBetweenTouchEndAndMouseMoved = isBetween; }
+    bool isBetweenTouchEndAndMouseMoved() const { return m_isBetweenTouchEndAndMouseMoved; }
+
     bool hasPendingActivity() const { return hasObservedDOMTimer() || m_document.hasPendingStyleRecalc() || isObservationTimeWindowActive(); }
     bool isObservationTimeWindowActive() const { return m_contentObservationTimer.isActive(); }
 #if !ASSERT_DISABLED
@@ -168,8 +172,8 @@ private:
     bool m_isInObservedStyleRecalc { false };
     bool m_isObservingDOMTimerScheduling { false };
     bool m_observedDomTimerIsBeingExecuted { false };
-    bool m_isMouseMovedPrecededByTouch { false };
     bool m_mouseMovedEventIsBeingDispatched { false };
+    bool m_isBetweenTouchEndAndMouseMoved { false };
 };
 
 inline void ContentChangeObserver::setHasNoChangeState()
@@ -188,5 +192,15 @@ inline void ContentChangeObserver::setHasVisibleChangeState()
     WKSetObservedContentChange(WKContentVisibilityChange);
 }
 
+inline bool ContentChangeObserver::isObservingContentChanges() const
+{
+    return m_touchEventIsBeingDispatched
+        || m_isBetweenTouchEndAndMouseMoved
+        || m_mouseMovedEventIsBeingDispatched
+        || m_observedDomTimerIsBeingExecuted
+        || m_isInObservedStyleRecalc
+        || m_contentObservationTimer.isActive();
+    }
 }
+
 #endif
index 8aac502..80be999 100644 (file)
@@ -1,3 +1,14 @@
+2019-03-09  Zalan Bujtas  <zalan@apple.com>
+
+        [ContentChangeObserver] Start observing for content change between touchEnd and mouseMoved start
+        https://bugs.webkit.org/show_bug.cgi?id=195510
+        <rdar://problem/48735695>
+
+        Reviewed by Simon Fraser.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::cancelPotentialTapInFrame):
+
 2019-03-08  Chris Dumez  <cdumez@apple.com>
 
         Enable ProcessAssertions on iOS Simulator
index 7f517e4..e50985a 100644 (file)
@@ -865,7 +865,8 @@ void WebPage::cancelPotentialTap()
 void WebPage::cancelPotentialTapInFrame(WebFrame& frame)
 {
     if (m_potentialTapNode) {
-        Frame* potentialTapFrame = m_potentialTapNode->document().frame();
+        m_potentialTapNode->document().contentChangeObserver().willNotProceedWithClick();
+        auto* potentialTapFrame = m_potentialTapNode->document().frame();
         if (potentialTapFrame && !potentialTapFrame->tree().isDescendantOf(frame.coreFrame()))
             return;
     }