Diff
Modified: trunk/Source/WebCore/ChangeLog (231846 => 231847)
--- trunk/Source/WebCore/ChangeLog 2018-05-16 14:49:55 UTC (rev 231846)
+++ trunk/Source/WebCore/ChangeLog 2018-05-16 14:51:39 UTC (rev 231847)
@@ -1,5 +1,30 @@
2018-05-16 Zalan Bujtas <za...@apple.com>
+ [LFC] Implement width computation for replaced inflow elements.
+ https://bugs.webkit.org/show_bug.cgi?id=185672
+
+ Reviewed by Antti Koivisto.
+
+ Replaced width for block, inline and float elements compute the same way.
+
+ * layout/FormattingContext.cpp:
+ (WebCore::Layout::FormattingContext::computeWidth const):
+ (WebCore::Layout::FormattingContext::computeFloatingWidth const):
+ (WebCore::Layout::FormattingContext::computeInFlowReplacedWidth const):
+ * layout/FormattingContext.h:
+ * layout/blockformatting/BlockFormattingContext.cpp:
+ (WebCore::Layout::BlockFormattingContext::computeInFlowWidth const):
+ * layout/layouttree/LayoutBox.cpp:
+ (WebCore::Layout::Box::hasIntrinsicWidth const):
+ (WebCore::Layout::Box::hasIntrinsicHeight const):
+ (WebCore::Layout::Box::hasIntrinsicRatio const):
+ (WebCore::Layout::Box::intrinsicWidth const):
+ (WebCore::Layout::Box::intrinsicHeight const):
+ (WebCore::Layout::Box::intrinsicRatio const):
+ * layout/layouttree/LayoutBox.h:
+
+2018-05-16 Zalan Bujtas <za...@apple.com>
+
[LFC] Make Display::Box box sizing aware
https://bugs.webkit.org/show_bug.cgi?id=185649
Modified: trunk/Source/WebCore/layout/FormattingContext.cpp (231846 => 231847)
--- trunk/Source/WebCore/layout/FormattingContext.cpp 2018-05-16 14:49:55 UTC (rev 231846)
+++ trunk/Source/WebCore/layout/FormattingContext.cpp 2018-05-16 14:51:39 UTC (rev 231847)
@@ -65,7 +65,7 @@
if (layoutBox.isOutOfFlowPositioned())
return computeOutOfFlowWidth(layoutContext, layoutBox, displayBox);
if (layoutBox.isFloatingPositioned())
- return computeFloatingWidth(layoutBox, displayBox);
+ return computeFloatingWidth(layoutContext, layoutBox, displayBox);
return computeInFlowWidth(layoutContext, layoutBox, displayBox);
}
@@ -87,8 +87,13 @@
ASSERT_NOT_REACHED();
}
-void FormattingContext::computeFloatingWidth(const Box&, Display::Box&) const
+void FormattingContext::computeFloatingWidth(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
{
+ if (!layoutBox.isReplaced()) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ computeInFlowReplacedWidth(layoutContext, layoutBox, displayBox);
}
void FormattingContext::computeOutOfFlowHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
@@ -203,6 +208,55 @@
displayBox.setHeight(computedHeightValue);
}
+void FormattingContext::computeInFlowReplacedWidth(LayoutContext&, const Box& layoutBox, Display::Box& displayBox) const
+{
+ // 10.3.4 Block-level, replaced elements in normal flow: The used value of 'width' is determined as for inline replaced elements
+ // 10.3.6 Floating, replaced elements: The used value of 'width' is determined as for inline replaced elements.
+
+ // 10.3.2 Inline, replaced elements
+ //
+ // 1. If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'.
+ //
+ // 2. If 'height' and 'width' both have computed values of 'auto' and the element has no intrinsic width, but does have an intrinsic height and intrinsic ratio;
+ // or if 'width' has a computed value of 'auto', 'height' has some other computed value, and the element does have an intrinsic ratio;
+ // then the used value of 'width' is: (used height) * (intrinsic ratio)
+ //
+ // 3. If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width,
+ // then the used value of 'width' is undefined in CSS 2.2. However, it is suggested that, if the containing block's width does not itself depend on the replaced
+ // element's width, then the used value of 'width' is calculated from the constraint equation used for block-level, non-replaced elements in normal flow.
+ //
+ // 4. Otherwise, if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'.
+ //
+ // 5. Otherwise, if 'width' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'width' becomes 300px.
+ // If 300px is too wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
+ auto& style = layoutBox.style();
+ auto width = style.logicalWidth();
+ auto height = style.logicalHeight();
+
+ LayoutUnit computedWidthValue;
+
+ if (width.isAuto() && height.isAuto() && layoutBox.hasIntrinsicWidth()) {
+ // #1
+ computedWidthValue = layoutBox.intrinsicWidth();
+ } else if (width.isAuto() && (height.isCalculated() || layoutBox.hasIntrinsicHeight()) && layoutBox.hasIntrinsicRatio()) {
+ // #2
+ auto usedHeight = height.isCalculated() ? LayoutUnit(height.value()) : layoutBox.intrinsicHeight();
+ computedWidthValue = usedHeight * layoutBox.intrinsicRatio();
+ } else if (width.isAuto() && height.isAuto() && layoutBox.hasIntrinsicRatio()) {
+ // #3
+ // FIXME: undefined but surely doable.
+ ASSERT_NOT_REACHED();
+ } else if (width.isAuto() && layoutBox.hasIntrinsicWidth()) {
+ // #4
+ computedWidthValue = layoutBox.intrinsicWidth();
+ } else {
+ // #5
+ computedWidthValue = 300;
+ }
+
+ displayBox.setWidth(computedWidthValue);
+}
+
LayoutUnit FormattingContext::contentHeightForFormattingContextRoot(LayoutContext& layoutContext, const Box& layoutBox) const
{
ASSERT(layoutBox.style().logicalHeight().isAuto());
Modified: trunk/Source/WebCore/layout/FormattingContext.h (231846 => 231847)
--- trunk/Source/WebCore/layout/FormattingContext.h 2018-05-16 14:49:55 UTC (rev 231846)
+++ trunk/Source/WebCore/layout/FormattingContext.h 2018-05-16 14:51:39 UTC (rev 231847)
@@ -72,7 +72,7 @@
virtual void computeHeight(LayoutContext&, const Box&, Display::Box&) const;
virtual void computeOutOfFlowWidth(LayoutContext&, const Box&, Display::Box&) const;
- virtual void computeFloatingWidth(const Box&, Display::Box&) const;
+ virtual void computeFloatingWidth(LayoutContext&, const Box&, Display::Box&) const;
virtual void computeInFlowWidth(LayoutContext&, const Box&, Display::Box&) const = 0;
virtual void computeOutOfFlowHeight(LayoutContext&, const Box&, Display::Box&) const;
@@ -87,6 +87,8 @@
void placeInFlowPositionedChildren(const Container&) const;
void layoutOutOfFlowDescendants(LayoutContext&s) const;
+ void computeInFlowReplacedWidth(LayoutContext&, const Box&, Display::Box&) const;
+
private:
void computeOutOfFlowNonReplacedHeight(LayoutContext&, const Box&, Display::Box&) const;
void computeOutOfFlowNonReplacedWidth(LayoutContext&, const Box&, Display::Box&) const;
Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp (231846 => 231847)
--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp 2018-05-16 14:49:55 UTC (rev 231846)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp 2018-05-16 14:51:39 UTC (rev 231847)
@@ -149,7 +149,7 @@
computeInFlowNonReplacedWidth(layoutContext, layoutBox, displayBox);
return;
}
- ASSERT_NOT_REACHED();
+ computeInFlowReplacedWidth(layoutContext, layoutBox, displayBox);
}
void BlockFormattingContext::computeInFlowNonReplacedWidth(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp (231846 => 231847)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp 2018-05-16 14:49:55 UTC (rev 231846)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp 2018-05-16 14:51:39 UTC (rev 231847)
@@ -230,7 +230,40 @@
return m_style.overflowX() == OVISIBLE || m_style.overflowY() == OVISIBLE;
}
+bool Box::hasIntrinsicWidth() const
+{
+ return false;
}
+
+bool Box::hasIntrinsicHeight() const
+{
+ return false;
}
+bool Box::hasIntrinsicRatio() const
+{
+ return false;
+}
+
+LayoutUnit Box::intrinsicWidth() const
+{
+ ASSERT(hasIntrinsicWidth());
+ return { };
+}
+
+LayoutUnit Box::intrinsicHeight() const
+{
+ ASSERT(hasIntrinsicHeight());
+ return { };
+}
+
+LayoutUnit Box::intrinsicRatio() const
+{
+ ASSERT(hasIntrinsicRatio());
+ return { };
+}
+
+}
+}
+
#endif
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.h (231846 => 231847)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2018-05-16 14:49:55 UTC (rev 231846)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2018-05-16 14:51:39 UTC (rev 231847)
@@ -72,7 +72,6 @@
bool isInlineBlockBox() const;
bool isBlockContainerBox() const;
bool isInitialContainingBlock() const;
- bool isReplaced() const;
const Container* parent() const { return m_parent; }
const Box* nextSibling() const { return m_nextSibling; }
@@ -91,6 +90,15 @@
const RenderStyle& style() const { return m_style; }
auto& weakPtrFactory() const { return m_weakFactory; }
+ bool isReplaced() const;
+ // FIXME: find out how to not pollute the Box interface
+ bool hasIntrinsicWidth() const;
+ bool hasIntrinsicHeight() const;
+ bool hasIntrinsicRatio() const;
+ LayoutUnit intrinsicWidth() const;
+ LayoutUnit intrinsicHeight() const;
+ LayoutUnit intrinsicRatio() const;
+
protected:
enum BaseTypeFlag {
ContainerFlag = 1 << 0,