Changeset 244098 in webkit


Ignore:
Timestamp:
Apr 9, 2019 4:42:18 PM (5 years ago)
Author:
Alan Bujtas
Message:

[AutoSizing] Avoid making text paragraphs scroll horizontally when there is a wide table
https://bugs.webkit.org/show_bug.cgi?id=196743
<rdar://problem/43897551>

Reviewed by Tim Horton.

Source/WebCore:

This patch changes the auto size behavior by using fixed constraint (instead of a min/max pair) to compute the content height.
Now with the initial containing block width is firmly set to auto-sizing width, the overflow content will not stretch the ICB. Instead it overflows the ICB
and triggers scrolling the same way the non-auto-sizing mode does.

  • page/FrameView.cpp:

(WebCore::FrameView::autoSizeIfEnabled):
(WebCore::FrameView::enableAutoSizeMode):

  • page/FrameView.h:
  • testing/Internals.cpp:

(WebCore::Internals::enableAutoSizeMode):

  • testing/Internals.h:
  • testing/Internals.idl:

Source/WebKit:

  • WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:

(WebKit::WebFrameLoaderClient::transitionToCommittedForNewPage):

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::setViewLayoutSize):

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/AutoLayoutIntegration.mm: expected behavior change.

(TEST):

LayoutTests:

  • css3/viewport-percentage-lengths/vh-auto-size-expected.html:
  • css3/viewport-percentage-lengths/vh-auto-size.html:
  • fast/dynamic/crash-subtree-layout-when-auto-size-enabled.html:
  • fast/dynamic/mail-autosize-viewport-unit.html:
Location:
trunk
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r244096 r244098  
     12019-04-09  Zalan Bujtas  <zalan@apple.com>
     2
     3        [AutoSizing] Avoid making text paragraphs scroll horizontally when there is a wide table
     4        https://bugs.webkit.org/show_bug.cgi?id=196743
     5        <rdar://problem/43897551>
     6
     7        Reviewed by Tim Horton.
     8
     9        * css3/viewport-percentage-lengths/vh-auto-size-expected.html:
     10        * css3/viewport-percentage-lengths/vh-auto-size.html:
     11        * fast/dynamic/crash-subtree-layout-when-auto-size-enabled.html:
     12        * fast/dynamic/mail-autosize-viewport-unit.html:
     13
    1142019-04-09  Daniel Bates  <dabates@apple.com>
    215
  • trunk/LayoutTests/css3/viewport-percentage-lengths/vh-auto-size-expected.html

    r215874 r244098  
    11<script>
    22if (window.internals)
    3     internals.enableAutoSizeMode(true, 1000, 1, 1000000, 1000000);
     3    internals.enableAutoSizeMode(true, 1000, 1);
    44</script>
    55text text text text text text text
  • trunk/LayoutTests/css3/viewport-percentage-lengths/vh-auto-size.html

    r215874 r244098  
    33<script>
    44if (window.internals)
    5     internals.enableAutoSizeMode(true, 1000, 1, 1000000, 1000000);
     5    internals.enableAutoSizeMode(true, 1000, 1);
    66</script>
    77</head>
  • trunk/LayoutTests/fast/dynamic/crash-subtree-layout-when-auto-size-enabled.html

    r192136 r244098  
    1616<script>
    1717if (window.internals)
    18     internals.enableAutoSizeMode(true, 800, 600, 1000, 1000);
     18    internals.enableAutoSizeMode(true, 800, 600);
    1919
    2020if (window.testRunner) {
  • trunk/LayoutTests/fast/dynamic/mail-autosize-viewport-unit.html

    r233132 r244098  
    2626<script>
    2727if (window.internals)
    28     internals.enableAutoSizeMode(true, 2000, 600, 4000, 1000);
     28    internals.enableAutoSizeMode(true, 2000, 600);
    2929
    3030if (window.testRunner)
  • trunk/Source/WebCore/ChangeLog

    r244097 r244098  
     12019-04-09  Zalan Bujtas  <zalan@apple.com>
     2
     3        [AutoSizing] Avoid making text paragraphs scroll horizontally when there is a wide table
     4        https://bugs.webkit.org/show_bug.cgi?id=196743
     5        <rdar://problem/43897551>
     6
     7        Reviewed by Tim Horton.
     8
     9        This patch changes the auto size behavior by using fixed constraint (instead of a min/max pair) to compute the content height.
     10        Now with the initial containing block width is firmly set to auto-sizing width, the overflow content will not stretch the ICB. Instead it overflows the ICB
     11        and triggers scrolling the same way the non-auto-sizing mode does.
     12
     13        * page/FrameView.cpp:
     14        (WebCore::FrameView::autoSizeIfEnabled):
     15        (WebCore::FrameView::enableAutoSizeMode):
     16        * page/FrameView.h:
     17        * testing/Internals.cpp:
     18        (WebCore::Internals::enableAutoSizeMode):
     19        * testing/Internals.h:
     20        * testing/Internals.idl:
     21
    1222019-04-09  Youenn Fablet  <youenn@apple.com>
    223
  • trunk/Source/WebCore/page/FrameView.cpp

    r243919 r244098  
    34593459        return;
    34603460
     3461    auto* firstChild = renderView->firstChild();
     3462    if (!firstChild)
     3463        return;
     3464
    34613465    LOG(Layout, "FrameView %p autoSizeIfEnabled", this);
    34623466    SetForScope<bool> changeInAutoSize(m_inAutoSize, true);
    34633467    if (layoutContext().subtreeLayoutRoot())
    34643468        layoutContext().convertSubtreeLayoutToFullLayout();
    3465     // Start from the minimum size and allow it to grow.
    3466     resize(m_minAutoSize.width(), m_minAutoSize.height());
    3467     IntSize size = frameRect().size();
    3468     // Do the resizing twice. The first time is basically a rough calculation using the preferred width
    3469     // which may result in a height change during the second iteration.
    3470     for (int i = 0; i < 2; i++) {
    3471         // Update various sizes including contentsSize, scrollHeight, etc.
    3472         document->updateLayoutIgnorePendingStylesheets();
    3473         int width = renderView->minPreferredLogicalWidth();
    3474         int height = renderView->documentRect().height();
    3475         IntSize newSize(width, height);
    3476 
    3477         // Check to see if a scrollbar is needed for a given dimension and
    3478         // if so, increase the other dimension to account for the scrollbar.
    3479         // Since the dimensions are only for the view rectangle, once a
    3480         // dimension exceeds the maximum, there is no need to increase it further.
    3481         if (newSize.width() > m_maxAutoSize.width()) {
    3482             RefPtr<Scrollbar> localHorizontalScrollbar = horizontalScrollbar();
    3483             if (!localHorizontalScrollbar)
    3484                 localHorizontalScrollbar = createScrollbar(HorizontalScrollbar);
    3485             newSize.expand(0, localHorizontalScrollbar->occupiedHeight());
    3486 
    3487             // Don't bother checking for a vertical scrollbar because the width is at
    3488             // already greater the maximum.
    3489         } else if (newSize.height() > m_maxAutoSize.height()) {
    3490             RefPtr<Scrollbar> localVerticalScrollbar = verticalScrollbar();
    3491             if (!localVerticalScrollbar)
    3492                 localVerticalScrollbar = createScrollbar(VerticalScrollbar);
    3493             newSize.expand(localVerticalScrollbar->occupiedWidth(), 0);
    3494 
    3495             // Don't bother checking for a horizontal scrollbar because the height is
    3496             // already greater the maximum.
    3497         }
    3498 
    3499         // Ensure the size is at least the min bounds.
    3500         newSize = newSize.expandedTo(m_minAutoSize);
    3501 
    3502         // Bound the dimensions by the max bounds and determine what scrollbars to show.
    3503         ScrollbarMode horizonalScrollbarMode = ScrollbarAlwaysOff;
    3504         if (newSize.width() > m_maxAutoSize.width()) {
    3505             newSize.setWidth(m_maxAutoSize.width());
    3506             horizonalScrollbarMode = ScrollbarAlwaysOn;
    3507         }
    3508         ScrollbarMode verticalScrollbarMode = ScrollbarAlwaysOff;
    3509         if (newSize.height() > m_maxAutoSize.height()) {
    3510             newSize.setHeight(m_maxAutoSize.height());
    3511             verticalScrollbarMode = ScrollbarAlwaysOn;
    3512         }
    3513 
    3514         if (newSize == size)
    3515             continue;
    3516 
    3517         // While loading only allow the size to increase (to avoid twitching during intermediate smaller states)
    3518         // unless autoresize has just been turned on or the maximum size is smaller than the current size.
    3519         if (m_didRunAutosize && size.height() <= m_maxAutoSize.height() && size.width() <= m_maxAutoSize.width()
    3520             && !frame().loader().isComplete() && (newSize.height() < size.height() || newSize.width() < size.width()))
    3521             break;
    3522 
    3523         // The first time around, resize to the minimum height again; otherwise,
    3524         // on pages (e.g. quirks mode) where the body/document resize to the view size,
    3525         // we'll end up not shrinking back down after resizing to the computed preferred width.
    3526         resize(newSize.width(), i ? newSize.height() : m_minAutoSize.height());
    3527         // Force the scrollbar state to avoid the scrollbar code adding them and causing them to be needed. For example,
    3528         // a vertical scrollbar may cause text to wrap and thus increase the height (which is the only reason the scollbar is needed).
    3529         setVerticalScrollbarLock(false);
    3530         setHorizontalScrollbarLock(false);
    3531         setScrollbarModes(horizonalScrollbarMode, verticalScrollbarMode, true, true);
    3532     }
    3533     // All the resizing above may have invalidated style (for example if viewport units are being used).
     3469
     3470    ScrollbarMode horizonalScrollbarMode = ScrollbarAlwaysOff;
     3471    ScrollbarMode verticalScrollbarMode = ScrollbarAlwaysOff;
     3472    setVerticalScrollbarLock(false);
     3473    setHorizontalScrollbarLock(false);
     3474    setScrollbarModes(horizonalScrollbarMode, verticalScrollbarMode, true, true);
     3475
     3476    ASSERT(is<RenderElement>(*firstChild));
     3477    auto& documentRenderer = downcast<RenderElement>(*firstChild);
     3478    documentRenderer.mutableStyle().setMaxWidth(Length(m_autoSizeConstraint.width(), Fixed));
     3479    resize(m_autoSizeConstraint.width(), m_autoSizeConstraint.height());
    35343480    document->updateStyleIfNeeded();
    3535     // FIXME: Use the final layout's result as the content size (webkit.org/b/173561).
     3481    document->updateLayoutIgnorePendingStylesheets();
    35363482    m_autoSizeContentSize = contentsSize();
    3537     if (m_autoSizeFixedMinimumHeight) {
    3538         auto contentsSize = this->contentsSize();
    3539         resize(contentsSize.width(), std::max(m_autoSizeFixedMinimumHeight, contentsSize.height()));
    3540         document->updateLayoutIgnorePendingStylesheets();
    3541     }
     3483
     3484    auto finalWidth = std::max(m_autoSizeConstraint.width(), m_autoSizeContentSize.width());
     3485    auto finalHeight = m_autoSizeFixedMinimumHeight ? std::max(m_autoSizeFixedMinimumHeight, m_autoSizeContentSize.height()) : m_autoSizeContentSize.height();
     3486    resize(finalWidth, finalHeight);
     3487    document->updateLayoutIgnorePendingStylesheets();
    35423488    m_didRunAutosize = true;
    3543 
    3544     LOG_WITH_STREAM(Layout, stream << "FrameView " << this << " autoSizeIfEnabled() changed size from " << size << " to " << frameRect().size());
    35453489}
    35463490
     
    45354479}
    45364480
    4537 void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize)
    4538 {
    4539     ASSERT(!enable || !minSize.isEmpty());
    4540     ASSERT(minSize.width() <= maxSize.width());
    4541     ASSERT(minSize.height() <= maxSize.height());
    4542 
    4543     if (m_shouldAutoSize == enable && m_minAutoSize == minSize && m_maxAutoSize == maxSize)
     4481void FrameView::enableAutoSizeMode(bool enable, const IntSize& viewSize)
     4482{
     4483    ASSERT(!enable || !viewSize.isEmpty());
     4484    if (m_shouldAutoSize == enable && m_autoSizeConstraint == viewSize)
    45444485        return;
    45454486
    45464487    m_shouldAutoSize = enable;
    4547     m_minAutoSize = minSize;
    4548     m_maxAutoSize = maxSize;
     4488    m_autoSizeConstraint = viewSize;
    45494489    m_didRunAutosize = false;
    45504490
     
    45524492    layoutContext().scheduleLayout();
    45534493    if (m_shouldAutoSize) {
    4554         overrideViewportSizeForCSSViewportUnits({ minSize.width(), m_overrideViewportSize ? m_overrideViewportSize->height : WTF::nullopt });
     4494        overrideViewportSizeForCSSViewportUnits({ m_autoSizeConstraint.width(), m_overrideViewportSize ? m_overrideViewportSize->height : WTF::nullopt });
    45554495        return;
    45564496    }
  • trunk/Source/WebCore/page/FrameView.h

    r243905 r244098  
    400400    void updateSignificantRenderedTextMilestoneIfNeeded();
    401401    bool isVisuallyNonEmpty() const { return m_isVisuallyNonEmpty; }
    402     WEBCORE_EXPORT void enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize);
     402    WEBCORE_EXPORT void enableAutoSizeMode(bool enable, const IntSize& minSize);
    403403    WEBCORE_EXPORT void setAutoSizeFixedMinimumHeight(int);
    404404    IntSize autoSizingIntrinsicContentSize() const { return m_autoSizeContentSize; }
     
    874874    Optional<OverrideViewportSize> m_overrideViewportSize;
    875875
    876     // The lower bound on the size when autosizing.
    877     IntSize m_minAutoSize;
    878     // The upper bound on the size when autosizing.
    879     IntSize m_maxAutoSize;
     876    // The view size when autosizing.
     877    IntSize m_autoSizeConstraint;
    880878    // The fixed height to resize the view to after autosizing is complete.
    881879    int m_autoSizeFixedMinimumHeight { 0 };
  • trunk/Source/WebCore/testing/Internals.cpp

    r244078 r244098  
    33853385}
    33863386
    3387 void Internals::enableAutoSizeMode(bool enabled, int minimumWidth, int minimumHeight, int maximumWidth, int maximumHeight)
     3387void Internals::enableAutoSizeMode(bool enabled, int width, int height)
    33883388{
    33893389    auto* document = contextDocument();
    33903390    if (!document || !document->view())
    33913391        return;
    3392     document->view()->enableAutoSizeMode(enabled, IntSize(minimumWidth, minimumHeight), IntSize(maximumWidth, maximumHeight));
     3392    document->view()->enableAutoSizeMode(enabled, { width, height });
    33933393}
    33943394
  • trunk/Source/WebCore/testing/Internals.h

    r244078 r244098  
    494494    void reloadExpiredOnly();
    495495
    496     void enableAutoSizeMode(bool enabled, int minimumWidth, int minimumHeight, int maximumWidth, int maximumHeight);
     496    void enableAutoSizeMode(bool enabled, int width, int height);
    497497
    498498#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
  • trunk/Source/WebCore/testing/Internals.idl

    r244078 r244098  
    518518    void reloadExpiredOnly();
    519519
    520     void enableAutoSizeMode(boolean enabled, long minimumWidth, long minimumHeight, long maximumWidth, long maximumHeight);
     520    void enableAutoSizeMode(boolean enabled, long width, long height);
    521521
    522522    [Conditional=VIDEO] sequence<DOMString> mediaResponseSources(HTMLMediaElement media);
  • trunk/Source/WebKit/ChangeLog

    r244097 r244098  
     12019-04-09  Zalan Bujtas  <zalan@apple.com>
     2
     3        [AutoSizing] Avoid making text paragraphs scroll horizontally when there is a wide table
     4        https://bugs.webkit.org/show_bug.cgi?id=196743
     5        <rdar://problem/43897551>
     6
     7        Reviewed by Tim Horton.
     8
     9        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
     10        (WebKit::WebFrameLoaderClient::transitionToCommittedForNewPage):
     11        * WebProcess/WebPage/WebPage.cpp:
     12        (WebKit::WebPage::setViewLayoutSize):
     13
    1142019-04-09  Youenn Fablet  <youenn@apple.com>
    215
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp

    r243860 r244098  
    14741474    if (int viewLayoutWidth = webPage->viewLayoutSize().width()) {
    14751475        int viewLayoutHeight = std::max(webPage->viewLayoutSize().height(), 1);
    1476         int maximumSize = std::numeric_limits<int>::max();
    1477         m_frame->coreFrame()->view()->enableAutoSizeMode(true, IntSize(viewLayoutWidth, viewLayoutHeight), IntSize(maximumSize, maximumSize));
     1476        m_frame->coreFrame()->view()->enableAutoSizeMode(true, { viewLayoutWidth, viewLayoutHeight });
    14781477
    14791478        if (webPage->autoSizingShouldExpandToViewHeight())
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r243961 r244098  
    54835483    m_viewLayoutSize = viewLayoutSize;
    54845484    if (viewLayoutSize.width() <= 0) {
    5485         corePage()->mainFrame().view()->enableAutoSizeMode(false, IntSize(), IntSize());
     5485        corePage()->mainFrame().view()->enableAutoSizeMode(false, { });
    54865486        return;
    54875487    }
     
    54895489    int viewLayoutWidth = viewLayoutSize.width();
    54905490    int viewLayoutHeight = std::max(viewLayoutSize.height(), 1);
    5491 
    5492     int maximumSize = std::numeric_limits<int>::max();
    5493 
    5494     corePage()->mainFrame().view()->enableAutoSizeMode(true, IntSize(viewLayoutWidth, viewLayoutHeight), IntSize(maximumSize, maximumSize));
     5491    corePage()->mainFrame().view()->enableAutoSizeMode(true, { viewLayoutWidth, viewLayoutHeight });
    54955492}
    54965493
  • trunk/Tools/ChangeLog

    r244097 r244098  
     12019-04-09  Zalan Bujtas  <zalan@apple.com>
     2
     3        [AutoSizing] Avoid making text paragraphs scroll horizontally when there is a wide table
     4        https://bugs.webkit.org/show_bug.cgi?id=196743
     5        <rdar://problem/43897551>
     6
     7        Reviewed by Tim Horton.
     8
     9        * TestWebKitAPI/Tests/WebKitCocoa/AutoLayoutIntegration.mm: expected behavior change.
     10        (TEST):
     11
    1122019-04-09  Youenn Fablet  <youenn@apple.com>
    213
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AutoLayoutIntegration.mm

    r242339 r244098  
    146146    [webView layoutAtMinimumWidth:100 andExpectContentSizeChange:NSMakeSize(100, 10) resettingWidth:YES];
    147147
    148     // One 100x100 rect and ten 10x10 rects, inline; with the constraint (width >= 20) -> 100x110
    149     [webView load:@"<div class='large'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div>" withWidth:20 expectingContentSize:NSMakeSize(100, 110)];
     148    // One 100x100 rect and ten 10x10 rects, inline; with the constraint (width >= 20) -> 100x150
     149    [webView load:@"<div class='large'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div><div class='small inline'></div>" withWidth:20 expectingContentSize:NSMakeSize(100, 150)];
    150150
    151151    // With _shouldExpandContentToViewHeightForAutoLayout off (the default), the page should lay out to the intrinsic height
Note: See TracChangeset for help on using the changeset viewer.