[ContentChangeObserver] Keep track of all the visibility candidates.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Aug 2019 02:20:57 +0000 (02:20 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Aug 2019 02:20:57 +0000 (02:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200777
<rdar://problem/54356331>

Reviewed by Simon Fraser.

Source/WebCore:

In order to find out whether a visible (and actionable) content change happened, we need to keep track of all the candidate elements.

Test: fast/events/touch/ios/content-observation/going-from-hidden-to-visible-and-to-hidden2.html

* page/ios/ContentChangeObserver.cpp:
(WebCore::ContentChangeObserver::reset):
(WebCore::ContentChangeObserver::rendererWillBeDestroyed):
(WebCore::ContentChangeObserver::contentVisibilityDidChange):
(WebCore::ContentChangeObserver::shouldObserveVisibilityChangeForElement):
* page/ios/ContentChangeObserver.h:

Source/WTF:

* wtf/WeakHashSet.h:

LayoutTests:

* fast/events/touch/ios/content-observation/going-from-hidden-to-visible-and-to-hidden2-expected.txt: Added.
* fast/events/touch/ios/content-observation/going-from-hidden-to-visible-and-to-hidden2.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/events/touch/ios/content-observation/going-from-hidden-to-visible-and-to-hidden2-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/content-observation/going-from-hidden-to-visible-and-to-hidden2.html [new file with mode: 0644]
Source/WTF/ChangeLog
Source/WTF/wtf/WeakHashSet.h
Source/WebCore/ChangeLog
Source/WebCore/page/ios/ContentChangeObserver.cpp
Source/WebCore/page/ios/ContentChangeObserver.h

index 9d0cc50..9493cf2 100644 (file)
@@ -1,3 +1,14 @@
+2019-08-15  Zalan Bujtas  <zalan@apple.com>
+
+        [ContentChangeObserver] Keep track of all the visibility candidates.
+        https://bugs.webkit.org/show_bug.cgi?id=200777
+        <rdar://problem/54356331>
+
+        Reviewed by Simon Fraser.
+
+        * fast/events/touch/ios/content-observation/going-from-hidden-to-visible-and-to-hidden2-expected.txt: Added.
+        * fast/events/touch/ios/content-observation/going-from-hidden-to-visible-and-to-hidden2.html: Added.
+
 2019-08-15  Myles C. Maxfield  <mmaxfield@apple.com>
 
         [WHLSL] Add unary plus
diff --git a/LayoutTests/fast/events/touch/ios/content-observation/going-from-hidden-to-visible-and-to-hidden2-expected.txt b/LayoutTests/fast/events/touch/ios/content-observation/going-from-hidden-to-visible-and-to-hidden2-expected.txt
new file mode 100644 (file)
index 0000000..dcc13e9
--- /dev/null
@@ -0,0 +1 @@
+PASS if 'clicked' text is not shown below.
diff --git a/LayoutTests/fast/events/touch/ios/content-observation/going-from-hidden-to-visible-and-to-hidden2.html b/LayoutTests/fast/events/touch/ios/content-observation/going-from-hidden-to-visible-and-to-hidden2.html
new file mode 100644 (file)
index 0000000..880b9fe
--- /dev/null
@@ -0,0 +1,70 @@
+<!DOCTYPE html><!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<title>This tests the case when 2 visible and actionable elements show up and the first one gets destroyed right away.</title>
+<script src="../../../../../resources/ui-helper.js"></script>
+<style>
+#tapThis {
+    width: 400px;
+    height: 400px;
+    border: 1px solid green;
+}
+
+#willBecomeVisibleMomentarily {
+    display: none;
+    width: 100px;
+    height: 100px;
+    background-color: red;
+}
+#willBecomeVisible {
+    display: none;
+    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();
+
+    await UIHelper.activateElement(tapThis);
+}
+</script>
+</head>
+<body onload="test()">
+<div id=tapThis>PASS if 'clicked' text is not shown below.</div>
+<div id=willBecomeVisibleMomentarily></div>
+<div id=willBecomeVisible></div>
+<pre id=result></pre>
+<script>
+tapThis.addEventListener("touchstart", function( event ) {
+       willBecomeVisibleMomentarily.style.display = "block";
+       willBecomeVisible.style.display = "block";
+}, false);
+
+tapThis.addEventListener("mouseover", function( event ) {
+       willBecomeVisibleMomentarily.style.display = "none";
+    if (window.testRunner)
+        setTimeout("testRunner.notifyDone()", 50);
+}, false);
+
+willBecomeVisibleMomentarily.addEventListener("click", function( event ) {
+    result.innerHTML = "clicked willBecomeVisibleMomentarily";
+}, false);
+
+willBecomeVisible.addEventListener("click", function( event ) {
+    result.innerHTML = "clicked willBecomeVisible";
+}, false);
+
+tapThis.addEventListener("click", function( event ) {   
+    result.innerHTML = "clicked";
+}, false);
+</script>
+</body>
+</html>
index e6a8112..7e2f0b2 100644 (file)
@@ -1,3 +1,13 @@
+2019-08-15  Zalan Bujtas  <zalan@apple.com>
+
+        [ContentChangeObserver] Keep track of all the visibility candidates.
+        https://bugs.webkit.org/show_bug.cgi?id=200777
+        <rdar://problem/54356331>
+
+        Reviewed by Simon Fraser.
+
+        * wtf/WeakHashSet.h:
+
 2019-08-15  Brent Fulgham  <bfulgham@apple.com>
 
         [FTW] Enable CoreFoundation use if building for Apple target
index 2c4d293..34676c1 100644 (file)
@@ -112,6 +112,8 @@ public:
         return m_set.remove(*weakPtrImpl);
     }
 
+    void clear() { m_set.clear(); }
+
     template <typename U>
     bool contains(const U& value) const
     {
index c151f53..1085d1c 100644 (file)
@@ -1,3 +1,22 @@
+2019-08-15  Zalan Bujtas  <zalan@apple.com>
+
+        [ContentChangeObserver] Keep track of all the visibility candidates.
+        https://bugs.webkit.org/show_bug.cgi?id=200777
+        <rdar://problem/54356331>
+
+        Reviewed by Simon Fraser.
+
+        In order to find out whether a visible (and actionable) content change happened, we need to keep track of all the candidate elements.
+
+        Test: fast/events/touch/ios/content-observation/going-from-hidden-to-visible-and-to-hidden2.html
+
+        * page/ios/ContentChangeObserver.cpp:
+        (WebCore::ContentChangeObserver::reset):
+        (WebCore::ContentChangeObserver::rendererWillBeDestroyed):
+        (WebCore::ContentChangeObserver::contentVisibilityDidChange):
+        (WebCore::ContentChangeObserver::shouldObserveVisibilityChangeForElement):
+        * page/ios/ContentChangeObserver.h:
+
 2019-08-15  Myles C. Maxfield  <mmaxfield@apple.com>
 
         [WHLSL] Add unary plus
index 7f568bf..e2a469f 100644 (file)
@@ -371,7 +371,7 @@ void ContentChangeObserver::reset()
     m_isInObservedStyleRecalc = false;
     m_observedDomTimerIsBeingExecuted = false;
 
-    m_visibilityCandidateElement = { };
+    m_visibilityCandidateList.clear();
 
     m_contentObservationTimer.stop();
     m_elementsWithDestroyedVisibleRenderer.clear();
@@ -401,19 +401,18 @@ void ContentChangeObserver::rendererWillBeDestroyed(const Element& element)
     if (!isVisuallyHidden(element))
         m_elementsWithDestroyedVisibleRenderer.add(&element);
     // Candidate element is no longer visible.
-    if (m_visibilityCandidateElement == &element) {
+    if (m_visibilityCandidateList.remove(element)) {
         // FIXME: We should also check for other type of visiblity changes.
         ASSERT(hasVisibleChangeState());
-        m_visibilityCandidateElement = { };
-        setHasIndeterminateState();
+        if (m_visibilityCandidateList.computesEmpty())
+            setHasIndeterminateState();
     }
 }
 
 void ContentChangeObserver::contentVisibilityDidChange(const Element& element)
 {
     LOG(ContentObservation, "contentVisibilityDidChange: visible content change did happen.");
-    // FIXME: This should evolve into a list of candidate elements.
-    m_visibilityCandidateElement = makeWeakPtr(element);
+    m_visibilityCandidateList.add(element);
     adjustObservedState(Event::ContentVisibilityChanged);
 }
 
@@ -623,7 +622,7 @@ void ContentChangeObserver::adjustObservedState(Event event)
 
 bool ContentChangeObserver::shouldObserveVisibilityChangeForElement(const Element& element)
 {
-    return isObservingContentChanges() && !hasVisibleChangeState() && !visibleRendererWasDestroyed(element) && !element.document().quirks().shouldIgnoreContentChange(element);
+    return isObservingContentChanges() && !visibleRendererWasDestroyed(element) && !element.document().quirks().shouldIgnoreContentChange(element);
 }
 
 ContentChangeObserver::StyleChangeScope::StyleChangeScope(Document& document, const Element& element)
index 3094e28..21c2fd6 100644 (file)
@@ -207,7 +207,7 @@ private:
     HashSet<const Element*> m_elementsWithDestroyedVisibleRenderer;
     WKContentChange m_observedContentState { WKContentNoChange };
     WeakPtr<Element> m_hiddenTouchTargetElement;
-    WeakPtr<Element> m_visibilityCandidateElement;
+    WeakHashSet<Element> m_visibilityCandidateList;
     bool m_touchEventIsBeingDispatched { false };
     bool m_isWaitingForStyleRecalc { false };
     bool m_isInObservedStyleRecalc { false };