[ContentChangeObserver] Start tracking implicit transitions at mousemove
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Mar 2019 19:01:47 +0000 (19:01 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Mar 2019 19:01:47 +0000 (19:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196054
<rdar://problem/49093840>

Reviewed by Simon Fraser.

Source/WebCore:

This patch fixes the hover menu issue on seriouseats.com. After tapping on the menu items, the submenus show up now.

1. Start observing at mousemove
2. Check if the style change is synchronous or not and start observing it accordingly.

Tests: fast/events/touch/ios/content-observation/0ms-delay-0ms-transition-on-mousemove.html
       fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove.html
       fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-mousemove.html
       fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-touch-start.html

* page/ios/ContentChangeObserver.cpp:
(WebCore::ContentChangeObserver::adjustObservedState):

LayoutTests:

* fast/events/touch/ios/content-observation/0ms-delay-0ms-transition-on-mousemove-expected.txt: Added.
* fast/events/touch/ios/content-observation/0ms-delay-0ms-transition-on-mousemove.html: Added.
* fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove-expected.txt: Added.
* fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove.html: Added.
* fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-mousemove-expected.txt: Added.
* fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-mousemove.html: Added.
* fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-touch-start-expected.txt: Added.
* fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-touch-start.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/events/touch/ios/content-observation/0ms-delay-0ms-transition-on-mousemove-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/content-observation/0ms-delay-0ms-transition-on-mousemove.html [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove.html [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-mousemove-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-mousemove.html [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-touch-start-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-touch-start.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/ios/ContentChangeObserver.cpp

index bd9de71..e1897a3 100644 (file)
@@ -1,3 +1,20 @@
+2019-03-21  Zalan Bujtas  <zalan@apple.com>
+
+        [ContentChangeObserver] Start tracking implicit transitions at mousemove
+        https://bugs.webkit.org/show_bug.cgi?id=196054
+        <rdar://problem/49093840>
+
+        Reviewed by Simon Fraser.
+
+        * fast/events/touch/ios/content-observation/0ms-delay-0ms-transition-on-mousemove-expected.txt: Added.
+        * fast/events/touch/ios/content-observation/0ms-delay-0ms-transition-on-mousemove.html: Added.
+        * fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove-expected.txt: Added.
+        * fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove.html: Added.
+        * fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-mousemove-expected.txt: Added.
+        * fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-mousemove.html: Added.
+        * fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-touch-start-expected.txt: Added.
+        * fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-touch-start.html: Added.
+
 2019-03-21  Simon Fraser  <simon.fraser@apple.com>
 
         Absolute in stacking-context scroller jiggles when scrolled
diff --git a/LayoutTests/fast/events/touch/ios/content-observation/0ms-delay-0ms-transition-on-mousemove-expected.txt b/LayoutTests/fast/events/touch/ios/content-observation/0ms-delay-0ms-transition-on-mousemove-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/0ms-delay-0ms-transition-on-mousemove.html b/LayoutTests/fast/events/touch/ios/content-observation/0ms-delay-0ms-transition-on-mousemove.html
new file mode 100644 (file)
index 0000000..93a25fb
--- /dev/null
@@ -0,0 +1,60 @@
+<html>
+<head>
+<title>This tests the case when mousemove triggers a 0ms transition with no delay.</title>
+<script src="../../../../../resources/basic-gestures.js"></script>
+<style>
+#tapthis {
+    width: 400px;
+    height: 400px;
+    border: 1px solid green;
+}
+
+#becomesVisible {
+       position: absolute;
+       top: 100px;
+       left: -1000px;
+       width: 100px;
+       height: 100px;
+       background-color: green;
+       transition: left 0ms ease-in-out 0ms;
+}
+</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("mousemove", function( event ) {
+    becomesVisible.style.left = "10px";
+    if (window.testRunner)
+        testRunner.notifyDone();
+}, false);
+
+becomesVisible.addEventListener("click", function( event ) {   
+    result.innerHTML = "clicked hidden";
+}, false);
+
+tapthis.addEventListener("click", function( event ) {   
+    result.innerHTML = "clicked";
+}, false);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove-expected.txt b/LayoutTests/fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove-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/100ms-delay-10ms-transition-on-mousemove.html b/LayoutTests/fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove.html
new file mode 100644 (file)
index 0000000..5fe11f8
--- /dev/null
@@ -0,0 +1,60 @@
+<html>
+<head>
+<title>This tests the case when mousemove triggers a 10ms transition with delay.</title>
+<script src="../../../../../resources/basic-gestures.js"></script>
+<style>
+#tapthis {
+    width: 400px;
+    height: 400px;
+    border: 1px solid green;
+}
+
+#becomesVisible {
+       position: absolute;
+       top: 100px;
+       left: -1000px;
+       width: 100px;
+       height: 100px;
+       background-color: green;
+       transition: left 10ms ease-in-out 100ms;
+}
+</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("mousemove", function( event ) {
+    becomesVisible.style.left = "10px";
+    if (window.testRunner)
+        testRunner.notifyDone();
+}, false);
+
+becomesVisible.addEventListener("click", function( event ) {   
+    result.innerHTML = "clicked hidden";
+}, false);
+
+tapthis.addEventListener("click", function( event ) {   
+    result.innerHTML = "clicked";
+}, false);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-mousemove-expected.txt b/LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-mousemove-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/10ms-delay-0ms-transition-on-mousemove.html b/LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-mousemove.html
new file mode 100644 (file)
index 0000000..22459c2
--- /dev/null
@@ -0,0 +1,60 @@
+<html>
+<head>
+<title>This tests the case when mousemove triggers a 0ms transition with delay.</title>
+<script src="../../../../../resources/basic-gestures.js"></script>
+<style>
+#tapthis {
+    width: 400px;
+    height: 400px;
+    border: 1px solid green;
+}
+
+#becomesVisible {
+       position: absolute;
+       top: 100px;
+       left: -1000px;
+       width: 100px;
+       height: 100px;
+       background-color: green;
+       transition: left 0ms ease-in-out 10ms;
+}
+</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("mousemove", function( event ) {
+    becomesVisible.style.left = "10px";
+    if (window.testRunner)
+        testRunner.notifyDone();
+}, false);
+
+becomesVisible.addEventListener("click", function( event ) {   
+    result.innerHTML = "clicked hidden";
+}, false);
+
+tapthis.addEventListener("click", function( event ) {   
+    result.innerHTML = "clicked";
+}, false);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-touch-start-expected.txt b/LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-touch-start-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/10ms-delay-0ms-transition-on-touch-start.html b/LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-touch-start.html
new file mode 100644 (file)
index 0000000..a0f2aba
--- /dev/null
@@ -0,0 +1,60 @@
+<html>
+<head>
+<title>This tests the case when touchEnd triggers a 0ms transition with delay.</title>
+<script src="../../../../../resources/basic-gestures.js"></script>
+<style>
+#tapthis {
+    width: 400px;
+    height: 400px;
+    border: 1px solid green;
+}
+
+#becomesVisible {
+       position: absolute;
+       top: 100px;
+       left: -1000px;
+       width: 100px;
+       height: 100px;
+       background-color: green;
+       transition: left 0ms ease-in-out 10ms;
+}
+</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("touchstart", function( event ) {
+    becomesVisible.style.left = "10px";
+    if (window.testRunner)
+        testRunner.notifyDone();
+}, false);
+
+becomesVisible.addEventListener("click", function( event ) {   
+    result.innerHTML = "clicked hidden";
+}, false);
+
+tapthis.addEventListener("click", function( event ) {   
+    result.innerHTML = "clicked";
+}, false);
+</script>
+</body>
+</html>
index 3f106f5..38d75e6 100644 (file)
@@ -1,3 +1,24 @@
+2019-03-21  Zalan Bujtas  <zalan@apple.com>
+
+        [ContentChangeObserver] Start tracking implicit transitions at mousemove
+        https://bugs.webkit.org/show_bug.cgi?id=196054
+        <rdar://problem/49093840>
+
+        Reviewed by Simon Fraser.
+
+        This patch fixes the hover menu issue on seriouseats.com. After tapping on the menu items, the submenus show up now.
+
+        1. Start observing at mousemove
+        2. Check if the style change is synchronous or not and start observing it accordingly.
+
+        Tests: fast/events/touch/ios/content-observation/0ms-delay-0ms-transition-on-mousemove.html
+               fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove.html
+               fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-mousemove.html
+               fast/events/touch/ios/content-observation/10ms-delay-0ms-transition-on-touch-start.html
+
+        * page/ios/ContentChangeObserver.cpp:
+        (WebCore::ContentChangeObserver::adjustObservedState):
+
 2019-03-21  Simon Fraser  <simon.fraser@apple.com>
 
         Absolute in stacking-context scroller jiggles when scrolled
index 779087c..cc5f773 100644 (file)
@@ -384,16 +384,15 @@ void ContentChangeObserver::adjustObservedState(Event event)
         break;
     case Event::StartedMouseMovedEventDispatching:
         ASSERT(!m_document.hasPendingStyleRecalc());
-        if (!isBetweenTouchEndAndMouseMoved()) {
-            setHasNoChangeState();
-            clearObservedDOMTimers();
-            setShouldObserveDOMTimerScheduling(true);
-        } else
-            setShouldObserveDOMTimerScheduling(!hasVisibleChangeState());
+        if (!isBetweenTouchEndAndMouseMoved())
+            reset();
         setIsBetweenTouchEndAndMouseMoved(false);
+        setShouldObserveDOMTimerScheduling(!hasVisibleChangeState());
+        setShouldObserveTransitions(!hasVisibleChangeState());
         break;
     case Event::EndedMouseMovedEventDispatching:
         setShouldObserveDOMTimerScheduling(false);
+        setShouldObserveTransitions(false);
         break;
     case Event::StartedStyleRecalc:
         setShouldObserveNextStyleRecalc(false);
@@ -408,7 +407,6 @@ void ContentChangeObserver::adjustObservedState(Event event)
         setHasIndeterminateState();
         break;
     case Event::EndedDOMTimerExecution:
-    case Event::EndedTransition:
         setShouldObserveNextStyleRecalc(m_document.hasPendingStyleRecalc());
         FALLTHROUGH;
     case Event::EndedStyleRecalc:
@@ -417,6 +415,15 @@ void ContentChangeObserver::adjustObservedState(Event event)
         if (!isObservationTimeWindowActive())
             adjustStateAndNotifyContentChangeIfNeeded();
         break;
+    case Event::EndedTransition:
+        // onAnimationEnd can be called while in the middle of resolving the document (synchronously) or
+        // asynchronously right before the style update is issued.
+        if (m_document.inStyleRecalc()) {
+            // We need to start observing this style change synchronously.
+            m_isInObservedStyleRecalc = true;
+        } else
+            setShouldObserveNextStyleRecalc(true);
+        break;
     case Event::EndedFixedObservationTimeWindow:
         adjustStateAndNotifyContentChangeIfNeeded();
         break;