Implement VisualViewport API attributes
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Nov 2017 07:26:16 +0000 (07:26 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Nov 2017 07:26:16 +0000 (07:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179385

Patch by Ali Juma <ajuma@chromium.org> on 2017-11-21
Reviewed by Frédéric Wang.

LayoutTests/imported/w3c:

Update expectations for viewport WPTs. The new expectations are all passing,
except as mentioned below.

* web-platform-tests/viewport/viewport-no-resize-event-on-overflow-recalc-expected.txt:
* web-platform-tests/viewport/viewport-read-size-causes-layout-expected.txt:
* web-platform-tests/viewport/viewport-read-size-in-iframe-causes-layout-expected.txt:
* web-platform-tests/viewport/viewport-resize-event-on-load-overflowing-page-expected.txt:
  Fails since events are not implemented yet (wkbug.com/b/179386).
* web-platform-tests/viewport/viewport-scrollbars-cause-resize-expected.txt:
* web-platform-tests/viewport/viewport-type-expected.txt:
* web-platform-tests/viewport/viewport-unscaled-scale-expected.txt:
* web-platform-tests/viewport/viewport-unscaled-scale-iframe-expected.txt:
* web-platform-tests/viewport/viewport-unscaled-scroll-expected.txt:
* web-platform-tests/viewport/viewport-unscaled-scroll-iframe-expected.txt:
  Passing expectation for non-iOS, but fails on iOS because iframes aren't scrollable (wkbug.com/b/179794).
* web-platform-tests/viewport/viewport-unscaled-size-expected.txt:
* web-platform-tests/viewport/viewport-unscaled-size-iframe-expected.txt:
  Passing expectation for non-iOS, but fails on iOS because iframes aren't scrollable (wkbug.com/b/179794).

Source/WebCore:

Add a visualViewport attribute to Window, and implement the VisualViewport
interface (https://wicg.github.io/visual-viewport/#the-visualviewport-interface).

This is behind a newly-added VisualViewportAPI experimental feature flag.

Tests: fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars.html
       fast/visual-viewport/viewport-dimensions-exclude-scrollbars.html
       fast/visual-viewport/viewport-dimensions-iframe.html
       fast/visual-viewport/viewport-dimensions-under-page-zoom.html
       fast/visual-viewport/viewport-dimensions.html

* CMakeLists.txt:
* DerivedSources.cpp:
* DerivedSources.make:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/WebCoreBuiltinNames.h:
* dom/EventTargetFactory.in:
* page/DOMWindow.cpp:
(WebCore::DOMWindow::~DOMWindow):
(WebCore::DOMWindow::resetDOMWindowProperties):
(WebCore::DOMWindow::visualViewport const):
* page/DOMWindow.h:
* page/DOMWindow.idl:
* page/Settings.yaml:
* page/VisualViewport.cpp: Added.
(WebCore::VisualViewport::VisualViewport):
(WebCore::VisualViewport::eventTargetInterface const):
(WebCore::VisualViewport::scriptExecutionContext const):
(WebCore::getFrameViewAndLayoutIfNonNull):
(WebCore::VisualViewport::offsetLeft const):
(WebCore::VisualViewport::offsetTop const):
(WebCore::VisualViewport::pageLeft const):
(WebCore::VisualViewport::pageTop const):
(WebCore::VisualViewport::width const):
(WebCore::VisualViewport::height const):
(WebCore::VisualViewport::scale const):
* page/VisualViewport.h: Added.
* page/VisualViewport.idl: Added.

Source/WebKit:

Add a VisualViewportAPI experimental feature.

* Shared/WebPreferences.yaml:

Source/WebKitLegacy/mac:

Add a VisualViewportAPI preference.

* WebView/WebPreferenceKeysPrivate.h:
* WebView/WebPreferences.mm:
(+[WebPreferences initialize]):
(-[WebPreferences visualViewportAPIEnabled]):
(-[WebPreferences setVisualViewportAPIEnabled:]):
* WebView/WebPreferencesPrivate.h:
* WebView/WebView.mm:
(-[WebView _preferencesChanged:]):

Source/WebKitLegacy/win:

Add a VisualViewportAPI preference.

* Interfaces/IWebPreferencesPrivate.idl:
* WebPreferenceKeysPrivate.h:
* WebPreferences.cpp:
(WebPreferences::initializeDefaultSettings):
(WebPreferences::visualViewportAPIEnabled):
(WebPreferences::setVisualViewportAPIEnabled):
* WebPreferences.h:
* WebView.cpp:
(WebView::notifyPreferencesChanged):

Tools:

Enable the VisualViewportAPI in layout tests.

* DumpRenderTree/mac/DumpRenderTree.mm:
(enableExperimentalFeatures):
* DumpRenderTree/win/DumpRenderTree.cpp:
(enableExperimentalFeatures):

LayoutTests:

Add tests for the Visual Viewport API, based on Blink's layout tests but modified
to use UIScriptController.

* fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars-expected.txt: Added.
* fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars.html: Added.
* fast/visual-viewport/viewport-dimensions-exclude-scrollbars-expected.txt: Added.
* fast/visual-viewport/viewport-dimensions-exclude-scrollbars.html: Added.
* fast/visual-viewport/viewport-dimensions-expected.txt: Added.
* fast/visual-viewport/viewport-dimensions-iframe-expected.txt: Added.
* fast/visual-viewport/viewport-dimensions-iframe.html: Added.
* fast/visual-viewport/viewport-dimensions-under-page-zoom-expected.txt: Added.
* fast/visual-viewport/viewport-dimensions-under-page-zoom.html: Added.
* fast/visual-viewport/viewport-dimensions.html: Added.
* platform/gtk/TestExpectations:
  Skipped tests that use UIScriptController::zoomToScale, since this isn't implemented on GTK (webkit.org/b/168050).
* platform/ios/fast/visual-viewport/viewport-dimensions-iframe-expected.txt: Added.
  Fails because iframes aren't scrollable on iOS (webkit.org/b/179794).
* platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-scroll-iframe-expected.txt: Added.
  Fails because iframes aren't scrollable on iOS (webkit.org/b/179794).
* platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-size-expected.txt: Added.
  Platform-specific expectation because of the window size being different on iOS.
* platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-size-iframe-expected.txt: Added.
  Fails because iframes aren't scrollable on iOS (webkit.org/b/179794).
* platform/mac-wk1/TestExpectations:
  Skipped a test that applies webkit-scrollbar to main frame scrollbars, since this is unsupported in WK1.

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

61 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars-expected.txt [new file with mode: 0644]
LayoutTests/fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars.html [new file with mode: 0644]
LayoutTests/fast/visual-viewport/viewport-dimensions-exclude-scrollbars-expected.txt [new file with mode: 0644]
LayoutTests/fast/visual-viewport/viewport-dimensions-exclude-scrollbars.html [new file with mode: 0644]
LayoutTests/fast/visual-viewport/viewport-dimensions-expected.txt [new file with mode: 0644]
LayoutTests/fast/visual-viewport/viewport-dimensions-iframe-expected.txt [new file with mode: 0644]
LayoutTests/fast/visual-viewport/viewport-dimensions-iframe.html [new file with mode: 0644]
LayoutTests/fast/visual-viewport/viewport-dimensions-under-page-zoom-expected.txt [new file with mode: 0644]
LayoutTests/fast/visual-viewport/viewport-dimensions-under-page-zoom.html [new file with mode: 0644]
LayoutTests/fast/visual-viewport/viewport-dimensions.html [new file with mode: 0644]
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-no-resize-event-on-overflow-recalc-expected.txt
LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-read-size-causes-layout-expected.txt
LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-read-size-in-iframe-causes-layout-expected.txt
LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-resize-event-on-load-overflowing-page-expected.txt
LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-scrollbars-cause-resize-expected.txt
LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-type-expected.txt
LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-unscaled-scale-expected.txt
LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-unscaled-scale-iframe-expected.txt
LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-unscaled-scroll-expected.txt
LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-unscaled-scroll-iframe-expected.txt
LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-unscaled-size-expected.txt
LayoutTests/imported/w3c/web-platform-tests/viewport/viewport-unscaled-size-iframe-expected.txt
LayoutTests/platform/gtk/TestExpectations
LayoutTests/platform/ios/fast/visual-viewport/viewport-dimensions-iframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-scroll-iframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-size-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-size-iframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk1/TestExpectations
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/DerivedSources.cpp
Source/WebCore/DerivedSources.make
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/WebCoreBuiltinNames.h
Source/WebCore/dom/EventTargetFactory.in
Source/WebCore/page/DOMWindow.cpp
Source/WebCore/page/DOMWindow.h
Source/WebCore/page/DOMWindow.idl
Source/WebCore/page/Settings.yaml
Source/WebCore/page/VisualViewport.cpp [new file with mode: 0644]
Source/WebCore/page/VisualViewport.h [new file with mode: 0644]
Source/WebCore/page/VisualViewport.idl [new file with mode: 0644]
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebPreferences.yaml
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h
Source/WebKitLegacy/mac/WebView/WebPreferences.mm
Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h
Source/WebKitLegacy/mac/WebView/WebView.mm
Source/WebKitLegacy/win/ChangeLog
Source/WebKitLegacy/win/Interfaces/IWebPreferencesPrivate.idl
Source/WebKitLegacy/win/WebPreferenceKeysPrivate.h
Source/WebKitLegacy/win/WebPreferences.cpp
Source/WebKitLegacy/win/WebPreferences.h
Source/WebKitLegacy/win/WebView.cpp
Tools/ChangeLog
Tools/DumpRenderTree/mac/DumpRenderTree.mm
Tools/DumpRenderTree/win/DumpRenderTree.cpp

index 6b13e9e..e9d4c75 100644 (file)
@@ -1,3 +1,36 @@
+2017-11-21  Ali Juma  <ajuma@chromium.org>
+
+        Implement VisualViewport API attributes
+        https://bugs.webkit.org/show_bug.cgi?id=179385
+
+        Reviewed by Frédéric Wang.
+
+        Add tests for the Visual Viewport API, based on Blink's layout tests but modified
+        to use UIScriptController.
+
+        * fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars-expected.txt: Added.
+        * fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars.html: Added.
+        * fast/visual-viewport/viewport-dimensions-exclude-scrollbars-expected.txt: Added.
+        * fast/visual-viewport/viewport-dimensions-exclude-scrollbars.html: Added.
+        * fast/visual-viewport/viewport-dimensions-expected.txt: Added.
+        * fast/visual-viewport/viewport-dimensions-iframe-expected.txt: Added.
+        * fast/visual-viewport/viewport-dimensions-iframe.html: Added.
+        * fast/visual-viewport/viewport-dimensions-under-page-zoom-expected.txt: Added.
+        * fast/visual-viewport/viewport-dimensions-under-page-zoom.html: Added.
+        * fast/visual-viewport/viewport-dimensions.html: Added.
+        * platform/gtk/TestExpectations:
+          Skipped tests that use UIScriptController::zoomToScale, since this isn't implemented on GTK (webkit.org/b/168050).
+        * platform/ios/fast/visual-viewport/viewport-dimensions-iframe-expected.txt: Added.
+          Fails because iframes aren't scrollable on iOS (webkit.org/b/179794).
+        * platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-scroll-iframe-expected.txt: Added.
+          Fails because iframes aren't scrollable on iOS (webkit.org/b/179794).
+        * platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-size-expected.txt: Added.
+          Platform-specific expectation because of the window size being different on iOS.
+        * platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-size-iframe-expected.txt: Added.
+          Fails because iframes aren't scrollable on iOS (webkit.org/b/179794).
+        * platform/mac-wk1/TestExpectations:
+          Skipped a test that applies webkit-scrollbar to main frame scrollbars, since this is unsupported in WK1.
+
 2017-11-21  Frederic Wang  <fwang@igalia.com>
 
         Async frame scrolling: handle fixed root backgrounds in frames
diff --git a/LayoutTests/fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars-expected.txt b/LayoutTests/fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars-expected.txt
new file mode 100644 (file)
index 0000000..1ad2662
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS Verify viewport dimensions exclude custom scrollbars. 
+
diff --git a/LayoutTests/fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars.html b/LayoutTests/fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars.html
new file mode 100644 (file)
index 0000000..163c401
--- /dev/null
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<style>
+    body {
+        height: 2000px;
+        width: 2000px;
+    }
+    ::-webkit-scrollbar {
+        width: 20px;
+        height: 20px;
+    }
+
+    ::-webkit-scrollbar-track {
+        background-color: #b46868;
+    }
+
+    ::-webkit-scrollbar-thumb {
+        background-color: rgba(0, 0, 0, 0.2);
+    }
+</style>
+
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+    var pageZoomFactor = 1.25;
+    var pageScaleFactor = 2;
+    var scrollbarThicknessInCSSPixels;
+
+    if (window.internals)
+        internals.settings.setVisualViewportEnabled(true);
+
+    function viewport() {
+        return window.visualViewport;
+    }
+
+    var test = async_test('Verify viewport dimensions exclude custom scrollbars.');
+
+    var doAfterZooming = test.step_func(function() {
+        window.scrollTo(0, 0);
+        scrollbarThicknessInCSSPixels /= pageScaleFactor;
+
+        assert_equals(
+            viewport().width,
+            800 / pageScaleFactor - scrollbarThicknessInCSSPixels,
+            "Width with page scale");
+        assert_equals(
+            viewport().height, 600 / pageScaleFactor - scrollbarThicknessInCSSPixels,
+            "Height with page scale");
+
+        window.internals.setPageZoomFactor(pageZoomFactor);
+
+        // Verify scrollbar exclusion with page zoom. Custom scrollbars are
+        // scaled with page zoom, so their size in CSS pixels remains unchanged.
+        assert_equals(
+            viewport().width,
+            800 / pageZoomFactor / pageScaleFactor - scrollbarThicknessInCSSPixels,
+            "Width with page scale and page zoom");
+        assert_equals(
+            viewport().height,
+            600 / pageZoomFactor / pageScaleFactor - scrollbarThicknessInCSSPixels,
+            "Height with page scale and page zoom");
+        test.done();
+    });
+
+    function getUIScript() {
+        return `(function() {
+            uiController.zoomToScale(${pageScaleFactor}, function() {
+                uiController.uiScriptComplete(uiController.zoomScale);
+            });
+        })();`;
+    }
+
+    window.onload = function() {
+        scrollbarThicknessInCSSPixels = window.innerWidth - document.documentElement.clientWidth;
+        testRunner.runUIScript(getUIScript(), function(zoomScale) {
+            doAfterZooming();
+        });
+    };
+</script>
diff --git a/LayoutTests/fast/visual-viewport/viewport-dimensions-exclude-scrollbars-expected.txt b/LayoutTests/fast/visual-viewport/viewport-dimensions-exclude-scrollbars-expected.txt
new file mode 100644 (file)
index 0000000..c4dfaf7
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS Verify viewport dimensions exclude scrollbars. 
+
diff --git a/LayoutTests/fast/visual-viewport/viewport-dimensions-exclude-scrollbars.html b/LayoutTests/fast/visual-viewport/viewport-dimensions-exclude-scrollbars.html
new file mode 100644 (file)
index 0000000..1b58f19
--- /dev/null
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<style>
+    body {
+        height: 2000px;
+        width: 2000px;
+    }
+</style>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+    var pageZoomFactor = 1.25;
+    var pageScaleFactor = 2;
+    var scrollbarThicknessInCSSPixels;
+
+    if (window.internals)
+        internals.settings.setVisualViewportEnabled(true);
+
+    function viewport() {
+        return window.visualViewport;
+    }
+
+    var test = async_test('Verify viewport dimensions exclude scrollbars.');
+
+    var doAfterZooming = test.step_func(function() {
+        window.scrollTo(0, 0);
+        scrollbarThicknessInCSSPixels /= pageScaleFactor;
+
+        assert_equals(
+            viewport().width,
+            800 / pageScaleFactor - scrollbarThicknessInCSSPixels,
+            "Width with page scale");
+        assert_equals(
+            viewport().height,
+            600 / pageScaleFactor - scrollbarThicknessInCSSPixels,
+            "Height with page scale");
+
+        window.internals.setPageZoomFactor(pageZoomFactor);
+
+        // Since the scrollbars don't change size to the user with page zoom,
+        // they're actually smaller in CSS pixels.
+        scrollbarThicknessInCSSPixels /= pageZoomFactor;
+        assert_equals(
+            viewport().width, 
+            800 / pageScaleFactor / pageZoomFactor - scrollbarThicknessInCSSPixels,
+            "Width with page scale and page zoom");
+        assert_equals(
+            viewport().height,
+            600 / pageScaleFactor / pageZoomFactor - scrollbarThicknessInCSSPixels,
+            "Height with page scale and page zoom");
+        test.done();
+    });
+
+    function getUIScript() {
+        return `(function() {
+            uiController.zoomToScale(${pageScaleFactor}, function() {
+                uiController.uiScriptComplete(uiController.zoomScale);
+            });
+        })();`;
+    }
+
+    window.onload = function() {
+        scrollbarThicknessInCSSPixels = window.innerWidth - document.documentElement.clientWidth;
+        testRunner.runUIScript(getUIScript(), function(zoomScale) {
+            doAfterZooming();
+        });
+    };
+</script>
diff --git a/LayoutTests/fast/visual-viewport/viewport-dimensions-expected.txt b/LayoutTests/fast/visual-viewport/viewport-dimensions-expected.txt
new file mode 100644 (file)
index 0000000..4183dd1
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS Verify viewport dimensions 
+
diff --git a/LayoutTests/fast/visual-viewport/viewport-dimensions-iframe-expected.txt b/LayoutTests/fast/visual-viewport/viewport-dimensions-iframe-expected.txt
new file mode 100644 (file)
index 0000000..5a39f2f
--- /dev/null
@@ -0,0 +1,4 @@
+
+
+PASS Verify viewport dimensions for iframe. 
+
diff --git a/LayoutTests/fast/visual-viewport/viewport-dimensions-iframe.html b/LayoutTests/fast/visual-viewport/viewport-dimensions-iframe.html
new file mode 100644 (file)
index 0000000..e287aae
--- /dev/null
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<style>
+    body {
+        height: 2000px;
+        width: 2000px;
+    }
+    #frame {
+        height: 500px;
+        width: 200px;
+    }
+</style>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+    var pageScaleFactor = 2;
+    var scrollbarThicknessInCSSPixels;
+
+    if (window.internals)
+        internals.settings.setVisualViewportEnabled(true);
+
+    function frameViewport() {
+        var frame = document.getElementById("frame");
+        return frame.contentWindow.visualViewport;
+    }
+
+    var test = async_test('Verify viewport dimensions for iframe.');
+
+    var doAfterZooming = test.step_func(function() {
+        // The page scale on the root frame shouldn't affect the viewport/scale
+        // values in the iframe.
+        var frame = document.getElementById("frame");
+        frame.contentWindow.scrollTo(10, 15);
+        assert_equals(frameViewport().width, 200 - scrollbarThicknessInCSSPixels, "width");
+        assert_equals(frameViewport().height, 500 - scrollbarThicknessInCSSPixels, "height");
+        assert_equals(frameViewport().pageLeft, 10, "pageLeft");
+        assert_equals(frameViewport().pageTop, 15, "pageTop");
+        assert_equals(frameViewport().offsetLeft, 0, "offsetLeft");
+        assert_equals(frameViewport().offsetTop, 0, "offsetTop");
+        assert_equals(frameViewport().scale, 1, "scale");
+
+        test.done();
+    });
+
+    function getUIScript() {
+        return `(function() {
+            uiController.zoomToScale(${pageScaleFactor}, function() {
+                uiController.uiScriptComplete(uiController.zoomScale);
+            });
+        })();`;
+    }
+
+    window.onload = function() {
+        scrollbarThicknessInCSSPixels = window.innerWidth - document.documentElement.clientWidth;
+        testRunner.runUIScript(getUIScript(), function(zoomScale) {
+            doAfterZooming();
+        });
+    };
+</script>
+<iframe id="frame" srcdoc="
+<style>
+  body {
+    width: 2000px;
+    height: 2000px;
+  }
+</style>
+"></iframe>
diff --git a/LayoutTests/fast/visual-viewport/viewport-dimensions-under-page-zoom-expected.txt b/LayoutTests/fast/visual-viewport/viewport-dimensions-under-page-zoom-expected.txt
new file mode 100644 (file)
index 0000000..1ac361a
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS Verify viewport dimensions under page zoom. 
+
diff --git a/LayoutTests/fast/visual-viewport/viewport-dimensions-under-page-zoom.html b/LayoutTests/fast/visual-viewport/viewport-dimensions-under-page-zoom.html
new file mode 100644 (file)
index 0000000..b50b11d
--- /dev/null
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<style>
+    body {
+        height: 2000px;
+        width: 2000px;
+    }
+</style>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+    var pageScaleFactor = 2;
+    var pageZoomFactor = 2;
+    var scrollbarThicknessInCSSPixels;
+
+    if (window.internals)
+        internals.settings.setVisualViewportEnabled(true);
+
+    function viewport() {
+        return window.visualViewport;
+    }
+
+    var test = async_test('Verify viewport dimensions under page zoom.');
+
+    var doAfterZooming = test.step_func(function() {
+        window.scrollTo(0, 0);
+        scrollbarThicknessInCSSPixels /= pageScaleFactor;
+
+        // Make the layout viewport have origin (100, 100).
+        window.scrollTo(1500, 1500);
+        window.scrollTo(100, 100);
+        window.scrollTo(110, 110);
+
+        assert_equals(viewport().offsetTop, 10, "offsetTop with page scale");
+        assert_equals(viewport().offsetLeft, 10, "offsetLeft with page scale");
+        assert_equals(viewport().pageLeft, 110, "pageLeft with page scale");
+        assert_equals(viewport().pageTop, 110, "pageTop with page scale");
+        assert_equals(viewport().width, 400 - scrollbarThicknessInCSSPixels, "width with page scale");
+        assert_equals(viewport().height, 300 - scrollbarThicknessInCSSPixels, "height with page scale");
+        assert_equals(viewport().scale, 2, "scale with page scale");
+
+        window.internals.setPageZoomFactor(pageZoomFactor);
+        scrollbarThicknessInCSSPixels /= pageZoomFactor;
+
+        testRunner.runUIScript(getUIScript(), function(zoomScale) {
+            // Make the layout viewport havie origin (100, 100).
+            window.scrollTo(1500, 1500);
+            window.scrollTo(100, 100);
+            window.scrollTo(110, 110);
+
+            assert_equals(viewport().offsetTop, 10, "offsetTop with page scale and page zoom");
+            assert_equals(viewport().offsetLeft, 10, "offsetLeft with page scale and page zoom");
+            assert_equals(viewport().pageLeft, 110, "pageLeft with page scale and page zoom");
+            assert_equals(viewport().pageTop, 110, "pageTop with page scale and page zoom");
+            assert_equals(viewport().width,
+                400 / pageZoomFactor - scrollbarThicknessInCSSPixels,
+                "width with page scale and page zoom");
+            assert_equals(viewport().height,
+                300 / pageZoomFactor - scrollbarThicknessInCSSPixels,
+                "height with page scale and page zoom");
+            assert_equals(viewport().scale, 2, "scale with page scale and page zoom");
+
+            test.done();
+        });
+    });
+
+    function getUIScript() {
+        return `(function() {
+            uiController.zoomToScale(${pageScaleFactor}, function() {
+                uiController.uiScriptComplete(uiController.zoomScale);
+            });
+        })();`;
+    }
+
+    window.onload = function() {
+        scrollbarThicknessInCSSPixels = window.innerWidth - document.documentElement.clientWidth;
+        testRunner.runUIScript(getUIScript(), function(zoomScale) {
+            doAfterZooming();
+        });
+    };
+</script>
diff --git a/LayoutTests/fast/visual-viewport/viewport-dimensions.html b/LayoutTests/fast/visual-viewport/viewport-dimensions.html
new file mode 100644 (file)
index 0000000..f533330
--- /dev/null
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<style>
+    body {
+        height: 2000px;
+        width: 2000px;
+    }
+</style>
+
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+
+<script>
+    var pageScaleFactor = 2;
+    var scrollbarThicknessInCSSPixels;
+
+    if (window.internals)
+        internals.settings.setVisualViewportEnabled(true);
+
+    function viewport() {
+        return window.visualViewport;
+    }
+
+    var test = async_test('Verify viewport dimensions');
+
+    var doBeforeZooming = test.step_func(function() {
+        scrollbarThicknessInCSSPixels = window.innerWidth - document.documentElement.clientWidth;
+        window.scrollTo(100, 100);
+
+        // Initial viewport dimensions.
+        assert_equals(viewport().width, 800 - scrollbarThicknessInCSSPixels, "initial width");
+        assert_equals(viewport().height, 600 - scrollbarThicknessInCSSPixels, "initial height");
+        assert_equals(viewport().offsetLeft, 0, "initial offsetLeft");
+        assert_equals(viewport().offsetTop, 0, "initial offsetTop");
+        assert_equals(viewport().pageLeft, 100, "initial pageLeft");
+        assert_equals(viewport().pageTop, 100, "initial pageTop");
+        assert_equals(viewport().scale, 1, "initial scale");
+    });
+
+    var doAfterZooming = test.step_func(function() {
+        scrollbarThicknessInCSSPixels /= pageScaleFactor;
+
+        // Make the layout viewport have origin (100, 100).
+        window.scrollTo(1500, 1500);
+        window.scrollTo(100, 100);
+        window.scrollTo(110, 110);
+        assert_equals(viewport().width, 800 / pageScaleFactor - scrollbarThicknessInCSSPixels, "scaled width");
+        assert_equals(viewport().height, 600 / pageScaleFactor - scrollbarThicknessInCSSPixels, "scaled height");
+        assert_equals(viewport().offsetLeft, 10, "scrolled left viewport");
+        assert_equals(viewport().offsetTop, 10, "scrolled top viewport");
+        assert_equals(viewport().pageLeft, 110, "scrolled pageLeft");
+        assert_equals(viewport().pageTop, 110, "scrolled pageTop");
+        assert_equals(viewport().scale, 2, "scale");
+
+        // Scroll the visual viewport.
+        window.scrollTo(100, 120);
+        assert_equals(viewport().offsetTop, 20, "set offsetTop");
+        assert_equals(viewport().offsetLeft, 0, "set offsetLeft");
+
+        test.done();
+    });
+
+    function getUIScript() {
+        return `(function() {
+            uiController.zoomToScale(${pageScaleFactor}, function() {
+                uiController.uiScriptComplete(uiController.zoomScale);
+            });
+        })();`;
+    }
+
+    window.onload = function() {
+        doBeforeZooming();
+        testRunner.runUIScript(getUIScript(), function(zoomScale) {
+            doAfterZooming();
+        });
+    };
+</script>
index be1f52a..eb4b5bf 100644 (file)
@@ -1,3 +1,29 @@
+2017-11-21  Ali Juma  <ajuma@chromium.org>
+
+        Implement VisualViewport API attributes
+        https://bugs.webkit.org/show_bug.cgi?id=179385
+
+        Reviewed by Frédéric Wang.
+
+        Update expectations for viewport WPTs. The new expectations are all passing,
+        except as mentioned below.
+
+        * web-platform-tests/viewport/viewport-no-resize-event-on-overflow-recalc-expected.txt:
+        * web-platform-tests/viewport/viewport-read-size-causes-layout-expected.txt:
+        * web-platform-tests/viewport/viewport-read-size-in-iframe-causes-layout-expected.txt:
+        * web-platform-tests/viewport/viewport-resize-event-on-load-overflowing-page-expected.txt:
+          Fails since events are not implemented yet (wkbug.com/b/179386).
+        * web-platform-tests/viewport/viewport-scrollbars-cause-resize-expected.txt:
+        * web-platform-tests/viewport/viewport-type-expected.txt:
+        * web-platform-tests/viewport/viewport-unscaled-scale-expected.txt:
+        * web-platform-tests/viewport/viewport-unscaled-scale-iframe-expected.txt:
+        * web-platform-tests/viewport/viewport-unscaled-scroll-expected.txt:
+        * web-platform-tests/viewport/viewport-unscaled-scroll-iframe-expected.txt:
+          Passing expectation for non-iOS, but fails on iOS because iframes aren't scrollable (wkbug.com/b/179794).
+        * web-platform-tests/viewport/viewport-unscaled-size-expected.txt:
+        * web-platform-tests/viewport/viewport-unscaled-size-iframe-expected.txt:
+          Passing expectation for non-iOS, but fails on iOS because iframes aren't scrollable (wkbug.com/b/179794).
+
 2017-11-21  Ms2ger  <Ms2ger@igalia.com>
 
         [GTK] Update expectations for wpt/url/failure.html.
index 9c09dc9..dc23532 100644 (file)
@@ -1,10 +1,7 @@
-CONSOLE MESSAGE: line 31: TypeError: undefined is not an object (evaluating 'window.visualViewport.addEventListener')
 No Resize Event Fired on Overflow Recalc
 
 Test Description: This test ensures we don't fire spurrious resize events when overflow is recalculated.
 
 
-Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'window.visualViewport.addEventListener')
-
-NOTRUN Resize event not fired at window.visualViewport when content is added 
+PASS Resize event not fired at window.visualViewport when content is added 
 
index 00a1d6b..6b5c732 100644 (file)
@@ -1,5 +1,5 @@
 This test checks that requesting the viewport size causes any pending layout to occur.
 
 
-FAIL Untitled undefined is not an object (evaluating 'window.visualViewport.width')
+PASS Untitled 
 
index d592712..00ef16d 100644 (file)
@@ -1,10 +1,7 @@
-CONSOLE MESSAGE: line 24: TypeError: undefined is not an object (evaluating 'window.visualViewport.addEventListener')
 Viewport: Resize Event On Load Overflowing Page
 
 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).
 
 
-Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'window.visualViewport.addEventListener')
-
-NOTRUN Resize event fired exactly once against window.visualViewport if scrollbars affect layout. 
+FAIL Resize event fired exactly once against window.visualViewport if scrollbars affect layout. assert_equals: expected 1 but got 0
 
index e7f4b53..ef0496f 100644 (file)
@@ -1,8 +1,7 @@
-CONSOLE MESSAGE: line 22: ReferenceError: Can't find variable: visualViewport
 Viewport: Scrollbars Cause Resize
 
 Test Description: This test checks that the appearance of classic scrollbars will cause a resize event to be fired at window.visualViewport.
 
 
-FAIL Viewport: Scrollbars Cause Resize ReferenceError: Can't find variable: visualViewport
+PASS view size initially matches window size 
 
index 12da4bb..045c357 100644 (file)
@@ -2,9 +2,9 @@ Viewport: window.visualViewport type
 
 Test Description: This test checks that window.visualViewport is an object of type VisualViewport.
 
-window.visualViewport is of type: undefined.
+window.visualViewport is of type: object.
 
 
-FAIL window.visualViewport is an object assert_equals: expected "object" but got "undefined"
-FAIL window.visualViewport has type `VisualViewport` undefined is not an object (evaluating 'window.visualViewport.toString')
+PASS window.visualViewport is an object 
+PASS window.visualViewport has type `VisualViewport` 
 
index 2fa6713..b745d42 100644 (file)
@@ -1,12 +1,9 @@
-CONSOLE MESSAGE: line 24: TypeError: undefined is not an object (evaluating 'window.visualViewport.scale')
 Viewport: Unscaled scale
 
 Test Description: This test checks that the default value for scale is 1.
 
-window.visualViewport.scale is .
+window.visualViewport.scale is 1.
 
 
-Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'window.visualViewport.scale')
-
-FAIL visualViewport.scale default value. undefined is not an object (evaluating 'window.visualViewport.scale')
+PASS visualViewport.scale default value. 
 
index 10831d1..80f34ef 100644 (file)
@@ -1,13 +1,10 @@
-CONSOLE MESSAGE: line 31: TypeError: undefined is not an object (evaluating 'frames[0].window.visualViewport.scale')
 Viewport: Unscaled scale iframe
 
 Test Description: This test checks that the default value for scale inside an iframe is 1.
 
 
-iframe's window.visualViewport.scale is .
+iframe's window.visualViewport.scale is 1.
 
 
-Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'frames[0].window.visualViewport.scale')
-
-FAIL iframe's visualViewport.scale default value. undefined is not an object (evaluating 'frames[0].window.visualViewport.scale')
+PASS iframe's visualViewport.scale default value. 
 
index f6a6a4d..f0db3d5 100644 (file)
@@ -1,17 +1,14 @@
-CONSOLE MESSAGE: line 40: TypeError: undefined is not an object (evaluating 'window.visualViewport.offsetLeft')
 Viewport: Scroll - no page scale
 
 Test Description: This test checks that window.visualViewport returns correct offset and scroll values without any pinch-zoom page scale applied.
 
-window.visualViewport's offsetLeft and offsetTop is ().
+window.visualViewport's offsetLeft and offsetTop is (0, 0).
 
-window.visualViewport's pageLeft and pageTop is ().
+window.visualViewport's pageLeft and pageTop is (1000, 1200).
 
 
-Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'window.visualViewport.offsetLeft')
-
-FAIL offsetLeft must be 0. undefined is not an object (evaluating 'window.visualViewport.offsetLeft')
-FAIL offsetTop must be 0. undefined is not an object (evaluating 'window.visualViewport.offsetTop')
-FAIL pageLeft must reflect location of viewport in document. undefined is not an object (evaluating 'window.visualViewport.pageLeft')
-FAIL pageTop must reflect location of viewport in document. undefined is not an object (evaluating 'window.visualViewport.pageTop')
+PASS offsetLeft must be 0. 
+PASS offsetTop must be 0. 
+PASS pageLeft must reflect location of viewport in document. 
+PASS pageTop must reflect location of viewport in document. 
 
index fe51b20..66c66f7 100644 (file)
@@ -1,18 +1,15 @@
-CONSOLE MESSAGE: line 51: TypeError: undefined is not an object (evaluating 'iframe.visualViewport.offsetLeft')
 Viewport: Scroll in iframe - no page scale
 
 Test Description: This test checks that window.visualViewport returns correct offset and scroll values without any pinch-zoom page scale applied.
 
 
-frames[0].window.visualViewport's offsetLeft and offsetTop is ().
+frames[0].window.visualViewport's offsetLeft and offsetTop is (0, 0).
 
-frames[0].window.visualViewport's pageLeft and pageTop is ().
+frames[0].window.visualViewport's pageLeft and pageTop is (1000, 1200).
 
 
-Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'iframe.visualViewport.offsetLeft')
-
-FAIL offsetLeft must be 0. undefined is not an object (evaluating 'iframe.visualViewport.offsetLeft')
-FAIL offsetTop must be 0. undefined is not an object (evaluating 'iframe.visualViewport.offsetTop')
-FAIL pageLeft must reflect location of viewport in document. undefined is not an object (evaluating 'iframe.visualViewport.pageLeft')
-FAIL pageTop must reflect location of viewport in document. undefined is not an object (evaluating 'iframe.visualViewport.pageTop')
+PASS offsetLeft must be 0. 
+PASS offsetTop must be 0. 
+PASS pageLeft must reflect location of viewport in document. 
+PASS pageTop must reflect location of viewport in document. 
 
index 62a3481..48bc964 100644 (file)
@@ -1,15 +1,14 @@
-CONSOLE MESSAGE: line 36: TypeError: undefined is not an object (evaluating 'window.visualViewport.width')
 Viewport: Size unscaled
 
 Test Description: This test checks that window.visualViewport returns correct sizes without any pinch-zoom page scale applied.
 
-window.visualViewport width and height is ().
+window.visualViewport width and height is (800, 600).
 
-window.visualViewport width and height when scrollbars are present is ().
+window.visualViewport width and height when scrollbars are present is (785, 585).
 
 
-Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'window.visualViewport.width')
-
-FAIL visualViewport.width should match documentElement.clientWidth when unzoomed. undefined is not an object (evaluating 'window.visualViewport.width')
-FAIL visualViewport.height should match documentElement.clientHeight when unzoomed. undefined is not an object (evaluating 'window.visualViewport.height')
+PASS visualViewport.width should match documentElement.clientWidth when unzoomed. 
+PASS visualViewport.height should match documentElement.clientHeight when unzoomed. 
+PASS visualViewport.width should exclude scrollbar. 
+PASS visualViewport.height should exclude scrollbar. 
 
index a6d0564..fb16e4b 100644 (file)
@@ -1,16 +1,15 @@
-CONSOLE MESSAGE: line 38: TypeError: undefined is not an object (evaluating 'frames[0].window.visualViewport.width')
 Viewport: Size in iframe - no page scale
 
 Test Description: This test checks that window.visualViewport returns correct sizes without any pinch-zoom page scale applied but with scrollbars.
 
 
-frames[0].window.visualViewport width and height is ().
+frames[0].window.visualViewport width and height is (200, 300).
 
-frames[0].window.visualViewport width and height when scrollbars are present is ().
+frames[0].window.visualViewport width and height when scrollbars are present is (185, 285).
 
 
-Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'frames[0].window.visualViewport.width')
-
-FAIL window.visualViewport.width of iframe viewport should match iframe width. undefined is not an object (evaluating 'frames[0].window.visualViewport.width')
-FAIL window.visualViewport.height of iframe viewport should match iframe height. undefined is not an object (evaluating 'frames[0].window.visualViewport.height')
+PASS window.visualViewport.width of iframe viewport should match iframe width. 
+PASS window.visualViewport.height of iframe viewport should match iframe height. 
+PASS window.visualViewport.width of iframe viewport should not include scrollbar. 
+PASS window.visualViewport.height of iframe viewport should not include scrollbar. 
 
index c52bd8f..92c7b89 100644 (file)
@@ -978,6 +978,11 @@ webkit.org/b/153833 fast/events/input-event-insert-replacement.html [ Skip ]
 
 # Skip tests requiring UIScriptController::zoomToScale
 webkit.org/b/168050 fast/visual-viewport/rtl-zoomed-rects.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 ]
+webkit.org/b/168050 fast/visual-viewport/viewport-dimensions-under-page-zoom.html [ Skip ]
+webkit.org/b/168050 fast/visual-viewport/viewport-dimensions.html [ Skip ]
 webkit.org/b/168050 fast/visual-viewport/zoomed-fixed-header-and-footer.html [ Skip ]
 webkit.org/b/168050 fast/visual-viewport/zoomed-fixed-scroll-down-then-up.html [ Skip ]
 webkit.org/b/168050 fast/visual-viewport/zoomed-fixed.html [ Skip ]
diff --git a/LayoutTests/platform/ios/fast/visual-viewport/viewport-dimensions-iframe-expected.txt b/LayoutTests/platform/ios/fast/visual-viewport/viewport-dimensions-iframe-expected.txt
new file mode 100644 (file)
index 0000000..fa8f9d2
--- /dev/null
@@ -0,0 +1,4 @@
+
+
+FAIL Verify viewport dimensions for iframe. assert_equals: pageLeft expected 10 but got 0
+
diff --git a/LayoutTests/platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-scroll-iframe-expected.txt b/LayoutTests/platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-scroll-iframe-expected.txt
new file mode 100644 (file)
index 0000000..5e8c657
--- /dev/null
@@ -0,0 +1,15 @@
+Viewport: Scroll in iframe - no page scale
+
+Test Description: This test checks that window.visualViewport returns correct offset and scroll values without any pinch-zoom page scale applied.
+
+
+frames[0].window.visualViewport's offsetLeft and offsetTop is (0, 0).
+
+frames[0].window.visualViewport's pageLeft and pageTop is (0, 0).
+
+
+PASS offsetLeft must be 0. 
+PASS offsetTop must be 0. 
+FAIL pageLeft must reflect location of viewport in document. assert_equals: expected 1000 but got 0
+FAIL pageTop must reflect location of viewport in document. assert_equals: expected 1200 but got 0
+
diff --git a/LayoutTests/platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-size-expected.txt b/LayoutTests/platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-size-expected.txt
new file mode 100644 (file)
index 0000000..78077d5
--- /dev/null
@@ -0,0 +1,14 @@
+Viewport: Size unscaled
+
+Test Description: This test checks that window.visualViewport returns correct sizes without any pinch-zoom page scale applied.
+
+window.visualViewport width and height is (320, 548).
+
+window.visualViewport width and height when scrollbars are present is (320, 548).
+
+
+PASS visualViewport.width should match documentElement.clientWidth when unzoomed. 
+PASS visualViewport.height should match documentElement.clientHeight when unzoomed. 
+PASS visualViewport.width should exclude scrollbar. 
+PASS visualViewport.height should exclude scrollbar. 
+
diff --git a/LayoutTests/platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-size-iframe-expected.txt b/LayoutTests/platform/ios/imported/w3c/web-platform-tests/viewport/viewport-unscaled-size-iframe-expected.txt
new file mode 100644 (file)
index 0000000..affde05
--- /dev/null
@@ -0,0 +1,15 @@
+Viewport: Size in iframe - no page scale
+
+Test Description: This test checks that window.visualViewport returns correct sizes without any pinch-zoom page scale applied but with scrollbars.
+
+
+frames[0].window.visualViewport width and height is (200, 300).
+
+frames[0].window.visualViewport width and height when scrollbars are present is (200, 300).
+
+
+PASS window.visualViewport.width of iframe viewport should match iframe width. 
+PASS window.visualViewport.height of iframe viewport should match iframe height. 
+FAIL window.visualViewport.width of iframe viewport should not include scrollbar. assert_equals: expected 185 but got 200
+FAIL window.visualViewport.height of iframe viewport should not include scrollbar. assert_equals: expected 285 but got 300
+
index afd8287..c645c29 100644 (file)
@@ -245,6 +245,9 @@ inspector/unit-tests/heap-snapshot-collection-event.html [ Skip ]
 fast/scrolling/scroll-animator-overlay-scrollbars-clicked.html [ Skip ]
 fast/scrolling/scroll-animator-overlay-scrollbars-hovered.html [ Skip ]
 
+# WK1 main frame scrollbars are native widgets whose size is unaffected by webkit-scrollbar.
+fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars.html [ Skip ]
+
 # This hit-test test doesn't work on DRT
 webkit.org/b/156084 accessibility/mac/video-tag-hit-test.html [ Skip ]
 
index 859988d..fd76695 100644 (file)
@@ -785,6 +785,7 @@ set(WebCore_NON_SVG_IDL_FILES
     page/PerformanceTiming.idl
     page/Screen.idl
     page/ScrollToOptions.idl
+    page/VisualViewport.idl
     page/WebKitPoint.idl
     page/WindowEventHandlers.idl
     page/WindowOrWorkerGlobalScope.idl
index c62b69d..2609bba 100644 (file)
@@ -1,3 +1,50 @@
+2017-11-21  Ali Juma  <ajuma@chromium.org>
+
+        Implement VisualViewport API attributes
+        https://bugs.webkit.org/show_bug.cgi?id=179385
+
+        Reviewed by Frédéric Wang.
+
+        Add a visualViewport attribute to Window, and implement the VisualViewport
+        interface (https://wicg.github.io/visual-viewport/#the-visualviewport-interface).
+
+        This is behind a newly-added VisualViewportAPI experimental feature flag.
+
+        Tests: fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars.html
+               fast/visual-viewport/viewport-dimensions-exclude-scrollbars.html
+               fast/visual-viewport/viewport-dimensions-iframe.html
+               fast/visual-viewport/viewport-dimensions-under-page-zoom.html
+               fast/visual-viewport/viewport-dimensions.html
+
+        * CMakeLists.txt:
+        * DerivedSources.cpp:
+        * DerivedSources.make:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/WebCoreBuiltinNames.h:
+        * dom/EventTargetFactory.in:
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::~DOMWindow):
+        (WebCore::DOMWindow::resetDOMWindowProperties):
+        (WebCore::DOMWindow::visualViewport const):
+        * page/DOMWindow.h:
+        * page/DOMWindow.idl:
+        * page/Settings.yaml:
+        * page/VisualViewport.cpp: Added.
+        (WebCore::VisualViewport::VisualViewport):
+        (WebCore::VisualViewport::eventTargetInterface const):
+        (WebCore::VisualViewport::scriptExecutionContext const):
+        (WebCore::getFrameViewAndLayoutIfNonNull):
+        (WebCore::VisualViewport::offsetLeft const):
+        (WebCore::VisualViewport::offsetTop const):
+        (WebCore::VisualViewport::pageLeft const):
+        (WebCore::VisualViewport::pageTop const):
+        (WebCore::VisualViewport::width const):
+        (WebCore::VisualViewport::height const):
+        (WebCore::VisualViewport::scale const):
+        * page/VisualViewport.h: Added.
+        * page/VisualViewport.idl: Added.
+
 2017-11-21  Frederic Wang  <fwang@igalia.com>
 
         Async frame scrolling: handle fixed root backgrounds in frames
index 5ffbec2..2cc40ae 100644 (file)
 #endif
 #include "JSValidityState.cpp"
 #include "JSVideoPlaybackQuality.cpp"
+#include "JSVisualViewport.cpp"
 #include "JSVoidCallback.cpp"
 #include "JSWaveShaperNode.cpp"
 #include "JSWebKitAnimationEvent.cpp"
index 8cab11f..fc471b9 100644 (file)
@@ -755,6 +755,7 @@ JS_BINDING_IDLS = \
     $(WebCore)/page/ScrollToOptions.idl \
     $(WebCore)/page/UserMessageHandler.idl \
     $(WebCore)/page/UserMessageHandlersNamespace.idl \
+    $(WebCore)/page/VisualViewport.idl \
     $(WebCore)/page/WebKitNamespace.idl \
     $(WebCore)/page/WebKitPoint.idl \
     $(WebCore)/page/WindowEventHandlers.idl \
index b13ccc4..60c4a3b 100644 (file)
@@ -1336,6 +1336,7 @@ page/UserContentProvider.cpp
 page/UserContentController.cpp
 page/UserContentURLPattern.cpp
 page/VisitedLinkStore.cpp
+page/VisualViewport.cpp
 page/WheelEventDeltaFilter.cpp
 page/WheelEventTestTrigger.cpp
 page/WindowFeatures.cpp
@@ -2941,6 +2942,7 @@ JSVRStageParameters.cpp
 JSValidityState.cpp
 JSVideoPlaybackQuality.cpp
 JSVisibilityState.cpp
+JSVisualViewport.cpp
 JSVoidCallback.cpp
 JSWaveShaperNode.cpp
 JSWebAnimation.cpp
index 8aff847..a1596d3 100644 (file)
                7728694E14F8882500F484DC /* EXTTextureFilterAnisotropic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7728694B14F8882500F484DC /* EXTTextureFilterAnisotropic.cpp */; };
                7728694F14F8882500F484DC /* EXTTextureFilterAnisotropic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7728694C14F8882500F484DC /* EXTTextureFilterAnisotropic.h */; };
                7728698414FD9ADA00F484DC /* JSEXTTextureFilterAnisotropic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7728698214FD9ADA00F484DC /* JSEXTTextureFilterAnisotropic.h */; };
+               7779BD951F312D0100C21417 /* VisualViewport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7779BD941F3117B700C21417 /* VisualViewport.cpp */; };
+               7779BD961F32246A00C21417 /* JSVisualViewport.h in Headers */ = {isa = PBXBuildFile; fileRef = 7779BD921F2FDBF700C21417 /* JSVisualViewport.h */; };
+               7779BD971F32246D00C21417 /* JSVisualViewport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7779BD911F2FDBCE00C21417 /* JSVisualViewport.cpp */; };
                77A17A7112F28182004E02F6 /* OESVertexArrayObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 77A17A6E12F28182004E02F6 /* OESVertexArrayObject.cpp */; };
                77A17A7212F28182004E02F6 /* OESVertexArrayObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 77A17A6F12F28182004E02F6 /* OESVertexArrayObject.h */; };
                77A17A7712F28642004E02F6 /* WebGLVertexArrayObjectOES.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 77A17A7412F28642004E02F6 /* WebGLVertexArrayObjectOES.cpp */; };
                77534FF21ED4C96B00A9646E /* JSFederatedCredentialInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFederatedCredentialInit.h; sourceTree = "<group>"; };
                77534FF31ED4C99F00A9646E /* JSPasswordCredentialData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPasswordCredentialData.cpp; sourceTree = "<group>"; };
                77534FF41ED4C99F00A9646E /* JSPasswordCredentialData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPasswordCredentialData.h; sourceTree = "<group>"; };
+               7779BD911F2FDBCE00C21417 /* JSVisualViewport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSVisualViewport.cpp; sourceTree = "<group>"; };
+               7779BD921F2FDBF700C21417 /* JSVisualViewport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVisualViewport.h; sourceTree = "<group>"; };
+               7779BD931F2FDFCB00C21417 /* VisualViewport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VisualViewport.h; sourceTree = "<group>"; };
+               7779BD941F3117B700C21417 /* VisualViewport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VisualViewport.cpp; sourceTree = "<group>"; };
                77A17A6E12F28182004E02F6 /* OESVertexArrayObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OESVertexArrayObject.cpp; sourceTree = "<group>"; };
                77A17A6F12F28182004E02F6 /* OESVertexArrayObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OESVertexArrayObject.h; sourceTree = "<group>"; };
                77A17A7012F28182004E02F6 /* OESVertexArrayObject.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OESVertexArrayObject.idl; sourceTree = "<group>"; };
                77AAD6811ECF8D3800BFA2D1 /* FederatedCredential.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FederatedCredential.cpp; sourceTree = "<group>"; };
                77AAD6831ECFB66200BFA2D1 /* CredentialCreationOptions.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CredentialCreationOptions.idl; sourceTree = "<group>"; };
                77AAD6851ECFBD3900BFA2D1 /* CredentialCreationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CredentialCreationOptions.h; sourceTree = "<group>"; };
+               77CAAAEF1F2FC35000CB5C8D /* VisualViewport.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VisualViewport.idl; sourceTree = "<group>"; };
                77CD167D1ED3BDB8009E9536 /* FederatedCredentialInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = FederatedCredentialInit.idl; sourceTree = "<group>"; };
                77CD167E1ED3BE11009E9536 /* FederatedCredentialInit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FederatedCredentialInit.h; sourceTree = "<group>"; };
                77CD167F1ED3C2DB009E9536 /* PasswordCredentialData.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PasswordCredentialData.idl; sourceTree = "<group>"; };
                                26F9A83718A046AC00AEB88A /* ViewportConfiguration.h */,
                                1AF4CEEB18BC3C1B00BC2D34 /* VisitedLinkStore.cpp */,
                                1ABA7FFF1897341200DCE9D6 /* VisitedLinkStore.h */,
+                               7779BD941F3117B700C21417 /* VisualViewport.cpp */,
+                               7779BD931F2FDFCB00C21417 /* VisualViewport.h */,
+                               77CAAAEF1F2FC35000CB5C8D /* VisualViewport.idl */,
                                BE983D95052A2E0A00892D85 /* WebCoreKeyboardUIMode.h */,
                                7C48A6CE191C9D6500026674 /* WebKitNamespace.cpp */,
                                7C48A6CF191C9D6500026674 /* WebKitNamespace.h */,
                                65DF31F009D1CC60000BE325 /* JSText.h */,
                                46E791451F97E01700199739 /* JSVisibilityState.cpp */,
                                46E791461F97E01700199739 /* JSVisibilityState.h */,
+                               7779BD911F2FDBCE00C21417 /* JSVisualViewport.cpp */,
+                               7779BD921F2FDBF700C21417 /* JSVisualViewport.h */,
                                83F570AE1C53268E007FD6CB /* JSXMLDocument.cpp */,
                                83F570AD1C53268E007FD6CB /* JSXMLDocument.h */,
                        );
                                BE8EF04B171C9014009B48C3 /* JSVideoTrack.h in Headers */,
                                BE8EF04D171C9014009B48C3 /* JSVideoTrackList.h in Headers */,
                                46E791491F97E01A00199739 /* JSVisibilityState.h in Headers */,
+                               7779BD961F32246A00C21417 /* JSVisualViewport.h in Headers */,
                                2DDE1CE41F574AE900D1A365 /* JSVRDisplay.h in Headers */,
                                2DDE1CF81F574C3900D1A365 /* JSVRDisplayCapabilities.h in Headers */,
                                2DDE1CFA1F574C3E00D1A365 /* JSVRDisplayEvent.h in Headers */,
index 05c754f..ac77fdf 100644 (file)
@@ -141,6 +141,7 @@ namespace WebCore {
     macro(VRFieldOfView) \
     macro(VRFrameData) \
     macro(VRStageParameters) \
+    macro(VisualViewport) \
     macro(WebGL2RenderingContext) \
     macro(WebGLVertexArrayObject) \
     macro(WebGPUBuffer) \
@@ -279,6 +280,7 @@ namespace WebCore {
     macro(underlyingSink) \
     macro(underlyingSource) \
     macro(view) \
+    macro(visualViewport) \
     macro(webRTCLegacyAPIEnabled) \
     macro(webkit) \
     macro(webkitAudioContext) \
index 36cf0c1..711689b 100644 (file)
@@ -43,6 +43,7 @@ TextTrackCue conditional=VIDEO_TRACK
 TextTrackList conditional=VIDEO_TRACK
 VRDisplay
 VideoTrackList conditional=VIDEO_TRACK
+VisualViewport
 WebKitMediaKeySession conditional=LEGACY_ENCRYPTED_MEDIA
 WebSocket
 Worker
index f0a45e3..17a7a61 100644 (file)
 #include "SuddenTermination.h"
 #include "URL.h"
 #include "UserGestureIndicator.h"
+#include "VisualViewport.h"
 #include "WebKitPoint.h"
 #include "WindowFeatures.h"
 #include "WindowFocusAllowedIndicator.h"
@@ -424,6 +425,7 @@ DOMWindow::~DOMWindow()
         ASSERT(!m_sessionStorage);
         ASSERT(!m_localStorage);
         ASSERT(!m_applicationCache);
+        ASSERT(!m_visualViewport);
     }
 #endif
 
@@ -586,6 +588,7 @@ void DOMWindow::resetDOMWindowProperties()
     m_statusbar = nullptr;
     m_toolbar = nullptr;
     m_performance = nullptr;
+    m_visualViewport = nullptr;
 }
 
 bool DOMWindow::isCurrentlyDisplayedInFrame() const
@@ -799,6 +802,15 @@ Location* DOMWindow::location() const
     return m_location.get();
 }
 
+VisualViewport* DOMWindow::visualViewport() const
+{
+    if (!isCurrentlyDisplayedInFrame())
+        return nullptr;
+    if (!m_visualViewport)
+        m_visualViewport = VisualViewport::create(m_frame);
+    return m_visualViewport.get();
+}
+
 #if ENABLE(USER_MESSAGE_HANDLERS)
 
 bool DOMWindow::shouldHaveWebKitNamespaceForWorld(DOMWrapperWorld& world)
index 184b792..8c8e3d9 100644 (file)
@@ -77,6 +77,7 @@ class ScheduledAction;
 class Screen;
 class Storage;
 class StyleMedia;
+class VisualViewport;
 class WebKitNamespace;
 class WebKitPoint;
 
@@ -243,6 +244,8 @@ public:
     void resizeBy(float x, float y) const;
     void resizeTo(float width, float height) const;
 
+    VisualViewport* visualViewport() const;
+
     // Timers
     ExceptionOr<int> setTimeout(JSC::ExecState&, std::unique_ptr<ScheduledAction>, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
     void clearTimeout(int timeoutId);
@@ -384,6 +387,7 @@ private:
     mutable RefPtr<BarProp> m_statusbar;
     mutable RefPtr<BarProp> m_toolbar;
     mutable RefPtr<Location> m_location;
+    mutable RefPtr<VisualViewport> m_visualViewport;
 
     String m_status;
     String m_defaultStatus;
index 85af6a3..02ebbba 100644 (file)
@@ -133,6 +133,9 @@ typedef USVString CSSOMString;
     void scrollBy(optional ScrollToOptions option);
     void scrollBy(unrestricted double x, unrestricted double y);
 
+    // Visual Viewport (https://wicg.github.io/ViewportAPI/spec.html)
+    [EnabledBySetting=VisualViewportAPI, Replaceable] readonly attribute VisualViewport visualViewport; // FIXME: Should be [SameObject]. https://bugs.webkit.org/show_bug.cgi?id=163414
+
     // Client (CSSOM-View).
     [Replaceable] readonly attribute long screenX;
     [Replaceable] readonly attribute long screenY;
index deee7ab..1995f7b 100644 (file)
@@ -523,6 +523,9 @@ visualViewportEnabled:
   initial: false
   onChange: setNeedsRecalcStyleInAllFrames
 
+visualViewportAPIEnabled:
+  initial: false
+
 inputEventsEnabled:
   initial: true
 
diff --git a/Source/WebCore/page/VisualViewport.cpp b/Source/WebCore/page/VisualViewport.cpp
new file mode 100644 (file)
index 0000000..63e897b
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "VisualViewport.h"
+
+#include "ContextDestructionObserver.h"
+#include "DOMWindow.h"
+#include "Document.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "Page.h"
+
+namespace WebCore {
+
+VisualViewport::VisualViewport(Frame* frame)
+    : DOMWindowProperty(frame)
+{
+}
+
+EventTargetInterface VisualViewport::eventTargetInterface() const
+{
+    return VisualViewportEventTargetInterfaceType;
+}
+
+ScriptExecutionContext* VisualViewport::scriptExecutionContext() const
+{
+    if (!m_associatedDOMWindow)
+        return nullptr;
+    return static_cast<ContextDestructionObserver*>(m_associatedDOMWindow)->scriptExecutionContext();
+}
+
+static FrameView* getFrameViewAndLayoutIfNonNull(Frame* frame)
+{
+    auto* view = frame ? frame->view() : nullptr;
+    if (view) {
+        ASSERT(frame->pageZoomFactor());
+        frame->document()->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
+    }
+    return view;
+}
+
+double VisualViewport::offsetLeft() const
+{
+    if (auto* view = getFrameViewAndLayoutIfNonNull(m_frame))
+        return (view->visualViewportRect().x() - view->layoutViewportRect().x()) / m_frame->pageZoomFactor();
+    return 0;
+}
+
+double VisualViewport::offsetTop() const
+{
+    if (auto* view = getFrameViewAndLayoutIfNonNull(m_frame))
+        return (view->visualViewportRect().y() - view->layoutViewportRect().y()) / m_frame->pageZoomFactor();
+    return 0;
+}
+
+double VisualViewport::pageLeft() const
+{
+    if (auto* view = getFrameViewAndLayoutIfNonNull(m_frame))
+        return view->visualViewportRect().x() / m_frame->pageZoomFactor();
+    return 0;
+}
+
+double VisualViewport::pageTop() const
+{
+    if (auto* view = getFrameViewAndLayoutIfNonNull(m_frame))
+        return view->visualViewportRect().y() / m_frame->pageZoomFactor();
+    return 0;
+}
+
+double VisualViewport::width() const
+{
+    if (auto* view = getFrameViewAndLayoutIfNonNull(m_frame))
+        return view->visualViewportRect().width() / m_frame->pageZoomFactor();
+    return 0;
+}
+
+double VisualViewport::height() const
+{
+    if (auto* view = getFrameViewAndLayoutIfNonNull(m_frame))
+        return view->visualViewportRect().height() / m_frame->pageZoomFactor();
+    return 0;
+}
+
+double VisualViewport::scale() const
+{
+    // Subframes always have scale 1 since they aren't scaled relative to their parent frame.
+    if (!m_frame || !m_frame->isMainFrame())
+        return 1;
+
+    if (auto* page = m_frame->page()) {
+        m_frame->document()->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
+        return page->pageScaleFactor();
+    }
+    return 1;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/page/VisualViewport.h b/Source/WebCore/page/VisualViewport.h
new file mode 100644 (file)
index 0000000..15f7fe7
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "DOMWindowProperty.h"
+#include "EventTarget.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class Frame;
+
+class VisualViewport final : public RefCounted<VisualViewport>, public EventTargetWithInlineData, public DOMWindowProperty {
+public:
+    static Ref<VisualViewport> create(Frame* frame) { return adoptRef(*new VisualViewport(frame)); }
+
+    EventTargetInterface eventTargetInterface() const final;
+    ScriptExecutionContext* scriptExecutionContext() const final;
+
+    double offsetLeft() const;
+    double offsetTop() const;
+    double pageLeft() const;
+    double pageTop() const;
+    double width() const;
+    double height() const;
+    double scale() const;
+
+    using RefCounted::ref;
+    using RefCounted::deref;
+
+private:
+    explicit VisualViewport(Frame*);
+
+    void refEventTarget() final { ref(); }
+    void derefEventTarget() final { deref(); }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/page/VisualViewport.idl b/Source/WebCore/page/VisualViewport.idl
new file mode 100644 (file)
index 0000000..caf1620
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+* Copyright (C) 2017 Google Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// https://wicg.github.io/ViewportAPI/spec.html
+[
+EnabledBySetting=VisualViewportAPI
+]
+interface VisualViewport : EventTarget {
+    readonly attribute double offsetLeft;
+    readonly attribute double offsetTop;
+
+    readonly attribute double pageLeft;
+    readonly attribute double pageTop;
+
+    readonly attribute double width;
+    readonly attribute double height;
+
+    readonly attribute double scale;
+
+    attribute EventHandler onresize;
+    attribute EventHandler onscroll;
+};
index 45b3b5a..b53968d 100644 (file)
@@ -1,3 +1,14 @@
+2017-11-21  Ali Juma  <ajuma@chromium.org>
+
+        Implement VisualViewport API attributes
+        https://bugs.webkit.org/show_bug.cgi?id=179385
+
+        Reviewed by Frédéric Wang.
+
+        Add a VisualViewportAPI experimental feature.
+
+        * Shared/WebPreferences.yaml:
+
 2017-11-21  Christopher Reid  <chris.reid@sony.com>
 
         [PAL] Remove FileSystem's dependency on WebCoreNSStringExtras
index 0d600b4..c532589 100644 (file)
@@ -1122,6 +1122,13 @@ SubresourceIntegrityEnabled:
   humanReadableDescription: "Enable SubresourceIntegrity"
   category: experimental
 
+VisualViewportAPIEnabled:
+  type: bool
+  defaultValue: false
+  humanReadableName: "VisualViewportAPI"
+  humanReadableDescription: "Enable Visual Viewport API"
+  category: experimental
+
 WebAnimationsEnabled:
   type: bool
   defaultValue: false
index ecdb86e..7980950 100644 (file)
@@ -1,3 +1,21 @@
+2017-11-21  Ali Juma  <ajuma@chromium.org>
+
+        Implement VisualViewport API attributes
+        https://bugs.webkit.org/show_bug.cgi?id=179385
+
+        Reviewed by Frédéric Wang.
+
+        Add a VisualViewportAPI preference.
+
+        * WebView/WebPreferenceKeysPrivate.h:
+        * WebView/WebPreferences.mm:
+        (+[WebPreferences initialize]):
+        (-[WebPreferences visualViewportAPIEnabled]):
+        (-[WebPreferences setVisualViewportAPIEnabled:]):
+        * WebView/WebPreferencesPrivate.h:
+        * WebView/WebView.mm:
+        (-[WebView _preferencesChanged:]):
+
 2017-11-21  Christopher Reid  <chris.reid@sony.com>
 
         [PAL] Remove FileSystem's dependency on WebCoreNSStringExtras
index 4496bba..744887b 100644 (file)
 #define WebKitDirectoryUploadEnabledPreferenceKey @"WebKitDirectoryUploadEnabled"
 #define WebKitCSSGridLayoutEnabledPreferenceKey @"WebKitCSSGridLayoutEnabled"
 #define WebKitVisualViewportEnabledPreferenceKey @"WebKitVisualViewportEnabled"
+#define WebKitVisualViewportAPIEnabledPreferenceKey @"WebKitVisualViewportAPIEnabled"
 #define WebKitModernMediaControlsEnabledPreferenceKey @"WebKitModernMediaControlsEnabled"
 #define WebKitSubtleCryptoEnabledPreferenceKey @"WebKitSubtleCryptoEnabled"
 #define WebKitMediaDevicesEnabledPreferenceKey @"WebKitMediaDevicesEnabled"
index 3320c83..e04c4a1 100644 (file)
@@ -650,6 +650,7 @@ public:
 #else
         [NSNumber numberWithBool:YES], WebKitVisualViewportEnabledPreferenceKey,
 #endif
+        [NSNumber numberWithBool:NO], WebKitVisualViewportAPIEnabledPreferenceKey,
 
         [NSNumber numberWithBool:YES], WebKitNeedsStorageAccessFromFileURLsQuirkKey,
 #if ENABLE(MEDIA_STREAM)
@@ -3075,6 +3076,15 @@ static NSString *classIBCreatorID = nil;
     [self _setBoolValue:flag forKey:WebKitVisualViewportEnabledPreferenceKey];
 }
 
+- (BOOL)visualViewportAPIEnabled
+{
+    return [self _boolValueForKey:WebKitVisualViewportAPIEnabledPreferenceKey];
+}
+
+- (void)setVisualViewportAPIEnabled:(BOOL)flag
+{
+    [self _setBoolValue:flag forKey:WebKitVisualViewportAPIEnabledPreferenceKey];
+}
 - (BOOL)webAnimationsEnabled
 {
     return [self _boolValueForKey:WebKitWebAnimationsEnabledPreferenceKey];
index 84c1150..c92af29 100644 (file)
@@ -574,6 +574,7 @@ extern NSString *WebPreferencesCacheModelChangedInternalNotification;
 - (BOOL)isSecureContextAttributeEnabled;
 
 @property (nonatomic) BOOL visualViewportEnabled;
+@property (nonatomic) BOOL visualViewportAPIEnabled;
 @property (nonatomic) BOOL largeImageAsyncDecodingEnabled;
 @property (nonatomic) BOOL animatedImageAsyncDecodingEnabled;
 @property (nonatomic) BOOL javaScriptMarkupEnabled;
index 4466d99..ec00796 100644 (file)
@@ -2860,6 +2860,7 @@ static bool needsSelfRetainWhileLoadingQuirk()
     settings.setJavaScriptCanOpenWindowsAutomatically([preferences javaScriptCanOpenWindowsAutomatically] || shouldAllowWindowOpenWithoutUserGesture());
 
     settings.setVisualViewportEnabled([preferences visualViewportEnabled]);
+    settings.setVisualViewportAPIEnabled([preferences visualViewportAPIEnabled]);
     settings.setMediaContentTypesRequiringHardwareSupport([preferences mediaContentTypesRequiringHardwareSupport]);
 
     switch ([preferences storageBlockingPolicy]) {
index 5a8ebc5..1a2ead9 100644 (file)
@@ -1,3 +1,22 @@
+2017-11-21  Ali Juma  <ajuma@chromium.org>
+
+        Implement VisualViewport API attributes
+        https://bugs.webkit.org/show_bug.cgi?id=179385
+
+        Reviewed by Frédéric Wang.
+
+        Add a VisualViewportAPI preference.
+
+        * Interfaces/IWebPreferencesPrivate.idl:
+        * WebPreferenceKeysPrivate.h:
+        * WebPreferences.cpp:
+        (WebPreferences::initializeDefaultSettings):
+        (WebPreferences::visualViewportAPIEnabled):
+        (WebPreferences::setVisualViewportAPIEnabled):
+        * WebPreferences.h:
+        * WebView.cpp:
+        (WebView::notifyPreferencesChanged):
+
 2017-11-14  Alex Christensen  <achristensen@webkit.org>
 
         Clean up old URL parser remnants
index 618d838..1e9289b 100644 (file)
@@ -217,4 +217,6 @@ interface IWebPreferencesPrivate6 : IWebPreferencesPrivate5
     HRESULT setDataTransferItemsEnabled([in] BOOL enabled);
     HRESULT inspectorAdditionsEnabled([out, retval] BOOL*);
     HRESULT setInspectorAdditionsEnabled([in] BOOL enabled);
+    HRESULT visualViewportAPIEnabled([out, retval] BOOL*);
+    HRESULT setVisualViewportAPIEnabled([in] BOOL enabled);
 }
index a062241..665f22c 100644 (file)
 #define WebKitDataTransferItemsEnabledPreferenceKey "WebKitDataTransferItemsEnabled"
 
 #define WebKitInspectorAdditionsEnabledPreferenceKey "WebKitInspectorAdditionsEnabled"
+
+#define WebKitVisualViewportAPIEnabledPreferenceKey "WebKitVisualViewportAPIEnabled"
index f1150ee..bef34b3 100644 (file)
@@ -322,6 +322,8 @@ void WebPreferences::initializeDefaultSettings()
 
     CFDictionaryAddValue(defaults, CFSTR(WebKitInspectorAdditionsEnabledPreferenceKey), kCFBooleanFalse);
 
+    CFDictionaryAddValue(defaults, CFSTR(WebKitVisualViewportAPIEnabledPreferenceKey), kCFBooleanFalse);
+
     defaultSettings = defaults;
 }
 
@@ -2093,6 +2095,20 @@ HRESULT WebPreferences::setInspectorAdditionsEnabled(BOOL enabled)
     return S_OK;
 }
 
+HRESULT WebPreferences::visualViewportAPIEnabled(_Out_ BOOL* enabled)
+{
+    if (!enabled)
+        return E_POINTER;
+    *enabled = boolValueForKey(WebKitVisualViewportAPIEnabledPreferenceKey);
+    return S_OK;
+}
+
+HRESULT WebPreferences::setVisualViewportAPIEnabled(BOOL enabled)
+{
+    setBoolValue(WebKitVisualViewportAPIEnabledPreferenceKey, enabled);
+    return S_OK;
+}
+
 HRESULT WebPreferences::setApplicationId(BSTR applicationId)
 {
     m_applicationId = String(applicationId).createCFString();
index a8b6f55..a75dae8 100644 (file)
@@ -265,6 +265,8 @@ public:
     virtual HRESULT STDMETHODCALLTYPE setDataTransferItemsEnabled(BOOL);
     virtual HRESULT STDMETHODCALLTYPE inspectorAdditionsEnabled(_Out_ BOOL*);
     virtual HRESULT STDMETHODCALLTYPE setInspectorAdditionsEnabled(BOOL);
+    virtual HRESULT STDMETHODCALLTYPE visualViewportAPIEnabled(_Out_ BOOL*);
+    virtual HRESULT STDMETHODCALLTYPE setVisualViewportAPIEnabled(BOOL);
 
     // WebPreferences
 
index 0ed3e33..b5d8d3e 100644 (file)
@@ -5243,6 +5243,11 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
         return hr;
     RuntimeEnabledFeatures::sharedFeatures().setInspectorAdditionsEnabled(!!enabled);
 
+    hr = prefsPrivate->visualViewportAPIEnabled(&enabled);
+    if (FAILED(hr))
+        return hr;
+    settings.setVisualViewportAPIEnabled(!!enabled);
+
     hr = preferences->privateBrowsingEnabled(&enabled);
     if (FAILED(hr))
         return hr;
index 4d85af0..6a8c07c 100644 (file)
@@ -1,3 +1,17 @@
+2017-11-21  Ali Juma  <ajuma@chromium.org>
+
+        Implement VisualViewport API attributes
+        https://bugs.webkit.org/show_bug.cgi?id=179385
+
+        Reviewed by Frédéric Wang.
+
+        Enable the VisualViewportAPI in layout tests.
+
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (enableExperimentalFeatures):
+        * DumpRenderTree/win/DumpRenderTree.cpp:
+        (enableExperimentalFeatures):
+
 2017-11-21  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [WPE] Run unit tests in the bots
index 5169e69..4a097a3 100644 (file)
@@ -856,6 +856,7 @@ static void enableExperimentalFeatures(WebPreferences* preferences)
     [preferences setWritableStreamAPIEnabled:YES];
     preferences.encryptedMediaAPIEnabled = YES;
     [preferences setAccessibilityObjectModelEnabled:YES];
+    [preferences setVisualViewportAPIEnabled:YES];
 }
 
 // Called before each test.
index 0b59ea1..8c84065 100644 (file)
@@ -772,7 +772,7 @@ static bool shouldEnableDeveloperExtras(const char* pathOrURL)
 
 static void enableExperimentalFeatures(IWebPreferences* preferences)
 {
-    COMPtr<IWebPreferencesPrivate5> prefsPrivate { Query, preferences };
+    COMPtr<IWebPreferencesPrivate6> prefsPrivate { Query, preferences };
 
     // FIXME: CSSGridLayout
     // FIXME: SpringTimingFunction
@@ -782,6 +782,7 @@ static void enableExperimentalFeatures(IWebPreferences* preferences)
     // FIXME: ModernMediaControls
     // FIXME: InputEvents
     // FIXME: SubtleCrypto
+    prefsPrivate->setVisualViewportAPIEnabled(TRUE);
     prefsPrivate->setWebAnimationsEnabled(TRUE);
     // FIXME: WebGL2
     // FIXME: WebRTC