Bug 1389029 - Create custom change hint and post restyle event for rowspan, colspan attribute changes. r=dbaron
MozReview-Commit-ID: IwUlgDa3DAj
This commit is contained in:
@@ -432,12 +432,12 @@ RestyleManager::ChangeHintToString(nsChangeHint aHint)
|
|||||||
"ReflowChangesSizeOrPosition", "UpdateComputedBSize",
|
"ReflowChangesSizeOrPosition", "UpdateComputedBSize",
|
||||||
"UpdateUsesOpacity", "UpdateBackgroundPosition",
|
"UpdateUsesOpacity", "UpdateBackgroundPosition",
|
||||||
"AddOrRemoveTransform", "CSSOverflowChange",
|
"AddOrRemoveTransform", "CSSOverflowChange",
|
||||||
"UpdateWidgetProperties"
|
"UpdateWidgetProperties", "UpdateTableCellSpans"
|
||||||
};
|
};
|
||||||
static_assert(nsChangeHint_AllHints == (1 << ArrayLength(names)) - 1,
|
static_assert(nsChangeHint_AllHints == (1u << ArrayLength(names)) - 1,
|
||||||
"Name list doesn't match change hints.");
|
"Name list doesn't match change hints.");
|
||||||
uint32_t hint = aHint & ((1 << ArrayLength(names)) - 1);
|
uint32_t hint = aHint & ((1u << ArrayLength(names)) - 1);
|
||||||
uint32_t rest = aHint & ~((1 << ArrayLength(names)) - 1);
|
uint32_t rest = aHint & ~((1u << ArrayLength(names)) - 1);
|
||||||
if ((hint & NS_STYLE_HINT_REFLOW) == NS_STYLE_HINT_REFLOW) {
|
if ((hint & NS_STYLE_HINT_REFLOW) == NS_STYLE_HINT_REFLOW) {
|
||||||
result.AppendLiteral("NS_STYLE_HINT_REFLOW");
|
result.AppendLiteral("NS_STYLE_HINT_REFLOW");
|
||||||
hint = hint & ~NS_STYLE_HINT_REFLOW;
|
hint = hint & ~NS_STYLE_HINT_REFLOW;
|
||||||
@@ -1697,6 +1697,9 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
|||||||
if (hint & nsChangeHint_UpdateWidgetProperties) {
|
if (hint & nsChangeHint_UpdateWidgetProperties) {
|
||||||
frame->UpdateWidgetProperties();
|
frame->UpdateWidgetProperties();
|
||||||
}
|
}
|
||||||
|
if (hint & nsChangeHint_UpdateTableCellSpans) {
|
||||||
|
frameConstructor->UpdateTableCellSpans(content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9958,6 +9958,21 @@ nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsCSSFrameConstructor::UpdateTableCellSpans(nsIContent* aContent)
|
||||||
|
{
|
||||||
|
nsTableCellFrame* cellFrame = do_QueryFrame(aContent->GetPrimaryFrame());
|
||||||
|
|
||||||
|
// It's possible that this warning could fire if some other style change
|
||||||
|
// simultaneously changes the 'display' of the element and makes it no
|
||||||
|
// longer be a table cell.
|
||||||
|
NS_WARNING_ASSERTION(cellFrame, "Hint should only be posted on table cells!");
|
||||||
|
|
||||||
|
if (cellFrame) {
|
||||||
|
cellFrame->GetTableFrame()->RowOrColSpanChanged(cellFrame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsCSSFrameConstructor::RecreateFramesForContent(nsIContent* aContent,
|
nsCSSFrameConstructor::RecreateFramesForContent(nsIContent* aContent,
|
||||||
InsertionKind aInsertionKind,
|
InsertionKind aInsertionKind,
|
||||||
|
|||||||
@@ -1803,6 +1803,11 @@ private:
|
|||||||
InsertionKind aInsertionKind,
|
InsertionKind aInsertionKind,
|
||||||
RemoveFlags aFlags);
|
RemoveFlags aFlags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles change of rowspan and colspan attributes on table cells.
|
||||||
|
*/
|
||||||
|
void UpdateTableCellSpans(nsIContent* aContent);
|
||||||
|
|
||||||
// If removal of aFrame from the frame tree requires reconstruction of some
|
// If removal of aFrame from the frame tree requires reconstruction of some
|
||||||
// containing block (either of aFrame or of its parent) due to {ib} splits or
|
// containing block (either of aFrame or of its parent) due to {ib} splits or
|
||||||
// table pseudo-frames, recreate the relevant frame subtree. The return value
|
// table pseudo-frames, recreate the relevant frame subtree. The return value
|
||||||
|
|||||||
@@ -238,6 +238,12 @@ enum nsChangeHint : uint32_t {
|
|||||||
*/
|
*/
|
||||||
nsChangeHint_UpdateWidgetProperties = 1 << 29,
|
nsChangeHint_UpdateWidgetProperties = 1 << 29,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that there has been a colspan or rowspan attribute change
|
||||||
|
* on the cells of a table.
|
||||||
|
*/
|
||||||
|
nsChangeHint_UpdateTableCellSpans = 1 << 30,
|
||||||
|
|
||||||
// IMPORTANT NOTE: When adding a new hint, you will need to add it to
|
// IMPORTANT NOTE: When adding a new hint, you will need to add it to
|
||||||
// one of:
|
// one of:
|
||||||
//
|
//
|
||||||
@@ -253,7 +259,7 @@ enum nsChangeHint : uint32_t {
|
|||||||
/**
|
/**
|
||||||
* Dummy hint value for all hints. It exists for compile time check.
|
* Dummy hint value for all hints. It exists for compile time check.
|
||||||
*/
|
*/
|
||||||
nsChangeHint_AllHints = (1 << 30) - 1,
|
nsChangeHint_AllHints = (1u << 31) - 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Redefine these operators to return nothing. This will catch any use
|
// Redefine these operators to return nothing. This will catch any use
|
||||||
@@ -353,6 +359,7 @@ inline nsChangeHint operator^=(nsChangeHint& aLeft, nsChangeHint aRight)
|
|||||||
nsChangeHint_UpdateOverflow | \
|
nsChangeHint_UpdateOverflow | \
|
||||||
nsChangeHint_UpdateParentOverflow | \
|
nsChangeHint_UpdateParentOverflow | \
|
||||||
nsChangeHint_UpdatePostTransformOverflow | \
|
nsChangeHint_UpdatePostTransformOverflow | \
|
||||||
|
nsChangeHint_UpdateTableCellSpans | \
|
||||||
nsChangeHint_UpdateTransformLayer | \
|
nsChangeHint_UpdateTransformLayer | \
|
||||||
nsChangeHint_UpdateUsesOpacity | \
|
nsChangeHint_UpdateUsesOpacity | \
|
||||||
nsChangeHint_AddOrRemoveTransform | \
|
nsChangeHint_AddOrRemoveTransform | \
|
||||||
|
|||||||
@@ -230,8 +230,12 @@ nsTableCellFrame::AttributeChanged(int32_t aNameSpaceID,
|
|||||||
PresContext()->PresShell()->
|
PresContext()->PresShell()->
|
||||||
FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
|
FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
|
||||||
}
|
}
|
||||||
// let the table frame decide what to do
|
|
||||||
GetTableFrame()->AttributeChangedFor(this, mContent, aAttribute);
|
if (aAttribute == nsGkAtoms::rowspan || aAttribute == nsGkAtoms::colspan) {
|
||||||
|
nsLayoutUtils::PostRestyleEvent(mContent->AsElement(),
|
||||||
|
nsRestyleHint(0),
|
||||||
|
nsChangeHint_UpdateTableCellSpans);
|
||||||
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -355,30 +355,24 @@ nsTableFrame::SetInitialChildList(ChildListID aListID,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsTableFrame::AttributeChangedFor(nsIFrame* aFrame,
|
nsTableFrame::RowOrColSpanChanged(nsTableCellFrame* aCellFrame)
|
||||||
nsIContent* aContent,
|
|
||||||
nsIAtom* aAttribute)
|
|
||||||
{
|
{
|
||||||
nsTableCellFrame *cellFrame = do_QueryFrame(aFrame);
|
if (aCellFrame) {
|
||||||
if (cellFrame) {
|
nsTableCellMap* cellMap = GetCellMap();
|
||||||
if ((nsGkAtoms::rowspan == aAttribute) ||
|
if (cellMap) {
|
||||||
(nsGkAtoms::colspan == aAttribute)) {
|
// for now just remove the cell from the map and reinsert it
|
||||||
nsTableCellMap* cellMap = GetCellMap();
|
int32_t rowIndex, colIndex;
|
||||||
if (cellMap) {
|
aCellFrame->GetRowIndex(rowIndex);
|
||||||
// for now just remove the cell from the map and reinsert it
|
aCellFrame->GetColIndex(colIndex);
|
||||||
int32_t rowIndex, colIndex;
|
RemoveCell(aCellFrame, rowIndex);
|
||||||
cellFrame->GetRowIndex(rowIndex);
|
AutoTArray<nsTableCellFrame*, 1> cells;
|
||||||
cellFrame->GetColIndex(colIndex);
|
cells.AppendElement(aCellFrame);
|
||||||
RemoveCell(cellFrame, rowIndex);
|
InsertCells(cells, rowIndex, colIndex - 1);
|
||||||
AutoTArray<nsTableCellFrame*, 1> cells;
|
|
||||||
cells.AppendElement(cellFrame);
|
|
||||||
InsertCells(cells, rowIndex, colIndex - 1);
|
|
||||||
|
|
||||||
// XXX Should this use eStyleChange? It currently doesn't need
|
// XXX Should this use eStyleChange? It currently doesn't need
|
||||||
// to, but it might given more optimization.
|
// to, but it might given more optimization.
|
||||||
PresContext()->PresShell()->
|
PresContext()->PresShell()->
|
||||||
FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
|
FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,12 +180,12 @@ public:
|
|||||||
nsIFrame* aDestructRoot);
|
nsIFrame* aDestructRoot);
|
||||||
|
|
||||||
nsPoint GetFirstSectionOrigin(const ReflowInput& aReflowInput) const;
|
nsPoint GetFirstSectionOrigin(const ReflowInput& aReflowInput) const;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Notification that aAttribute has changed for content inside a table (cell, row, etc)
|
* Notification that rowspan or colspan has changed for content inside a
|
||||||
|
* table cell
|
||||||
*/
|
*/
|
||||||
void AttributeChangedFor(nsIFrame* aFrame,
|
void RowOrColSpanChanged(nsTableCellFrame* aCellFrame);
|
||||||
nsIContent* aContent,
|
|
||||||
nsIAtom* aAttribute);
|
|
||||||
|
|
||||||
/** @see nsIFrame::DestroyFrom */
|
/** @see nsIFrame::DestroyFrom */
|
||||||
virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
|
virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
|
||||||
|
|||||||
Reference in New Issue
Block a user