Changeset 118291 in webkit


Ignore:
Timestamp:
May 23, 2012 6:07:22 PM (12 years ago)
Author:
eric@webkit.org
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:
Location:
trunk
Files:
3 added
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r118279 r118291  
     12012-05-23  Eric Seidel  <eric@webkit.org>
     2
     3        Add seamless layout code (and pass most of the remaining seamless tests)
     4        https://bugs.webkit.org/show_bug.cgi?id=86608
     5
     6        Reviewed by Ojan Vafai.
     7
     8        Add a test for percent height in child documents, as well as
     9        disabling the expand-to-fill-viewport quirk of html/body elements
     10        in quirks mode.
     11        Also update all the expectations now that we pass almost all the tests.
     12
     13        * fast/frames/seamless/resources/percent-square.html: Added.
     14        * fast/frames/seamless/resources/two-inline-blocks.html:
     15        * fast/frames/seamless/seamless-basic-expected.txt:
     16        * fast/frames/seamless/seamless-float-expected.txt:
     17        * fast/frames/seamless/seamless-inherited-origin-expected.txt:
     18        * fast/frames/seamless/seamless-inherited-origin.html:
     19        * fast/frames/seamless/seamless-inline-expected.txt:
     20        * fast/frames/seamless/seamless-nested-expected.txt:
     21        * fast/frames/seamless/seamless-percent-height-expected.txt: Added.
     22        * fast/frames/seamless/seamless-percent-height.html: Added.
     23        * fast/frames/seamless/seamless-quirks-expected.txt:
     24        * fast/frames/seamless/seamless-sandbox-flag-expected.txt:
     25        * fast/frames/seamless/seamless-sandbox-srcdoc-expected.txt:
     26
    1272012-05-23  Tony Chang  <tony@chromium.org>
    228
  • trunk/LayoutTests/fast/frames/seamless/resources/two-inline-blocks.html

    r115742 r118291  
    22<html><head><style>
    33body { margin: 0px; line-height: 0px; }
     4/* FIXME: This vertical-align should not be needed, but without it the contentHeight()
     5of the document is reported as 4px too large, likely due to implied line decent? */
     6div { vertical-align: top; }
    47</style></head>
    58<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>
  • trunk/LayoutTests/fast/frames/seamless/seamless-basic-expected.txt

    r115773 r118291  
    22FAIL iframe.seamless should be true (of type boolean). Was undefined (of type undefined).
    33PASS window.getComputedStyle(iframe).display is "block"
    4 FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
    5 FAIL window.getComputedStyle(iframe).height should be 100px. Was 150px.
    6 FAIL window.getComputedStyle(iframe).height should be 200px. Was 150px.
    7 FAIL window.getComputedStyle(iframe).width should be 100px. Was 300px.
     4PASS window.getComputedStyle(iframe).width is "200px"
     5PASS window.getComputedStyle(iframe).height is "100px"
     6PASS window.getComputedStyle(iframe).height is "200px"
     7PASS window.getComputedStyle(iframe).width is "100px"
    88
  • trunk/LayoutTests/fast/frames/seamless/seamless-float-expected.txt

    r115742 r118291  
    11Test that floated seamless iframes 'shrink-wrap' their contents, as floated divs would.
    2 FAIL window.getComputedStyle(iframe1).width should be 150px. Was 300px.
    3 FAIL window.getComputedStyle(iframe1).height should be 50px. Was 150px.
    4 FAIL window.getComputedStyle(iframe2).width should be 100px. Was 300px.
    5 FAIL window.getComputedStyle(iframe2).height should be 100px. Was 150px.
     2PASS window.getComputedStyle(iframe1).width is "150px"
     3FAIL window.getComputedStyle(iframe1).height should be 50px. Was 100px.
     4PASS window.getComputedStyle(iframe2).width is "100px"
     5PASS window.getComputedStyle(iframe2).height is "100px"
    66
    77
  • trunk/LayoutTests/fast/frames/seamless/seamless-inherited-origin-expected.txt

    r115773 r118291  
    11Test that frames with inherited security origins can still be seamless.
    22FAIL iframe.seamless should be true (of type boolean). Was undefined (of type undefined).
    3 FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
    4 FAIL window.getComputedStyle(iframe).height should be 0px. Was 150px.
    5 FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
    6 FAIL window.getComputedStyle(iframe).height should be 100px. Was 150px.
     3PASS window.getComputedStyle(iframe).width is "200px"
     4PASS window.getComputedStyle(iframe).height is "8px"
     5PASS window.getComputedStyle(iframe).width is "200px"
     6PASS window.getComputedStyle(iframe).height is "100px"
    77
  • trunk/LayoutTests/fast/frames/seamless/seamless-inherited-origin.html

    r115773 r118291  
    1010    shouldBeTrue("iframe.seamless");
    1111
    12     // Initially about:blank should have 0 height.
    1312    shouldBeEqualToString("window.getComputedStyle(iframe).width", "200px");
    14     shouldBeEqualToString("window.getComputedStyle(iframe).height", "0px");
     13    // Initially about:blank has no content, thus no height, except the body
     14    // element defaults to margin: 8px (which gets collapsed to 8px when rendered).
     15    shouldBeEqualToString("window.getComputedStyle(iframe).height", "8px");
    1516
    1617    // Replace the empty document with a 100x100px square to test if it displays seamlessly.
  • trunk/LayoutTests/fast/frames/seamless/seamless-inline-expected.txt

    r115773 r118291  
    11Test that inline seamless iframes 'shrink-wrap' their contents like inline-blocks do.
    2 FAIL window.getComputedStyle(iframe1).display should be inline-block. Was inline.
    3 FAIL window.getComputedStyle(iframe2).display should be inline-block. Was inline.
    4 FAIL window.getComputedStyle(iframe1).width should be 150px. Was 300px.
    5 FAIL window.getComputedStyle(iframe1).height should be 50px. Was 150px.
    6 FAIL window.getComputedStyle(parent1).height should be 50px. Was 200px.
    7 FAIL window.getComputedStyle(iframe2).width should be 100px. Was 300px.
    8 FAIL window.getComputedStyle(iframe2).height should be 100px. Was 150px.
    9 FAIL window.getComputedStyle(parent2).height should be 150px. Was 200px.
     2PASS window.getComputedStyle(iframe1).display is "inline-block"
     3PASS window.getComputedStyle(iframe2).display is "inline-block"
     4PASS window.getComputedStyle(iframe1).width is "150px"
     5FAIL window.getComputedStyle(iframe1).height should be 50px. Was 100px.
     6FAIL window.getComputedStyle(parent1).height should be 50px. Was 100px.
     7PASS window.getComputedStyle(iframe2).width is "100px"
     8PASS window.getComputedStyle(iframe2).height is "100px"
     9PASS window.getComputedStyle(parent2).height is "150px"
    1010
    1111
  • trunk/LayoutTests/fast/frames/seamless/seamless-nested-expected.txt

    r115742 r118291  
    22FAIL iframe.seamless should be true (of type boolean). Was undefined (of type undefined).
    33FAIL nestedFrame.seamless should be true (of type boolean). Was undefined (of type undefined).
    4 FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
    5 FAIL window.getComputedStyle(iframe).height should be 100px. Was 150px.
     4PASS window.getComputedStyle(iframe).width is "200px"
     5PASS window.getComputedStyle(iframe).height is "100px"
    66
  • trunk/LayoutTests/fast/frames/seamless/seamless-quirks-expected.txt

    r115742 r118291  
    22FAIL iframe.seamless should be true (of type boolean). Was undefined (of type undefined).
    33PASS iframe.contentDocument.compatMode is "BackCompat"
    4 FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
    5 FAIL window.getComputedStyle(iframe).height should be 100px. Was 150px.
     4PASS window.getComputedStyle(iframe).width is "200px"
     5PASS window.getComputedStyle(iframe).height is "100px"
    66
  • trunk/LayoutTests/fast/frames/seamless/seamless-sandbox-flag-expected.txt

    r115773 r118291  
    55PASS window.getComputedStyle(iframe).borderWidth is "0px"
    66PASS window.getComputedStyle(iframe).borderStyle is "none"
    7 FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
     7PASS window.getComputedStyle(iframe).width is "200px"
    88PASS window.getComputedStyle(iframe).height is "150px"
    99
  • trunk/LayoutTests/fast/frames/seamless/seamless-sandbox-srcdoc-expected.txt

    r115742 r118291  
    11Test that iframes with srcdoc contents can still be seamless.
    22FAIL iframe.seamless should be true (of type boolean). Was undefined (of type undefined).
    3 FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
    4 FAIL window.getComputedStyle(iframe).height should be 100px. Was 150px.
     3PASS window.getComputedStyle(iframe).width is "200px"
     4PASS window.getComputedStyle(iframe).height is "100px"
    55
  • trunk/LayoutTests/http/tests/security/seamless/seamless-cross-origin-expected.txt

    r115742 r118291  
    11FAIL iframe1.seamless should be true (of type boolean). Was undefined (of type undefined).
    22FAIL iframe2.seamless should be true (of type boolean). Was undefined (of type undefined).
    3 FAIL window.getComputedStyle(iframe1).width should be 200px. Was 300px.
    4 FAIL window.getComputedStyle(iframe1).height should be 100px. Was 150px.
     3PASS window.getComputedStyle(iframe1).width is "200px"
     4PASS window.getComputedStyle(iframe1).height is "100px"
    55PASS window.getComputedStyle(iframe2).width is "300px"
    66PASS window.getComputedStyle(iframe2).height is "150px"
  • trunk/LayoutTests/http/tests/security/seamless/seamless-sandbox-srcdoc-expected.txt

    r115742 r118291  
    11FAIL iframe.seamless should be true (of type boolean). Was undefined (of type undefined).
    2 FAIL window.getComputedStyle(iframe).width should be 200px. Was 300px.
    3 FAIL window.getComputedStyle(iframe).height should be 100px. Was 150px.
     2PASS window.getComputedStyle(iframe).width is "200px"
     3PASS window.getComputedStyle(iframe).height is "100px"
    44
  • trunk/Source/WebCore/ChangeLog

    r118289 r118291  
     12012-05-23  Eric Seidel  <eric@webkit.org>
     2
     3        Add seamless layout code (and pass most of the remaining seamless tests)
     4        https://bugs.webkit.org/show_bug.cgi?id=86608
     5
     6        Reviewed by Ojan Vafai.
     7
     8        This patch contains almost all the layout changes needed for seamless iframes.
     9        I removed the scroll-bar avoiding code at the last moment, as it didn't
     10        work for platforms other than mac-lion.  I'll add that, as well as the
     11        HTMLIFrameElement.seamless idl attribute in a follow-up patch.
     12
     13        Seamless iframes piggy-back a bit on the existing frame-flattening
     14        logic, however seamless is different from frame-flattening in a few ways:
     15        - Frame flattening can only ever make an iframe larger (seamless just behaves like a normal div).
     16        - Frame flattening disables scrollbars (seamless frames behave like normal overflow: auto divs).
     17        - Seamless only has to work with iframes (flattening works with frame/frameset as well).
     18        - Seamless support shrink-wrap size negotiation when the iframe is inline.
     19
     20        Test: fast/frames/seamless/seamless-percent-height.html
     21
     22        * css/StyleResolver.cpp:
     23        (WebCore::StyleResolver::adjustRenderStyle): map inline -> inline-block for seamless iframes.
     24        * dom/Document.cpp:
     25        (WebCore::Document::scheduleStyleRecalc):
     26         - Seamless iframes don't manage their own style recalc.
     27        (WebCore::Document::recalcStyle):
     28         - We should make sure our parent is resolved before we are, but currently that causes some tests to crash
     29           I don't have a test to demonstrate this need yet, as presumably it's fulfilled through other codepaths atm.
     30        * page/FrameView.cpp:
     31        (WebCore::FrameView::scheduleRelayout): Do the cheaper check first.
     32        (WebCore::FrameView::isInChildFrameWithFrameFlattening): Make frameview layout abort child layouts like how frame flattening does.
     33        * rendering/RenderBox.h:
     34        (WebCore::RenderBox::stretchesToViewport): Disable the stretch-to-viewport quirk for seamless iframes (it makes no sense and breaks the layout code).
     35        * rendering/RenderIFrame.cpp:
     36        (WebCore::RenderIFrame::computeLogicalHeight):
     37         - This function is needed for the child document to participate in the normal block shrink-wrap algorithm.
     38           Thankfully all the shrink-wrap logic is in RenderBox instead of RenderBlock. In the future we may make
     39           RenderIframe a RenderBlock for the seamless case. We may just split RenderIframe into two renderers.
     40        (WebCore::RenderIFrame::computeLogicalWidth):
     41        (WebCore::RenderIFrame::shouldComputeSizeAsReplaced):
     42         - seamless iframes behave like blocks, not inline replaced elements.
     43        (WebCore):
     44        (WebCore::RenderIFrame::isInlineBlockOrInlineTable):
     45         - Behave like an inline-block when marked inline.
     46        (WebCore::RenderIFrame::minPreferredLogicalWidth):
     47         - When asked for our pref widths, return those of our child document.
     48        (WebCore::RenderIFrame::maxPreferredLogicalWidth):
     49        (WebCore::RenderIFrame::isSeamless): helper function
     50        (WebCore::RenderIFrame::contentRootRenderer): helper function
     51        (WebCore::RenderIFrame::flattenFrame): seamless iframes never use the frame-flattening feature.
     52        (WebCore::RenderIFrame::layoutSeamlessly): The guts of seamless layout.
     53        (WebCore::RenderIFrame::layout):
     54        * rendering/RenderIFrame.h:
     55        (WebCore):
     56        (RenderIFrame):
     57
    1582012-05-23  Rafael Brandao  <rafael.lobo@openbossa.org>
    259
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r118263 r118291  
    21282128        || style->hasFilter()))
    21292129        style->setTransformStyle3D(TransformStyle3DFlat);
     2130
     2131    // Seamless iframes behave like blocks. Map their display to inline-block when marked inline.
     2132    if (e && e->hasTagName(iframeTag) && style->display() == INLINE && static_cast<HTMLIFrameElement*>(e)->shouldDisplaySeamlessly())
     2133        style->setDisplay(INLINE_BLOCK);
    21302134
    21312135#if ENABLE(SVG)
  • trunk/Source/WebCore/dom/Document.cpp

    r118194 r118291  
    16611661void Document::scheduleStyleRecalc()
    16621662{
    1663     // FIXME: In the seamless case, we should likely schedule a style recalc
    1664     // on our parent and instead return early here.
     1663    if (shouldDisplaySeamlesslyWithParent()) {
     1664        // When we're seamless, our parent document manages our style recalcs.
     1665        ownerElement()->setNeedsStyleRecalc();
     1666        ownerElement()->document()->scheduleStyleRecalc();
     1667        return;
     1668    }
    16651669
    16661670    if (m_styleRecalcTimer.isActive() || inPageCache())
     
    17181722        return; // Guard against re-entrancy. -dwh
    17191723
    1720     // FIXME: In the seamless case, we may wish to exit early in the child after recalcing our parent chain.
    1721     // I have not yet found a test which requires such.
     1724    // FIXME: We should update style on our ancestor chain before proceeding (especially for seamless),
     1725    // however doing so currently causes several tests to crash, as Frame::setDocument calls Document::attach
     1726    // before setting the DOMWindow on the Frame, or the SecurityOrigin on the document. The attach, in turn
     1727    // resolves style (here) and then when we resolve style on the parent chain, we may end up
     1728    // re-attaching our containing iframe, which when asked HTMLFrameElementBase::isURLAllowed
     1729    // hits a null-dereference due to security code always assuming the document has a SecurityOrigin.
    17221730
    17231731    if (m_hasDirtyStyleResolver)
  • trunk/Source/WebCore/page/FrameView.cpp

    r117697 r118291  
    20422042    // When frame flattening is enabled, the contents of the frame could affect the layout of the parent frames.
    20432043    // Also invalidate parent frame starting from the owner element of this frame.
    2044     if (isInChildFrameWithFrameFlattening() && m_frame->ownerRenderer())
     2044    if (m_frame->ownerRenderer() && isInChildFrameWithFrameFlattening())
    20452045        m_frame->ownerRenderer()->setNeedsLayout(true, MarkContainingBlockChain);
    20462046
     
    29192919bool FrameView::isInChildFrameWithFrameFlattening()
    29202920{
    2921     if (!parent() || !m_frame->ownerElement() || !m_frame->settings() || !m_frame->settings()->frameFlatteningEnabled())
     2921    if (!parent() || !m_frame->ownerElement())
    29222922        return false;
    29232923
     
    29262926    if (m_frame->ownerElement()->hasTagName(iframeTag)) {
    29272927        RenderIFrame* iframeRenderer = toRenderIFrame(m_frame->ownerElement()->renderPart());
    2928 
    2929         if (iframeRenderer->flattenFrame())
     2928        if (iframeRenderer->flattenFrame() || iframeRenderer->isSeamless())
    29302929            return true;
    2931 
    2932     } else if (m_frame->ownerElement()->hasTagName(frameTag))
     2930    }
     2931
     2932    if (!m_frame->settings() || !m_frame->settings()->frameFlatteningEnabled())
     2933        return false;
     2934
     2935    if (m_frame->ownerElement()->hasTagName(frameTag))
    29332936        return true;
    29342937
  • trunk/Source/WebCore/rendering/RenderBox.h

    r118076 r118291  
    327327    bool stretchesToViewport() const
    328328    {
    329         return document()->inQuirksMode() && style()->logicalHeight().isAuto() && !isFloatingOrPositioned() && (isRoot() || isBody());
     329        return document()->inQuirksMode() && style()->logicalHeight().isAuto() && !isFloatingOrPositioned() && (isRoot() || isBody()) && !document()->shouldDisplaySeamlesslyWithParent();
    330330    }
    331331
  • trunk/Source/WebCore/rendering/RenderIFrame.cpp

    r111515 r118291  
    6464void RenderIFrame::computeLogicalWidth()
    6565{
     66    // When we're seamless, we behave like a block. Thankfully RenderBox has all the right logic for this.
     67    if (isSeamless())
     68        return RenderBox::computeLogicalWidth();
     69
    6670    RenderPart::computeLogicalWidth();
    6771    if (!flattenFrame())
     
    8084}
    8185
    82 bool RenderIFrame::flattenFrame()
     86bool RenderIFrame::shouldComputeSizeAsReplaced() const
     87{
     88    // When we're seamless, we use normal block/box sizing code except when inline.
     89    return !isSeamless();
     90}
     91
     92bool RenderIFrame::isInlineBlockOrInlineTable() const
     93{
     94    return isSeamless() && isInline();
     95}
     96
     97LayoutUnit RenderIFrame::minPreferredLogicalWidth() const
     98{
     99    if (!isSeamless())
     100        return RenderFrameBase::minPreferredLogicalWidth();
     101
     102    RenderView* childRoot = contentRootRenderer();
     103    if (!childRoot)
     104        return 0;
     105
     106    return childRoot->minPreferredLogicalWidth();
     107}
     108
     109LayoutUnit RenderIFrame::maxPreferredLogicalWidth() const
     110{
     111    if (!isSeamless())
     112        return RenderFrameBase::maxPreferredLogicalWidth();
     113
     114    RenderView* childRoot = contentRootRenderer();
     115    if (!childRoot)
     116        return 0;
     117
     118    return childRoot->maxPreferredLogicalWidth();
     119}
     120
     121bool RenderIFrame::isSeamless() const
     122{
     123    return node() && node()->hasTagName(iframeTag) && static_cast<HTMLIFrameElement*>(node())->shouldDisplaySeamlessly();
     124}
     125
     126RenderView* RenderIFrame::contentRootRenderer() const
     127{
     128    // FIXME: Is this always a valid cast? What about plugins?
     129    ASSERT(!widget() || widget()->isFrameView());
     130    FrameView* childFrameView = static_cast<FrameView*>(widget());
     131    return childFrameView ? static_cast<RenderView*>(childFrameView->frame()->contentRenderer()) : 0;
     132}
     133
     134bool RenderIFrame::flattenFrame() const
    83135{
    84136    if (!node() || !node()->hasTagName(iframeTag))
     
    87139    HTMLIFrameElement* element = static_cast<HTMLIFrameElement*>(node());
    88140    Frame* frame = element->document()->frame();
     141
     142    if (isSeamless())
     143        return false; // Seamless iframes are already "flat", don't try to flatten them.
    89144
    90145    bool enabled = frame && frame->settings() && frame->settings()->frameFlatteningEnabled();
     
    106161}
    107162
     163void RenderIFrame::layoutSeamlessly()
     164{
     165    computeLogicalWidth();
     166    // FIXME: Containers set their height to 0 before laying out their kids (as we're doing here)
     167    // however, this causes FrameView::layout() to add vertical scrollbars, incorrectly inflating
     168    // the resulting contentHeight(). We'll need to make FrameView::layout() smarter.
     169    setLogicalHeight(0);
     170    updateWidgetPosition(); // Tell the Widget about our new width/height (it will also layout the child document).
     171
     172    // Laying out our kids is normally responsible for adjusting our height, so we set it here.
     173    // Replaced elements do not respect padding, so we just add border to the child's height.
     174    // FIXME: It's possible that seamless iframes (since they act like divs) *should* respect padding.
     175    FrameView* childFrameView = static_cast<FrameView*>(widget());
     176    if (childFrameView) // Widget should never be null during layout(), but just in case.
     177        setLogicalHeight(childFrameView->contentsHeight() + borderTop() + borderBottom());
     178    computeLogicalHeight();
     179
     180    updateWidgetPosition(); // Notify the Widget of our final height.
     181
     182    // Assert that the child document did a complete layout.
     183    RenderView* childRoot = childFrameView ? static_cast<RenderView*>(childFrameView->frame()->contentRenderer()) : 0;
     184    ASSERT(!childFrameView || !childFrameView->layoutPending());
     185    ASSERT_UNUSED(childRoot, !childRoot || !childRoot->needsLayout());
     186}
     187
    108188void RenderIFrame::layout()
    109189{
    110190    ASSERT(needsLayout());
    111191
    112     RenderPart::computeLogicalWidth();
    113     RenderPart::computeLogicalHeight();
    114 
    115192    if (flattenFrame()) {
     193        RenderPart::computeLogicalWidth();
     194        RenderPart::computeLogicalHeight();
    116195        layoutWithFlattening(style()->width().isFixed(), style()->height().isFixed());
     196        // FIXME: Is early return really OK here? What about transform/overflow code below?
    117197        return;
    118     }
    119 
    120     RenderPart::layout();
     198    } else if (isSeamless()) {
     199        layoutSeamlessly();
     200        // Do not return so as to share the layer and overflow updates below.
     201    } else {
     202        computeLogicalWidth();
     203        // No kids to layout as a replaced element.
     204        computeLogicalHeight();
     205    }
    121206
    122207    m_overflow.clear();
  • trunk/Source/WebCore/rendering/RenderIFrame.h

    r110738 r118291  
    3131namespace WebCore {
    3232
     33class RenderView;
     34
    3335class RenderIFrame : public RenderFrameBase {
    3436public:
    3537    explicit RenderIFrame(Element*);
    3638
    37     bool flattenFrame();
     39    bool flattenFrame() const;
     40    bool isSeamless() const;
    3841
    3942private:
    40     virtual void computeLogicalHeight();
    41     virtual void computeLogicalWidth();
     43    virtual void computeLogicalHeight() OVERRIDE;
     44    virtual void computeLogicalWidth() OVERRIDE;
    4245
    43     virtual void layout();
     46    virtual LayoutUnit minPreferredLogicalWidth() const OVERRIDE;
     47    virtual LayoutUnit maxPreferredLogicalWidth() const OVERRIDE;
    4448
    45     virtual bool isRenderIFrame() const { return true; }
     49    virtual bool shouldComputeSizeAsReplaced() const OVERRIDE;
     50    virtual bool isInlineBlockOrInlineTable() const OVERRIDE;
    4651
    47     virtual const char* renderName() const { return "RenderPartObject"; } // Lying for now to avoid breaking tests
     52    virtual void layout() OVERRIDE;
    4853
     54    virtual bool isRenderIFrame() const OVERRIDE { return true; }
     55
     56    virtual const char* renderName() const OVERRIDE { return "RenderPartObject"; } // Lying for now to avoid breaking tests
     57
     58    void layoutSeamlessly();
     59
     60    RenderView* contentRootRenderer() const;
    4961};
    5062
Note: See TracChangeset for help on using the changeset viewer.