Title: [249873] trunk/Source/WebCore
Revision
249873
Author
za...@apple.com
Date
2019-09-14 06:55:34 -0700 (Sat, 14 Sep 2019)

Log Message

[LFC] FormattingContext::Geometry::computedHeightValue should not read containing block's height.
https://bugs.webkit.org/show_bug.cgi?id=201791
<rdar://problem/55361695>

Reviewed by Antti Koivisto.

While sizing/positioning a particular box, we oftentimes need some containing block geometry information.
The idea here is that instead of calling formattingContext().geometry(containingBlock), these constraint values
would be pushed in to those compute* functions. It helps controlling the access to the display box tree and
prevents formatting context escaping.

* layout/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry):
* layout/FormattingContext.h:
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::computedHeightValue const):
(WebCore::Layout::FormattingContext::Geometry::computedMaxHeight const):
(WebCore::Layout::FormattingContext::Geometry::computedMinHeight const):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry const):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry const):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowVerticalGeometry const):
(WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin const):
* layout/LayoutUnits.h:
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::computeHeightAndMargin):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (249872 => 249873)


--- trunk/Source/WebCore/ChangeLog	2019-09-14 10:11:23 UTC (rev 249872)
+++ trunk/Source/WebCore/ChangeLog	2019-09-14 13:55:34 UTC (rev 249873)
@@ -1,3 +1,31 @@
+2019-09-14  Zalan Bujtas  <za...@apple.com>
+
+        [LFC] FormattingContext::Geometry::computedHeightValue should not read containing block's height.
+        https://bugs.webkit.org/show_bug.cgi?id=201791
+        <rdar://problem/55361695>
+
+        Reviewed by Antti Koivisto.
+
+        While sizing/positioning a particular box, we oftentimes need some containing block geometry information.
+        The idea here is that instead of calling formattingContext().geometry(containingBlock), these constraint values
+        would be pushed in to those compute* functions. It helps controlling the access to the display box tree and
+        prevents formatting context escaping.
+
+        * layout/FormattingContext.cpp:
+        (WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry):
+        * layout/FormattingContext.h:
+        * layout/FormattingContextGeometry.cpp:
+        (WebCore::Layout::FormattingContext::Geometry::computedHeightValue const):
+        (WebCore::Layout::FormattingContext::Geometry::computedMaxHeight const):
+        (WebCore::Layout::FormattingContext::Geometry::computedMinHeight const):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry const):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry const):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowVerticalGeometry const):
+        (WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin const):
+        * layout/LayoutUnits.h:
+        * layout/blockformatting/BlockFormattingContext.cpp:
+        (WebCore::Layout::BlockFormattingContext::computeHeightAndMargin):
+
 2019-09-11  Dean Jackson  <d...@apple.com>
 
         Provide a prototype for AR QuickLook to trigger processing in the originating page

Modified: trunk/Source/WebCore/layout/FormattingContext.cpp (249872 => 249873)


--- trunk/Source/WebCore/layout/FormattingContext.cpp	2019-09-14 10:11:23 UTC (rev 249872)
+++ trunk/Source/WebCore/layout/FormattingContext.cpp	2019-09-14 13:55:34 UTC (rev 249873)
@@ -95,19 +95,22 @@
 
 void FormattingContext::computeOutOfFlowVerticalGeometry(const Box& layoutBox)
 {
-    auto compute = [&](UsedVerticalValues usedValues) {
-        return geometry().outOfFlowVerticalGeometry(layoutBox, usedValues);
+    auto compute = [&](auto usedVerticalValues) {
+        return geometry().outOfFlowVerticalGeometry(layoutBox, usedVerticalValues);
     };
-
-    auto verticalGeometry = compute({ });
-    if (auto maxHeight = geometry().computedMaxHeight(layoutBox)) {
-        auto maxVerticalGeometry = compute({ *maxHeight });
+    auto containingBlockHeight = geometryForBox(*layoutBox.containingBlock()).paddingBoxHeight();
+    auto usedVerticalValuesForHeight = UsedVerticalValues { containingBlockHeight, { } };
+    auto verticalGeometry = compute(usedVerticalValuesForHeight);
+    if (auto maxHeight = geometry().computedMaxHeight(layoutBox, usedVerticalValuesForHeight)) {
+        auto usedValuesForMaxHeight = UsedVerticalValues { containingBlockHeight, maxHeight };
+        auto maxVerticalGeometry = compute(usedValuesForMaxHeight);
         if (verticalGeometry.heightAndMargin.height > maxVerticalGeometry.heightAndMargin.height)
             verticalGeometry = maxVerticalGeometry;
     }
 
-    if (auto minHeight = geometry().computedMinHeight(layoutBox)) {
-        auto minVerticalGeometry = compute({ *minHeight });
+    if (auto minHeight = geometry().computedMinHeight(layoutBox, usedVerticalValuesForHeight)) {
+        auto usedValuesForMinHeight = UsedVerticalValues { containingBlockHeight, minHeight };
+        auto minVerticalGeometry = compute(usedValuesForMinHeight);
         if (verticalGeometry.heightAndMargin.height < minVerticalGeometry.heightAndMargin.height)
             verticalGeometry = minVerticalGeometry;
     }

Modified: trunk/Source/WebCore/layout/FormattingContext.h (249872 => 249873)


--- trunk/Source/WebCore/layout/FormattingContext.h	2019-09-14 10:11:23 UTC (rev 249872)
+++ trunk/Source/WebCore/layout/FormattingContext.h	2019-09-14 13:55:34 UTC (rev 249873)
@@ -118,8 +118,8 @@
         Optional<LayoutUnit> computedValueIfNotAuto(const Length& geometryProperty, LayoutUnit containingBlockWidth) const;
         Optional<LayoutUnit> fixedValue(const Length& geometryProperty) const;
 
-        Optional<LayoutUnit> computedMinHeight(const Box&) const;
-        Optional<LayoutUnit> computedMaxHeight(const Box&) const;
+        Optional<LayoutUnit> computedMinHeight(const Box&, Optional<UsedVerticalValues> = WTF::nullopt) const;
+        Optional<LayoutUnit> computedMaxHeight(const Box&, Optional<UsedVerticalValues> = WTF::nullopt) const;
 
         FormattingContext::IntrinsicWidthConstraints constrainByMinMaxWidth(const Box&, IntrinsicWidthConstraints) const;
 
@@ -127,7 +127,7 @@
 
     protected:
         enum class HeightType { Min, Max, Normal };
-        Optional<LayoutUnit> computedHeightValue(const Box&, HeightType) const;
+        Optional<LayoutUnit> computedHeightValue(const Box&, HeightType, Optional<UsedVerticalValues> = WTF::nullopt) const;
 
         const LayoutState& layoutState() const { return m_formattingContext.layoutState(); }
         LayoutState& layoutState() { return m_formattingContext.layoutState(); }

Modified: trunk/Source/WebCore/layout/FormattingContextGeometry.cpp (249872 => 249873)


--- trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2019-09-14 10:11:23 UTC (rev 249872)
+++ trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2019-09-14 13:55:34 UTC (rev 249873)
@@ -59,7 +59,7 @@
     return false;
 }
 
-Optional<LayoutUnit> FormattingContext::Geometry::computedHeightValue(const Box& layoutBox, HeightType heightType) const
+Optional<LayoutUnit> FormattingContext::Geometry::computedHeightValue(const Box& layoutBox, HeightType heightType, Optional<UsedVerticalValues> usedVerticalValues) const
 {
     auto& style = layoutBox.style();
     auto height = heightType == HeightType::Normal ? style.logicalHeight() : heightType == HeightType::Min ? style.logicalMinHeight() : style.logicalMaxHeight();
@@ -67,12 +67,13 @@
         return { };
 
     if (height.isFixed())
-        return LayoutUnit(height.value());
+        return LayoutUnit { height.value() };
 
     Optional<LayoutUnit> containingBlockHeightValue;
-    if (layoutBox.isOutOfFlowPositioned()) {
+    if (usedVerticalValues && usedVerticalValues->containingBlockHeight) {
+        ASSERT(layoutBox.isOutOfFlowPositioned());
         // Containing block's height is already computed since we layout the out-of-flow boxes as the last step.
-        containingBlockHeightValue = formattingContext().geometryForBox(*layoutBox.containingBlock()).height();
+        containingBlockHeightValue = *usedVerticalValues->containingBlockHeight;
     } else {
         if (layoutState().inQuirksMode())
             containingBlockHeightValue = formattingContext().quirks().heightValueOfNearestContainingBlockWithFixedHeight(layoutBox);
@@ -171,17 +172,17 @@
 // Specifies a percentage for determining the used value. The percentage is calculated with respect to the height of the generated box's containing block.
 // If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned,
 // the percentage value is treated as '0' (for 'min-height') or 'none' (for 'max-height').
-Optional<LayoutUnit> FormattingContext::Geometry::computedMaxHeight(const Box& layoutBox) const
+Optional<LayoutUnit> FormattingContext::Geometry::computedMaxHeight(const Box& layoutBox, Optional<UsedVerticalValues> usedVerticalValues) const
 {
-    return computedHeightValue(layoutBox, HeightType::Max);
+    return computedHeightValue(layoutBox, HeightType::Max, usedVerticalValues);
 }
 
-Optional<LayoutUnit> FormattingContext::Geometry::computedMinHeight(const Box& layoutBox) const
+Optional<LayoutUnit> FormattingContext::Geometry::computedMinHeight(const Box& layoutBox, Optional<UsedVerticalValues> usedVerticalValues) const
 {
-    if (auto minHeightValue = computedHeightValue(layoutBox, HeightType::Min))
+    if (auto minHeightValue = computedHeightValue(layoutBox, HeightType::Min, usedVerticalValues))
         return minHeightValue;
 
-    return { 0 };
+    return { LayoutUnit { } };
 }
 
 LayoutUnit FormattingContext::Geometry::staticVerticalPositionForOutOfFlowPositioned(const Box& layoutBox) const
@@ -271,9 +272,10 @@
     return std::min(std::max(intrinsicWidthConstraints.minimum, availableWidth), intrinsicWidthConstraints.maximum);
 }
 
-VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry(const Box& layoutBox, UsedVerticalValues usedValues) const
+VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry(const Box& layoutBox, UsedVerticalValues usedVerticalValues) const
 {
     ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced());
+    ASSERT(usedVerticalValues.containingBlockHeight);
 
     // 10.6.4 Absolutely positioned, non-replaced elements
     //
@@ -303,12 +305,12 @@
     auto& style = layoutBox.style();
     auto& boxGeometry = formattingContext.geometryForBox(layoutBox);
     auto& containingBlockGeometry = formattingContext.geometryForBox(*layoutBox.containingBlock());
-    auto containingBlockHeight = containingBlockGeometry.paddingBoxHeight();
+    auto containingBlockHeight = *usedVerticalValues.containingBlockHeight;
     auto containingBlockWidth = containingBlockGeometry.paddingBoxWidth();
 
     auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
     auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
-    auto height = usedValues.height ? usedValues.height.value() : computedHeightValue(layoutBox, HeightType::Normal);
+    auto height = usedVerticalValues.height ? usedVerticalValues.height.value() : computedHeightValue(layoutBox, HeightType::Normal, usedVerticalValues);
     auto computedVerticalMargin = Geometry::computedVerticalMargin(layoutBox, UsedHorizontalValues { containingBlockWidth });
     UsedVerticalMargin::NonCollapsedValues usedVerticalMargin; 
     auto paddingTop = boxGeometry.paddingTop().valueOr(0);
@@ -544,7 +546,7 @@
     return { *left, *right, { contentWidth(), usedHorizontalMargin, computedHorizontalMargin } };
 }
 
-VerticalGeometry FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry(const Box& layoutBox, UsedVerticalValues usedValues) const
+VerticalGeometry FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry(const Box& layoutBox, UsedVerticalValues usedVerticalValues) const
 {
     ASSERT(layoutBox.isOutOfFlowPositioned() && layoutBox.replaced());
 
@@ -567,7 +569,7 @@
 
     auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
     auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
-    auto height = inlineReplacedHeightAndMargin(layoutBox, usedValues).height;
+    auto height = inlineReplacedHeightAndMargin(layoutBox, usedVerticalValues).height;
     auto computedVerticalMargin = Geometry::computedVerticalMargin(layoutBox, UsedHorizontalValues { containingBlockWidth });
     Optional<LayoutUnit> usedMarginBefore = computedVerticalMargin.before;
     Optional<LayoutUnit> usedMarginAfter = computedVerticalMargin.after;
@@ -809,13 +811,13 @@
         usedValues.width, UsedHorizontalMargin { computedHorizontalMargin.start.valueOr(0), computedHorizontalMargin.end.valueOr(0) } });
 }
 
-VerticalGeometry FormattingContext::Geometry::outOfFlowVerticalGeometry(const Box& layoutBox, UsedVerticalValues usedValues) const
+VerticalGeometry FormattingContext::Geometry::outOfFlowVerticalGeometry(const Box& layoutBox, UsedVerticalValues usedVerticalValues) const
 {
     ASSERT(layoutBox.isOutOfFlowPositioned());
 
     if (!layoutBox.replaced())
-        return outOfFlowNonReplacedVerticalGeometry(layoutBox, usedValues);
-    return outOfFlowReplacedVerticalGeometry(layoutBox, usedValues);
+        return outOfFlowNonReplacedVerticalGeometry(layoutBox, usedVerticalValues);
+    return outOfFlowReplacedVerticalGeometry(layoutBox, usedVerticalValues);
 }
 
 HorizontalGeometry FormattingContext::Geometry::outOfFlowHorizontalGeometry(const Box& layoutBox, UsedHorizontalValues usedValues)
@@ -845,7 +847,7 @@
     return floatingReplacedWidthAndMargin(layoutBox, usedValues);
 }
 
-HeightAndMargin FormattingContext::Geometry::inlineReplacedHeightAndMargin(const Box& layoutBox, UsedVerticalValues usedValues) const
+HeightAndMargin FormattingContext::Geometry::inlineReplacedHeightAndMargin(const Box& layoutBox, UsedVerticalValues usedVerticalValues) const
 {
     ASSERT((layoutBox.isOutOfFlowPositioned() || layoutBox.isFloatingPositioned() || layoutBox.isInFlow()) && layoutBox.replaced());
 
@@ -867,8 +869,8 @@
     auto& style = layoutBox.style();
     auto replaced = layoutBox.replaced();
 
-    auto height = usedValues.height ? usedValues.height.value() : computedHeightValue(layoutBox, HeightType::Normal);
-    auto heightIsAuto = !usedValues.height && isHeightAuto(layoutBox);
+    auto height = usedVerticalValues.height ? usedVerticalValues.height.value() : computedHeightValue(layoutBox, HeightType::Normal, usedVerticalValues);
+    auto heightIsAuto = !usedVerticalValues.height && isHeightAuto(layoutBox);
     auto widthIsAuto = style.logicalWidth().isAuto();
 
     if (heightIsAuto && widthIsAuto && replaced->hasIntrinsicHeight()) {

Modified: trunk/Source/WebCore/layout/LayoutUnits.h (249872 => 249873)


--- trunk/Source/WebCore/layout/LayoutUnits.h	2019-09-14 10:11:23 UTC (rev 249872)
+++ trunk/Source/WebCore/layout/LayoutUnits.h	2019-09-14 13:55:34 UTC (rev 249873)
@@ -160,6 +160,7 @@
 };
 
 struct UsedVerticalValues {
+    Optional<LayoutUnit> containingBlockHeight;
     Optional<LayoutUnit> height;
 };
 

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp (249872 => 249873)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2019-09-14 10:11:23 UTC (rev 249872)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2019-09-14 13:55:34 UTC (rev 249873)
@@ -384,7 +384,7 @@
 
 void BlockFormattingContext::computeHeightAndMargin(const Box& layoutBox)
 {
-    auto compute = [&](UsedVerticalValues usedValues) -> HeightAndMargin {
+    auto compute = [&](auto usedValues) -> HeightAndMargin {
 
         if (layoutBox.isInFlow())
             return geometry().inFlowHeightAndMargin(layoutBox, usedValues);
@@ -396,10 +396,10 @@
         return { };
     };
 
-    auto heightAndMargin = compute({ });
+    auto heightAndMargin = compute(UsedVerticalValues { });
     if (auto maxHeight = geometry().computedMaxHeight(layoutBox)) {
         if (heightAndMargin.height > *maxHeight) {
-            auto maxHeightAndMargin = compute({ *maxHeight });
+            auto maxHeightAndMargin = compute(UsedVerticalValues { { }, *maxHeight });
             // Used height should remain the same.
             ASSERT((layoutState().inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || maxHeightAndMargin.height == *maxHeight);
             heightAndMargin = { *maxHeight, maxHeightAndMargin.nonCollapsedMargin };
@@ -408,7 +408,7 @@
 
     if (auto minHeight = geometry().computedMinHeight(layoutBox)) {
         if (heightAndMargin.height < *minHeight) {
-            auto minHeightAndMargin = compute({ *minHeight });
+            auto minHeightAndMargin = compute(UsedVerticalValues { { }, *minHeight });
             // Used height should remain the same.
             ASSERT((layoutState().inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || minHeightAndMargin.height == *minHeight);
             heightAndMargin = { *minHeight, minHeightAndMargin.nonCollapsedMargin };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to