Title: [226622] trunk
Revision
226622
Author
[email protected]
Date
2018-01-09 02:53:12 -0800 (Tue, 09 Jan 2018)

Log Message

Implement VisualViewport API events
https://bugs.webkit.org/show_bug.cgi?id=179386

Patch by Ali Juma <[email protected]> on 2018-01-09
Reviewed by Frédéric Wang.

LayoutTests/imported/w3c:

Update expectation for a viewport WPT that now passes.

* web-platform-tests/viewport/viewport-resize-event-on-load-overflowing-page-expected.txt:

Source/WebCore:

Implement the events (resize and scroll) defined by the Visual Viewport API
(https://wicg.github.io/visual-viewport/#events).

This is behind the VisualViewportAPI experimental feature flag.

In order to detect when events need to be fired, change the computation of
Visual Viewport attributes to happen whenever the layout viewport is updated
rather than only on-demand.

Tests: fast/visual-viewport/resize-event-fired-window-resized.html
       fast/visual-viewport/resize-event-fired.html
       fast/visual-viewport/scroll-event-fired.html

* dom/Document.cpp:
(WebCore::Document::addListenerTypeIfNeeded):
Add support for tracking resize event listeners.
* dom/Document.h:
* dom/DocumentEventQueue.cpp:
(WebCore::DocumentEventQueue::enqueueOrDispatchScrollEvent):
(WebCore::DocumentEventQueue::enqueueScrollEvent):
Factored out of enqueueOrDispatchScrollEvent so that this logic can be reused
for Visual Viewport scroll events.
(WebCore::DocumentEventQueue::enqueueResizeEvent):
(WebCore::DocumentEventQueue::pendingEventTimerFired):
* dom/DocumentEventQueue.h:
* page/FrameView.cpp:
(WebCore::FrameView::updateLayoutViewport):
* page/VisualViewport.cpp:
(WebCore::VisualViewport::addEventListener):
(WebCore::layoutIfNonNull):
(WebCore::VisualViewport::offsetLeft const):
Remove attribute computation logic since this now happens during update().
(WebCore::VisualViewport::offsetTop const): Ditto.
(WebCore::VisualViewport::pageLeft const): Ditto.
(WebCore::VisualViewport::pageTop const): Ditto.
(WebCore::VisualViewport::width const): Ditto.
(WebCore::VisualViewport::height const): Ditto.
(WebCore::VisualViewport::scale const):
(WebCore::VisualViewport::update):
Added. Computes all of the Visual Viewport attributes and determines
whether events need to be fired.
(WebCore::VisualViewport::enqueueResizeEvent):
(WebCore::VisualViewport::enqueueScrollEvent):
(WebCore::getFrameViewAndLayoutIfNonNull): Deleted.
* page/VisualViewport.h:

Source/WebKit:

Change the default value of the VisualViewportAPI experimental feature flag to
DEFAULT_EXPERIMENTAL_FEATURES_ENABLED. This patch completes the implementation
of this feature as specified by https://wicg.github.io/visual-viewport/, so this
feature is now ready for wider testing.

* Shared/WebPreferences.yaml:

LayoutTests:

Add tests for Visual Viewport API events. Test that a resize event is fired after
pinch zoom and after window resize, and test that a scroll event is fired when the
visual viewport is scrolled.

* fast/visual-viewport/resize-event-fired-expected.txt: Added.
* fast/visual-viewport/resize-event-fired-window-resized-expected.txt: Added.
* fast/visual-viewport/resize-event-fired-window-resized.html: Added.
* fast/visual-viewport/resize-event-fired.html: Added.
* fast/visual-viewport/scroll-event-fired-expected.txt: Added.
* fast/visual-viewport/scroll-event-fired.html: Added.
* platform/gtk/TestExpectations:
Skipped tests that use UIScriptController::zoomToScale, since this isn't implemented on GTK.
* platform/ios/TestExpectations:
Skipped test that resizes a window, since this isn't supported on iOS.
* platform/win/TestExpectations:
Skipped tests that use UIScriptController::zoomToScale, since this isn't implemented on Windows.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (226621 => 226622)


--- trunk/LayoutTests/ChangeLog	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/LayoutTests/ChangeLog	2018-01-09 10:53:12 UTC (rev 226622)
@@ -1,3 +1,27 @@
+2018-01-09  Ali Juma  <[email protected]>
+
+        Implement VisualViewport API events
+        https://bugs.webkit.org/show_bug.cgi?id=179386
+
+        Reviewed by Frédéric Wang.
+
+        Add tests for Visual Viewport API events. Test that a resize event is fired after
+        pinch zoom and after window resize, and test that a scroll event is fired when the
+        visual viewport is scrolled.
+
+        * fast/visual-viewport/resize-event-fired-expected.txt: Added.
+        * fast/visual-viewport/resize-event-fired-window-resized-expected.txt: Added.
+        * fast/visual-viewport/resize-event-fired-window-resized.html: Added.
+        * fast/visual-viewport/resize-event-fired.html: Added.
+        * fast/visual-viewport/scroll-event-fired-expected.txt: Added.
+        * fast/visual-viewport/scroll-event-fired.html: Added.
+        * platform/gtk/TestExpectations:
+        Skipped tests that use UIScriptController::zoomToScale, since this isn't implemented on GTK.
+        * platform/ios/TestExpectations:
+        Skipped test that resizes a window, since this isn't supported on iOS.
+        * platform/win/TestExpectations:
+        Skipped tests that use UIScriptController::zoomToScale, since this isn't implemented on Windows.
+
 2018-01-09  Ryosuke Niwa  <[email protected]>
 
         Release assert in addResourceTiming when a cache resource is requested during style recalc

Added: trunk/LayoutTests/fast/visual-viewport/resize-event-fired-expected.txt (0 => 226622)


--- trunk/LayoutTests/fast/visual-viewport/resize-event-fired-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/visual-viewport/resize-event-fired-expected.txt	2018-01-09 10:53:12 UTC (rev 226622)
@@ -0,0 +1,3 @@
+
+PASS Verify a resize event gets fired on window.visualViewport after pinch-zoom 
+

Added: trunk/LayoutTests/fast/visual-viewport/resize-event-fired-window-resized-expected.txt (0 => 226622)


--- trunk/LayoutTests/fast/visual-viewport/resize-event-fired-window-resized-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/visual-viewport/resize-event-fired-window-resized-expected.txt	2018-01-09 10:53:12 UTC (rev 226622)
@@ -0,0 +1,3 @@
+
+PASS Verify that a resize event gets fired when the window is resized. 
+

Added: trunk/LayoutTests/fast/visual-viewport/resize-event-fired-window-resized.html (0 => 226622)


--- trunk/LayoutTests/fast/visual-viewport/resize-event-fired-window-resized.html	                        (rev 0)
+++ trunk/LayoutTests/fast/visual-viewport/resize-event-fired-window-resized.html	2018-01-09 10:53:12 UTC (rev 226622)
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<script src=""
+<script src=""
+<script>
+    if (window.internals)
+        internals.settings.setVisualViewportEnabled(true);
+
+    var test = async_test('Verify that a resize event gets fired when the window is resized.');
+
+    function resizeHandler() {
+        test.done();
+    }
+
+    window._onload_ = function() {
+        window.visualViewport.addEventListener('resize', resizeHandler);
+        window.resizeTo(window.outerWidth - 40, window.outerHeight + 40);
+    };
+</script>

Added: trunk/LayoutTests/fast/visual-viewport/resize-event-fired.html (0 => 226622)


--- trunk/LayoutTests/fast/visual-viewport/resize-event-fired.html	                        (rev 0)
+++ trunk/LayoutTests/fast/visual-viewport/resize-event-fired.html	2018-01-09 10:53:12 UTC (rev 226622)
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<style>
+  body {
+    height: 2000px;
+    width: 2000px;
+  }
+</style>
+
+<script src=""
+<script src=""
+<script>
+    var pageScaleFactor = 2;
+
+    if (window.internals)
+        internals.settings.setVisualViewportEnabled(true);
+
+    var test = async_test('Verify a resize event gets fired on window.visualViewport after pinch-zoom');
+
+    function resizeHandler() {
+        test.done();
+    }
+
+    function getUIScript() {
+        return `(function() {
+            uiController.zoomToScale(${pageScaleFactor}, function() {
+                uiController.uiScriptComplete(uiController.zoomScale);
+            });
+        })();`;
+    }
+
+    window._onload_ = function() {
+        window.visualViewport.addEventListener('resize', resizeHandler);
+        testRunner.runUIScript(getUIScript(), function() {});
+    };
+</script>

Added: trunk/LayoutTests/fast/visual-viewport/scroll-event-fired-expected.txt (0 => 226622)


--- trunk/LayoutTests/fast/visual-viewport/scroll-event-fired-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/visual-viewport/scroll-event-fired-expected.txt	2018-01-09 10:53:12 UTC (rev 226622)
@@ -0,0 +1,3 @@
+
+PASS Verify that a scroll event gets fired on window.visualViewport when its offset changes 
+

Added: trunk/LayoutTests/fast/visual-viewport/scroll-event-fired.html (0 => 226622)


--- trunk/LayoutTests/fast/visual-viewport/scroll-event-fired.html	                        (rev 0)
+++ trunk/LayoutTests/fast/visual-viewport/scroll-event-fired.html	2018-01-09 10:53:12 UTC (rev 226622)
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<style>
+  body {
+    height: 2000px;
+    width: 2000px;
+  }
+</style>
+
+<script src=""
+<script src=""
+<script>
+    var pageScaleFactor = 2;
+
+    if (window.internals)
+        internals.settings.setVisualViewportEnabled(true);
+
+    var test = async_test('Verify that a scroll event gets fired on window.visualViewport when its offset changes');
+
+    function scrollEventHandler() {
+        test.done();
+    }
+
+    function doAfterZooming() {
+        window.visualViewport.addEventListener('scroll', scrollEventHandler);
+        window.scrollTo(1000, 1000);
+    }
+
+    function getUIScript() {
+        return `(function() {
+            uiController.zoomToScale(${pageScaleFactor}, function() {
+                uiController.uiScriptComplete(uiController.zoomScale);
+            });
+        })();`;
+    }
+
+    window._onload_ = function() {
+        testRunner.runUIScript(getUIScript(), doAfterZooming);
+    };
+</script>

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (226621 => 226622)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2018-01-09 10:53:12 UTC (rev 226622)
@@ -1,3 +1,14 @@
+2018-01-09  Ali Juma  <[email protected]>
+
+        Implement VisualViewport API events
+        https://bugs.webkit.org/show_bug.cgi?id=179386
+
+        Reviewed by Frédéric Wang.
+
+        Update expectation for a viewport WPT that now passes.
+
+        * web-platform-tests/viewport/viewport-resize-event-on-load-overflowing-page-expected.txt:
+
 2018-01-08  Chris Nardi  <[email protected]>
 
         ::first-letter incorrectly selects grapheme pairs

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-resize-event-on-load-overflowing-page-expected.txt (226621 => 226622)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-resize-event-on-load-overflowing-page-expected.txt	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-resize-event-on-load-overflowing-page-expected.txt	2018-01-09 10:53:12 UTC (rev 226622)
@@ -3,5 +3,5 @@
 Test Description: This test ensures that we fire a resize event against window.visualViewport if the page has overflow (since this creates a scrollbar and thus changes the viewport size).
 
 
-FAIL Resize event fired exactly once against window.visualViewport if scrollbars affect layout. assert_equals: expected 1 but got 0
+PASS Resize event fired exactly once against window.visualViewport if scrollbars affect layout. 
 

Modified: trunk/LayoutTests/platform/gtk/TestExpectations (226621 => 226622)


--- trunk/LayoutTests/platform/gtk/TestExpectations	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/LayoutTests/platform/gtk/TestExpectations	2018-01-09 10:53:12 UTC (rev 226622)
@@ -968,7 +968,9 @@
 webkit.org/b/153833 fast/events/input-event-insert-replacement.html [ Skip ]
 
 # Skip tests requiring UIScriptController::zoomToScale
+webkit.org/b/168050 fast/visual-viewport/resize-event-fired.html [ Skip ]
 webkit.org/b/168050 fast/visual-viewport/rtl-zoomed-rects.html [ Skip ]
+webkit.org/b/168050 fast/visual-viewport/scroll-event-fired.html [ Skip ]
 webkit.org/b/168050 fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars.html [ Skip ]
 webkit.org/b/168050 fast/visual-viewport/viewport-dimensions-exclude-scrollbars.html [ Skip ]
 webkit.org/b/168050 fast/visual-viewport/viewport-dimensions-iframe.html [ Skip ]

Modified: trunk/LayoutTests/platform/ios/TestExpectations (226621 => 226622)


--- trunk/LayoutTests/platform/ios/TestExpectations	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/LayoutTests/platform/ios/TestExpectations	2018-01-09 10:53:12 UTC (rev 226622)
@@ -2036,6 +2036,7 @@
 fast/dom/Window/window-resize-update-scrollbars.html [ Skip ]
 fast/dynamic/window-resize-scrollbars-test.html [ Skip ]
 fast/images/animated-gif-window-resizing.html [ Skip ]
+fast/visual-viewport/resize-event-fired-window-resized.html [ Skip ]
 loader/go-back-to-different-window-size.html [ Skip ]
 webkit.org/b/178739 css3/viewport-percentage-lengths/viewport-percentage-lengths-anonymous-block.html [ Skip ]
 webkit.org/b/178739 css3/viewport-percentage-lengths/viewport-percentage-lengths-percent-size-child.html [ Skip ]

Modified: trunk/LayoutTests/platform/win/TestExpectations (226621 => 226622)


--- trunk/LayoutTests/platform/win/TestExpectations	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/LayoutTests/platform/win/TestExpectations	2018-01-09 10:53:12 UTC (rev 226622)
@@ -629,7 +629,9 @@
 http/wpt/credential-management/ [ Skip ]
 
 # UIScriptController::zoomToScale is not implemented on Windows.
+webkit.org/b/180424 fast/visual-viewport/resize-event-fired.html [ Skip ]
 webkit.org/b/180424 fast/visual-viewport/rtl-zoomed-rects.html [ Skip ]
+webkit.org/b/180424 fast/visual-viewport/scroll-event-fired.html [ Skip ]
 webkit.org/b/180424 fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars.html [ Skip ]
 webkit.org/b/180424 fast/visual-viewport/viewport-dimensions-exclude-scrollbars.html [ Skip ]
 webkit.org/b/180424 fast/visual-viewport/viewport-dimensions-iframe.html [ Skip ]

Modified: trunk/Source/WebCore/ChangeLog (226621 => 226622)


--- trunk/Source/WebCore/ChangeLog	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/Source/WebCore/ChangeLog	2018-01-09 10:53:12 UTC (rev 226622)
@@ -1,3 +1,56 @@
+2018-01-09  Ali Juma  <[email protected]>
+
+        Implement VisualViewport API events
+        https://bugs.webkit.org/show_bug.cgi?id=179386
+
+        Reviewed by Frédéric Wang.
+
+        Implement the events (resize and scroll) defined by the Visual Viewport API
+        (https://wicg.github.io/visual-viewport/#events).
+
+        This is behind the VisualViewportAPI experimental feature flag.
+
+        In order to detect when events need to be fired, change the computation of
+        Visual Viewport attributes to happen whenever the layout viewport is updated
+        rather than only on-demand.
+
+        Tests: fast/visual-viewport/resize-event-fired-window-resized.html
+               fast/visual-viewport/resize-event-fired.html
+               fast/visual-viewport/scroll-event-fired.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::addListenerTypeIfNeeded):
+        Add support for tracking resize event listeners.
+        * dom/Document.h:
+        * dom/DocumentEventQueue.cpp:
+        (WebCore::DocumentEventQueue::enqueueOrDispatchScrollEvent):
+        (WebCore::DocumentEventQueue::enqueueScrollEvent):
+        Factored out of enqueueOrDispatchScrollEvent so that this logic can be reused
+        for Visual Viewport scroll events.
+        (WebCore::DocumentEventQueue::enqueueResizeEvent):
+        (WebCore::DocumentEventQueue::pendingEventTimerFired):
+        * dom/DocumentEventQueue.h:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::updateLayoutViewport):
+        * page/VisualViewport.cpp:
+        (WebCore::VisualViewport::addEventListener):
+        (WebCore::layoutIfNonNull):
+        (WebCore::VisualViewport::offsetLeft const):
+        Remove attribute computation logic since this now happens during update().
+        (WebCore::VisualViewport::offsetTop const): Ditto.
+        (WebCore::VisualViewport::pageLeft const): Ditto.
+        (WebCore::VisualViewport::pageTop const): Ditto.
+        (WebCore::VisualViewport::width const): Ditto.
+        (WebCore::VisualViewport::height const): Ditto.
+        (WebCore::VisualViewport::scale const):
+        (WebCore::VisualViewport::update):
+        Added. Computes all of the Visual Viewport attributes and determines
+        whether events need to be fired.
+        (WebCore::VisualViewport::enqueueResizeEvent):
+        (WebCore::VisualViewport::enqueueScrollEvent):
+        (WebCore::getFrameViewAndLayoutIfNonNull): Deleted.
+        * page/VisualViewport.h:
+
 2018-01-09  Yacine Bandou  <[email protected]>
 
         [EME] Add the CENC initData support in ClearKey CDM

Modified: trunk/Source/WebCore/dom/Document.cpp (226621 => 226622)


--- trunk/Source/WebCore/dom/Document.cpp	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/Source/WebCore/dom/Document.cpp	2018-01-09 10:53:12 UTC (rev 226622)
@@ -4464,6 +4464,8 @@
         addListenerType(FORCEDOWN_LISTENER);
     else if (eventType == eventNames().webkitmouseforceupEvent)
         addListenerType(FORCEUP_LISTENER);
+    else if (eventType == eventNames().resizeEvent)
+        addListenerType(RESIZE_LISTENER);
 }
 
 CSSStyleDeclaration* Document::getOverrideStyle(Element*, const String&)

Modified: trunk/Source/WebCore/dom/Document.h (226621 => 226622)


--- trunk/Source/WebCore/dom/Document.h	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/Source/WebCore/dom/Document.h	2018-01-09 10:53:12 UTC (rev 226622)
@@ -825,7 +825,8 @@
         FORCEWILLBEGIN_LISTENER              = 1 << 13,
         FORCECHANGED_LISTENER                = 1 << 14,
         FORCEDOWN_LISTENER                   = 1 << 15,
-        FORCEUP_LISTENER                     = 1 << 16
+        FORCEUP_LISTENER                     = 1 << 16,
+        RESIZE_LISTENER                      = 1 << 17
     };
 
     bool hasListenerType(ListenerType listenerType) const { return (m_listenerTypes & listenerType); }

Modified: trunk/Source/WebCore/dom/DocumentEventQueue.cpp (226621 => 226622)


--- trunk/Source/WebCore/dom/DocumentEventQueue.cpp	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/Source/WebCore/dom/DocumentEventQueue.cpp	2018-01-09 10:53:12 UTC (rev 226622)
@@ -85,6 +85,14 @@
 {
     ASSERT(&target.document() == &m_document);
 
+    // Per the W3C CSSOM View Module, scroll events fired at the document should bubble, others should not.
+    bool bubbles = target.isDocumentNode();
+    bool cancelable = false;
+    enqueueScrollEvent(target, bubbles, cancelable);
+}
+
+void DocumentEventQueue::enqueueScrollEvent(EventTarget& target, bool bubbles, bool cancelable)
+{
     if (m_isClosed)
         return;
 
@@ -91,18 +99,30 @@
     if (!m_document.hasListenerType(Document::SCROLL_LISTENER))
         return;
 
-    if (!m_nodesWithQueuedScrollEvents.add(&target).isNewEntry)
+    if (!m_targetsWithQueuedScrollEvents.add(&target).isNewEntry)
         return;
 
-    // Per the W3C CSSOM View Module, scroll events fired at the document should bubble, others should not.
-    bool bubbles = target.isDocumentNode();
-    bool cancelable = false;
-
     Ref<Event> scrollEvent = Event::create(eventNames().scrollEvent, bubbles, cancelable);
     scrollEvent->setTarget(&target);
     enqueueEvent(WTFMove(scrollEvent));
 }
 
+void DocumentEventQueue::enqueueResizeEvent(EventTarget& target, bool bubbles, bool cancelable)
+{
+    if (m_isClosed)
+        return;
+
+    if (!m_document.hasListenerType(Document::RESIZE_LISTENER))
+        return;
+
+    if (!m_targetsWithQueuedResizeEvents.add(&target).isNewEntry)
+        return;
+
+    Ref<Event> resizeEvent = Event::create(eventNames().resizeEvent, bubbles, cancelable);
+    resizeEvent->setTarget(&target);
+    enqueueEvent(WTFMove(resizeEvent));
+}
+
 bool DocumentEventQueue::cancelEvent(Event& event)
 {
     bool found = m_queuedEvents.remove(&event);
@@ -123,7 +143,8 @@
     ASSERT(!m_pendingEventTimer->isActive());
     ASSERT(!m_queuedEvents.isEmpty());
 
-    m_nodesWithQueuedScrollEvents.clear();
+    m_targetsWithQueuedScrollEvents.clear();
+    m_targetsWithQueuedResizeEvents.clear();
 
     // Insert a marker for where we should stop.
     ASSERT(!m_queuedEvents.contains(nullptr));

Modified: trunk/Source/WebCore/dom/DocumentEventQueue.h (226621 => 226622)


--- trunk/Source/WebCore/dom/DocumentEventQueue.h	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/Source/WebCore/dom/DocumentEventQueue.h	2018-01-09 10:53:12 UTC (rev 226622)
@@ -48,6 +48,8 @@
     void close() override;
 
     void enqueueOrDispatchScrollEvent(Node&);
+    void enqueueScrollEvent(EventTarget&, bool bubbles, bool cancelable);
+    void enqueueResizeEvent(EventTarget&, bool bubbles, bool cancelable);
 
 private:
     void pendingEventTimerFired();
@@ -58,7 +60,8 @@
     Document& m_document;
     std::unique_ptr<Timer> m_pendingEventTimer;
     ListHashSet<RefPtr<Event>> m_queuedEvents;
-    HashSet<Node*> m_nodesWithQueuedScrollEvents;
+    HashSet<EventTarget*> m_targetsWithQueuedScrollEvents;
+    HashSet<EventTarget*> m_targetsWithQueuedResizeEvents;
     bool m_isClosed;
 };
 

Modified: trunk/Source/WebCore/page/FrameView.cpp (226621 => 226622)


--- trunk/Source/WebCore/page/FrameView.cpp	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/Source/WebCore/page/FrameView.cpp	2018-01-09 10:53:12 UTC (rev 226622)
@@ -94,6 +94,7 @@
 #include "StyleScope.h"
 #include "TextResourceDecoder.h"
 #include "TiledBacking.h"
+#include "VisualViewport.h"
 #include "WheelEventTestTrigger.h"
 #include <wtf/text/TextStream.h>
 
@@ -1673,6 +1674,10 @@
             LayoutPoint newOrigin = computeLayoutViewportOrigin(visualViewportRect(), minStableLayoutViewportOrigin(), maxStableLayoutViewportOrigin(), layoutViewport, StickToDocumentBounds);
             setLayoutViewportOverrideRect(LayoutRect(newOrigin, m_layoutViewportOverrideRect.value().size()));
         }
+        if (frame().settings().visualViewportAPIEnabled()) {
+            if (Document* document = frame().document())
+                document->domWindow()->visualViewport()->update();
+        }
         return;
     }
 
@@ -1681,6 +1686,10 @@
         setBaseLayoutViewportOrigin(newLayoutViewportOrigin);
         LOG_WITH_STREAM(Scrolling, stream << "layoutViewport changed to " << layoutViewportRect());
     }
+    if (frame().settings().visualViewportAPIEnabled()) {
+        if (Document* document = frame().document())
+            document->domWindow()->visualViewport()->update();
+    }
 }
 
 LayoutPoint FrameView::minStableLayoutViewportOrigin() const

Modified: trunk/Source/WebCore/page/VisualViewport.cpp (226621 => 226622)


--- trunk/Source/WebCore/page/VisualViewport.cpp	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/Source/WebCore/page/VisualViewport.cpp	2018-01-09 10:53:12 UTC (rev 226622)
@@ -29,6 +29,9 @@
 #include "ContextDestructionObserver.h"
 #include "DOMWindow.h"
 #include "Document.h"
+#include "DocumentEventQueue.h"
+#include "Event.h"
+#include "EventNames.h"
 #include "Frame.h"
 #include "FrameView.h"
 #include "Page.h"
@@ -52,56 +55,74 @@
     return static_cast<ContextDestructionObserver*>(m_associatedDOMWindow)->scriptExecutionContext();
 }
 
-static FrameView* getFrameViewAndLayoutIfNonNull(Frame* frame)
+bool VisualViewport::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
 {
-    auto* view = frame ? frame->view() : nullptr;
-    if (view) {
-        ASSERT(frame->pageZoomFactor());
-        frame->document()->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
-    }
-    return view;
+    if (!EventTarget::addEventListener(eventType, WTFMove(listener), options))
+        return false;
+
+    if (m_frame)
+        m_frame->document()->addListenerTypeIfNeeded(eventType);
+    return true;
 }
 
+void VisualViewport::updateFrameLayout() const
+{
+    ASSERT(m_frame);
+    m_frame->document()->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
+}
+
 double VisualViewport::offsetLeft() const
 {
-    if (auto* view = getFrameViewAndLayoutIfNonNull(m_frame))
-        return (view->visualViewportRect().x() - view->layoutViewportRect().x()) / m_frame->pageZoomFactor();
-    return 0;
+    if (!m_frame)
+        return 0;
+
+    updateFrameLayout();
+    return m_offsetLeft;
 }
 
 double VisualViewport::offsetTop() const
 {
-    if (auto* view = getFrameViewAndLayoutIfNonNull(m_frame))
-        return (view->visualViewportRect().y() - view->layoutViewportRect().y()) / m_frame->pageZoomFactor();
-    return 0;
+    if (!m_frame)
+        return 0;
+
+    updateFrameLayout();
+    return m_offsetTop;
 }
 
 double VisualViewport::pageLeft() const
 {
-    if (auto* view = getFrameViewAndLayoutIfNonNull(m_frame))
-        return view->visualViewportRect().x() / m_frame->pageZoomFactor();
-    return 0;
+    if (!m_frame)
+        return 0;
+
+    updateFrameLayout();
+    return m_pageLeft;
 }
 
 double VisualViewport::pageTop() const
 {
-    if (auto* view = getFrameViewAndLayoutIfNonNull(m_frame))
-        return view->visualViewportRect().y() / m_frame->pageZoomFactor();
-    return 0;
+    if (!m_frame)
+        return 0;
+
+    updateFrameLayout();
+    return m_pageTop;
 }
 
 double VisualViewport::width() const
 {
-    if (auto* view = getFrameViewAndLayoutIfNonNull(m_frame))
-        return view->visualViewportRect().width() / m_frame->pageZoomFactor();
-    return 0;
+    if (!m_frame)
+        return 0;
+
+    updateFrameLayout();
+    return m_width;
 }
 
 double VisualViewport::height() const
 {
-    if (auto* view = getFrameViewAndLayoutIfNonNull(m_frame))
-        return view->visualViewportRect().height() / m_frame->pageZoomFactor();
-    return 0;
+    if (!m_frame)
+        return 0;
+
+    updateFrameLayout();
+    return m_height;
 }
 
 double VisualViewport::scale() const
@@ -110,11 +131,68 @@
     if (!m_frame || !m_frame->isMainFrame())
         return 1;
 
-    if (auto* page = m_frame->page()) {
-        m_frame->document()->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
-        return page->pageScaleFactor();
+    updateFrameLayout();
+    return m_scale;
+}
+
+void VisualViewport::update()
+{
+    double offsetLeft = 0;
+    double offsetTop = 0;
+    m_pageLeft = 0;
+    m_pageTop = 0;
+    double width = 0;
+    double height = 0;
+    double scale = 1;
+
+    if (m_frame) {
+        if (auto* view = m_frame->view()) {
+            auto visualViewportRect = view->visualViewportRect();
+            auto layoutViewportRect = view->layoutViewportRect();
+            auto pageZoomFactor = m_frame->pageZoomFactor();
+            ASSERT(pageZoomFactor);
+            offsetLeft = (visualViewportRect.x() - layoutViewportRect.x()) / pageZoomFactor;
+            offsetTop = (visualViewportRect.y() - layoutViewportRect.y()) / pageZoomFactor;
+            m_pageLeft = visualViewportRect.x() / pageZoomFactor;
+            m_pageTop = visualViewportRect.y() / pageZoomFactor;
+            width = visualViewportRect.width() / pageZoomFactor;
+            height = visualViewportRect.height() / pageZoomFactor;
+        }
+        if (auto* page = m_frame->page())
+            scale = page->pageScaleFactor();
     }
-    return 1;
+
+    if (m_offsetLeft != offsetLeft || m_offsetTop != offsetTop) {
+        enqueueScrollEvent();
+        m_offsetLeft = offsetLeft;
+        m_offsetTop = offsetTop;
+    }
+    if (m_width != width || m_height != height || m_scale != scale) {
+        enqueueResizeEvent();
+        m_width = width;
+        m_height = height;
+        m_scale = scale;
+    }
 }
 
+void VisualViewport::enqueueResizeEvent()
+{
+    if (!m_frame)
+        return;
+
+    bool bubbles = false;
+    bool cancelable = false;
+    m_frame->document()->eventQueue().enqueueResizeEvent(*this, bubbles, cancelable);
+}
+
+void VisualViewport::enqueueScrollEvent()
+{
+    if (!m_frame)
+        return;
+
+    bool bubbles = false;
+    bool cancelable = false;
+    m_frame->document()->eventQueue().enqueueScrollEvent(*this, bubbles, cancelable);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/page/VisualViewport.h (226621 => 226622)


--- trunk/Source/WebCore/page/VisualViewport.h	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/Source/WebCore/page/VisualViewport.h	2018-01-09 10:53:12 UTC (rev 226622)
@@ -37,8 +37,10 @@
 public:
     static Ref<VisualViewport> create(Frame* frame) { return adoptRef(*new VisualViewport(frame)); }
 
+    // EventTarget
     EventTargetInterface eventTargetInterface() const final;
     ScriptExecutionContext* scriptExecutionContext() const final;
+    bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) final;
 
     double offsetLeft() const;
     double offsetTop() const;
@@ -48,6 +50,8 @@
     double height() const;
     double scale() const;
 
+    void update();
+
     using RefCounted::ref;
     using RefCounted::deref;
 
@@ -56,6 +60,19 @@
 
     void refEventTarget() final { ref(); }
     void derefEventTarget() final { deref(); }
+
+    void enqueueResizeEvent();
+    void enqueueScrollEvent();
+
+    void updateFrameLayout() const;
+
+    double m_offsetLeft { 0 };
+    double m_offsetTop { 0 };
+    double m_pageLeft { 0 };
+    double m_pageTop { 0 };
+    double m_width { 0 };
+    double m_height { 0 };
+    double m_scale { 1 };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebKit/ChangeLog (226621 => 226622)


--- trunk/Source/WebKit/ChangeLog	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/Source/WebKit/ChangeLog	2018-01-09 10:53:12 UTC (rev 226622)
@@ -1,3 +1,17 @@
+2018-01-09  Ali Juma  <[email protected]>
+
+        Implement VisualViewport API events
+        https://bugs.webkit.org/show_bug.cgi?id=179386
+
+        Reviewed by Frédéric Wang.
+
+        Change the default value of the VisualViewportAPI experimental feature flag to
+        DEFAULT_EXPERIMENTAL_FEATURES_ENABLED. This patch completes the implementation
+        of this feature as specified by https://wicg.github.io/visual-viewport/, so this
+        feature is now ready for wider testing.
+
+        * Shared/WebPreferences.yaml:
+
 2018-01-08  Alex Christensen  <[email protected]>
 
         Add WKNavigationDelegate SPI exposing WebProcess crash reason

Modified: trunk/Source/WebKit/Shared/WebPreferences.yaml (226621 => 226622)


--- trunk/Source/WebKit/Shared/WebPreferences.yaml	2018-01-09 10:02:46 UTC (rev 226621)
+++ trunk/Source/WebKit/Shared/WebPreferences.yaml	2018-01-09 10:53:12 UTC (rev 226622)
@@ -1146,7 +1146,7 @@
 
 VisualViewportAPIEnabled:
   type: bool
-  defaultValue: false
+  defaultValue: DEFAULT_EXPERIMENTAL_FEATURES_ENABLED
   humanReadableName: "VisualViewportAPI"
   humanReadableDescription: "Enable Visual Viewport API"
   category: experimental
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to