Modified: trunk/Source/WebCore/ChangeLog (233258 => 233259)
--- trunk/Source/WebCore/ChangeLog 2018-06-27 16:13:43 UTC (rev 233258)
+++ trunk/Source/WebCore/ChangeLog 2018-06-27 16:13:48 UTC (rev 233259)
@@ -1,3 +1,23 @@
+2018-06-27 Zalan Bujtas <[email protected]>
+
+ [LFC] Compute static position for out-of-flow elements only when required.
+ https://bugs.webkit.org/show_bug.cgi?id=187096
+
+ Reviewed by Antti Koivisto.
+
+ Computing static position for out-of-flow elements could be somewhat expensive, so let's not do it unless we actually need it.
+
+ * layout/FormattingContextGeometry.cpp:
+ (WebCore::Layout::staticVerticalPositionForOutOfFlowPositioned):
+ (WebCore::Layout::staticHorizontalPositionForOutOfFlowPositioned):
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry):
+ * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+ (WebCore::Layout::BlockFormattingContext::Geometry::staticPosition):
+ (WebCore::Layout::BlockFormattingContext::Geometry::staticPositionForOutOfFlowPositioned): Deleted.
+
2018-06-27 Nan Wang <[email protected]>
AX: [iOS] Remove the ability to set keyboard focus when VoiceOver takes focus
Modified: trunk/Source/WebCore/layout/FormattingContextGeometry.cpp (233258 => 233259)
--- trunk/Source/WebCore/layout/FormattingContextGeometry.cpp 2018-06-27 16:13:43 UTC (rev 233258)
+++ trunk/Source/WebCore/layout/FormattingContextGeometry.cpp 2018-06-27 16:13:48 UTC (rev 233259)
@@ -75,6 +75,45 @@
return valueForLength(geometryProperty, containingBlockWidth);
}
+static LayoutUnit staticVerticalPositionForOutOfFlowPositioned(const LayoutContext& layoutContext, const Box& layoutBox)
+{
+ ASSERT(layoutBox.isOutOfFlowPositioned());
+
+ LayoutUnit top;
+ // Resolve top all the way up to the containing block.
+ auto* containingBlock = layoutBox.containingBlock();
+ for (auto* parent = layoutBox.parent(); parent; parent = parent->parent()) {
+ auto& displayBox = *layoutContext.displayBoxForLayoutBox(*parent);
+ top += (displayBox.top() + displayBox.contentBoxTop());
+ if (parent == containingBlock)
+ break;
+ }
+ // Add sibling offset
+ if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {
+ auto& previousInFlowDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
+ top += previousInFlowDisplayBox.bottom() + previousInFlowDisplayBox.marginBottom();
+ }
+ // FIXME: floatings need to be taken into account.
+ return top;
+}
+
+static LayoutUnit staticHorizontalPositionForOutOfFlowPositioned(const LayoutContext& layoutContext, const Box& layoutBox)
+{
+ ASSERT(layoutBox.isOutOfFlowPositioned());
+
+ LayoutUnit left;
+ // Resolve left all the way up to the containing block.
+ auto* containingBlock = layoutBox.containingBlock();
+ for (auto* parent = layoutBox.parent(); parent; parent = parent->parent()) {
+ auto& displayBox = *layoutContext.displayBoxForLayoutBox(*parent);
+ left += (displayBox.left() + displayBox.contentBoxLeft());
+ if (parent == containingBlock)
+ break;
+ }
+ // FIXME: floatings need to be taken into account.
+ return left;
+}
+
FormattingContext::Geometry::VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry(LayoutContext& layoutContext, const Box& layoutBox)
{
ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced());
@@ -120,7 +159,7 @@
auto borderBottom = displayBox.borderBottom();
if (!top && !height && !bottom)
- top = displayBox.top();
+ top = staticVerticalPositionForOutOfFlowPositioned(layoutContext, layoutBox);
if (top && height && bottom) {
if (!marginTop && !marginBottom) {
@@ -146,7 +185,7 @@
if (!top && !bottom && height) {
// #2
- top = displayBox.top();
+ top = staticVerticalPositionForOutOfFlowPositioned(layoutContext, layoutBox);
marginTop = marginTop.value_or(0);
marginBottom = marginBottom.value_or(0);
bottom = containingBlockHeight - (*top + *marginTop + borderTop + paddingTop + *height + paddingBottom + borderBottom + *marginBottom);
@@ -244,10 +283,11 @@
marginLeft = marginLeft.value_or(0);
marginRight = marginRight.value_or(0);
+ auto staticHorizontalPosition = staticHorizontalPositionForOutOfFlowPositioned(layoutContext, layoutBox);
if (isLeftToRightDirection)
- left = displayBox.left();
+ left = staticHorizontalPosition;
else
- right = displayBox.right();
+ right = staticHorizontalPosition;
} else if (left && width && right) {
// If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values,
// unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and
@@ -301,11 +341,12 @@
left = containingBlockWidth - (*marginLeft + borderLeft + paddingLeft + *width + paddingRight + borderRight + *marginRight + *right);
} else if (!left && !right && width) {
// #2
+ auto staticHorizontalPosition = staticHorizontalPositionForOutOfFlowPositioned(layoutContext, layoutBox);
if (isLeftToRightDirection) {
- left = displayBox.left();
+ left = staticHorizontalPosition;
right = containingBlockWidth - (*left + *marginLeft + borderLeft + paddingLeft + *width + paddingRight + borderRight + *marginRight);
} else {
- right = displayBox.right();
+ right = staticHorizontalPosition;
left = containingBlockWidth - (*marginLeft + borderLeft + paddingLeft + *width + paddingRight + borderRight + *marginRight + *right);
}
} else if (!width && !right && left) {
@@ -365,7 +406,7 @@
if (!top && !bottom) {
// #1
- top = displayBox.top();
+ top = staticVerticalPositionForOutOfFlowPositioned(layoutContext, layoutBox);
}
if (!bottom) {
@@ -438,10 +479,11 @@
if (!left && !right) {
// #1
+ auto staticHorizontalPosition = staticHorizontalPositionForOutOfFlowPositioned(layoutContext, layoutBox);
if (isLeftToRightDirection)
- left = displayBox.left();
+ left = staticHorizontalPosition;
else
- right = displayBox.right();
+ right = staticHorizontalPosition;
}
if (!left || !right) {
Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp (233258 => 233259)
--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp 2018-06-27 16:13:43 UTC (rev 233258)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp 2018-06-27 16:13:48 UTC (rev 233259)
@@ -265,31 +265,6 @@
return { width, margin };
}
-FormattingContext::Geometry::Position BlockFormattingContext::Geometry::staticPositionForOutOfFlowPositioned(const LayoutContext& layoutContext, const Box& layoutBox)
-{
- // FIXME: This is certainly only really needed when top/bottom left/right are auto.
- ASSERT(layoutBox.isOutOfFlowPositioned());
- LayoutUnit top;
- LayoutUnit left;
- // Resolve top/left all the way up to the containing block.
- auto* containingBlock = layoutBox.containingBlock();
- for (auto* parent = layoutBox.parent(); parent; parent = parent->parent()) {
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(*parent);
- top += (displayBox.top() + displayBox.contentBoxTop());
- left += (displayBox.left() + displayBox.contentBoxLeft());
- if (parent == containingBlock)
- break;
- }
- // Add sibling offset
- if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {
- auto& previousInFlowDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
- top += previousInFlowDisplayBox.bottom() + previousInFlowDisplayBox.marginBottom();
- }
-
- LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position] -> out-of-flow -> static -> top(" << top << "px) left(" << left << "px) layoutBox(" << &layoutBox << ")");
- return { left, top };
-}
-
FormattingContext::Geometry::Position BlockFormattingContext::Geometry::staticPosition(LayoutContext& layoutContext, const Box& layoutBox)
{
// https://www.w3.org/TR/CSS22/visuren.html#block-formatting
@@ -298,9 +273,6 @@
// Vertical margins between adjacent block-level boxes in a block formatting context collapse.
// In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch).
- if (layoutBox.isOutOfFlowPositioned())
- return staticPositionForOutOfFlowPositioned(layoutContext, layoutBox);
-
LayoutUnit top;
auto& containingBlockDisplayBox = *layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {