Title: [117451] trunk
Revision
117451
Author
an...@apple.com
Date
2012-05-17 08:42:17 -0700 (Thu, 17 May 2012)

Log Message

Frame flattening should not expand tiny frames
https://bugs.webkit.org/show_bug.cgi?id=86736

Source/WebCore: 

Reviewed by Kenneth Rohde Christiansen.
        
If a frame has so small fixed size that it is not usefully scrollable on desktop it is probably
not meant to be scrolled. Displaying any otherwise invisible content by expanding the frame
may end up looking like a rendering error.

The patch prevents expansion of frames that have fixed width or height less than 8px.

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

* rendering/RenderFrameBase.cpp:
(WebCore::shouldExpandFrame):
(WebCore):
(WebCore::RenderFrameBase::layoutWithFlattening):

LayoutTests: 

Reviewed by Kenneth Rohde Christiansen.

* fast/frames/flattening/iframe-tiny-expected.txt: Added.
* fast/frames/flattening/iframe-tiny.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (117450 => 117451)


--- trunk/LayoutTests/ChangeLog	2012-05-17 15:21:08 UTC (rev 117450)
+++ trunk/LayoutTests/ChangeLog	2012-05-17 15:42:17 UTC (rev 117451)
@@ -1,3 +1,13 @@
+2012-05-17  Antti Koivisto  <an...@apple.com>
+
+        Frame flattening should not expand tiny frames
+        https://bugs.webkit.org/show_bug.cgi?id=86736
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        * fast/frames/flattening/iframe-tiny-expected.txt: Added.
+        * fast/frames/flattening/iframe-tiny.html: Added.
+
 2012-05-17  Krzysztof Czech  <k.cz...@samsung.com>, Mariusz Grzegorczyk <marius...@samsung.com>
 
         [EFL] Gardening failure test cases.

Added: trunk/LayoutTests/fast/frames/flattening/iframe-tiny-expected.txt (0 => 117451)


--- trunk/LayoutTests/fast/frames/flattening/iframe-tiny-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/flattening/iframe-tiny-expected.txt	2012-05-17 15:42:17 UTC (rev 117451)
@@ -0,0 +1,45 @@
+Test that frame flattening is not used for tiny frames. This test requires DRT or user agent with flattening enabled.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+testFrame0
+PASS getComputedStyle(frame, 0).width is '0px'
+PASS getComputedStyle(frame, 0).height is '0px'
+testFrame1
+PASS getComputedStyle(frame, 0).width is '1px'
+PASS getComputedStyle(frame, 0).height is '1px'
+testFrame2
+PASS getComputedStyle(frame, 0).width is '7px'
+PASS getComputedStyle(frame, 0).height is '7px'
+testFrame3
+PASS getComputedStyle(frame, 0).width is '400px'
+PASS getComputedStyle(frame, 0).height is '400px'
+testFrame4
+PASS getComputedStyle(frame, 0).width is '0px'
+PASS getComputedStyle(frame, 0).height is '100px'
+testFrame5
+PASS getComputedStyle(frame, 0).width is '100px'
+PASS getComputedStyle(frame, 0).height is '0px'
+testFrame6
+PASS getComputedStyle(frame, 0).width is '100px'
+PASS getComputedStyle(frame, 0).height is '2px'
+testFrame7
+PASS getComputedStyle(frame, 0).width is '2px'
+PASS getComputedStyle(frame, 0).height is '100px'
+testFrame8
+PASS getComputedStyle(frame, 0).width is '2px'
+PASS getComputedStyle(frame, 0).height is '150px'
+testFrame9
+PASS getComputedStyle(frame, 0).width is '300px'
+PASS getComputedStyle(frame, 0).height is '2px'
+testFrame10
+PASS getComputedStyle(frame, 0).width is '400px'
+PASS getComputedStyle(frame, 0).height is '400px'
+testFrame11
+PASS getComputedStyle(frame, 0).width is '400px'
+PASS getComputedStyle(frame, 0).height is '400px'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+           

Added: trunk/LayoutTests/fast/frames/flattening/iframe-tiny.html (0 => 117451)


--- trunk/LayoutTests/fast/frames/flattening/iframe-tiny.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/flattening/iframe-tiny.html	2012-05-17 15:42:17 UTC (rev 117451)
@@ -0,0 +1,126 @@
+<html>
+<head>
+<script>window.jsTestIsAsync = true;</script>
+<script src=""
+<script>
+description("Test that frame flattening is not used for tiny frames. This test requires DRT or user agent with flattening enabled.");
+
+if (window.layoutTestController)
+    layoutTestController.setFrameFlatteningEnabled(true);
+
+function checkResult(frameName, expectedWidth, expectedHeight)
+{
+    frame = document.getElementById(frameName);
+    debug(frameName);
+    shouldBe("getComputedStyle(frame, 0).width", expectedWidth);
+    shouldBe("getComputedStyle(frame, 0).height", expectedHeight);
+}
+
+function test()
+{
+    setTimeout(function() {
+        checkResult("testFrame0", "'0px'", "'0px'");
+        checkResult("testFrame1", "'1px'", "'1px'");
+        checkResult("testFrame2", "'7px'", "'7px'");
+        checkResult("testFrame3", "'400px'", "'400px'");
+        checkResult("testFrame4", "'0px'", "'100px'");
+        checkResult("testFrame5", "'100px'", "'0px'");
+        checkResult("testFrame6", "'100px'", "'2px'");
+        checkResult("testFrame7", "'2px'", "'100px'");
+        checkResult("testFrame8", "'2px'", "'150px'");
+        checkResult("testFrame9", "'300px'", "'2px'");
+        checkResult("testFrame10", "'400px'", "'400px'");
+        checkResult("testFrame11", "'400px'", "'400px'");
+        finishJSTest();
+    }, 0);
+}
+</script>
+</head>
+<body _onload_="test()">
+<iframe id="testFrame0" width="0px" height="0px" style="border-width:0px" scrolling=auto src=""
+    <style>body { background-color: red; }</style>
+    <body>
+    <div style='position: absolute; width: 400px; height: 400px; left: 0; top: 0px;'></div>
+    </body>
+    ">
+</iframe>
+<iframe id="testFrame1" width="1px" height="1px" style="border-width:0px" scrolling=auto src=""
+    <style>body { background-color: red; }</style>
+    <body>
+        <div style='position: absolute; width: 400px; height: 400px; left: 0; top: 0px;'></div>
+    </body>
+    ">
+</iframe>
+<iframe id="testFrame2" width="7px" height="7px" style="border-width:0px" scrolling=auto src=""
+    <style>body { background-color: red; }</style>
+    <body>
+        <div style='position: absolute; width: 400px; height: 400px; left: 0; top: 0px;'></div>
+    </body>
+    ">
+</iframe>
+<iframe id="testFrame3" width="8px" height="8px" style="border-width:0px" scrolling=auto src=""
+    <style>body { background-color: red; }</style>
+    <body>
+    <div style='position: absolute; width: 400px; height: 400px; left: 0; top: 0px;'></div>
+    </body>
+    ">
+</iframe>
+<iframe id="testFrame4" width="0px" height="100px" style="border-width:0px" scrolling=auto src=""
+    <style>body { background-color: red; }</style>
+    <body>
+    <div style='position: absolute; width: 400px; height: 400px; left: 0; top: 0px;'></div>
+    </body>
+    ">
+</iframe>
+<iframe id="testFrame5" width="100px" height="0px" style="border-width:0px" scrolling=auto src=""
+    <style>body { background-color: red; }</style>
+    <body>
+    <div style='position: absolute; width: 400px; height: 400px; left: 0; top: 0px;'></div>
+    </body>
+    ">
+</iframe>
+<iframe id="testFrame6" width="100px" height="2px" style="border-width:0px" scrolling=auto src=""
+    <style>body { background-color: red; }</style>
+    <body>
+    <div style='position: absolute; width: 400px; height: 400px; left: 0; top: 0px;'></div>
+    </body>
+    ">
+</iframe>
+<iframe id="testFrame7" width="2px" height="100px" style="border-width:0px" scrolling=auto src=""
+    <style>body { background-color: red; }</style>
+    <body>
+    <div style='position: absolute; width: 400px; height: 400px; left: 0; top: 0px;'></div>
+    </body>
+    ">
+</iframe>
+<iframe id="testFrame8" width="2px" scrolling=auto style="border-width:0px" src=""
+    <style>body { background-color: red; }</style>
+    <body>
+    <div style='position: absolute; width: 400px; height: 400px; left: 0; top: 0px;'></div>
+    </body>
+    ">
+</iframe>
+<iframe id="testFrame9" height="2px" scrolling=auto style="border-width:0px" src=""
+    <style>body { background-color: red; }</style>
+    <body>
+    <div style='position: absolute; width: 400px; height: 400px; left: 0; top: 0px;'></div>
+    </body>
+    ">
+</iframe>
+<iframe id="testFrame10" width="8px" scrolling=auto style="border-width:0px" src=""
+    <style>body { background-color: red; }</style>
+    <body>
+    <div style='position: absolute; width: 400px; height: 400px; left: 0; top: 0px;'></div>
+    </body>
+    ">
+</iframe>
+<iframe id="testFrame11" height="8px" scrolling=auto style="border-width:0px" src=""
+    <style>body { background-color: red; }</style>
+    <body>
+    <div style='position: absolute; width: 400px; height: 400px; left: 0; top: 0px;'></div>
+    </body>
+    ">
+</iframe>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (117450 => 117451)


--- trunk/Source/WebCore/ChangeLog	2012-05-17 15:21:08 UTC (rev 117450)
+++ trunk/Source/WebCore/ChangeLog	2012-05-17 15:42:17 UTC (rev 117451)
@@ -1,3 +1,23 @@
+2012-05-17  Antti Koivisto  <an...@apple.com>
+
+        Frame flattening should not expand tiny frames
+        https://bugs.webkit.org/show_bug.cgi?id=86736
+
+        Reviewed by Kenneth Rohde Christiansen.
+        
+        If a frame has so small fixed size that it is not usefully scrollable on desktop it is probably
+        not meant to be scrolled. Displaying any otherwise invisible content by expanding the frame
+        may end up looking like a rendering error.
+
+        The patch prevents expansion of frames that have fixed width or height less than 8px.
+
+        Test: fast/frames/flattening/iframe-tiny.html
+
+        * rendering/RenderFrameBase.cpp:
+        (WebCore::shouldExpandFrame):
+        (WebCore):
+        (WebCore::RenderFrameBase::layoutWithFlattening):
+
 2012-05-17  Yury Semikhatsky  <yu...@chromium.org>
 
         [Chromium] Web Inspector: assertion failure when inspecting a shared worker in debug mode

Modified: trunk/Source/WebCore/rendering/RenderFrameBase.cpp (117450 => 117451)


--- trunk/Source/WebCore/rendering/RenderFrameBase.cpp	2012-05-17 15:21:08 UTC (rev 117450)
+++ trunk/Source/WebCore/rendering/RenderFrameBase.cpp	2012-05-17 15:42:17 UTC (rev 117451)
@@ -38,13 +38,26 @@
 {
 }
 
-void RenderFrameBase::layoutWithFlattening(bool fixedWidth, bool fixedHeight)
+inline bool shouldExpandFrame(LayoutUnit width, LayoutUnit height, bool hasFixedWidth, bool hasFixedHeight)
 {
+    // If the size computed to zero never expand.
+    if (!width || !height)
+        return false;
+    // Really small fixed size frames can't be meant to be scrolled and are there probably by mistake. Avoid expanding.
+    static unsigned smallestUsefullyScrollableDimension = 8;
+    if (hasFixedWidth && width < LayoutUnit(smallestUsefullyScrollableDimension))
+        return false;
+    if (hasFixedHeight && height < LayoutUnit(smallestUsefullyScrollableDimension))
+        return false;
+    return true;
+}
+
+void RenderFrameBase::layoutWithFlattening(bool hasFixedWidth, bool hasFixedHeight)
+{
     FrameView* childFrameView = static_cast<FrameView*>(widget());
     RenderView* childRoot = childFrameView ? static_cast<RenderView*>(childFrameView->frame()->contentRenderer()) : 0;
 
-    // Do not expand frames which has zero width or height
-    if (!width() || !height() || !childRoot) {
+    if (!childRoot || !shouldExpandFrame(width(), height(), hasFixedWidth, hasFixedHeight)) {
         updateWidgetPosition();
         if (childFrameView)
             childFrameView->layout();
@@ -69,7 +82,7 @@
     int vBorder = borderTop() + borderBottom();
 
     // make sure minimum preferred width is enforced
-    if (isScrollable || !fixedWidth) {
+    if (isScrollable || !hasFixedWidth) {
         setWidth(max(width(), childRoot->minPreferredLogicalWidth() + hBorder));
         // update again to pass the new width to the child frame
         updateWidgetPosition();
@@ -77,9 +90,9 @@
     }
 
     // expand the frame by setting frame height = content height
-    if (isScrollable || !fixedHeight || childRoot->isFrameSet())
+    if (isScrollable || !hasFixedHeight || childRoot->isFrameSet())
         setHeight(max<LayoutUnit>(height(), childFrameView->contentsHeight() + vBorder));
-    if (isScrollable || !fixedWidth || childRoot->isFrameSet())
+    if (isScrollable || !hasFixedWidth || childRoot->isFrameSet())
         setWidth(max<LayoutUnit>(width(), childFrameView->contentsWidth() + hBorder));
 
     updateWidgetPosition();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to