diff options
author | Steve Block <steveblock@google.com> | 2010-04-30 15:36:55 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-05-11 14:42:14 +0100 |
commit | fc38d325f67d0fc26fd82125299088a790627d31 (patch) | |
tree | 6d2b08740ba106d2460a90aeefcc67d671e63a95 /WebCore/rendering/RenderIFrame.cpp | |
parent | 8c053ec93ab9e7ff792eed9f0eb2fbc01155ad1d (diff) | |
download | external_webkit-fc38d325f67d0fc26fd82125299088a790627d31.zip external_webkit-fc38d325f67d0fc26fd82125299088a790627d31.tar.gz external_webkit-fc38d325f67d0fc26fd82125299088a790627d31.tar.bz2 |
Merge webkit.org at r58033 : Move Android iframe-flattening code to RenderIFrame.cpp
The Android iframe-flattening code was in RenderPartObject. The rendering
classes have been refactored upstream in http://trac.webkit.org/changeset/57866
so that most of RenderPartObject was moved to RenderIFrame. RenderPartObject was
then removed in http://trac.webkit.org/changeset/57900.
Iframe-flattening was also added upstream in
http://trac.webkit.org/changeset/56718.
This change takes the Android iframe-flattening code from RenderPartObject and
moves it to RenderIFrame. It also renames FLATTEN_IFRAME to
ANDROID_FLATTEN_IFRAME and FLATTEN_FRAMESET to ANDROID_FLATTEN_FRAMESET for
clarity.
Change-Id: I1af8d042f8d0c4abd513f8a315ac681360c1cc53
Diffstat (limited to 'WebCore/rendering/RenderIFrame.cpp')
-rw-r--r-- | WebCore/rendering/RenderIFrame.cpp | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/WebCore/rendering/RenderIFrame.cpp b/WebCore/rendering/RenderIFrame.cpp index bfea7bd..5852468 100644 --- a/WebCore/rendering/RenderIFrame.cpp +++ b/WebCore/rendering/RenderIFrame.cpp @@ -43,6 +43,32 @@ RenderIFrame::RenderIFrame(Element* element) void RenderIFrame::calcHeight() { RenderPart::calcHeight(); +#ifdef ANDROID_FLATTEN_IFRAME + if (!node()->hasTagName(iframeTag) || !widget() || !widget()->isFrameView()) + return; + FrameView* view = static_cast<FrameView*>(widget()); + RenderView* root = static_cast<RenderView*>(view->frame()->contentRenderer()); + if (!root) + return; + // Do not expand if the scrollbars are suppressed and the height is fixed. + bool scrolling = static_cast<HTMLIFrameElement*>(node())->scrollingMode() != ScrollbarAlwaysOff; + if (!scrolling && style()->height().isFixed()) + return; + // Update the widget + updateWidgetPosition(); + + // Layout to get the content height + do { + view->layout(); + } while (view->layoutPending() || root->needsLayout()); + + int extraHeight = paddingTop() + paddingBottom() + borderTop() + borderBottom(); + setHeight(max(width(), view->contentsHeight() + extraHeight)); + + // Update one last time to ensure the dimensions. + updateWidgetPosition(); + return; +#endif if (!flattenFrame()) return; @@ -59,6 +85,39 @@ void RenderIFrame::calcHeight() void RenderIFrame::calcWidth() { RenderPart::calcWidth(); +#ifdef ANDROID_FLATTEN_IFRAME + if (!node()->hasTagName(iframeTag) || !widget() || !widget()->isFrameView()) + return; + FrameView* view = static_cast<FrameView*>(widget()); + RenderView* root = static_cast<RenderView*>(view->frame()->contentRenderer()); + if (!root) + return; + // Do not expand if the scrollbars are suppressed and the width is fixed. + bool scrolling = static_cast<HTMLIFrameElement*>(node())->scrollingMode() != ScrollbarAlwaysOff; + if (!scrolling && style()->width().isFixed()) + return; + // Update the dimensions to get the correct minimum preferred + // width + updateWidgetPosition(); + + int extraWidth = paddingLeft() + paddingRight() + borderLeft() + borderRight(); + // Set the width + setWidth(max(width(), root->minPrefWidth()) + extraWidth); + + // Update based on the new width + updateWidgetPosition(); + + // Layout to get the content width + do { + view->layout(); + } while (view->layoutPending() || root->needsLayout()); + + setWidth(max(width(), view->contentsWidth() + extraWidth)); + + // Update one last time to ensure the dimensions. + updateWidgetPosition(); + return; +#endif if (!flattenFrame()) return; @@ -105,6 +164,81 @@ void RenderIFrame::layout() RenderPart::calcWidth(); RenderPart::calcHeight(); +#ifdef ANDROID_FLATTEN_IFRAME + // Calculate the styled dimensions by subtracting the border and padding. + int extraWidth = paddingLeft() + paddingRight() + borderLeft() + borderRight(); + int extraHeight = paddingTop() + paddingBottom() + borderTop() + borderBottom(); + int styleWidth = width() - extraWidth; + int styleHeight = height() - extraHeight; + // Some IFrames have a width and/or height of 1 when they are meant to be + // hidden. If that is the case, do not try to expand. + if (node()->hasTagName(iframeTag) && widget() && widget()->isFrameView() && + styleWidth > 1 && styleHeight > 1) { + HTMLIFrameElement* element = static_cast<HTMLIFrameElement*>(node()); + bool scrolling = element->scrollingMode() != ScrollbarAlwaysOff; + bool widthIsFixed = style()->width().isFixed(); + bool heightIsFixed = style()->height().isFixed(); + // If an iframe has a fixed dimension and suppresses scrollbars, it + // will disrupt layout if we force it to expand. Plus on a desktop, + // the extra content is not accessible. + if (scrolling || !widthIsFixed || !heightIsFixed) { + FrameView* view = static_cast<FrameView*>(widget()); + RenderView* root = view ? view->frame()->contentRenderer() : NULL; + if (root && style()->visibility() != HIDDEN) { + // Update the dimensions to get the correct minimum preferred + // width + updateWidgetPosition(); + + // Use the preferred width if it is larger and only if + // scrollbars are visible or the width style is not fixed. + if (scrolling || !widthIsFixed) + setWidth(max(width(), root->minPrefWidth()) + extraWidth); + + // Resize the view to recalc the height. + int h = height() - extraHeight; + int w = width() - extraWidth; + if (w > view->width()) + h = 0; + if (w != view->width() || h != view->height()) { + view->resize(w, h); + } + + // Layout the view. + do { + view->layout(); + } while (view->layoutPending() || root->needsLayout()); + + int contentHeight = view->contentsHeight(); + int contentWidth = view->contentsWidth(); + // Only change the width or height if scrollbars are visible or + // if the style is not a fixed value. Use the maximum value so + // that iframes never shrink. + if (scrolling || !heightIsFixed) + setHeight(max(height(), contentHeight + extraHeight)); + if (scrolling || !widthIsFixed) + setWidth(max(width(), contentWidth + extraWidth)); + + // Update one last time + updateWidgetPosition(); + + // Layout one more time to ensure all objects have the correct + // height. + view->layout(); + +#if !ASSERT_DISABLED + ASSERT(!view->layoutPending()); + ASSERT(!root->needsLayout()); + // Sanity check when assertions are enabled. + RenderObject* c = root->nextInPreOrder(); + while (c) { + ASSERT(!c->needsLayout()); + c = c->nextInPreOrder(); + } +#endif + } + } + } +#endif if (flattenFrame()) { layoutWithFlattening(style()->width().isFixed(), style()->height().isFixed()); return; |