REGRESSION: Block no longer shrinks to preferred width in this flex box layout
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Mar 2017 01:29:19 +0000 (01:29 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Mar 2017 01:29:19 +0000 (01:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=169203
<rdar://problem/30873895>

Reviewed by Simon Fraser.

Source/WebCore:

Added new test in css3/flexbox.

* css/StyleResolver.cpp:
(WebCore::StyleResolver::adjustRenderStyle):
(WebCore::StyleResolver::adjustStyleForAlignment):
* html/shadow/TextControlInnerElements.cpp:
(WebCore::TextControlInnerElement::resolveCustomStyle):
Resolve auto alignment values by adjusting the render style as needed. Make a helper
function for adjusting only alignment that can be called from the inner text control
custom style creation.

* rendering/GridTrackSizingAlgorithm.cpp:
(WebCore::GridTrackSizingAlgorithmStrategy::minSizeForChild):
Replaced items in grids should not stretch by default.

* rendering/RenderBox.cpp:
(WebCore::RenderBox::hasStretchedLogicalWidth):
Patched to properly check the default alignment for the child, making sure
that if it's a replacd item inside a grid, that the default is start and not
stretch.

* rendering/RenderBox.h:
(WebCore::RenderBox::selfAlignmentNormalBehavior):
Self-alignment function now takes an optional child argument, since the behavior
varies in grids depending on the child being replaced or not.

* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::alignmentForChild):
Fixed to do the right thing when the child is anonymous.

(WebCore::RenderFlexibleBox::styleDidChange): Deleted.
* rendering/RenderFlexibleBox.h:
Deleted, since alignment changes are handled at the style diff level now.

* rendering/RenderFullScreen.h:
Patched the selfAlignmentNormalBehavior method to take an optional child argument.

* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::styleDidChange):
(WebCore::RenderGrid::alignSelfForChild):
(WebCore::RenderGrid::justifySelfForChild):
(WebCore::RenderGrid::columnAxisPositionForChild):
(WebCore::RenderGrid::rowAxisPositionForChild):
(WebCore::RenderGrid::columnAxisOffsetForChild):
(WebCore::RenderGrid::rowAxisOffsetForChild):
(WebCore::defaultAlignmentIsStretch): Deleted.
(WebCore::defaultAlignmentChangedToStretchInRowAxis): Deleted.
(WebCore::defaultAlignmentChangedFromStretchInRowAxis): Deleted.
(WebCore::defaultAlignmentChangedFromStretchInColumnAxis): Deleted.
(WebCore::selfAlignmentChangedToStretchInRowAxis): Deleted.
(WebCore::selfAlignmentChangedFromStretchInRowAxis): Deleted.
(WebCore::selfAlignmentChangedFromStretchInColumnAxis): Deleted.
* rendering/RenderGrid.h:
Removed the alignment change logic in styleDidChange for grids, since style diffing handles
it now. Updated all selfAlignmentForNormalBehavior queries to pass in the child so that
replaced elements are handled properly.

* rendering/style/RenderStyle.h:
(WebCore::RenderStyle::overflowInlineDirection):
(WebCore::RenderStyle::overflowBlockDirection):
(WebCore::RenderStyle::setJustifySelfPosition):
New helpers used by grid and by adjustRenderStyle.

* style/StyleChange.cpp:
(WebCore::Style::determineChange):
If alignment or justification changes occur on a parent that could affect the child (e.g., align-items)
return Inherit so the child render styles get adjusted properly.

LayoutTests:

* css3/flexbox/column-inside-normal-block-preferred-width-expected.html: Added.
* css3/flexbox/column-inside-normal-block-preferred-width.html: Added.
* fast/css-grid-layout/grid-align-stretching-replaced-items-expected.txt:
* fast/css-grid-layout/grid-align-stretching-replaced-items.html:
* fast/repaint/align-items-change-expected.txt:
* fast/repaint/align-items-overflow-change-expected.txt:
* fast/repaint/justify-items-change-expected.txt:
* fast/repaint/justify-items-legacy-change-expected.txt:
* fast/repaint/justify-items-overflow-change-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@213480 268f45cc-cd09-0410-ab3c-d52691b4dbfc

24 files changed:
LayoutTests/ChangeLog
LayoutTests/css3/flexbox/column-inside-normal-block-preferred-width-expected.html [new file with mode: 0644]
LayoutTests/css3/flexbox/column-inside-normal-block-preferred-width.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/grid-align-stretching-replaced-items-expected.txt
LayoutTests/fast/css-grid-layout/grid-align-stretching-replaced-items.html
LayoutTests/fast/repaint/align-items-change-expected.txt
LayoutTests/fast/repaint/align-items-overflow-change-expected.txt
LayoutTests/fast/repaint/justify-items-change-expected.txt
LayoutTests/fast/repaint/justify-items-legacy-change-expected.txt
LayoutTests/fast/repaint/justify-items-overflow-change-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/StyleResolver.h
Source/WebCore/html/shadow/TextControlInnerElements.cpp
Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBox.h
Source/WebCore/rendering/RenderFlexibleBox.cpp
Source/WebCore/rendering/RenderFlexibleBox.h
Source/WebCore/rendering/RenderFullScreen.h
Source/WebCore/rendering/RenderGrid.cpp
Source/WebCore/rendering/RenderGrid.h
Source/WebCore/rendering/style/RenderStyle.h
Source/WebCore/style/StyleChange.cpp

index b6af9ec..1024637 100644 (file)
@@ -1,3 +1,21 @@
+2017-03-06  Dave Hyatt  <hyatt@apple.com>
+
+        REGRESSION: Block no longer shrinks to preferred width in this flex box layout
+        https://bugs.webkit.org/show_bug.cgi?id=169203
+        <rdar://problem/30873895>
+
+        Reviewed by Simon Fraser.
+
+        * css3/flexbox/column-inside-normal-block-preferred-width-expected.html: Added.
+        * css3/flexbox/column-inside-normal-block-preferred-width.html: Added.
+        * fast/css-grid-layout/grid-align-stretching-replaced-items-expected.txt:
+        * fast/css-grid-layout/grid-align-stretching-replaced-items.html:
+        * fast/repaint/align-items-change-expected.txt:
+        * fast/repaint/align-items-overflow-change-expected.txt:
+        * fast/repaint/justify-items-change-expected.txt:
+        * fast/repaint/justify-items-legacy-change-expected.txt:
+        * fast/repaint/justify-items-overflow-change-expected.txt:
+
 2017-03-06  Ryan Haddad  <ryanhaddad@apple.com>
 
         Mark inspector/worker/console-basic.html as flaky.
diff --git a/LayoutTests/css3/flexbox/column-inside-normal-block-preferred-width-expected.html b/LayoutTests/css3/flexbox/column-inside-normal-block-preferred-width-expected.html
new file mode 100644 (file)
index 0000000..219bab0
--- /dev/null
@@ -0,0 +1,3 @@
+<!doctype html>
+
+<div style="display: flex; flex-direction: row: justify-contents: center;border:5px solid lime"><div style="border:solid">test</div></div>
diff --git a/LayoutTests/css3/flexbox/column-inside-normal-block-preferred-width.html b/LayoutTests/css3/flexbox/column-inside-normal-block-preferred-width.html
new file mode 100644 (file)
index 0000000..5f9a2be
--- /dev/null
@@ -0,0 +1,3 @@
+<!doctype html>
+
+<div style="display: flex; flex-direction: row; align-items: center;border:5px solid lime"><div style="border:solid">test</div></div>
index 1faef8a..ca2237c 100644 (file)
@@ -1,6 +1,14 @@
 This test checks that the alignment properties align-self and justify-self apply the 'stretch' value correctly on replaced elements.
 
-The blue image's original size is 100px x 100px, but it should be stretched to fill the 500px x 500px grid area it's placed into
+The blue image's original size is 100px x 100px, default alignment is resolved as 'start' for replaced elements so it prevents stretching to be applied.
+
+
+PASS
+The blue image's original size is 100px x 100px, 'normal' is resolved as 'start' for replaced elements so it prevents stretching to be applied.
+
+
+PASS
+The blue image's original size is 100px x 100px, but it should be stretched to fill the 500px x 500px grid area it's placed into.
 
 
 PASS
index 274de17..1e977b9 100644 (file)
 </style>
 
 <body onload="checkLayout('.grid')">
-
-<p>This test checks that the alignment properties align-self and justify-self apply the 'stretch' value correctly on replaced elements.</p>
-
-<div style="position: relative">
-    <p>The blue image's original size is 100px x 100px, but it should be stretched to fill the 500px x 500px grid area it's placed into</p>
-    <div class="grid">
-        <img src="../../css3/images/resources/blue-100.png" data-expected-width="500" data-expected-height="500"/>
+    
+    <p>This test checks that the alignment properties align-self and justify-self apply the 'stretch' value correctly on replaced elements.</p>
+    
+    <div style="position: relative">
+        <p>The blue image's original size is 100px x 100px, default alignment is resolved as 'start' for replaced elements so it prevents stretching to be applied.</p>
+        <div class="grid">
+            <img src="../../css3/images/resources/blue-100.png" data-expected-width="100" data-expected-height="100"/>
+        </div>
     </div>
-</div>
-
-<div style="position: relative">
-    <p>The blue image's original size is 100px x 100px, non-stretch values prevent stretching to be applied.</p>
-    <div class="grid itemsCenter">
-        <img src="../../css3/images/resources/blue-100.png" data-expected-width="100" data-expected-height="100"/>
+    
+    <div style="position: relative">
+        <p>The blue image's original size is 100px x 100px, 'normal' is resolved as 'start' for replaced elements so it prevents stretching to be applied.</p>
+        <div class="grid itemsNormal">
+            <img src="../../css3/images/resources/blue-100.png" data-expected-width="100" data-expected-height="100"/>
+        </div>
     </div>
-</div>
-
-<div style="position: relative">
-    <p>The blue image's original size is 100px x 100px, non-auto sizes prevent stretching to be applied.</p>
-    <div class="grid">
-        <img class="fixedSizes" src="../../css3/images/resources/blue-100.png" data-expected-width="150" data-expected-height="150"/>
+    
+    <div style="position: relative">
+        <p>The blue image's original size is 100px x 100px, but it should be stretched to fill the 500px x 500px grid area it's placed into.</p>
+        <div class="grid alignItemsStretch justifyItemsStretch">
+            <img src="../../css3/images/resources/blue-100.png" data-expected-width="500" data-expected-height="500"/>
+        </div>
     </div>
-</div>
-
-<div style="position: relative">
-    <p>The blue image's original size is 100px x 100px, auto-margins prevent stretching to be applied.</p>
-    <div class="grid">
-        <img class="autoMargins" src="../../css3/images/resources/blue-100.png" data-expected-width="100" data-expected-height="100"/>
+    
+    <div style="position: relative">
+        <p>The blue image's original size is 100px x 100px, non-stretch values prevent stretching to be applied.</p>
+        <div class="grid itemsCenter">
+            <img src="../../css3/images/resources/blue-100.png" data-expected-width="100" data-expected-height="100"/>
+        </div>
+    </div>
+    
+    <div style="position: relative">
+        <p>The blue image's original size is 100px x 100px, non-auto sizes prevent stretching to be applied.</p>
+        <div class="grid">
+            <img class="fixedSizes" src="../../css3/images/resources/blue-100.png" data-expected-width="150" data-expected-height="150"/>
+        </div>
+    </div>
+    
+    <div style="position: relative">
+        <p>The blue image's original size is 100px x 100px, auto-margins prevent stretching to be applied.</p>
+        <div class="grid">
+            <img class="autoMargins" src="../../css3/images/resources/blue-100.png" data-expected-width="100" data-expected-height="100"/>
+        </div>
     </div>
-</div>
-
 </body>
index 750a424..119068b 100644 (file)
@@ -1,6 +1,8 @@
 Tests invalidation on align-items style change. Passes if there is no red.
 
 (repaint rects
+  (rect 0 52 100 102)
+  (rect 100 52 100 152)
   (rect 0 52 100 300)
   (rect 0 51 100 1)
   (rect 100 52 100 300)
index d7a397c..272029e 100644 (file)
@@ -1,6 +1,8 @@
 Tests invalidation on align-items style change (just overflow). Passes if there is no red.
 
 (repaint rects
+  (rect 0 2 200 200)
+  (rect 0 252 200 100)
   (rect 0 2 200 350)
   (rect 0 52 200 300)
   (rect 0 2 800 14)
index 418e417..2124245 100644 (file)
@@ -1,7 +1,8 @@
 Tests invalidation on justify-items style change. Passes if there is no red.
 
 (repaint rects
-  (rect 200 52 150 300)
+  (rect 150 52 50 300)
+  (rect 150 52 200 300)
   (rect 0 52 200 300)
 )
 
index fa2b44f..848be73 100644 (file)
@@ -1,6 +1,12 @@
 Tests invalidation on justify-items style change (legacy value). Passes if green bars are centerd inside their red container.
 
 (repaint rects
+  (rect 1 53 50 50)
+  (rect 0 52 52 100)
+  (rect 151 53 50 50)
+  (rect 150 52 52 100)
+  (rect 0 52 202 300)
+  (rect 0 52 251 300)
   (rect 0 52 300 400)
 )
 
index 96654c6..88d6599 100644 (file)
@@ -1,6 +1,8 @@
 Tests invalidation on justify-items style change. Passes if there is no red.
 
 (repaint rects
+  (rect -60 52 160 300)
+  (rect 150 52 50 300)
   (rect -60 52 260 300)
   (rect 0 52 200 300)
   (rect -60 16 60 336)
index 47c7ffe..5220e1f 100644 (file)
@@ -1,3 +1,79 @@
+2017-03-06  Dave Hyatt  <hyatt@apple.com>
+
+        REGRESSION: Block no longer shrinks to preferred width in this flex box layout
+        https://bugs.webkit.org/show_bug.cgi?id=169203
+        <rdar://problem/30873895>
+
+        Reviewed by Simon Fraser.
+
+        Added new test in css3/flexbox.
+
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::adjustRenderStyle):
+        (WebCore::StyleResolver::adjustStyleForAlignment):
+        * html/shadow/TextControlInnerElements.cpp:
+        (WebCore::TextControlInnerElement::resolveCustomStyle):
+        Resolve auto alignment values by adjusting the render style as needed. Make a helper
+        function for adjusting only alignment that can be called from the inner text control
+        custom style creation.
+
+        * rendering/GridTrackSizingAlgorithm.cpp:
+        (WebCore::GridTrackSizingAlgorithmStrategy::minSizeForChild):
+        Replaced items in grids should not stretch by default.
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::hasStretchedLogicalWidth):
+        Patched to properly check the default alignment for the child, making sure
+        that if it's a replacd item inside a grid, that the default is start and not
+        stretch.
+
+        * rendering/RenderBox.h:
+        (WebCore::RenderBox::selfAlignmentNormalBehavior):
+        Self-alignment function now takes an optional child argument, since the behavior
+        varies in grids depending on the child being replaced or not.
+
+        * rendering/RenderFlexibleBox.cpp:
+        (WebCore::RenderFlexibleBox::alignmentForChild):
+        Fixed to do the right thing when the child is anonymous.
+
+        (WebCore::RenderFlexibleBox::styleDidChange): Deleted.
+        * rendering/RenderFlexibleBox.h:
+        Deleted, since alignment changes are handled at the style diff level now.
+
+        * rendering/RenderFullScreen.h:
+        Patched the selfAlignmentNormalBehavior method to take an optional child argument.
+
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::styleDidChange):
+        (WebCore::RenderGrid::alignSelfForChild):
+        (WebCore::RenderGrid::justifySelfForChild):
+        (WebCore::RenderGrid::columnAxisPositionForChild):
+        (WebCore::RenderGrid::rowAxisPositionForChild):
+        (WebCore::RenderGrid::columnAxisOffsetForChild):
+        (WebCore::RenderGrid::rowAxisOffsetForChild):
+        (WebCore::defaultAlignmentIsStretch): Deleted.
+        (WebCore::defaultAlignmentChangedToStretchInRowAxis): Deleted.
+        (WebCore::defaultAlignmentChangedFromStretchInRowAxis): Deleted.
+        (WebCore::defaultAlignmentChangedFromStretchInColumnAxis): Deleted.
+        (WebCore::selfAlignmentChangedToStretchInRowAxis): Deleted.
+        (WebCore::selfAlignmentChangedFromStretchInRowAxis): Deleted.
+        (WebCore::selfAlignmentChangedFromStretchInColumnAxis): Deleted.
+        * rendering/RenderGrid.h:
+        Removed the alignment change logic in styleDidChange for grids, since style diffing handles
+        it now. Updated all selfAlignmentForNormalBehavior queries to pass in the child so that
+        replaced elements are handled properly.
+
+        * rendering/style/RenderStyle.h:
+        (WebCore::RenderStyle::overflowInlineDirection):
+        (WebCore::RenderStyle::overflowBlockDirection):
+        (WebCore::RenderStyle::setJustifySelfPosition):
+        New helpers used by grid and by adjustRenderStyle.
+
+        * style/StyleChange.cpp:
+        (WebCore::Style::determineChange):
+        If alignment or justification changes occur on a parent that could affect the child (e.g., align-items)
+        return Inherit so the child render styles get adjusted properly.
+
 2017-03-06  Youenn Fablet  <youenn@apple.com>
 
         ASSERTION FAILED: numberOfChannels == 2 in WebCore::RealtimeIncomingAudioSource::OnData
index efe5628..5f84f2d 100644 (file)
@@ -1028,6 +1028,37 @@ void StyleResolver::adjustRenderStyle(RenderStyle& style, const RenderStyle& par
         if ((element->hasTagName(SVGNames::foreignObjectTag) || element->hasTagName(SVGNames::textTag)) && style.isDisplayInlineType())
             style.setDisplay(BLOCK);
     }
+    
+    adjustStyleForAlignment(style, parentStyle);
+}
+    
+void StyleResolver::adjustStyleForAlignment(RenderStyle& style, const RenderStyle& parentStyle)
+{
+    // To avoid needing to copy the StyleRareNonInheritedData, we repurpose the 'auto'
+    // flag to not just mean 'auto' prior to running adjustRenderStyle but also
+    // mean 'normal' after running it.
+    
+    // If the inherited value of justify-items includes the 'legacy' keyword,
+    // 'auto' computes to the the inherited value. Otherwise, 'auto' computes to
+    // 'normal'.
+    if (style.justifyItems().position() == ItemPositionAuto) {
+        if (parentStyle.justifyItems().positionType() == LegacyPosition)
+            style.setJustifyItems(parentStyle.justifyItems());
+    }
+    
+    // The 'auto' keyword computes the computed value of justify-items on the
+    // parent (minus any legacy keywords), or 'normal' if the box has no parent.
+    if (style.justifySelf().position() == ItemPositionAuto) {
+        if (parentStyle.justifyItems().positionType() == LegacyPosition)
+            style.setJustifySelfPosition(parentStyle.justifyItems().position());
+        else if (parentStyle.justifyItems().position() != ItemPositionAuto)
+            style.setJustifySelf(parentStyle.justifyItems());
+    }
+    
+    // The 'auto' keyword computes the computed value of align-items on the parent
+    // or 'normal' if the box has no parent.
+    if (style.alignSelf().position() == ItemPositionAuto && parentStyle.alignItems().position() != RenderStyle::initialDefaultAlignment().position())
+        style.setAlignSelf(parentStyle.alignItems());
 }
 
 bool StyleResolver::checkRegionStyle(const Element* regionElement)
index 02e6727..ec95702 100644 (file)
@@ -308,6 +308,10 @@ public:
         WritingMode m_writingMode;
     };
 
+    // FIXME: Should make a StyleAdjuster class (like Blink has) that handles all RenderStyle
+    // adjustments. For now put this function on StyleResolver, since adjustRenderStyle is here.
+    static void adjustStyleForAlignment(RenderStyle&, const RenderStyle& parentStyle);
+    
 private:
     // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
     void checkForGenericFamilyChange(RenderStyle*, const RenderStyle* parentStyle);
index 584da68..614fc1b 100644 (file)
@@ -75,7 +75,7 @@ Ref<TextControlInnerElement> TextControlInnerElement::create(Document& document)
     return adoptRef(*new TextControlInnerElement(document));
 }
 
-std::optional<ElementStyle> TextControlInnerElement::resolveCustomStyle(const RenderStyle&, const RenderStyle* shadowHostStyle)
+std::optional<ElementStyle> TextControlInnerElement::resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle* shadowHostStyle)
 {
     auto innerContainerStyle = RenderStyle::createPtr();
     innerContainerStyle->inheritFrom(*shadowHostStyle);
@@ -89,6 +89,8 @@ std::optional<ElementStyle> TextControlInnerElement::resolveCustomStyle(const Re
     // We don't want the shadow dom to be editable, so we set this block to read-only in case the input itself is editable.
     innerContainerStyle->setUserModify(READ_ONLY);
 
+    StyleResolver::adjustStyleForAlignment(*innerContainerStyle, parentStyle);
+
     return ElementStyle(WTFMove(innerContainerStyle));
 }
 
index 7412c65..fa7e71d 100644 (file)
@@ -793,8 +793,17 @@ LayoutUnit GridTrackSizingAlgorithmStrategy::minSizeForChild(RenderBox& child) c
     bool isRowAxis = direction() == childInlineDirection;
     const Length& childMinSize = isRowAxis ? child.style().logicalMinWidth() : child.style().logicalMinHeight();
     const Length& childSize = isRowAxis ? child.style().logicalWidth() : child.style().logicalHeight();
-    if (!childSize.isAuto() || childMinSize.isAuto())
+
+    bool overflowIsVisible = isRowAxis ? child.style().overflowInlineDirection() == OVISIBLE : child.style().overflowBlockDirection() == OVISIBLE;
+    if (!childSize.isAuto() || (childMinSize.isAuto() && overflowIsVisible)) {
+        if (child.isRenderReplaced() && childSize.isAuto()) {
+            // If the box has an aspect ratio and no specified size, its automatic
+            // minimum size is the smaller of its content size and its transferred
+            // size.
+            return isRowAxis ? std::min(child.intrinsicLogicalWidth(), minContentForChild(child)) : std::min(child.intrinsicLogicalHeight(), minContentForChild(child));
+        }
         return minContentForChild(child);
+    }
 
     bool overrideSizeHasChanged = updateOverrideContainingBlockContentSizeForChild(child, childInlineDirection);
 
index 3a1ba2a..0721d3b 100644 (file)
@@ -2565,9 +2565,10 @@ bool RenderBox::hasStretchedLogicalWidth() const
         // The 'normal' value behaves like 'start' except for Flexbox Items, which obviously should have a container.
         return false;
     }
+    const auto* parentStyle = isAnonymous() ? &containingBlock->style() : nullptr;
     if (containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode())
-        return style.resolvedAlignSelf(&containingBlock->style(), ItemPositionStretch).position() == ItemPositionStretch;
-    return style.resolvedJustifySelf(&containingBlock->style(), ItemPositionStretch).position() == ItemPositionStretch;
+        return style.resolvedAlignSelf(parentStyle, containingBlock->selfAlignmentNormalBehavior(this)).position() == ItemPositionStretch;
+    return style.resolvedJustifySelf(parentStyle, containingBlock->selfAlignmentNormalBehavior(this)).position() == ItemPositionStretch;
 }
 
 bool RenderBox::sizesLogicalWidthToFitContent(SizeType widthType) const
index 065547f..2f1bc1b 100644 (file)
@@ -637,7 +637,7 @@ protected:
 
     bool createsNewFormattingContext() const;
 
-    virtual ItemPosition selfAlignmentNormalBehavior() const { return ItemPositionStretch; }
+    virtual ItemPosition selfAlignmentNormalBehavior(const RenderBox* = nullptr) const { return ItemPositionStretch; }
 
     // Returns false if it could not cheaply compute the extent (e.g. fixed background), in which case the returned rect may be incorrect.
     bool getBackgroundPaintedExtent(const LayoutPoint& paintOffset, LayoutRect&) const;
index f319364..9be6084 100644 (file)
@@ -235,23 +235,6 @@ static const StyleContentAlignmentData& contentAlignmentNormalBehavior()
     return normalBehavior;
 }
 
-void RenderFlexibleBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
-    RenderBlock::styleDidChange(diff, oldStyle);
-
-    if (oldStyle && oldStyle->resolvedAlignItems(selfAlignmentNormalBehavior()).position() == ItemPositionStretch && diff == StyleDifferenceLayout) {
-        // Flex items that were previously stretching need to be relayed out so we can compute new available cross axis space.
-        // This is only necessary for stretching since other alignment values don't change the size of the box.
-        auto& newStyle = style();
-        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
-            auto& childStyle = child->style();
-            auto previousAlignment = childStyle.resolvedAlignSelf(oldStyle, selfAlignmentNormalBehavior()).position();
-            if (previousAlignment == ItemPositionStretch && previousAlignment != childStyle.resolvedAlignSelf(&newStyle, selfAlignmentNormalBehavior()).position())
-                child->setChildNeedsLayout(MarkOnlyThis);
-        }
-    }
-}
-
 void RenderFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit)
 {
     ASSERT(needsLayout());
@@ -1448,7 +1431,7 @@ void RenderFlexibleBox::prepareChildForPositionedLayout(RenderBox& child)
 
 ItemPosition RenderFlexibleBox::alignmentForChild(const RenderBox& child) const
 {
-    ItemPosition align = child.style().resolvedAlignSelf(&style(), selfAlignmentNormalBehavior()).position();
+    ItemPosition align = child.style().resolvedAlignSelf(child.isAnonymous() ? &style() : nullptr, selfAlignmentNormalBehavior()).position();
     ASSERT(align != ItemPositionAuto && align != ItemPositionNormal);
 
     if (align == ItemPositionBaseline && hasOrthogonalFlow(child))
index 988b705..b206039 100644 (file)
@@ -90,8 +90,6 @@ protected:
     void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
     void computePreferredLogicalWidths() override;
 
-    void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
-
 private:
     enum FlexSign {
         PositiveFlexibility,
index 749ce2e..a7dd6b6 100644 (file)
@@ -44,7 +44,7 @@ public:
     static RenderFullScreen* wrapRenderer(RenderObject*, RenderElement*, Document&);
     void unwrapRenderer(bool& requiresRenderTreeRebuild);
 
-    ItemPosition selfAlignmentNormalBehavior() const override { return ItemPositionCenter; }
+    ItemPosition selfAlignmentNormalBehavior(const RenderBox* = nullptr) const override { return ItemPositionCenter; }
     
 private:
     bool isRenderFullScreen() const override { return true; }
index be5b0d2..d90946d 100644 (file)
@@ -65,41 +65,6 @@ RenderGrid::~RenderGrid()
 {
 }
 
-static inline bool defaultAlignmentIsStretch(ItemPosition position)
-{
-    return position == ItemPositionStretch || position == ItemPositionAuto;
-}
-
-static inline bool defaultAlignmentChangedToStretchInRowAxis(const RenderStyle& oldStyle, const RenderStyle& newStyle)
-{
-    return !defaultAlignmentIsStretch(oldStyle.justifyItems().position()) && defaultAlignmentIsStretch(newStyle.justifyItems().position());
-}
-
-static inline bool defaultAlignmentChangedFromStretchInRowAxis(const RenderStyle& oldStyle, const RenderStyle& newStyle)
-{
-    return defaultAlignmentIsStretch(oldStyle.justifyItems().position()) && !defaultAlignmentIsStretch(newStyle.justifyItems().position());
-}
-
-static inline bool defaultAlignmentChangedFromStretchInColumnAxis(const RenderStyle& oldStyle, const RenderStyle& newStyle)
-{
-    return defaultAlignmentIsStretch(oldStyle.alignItems().position()) && !defaultAlignmentIsStretch(newStyle.alignItems().position());
-}
-
-static inline bool selfAlignmentChangedToStretchInRowAxis(const RenderStyle& oldStyle, const RenderStyle& newStyle, const RenderStyle& childStyle, ItemPosition selfAlignNormalBehavior)
-{
-    return childStyle.resolvedJustifySelf(&oldStyle, selfAlignNormalBehavior).position() != ItemPositionStretch && childStyle.resolvedJustifySelf(&newStyle, selfAlignNormalBehavior).position() == ItemPositionStretch;
-}
-
-static inline bool selfAlignmentChangedFromStretchInRowAxis(const RenderStyle& oldStyle, const RenderStyle& newStyle, const RenderStyle& childStyle, ItemPosition selfAlignNormalBehavior)
-{
-    return childStyle.resolvedJustifySelf(&oldStyle, selfAlignNormalBehavior).position() == ItemPositionStretch && childStyle.resolvedJustifySelf(&newStyle, selfAlignNormalBehavior).position() != ItemPositionStretch;
-}
-
-static inline bool selfAlignmentChangedFromStretchInColumnAxis(const RenderStyle& oldStyle, const RenderStyle& newStyle, const RenderStyle& childStyle, ItemPosition selfAlignNormalBehavior)
-{
-    return childStyle.resolvedAlignSelf(&oldStyle, selfAlignNormalBehavior).position() == ItemPositionStretch && childStyle.resolvedAlignSelf(&newStyle, selfAlignNormalBehavior).position() != ItemPositionStretch;
-}
-
 void RenderGrid::addChild(RenderObject* newChild, RenderObject* beforeChild)
 {
     RenderBlock::addChild(newChild, beforeChild);
@@ -124,22 +89,6 @@ void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl
     if (!oldStyle || diff != StyleDifferenceLayout)
         return;
 
-    const RenderStyle& newStyle = style();
-    if (defaultAlignmentChangedToStretchInRowAxis(*oldStyle, newStyle) || defaultAlignmentChangedFromStretchInRowAxis(*oldStyle, newStyle)
-        || defaultAlignmentChangedFromStretchInColumnAxis(*oldStyle, newStyle)) {
-        // Grid items that were not previously stretched in row-axis need to be relayed out so we can compute new available space.
-        // Grid items that were previously stretching in column-axis need to be relayed out so we can compute new available space.
-        // This is only necessary for stretching since other alignment values don't change the size of the box.
-        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
-            if (child->isOutOfFlowPositioned())
-                continue;
-            if (selfAlignmentChangedToStretchInRowAxis(*oldStyle, newStyle, child->style(), selfAlignmentNormalBehavior()) || selfAlignmentChangedFromStretchInRowAxis(*oldStyle, newStyle, child->style(), selfAlignmentNormalBehavior())
-                || selfAlignmentChangedFromStretchInColumnAxis(*oldStyle, newStyle, child->style(), selfAlignmentNormalBehavior())) {
-                child->setChildNeedsLayout(MarkOnlyThis);
-            }
-        }
-    }
-
     if (explicitGridDidResize(*oldStyle) || namedGridLinesDefinitionDidChange(*oldStyle) || oldStyle->gridAutoFlow() != style().gridAutoFlow()
         || (style().gridAutoRepeatColumns().size() || style().gridAutoRepeatRows().size()))
         dirtyGrid();
@@ -1179,12 +1128,24 @@ LayoutUnit RenderGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUni
 
 StyleSelfAlignmentData RenderGrid::alignSelfForChild(const RenderBox& child) const
 {
-    return child.style().resolvedAlignSelf(&style(), selfAlignmentNormalBehavior());
+    if (!child.isAnonymous())
+        return child.style().resolvedAlignSelf(nullptr, selfAlignmentNormalBehavior(&child));
+
+    // All the 'auto' values have been resolved by the StyleAdjuster, but it's
+    // possible that some grid items generate Anonymous boxes, which need to be
+    // solved during layout.
+    return child.style().resolvedAlignSelf(&style(), selfAlignmentNormalBehavior(&child));
 }
 
 StyleSelfAlignmentData RenderGrid::justifySelfForChild(const RenderBox& child) const
 {
-    return child.style().resolvedJustifySelf(&style(), selfAlignmentNormalBehavior());
+    if (!child.isAnonymous())
+        return child.style().resolvedJustifySelf(nullptr, selfAlignmentNormalBehavior(&child));
+    
+    // All the 'auto' values have been resolved by the StyleAdjuster, but it's
+    // possible that some grid items generate Anonymous boxes, which need to be
+    // solved during layout.
+    return child.style().resolvedJustifySelf(&style(), selfAlignmentNormalBehavior(&child));
 }
 
 // FIXME: This logic is shared by RenderFlexibleBox, so it should be moved to RenderBox.
@@ -1345,7 +1306,7 @@ GridAxisPosition RenderGrid::columnAxisPositionForChild(const RenderBox& child)
     bool hasSameWritingMode = child.style().writingMode() == style().writingMode();
     bool childIsLTR = child.style().isLeftToRightDirection();
 
-    switch (child.style().resolvedAlignSelf(&style(), selfAlignmentNormalBehavior()).position()) {
+    switch (alignSelfForChild(child).position()) {
     case ItemPositionSelfStart:
         // FIXME: Should we implement this logic in a generic utility function ?
         // Aligns the alignment subject to be flush with the edge of the alignment container
@@ -1410,7 +1371,7 @@ GridAxisPosition RenderGrid::rowAxisPositionForChild(const RenderBox& child) con
     bool hasSameDirection = child.style().direction() == style().direction();
     bool gridIsLTR = style().isLeftToRightDirection();
 
-    switch (child.style().resolvedJustifySelf(&style(), selfAlignmentNormalBehavior()).position()) {
+    switch (justifySelfForChild(child).position()) {
     case ItemPositionSelfStart:
         // FIXME: Should we implement this logic in a generic utility function ?
         // Aligns the alignment subject to be flush with the edge of the alignment container
@@ -1492,7 +1453,7 @@ LayoutUnit RenderGrid::columnAxisOffsetForChild(const RenderBox& child) const
         if (childEndLine < m_rowPositions.size() - 1)
             endOfRow -= gridGapForDirection(ForRows, TrackSizing) + m_offsetBetweenRows;
         LayoutUnit columnAxisChildSize = isOrthogonalChild(child) ? child.logicalWidth() + child.marginLogicalWidth() : child.logicalHeight() + child.marginLogicalHeight();
-        auto overflow = child.style().resolvedAlignSelf(&style(), selfAlignmentNormalBehavior()).overflow();
+        auto overflow = alignSelfForChild(child).overflow();
         LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(overflow, endOfRow - startOfRow, columnAxisChildSize);
         return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPosition : offsetFromStartPosition / 2);
     }
@@ -1524,7 +1485,7 @@ LayoutUnit RenderGrid::rowAxisOffsetForChild(const RenderBox& child) const
         if (childEndLine < m_columnPositions.size() - 1)
             endOfColumn -= gridGapForDirection(ForColumns, TrackSizing) + m_offsetBetweenColumns;
         LayoutUnit rowAxisChildSize = isOrthogonalChild(child) ? child.logicalHeight() + child.marginLogicalHeight() : child.logicalWidth() + child.marginLogicalWidth();
-        auto overflow = child.style().resolvedJustifySelf(&style(), selfAlignmentNormalBehavior()).overflow();
+        auto overflow = justifySelfForChild(child).overflow();
         LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(overflow, endOfColumn - startOfColumn, rowAxisChildSize);
         return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPosition : offsetFromStartPosition / 2);
     }
index 0727f32..5faf435 100644 (file)
@@ -63,6 +63,14 @@ public:
     // Required by GridTrackSizingAlgorithm. Keep them under control.
     bool isOrthogonalChild(const RenderBox&) const;
     LayoutUnit guttersSize(const Grid&, GridTrackSizingDirection, unsigned startLine, unsigned span, SizingOperation) const;
+    
+protected:
+    ItemPosition selfAlignmentNormalBehavior(const RenderBox* child = nullptr) const override
+    {
+        ASSERT(child);
+        return child->isRenderReplaced() ? ItemPositionStart : ItemPositionStretch;
+    }
+
 private:
     const char* renderName() const override;
     bool isRenderGrid() const override { return true; }
index 224b302..f200d6b 100644 (file)
@@ -323,7 +323,9 @@ public:
     
     EOverflow overflowX() const { return m_nonInheritedFlags.overflowX(); }
     EOverflow overflowY() const { return m_nonInheritedFlags.overflowY(); }
-
+    EOverflow overflowInlineDirection() const { return isHorizontalWritingMode() ? overflowX() : overflowY(); }
+    EOverflow overflowBlockDirection() const { return isHorizontalWritingMode() ? overflowY() : overflowX(); }
+    
     EVisibility visibility() const { return static_cast<EVisibility>(m_inheritedFlags.visibility); }
     EVerticalAlign verticalAlign() const { return m_nonInheritedFlags.verticalAlign(); }
     const Length& verticalAlignLength() const { return m_boxData->verticalAlign(); }
@@ -1055,6 +1057,7 @@ public:
     void setJustifyContentPosition(ContentPosition position) { m_rareNonInheritedData.access().justifyContent.setPosition(position); }
     void setJustifyItems(const StyleSelfAlignmentData& data) { SET_VAR(m_rareNonInheritedData, justifyItems, data); }
     void setJustifySelf(const StyleSelfAlignmentData& data) { SET_VAR(m_rareNonInheritedData, justifySelf, data); }
+    void setJustifySelfPosition(ItemPosition position) { m_rareNonInheritedData.access().justifySelf.setPosition(position); }
 
 #if ENABLE(CSS_BOX_DECORATION_BREAK)
     void setBoxDecorationBreak(EBoxDecorationBreak b) { SET_VAR(m_boxData, m_boxDecorationBreak, b); }
index ac850ac..1980431 100644 (file)
@@ -64,8 +64,12 @@ Change determineChange(const RenderStyle& s1, const RenderStyle& s2)
         if (s1.inheritedNotEqual(&s2))
             return Inherit;
 
+        if (s1.alignItems() != s2.alignItems() || s1.justifyItems() != s2.justifyItems())
+            return Inherit;
+
         return NoInherit;
     }
+
     // If the pseudoStyles have changed, we want any StyleChange that is not NoChange
     // because setStyle will do the right thing with anything else.
     if (s1.hasAnyPublicPseudoStyles()) {