Diff
Modified: trunk/Source/WebCore/ChangeLog (231107 => 231108)
--- trunk/Source/WebCore/ChangeLog 2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/ChangeLog 2018-04-27 18:17:46 UTC (rev 231108)
@@ -1,3 +1,43 @@
+2018-04-27 Zalan Bujtas <[email protected]>
+
+ [LFC] Implement BlockFormattingContext::layout logic and its dependencies
+ https://bugs.webkit.org/show_bug.cgi?id=185024
+
+ Reviewed by Antti Koivisto.
+
+ This patch implements the logic for block formatting context according to
+ https://www.w3.org/TR/CSS22/visuren.html#block-formatting
+
+ 1. Traverse the tree iteratively (in post-order fashion) and compute the width/static position for the containers as
+ we visit the descendant nodes until we hit a leaf node.
+ 2. Compute the position/geometry of the leaf node and move over to its sibling(s).
+ 3. Finalize the container's height/final position as we climb back on the tree.
+ 4. Run layout on the out-of-flow descendants.
+
+ Note that subtrees with a formatting context root need to be laid out completely before moving on to the next box.
+ The formatting root box is laid out in the formatting context it lives in, however its descendants get laid out
+ in a separate formatting context (excluding out-of-flow boxes that don't belong to the root).
+
+ * layout/FloatingContext.cpp:
+ (WebCore::Layout::FloatingContext::FloatingContext):
+ (WebCore::Layout::FloatingContext::computePosition):
+ * layout/FormattingContext.cpp:
+ (WebCore::Layout::FormattingContext::placeInFlowPositionedChildren const):
+ (WebCore::Layout::FormattingContext::layoutOutOfFlowDescendants const):
+ * layout/FormattingContext.h:
+ * layout/LayoutContext.cpp:
+ (WebCore::Layout::LayoutContext::updateLayout):
+ (WebCore::Layout::LayoutContext::establishedFormattingState):
+ * layout/LayoutContext.h:
+ * layout/blockformatting/BlockFormattingContext.cpp:
+ (WebCore::Layout::BlockFormattingContext::layout const):
+ (WebCore::Layout::BlockFormattingContext::layout): Deleted.
+ * layout/blockformatting/BlockFormattingContext.h:
+ * layout/inlineformatting/InlineFormattingContext.cpp:
+ (WebCore::Layout::InlineFormattingContext::layout const):
+ (WebCore::Layout::InlineFormattingContext::layout): Deleted.
+ * layout/inlineformatting/InlineFormattingContext.h:
+
2018-04-27 Youenn Fablet <[email protected]>
Use NetworkLoadChecker for XHR/fetch loads
Modified: trunk/Source/WebCore/layout/FloatingContext.cpp (231107 => 231108)
--- trunk/Source/WebCore/layout/FloatingContext.cpp 2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/FloatingContext.cpp 2018-04-27 18:17:46 UTC (rev 231108)
@@ -25,3 +25,24 @@
#include "config.h"
#include "FloatingContext.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+namespace Layout {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(FloatingContext);
+
+FloatingContext::FloatingContext(FloatingState&)
+{
+}
+
+void FloatingContext::computePosition(const Box&)
+{
+}
+
+}
+}
+#endif
Modified: trunk/Source/WebCore/layout/FormattingContext.cpp (231107 => 231108)
--- trunk/Source/WebCore/layout/FormattingContext.cpp 2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/FormattingContext.cpp 2018-04-27 18:17:46 UTC (rev 231108)
@@ -85,6 +85,14 @@
return 0;
}
+void FormattingContext::placeInFlowPositionedChildren(const Container&) const
+{
}
+
+void FormattingContext::layoutOutOfFlowDescendants() const
+{
}
+
+}
+}
#endif
Modified: trunk/Source/WebCore/layout/FormattingContext.h (231107 => 231108)
--- trunk/Source/WebCore/layout/FormattingContext.h 2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/FormattingContext.h 2018-04-27 18:17:46 UTC (rev 231108)
@@ -37,6 +37,7 @@
namespace Layout {
class Box;
+class Container;
class FormattingState;
class LayoutContext;
@@ -46,7 +47,7 @@
FormattingContext(const Box& formattingContextRoot, LayoutContext&);
virtual ~FormattingContext();
- virtual void layout(FormattingState&) = 0;
+ virtual void layout(LayoutContext&, FormattingState&) const = 0;
virtual std::unique_ptr<FormattingState> createFormattingState(Ref<FloatingState>&&) const = 0;
virtual Ref<FloatingState> createOrFindFloatingState() const = 0;
@@ -66,6 +67,9 @@
virtual LayoutUnit marginBottom(const Box&) const;
virtual LayoutUnit marginRight(const Box&) const;
+ void placeInFlowPositionedChildren(const Container&) const;
+ void layoutOutOfFlowDescendants() const;
+
private:
WeakPtr<Box> m_root;
LayoutContext& m_layoutContext;
Modified: trunk/Source/WebCore/layout/LayoutContext.cpp (231107 => 231108)
--- trunk/Source/WebCore/layout/LayoutContext.cpp 2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/LayoutContext.cpp 2018-04-27 18:17:46 UTC (rev 231108)
@@ -50,7 +50,7 @@
{
auto context = formattingContext(*m_root);
auto& state = establishedFormattingState(*m_root, *context);
- context->layout(state);
+ context->layout(*this, state);
}
FormattingState& LayoutContext::formattingStateForBox(const Box& layoutBox) const
@@ -60,7 +60,7 @@
return *m_formattingStates.get(&root);
}
-FormattingState& LayoutContext::establishedFormattingState(Box& formattingContextRoot, const FormattingContext& context)
+FormattingState& LayoutContext::establishedFormattingState(const Box& formattingContextRoot, const FormattingContext& context)
{
return *m_formattingStates.ensure(&formattingContextRoot, [this, &context] {
return context.createFormattingState(context.createOrFindFloatingState());
Modified: trunk/Source/WebCore/layout/LayoutContext.h (231107 => 231108)
--- trunk/Source/WebCore/layout/LayoutContext.h 2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/LayoutContext.h 2018-04-27 18:17:46 UTC (rev 231108)
@@ -61,11 +61,10 @@
bool needsLayout(const Box&) const;
FormattingState& formattingStateForBox(const Box&) const;
+ FormattingState& establishedFormattingState(const Box& formattingContextRoot, const FormattingContext&);
+ std::unique_ptr<FormattingContext> formattingContext(const Box& formattingContextRoot);
private:
- FormattingState& establishedFormattingState(Box& formattingContextRoot, const FormattingContext&);
- std::unique_ptr<FormattingContext> formattingContext(const Box& formattingContextRoot);
-
WeakPtr<Box> m_root;
HashMap<const Box*, std::unique_ptr<FormattingState>> m_formattingStates;
};
Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp (231107 => 231108)
--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp 2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp 2018-04-27 18:17:46 UTC (rev 231108)
@@ -29,7 +29,11 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "BlockFormattingState.h"
+#include "FloatingContext.h"
#include "FloatingState.h"
+#include "LayoutBox.h"
+#include "LayoutContainer.h"
+#include "LayoutContext.h"
#include <wtf/IsoMallocInlines.h>
namespace WebCore {
@@ -42,8 +46,63 @@
{
}
-void BlockFormattingContext::layout(FormattingState&)
+void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingState& formattingState) const
{
+ // 9.4.1 Block formatting contexts
+ // In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block.
+ // The vertical distance between two sibling boxes is determined by the 'margin' properties.
+ // Vertical margins between adjacent block-level boxes in a block formatting context collapse.
+ if (!is<Container>(root()))
+ return;
+ auto& formattingRoot = downcast<Container>(root());
+ Vector<const Box*> layoutQueue;
+ FloatingContext floatingContext(formattingState.floatingState());
+ // This is a post-order tree traversal layout.
+ // The root container layout is done in the formatting context it lives in, not that one it creates, so let's start with the first child.
+ if (formattingRoot.hasInFlowOrFloatingChild())
+ layoutQueue.append(formattingRoot.firstInFlowOrFloatingChild());
+ // 1. Go all the way down to the leaf node
+ // 2. Compute static position and width as we traverse down
+ // 3. As we climb back on the tree, compute height and finialize position
+ // (Any subtrees with new formatting contexts need to layout synchronously)
+ while (!layoutQueue.isEmpty()) {
+ // Traverse down on the descendants and compute width/static position until we find a leaf node.
+ while (true) {
+ auto& layoutBox = *layoutQueue.last();
+ computeWidth(layoutBox);
+ computeStaticPosition(layoutBox);
+ if (layoutBox.establishesFormattingContext()) {
+ auto formattingContext = layoutContext.formattingContext(layoutBox);
+ formattingContext->layout(layoutContext, layoutContext.establishedFormattingState(layoutBox, *formattingContext));
+ break;
+ }
+ if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowOrFloatingChild())
+ break;
+ layoutQueue.append(downcast<Container>(layoutBox).firstInFlowOrFloatingChild());
+ }
+
+ // Climb back on the ancestors and compute height/final position.
+ while (!layoutQueue.isEmpty()) {
+ // All inflow descendants (if there are any) are laid out by now. Let's compute the box's height.
+ auto& layoutBox = *layoutQueue.takeLast();
+ computeHeight(layoutBox);
+ // Adjust position now that we have all the previous floats placed in this context -if needed.
+ floatingContext.computePosition(layoutBox);
+ if (!is<Container>(layoutBox))
+ continue;
+ auto& container = downcast<Container>(layoutBox);
+ // Move in-flow positioned children to their final position.
+ placeInFlowPositionedChildren(container);
+ if (auto* nextSibling = container.nextInFlowOrFloatingSibling()) {
+ layoutQueue.append(nextSibling);
+ break;
+ }
+ }
+ }
+ // Place the inflow positioned children.
+ placeInFlowPositionedChildren(formattingRoot);
+ // And take care of out-of-flow boxes as the final step.
+ layoutOutOfFlowDescendants();
}
std::unique_ptr<FormattingState> BlockFormattingContext::createFormattingState(Ref<FloatingState>&& floatingState) const
Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h (231107 => 231108)
--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h 2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h 2018-04-27 18:17:46 UTC (rev 231108)
@@ -45,7 +45,7 @@
public:
BlockFormattingContext(const Box& formattingContextRoot, LayoutContext&);
- void layout(FormattingState&) override;
+ void layout(LayoutContext&, FormattingState&) const override;
std::unique_ptr<FormattingState> createFormattingState(Ref<FloatingState>&&) const override;
Ref<FloatingState> createOrFindFloatingState() const override;
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (231107 => 231108)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2018-04-27 18:17:46 UTC (rev 231108)
@@ -44,7 +44,7 @@
{
}
-void InlineFormattingContext::layout(FormattingState&)
+void InlineFormattingContext::layout(LayoutContext&, FormattingState&) const
{
}
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (231107 => 231108)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h 2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h 2018-04-27 18:17:46 UTC (rev 231108)
@@ -43,7 +43,7 @@
public:
InlineFormattingContext(const Box& formattingContextRoot, LayoutContext&);
- void layout(FormattingState&) override;
+ void layout(LayoutContext&, FormattingState&) const override;
std::unique_ptr<FormattingState> createFormattingState(Ref<FloatingState>&&) const override;
Ref<FloatingState> createOrFindFloatingState() const override;
};