Commit 40bb8833 authored by dgrogan's avatar dgrogan Committed by Commit bot

[css-tables] Clean up code that detects significant border changes

De-duplicate; narrow a condition; fix a method that did the opposite of
its name; add comments, etc.

No new tests because there _should_ be no behavior changes.

BUG=613728

Review-Url: https://codereview.chromium.org/2153283002
Cr-Commit-Position: refs/heads/master@{#406051}
parent 900a8d83
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "core/layout/LayoutTableBoxComponent.h" #include "core/layout/LayoutTableBoxComponent.h"
#include "core/layout/LayoutTable.h"
#include "core/style/ComputedStyle.h" #include "core/style/ComputedStyle.h"
namespace blink { namespace blink {
...@@ -25,4 +26,13 @@ void LayoutTableBoxComponent::imageChanged(WrappedImagePtr, const IntRect*) ...@@ -25,4 +26,13 @@ void LayoutTableBoxComponent::imageChanged(WrappedImagePtr, const IntRect*)
m_backgroundChangedSinceLastPaintInvalidation = true; m_backgroundChangedSinceLastPaintInvalidation = true;
} }
bool LayoutTableBoxComponent::doCellsHaveDirtyWidth(const LayoutObject& tablePart, const LayoutTable& table, const StyleDifference& diff, const ComputedStyle& oldStyle)
{
// ComputedStyle::diffNeedsFullLayoutAndPaintInvalidation sets needsFullLayout when border sizes
// change: checking diff.needsFullLayout() is an optimization, not required for correctness.
// TODO(dgrogan): Remove tablePart.needsLayout()? Perhaps it was an old optimization but now it
// seems that diff.needsFullLayout() implies tablePart.needsLayout().
return diff.needsFullLayout() && tablePart.needsLayout() && table.collapseBorders() && !oldStyle.border().sizeEquals(tablePart.style()->border());
}
} // namespace blink } // namespace blink
...@@ -10,12 +10,14 @@ ...@@ -10,12 +10,14 @@
namespace blink { namespace blink {
class LayoutTable;
// Common super class for LayoutTableCol, LayoutTableSection and LayoutTableRow. // Common super class for LayoutTableCol, LayoutTableSection and LayoutTableRow.
class CORE_EXPORT LayoutTableBoxComponent : public LayoutBox { class CORE_EXPORT LayoutTableBoxComponent : public LayoutBox {
public: public:
bool backgroundChangedSinceLastPaintInvalidation() const { return m_backgroundChangedSinceLastPaintInvalidation; } bool backgroundChangedSinceLastPaintInvalidation() const { return m_backgroundChangedSinceLastPaintInvalidation; }
void clearBackgroundChangedSinceLastPaintInvalidation() { m_backgroundChangedSinceLastPaintInvalidation = false; } void clearBackgroundChangedSinceLastPaintInvalidation() { m_backgroundChangedSinceLastPaintInvalidation = false; }
static bool doCellsHaveDirtyWidth(const LayoutObject& tablePart, const LayoutTable&, const StyleDifference&, const ComputedStyle& oldStyle);
protected: protected:
explicit LayoutTableBoxComponent(Element* element) explicit LayoutTableBoxComponent(Element* element)
: LayoutBox(element) : LayoutBox(element)
......
...@@ -45,19 +45,22 @@ LayoutTableCol::LayoutTableCol(Element* element) ...@@ -45,19 +45,22 @@ LayoutTableCol::LayoutTableCol(Element* element)
void LayoutTableCol::styleDidChange(StyleDifference diff, const ComputedStyle* oldStyle) void LayoutTableCol::styleDidChange(StyleDifference diff, const ComputedStyle* oldStyle)
{ {
DCHECK(style()->display() == TABLE_COLUMN || style()->display() == TABLE_COLUMN_GROUP);
LayoutTableBoxComponent::styleDidChange(diff, oldStyle); LayoutTableBoxComponent::styleDidChange(diff, oldStyle);
if (LayoutTable* table = this->table()) {
if (!oldStyle) if (!oldStyle)
return; return;
LayoutTable* table = this->table();
if (!table)
return;
// TODO(dgrogan): Is the "else" necessary for correctness or just a brittle optimization? The optimization would be: // TODO(dgrogan): Is the "else" necessary for correctness or just a brittle optimization? The optimization would be:
// if the first branch is taken then the next one can't be, so don't even check its condition. // if the first branch is taken then the next one can't be, so don't even check its condition.
if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() && oldStyle->border() != style()->border()) { if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() && oldStyle->border() != style()->border()) {
// If border was changed, notify table.
table->invalidateCollapsedBorders(); table->invalidateCollapsedBorders();
} else if ((oldStyle->logicalWidth() != style()->logicalWidth()) || (diff.needsFullLayout() && needsLayout() && table->collapseBorders() && oldStyle->border().sizeEquals(style()->border()))) { } else if ((oldStyle->logicalWidth() != style()->logicalWidth()) || LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *table, diff, *oldStyle)) {
// TODO(dgrogan): Move second clause above to LayoutTableBoxComponent for re-use.
// TODO(dgrogan): Optimization opportunities: // TODO(dgrogan): Optimization opportunities:
// (1) Only mark cells which are affected by this col, not every cell in the table. // (1) Only mark cells which are affected by this col, not every cell in the table.
// (2) If only the col width changes and its border width doesn't, do the cells need to be marked as // (2) If only the col width changes and its border width doesn't, do the cells need to be marked as
...@@ -69,7 +72,6 @@ void LayoutTableCol::styleDidChange(StyleDifference diff, const ComputedStyle* o ...@@ -69,7 +72,6 @@ void LayoutTableCol::styleDidChange(StyleDifference diff, const ComputedStyle* o
section->markAllCellsWidthsDirtyAndOrNeedsLayout(LayoutTableSection::MarkDirtyAndNeedsLayout); section->markAllCellsWidthsDirtyAndOrNeedsLayout(LayoutTableSection::MarkDirtyAndNeedsLayout);
} }
} }
}
} }
void LayoutTableCol::updateFromElement() void LayoutTableCol::updateFromElement()
......
...@@ -60,16 +60,22 @@ void LayoutTableRow::styleDidChange(StyleDifference diff, const ComputedStyle* o ...@@ -60,16 +60,22 @@ void LayoutTableRow::styleDidChange(StyleDifference diff, const ComputedStyle* o
LayoutTableBoxComponent::styleDidChange(diff, oldStyle); LayoutTableBoxComponent::styleDidChange(diff, oldStyle);
propagateStyleToAnonymousChildren(); propagateStyleToAnonymousChildren();
if (section() && oldStyle && style()->logicalHeight() != oldStyle->logicalHeight()) if (!oldStyle)
return;
if (section() && style()->logicalHeight() != oldStyle->logicalHeight())
section()->rowLogicalHeightChanged(this); section()->rowLogicalHeightChanged(this);
// If border was changed, notify table. if (!parent())
if (parent()) { return;
LayoutTable* table = this->table(); LayoutTable* table = this->table();
if (table && !table->selfNeedsLayout() && !table->normalChildNeedsLayout() && oldStyle && oldStyle->border() != style()->border()) if (!table)
return;
if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() && oldStyle->border() != style()->border())
table->invalidateCollapsedBorders(); table->invalidateCollapsedBorders();
if (table && oldStyle && diff.needsFullLayout() && needsLayout() && table->collapseBorders() && oldStyle->border().sizeEquals(style()->border())) { if (LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *table, diff, *oldStyle)) {
// If the border width changes on a row, we need to make sure the cells in the row know to lay out again. // If the border width changes on a row, we need to make sure the cells in the row know to lay out again.
// This only happens when borders are collapsed, since they end up affecting the border sides of the cell // This only happens when borders are collapsed, since they end up affecting the border sides of the cell
// itself. // itself.
...@@ -88,7 +94,6 @@ void LayoutTableRow::styleDidChange(StyleDifference diff, const ComputedStyle* o ...@@ -88,7 +94,6 @@ void LayoutTableRow::styleDidChange(StyleDifference diff, const ComputedStyle* o
// TODO(dgrogan): Make LayoutTableSection clear its dirty bit. // TODO(dgrogan): Make LayoutTableSection clear its dirty bit.
table->setPreferredLogicalWidthsDirty(); table->setPreferredLogicalWidthsDirty();
} }
}
} }
const BorderValue& LayoutTableRow::borderAdjoiningStartCell(const LayoutTableCell* cell) const const BorderValue& LayoutTableRow::borderAdjoiningStartCell(const LayoutTableCell* cell) const
......
...@@ -119,17 +119,23 @@ LayoutTableSection::~LayoutTableSection() ...@@ -119,17 +119,23 @@ LayoutTableSection::~LayoutTableSection()
void LayoutTableSection::styleDidChange(StyleDifference diff, const ComputedStyle* oldStyle) void LayoutTableSection::styleDidChange(StyleDifference diff, const ComputedStyle* oldStyle)
{ {
DCHECK(style()->display() == TABLE_FOOTER_GROUP || style()->display() == TABLE_ROW_GROUP || style()->display() == TABLE_HEADER_GROUP);
LayoutTableBoxComponent::styleDidChange(diff, oldStyle); LayoutTableBoxComponent::styleDidChange(diff, oldStyle);
propagateStyleToAnonymousChildren(); propagateStyleToAnonymousChildren();
// If border was changed, notify table. if (!oldStyle)
return;
LayoutTable* table = this->table(); LayoutTable* table = this->table();
if (table && !table->selfNeedsLayout() && !table->normalChildNeedsLayout() && oldStyle && oldStyle->border() != style()->border()) if (!table)
return;
if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() && oldStyle->border() != style()->border())
table->invalidateCollapsedBorders(); table->invalidateCollapsedBorders();
if (table && oldStyle && diff.needsFullLayout() && needsLayout() && table->collapseBorders() && oldStyle->border() != style()->border()) { if (LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *table, diff, *oldStyle))
markAllCellsWidthsDirtyAndOrNeedsLayout(MarkDirtyAndNeedsLayout); markAllCellsWidthsDirtyAndOrNeedsLayout(MarkDirtyAndNeedsLayout);
}
} }
void LayoutTableSection::willBeRemovedFromTree() void LayoutTableSection::willBeRemovedFromTree()
......
...@@ -126,10 +126,10 @@ public: ...@@ -126,10 +126,10 @@ public:
bool sizeEquals(const BorderData& o) const bool sizeEquals(const BorderData& o) const
{ {
return borderLeftWidth() != o.borderLeftWidth() return borderLeftWidth() == o.borderLeftWidth()
|| borderTopWidth() != o.borderTopWidth() && borderTopWidth() == o.borderTopWidth()
|| borderRightWidth() != o.borderRightWidth() && borderRightWidth() == o.borderRightWidth()
|| borderBottomWidth() != o.borderBottomWidth(); && borderBottomWidth() == o.borderBottomWidth();
} }
const BorderValue& left() const { return m_left; } const BorderValue& left() const { return m_left; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment