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 |