/src/mozilla-central/layout/generic/nsIFrameInlines.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef nsIFrameInlines_h___ |
8 | | #define nsIFrameInlines_h___ |
9 | | |
10 | | #include "mozilla/dom/ElementInlines.h" |
11 | | #include "nsContainerFrame.h" |
12 | | #include "nsPlaceholderFrame.h" |
13 | | #include "nsStyleStructInlines.h" |
14 | | #include "nsCSSAnonBoxes.h" |
15 | | #include "nsFrameManager.h" |
16 | | |
17 | | bool |
18 | | nsIFrame::IsFlexItem() const |
19 | 0 | { |
20 | 0 | return GetParent() && GetParent()->IsFlexContainerFrame() && |
21 | 0 | !(GetStateBits() & NS_FRAME_OUT_OF_FLOW); |
22 | 0 | } |
23 | | |
24 | | bool |
25 | | nsIFrame::IsFlexOrGridContainer() const |
26 | 0 | { |
27 | 0 | return IsFlexContainerFrame() || IsGridContainerFrame(); |
28 | 0 | } |
29 | | |
30 | | bool |
31 | | nsIFrame::IsFlexOrGridItem() const |
32 | 0 | { |
33 | 0 | return !(GetStateBits() & NS_FRAME_OUT_OF_FLOW) && |
34 | 0 | GetParent() && |
35 | 0 | GetParent()->IsFlexOrGridContainer(); |
36 | 0 | } |
37 | | |
38 | | bool |
39 | | nsIFrame::IsTableCaption() const |
40 | 0 | { |
41 | 0 | return StyleDisplay()->mDisplay == mozilla::StyleDisplay::TableCaption && |
42 | 0 | GetParent()->Style()->GetPseudo() == nsCSSAnonBoxes::tableWrapper(); |
43 | 0 | } |
44 | | |
45 | | bool |
46 | | nsIFrame::IsFloating() const |
47 | 0 | { |
48 | 0 | return StyleDisplay()->IsFloating(this); |
49 | 0 | } |
50 | | |
51 | | bool |
52 | | nsIFrame::IsAbsPosContainingBlock() const |
53 | 0 | { |
54 | 0 | return StyleDisplay()->IsAbsPosContainingBlock(this); |
55 | 0 | } |
56 | | |
57 | | bool |
58 | | nsIFrame::IsFixedPosContainingBlock() const |
59 | 0 | { |
60 | 0 | return StyleDisplay()->IsFixedPosContainingBlock(this); |
61 | 0 | } |
62 | | |
63 | | bool |
64 | | nsIFrame::IsRelativelyPositioned() const |
65 | 0 | { |
66 | 0 | return StyleDisplay()->IsRelativelyPositioned(this); |
67 | 0 | } |
68 | | |
69 | | bool |
70 | | nsIFrame::IsAbsolutelyPositioned(const nsStyleDisplay* aStyleDisplay) const |
71 | 0 | { |
72 | 0 | const nsStyleDisplay* disp = StyleDisplayWithOptionalParam(aStyleDisplay); |
73 | 0 | return disp->IsAbsolutelyPositioned(this); |
74 | 0 | } |
75 | | |
76 | | bool |
77 | | nsIFrame::IsBlockInside() const |
78 | 0 | { |
79 | 0 | return StyleDisplay()->IsBlockInside(this); |
80 | 0 | } |
81 | | |
82 | | bool |
83 | | nsIFrame::IsBlockOutside() const |
84 | 0 | { |
85 | 0 | return StyleDisplay()->IsBlockOutside(this); |
86 | 0 | } |
87 | | |
88 | | bool |
89 | | nsIFrame::IsInlineOutside() const |
90 | 0 | { |
91 | 0 | return StyleDisplay()->IsInlineOutside(this); |
92 | 0 | } |
93 | | |
94 | | mozilla::StyleDisplay |
95 | | nsIFrame::GetDisplay() const |
96 | 0 | { |
97 | 0 | return StyleDisplay()->GetDisplay(this); |
98 | 0 | } |
99 | | |
100 | | nscoord |
101 | | nsIFrame::SynthesizeBaselineBOffsetFromMarginBox( |
102 | | mozilla::WritingMode aWM, |
103 | | BaselineSharingGroup aGroup) const |
104 | 0 | { |
105 | 0 | MOZ_ASSERT(!aWM.IsOrthogonalTo(GetWritingMode())); |
106 | 0 | auto margin = GetLogicalUsedMargin(aWM); |
107 | 0 | if (aGroup == BaselineSharingGroup::eFirst) { |
108 | 0 | if (aWM.IsAlphabeticalBaseline()) { |
109 | 0 | // First baseline for inverted-line content is the block-start margin edge, |
110 | 0 | // as the frame is in effect "flipped" for alignment purposes. |
111 | 0 | return MOZ_UNLIKELY(aWM.IsLineInverted()) ? -margin.BStart(aWM) |
112 | 0 | : BSize(aWM) + margin.BEnd(aWM); |
113 | 0 | } |
114 | 0 | nscoord marginBoxCenter = (BSize(aWM) + margin.BStartEnd(aWM)) / 2; |
115 | 0 | return marginBoxCenter - margin.BStart(aWM); |
116 | 0 | } |
117 | 0 | MOZ_ASSERT(aGroup == BaselineSharingGroup::eLast); |
118 | 0 | if (aWM.IsAlphabeticalBaseline()) { |
119 | 0 | // Last baseline for inverted-line content is the block-start margin edge, |
120 | 0 | // as the frame is in effect "flipped" for alignment purposes. |
121 | 0 | return MOZ_UNLIKELY(aWM.IsLineInverted()) ? BSize(aWM) + margin.BStart(aWM) |
122 | 0 | : -margin.BEnd(aWM); |
123 | 0 | } |
124 | 0 | // Round up for central baseline offset, to be consistent with eFirst. |
125 | 0 | nscoord marginBoxSize = BSize(aWM) + margin.BStartEnd(aWM); |
126 | 0 | nscoord marginBoxCenter = (marginBoxSize / 2) + (marginBoxSize % 2); |
127 | 0 | return marginBoxCenter - margin.BEnd(aWM); |
128 | 0 | } |
129 | | |
130 | | nscoord |
131 | | nsIFrame::SynthesizeBaselineBOffsetFromBorderBox( |
132 | | mozilla::WritingMode aWM, |
133 | | BaselineSharingGroup aGroup) const |
134 | 0 | { |
135 | 0 | MOZ_ASSERT(!aWM.IsOrthogonalTo(GetWritingMode())); |
136 | 0 | nscoord borderBoxSize = BSize(aWM); |
137 | 0 | if (aGroup == BaselineSharingGroup::eFirst) { |
138 | 0 | return MOZ_LIKELY(aWM.IsAlphabeticalBaseline()) ? borderBoxSize |
139 | 0 | : borderBoxSize / 2; |
140 | 0 | } |
141 | 0 | MOZ_ASSERT(aGroup == BaselineSharingGroup::eLast); |
142 | 0 | // Round up for central baseline offset, to be consistent with eFirst. |
143 | 0 | auto borderBoxCenter = (borderBoxSize / 2) + (borderBoxSize % 2); |
144 | 0 | return MOZ_LIKELY(aWM.IsAlphabeticalBaseline()) ? 0 : borderBoxCenter; |
145 | 0 | } |
146 | | |
147 | | nscoord |
148 | | nsIFrame::BaselineBOffset(mozilla::WritingMode aWM, |
149 | | BaselineSharingGroup aBaselineGroup, |
150 | | AlignmentContext aAlignmentContext) const |
151 | 0 | { |
152 | 0 | MOZ_ASSERT(!aWM.IsOrthogonalTo(GetWritingMode())); |
153 | 0 | nscoord baseline; |
154 | 0 | if (GetNaturalBaselineBOffset(aWM, aBaselineGroup, &baseline)) { |
155 | 0 | return baseline; |
156 | 0 | } |
157 | 0 | if (aAlignmentContext == AlignmentContext::eInline) { |
158 | 0 | return SynthesizeBaselineBOffsetFromMarginBox(aWM, aBaselineGroup); |
159 | 0 | } |
160 | 0 | // XXX AlignmentContext::eTable should use content box? |
161 | 0 | return SynthesizeBaselineBOffsetFromBorderBox(aWM, aBaselineGroup); |
162 | 0 | } |
163 | | |
164 | | void |
165 | | nsIFrame::PropagateRootElementWritingMode(mozilla::WritingMode aRootElemWM) |
166 | 0 | { |
167 | 0 | MOZ_ASSERT(IsCanvasFrame()); |
168 | 0 | for (auto f = this; f; f = f->GetParent()) { |
169 | 0 | f->mWritingMode = aRootElemWM; |
170 | 0 | } |
171 | 0 | } |
172 | | |
173 | | nsContainerFrame* |
174 | | nsIFrame::GetInFlowParent() const |
175 | 0 | { |
176 | 0 | if (GetStateBits() & NS_FRAME_OUT_OF_FLOW) { |
177 | 0 | nsIFrame* ph = FirstContinuation()->GetProperty(nsIFrame::PlaceholderFrameProperty()); |
178 | 0 | return ph->GetParent(); |
179 | 0 | } |
180 | 0 | |
181 | 0 | return GetParent(); |
182 | 0 | } |
183 | | |
184 | | // We generally want to follow the style tree for preserve-3d, jumping through |
185 | | // display: contents. |
186 | | // |
187 | | // There are various fun mismatches between the flattened tree and the frame |
188 | | // tree which makes this non-trivial to do looking at the frame tree state: |
189 | | // |
190 | | // - Anon boxes. You'd have to step through them, because you generally want to |
191 | | // ignore them. |
192 | | // |
193 | | // - IB-splits, which produce a frame tree where frames for the block inside |
194 | | // the inline are not children of any frame from the inline. |
195 | | // |
196 | | // - display: contents, which makes DOM ancestors not have frames even when a |
197 | | // descendant does. |
198 | | // |
199 | | // See GetFlattenedTreeParentElementForStyle for the difference between it and |
200 | | // plain GetFlattenedTreeParentElement. |
201 | | nsIFrame* |
202 | | nsIFrame::GetClosestFlattenedTreeAncestorPrimaryFrame() const |
203 | 0 | { |
204 | 0 | if (!mContent) { |
205 | 0 | return nullptr; |
206 | 0 | } |
207 | 0 | Element* parent = mContent->GetFlattenedTreeParentElementForStyle(); |
208 | 0 | while (parent) { |
209 | 0 | if (nsIFrame* frame = parent->GetPrimaryFrame()) { |
210 | 0 | return frame; |
211 | 0 | } |
212 | 0 | // NOTE(emilio): This should be an assert except we have code in tree which |
213 | 0 | // violates invariants like the <frameset> frame construction code. |
214 | 0 | if (MOZ_UNLIKELY(!parent->IsDisplayContents())) { |
215 | 0 | return nullptr; |
216 | 0 | } |
217 | 0 | parent = parent->GetFlattenedTreeParentElementForStyle(); |
218 | 0 | } |
219 | 0 | return nullptr; |
220 | 0 | } |
221 | | |
222 | | #endif |