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

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

Issue 2549973003: Revert commit# 415577 "Add grid/flex layout support for <fieldset>" (Closed)
Patch Set: updated TestExpectations, verified that there are no changes in images 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
95 // intrinsic width. Make sure that we 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 115 // so the latter determines positioning of the <legend>. The sizing
181 // depends on the legend's margins as we want to still follow the 116 // depends
182 // author's cues. 117 // on the legend's margins as we want to still follow the author's cues.
183 // Firefox completely ignores the margins in this case which seems wrong. 118 // Firefox completely ignores the margins in this case which seems wrong.
184 legendLogicalTop = (fieldsetBorderBefore - legendLogicalHeight) / 2; 119 legendLogicalTop = (fieldsetBorderBefore - legendLogicalHeight) / 2;
185 collapsedLegendExtent = max<LayoutUnit>( 120 collapsedLegendExtent = max<LayoutUnit>(
186 fieldsetBorderBefore, legendLogicalTop + legendLogicalHeight + 121 fieldsetBorderBefore, legendLogicalTop + legendLogicalHeight +
187 marginAfterForChild(*legend)); 122 marginAfterForChild(*legend));
188 innerBlockPadding = marginAfterForChild(*legend)
189 ? marginAfterForChild(*legend) - legendLogicalTop
190 : LayoutUnit();
191 } else { 123 } else {
192 collapsedLegendExtent = 124 collapsedLegendExtent =
193 legendLogicalHeight + marginAfterForChild(*legend); 125 legendLogicalHeight + marginAfterForChild(*legend);
194 innerBlockPadding =
195 legendLogicalHeight - borderAfter() + marginAfterForChild(*legend);
196 } 126 }
197 127
198 if (m_innerBlock)
199 setInnerBlockPadding(isHorizontalWritingMode(), m_innerBlock,
200 innerBlockPadding);
201 setLogicalTopForChild(*legend, legendLogicalTop); 128 setLogicalTopForChild(*legend, legendLogicalTop);
202 setLogicalHeight(paddingBefore() + collapsedLegendExtent); 129 setLogicalHeight(paddingBefore() + collapsedLegendExtent);
203 130
204 if (legend->frameRect() != oldLegendFrameRect) { 131 if (legend->frameRect() != oldLegendFrameRect) {
205 // We need to invalidate the fieldset border if the legend's frame 132 // We need to invalidate the fieldset border if the legend's frame
206 // changed. 133 // changed.
207 setShouldDoFullPaintInvalidation(); 134 setShouldDoFullPaintInvalidation();
208 if (m_innerBlock)
209 m_innerBlock->setNeedsLayout(LayoutInvalidationReason::FieldsetChanged,
210 MarkOnlyThis);
211 } 135 }
212 } 136 }
213 return legend; 137 return legend;
214 } 138 }
215 139
216 LayoutBox* LayoutFieldset::findInFlowLegend() const { 140 LayoutBox* LayoutFieldset::findInFlowLegend() const {
217 for (LayoutObject* legend = firstChild(); legend; 141 for (LayoutObject* legend = firstChild(); legend;
218 legend = legend->nextSibling()) { 142 legend = legend->nextSibling()) {
219 if (legend->isFloatingOrOutOfFlowPositioned()) 143 if (legend->isFloatingOrOutOfFlowPositioned())
220 continue; 144 continue;
221 145
222 if (isHTMLLegendElement(legend->node())) 146 if (isHTMLLegendElement(legend->node()))
223 return toLayoutBox(legend); 147 return toLayoutBox(legend);
224 } 148 }
225 return nullptr; 149 return nullptr;
226 } 150 }
227 151
228 void LayoutFieldset::paintBoxDecorationBackground( 152 void LayoutFieldset::paintBoxDecorationBackground(
229 const PaintInfo& paintInfo, 153 const PaintInfo& paintInfo,
230 const LayoutPoint& paintOffset) const { 154 const LayoutPoint& paintOffset) const {
231 FieldsetPainter(*this).paintBoxDecorationBackground(paintInfo, paintOffset); 155 FieldsetPainter(*this).paintBoxDecorationBackground(paintInfo, paintOffset);
232 } 156 }
233 157
234 void LayoutFieldset::paintMask(const PaintInfo& paintInfo, 158 void LayoutFieldset::paintMask(const PaintInfo& paintInfo,
235 const LayoutPoint& paintOffset) const { 159 const LayoutPoint& paintOffset) const {
236 FieldsetPainter(*this).paintMask(paintInfo, paintOffset); 160 FieldsetPainter(*this).paintMask(paintInfo, paintOffset);
237 } 161 }
238 162
239 void LayoutFieldset::updateAnonymousChildStyle(
240 const LayoutObject& child,
241 ComputedStyle& childStyle) const {
242 childStyle.setFlexShrink(1.0f);
243 childStyle.setFlexGrow(1.0f);
244 // min-width: 0; is needed for correct shrinking.
245 childStyle.setMinWidth(Length(0, Fixed));
246 childStyle.setFlexDirection(style()->flexDirection());
247 childStyle.setJustifyContent(style()->justifyContent());
248 childStyle.setFlexWrap(style()->flexWrap());
249 childStyle.setAlignItems(style()->alignItems());
250 childStyle.setAlignContent(style()->alignContent());
251 // Let anonymous block to be the 1st for correct layout positioning.
252 childStyle.setOrder(1);
253 }
254
255 void LayoutFieldset::addChild(LayoutObject* newChild,
256 LayoutObject* beforeChild) {
257 if (!m_innerBlock)
258 createInnerBlock();
259
260 if (isHTMLLegendElement(newChild->node())) {
261 // Let legend block to be the 2nd for correct layout positioning.
262 newChild->mutableStyle()->setOrder(2);
263 LayoutFlexibleBox::addChild(newChild, m_innerBlock);
264 } else {
265 if (beforeChild && isHTMLLegendElement(beforeChild->node())) {
266 m_innerBlock->addChild(newChild);
267 } else {
268 m_innerBlock->addChild(newChild, beforeChild);
269 }
270 if (AXObjectCache* cache = document().existingAXObjectCache())
271 cache->childrenChanged(this);
272 }
273 }
274
275 void LayoutFieldset::createInnerBlock() {
276 if (m_innerBlock) {
277 DCHECK(firstChild() == m_innerBlock);
278 return;
279 }
280 m_innerBlock = createAnonymousBlock(style()->display());
281 LayoutFlexibleBox::addChild(m_innerBlock);
282 }
283
284 void LayoutFieldset::removeChild(LayoutObject* oldChild) {
285 if (isHTMLLegendElement(oldChild->node())) {
286 LayoutFlexibleBox::removeChild(oldChild);
287 if (m_innerBlock) {
288 resetInnerBlockPadding(isHorizontalWritingMode(), m_innerBlock);
289 m_innerBlock->setNeedsLayout(LayoutInvalidationReason::FieldsetChanged,
290 MarkOnlyThis);
291 }
292 setShouldDoFullPaintInvalidation();
293 } else if (oldChild == m_innerBlock) {
294 LayoutFlexibleBox::removeChild(oldChild);
295 m_innerBlock = nullptr;
296 } else if (oldChild->parent() == this) {
297 LayoutFlexibleBox::removeChild(oldChild);
298 } else if (m_innerBlock) {
299 m_innerBlock->removeChild(oldChild);
300 }
301 }
302
303 } // namespace blink 163 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698