diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index dc924a05a33..6bac036f664 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -467,6 +467,8 @@ public: NS_IMETHOD GetOffsets(PRInt32 &start, PRInt32 &end)const; virtual void AdjustOffsetsForBidi(PRInt32 start, PRInt32 end); + + NS_IMETHOD DidSetStyleContext(nsPresContext* aPresContext); NS_IMETHOD GetPointFromOffset(nsPresContext* inPresContext, nsIRenderingContext* inRendContext, @@ -1274,6 +1276,12 @@ DrawSelectionIterator::IsBeforeOrAfter() #define TEXT_BLINK_ON 0x80000000 +#define TEXT_IS_EMPTY 0x00100000 + +#define TEXT_ISNOT_EMPTY 0x00200000 + +#define TEXT_ISEMPTY_FLAGS 0x00300000 + //---------------------------------------------------------------------- nsresult @@ -1389,6 +1397,7 @@ nsTextFrame::CharacterDataChanged(nsPresContext* aPresContext, if (aAppend) { markAllDirty = PR_FALSE; nsTextFrame* frame = (nsTextFrame*)GetLastInFlow(); + frame->mState &= ~TEXT_ISEMPTY_FLAGS; frame->mState |= NS_FRAME_IS_DIRTY; targetTextFrame = frame; } @@ -1397,6 +1406,7 @@ nsTextFrame::CharacterDataChanged(nsPresContext* aPresContext, // Mark this frame and all the next-in-flow frames as dirty nsTextFrame* textFrame = this; while (textFrame) { + textFrame->mState &= ~TEXT_ISEMPTY_FLAGS; textFrame->mState |= NS_FRAME_IS_DIRTY; #ifdef IBMBIDI void* nextBidiFrame; @@ -5826,8 +5836,20 @@ nsTextFrame::GetType() const /* virtual */ PRBool nsTextFrame::IsEmpty() { - // XXXldb Should this check compatibility mode as well??? + NS_ASSERTION(!(mState & TEXT_IS_EMPTY) || !(mState & TEXT_ISNOT_EMPTY), + "Invalid state"); + + if (mState & TEXT_ISNOT_EMPTY) { + return PR_FALSE; + } + + if (mState & TEXT_IS_EMPTY) { + return PR_TRUE; + } + + // XXXldb Should this check compatibility mode as well??? if (GetStyleText()->WhiteSpaceIsSignificant()) { + mState |= TEXT_ISNOT_EMPTY; return PR_FALSE; } @@ -5836,7 +5858,18 @@ nsTextFrame::IsEmpty() NS_NOTREACHED("text frame has no text content"); return PR_TRUE; } - return textContent->IsOnlyWhitespace(); + + PRBool isEmpty = textContent->IsOnlyWhitespace(); + mState |= (isEmpty ? TEXT_IS_EMPTY : TEXT_ISNOT_EMPTY); + return isEmpty; +} + +NS_IMETHODIMP +nsTextFrame::DidSetStyleContext(nsPresContext* aPresContext) { + // Clear out our cached IsEmpty() state, since that depends on style + mState &= ~TEXT_ISEMPTY_FLAGS; + + return nsFrame::DidSetStyleContext(aPresContext); } #ifdef DEBUG diff --git a/layout/html/base/src/nsTextFrame.cpp b/layout/html/base/src/nsTextFrame.cpp index dc924a05a33..6bac036f664 100644 --- a/layout/html/base/src/nsTextFrame.cpp +++ b/layout/html/base/src/nsTextFrame.cpp @@ -467,6 +467,8 @@ public: NS_IMETHOD GetOffsets(PRInt32 &start, PRInt32 &end)const; virtual void AdjustOffsetsForBidi(PRInt32 start, PRInt32 end); + + NS_IMETHOD DidSetStyleContext(nsPresContext* aPresContext); NS_IMETHOD GetPointFromOffset(nsPresContext* inPresContext, nsIRenderingContext* inRendContext, @@ -1274,6 +1276,12 @@ DrawSelectionIterator::IsBeforeOrAfter() #define TEXT_BLINK_ON 0x80000000 +#define TEXT_IS_EMPTY 0x00100000 + +#define TEXT_ISNOT_EMPTY 0x00200000 + +#define TEXT_ISEMPTY_FLAGS 0x00300000 + //---------------------------------------------------------------------- nsresult @@ -1389,6 +1397,7 @@ nsTextFrame::CharacterDataChanged(nsPresContext* aPresContext, if (aAppend) { markAllDirty = PR_FALSE; nsTextFrame* frame = (nsTextFrame*)GetLastInFlow(); + frame->mState &= ~TEXT_ISEMPTY_FLAGS; frame->mState |= NS_FRAME_IS_DIRTY; targetTextFrame = frame; } @@ -1397,6 +1406,7 @@ nsTextFrame::CharacterDataChanged(nsPresContext* aPresContext, // Mark this frame and all the next-in-flow frames as dirty nsTextFrame* textFrame = this; while (textFrame) { + textFrame->mState &= ~TEXT_ISEMPTY_FLAGS; textFrame->mState |= NS_FRAME_IS_DIRTY; #ifdef IBMBIDI void* nextBidiFrame; @@ -5826,8 +5836,20 @@ nsTextFrame::GetType() const /* virtual */ PRBool nsTextFrame::IsEmpty() { - // XXXldb Should this check compatibility mode as well??? + NS_ASSERTION(!(mState & TEXT_IS_EMPTY) || !(mState & TEXT_ISNOT_EMPTY), + "Invalid state"); + + if (mState & TEXT_ISNOT_EMPTY) { + return PR_FALSE; + } + + if (mState & TEXT_IS_EMPTY) { + return PR_TRUE; + } + + // XXXldb Should this check compatibility mode as well??? if (GetStyleText()->WhiteSpaceIsSignificant()) { + mState |= TEXT_ISNOT_EMPTY; return PR_FALSE; } @@ -5836,7 +5858,18 @@ nsTextFrame::IsEmpty() NS_NOTREACHED("text frame has no text content"); return PR_TRUE; } - return textContent->IsOnlyWhitespace(); + + PRBool isEmpty = textContent->IsOnlyWhitespace(); + mState |= (isEmpty ? TEXT_IS_EMPTY : TEXT_ISNOT_EMPTY); + return isEmpty; +} + +NS_IMETHODIMP +nsTextFrame::DidSetStyleContext(nsPresContext* aPresContext) { + // Clear out our cached IsEmpty() state, since that depends on style + mState &= ~TEXT_ISEMPTY_FLAGS; + + return nsFrame::DidSetStyleContext(aPresContext); } #ifdef DEBUG