зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
8216808d0e
Коммит
7f0ccc9510
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
||||
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
|
||||
|
||||
== 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;
|
||||
}
|
||||
|
||||
bool
|
||||
nsTableCellFrame::ShouldPaintBackground(nsDisplayListBuilder* aBuilder)
|
||||
{
|
||||
return ShouldPaintBordersAndBackgrounds() && IsVisibleInSelection(aBuilder);
|
||||
}
|
||||
|
||||
void
|
||||
nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists)
|
||||
|
|
|
@ -226,6 +226,8 @@ public:
|
|||
|
||||
bool ShouldPaintBordersAndBackgrounds() const;
|
||||
|
||||
bool ShouldPaintBackground(nsDisplayListBuilder* aBuilder);
|
||||
|
||||
protected:
|
||||
nsTableCellFrame(nsStyleContext* aContext, nsTableFrame* aTableFrame,
|
||||
ClassID aID);
|
||||
|
|
|
@ -1377,6 +1377,10 @@ PaintRowBackground(nsTableRowFrame* aRow,
|
|||
{
|
||||
// Compute background rect by iterating all cell frame.
|
||||
for (nsTableCellFrame* cell = aRow->GetFirstCell(); cell; cell = cell->GetNextCell()) {
|
||||
if (!cell->ShouldPaintBackground(aBuilder)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto cellRect = cell->GetRectRelativeToSelf() + cell->GetNormalPosition() + aOffset;
|
||||
if (!aBuilder->GetDirtyRect().Intersects(cellRect)) {
|
||||
continue;
|
||||
|
@ -1418,6 +1422,10 @@ PaintRowGroupBackgroundByColIdx(nsTableRowGroupFrame* aRowGroup,
|
|||
continue;
|
||||
}
|
||||
for (nsTableCellFrame* cell = row->GetFirstCell(); cell; cell = cell->GetNextCell()) {
|
||||
if (!cell->ShouldPaintBackground(aBuilder)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t curColIdx;
|
||||
cell->GetColIndex(curColIdx);
|
||||
if (aColIdx.Contains(curColIdx)) {
|
||||
|
@ -1511,89 +1519,90 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
|
|||
DisplayGenericTablePartTraversal aTraversal)
|
||||
{
|
||||
bool isVisible = aFrame->IsVisibleForPainting(aBuilder);
|
||||
bool isColumn = aFrame->IsTableColFrame();
|
||||
// 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
|
||||
// styles) while the colgroup as a whole is actually not visible for painting
|
||||
// because it has hidden visibility. In that situation we should also treat
|
||||
// the column as not visible, because otherwise hit-testing can get a bit
|
||||
// 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) {
|
||||
bool isTable = aFrame->IsTableFrame();
|
||||
|
||||
// Note that we UpdateForFrameBackground() even if we're not visible, unless
|
||||
// we're a table frame, because our backgrounds may paint anyway if the _cell_
|
||||
// is visible.
|
||||
if (isVisible || !isTable) {
|
||||
nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem();
|
||||
// currentItem may be null, when none of the table parts have a
|
||||
// background or border
|
||||
if (currentItem) {
|
||||
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
|
||||
bool hasBoxShadow = aFrame->StyleEffects()->mBoxShadow != nullptr;
|
||||
if (hasBoxShadow) {
|
||||
if (aFrame->StyleEffects()->mBoxShadow) {
|
||||
aLists.BorderBackground()->AppendNewToTop(
|
||||
new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, aFrame));
|
||||
}
|
||||
}
|
||||
|
||||
if (aFrame->IsTableRowGroupFrame()) {
|
||||
nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame);
|
||||
PaintRowGroupBackground(rowGroup, aFrame, aBuilder, aLists);
|
||||
} else if (aFrame->IsTableRowFrame()) {
|
||||
nsTableRowFrame* row = static_cast<nsTableRowFrame*>(aFrame);
|
||||
PaintRowBackground(row, aFrame, aBuilder, aLists);
|
||||
} else if (aFrame->IsTableColGroupFrame()) {
|
||||
// Compute background rect by iterating all cell frame.
|
||||
nsTableColGroupFrame* colGroup = static_cast<nsTableColGroupFrame*>(aFrame);
|
||||
// Collecting column index.
|
||||
AutoTArray<int32_t, 1> colIdx;
|
||||
for (nsTableColFrame* col = colGroup->GetFirstColumn(); col; col = col->GetNextCol()) {
|
||||
colIdx.AppendElement(col->GetColIndex());
|
||||
}
|
||||
|
||||
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;
|
||||
// Background visibility for rows, rowgroups, columns, colgroups depends on
|
||||
// the visibility of the _cell_, not of the row/col(group).
|
||||
if (aFrame->IsTableRowGroupFrame()) {
|
||||
nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame);
|
||||
PaintRowGroupBackground(rowGroup, aFrame, aBuilder, aLists);
|
||||
} else if (aFrame->IsTableRowFrame()) {
|
||||
nsTableRowFrame* row = static_cast<nsTableRowFrame*>(aFrame);
|
||||
PaintRowBackground(row, aFrame, aBuilder, aLists);
|
||||
} else if (aFrame->IsTableColGroupFrame()) {
|
||||
// Compute background rect by iterating all cell frame.
|
||||
nsTableColGroupFrame* colGroup = static_cast<nsTableColGroupFrame*>(aFrame);
|
||||
// Collecting column index.
|
||||
AutoTArray<int32_t, 1> colIdx;
|
||||
for (nsTableColFrame* col = colGroup->GetFirstColumn(); col; col = col->GetNextCol()) {
|
||||
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
|
||||
if (hasBoxShadow) {
|
||||
if (aFrame->StyleEffects()->mBoxShadow) {
|
||||
aLists.BorderBackground()->AppendNewToTop(
|
||||
new (aBuilder) nsDisplayBoxShadowInner(aBuilder, aFrame));
|
||||
}
|
||||
|
@ -1602,7 +1611,7 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
|
|||
aTraversal(aBuilder, aFrame, aLists);
|
||||
|
||||
if (isVisible) {
|
||||
if (aFrame->IsTableFrame()) {
|
||||
if (isTable) {
|
||||
nsTableFrame* table = static_cast<nsTableFrame*>(aFrame);
|
||||
// In the collapsed border model, overlay all collapsed borders.
|
||||
if (table->IsBorderCollapse()) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче