| Index: Source/core/frame/FrameView.cpp | 
| diff --git a/Source/core/frame/FrameView.cpp b/Source/core/frame/FrameView.cpp | 
| index 20aaac2a27a9aacbea207d8c6de4b1d9bbfce281..a93df23cf6b1c4c5ac6b3affc2535d85e7c63590 100644 | 
| --- a/Source/core/frame/FrameView.cpp | 
| +++ b/Source/core/frame/FrameView.cpp | 
| @@ -95,6 +95,134 @@ bool FrameView::s_inPaintContents = false; | 
| static const unsigned maxUpdateWidgetsIterations = 2; | 
| static const double resourcePriorityUpdateDelayAfterScroll = 0.250; | 
|  | 
| +void FrameViewAutoSizeData::enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize) | 
| +{ | 
| +    ASSERT(!enable || !minSize.isEmpty()); | 
| +    ASSERT(minSize.width() <= maxSize.width()); | 
| +    ASSERT(minSize.height() <= maxSize.height()); | 
| + | 
| +    if (m_shouldAutoSize == enable && m_minAutoSize == minSize && m_maxAutoSize == maxSize) | 
| +        return; | 
| + | 
| +    m_shouldAutoSize = enable; | 
| +    m_minAutoSize = minSize; | 
| +    m_maxAutoSize = maxSize; | 
| +    m_didRunAutosize = false; | 
| + | 
| +    m_frameView->setLayoutSizeFixedToFrameSize(enable); | 
| +    m_frameView->setNeedsLayout(); | 
| +    m_frameView->scheduleRelayout(); | 
| +    if (m_shouldAutoSize) | 
| +        return; | 
| + | 
| +    // Since autosize mode forces the scrollbar mode, change them to being auto. | 
| +    m_frameView->setVerticalScrollbarLock(false); | 
| +    m_frameView->setHorizontalScrollbarLock(false); | 
| +    m_frameView->setScrollbarModes(ScrollbarAuto, ScrollbarAuto); | 
| +} | 
| + | 
| +void FrameViewAutoSizeData::autoSizeIfEnabled() | 
| +{ | 
| +    if (!m_shouldAutoSize) | 
| +        return; | 
| + | 
| +    if (m_inAutoSize) | 
| +        return; | 
| + | 
| +    TemporaryChange<bool> changeInAutoSize(m_inAutoSize, true); | 
| + | 
| +    Document* document = m_frameView->frame().document(); | 
| +    if (!document || !document->isActive()) | 
| +        return; | 
| + | 
| +    Element* documentElement = document->documentElement(); | 
| +    if (!documentElement) | 
| +        return; | 
| + | 
| +    // If this is the first time we run autosize, start from small height and | 
| +    // allow it to grow. | 
| +    if (!m_didRunAutosize) | 
| +        m_frameView->resize(m_frameView->frameRect().width(), m_minAutoSize.height()); | 
| + | 
| +    IntSize size = m_frameView->frameRect().size(); | 
| + | 
| +    // Do the resizing twice. The first time is basically a rough calculation using the preferred width | 
| +    // which may result in a height change during the second iteration. | 
| +    for (int i = 0; i < 2; i++) { | 
| +        // Update various sizes including contentsSize, scrollHeight, etc. | 
| +        document->updateLayoutIgnorePendingStylesheets(); | 
| + | 
| +        RenderView* renderView = document->renderView(); | 
| +        if (!renderView) | 
| +            return; | 
| + | 
| +        int width = renderView->minPreferredLogicalWidth(); | 
| + | 
| +        RenderBox* documentRenderBox = documentElement->renderBox(); | 
| +        if (!documentRenderBox) | 
| +            return; | 
| + | 
| +        int height = documentRenderBox->scrollHeight(); | 
| +        IntSize newSize(width, height); | 
| + | 
| +        // Check to see if a scrollbar is needed for a given dimension and | 
| +        // if so, increase the other dimension to account for the scrollbar. | 
| +        // Since the dimensions are only for the view rectangle, once a | 
| +        // dimension exceeds the maximum, there is no need to increase it further. | 
| +        if (newSize.width() > m_maxAutoSize.width()) { | 
| +            RefPtr<Scrollbar> localHorizontalScrollbar = m_frameView->horizontalScrollbar(); | 
| +            if (!localHorizontalScrollbar) | 
| +                localHorizontalScrollbar = m_frameView->createScrollbar(HorizontalScrollbar); | 
| +            if (!localHorizontalScrollbar->isOverlayScrollbar()) | 
| +                newSize.setHeight(newSize.height() + localHorizontalScrollbar->height()); | 
| + | 
| +            // Don't bother checking for a vertical scrollbar because the width is at | 
| +            // already greater the maximum. | 
| +        } else if (newSize.height() > m_maxAutoSize.height()) { | 
| +            RefPtr<Scrollbar> localVerticalScrollbar = m_frameView->verticalScrollbar(); | 
| +            if (!localVerticalScrollbar) | 
| +                localVerticalScrollbar = m_frameView->createScrollbar(VerticalScrollbar); | 
| +            if (!localVerticalScrollbar->isOverlayScrollbar()) | 
| +                newSize.setWidth(newSize.width() + localVerticalScrollbar->width()); | 
| + | 
| +            // Don't bother checking for a horizontal scrollbar because the height is | 
| +            // already greater the maximum. | 
| +        } | 
| + | 
| +        // Ensure the size is at least the min bounds. | 
| +        newSize = newSize.expandedTo(m_minAutoSize); | 
| + | 
| +        // Bound the dimensions by the max bounds and determine what scrollbars to show. | 
| +        ScrollbarMode horizonalScrollbarMode = ScrollbarAlwaysOff; | 
| +        if (newSize.width() > m_maxAutoSize.width()) { | 
| +            newSize.setWidth(m_maxAutoSize.width()); | 
| +            horizonalScrollbarMode = ScrollbarAlwaysOn; | 
| +        } | 
| +        ScrollbarMode verticalScrollbarMode = ScrollbarAlwaysOff; | 
| +        if (newSize.height() > m_maxAutoSize.height()) { | 
| +            newSize.setHeight(m_maxAutoSize.height()); | 
| +            verticalScrollbarMode = ScrollbarAlwaysOn; | 
| +        } | 
| + | 
| +        if (newSize == size) | 
| +            continue; | 
| + | 
| +        // While loading only allow the size to increase (to avoid twitching during intermediate smaller states) | 
| +        // unless autoresize has just been turned on or the maximum size is smaller than the current size. | 
| +        if (m_didRunAutosize && size.height() <= m_maxAutoSize.height() && size.width() <= m_maxAutoSize.width() | 
| +            && !m_frameView->frame().document()->loadEventFinished() && (newSize.height() < size.height() || newSize.width() < size.width())) | 
| +            break; | 
| + | 
| +        m_frameView->resize(newSize.width(), newSize.height()); | 
| +        // Force the scrollbar state to avoid the scrollbar code adding them and causing them to be needed. For example, | 
| +        // a vertical scrollbar may cause text to wrap and thus increase the height (which is the only reason the scollbar is needed). | 
| +        m_frameView->setVerticalScrollbarLock(false); | 
| +        m_frameView->setHorizontalScrollbarLock(false); | 
| +        m_frameView->setScrollbarModes(horizonalScrollbarMode, verticalScrollbarMode, true, true); | 
| +    } | 
| +    m_didRunAutosize = true; | 
| +} | 
| + | 
| static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLayer* layer, bool isRelayoutingSubtree, bool didFullPaintInvalidation) | 
| { | 
| RenderLayer::UpdateLayerPositionsFlags flags = didFullPaintInvalidation ? RenderLayer::NeedsFullPaintInvalidationInBacking : RenderLayer::CheckForPaintInvalidation; | 
| @@ -124,9 +252,6 @@ FrameView::FrameView(LocalFrame* frame) | 
| , m_safeToPropagateScrollToParent(true) | 
| , m_isTrackingPaintInvalidations(false) | 
| , m_scrollCorner(0) | 
| -    , m_shouldAutoSize(false) | 
| -    , m_inAutoSize(false) | 
| -    , m_didRunAutosize(false) | 
| , m_hasSoftwareFilters(false) | 
| , m_visibleContentScaleFactor(1) | 
| , m_inputEventsScaleFactorForEmulation(1) | 
| @@ -902,7 +1027,7 @@ void FrameView::layout(bool allowSubtree) | 
| } | 
| } | 
| updateCounters(); | 
| -        autoSizeIfEnabled(); | 
| +        ensureAutoSizeData().autoSizeIfEnabled(); | 
|  | 
| ScrollbarMode hMode; | 
| ScrollbarMode vMode; | 
| @@ -1787,7 +1912,7 @@ void FrameView::handleLoadCompleted() | 
| { | 
| // Once loading has completed, allow autoSize one last opportunity to | 
| // reduce the size of the frame. | 
| -    autoSizeIfEnabled(); | 
| +    ensureAutoSizeData().autoSizeIfEnabled(); | 
| } | 
|  | 
| void FrameView::scheduleRelayout() | 
| @@ -2144,108 +2269,6 @@ void FrameView::updateCounters() | 
| } | 
| } | 
|  | 
| -void FrameView::autoSizeIfEnabled() | 
| -{ | 
| -    if (!m_shouldAutoSize) | 
| -        return; | 
| - | 
| -    if (m_inAutoSize) | 
| -        return; | 
| - | 
| -    TemporaryChange<bool> changeInAutoSize(m_inAutoSize, true); | 
| - | 
| -    Document* document = frame().document(); | 
| -    if (!document || !document->isActive()) | 
| -        return; | 
| - | 
| -    Element* documentElement = document->documentElement(); | 
| -    if (!documentElement) | 
| -        return; | 
| - | 
| -    // If this is the first time we run autosize, start from small height and | 
| -    // allow it to grow. | 
| -    if (!m_didRunAutosize) | 
| -        resize(frameRect().width(), m_minAutoSize.height()); | 
| - | 
| -    IntSize size = frameRect().size(); | 
| - | 
| -    // Do the resizing twice. The first time is basically a rough calculation using the preferred width | 
| -    // which may result in a height change during the second iteration. | 
| -    for (int i = 0; i < 2; i++) { | 
| -        // Update various sizes including contentsSize, scrollHeight, etc. | 
| -        document->updateLayoutIgnorePendingStylesheets(); | 
| - | 
| -        RenderView* renderView = document->renderView(); | 
| -        if (!renderView) | 
| -            return; | 
| - | 
| -        int width = renderView->minPreferredLogicalWidth(); | 
| - | 
| -        RenderBox* documentRenderBox = documentElement->renderBox(); | 
| -        if (!documentRenderBox) | 
| -            return; | 
| - | 
| -        int height = documentRenderBox->scrollHeight(); | 
| -        IntSize newSize(width, height); | 
| - | 
| -        // Check to see if a scrollbar is needed for a given dimension and | 
| -        // if so, increase the other dimension to account for the scrollbar. | 
| -        // Since the dimensions are only for the view rectangle, once a | 
| -        // dimension exceeds the maximum, there is no need to increase it further. | 
| -        if (newSize.width() > m_maxAutoSize.width()) { | 
| -            RefPtr<Scrollbar> localHorizontalScrollbar = horizontalScrollbar(); | 
| -            if (!localHorizontalScrollbar) | 
| -                localHorizontalScrollbar = createScrollbar(HorizontalScrollbar); | 
| -            if (!localHorizontalScrollbar->isOverlayScrollbar()) | 
| -                newSize.setHeight(newSize.height() + localHorizontalScrollbar->height()); | 
| - | 
| -            // Don't bother checking for a vertical scrollbar because the width is at | 
| -            // already greater the maximum. | 
| -        } else if (newSize.height() > m_maxAutoSize.height()) { | 
| -            RefPtr<Scrollbar> localVerticalScrollbar = verticalScrollbar(); | 
| -            if (!localVerticalScrollbar) | 
| -                localVerticalScrollbar = createScrollbar(VerticalScrollbar); | 
| -            if (!localVerticalScrollbar->isOverlayScrollbar()) | 
| -                newSize.setWidth(newSize.width() + localVerticalScrollbar->width()); | 
| - | 
| -            // Don't bother checking for a horizontal scrollbar because the height is | 
| -            // already greater the maximum. | 
| -        } | 
| - | 
| -        // Ensure the size is at least the min bounds. | 
| -        newSize = newSize.expandedTo(m_minAutoSize); | 
| - | 
| -        // Bound the dimensions by the max bounds and determine what scrollbars to show. | 
| -        ScrollbarMode horizonalScrollbarMode = ScrollbarAlwaysOff; | 
| -        if (newSize.width() > m_maxAutoSize.width()) { | 
| -            newSize.setWidth(m_maxAutoSize.width()); | 
| -            horizonalScrollbarMode = ScrollbarAlwaysOn; | 
| -        } | 
| -        ScrollbarMode verticalScrollbarMode = ScrollbarAlwaysOff; | 
| -        if (newSize.height() > m_maxAutoSize.height()) { | 
| -            newSize.setHeight(m_maxAutoSize.height()); | 
| -            verticalScrollbarMode = ScrollbarAlwaysOn; | 
| -        } | 
| - | 
| -        if (newSize == size) | 
| -            continue; | 
| - | 
| -        // While loading only allow the size to increase (to avoid twitching during intermediate smaller states) | 
| -        // unless autoresize has just been turned on or the maximum size is smaller than the current size. | 
| -        if (m_didRunAutosize && size.height() <= m_maxAutoSize.height() && size.width() <= m_maxAutoSize.width() | 
| -            && !m_frame->document()->loadEventFinished() && (newSize.height() < size.height() || newSize.width() < size.width())) | 
| -            break; | 
| - | 
| -        resize(newSize.width(), newSize.height()); | 
| -        // Force the scrollbar state to avoid the scrollbar code adding them and causing them to be needed. For example, | 
| -        // a vertical scrollbar may cause text to wrap and thus increase the height (which is the only reason the scollbar is needed). | 
| -        setVerticalScrollbarLock(false); | 
| -        setHorizontalScrollbarLock(false); | 
| -        setScrollbarModes(horizonalScrollbarMode, verticalScrollbarMode, true, true); | 
| -    } | 
| -    m_didRunAutosize = true; | 
| -} | 
| - | 
| void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow) | 
| { | 
| if (!m_viewportRenderer) | 
| @@ -2900,29 +2923,7 @@ void FrameView::invalidateTreeIfNeededRecursive() | 
|  | 
| void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize) | 
| { | 
| -    ASSERT(!enable || !minSize.isEmpty()); | 
| -    ASSERT(minSize.width() <= maxSize.width()); | 
| -    ASSERT(minSize.height() <= maxSize.height()); | 
| - | 
| -    if (m_shouldAutoSize == enable && m_minAutoSize == minSize && m_maxAutoSize == maxSize) | 
| -        return; | 
| - | 
| - | 
| -    m_shouldAutoSize = enable; | 
| -    m_minAutoSize = minSize; | 
| -    m_maxAutoSize = maxSize; | 
| -    m_didRunAutosize = false; | 
| - | 
| -    setLayoutSizeFixedToFrameSize(enable); | 
| -    setNeedsLayout(); | 
| -    scheduleRelayout(); | 
| -    if (m_shouldAutoSize) | 
| -        return; | 
| - | 
| -    // Since autosize mode forces the scrollbar mode, change them to being auto. | 
| -    setVerticalScrollbarLock(false); | 
| -    setHorizontalScrollbarLock(false); | 
| -    setScrollbarModes(ScrollbarAuto, ScrollbarAuto); | 
| +    ensureAutoSizeData().enableAutoSizeMode(enable, minSize, maxSize); | 
| } | 
|  | 
| void FrameView::forceLayout(bool allowSubtree) | 
|  |