summaryrefslogtreecommitdiffstats
path: root/layout
diff options
context:
space:
mode:
Diffstat (limited to 'layout')
-rw-r--r--layout/generic/nsFrame.cpp14
-rw-r--r--layout/generic/nsGridContainerFrame.cpp58
-rw-r--r--layout/reftests/css-grid/grid-max-sizing-flex-007-ref.html24
-rw-r--r--layout/reftests/css-grid/grid-max-sizing-flex-007.html24
-rw-r--r--layout/tables/nsTableFrame.cpp83
-rw-r--r--layout/tables/nsTableFrame.h33
6 files changed, 201 insertions, 35 deletions
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
index 8d4ea8754..0d0c7108c 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -8447,9 +8447,13 @@ UnionBorderBoxes(nsIFrame* aFrame, bool aApplyTransform,
Maybe<nsRect> clipPropClipRect =
aFrame->GetClipPropClipRect(disp, effects, bounds.Size());
- // Iterate over all children except pop-ups.
+ // Iterate over all children except pop-ups, absolutely positioned children,
+ // fixed-positioned children and floats.
const nsIFrame::ChildListIDs skip(nsIFrame::kPopupList |
- nsIFrame::kSelectPopupList);
+ nsIFrame::kSelectPopupList |
+ nsIFrame::kAbsoluteList |
+ nsIFrame::kFixedList |
+ nsIFrame::kFloatList);
for (nsIFrame::ChildListIterator childLists(aFrame);
!childLists.IsDone(); childLists.Next()) {
if (skip.Contains(childLists.CurrentID())) {
@@ -8459,6 +8463,12 @@ UnionBorderBoxes(nsIFrame* aFrame, bool aApplyTransform,
nsFrameList children = childLists.CurrentList();
for (nsFrameList::Enumerator e(children); !e.AtEnd(); e.Next()) {
nsIFrame* child = e.get();
+
+ if (child->GetType() == nsGkAtoms::placeholderFrame) {
+ // Skip placeholders too.
+ continue;
+ }
+
// Note that passing |true| for aApplyTransform when
// child->Combines3DTransformWithAncestors() is incorrect if our
// aApplyTransform is false... but the opposite would be as
diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp
index 959061e33..f771c9d7c 100644
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -4822,14 +4822,14 @@ nsGridContainerFrame::Tracks::StretchFlexibleTracks(
: ri->ComputedMaxISize();
}
Maybe<nsTArray<TrackSize>> origSizes;
+ bool applyMinMax = (minSize != 0 || maxSize != NS_UNCONSTRAINEDSIZE) &&
+ aAvailableSize == NS_UNCONSTRAINEDSIZE;
// We iterate twice at most. The 2nd time if the grid size changed after
// applying a min/max-size (can only occur if aAvailableSize is indefinite).
while (true) {
float fr = FindUsedFlexFraction(aState, aGridItems, flexTracks,
aFunctions, aAvailableSize);
if (fr != 0.0f) {
- bool applyMinMax = (minSize != 0 || maxSize != NS_UNCONSTRAINEDSIZE) &&
- aAvailableSize == NS_UNCONSTRAINEDSIZE;
for (uint32_t i : flexTracks) {
float flexFactor = aFunctions.MaxSizingFor(i).GetFlexFractionValue();
nscoord flexLength = NSToCoordRound(flexFactor * fr);
@@ -4841,36 +4841,36 @@ nsGridContainerFrame::Tracks::StretchFlexibleTracks(
base = flexLength;
}
}
- if (applyMinMax && origSizes.isSome()) {
- // https://drafts.csswg.org/css-grid/#algo-flex-tracks
- // "If using this flex fraction would cause the grid to be smaller than
- // the grid container’s min-width/height (or larger than the grid
- // container’s max-width/height), then redo this step, treating the free
- // space as definite [...]"
- nscoord newSize = 0;
- for (auto& sz : mSizes) {
- newSize += sz.mBase;
- }
- const auto sumOfGridGaps = SumOfGridGaps();
- newSize += sumOfGridGaps;
- if (newSize > maxSize) {
- aAvailableSize = maxSize;
- } else if (newSize < minSize) {
- aAvailableSize = minSize;
- }
- if (aAvailableSize != NS_UNCONSTRAINEDSIZE) {
- // Reset min/max-size to ensure 'applyMinMax' becomes false next time.
- minSize = 0;
- maxSize = NS_UNCONSTRAINEDSIZE;
- aAvailableSize = std::max(0, aAvailableSize - sumOfGridGaps);
- // Restart with the original track sizes and definite aAvailableSize.
+ }
+ if (applyMinMax) {
+ applyMinMax = false;
+ // https://drafts.csswg.org/css-grid/#algo-flex-tracks
+ // "If using this flex fraction would cause the grid to be smaller than
+ // the grid container’s min-width/height (or larger than the grid
+ // container’s max-width/height), then redo this step, treating the free
+ // space as definite [...]"
+ nscoord newSize = 0;
+ for (auto& sz : mSizes) {
+ newSize += sz.mBase;
+ }
+ const auto sumOfGridGaps = SumOfGridGaps();
+ newSize += sumOfGridGaps;
+ if (newSize > maxSize) {
+ aAvailableSize = maxSize;
+ } else if (newSize < minSize) {
+ aAvailableSize = minSize;
+ }
+ if (aAvailableSize != NS_UNCONSTRAINEDSIZE) {
+ aAvailableSize = std::max(0, aAvailableSize - sumOfGridGaps);
+ // Restart with the original track sizes and definite aAvailableSize.
+ if (origSizes.isSome()) {
mSizes = Move(*origSizes);
origSizes.reset();
- if (aAvailableSize == 0) {
- break; // zero available size wouldn't change any sizes though...
- }
- continue;
+ } // else, no mSizes[].mBase were changed above so it's still correct
+ if (aAvailableSize == 0) {
+ break; // zero available size wouldn't change any sizes though...
}
+ continue;
}
}
break;
diff --git a/layout/reftests/css-grid/grid-max-sizing-flex-007-ref.html b/layout/reftests/css-grid/grid-max-sizing-flex-007-ref.html
index c5392d32c..b17a1cc02 100644
--- a/layout/reftests/css-grid/grid-max-sizing-flex-007-ref.html
+++ b/layout/reftests/css-grid/grid-max-sizing-flex-007-ref.html
@@ -107,4 +107,28 @@
<div class="item"></div>
</div>
+<pre>The first 6 grids should look the same:</pre>
+<div class="grid rows" style="grid: 1fr / 30px; height:83px">
+ <div class="item"></div>
+</div>
+<div class="grid rows" style="grid: 10px 1fr / 30px; height:83px">
+ <div class="item" style="grid-row:span 2"></div>
+</div>
+<div class="grid rows" style="grid: 1fr / 30px; height:83px">
+ <div class="item"></div>
+</div>
+<div class="grid rows" style="grid: 1fr 1fr / 30px; height:83px">
+ <div class="item" style="grid-row:span 2"><div style="height:90px"></div></div>
+</div>
+<div class="grid rows" style="grid: 1fr auto / 30px; height:83px">
+ <div class="item" style="grid-row:span 2"><div style="height:90px"></div></div>
+</div>
+<div class="grid rows" style="grid: 10px 1fr / 30px; height:83px">
+ <div class="item" style="grid-row:span 2"><div style="height:90px"></div></div>
+</div>
+<div class="grid rows" style="grid: 1fr 1fr / 30px; grid-row-gap:10px; height:83px">
+ <div class="item" style="grid-row:span 2"><div style="height:40px"></div></div>
+ <div class="item"><div style="height:40px"></div></div>
+</div>
+
</body></html>
diff --git a/layout/reftests/css-grid/grid-max-sizing-flex-007.html b/layout/reftests/css-grid/grid-max-sizing-flex-007.html
index ac9dcc77c..a2f39e95b 100644
--- a/layout/reftests/css-grid/grid-max-sizing-flex-007.html
+++ b/layout/reftests/css-grid/grid-max-sizing-flex-007.html
@@ -105,4 +105,28 @@
<div class="item"></div>
</div>
+<pre>The first 6 grids should look the same:</pre>
+<div class="grid rows" style="grid: 1fr / 30px; min-height:83px">
+ <div class="item"></div>
+</div>
+<div class="grid rows" style="grid: 10px 1fr / 30px; min-height:83px">
+ <div class="item" style="grid-row:span 2"></div>
+</div>
+<div class="grid rows" style="grid: 1fr / 30px; max-height:30px; min-height:83px">
+ <div class="item"></div>
+</div>
+<div class="grid rows" style="grid: 1fr 1fr / 30px; max-height:83px">
+ <div class="item" style="grid-row:span 2"><div style="height:90px"></div></div>
+</div>
+<div class="grid rows" style="grid: 1fr auto / 30px; max-height:83px">
+ <div class="item" style="grid-row:span 2"><div style="height:90px"></div></div>
+</div>
+<div class="grid rows" style="grid: 10px 1fr / 30px; max-height:83px">
+ <div class="item" style="grid-row:span 2"><div style="height:90px"></div></div>
+</div>
+<div class="grid rows" style="grid: 1fr 1fr / 30px; grid-row-gap:10px; max-height:83px">
+ <div class="item" style="grid-row:span 2"><div style="height:40px"></div></div>
+ <div class="item"><div style="height:40px"></div></div>
+</div>
+
</body></html>
diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp
index 4257c9c57..e5a48139a 100644
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1268,6 +1268,74 @@ PaintRowGroupBackgroundByColIdx(nsTableRowGroupFrame* aRowGroup,
}
}
+static inline bool FrameHasBorder(nsIFrame* f)
+{
+ if (!f->StyleVisibility()->IsVisible()) {
+ return false;
+ }
+
+ if (f->StyleBorder()->HasBorder()) {
+ return true;
+ }
+
+ return false;
+}
+
+void nsTableFrame::CalcHasBCBorders()
+{
+ if (!IsBorderCollapse()) {
+ SetHasBCBorders(false);
+ return;
+ }
+
+ if (FrameHasBorder(this)) {
+ SetHasBCBorders(true);
+ return;
+ }
+
+ // Check col and col group has borders.
+ for (nsIFrame* f : this->GetChildList(kColGroupList)) {
+ if (FrameHasBorder(f)) {
+ SetHasBCBorders(true);
+ return;
+ }
+
+ nsTableColGroupFrame *colGroup = static_cast<nsTableColGroupFrame*>(f);
+ for (nsTableColFrame* col = colGroup->GetFirstColumn(); col; col = col->GetNextCol()) {
+ if (FrameHasBorder(col)) {
+ SetHasBCBorders(true);
+ return;
+ }
+ }
+ }
+
+ // check row group, row and cell has borders.
+ RowGroupArray rowGroups;
+ OrderRowGroups(rowGroups);
+ for (nsTableRowGroupFrame* rowGroup : rowGroups) {
+ if (FrameHasBorder(rowGroup)) {
+ SetHasBCBorders(true);
+ return;
+ }
+
+ for (nsTableRowFrame* row = rowGroup->GetFirstRow(); row; row = row->GetNextRow()) {
+ if (FrameHasBorder(row)) {
+ SetHasBCBorders(true);
+ return;
+ }
+
+ for (nsTableCellFrame* cell = row->GetFirstCell(); cell; cell = cell->GetNextCell()) {
+ if (FrameHasBorder(cell)) {
+ SetHasBCBorders(true);
+ return;
+ }
+ }
+ }
+ }
+
+ SetHasBCBorders(false);
+}
+
/* static */ void
nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
nsFrame* aFrame,
@@ -1375,11 +1443,16 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
nsTableFrame* table = static_cast<nsTableFrame*>(aFrame);
// In the collapsed border model, overlay all collapsed borders.
if (table->IsBorderCollapse()) {
- aLists.BorderBackground()->AppendNewToTop(
- new (aBuilder) nsDisplayTableBorderCollapse(aBuilder, table));
+ if (table->HasBCBorders()) {
+ aLists.BorderBackground()->AppendNewToTop(
+ new (aBuilder) nsDisplayTableBorderCollapse(aBuilder, table));
+ }
} else {
- aLists.BorderBackground()->AppendNewToTop(
- new (aBuilder) nsDisplayBorder(aBuilder, table));
+ const nsStyleBorder* borderStyle = aFrame->StyleBorder();
+ if (borderStyle->HasBorder()) {
+ aLists.BorderBackground()->AppendNewToTop(
+ new (aBuilder) nsDisplayBorder(aBuilder, table));
+ }
}
}
}
@@ -4101,6 +4174,7 @@ nsTableFrame::AddBCDamageArea(const TableArea& aValue)
#endif
SetNeedToCalcBCBorders(true);
+ SetNeedToCalcHasBCBorders(true);
// Get the property
BCPropertyData* value = GetOrCreateBCProperty();
if (value) {
@@ -4141,6 +4215,7 @@ nsTableFrame::SetFullBCDamageArea()
NS_ASSERTION(IsBorderCollapse(), "invalid SetFullBCDamageArea call");
SetNeedToCalcBCBorders(true);
+ SetNeedToCalcHasBCBorders(true);
BCPropertyData* value = GetOrCreateBCProperty();
if (value) {
diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h
index a6b786402..d739faa72 100644
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -761,6 +761,13 @@ public:
bool NeedToCollapse() const;
void SetNeedToCollapse(bool aValue);
+ bool NeedToCalcHasBCBorders() const;
+ void SetNeedToCalcHasBCBorders(bool aValue);
+
+ void CalcHasBCBorders();
+ bool HasBCBorders();
+ void SetHasBCBorders(bool aValue);
+
/** The GeometryDirty bit is similar to the NS_FRAME_IS_DIRTY frame
* state bit, which implies that all descendants are dirty. The
* GeometryDirty still implies that all the parts of the table are
@@ -870,6 +877,8 @@ protected:
uint32_t mIStartContBCBorder:8;
uint32_t mNeedToCollapse:1; // rows, cols that have visibility:collapse need to be collapsed
uint32_t mResizedColumns:1; // have we resized columns since last reflow?
+ uint32_t mNeedToCalcHasBCBorders:1;
+ uint32_t mHasBCBorders:1;
} mBits;
nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
@@ -965,6 +974,30 @@ inline void nsTableFrame::SetNeedToCalcBCBorders(bool aValue)
mBits.mNeedToCalcBCBorders = (unsigned)aValue;
}
+inline bool nsTableFrame::NeedToCalcHasBCBorders() const
+{
+ return (bool)mBits.mNeedToCalcHasBCBorders;
+}
+
+inline void nsTableFrame::SetNeedToCalcHasBCBorders(bool aValue)
+{
+ mBits.mNeedToCalcHasBCBorders = (unsigned)aValue;
+}
+
+inline bool nsTableFrame::HasBCBorders()
+{
+ if (NeedToCalcHasBCBorders()) {
+ CalcHasBCBorders();
+ SetNeedToCalcHasBCBorders(false);
+ }
+ return (bool)mBits.mHasBCBorders;
+}
+
+inline void nsTableFrame::SetHasBCBorders(bool aValue)
+{
+ mBits.mHasBCBorders = (unsigned)aValue;
+}
+
inline nscoord
nsTableFrame::GetContinuousIStartBCBorderWidth() const
{