bug 258377, make border collapsed tables to listen for dynamic border style changes r/sr=bzbarsky

This commit is contained in:
Bernd 2008-10-26 11:11:34 +01:00
Родитель 4712683465
Коммит 867fdf2cb0
37 изменённых файлов: 220 добавлений и 53 удалений

Просмотреть файл

@ -133,9 +133,9 @@ nsBulletFrame::IsSelfEmpty()
}
/* virtual */ void
nsBulletFrame::DidSetStyleContext()
nsBulletFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsFrame::DidSetStyleContext();
nsFrame::DidSetStyleContext(aOldStyleContext);
imgIRequest *newRequest = GetStyleList()->mListStyleImage;

Просмотреть файл

@ -62,7 +62,7 @@ public:
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists);
virtual nsIAtom* GetType() const;
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
#ifdef NS_DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const;
#endif

Просмотреть файл

@ -449,7 +449,7 @@ nsFrame::Init(nsIContent* aContent,
mState |= NS_FRAME_MAY_BE_TRANSFORMED_OR_HAVE_RENDERING_OBSERVERS;
}
DidSetStyleContext();
DidSetStyleContext(nsnull);
if (IsBoxWrapped())
InitBoxMetrics(PR_FALSE);
@ -553,7 +553,7 @@ nsFrame::GetOffsets(PRInt32 &aStart, PRInt32 &aEnd) const
// Subclass hook for style post processing
/* virtual */ void
nsFrame::DidSetStyleContext()
nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
// Ensure that this frame gets invalidates (and, in the case of some
// 'border-image's, reflows) when images that affect it load.

Просмотреть файл

@ -557,7 +557,7 @@ protected:
PRInt16 DisplaySelection(nsPresContext* aPresContext, PRBool isOkToTurnOn = PR_FALSE);
// Style post processing hook
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
public:
//given a frame five me the first/last leaf available

Просмотреть файл

@ -610,13 +610,14 @@ public:
void SetStyleContext(nsStyleContext* aContext)
{
if (aContext != mStyleContext) {
if (mStyleContext)
mStyleContext->Release();
nsStyleContext* oldStyleContext = mStyleContext;
mStyleContext = aContext;
if (aContext) {
aContext->AddRef();
DidSetStyleContext();
DidSetStyleContext(oldStyleContext);
}
if (oldStyleContext)
oldStyleContext->Release();
}
}
@ -633,7 +634,10 @@ public:
}
// Style post processing hook
virtual void DidSetStyleContext() = 0;
// Attention: the old style context is the one we're forgetting,
// and hence possibly completely bogus for GetStyle* purposes.
// Use PeekStyleData instead.
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) = 0;
/**
* Get the style data associated with this frame. This returns a

Просмотреть файл

@ -625,7 +625,7 @@ nsObjectFrame::Destroy()
}
/* virtual */ void
nsObjectFrame::DidSetStyleContext()
nsObjectFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
if (HasView()) {
nsIView* view = GetView();
@ -637,7 +637,7 @@ nsObjectFrame::DidSetStyleContext()
}
}
nsObjectFrameSuper::DidSetStyleContext();
nsObjectFrameSuper::DidSetStyleContext(aOldStyleContext);
}
nsIAtom*

Просмотреть файл

@ -102,7 +102,7 @@ public:
virtual void Destroy();
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
NS_IMETHOD GetPluginInstance(nsIPluginInstance*& aPluginInstance);
virtual nsresult Instantiate(nsIChannel* aChannel, nsIStreamListener** aStreamListener);

Просмотреть файл

@ -90,7 +90,7 @@ public:
nsIContent* aChild,
PRBool aAppend);
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
virtual nsIFrame* GetNextContinuation() const {
return mNextContinuation;

Просмотреть файл

@ -3625,9 +3625,9 @@ nsTextFrame::CharacterDataChanged(nsPresContext* aPresContext,
}
/* virtual */ void
nsTextFrame::DidSetStyleContext()
nsTextFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsFrame::DidSetStyleContext();
nsFrame::DidSetStyleContext(aOldStyleContext);
ClearTextRun();
}

Просмотреть файл

@ -226,9 +226,9 @@ nsSVGGlyphFrame::CharacterDataChanged(nsPresContext* aPresContext,
#define PRECISE_SIZE 200
/* virtual */ void
nsSVGGlyphFrame::DidSetStyleContext()
nsSVGGlyphFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsSVGGlyphFrameBase::DidSetStyleContext();
nsSVGGlyphFrameBase::DidSetStyleContext(aOldStyleContext);
if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
ClearTextRun();

Просмотреть файл

@ -81,7 +81,7 @@ public:
nsIContent* aChild,
PRBool aAppend);
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
NS_IMETHOD SetSelected(nsPresContext* aPresContext,
nsIDOMRange* aRange,

Просмотреть файл

@ -64,10 +64,10 @@ nsSVGGradientFrame::nsSVGGradientFrame(nsStyleContext* aContext) :
// nsIFrame methods:
/* virtual */ void
nsSVGGradientFrame::DidSetStyleContext()
nsSVGGradientFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGGradientFrameBase::DidSetStyleContext();
nsSVGGradientFrameBase::DidSetStyleContext(aOldStyleContext);
}
NS_IMETHODIMP

Просмотреть файл

@ -65,7 +65,7 @@ public:
float aGraphicOpacity);
// nsIFrame interface:
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute,

Просмотреть файл

@ -57,7 +57,7 @@ public:
}
#endif
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
};
nsIFrame*
@ -67,8 +67,8 @@ NS_NewSVGLeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
}
/* virtual */ void
nsSVGLeafFrame::DidSetStyleContext()
nsSVGLeafFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsFrame::DidSetStyleContext();
nsFrame::DidSetStyleContext(aOldStyleContext);
nsSVGEffects::InvalidateRenderingObservers(this);
}

Просмотреть файл

@ -84,9 +84,9 @@ nsSVGPathGeometryFrame::AttributeChanged(PRInt32 aNameSpaceID,
}
/* virtual */ void
nsSVGPathGeometryFrame::DidSetStyleContext()
nsSVGPathGeometryFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsSVGPathGeometryFrameBase::DidSetStyleContext();
nsSVGPathGeometryFrameBase::DidSetStyleContext(aOldStyleContext);
nsSVGOuterSVGFrame *outerSVGFrame = nsSVGUtils::GetOuterSVGFrame(this);
if (outerSVGFrame) {

Просмотреть файл

@ -80,7 +80,7 @@ public:
nsIAtom* aAttribute,
PRInt32 aModType);
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
/**
* Get the "type" of the frame

Просмотреть файл

@ -77,10 +77,10 @@ nsSVGPatternFrame::nsSVGPatternFrame(nsStyleContext* aContext) :
// nsIFrame methods:
/* virtual */ void
nsSVGPatternFrame::DidSetStyleContext()
nsSVGPatternFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGPatternFrameBase::DidSetStyleContext();
nsSVGPatternFrameBase::DidSetStyleContext(aOldStyleContext);
}
NS_IMETHODIMP

Просмотреть файл

@ -80,7 +80,7 @@ public:
virtual already_AddRefed<nsIDOMSVGMatrix> GetCanvasTM();
// nsIFrame interface:
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute,

Просмотреть файл

@ -58,7 +58,7 @@ protected:
public:
// nsIFrame interface:
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
@ -92,9 +92,9 @@ public:
// nsIFrame methods:
/* virtual */ void
nsSVGStopFrame::DidSetStyleContext()
nsSVGStopFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsSVGStopFrameBase::DidSetStyleContext();
nsSVGStopFrameBase::DidSetStyleContext(aOldStyleContext);
nsSVGEffects::InvalidateRenderingObservers(this);
}

Просмотреть файл

@ -237,6 +237,25 @@ nsTableCellFrame::AttributeChanged(PRInt32 aNameSpaceID,
return NS_OK;
}
/* virtual */ void
nsTableCellFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
if (!aOldStyleContext) //avoid this on init
return;
nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
if (tableFrame->IsBorderCollapse() &&
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
PRInt32 colIndex, rowIndex;
GetColIndex(colIndex);
GetRowIndex(rowIndex);
nsRect damageArea(colIndex, rowIndex, GetColSpan(), GetRowSpan());
tableFrame->SetBCDamageArea(damageArea);
}
}
NS_IMETHODIMP
nsTableCellFrame::AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList)

Просмотреть файл

@ -92,6 +92,9 @@ public:
nsIAtom* aAttribute,
PRInt32 aModType);
/** @see nsIFrame::DidSetStyleContext */
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
// table cells contain an area frame which does most of the work, and
// so these functions should never be called. They assert and return
// NS_ERROR_NOT_IMPLEMENTED

Просмотреть файл

@ -83,6 +83,22 @@ nsTableColFrame::SetColType(nsTableColType aType)
mState |= (type << COL_TYPE_OFFSET);
}
/* virtual */ void
nsTableColFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
if (!aOldStyleContext) //avoid this on init
return;
nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
if (tableFrame->IsBorderCollapse() &&
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
nsRect damageArea = nsRect(GetColIndex(), 0, 1, tableFrame->GetRowCount());
tableFrame->SetBCDamageArea(damageArea);
}
return;
}
void nsTableColFrame::SetContinuousBCBorderWidth(PRUint8 aForSide,
BCPixelSize aPixelValue)
{

Просмотреть файл

@ -69,6 +69,8 @@ public:
*/
friend nsTableColFrame* NS_NewTableColFrame(nsIPresShell* aPresShell,
nsStyleContext* aContext);
/** @see nsIFrame::DidSetStyleContext */
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
PRInt32 GetColIndex() const;

Просмотреть файл

@ -205,6 +205,23 @@ nsTableColGroupFrame::SetInitialChildList(nsIAtom* aListName,
return NS_OK;
}
/* virtual */ void
nsTableColGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
if (!aOldStyleContext) //avoid this on init
return;
nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
if (tableFrame->IsBorderCollapse() &&
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
nsRect damageArea(GetFirstColumn()->GetColIndex(), 0, GetColCount(),
tableFrame->GetRowCount());
tableFrame->SetBCDamageArea(damageArea);
}
return;
}
NS_IMETHODIMP
nsTableColGroupFrame::AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList)

Просмотреть файл

@ -109,6 +109,9 @@ public:
static PRBool GetLastRealColGroup(nsTableFrame* aTableFrame,
nsIFrame** aLastColGroup);
/** @see nsIFrame::DidSetStyleContext */
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
/** @see nsIFrame::AppendFrames, InsertFrames, RemoveFrame
*/
NS_IMETHOD AppendFrames(nsIAtom* aListName,

Просмотреть файл

@ -275,6 +275,7 @@ nsTableFrame::Destroy()
nsHTMLContainerFrame::Destroy();
}
// Make sure any views are positioned properly
void
nsTableFrame::RePositionViews(nsIFrame* aFrame)
@ -2226,9 +2227,19 @@ nsTableFrame::GetCollapsedWidth(nsMargin aBorderPadding)
return width;
}
/* virtual */ void
nsTableFrame::DidSetStyleContext()
/* virtual */ void
nsTableFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
if (!aOldStyleContext) //avoid this on init
return;
if (IsBorderCollapse() &&
BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
nsRect damageArea(0, 0, GetColCount(), GetRowCount());
SetBCDamageArea(damageArea);
}
//avoid this on init or nextinflow
if (!mTableLayoutStrategy || GetPrevInFlow())
return;
@ -4679,6 +4690,60 @@ GetColorAndStyle(const nsIFrame* aFrame,
aWidth = nsPresContext::AppUnitsToIntCSSPixels(width);
}
class nsDelayedCalcBCBorders : public nsRunnable {
public:
nsDelayedCalcBCBorders(nsIFrame* aFrame) :
mFrame(aFrame) {}
NS_IMETHOD Run() {
if (mFrame) {
nsTableFrame* tableFrame = static_cast <nsTableFrame*>(mFrame.GetFrame());
if (tableFrame) {
if (tableFrame->NeedToCalcBCBorders()) {
tableFrame->CalcBCBorders();
}
}
}
return NS_OK;
}
private:
nsWeakFrame mFrame;
};
PRBool
nsTableFrame::BCRecalcNeeded(nsStyleContext* aOldStyleContext,
nsStyleContext* aNewStyleContext)
{
// Attention: the old style context is the one we're forgetting,
// and hence possibly completely bogus for GetStyle* purposes.
// We use PeekStyleData instead.
const nsStyleBorder* oldStyleData = static_cast<const nsStyleBorder*>
(aOldStyleContext->PeekStyleData(eStyleStruct_Border));
if (!oldStyleData)
return PR_FALSE;
const nsStyleBorder* newStyleData = aNewStyleContext->GetStyleBorder();
nsChangeHint change = newStyleData->CalcDifference(*oldStyleData);
if (change == NS_STYLE_HINT_NONE)
return PR_FALSE;
if (change == NS_STYLE_HINT_REFLOW)
return PR_TRUE; // the caller only needs to mark the bc damage area
if (change == NS_STYLE_HINT_VISUAL) {
NS_FOR_CSS_SIDES(side) {
if (newStyleData->GetBorderStyle(side) !=
oldStyleData->GetBorderStyle(side)) {
// we need to recompute the borders and the caller needs to mark
// the bc damage area
nsCOMPtr<nsIRunnable> evt = new nsDelayedCalcBCBorders(this);
if (evt)
NS_DispatchToCurrentThread(evt);
return PR_TRUE;
}
}
}
return PR_FALSE;
}
/* BCCellBorder represents a border segment which can be either a horizontal
* or a vertical segment. For each segment we need to know the color, width,

Просмотреть файл

@ -198,7 +198,7 @@ public:
virtual void Destroy();
/** @see nsIFrame::DidSetStyleContext */
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
NS_IMETHOD AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList);
@ -307,9 +307,11 @@ public:
* @param aGetInner - get only inner half of border width
*/
nscoord GetContinuousLeftBCBorderWidth() const;
friend class nsDelayedCalcBCBorders;
void SetBCDamageArea(const nsRect& aValue);
PRBool BCRecalcNeeded(nsStyleContext* aOldStyleContext,
nsStyleContext* aNewStyleContext);
void PaintBCBorders(nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);

Просмотреть файл

@ -177,6 +177,21 @@ nsTableRowFrame::Init(nsIContent* aContent,
return rv;
}
/* virtual */ void
nsTableRowFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
if (!aOldStyleContext) //avoid this on init
return;
nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
if (tableFrame->IsBorderCollapse() &&
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
nsRect damageArea(0, GetRowIndex(), tableFrame->GetColCount(), 1);
tableFrame->SetBCDamageArea(damageArea);
}
return;
}
NS_IMETHODIMP
nsTableRowFrame::AppendFrames(nsIAtom* aListName,

Просмотреть файл

@ -72,6 +72,8 @@ public:
NS_IMETHOD Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow);
/** @see nsIFrame::DidSetStyleContext */
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
NS_IMETHOD AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList);

Просмотреть файл

@ -1395,6 +1395,23 @@ nsTableRowGroupFrame::Reflow(nsPresContext* aPresContext,
return rv;
}
/* virtual */ void
nsTableRowGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
if (!aOldStyleContext) //avoid this on init
return;
nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
if (tableFrame->IsBorderCollapse() &&
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
nsRect damageArea(0, GetStartRowIndex(), tableFrame->GetColCount(),
GetRowCount());
tableFrame->SetBCDamageArea(damageArea);
}
return;
}
NS_IMETHODIMP
nsTableRowGroupFrame::AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList)

Просмотреть файл

@ -109,6 +109,8 @@ public:
*/
friend nsIFrame* NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
virtual ~nsTableRowGroupFrame();
/** @see nsIFrame::DidSetStyleContext */
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
NS_IMETHOD AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList);

Просмотреть файл

@ -180,9 +180,9 @@ nsBoxFrame::SetInitialChildList(nsIAtom* aListName,
}
/* virtual */ void
nsBoxFrame::DidSetStyleContext()
nsBoxFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsContainerFrame::DidSetStyleContext();
nsContainerFrame::DidSetStyleContext(aOldStyleContext);
// The values that CacheAttributes() computes depend on our style,
// so we need to recompute them here...

Просмотреть файл

@ -139,7 +139,7 @@ public:
NS_IMETHOD SetInitialChildList(nsIAtom* aListName,
nsIFrame* aChildList);
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
virtual nsIAtom* GetType() const;

Просмотреть файл

@ -390,9 +390,9 @@ nsImageBoxFrame::PaintImage(nsIRenderingContext& aRenderingContext,
// When the style context changes, make sure that all of our image is up to date.
//
/* virtual */ void
nsImageBoxFrame::DidSetStyleContext()
nsImageBoxFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsLeafBoxFrame::DidSetStyleContext();
nsLeafBoxFrame::DidSetStyleContext(aOldStyleContext);
// Fetch our subrect.
const nsStyleList* myList = GetStyleList();

Просмотреть файл

@ -90,7 +90,7 @@ public:
nsIAtom* aAttribute,
PRInt32 aModType);
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
virtual void Destroy();

Просмотреть файл

@ -4219,9 +4219,9 @@ nsTreeBodyFrame::ClearStyleAndImageCaches()
}
/* virtual */ void
nsTreeBodyFrame::DidSetStyleContext()
nsTreeBodyFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsLeafBoxFrame::DidSetStyleContext();
nsLeafBoxFrame::DidSetStyleContext(aOldStyleContext);
// Clear the style cache; the pointers are no longer even valid
mStyleCache.Clear();

Просмотреть файл

@ -121,7 +121,7 @@ public:
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists);
virtual void DidSetStyleContext();
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
friend nsIFrame* NS_NewTreeBodyFrame(nsIPresShell* aPresShell);
friend class nsTreeColumn;