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
+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
#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
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include <wtf/IsoMalloc.h>
+#include <wtf/Ref.h>
namespace WebCore {
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();
};
}
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)
{
}
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+#include "FloatingState.h"
#include "LayoutUnit.h"
#include <wtf/IsoMalloc.h>
#include <wtf/WeakPtr.h>
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;
private:
WeakPtr<Box> m_root;
+ LayoutContext& m_layoutContext;
};
}
WTF_MAKE_ISO_ALLOCATED_IMPL(FormattingState);
-FormattingState::FormattingState()
+FormattingState::FormattingState(Ref<FloatingState>&& floatingState)
+ : m_floatingState(WTFMove(floatingState))
{
}
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+#include "FloatingState.h"
#include <wtf/IsoMalloc.h>
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;
};
}
#include "InlineFormattingContext.h"
#include "InlineFormattingState.h"
#include "LayoutBox.h"
+#include "LayoutContainer.h"
#include <wtf/IsoMallocInlines.h>
namespace WebCore {
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;
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;
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "BlockFormattingState.h"
+#include "FloatingState.h"
#include <wtf/IsoMallocInlines.h>
namespace WebCore {
WTF_MAKE_ISO_ALLOCATED_IMPL(BlockFormattingContext);
-BlockFormattingContext::BlockFormattingContext(const Box& formattingContextRoot)
- : FormattingContext(formattingContextRoot)
+BlockFormattingContext::BlockFormattingContext(const Box& formattingContextRoot, LayoutContext& layoutContext)
+ : FormattingContext(formattingContextRoot, layoutContext)
{
}
{
}
-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
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;
WTF_MAKE_ISO_ALLOCATED_IMPL(BlockFormattingState);
-BlockFormattingState::BlockFormattingState()
- : FormattingState()
+BlockFormattingState::BlockFormattingState(Ref<FloatingState>&& floatingState)
+ : FormattingState(WTFMove(floatingState))
{
}
class BlockFormattingState : public FormattingState {
WTF_MAKE_ISO_ALLOCATED(BlockFormattingState);
public:
- BlockFormattingState();
+ BlockFormattingState(Ref<FloatingState>&&);
};
}
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+#include "FloatingState.h"
#include "InlineFormattingState.h"
+#include "LayoutBox.h"
+#include "LayoutContext.h"
#include <wtf/IsoMallocInlines.h>
namespace WebCore {
WTF_MAKE_ISO_ALLOCATED_IMPL(InlineFormattingContext);
-InlineFormattingContext::InlineFormattingContext(const Box& formattingContextRoot)
- : FormattingContext(formattingContextRoot)
+InlineFormattingContext::InlineFormattingContext(const Box& formattingContextRoot, LayoutContext& layoutContext)
+ : FormattingContext(formattingContextRoot, layoutContext)
{
}
{
}
-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();
}
}
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;
};
}
WTF_MAKE_ISO_ALLOCATED_IMPL(InlineFormattingState);
-InlineFormattingState::InlineFormattingState()
- : FormattingState()
+InlineFormattingState::InlineFormattingState(Ref<FloatingState>&& floatingState)
+ : FormattingState(WTFMove(floatingState))
{
}
class InlineFormattingState : public FormattingState {
WTF_MAKE_ISO_ALLOCATED(InlineFormattingState);
public:
- InlineFormattingState();
+ InlineFormattingState(Ref<FloatingState>&&);
};
}
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();
bool isFloatingOrOutOfFlowPositioned() const { return isFloatingPositioned() || isOutOfFlowPositioned(); }
const Container* containingBlock() const;
+ const Container& formattingContextRoot() const;
bool isDescendantOf(Container&) const;
bool isAnonymous() const { return m_isAnonymous; }