[LFC] The static position for an out-of-flow box should include the previous sibling...
[WebKit-https.git] / Source / WebCore / layout / LayoutContext.cpp
1 /*
2  * Copyright (C) 2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "LayoutContext.h"
28
29 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
30
31 #include "BlockFormattingContext.h"
32 #include "BlockFormattingState.h"
33 #include "BlockInvalidation.h"
34 #include "DisplayBox.h"
35 #include "InlineFormattingContext.h"
36 #include "InlineFormattingState.h"
37 #include "InlineInvalidation.h"
38 #include "Invalidation.h"
39 #include "LayoutBox.h"
40 #include "LayoutContainer.h"
41 #include <wtf/IsoMallocInlines.h>
42
43 namespace WebCore {
44 namespace Layout {
45
46 WTF_MAKE_ISO_ALLOCATED_IMPL(LayoutContext);
47
48 LayoutContext::LayoutContext()
49 {
50 }
51
52 void LayoutContext::initializeRoot(const Container& root, const LayoutSize& containerSize)
53 {
54     ASSERT(root.establishesFormattingContext());
55
56     m_root = makeWeakPtr(const_cast<Container&>(root));
57     auto& displayBox = createDisplayBox(root);
58
59     // FIXME: m_root could very well be a formatting context root with ancestors and resolvable border and padding (as opposed to the topmost root)
60     displayBox.setHorizontalMargin({ });
61     displayBox.setVerticalMargin({ });
62     displayBox.setVerticalNonCollapsedMargin({ });
63     displayBox.setBorder({ });
64     displayBox.setPadding({ });
65     displayBox.setContentBoxHeight(containerSize.height());
66     displayBox.setContentBoxWidth(containerSize.width());
67     displayBox.setTopLeft({ });
68
69     m_formattingContextRootListForLayout.add(&root);
70 }
71
72 void LayoutContext::updateLayout()
73 {
74     ASSERT(!m_formattingContextRootListForLayout.isEmpty());
75     for (auto* layoutRoot : m_formattingContextRootListForLayout)
76         layoutFormattingContextSubtree(*layoutRoot);
77     m_formattingContextRootListForLayout.clear();
78 }
79
80 void LayoutContext::layoutFormattingContextSubtree(const Box& layoutRoot)
81 {
82     RELEASE_ASSERT(layoutRoot.establishesFormattingContext());
83     auto formattingContext = this->formattingContext(layoutRoot);
84     auto& formattingState = establishedFormattingState(layoutRoot, *formattingContext);
85     formattingContext->layout(*this, formattingState);
86     formattingContext->layoutOutOfFlowDescendants(*this, layoutRoot);
87 }
88
89 Display::Box& LayoutContext::createDisplayBox(const Box& layoutBox)
90 {
91     std::unique_ptr<Display::Box> displayBox(new Display::Box(layoutBox.style()));
92     auto* displayBoxPtr = displayBox.get();
93     m_layoutToDisplayBox.add(&layoutBox, WTFMove(displayBox));
94     return *displayBoxPtr;
95 }
96
97 void LayoutContext::styleChanged(const Box& layoutBox, StyleDiff styleDiff)
98 {
99     auto& formattingState = formattingStateForBox(layoutBox);
100     const Container* invalidationRoot = nullptr;
101     if (is<BlockFormattingState>(formattingState))
102         invalidationRoot = BlockInvalidation::invalidate(layoutBox, styleDiff, *this, downcast<BlockFormattingState>(formattingState)).root;
103     else if (is<InlineFormattingState>(formattingState))
104         invalidationRoot = InlineInvalidation::invalidate(layoutBox, styleDiff, *this, downcast<InlineFormattingState>(formattingState)).root;
105     else
106         ASSERT_NOT_IMPLEMENTED_YET();
107     ASSERT(invalidationRoot);
108     m_formattingContextRootListForLayout.addVoid(invalidationRoot);
109 }
110
111 void LayoutContext::markNeedsUpdate(const Box&, OptionSet<UpdateType>)
112 {
113 }
114
115 FormattingState& LayoutContext::formattingStateForBox(const Box& layoutBox) const
116 {
117     auto& root = layoutBox.formattingContextRoot();
118     RELEASE_ASSERT(m_formattingStates.contains(&root));
119     return *m_formattingStates.get(&root);
120 }
121
122 FormattingState& LayoutContext::establishedFormattingState(const Box& formattingContextRoot, const FormattingContext& context)
123 {
124     return *m_formattingStates.ensure(&formattingContextRoot, [this, &context] {
125         return context.createFormattingState(context.createOrFindFloatingState(*this));
126     }).iterator->value;
127 }
128
129 std::unique_ptr<FormattingContext> LayoutContext::formattingContext(const Box& formattingContextRoot)
130 {
131     if (formattingContextRoot.establishesBlockFormattingContext())
132         return std::make_unique<BlockFormattingContext>(formattingContextRoot);
133
134     if (formattingContextRoot.establishesInlineFormattingContext())
135         return std::make_unique<InlineFormattingContext>(formattingContextRoot);
136
137     ASSERT_NOT_IMPLEMENTED_YET();
138     return nullptr;
139 }
140
141 }
142 }
143
144 #endif