Title: [220112] trunk
Revision
220112
Author
[email protected]
Date
2017-08-01 14:42:28 -0700 (Tue, 01 Aug 2017)

Log Message

REGRESSION (r217197): New Yorker website hangs for a long time on load, lots of blank tiles
https://bugs.webkit.org/show_bug.cgi?id=175009
<rdar://problem/33505791>

Reviewed by Simon Fraser.

Source/WebCore:

This patch ensures that we report the desktop, non-frame-flattened frame size for media queries in subframes.
Some websites don't expect the iframes to be expanded to the size of the content and when the media query
callback mutates the content (triggering frame resize), they might end up getting into a never ending layout.

Test: fast/frames/flattening/media-query-growing-content.html

* css/MediaQueryEvaluator.cpp:
(WebCore::orientationEvaluate):
(WebCore::aspectRatioEvaluate):
(WebCore::heightEvaluate):
(WebCore::widthEvaluate):
* page/FrameView.cpp:
(WebCore::FrameView::layout):
(WebCore::FrameView::layoutSizeForMediaQuery const):
(WebCore::FrameView::evaluateMediaQueryList):
* page/FrameView.h:

LayoutTests:

* fast/frames/flattening/media-query-growing-content-expected.txt: Added.
* fast/frames/flattening/media-query-growing-content.html: Added.
* fast/frames/flattening/resources/media-query-min-height-with-flattening.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (220111 => 220112)


--- trunk/LayoutTests/ChangeLog	2017-08-01 21:02:37 UTC (rev 220111)
+++ trunk/LayoutTests/ChangeLog	2017-08-01 21:42:28 UTC (rev 220112)
@@ -1,3 +1,15 @@
+2017-08-01  Zalan Bujtas  <[email protected]>
+
+        REGRESSION (r217197): New Yorker website hangs for a long time on load, lots of blank tiles
+        https://bugs.webkit.org/show_bug.cgi?id=175009
+        <rdar://problem/33505791>
+
+        Reviewed by Simon Fraser.
+
+        * fast/frames/flattening/media-query-growing-content-expected.txt: Added.
+        * fast/frames/flattening/media-query-growing-content.html: Added.
+        * fast/frames/flattening/resources/media-query-min-height-with-flattening.html: Added.
+
 2017-08-01  Youenn Fablet  <[email protected]>
 
         Layout tests with 'https' suffix should be run over HTTPS

Added: trunk/LayoutTests/fast/frames/flattening/media-query-growing-content-expected.txt (0 => 220112)


--- trunk/LayoutTests/fast/frames/flattening/media-query-growing-content-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/flattening/media-query-growing-content-expected.txt	2017-08-01 21:42:28 UTC (rev 220112)
@@ -0,0 +1,2 @@
+
+

Added: trunk/LayoutTests/fast/frames/flattening/media-query-growing-content.html (0 => 220112)


--- trunk/LayoutTests/fast/frames/flattening/media-query-growing-content.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/flattening/media-query-growing-content.html	2017-08-01 21:42:28 UTC (rev 220112)
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that media query can't get into an ever-growing cycle.</title>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+if (window.internals)
+    internals.settings.setFrameFlattening("FullyEnabled");
+
+function runTest() {
+    if (window.testRunner) {
+        testRunner.waitUntilDone();
+        setTimeout(function() {
+            testRunner.notifyDone();
+        }, 50);
+    }
+}
+</script>
+</head>
+<body>
+<iframe _onload_="runTest()" src=""
+<div id=testResult></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/frames/flattening/resources/media-query-min-height-with-flattening.html (0 => 220112)


--- trunk/LayoutTests/fast/frames/flattening/resources/media-query-min-height-with-flattening.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/flattening/resources/media-query-min-height-with-flattening.html	2017-08-01 21:42:28 UTC (rev 220112)
@@ -0,0 +1,34 @@
+<style>
+    div {
+        width: 200px;
+        height: 600px;
+    }
+</style>
+<div id=growingDiv></div>
+<script>
+var counter = 0;
+window.matchMedia('(min-height: 200px)').addListener(function(changed) {
+    ++counter;
+    setTimeout(function() {
+        growingDiv.innerText = growingDiv.innerText + ' media query callback ';
+        parent.document.getElementById("testResult").innerText = counter;
+    }, 0);
+});
+
+window.matchMedia('(min-width: 600px)').addListener(function(changed) {
+    ++counter;
+    setTimeout(function() {
+        growingDiv.innerText = growingDiv.innerText + ' media query callback ';
+        parent.document.getElementById("testResult").innerText = counter;
+    }, 0);
+});
+
+window.matchMedia('(min-aspect-ratio: 1/1)').addListener(function(changed) {
+    ++counter;
+    setTimeout(function() {
+        growingDiv.innerText = growingDiv.innerText + ' media query callback ';
+        parent.document.getElementById("testResult").innerText = counter;
+    }, 0);
+});
+
+</script>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (220111 => 220112)


--- trunk/Source/WebCore/ChangeLog	2017-08-01 21:02:37 UTC (rev 220111)
+++ trunk/Source/WebCore/ChangeLog	2017-08-01 21:42:28 UTC (rev 220112)
@@ -1,3 +1,28 @@
+2017-08-01  Zalan Bujtas  <[email protected]>
+
+        REGRESSION (r217197): New Yorker website hangs for a long time on load, lots of blank tiles
+        https://bugs.webkit.org/show_bug.cgi?id=175009
+        <rdar://problem/33505791>
+
+        Reviewed by Simon Fraser.
+
+        This patch ensures that we report the desktop, non-frame-flattened frame size for media queries in subframes.
+        Some websites don't expect the iframes to be expanded to the size of the content and when the media query
+        callback mutates the content (triggering frame resize), they might end up getting into a never ending layout.
+
+        Test: fast/frames/flattening/media-query-growing-content.html
+
+        * css/MediaQueryEvaluator.cpp:
+        (WebCore::orientationEvaluate):
+        (WebCore::aspectRatioEvaluate):
+        (WebCore::heightEvaluate):
+        (WebCore::widthEvaluate):
+        * page/FrameView.cpp:
+        (WebCore::FrameView::layout):
+        (WebCore::FrameView::layoutSizeForMediaQuery const):
+        (WebCore::FrameView::evaluateMediaQueryList):
+        * page/FrameView.h:
+
 2017-07-26  Jiewen Tan  <[email protected]>
 
         Add tests to detect mistakes in backward compatibility when the structured clone algorithm is changed in the future

Modified: trunk/Source/WebCore/css/MediaQueryEvaluator.cpp (220111 => 220112)


--- trunk/Source/WebCore/css/MediaQueryEvaluator.cpp	2017-08-01 21:02:37 UTC (rev 220111)
+++ trunk/Source/WebCore/css/MediaQueryEvaluator.cpp	2017-08-01 21:42:28 UTC (rev 220112)
@@ -304,16 +304,14 @@
     if (!view)
         return false;
 
-    auto width = view->layoutWidth();
-    auto height = view->layoutHeight();
-
+    auto viewSize = view->layoutSizeForMediaQuery();
     if (!is<CSSPrimitiveValue>(value)) {
         // _expression_ (orientation) evaluates to true if width and height >= 0.
-        return height >= 0 && width >= 0;
+        return viewSize.height() >= 0 && viewSize.width() >= 0;
     }
 
     auto keyword = downcast<CSSPrimitiveValue>(*value).valueID();
-    if (width > height) // Square viewport is portrait.
+    if (viewSize.width() > viewSize.height()) // Square viewport is portrait.
         return keyword == CSSValueLandscape;
     return keyword == CSSValuePortrait;
 }
@@ -324,12 +322,11 @@
     // assume if we have a device, its aspect ratio is non-zero
     if (!value)
         return true;
-
     FrameView* view = frame.view();
     if (!view)
         return true;
-
-    return compareAspectRatioValue(value, view->layoutWidth(), view->layoutHeight(), op);
+    auto viewSize = view->layoutSizeForMediaQuery();
+    return compareAspectRatioValue(value, viewSize.width(), viewSize.height(), op);
 }
 
 static bool deviceAspectRatioEvaluate(CSSValue* value, const CSSToLengthConversionData&, Frame& frame, MediaFeaturePrefix op)
@@ -445,7 +442,7 @@
     FrameView* view = frame.view();
     if (!view)
         return false;
-    int height = view->layoutHeight();
+    int height = view->layoutSizeForMediaQuery().height();
     if (!value)
         return height;
     if (auto* renderView = frame.document()->renderView())
@@ -459,7 +456,7 @@
     FrameView* view = frame.view();
     if (!view)
         return false;
-    int width = view->layoutWidth();
+    int width = view->layoutSizeForMediaQuery().width();
     if (!value)
         return width;
     if (auto* renderView = frame.document()->renderView())

Modified: trunk/Source/WebCore/page/FrameView.cpp (220111 => 220112)


--- trunk/Source/WebCore/page/FrameView.cpp	2017-08-01 21:02:37 UTC (rev 220111)
+++ trunk/Source/WebCore/page/FrameView.cpp	2017-08-01 21:42:28 UTC (rev 220112)
@@ -1316,6 +1316,8 @@
     bool inChildFrameLayoutWithFrameFlattening = isInChildFrameWithFrameFlattening();
 
     if (inChildFrameLayoutWithFrameFlattening) {
+        if (!m_frameFlatteningViewSizeForMediaQuery)
+            m_frameFlatteningViewSizeForMediaQuery = ScrollView::layoutSize();
         startLayoutAtMainFrameViewIfNeeded(allowSubtree);
         RenderElement* root = m_layoutRoot ? m_layoutRoot : frame().document()->renderView();
         if (!root || !root->needsLayout())
@@ -1370,13 +1372,10 @@
             // FIXME: This instrumentation event is not strictly accurate since cached media query results do not persist across StyleResolver rebuilds.
             InspectorInstrumentation::mediaQueryResultChanged(document);
         }
-        
         document.evaluateMediaQueryList();
-
         // If there is any pagination to apply, it will affect the RenderView's style, so we should
         // take care of that now.
         applyPaginationToViewport();
-
         // Always ensure our style info is up-to-date. This can happen in situations where
         // the layout beats any sort of style recalc update that needs to occur.
         document.updateStyleIfNeeded();
@@ -5407,5 +5406,10 @@
 {
     return renderView() && renderView()->shouldPlaceBlockDirectionScrollbarOnLeft();
 }
-    
+
+IntSize FrameView::layoutSizeForMediaQuery() const
+{
+    return m_frameFlatteningViewSizeForMediaQuery.value_or(ScrollView::layoutSize());
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/page/FrameView.h (220111 => 220112)


--- trunk/Source/WebCore/page/FrameView.h	2017-08-01 21:02:37 UTC (rev 220111)
+++ trunk/Source/WebCore/page/FrameView.h	2017-08-01 21:42:28 UTC (rev 220112)
@@ -216,7 +216,8 @@
     bool shouldUpdate() const;
 
     WEBCORE_EXPORT void adjustViewSize();
-    
+    IntSize layoutSizeForMediaQuery() const;
+
     WEBCORE_EXPORT void setViewportSizeForCSSViewportUnits(IntSize);
     IntSize viewportSizeForCSSViewportUnits() const;
     
@@ -890,6 +891,8 @@
     int m_autoSizeFixedMinimumHeight;
     // The intrinsic content size decided by autosizing.
     IntSize m_autoSizeContentSize;
+    // Report the first computed frame view size to media queries.
+    std::optional<IntSize> m_frameFlatteningViewSizeForMediaQuery;
 
     std::unique_ptr<ScrollableAreaSet> m_scrollableAreas;
     std::unique_ptr<ViewportConstrainedObjectSet> m_viewportConstrainedObjects;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to