Title: [235424] trunk
Revision
235424
Author
aj...@chromium.org
Date
2018-08-28 08:45:32 -0700 (Tue, 28 Aug 2018)

Log Message

[IntersectionObserver] Schedule intersection observation updates
https://bugs.webkit.org/show_bug.cgi?id=189007

Reviewed by Simon Fraser.

LayoutTests/imported/w3c:

Rebaseline tests that now pass.

* web-platform-tests/intersection-observer/bounding-box-expected.txt:
* web-platform-tests/intersection-observer/containing-block-expected.txt:
* web-platform-tests/intersection-observer/remove-element-expected.txt:
* web-platform-tests/intersection-observer/same-document-root-expected.txt:
* web-platform-tests/intersection-observer/unclipped-root-expected.txt:

Source/WebCore:

Schedule intersection observation updates in the following situations:
1) A new observation target is added.
2) FrameView::viewportContentsChanged -- this covers changes to layout and
   to scroll positions for same-document observation. Scheduling for
   cross-document observation will be handled in a future patch.
3) Style is resolved without triggering layout -- this handles updates that
   were deferred because of a pending style recalculation.

Tested by existing tests in imported/w3c/web-platform-tests/intersection-observer.

* dom/Document.cpp:
(WebCore::Document::resolveStyle):
(WebCore::Document::updateIntersectionObservations):
(WebCore::Document::scheduleIntersectionObservationUpdate):
* dom/Document.h:
* page/FrameView.cpp:
(WebCore::FrameView::viewportContentsChanged):
* page/IntersectionObserver.cpp:
(WebCore::IntersectionObserver::observe):

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (235423 => 235424)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2018-08-28 15:01:37 UTC (rev 235423)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2018-08-28 15:45:32 UTC (rev 235424)
@@ -1,3 +1,18 @@
+2018-08-28  Ali Juma  <aj...@chromium.org>
+
+        [IntersectionObserver] Schedule intersection observation updates
+        https://bugs.webkit.org/show_bug.cgi?id=189007
+
+        Reviewed by Simon Fraser.
+
+        Rebaseline tests that now pass.
+
+        * web-platform-tests/intersection-observer/bounding-box-expected.txt:
+        * web-platform-tests/intersection-observer/containing-block-expected.txt:
+        * web-platform-tests/intersection-observer/remove-element-expected.txt:
+        * web-platform-tests/intersection-observer/same-document-root-expected.txt:
+        * web-platform-tests/intersection-observer/unclipped-root-expected.txt:
+
 2018-08-27  Andy Estes  <aes...@apple.com>
 
         [Payment Request] Update payment-request web platform tests

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/bounding-box-expected.txt (235423 => 235424)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/bounding-box-expected.txt	2018-08-28 15:01:37 UTC (rev 235423)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/bounding-box-expected.txt	2018-08-28 15:45:32 UTC (rev 235424)
@@ -1,5 +1,5 @@
 
 PASS Test that the target's border bounding box is used to calculate intersection. 
 PASS First rAF. 
-FAIL target.style.transform = 'translateY(195px)' assert_equals: entries.length expected 2 but got 1
+PASS target.style.transform = 'translateY(195px)' 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/containing-block-expected.txt (235423 => 235424)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/containing-block-expected.txt	2018-08-28 15:01:37 UTC (rev 235423)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/containing-block-expected.txt	2018-08-28 15:45:32 UTC (rev 235424)
@@ -1,7 +1,7 @@
 
 PASS IntersectionObserver should only report intersections if root is a containing block ancestor of target. 
-FAIL In containing block and intersecting. assert_equals: entries[0].boundingClientRect.top expected 18 but got 258
-FAIL In containing block and not intersecting. assert_equals: entries.length expected 2 but got 1
-FAIL Not in containing block and intersecting. assert_equals: entries.length expected 2 but got 1
-FAIL Not in containing block and not intersecting. assert_equals: entries.length expected 2 but got 1
+PASS In containing block and intersecting. 
+PASS In containing block and not intersecting. 
+PASS Not in containing block and intersecting. 
+PASS Not in containing block and not intersecting. 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/remove-element-expected.txt (235423 => 235424)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/remove-element-expected.txt	2018-08-28 15:01:37 UTC (rev 235423)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/remove-element-expected.txt	2018-08-28 15:45:32 UTC (rev 235424)
@@ -1,8 +1,8 @@
 
 PASS Verify that not-intersecting notifications are sent when a target is removed from the DOM tree. 
 PASS First rAF 
-FAIL root.scrollTop = 150 assert_equals: entries.length expected 2 but got 1
-FAIL root.removeChild(target). assert_equals: entries.length expected 3 but got 1
-FAIL root.insertBefore(target, trailingSpace). assert_equals: entries.length expected 3 but got 1
-FAIL root.scrollTop = 150 after reinserting target. assert_equals: entries.length expected 4 but got 1
+PASS root.scrollTop = 150 
+PASS root.removeChild(target). 
+PASS root.insertBefore(target, trailingSpace). 
+PASS root.scrollTop = 150 after reinserting target. 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-root-expected.txt (235423 => 235424)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-root-expected.txt	2018-08-28 15:01:37 UTC (rev 235423)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-root-expected.txt	2018-08-28 15:45:32 UTC (rev 235424)
@@ -2,8 +2,8 @@
 PASS IntersectionObserver in a single document with explicit root. 
 PASS First rAF 
 PASS document.scrollingElement.scrollTop = window.innerHeight. 
-FAIL root.scrollTop = 150 with root scrolled into view. assert_equals: entries.length expected 2 but got 1
-FAIL document.scrollingElement.scrollTop = 0. assert_equals: entries.length expected 2 but got 1
-FAIL root.scrollTop = 0 assert_equals: entries.length expected 3 but got 1
-FAIL root.scrollTop = 150 with root scrolled out of view. assert_equals: entries.length expected 4 but got 1
+PASS root.scrollTop = 150 with root scrolled into view. 
+PASS document.scrollingElement.scrollTop = 0. 
+PASS root.scrollTop = 0 
+PASS root.scrollTop = 150 with root scrolled out of view. 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/unclipped-root-expected.txt (235423 => 235424)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/unclipped-root-expected.txt	2018-08-28 15:01:37 UTC (rev 235423)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/unclipped-root-expected.txt	2018-08-28 15:45:32 UTC (rev 235424)
@@ -1,5 +1,5 @@
 
 PASS Test that border bounding box is used to calculate intersection with a non-scrolling root. 
 PASS First rAF. 
-FAIL target.style.transform = 'translateY(195px)' assert_equals: entries.length expected 2 but got 1
+PASS target.style.transform = 'translateY(195px)' 
 

Modified: trunk/Source/WebCore/ChangeLog (235423 => 235424)


--- trunk/Source/WebCore/ChangeLog	2018-08-28 15:01:37 UTC (rev 235423)
+++ trunk/Source/WebCore/ChangeLog	2018-08-28 15:45:32 UTC (rev 235424)
@@ -1,3 +1,30 @@
+2018-08-28  Ali Juma  <aj...@chromium.org>
+
+        [IntersectionObserver] Schedule intersection observation updates
+        https://bugs.webkit.org/show_bug.cgi?id=189007
+
+        Reviewed by Simon Fraser.
+
+        Schedule intersection observation updates in the following situations:
+        1) A new observation target is added.
+        2) FrameView::viewportContentsChanged -- this covers changes to layout and
+           to scroll positions for same-document observation. Scheduling for
+           cross-document observation will be handled in a future patch.
+        3) Style is resolved without triggering layout -- this handles updates that
+           were deferred because of a pending style recalculation.
+
+        Tested by existing tests in imported/w3c/web-platform-tests/intersection-observer.
+
+        * dom/Document.cpp:
+        (WebCore::Document::resolveStyle):
+        (WebCore::Document::updateIntersectionObservations):
+        (WebCore::Document::scheduleIntersectionObservationUpdate):
+        * dom/Document.h:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::viewportContentsChanged):
+        * page/IntersectionObserver.cpp:
+        (WebCore::IntersectionObserver::observe):
+
 2018-08-28  Zalan Bujtas  <za...@apple.com>
 
         [LFC][Floating] Remove redundant FloatAvoider functions.

Modified: trunk/Source/WebCore/dom/Document.cpp (235423 => 235424)


--- trunk/Source/WebCore/dom/Document.cpp	2018-08-28 15:01:37 UTC (rev 235423)
+++ trunk/Source/WebCore/dom/Document.cpp	2018-08-28 15:45:32 UTC (rev 235424)
@@ -507,6 +507,7 @@
     , m_documentClasses(documentClasses)
     , m_eventQueue(*this)
 #if ENABLE(INTERSECTION_OBSERVER)
+    , m_intersectionObservationUpdateTimer(*this, &Document::updateIntersectionObservations)
     , m_intersectionObserversNotifyTimer(*this, &Document::notifyIntersectionObserversTimerFired)
 #endif
     , m_loadEventDelayTimer(*this, &Document::loadEventDelayTimerFired)
@@ -1878,8 +1879,11 @@
             frameView.layoutContext().scheduleLayout();
 
         // Usually this is handled by post-layout.
-        if (!frameView.needsLayout())
+        if (!frameView.needsLayout()) {
             frameView.frame().selection().scheduleAppearanceUpdateAfterStyleChange();
+            if (m_needsIntersectionObservationUpdate)
+                scheduleIntersectionObservationUpdate();
+        }
 
         // As a result of the style recalculation, the currently hovered element might have been
         // detached (for example, by setting display:none in the :hover style), schedule another mouseMove event
@@ -7488,10 +7492,17 @@
 
 void Document::updateIntersectionObservations()
 {
+    ASSERT(m_needsIntersectionObservationUpdate);
     auto* frameView = view();
     if (!frameView)
         return;
 
+    bool needsLayout = frameView->layoutContext().isLayoutPending() || (renderView() && renderView()->needsLayout());
+    if (needsLayout || hasPendingStyleRecalc())
+        return;
+
+    m_needsIntersectionObservationUpdate = false;
+
     for (auto observer : m_intersectionObservers) {
         bool needNotify = false;
         DOMHighResTimeStamp timestamp;
@@ -7555,6 +7566,15 @@
         m_intersectionObserversNotifyTimer.startOneShot(0_s);
 }
 
+void Document::scheduleIntersectionObservationUpdate()
+{
+    if (m_intersectionObservers.isEmpty() || m_intersectionObservationUpdateTimer.isActive())
+        return;
+
+    m_needsIntersectionObservationUpdate = true;
+    m_intersectionObservationUpdateTimer.startOneShot(0_s);
+}
+
 void Document::notifyIntersectionObserversTimerFired()
 {
     for (auto observer : m_intersectionObserversWithPendingNotifications) {

Modified: trunk/Source/WebCore/dom/Document.h (235423 => 235424)


--- trunk/Source/WebCore/dom/Document.h	2018-08-28 15:01:37 UTC (rev 235423)
+++ trunk/Source/WebCore/dom/Document.h	2018-08-28 15:45:32 UTC (rev 235424)
@@ -1368,6 +1368,7 @@
     RefPtr<IntersectionObserver> removeIntersectionObserver(IntersectionObserver&);
     unsigned numberOfIntersectionObservers() const { return m_intersectionObservers.size(); }
     void updateIntersectionObservations();
+    void scheduleIntersectionObservationUpdate();
 #endif
 
 #if ENABLE(MEDIA_STREAM)
@@ -1775,6 +1776,10 @@
 #if ENABLE(INTERSECTION_OBSERVER)
     Vector<RefPtr<IntersectionObserver>> m_intersectionObservers;
     Vector<WeakPtr<IntersectionObserver>> m_intersectionObserversWithPendingNotifications;
+
+    // FIXME: Schedule intersection observation updates in a way that fits into the HTML
+    // EventLoop. See https://bugs.webkit.org/show_bug.cgi?id=160711.
+    Timer m_intersectionObservationUpdateTimer;
     Timer m_intersectionObserversNotifyTimer;
 #endif
 
@@ -1962,6 +1967,10 @@
     bool m_isTelephoneNumberParsingAllowed { true };
 #endif
 
+#if ENABLE(INTERSECTION_OBSERVER)
+    bool m_needsIntersectionObservationUpdate { false };
+#endif
+
 #if ENABLE(MEDIA_STREAM)
     HashSet<HTMLMediaElement*> m_mediaStreamStateChangeElements;
     String m_idHashSalt;

Modified: trunk/Source/WebCore/page/FrameView.cpp (235423 => 235424)


--- trunk/Source/WebCore/page/FrameView.cpp	2018-08-28 15:01:37 UTC (rev 235423)
+++ trunk/Source/WebCore/page/FrameView.cpp	2018-08-28 15:45:32 UTC (rev 235424)
@@ -2001,6 +2001,11 @@
         if (auto* renderView = frameView.frame().contentRenderer())
             renderView->updateVisibleViewportRect(visibleRect);
     });
+
+#if ENABLE(INTERSECTION_OBSERVER)
+    if (auto* document = frame().document())
+        frame().document()->scheduleIntersectionObservationUpdate();
+#endif
 }
 
 bool FrameView::fixedElementsLayoutRelativeToFrame() const

Modified: trunk/Source/WebCore/page/IntersectionObserver.cpp (235423 => 235424)


--- trunk/Source/WebCore/page/IntersectionObserver.cpp	2018-08-28 15:01:37 UTC (rev 235423)
+++ trunk/Source/WebCore/page/IntersectionObserver.cpp	2018-08-28 15:45:32 UTC (rev 235424)
@@ -154,9 +154,7 @@
     auto* document = trackingDocument();
     if (!hadObservationTargets)
         document->addIntersectionObserver(this);
-    document->postTask([document] (ScriptExecutionContext&) mutable {
-        document->updateIntersectionObservations();
-    });
+    document->scheduleIntersectionObservationUpdate();
 }
 
 void IntersectionObserver::unobserve(Element& target)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to