Title: [118291] trunk
Revision
118291
Author
[email protected]
Date
2012-05-23 18:07:22 -0700 (Wed, 23 May 2012)

Log Message

Add seamless layout code (and pass most of the remaining seamless tests)
https://bugs.webkit.org/show_bug.cgi?id=86608

Reviewed by Ojan Vafai.

Source/WebCore:

This patch contains almost all the layout changes needed for seamless iframes.
I removed the scroll-bar avoiding code at the last moment, as it didn't
work for platforms other than mac-lion.  I'll add that, as well as the
HTMLIFrameElement.seamless idl attribute in a follow-up patch.

Seamless iframes piggy-back a bit on the existing frame-flattening
logic, however seamless is different from frame-flattening in a few ways:
- Frame flattening can only ever make an iframe larger (seamless just behaves like a normal div).
- Frame flattening disables scrollbars (seamless frames behave like normal overflow: auto divs).
- Seamless only has to work with iframes (flattening works with frame/frameset as well).
- Seamless support shrink-wrap size negotiation when the iframe is inline.

Test: fast/frames/seamless/seamless-percent-height.html

* css/StyleResolver.cpp:
(WebCore::StyleResolver::adjustRenderStyle): map inline -> inline-block for seamless iframes.
* dom/Document.cpp:
(WebCore::Document::scheduleStyleRecalc):
 - Seamless iframes don't manage their own style recalc.
(WebCore::Document::recalcStyle):
 - We should make sure our parent is resolved before we are, but currently that causes some tests to crash
   I don't have a test to demonstrate this need yet, as presumably it's fulfilled through other codepaths atm.
* page/FrameView.cpp:
(WebCore::FrameView::scheduleRelayout): Do the cheaper check first.
(WebCore::FrameView::isInChildFrameWithFrameFlattening): Make frameview layout abort child layouts like how frame flattening does.
* rendering/RenderBox.h:
(WebCore::RenderBox::stretchesToViewport): Disable the stretch-to-viewport quirk for seamless iframes (it makes no sense and breaks the layout code).
* rendering/RenderIFrame.cpp:
(WebCore::RenderIFrame::computeLogicalHeight):
 - This function is needed for the child document to participate in the normal block shrink-wrap algorithm.
   Thankfully all the shrink-wrap logic is in RenderBox instead of RenderBlock. In the future we may make
   RenderIframe a RenderBlock for the seamless case. We may just split RenderIframe into two renderers.
(WebCore::RenderIFrame::computeLogicalWidth):
(WebCore::RenderIFrame::shouldComputeSizeAsReplaced):
 - seamless iframes behave like blocks, not inline replaced elements.
(WebCore):
(WebCore::RenderIFrame::isInlineBlockOrInlineTable):
 - Behave like an inline-block when marked inline.
(WebCore::RenderIFrame::minPreferredLogicalWidth):
 - When asked for our pref widths, return those of our child document.
(WebCore::RenderIFrame::maxPreferredLogicalWidth):
(WebCore::RenderIFrame::isSeamless): helper function
(WebCore::RenderIFrame::contentRootRenderer): helper function
(WebCore::RenderIFrame::flattenFrame): seamless iframes never use the frame-flattening feature.
(WebCore::RenderIFrame::layoutSeamlessly): The guts of seamless layout.
(WebCore::RenderIFrame::layout):
* rendering/RenderIFrame.h:
(WebCore):
(RenderIFrame):

LayoutTests:

Add a test for percent height in child documents, as well as
disabling the expand-to-fill-viewport quirk of html/body elements
in quirks mode.
Also update all the expectations now that we pass almost all the tests.

* fast/frames/seamless/resources/percent-square.html: Added.
* fast/frames/seamless/resources/two-inline-blocks.html:
* fast/frames/seamless/seamless-basic-expected.txt:
* fast/frames/seamless/seamless-float-expected.txt:
* fast/frames/seamless/seamless-inherited-origin-expected.txt:
* fast/frames/seamless/seamless-inherited-origin.html:
* fast/frames/seamless/seamless-inline-expected.txt:
* fast/frames/seamless/seamless-nested-expected.txt:
* fast/frames/seamless/seamless-percent-height-expected.txt: Added.
* fast/frames/seamless/seamless-percent-height.html: Added.
* fast/frames/seamless/seamless-quirks-expected.txt:
* fast/frames/seamless/seamless-sandbox-flag-expected.txt:
* fast/frames/seamless/seamless-sandbox-srcdoc-expected.txt:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (118290 => 118291)


--- trunk/LayoutTests/ChangeLog	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/ChangeLog	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1,3 +1,29 @@
+2012-05-23  Eric Seidel  <[email protected]>
+
+        Add seamless layout code (and pass most of the remaining seamless tests)
+        https://bugs.webkit.org/show_bug.cgi?id=86608
+
+        Reviewed by Ojan Vafai.
+
+        Add a test for percent height in child documents, as well as
+        disabling the expand-to-fill-viewport quirk of html/body elements
+        in quirks mode.
+        Also update all the expectations now that we pass almost all the tests.
+
+        * fast/frames/seamless/resources/percent-square.html: Added.
+        * fast/frames/seamless/resources/two-inline-blocks.html:
+        * fast/frames/seamless/seamless-basic-expected.txt:
+        * fast/frames/seamless/seamless-float-expected.txt:
+        * fast/frames/seamless/seamless-inherited-origin-expected.txt:
+        * fast/frames/seamless/seamless-inherited-origin.html:
+        * fast/frames/seamless/seamless-inline-expected.txt:
+        * fast/frames/seamless/seamless-nested-expected.txt:
+        * fast/frames/seamless/seamless-percent-height-expected.txt: Added.
+        * fast/frames/seamless/seamless-percent-height.html: Added.
+        * fast/frames/seamless/seamless-quirks-expected.txt:
+        * fast/frames/seamless/seamless-sandbox-flag-expected.txt:
+        * fast/frames/seamless/seamless-sandbox-srcdoc-expected.txt:
+
 2012-05-23  Tony Chang  <[email protected]>
 
         auto margins on flexbox should allocate space in the cross direction

Added: trunk/LayoutTests/fast/frames/seamless/resources/percent-square.html (0 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/resources/percent-square.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/seamless/resources/percent-square.html	2012-05-24 01:07:22 UTC (rev 118291)
@@ -0,0 +1,2 @@
+<!-- This is intentionally quirks mode. -->
+<html style="width: 100%; height: 100%"></html>

Modified: trunk/LayoutTests/fast/frames/seamless/resources/two-inline-blocks.html (118290 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/resources/two-inline-blocks.html	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/fast/frames/seamless/resources/two-inline-blocks.html	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1,5 +1,8 @@
 <!DOCTYPE html>
 <html><head><style>
 body { margin: 0px; line-height: 0px; }
+/* FIXME: This vertical-align should not be needed, but without it the contentHeight()
+of the document is reported as 4px too large, likely due to implied line decent? */
+div { vertical-align: top; }
 </style></head>
 <body><div style="background-color: orange; display: inline-block; width: 100px; height: 50px;"></div><div style="background-color: blue; display: inline-block; width: 50px; height: 50px;"></div></body></html>

Modified: trunk/LayoutTests/fast/frames/seamless/seamless-basic-expected.txt (118290 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/seamless-basic-expected.txt	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-basic-expected.txt	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1,8 +1,8 @@
 Test basic seamless auto-sizing-to-content functionality.
 FAIL iframe.seamless should be true (of type boolean). Was undefined (of type undefined).
 PASS window.getComputedStyle(iframe).display is "block"
-FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
-FAIL window.getComputedStyle(iframe).height should be 100px. Was 150px.
-FAIL window.getComputedStyle(iframe).height should be 200px. Was 150px.
-FAIL window.getComputedStyle(iframe).width should be 100px. Was 300px.
+PASS window.getComputedStyle(iframe).width is "200px"
+PASS window.getComputedStyle(iframe).height is "100px"
+PASS window.getComputedStyle(iframe).height is "200px"
+PASS window.getComputedStyle(iframe).width is "100px"
 

Modified: trunk/LayoutTests/fast/frames/seamless/seamless-float-expected.txt (118290 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/seamless-float-expected.txt	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-float-expected.txt	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1,7 +1,7 @@
 Test that floated seamless iframes 'shrink-wrap' their contents, as floated divs would.
-FAIL window.getComputedStyle(iframe1).width should be 150px. Was 300px.
-FAIL window.getComputedStyle(iframe1).height should be 50px. Was 150px.
-FAIL window.getComputedStyle(iframe2).width should be 100px. Was 300px.
-FAIL window.getComputedStyle(iframe2).height should be 100px. Was 150px.
+PASS window.getComputedStyle(iframe1).width is "150px"
+FAIL window.getComputedStyle(iframe1).height should be 50px. Was 100px.
+PASS window.getComputedStyle(iframe2).width is "100px"
+PASS window.getComputedStyle(iframe2).height is "100px"
 
 

Modified: trunk/LayoutTests/fast/frames/seamless/seamless-inherited-origin-expected.txt (118290 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/seamless-inherited-origin-expected.txt	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-inherited-origin-expected.txt	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1,7 +1,7 @@
 Test that frames with inherited security origins can still be seamless.
 FAIL iframe.seamless should be true (of type boolean). Was undefined (of type undefined).
-FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
-FAIL window.getComputedStyle(iframe).height should be 0px. Was 150px.
-FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
-FAIL window.getComputedStyle(iframe).height should be 100px. Was 150px.
+PASS window.getComputedStyle(iframe).width is "200px"
+PASS window.getComputedStyle(iframe).height is "8px"
+PASS window.getComputedStyle(iframe).width is "200px"
+PASS window.getComputedStyle(iframe).height is "100px"
 

Modified: trunk/LayoutTests/fast/frames/seamless/seamless-inherited-origin.html (118290 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/seamless-inherited-origin.html	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-inherited-origin.html	2012-05-24 01:07:22 UTC (rev 118291)
@@ -9,9 +9,10 @@
     window.iframe = document.getElementById("iframe");
     shouldBeTrue("iframe.seamless");
 
-    // Initially about:blank should have 0 height.
     shouldBeEqualToString("window.getComputedStyle(iframe).width", "200px");
-    shouldBeEqualToString("window.getComputedStyle(iframe).height", "0px");
+    // Initially about:blank has no content, thus no height, except the body
+    // element defaults to margin: 8px (which gets collapsed to 8px when rendered).
+    shouldBeEqualToString("window.getComputedStyle(iframe).height", "8px");
 
     // Replace the empty document with a 100x100px square to test if it displays seamlessly.
     window.iframe.contentDocument.write("<!DOCTYPE html><html style='width: 100px; height: 100px; background-color: green'></html>");

Modified: trunk/LayoutTests/fast/frames/seamless/seamless-inline-expected.txt (118290 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/seamless-inline-expected.txt	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-inline-expected.txt	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1,11 +1,11 @@
 Test that inline seamless iframes 'shrink-wrap' their contents like inline-blocks do.
-FAIL window.getComputedStyle(iframe1).display should be inline-block. Was inline.
-FAIL window.getComputedStyle(iframe2).display should be inline-block. Was inline.
-FAIL window.getComputedStyle(iframe1).width should be 150px. Was 300px.
-FAIL window.getComputedStyle(iframe1).height should be 50px. Was 150px.
-FAIL window.getComputedStyle(parent1).height should be 50px. Was 200px.
-FAIL window.getComputedStyle(iframe2).width should be 100px. Was 300px.
-FAIL window.getComputedStyle(iframe2).height should be 100px. Was 150px.
-FAIL window.getComputedStyle(parent2).height should be 150px. Was 200px.
+PASS window.getComputedStyle(iframe1).display is "inline-block"
+PASS window.getComputedStyle(iframe2).display is "inline-block"
+PASS window.getComputedStyle(iframe1).width is "150px"
+FAIL window.getComputedStyle(iframe1).height should be 50px. Was 100px.
+FAIL window.getComputedStyle(parent1).height should be 50px. Was 100px.
+PASS window.getComputedStyle(iframe2).width is "100px"
+PASS window.getComputedStyle(iframe2).height is "100px"
+PASS window.getComputedStyle(parent2).height is "150px"
 
 

Modified: trunk/LayoutTests/fast/frames/seamless/seamless-nested-expected.txt (118290 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/seamless-nested-expected.txt	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-nested-expected.txt	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1,6 +1,6 @@
 Test that nested seamless iframes size correctly.
 FAIL iframe.seamless should be true (of type boolean). Was undefined (of type undefined).
 FAIL nestedFrame.seamless should be true (of type boolean). Was undefined (of type undefined).
-FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
-FAIL window.getComputedStyle(iframe).height should be 100px. Was 150px.
+PASS window.getComputedStyle(iframe).width is "200px"
+PASS window.getComputedStyle(iframe).height is "100px"
 

Added: trunk/LayoutTests/fast/frames/seamless/seamless-percent-height-expected.txt (0 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/seamless-percent-height-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-percent-height-expected.txt	2012-05-24 01:07:22 UTC (rev 118291)
@@ -0,0 +1,4 @@
+Test that the 'initial containing block height' is 0 for seamless child documents.
+PASS window.getComputedStyle(iframe).width is "200px"
+PASS window.getComputedStyle(iframe).height is "0px"
+

Added: trunk/LayoutTests/fast/frames/seamless/seamless-percent-height.html (0 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/seamless-percent-height.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-percent-height.html	2012-05-24 01:07:22 UTC (rev 118291)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<script src=""
+<div id="parent" style="width: 200px; height: 200px;">
+<iframe id="iframe" seamless src=""
+</div>
+<script>
+debug("Test that the 'initial containing block height' is 0 for seamless child documents.")
+window._onload_ = function () {
+    window.iframe = document.getElementById("iframe");
+
+    // Width 100% still works as expected.
+    shouldBeEqualToString("window.getComputedStyle(iframe).width", "200px");
+
+    // But height: 100% should be 0, per the spec:
+    // In visual media, in a CSS-supporting user agent: the user agent must force the
+    // height of the initial containing block of the active document of the nested
+    // browsing context of the iframe to zero.
+    shouldBeEqualToString("window.getComputedStyle(iframe).height", "0px");
+}
+</script>

Modified: trunk/LayoutTests/fast/frames/seamless/seamless-quirks-expected.txt (118290 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/seamless-quirks-expected.txt	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-quirks-expected.txt	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1,6 +1,6 @@
 Test that a quirks-mode document inside a seamless iframe sizes correctly.
 FAIL iframe.seamless should be true (of type boolean). Was undefined (of type undefined).
 PASS iframe.contentDocument.compatMode is "BackCompat"
-FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
-FAIL window.getComputedStyle(iframe).height should be 100px. Was 150px.
+PASS window.getComputedStyle(iframe).width is "200px"
+PASS window.getComputedStyle(iframe).height is "100px"
 

Modified: trunk/LayoutTests/fast/frames/seamless/seamless-sandbox-flag-expected.txt (118290 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/seamless-sandbox-flag-expected.txt	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-sandbox-flag-expected.txt	2012-05-24 01:07:22 UTC (rev 118291)
@@ -4,6 +4,6 @@
 PASS window.getComputedStyle(iframe).display is "block"
 PASS window.getComputedStyle(iframe).borderWidth is "0px"
 PASS window.getComputedStyle(iframe).borderStyle is "none"
-FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
+PASS window.getComputedStyle(iframe).width is "200px"
 PASS window.getComputedStyle(iframe).height is "150px"
 

Modified: trunk/LayoutTests/fast/frames/seamless/seamless-sandbox-srcdoc-expected.txt (118290 => 118291)


--- trunk/LayoutTests/fast/frames/seamless/seamless-sandbox-srcdoc-expected.txt	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-sandbox-srcdoc-expected.txt	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1,5 +1,5 @@
 Test that iframes with srcdoc contents can still be seamless.
 FAIL iframe.seamless should be true (of type boolean). Was undefined (of type undefined).
-FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
-FAIL window.getComputedStyle(iframe).height should be 100px. Was 150px.
+PASS window.getComputedStyle(iframe).width is "200px"
+PASS window.getComputedStyle(iframe).height is "100px"
 

Modified: trunk/LayoutTests/http/tests/security/seamless/seamless-cross-origin-expected.txt (118290 => 118291)


--- trunk/LayoutTests/http/tests/security/seamless/seamless-cross-origin-expected.txt	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/http/tests/security/seamless/seamless-cross-origin-expected.txt	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1,7 +1,7 @@
 FAIL iframe1.seamless should be true (of type boolean). Was undefined (of type undefined).
 FAIL iframe2.seamless should be true (of type boolean). Was undefined (of type undefined).
-FAIL window.getComputedStyle(iframe1).width should be 200px. Was 300px.
-FAIL window.getComputedStyle(iframe1).height should be 100px. Was 150px.
+PASS window.getComputedStyle(iframe1).width is "200px"
+PASS window.getComputedStyle(iframe1).height is "100px"
 PASS window.getComputedStyle(iframe2).width is "300px"
 PASS window.getComputedStyle(iframe2).height is "150px"
 

Modified: trunk/LayoutTests/http/tests/security/seamless/seamless-sandbox-srcdoc-expected.txt (118290 => 118291)


--- trunk/LayoutTests/http/tests/security/seamless/seamless-sandbox-srcdoc-expected.txt	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/LayoutTests/http/tests/security/seamless/seamless-sandbox-srcdoc-expected.txt	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1,4 +1,4 @@
 FAIL iframe.seamless should be true (of type boolean). Was undefined (of type undefined).
-FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
-FAIL window.getComputedStyle(iframe).height should be 100px. Was 150px.
+PASS window.getComputedStyle(iframe).width is "200px"
+PASS window.getComputedStyle(iframe).height is "100px"
 

Modified: trunk/Source/WebCore/ChangeLog (118290 => 118291)


--- trunk/Source/WebCore/ChangeLog	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/Source/WebCore/ChangeLog	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1,3 +1,60 @@
+2012-05-23  Eric Seidel  <[email protected]>
+
+        Add seamless layout code (and pass most of the remaining seamless tests)
+        https://bugs.webkit.org/show_bug.cgi?id=86608
+
+        Reviewed by Ojan Vafai.
+
+        This patch contains almost all the layout changes needed for seamless iframes.
+        I removed the scroll-bar avoiding code at the last moment, as it didn't
+        work for platforms other than mac-lion.  I'll add that, as well as the
+        HTMLIFrameElement.seamless idl attribute in a follow-up patch.
+
+        Seamless iframes piggy-back a bit on the existing frame-flattening
+        logic, however seamless is different from frame-flattening in a few ways:
+        - Frame flattening can only ever make an iframe larger (seamless just behaves like a normal div).
+        - Frame flattening disables scrollbars (seamless frames behave like normal overflow: auto divs).
+        - Seamless only has to work with iframes (flattening works with frame/frameset as well).
+        - Seamless support shrink-wrap size negotiation when the iframe is inline.
+
+        Test: fast/frames/seamless/seamless-percent-height.html
+
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::adjustRenderStyle): map inline -> inline-block for seamless iframes.
+        * dom/Document.cpp:
+        (WebCore::Document::scheduleStyleRecalc):
+         - Seamless iframes don't manage their own style recalc.
+        (WebCore::Document::recalcStyle):
+         - We should make sure our parent is resolved before we are, but currently that causes some tests to crash
+           I don't have a test to demonstrate this need yet, as presumably it's fulfilled through other codepaths atm.
+        * page/FrameView.cpp:
+        (WebCore::FrameView::scheduleRelayout): Do the cheaper check first.
+        (WebCore::FrameView::isInChildFrameWithFrameFlattening): Make frameview layout abort child layouts like how frame flattening does.
+        * rendering/RenderBox.h:
+        (WebCore::RenderBox::stretchesToViewport): Disable the stretch-to-viewport quirk for seamless iframes (it makes no sense and breaks the layout code).
+        * rendering/RenderIFrame.cpp:
+        (WebCore::RenderIFrame::computeLogicalHeight):
+         - This function is needed for the child document to participate in the normal block shrink-wrap algorithm.
+           Thankfully all the shrink-wrap logic is in RenderBox instead of RenderBlock. In the future we may make
+           RenderIframe a RenderBlock for the seamless case. We may just split RenderIframe into two renderers.
+        (WebCore::RenderIFrame::computeLogicalWidth):
+        (WebCore::RenderIFrame::shouldComputeSizeAsReplaced):
+         - seamless iframes behave like blocks, not inline replaced elements.
+        (WebCore):
+        (WebCore::RenderIFrame::isInlineBlockOrInlineTable):
+         - Behave like an inline-block when marked inline.
+        (WebCore::RenderIFrame::minPreferredLogicalWidth):
+         - When asked for our pref widths, return those of our child document.
+        (WebCore::RenderIFrame::maxPreferredLogicalWidth):
+        (WebCore::RenderIFrame::isSeamless): helper function
+        (WebCore::RenderIFrame::contentRootRenderer): helper function
+        (WebCore::RenderIFrame::flattenFrame): seamless iframes never use the frame-flattening feature.
+        (WebCore::RenderIFrame::layoutSeamlessly): The guts of seamless layout.
+        (WebCore::RenderIFrame::layout):
+        * rendering/RenderIFrame.h:
+        (WebCore):
+        (RenderIFrame):
+
 2012-05-23  Rafael Brandao  <[email protected]>
 
         [Qt] GraphicsContext should avoid converting rotation angle to degrees

Modified: trunk/Source/WebCore/css/StyleResolver.cpp (118290 => 118291)


--- trunk/Source/WebCore/css/StyleResolver.cpp	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/Source/WebCore/css/StyleResolver.cpp	2012-05-24 01:07:22 UTC (rev 118291)
@@ -2128,6 +2128,10 @@
         || style->hasFilter()))
         style->setTransformStyle3D(TransformStyle3DFlat);
 
+    // Seamless iframes behave like blocks. Map their display to inline-block when marked inline.
+    if (e && e->hasTagName(iframeTag) && style->display() == INLINE && static_cast<HTMLIFrameElement*>(e)->shouldDisplaySeamlessly())
+        style->setDisplay(INLINE_BLOCK);
+
 #if ENABLE(SVG)
     if (e && e->isSVGElement()) {
         // Spec: http://www.w3.org/TR/SVG/masking.html#OverflowProperty

Modified: trunk/Source/WebCore/dom/Document.cpp (118290 => 118291)


--- trunk/Source/WebCore/dom/Document.cpp	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/Source/WebCore/dom/Document.cpp	2012-05-24 01:07:22 UTC (rev 118291)
@@ -1660,8 +1660,12 @@
 
 void Document::scheduleStyleRecalc()
 {
-    // FIXME: In the seamless case, we should likely schedule a style recalc
-    // on our parent and instead return early here.
+    if (shouldDisplaySeamlesslyWithParent()) {
+        // When we're seamless, our parent document manages our style recalcs.
+        ownerElement()->setNeedsStyleRecalc();
+        ownerElement()->document()->scheduleStyleRecalc();
+        return;
+    }
 
     if (m_styleRecalcTimer.isActive() || inPageCache())
         return;
@@ -1717,8 +1721,12 @@
     if (m_inStyleRecalc)
         return; // Guard against re-entrancy. -dwh
 
-    // FIXME: In the seamless case, we may wish to exit early in the child after recalcing our parent chain.
-    // I have not yet found a test which requires such.
+    // FIXME: We should update style on our ancestor chain before proceeding (especially for seamless),
+    // however doing so currently causes several tests to crash, as Frame::setDocument calls Document::attach
+    // before setting the DOMWindow on the Frame, or the SecurityOrigin on the document. The attach, in turn
+    // resolves style (here) and then when we resolve style on the parent chain, we may end up
+    // re-attaching our containing iframe, which when asked HTMLFrameElementBase::isURLAllowed
+    // hits a null-dereference due to security code always assuming the document has a SecurityOrigin.
 
     if (m_hasDirtyStyleResolver)
         updateActiveStylesheets(RecalcStyleImmediately);

Modified: trunk/Source/WebCore/page/FrameView.cpp (118290 => 118291)


--- trunk/Source/WebCore/page/FrameView.cpp	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/Source/WebCore/page/FrameView.cpp	2012-05-24 01:07:22 UTC (rev 118291)
@@ -2041,7 +2041,7 @@
 
     // When frame flattening is enabled, the contents of the frame could affect the layout of the parent frames.
     // Also invalidate parent frame starting from the owner element of this frame.
-    if (isInChildFrameWithFrameFlattening() && m_frame->ownerRenderer())
+    if (m_frame->ownerRenderer() && isInChildFrameWithFrameFlattening())
         m_frame->ownerRenderer()->setNeedsLayout(true, MarkContainingBlockChain);
 
     int delay = m_frame->document()->minimumLayoutDelay();
@@ -2918,18 +2918,21 @@
 
 bool FrameView::isInChildFrameWithFrameFlattening()
 {
-    if (!parent() || !m_frame->ownerElement() || !m_frame->settings() || !m_frame->settings()->frameFlatteningEnabled())
+    if (!parent() || !m_frame->ownerElement())
         return false;
 
     // Frame flattening applies when the owner element is either in a frameset or
     // an iframe with flattening parameters.
     if (m_frame->ownerElement()->hasTagName(iframeTag)) {
         RenderIFrame* iframeRenderer = toRenderIFrame(m_frame->ownerElement()->renderPart());
-
-        if (iframeRenderer->flattenFrame())
+        if (iframeRenderer->flattenFrame() || iframeRenderer->isSeamless())
             return true;
+    }
 
-    } else if (m_frame->ownerElement()->hasTagName(frameTag))
+    if (!m_frame->settings() || !m_frame->settings()->frameFlatteningEnabled())
+        return false;
+
+    if (m_frame->ownerElement()->hasTagName(frameTag))
         return true;
 
     return false;

Modified: trunk/Source/WebCore/rendering/RenderBox.h (118290 => 118291)


--- trunk/Source/WebCore/rendering/RenderBox.h	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/Source/WebCore/rendering/RenderBox.h	2012-05-24 01:07:22 UTC (rev 118291)
@@ -326,7 +326,7 @@
 
     bool stretchesToViewport() const
     {
-        return document()->inQuirksMode() && style()->logicalHeight().isAuto() && !isFloatingOrPositioned() && (isRoot() || isBody());
+        return document()->inQuirksMode() && style()->logicalHeight().isAuto() && !isFloatingOrPositioned() && (isRoot() || isBody()) && !document()->shouldDisplaySeamlesslyWithParent();
     }
 
     virtual IntSize intrinsicSize() const { return IntSize(); }

Modified: trunk/Source/WebCore/rendering/RenderIFrame.cpp (118290 => 118291)


--- trunk/Source/WebCore/rendering/RenderIFrame.cpp	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/Source/WebCore/rendering/RenderIFrame.cpp	2012-05-24 01:07:22 UTC (rev 118291)
@@ -63,6 +63,10 @@
 
 void RenderIFrame::computeLogicalWidth()
 {
+    // When we're seamless, we behave like a block. Thankfully RenderBox has all the right logic for this.
+    if (isSeamless())
+        return RenderBox::computeLogicalWidth();
+
     RenderPart::computeLogicalWidth();
     if (!flattenFrame())
         return;
@@ -79,14 +83,65 @@
     }
 }
 
-bool RenderIFrame::flattenFrame()
+bool RenderIFrame::shouldComputeSizeAsReplaced() const
 {
+    // When we're seamless, we use normal block/box sizing code except when inline.
+    return !isSeamless();
+}
+
+bool RenderIFrame::isInlineBlockOrInlineTable() const
+{
+    return isSeamless() && isInline();
+}
+
+LayoutUnit RenderIFrame::minPreferredLogicalWidth() const
+{
+    if (!isSeamless())
+        return RenderFrameBase::minPreferredLogicalWidth();
+
+    RenderView* childRoot = contentRootRenderer();
+    if (!childRoot)
+        return 0;
+
+    return childRoot->minPreferredLogicalWidth();
+}
+
+LayoutUnit RenderIFrame::maxPreferredLogicalWidth() const
+{
+    if (!isSeamless())
+        return RenderFrameBase::maxPreferredLogicalWidth();
+
+    RenderView* childRoot = contentRootRenderer();
+    if (!childRoot)
+        return 0;
+
+    return childRoot->maxPreferredLogicalWidth();
+}
+
+bool RenderIFrame::isSeamless() const
+{
+    return node() && node()->hasTagName(iframeTag) && static_cast<HTMLIFrameElement*>(node())->shouldDisplaySeamlessly();
+}
+
+RenderView* RenderIFrame::contentRootRenderer() const
+{
+    // FIXME: Is this always a valid cast? What about plugins?
+    ASSERT(!widget() || widget()->isFrameView());
+    FrameView* childFrameView = static_cast<FrameView*>(widget());
+    return childFrameView ? static_cast<RenderView*>(childFrameView->frame()->contentRenderer()) : 0;
+}
+
+bool RenderIFrame::flattenFrame() const
+{
     if (!node() || !node()->hasTagName(iframeTag))
         return false;
 
     HTMLIFrameElement* element = static_cast<HTMLIFrameElement*>(node());
     Frame* frame = element->document()->frame();
 
+    if (isSeamless())
+        return false; // Seamless iframes are already "flat", don't try to flatten them.
+
     bool enabled = frame && frame->settings() && frame->settings()->frameFlatteningEnabled();
 
     if (!enabled || !frame->page())
@@ -105,20 +160,50 @@
     return boundingRect.maxX() > 0 && boundingRect.maxY() > 0;
 }
 
+void RenderIFrame::layoutSeamlessly()
+{
+    computeLogicalWidth();
+    // FIXME: Containers set their height to 0 before laying out their kids (as we're doing here)
+    // however, this causes FrameView::layout() to add vertical scrollbars, incorrectly inflating
+    // the resulting contentHeight(). We'll need to make FrameView::layout() smarter.
+    setLogicalHeight(0);
+    updateWidgetPosition(); // Tell the Widget about our new width/height (it will also layout the child document).
+
+    // Laying out our kids is normally responsible for adjusting our height, so we set it here.
+    // Replaced elements do not respect padding, so we just add border to the child's height.
+    // FIXME: It's possible that seamless iframes (since they act like divs) *should* respect padding.
+    FrameView* childFrameView = static_cast<FrameView*>(widget());
+    if (childFrameView) // Widget should never be null during layout(), but just in case.
+        setLogicalHeight(childFrameView->contentsHeight() + borderTop() + borderBottom());
+    computeLogicalHeight();
+
+    updateWidgetPosition(); // Notify the Widget of our final height.
+
+    // Assert that the child document did a complete layout.
+    RenderView* childRoot = childFrameView ? static_cast<RenderView*>(childFrameView->frame()->contentRenderer()) : 0;
+    ASSERT(!childFrameView || !childFrameView->layoutPending());
+    ASSERT_UNUSED(childRoot, !childRoot || !childRoot->needsLayout());
+}
+
 void RenderIFrame::layout()
 {
     ASSERT(needsLayout());
 
-    RenderPart::computeLogicalWidth();
-    RenderPart::computeLogicalHeight();
-
     if (flattenFrame()) {
+        RenderPart::computeLogicalWidth();
+        RenderPart::computeLogicalHeight();
         layoutWithFlattening(style()->width().isFixed(), style()->height().isFixed());
+        // FIXME: Is early return really OK here? What about transform/overflow code below?
         return;
+    } else if (isSeamless()) {
+        layoutSeamlessly();
+        // Do not return so as to share the layer and overflow updates below.
+    } else {
+        computeLogicalWidth();
+        // No kids to layout as a replaced element.
+        computeLogicalHeight();
     }
 
-    RenderPart::layout();
-
     m_overflow.clear();
     addVisualEffectOverflow();
     updateLayerTransform();

Modified: trunk/Source/WebCore/rendering/RenderIFrame.h (118290 => 118291)


--- trunk/Source/WebCore/rendering/RenderIFrame.h	2012-05-24 01:04:55 UTC (rev 118290)
+++ trunk/Source/WebCore/rendering/RenderIFrame.h	2012-05-24 01:07:22 UTC (rev 118291)
@@ -30,22 +30,34 @@
 
 namespace WebCore {
 
+class RenderView;
+
 class RenderIFrame : public RenderFrameBase {
 public:
     explicit RenderIFrame(Element*);
 
-    bool flattenFrame();
+    bool flattenFrame() const;
+    bool isSeamless() const;
 
 private:
-    virtual void computeLogicalHeight();
-    virtual void computeLogicalWidth();
+    virtual void computeLogicalHeight() OVERRIDE;
+    virtual void computeLogicalWidth() OVERRIDE;
 
-    virtual void layout();
+    virtual LayoutUnit minPreferredLogicalWidth() const OVERRIDE;
+    virtual LayoutUnit maxPreferredLogicalWidth() const OVERRIDE;
 
-    virtual bool isRenderIFrame() const { return true; }
+    virtual bool shouldComputeSizeAsReplaced() const OVERRIDE;
+    virtual bool isInlineBlockOrInlineTable() const OVERRIDE;
 
-    virtual const char* renderName() const { return "RenderPartObject"; } // Lying for now to avoid breaking tests
+    virtual void layout() OVERRIDE;
 
+    virtual bool isRenderIFrame() const OVERRIDE { return true; }
+
+    virtual const char* renderName() const OVERRIDE { return "RenderPartObject"; } // Lying for now to avoid breaking tests
+
+    void layoutSeamlessly();
+
+    RenderView* contentRootRenderer() const;
 };
 
 inline RenderIFrame* toRenderIFrame(RenderObject* object)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to