Diff
Modified: trunk/LayoutTests/ChangeLog (243306 => 243307)
--- trunk/LayoutTests/ChangeLog 2019-03-21 18:46:54 UTC (rev 243306)
+++ trunk/LayoutTests/ChangeLog 2019-03-21 18:49:52 UTC (rev 243307)
@@ -1,3 +1,20 @@
+2019-03-21 Zalan Bujtas <[email protected]>
+
+ [ContentChangeObserver] Start tracking implicit transitions at touchStart
+ https://bugs.webkit.org/show_bug.cgi?id=196051
+ <rdar://problem/49092952>
+
+ Reviewed by Simon Fraser.
+
+ * fast/events/touch/ios/content-observation/0ms-transition-on-touch-start-expected.txt: Added.
+ * fast/events/touch/ios/content-observation/0ms-transition-on-touch-start.html: Added.
+ * fast/events/touch/ios/content-observation/100ms-transition-on-touch-start-expected.txt: Added.
+ * fast/events/touch/ios/content-observation/100ms-transition-on-touch-start.html: Added.
+ * fast/events/touch/ios/content-observation/10ms-delay-transition-on-touch-start-expected.txt: Added.
+ * fast/events/touch/ios/content-observation/10ms-delay-transition-on-touch-start.html: Added.
+ * fast/events/touch/ios/content-observation/transition-on-touch-start-and-remove-expected.txt: Added.
+ * fast/events/touch/ios/content-observation/transition-on-touch-start-and-remove.html: Added.
+
2019-03-21 Shawn Roberts <[email protected]>
Unreviewed, rolling out r243250.
Added: trunk/LayoutTests/fast/events/touch/ios/content-observation/0ms-transition-on-touch-start-expected.txt (0 => 243307)
--- trunk/LayoutTests/fast/events/touch/ios/content-observation/0ms-transition-on-touch-start-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/content-observation/0ms-transition-on-touch-start-expected.txt 2019-03-21 18:49:52 UTC (rev 243307)
@@ -0,0 +1,2 @@
+PASS if 'clicked' text is not shown below.
+
Added: trunk/LayoutTests/fast/events/touch/ios/content-observation/0ms-transition-on-touch-start.html (0 => 243307)
--- trunk/LayoutTests/fast/events/touch/ios/content-observation/0ms-transition-on-touch-start.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/content-observation/0ms-transition-on-touch-start.html 2019-03-21 18:49:52 UTC (rev 243307)
@@ -0,0 +1,60 @@
+<html>
+<head>
+<title>This tests the case when touchEnd triggers a 0ms transition.</title>
+<script src=""
+<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("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>
Added: trunk/LayoutTests/fast/events/touch/ios/content-observation/100ms-transition-on-touch-start-expected.txt (0 => 243307)
--- trunk/LayoutTests/fast/events/touch/ios/content-observation/100ms-transition-on-touch-start-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/content-observation/100ms-transition-on-touch-start-expected.txt 2019-03-21 18:49:52 UTC (rev 243307)
@@ -0,0 +1,2 @@
+PASS if 'clicked' text is not shown below.
+
Added: trunk/LayoutTests/fast/events/touch/ios/content-observation/100ms-transition-on-touch-start.html (0 => 243307)
--- trunk/LayoutTests/fast/events/touch/ios/content-observation/100ms-transition-on-touch-start.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/content-observation/100ms-transition-on-touch-start.html 2019-03-21 18:49:52 UTC (rev 243307)
@@ -0,0 +1,60 @@
+<html>
+<head>
+<title>This tests the case when touchEnd triggers a non-0ms transition.</title>
+<script src=""
+<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 100ms 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("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>
Added: trunk/LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-transition-on-touch-start-expected.txt (0 => 243307)
--- trunk/LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-transition-on-touch-start-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-transition-on-touch-start-expected.txt 2019-03-21 18:49:52 UTC (rev 243307)
@@ -0,0 +1,2 @@
+PASS if 'clicked' text is not shown below.
+
Added: trunk/LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-transition-on-touch-start.html (0 => 243307)
--- trunk/LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-transition-on-touch-start.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/content-observation/10ms-delay-transition-on-touch-start.html 2019-03-21 18:49:52 UTC (rev 243307)
@@ -0,0 +1,60 @@
+<html>
+<head>
+<title>This tests the case when touchEnd triggers a non-0ms transition with delay.</title>
+<script src=""
+<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 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>
Added: trunk/LayoutTests/fast/events/touch/ios/content-observation/transition-on-touch-start-and-remove-expected.txt (0 => 243307)
--- trunk/LayoutTests/fast/events/touch/ios/content-observation/transition-on-touch-start-and-remove-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/content-observation/transition-on-touch-start-and-remove-expected.txt 2019-03-21 18:49:52 UTC (rev 243307)
@@ -0,0 +1,2 @@
+PASS if 'clicked' text is shown below.
+clicked
Added: trunk/LayoutTests/fast/events/touch/ios/content-observation/transition-on-touch-start-and-remove.html (0 => 243307)
--- trunk/LayoutTests/fast/events/touch/ios/content-observation/transition-on-touch-start-and-remove.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/content-observation/transition-on-touch-start-and-remove.html 2019-03-21 18:49:52 UTC (rev 243307)
@@ -0,0 +1,60 @@
+<html>
+<head>
+<title>This tests the case when touchEnd triggers a transition and the element is removed.</title>
+<script src=""
+<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 100ms 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 shown below.</div>
+<div id=becomesVisible></div>
+<pre id=result></pre>
+<script>
+tapthis.addEventListener("touchstart", function( event ) {
+ becomesVisible.remove();
+}, false);
+
+becomesVisible.addEventListener("click", function( event ) {
+ result.innerHTML = "clicked hidden";
+}, false);
+
+tapthis.addEventListener("click", function( event ) {
+ result.innerHTML = "clicked";
+ if (window.testRunner)
+ testRunner.notifyDone();
+}, false);
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (243306 => 243307)
--- trunk/Source/WebCore/ChangeLog 2019-03-21 18:46:54 UTC (rev 243306)
+++ trunk/Source/WebCore/ChangeLog 2019-03-21 18:49:52 UTC (rev 243307)
@@ -1,5 +1,36 @@
2019-03-21 Zalan Bujtas <[email protected]>
+ [ContentChangeObserver] Start tracking implicit transitions at touchStart
+ https://bugs.webkit.org/show_bug.cgi?id=196051
+ <rdar://problem/49092952>
+
+ Reviewed by Simon Fraser.
+
+ This patch enables transition tracking on touchStart.
+
+ 1. Start observing for new transitions at touchStart
+ 2. Stop observing at touchEnd
+ 3. Check the next style recalc when the transition is finished (at onAnimationEnd we don't yet have the final computed style).
+ 4. Remove the tracked transition when it is canceled.
+
+ Tests: fast/events/touch/ios/content-observation/0ms-transition-on-touch-start.html
+ fast/events/touch/ios/content-observation/100ms-transition-on-touch-start.html
+ fast/events/touch/ios/content-observation/10ms-delay-transition-on-touch-start.html
+ fast/events/touch/ios/content-observation/transition-on-touch-start-and-remove.html
+
+ * page/ios/ContentChangeObserver.cpp:
+ (WebCore::ContentChangeObserver::didAddTransition):
+ (WebCore::ContentChangeObserver::didFinishTransition):
+ (WebCore::ContentChangeObserver::didRemoveTransition):
+ (WebCore::ContentChangeObserver::adjustObservedState):
+ * page/ios/ContentChangeObserver.h:
+ (WebCore::ContentChangeObserver::setShouldObserveTransitions):
+ (WebCore::ContentChangeObserver::clearObservedTransitions):
+ (WebCore::ContentChangeObserver::hasObservedTransition const):
+ (WebCore::ContentChangeObserver::hasPendingActivity const):
+
+2019-03-21 Zalan Bujtas <[email protected]>
+
[ContentChangeObserver] Track hidden elements only while transitioning.
https://bugs.webkit.org/show_bug.cgi?id=196050
<rdar://problem/49092037>
Modified: trunk/Source/WebCore/page/ios/ContentChangeObserver.cpp (243306 => 243307)
--- trunk/Source/WebCore/page/ios/ContentChangeObserver.cpp 2019-03-21 18:46:54 UTC (rev 243306)
+++ trunk/Source/WebCore/page/ios/ContentChangeObserver.cpp 2019-03-21 18:49:52 UTC (rev 243307)
@@ -141,7 +141,7 @@
LOG_WITH_STREAM(ContentObservation, stream << "didAddTransition: transition created on " << &element << " (" << transitionEnd.milliseconds() << "ms).");
m_elementsWithTransition.add(&element);
- // FIXME: report state change.
+ adjustObservedState(Event::AddedTransition);
}
void ContentChangeObserver::didFinishTransition(const Element& element, CSSPropertyID propertyID)
@@ -151,7 +151,8 @@
if (!m_elementsWithTransition.take(&element))
return;
LOG_WITH_STREAM(ContentObservation, stream << "didFinishTransition: transition finished (" << &element << ").");
- // FIXME: report state change.
+
+ adjustObservedState(Event::EndedTransition);
}
void ContentChangeObserver::didRemoveTransition(const Element& element, CSSPropertyID propertyID)
@@ -161,7 +162,8 @@
if (!m_elementsWithTransition.take(&element))
return;
LOG_WITH_STREAM(ContentObservation, stream << "didRemoveTransition: transition got interrupted (" << &element << ").");
- // FIXME: report state change.
+
+ adjustObservedState(Event::CanceledTransition);
}
void ContentChangeObserver::didInstallDOMTimer(const DOMTimer& timer, Seconds timeout, bool singleShot)
@@ -334,6 +336,7 @@
auto reset = [&] {
setHasNoChangeState();
clearObservedDOMTimers();
+ clearObservedTransitions();
setIsBetweenTouchEndAndMouseMoved(false);
ASSERT(!m_isObservingDOMTimerScheduling);
ASSERT(!m_isWaitingForStyleRecalc);
@@ -351,6 +354,10 @@
LOG(ContentObservation, "adjustStateAndNotifyContentChangeIfNeeded: in mouseMoved call. No need to notify the client.");
return;
}
+ if (isBetweenTouchEndAndMouseMoved()) {
+ LOG(ContentObservation, "adjustStateAndNotifyContentChangeIfNeeded: Not reached mouseMoved yet. No need to notify the client.");
+ return;
+ }
if (!hasDeterminateState()) {
LOG(ContentObservation, "adjustStateAndNotifyContentChangeIfNeeded: not in a determined state yet.");
return;
@@ -365,9 +372,11 @@
case Event::StartedTouchStartEventDispatching:
reset();
setShouldObserveDOMTimerScheduling(true);
+ setShouldObserveTransitions(true);
break;
case Event::EndedTouchStartEventDispatching:
setShouldObserveDOMTimerScheduling(false);
+ setShouldObserveTransitions(false);
setIsBetweenTouchEndAndMouseMoved(true);
break;
case Event::WillNotProceedWithClick:
@@ -394,14 +403,17 @@
break;
case Event::InstalledDOMTimer:
case Event::StartedFixedObservationTimeWindow:
+ case Event::AddedTransition:
ASSERT(!hasVisibleChangeState());
setHasIndeterminateState();
break;
case Event::EndedDOMTimerExecution:
+ case Event::EndedTransition:
setShouldObserveNextStyleRecalc(m_document.hasPendingStyleRecalc());
FALLTHROUGH;
case Event::EndedStyleRecalc:
case Event::RemovedDOMTimer:
+ case Event::CanceledTransition:
if (!isObservationTimeWindowActive())
adjustStateAndNotifyContentChangeIfNeeded();
break;
@@ -413,6 +425,7 @@
// Remove pending activities. We don't need to observe them anymore.
setShouldObserveNextStyleRecalc(false);
clearObservedDOMTimers();
+ clearObservedTransitions();
break;
}
}
Modified: trunk/Source/WebCore/page/ios/ContentChangeObserver.h (243306 => 243307)
--- trunk/Source/WebCore/page/ios/ContentChangeObserver.h 2019-03-21 18:46:54 UTC (rev 243306)
+++ trunk/Source/WebCore/page/ios/ContentChangeObserver.h 2019-03-21 18:49:52 UTC (rev 243307)
@@ -120,6 +120,7 @@
void setShouldObserveDOMTimerScheduling(bool observe) { m_isObservingDOMTimerScheduling = observe; }
bool isObservingDOMTimerScheduling() const { return m_isObservingDOMTimerScheduling; }
+ void setShouldObserveTransitions(bool observe) { m_isObservingTransitions = observe; }
bool isObservingTransitions() const { return m_isObservingTransitions; }
bool isObservedPropertyForTransition(CSSPropertyID propertyId) const { return propertyId == CSSPropertyLeft; }
void domTimerExecuteDidStart(const DOMTimer&);
@@ -127,6 +128,7 @@
void registerDOMTimer(const DOMTimer& timer) { m_DOMTimerList.add(&timer); }
void unregisterDOMTimer(const DOMTimer& timer) { m_DOMTimerList.remove(&timer); }
void clearObservedDOMTimers() { m_DOMTimerList.clear(); }
+ void clearObservedTransitions() { m_elementsWithTransition.clear(); }
bool containsObservedDOMTimer(const DOMTimer& timer) const { return m_DOMTimerList.contains(&timer); }
void styleRecalcDidStart();
@@ -144,12 +146,13 @@
bool hasVisibleChangeState() const { return observedContentChange() == WKContentVisibilityChange; }
bool hasObservedDOMTimer() const { return !m_DOMTimerList.isEmpty(); }
+ bool hasObservedTransition() const { return !m_elementsWithTransition.isEmpty(); }
bool hasDeterminateState() const;
void setIsBetweenTouchEndAndMouseMoved(bool isBetween) { m_isBetweenTouchEndAndMouseMoved = isBetween; }
bool isBetweenTouchEndAndMouseMoved() const { return m_isBetweenTouchEndAndMouseMoved; }
- bool hasPendingActivity() const { return hasObservedDOMTimer() || m_isWaitingForStyleRecalc || isObservationTimeWindowActive(); }
+ bool hasPendingActivity() const { return hasObservedDOMTimer() || hasObservedTransition() || m_isWaitingForStyleRecalc || isObservationTimeWindowActive(); }
bool isObservationTimeWindowActive() const { return m_contentObservationTimer.isActive(); }
void completeDurationBasedContentObservation();
@@ -166,6 +169,9 @@
EndedDOMTimerExecution,
StartedStyleRecalc,
EndedStyleRecalc,
+ AddedTransition,
+ EndedTransition,
+ CanceledTransition,
StartedFixedObservationTimeWindow,
EndedFixedObservationTimeWindow,
ContentVisibilityChanged