[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:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@231096 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 1d57f4a..9824170 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -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
diff --git a/Source/WebCore/layout/FloatingState.cpp b/Source/WebCore/layout/FloatingState.cpp
index 5e00ba7..50519a9 100644
--- a/Source/WebCore/layout/FloatingState.cpp
+++ b/Source/WebCore/layout/FloatingState.cpp
@@ -25,3 +25,20 @@
 
 #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
diff --git a/Source/WebCore/layout/FloatingState.h b/Source/WebCore/layout/FloatingState.h
index cb1781b..6fe7e22 100644
--- a/Source/WebCore/layout/FloatingState.h
+++ b/Source/WebCore/layout/FloatingState.h
@@ -28,6 +28,7 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include <wtf/IsoMalloc.h>
+#include <wtf/Ref.h>
 
 namespace WebCore {
 
@@ -36,10 +37,13 @@
 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();
 };
 
 }
diff --git a/Source/WebCore/layout/FormattingContext.cpp b/Source/WebCore/layout/FormattingContext.cpp
index 87ef299..dca0475 100644
--- a/Source/WebCore/layout/FormattingContext.cpp
+++ b/Source/WebCore/layout/FormattingContext.cpp
@@ -35,8 +35,9 @@
 
 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)
 {
 }
 
diff --git a/Source/WebCore/layout/FormattingContext.h b/Source/WebCore/layout/FormattingContext.h
index 38c5a4a..bde31e2 100644
--- a/Source/WebCore/layout/FormattingContext.h
+++ b/Source/WebCore/layout/FormattingContext.h
@@ -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 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;
-
-    const Box& root() const { return *m_root; }
+    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; }
+
     virtual void computeStaticPosition(const Box&) const;
     virtual void computeInFlowPositionedPosition(const Box&) const;
     virtual void computeOutOfFlowPosition(const Box&) const;
@@ -64,6 +68,7 @@
 
 private:
     WeakPtr<Box> m_root;
+    LayoutContext& m_layoutContext;
 };
 
 }
diff --git a/Source/WebCore/layout/FormattingState.cpp b/Source/WebCore/layout/FormattingState.cpp
index 8fa0d43..0e28e85 100644
--- a/Source/WebCore/layout/FormattingState.cpp
+++ b/Source/WebCore/layout/FormattingState.cpp
@@ -35,7 +35,8 @@
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(FormattingState);
 
-FormattingState::FormattingState()
+FormattingState::FormattingState(Ref<FloatingState>&& floatingState)
+    : m_floatingState(WTFMove(floatingState))
 {
 }
 
diff --git a/Source/WebCore/layout/FormattingState.h b/Source/WebCore/layout/FormattingState.h
index e34c009..698b3c7 100644
--- a/Source/WebCore/layout/FormattingState.h
+++ b/Source/WebCore/layout/FormattingState.h
@@ -27,6 +27,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "FloatingState.h"
 #include <wtf/IsoMalloc.h>
 
 namespace WebCore {
@@ -34,18 +35,20 @@
 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;
 };
 
 }
diff --git a/Source/WebCore/layout/LayoutContext.cpp b/Source/WebCore/layout/LayoutContext.cpp
index 2e363a4..4c9b6fd 100644
--- a/Source/WebCore/layout/LayoutContext.cpp
+++ b/Source/WebCore/layout/LayoutContext.cpp
@@ -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 @@
 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;
diff --git a/Source/WebCore/layout/LayoutContext.h b/Source/WebCore/layout/LayoutContext.h
index 838b527..6589e51 100644
--- a/Source/WebCore/layout/LayoutContext.h
+++ b/Source/WebCore/layout/LayoutContext.h
@@ -60,8 +60,10 @@
     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;
diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp b/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp
index 70f7739..e80545b 100644
--- a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp
+++ b/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp
@@ -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 @@
 
 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 @@
 {
 }
 
-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
diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContext.h b/Source/WebCore/layout/blockformatting/BlockFormattingContext.h
index b45940e..026398b 100644
--- a/Source/WebCore/layout/blockformatting/BlockFormattingContext.h
+++ b/Source/WebCore/layout/blockformatting/BlockFormattingContext.h
@@ -43,10 +43,11 @@
 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;
diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingState.cpp b/Source/WebCore/layout/blockformatting/BlockFormattingState.cpp
index 244d825..95a8a0b 100644
--- a/Source/WebCore/layout/blockformatting/BlockFormattingState.cpp
+++ b/Source/WebCore/layout/blockformatting/BlockFormattingState.cpp
@@ -35,8 +35,8 @@
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(BlockFormattingState);
 
-BlockFormattingState::BlockFormattingState()
-    : FormattingState()
+BlockFormattingState::BlockFormattingState(Ref<FloatingState>&& floatingState)
+    : FormattingState(WTFMove(floatingState))
 {
 }
 
diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingState.h b/Source/WebCore/layout/blockformatting/BlockFormattingState.h
index 5485bda..6202310 100644
--- a/Source/WebCore/layout/blockformatting/BlockFormattingState.h
+++ b/Source/WebCore/layout/blockformatting/BlockFormattingState.h
@@ -38,7 +38,7 @@
 class BlockFormattingState : public FormattingState {
     WTF_MAKE_ISO_ALLOCATED(BlockFormattingState);
 public:
-    BlockFormattingState();
+    BlockFormattingState(Ref<FloatingState>&&);
 };
 
 }
diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
index db7008a..22a4807 100644
--- a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
@@ -28,7 +28,10 @@
 
 #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 @@
 
 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 @@
 {
 }
 
-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();
 }
 
 }
diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h
index 6686e9b..36580e1 100644
--- a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h
+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h
@@ -41,10 +41,11 @@
 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;
 };
 
 }
diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingState.cpp b/Source/WebCore/layout/inlineformatting/InlineFormattingState.cpp
index 930a885..99970d1 100644
--- a/Source/WebCore/layout/inlineformatting/InlineFormattingState.cpp
+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingState.cpp
@@ -35,8 +35,8 @@
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(InlineFormattingState);
 
-InlineFormattingState::InlineFormattingState()
-    : FormattingState()
+InlineFormattingState::InlineFormattingState(Ref<FloatingState>&& floatingState)
+    : FormattingState(WTFMove(floatingState))
 {
 }
 
diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingState.h b/Source/WebCore/layout/inlineformatting/InlineFormattingState.h
index ed9bcda..c7b5d7b 100644
--- a/Source/WebCore/layout/inlineformatting/InlineFormattingState.h
+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingState.h
@@ -38,7 +38,7 @@
 class InlineFormattingState : public FormattingState {
     WTF_MAKE_ISO_ALLOCATED(InlineFormattingState);
 public:
-    InlineFormattingState();
+    InlineFormattingState(Ref<FloatingState>&&);
 };
 
 }
diff --git a/Source/WebCore/layout/layouttree/LayoutBox.cpp b/Source/WebCore/layout/layouttree/LayoutBox.cpp
index dec0d35..44797af 100644
--- a/Source/WebCore/layout/layouttree/LayoutBox.cpp
+++ b/Source/WebCore/layout/layouttree/LayoutBox.cpp
@@ -128,6 +128,19 @@
     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();
diff --git a/Source/WebCore/layout/layouttree/LayoutBox.h b/Source/WebCore/layout/layouttree/LayoutBox.h
index d3124a5..2c81a91 100644
--- a/Source/WebCore/layout/layouttree/LayoutBox.h
+++ b/Source/WebCore/layout/layouttree/LayoutBox.h
@@ -64,6 +64,7 @@
     bool isFloatingOrOutOfFlowPositioned() const { return isFloatingPositioned() || isOutOfFlowPositioned(); }
 
     const Container* containingBlock() const;
+    const Container& formattingContextRoot() const;
     bool isDescendantOf(Container&) const;
 
     bool isAnonymous() const { return m_isAnonymous; }