| 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)
|
|
|