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

Unified 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: updated TestExpectations and fixed legend-after-margin-vertical-writing-mode.html Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/layout/LayoutFieldset.cpp
diff --git a/third_party/WebKit/Source/core/layout/LayoutFieldset.cpp b/third_party/WebKit/Source/core/layout/LayoutFieldset.cpp
index 1af7515adb104d99aa17dda22498d3289939bd56..6797f89a7f32e13395f5aa75b015a9f9d5ee0952 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFieldset.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutFieldset.cpp
@@ -35,26 +35,57 @@ namespace blink {
using namespace HTMLNames;
LayoutFieldset::LayoutFieldset(Element* element)
- : LayoutBlockFlow(element)
+ : LayoutFlexibleBox(element), m_innerBlock(nullptr)
jfernandez 2016/07/20 14:59:57 What's the rationale of inheriting from Flexbox ?
cbiesinger 2016/07/20 20:30:49 LayoutButton inherits from flexbox for the same pu
Manuel Rego 2016/07/21 10:28:43 What are the actual reasons Flexbox will be needed
Gleb Lanbin 2016/07/21 18:25:31 The anonymous block needs to use all available hei
{
}
-void LayoutFieldset::computePreferredLogicalWidths()
+int LayoutFieldset::baselinePosition(FontBaseline baseline, bool firstLine, LineDirectionMode direction, LinePositionMode position) const
{
- LayoutBlockFlow::computePreferredLogicalWidths();
+ return LayoutBlock::baselinePosition(baseline, firstLine, direction, position);
jfernandez 2016/07/20 14:59:57 So you want to avoid the LayoutFlexibleBox::baseli
cbiesinger 2016/07/20 20:30:49 flexbox has a different baseline behavior which mo
+}
+
+void LayoutFieldset::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
+{
+ if (m_innerBlock)
+ computeChildPreferredLogicalWidths(*m_innerBlock, minLogicalWidth, maxLogicalWidth);
+
if (LayoutBox* legend = findInFlowLegend()) {
- int legendMinWidth = legend->minPreferredLogicalWidth();
+ LayoutUnit minPreferredLegendLogicalWidth;
+ LayoutUnit maxPreferredLegendLogicalWidth;
+ computeChildPreferredLogicalWidths(*legend, minPreferredLegendLogicalWidth, maxPreferredLegendLogicalWidth);
+ LayoutUnit margin = marginIntrinsicLogicalWidthForChild(*legend);
+ minPreferredLegendLogicalWidth += margin;
+ maxPreferredLegendLogicalWidth += margin;
+ minLogicalWidth = std::max(minLogicalWidth, minPreferredLegendLogicalWidth);
+ maxLogicalWidth = std::max(maxLogicalWidth, maxPreferredLegendLogicalWidth);
+ }
+ maxLogicalWidth = std::max(minLogicalWidth, maxLogicalWidth);
- Length legendMarginLeft = legend->style()->marginLeft();
- Length legendMarginRight = legend->style()->marginRight();
+ // Due to negative margins, it is possible that we calculated a negative intrinsic width. Make sure that we
+ // never return a negative width.
+ minLogicalWidth = std::max(LayoutUnit(), minLogicalWidth);
+ maxLogicalWidth = std::max(LayoutUnit(), maxLogicalWidth);
- if (legendMarginLeft.isFixed())
- legendMinWidth += legendMarginLeft.value();
+ LayoutUnit scrollbarWidth(scrollbarLogicalWidth());
+ maxLogicalWidth += scrollbarWidth;
+ minLogicalWidth += scrollbarWidth;
+}
- if (legendMarginRight.isFixed())
- legendMinWidth += legendMarginRight.value();
+void LayoutFieldset::setLogicalLeftForChild(LayoutBox& child, LayoutUnit logicalLeft)
+{
+ if (isHorizontalWritingMode()) {
+ child.setX(logicalLeft);
+ } else {
+ child.setY(logicalLeft);
+ }
+}
- m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, legendMinWidth + borderAndPaddingWidth());
+void LayoutFieldset::setLogicalTopForChild(LayoutBox& child, LayoutUnit logicalTop)
+{
+ if (isHorizontalWritingMode()) {
+ child.setY(logicalTop);
+ } else {
+ child.setX(logicalTop);
}
}
@@ -106,6 +137,7 @@ LayoutObject* LayoutFieldset::layoutSpecialExcludedChild(bool relayoutChildren,
LayoutUnit legendLogicalTop;
LayoutUnit collapsedLegendExtent;
+ LayoutUnit innerBlockPadding;
// FIXME: We need to account for the legend's margin before too.
if (fieldsetBorderBefore > legendLogicalHeight) {
// The <legend> is smaller than the associated fieldset before border
@@ -114,8 +146,16 @@ LayoutObject* LayoutFieldset::layoutSpecialExcludedChild(bool relayoutChildren,
// Firefox completely ignores the margins in this case which seems wrong.
legendLogicalTop = (fieldsetBorderBefore - legendLogicalHeight) / 2;
collapsedLegendExtent = max<LayoutUnit>(fieldsetBorderBefore, legendLogicalTop + legendLogicalHeight + marginAfterForChild(*legend));
+ innerBlockPadding = marginAfterForChild(*legend) ? marginAfterForChild(*legend) - legendLogicalTop : LayoutUnit();
} else {
collapsedLegendExtent = legendLogicalHeight + marginAfterForChild(*legend);
+ innerBlockPadding = legendLogicalHeight - borderAfter() + marginAfterForChild(*legend);
+ }
+
+ if (isHorizontalWritingMode()) {
+ m_innerBlock->mutableStyleRef().setPaddingTop(Length(innerBlockPadding, Fixed));
+ } else {
+ m_innerBlock->mutableStyleRef().setPaddingLeft(Length(innerBlockPadding, Fixed));
}
setLogicalTopForChild(*legend, legendLogicalTop);
@@ -153,4 +193,73 @@ void LayoutFieldset::paintMask(const PaintInfo& paintInfo, const LayoutPoint& pa
FieldsetPainter(*this).paintMask(paintInfo, paintOffset);
}
+void LayoutFieldset::styleDidChange(StyleDifference diff, const ComputedStyle* oldStyle)
+{
+ LayoutFlexibleBox::styleDidChange(diff, oldStyle);
+ adjustInnerStyle();
+}
+
+void LayoutFieldset::updateLogicalWidth()
+{
+ LayoutFlexibleBox::updateLogicalWidth();
+ LogicalExtentComputedValues computedValues;
+ computeLogicalWidth(computedValues);
+
+ ComputedStyle& innerStyle = m_innerBlock->mutableStyleRef();
jfernandez 2016/07/20 14:59:57 Altering the ComputedStyle during layout is not a
cbiesinger 2016/07/20 20:30:49 Yeah, I don't understand why this is necessary? Do
Gleb Lanbin 2016/07/21 18:25:31 done, removed I needed it to pass //src/third_par
+ if (style()->isHorizontalWritingMode())
+ innerStyle.setWidth(Length(computedValues.m_extent, Fixed));
+ else
+ innerStyle.setHeight(Length(computedValues.m_extent, Fixed));
+}
+
+void LayoutFieldset::addChild(LayoutObject* newChild, LayoutObject* beforeChild)
+{
+ if (!m_innerBlock)
+ createInnerBlock();
+
+ if (isHTMLLegendElement(newChild->node())) {
+ LayoutFlexibleBox::addChild(newChild);
+ setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::FieldsetChanged);
+ } else {
+ m_innerBlock->addChild(newChild, beforeChild);
+ DCHECK(m_innerBlock == firstChild());
+ }
+
+ if (AXObjectCache* cache = document().existingAXObjectCache())
cbiesinger 2016/07/20 20:30:49 Hm, why is this necessary? We don't call it in oth
Gleb Lanbin 2016/07/21 18:25:31 done. I copied it from LayoutMenuList as I was un
cbiesinger 2016/07/21 19:54:16 Interesting. Looking at some archaeology: https://
+ cache->childrenChanged(this);
+}
+
+void LayoutFieldset::adjustInnerStyle()
+{
+ if (!m_innerBlock)
+ createInnerBlock();
+
+ ComputedStyle& innerStyle = m_innerBlock->mutableStyleRef();
jfernandez 2016/07/20 14:59:57 Ditto.
Gleb Lanbin 2016/07/21 18:25:31 this is similar to LayoutButton::updateAnonymousCh
+ innerStyle.setFlexShrink(1);
cbiesinger 2016/07/20 20:30:49 Use 1.0f, since these are floats, not ints.
Gleb Lanbin 2016/07/21 18:25:31 Done.
+ innerStyle.setFlexGrow(1);
cbiesinger 2016/07/20 20:30:49 I think you'll want to setMinWidth to Length(0, Fi
Gleb Lanbin 2016/07/21 18:25:31 Done.
+}
+
+void LayoutFieldset::createInnerBlock()
+{
+ if (m_innerBlock) {
+ DCHECK(firstChild() == m_innerBlock);
+ return;
+ }
+ m_innerBlock = createAnonymousBlock(style()->display());
+ LayoutFlexibleBox::addChild(m_innerBlock);
+}
+
+void LayoutFieldset::removeChild(LayoutObject* oldChild)
+{
Manuel Rego 2016/07/20 06:00:23 I didn't review all the changes in this file, but
Gleb Lanbin 2016/07/21 18:25:31 done. after submitting this patch for review I f
Manuel Rego 2016/07/22 06:16:06 Shouldn't we add tests to check that this kind of
Gleb Lanbin 2016/07/22 22:16:15 we already have test to check this src/third_party
+ if (isHTMLLegendElement(oldChild->node())) {
+ LayoutFlexibleBox::removeChild(oldChild);
+ setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::FieldsetChanged);
cbiesinger 2016/07/20 20:30:49 Admittedly I don't fully understand our invalidati
Gleb Lanbin 2016/07/21 18:25:31 so usually <fieldset> looks like this +-- Legend -
cbiesinger 2016/07/21 19:54:16 Hm... I see. But, in general when we remove a chil
Gleb Lanbin 2016/07/21 20:49:01 done. removed. you're right. I don't need it anym
+ } else if (oldChild == m_innerBlock) {
+ LayoutFlexibleBox::removeChild(oldChild);
+ m_innerBlock = nullptr;
+ } else if (m_innerBlock) {
+ m_innerBlock->removeChild(oldChild);
+ }
+}
+
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698