[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 1d57f4a..9824170 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 5e00ba7..50519a9 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 cb1781b..6fe7e22 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 87ef299..dca0475 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 38c5a4a..bde31e2 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 8fa0d43..0e28e85 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 e34c009..698b3c7 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 2e363a4..4c9b6fd 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 838b527..6589e51 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 70f7739..e80545b 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 b45940e..026398b 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 244d825..95a8a0b 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 5485bda..6202310 100644 (file)
@@ -38,7 +38,7 @@ namespace Layout {
 class BlockFormattingState : public FormattingState {
     WTF_MAKE_ISO_ALLOCATED(BlockFormattingState);
 public:
-    BlockFormattingState();
+    BlockFormattingState(Ref<FloatingState>&&);
 };
 
 }
index db7008a..22a4807 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 6686e9b..36580e1 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 930a885..99970d1 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 ed9bcda..c7b5d7b 100644 (file)
@@ -38,7 +38,7 @@ namespace Layout {
 class InlineFormattingState : public FormattingState {
     WTF_MAKE_ISO_ALLOCATED(InlineFormattingState);
 public:
-    InlineFormattingState();
+    InlineFormattingState(Ref<FloatingState>&&);
 };
 
 }
index dec0d35..44797af 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 d3124a5..2c81a91 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; }