Bug 1395312 part 2. Table backgrounds should be drawn or not based on the visibility of the relevant cell, not of the column/row/colgroup/rowgroup they come from. r=heycam
MozReview-Commit-ID: B863KFWjLLW
This commit is contained in:
12
layout/reftests/table-background/hidden-cells-1.html
Normal file
12
layout/reftests/table-background/hidden-cells-1.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<table style="width: 200px; height: 200px; empty-cells: hide; color: white">
|
||||||
|
<colgroup style="background: red">
|
||||||
|
<col style="background: red">
|
||||||
|
</colgroup>
|
||||||
|
<tbody style="background: red">
|
||||||
|
<tr style="background: red">
|
||||||
|
<td></td>
|
||||||
|
<td style="visibility: hidden">X</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
12
layout/reftests/table-background/hidden-cells-2.html
Normal file
12
layout/reftests/table-background/hidden-cells-2.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<table style="width: 200px; height: 200px; empty-cells: show; color: white">
|
||||||
|
<colgroup style="background: red">
|
||||||
|
<col style="background: red">
|
||||||
|
</colgroup>
|
||||||
|
<tbody style="background: red">
|
||||||
|
<tr style="background: red">
|
||||||
|
<td style="background: white"></td>
|
||||||
|
<td style="visibility: hidden"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
14
layout/reftests/table-background/hidden-cells-3-ref.html
Normal file
14
layout/reftests/table-background/hidden-cells-3-ref.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<table style="width: 200px; height: 200px; empty-cells: show; border-collapse: collapse">
|
||||||
|
<colgroup style="background: red">
|
||||||
|
<col style="background: red">
|
||||||
|
</colgroup>
|
||||||
|
<tbody style="background: red">
|
||||||
|
<tr style="background: red">
|
||||||
|
<td style="background: green">
|
||||||
|
</td>
|
||||||
|
<td style="background: white">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
14
layout/reftests/table-background/hidden-cells-3.html
Normal file
14
layout/reftests/table-background/hidden-cells-3.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<table style="width: 200px; height: 200px; empty-cells: hide; border-collapse: collapse">
|
||||||
|
<colgroup style="background: red">
|
||||||
|
<col style="background: red">
|
||||||
|
</colgroup>
|
||||||
|
<tbody style="background: red">
|
||||||
|
<tr style="background: green; visibility: hidden">
|
||||||
|
<td style="visibility: visible">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
@@ -60,3 +60,7 @@ fuzzy-if(d2d||skiaContent,1,95000) == border-separate-opacity-table.html border-
|
|||||||
== empty-cells-default-2.html empty-cells-default-2-ref.html
|
== empty-cells-default-2.html empty-cells-default-2-ref.html
|
||||||
fuzzy-if(OSX,1,113) fuzzy-if(winWidget,1,12) fuzzy-if(winWidget&&!layersGPUAccelerated,82,116) fuzzy-if(skiaContent,84,5500) fuzzy-if(Android,2,5957) == table-row-opacity-dynamic-1.html table-row-opacity-dynamic-1-ref.html
|
fuzzy-if(OSX,1,113) fuzzy-if(winWidget,1,12) fuzzy-if(winWidget&&!layersGPUAccelerated,82,116) fuzzy-if(skiaContent,84,5500) fuzzy-if(Android,2,5957) == table-row-opacity-dynamic-1.html table-row-opacity-dynamic-1-ref.html
|
||||||
== table-row-opacity-dynamic-2.html table-row-opacity-dynamic-2-ref.html
|
== table-row-opacity-dynamic-2.html table-row-opacity-dynamic-2-ref.html
|
||||||
|
|
||||||
|
== hidden-cells-1.html about:blank
|
||||||
|
== hidden-cells-2.html about:blank
|
||||||
|
== hidden-cells-3.html hidden-cells-3-ref.html
|
||||||
|
|||||||
@@ -491,6 +491,12 @@ nsTableCellFrame::ShouldPaintBordersAndBackgrounds() const
|
|||||||
return StyleTableBorder()->mEmptyCells == NS_STYLE_TABLE_EMPTY_CELLS_SHOW;
|
return StyleTableBorder()->mEmptyCells == NS_STYLE_TABLE_EMPTY_CELLS_SHOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsTableCellFrame::ShouldPaintBackground(nsDisplayListBuilder* aBuilder)
|
||||||
|
{
|
||||||
|
return ShouldPaintBordersAndBackgrounds() && IsVisibleInSelection(aBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
const nsDisplayListSet& aLists)
|
const nsDisplayListSet& aLists)
|
||||||
|
|||||||
@@ -226,6 +226,8 @@ public:
|
|||||||
|
|
||||||
bool ShouldPaintBordersAndBackgrounds() const;
|
bool ShouldPaintBordersAndBackgrounds() const;
|
||||||
|
|
||||||
|
bool ShouldPaintBackground(nsDisplayListBuilder* aBuilder);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsTableCellFrame(nsStyleContext* aContext, nsTableFrame* aTableFrame,
|
nsTableCellFrame(nsStyleContext* aContext, nsTableFrame* aTableFrame,
|
||||||
ClassID aID);
|
ClassID aID);
|
||||||
|
|||||||
@@ -1377,6 +1377,10 @@ PaintRowBackground(nsTableRowFrame* aRow,
|
|||||||
{
|
{
|
||||||
// Compute background rect by iterating all cell frame.
|
// Compute background rect by iterating all cell frame.
|
||||||
for (nsTableCellFrame* cell = aRow->GetFirstCell(); cell; cell = cell->GetNextCell()) {
|
for (nsTableCellFrame* cell = aRow->GetFirstCell(); cell; cell = cell->GetNextCell()) {
|
||||||
|
if (!cell->ShouldPaintBackground(aBuilder)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto cellRect = cell->GetRectRelativeToSelf() + cell->GetNormalPosition() + aOffset;
|
auto cellRect = cell->GetRectRelativeToSelf() + cell->GetNormalPosition() + aOffset;
|
||||||
if (!aBuilder->GetDirtyRect().Intersects(cellRect)) {
|
if (!aBuilder->GetDirtyRect().Intersects(cellRect)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -1418,6 +1422,10 @@ PaintRowGroupBackgroundByColIdx(nsTableRowGroupFrame* aRowGroup,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (nsTableCellFrame* cell = row->GetFirstCell(); cell; cell = cell->GetNextCell()) {
|
for (nsTableCellFrame* cell = row->GetFirstCell(); cell; cell = cell->GetNextCell()) {
|
||||||
|
if (!cell->ShouldPaintBackground(aBuilder)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t curColIdx;
|
int32_t curColIdx;
|
||||||
cell->GetColIndex(curColIdx);
|
cell->GetColIndex(curColIdx);
|
||||||
if (aColIdx.Contains(curColIdx)) {
|
if (aColIdx.Contains(curColIdx)) {
|
||||||
@@ -1511,89 +1519,90 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
|
|||||||
DisplayGenericTablePartTraversal aTraversal)
|
DisplayGenericTablePartTraversal aTraversal)
|
||||||
{
|
{
|
||||||
bool isVisible = aFrame->IsVisibleForPainting(aBuilder);
|
bool isVisible = aFrame->IsVisibleForPainting(aBuilder);
|
||||||
bool isColumn = aFrame->IsTableColFrame();
|
bool isTable = aFrame->IsTableFrame();
|
||||||
// If we have an anonymous column in the AppendAnonymousColFrames sense, it
|
|
||||||
// might think it's visible for painting (due to not inheriting its colgroup's
|
// Note that we UpdateForFrameBackground() even if we're not visible, unless
|
||||||
// styles) while the colgroup as a whole is actually not visible for painting
|
// we're a table frame, because our backgrounds may paint anyway if the _cell_
|
||||||
// because it has hidden visibility. In that situation we should also treat
|
// is visible.
|
||||||
// the column as not visible, because otherwise hit-testing can get a bit
|
if (isVisible || !isTable) {
|
||||||
// confused.
|
|
||||||
//
|
|
||||||
// XXXbz It's not clear whether anonymous columns and column groups should
|
|
||||||
// ever affect hit-testing at all. See
|
|
||||||
// https://github.com/w3c/csswg-drafts/issues/1763 which might result in them
|
|
||||||
// not existing conceptually and hence not affecting hit-testing.
|
|
||||||
if (isVisible && isColumn &&
|
|
||||||
aFrame->StyleContext()->GetPseudo() == nsCSSAnonBoxes::tableCol &&
|
|
||||||
!aFrame->GetParent()->StyleVisibility()->IsVisible()) {
|
|
||||||
isVisible = false;
|
|
||||||
}
|
|
||||||
if (isVisible) {
|
|
||||||
nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem();
|
nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem();
|
||||||
// currentItem may be null, when none of the table parts have a
|
// currentItem may be null, when none of the table parts have a
|
||||||
// background or border
|
// background or border
|
||||||
if (currentItem) {
|
if (currentItem) {
|
||||||
currentItem->UpdateForFrameBackground(aFrame);
|
currentItem->UpdateForFrameBackground(aFrame);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isVisible) {
|
||||||
|
// XXXbz should box-shadow for rows/rowgroups/columns/colgroups get painted
|
||||||
|
// just because we're visible? Or should it depend on the cell visibility
|
||||||
|
// when we're not the whole table?
|
||||||
|
|
||||||
// Paint the outset box-shadows for the table frames
|
// Paint the outset box-shadows for the table frames
|
||||||
bool hasBoxShadow = aFrame->StyleEffects()->mBoxShadow != nullptr;
|
if (aFrame->StyleEffects()->mBoxShadow) {
|
||||||
if (hasBoxShadow) {
|
|
||||||
aLists.BorderBackground()->AppendNewToTop(
|
aLists.BorderBackground()->AppendNewToTop(
|
||||||
new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, aFrame));
|
new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, aFrame));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (aFrame->IsTableRowGroupFrame()) {
|
// Background visibility for rows, rowgroups, columns, colgroups depends on
|
||||||
nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame);
|
// the visibility of the _cell_, not of the row/col(group).
|
||||||
PaintRowGroupBackground(rowGroup, aFrame, aBuilder, aLists);
|
if (aFrame->IsTableRowGroupFrame()) {
|
||||||
} else if (aFrame->IsTableRowFrame()) {
|
nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame);
|
||||||
nsTableRowFrame* row = static_cast<nsTableRowFrame*>(aFrame);
|
PaintRowGroupBackground(rowGroup, aFrame, aBuilder, aLists);
|
||||||
PaintRowBackground(row, aFrame, aBuilder, aLists);
|
} else if (aFrame->IsTableRowFrame()) {
|
||||||
} else if (aFrame->IsTableColGroupFrame()) {
|
nsTableRowFrame* row = static_cast<nsTableRowFrame*>(aFrame);
|
||||||
// Compute background rect by iterating all cell frame.
|
PaintRowBackground(row, aFrame, aBuilder, aLists);
|
||||||
nsTableColGroupFrame* colGroup = static_cast<nsTableColGroupFrame*>(aFrame);
|
} else if (aFrame->IsTableColGroupFrame()) {
|
||||||
// Collecting column index.
|
// Compute background rect by iterating all cell frame.
|
||||||
AutoTArray<int32_t, 1> colIdx;
|
nsTableColGroupFrame* colGroup = static_cast<nsTableColGroupFrame*>(aFrame);
|
||||||
for (nsTableColFrame* col = colGroup->GetFirstColumn(); col; col = col->GetNextCol()) {
|
// Collecting column index.
|
||||||
colIdx.AppendElement(col->GetColIndex());
|
AutoTArray<int32_t, 1> colIdx;
|
||||||
}
|
for (nsTableColFrame* col = colGroup->GetFirstColumn(); col; col = col->GetNextCol()) {
|
||||||
|
|
||||||
nsTableFrame* table = colGroup->GetTableFrame();
|
|
||||||
RowGroupArray rowGroups;
|
|
||||||
table->OrderRowGroups(rowGroups);
|
|
||||||
for (nsTableRowGroupFrame* rowGroup : rowGroups) {
|
|
||||||
auto offset = rowGroup->GetNormalPosition() - colGroup->GetNormalPosition();
|
|
||||||
if (!aBuilder->GetDirtyRect().Intersects(nsRect(offset, rowGroup->GetSize()))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, colIdx, offset);
|
|
||||||
}
|
|
||||||
} else if (isColumn) {
|
|
||||||
// Compute background rect by iterating all cell frame.
|
|
||||||
nsTableColFrame* col = static_cast<nsTableColFrame*>(aFrame);
|
|
||||||
AutoTArray<int32_t, 1> colIdx;
|
|
||||||
colIdx.AppendElement(col->GetColIndex());
|
colIdx.AppendElement(col->GetColIndex());
|
||||||
|
|
||||||
nsTableFrame* table = col->GetTableFrame();
|
|
||||||
RowGroupArray rowGroups;
|
|
||||||
table->OrderRowGroups(rowGroups);
|
|
||||||
for (nsTableRowGroupFrame* rowGroup : rowGroups) {
|
|
||||||
auto offset = rowGroup->GetNormalPosition() -
|
|
||||||
col->GetNormalPosition() -
|
|
||||||
col->GetTableColGroupFrame()->GetNormalPosition();
|
|
||||||
if (!aBuilder->GetDirtyRect().Intersects(nsRect(offset, rowGroup->GetSize()))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, colIdx, offset);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame,
|
|
||||||
aFrame->GetRectRelativeToSelf(),
|
|
||||||
aLists.BorderBackground());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsTableFrame* table = colGroup->GetTableFrame();
|
||||||
|
RowGroupArray rowGroups;
|
||||||
|
table->OrderRowGroups(rowGroups);
|
||||||
|
for (nsTableRowGroupFrame* rowGroup : rowGroups) {
|
||||||
|
auto offset = rowGroup->GetNormalPosition() - colGroup->GetNormalPosition();
|
||||||
|
if (!aBuilder->GetDirtyRect().Intersects(nsRect(offset, rowGroup->GetSize()))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, colIdx, offset);
|
||||||
|
}
|
||||||
|
} else if (aFrame->IsTableColFrame()) {
|
||||||
|
// Compute background rect by iterating all cell frame.
|
||||||
|
nsTableColFrame* col = static_cast<nsTableColFrame*>(aFrame);
|
||||||
|
AutoTArray<int32_t, 1> colIdx;
|
||||||
|
colIdx.AppendElement(col->GetColIndex());
|
||||||
|
|
||||||
|
nsTableFrame* table = col->GetTableFrame();
|
||||||
|
RowGroupArray rowGroups;
|
||||||
|
table->OrderRowGroups(rowGroups);
|
||||||
|
for (nsTableRowGroupFrame* rowGroup : rowGroups) {
|
||||||
|
auto offset = rowGroup->GetNormalPosition() -
|
||||||
|
col->GetNormalPosition() -
|
||||||
|
col->GetTableColGroupFrame()->GetNormalPosition();
|
||||||
|
if (!aBuilder->GetDirtyRect().Intersects(nsRect(offset, rowGroup->GetSize()))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, colIdx, offset);
|
||||||
|
}
|
||||||
|
} else if (isVisible) {
|
||||||
|
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame,
|
||||||
|
aFrame->GetRectRelativeToSelf(),
|
||||||
|
aLists.BorderBackground());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isVisible) {
|
||||||
|
// XXXbz should box-shadow for rows/rowgroups/columns/colgroups get painted
|
||||||
|
// just because we're visible? Or should it depend on the cell visibility
|
||||||
|
// when we're not the whole table?
|
||||||
|
|
||||||
// Paint the inset box-shadows for the table frames
|
// Paint the inset box-shadows for the table frames
|
||||||
if (hasBoxShadow) {
|
if (aFrame->StyleEffects()->mBoxShadow) {
|
||||||
aLists.BorderBackground()->AppendNewToTop(
|
aLists.BorderBackground()->AppendNewToTop(
|
||||||
new (aBuilder) nsDisplayBoxShadowInner(aBuilder, aFrame));
|
new (aBuilder) nsDisplayBoxShadowInner(aBuilder, aFrame));
|
||||||
}
|
}
|
||||||
@@ -1602,7 +1611,7 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
|
|||||||
aTraversal(aBuilder, aFrame, aLists);
|
aTraversal(aBuilder, aFrame, aLists);
|
||||||
|
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
if (aFrame->IsTableFrame()) {
|
if (isTable) {
|
||||||
nsTableFrame* table = static_cast<nsTableFrame*>(aFrame);
|
nsTableFrame* table = static_cast<nsTableFrame*>(aFrame);
|
||||||
// In the collapsed border model, overlay all collapsed borders.
|
// In the collapsed border model, overlay all collapsed borders.
|
||||||
if (table->IsBorderCollapse()) {
|
if (table->IsBorderCollapse()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user