Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutFieldset.cpp

Issue 2555413002: Revert commit# 415577 "Add grid/flex layout support for <fieldset>" (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2000 Dirk Mueller (mueller@kde.org) 4 * (C) 2000 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. 5 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details. 15 * Library General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Library General Public License 17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to 18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA. 20 * Boston, MA 02110-1301, USA.
21 * 21 *
22 */ 22 */
23 23
24 #include "core/layout/LayoutFieldset.h" 24 #include "core/layout/LayoutFieldset.h"
25 25
26 #include "core/CSSPropertyNames.h" 26 #include "core/CSSPropertyNames.h"
27 #include "core/HTMLNames.h" 27 #include "core/HTMLNames.h"
28 #include "core/dom/AXObjectCache.h"
29 #include "core/html/HTMLLegendElement.h" 28 #include "core/html/HTMLLegendElement.h"
30 #include "core/paint/FieldsetPainter.h" 29 #include "core/paint/FieldsetPainter.h"
31 30
32 using namespace std; 31 using namespace std;
33 32
34 namespace blink { 33 namespace blink {
35 34
36 using namespace HTMLNames; 35 using namespace HTMLNames;
37 36
38 namespace { 37 LayoutFieldset::LayoutFieldset(Element* element) : LayoutBlockFlow(element) {}
39 38
40 void setInnerBlockPadding(bool isHorizontalWritingMode, 39 void LayoutFieldset::computePreferredLogicalWidths() {
41 const LayoutObject* innerBlock, 40 LayoutBlockFlow::computePreferredLogicalWidths();
42 const LayoutUnit& padding) { 41 if (LayoutBox* legend = findInFlowLegend()) {
43 if (isHorizontalWritingMode) 42 int legendMinWidth = legend->minPreferredLogicalWidth().toInt();
44 innerBlock->mutableStyleRef().setPaddingTop(Length(padding, Fixed));
45 else
46 innerBlock->mutableStyleRef().setPaddingLeft(Length(padding, Fixed));
47 }
48 43
49 void resetInnerBlockPadding(bool isHorizontalWritingMode, 44 Length legendMarginLeft = legend->style()->marginLeft();
50 const LayoutObject* innerBlock) { 45 Length legendMarginRight = legend->style()->marginRight();
51 if (isHorizontalWritingMode)
52 innerBlock->mutableStyleRef().setPaddingTop(Length(0, Fixed));
53 else
54 innerBlock->mutableStyleRef().setPaddingLeft(Length(0, Fixed));
55 }
56 46
57 } // namespace 47 if (legendMarginLeft.isFixed())
48 legendMinWidth += legendMarginLeft.value();
58 49
59 LayoutFieldset::LayoutFieldset(Element* element) 50 if (legendMarginRight.isFixed())
60 : LayoutFlexibleBox(element), m_innerBlock(nullptr) {} 51 legendMinWidth += legendMarginRight.value();
61 52
62 int LayoutFieldset::baselinePosition(FontBaseline baseline, 53 m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth,
63 bool firstLine, 54 legendMinWidth + borderAndPaddingWidth());
64 LineDirectionMode direction,
65 LinePositionMode position) const {
66 return LayoutBlock::baselinePosition(baseline, firstLine, direction,
67 position);
68 }
69
70 void LayoutFieldset::computeIntrinsicLogicalWidths(
71 LayoutUnit& minLogicalWidth,
72 LayoutUnit& maxLogicalWidth) const {
73 for (LayoutBox* child = firstChildBox(); child;
74 child = child->nextSiblingBox()) {
75 if (child->isOutOfFlowPositioned())
76 continue;
77
78 LayoutUnit margin = marginIntrinsicLogicalWidthForChild(*child);
79
80 LayoutUnit minPreferredLogicalWidth;
81 LayoutUnit maxPreferredLogicalWidth;
82 computeChildPreferredLogicalWidths(*child, minPreferredLogicalWidth,
83 maxPreferredLogicalWidth);
84 DCHECK_GE(minPreferredLogicalWidth, LayoutUnit());
85 DCHECK_GE(maxPreferredLogicalWidth, LayoutUnit());
86 minPreferredLogicalWidth += margin;
87 maxPreferredLogicalWidth += margin;
88 minLogicalWidth = std::max(minPreferredLogicalWidth, minLogicalWidth);
89 maxLogicalWidth = std::max(maxPreferredLogicalWidth, maxLogicalWidth);
90 }
91
92 maxLogicalWidth = std::max(minLogicalWidth, maxLogicalWidth);
93
94 // Due to negative margins, it is possible that we calculated a negative intri nsic width. Make sure that we
95 // never return a negative width.
96 minLogicalWidth = std::max(LayoutUnit(), minLogicalWidth);
97 maxLogicalWidth = std::max(LayoutUnit(), maxLogicalWidth);
98
99 LayoutUnit scrollbarWidth(scrollbarLogicalWidth());
100 maxLogicalWidth += scrollbarWidth;
101 minLogicalWidth += scrollbarWidth;
102 }
103
104 void LayoutFieldset::setLogicalLeftForChild(LayoutBox& child,
105 LayoutUnit logicalLeft) {
106 if (isHorizontalWritingMode()) {
107 child.setX(logicalLeft);
108 } else {
109 child.setY(logicalLeft);
110 } 55 }
111 } 56 }
112 57
113 void LayoutFieldset::setLogicalTopForChild(LayoutBox& child,
114 LayoutUnit logicalTop) {
115 if (isHorizontalWritingMode()) {
116 child.setY(logicalTop);
117 } else {
118 child.setX(logicalTop);
119 }
120 }
121
122 LayoutObject* LayoutFieldset::layoutSpecialExcludedChild(bool relayoutChildren, 58 LayoutObject* LayoutFieldset::layoutSpecialExcludedChild(bool relayoutChildren,
123 SubtreeLayoutScope&) { 59 SubtreeLayoutScope&) {
124 LayoutBox* legend = findInFlowLegend(); 60 LayoutBox* legend = findInFlowLegend();
125 if (legend) { 61 if (legend) {
126 LayoutRect oldLegendFrameRect = legend->frameRect(); 62 LayoutRect oldLegendFrameRect = legend->frameRect();
127 63
128 if (relayoutChildren) 64 if (relayoutChildren)
129 legend->setNeedsLayoutAndFullPaintInvalidation( 65 legend->setNeedsLayoutAndFullPaintInvalidation(
130 LayoutInvalidationReason::FieldsetChanged); 66 LayoutInvalidationReason::FieldsetChanged);
131 legend->layoutIfNeeded(); 67 legend->layoutIfNeeded();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 } 102 }
167 } 103 }
168 104
169 setLogicalLeftForChild(*legend, logicalLeft); 105 setLogicalLeftForChild(*legend, logicalLeft);
170 106
171 LayoutUnit fieldsetBorderBefore = LayoutUnit(borderBefore()); 107 LayoutUnit fieldsetBorderBefore = LayoutUnit(borderBefore());
172 LayoutUnit legendLogicalHeight = logicalHeightForChild(*legend); 108 LayoutUnit legendLogicalHeight = logicalHeightForChild(*legend);
173 109
174 LayoutUnit legendLogicalTop; 110 LayoutUnit legendLogicalTop;
175 LayoutUnit collapsedLegendExtent; 111 LayoutUnit collapsedLegendExtent;
176 LayoutUnit innerBlockPadding;
177 // FIXME: We need to account for the legend's margin before too. 112 // FIXME: We need to account for the legend's margin before too.
178 if (fieldsetBorderBefore > legendLogicalHeight) { 113 if (fieldsetBorderBefore > legendLogicalHeight) {
179 // The <legend> is smaller than the associated fieldset before border 114 // The <legend> is smaller than the associated fieldset before border
180 // so the latter determines positioning of the <legend>. The sizing depend s 115 // so the latter determines positioning of the <legend>. The sizing depend s
181 // on the legend's margins as we want to still follow the author's cues. 116 // on the legend's margins as we want to still follow the author's cues.
182 // Firefox completely ignores the margins in this case which seems wrong. 117 // Firefox completely ignores the margins in this case which seems wrong.
183 legendLogicalTop = (fieldsetBorderBefore - legendLogicalHeight) / 2; 118 legendLogicalTop = (fieldsetBorderBefore - legendLogicalHeight) / 2;
184 collapsedLegendExtent = max<LayoutUnit>( 119 collapsedLegendExtent = max<LayoutUnit>(
185 fieldsetBorderBefore, legendLogicalTop + legendLogicalHeight + 120 fieldsetBorderBefore, legendLogicalTop + legendLogicalHeight +
186 marginAfterForChild(*legend)); 121 marginAfterForChild(*legend));
187 innerBlockPadding = marginAfterForChild(*legend)
188 ? marginAfterForChild(*legend) - legendLogicalTop
189 : LayoutUnit();
190 } else { 122 } else {
191 collapsedLegendExtent = 123 collapsedLegendExtent =
192 legendLogicalHeight + marginAfterForChild(*legend); 124 legendLogicalHeight + marginAfterForChild(*legend);
193 innerBlockPadding =
194 legendLogicalHeight - borderAfter() + marginAfterForChild(*legend);
195 } 125 }
196 126
197 if (m_innerBlock)
198 setInnerBlockPadding(isHorizontalWritingMode(), m_innerBlock,
199 innerBlockPadding);
200 setLogicalTopForChild(*legend, legendLogicalTop); 127 setLogicalTopForChild(*legend, legendLogicalTop);
201 setLogicalHeight(paddingBefore() + collapsedLegendExtent); 128 setLogicalHeight(paddingBefore() + collapsedLegendExtent);
202 129
203 if (legend->frameRect() != oldLegendFrameRect) { 130 if (legend->frameRect() != oldLegendFrameRect) {
204 // We need to invalidate the fieldset border if the legend's frame changed . 131 // We need to invalidate the fieldset border if the legend's frame changed .
205 setShouldDoFullPaintInvalidation(); 132 setShouldDoFullPaintInvalidation();
206 if (m_innerBlock)
207 m_innerBlock->setNeedsLayout(LayoutInvalidationReason::FieldsetChanged,
208 MarkOnlyThis);
209 } 133 }
210 } 134 }
211 return legend; 135 return legend;
212 } 136 }
213 137
214 LayoutBox* LayoutFieldset::findInFlowLegend() const { 138 LayoutBox* LayoutFieldset::findInFlowLegend() const {
215 for (LayoutObject* legend = firstChild(); legend; 139 for (LayoutObject* legend = firstChild(); legend;
216 legend = legend->nextSibling()) { 140 legend = legend->nextSibling()) {
217 if (legend->isFloatingOrOutOfFlowPositioned()) 141 if (legend->isFloatingOrOutOfFlowPositioned())
218 continue; 142 continue;
219 143
220 if (isHTMLLegendElement(legend->node())) 144 if (isHTMLLegendElement(legend->node()))
221 return toLayoutBox(legend); 145 return toLayoutBox(legend);
222 } 146 }
223 return nullptr; 147 return nullptr;
224 } 148 }
225 149
226 void LayoutFieldset::paintBoxDecorationBackground( 150 void LayoutFieldset::paintBoxDecorationBackground(
227 const PaintInfo& paintInfo, 151 const PaintInfo& paintInfo,
228 const LayoutPoint& paintOffset) const { 152 const LayoutPoint& paintOffset) const {
229 FieldsetPainter(*this).paintBoxDecorationBackground(paintInfo, paintOffset); 153 FieldsetPainter(*this).paintBoxDecorationBackground(paintInfo, paintOffset);
230 } 154 }
231 155
232 void LayoutFieldset::paintMask(const PaintInfo& paintInfo, 156 void LayoutFieldset::paintMask(const PaintInfo& paintInfo,
233 const LayoutPoint& paintOffset) const { 157 const LayoutPoint& paintOffset) const {
234 FieldsetPainter(*this).paintMask(paintInfo, paintOffset); 158 FieldsetPainter(*this).paintMask(paintInfo, paintOffset);
235 } 159 }
236 160
237 void LayoutFieldset::updateAnonymousChildStyle(
238 const LayoutObject& child,
239 ComputedStyle& childStyle) const {
240 childStyle.setFlexShrink(1.0f);
241 childStyle.setFlexGrow(1.0f);
242 // min-width: 0; is needed for correct shrinking.
243 childStyle.setMinWidth(Length(0, Fixed));
244 childStyle.setFlexDirection(style()->flexDirection());
245 childStyle.setJustifyContent(style()->justifyContent());
246 childStyle.setFlexWrap(style()->flexWrap());
247 childStyle.setAlignItems(style()->alignItems());
248 childStyle.setAlignContent(style()->alignContent());
249 // Let anonymous block to be the 1st for correct layout positioning.
250 childStyle.setOrder(1);
251 }
252
253 void LayoutFieldset::addChild(LayoutObject* newChild,
254 LayoutObject* beforeChild) {
255 if (!m_innerBlock)
256 createInnerBlock();
257
258 if (isHTMLLegendElement(newChild->node())) {
259 // Let legend block to be the 2nd for correct layout positioning.
260 newChild->mutableStyle()->setOrder(2);
261 LayoutFlexibleBox::addChild(newChild, m_innerBlock);
262 } else {
263 if (beforeChild && isHTMLLegendElement(beforeChild->node())) {
264 m_innerBlock->addChild(newChild);
265 } else {
266 m_innerBlock->addChild(newChild, beforeChild);
267 }
268 if (AXObjectCache* cache = document().existingAXObjectCache())
269 cache->childrenChanged(this);
270 }
271 }
272
273 void LayoutFieldset::createInnerBlock() {
274 if (m_innerBlock) {
275 DCHECK(firstChild() == m_innerBlock);
276 return;
277 }
278 m_innerBlock = createAnonymousBlock(style()->display());
279 LayoutFlexibleBox::addChild(m_innerBlock);
280 }
281
282 void LayoutFieldset::removeChild(LayoutObject* oldChild) {
283 if (isHTMLLegendElement(oldChild->node())) {
284 LayoutFlexibleBox::removeChild(oldChild);
285 if (m_innerBlock) {
286 resetInnerBlockPadding(isHorizontalWritingMode(), m_innerBlock);
287 m_innerBlock->setNeedsLayout(LayoutInvalidationReason::FieldsetChanged,
288 MarkOnlyThis);
289 }
290 setShouldDoFullPaintInvalidation();
291 } else if (oldChild == m_innerBlock) {
292 LayoutFlexibleBox::removeChild(oldChild);
293 m_innerBlock = nullptr;
294 } else if (oldChild->parent() == this) {
295 LayoutFlexibleBox::removeChild(oldChild);
296 } else if (m_innerBlock) {
297 m_innerBlock->removeChild(oldChild);
298 }
299 }
300
301 } // namespace blink 161 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutFieldset.h ('k') | third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698