diff options
author | Patrick Scott <phanna@android.com> | 2011-02-17 10:58:02 -0500 |
---|---|---|
committer | Patrick Scott <phanna@android.com> | 2011-02-25 13:04:41 -0500 |
commit | 5c9b9436a58504f9e48283bfd450c688df9f3d45 (patch) | |
tree | 034f51d8e5f447aae3c640b35f8b17d534942f53 | |
parent | 3a89d2677bb5634df98cd01414220b8e095f58a9 (diff) | |
download | external_webkit-5c9b9436a58504f9e48283bfd450c688df9f3d45.zip external_webkit-5c9b9436a58504f9e48283bfd450c688df9f3d45.tar.gz external_webkit-5c9b9436a58504f9e48283bfd450c688df9f3d45.tar.bz2 |
Fix frameset expansion.
Do not expand frames that cannot scroll. Use contentsWidth and contentsHeight
instead of exposing docWidth. Trigger a layout of the parent if the FrameView's
layout reveals a larger content dimension. Remove iframe flattening code.
Bug: 3370518
Bug: 3323913
Change-Id: I60e89caf335bfaf271f90ffd538c65f3735572da
-rw-r--r-- | WebCore/page/FrameView.cpp | 20 | ||||
-rw-r--r-- | WebCore/rendering/RenderBlockLineLayout.cpp | 16 | ||||
-rw-r--r-- | WebCore/rendering/RenderFrame.cpp | 50 | ||||
-rw-r--r-- | WebCore/rendering/RenderIFrame.cpp | 129 | ||||
-rw-r--r-- | WebCore/rendering/RenderView.h | 3 | ||||
-rw-r--r-- | WebCore/rendering/RenderWidget.cpp | 2 |
6 files changed, 32 insertions, 188 deletions
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp index 1f03599..422343d 100644 --- a/WebCore/page/FrameView.cpp +++ b/WebCore/page/FrameView.cpp @@ -515,11 +515,9 @@ void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, Scrollbar Node* body = document->body(); if (body && body->renderer()) { if (body->hasTagName(framesetTag) && m_frame->settings() && !m_frame->settings()->frameFlatteningEnabled()) { -#if !defined(ANDROID_FLATTEN_IFRAME) && !defined(ANDROID_FLATTEN_FRAMESET) body->renderer()->setChildNeedsLayout(true); vMode = ScrollbarAlwaysOff; hMode = ScrollbarAlwaysOff; -#endif } else if (body->hasTagName(bodyTag)) { // It's sufficient to just check the X overflow, // since it's illegal to have visible in only one direction. @@ -928,7 +926,7 @@ void FrameView::layout(bool allowSubtree) InspectorInstrumentation::didLayout(cookie); m_nestedLayoutCount--; -#if ENABLE(ANDROID_OVERFLOW_SCROLL) && !defined(ANDROID_FLATTEN_IFRAME) +#if ENABLE(ANDROID_OVERFLOW_SCROLL) // Reset to false each time we layout in case the overflow status changed. bool hasOverflowScroll = false; RenderObject* ownerRenderer = m_frame->ownerRenderer(); @@ -952,6 +950,15 @@ void FrameView::layout(bool allowSubtree) } m_hasOverflowScroll = hasOverflowScroll; #endif +#ifdef ANDROID_FLATTEN_FRAMESET + // Request a layout to use the content dimensions. + if (m_frame->ownerRenderer() && m_frame->ownerElement()->hasTagName(frameTag)) { + if (canHaveScrollbars() && layoutWidth() > 1 && layoutHeight() > 1) { + if (layoutWidth() < contentsWidth() || layoutHeight() < contentsHeight()) + m_frame->ownerRenderer()->setNeedsLayout(true, true); + } + } +#endif } void FrameView::addWidgetToUpdate(RenderEmbeddedObject* object) @@ -1556,13 +1563,6 @@ void FrameView::scheduleRelayout() if (!m_frame->document()->shouldScheduleLayout()) return; -#if defined(ANDROID_FLATTEN_IFRAME) || defined(ANDROID_FLATTEN_FRAMESET) - // This is the Android frame flattening code. The common code below is not - // used as frameSetFlatteningEnabled() is false on Android. - if (m_frame->ownerRenderer()) - m_frame->ownerRenderer()->setNeedsLayoutAndPrefWidthsRecalc(); -#endif - // When frame flattening is enabled, the contents of the frame affects layout of the parent frames. // Also invalidate parent frame starting from the owner element of this frame. if (m_frame->settings() && m_frame->settings()->frameFlatteningEnabled() && m_frame->ownerRenderer()) { diff --git a/WebCore/rendering/RenderBlockLineLayout.cpp b/WebCore/rendering/RenderBlockLineLayout.cpp index 6b9fc68..c722136 100644 --- a/WebCore/rendering/RenderBlockLineLayout.cpp +++ b/WebCore/rendering/RenderBlockLineLayout.cpp @@ -609,23 +609,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica else if (fullLayout || o->needsLayout()) { // Replaced elements toRenderBox(o)->dirtyLineBoxes(fullLayout); -#if defined(ANDROID_FLATTEN_IFRAME) || defined(ANDROID_FLATTEN_FRAMESET) - // Android frame flattening during layout() may cause the - // renderer to be destroyed, if for example a frames onresize handler - // deletes the frame - see http://trac.webkit.org/changeset/61070 for example. - // We may be able to remove this protector when we switch to the upstream - // frame flattening code. In the case of an anonymous render object like RenderListMarker - // the document is the DOM node associated with this RenderObject. - RefPtr<Node> protector(o->isAnonymous() ? o->document() : o->node()); -#endif o->layoutIfNeeded(); -#if defined(ANDROID_FLATTEN_IFRAME) || defined(ANDROID_FLATTEN_FRAMESET) - // Ensure that the renderer still exists. If it's gone away we will crash pretty - // fast by continuing to use the now invalid o pointer. If the renderer has gone, - // then there's no point in continuing to try to layout it's children so we break. - if (!protector->renderer()) - break; -#endif } } #else diff --git a/WebCore/rendering/RenderFrame.cpp b/WebCore/rendering/RenderFrame.cpp index c3283f8..bc40976 100644 --- a/WebCore/rendering/RenderFrame.cpp +++ b/WebCore/rendering/RenderFrame.cpp @@ -28,12 +28,6 @@ #include "HTMLFrameElement.h" #include "RenderView.h" -#ifdef ANDROID_FLATTEN_FRAMESET -#include "Frame.h" -#include "Document.h" -#include "RenderView.h" -#endif - namespace WebCore { RenderFrame::RenderFrame(HTMLFrameElement* frame) @@ -68,29 +62,29 @@ void RenderFrame::viewCleared() #ifdef ANDROID_FLATTEN_FRAMESET void RenderFrame::layout() { - if (widget() && widget()->isFrameView()) { - FrameView* view = static_cast<FrameView*>(widget()); - RenderView* root = NULL; - if (view->frame() && view->frame()->document() && - view->frame()->document()->renderer() && - view->frame()->document()->renderer()->isRenderView()) - root = static_cast<RenderView*>(view->frame()->document()->renderer()); - if (root) { - // Resize the widget so that the RenderView will layout according to those dimensions. - view->resize(width(), height()); - view->layout(); - // We can only grow in width and height because if positionFrames gives us a width and we become smaller, - // then the fixup process of forcing the frame to fill extra space will fail. - const int docLeft = root->docLeft(); - if (width() > root->docWidth(docLeft)) { - view->resize(root->docWidth(docLeft), 0); - view->layout(); - } - // Honor the height set by RenderFrameSet::positionFrames unless our document height is larger. - setHeight(max(root->docHeight(), height())); - setWidth(max(root->docWidth(docLeft), width())); - } + FrameView* view = static_cast<FrameView*>(widget()); + RenderView* root = view ? view->frame()->contentRenderer() : 0; + if (!width() || !height() || !root) { + setNeedsLayout(false); + return; } + + HTMLFrameElementBase* element = static_cast<HTMLFrameElementBase*>(node()); + if (element->scrollingMode() == ScrollbarAlwaysOff && !root->isFrameSet()) { + setNeedsLayout(false); + return; + } + + int layoutWidth = width(); + + setWidth(max(view->contentsWidth() + borderAndPaddingWidth(), width())); + setHeight(max(view->contentsHeight() + borderAndPaddingHeight(), height())); + + // This should trigger a layout of the FrameView which will schedule a + // relayout of this RenderFrame. + if (layoutWidth < width()) + setHeight(0); + setNeedsLayout(false); } #endif diff --git a/WebCore/rendering/RenderIFrame.cpp b/WebCore/rendering/RenderIFrame.cpp index 36d2449..19bca49 100644 --- a/WebCore/rendering/RenderIFrame.cpp +++ b/WebCore/rendering/RenderIFrame.cpp @@ -44,30 +44,6 @@ RenderIFrame::RenderIFrame(Element* element) void RenderIFrame::computeLogicalHeight() { RenderPart::computeLogicalHeight(); -#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 - view->layout(); - - 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; @@ -86,38 +62,6 @@ void RenderIFrame::computeLogicalHeight() void RenderIFrame::computeLogicalWidth() { RenderPart::computeLogicalWidth(); -#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->minPreferredLogicalWidth()) + extraWidth); - - // Update based on the new width - updateWidgetPosition(); - - // Layout to get the content width - view->layout(); - - setWidth(max(width(), view->contentsWidth() + extraWidth)); - - // Update one last time to ensure the dimensions. - updateWidgetPosition(); - return; -#endif - if (!flattenFrame()) return; @@ -166,79 +110,6 @@ void RenderIFrame::layout() RenderPart::computeLogicalWidth(); RenderPart::computeLogicalHeight(); -#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->minPreferredLogicalWidth()) + 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. - view->layout(); - - 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; diff --git a/WebCore/rendering/RenderView.h b/WebCore/rendering/RenderView.h index 66b1d74..8436762 100644 --- a/WebCore/rendering/RenderView.h +++ b/WebCore/rendering/RenderView.h @@ -176,9 +176,6 @@ protected: private: bool shouldRepaint(const IntRect& r) const; -#ifdef ANDROID_FLATTEN_FRAMESET -public: // used by layout function -#endif int docHeight() const; int docLeft() const; int docWidth(int leftOverflow) const; diff --git a/WebCore/rendering/RenderWidget.cpp b/WebCore/rendering/RenderWidget.cpp index e5ccd05..6ea620f 100644 --- a/WebCore/rendering/RenderWidget.cpp +++ b/WebCore/rendering/RenderWidget.cpp @@ -345,7 +345,6 @@ void RenderWidget::updateWidgetPosition() bool boundsChanged = setWidgetGeometry(IntRect(absPos.x(), absPos.y(), w, h)); -#ifndef ANDROID_FLATTEN_IFRAME // if the frame bounds got changed, or if view needs layout (possibly indicating // content size is wrong) we have to do a layout to set the right widget size if (m_widget && m_widget->isFrameView()) { @@ -354,7 +353,6 @@ void RenderWidget::updateWidgetPosition() if ((boundsChanged || frameView->needsLayout()) && frameView->frame()->page()) frameView->layout(); } -#endif } void RenderWidget::widgetPositionsUpdated() |