Add heuristic to avoid flattening "fullscreen" iframes
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 19 Jun 2017 07:41:11 +0000 (07:41 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 19 Jun 2017 07:41:11 +0000 (07:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=171914

Patch by Frederic Wang <fwang@igalia.com> on 2017-05-14
Reviewed by Simon Fraser.

Source/WebCore:

Some authors implement fullscreen popups as out-of-flow iframes with size set to full viewport (using vw/vh CSS units).
When iframe flattening is enabled, such iframes may unexpectedly become larger than the viewport.
This commit adds a simple heuristic to avoid frame flattening in that case.
It is experimented by introducing a "enable for non-fullscreen iframes" state for the frame
flattening setting.
The default frame flattening is still either disabled or (fully) enabled on all platforms.
InternalSettings is also adjusted so that the tests can still set the frame flattening setting.

Test: fast/frames/flattening/iframe-flattening-fullscreen.html

* page/FrameView.cpp:
(WebCore::FrameView::frameFlatteningEnabled): Use the frame flattening enum setting.
* page/Settings.h: Define a frame flattening enum that includes a "enable for non-fullscreen
iframes" state.
* page/Settings.in: Redefine frame flattening using that enum.
* rendering/RenderFrameSet.cpp:
(WebCore::RenderFrameSet::flattenFrameSet): Use the frame flattening enum setting.
* rendering/RenderIFrame.cpp:
(WebCore::RenderIFrame::isFullScreenIFrame): Add a heuristic when partial frame flattening
is enabled setting is enabled.
There is not a strict comparison against the viewport size since authors may not exactly use
100vw/100vh.
Anyway, it is hard to do such comparison using the resolved width & height on RenderStyle.
(WebCore::RenderIFrame::flattenFrame): Add a comment for the existing "zero size" heuristic.
Use isFullScreenIFrame heuristic.
* rendering/RenderView.cpp:
(WebCore::FrameFlatteningLayoutDisallower::FrameFlatteningLayoutDisallower): Use the frame flattening enum setting.
* testing/InternalSettings.cpp:
(WebCore::InternalSettings::Backup::Backup): Add backup for frame flattening.
(WebCore::InternalSettings::Backup::restoreTo): Ditto.
(WebCore::internalSettingsToWebCoreValue): Helper function to cast the frame flattening values.
(WebCore::InternalSettings::setFrameFlattening): Redefine setFrameFlattening to accept an enum.
* testing/InternalSettings.h: Define new enum & setter for frame flattening as well as a backup value.
* testing/InternalSettings.idl: Define new enum & setter for frame flattening.

Source/WebKit/mac:

This commit adjusts the mac/ios preference interface to treat frame flattening as an enum.

* WebView/WebPreferenceKeysPrivate.h: Rename the key.
* WebView/WebPreferences.mm:
(+[WebPreferences initialize]): Handle frame flattening as an enum.
(-[WebPreferences isFrameFlatteningEnabled]): Ditto.
(-[WebPreferences setFrameFlatteningEnabled:]): Ditto.
(-[WebPreferences frameFlattening]): New function to get frame flattening as an enum.
(-[WebPreferences setFrameFlattening:]): New function to set frame flattening as an enum.
* WebView/WebPreferencesPrivate.h: Ditto.
* WebView/WebView.mm:
(-[WebView _preferencesChanged:]): Ditto.
* WebView/WebPreferencesPrivate.h: Add new enum definition.

Source/WebKit/win:

This commit ajusts the window port to internally use the new preference type for frame flattening.
However, the "partial frame flattening" value is not exposed yet.

* WebView.cpp:
(WebView::notifyPreferencesChanged): Use the new type for frame flattening.

Source/WebKit2:

This commit ajusts the preference API to internally treat frame flattening as an enum.
However, the "partial frame flattening" value is not exposed to GTK, C or InjectedBundle APIs yet.

* Shared/WebPreferencesDefinitions.h: Define frame flattening as an enum.
* UIProcess/API/C/WKPreferences.cpp:
(WKPreferencesSetFrameFlatteningEnabled): Treat frame flattening as an enum.
(WKPreferencesGetFrameFlatteningEnabled): Ditto.
* UIProcess/API/gtk/WebKitSettings.cpp:
(webkit_settings_get_enable_frame_flattening): Ditto.
(webkit_settings_set_enable_frame_flattening): Ditto.
* WebProcess/InjectedBundle/InjectedBundle.cpp:
(WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner): Do not handle frame flattening since it is an enum.
For now, this breaks one test checking preference overriding because of bug 128594.
(WebKit::InjectedBundle::setFrameFlatteningEnabled): Treat frame flattening as an enum.
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::contentsSizeChanged): Use enum value.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::updatePreferences): Ditto.

Tools:

* DumpRenderTree/mac/DumpRenderTree.mm:
(resetWebPreferencesToConsistentValues): Use WebKitFrameFlatteningDisabled.

LayoutTests:

This commit adjusts tests to work when frame flattening is an enum.
It also adds a test to check the new heuristic when "frame flattening for non-fullscreen
iframes" is enabled.
set-preference.html is disabled for now, as the test suite does not support overridePreference()
for non-boolean values (bug 128594).

* fast/forms/ios/delete-in-input-in-iframe.html: Use enum value "FullyEnabled".
* fast/forms/ios/focus-input-in-iframe.html: Ditto.
* fast/forms/ios/programmatic-focus-input-in-iframe.html: Ditto.
* fast/forms/ios/typing-in-input-in-iframe.html: Ditto.
* fast/frames/flattening/crash-remove-iframe-during-object-beforeload.html: Ditto.
* fast/frames/flattening/crash-svg-document.html: Ditto.
* fast/frames/flattening/crash-when-sibling-iframe-is-destroyed-with-subtree-layoutroot.html: Ditto.
* fast/frames/flattening/frameset-flattening-advanced.html: Ditto.
* fast/frames/flattening/frameset-flattening-grid.html: Ditto.
* fast/frames/flattening/frameset-flattening-simple.html: Ditto.
* fast/frames/flattening/frameset-flattening-subframe-resize.html: Ditto.
* fast/frames/flattening/frameset-flattening-subframesets.html: Ditto.
* fast/frames/flattening/hittest-iframe-while-style-changes-crash.html: Ditto.
Be sure to use single quotes for the inline iframe page.
* fast/frames/flattening/iframe-flattening-crash.html: Use enum value "FullyEnabled".
* fast/frames/flattening/iframe-flattening-fixed-height.html: Ditto.
* fast/frames/flattening/iframe-flattening-fixed-width-and-height-no-scrolling-with-js-forced-layout.html: Ditto.
* fast/frames/flattening/iframe-flattening-fixed-width-and-height-no-scrolling.html: Ditto.
* fast/frames/flattening/iframe-flattening-fixed-width-and-height-zero-size.html: Ditto.
* fast/frames/flattening/iframe-flattening-fixed-width-and-height.html: Ditto.
* fast/frames/flattening/iframe-flattening-fixed-width.html: Ditto.
* fast/frames/flattening/iframe-flattening-fullscreen.html: Added. Check the new heuristic.
* fast/frames/flattening/iframe-flattening-fullscreen-expected.txt: Added.
* fast/frames/flattening/iframe-flattening-inside-flexbox-with-delayed-scroll-update.html: Use enum value "FullyEnabled".
* fast/frames/flattening/iframe-flattening-nested.html: Ditto.
* fast/frames/flattening/iframe-flattening-offscreen.html: Ditto.
* fast/frames/flattening/iframe-flattening-out-of-view-and-scroll.html: Ditto.
* fast/frames/flattening/iframe-flattening-out-of-view-scroll-and-relayout.html: Ditto.
* fast/frames/flattening/iframe-flattening-out-of-view.html: Ditto.
* fast/frames/flattening/iframe-flattening-resize-event-count.html: Ditto.
* fast/frames/flattening/iframe-flattening-selection-crash.html: Ditto.
* fast/frames/flattening/iframe-flattening-simple.html: Ditto.
* fast/frames/flattening/iframe-tiny.html: Ditto.
* fast/frames/flattening/scrollable-flexbox-inside-iframe-with-zero-height-and-needs-full-repaint-crash.html: Ditto.
* fast/frames/flattening/scrollable-flexbox-inside-iframe-with-zero-height-assertion-failure.html: Ditto.
* fast/frames/flattening/scrolling-in-object.html: Ditto.
* fast/spatial-navigation/snav-iframe-flattening-simple.html: Ditto.
* http/tests/misc/iframe-flattening-3level-nesting-with-blocking-resource.html: Ditto.
* platform/mac/TestExpectations: Disable this due to limitation in the test infrastructure.
* plugins/frameset-with-plugin-frame.html: Use enum value "FullyEnabled".

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

67 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/forms/ios/delete-in-input-in-iframe.html
LayoutTests/fast/forms/ios/focus-input-in-iframe.html
LayoutTests/fast/forms/ios/programmatic-focus-input-in-iframe.html
LayoutTests/fast/forms/ios/typing-in-input-in-iframe.html
LayoutTests/fast/frames/flattening/crash-remove-iframe-during-object-beforeload.html
LayoutTests/fast/frames/flattening/crash-svg-document.html
LayoutTests/fast/frames/flattening/crash-when-sibling-iframe-is-destroyed-with-subtree-layoutroot.html
LayoutTests/fast/frames/flattening/frameset-flattening-advanced.html
LayoutTests/fast/frames/flattening/frameset-flattening-grid.html
LayoutTests/fast/frames/flattening/frameset-flattening-simple.html
LayoutTests/fast/frames/flattening/frameset-flattening-subframe-resize.html
LayoutTests/fast/frames/flattening/frameset-flattening-subframesets.html
LayoutTests/fast/frames/flattening/hittest-iframe-while-style-changes-crash.html
LayoutTests/fast/frames/flattening/iframe-flattening-crash.html
LayoutTests/fast/frames/flattening/iframe-flattening-fixed-height.html
LayoutTests/fast/frames/flattening/iframe-flattening-fixed-width-and-height-no-scrolling-with-js-forced-layout.html
LayoutTests/fast/frames/flattening/iframe-flattening-fixed-width-and-height-no-scrolling.html
LayoutTests/fast/frames/flattening/iframe-flattening-fixed-width-and-height-zero-size.html
LayoutTests/fast/frames/flattening/iframe-flattening-fixed-width-and-height.html
LayoutTests/fast/frames/flattening/iframe-flattening-fixed-width.html
LayoutTests/fast/frames/flattening/iframe-flattening-fullscreen-expected.txt [new file with mode: 0644]
LayoutTests/fast/frames/flattening/iframe-flattening-fullscreen.html [new file with mode: 0644]
LayoutTests/fast/frames/flattening/iframe-flattening-inside-flexbox-with-delayed-scroll-update.html
LayoutTests/fast/frames/flattening/iframe-flattening-nested.html
LayoutTests/fast/frames/flattening/iframe-flattening-offscreen.html
LayoutTests/fast/frames/flattening/iframe-flattening-out-of-view-and-scroll.html
LayoutTests/fast/frames/flattening/iframe-flattening-out-of-view-scroll-and-relayout.html
LayoutTests/fast/frames/flattening/iframe-flattening-out-of-view.html
LayoutTests/fast/frames/flattening/iframe-flattening-resize-event-count.html
LayoutTests/fast/frames/flattening/iframe-flattening-selection-crash.html
LayoutTests/fast/frames/flattening/iframe-flattening-simple.html
LayoutTests/fast/frames/flattening/iframe-tiny.html
LayoutTests/fast/frames/flattening/scrollable-flexbox-inside-iframe-with-zero-height-and-needs-full-repaint-crash.html
LayoutTests/fast/frames/flattening/scrollable-flexbox-inside-iframe-with-zero-height-assertion-failure.html
LayoutTests/fast/frames/flattening/scrolling-in-object.html
LayoutTests/fast/spatial-navigation/snav-iframe-flattening-simple.html
LayoutTests/http/tests/misc/iframe-flattening-3level-nesting-with-blocking-resource.html
LayoutTests/platform/mac/TestExpectations
LayoutTests/plugins/frameset-with-plugin-frame.html
Source/WebCore/ChangeLog
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/Settings.h
Source/WebCore/page/Settings.in
Source/WebCore/rendering/RenderFrameSet.cpp
Source/WebCore/rendering/RenderIFrame.cpp
Source/WebCore/rendering/RenderIFrame.h
Source/WebCore/rendering/RenderView.cpp
Source/WebCore/testing/InternalSettings.cpp
Source/WebCore/testing/InternalSettings.h
Source/WebCore/testing/InternalSettings.idl
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebPreferenceKeysPrivate.h
Source/WebKit/mac/WebView/WebPreferences.mm
Source/WebKit/mac/WebView/WebPreferencesPrivate.h
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit/win/ChangeLog
Source/WebKit/win/WebView.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/WebPreferencesDefinitions.h
Source/WebKit2/UIProcess/API/C/WKPreferences.cpp
Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp
Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Tools/ChangeLog
Tools/DumpRenderTree/mac/DumpRenderTree.mm

index 487bc26..2cf3542 100644 (file)
@@ -1,3 +1,57 @@
+2017-05-14 Frederic Wang  <fwang@igalia.com>
+
+        Add heuristic to avoid flattening "fullscreen" iframes
+        https://bugs.webkit.org/show_bug.cgi?id=171914
+
+        Reviewed by Simon Fraser.
+
+        This commit adjusts tests to work when frame flattening is an enum.
+        It also adds a test to check the new heuristic when "frame flattening for non-fullscreen
+        iframes" is enabled.
+        set-preference.html is disabled for now, as the test suite does not support overridePreference()
+        for non-boolean values (bug 128594).
+
+        * fast/forms/ios/delete-in-input-in-iframe.html: Use enum value "FullyEnabled".
+        * fast/forms/ios/focus-input-in-iframe.html: Ditto.
+        * fast/forms/ios/programmatic-focus-input-in-iframe.html: Ditto.
+        * fast/forms/ios/typing-in-input-in-iframe.html: Ditto.
+        * fast/frames/flattening/crash-remove-iframe-during-object-beforeload.html: Ditto.
+        * fast/frames/flattening/crash-svg-document.html: Ditto.
+        * fast/frames/flattening/crash-when-sibling-iframe-is-destroyed-with-subtree-layoutroot.html: Ditto.
+        * fast/frames/flattening/frameset-flattening-advanced.html: Ditto.
+        * fast/frames/flattening/frameset-flattening-grid.html: Ditto.
+        * fast/frames/flattening/frameset-flattening-simple.html: Ditto.
+        * fast/frames/flattening/frameset-flattening-subframe-resize.html: Ditto.
+        * fast/frames/flattening/frameset-flattening-subframesets.html: Ditto.
+        * fast/frames/flattening/hittest-iframe-while-style-changes-crash.html: Ditto.
+        Be sure to use single quotes for the inline iframe page.
+        * fast/frames/flattening/iframe-flattening-crash.html: Use enum value "FullyEnabled".
+        * fast/frames/flattening/iframe-flattening-fixed-height.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-fixed-width-and-height-no-scrolling-with-js-forced-layout.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-fixed-width-and-height-no-scrolling.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-fixed-width-and-height-zero-size.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-fixed-width-and-height.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-fixed-width.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-fullscreen.html: Added. Check the new heuristic.
+        * fast/frames/flattening/iframe-flattening-fullscreen-expected.txt: Added.
+        * fast/frames/flattening/iframe-flattening-inside-flexbox-with-delayed-scroll-update.html: Use enum value "FullyEnabled".
+        * fast/frames/flattening/iframe-flattening-nested.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-offscreen.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-out-of-view-and-scroll.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-out-of-view-scroll-and-relayout.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-out-of-view.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-resize-event-count.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-selection-crash.html: Ditto.
+        * fast/frames/flattening/iframe-flattening-simple.html: Ditto.
+        * fast/frames/flattening/iframe-tiny.html: Ditto.
+        * fast/frames/flattening/scrollable-flexbox-inside-iframe-with-zero-height-and-needs-full-repaint-crash.html: Ditto.
+        * fast/frames/flattening/scrollable-flexbox-inside-iframe-with-zero-height-assertion-failure.html: Ditto.
+        * fast/frames/flattening/scrolling-in-object.html: Ditto.
+        * fast/spatial-navigation/snav-iframe-flattening-simple.html: Ditto.
+        * http/tests/misc/iframe-flattening-3level-nesting-with-blocking-resource.html: Ditto.
+        * platform/mac/TestExpectations: Disable this due to limitation in the test infrastructure.
+        * plugins/frameset-with-plugin-frame.html: Use enum value "FullyEnabled".
+
 2017-06-18  Ryosuke Niwa  <rniwa@webkit.org>
 
         Meter element doesn't respect the writing direction
index 7830690..3352c7d 100644 (file)
@@ -20,7 +20,7 @@
     }
 
     if (window.internals)
-        internals.settings.setFrameFlatteningEnabled(true);
+        internals.settings.setFrameFlattening("FullyEnabled")
 
     function getTypingUIScript()
     {
index c3712de..8398151 100644 (file)
@@ -20,7 +20,7 @@
     }
 
     if (window.internals)
-        internals.settings.setFrameFlatteningEnabled(true);
+        internals.settings.setFrameFlattening("FullyEnabled")
     
     function buttonClicked()
     {
index 6edb5fa..420004e 100644 (file)
@@ -19,7 +19,7 @@
     }
     
     if (window.internals)
-        internals.settings.setFrameFlatteningEnabled(true);
+        internals.settings.setFrameFlattening("FullyEnabled")
     
     function pageDidScroll()
     {
index 3ae9f0b..c4d4123 100644 (file)
@@ -20,7 +20,7 @@
     }
 
     if (window.internals)
-        internals.settings.setFrameFlatteningEnabled(true);
+        internals.settings.setFrameFlattening("FullyEnabled")
 
     function getTypingUIScript()
     {
index b38da57..1319103 100644 (file)
@@ -4,7 +4,7 @@
 if (window.testRunner && window.internals) {
     testRunner.dumpAsText();
     testRunner.waitUntilDone();
-    window.internals.settings.setFrameFlatteningEnabled(true);
+    window.internals.settings.setFrameFlattening("FullyEnabled")
 }
 
 </script>
index 8400e43..e9c509f 100644 (file)
@@ -2,7 +2,7 @@
 <script>
 
 if (window.testRunner && window.internals) {
-    internals.settings.setFrameFlatteningEnabled(true);
+    internals.settings.setFrameFlattening("FullyEnabled")
     testRunner.dumpAsText();
 }
 
index 31ea39a..bd102f8 100644 (file)
@@ -9,7 +9,7 @@
   }
 
   if (window.internals)
-    internals.settings.setFrameFlatteningEnabled(true);
+    internals.settings.setFrameFlattening("FullyEnabled")
 
   window.onload = function() {
     if (location.hash == "#1") {
index b8832ad..a0f3fc8 100644 (file)
@@ -4,7 +4,7 @@
         function test()
         {
             if (window.internals)
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             // Force synchronous layout.
             document.body.offsetHeight;
         }
index 93462ff..598c19a 100644 (file)
@@ -4,7 +4,7 @@
     function test()
     {
         if (window.internals)
-            internals.settings.setFrameFlatteningEnabled(true);
+            internals.settings.setFrameFlattening("FullyEnabled")
         // Force synchronous layout.
         document.body.offsetHeight;
     }
index 59d57d4..50c5ca0 100644 (file)
@@ -3,7 +3,7 @@
     <script type="text/javascript">
         if (window.testRunner && window.internals) {
             testRunner.waitUntilDone();
-            internals.settings.setFrameFlatteningEnabled(true);
+            internals.settings.setFrameFlattening("FullyEnabled")
         }
 
         function test()
index ac33e01..ce9d80c 100644 (file)
@@ -3,7 +3,7 @@
     <script type="text/javascript">
         if (window.testRunner && window.internals) {
             testRunner.waitUntilDone();
-            internals.settings.setFrameFlatteningEnabled(true);
+            internals.settings.setFrameFlattening("FullyEnabled")
         }
 
         function test()
index d669653..d4b1f9e 100644 (file)
@@ -4,7 +4,7 @@
         function test()
         {
             if (window.internals)
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             // Force synchronous layout.
             document.body.offsetHeight;
         }
index b0caeab..77531ce 100644 (file)
@@ -9,7 +9,7 @@ if (window.testRunner) {
 }
 
 if (window.internals)
-    internals.settings.setFrameFlatteningEnabled(true);
+    internals.settings.setFrameFlattening("FullyEnabled")
 
 function runTest() {
     setTimeout(function() {
index fc114da..66b9188 100644 (file)
@@ -4,7 +4,7 @@
         if (window.testRunner && window.internals) {
             testRunner.dumpAsText();
             testRunner.waitUntilDone();
-            internals.settings.setFrameFlatteningEnabled(true);
+            internals.settings.setFrameFlattening("FullyEnabled")
         }
     </script>
 </head>
@@ -20,7 +20,7 @@
             if (window.testRunner)
                 testRunner.notifyDone();
             if (window.testRunner)
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening('FullyEnabled')
         }
     </script>
     <body onresize='test2();'>
index fb1a45e..6f2f522 100644 (file)
@@ -4,7 +4,7 @@
         function test()
         {
             if (window.internals)
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             // Force synchronous layout.
             document.body.offsetHeight;
         }
index 10bfcef..cdded8f 100644 (file)
@@ -6,7 +6,7 @@
         {
             if (window.testRunner && window.internals) {
                 testRunner.dumpAsText();
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             }
         }
     </script>
index ce61bb3..1be9a03 100644 (file)
@@ -4,7 +4,7 @@
         function test()
         {
             if (window.internals)
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             // Force synchronous layout.
             document.body.offsetHeight;
         }
index 33bc1b8..8825bf4 100644 (file)
@@ -6,7 +6,7 @@
         {
             if (window.testRunner && window.internals) {
                 testRunner.dumpAsText();
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             }
 
             // Force synchronous layout.
index 0883c00..543d4e1 100644 (file)
@@ -3,7 +3,7 @@
     <script type="text/javascript">
         if (window.testRunner && window.internals) {
             testRunner.waitUntilDone();
-            internals.settings.setFrameFlatteningEnabled(true);
+            internals.settings.setFrameFlattening("FullyEnabled")
         }
 
         function test()
index 3eef053..4b0acd7 100644 (file)
@@ -4,7 +4,7 @@
         function test()
         {
             if (window.internals)
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             // Force synchronous layout.
             document.body.offsetHeight;
         }
diff --git a/LayoutTests/fast/frames/flattening/iframe-flattening-fullscreen-expected.txt b/LayoutTests/fast/frames/flattening/iframe-flattening-fullscreen-expected.txt
new file mode 100644 (file)
index 0000000..7c0670f
--- /dev/null
@@ -0,0 +1,7 @@
+    
+
+PASS simple iframe 
+PASS out-of-flow iframe 
+PASS iframe with vw/vh units 
+PASS fullscreen iframe 
+
diff --git a/LayoutTests/fast/frames/flattening/iframe-flattening-fullscreen.html b/LayoutTests/fast/frames/flattening/iframe-flattening-fullscreen.html
new file mode 100644 (file)
index 0000000..19f26aa
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>This tests that "fullscreen" iframes are not flatten</title>
+    <meta charset="utf-8"/>
+    <script src="../../../resources/testharness.js"></script>
+    <script src="../../../resources/testharnessreport.js"></script>
+    <script>
+      if (window.internals)
+        window.internals.settings.setFrameFlattening("EnabledForNonFullScreenIFrames");
+
+      setup({explicit_done: true});
+      function isUnflatten(id) {
+        var iframe = document.getElementById(id);
+        var iframeBox = iframe.getBoundingClientRect();
+        var innerDivBox = iframe.contentDocument.body.firstElementChild.getBoundingClientRect();
+        return iframeBox.width < innerDivBox.width && iframeBox.height < innerDivBox.height;
+      }
+      function start() {
+        test(function() { assert_false(isUnflatten("iframe0")); }, "simple iframe");
+        test(function() { assert_false(isUnflatten("iframe1")); }, "out-of-flow iframe");
+        test(function() { assert_false(isUnflatten("iframe2")); }, "iframe with vw/vh units");
+        test(function() {
+          assert_true(isUnflatten("iframe3"), "position: absolute");
+          assert_true(isUnflatten("iframe4"), "position: fixed");
+        }, "fullscreen iframe");
+        done();
+      }
+    </script>
+  </head>
+  <body onload="start()">
+    <iframe id="iframe0" style="background: blue; width: 50px; height: 50px;" scrolling="yes" srcdoc="&lt;div style='width: 1000px; height: 1000px;'&gt;&lt;/div&gt;"></iframe>
+    <iframe id="iframe1" style="background: purple; position: absolute;" scrolling="yes" srcdoc="&lt;div style='width: 1000px; height: 1000px;'&gt;&lt;/div&gt;"></iframe>
+    <iframe id="iframe2" style="background: brown; width: 100vw; height: 100vh;" scrolling="yes" srcdoc="&lt;div style='width: 1000px; height: 1000px;'&gt;&lt;/div&gt;"></iframe>
+    <iframe id="iframe3" style="background: cyan; position: absolute; width: 100vw; height: 100vh;" scrolling="yes" srcdoc="&lt;div style='width: 1000px; height: 1000px;'&gt;&lt;/div&gt;"></iframe>
+    <iframe id="iframe4" style="background: yellow; position: fixed; width: 100vw; height: 100vh;" scrolling="yes" srcdoc="&lt;div style='width: 1000px; height: 1000px;'&gt;&lt;/div&gt;"></iframe>
+  </body>
+</html>
index e3c12ad..b180a8f 100644 (file)
@@ -10,7 +10,7 @@
         function test()
         {
             if (window.internals)
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             // Force synchronous layout.
             document.body.offsetHeight;
         }
index d0c8afb..71c57d4 100644 (file)
@@ -4,7 +4,7 @@
         function test()
         {
             if (window.internals)
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             // Force synchronous layout.
             document.body.offsetHeight;
         }
index ef638b9..583323c 100644 (file)
@@ -3,7 +3,7 @@
     <script type="text/javascript">
         if (window.testRunner && window.internals) {
             testRunner.waitUntilDone();
-            internals.settings.setFrameFlatteningEnabled(true);
+            internals.settings.setFrameFlattening("FullyEnabled")
         }
 
         function test()
index 28aee67..e582742 100644 (file)
@@ -3,7 +3,7 @@
     <script type="text/javascript">
         if (window.testRunner && window.internals) {
             testRunner.waitUntilDone();
-            internals.settings.setFrameFlatteningEnabled(true);
+            internals.settings.setFrameFlattening("FullyEnabled")
         }
 
         function test()
index 4e80746..d369f82 100644 (file)
@@ -4,7 +4,7 @@
         function test()
         {
             if (window.internals)
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             // Force synchronous layout.
             document.body.offsetHeight;
         }
index f554787..259d668 100644 (file)
@@ -3,7 +3,7 @@
 <head>
 <script>
 if (window.internals)
-    internals.settings.setFrameFlatteningEnabled(true);
+    internals.settings.setFrameFlattening("FullyEnabled")
   
 if (window.testRunner) {
     testRunner.dumpAsText();
index c88a112..9a90385 100644 (file)
@@ -4,7 +4,7 @@
         function test() {
             if (window.testRunner && window.internals) {
                 testRunner.dumpAsText();
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             }
 
             // Force synchronous layout.
index 271b877..690b57f 100644 (file)
@@ -4,7 +4,7 @@
         function test()
         {
             if (window.internals)
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             // Force synchronous layout.
             document.body.offsetHeight;
         }
index 633722a..896bd9f 100644 (file)
@@ -6,7 +6,7 @@
 description("Test that frame flattening is not used for tiny frames. This test requires DRT or user agent with flattening enabled.");
 
 if (window.internals)
-    internals.settings.setFrameFlatteningEnabled(true);
+    internals.settings.setFrameFlattening("FullyEnabled")
 
 function checkResult(frameName, expectedWidth, expectedHeight)
 {
index 98418ff..db6804a 100644 (file)
@@ -3,7 +3,7 @@
         <script type="text/javascript">
             if (window.testRunner && window.internals) {
                 testRunner.waitUntilDone();
-                internals.settings.setFrameFlatteningEnabled(true);
+                internals.settings.setFrameFlattening("FullyEnabled")
             }
 
             function runTest()
index 03ba835..4e7c3e9 100644 (file)
@@ -38,7 +38,7 @@
     function runTest()
     {
       if (window.internals)
-        internals.settings.setFrameFlatteningEnabled(true);
+        internals.settings.setFrameFlattening("FullyEnabled")
 
       // starting the test itself: get to a known place.
       document.getElementById("start").focus();
index ba9ddce..4812521 100644 (file)
@@ -4,7 +4,7 @@
         if (window.testRunner && window.internals) {
             testRunner.waitUntilDone();
             testRunner.dumpAsText();
-            internals.settings.setFrameFlatteningEnabled(true);
+            internals.settings.setFrameFlattening("FullyEnabled")
         }
     </script>
     <style>body { background-color: green; }</style>
index ed4787a..10421e0 100644 (file)
@@ -498,6 +498,9 @@ webkit.org/b/112532 fast/frames/flattening/frameset-flattening-subframesets.html
 webkit.org/b/106185 fast/frames/flattening/iframe-flattening-fixed-height.html [ Failure Pass ]
 webkit.org/b/106185 fast/frames/flattening/frameset-flattening-grid.html [ Failure Pass ]
 
+# FrameFlattening enum preferences can not be overridden.
+webkit.org/b/128594 platform/mac/fast/frames/flattening/set-preference.html [ Failure ]
+
 webkit.org/b/73766 css3/unicode-bidi-isolate-aharon-failing.html [ ImageOnlyFailure ]
 
 # Failing ref tests
index 1f38e7a..a4256d7 100644 (file)
@@ -3,7 +3,7 @@
     if (window.testRunner && window.internals) {
         testRunner.dumpAsText();
         testRunner.waitUntilDone();
-        internals.settings.setFrameFlatteningEnabled(true);
+        internals.settings.setFrameFlattening("FullyEnabled")
         testRunner.overridePreference("WebKitUsesPageCachePreferenceKey", 1);
         testRunner.overridePreference("WebKitPageCacheSupportsPluginsPreferenceKey", 1);
     }
index cd4f491..02b385e 100644 (file)
@@ -1,3 +1,45 @@
+2017-05-14 Frederic Wang  <fwang@igalia.com>
+
+        Add heuristic to avoid flattening "fullscreen" iframes
+        https://bugs.webkit.org/show_bug.cgi?id=171914
+
+        Reviewed by Simon Fraser.
+
+        Some authors implement fullscreen popups as out-of-flow iframes with size set to full viewport (using vw/vh CSS units).
+        When iframe flattening is enabled, such iframes may unexpectedly become larger than the viewport.
+        This commit adds a simple heuristic to avoid frame flattening in that case.
+        It is experimented by introducing a "enable for non-fullscreen iframes" state for the frame
+        flattening setting.
+        The default frame flattening is still either disabled or (fully) enabled on all platforms.
+        InternalSettings is also adjusted so that the tests can still set the frame flattening setting.
+
+        Test: fast/frames/flattening/iframe-flattening-fullscreen.html
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::frameFlatteningEnabled): Use the frame flattening enum setting.
+        * page/Settings.h: Define a frame flattening enum that includes a "enable for non-fullscreen
+        iframes" state.
+        * page/Settings.in: Redefine frame flattening using that enum.
+        * rendering/RenderFrameSet.cpp:
+        (WebCore::RenderFrameSet::flattenFrameSet): Use the frame flattening enum setting.
+        * rendering/RenderIFrame.cpp:
+        (WebCore::RenderIFrame::isFullScreenIFrame): Add a heuristic when partial frame flattening
+        is enabled setting is enabled.
+        There is not a strict comparison against the viewport size since authors may not exactly use
+        100vw/100vh.
+        Anyway, it is hard to do such comparison using the resolved width & height on RenderStyle.
+        (WebCore::RenderIFrame::flattenFrame): Add a comment for the existing "zero size" heuristic.
+        Use isFullScreenIFrame heuristic.
+        * rendering/RenderView.cpp:
+        (WebCore::FrameFlatteningLayoutDisallower::FrameFlatteningLayoutDisallower): Use the frame flattening enum setting.
+        * testing/InternalSettings.cpp:
+        (WebCore::InternalSettings::Backup::Backup): Add backup for frame flattening.
+        (WebCore::InternalSettings::Backup::restoreTo): Ditto.
+        (WebCore::internalSettingsToWebCoreValue): Helper function to cast the frame flattening values.
+        (WebCore::InternalSettings::setFrameFlattening): Redefine setFrameFlattening to accept an enum.
+        * testing/InternalSettings.h: Define new enum & setter for frame flattening as well as a backup value.
+        * testing/InternalSettings.idl: Define new enum & setter for frame flattening.
+
 2017-06-18  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         REGRESSION(r218253): Infinite animated gifs no longer loop
index 44eb44e..55c6cb2 100644 (file)
@@ -567,7 +567,7 @@ void FrameView::setMarginHeight(LayoutUnit h)
 
 bool FrameView::frameFlatteningEnabled() const
 {
-    return frame().settings().frameFlatteningEnabled();
+    return frame().settings().frameFlattening() != FrameFlatteningDisabled;
 }
 
 bool FrameView::isFrameFlatteningValidForThisFrame() const
index d8f0940..83b1988 100644 (file)
@@ -88,6 +88,12 @@ enum PDFImageCachingPolicy {
 #endif
 };
 
+enum FrameFlattening {
+    FrameFlatteningDisabled,
+    FrameFlatteningEnabledForNonFullScreenIFrames,
+    FrameFlatteningFullyEnabled
+};
+
 typedef unsigned DebugOverlayRegions;
 
 class Settings : public RefCounted<Settings> {
index 5137300..f94303d 100644 (file)
@@ -175,7 +175,7 @@ snapshotAllPlugIns initial=false
 autostartOriginPlugInSnapshottingEnabled initial=true
 primaryPlugInSnapshotDetectionEnabled initial=true
 maximumPlugInSnapshotAttempts type=unsigned, initial=20
-frameFlatteningEnabled initial=false
+frameFlattening type=FrameFlattening, initial=FrameFlatteningDisabled
 
 webSecurityEnabled initial=true
 spatialNavigationEnabled initial=false
index 052a32c..a10f6bf 100644 (file)
@@ -651,7 +651,7 @@ void RenderFrameSet::positionFramesWithFlattening()
 
 bool RenderFrameSet::flattenFrameSet() const
 {
-    return settings().frameFlatteningEnabled();
+    return settings().frameFlattening() != FrameFlatteningDisabled;
 }
 
 void RenderFrameSet::startResizing(GridAxis& axis, int position)
index ea737a4..1ef0dd3 100644 (file)
@@ -69,17 +69,28 @@ RenderView* RenderIFrame::contentRootRenderer() const
     return childFrameView ? childFrameView->frame().contentRenderer() : 0;
 }
 
+bool RenderIFrame::isFullScreenIFrame() const
+{
+    // Some authors implement fullscreen popups as out-of-flow iframes with size set to full viewport (using vw/vh units).
+    // The size used may not perfectly match the viewport size so the following heuristic uses a relaxed constraint.
+    return style().hasOutOfFlowPosition() && style().hasViewportUnits();
+}
+
 bool RenderIFrame::flattenFrame() const
 {
-    if (!settings().frameFlatteningEnabled())
+    if (settings().frameFlattening() == FrameFlatteningDisabled)
         return false;
 
     if (style().width().isFixed() && style().height().isFixed()) {
         // Do not flatten iframes with scrolling="no".
         if (iframeElement().scrollingMode() == ScrollbarAlwaysOff)
             return false;
+        // Do not flatten iframes that have zero size, as flattening might make them visible.
         if (style().width().value() <= 0 || style().height().value() <= 0)
             return false;
+        // Do not flatten "fullscreen" iframes or they could become larger than the viewport.
+        if (settings().frameFlattening() <= FrameFlatteningEnabledForNonFullScreenIFrames && isFullScreenIFrame())
+            return false;
     }
 
     // Do not flatten offscreen inner frames during frame flattening, as flattening might make them visible.
index 8cf04cf..ff8b88a 100644 (file)
@@ -59,6 +59,8 @@ private:
     bool requiresLayer() const override;
 
     RenderView* contentRootRenderer() const;
+
+    bool isFullScreenIFrame() const;
 };
 
 } // namespace WebCore
index b6dae4c..523bc6a 100644 (file)
@@ -61,7 +61,7 @@ namespace WebCore {
 struct FrameFlatteningLayoutDisallower {
     FrameFlatteningLayoutDisallower(FrameView& frameView)
         : m_frameView(frameView)
-        , m_disallowLayout(frameView.frame().settings().frameFlatteningEnabled())
+        , m_disallowLayout(frameView.frame().settings().frameFlattening() != FrameFlatteningDisabled)
     {
         if (m_disallowLayout)
             m_frameView.startDisallowingLayout();
index 74b2713..f04fe27 100644 (file)
@@ -100,6 +100,7 @@ InternalSettings::Backup::Backup(Settings& settings)
     , m_forcedColorsAreInvertedAccessibilityValue(settings.forcedColorsAreInvertedAccessibilityValue())
     , m_forcedDisplayIsMonochromeAccessibilityValue(settings.forcedDisplayIsMonochromeAccessibilityValue())
     , m_forcedPrefersReducedMotionAccessibilityValue(settings.forcedPrefersReducedMotionAccessibilityValue())
+    , m_frameFlattening(settings.frameFlattening())
 #if ENABLE(INDEXED_DATABASE_IN_WORKERS)
     , m_indexedDBWorkersEnabled(RuntimeEnabledFeatures::sharedFeatures().indexedDBWorkersEnabled())
 #endif
@@ -193,6 +194,7 @@ void InternalSettings::Backup::restoreTo(Settings& settings)
     Settings::setAllowsAnySSLCertificate(false);
     RenderTheme::singleton().setShouldMockBoldSystemFontForAccessibility(m_shouldMockBoldSystemFontForAccessibility);
     FontCache::singleton().setShouldMockBoldSystemFontForAccessibility(m_shouldMockBoldSystemFontForAccessibility);
+    settings.setFrameFlattening(m_frameFlattening);
 
 #if ENABLE(INDEXED_DATABASE_IN_WORKERS)
     RuntimeEnabledFeatures::sharedFeatures().setIndexedDBWorkersEnabled(m_indexedDBWorkersEnabled);
@@ -788,6 +790,29 @@ ExceptionOr<void> InternalSettings::setSystemLayoutDirection(const String& direc
     return Exception { INVALID_ACCESS_ERR };
 }
 
+static FrameFlattening internalSettingsToWebCoreValue(InternalSettings::FrameFlatteningValue value)
+{
+    switch (value) {
+    case InternalSettings::FrameFlatteningValue::Disabled:
+        return FrameFlatteningDisabled;
+    case InternalSettings::FrameFlatteningValue::EnabledForNonFullScreenIFrames:
+        return FrameFlatteningEnabledForNonFullScreenIFrames;
+    case InternalSettings::FrameFlatteningValue::FullyEnabled:
+        return FrameFlatteningFullyEnabled;
+    }
+
+    ASSERT_NOT_REACHED();
+    return FrameFlatteningDisabled;
+}
+
+ExceptionOr<void> InternalSettings::setFrameFlattening(const FrameFlatteningValue& frameFlattening)
+{
+    if (!m_page)
+        return Exception { INVALID_ACCESS_ERR };
+    settings().setFrameFlattening(internalSettingsToWebCoreValue(frameFlattening));
+    return { };
+}
+
 void InternalSettings::setAllowsAnySSLCertificate(bool allowsAnyCertificate)
 {
     Settings::setAllowsAnySSLCertificate(allowsAnyCertificate);
index b9947b7..e474260 100644 (file)
@@ -97,6 +97,9 @@ public:
     ExceptionOr<void> setSystemLayoutDirection(const String&);
     ExceptionOr<void> setShouldMockBoldSystemFontForAccessibility(bool);
     ExceptionOr<void> setShouldManageAudioSessionCategory(bool);
+
+    enum class FrameFlatteningValue { Disabled, EnabledForNonFullScreenIFrames, FullyEnabled };
+    ExceptionOr<void> setFrameFlattening(const FrameFlatteningValue&);
     
     static void setAllowsAnySSLCertificate(bool);
 
@@ -187,6 +190,7 @@ private:
         Settings::ForcedAccessibilityValue m_forcedColorsAreInvertedAccessibilityValue;
         Settings::ForcedAccessibilityValue m_forcedDisplayIsMonochromeAccessibilityValue;
         Settings::ForcedAccessibilityValue m_forcedPrefersReducedMotionAccessibilityValue;
+        FrameFlattening m_frameFlattening;
 
         // Runtime enabled settings.
         bool m_indexedDBWorkersEnabled;
index 77dd2cc..b003ca6 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 enum ForcedAccessibilityValue { "system", "on", "off" };
+enum FrameFlatteningValue { "Disabled", "EnabledForNonFullScreenIFrames", "FullyEnabled" };
 
 [
     NoInterfaceObject,
@@ -81,6 +82,7 @@ enum ForcedAccessibilityValue { "system", "on", "off" };
     [MayThrowException] void setAllowsInlineMediaPlayback(boolean allows);
     [MayThrowException] void setAllowsInlineMediaPlaybackAfterFullscreen(boolean allows);
     [MayThrowException] void setInlineMediaPlaybackRequiresPlaysInlineAttribute(boolean requires);
+    [MayThrowException] void setFrameFlattening(FrameFlatteningValue frameFlattening);
 
     // RuntimeEnabledFeatures.
     void setIndexedDBWorkersEnabled(boolean enabled);
index 0bcfb2b..ae8d9ed 100644 (file)
@@ -1,3 +1,24 @@
+2017-05-14 Frederic Wang  <fwang@igalia.com>
+
+        Add heuristic to avoid flattening "fullscreen" iframes
+        https://bugs.webkit.org/show_bug.cgi?id=171914
+
+        Reviewed by Simon Fraser.
+
+        This commit adjusts the mac/ios preference interface to treat frame flattening as an enum.
+
+        * WebView/WebPreferenceKeysPrivate.h: Rename the key.
+        * WebView/WebPreferences.mm:
+        (+[WebPreferences initialize]): Handle frame flattening as an enum.
+        (-[WebPreferences isFrameFlatteningEnabled]): Ditto.
+        (-[WebPreferences setFrameFlatteningEnabled:]): Ditto.
+        (-[WebPreferences frameFlattening]): New function to get frame flattening as an enum.
+        (-[WebPreferences setFrameFlattening:]): New function to set frame flattening as an enum.
+        * WebView/WebPreferencesPrivate.h: Ditto.
+        * WebView/WebView.mm:
+        (-[WebView _preferencesChanged:]): Ditto.
+        * WebView/WebPreferencesPrivate.h: Add new enum definition.
+
 2017-06-17  Chris Dumez  <cdumez@apple.com>
 
         Use WTF::Function instead of std::function in WebKit2/
index ea46ad1..fabcce6 100644 (file)
 #define WebKitForceSoftwareWebGLRenderingPreferenceKey @"WebKitForceSoftwareWebGLRendering"
 #define WebKitForceWebGLUsesLowPowerPreferenceKey @"WebKitForceWebGLUsesLowPower"
 #define WebKitAccelerated2dCanvasEnabledPreferenceKey @"WebKitAccelerated2dCanvasEnabled"
-#define WebKitFrameFlatteningEnabledPreferenceKey @"WebKitFrameFlatteningEnabled"
+#define WebKitFrameFlatteningPreferenceKey @"WebKitFrameFlattening"
 #define WebKitSpatialNavigationEnabledPreferenceKey @"WebKitSpatialNavigationEnabled"
 #define WebKitPaginateDuringLayoutEnabledPreferenceKey @"WebKitPaginateDuringLayoutEnabled"
 #define WebKitDNSPrefetchingEnabledPreferenceKey @"WebKitDNSPrefetchingEnabled"
index 3e4bce2..91943c4 100644 (file)
@@ -520,9 +520,9 @@ public:
         [NSNumber numberWithBool:YES],  WebKitLargeImageAsyncDecodingEnabledPreferenceKey,
         [NSNumber numberWithBool:YES],  WebKitAnimatedImageAsyncDecodingEnabledPreferenceKey,
 #if PLATFORM(IOS)
-        [NSNumber numberWithBool:YES],  WebKitFrameFlatteningEnabledPreferenceKey,
+        [NSNumber numberWithUnsignedInt:FrameFlatteningFullyEnabled], WebKitFrameFlatteningPreferenceKey,
 #else
-        [NSNumber numberWithBool:NO],   WebKitFrameFlatteningEnabledPreferenceKey,
+        [NSNumber numberWithUnsignedInt:FrameFlatteningDisabled], WebKitFrameFlatteningPreferenceKey,
 #endif
         [NSNumber numberWithBool:NO],   WebKitSpatialNavigationEnabledPreferenceKey,
         [NSNumber numberWithBool:NO],  WebKitDNSPrefetchingEnabledPreferenceKey,
@@ -2108,12 +2108,23 @@ static NSString *classIBCreatorID = nil;
 
 - (BOOL)isFrameFlatteningEnabled
 {
-    return [self _boolValueForKey:WebKitFrameFlatteningEnabledPreferenceKey];
+    return [self _unsignedIntValueForKey:WebKitFrameFlatteningPreferenceKey] != WebKitFrameFlatteningDisabled;
 }
 
-- (void)setFrameFlatteningEnabled:(BOOL)flag
+- (void)setFrameFlatteningEnabled:(BOOL)flattening
 {
-    [self _setBoolValue:flag forKey:WebKitFrameFlatteningEnabledPreferenceKey];
+    WebKitFrameFlattening value = flattening ? WebKitFrameFlatteningFullyEnabled : WebKitFrameFlatteningDisabled;
+    [self _setUnsignedIntValue:value forKey:WebKitFrameFlatteningPreferenceKey];
+}
+
+- (WebKitFrameFlattening)frameFlattening
+{
+    return static_cast<WebKitFrameFlattening>([self _unsignedIntValueForKey:WebKitFrameFlatteningPreferenceKey]);
+}
+
+- (void)setFrameFlattening:(WebKitFrameFlattening)flattening
+{
+    [self _setUnsignedIntValue:flattening forKey:WebKitFrameFlatteningPreferenceKey];
 }
 
 - (BOOL)isSpatialNavigationEnabled
index 2e08b59..c49c58f 100644 (file)
@@ -56,6 +56,12 @@ typedef enum {
     WebKitJavaScriptRuntimeFlagsAllEnabled = 0
 } WebKitJavaScriptRuntimeFlags;
 
+typedef enum {
+    WebKitFrameFlatteningDisabled,
+    WebKitFrameFlatteningEnabledForNonFullScreenIFrames,
+    WebKitFrameFlatteningFullyEnabled
+} WebKitFrameFlattening;
+
 extern NSString *WebPreferencesChangedNotification;
 extern NSString *WebPreferencesRemovedNotification;
 extern NSString *WebPreferencesChangedInternalNotification;
@@ -156,6 +162,9 @@ extern NSString *WebPreferencesCacheModelChangedInternalNotification;
 - (BOOL)isFrameFlatteningEnabled;
 - (void)setFrameFlatteningEnabled:(BOOL)flag;
 
+- (WebKitFrameFlattening)frameFlattening;
+- (void)setFrameFlattening:(WebKitFrameFlattening)flag;
+
 - (BOOL)isSpatialNavigationEnabled;
 - (void)setSpatialNavigationEnabled:(BOOL)flag;
 
index 38a4601..808ee06 100644 (file)
@@ -2801,7 +2801,7 @@ static bool needsSelfRetainWhileLoadingQuirk()
     settings.setAccelerated2dCanvasEnabled([preferences accelerated2dCanvasEnabled]);
     settings.setLoadDeferringEnabled(shouldEnableLoadDeferring());
     settings.setWindowFocusRestricted(shouldRestrictWindowFocus());
-    settings.setFrameFlatteningEnabled([preferences isFrameFlatteningEnabled]);
+    settings.setFrameFlattening((const WebCore::FrameFlattening)[preferences frameFlattening]);
     settings.setSpatialNavigationEnabled([preferences isSpatialNavigationEnabled]);
     settings.setPaginateDuringLayoutEnabled([preferences paginateDuringLayoutEnabled]);
 
index 0ec659b..ca8a1e7 100644 (file)
@@ -1,3 +1,16 @@
+2017-05-14 Frederic Wang  <fwang@igalia.com>
+
+        Add heuristic to avoid flattening "fullscreen" iframes
+        https://bugs.webkit.org/show_bug.cgi?id=171914
+
+        Reviewed by Simon Fraser.
+
+        This commit ajusts the window port to internally use the new preference type for frame flattening.
+        However, the "partial frame flattening" value is not exposed yet.
+
+        * WebView.cpp:
+        (WebView::notifyPreferencesChanged): Use the new type for frame flattening.
+
 2017-06-17  Chris Dumez  <cdumez@apple.com>
 
         Use WTF::Function instead of std::function in WebKit2/
index 60b1df5..0b9791d 100644 (file)
@@ -5466,7 +5466,7 @@ HRESULT WebView::notifyPreferencesChanged(IWebNotification* notification)
     hr = prefsPrivate->isFrameFlatteningEnabled(&enabled);
     if (FAILED(hr))
         return hr;
-    settings.setFrameFlatteningEnabled(enabled);
+    settings.setFrameFlattening(enabled ? FrameFlatteningFullyEnabled : FrameFlatteningDisabled);
 
     hr = prefsPrivate->acceleratedCompositingEnabled(&enabled);
     if (FAILED(hr))
index 2611ac0..53b4a1c 100644 (file)
@@ -1,3 +1,29 @@
+2017-05-14 Frederic Wang  <fwang@igalia.com>
+
+        Add heuristic to avoid flattening "fullscreen" iframes
+        https://bugs.webkit.org/show_bug.cgi?id=171914
+
+        Reviewed by Simon Fraser.
+
+        This commit ajusts the preference API to internally treat frame flattening as an enum.
+        However, the "partial frame flattening" value is not exposed to GTK, C or InjectedBundle APIs yet.
+
+        * Shared/WebPreferencesDefinitions.h: Define frame flattening as an enum.
+        * UIProcess/API/C/WKPreferences.cpp:
+        (WKPreferencesSetFrameFlatteningEnabled): Treat frame flattening as an enum.
+        (WKPreferencesGetFrameFlatteningEnabled): Ditto.
+        * UIProcess/API/gtk/WebKitSettings.cpp:
+        (webkit_settings_get_enable_frame_flattening): Ditto.
+        (webkit_settings_set_enable_frame_flattening): Ditto.
+        * WebProcess/InjectedBundle/InjectedBundle.cpp:
+        (WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner): Do not handle frame flattening since it is an enum.
+        For now, this breaks one test checking preference overriding because of bug 128594.
+        (WebKit::InjectedBundle::setFrameFlatteningEnabled): Treat frame flattening as an enum.
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::contentsSizeChanged): Use enum value.
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::updatePreferences): Ditto.
+
 2017-06-18  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         Unreviewed. Update OptionsGTK.cmake and NEWS for 2.17.4 release.
index 9fc5a7b..9ecdae2 100644 (file)
@@ -60,7 +60,7 @@
 #if PLATFORM(IOS)
 #define DEFAULT_ALLOWS_PICTURE_IN_PICTURE_MEDIA_PLAYBACK true
 #define DEFAULT_BACKSPACE_KEY_NAVIGATION_ENABLED false
-#define DEFAULT_FRAME_FLATTENING_ENABLED true
+#define DEFAULT_FRAME_FLATTENING FrameFlatteningFullyEnabled
 #define DEFAULT_SHOULD_PRINT_BACKGROUNDS true
 #define DEFAULT_TEXT_AREAS_ARE_RESIZABLE false
 #define DEFAULT_JAVASCRIPT_CAN_OPEN_WINDOWS_AUTOMATICALLY false
@@ -77,7 +77,7 @@
 #else
 #define DEFAULT_ALLOWS_PICTURE_IN_PICTURE_MEDIA_PLAYBACK false
 #define DEFAULT_BACKSPACE_KEY_NAVIGATION_ENABLED true
-#define DEFAULT_FRAME_FLATTENING_ENABLED false
+#define DEFAULT_FRAME_FLATTENING FrameFlatteningDisabled
 #define DEFAULT_SHOULD_PRINT_BACKGROUNDS false
 #define DEFAULT_TEXT_AREAS_ARE_RESIZABLE true
 #define DEFAULT_JAVASCRIPT_CAN_OPEN_WINDOWS_AUTOMATICALLY true
     macro(LocalStorageEnabled, localStorageEnabled, Bool, bool, true, "", "") \
     macro(DatabasesEnabled, databasesEnabled, Bool, bool, true, "", "") \
     macro(XSSAuditorEnabled, xssAuditorEnabled, Bool, bool, true, "", "") \
-    macro(FrameFlatteningEnabled, frameFlatteningEnabled, Bool, bool, DEFAULT_FRAME_FLATTENING_ENABLED, "", "") \
     macro(PrivateBrowsingEnabled, privateBrowsingEnabled, Bool, bool, false, "", "") \
     macro(TextAreasAreResizable, textAreasAreResizable, Bool, bool, DEFAULT_TEXT_AREAS_ARE_RESIZABLE, "", "") \
     macro(JavaScriptCanOpenWindowsAutomatically, javaScriptCanOpenWindowsAutomatically, Bool, bool, DEFAULT_JAVASCRIPT_CAN_OPEN_WINDOWS_AUTOMATICALLY, "", "") \
     macro(DataDetectorTypes, dataDetectorTypes, UInt32, uint32_t, 0, "", "") \
     macro(UserInterfaceDirectionPolicy, userInterfaceDirectionPolicy, UInt32, uint32_t, 0, "", "") \
     macro(SystemLayoutDirection, systemLayoutDirection, UInt32, uint32_t, 0, "", "") \
+    macro(FrameFlattening, frameFlattening, UInt32, uint32_t, DEFAULT_FRAME_FLATTENING, "", "") \
     \
 
 #define FOR_EACH_WEBKIT_DEBUG_BOOL_PREFERENCE(macro) \
index 72480ae..f43cdfd 100644 (file)
@@ -144,12 +144,14 @@ bool WKPreferencesGetXSSAuditorEnabled(WKPreferencesRef preferencesRef)
 
 void WKPreferencesSetFrameFlatteningEnabled(WKPreferencesRef preferencesRef, bool frameFlatteningEnabled)
 {
-    toImpl(preferencesRef)->setFrameFlatteningEnabled(frameFlatteningEnabled);
+    // FIXME: Expose more frame flattening values.
+    toImpl(preferencesRef)->setFrameFlattening(frameFlatteningEnabled ? WebCore::FrameFlatteningFullyEnabled : WebCore::FrameFlatteningDisabled);
 }
 
 bool WKPreferencesGetFrameFlatteningEnabled(WKPreferencesRef preferencesRef)
 {
-    return toImpl(preferencesRef)->frameFlatteningEnabled();
+    // FIXME: Expose more frame flattening values.
+    return toImpl(preferencesRef)->frameFlattening() != WebCore::FrameFlatteningDisabled;
 }
 
 void WKPreferencesSetPluginsEnabled(WKPreferencesRef preferencesRef, bool pluginsEnabled)
index 537fc99..edef3f4 100644 (file)
@@ -1608,7 +1608,8 @@ gboolean webkit_settings_get_enable_frame_flattening(WebKitSettings* settings)
 {
     g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE);
 
-    return settings->priv->preferences->frameFlatteningEnabled();
+    // FIXME: Expose more frame flattening values.
+    return settings->priv->preferences->frameFlattening() != WebCore::FrameFlatteningDisabled;
 }
 
 /**
@@ -1623,11 +1624,12 @@ void webkit_settings_set_enable_frame_flattening(WebKitSettings* settings, gbool
     g_return_if_fail(WEBKIT_IS_SETTINGS(settings));
 
     WebKitSettingsPrivate* priv = settings->priv;
-    bool currentValue = priv->preferences->frameFlatteningEnabled();
+    bool currentValue = priv->preferences->frameFlattening() != WebCore::FrameFlatteningDisabled;
     if (currentValue == enabled)
         return;
 
-    priv->preferences->setFrameFlatteningEnabled(enabled);
+    // FIXME: Expose more frame flattening values.
+    priv->preferences->setFrameFlattening(enabled ? WebCore::FrameFlatteningFullyEnabled : WebCore::FrameFlatteningDisabled);
     g_object_notify(G_OBJECT(settings), "enable-frame-flattening");
 }
 
index b6362ae..1e5c4ff 100644 (file)
@@ -235,7 +235,6 @@ void InjectedBundle::overrideBoolPreferenceForTestRunner(WebPageGroupProxy* page
 #define FOR_EACH_OVERRIDE_BOOL_PREFERENCE(macro) \
     macro(WebKitAcceleratedCompositingEnabled, AcceleratedCompositingEnabled, acceleratedCompositingEnabled) \
     macro(WebKitCanvasUsesAcceleratedDrawing, CanvasUsesAcceleratedDrawing, canvasUsesAcceleratedDrawing) \
-    macro(WebKitFrameFlatteningEnabled, FrameFlatteningEnabled, frameFlatteningEnabled) \
     macro(WebKitJavaEnabled, JavaEnabled, javaEnabled) \
     macro(WebKitJavaScriptEnabled, ScriptEnabled, javaScriptEnabled) \
     macro(WebKitLoadSiteIconsKey, LoadsSiteIconsIgnoringImageLoadingSetting, loadsSiteIconsIgnoringImageLoadingPreference) \
@@ -303,7 +302,7 @@ void InjectedBundle::setFrameFlatteningEnabled(WebPageGroupProxy* pageGroup, boo
 {
     const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages();
     for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter)
-        (*iter)->settings().setFrameFlatteningEnabled(enabled);
+        (*iter)->settings().setFrameFlattening(enabled ? FrameFlatteningFullyEnabled : FrameFlatteningDisabled);
 }
 
 void InjectedBundle::setJavaScriptCanAccessClipboard(WebPageGroupProxy* pageGroup, bool enabled)
index 1c6bafa..6edcb5a 100644 (file)
@@ -564,7 +564,7 @@ PlatformPageClient WebChromeClient::platformPageClient() const
 
 void WebChromeClient::contentsSizeChanged(Frame& frame, const IntSize& size) const
 {
-    if (!m_page.corePage()->settings().frameFlatteningEnabled()) {
+    if (m_page.corePage()->settings().frameFlattening() == FrameFlatteningDisabled) {
         WebFrame* largestFrame = findLargestFrameInFrameSet(m_page);
         if (largestFrame != m_cachedFrameSetLargestFrame.get()) {
             m_cachedFrameSetLargestFrame = largestFrame;
index 3059d8b..ac4ea2f 100644 (file)
@@ -3054,7 +3054,7 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
     settings.setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey()));
     settings.setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey()));
     settings.setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey()));
-    settings.setFrameFlatteningEnabled(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey()));
+    settings.setFrameFlattening(static_cast<WebCore::FrameFlattening>(store.getUInt32ValueForKey(WebPreferencesKey::frameFlatteningKey())));
     if (store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()) && !usesEphemeralSession())
         setSessionID(SessionID::legacyPrivateSessionID());
     else if (!store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()) && sessionID() == SessionID::legacyPrivateSessionID())
index 2dbc4c1..4f060e4 100644 (file)
@@ -1,3 +1,13 @@
+2017-05-14 Frederic Wang  <fwang@igalia.com>
+
+        Add heuristic to avoid flattening "fullscreen" iframes
+        https://bugs.webkit.org/show_bug.cgi?id=171914
+
+        Reviewed by Simon Fraser.
+
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (resetWebPreferencesToConsistentValues): Use WebKitFrameFlatteningDisabled.
+
 2017-06-18  Chris Dumez  <cdumez@apple.com>
 
         Crash when re-entering MediaDevicesEnumerationRequest::cancel()
index e2058d4..611ffac 100644 (file)
@@ -903,7 +903,7 @@ static void resetWebPreferencesToConsistentValues()
     [preferences setJavaScriptRuntimeFlags:WebKitJavaScriptRuntimeFlagsAllEnabled];
     [preferences setLoadsImagesAutomatically:YES];
     [preferences setLoadsSiteIconsIgnoringImageLoadingPreference:NO];
-    [preferences setFrameFlatteningEnabled:NO];
+    [preferences setFrameFlattening:WebKitFrameFlatteningDisabled];
     [preferences setSpatialNavigationEnabled:NO];
     [preferences setMetaRefreshEnabled:YES];