[LFC] Formatting contexts should create floating states.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Apr 2018 15:40:16 +0000 (15:40 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Apr 2018 15:40:16 +0000 (15:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=185032

Reviewed by Antti Koivisto.

This patch implements the logic for sharing floating states across multiple formatting contexts.
At this point this is mostly about inline formatting contexts. They either create a new floating state
or inherit it from the parent formatting context.

* layout/FloatingState.cpp:
(WebCore::Layout::FloatingState::FloatingState):
* layout/FloatingState.h:
(WebCore::Layout::FloatingState::create):
* layout/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::FormattingContext):
* layout/FormattingContext.h:
(WebCore::Layout::FormattingContext::layoutContext const):
* layout/FormattingState.cpp:
(WebCore::Layout::FormattingState::FormattingState):
* layout/FormattingState.h:
(WebCore::Layout::FormattingState::floatingState const):
* layout/LayoutContext.cpp:
(WebCore::Layout::LayoutContext::updateLayout):
(WebCore::Layout::LayoutContext::formattingStateForBox const):
(WebCore::Layout::LayoutContext::establishedFormattingState):
(WebCore::Layout::LayoutContext::formattingContext):
(WebCore::Layout::LayoutContext::formattingState): Deleted.
* layout/LayoutContext.h:
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::BlockFormattingContext):
(WebCore::Layout::BlockFormattingContext::createFormattingState const):
(WebCore::Layout::BlockFormattingContext::createOrFindFloatingState const):
(WebCore::Layout::BlockFormattingContext::formattingState const): Deleted.
* layout/blockformatting/BlockFormattingContext.h:
* layout/blockformatting/BlockFormattingState.cpp:
(WebCore::Layout::BlockFormattingState::BlockFormattingState):
* layout/blockformatting/BlockFormattingState.h:
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::InlineFormattingContext):
(WebCore::Layout::InlineFormattingContext::createFormattingState const):
(WebCore::Layout::InlineFormattingContext::createOrFindFloatingState const):
(WebCore::Layout::InlineFormattingContext::formattingState const): Deleted.
* layout/inlineformatting/InlineFormattingContext.h:
* layout/inlineformatting/InlineFormattingState.cpp:
(WebCore::Layout::InlineFormattingState::InlineFormattingState):
* layout/inlineformatting/InlineFormattingState.h:
* layout/layouttree/LayoutBox.cpp:
(WebCore::Layout::Box::formattingContextRoot const):
* layout/layouttree/LayoutBox.h:

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

19 files changed:
Source/WebCore/ChangeLog
Source/WebCore/layout/FloatingState.cpp
Source/WebCore/layout/FloatingState.h
Source/WebCore/layout/FormattingContext.cpp
Source/WebCore/layout/FormattingContext.h
Source/WebCore/layout/FormattingState.cpp
Source/WebCore/layout/FormattingState.h
Source/WebCore/layout/LayoutContext.cpp
Source/WebCore/layout/LayoutContext.h
Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp
Source/WebCore/layout/blockformatting/BlockFormattingContext.h
Source/WebCore/layout/blockformatting/BlockFormattingState.cpp
Source/WebCore/layout/blockformatting/BlockFormattingState.h
Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
Source/WebCore/layout/inlineformatting/InlineFormattingContext.h
Source/WebCore/layout/inlineformatting/InlineFormattingState.cpp
Source/WebCore/layout/inlineformatting/InlineFormattingState.h
Source/WebCore/layout/layouttree/LayoutBox.cpp
Source/WebCore/layout/layouttree/LayoutBox.h

index 1d57f4a6f2fff4b22674d55bb4124de982626a16..98241705f3f50ac9a1f3405d50d9c394ecb86a22 100644 (file)
@@ -1,3 +1,55 @@
+2018-04-27  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC] Formatting contexts should create floating states.
+        https://bugs.webkit.org/show_bug.cgi?id=185032
+
+        Reviewed by Antti Koivisto.
+
+        This patch implements the logic for sharing floating states across multiple formatting contexts.
+        At this point this is mostly about inline formatting contexts. They either create a new floating state
+        or inherit it from the parent formatting context.
+
+        * layout/FloatingState.cpp:
+        (WebCore::Layout::FloatingState::FloatingState):
+        * layout/FloatingState.h:
+        (WebCore::Layout::FloatingState::create):
+        * layout/FormattingContext.cpp:
+        (WebCore::Layout::FormattingContext::FormattingContext):
+        * layout/FormattingContext.h:
+        (WebCore::Layout::FormattingContext::layoutContext const):
+        * layout/FormattingState.cpp:
+        (WebCore::Layout::FormattingState::FormattingState):
+        * layout/FormattingState.h:
+        (WebCore::Layout::FormattingState::floatingState const):
+        * layout/LayoutContext.cpp:
+        (WebCore::Layout::LayoutContext::updateLayout):
+        (WebCore::Layout::LayoutContext::formattingStateForBox const):
+        (WebCore::Layout::LayoutContext::establishedFormattingState):
+        (WebCore::Layout::LayoutContext::formattingContext):
+        (WebCore::Layout::LayoutContext::formattingState): Deleted.
+        * layout/LayoutContext.h:
+        * layout/blockformatting/BlockFormattingContext.cpp:
+        (WebCore::Layout::BlockFormattingContext::BlockFormattingContext):
+        (WebCore::Layout::BlockFormattingContext::createFormattingState const):
+        (WebCore::Layout::BlockFormattingContext::createOrFindFloatingState const):
+        (WebCore::Layout::BlockFormattingContext::formattingState const): Deleted.
+        * layout/blockformatting/BlockFormattingContext.h:
+        * layout/blockformatting/BlockFormattingState.cpp:
+        (WebCore::Layout::BlockFormattingState::BlockFormattingState):
+        * layout/blockformatting/BlockFormattingState.h:
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::InlineFormattingContext):
+        (WebCore::Layout::InlineFormattingContext::createFormattingState const):
+        (WebCore::Layout::InlineFormattingContext::createOrFindFloatingState const):
+        (WebCore::Layout::InlineFormattingContext::formattingState const): Deleted.
+        * layout/inlineformatting/InlineFormattingContext.h:
+        * layout/inlineformatting/InlineFormattingState.cpp:
+        (WebCore::Layout::InlineFormattingState::InlineFormattingState):
+        * layout/inlineformatting/InlineFormattingState.h:
+        * layout/layouttree/LayoutBox.cpp:
+        (WebCore::Layout::Box::formattingContextRoot const):
+        * layout/layouttree/LayoutBox.h:
+
 2018-04-27  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [Extra zoom mode] Add a mechanism to override default viewport behaviors in extra zoom mode
index 5e00ba70b9a5f57b85387ba7b0c0da053acaec36..50519a9dc89b6de534a7aeacbf400e75b18eb441 100644 (file)
 
 #include "config.h"
 #include "FloatingState.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+namespace Layout {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(FloatingState);
+
+FloatingState::FloatingState()
+{
+}
+
+}
+}
+#endif
index cb1781b8c67fe6f3cb6d4cfdeb49f86e2533504e..6fe7e22570ffb0de26bfa02d08d2e738c9700e52 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include <wtf/IsoMalloc.h>
+#include <wtf/Ref.h>
 
 namespace WebCore {
 
@@ -36,10 +37,13 @@ namespace Layout {
 class FormattingState;
 
 // FloatingState holds the floating boxes per formatting context.
-class FloatingState {
+class FloatingState : public RefCounted<FloatingState> {
     WTF_MAKE_ISO_ALLOCATED(FloatingState);
 public:
-    FloatingState(FormattingState& parentFormattingState);
+    static Ref<FloatingState> create() { return adoptRef(*new FloatingState()); }
+
+private:
+    FloatingState();
 };
 
 }
index 87ef299c648401410d37301b62fbcfd32d75c257..dca0475ea58a7e8cf3288659ce551b16553b0c53 100644 (file)
@@ -35,8 +35,9 @@ namespace Layout {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(FormattingContext);
 
-FormattingContext::FormattingContext(const Box& formattingContextRoot)
+FormattingContext::FormattingContext(const Box& formattingContextRoot, LayoutContext& layoutContext)
     : m_root(makeWeakPtr(const_cast<Box&>(formattingContextRoot)))
+    , m_layoutContext(layoutContext)
 {
 }
 
index 38c5a4ae0f804550b10a8e47fd3f73fab90c692b..bde31e212262915681ca7046050a08b0e404e760 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "FloatingState.h"
 #include "LayoutUnit.h"
 #include <wtf/IsoMalloc.h>
 #include <wtf/WeakPtr.h>
@@ -35,21 +36,24 @@ namespace WebCore {
 
 namespace Layout {
 
-class FormattingState;
 class Box;
+class FormattingState;
+class LayoutContext;
 
 class FormattingContext {
     WTF_MAKE_ISO_ALLOCATED(FormattingContext);
 public:
-    FormattingContext(const Box& formattingContextRoot);
+    FormattingContext(const Box& formattingContextRoot, LayoutContext&);
     virtual ~FormattingContext();
 
     virtual void layout(FormattingState&) = 0;
-    virtual std::unique_ptr<FormattingState> formattingState() const = 0;
+    virtual std::unique_ptr<FormattingState> createFormattingState(Ref<FloatingState>&&) const = 0;
+    virtual Ref<FloatingState> createOrFindFloatingState() const = 0;
 
+protected:
     const Box& root() const { return *m_root; }
+    const LayoutContext& layoutContext() const { return m_layoutContext; }
 
-protected:
     virtual void computeStaticPosition(const Box&) const;
     virtual void computeInFlowPositionedPosition(const Box&) const;
     virtual void computeOutOfFlowPosition(const Box&) const;
@@ -64,6 +68,7 @@ protected:
 
 private:
     WeakPtr<Box> m_root;
+    LayoutContext& m_layoutContext;
 };
 
 }
index 8fa0d438ccf7c53096a38db4c44afc12e410c93f..0e28e8569a949e775f5adcbcfee54f4c2f08f82a 100644 (file)
@@ -35,7 +35,8 @@ namespace Layout {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(FormattingState);
 
-FormattingState::FormattingState()
+FormattingState::FormattingState(Ref<FloatingState>&& floatingState)
+    : m_floatingState(WTFMove(floatingState))
 {
 }
 
index e34c009c3c0631f42baa5b6f2f61c705efba219d..698b3c7f2cbc51dc502dfaa548a6b6d6db71ee5e 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "FloatingState.h"
 #include <wtf/IsoMalloc.h>
 
 namespace WebCore {
@@ -34,18 +35,20 @@ namespace WebCore {
 namespace Layout {
 
 class Box;
-class FloatingState;
 class StyleDiff;
 
 class FormattingState {
     WTF_MAKE_ISO_ALLOCATED(FormattingState);
 public:
-    FormattingState();
+    FormattingState(Ref<FloatingState>&&);
 
-    FloatingState& floatingState();
+    FloatingState& floatingState() const { return m_floatingState; }
 
     void markNeedsLayout(const Box&, StyleDiff);
     bool needsLayout(const Box&);
+
+private:
+    Ref<FloatingState> m_floatingState;
 };
 
 }
index 2e363a498e0cd45bb758e1e909bb95afa2990a34..4c9b6fd092a92efd8f88a2e005f68df486f2bc7d 100644 (file)
@@ -33,6 +33,7 @@
 #include "InlineFormattingContext.h"
 #include "InlineFormattingState.h"
 #include "LayoutBox.h"
+#include "LayoutContainer.h"
 #include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
@@ -48,24 +49,31 @@ LayoutContext::LayoutContext(const Box& root)
 void LayoutContext::updateLayout()
 {
     auto context = formattingContext(*m_root);
-    auto state = formattingState(*context);
+    auto& state = establishedFormattingState(*m_root, *context);
     context->layout(state);
 }
 
-FormattingState& LayoutContext::formattingState(const FormattingContext& context)
+FormattingState& LayoutContext::formattingStateForBox(const Box& layoutBox) const
 {
-    return *m_formattingStates.ensure(&context.root(), [&context] {
-        return context.formattingState();
+    auto& root = layoutBox.formattingContextRoot();
+    RELEASE_ASSERT(m_formattingStates.contains(&root));
+    return *m_formattingStates.get(&root);
+}
+
+FormattingState& LayoutContext::establishedFormattingState(Box& formattingContextRoot, const FormattingContext& context)
+{
+    return *m_formattingStates.ensure(&formattingContextRoot, [this, &context] {
+        return context.createFormattingState(context.createOrFindFloatingState());
     }).iterator->value;
 }
 
 std::unique_ptr<FormattingContext> LayoutContext::formattingContext(const Box& formattingContextRoot)
 {
     if (formattingContextRoot.establishesBlockFormattingContext())
-        return std::make_unique<BlockFormattingContext>(formattingContextRoot);
+        return std::make_unique<BlockFormattingContext>(formattingContextRoot, *this);
 
     if (formattingContextRoot.establishesInlineFormattingContext())
-        return std::make_unique<InlineFormattingContext>(formattingContextRoot);
+        return std::make_unique<InlineFormattingContext>(formattingContextRoot, *this);
 
     ASSERT_NOT_REACHED();
     return nullptr;
index 838b527be3cf9aee51cc37db2e8e3c0e5f0b51f2..6589e51940b35484661ec2e7ab56bfb3035411aa 100644 (file)
@@ -60,8 +60,10 @@ public:
     void markNeedsLayout(const Box&, StyleDiff);
     bool needsLayout(const Box&) const;
 
+    FormattingState& formattingStateForBox(const Box&) const;
+
 private:
-    FormattingState& formattingState(const FormattingContext&);
+    FormattingState& establishedFormattingState(Box& formattingContextRoot, const FormattingContext&);
     std::unique_ptr<FormattingContext> formattingContext(const Box& formattingContextRoot);
 
     WeakPtr<Box> m_root;
index 70f77393f549dd45d710aeef30c847081ea710e7..e80545b9f036b290aa67531fb15d3de46b5697ce 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "BlockFormattingState.h"
+#include "FloatingState.h"
 #include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
@@ -36,8 +37,8 @@ namespace Layout {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(BlockFormattingContext);
 
-BlockFormattingContext::BlockFormattingContext(const Box& formattingContextRoot)
-    : FormattingContext(formattingContextRoot)
+BlockFormattingContext::BlockFormattingContext(const Box& formattingContextRoot, LayoutContext& layoutContext)
+    : FormattingContext(formattingContextRoot, layoutContext)
 {
 }
 
@@ -45,9 +46,15 @@ void BlockFormattingContext::layout(FormattingState&)
 {
 }
 
-std::unique_ptr<FormattingState> BlockFormattingContext::formattingState() const
+std::unique_ptr<FormattingState> BlockFormattingContext::createFormattingState(Ref<FloatingState>&& floatingState) const
 {
-    return std::make_unique<BlockFormattingState>();
+    return std::make_unique<BlockFormattingState>(WTFMove(floatingState));
+}
+
+Ref<FloatingState> BlockFormattingContext::createOrFindFloatingState() const
+{
+    // Block formatting context always establishes a new floating state.
+    return FloatingState::create();
 }
 
 void BlockFormattingContext::computeStaticPosition(const Box&) const
index b45940ecc160b75437b06840592d4196037e2c09..026398ba275d3b613b2473d32f9bdc0b7c0cef55 100644 (file)
@@ -43,10 +43,11 @@ class Box;
 class BlockFormattingContext : public FormattingContext {
     WTF_MAKE_ISO_ALLOCATED(BlockFormattingContext);
 public:
-    BlockFormattingContext(const Box& formattingContextRoot);
+    BlockFormattingContext(const Box& formattingContextRoot, LayoutContext&);
 
     void layout(FormattingState&) override;
-    std::unique_ptr<FormattingState> formattingState() const override;
+    std::unique_ptr<FormattingState> createFormattingState(Ref<FloatingState>&&) const override;
+    Ref<FloatingState> createOrFindFloatingState() const override;
 
 protected:
     void computeStaticPosition(const Box&) const override;
index 244d8254acef7f1c3291de976204af82de57fe2c..95a8a0bd3f4aafc44193075a3c853ce18ac33749 100644 (file)
@@ -35,8 +35,8 @@ namespace Layout {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(BlockFormattingState);
 
-BlockFormattingState::BlockFormattingState()
-    : FormattingState()
+BlockFormattingState::BlockFormattingState(Ref<FloatingState>&& floatingState)
+    : FormattingState(WTFMove(floatingState))
 {
 }
 
index 5485bda2f68ddeacc14e28bd5c95f1bc74c5633f..6202310888461f38c704e60a959d855e54813232 100644 (file)
@@ -38,7 +38,7 @@ namespace Layout {
 class BlockFormattingState : public FormattingState {
     WTF_MAKE_ISO_ALLOCATED(BlockFormattingState);
 public:
-    BlockFormattingState();
+    BlockFormattingState(Ref<FloatingState>&&);
 };
 
 }
index db7008a10bb5f2adf30144d9e43558ce1af7216a..22a4807b6dfeb9d5c9b77eb0ed04e79bf50a12db 100644 (file)
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "FloatingState.h"
 #include "InlineFormattingState.h"
+#include "LayoutBox.h"
+#include "LayoutContext.h"
 #include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
@@ -36,8 +39,8 @@ namespace Layout {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(InlineFormattingContext);
 
-InlineFormattingContext::InlineFormattingContext(const Box& formattingContextRoot)
-    : FormattingContext(formattingContextRoot)
+InlineFormattingContext::InlineFormattingContext(const Box& formattingContextRoot, LayoutContext& layoutContext)
+    : FormattingContext(formattingContextRoot, layoutContext)
 {
 }
 
@@ -45,9 +48,22 @@ void InlineFormattingContext::layout(FormattingState&)
 {
 }
 
-std::unique_ptr<FormattingState> InlineFormattingContext::formattingState() const
+std::unique_ptr<FormattingState> InlineFormattingContext::createFormattingState(Ref<FloatingState>&& floatingState) const
 {
-    return std::make_unique<InlineFormattingState>();
+    return std::make_unique<InlineFormattingState>(WTFMove(floatingState));
+}
+
+Ref<FloatingState> InlineFormattingContext::createOrFindFloatingState() const
+{
+    // If the block container box that initiates this inline formatting context also establishes a block context, the floats outside of the formatting root
+    // should not interfere with the content inside.
+    // <div style="float: left"></div><div style="overflow: hidden"> <- is a non-intrusive float, because overflow: hidden triggers new block formatting context.</div>
+    if (root().establishesBlockFormattingContext())
+        return FloatingState::create();
+    // Otherwise, the formatting context inherits the floats from the parent formatting context.
+    // Find the formatting state in which this formatting root lives, not the one it creates (this) and use its floating state.
+    auto& formattingState = layoutContext().formattingStateForBox(root());
+    return formattingState.floatingState();
 }
 
 }
index 6686e9b39182c11c5fa88ce985e0cc4870e322d7..36580e1db4403e3645f771c3b1190585890309fb 100644 (file)
@@ -41,10 +41,11 @@ class InlineFormattingState;
 class InlineFormattingContext : public FormattingContext {
     WTF_MAKE_ISO_ALLOCATED(InlineFormattingContext);
 public:
-    InlineFormattingContext(const Box& formattingContextRoot);
+    InlineFormattingContext(const Box& formattingContextRoot, LayoutContext&);
 
     void layout(FormattingState&) override;
-    std::unique_ptr<FormattingState> formattingState() const override;
+    std::unique_ptr<FormattingState> createFormattingState(Ref<FloatingState>&&) const override;
+    Ref<FloatingState> createOrFindFloatingState() const override;
 };
 
 }
index 930a88504192b2f75ac52fd6ec1a8c8a26065640..99970d1d8ca85cbb58c10a1bcc6f4562365666bb 100644 (file)
@@ -35,8 +35,8 @@ namespace Layout {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(InlineFormattingState);
 
-InlineFormattingState::InlineFormattingState()
-    : FormattingState()
+InlineFormattingState::InlineFormattingState(Ref<FloatingState>&& floatingState)
+    : FormattingState(WTFMove(floatingState))
 {
 }
 
index ed9bcdadc7844f17e0e7ea861734d05b31ee55bc..c7b5d7b3296f7b2b325ae481490ffc63e0ed25cd 100644 (file)
@@ -38,7 +38,7 @@ namespace Layout {
 class InlineFormattingState : public FormattingState {
     WTF_MAKE_ISO_ALLOCATED(InlineFormattingState);
 public:
-    InlineFormattingState();
+    InlineFormattingState(Ref<FloatingState>&&);
 };
 
 }
index dec0d3529cded90cc5b843a74586e36b52c90a68..44797af8ec71a028e68baee13d31282f54f0f65a 100644 (file)
@@ -128,6 +128,19 @@ const Container* Box::containingBlock() const
     return nullptr;
 }
 
+const Container& Box::formattingContextRoot() const
+{
+    for (auto* ancestor = containingBlock(); ancestor; ancestor = ancestor->containingBlock()) {
+        if (ancestor->establishesFormattingContext())
+            return *ancestor;
+    }
+
+    // Initial containing block always establishes a formatting context.
+    if (isInitialContainingBlock())
+        return downcast<Container>(*this);
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
 bool Box::isDescendantOf(Container& container) const
 {
     auto* ancestor = parent();
index d3124a5747e95db00390ed63adfd06151d9e3cb7..2c81a912a385f3581a277929047b0295f1b58a82 100644 (file)
@@ -64,6 +64,7 @@ public:
     bool isFloatingOrOutOfFlowPositioned() const { return isFloatingPositioned() || isOutOfFlowPositioned(); }
 
     const Container* containingBlock() const;
+    const Container& formattingContextRoot() const;
     bool isDescendantOf(Container&) const;
 
     bool isAnonymous() const { return m_isAnonymous; }