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

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

Issue 2150003005: Add grid/flex layout support for <fieldset> (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: revert a11y test expectations & explicitely set a11y fieldset role to GroupRole Created 4 years, 4 months 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.
(...skipping 16 matching lines...) Expand all
27 #include "core/HTMLNames.h" 27 #include "core/HTMLNames.h"
28 #include "core/html/HTMLLegendElement.h" 28 #include "core/html/HTMLLegendElement.h"
29 #include "core/paint/FieldsetPainter.h" 29 #include "core/paint/FieldsetPainter.h"
30 30
31 using namespace std; 31 using namespace std;
32 32
33 namespace blink { 33 namespace blink {
34 34
35 using namespace HTMLNames; 35 using namespace HTMLNames;
36 36
37 namespace {
38
39 void setInnerBlockPadding(bool isHorizontalWritingMode, const LayoutObject* inne rBlock, const LayoutUnit& padding)
40 {
41 if (isHorizontalWritingMode)
42 innerBlock->mutableStyleRef().setPaddingTop(Length(padding, Fixed));
43 else
44 innerBlock->mutableStyleRef().setPaddingLeft(Length(padding, Fixed));
45 }
46
47 void resetInnerBlockPadding(bool isHorizontalWritingMode, const LayoutObject* in nerBlock)
48 {
49 if (isHorizontalWritingMode)
50 innerBlock->mutableStyleRef().setPaddingTop(Length(0, Fixed));
51 else
52 innerBlock->mutableStyleRef().setPaddingLeft(Length(0, Fixed));
53 }
54
55 } // namespace
56
37 LayoutFieldset::LayoutFieldset(Element* element) 57 LayoutFieldset::LayoutFieldset(Element* element)
38 : LayoutBlockFlow(element) 58 : LayoutFlexibleBox(element), m_innerBlock(nullptr)
39 { 59 {
40 } 60 }
41 61
42 void LayoutFieldset::computePreferredLogicalWidths() 62 int LayoutFieldset::baselinePosition(FontBaseline baseline, bool firstLine, Line DirectionMode direction, LinePositionMode position) const
43 { 63 {
44 LayoutBlockFlow::computePreferredLogicalWidths(); 64 return LayoutBlock::baselinePosition(baseline, firstLine, direction, positio n);
65 }
66
67 void LayoutFieldset::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
68 {
69 if (m_innerBlock)
70 computeChildPreferredLogicalWidths(*m_innerBlock, minLogicalWidth, maxLo gicalWidth);
71
45 if (LayoutBox* legend = findInFlowLegend()) { 72 if (LayoutBox* legend = findInFlowLegend()) {
46 int legendMinWidth = legend->minPreferredLogicalWidth(); 73 LayoutUnit minPreferredLegendLogicalWidth;
74 LayoutUnit maxPreferredLegendLogicalWidth;
75 computeChildPreferredLogicalWidths(*legend, minPreferredLegendLogicalWid th, maxPreferredLegendLogicalWidth);
76 LayoutUnit margin = marginIntrinsicLogicalWidthForChild(*legend);
77 minPreferredLegendLogicalWidth += margin;
78 maxPreferredLegendLogicalWidth += margin;
79 minLogicalWidth = std::max(minLogicalWidth, minPreferredLegendLogicalWid th);
80 maxLogicalWidth = std::max(maxLogicalWidth, maxPreferredLegendLogicalWid th);
81 }
82 maxLogicalWidth = std::max(minLogicalWidth, maxLogicalWidth);
47 83
48 Length legendMarginLeft = legend->style()->marginLeft(); 84 // Due to negative margins, it is possible that we calculated a negative int rinsic width. Make sure that we
49 Length legendMarginRight = legend->style()->marginRight(); 85 // never return a negative width.
86 minLogicalWidth = std::max(LayoutUnit(), minLogicalWidth);
87 maxLogicalWidth = std::max(LayoutUnit(), maxLogicalWidth);
50 88
51 if (legendMarginLeft.isFixed()) 89 LayoutUnit scrollbarWidth(scrollbarLogicalWidth());
52 legendMinWidth += legendMarginLeft.value(); 90 maxLogicalWidth += scrollbarWidth;
91 minLogicalWidth += scrollbarWidth;
92 }
53 93
54 if (legendMarginRight.isFixed()) 94 void LayoutFieldset::setLogicalLeftForChild(LayoutBox& child, LayoutUnit logical Left)
55 legendMinWidth += legendMarginRight.value(); 95 {
56 96 if (isHorizontalWritingMode()) {
57 m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, legendMinWi dth + borderAndPaddingWidth()); 97 child.setX(logicalLeft);
98 } else {
99 child.setY(logicalLeft);
58 } 100 }
59 } 101 }
60 102
103 void LayoutFieldset::setLogicalTopForChild(LayoutBox& child, LayoutUnit logicalT op)
104 {
105 if (isHorizontalWritingMode()) {
106 child.setY(logicalTop);
107 } else {
108 child.setX(logicalTop);
109 }
110 }
111
61 LayoutObject* LayoutFieldset::layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope&) 112 LayoutObject* LayoutFieldset::layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope&)
62 { 113 {
63 LayoutBox* legend = findInFlowLegend(); 114 LayoutBox* legend = findInFlowLegend();
64 if (legend) { 115 if (legend) {
65 LayoutRect oldLegendFrameRect = legend->frameRect(); 116 LayoutRect oldLegendFrameRect = legend->frameRect();
66 117
67 if (relayoutChildren) 118 if (relayoutChildren)
68 legend->setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationRea son::FieldsetChanged); 119 legend->setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationRea son::FieldsetChanged);
69 legend->layoutIfNeeded(); 120 legend->layoutIfNeeded();
70 121
(...skipping 28 matching lines...) Expand all
99 } 150 }
100 } 151 }
101 152
102 setLogicalLeftForChild(*legend, logicalLeft); 153 setLogicalLeftForChild(*legend, logicalLeft);
103 154
104 LayoutUnit fieldsetBorderBefore = LayoutUnit(borderBefore()); 155 LayoutUnit fieldsetBorderBefore = LayoutUnit(borderBefore());
105 LayoutUnit legendLogicalHeight = logicalHeightForChild(*legend); 156 LayoutUnit legendLogicalHeight = logicalHeightForChild(*legend);
106 157
107 LayoutUnit legendLogicalTop; 158 LayoutUnit legendLogicalTop;
108 LayoutUnit collapsedLegendExtent; 159 LayoutUnit collapsedLegendExtent;
160 LayoutUnit innerBlockPadding;
109 // FIXME: We need to account for the legend's margin before too. 161 // FIXME: We need to account for the legend's margin before too.
110 if (fieldsetBorderBefore > legendLogicalHeight) { 162 if (fieldsetBorderBefore > legendLogicalHeight) {
111 // The <legend> is smaller than the associated fieldset before borde r 163 // The <legend> is smaller than the associated fieldset before borde r
112 // so the latter determines positioning of the <legend>. The sizing depends 164 // so the latter determines positioning of the <legend>. The sizing depends
113 // on the legend's margins as we want to still follow the author's c ues. 165 // on the legend's margins as we want to still follow the author's c ues.
114 // Firefox completely ignores the margins in this case which seems w rong. 166 // Firefox completely ignores the margins in this case which seems w rong.
115 legendLogicalTop = (fieldsetBorderBefore - legendLogicalHeight) / 2; 167 legendLogicalTop = (fieldsetBorderBefore - legendLogicalHeight) / 2;
116 collapsedLegendExtent = max<LayoutUnit>(fieldsetBorderBefore, legend LogicalTop + legendLogicalHeight + marginAfterForChild(*legend)); 168 collapsedLegendExtent = max<LayoutUnit>(fieldsetBorderBefore, legend LogicalTop + legendLogicalHeight + marginAfterForChild(*legend));
169 innerBlockPadding = marginAfterForChild(*legend) ? marginAfterForChi ld(*legend) - legendLogicalTop : LayoutUnit();
117 } else { 170 } else {
118 collapsedLegendExtent = legendLogicalHeight + marginAfterForChild(*l egend); 171 collapsedLegendExtent = legendLogicalHeight + marginAfterForChild(*l egend);
172 innerBlockPadding = legendLogicalHeight - borderAfter() + marginAfte rForChild(*legend);
119 } 173 }
120 174
175 setInnerBlockPadding(isHorizontalWritingMode(), m_innerBlock, innerBlock Padding);
121 setLogicalTopForChild(*legend, legendLogicalTop); 176 setLogicalTopForChild(*legend, legendLogicalTop);
122 setLogicalHeight(paddingBefore() + collapsedLegendExtent); 177 setLogicalHeight(paddingBefore() + collapsedLegendExtent);
123 178
124 if (legend->frameRect() != oldLegendFrameRect) { 179 if (legend->frameRect() != oldLegendFrameRect) {
125 // We need to invalidate the fieldset border if the legend's frame c hanged. 180 // We need to invalidate the fieldset border if the legend's frame c hanged.
126 setShouldDoFullPaintInvalidation(); 181 setShouldDoFullPaintInvalidation();
127 } 182 }
128 } 183 }
129 return legend; 184 return legend;
130 } 185 }
(...skipping 15 matching lines...) Expand all
146 void LayoutFieldset::paintBoxDecorationBackground(const PaintInfo& paintInfo, co nst LayoutPoint& paintOffset) const 201 void LayoutFieldset::paintBoxDecorationBackground(const PaintInfo& paintInfo, co nst LayoutPoint& paintOffset) const
147 { 202 {
148 FieldsetPainter(*this).paintBoxDecorationBackground(paintInfo, paintOffset); 203 FieldsetPainter(*this).paintBoxDecorationBackground(paintInfo, paintOffset);
149 } 204 }
150 205
151 void LayoutFieldset::paintMask(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) const 206 void LayoutFieldset::paintMask(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) const
152 { 207 {
153 FieldsetPainter(*this).paintMask(paintInfo, paintOffset); 208 FieldsetPainter(*this).paintMask(paintInfo, paintOffset);
154 } 209 }
155 210
211 void LayoutFieldset::styleDidChange(StyleDifference diff, const ComputedStyle* o ldStyle)
212 {
213 LayoutFlexibleBox::styleDidChange(diff, oldStyle);
214 adjustInnerStyle();
215 }
216
217 void LayoutFieldset::addChild(LayoutObject* newChild, LayoutObject* beforeChild)
218 {
219 if (!m_innerBlock)
220 createInnerBlock();
221
222 if (isHTMLLegendElement(newChild->node())) {
223 LayoutFlexibleBox::addChild(newChild, m_innerBlock);
224 } else {
225 m_innerBlock->addChild(newChild, beforeChild);
aboxhall 2016/07/27 21:44:45 I think you may need to explicitly call if (A
Gleb Lanbin 2016/07/27 21:55:08 Done.
226 }
227 }
228
229 void LayoutFieldset::adjustInnerStyle()
230 {
231 if (!m_innerBlock)
232 createInnerBlock();
233
234 ComputedStyle& innerStyle = m_innerBlock->mutableStyleRef();
235 innerStyle.setFlexShrink(1.0f);
236 innerStyle.setFlexGrow(1.0f);
237 // min-width: 0; is needed for correct shrinking.
238 innerStyle.setMinWidth(Length(0, Fixed));
239 innerStyle.setFlexDirection(style()->flexDirection());
240 innerStyle.setJustifyContent(style()->justifyContent());
241 innerStyle.setFlexWrap(style()->flexWrap());
242 innerStyle.setAlignItems(style()->alignItems());
243 innerStyle.setAlignContent(style()->alignContent());
244 }
245
246 void LayoutFieldset::createInnerBlock()
247 {
248 if (m_innerBlock) {
249 DCHECK(firstChild() == m_innerBlock);
250 return;
251 }
252 m_innerBlock = createAnonymousBlock(style()->display());
253 LayoutFlexibleBox::addChild(m_innerBlock);
254 }
255
256 void LayoutFieldset::removeChild(LayoutObject* oldChild)
257 {
258 if (isHTMLLegendElement(oldChild->node())) {
259 LayoutFlexibleBox::removeChild(oldChild);
260 if (m_innerBlock)
261 resetInnerBlockPadding(isHorizontalWritingMode(), m_innerBlock);
262 } else if (oldChild == m_innerBlock) {
263 LayoutFlexibleBox::removeChild(oldChild);
264 m_innerBlock = nullptr;
265 } else if (m_innerBlock) {
266 m_innerBlock->removeChild(oldChild);
267 }
268 }
269
156 } // namespace blink 270 } // 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