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 | #pragma once |
27 | |
28 | #if ENABLE(LAYOUT_FORMATTING_CONTEXT) |
29 | |
30 | #include "LayoutReplaced.h" |
31 | #include "RenderStyle.h" |
32 | #include <wtf/IsoMalloc.h> |
33 | #include <wtf/WeakPtr.h> |
34 | |
35 | namespace WebCore { |
36 | |
37 | namespace Layout { |
38 | |
39 | class Container; |
40 | class TreeBuilder; |
41 | |
42 | class Box : public CanMakeWeakPtr<Box> { |
43 | WTF_MAKE_ISO_ALLOCATED(Box); |
44 | public: |
45 | enum class ElementType { |
46 | Document, |
47 | Body, |
48 | TableCell, |
49 | TableColumn, |
50 | TableRow, |
51 | TableColumnGroup, |
52 | TableRowGroup, |
53 | TableHeaderGroup, |
54 | TableFooterGroup, |
55 | Image, |
56 | IFrame, |
57 | GenericElement |
58 | }; |
59 | |
60 | struct ElementAttributes { |
61 | ElementType elementType; |
62 | }; |
63 | |
64 | enum BaseTypeFlag { |
65 | BoxFlag = 1 << 0, |
66 | ContainerFlag = 1 << 1, |
67 | BlockContainerFlag = 1 << 2, |
68 | InlineBoxFlag = 1 << 3, |
69 | InlineContainerFlag = 1 << 4, |
70 | LineBreakBoxFlag = 1 << 5 |
71 | }; |
72 | typedef unsigned BaseTypeFlags; |
73 | |
74 | Box(Optional<ElementAttributes>, RenderStyle&&); |
75 | virtual ~Box(); |
76 | |
77 | bool establishesFormattingContext() const; |
78 | bool establishesBlockFormattingContext() const; |
79 | bool establishesBlockFormattingContextOnly() const; |
80 | virtual bool establishesInlineFormattingContext() const { return false; } |
81 | |
82 | bool isInFlow() const { return !isFloatingOrOutOfFlowPositioned(); } |
83 | bool isPositioned() const { return isInFlowPositioned() || isOutOfFlowPositioned(); } |
84 | bool isInFlowPositioned() const { return isRelativelyPositioned() || isStickyPositioned(); } |
85 | bool isOutOfFlowPositioned() const { return isAbsolutelyPositioned(); } |
86 | bool isRelativelyPositioned() const; |
87 | bool isStickyPositioned() const; |
88 | bool isAbsolutelyPositioned() const; |
89 | bool isFixedPositioned() const; |
90 | bool isFloatingPositioned() const; |
91 | bool isLeftFloatingPositioned() const; |
92 | bool isRightFloatingPositioned() const; |
93 | bool hasFloatClear() const; |
94 | |
95 | bool isFloatingOrOutOfFlowPositioned() const { return isFloatingPositioned() || isOutOfFlowPositioned(); } |
96 | |
97 | const Container* containingBlock() const; |
98 | const Container& formattingContextRoot() const; |
99 | const Container& initialContainingBlock() const; |
100 | |
101 | bool isDescendantOf(const Container&) const; |
102 | |
103 | bool isAnonymous() const { return !m_elementAttributes; } |
104 | |
105 | bool isBlockLevelBox() const; |
106 | bool isInlineLevelBox() const; |
107 | bool isInlineBlockBox() const; |
108 | bool isBlockContainerBox() const; |
109 | bool isInitialContainingBlock() const; |
110 | |
111 | bool isDocumentBox() const { return m_elementAttributes && m_elementAttributes.value().elementType == ElementType::Document; } |
112 | bool isBodyBox() const { return m_elementAttributes && m_elementAttributes.value().elementType == ElementType::Body; } |
113 | bool isTableCell() const { return m_elementAttributes && m_elementAttributes.value().elementType == ElementType::TableCell; } |
114 | bool isReplaced() const { return isImage() || isIFrame(); } |
115 | bool isIFrame() const { return m_elementAttributes && m_elementAttributes.value().elementType == ElementType::IFrame; } |
116 | bool isImage() const { return m_elementAttributes && m_elementAttributes.value().elementType == ElementType::Image; } |
117 | |
118 | const Container* parent() const { return m_parent; } |
119 | const Box* nextSibling() const { return m_nextSibling; } |
120 | const Box* nextInFlowSibling() const; |
121 | const Box* nextInFlowOrFloatingSibling() const; |
122 | const Box* previousSibling() const { return m_previousSibling; } |
123 | const Box* previousInFlowSibling() const; |
124 | const Box* previousInFlowOrFloatingSibling() const; |
125 | |
126 | bool isContainer() const { return m_baseTypeFlags & ContainerFlag; } |
127 | bool isBlockContainer() const { return m_baseTypeFlags & BlockContainerFlag; } |
128 | bool isInlineBox() const { return m_baseTypeFlags & InlineBoxFlag; } |
129 | bool isInlineContainer() const { return m_baseTypeFlags & InlineContainerFlag; } |
130 | bool isLineBreakBox() const { return m_baseTypeFlags & LineBreakBoxFlag; } |
131 | |
132 | bool isPaddingApplicable() const; |
133 | bool isOverflowVisible() const; |
134 | |
135 | const RenderStyle& style() const { return m_style; } |
136 | |
137 | const Replaced* replaced() const { return m_replaced.get(); } |
138 | // FIXME: Temporary until after intrinsic size change is tracked by Replaced. |
139 | Replaced* replaced() { return m_replaced.get(); } |
140 | |
141 | void setParent(Container& parent) { m_parent = &parent; } |
142 | void setNextSibling(Box& nextSibling) { m_nextSibling = &nextSibling; } |
143 | void setPreviousSibling(Box& previousSibling) { m_previousSibling = &previousSibling; } |
144 | |
145 | protected: |
146 | Box(Optional<ElementAttributes>, RenderStyle&&, BaseTypeFlags); |
147 | |
148 | private: |
149 | RenderStyle m_style; |
150 | Optional<ElementAttributes> m_elementAttributes; |
151 | |
152 | Container* m_parent { nullptr }; |
153 | Box* m_previousSibling { nullptr }; |
154 | Box* m_nextSibling { nullptr }; |
155 | |
156 | std::unique_ptr<Replaced> m_replaced; |
157 | |
158 | unsigned m_baseTypeFlags : 5; |
159 | }; |
160 | |
161 | } |
162 | } |
163 | |
164 | #define SPECIALIZE_TYPE_TRAITS_LAYOUT_BOX(ToValueTypeName, predicate) \ |
165 | SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::Layout::ToValueTypeName) \ |
166 | static bool isType(const WebCore::Layout::Box& box) { return box.predicate; } \ |
167 | SPECIALIZE_TYPE_TRAITS_END() |
168 | |
169 | #endif |
170 | |