From 287fc1dc9e25c20bc75609bba16d35497a540ccb Mon Sep 17 00:00:00 2001 From: "pierre%netscape.com" Date: Thu, 3 May 2001 13:20:48 +0000 Subject: [PATCH] 43457: change the mutable style context APIs, disable style context sharing, implement style data sharing. r=waterson. git-svn-id: svn://10.0.0.236/trunk@93798 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsStyleContext.cpp | 4177 +++++++------- mozilla/content/base/src/nsStyleSet.cpp | 12 +- .../html/content/src/nsGenericHTMLElement.cpp | 36 +- .../html/content/src/nsHTMLBRElement.cpp | 4 +- .../html/content/src/nsHTMLBodyElement.cpp | 37 +- .../content/src/nsHTMLDirectoryElement.cpp | 3 +- .../html/content/src/nsHTMLDivElement.cpp | 3 +- .../html/content/src/nsHTMLFontElement.cpp | 11 +- .../html/content/src/nsHTMLHRElement.cpp | 6 +- .../html/content/src/nsHTMLHeadingElement.cpp | 3 +- .../html/content/src/nsHTMLIFrameElement.cpp | 20 +- .../html/content/src/nsHTMLImageElement.cpp | 6 +- .../html/content/src/nsHTMLInputElement.cpp | 8 +- .../html/content/src/nsHTMLLIElement.cpp | 3 +- .../html/content/src/nsHTMLMenuElement.cpp | 3 +- .../html/content/src/nsHTMLOListElement.cpp | 3 +- .../content/src/nsHTMLParagraphElement.cpp | 3 +- .../html/content/src/nsHTMLPreElement.cpp | 18 +- .../html/content/src/nsHTMLSelectElement.cpp | 16 +- .../html/content/src/nsHTMLSpacerElement.cpp | 6 +- .../content/src/nsHTMLTableCaptionElement.cpp | 4 +- .../content/src/nsHTMLTableCellElement.cpp | 113 +- .../content/src/nsHTMLTableColElement.cpp | 32 +- .../src/nsHTMLTableColGroupElement.cpp | 29 +- .../html/content/src/nsHTMLTableElement.cpp | 42 +- .../content/src/nsHTMLTableRowElement.cpp | 28 +- .../content/src/nsHTMLTableSectionElement.cpp | 29 +- .../content/src/nsHTMLTextAreaElement.cpp | 21 +- .../html/content/src/nsHTMLUListElement.cpp | 3 +- .../content/html/style/src/nsCSSStyleRule.cpp | 73 +- .../html/style/src/nsHTMLCSSStyleSheet.cpp | 31 +- .../html/style/src/nsHTMLStyleSheet.cpp | 31 +- .../content/xul/content/src/nsXULElement.cpp | 1 + mozilla/layout/base/nsCSSFrameConstructor.cpp | 52 +- .../base/public/nsIMutableStyleContext.h | 90 +- mozilla/layout/base/public/nsIStyleContext.h | 94 +- mozilla/layout/base/public/nsIStyleSet.h | 8 +- mozilla/layout/base/public/nsStyleStruct.h | 10 +- .../html/forms/src/nsGfxTextControlFrame.cpp | 5043 +++++++++++++++++ .../html/style/src/nsCSSFrameConstructor.cpp | 52 +- .../html/table/src/nsTableCellFrame.cpp | 59 +- .../layout/html/table/src/nsTableFrame.cpp | 25 +- .../html/table/src/nsTableOuterFrame.cpp | 12 +- mozilla/layout/style/nsCSSStyleRule.cpp | 73 +- mozilla/layout/style/nsHTMLCSSStyleSheet.cpp | 31 +- mozilla/layout/style/nsHTMLStyleSheet.cpp | 31 +- mozilla/layout/style/nsStyleContext.cpp | 4177 +++++++------- mozilla/layout/style/nsStyleSet.cpp | 12 +- mozilla/layout/tables/nsTableCellFrame.cpp | 59 +- mozilla/layout/tables/nsTableFrame.cpp | 25 +- mozilla/layout/tables/nsTableOuterFrame.cpp | 12 +- .../src/outliner/src/nsOutlinerBodyFrame.h | 1 + .../xul/base/src/tree/src/nsTreeBodyFrame.h | 1 + 53 files changed, 9721 insertions(+), 4961 deletions(-) create mode 100644 mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp diff --git a/mozilla/content/base/src/nsStyleContext.cpp b/mozilla/content/base/src/nsStyleContext.cpp index 83d3ecb8bc6..388abd7b793 100644 --- a/mozilla/content/base/src/nsStyleContext.cpp +++ b/mozilla/content/base/src/nsStyleContext.cpp @@ -56,42 +56,22 @@ #endif #ifdef DEBUG -// #define NOISY_DEBUG -#endif - -// -------------------------------------- -// Macros for getting style data structs -// - if using external data, get from -// the member style data instance -// - if internal, get the data member -#ifdef SHARE_STYLECONTEXTS -#define GETSCDATA(data) mStyleData->m##data -#else -#define GETSCDATA(data) m##data +//#define NOISY_DEBUG #endif -#ifdef SHARE_STYLECONTEXTS +#ifdef USE_FAST_CACHE // define COMPUTE_STYLEDATA_CRC to actually compute a valid CRC32 - // - if not defined then the CRC will simply be 0 (see StyleContextData::ComputeCRC) - // - this is to avoid the cost of computing a CRC if it is not being used - // by the style set in caching the style contexts (not using the FAST_CACHE) - // which is the current situation since the CRC can change when GetMutableStyleData - // is used to poke values into the style context data. + // - Fast cache uses a CRC32 on the style context to quickly find sharing candidates. + // Enabling it by defining USE_FAST_CACHE makes style sharing significantly faster. #define COMPUTE_STYLEDATA_CRC -#endif //SHARE_STYLECONTEXTS +#endif -#ifdef COMPUTE_STYLEDATA_CRC - // helpers for computing CRC32 on style data -static void gen_crc_table(); -static PRUint32 AccumulateCRC(PRUint32 crc_accum, const char *data_blk_ptr, int data_blk_size); -static PRUint32 StyleSideCRC(PRUint32 crc,const nsStyleSides *aStyleSides); -static PRUint32 StyleCoordCRC(PRUint32 crc, const nsStyleCoord* aCoord); -static PRUint32 StyleMarginCRC(PRUint32 crc, const nsMargin *aMargin); -static PRUint32 StyleStringCRC(PRUint32 aCrc, const nsString *aString); -#define STYLEDATA_NO_CRC (0) -#define STYLEDATA_DEFAULT_CRC (0xcafebabe) -#endif // COMPUTE_STYLEDATA_CRC + +//------------------------------------------------------------------------------ +// Helper functions +//------------------------------------------------------------------------------ +// inline PRBool IsFixedUnit(nsStyleUnit aUnit, PRBool aEnumOK) { @@ -100,254 +80,6 @@ inline PRBool IsFixedUnit(nsStyleUnit aUnit, PRBool aEnumOK) (aEnumOK && (aUnit == eStyleUnit_Enumerated))); } -static PRBool IsFixedData(const nsStyleSides& aSides, PRBool aEnumOK); -static nscoord CalcCoord(const nsStyleCoord& aCoord, - const nscoord* aEnumTable, - PRInt32 aNumEnums); - -// EnsureBlockDisplay: -// - if the display value (argument) is not a block-type -// then we set it to a valid block display value -// - For enforcing the floated/positioned element CSS2 rules -static void EnsureBlockDisplay(/*in out*/PRUint8 &display); - -// -------------------- -// nsStyleFont -// -nsStyleFont::nsStyleFont(const nsFont& aVariableFont, const nsFont& aFixedFont) - : mFont(aVariableFont), - mFixedFont(aFixedFont) -{ } - -struct StyleFontImpl : public nsStyleFont { - StyleFontImpl(const nsFont& aVariableFont, const nsFont& aFixedFont) - : nsStyleFont(aVariableFont, aFixedFont) - {} - - void ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleFont& aSource); - void CopyTo(nsStyleFont& aDest) const; - PRInt32 CalcDifference(const StyleFontImpl& aOther) const; - static PRInt32 CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2); - PRUint32 ComputeCRC32(PRUint32 crc) const; - -private: // These are not allowed - StyleFontImpl(const StyleFontImpl& aOther); - StyleFontImpl& operator=(const StyleFontImpl& aOther); -}; - -void StyleFontImpl::ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext) -{ - if (nsnull != aParent) { - mFont = aParent->mFont; - mFixedFont = aParent->mFixedFont; - mFlags = aParent->mFlags; - } - else { - aPresContext->GetDefaultFont(mFont); - aPresContext->GetDefaultFixedFont(mFixedFont); - mFlags = NS_STYLE_FONT_DEFAULT; - } -} - -void StyleFontImpl::SetFrom(const nsStyleFont& aSource) -{ - mFont = aSource.mFont; - mFixedFont = aSource.mFixedFont; - mFlags = aSource.mFlags; -} - -void StyleFontImpl::CopyTo(nsStyleFont& aDest) const -{ - aDest.mFont = mFont; - aDest.mFixedFont = mFixedFont; - aDest.mFlags = mFlags; -} - -PRInt32 StyleFontImpl::CalcDifference(const StyleFontImpl& aOther) const -{ - if (mFlags == aOther.mFlags) { - PRInt32 impact = CalcFontDifference(mFont, aOther.mFont); - if (impact < NS_STYLE_HINT_REFLOW) { - impact = CalcFontDifference(mFixedFont, aOther.mFixedFont); - } - return impact; - } - return NS_STYLE_HINT_REFLOW; -} - -PRInt32 StyleFontImpl::CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2) -{ - if ((aFont1.size == aFont2.size) && - (aFont1.style == aFont2.style) && - (aFont1.variant == aFont2.variant) && - (aFont1.weight == aFont2.weight) && - (aFont1.name == aFont2.name)) { - if ((aFont1.decorations == aFont2.decorations)) { - return NS_STYLE_HINT_NONE; - } - return NS_STYLE_HINT_VISUAL; - } - return NS_STYLE_HINT_REFLOW; -} - -PRUint32 StyleFontImpl::ComputeCRC32(PRUint32 aCrc) const -{ - PRUint32 crc = aCrc; - -#ifdef COMPUTE_STYLEDATA_CRC - crc = AccumulateCRC(crc,(const char *)&(mFont.size),sizeof(mFont.size)); - crc = AccumulateCRC(crc,(const char *)&(mFont.style),sizeof(mFont.style)); - crc = AccumulateCRC(crc,(const char *)&(mFont.variant),sizeof(mFont.variant)); - crc = AccumulateCRC(crc,(const char *)&(mFont.weight),sizeof(mFont.weight)); - crc = AccumulateCRC(crc,(const char *)&(mFont.decorations),sizeof(mFont.decorations)); - crc = StyleStringCRC(crc,&(mFont.name)); - crc = AccumulateCRC(crc,(const char *)&(mFixedFont.size),sizeof(mFixedFont.size)); - crc = AccumulateCRC(crc,(const char *)&(mFixedFont.style),sizeof(mFixedFont.style)); - crc = AccumulateCRC(crc,(const char *)&(mFixedFont.variant),sizeof(mFixedFont.variant)); - crc = AccumulateCRC(crc,(const char *)&(mFixedFont.weight),sizeof(mFixedFont.weight)); - crc = AccumulateCRC(crc,(const char *)&(mFixedFont.decorations),sizeof(mFixedFont.decorations)); - crc = StyleStringCRC(crc,&(mFixedFont.name)); - crc = AccumulateCRC(crc,(const char *)&mFlags,sizeof(mFlags)); -#endif - - return crc; -} - -#ifdef XP_MAC -#pragma mark - -#endif - -// -------------------- -// nsStyleColor -// - -struct StyleColorImpl: public nsStyleColor { - StyleColorImpl(void) { } - - void ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleColor& aSource); - void CopyTo(nsStyleColor& aDest) const; - PRInt32 CalcDifference(const StyleColorImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; - -private: // These are not allowed - StyleColorImpl(const StyleColorImpl& aOther); - StyleColorImpl& operator=(const StyleColorImpl& aOther); -}; - -void StyleColorImpl::ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext) -{ - if (nsnull != aParent) { - mColor = aParent->mColor; - mOpacity = aParent->mOpacity; - mCursor = aParent->mCursor; // fix for bugzilla bug 51113 - } - else { - if (nsnull != aPresContext) { - aPresContext->GetDefaultColor(&mColor); - } - else { - mColor = NS_RGB(0x00, 0x00, 0x00); - } - mOpacity = 1.0f; - mCursor = NS_STYLE_CURSOR_AUTO; // fix for bugzilla bug 51113 - } - - mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE; - if (nsnull != aPresContext) { - aPresContext->GetDefaultBackgroundColor(&mBackgroundColor); - aPresContext->GetDefaultBackgroundImageAttachment(&mBackgroundAttachment); - aPresContext->GetDefaultBackgroundImageRepeat(&mBackgroundRepeat); - aPresContext->GetDefaultBackgroundImageOffset(&mBackgroundXPosition, &mBackgroundYPosition); - aPresContext->GetDefaultBackgroundImage(mBackgroundImage); - } - else { - mBackgroundColor = NS_RGB(192,192,192); - mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; - mBackgroundRepeat = NS_STYLE_BG_REPEAT_XY; - mBackgroundXPosition = 0; - mBackgroundYPosition = 0; - } -} - -void StyleColorImpl::SetFrom(const nsStyleColor& aSource) -{ - mColor = aSource.mColor; - - mBackgroundAttachment = aSource.mBackgroundAttachment; - mBackgroundFlags = aSource.mBackgroundFlags; - mBackgroundRepeat = aSource.mBackgroundRepeat; - - mBackgroundColor = aSource.mBackgroundColor; - mBackgroundXPosition = aSource.mBackgroundXPosition; - mBackgroundYPosition = aSource.mBackgroundYPosition; - mBackgroundImage = aSource.mBackgroundImage; - - mCursor = aSource.mCursor; - mCursorImage = aSource.mCursorImage; - mOpacity = aSource.mOpacity; -} - -void StyleColorImpl::CopyTo(nsStyleColor& aDest) const -{ - aDest.mColor = mColor; - - aDest.mBackgroundAttachment = mBackgroundAttachment; - aDest.mBackgroundFlags = mBackgroundFlags; - aDest.mBackgroundRepeat = mBackgroundRepeat; - - aDest.mBackgroundColor = mBackgroundColor; - aDest.mBackgroundXPosition = mBackgroundXPosition; - aDest.mBackgroundYPosition = mBackgroundYPosition; - aDest.mBackgroundImage = mBackgroundImage; - - aDest.mCursor = mCursor; - aDest.mCursorImage = mCursorImage; - aDest.mOpacity = mOpacity; -} - -PRInt32 StyleColorImpl::CalcDifference(const StyleColorImpl& aOther) const -{ - if ((mColor == aOther.mColor) && - (mBackgroundAttachment == aOther.mBackgroundAttachment) && - (mBackgroundFlags == aOther.mBackgroundFlags) && - (mBackgroundRepeat == aOther.mBackgroundRepeat) && - (mBackgroundColor == aOther.mBackgroundColor) && - (mBackgroundXPosition == aOther.mBackgroundXPosition) && - (mBackgroundYPosition == aOther.mBackgroundYPosition) && - (mBackgroundImage == aOther.mBackgroundImage) && - (mCursor == aOther.mCursor) && - (mCursorImage == aOther.mCursorImage) && - (mOpacity == aOther.mOpacity)) { - return NS_STYLE_HINT_NONE; - } - return NS_STYLE_HINT_VISUAL; -} - -PRUint32 StyleColorImpl::ComputeCRC32(PRUint32 aCrc) const -{ - PRUint32 crc = aCrc; -#ifdef COMPUTE_STYLEDATA_CRC - crc = AccumulateCRC(crc,(const char *)&mColor,sizeof(mColor)); - crc = AccumulateCRC(crc,(const char *)&mBackgroundAttachment,sizeof(mBackgroundAttachment)); - crc = AccumulateCRC(crc,(const char *)&mBackgroundFlags,sizeof(mBackgroundFlags)); - crc = AccumulateCRC(crc,(const char *)&mBackgroundRepeat,sizeof(mBackgroundRepeat)); - crc = AccumulateCRC(crc,(const char *)&mBackgroundColor,sizeof(mBackgroundColor)); - crc = AccumulateCRC(crc,(const char *)&mBackgroundXPosition,sizeof(mBackgroundXPosition)); - crc = AccumulateCRC(crc,(const char *)&mBackgroundYPosition,sizeof(mBackgroundYPosition)); - crc = StyleStringCRC(crc,&mBackgroundImage); - crc = AccumulateCRC(crc,(const char *)&mCursor,sizeof(mCursor)); - crc = StyleStringCRC(crc,&mCursorImage); - crc = AccumulateCRC(crc,(const char *)&mOpacity,sizeof(mOpacity)); -#endif - return crc; -} - -#ifdef XP_MAC -#pragma mark - -#endif - static PRBool IsFixedData(const nsStyleSides& aSides, PRBool aEnumOK) { return PRBool(IsFixedUnit(aSides.GetLeftUnit(), aEnumOK) && @@ -380,46 +112,331 @@ static nscoord CalcCoord(const nsStyleCoord& aCoord, return 0; } +#ifdef COMPUTE_STYLEDATA_CRC +static void gen_crc_table(); +static PRUint32 AccumulateCRC(PRUint32 crc_accum, const char *data_blk_ptr, int data_blk_size); +static PRUint32 StyleSideCRC(PRUint32 crc,const nsStyleSides *aStyleSides); +static PRUint32 StyleCoordCRC(PRUint32 crc, const nsStyleCoord* aCoord); +static PRUint32 StyleMarginCRC(PRUint32 crc, const nsMargin *aMargin); +static PRUint32 StyleStringCRC(PRUint32 aCrc, const nsString *aString); +#define STYLEDATA_NO_CRC (0) +#define STYLEDATA_DEFAULT_CRC (0xcafebabe) +#endif + #ifdef XP_MAC #pragma mark - #endif -struct StyleMarginImpl: public nsStyleMargin { - StyleMarginImpl(void) - : nsStyleMargin() - {} +struct StyleBlob { + virtual ~StyleBlob(void) {} - void ResetFrom(const nsStyleMargin* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleMargin& aSource); - void CopyTo(nsStyleMargin& aDest) const; - void RecalcData(void); - PRInt32 CalcDifference(const StyleMarginImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) = 0; + virtual void CopyTo(nsStyleStruct* aDest) const = 0; + virtual void SetFrom(const nsStyleStruct* aSource) = 0; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const = 0; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const = 0; -private: // These are not allowed - StyleMarginImpl(const StyleMarginImpl& aOther); - StyleMarginImpl& operator=(const StyleMarginImpl& aOther); + inline virtual const nsStyleStruct* GetData(void) const = 0; }; -void StyleMarginImpl::ResetFrom(const nsStyleMargin* aParent, nsIPresContext* aPresContext) +//------------------------------------------------------------------------------ +// nsStyleFont +//------------------------------------------------------------------------------ +// +struct StyleFontBlob : public nsStyleFont, public StyleBlob { + StyleFontBlob(const nsFont& aVariableFont, const nsFont& aFixedFont) + : nsStyleFont(aVariableFont, aFixedFont) + {} + + StyleFontBlob(void) {} + virtual ~StyleFontBlob(void) {} + + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleFont*)this;}; + + static PRInt32 CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2); + +private: // These are not allowed + StyleFontBlob(const StyleFontBlob& aOther); + StyleFontBlob& operator=(const StyleFontBlob& aOther); +}; + +void StyleFontBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) +{ + const nsStyleFont* parent = (nsStyleFont*)aParent; + + if (nsnull != parent) { + mFont = parent->mFont; + mFixedFont = parent->mFixedFont; + mFlags = parent->mFlags; + } + else { + aPresContext->GetDefaultFont(mFont); + aPresContext->GetDefaultFixedFont(mFixedFont); + mFlags = NS_STYLE_FONT_DEFAULT; + } +} + +void StyleFontBlob::SetFrom(const nsStyleStruct* aSource) +{ + const nsStyleFont* source = (nsStyleFont*)aSource; + + mFont = source->mFont; + mFixedFont = source->mFixedFont; + mFlags = source->mFlags; +} + +void StyleFontBlob::CopyTo(nsStyleStruct* aDest) const +{ + nsStyleFont* dest = (nsStyleFont*)aDest; + + dest->mFont = mFont; + dest->mFixedFont = mFixedFont; + dest->mFlags = mFlags; +} + +PRInt32 StyleFontBlob::CalcDifference(const nsStyleStruct* aOther) const +{ + const nsStyleFont* other = (nsStyleFont*)aOther; + + if (mFlags == other->mFlags) { + PRInt32 impact = CalcFontDifference(mFont, other->mFont); + if (impact < NS_STYLE_HINT_REFLOW) { + impact = CalcFontDifference(mFixedFont, other->mFixedFont); + } + return impact; + } + return NS_STYLE_HINT_REFLOW; +} + +PRInt32 StyleFontBlob::CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2) +{ + if ((aFont1.size == aFont2.size) && + (aFont1.style == aFont2.style) && + (aFont1.variant == aFont2.variant) && + (aFont1.weight == aFont2.weight) && + (aFont1.name == aFont2.name)) { + if ((aFont1.decorations == aFont2.decorations)) { + return NS_STYLE_HINT_NONE; + } + return NS_STYLE_HINT_VISUAL; + } + return NS_STYLE_HINT_REFLOW; +} + +PRUint32 StyleFontBlob::ComputeCRC32(PRUint32 aCrc) const +{ + PRUint32 crc = aCrc; + +#ifdef COMPUTE_STYLEDATA_CRC + crc = AccumulateCRC(crc,(const char *)&(mFont.size),sizeof(mFont.size)); + crc = AccumulateCRC(crc,(const char *)&(mFont.style),sizeof(mFont.style)); + crc = AccumulateCRC(crc,(const char *)&(mFont.variant),sizeof(mFont.variant)); + crc = AccumulateCRC(crc,(const char *)&(mFont.weight),sizeof(mFont.weight)); + crc = AccumulateCRC(crc,(const char *)&(mFont.decorations),sizeof(mFont.decorations)); + crc = StyleStringCRC(crc,&(mFont.name)); + crc = AccumulateCRC(crc,(const char *)&(mFixedFont.size),sizeof(mFixedFont.size)); + crc = AccumulateCRC(crc,(const char *)&(mFixedFont.style),sizeof(mFixedFont.style)); + crc = AccumulateCRC(crc,(const char *)&(mFixedFont.variant),sizeof(mFixedFont.variant)); + crc = AccumulateCRC(crc,(const char *)&(mFixedFont.weight),sizeof(mFixedFont.weight)); + crc = AccumulateCRC(crc,(const char *)&(mFixedFont.decorations),sizeof(mFixedFont.decorations)); + crc = StyleStringCRC(crc,&(mFixedFont.name)); + crc = AccumulateCRC(crc,(const char *)&mFlags,sizeof(mFlags)); +#endif + + return crc; +} + +#ifdef XP_MAC +#pragma mark - +#endif + +//------------------------------------------------------------------------------ +// nsStyleColor +//------------------------------------------------------------------------------ +// +struct StyleColorBlob: public nsStyleColor, public StyleBlob { + StyleColorBlob(void) { } + virtual ~StyleColorBlob(void) {} + + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleColor*)this;}; + +private: // These are not allowed + StyleColorBlob(const StyleColorBlob& aOther); + StyleColorBlob& operator=(const StyleColorBlob& aOther); +}; + +void StyleColorBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) +{ + const nsStyleColor* parent = (nsStyleColor*)aParent; + + if (nsnull != parent) { + mColor = parent->mColor; + mOpacity = parent->mOpacity; + mCursor = parent->mCursor; // fix for bugzilla bug 51113 + } + else { + if (nsnull != aPresContext) { + aPresContext->GetDefaultColor(&mColor); + } + else { + mColor = NS_RGB(0x00, 0x00, 0x00); + } + mOpacity = 1.0f; + mCursor = NS_STYLE_CURSOR_AUTO; // fix for bugzilla bug 51113 + } + + mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE; + if (nsnull != aPresContext) { + aPresContext->GetDefaultBackgroundColor(&mBackgroundColor); + aPresContext->GetDefaultBackgroundImageAttachment(&mBackgroundAttachment); + aPresContext->GetDefaultBackgroundImageRepeat(&mBackgroundRepeat); + aPresContext->GetDefaultBackgroundImageOffset(&mBackgroundXPosition, &mBackgroundYPosition); + aPresContext->GetDefaultBackgroundImage(mBackgroundImage); + } + else { + mBackgroundColor = NS_RGB(192,192,192); + mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; + mBackgroundRepeat = NS_STYLE_BG_REPEAT_XY; + mBackgroundXPosition = 0; + mBackgroundYPosition = 0; + } +} + +void StyleColorBlob::SetFrom(const nsStyleStruct* aSource) +{ + const nsStyleColor* source = (nsStyleColor*)aSource; + + mColor = source->mColor; + + mBackgroundAttachment = source->mBackgroundAttachment; + mBackgroundFlags = source->mBackgroundFlags; + mBackgroundRepeat = source->mBackgroundRepeat; + + mBackgroundColor = source->mBackgroundColor; + mBackgroundXPosition = source->mBackgroundXPosition; + mBackgroundYPosition = source->mBackgroundYPosition; + mBackgroundImage = source->mBackgroundImage; + + mCursor = source->mCursor; + mCursorImage = source->mCursorImage; + mOpacity = source->mOpacity; +} + +void StyleColorBlob::CopyTo(nsStyleStruct* aDest) const +{ + nsStyleColor* dest = (nsStyleColor*)aDest; + + dest->mColor = mColor; + + dest->mBackgroundAttachment = mBackgroundAttachment; + dest->mBackgroundFlags = mBackgroundFlags; + dest->mBackgroundRepeat = mBackgroundRepeat; + + dest->mBackgroundColor = mBackgroundColor; + dest->mBackgroundXPosition = mBackgroundXPosition; + dest->mBackgroundYPosition = mBackgroundYPosition; + dest->mBackgroundImage = mBackgroundImage; + + dest->mCursor = mCursor; + dest->mCursorImage = mCursorImage; + dest->mOpacity = mOpacity; +} + +PRInt32 StyleColorBlob::CalcDifference(const nsStyleStruct* aOther) const +{ + const nsStyleColor* other = (nsStyleColor*)aOther; + + if ((mColor == other->mColor) && + (mBackgroundAttachment == other->mBackgroundAttachment) && + (mBackgroundFlags == other->mBackgroundFlags) && + (mBackgroundRepeat == other->mBackgroundRepeat) && + (mBackgroundColor == other->mBackgroundColor) && + (mBackgroundXPosition == other->mBackgroundXPosition) && + (mBackgroundYPosition == other->mBackgroundYPosition) && + (mBackgroundImage == other->mBackgroundImage) && + (mCursor == other->mCursor) && + (mCursorImage == other->mCursorImage) && + (mOpacity == other->mOpacity)) { + return NS_STYLE_HINT_NONE; + } + return NS_STYLE_HINT_VISUAL; +} + +PRUint32 StyleColorBlob::ComputeCRC32(PRUint32 aCrc) const +{ + PRUint32 crc = aCrc; +#ifdef COMPUTE_STYLEDATA_CRC + crc = AccumulateCRC(crc,(const char *)&mColor,sizeof(mColor)); + crc = AccumulateCRC(crc,(const char *)&mBackgroundAttachment,sizeof(mBackgroundAttachment)); + crc = AccumulateCRC(crc,(const char *)&mBackgroundFlags,sizeof(mBackgroundFlags)); + crc = AccumulateCRC(crc,(const char *)&mBackgroundRepeat,sizeof(mBackgroundRepeat)); + crc = AccumulateCRC(crc,(const char *)&mBackgroundColor,sizeof(mBackgroundColor)); + crc = AccumulateCRC(crc,(const char *)&mBackgroundXPosition,sizeof(mBackgroundXPosition)); + crc = AccumulateCRC(crc,(const char *)&mBackgroundYPosition,sizeof(mBackgroundYPosition)); + crc = StyleStringCRC(crc,&mBackgroundImage); + crc = AccumulateCRC(crc,(const char *)&mCursor,sizeof(mCursor)); + crc = StyleStringCRC(crc,&mCursorImage); + crc = AccumulateCRC(crc,(const char *)&mOpacity,sizeof(mOpacity)); +#endif + return crc; +} + + +#ifdef XP_MAC +#pragma mark - +#endif + +//------------------------------------------------------------------------------ +// nsStyleMargin +//------------------------------------------------------------------------------ +// +struct StyleMarginBlob: public nsStyleMargin, public StyleBlob { + StyleMarginBlob(void) {} + virtual ~StyleMarginBlob(void) {} + + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleMargin*)this;}; + + void RecalcData(void); + +private: // These are not allowed + StyleMarginBlob(const StyleMarginBlob& aOther); + StyleMarginBlob& operator=(const StyleMarginBlob& aOther); +}; + +void StyleMarginBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { // spacing values not inherited mMargin.Reset(); mHasCachedMargin = PR_FALSE; } -void StyleMarginImpl::SetFrom(const nsStyleMargin& aSource) +void StyleMarginBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStyleMargin*)this, &aSource, sizeof(nsStyleMargin)); + nsCRT::memcpy((nsStyleMargin*)this, aSource, sizeof(nsStyleMargin)); } -void StyleMarginImpl::CopyTo(nsStyleMargin& aDest) const +void StyleMarginBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStyleMargin*)this, sizeof(nsStyleMargin)); + nsCRT::memcpy(aDest, (const nsStyleMargin*)this, sizeof(nsStyleMargin)); } -void StyleMarginImpl::RecalcData(void) +void StyleMarginBlob::RecalcData(void) { if (IsFixedData(mMargin, PR_FALSE)) { nsStyleCoord coord; @@ -435,15 +452,17 @@ void StyleMarginImpl::RecalcData(void) } } -PRInt32 StyleMarginImpl::CalcDifference(const StyleMarginImpl& aOther) const +PRInt32 StyleMarginBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mMargin == aOther.mMargin) { + const nsStyleMargin* other = (nsStyleMargin*)aOther; + + if (mMargin == other->mMargin) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_REFLOW; } -PRUint32 StyleMarginImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleMarginBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; @@ -462,41 +481,46 @@ PRUint32 StyleMarginImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -struct StylePaddingImpl: public nsStylePadding { - StylePaddingImpl(void) - : nsStylePadding() - {} +//------------------------------------------------------------------------------ +// nsStylePadding +//------------------------------------------------------------------------------ +// +struct StylePaddingBlob: public nsStylePadding, public StyleBlob { + StylePaddingBlob(void) {} + virtual ~StylePaddingBlob(void) {} + + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStylePadding*)this;}; - void ResetFrom(const nsStylePadding* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStylePadding& aSource); - void CopyTo(nsStylePadding& aDest) const; void RecalcData(void); - PRInt32 CalcDifference(const StylePaddingImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; private: // These are not allowed - StylePaddingImpl(const StylePaddingImpl& aOther); - StylePaddingImpl& operator=(const StylePaddingImpl& aOther); + StylePaddingBlob(const StylePaddingBlob& aOther); + StylePaddingBlob& operator=(const StylePaddingBlob& aOther); }; -void StylePaddingImpl::ResetFrom(const nsStylePadding* aParent, nsIPresContext* aPresContext) +void StylePaddingBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { // spacing values not inherited mPadding.Reset(); mHasCachedPadding = PR_FALSE; } -void StylePaddingImpl::SetFrom(const nsStylePadding& aSource) +void StylePaddingBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStylePadding*)this, &aSource, sizeof(nsStylePadding)); + nsCRT::memcpy((nsStylePadding*)this, aSource, sizeof(nsStylePadding)); } -void StylePaddingImpl::CopyTo(nsStylePadding& aDest) const +void StylePaddingBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStylePadding*)this, sizeof(nsStylePadding)); + nsCRT::memcpy(aDest, (const nsStylePadding*)this, sizeof(nsStylePadding)); } -void StylePaddingImpl::RecalcData(void) +void StylePaddingBlob::RecalcData(void) { if (IsFixedData(mPadding, PR_FALSE)) { nsStyleCoord coord; @@ -512,15 +536,17 @@ void StylePaddingImpl::RecalcData(void) } } -PRInt32 StylePaddingImpl::CalcDifference(const StylePaddingImpl& aOther) const +PRInt32 StylePaddingBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mPadding == aOther.mPadding) { + const nsStylePadding* other = (nsStylePadding*)aOther; + + if (mPadding == other->mPadding) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_REFLOW; } -PRUint32 StylePaddingImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StylePaddingBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; @@ -539,28 +565,35 @@ PRUint32 StylePaddingImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -struct StyleBorderImpl: public nsStyleBorder { - StyleBorderImpl(void) - : nsStyleBorder(), mWidthsInitialized(PR_FALSE) +//------------------------------------------------------------------------------ +// nsStyleBorder +//------------------------------------------------------------------------------ +// +struct StyleBorderBlob: public nsStyleBorder, public StyleBlob { + StyleBorderBlob(void) + : mWidthsInitialized(PR_FALSE) {} + virtual ~StyleBorderBlob(void) {} + + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleBorder*)this;}; - void ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleBorder& aSource); - void CopyTo(nsStyleBorder& aDest) const; PRBool IsBorderSideVisible(PRUint8 aSide) const; void RecalcData(nscolor color); - PRInt32 CalcDifference(const StyleBorderImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; private: // These are not allowed - StyleBorderImpl(const StyleBorderImpl& aOther); - StyleBorderImpl& operator=(const StyleBorderImpl& aOther); + StyleBorderBlob(const StyleBorderBlob& aOther); + StyleBorderBlob& operator=(const StyleBorderBlob& aOther); // XXX remove with deprecated methods PRBool mWidthsInitialized; }; -void StyleBorderImpl::ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aPresContext) +void StyleBorderBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { // XXX support mBorderWidhts until deprecated methods are removed if (! mWidthsInitialized) { @@ -599,24 +632,24 @@ void StyleBorderImpl::ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aP mHasCachedBorder = PR_FALSE; } -void StyleBorderImpl::SetFrom(const nsStyleBorder& aSource) +void StyleBorderBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStyleBorder*)this, &aSource, sizeof(nsStyleBorder)); + nsCRT::memcpy((nsStyleBorder*)this, aSource, sizeof(nsStyleBorder)); } -void StyleBorderImpl::CopyTo(nsStyleBorder& aDest) const +void StyleBorderBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStyleBorder*)this, sizeof(nsStyleBorder)); + nsCRT::memcpy(aDest, (const nsStyleBorder*)this, sizeof(nsStyleBorder)); } -PRBool StyleBorderImpl::IsBorderSideVisible(PRUint8 aSide) const +PRBool StyleBorderBlob::IsBorderSideVisible(PRUint8 aSide) const { PRUint8 borderStyle = GetBorderStyle(aSide); return ((borderStyle != NS_STYLE_BORDER_STYLE_NONE) && (borderStyle != NS_STYLE_BORDER_STYLE_HIDDEN)); } -void StyleBorderImpl::RecalcData(nscolor aColor) +void StyleBorderBlob::RecalcData(nscolor aColor) { if (((!IsBorderSideVisible(NS_SIDE_LEFT))|| IsFixedUnit(mBorder.GetLeftUnit(), PR_TRUE)) && @@ -671,25 +704,27 @@ void StyleBorderImpl::RecalcData(nscolor aColor) } } -PRInt32 StyleBorderImpl::CalcDifference(const StyleBorderImpl& aOther) const +PRInt32 StyleBorderBlob::CalcDifference(const nsStyleStruct* aOther) const { - if ((mBorder == aOther.mBorder) && - (mFloatEdge == aOther.mFloatEdge)) { + const nsStyleBorder* other = (nsStyleBorder*)aOther; + + if ((mBorder == other->mBorder) && + (mFloatEdge == other->mFloatEdge)) { PRInt32 ix; for (ix = 0; ix < 4; ix++) { - if ((mBorderStyle[ix] != aOther.mBorderStyle[ix]) || - (mBorderColor[ix] != aOther.mBorderColor[ix])) { - if ((mBorderStyle[ix] != aOther.mBorderStyle[ix]) && + if ((mBorderStyle[ix] != other->mBorderStyle[ix]) || + (mBorderColor[ix] != other->mBorderColor[ix])) { + if ((mBorderStyle[ix] != other->mBorderStyle[ix]) && ((NS_STYLE_BORDER_STYLE_NONE == mBorderStyle[ix]) || - (NS_STYLE_BORDER_STYLE_NONE == aOther.mBorderStyle[ix]) || + (NS_STYLE_BORDER_STYLE_NONE == other->mBorderStyle[ix]) || (NS_STYLE_BORDER_STYLE_HIDDEN == mBorderStyle[ix]) || // bug 45754 - (NS_STYLE_BORDER_STYLE_HIDDEN == aOther.mBorderStyle[ix]))) { + (NS_STYLE_BORDER_STYLE_HIDDEN == other->mBorderStyle[ix]))) { return NS_STYLE_HINT_REFLOW; // border on or off } return NS_STYLE_HINT_VISUAL; } } - if (mBorderRadius != aOther.mBorderRadius) { + if (mBorderRadius != other->mBorderRadius) { return NS_STYLE_HINT_VISUAL; } return NS_STYLE_HINT_NONE; @@ -697,7 +732,7 @@ PRInt32 StyleBorderImpl::CalcDifference(const StyleBorderImpl& aOther) const return NS_STYLE_HINT_REFLOW; } -PRUint32 StyleBorderImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleBorderBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; @@ -720,27 +755,34 @@ PRUint32 StyleBorderImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -struct StyleOutlineImpl: public nsStyleOutline { - StyleOutlineImpl(void) - : nsStyleOutline(), mWidthsInitialized(PR_FALSE) +//------------------------------------------------------------------------------ +// nsStyleOutline +//------------------------------------------------------------------------------ +// +struct StyleOutlineBlob: public nsStyleOutline, public StyleBlob { + StyleOutlineBlob(void) + : mWidthsInitialized(PR_FALSE) {} + virtual ~StyleOutlineBlob(void) {} + + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleOutline*)this;}; - void ResetFrom(const nsStyleOutline* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleOutline& aSource); - void CopyTo(nsStyleOutline& aDest) const; void RecalcData(void); - PRInt32 CalcDifference(const StyleOutlineImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; private: // These are not allowed - StyleOutlineImpl(const StyleOutlineImpl& aOther); - StyleOutlineImpl& operator=(const StyleOutlineImpl& aOther); + StyleOutlineBlob(const StyleOutlineBlob& aOther); + StyleOutlineBlob& operator=(const StyleOutlineBlob& aOther); // XXX remove with deprecated methods PRBool mWidthsInitialized; }; -void StyleOutlineImpl::ResetFrom(const nsStyleOutline* aParent, nsIPresContext* aPresContext) +void StyleOutlineBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { // XXX support mBorderWidhts until deprecated methods are removed if (! mWidthsInitialized) { @@ -765,17 +807,17 @@ void StyleOutlineImpl::ResetFrom(const nsStyleOutline* aParent, nsIPresContext* mHasCachedOutline = PR_FALSE; } -void StyleOutlineImpl::SetFrom(const nsStyleOutline& aSource) +void StyleOutlineBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStyleOutline*)this, &aSource, sizeof(nsStyleOutline)); + nsCRT::memcpy((nsStyleOutline*)this, aSource, sizeof(nsStyleOutline)); } -void StyleOutlineImpl::CopyTo(nsStyleOutline& aDest) const +void StyleOutlineBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStyleOutline*)this, sizeof(nsStyleOutline)); + nsCRT::memcpy(aDest, (const nsStyleOutline*)this, sizeof(nsStyleOutline)); } -void StyleOutlineImpl::RecalcData(void) +void StyleOutlineBlob::RecalcData(void) { if ((NS_STYLE_BORDER_STYLE_NONE == GetOutlineStyle()) || IsFixedUnit(mOutlineWidth.GetUnit(), PR_TRUE)) { @@ -792,18 +834,20 @@ void StyleOutlineImpl::RecalcData(void) } } -PRInt32 StyleOutlineImpl::CalcDifference(const StyleOutlineImpl& aOther) const +PRInt32 StyleOutlineBlob::CalcDifference(const nsStyleStruct* aOther) const { - if ((mOutlineWidth != aOther.mOutlineWidth) || - (mOutlineStyle != aOther.mOutlineStyle) || - (mOutlineColor != aOther.mOutlineColor) || - (mOutlineRadius != aOther.mOutlineRadius)) { + const nsStyleOutline* other = (nsStyleOutline*)aOther; + + if ((mOutlineWidth != other->mOutlineWidth) || + (mOutlineStyle != other->mOutlineStyle) || + (mOutlineColor != other->mOutlineColor) || + (mOutlineRadius != other->mOutlineRadius)) { return NS_STYLE_HINT_VISUAL; // XXX: should be VISUAL: see bugs 9809 and 9816 } return NS_STYLE_HINT_NONE; } -PRUint32 StyleOutlineImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleOutlineBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; @@ -823,32 +867,35 @@ PRUint32 StyleOutlineImpl::ComputeCRC32(PRUint32 aCrc) const #ifdef XP_MAC #pragma mark - #endif -// -------------------- -// nsStyleList + +//------------------------------------------------------------------------------ +// nsStyleList +//------------------------------------------------------------------------------ // -nsStyleList::nsStyleList(void) { } -nsStyleList::~nsStyleList(void) { } +struct StyleListBlob: public nsStyleList, public StyleBlob { + StyleListBlob(void) {} + virtual ~StyleListBlob(void) {} -struct StyleListImpl: public nsStyleList { - StyleListImpl(void) { } - - void ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleList& aSource); - void CopyTo(nsStyleList& aDest) const; - PRInt32 CalcDifference(const StyleListImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleList*)this;}; private: // These are not allowed - StyleListImpl(const StyleListImpl& aOther); - StyleListImpl& operator=(const StyleListImpl& aOther); + StyleListBlob(const StyleListBlob& aOther); + StyleListBlob& operator=(const StyleListBlob& aOther); }; -void StyleListImpl::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext) +void StyleListBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { - if (nsnull != aParent) { - mListStyleType = aParent->mListStyleType; - mListStyleImage = aParent->mListStyleImage; - mListStylePosition = aParent->mListStylePosition; + const nsStyleList* parent = (nsStyleList*)aParent; + + if (nsnull != parent) { + mListStyleType = parent->mListStyleType; + mListStyleImage = parent->mListStyleImage; + mListStylePosition = parent->mListStylePosition; } else { mListStyleType = NS_STYLE_LIST_STYLE_BASIC; @@ -857,25 +904,31 @@ void StyleListImpl::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresC } } -void StyleListImpl::SetFrom(const nsStyleList& aSource) +void StyleListBlob::SetFrom(const nsStyleStruct* aSource) { - mListStyleType = aSource.mListStyleType; - mListStylePosition = aSource.mListStylePosition; - mListStyleImage = aSource.mListStyleImage; + const nsStyleList* source = (nsStyleList*)aSource; + + mListStyleType = source->mListStyleType; + mListStylePosition = source->mListStylePosition; + mListStyleImage = source->mListStyleImage; } -void StyleListImpl::CopyTo(nsStyleList& aDest) const +void StyleListBlob::CopyTo(nsStyleStruct* aDest) const { - aDest.mListStyleType = mListStyleType; - aDest.mListStylePosition = mListStylePosition; - aDest.mListStyleImage = mListStyleImage; + nsStyleList* dest = (nsStyleList*)aDest; + + dest->mListStyleType = mListStyleType; + dest->mListStylePosition = mListStylePosition; + dest->mListStyleImage = mListStyleImage; } -PRInt32 StyleListImpl::CalcDifference(const StyleListImpl& aOther) const +PRInt32 StyleListBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mListStylePosition == aOther.mListStylePosition) { - if (mListStyleImage == aOther.mListStyleImage) { - if (mListStyleType == aOther.mListStyleType) { + const nsStyleList* other = (nsStyleList*)aOther; + + if (mListStylePosition == other->mListStylePosition) { + if (mListStyleImage == other->mListStyleImage) { + if (mListStyleType == other->mListStyleType) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_REFLOW; @@ -885,7 +938,7 @@ PRInt32 StyleListImpl::CalcDifference(const StyleListImpl& aOther) const return NS_STYLE_HINT_REFLOW; } -PRUint32 StyleListImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleListBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -900,27 +953,27 @@ PRUint32 StyleListImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -// -------------------- -// nsStylePosition +//------------------------------------------------------------------------------ +// nsStylePosition +//------------------------------------------------------------------------------ // -nsStylePosition::nsStylePosition(void) { } -nsStylePosition::~nsStylePosition(void) { } +struct StylePositionBlob: public nsStylePosition, public StyleBlob { + StylePositionBlob(void) {} + virtual ~StylePositionBlob(void) {} -struct StylePositionImpl: public nsStylePosition { - StylePositionImpl(void) { } - - void ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStylePosition& aSource); - void CopyTo(nsStylePosition& aDest) const; - PRInt32 CalcDifference(const StylePositionImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStylePosition*)this;}; private: // These are not allowed - StylePositionImpl(const StylePositionImpl& aOther); - StylePositionImpl& operator=(const StylePositionImpl& aOther); + StylePositionBlob(const StylePositionBlob& aOther); + StylePositionBlob& operator=(const StylePositionBlob& aOther); }; -void StylePositionImpl::ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext) +void StylePositionBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { // positioning values not inherited mPosition = NS_STYLE_POSITION_NORMAL; @@ -939,28 +992,30 @@ void StylePositionImpl::ResetFrom(const nsStylePosition* aParent, nsIPresContext mZIndex.SetAutoValue(); } -void StylePositionImpl::SetFrom(const nsStylePosition& aSource) +void StylePositionBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStylePosition*)this, &aSource, sizeof(nsStylePosition)); + nsCRT::memcpy((nsStylePosition*)this, aSource, sizeof(nsStylePosition)); } -void StylePositionImpl::CopyTo(nsStylePosition& aDest) const +void StylePositionBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStylePosition*)this, sizeof(nsStylePosition)); + nsCRT::memcpy(aDest, (const nsStylePosition*)this, sizeof(nsStylePosition)); } -PRInt32 StylePositionImpl::CalcDifference(const StylePositionImpl& aOther) const +PRInt32 StylePositionBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mPosition == aOther.mPosition) { - if ((mOffset == aOther.mOffset) && - (mWidth == aOther.mWidth) && - (mMinWidth == aOther.mMinWidth) && - (mMaxWidth == aOther.mMaxWidth) && - (mHeight == aOther.mHeight) && - (mMinHeight == aOther.mMinHeight) && - (mMaxHeight == aOther.mMaxHeight) && - (mBoxSizing == aOther.mBoxSizing) && - (mZIndex == aOther.mZIndex)) { + const nsStylePosition* other = (nsStylePosition*)aOther; + + if (mPosition == other->mPosition) { + if ((mOffset == other->mOffset) && + (mWidth == other->mWidth) && + (mMinWidth == other->mMinWidth) && + (mMaxWidth == other->mMaxWidth) && + (mHeight == other->mHeight) && + (mMinHeight == other->mMinHeight) && + (mMaxHeight == other->mMaxHeight) && + (mBoxSizing == other->mBoxSizing) && + (mZIndex == other->mZIndex)) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_REFLOW; @@ -968,7 +1023,7 @@ PRInt32 StylePositionImpl::CalcDifference(const StylePositionImpl& aOther) const return NS_STYLE_HINT_FRAMECHANGE; } -PRUint32 StylePositionImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StylePositionBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -990,53 +1045,54 @@ PRUint32 StylePositionImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -// -------------------- -// nsStyleText +//------------------------------------------------------------------------------ +// nsStyleText +//------------------------------------------------------------------------------ // +struct StyleTextBlob: public nsStyleText, public StyleBlob { + StyleTextBlob(void) {} + virtual ~StyleTextBlob(void) {} -nsStyleText::nsStyleText(void) { } -nsStyleText::~nsStyleText(void) { } - -struct StyleTextImpl: public nsStyleText { - StyleTextImpl(void) { } - - void ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleText& aSource); - void CopyTo(nsStyleText& aDest) const; - PRInt32 CalcDifference(const StyleTextImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleText*)this;}; private: // These are not allowed - StyleTextImpl(const StyleTextImpl& aOther); - StyleTextImpl& operator=(const StyleTextImpl& aOther); + StyleTextBlob(const StyleTextBlob& aOther); + StyleTextBlob& operator=(const StyleTextBlob& aOther); }; -void StyleTextImpl::ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext) +void StyleTextBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { + const nsStyleText* parent = (nsStyleText*)aParent; + // These properties not inherited mTextDecoration = NS_STYLE_TEXT_DECORATION_NONE; mVerticalAlign.SetIntValue(NS_STYLE_VERTICAL_ALIGN_BASELINE, eStyleUnit_Enumerated); // mVerticalAlign.Reset(); TBI - if (nsnull != aParent) { - mTextAlign = aParent->mTextAlign; - mTextTransform = aParent->mTextTransform; - mWhiteSpace = aParent->mWhiteSpace; - mLetterSpacing = aParent->mLetterSpacing; + if (nsnull != parent) { + mTextAlign = parent->mTextAlign; + mTextTransform = parent->mTextTransform; + mWhiteSpace = parent->mWhiteSpace; + mLetterSpacing = parent->mLetterSpacing; // Inherit everything except percentage line-height values - nsStyleUnit unit = aParent->mLineHeight.GetUnit(); + nsStyleUnit unit = parent->mLineHeight.GetUnit(); if ((eStyleUnit_Normal == unit) || (eStyleUnit_Factor == unit) || (eStyleUnit_Coord == unit)) { - mLineHeight = aParent->mLineHeight; + mLineHeight = parent->mLineHeight; } else { mLineHeight.SetInheritValue(); } - mTextIndent = aParent->mTextIndent; - mWordSpacing = aParent->mWordSpacing; + mTextIndent = parent->mTextIndent; + mWordSpacing = parent->mWordSpacing; #ifdef IBMBIDI - mUnicodeBidi = aParent->mUnicodeBidi; + mUnicodeBidi = parent->mUnicodeBidi; #endif // IBMBIDI } else { @@ -1054,30 +1110,32 @@ void StyleTextImpl::ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresC } } -void StyleTextImpl::SetFrom(const nsStyleText& aSource) +void StyleTextBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStyleText*)this, &aSource, sizeof(nsStyleText)); + nsCRT::memcpy((nsStyleText*)this, aSource, sizeof(nsStyleText)); } -void StyleTextImpl::CopyTo(nsStyleText& aDest) const +void StyleTextBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStyleText*)this, sizeof(nsStyleText)); + nsCRT::memcpy(aDest, (const nsStyleText*)this, sizeof(nsStyleText)); } -PRInt32 StyleTextImpl::CalcDifference(const StyleTextImpl& aOther) const +PRInt32 StyleTextBlob::CalcDifference(const nsStyleStruct* aOther) const { - if ((mTextAlign == aOther.mTextAlign) && - (mTextTransform == aOther.mTextTransform) && - (mWhiteSpace == aOther.mWhiteSpace) && - (mLetterSpacing == aOther.mLetterSpacing) && - (mLineHeight == aOther.mLineHeight) && - (mTextIndent == aOther.mTextIndent) && - (mWordSpacing == aOther.mWordSpacing) && + const nsStyleText* other = (nsStyleText*)aOther; + + if ((mTextAlign == other->mTextAlign) && + (mTextTransform == other->mTextTransform) && + (mWhiteSpace == other->mWhiteSpace) && + (mLetterSpacing == other->mLetterSpacing) && + (mLineHeight == other->mLineHeight) && + (mTextIndent == other->mTextIndent) && + (mWordSpacing == other->mWordSpacing) && #ifdef IBMBIDI - (mUnicodeBidi == aOther.mUnicodeBidi) && + (mUnicodeBidi == other.mUnicodeBidi) && #endif // IBMBIDI - (mVerticalAlign == aOther.mVerticalAlign)) { - if (mTextDecoration == aOther.mTextDecoration) { + (mVerticalAlign == other->mVerticalAlign)) { + if (mTextDecoration == other->mTextDecoration) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_VISUAL; @@ -1085,7 +1143,7 @@ PRInt32 StyleTextImpl::CalcDifference(const StyleTextImpl& aOther) const return NS_STYLE_HINT_REFLOW; } -PRUint32 StyleTextImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleTextBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; @@ -1110,39 +1168,45 @@ PRUint32 StyleTextImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -// -------------------- -// nsStyleDisplay +//------------------------------------------------------------------------------ +// nsStyleDisplay +//------------------------------------------------------------------------------ // +struct StyleDisplayBlob: public nsStyleDisplay, public StyleBlob { + StyleDisplayBlob(void) {} + virtual ~StyleDisplayBlob(void) {} -struct StyleDisplayImpl: public nsStyleDisplay { - StyleDisplayImpl(void) { } - - void ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleDisplay& aSource); - void CopyTo(nsStyleDisplay& aDest) const; - PRInt32 CalcDifference(const StyleDisplayImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleDisplay*)this;}; private: // These are not allowed - StyleDisplayImpl(const StyleDisplayImpl& aOther); - StyleDisplayImpl& operator=(const StyleDisplayImpl& aOther); + StyleDisplayBlob(const StyleDisplayBlob& aOther); + StyleDisplayBlob& operator=(const StyleDisplayBlob& aOther); }; -void StyleDisplayImpl::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext) +void StyleDisplayBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { - if (nsnull != aParent) { - mDirection = aParent->mDirection; - mLanguage = aParent->mLanguage; - mVisible = aParent->mVisible; + const nsStyleDisplay* parent = (nsStyleDisplay*)aParent; + + if (nsnull != parent) { + mDirection = parent->mDirection; + mLanguage = parent->mLanguage; + mVisible = parent->mVisible; } else { #ifdef IBMBIDI PRUint32 mBidioptions; aPresContext->GetBidi(&mBidioptions); - if (GET_BIDI_OPTION_DIRECTION(mBidioptions) == IBMBIDI_TEXTDIRECTION_RTL) + if (GET_BIDI_OPTION_DIRECTION(mBidioptions) == IBMBIDI_TEXTDIRECTION_RTL) { mDirection = NS_STYLE_DIRECTION_RTL; - else + } + else { mDirection = NS_STYLE_DIRECTION_LTR; + } #else // ifdef IBMBIDI aPresContext->GetDefaultDirection(&mDirection); #endif // IBMBIDI @@ -1162,60 +1226,66 @@ void StyleDisplayImpl::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* #endif // IBMBIDI } -void StyleDisplayImpl::SetFrom(const nsStyleDisplay& aSource) +void StyleDisplayBlob::SetFrom(const nsStyleStruct* aSource) { - mDirection = aSource.mDirection; + const nsStyleDisplay* source = (nsStyleDisplay*)aSource; + + mDirection = source->mDirection; #ifdef IBMBIDI - mExplicitDirection = aSource.mExplicitDirection; + mExplicitDirection = source->mExplicitDirection; #endif // IBMBIDI - mDisplay = aSource.mDisplay; - mFloats = aSource.mFloats; - mBreakType = aSource.mBreakType; - mBreakBefore = aSource.mBreakBefore; - mBreakAfter = aSource.mBreakAfter; - mVisible = aSource.mVisible; - mOverflow = aSource.mOverflow; - mClipFlags = aSource.mClipFlags; - mClip = aSource.mClip; - mLanguage = aSource.mLanguage; + mDisplay = source->mDisplay; + mFloats = source->mFloats; + mBreakType = source->mBreakType; + mBreakBefore = source->mBreakBefore; + mBreakAfter = source->mBreakAfter; + mVisible = source->mVisible; + mOverflow = source->mOverflow; + mClipFlags = source->mClipFlags; + mClip = source->mClip; + mLanguage = source->mLanguage; } -void StyleDisplayImpl::CopyTo(nsStyleDisplay& aDest) const +void StyleDisplayBlob::CopyTo(nsStyleStruct* aDest) const { - aDest.mDirection = mDirection; + nsStyleDisplay* dest = (nsStyleDisplay*)aDest; + + dest->mDirection = mDirection; #ifdef IBMBIDI - aDest.mExplicitDirection = mExplicitDirection; + dest->mExplicitDirection = mExplicitDirection; #endif // IBMBIDI - aDest.mDisplay = mDisplay; - aDest.mFloats = mFloats; - aDest.mBreakType = mBreakType; - aDest.mBreakBefore = mBreakBefore; - aDest.mBreakAfter = mBreakAfter; - aDest.mVisible = mVisible; - aDest.mOverflow = mOverflow; - aDest.mClipFlags = mClipFlags; - aDest.mClip = mClip; - aDest.mLanguage = mLanguage; + dest->mDisplay = mDisplay; + dest->mFloats = mFloats; + dest->mBreakType = mBreakType; + dest->mBreakBefore = mBreakBefore; + dest->mBreakAfter = mBreakAfter; + dest->mVisible = mVisible; + dest->mOverflow = mOverflow; + dest->mClipFlags = mClipFlags; + dest->mClip = mClip; + dest->mLanguage = mLanguage; } -PRInt32 StyleDisplayImpl::CalcDifference(const StyleDisplayImpl& aOther) const +PRInt32 StyleDisplayBlob::CalcDifference(const nsStyleStruct* aOther) const { - if ((mDisplay == aOther.mDisplay) && - (mFloats == aOther.mFloats) && - (mOverflow == aOther.mOverflow)) { - if ((mDirection == aOther.mDirection) && - (mLanguage == aOther.mLanguage) && - (mBreakType == aOther.mBreakType) && - (mBreakBefore == aOther.mBreakBefore) && - (mBreakAfter == aOther.mBreakAfter)) { - if ((mVisible == aOther.mVisible) && - (mClipFlags == aOther.mClipFlags) && - (mClip == aOther.mClip)) { + const nsStyleDisplay* other = (nsStyleDisplay*)aOther; + + if ((mDisplay == other->mDisplay) && + (mFloats == other->mFloats) && + (mOverflow == other->mOverflow)) { + if ((mDirection == other->mDirection) && + (mLanguage == other->mLanguage) && + (mBreakType == other->mBreakType) && + (mBreakBefore == other->mBreakBefore) && + (mBreakAfter == other->mBreakAfter)) { + if ((mVisible == other->mVisible) && + (mClipFlags == other->mClipFlags) && + (mClip == other->mClip)) { return NS_STYLE_HINT_NONE; } - if ((mVisible != aOther.mVisible) && + if ((mVisible != other->mVisible) && ((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) || - (NS_STYLE_VISIBILITY_COLLAPSE == aOther.mVisible))) { + (NS_STYLE_VISIBILITY_COLLAPSE == other->mVisible))) { return NS_STYLE_HINT_REFLOW; } return NS_STYLE_HINT_VISUAL; @@ -1225,7 +1295,7 @@ PRInt32 StyleDisplayImpl::CalcDifference(const StyleDisplayImpl& aOther) const return NS_STYLE_HINT_FRAMECHANGE; } -PRUint32 StyleDisplayImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleDisplayBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -1250,34 +1320,35 @@ PRUint32 StyleDisplayImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -// -------------------- -// nsStyleTable +//------------------------------------------------------------------------------ +// nsStyleTable +//------------------------------------------------------------------------------ // +struct StyleTableBlob: public nsStyleTable, public StyleBlob { + StyleTableBlob(void); + virtual ~StyleTableBlob(void) {}; -nsStyleTable::nsStyleTable(void) { } -nsStyleTable::~nsStyleTable(void) { } - -struct StyleTableImpl: public nsStyleTable { - StyleTableImpl(void); - - void ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleTable& aSource); - void CopyTo(nsStyleTable& aDest) const; - PRInt32 CalcDifference(const StyleTableImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleTable*)this;}; private: // These are not allowed - StyleTableImpl(const StyleTableImpl& aOther); - StyleTableImpl& operator=(const StyleTableImpl& aOther); + StyleTableBlob(const StyleTableBlob& aOther); + StyleTableBlob& operator=(const StyleTableBlob& aOther); }; -StyleTableImpl::StyleTableImpl() +StyleTableBlob::StyleTableBlob() { ResetFrom(nsnull, nsnull); } -void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext) +void StyleTableBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { + const nsStyleTable* parent = (nsStyleTable*)aParent; + // values not inherited mLayoutStrategy = NS_STYLE_TABLE_LAYOUT_AUTO; mCols = NS_STYLE_TABLE_COLS_NONE; @@ -1286,13 +1357,13 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre mCellPadding.Reset(); mSpan = 1; - if (aParent) { // handle inherited properties - mBorderCollapse = aParent->mBorderCollapse; - mEmptyCells = aParent->mEmptyCells; - mCaptionSide = aParent->mCaptionSide; - mBorderSpacingX = aParent->mBorderSpacingX; - mBorderSpacingY = aParent->mBorderSpacingY; - mSpanWidth = aParent->mSpanWidth; + if (parent) { // handle inherited properties + mBorderCollapse = parent->mBorderCollapse; + mEmptyCells = parent->mEmptyCells; + mCaptionSide = parent->mCaptionSide; + mBorderSpacingX = parent->mBorderSpacingX; + mBorderSpacingY = parent->mBorderSpacingY; + mSpanWidth = parent->mSpanWidth; } else { mBorderCollapse = NS_STYLE_BORDER_SEPARATE; @@ -1312,30 +1383,32 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre } } -void StyleTableImpl::SetFrom(const nsStyleTable& aSource) +void StyleTableBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStyleTable*)this, &aSource, sizeof(nsStyleTable)); + nsCRT::memcpy((nsStyleTable*)this, aSource, sizeof(nsStyleTable)); } -void StyleTableImpl::CopyTo(nsStyleTable& aDest) const +void StyleTableBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStyleTable*)this, sizeof(nsStyleTable)); + nsCRT::memcpy(aDest, (const nsStyleTable*)this, sizeof(nsStyleTable)); } -PRInt32 StyleTableImpl::CalcDifference(const StyleTableImpl& aOther) const +PRInt32 StyleTableBlob::CalcDifference(const nsStyleStruct* aOther) const { - if ((mLayoutStrategy == aOther.mLayoutStrategy) && - (mFrame == aOther.mFrame) && - (mRules == aOther.mRules) && - (mBorderCollapse == aOther.mBorderCollapse) && - (mBorderSpacingX == aOther.mBorderSpacingX) && - (mBorderSpacingY == aOther.mBorderSpacingY) && - (mCellPadding == aOther.mCellPadding) && - (mCaptionSide == aOther.mCaptionSide) && - (mCols == aOther.mCols) && - (mSpan == aOther.mSpan) && - (mSpanWidth == aOther.mSpanWidth)) { - if (mEmptyCells == aOther.mEmptyCells) { + const nsStyleTable* other = (nsStyleTable*)aOther; + + if ((mLayoutStrategy == other->mLayoutStrategy) && + (mFrame == other->mFrame) && + (mRules == other->mRules) && + (mBorderCollapse == other->mBorderCollapse) && + (mBorderSpacingX == other->mBorderSpacingX) && + (mBorderSpacingY == other->mBorderSpacingY) && + (mCellPadding == other->mCellPadding) && + (mCaptionSide == other->mCaptionSide) && + (mCols == other->mCols) && + (mSpan == other->mSpan) && + (mSpanWidth == other->mSpanWidth)) { + if (mEmptyCells == other->mEmptyCells) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_VISUAL; @@ -1343,7 +1416,7 @@ PRInt32 StyleTableImpl::CalcDifference(const StyleTableImpl& aOther) const return NS_STYLE_HINT_REFLOW; } -PRUint32 StyleTableImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleTableBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -1367,49 +1440,31 @@ PRUint32 StyleTableImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -//----------------------- -// nsStyleContent +//------------------------------------------------------------------------------ +// nsStyleContent +//------------------------------------------------------------------------------ // +struct StyleContentBlob: public nsStyleContent, public StyleBlob { + StyleContentBlob(void) {}; + virtual ~StyleContentBlob(void) {}; -nsStyleContent::nsStyleContent(void) - : mMarkerOffset(), - mContentCount(0), - mContents(nsnull), - mIncrementCount(0), - mIncrements(nsnull), - mResetCount(0), - mResets(nsnull), - mQuotesCount(0), - mQuotes(nsnull) -{ -} - -nsStyleContent::~nsStyleContent(void) -{ - DELETE_ARRAY_IF(mContents); - DELETE_ARRAY_IF(mIncrements); - DELETE_ARRAY_IF(mResets); - DELETE_ARRAY_IF(mQuotes); -} - - -struct StyleContentImpl: public nsStyleContent { - StyleContentImpl(void) : nsStyleContent() { }; - - void ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleContent& aSource); - void CopyTo(nsStyleContent& aDest) const; - PRInt32 CalcDifference(const StyleContentImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleContent*)this;}; private: // These are not allowed - StyleContentImpl(const StyleContentImpl& aOther); - StyleContentImpl& operator=(const StyleContentImpl& aOther); + StyleContentBlob(const StyleContentBlob& aOther); + StyleContentBlob& operator=(const StyleContentBlob& aOther); }; void -StyleContentImpl::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext) +StyleContentBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { + const nsStyleContent* parent = (nsStyleContent*)aParent; + // reset data mMarkerOffset.Reset(); mContentCount = 0; @@ -1420,11 +1475,11 @@ StyleContentImpl::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPr DELETE_ARRAY_IF(mResets); // inherited data - if (aParent) { - if (NS_SUCCEEDED(AllocateQuotes(aParent->mQuotesCount))) { + if (parent) { + if (NS_SUCCEEDED(AllocateQuotes(parent->mQuotesCount))) { PRUint32 ix = (mQuotesCount * 2); while (0 < ix--) { - mQuotes[ix] = aParent->mQuotes[ix]; + mQuotes[ix] = parent->mQuotes[ix]; } } } @@ -1434,105 +1489,111 @@ StyleContentImpl::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPr } } -void StyleContentImpl::SetFrom(const nsStyleContent& aSource) +void StyleContentBlob::SetFrom(const nsStyleStruct* aSource) { - mMarkerOffset = aSource.mMarkerOffset; + const nsStyleContent* source = (nsStyleContent*)aSource; + + mMarkerOffset = source->mMarkerOffset; PRUint32 index; - if (NS_SUCCEEDED(AllocateContents(aSource.ContentCount()))) { + if (NS_SUCCEEDED(AllocateContents(source->ContentCount()))) { for (index = 0; index < mContentCount; index++) { - aSource.GetContentAt(index, mContents[index].mType, mContents[index].mContent); + source->GetContentAt(index, mContents[index].mType, mContents[index].mContent); } } - if (NS_SUCCEEDED(AllocateCounterIncrements(aSource.CounterIncrementCount()))) { + if (NS_SUCCEEDED(AllocateCounterIncrements(source->CounterIncrementCount()))) { for (index = 0; index < mIncrementCount; index++) { - aSource.GetCounterIncrementAt(index, mIncrements[index].mCounter, + source->GetCounterIncrementAt(index, mIncrements[index].mCounter, mIncrements[index].mValue); } } - if (NS_SUCCEEDED(AllocateCounterResets(aSource.CounterResetCount()))) { + if (NS_SUCCEEDED(AllocateCounterResets(source->CounterResetCount()))) { for (index = 0; index < mResetCount; index++) { - aSource.GetCounterResetAt(index, mResets[index].mCounter, + source->GetCounterResetAt(index, mResets[index].mCounter, mResets[index].mValue); } } - if (NS_SUCCEEDED(AllocateQuotes(aSource.QuotesCount()))) { + if (NS_SUCCEEDED(AllocateQuotes(source->QuotesCount()))) { PRUint32 count = (mQuotesCount * 2); for (index = 0; index < count; index += 2) { - aSource.GetQuotesAt(index, mQuotes[index], mQuotes[index + 1]); + source->GetQuotesAt(index, mQuotes[index], mQuotes[index + 1]); } } } -void StyleContentImpl::CopyTo(nsStyleContent& aDest) const +void StyleContentBlob::CopyTo(nsStyleStruct* aDest) const { - aDest.mMarkerOffset = mMarkerOffset; + nsStyleContent* dest = (nsStyleContent*)aDest; + + dest->mMarkerOffset = mMarkerOffset; PRUint32 index; - if (NS_SUCCEEDED(aDest.AllocateContents(mContentCount))) { + if (NS_SUCCEEDED(dest->AllocateContents(mContentCount))) { for (index = 0; index < mContentCount; index++) { - aDest.SetContentAt(index, mContents[index].mType, + dest->SetContentAt(index, mContents[index].mType, mContents[index].mContent); } } - if (NS_SUCCEEDED(aDest.AllocateCounterIncrements(mIncrementCount))) { + if (NS_SUCCEEDED(dest->AllocateCounterIncrements(mIncrementCount))) { for (index = 0; index < mIncrementCount; index++) { - aDest.SetCounterIncrementAt(index, mIncrements[index].mCounter, + dest->SetCounterIncrementAt(index, mIncrements[index].mCounter, mIncrements[index].mValue); } } - if (NS_SUCCEEDED(aDest.AllocateCounterResets(mResetCount))) { + if (NS_SUCCEEDED(dest->AllocateCounterResets(mResetCount))) { for (index = 0; index < mResetCount; index++) { - aDest.SetCounterResetAt(index, mResets[index].mCounter, + dest->SetCounterResetAt(index, mResets[index].mCounter, mResets[index].mValue); } } - if (NS_SUCCEEDED(aDest.AllocateQuotes(mQuotesCount))) { + if (NS_SUCCEEDED(dest->AllocateQuotes(mQuotesCount))) { PRUint32 count = (mQuotesCount * 2); for (index = 0; index < count; index += 2) { - aDest.SetQuotesAt(index, mQuotes[index], mQuotes[index + 1]); + dest->SetQuotesAt(index, mQuotes[index], mQuotes[index + 1]); } } } PRInt32 -StyleContentImpl::CalcDifference(const StyleContentImpl& aOther) const +StyleContentBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mContentCount == aOther.mContentCount) { - if ((mMarkerOffset == aOther.mMarkerOffset) && - (mIncrementCount == aOther.mIncrementCount) && - (mResetCount == aOther.mResetCount) && - (mQuotesCount == aOther.mQuotesCount)) { + const nsStyleContent* other = (nsStyleContent*)aOther; + + if (mContentCount == other->mContentCount) { + if ((mMarkerOffset == other->mMarkerOffset) && + (mIncrementCount == other->mIncrementCount) && + (mResetCount == other->mResetCount) && + (mQuotesCount == other->mQuotesCount)) { PRUint32 ix = mContentCount; while (0 < ix--) { - if ((mContents[ix].mType != aOther.mContents[ix].mType) || - (mContents[ix].mContent != aOther.mContents[ix].mContent)) { + if ((mContents[ix].mType != other->mContents[ix].mType) || + (mContents[ix].mContent != other->mContents[ix].mContent)) { return NS_STYLE_HINT_REFLOW; } } ix = mIncrementCount; while (0 < ix--) { - if ((mIncrements[ix].mValue != aOther.mIncrements[ix].mValue) || - (mIncrements[ix].mCounter != aOther.mIncrements[ix].mCounter)) { + if ((mIncrements[ix].mValue != other->mIncrements[ix].mValue) || + (mIncrements[ix].mCounter != other->mIncrements[ix].mCounter)) { return NS_STYLE_HINT_REFLOW; } } ix = mResetCount; while (0 < ix--) { - if ((mResets[ix].mValue != aOther.mResets[ix].mValue) || - (mResets[ix].mCounter != aOther.mResets[ix].mCounter)) { + if ((mResets[ix].mValue != other->mResets[ix].mValue) || + (mResets[ix].mCounter != other->mResets[ix].mCounter)) { return NS_STYLE_HINT_REFLOW; } } ix = (mQuotesCount * 2); while (0 < ix--) { - if (mQuotes[ix] != aOther.mQuotes[ix]) { + if (mQuotes[ix] != other->mQuotes[ix]) { return NS_STYLE_HINT_REFLOW; } } @@ -1543,7 +1604,7 @@ StyleContentImpl::CalcDifference(const StyleContentImpl& aOther) const return NS_STYLE_HINT_FRAMECHANGE; } -PRUint32 StyleContentImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleContentBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -1573,33 +1634,34 @@ PRUint32 StyleContentImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -//----------------------- -// nsStyleUserInterface +//------------------------------------------------------------------------------ +// nsStyleUserInterface +//------------------------------------------------------------------------------ // +struct StyleUserInterfaceBlob: public nsStyleUserInterface, public StyleBlob { + StyleUserInterfaceBlob(void) {} + virtual ~StyleUserInterfaceBlob(void) {} -nsStyleUserInterface::nsStyleUserInterface(void) { } -nsStyleUserInterface::~nsStyleUserInterface(void) { } - -struct StyleUserInterfaceImpl: public nsStyleUserInterface { - StyleUserInterfaceImpl(void) { } - - void ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleUserInterface& aSource); - void CopyTo(nsStyleUserInterface& aDest) const; - PRInt32 CalcDifference(const StyleUserInterfaceImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleUserInterface*)this;}; private: // These are not allowed - StyleUserInterfaceImpl(const StyleUserInterfaceImpl& aOther); - StyleUserInterfaceImpl& operator=(const StyleUserInterfaceImpl& aOther); + StyleUserInterfaceBlob(const StyleUserInterfaceBlob& aOther); + StyleUserInterfaceBlob& operator=(const StyleUserInterfaceBlob& aOther); }; -void StyleUserInterfaceImpl::ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext) +void StyleUserInterfaceBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { - if (aParent) { - mUserInput = aParent->mUserInput; - mUserModify = aParent->mUserModify; - mUserFocus = aParent->mUserFocus; + const nsStyleUserInterface* parent = (nsStyleUserInterface*)aParent; + + if (parent) { + mUserInput = parent->mUserInput; + mUserModify = parent->mUserModify; + mUserFocus = parent->mUserFocus; } else { mUserInput = NS_STYLE_USER_INPUT_AUTO; @@ -1613,57 +1675,63 @@ void StyleUserInterfaceImpl::ResetFrom(const nsStyleUserInterface* aParent, nsIP mBehavior.SetLength(0); } -void StyleUserInterfaceImpl::SetFrom(const nsStyleUserInterface& aSource) +void StyleUserInterfaceBlob::SetFrom(const nsStyleStruct* aSource) { - mUserInput = aSource.mUserInput; - mUserModify = aSource.mUserModify; - mUserFocus = aSource.mUserFocus; + const nsStyleUserInterface* source = (nsStyleUserInterface*)aSource; - mUserSelect = aSource.mUserSelect; - mKeyEquivalent = aSource.mKeyEquivalent; - mResizer = aSource.mResizer; - mBehavior = aSource.mBehavior; + mUserInput = source->mUserInput; + mUserModify = source->mUserModify; + mUserFocus = source->mUserFocus; + + mUserSelect = source->mUserSelect; + mKeyEquivalent = source->mKeyEquivalent; + mResizer = source->mResizer; + mBehavior = source->mBehavior; } -void StyleUserInterfaceImpl::CopyTo(nsStyleUserInterface& aDest) const +void StyleUserInterfaceBlob::CopyTo(nsStyleStruct* aDest) const { - aDest.mUserInput = mUserInput; - aDest.mUserModify = mUserModify; - aDest.mUserFocus = mUserFocus; + nsStyleUserInterface* dest = (nsStyleUserInterface*)aDest; - aDest.mUserSelect = mUserSelect; - aDest.mKeyEquivalent = mKeyEquivalent; - aDest.mResizer = mResizer; - aDest.mBehavior = mBehavior; + dest->mUserInput = mUserInput; + dest->mUserModify = mUserModify; + dest->mUserFocus = mUserFocus; + + dest->mUserSelect = mUserSelect; + dest->mKeyEquivalent = mKeyEquivalent; + dest->mResizer = mResizer; + dest->mBehavior = mBehavior; } -PRInt32 StyleUserInterfaceImpl::CalcDifference(const StyleUserInterfaceImpl& aOther) const +PRInt32 StyleUserInterfaceBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mBehavior != aOther.mBehavior) + const nsStyleUserInterface* other = (nsStyleUserInterface*)aOther; + + if (mBehavior != other->mBehavior) return NS_STYLE_HINT_FRAMECHANGE; - if ((mUserInput == aOther.mUserInput) && - (mResizer == aOther.mResizer)) { - if ((mUserModify == aOther.mUserModify) && - (mUserSelect == aOther.mUserSelect)) { - if ((mKeyEquivalent == aOther.mKeyEquivalent) && - (mUserFocus == aOther.mUserFocus) && - (mResizer == aOther.mResizer)) { + if ((mUserInput == other->mUserInput) && + (mResizer == other->mResizer)) { + if ((mUserModify == other->mUserModify) && + (mUserSelect == other->mUserSelect)) { + if ((mKeyEquivalent == other->mKeyEquivalent) && + (mUserFocus == other->mUserFocus) && + (mResizer == other->mResizer)) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_CONTENT; } return NS_STYLE_HINT_VISUAL; } - if ((mUserInput != aOther.mUserInput) && + if ((mUserInput != other->mUserInput) && ((NS_STYLE_USER_INPUT_NONE == mUserInput) || - (NS_STYLE_USER_INPUT_NONE == aOther.mUserInput))) { + (NS_STYLE_USER_INPUT_NONE == other->mUserInput))) { return NS_STYLE_HINT_FRAMECHANGE; } return NS_STYLE_HINT_VISUAL; } -PRUint32 StyleUserInterfaceImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleUserInterfaceBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -1684,38 +1752,39 @@ PRUint32 StyleUserInterfaceImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -//----------------------- -// nsStylePrint +//------------------------------------------------------------------------------ +// nsStylePrint +//------------------------------------------------------------------------------ // +struct StylePrintBlob: public nsStylePrint, public StyleBlob { + StylePrintBlob(void) {} + virtual ~StylePrintBlob(void) {} -nsStylePrint::nsStylePrint(void) { } -nsStylePrint::~nsStylePrint(void) { } - -struct StylePrintImpl: public nsStylePrint { - StylePrintImpl(void) { } - - void ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStylePrint& aSource); - void CopyTo(nsStylePrint& aDest) const; - PRInt32 CalcDifference(const StylePrintImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStylePrint*)this;}; private: // These are not allowed - StylePrintImpl(const StylePrintImpl& aOther); - StylePrintImpl& operator=(const StylePrintImpl& aOther); + StylePrintBlob(const StylePrintBlob& aOther); + StylePrintBlob& operator=(const StylePrintBlob& aOther); }; -void StylePrintImpl::ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext) +void StylePrintBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { - if (aParent) { - mPageBreakBefore = aParent->mPageBreakBefore; - mPageBreakAfter = aParent->mPageBreakAfter; - mPageBreakInside = aParent->mPageBreakInside; - mWidows = aParent->mWidows; - mOrphans = aParent->mOrphans; - mMarks = aParent->mMarks; - mSizeWidth = aParent->mSizeWidth; - mSizeHeight = aParent->mSizeHeight; + const nsStylePrint* parent = (nsStylePrint*)aParent; + + if (parent) { + mPageBreakBefore = parent->mPageBreakBefore; + mPageBreakAfter = parent->mPageBreakAfter; + mPageBreakInside = parent->mPageBreakInside; + mWidows = parent->mWidows; + mOrphans = parent->mOrphans; + mMarks = parent->mMarks; + mSizeWidth = parent->mSizeWidth; + mSizeHeight = parent->mSizeHeight; } else { mPageBreakBefore = NS_STYLE_PAGE_BREAK_AUTO; @@ -1729,36 +1798,58 @@ void StylePrintImpl::ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPre } } -void StylePrintImpl::SetFrom(const nsStylePrint& aSource) +void StylePrintBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStylePrint*)this, &aSource, sizeof(nsStylePrint)); + const nsStylePrint* source = (nsStylePrint*)aSource; + + mPageBreakBefore = source->mPageBreakBefore; + mPageBreakAfter = source->mPageBreakAfter; + mPageBreakInside = source->mPageBreakInside; + mPage = source->mPage; + mWidows = source->mWidows; + mOrphans = source->mOrphans; + mMarks = source->mMarks; + mSizeWidth = source->mSizeWidth; + mSizeHeight = source->mSizeHeight; } -void StylePrintImpl::CopyTo(nsStylePrint& aDest) const +void StylePrintBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStylePrint*)this, sizeof(nsStylePrint)); + nsStylePrint* dest = (nsStylePrint*)aDest; + + dest->mPageBreakBefore = mPageBreakBefore; + dest->mPageBreakAfter = mPageBreakAfter; + dest->mPageBreakInside = mPageBreakInside; + dest->mPage = mPage; + dest->mWidows = mWidows; + dest->mOrphans = mOrphans; + dest->mMarks = mMarks; + dest->mSizeWidth = mSizeWidth; + dest->mSizeHeight = mSizeHeight; } -PRInt32 StylePrintImpl::CalcDifference(const StylePrintImpl& aOther) const +PRInt32 StylePrintBlob::CalcDifference(const nsStyleStruct* aOther) const { - if ((mPageBreakBefore == aOther.mPageBreakBefore) - && (mPageBreakAfter == aOther.mPageBreakAfter) - && (mPageBreakInside == aOther.mPageBreakInside) - && (mWidows == aOther.mWidows) - && (mOrphans == aOther.mOrphans) - && (mMarks == aOther.mMarks) - && (mSizeWidth == aOther.mSizeWidth) - && (mSizeHeight == aOther.mSizeHeight)) { + const nsStylePrint* other = (nsStylePrint*)aOther; + + if ((mPageBreakBefore == other->mPageBreakBefore) + && (mPageBreakAfter == other->mPageBreakAfter) + && (mPageBreakInside == other->mPageBreakInside) + && (mWidows == other->mWidows) + && (mOrphans == other->mOrphans) + && (mMarks == other->mMarks) + && (mSizeWidth == other->mSizeWidth) + && (mSizeHeight == other->mSizeHeight)) { return NS_STYLE_HINT_NONE; } - if (mMarks != aOther.mMarks) { + if (mMarks != other->mMarks) { return NS_STYLE_HINT_VISUAL; } return NS_STYLE_HINT_REFLOW; } -PRUint32 StylePrintImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StylePrintBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -1781,49 +1872,55 @@ PRUint32 StylePrintImpl::ComputeCRC32(PRUint32 aCrc) const #endif #ifdef INCLUDE_XUL -// -------------------- -// nsStyleXUL +//------------------------------------------------------------------------------ +// nsStyleXUL +//------------------------------------------------------------------------------ // -nsStyleXUL::nsStyleXUL() { } -nsStyleXUL::~nsStyleXUL() { } +struct StyleXULBlob: public nsStyleXUL, public StyleBlob { + StyleXULBlob() {} + virtual ~StyleXULBlob() {} -struct StyleXULImpl: public nsStyleXUL { - StyleXULImpl() { } - - void ResetFrom(const nsStyleXUL* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleXUL& aSource); - void CopyTo(nsStyleXUL& aDest) const; - PRInt32 CalcDifference(const StyleXULImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleXUL*)this;}; private: // These are not allowed - StyleXULImpl(const StyleXULImpl& aOther); - StyleXULImpl& operator=(const StyleXULImpl& aOther); + StyleXULBlob(const StyleXULBlob& aOther); + StyleXULBlob& operator=(const StyleXULBlob& aOther); }; -void StyleXULImpl::ResetFrom(const nsStyleXUL* aParent, nsIPresContext* aPresContext) +void StyleXULBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { mBoxOrient = NS_STYLE_BOX_ORIENT_HORIZONTAL; } -void StyleXULImpl::SetFrom(const nsStyleXUL& aSource) +void StyleXULBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStyleXUL*)this, &aSource, sizeof(nsStyleXUL)); + const nsStyleXUL* source = (nsStyleXUL*)aSource; + + mBoxOrient = source->mBoxOrient; } -void StyleXULImpl::CopyTo(nsStyleXUL& aDest) const +void StyleXULBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStyleXUL*)this, sizeof(nsStyleXUL)); + nsStyleXUL* dest = (nsStyleXUL*)aDest; + + dest->mBoxOrient = mBoxOrient; } -PRInt32 StyleXULImpl::CalcDifference(const StyleXULImpl& aOther) const +PRInt32 StyleXULBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mBoxOrient == aOther.mBoxOrient) + const nsStyleXUL* other = (nsStyleXUL*)aOther; + + if (mBoxOrient == other->mBoxOrient) return NS_STYLE_HINT_NONE; return NS_STYLE_HINT_REFLOW; } -PRUint32 StyleXULImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleXULBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -1831,246 +1928,86 @@ PRUint32 StyleXULImpl::ComputeCRC32(PRUint32 aCrc) const #endif return crc; } +#endif // INCLUDE_XUL #ifdef XP_MAC #pragma mark - #endif -#endif // INCLUDE_XUL -//---------------------------------------------------------------------- +//------------------------------------------------------------------------------ +// nsStyleContextData +//------------------------------------------------------------------------------ +// -#ifdef SHARE_STYLECONTEXTS +// --------------------- +// Macros for getting style data (StyleXXXBlob and nsStyleXXX) +// +#define STYLEDATA(type) nsStyle##type +#define STYLEBLOB(type) Style##type##Blob +#define BLOBARRAY mStyleData->mBlobArray +#define GETDATA(type) ((const nsStyle##type##*)FetchInheritedStyleStruct(eStyleStruct_##type)) +#define GETBLOB(type) ((STYLEBLOB(##type##)*)FetchInheritedStyleBlob(eStyleStruct_##type)) -//======================== -#ifdef DEBUG -// define this to get stats on the use of the |nsStyleStruct|s inside a |nsStyleContextData|. //XXX pierre + // Use the macro below with extreme caution. The only place where + // we want, and where we *can*, access the data pointers directly + // for modification (ie. non-const pointers) is in RemapStyle() + // because we are then garanteed to have the blobs in place. + // Everywhere else, the pointers can be null. + // + // On a related note... We never want to cast the pointer returned + // by FetchInheritedStyleStruct() to a non-const pointer because it + // would modify the parent's style (or the grand-parent's style) + // but not the current context's style. +#define GETMUTABLEDATAPTR(type) ((nsStyle##type##*)BLOBARRAY[eStyleStruct_##type - 1]->GetData()) + + // Same warning as above, except that it returns a const pointer. + // It's just a faster alternative to GETDATA() for use inside + // RemapStyle() only. +#define GETDATAPTR(type) ((const nsStyle##type##*)BLOBARRAY[eStyleStruct_##type - 1]->GetData()) + + +// --------------------- +// Debug definitions +// +#ifdef DEBUG //xxx pierre + // Define this to get stats on the use of the + // nsStyleStructs inside a nsStyleContextData. //#define LOG_STYLE_STRUCTS -#endif + + // Define this to get statistics on the number of calls + // to GetStyleData() and their depth in the Style tree. +//#define LOG_GET_STYLE_DATA_CALLS + + // Define this to get statistics on the number of calls + // to WriteMutableStyleData(). +//#define LOG_WRITE_STYLE_DATA_CALLS + #ifdef LOG_STYLE_STRUCTS -// StyleFontImpl mFont; -struct StyleFontImplLog: public StyleFontImpl { - StyleFontImplLog(const nsFont& aVariableFont, const nsFont& aFixedFont) - : StyleFontImpl(aVariableFont, aFixedFont), - mInternalFont(aVariableFont, aFixedFont) - {} - void ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext); - StyleFontImpl mInternalFont; - bool mSetFromParent; -}; +class StyleFontImplLog; +class StyleColorImplLog; +class StyleListImplLog; +class StylePositionImplLog; +class StyleTextImplLog; +class StyleDisplayImplLog; +class StyleTableImplLog; +class StyleContentImplLog; +class StyleUserInterfaceImplLog; +class StylePrintImplLog; +class StyleMarginImplLog; +class StylePaddingImplLog; +class StyleBorderImplLog; +class StyleOutlineImplLog; +#undef STYLEBLOB(data) +#define STYLEBLOB(data) Style##data##ImplLog +#endif //LOG_STYLE_STRUCTS -void StyleFontImplLog::ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext) -{ - StyleFontImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalFont); - mSetFromParent = (aParent != nsnull); -} +#endif //DEBUG -// StyleColorImpl mColor; -struct StyleColorImplLog: public StyleColorImpl { - void ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext); - StyleColorImpl mInternalColor; - bool mSetFromParent; -}; - -void StyleColorImplLog::ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext) -{ - StyleColorImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalColor); - mSetFromParent = (aParent != nsnull); -} - -// StyleListImpl mList; -struct StyleListImplLog: public StyleListImpl { - void ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext); - StyleListImpl mInternalList; - bool mSetFromParent; -}; - -void StyleListImplLog::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext) -{ - StyleListImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalList); - mSetFromParent = (aParent != nsnull); -} - -// StylePositionImpl mPosition; -struct StylePositionImplLog: public StylePositionImpl { - void ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext); - StylePositionImpl mInternalPosition; - bool mSetFromParent; -}; - -void StylePositionImplLog::ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext) -{ - StylePositionImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalPosition); - mSetFromParent = (aParent != nsnull); -} - -// StyleTextImpl mText; -struct StyleTextImplLog: public StyleTextImpl { - void ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext); - StyleTextImpl mInternalText; - bool mSetFromParent; -}; - -void StyleTextImplLog::ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext) -{ - StyleTextImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalText); - mSetFromParent = (aParent != nsnull); -} - -// StyleDisplayImpl mDisplay; -struct StyleDisplayImplLog: public StyleDisplayImpl { - void ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext); - StyleDisplayImpl mInternalDisplay; - bool mSetFromParent; -}; - -void StyleDisplayImplLog::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext) -{ - StyleDisplayImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalDisplay); - mSetFromParent = (aParent != nsnull); -} - -// StyleTableImpl mTable; -struct StyleTableImplLog: public StyleTableImpl { - void ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext); - StyleTableImpl mInternalTable; - bool mSetFromParent; -}; - -void StyleTableImplLog::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext) -{ - StyleTableImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalTable); - mSetFromParent = (aParent != nsnull); -} - -// StyleContentImpl mContent; -struct StyleContentImplLog: public StyleContentImpl { - void ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext); - StyleContentImpl mInternalContent; - bool mSetFromParent; -}; - -void StyleContentImplLog::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext) -{ - StyleContentImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalContent); - mSetFromParent = (aParent != nsnull); -} - -// StyleUserInterfaceImpl mUserInterface; -struct StyleUserInterfaceImplLog: public StyleUserInterfaceImpl { - void ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext); - StyleUserInterfaceImpl mInternalUserInterface; - bool mSetFromParent; -}; - -void StyleUserInterfaceImplLog::ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext) -{ - StyleUserInterfaceImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalUserInterface); - mSetFromParent = (aParent != nsnull); -} - -// StylePrintImpl mPrint; -struct StylePrintImplLog: public StylePrintImpl { - void ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext); - StylePrintImpl mInternalPrint; - bool mSetFromParent; -}; - -void StylePrintImplLog::ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext) -{ - StylePrintImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalPrint); - mSetFromParent = (aParent != nsnull); -} - -// StyleMarginImpl mMargin; -struct StyleMarginImplLog: public StyleMarginImpl { - void ResetFrom(const nsStyleMargin* aParent, nsIPresContext* aPresContext); - StyleMarginImpl mInternalMargin; - bool mSetFromParent; -}; - -void StyleMarginImplLog::ResetFrom(const nsStyleMargin* aParent, nsIPresContext* aPresContext) -{ - StyleMarginImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalMargin); - mSetFromParent = (aParent != nsnull); -} - -// StylePaddingImpl mPadding; -struct StylePaddingImplLog: public StylePaddingImpl { - void ResetFrom(const nsStylePadding* aParent, nsIPresContext* aPresContext); - StylePaddingImpl mInternalPadding; - bool mSetFromParent; -}; - -void StylePaddingImplLog::ResetFrom(const nsStylePadding* aParent, nsIPresContext* aPresContext) -{ - StylePaddingImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalPadding); - mSetFromParent = (aParent != nsnull); -} - -// StyleBorderImpl mBorder; -struct StyleBorderImplLog: public StyleBorderImpl { - void ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aPresContext); - StyleBorderImpl mInternalBorder; - bool mSetFromParent; -}; - -void StyleBorderImplLog::ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aPresContext) -{ - StyleBorderImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalBorder); - mSetFromParent = (aParent != nsnull); -} - -// StyleOutlineImpl mOutline; -struct StyleOutlineImplLog: public StyleOutlineImpl { - void ResetFrom(const nsStyleOutline* aParent, nsIPresContext* aPresContext); - StyleOutlineImpl mInternalOutline; - bool mSetFromParent; -}; - -void StyleOutlineImplLog::ResetFrom(const nsStyleOutline* aParent, nsIPresContext* aPresContext) -{ - StyleOutlineImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalOutline); - mSetFromParent = (aParent != nsnull); -} - -#ifdef INCLUDE_XUL -// StyleXULImpl mXUL; -struct StyleXULImplLog: public StyleXULImpl { - void ResetFrom(const nsStyleXUL* aParent, nsIPresContext* aPresContext); - StyleXULImpl mInternalXUL; - bool mSetFromParent; -}; - -void StyleXULImplLog::ResetFrom(const nsStyleXUL* aParent, nsIPresContext* aPresContext) -{ - StyleXULImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalXUL); - mSetFromParent = (aParent != nsnull); -} -#endif // INCLUDE_XUL - -#ifdef XP_MAC -#pragma mark - -#endif - -#endif // LOG_STYLE_STRUCTS -//======================== +// --------------------- +// nsStyleContextData +// class nsStyleContextData { public: @@ -2079,91 +2016,96 @@ public: void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); +private: // all data and methods private: only friends have access + #ifdef LOG_STYLE_STRUCTS public: -#else -private: // all data and methods private: only friends have access +#endif +#ifdef LOG_WRITE_STYLE_DATA_CALLS +public: #endif - static nsStyleContextData *Create(nsIPresContext *aPresContext); - - nsStyleContextData(nsIPresContext *aPresContext); +#ifdef SHARE_STYLECONTEXTS + static nsStyleContextData *Create(nsIStyleContext* aStyleContext, nsIPresContext *aPresContext); +#endif + static StyleBlob* AllocateOneBlob(nsStyleStructID aSID, nsIPresContext *aPresContext); + nsresult AllocateStyleBlobs(nsIStyleContext* aStyleContext, nsIPresContext *aPresContext); + void DeleteStyleBlobs(); + + nsStyleContextData(); ~nsStyleContextData(void); - PRUint32 ComputeCRC32(PRUint32 aCrc) const; - void SetCRC32(void) { - mCRC = ComputeCRC32(0); - if (mCRC==STYLEDATA_NO_CRC) - mCRC = STYLEDATA_DEFAULT_CRC; - } - PRUint32 GetCRC32(void) const { return mCRC; } - - PRUint32 AddRef(void); - PRUint32 Release(void); - // the style data... // - StyleContextImpl gets friend-access // -#ifdef LOG_STYLE_STRUCTS - StyleFontImplLog mFont; - StyleColorImplLog mColor; - StyleListImplLog mList; - StylePositionImplLog mPosition; - StyleTextImplLog mText; - StyleDisplayImplLog mDisplay; - StyleTableImplLog mTable; - StyleContentImplLog mContent; - StyleUserInterfaceImplLog mUserInterface; - StylePrintImplLog mPrint; - StyleMarginImplLog mMargin; - StylePaddingImplLog mPadding; - StyleBorderImplLog mBorder; - StyleOutlineImplLog mOutline; + union { + StyleBlob* mBlobArray[eStyleStruct_Max]; + struct { + STYLEBLOB(Font)* mFont; + STYLEBLOB(Color)* mColor; + STYLEBLOB(List)* mList; + STYLEBLOB(Position)* mPosition; + STYLEBLOB(Text)* mText; + STYLEBLOB(Display)* mDisplay; + STYLEBLOB(Table)* mTable; + STYLEBLOB(Content)* mContent; + STYLEBLOB(UserInterface)* mUserInterface; + STYLEBLOB(Print)* mPrint; + STYLEBLOB(Margin)* mMargin; + STYLEBLOB(Padding)* mPadding; + STYLEBLOB(Border)* mBorder; + STYLEBLOB(Outline)* mOutline; #ifdef INCLUDE_XUL - StyleXULImplLog mXUL; -#endif -#else - StyleFontImpl mFont; - StyleColorImpl mColor; - StyleListImpl mList; - StylePositionImpl mPosition; - StyleTextImpl mText; - StyleDisplayImpl mDisplay; - StyleTableImpl mTable; - StyleContentImpl mContent; - StyleUserInterfaceImpl mUserInterface; - StylePrintImpl mPrint; - StyleMarginImpl mMargin; - StylePaddingImpl mPadding; - StyleBorderImpl mBorder; - StyleOutlineImpl mOutline; -#ifdef INCLUDE_XUL - StyleXULImpl mXUL; -#endif + STYLEBLOB(XUL)* mXUL; #endif + //#insert new style structs here# + } mData; + }; - PRUint32 mRefCnt; - PRUint32 mCRC; - +#ifdef SHARE_STYLECONTEXTS + PRUint32 mRefCnt; + inline PRUint32 AddRef(void); + inline PRUint32 Release(void); #ifdef DEBUG - static PRUint32 gInstanceCount; + static PRUint32 gInstanceCount; +#endif +#ifdef COMPUTE_STYLEDATA_CRC + PRUint32 mCRC; + PRUint32 ComputeCRC32(PRUint32 aCrc) const; + PRUint32 GetCRC32(void) const { return mCRC; } + void SetCRC32(void) { + mCRC = ComputeCRC32(0); + if (mCRC==STYLEDATA_NO_CRC) { + mCRC = STYLEDATA_DEFAULT_CRC; + } + } +#endif // COMPUTE_STYLEDATA_CRC +#endif // SHARE_STYLECONTEXTS + +#ifdef LOG_STYLE_STRUCTS + PRBool mGotMutable[eStyleStruct_Max]; #endif }; -#ifndef DEBUG -inline +#ifdef DEBUG //xxx pierre +#include "nsStyleContextDebug.h" #endif -PRUint32 nsStyleContextData::AddRef(void) + +#ifdef SHARE_STYLECONTEXTS +// --------------------- +// AddRef +// +inline PRUint32 nsStyleContextData::AddRef(void) { ++mRefCnt; NS_LOG_ADDREF(this,mRefCnt,"nsStyleContextData",sizeof(*this)); return mRefCnt; } -#ifndef DEBUG -inline -#endif -PRUint32 nsStyleContextData::Release(void) +// --------------------- +// Release +// +inline PRUint32 nsStyleContextData::Release(void) { NS_ASSERTION(mRefCnt > 0, "RefCount error in nsStyleContextData"); --mRefCnt; @@ -2182,305 +2124,207 @@ PRUint32 nsStyleContextData::Release(void) /*static*/ PRUint32 nsStyleContextData::gInstanceCount; #endif // DEBUG -nsStyleContextData *nsStyleContextData::Create(nsIPresContext *aPresContext) +// --------------------- +// Create +// +nsStyleContextData *nsStyleContextData::Create(nsIStyleContext* aStyleContext, nsIPresContext *aPresContext) { NS_ASSERTION(aPresContext != nsnull, "parameter cannot be null"); nsStyleContextData *pData = nsnull; if (aPresContext) { - pData = new nsStyleContextData(aPresContext); + pData = new nsStyleContextData(); if (pData) { - NS_ADDREF(pData); + if (NS_SUCCEEDED(pData->AllocateStyleBlobs(aStyleContext, aPresContext))) { +#ifdef SHARE_STYLECONTEXTS + NS_ADDREF(pData); #ifdef NOISY_DEBUG - printf("new nsStyleContextData instance: (%ld) CRC=%lu\n", + printf("new nsStyleContextData instance: (%ld) CRC=%lu\n", (long)(++gInstanceCount), (unsigned long)pData->ComputeCRC32(0)); #endif // NOISY_DEBUG +#endif // SHARE_STYLECONTEXTS + } + else { + delete pData; + pData = nsnull; + } } } return pData; } +#endif //SHARE_STYLECONTEXTS -nsStyleContextData::nsStyleContextData(nsIPresContext *aPresContext) -: mFont(aPresContext->GetDefaultFontDeprecated(), - aPresContext->GetDefaultFixedFontDeprecated()), - mRefCnt(0), mCRC(0) + +// --------------------- +// nsStyleContextData ctor +// +nsStyleContextData::nsStyleContextData() { -} - -//========================================================================================================= - -#ifdef LOG_STYLE_STRUCTS //XXX pierre - -#ifdef XP_MAC -#include -static bool MacKeyDown(unsigned char theKey) -{ - KeyMap map; - GetKeys(map); - return ((*((unsigned char *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0; -} +#ifdef SHARE_STYLECONTEXTS + mRefCnt = 0; +#ifdef COMPUTE_STYLEDATA_CRC + mCRC = 0; +#endif #endif - -static bool IsTimeToDumpStyleStructs() -{ - bool timeToDump = false; -#ifdef XP_MAC - static unsigned long lastTicks = 0; - if (MacKeyDown(0x3b)) { // control key - if ((unsigned long)(::TickCount() - lastTicks) > 60) { - lastTicks = ::TickCount(); - timeToDump = true; - } - } + for (short i = 0; i < eStyleStruct_Max; i ++) { + mBlobArray[i] = nsnull; +#ifdef LOG_STYLE_STRUCTS + mGotMutable[i] = PR_FALSE; #endif - return timeToDump; + } } -static void LogStyleStructs(nsStyleContextData* aStyleContextData) + +// --------------------- +// AllocateOneBlob +// +StyleBlob* nsStyleContextData::AllocateOneBlob(nsStyleStructID aSID, nsIPresContext *aPresContext) { -#define max_structs eStyleStruct_Max - - static unsigned long totalCount = 0; - static unsigned long defaultStruct[max_structs]; - static unsigned long setFromParent[max_structs]; - - static bool resetCounters = true; - - if (IsTimeToDumpStyleStructs()) { - resetCounters = true; - printf("\n\n\n"); - printf("-------------------------------------------------------------------------------------------------------------\n"); - printf("Count of nsStyleContextData: %ld\n", totalCount); - printf("-------------------------------------------------------------------------------------------------------------\n"); - printf(" unchanged unchanged%c set-from-parent%c size-of-struct potential-gain-Kb\n", '%', '%'); - unsigned long totalFootprint = 0; - unsigned long totalPotentialGain = 0; - for (short i = 0; i < max_structs; i ++) { - short index = i+1; - short sizeOfStruct = 0; - unsigned long footprint = 0; - unsigned long potentialGain = 0; - switch (index) { - case eStyleStruct_Font: printf("eStyleStruct_Font "); sizeOfStruct = sizeof(StyleFontImpl); break; - case eStyleStruct_Color: printf("eStyleStruct_Color "); sizeOfStruct = sizeof(StyleColorImpl); break; - case eStyleStruct_List: printf("eStyleStruct_List "); sizeOfStruct = sizeof(StyleListImpl); break; - case eStyleStruct_Position: printf("eStyleStruct_Position "); sizeOfStruct = sizeof(StylePositionImpl); break; - case eStyleStruct_Text: printf("eStyleStruct_Text "); sizeOfStruct = sizeof(StyleTextImpl); break; - case eStyleStruct_Display: printf("eStyleStruct_Display "); sizeOfStruct = sizeof(StyleDisplayImpl); break; - case eStyleStruct_Table: printf("eStyleStruct_Table "); sizeOfStruct = sizeof(StyleTableImpl); break; - case eStyleStruct_Content: printf("eStyleStruct_Content "); sizeOfStruct = sizeof(StyleContentImpl); break; - case eStyleStruct_UserInterface: printf("eStyleStruct_UserInterface "); sizeOfStruct = sizeof(StyleUserInterfaceImpl); break; - case eStyleStruct_Print: printf("eStyleStruct_Print "); sizeOfStruct = sizeof(StylePrintImpl); break; - case eStyleStruct_Margin: printf("eStyleStruct_Margin "); sizeOfStruct = sizeof(StyleMarginImpl); break; - case eStyleStruct_Padding: printf("eStyleStruct_Padding "); sizeOfStruct = sizeof(StylePaddingImpl); break; - case eStyleStruct_Border: printf("eStyleStruct_Border "); sizeOfStruct = sizeof(StyleBorderImpl); break; - case eStyleStruct_Outline: printf("eStyleStruct_Outline "); sizeOfStruct = sizeof(StyleOutlineImpl); break; -#ifdef INCLUDE_XUL - case eStyleStruct_XUL: printf("eStyleStruct_XUL "); sizeOfStruct = sizeof(StyleXULImpl); break; -#endif + StyleBlob* result = nsnull; + switch (aSID) { + case eStyleStruct_Font: + if (aPresContext) { + result = new STYLEBLOB(Font)(aPresContext->GetDefaultFontDeprecated(), aPresContext->GetDefaultFixedFontDeprecated()); } - short percentDefault = (totalCount == 0 ? 0 : ((100 * defaultStruct[i]) / totalCount)); - short percentFromParent = (defaultStruct[i] == 0 ? 0 : ((100 * setFromParent[i]) / defaultStruct[i])); - - footprint = totalCount * sizeOfStruct; - totalFootprint += footprint; - - potentialGain = defaultStruct[i] * sizeOfStruct; - totalPotentialGain += potentialGain; - - printf(" %7ld %3d %3d %5d %5d\n", defaultStruct[i], percentDefault, percentFromParent, sizeOfStruct, potentialGain / 1024); - } - printf("-------------------------------------------------------------------------------------------------------------\n"); - printf("Current footprint: %4ld Kb\n", totalFootprint / 1024); - printf("Potential gain: %4ld Kb (or %d%c)\n", totalPotentialGain / 1024, totalPotentialGain*100/totalFootprint, '%'); - printf("Would remain: %4ld Kb\n", (totalFootprint - totalPotentialGain) / 1024); - printf("-------------------------------------------------------------------------------------------------------------\n"); - printf("These stats come from the nsStyleContextData structures that have been deleted since the last output.\n"); - printf("To get the stats for a particular page: load page, dump stats, load 'about:blank', dump stats again.\n"); - printf("-------------------------------------------------------------------------------------------------------------\n"); - printf("\n\n\n"); - } - - if (resetCounters) { - resetCounters = false; - totalCount = 0; - for (short i = 0; i < max_structs; i ++) { - defaultStruct[i] = 0L; - setFromParent[i] = 0L; - } - } - - if (!aStyleContextData) { - printf ("*** aStyleContextData is nil\n"); - return; - } - - totalCount++; - for (short i = 0; i < max_structs; i ++) { - short index = i+1; - switch (index) { - case eStyleStruct_Font: - if (aStyleContextData->mFont.CalcDifference(aStyleContextData->mFont.mInternalFont) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mFont.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Color: - if (aStyleContextData->mColor.CalcDifference(aStyleContextData->mColor.mInternalColor) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mColor.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_List: - if (aStyleContextData->mList.CalcDifference(aStyleContextData->mList.mInternalList) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mList.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Position: - if (aStyleContextData->mPosition.CalcDifference(aStyleContextData->mPosition.mInternalPosition) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mPosition.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Text: - if (aStyleContextData->mText.CalcDifference(aStyleContextData->mText.mInternalText) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mText.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Display: - if (aStyleContextData->mDisplay.CalcDifference(aStyleContextData->mDisplay.mInternalDisplay) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mDisplay.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Table: - if (aStyleContextData->mTable.CalcDifference(aStyleContextData->mTable.mInternalTable) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mTable.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Content: - if (aStyleContextData->mContent.CalcDifference(aStyleContextData->mContent.mInternalContent) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mContent.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_UserInterface: - if (aStyleContextData->mUserInterface.CalcDifference(aStyleContextData->mUserInterface.mInternalUserInterface) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mUserInterface.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Print: - if (aStyleContextData->mPrint.CalcDifference(aStyleContextData->mPrint.mInternalPrint) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mPrint.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Margin: - if (aStyleContextData->mMargin.CalcDifference(aStyleContextData->mMargin.mInternalMargin) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mMargin.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Padding: - if (aStyleContextData->mPadding.CalcDifference(aStyleContextData->mPadding.mInternalPadding) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mPadding.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Border: - if (aStyleContextData->mBorder.CalcDifference(aStyleContextData->mBorder.mInternalBorder) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mBorder.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Outline: - if (aStyleContextData->mOutline.CalcDifference(aStyleContextData->mOutline.mInternalOutline) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mOutline.mSetFromParent) - setFromParent[i]++; - } - break; + else { + result = new STYLEBLOB(Font); + } + break; + case eStyleStruct_Color: result = new STYLEBLOB(Color); break; + case eStyleStruct_List: result = new STYLEBLOB(List); break; + case eStyleStruct_Position: result = new STYLEBLOB(Position); break; + case eStyleStruct_Text: result = new STYLEBLOB(Text); break; + case eStyleStruct_Display: result = new STYLEBLOB(Display); break; + case eStyleStruct_Table: result = new STYLEBLOB(Table); break; + case eStyleStruct_Content: result = new STYLEBLOB(Content); break; + case eStyleStruct_UserInterface: result = new STYLEBLOB(UserInterface); break; + case eStyleStruct_Print: result = new STYLEBLOB(Print); break; + case eStyleStruct_Margin: result = new STYLEBLOB(Margin); break; + case eStyleStruct_Padding: result = new STYLEBLOB(Padding); break; + case eStyleStruct_Border: result = new STYLEBLOB(Border); break; + case eStyleStruct_Outline: result = new STYLEBLOB(Outline); break; #ifdef INCLUDE_XUL - case eStyleStruct_XUL: - if (aStyleContextData->mXUL.CalcDifference(aStyleContextData->mXUL.mInternalXUL) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mXUL.mSetFromParent) - setFromParent[i]++; - } - break; + case eStyleStruct_XUL: result = new STYLEBLOB(XUL); break; #endif + //#insert new style structs here# + default: + NS_ERROR("Invalid style struct id"); + break; + } + NS_ASSERTION(result != nsnull, "Out of mem"); + return result; +} + +// --------------------- +// CanShareStyleData +// Sharing of style data for the GfxScrollFrame is problematic +// and is currently disabled. These pseudos indicate the use of a GfxScrollFrame +// so we check for them and disallow sharing when any are found. +// If you haven't guessed it, this is a total hack until we can figure out +// why the GfxScrollFrame is not happy having its style data shared... +// (See bugzilla bug 39618 which also documents this problem) +// +static PRBool CanShareStyleData(nsIStyleContext* aStyleContext) +{ + PRBool isSharingSupported = PR_TRUE; + + nsIAtom* pseudoTag; + aStyleContext->GetPseudoType(pseudoTag); + if (pseudoTag) { + if (pseudoTag == nsLayoutAtoms::viewportPseudo || + pseudoTag == nsLayoutAtoms::canvasPseudo || + pseudoTag == nsLayoutAtoms::viewportScrollPseudo || + pseudoTag == nsLayoutAtoms::scrolledContentPseudo || + pseudoTag == nsLayoutAtoms::selectScrolledContentPseudo) { + isSharingSupported = PR_FALSE; + } else { + isSharingSupported = PR_TRUE; + } + } + NS_IF_RELEASE(pseudoTag); + + return isSharingSupported; +} + + +// --------------------- +// AllocateStyleBlobs +// +nsresult nsStyleContextData::AllocateStyleBlobs(nsIStyleContext* aStyleContext, nsIPresContext *aPresContext) +{ + short i; + + // clear the pointers: we'll inherit from the parent (if we have a parent) + for (i = 0; i < eStyleStruct_Max; i ++) { + mBlobArray[i] = nsnull; + } + + if (CanShareStyleData(aStyleContext)) { + nsIStyleContext* parent = aStyleContext->GetParent(); + if (parent != nsnull) { + NS_RELEASE(parent); + return NS_OK; } } - static short inCount = 0; - static short outCount = 0; - if (inCount++ % 1000 == 0) { - switch (outCount++) { - case 0: printf("still logging"); break; - case 20: printf("\n"); outCount = 0; break; - default: printf("."); fflush(stdout); break; + // no parent: allocate the blobs + for (i = 0; i < eStyleStruct_Max; i ++) { + nsStyleStructID structID = (nsStyleStructID)(i + 1); + mBlobArray[i] = AllocateOneBlob(structID, aPresContext); + if (!mBlobArray[i]) { + return NS_ERROR_OUT_OF_MEMORY; } } + return NS_OK; +} + +// --------------------- +// DeleteStyleBlobs +// +#define NS_IF_DELETE(ptr) \ + if (nsnull != ptr) { delete ptr; ptr = nsnull; } + +void nsStyleContextData::DeleteStyleBlobs() { + for (short i = 0; i < eStyleStruct_Max; i ++) { + NS_IF_DELETE(mBlobArray[i]); + } } -#endif // LOG_STYLE_STRUCTS - -//========================================================================================================= +// --------------------- +// nsStyleContextData dtor +// nsStyleContextData::~nsStyleContextData(void) { +#ifdef SHARE_STYLECONTEXTS NS_ASSERTION(0 == mRefCnt, "RefCount error in ~nsStyleContextData"); +#endif // debug here... #ifdef LOG_STYLE_STRUCTS LogStyleStructs(this); #endif + DeleteStyleBlobs(); } +// --------------------- +// ComputeCRC32 +// +#ifdef COMPUTE_STYLEDATA_CRC PRUint32 nsStyleContextData::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; -#ifdef COMPUTE_STYLEDATA_CRC - // have each style struct compute its own CRC, propogating the previous value... - crc = mFont.ComputeCRC32(crc); - crc = mColor.ComputeCRC32(crc); - crc = mList.ComputeCRC32(crc); - crc = mPosition.ComputeCRC32(crc); - crc = mText.ComputeCRC32(crc); - crc = mDisplay.ComputeCRC32(crc); - crc = mTable.ComputeCRC32(crc); - crc = mContent.ComputeCRC32(crc); - crc = mUserInterface.ComputeCRC32(crc); - crc = mPrint.ComputeCRC32(crc); - crc = mMargin.ComputeCRC32(crc); - crc = mPadding.ComputeCRC32(crc); - crc = mBorder.ComputeCRC32(crc); - crc = mOutline.ComputeCRC32(crc); -#ifdef INCLUDE_XUL - crc = mXUL.ComputeCRC32(crc); -#endif -#else - crc = 0; -#endif - + // have each style blob compute its own CRC, propagating the previous value... + for (short i = 0; i < eStyleStruct_Max; i ++) { + if (mBlobArray[i]) { + crc = mBlobArray[i]->ComputeCRC32(crc); + } + } return crc; } +#endif +// --------------------- +// SizeOf +// void nsStyleContextData::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) { NS_ASSERTION(aSizeOfHandler, "SizeOfHandler cannot be null in SizeOf"); @@ -2497,13 +2341,34 @@ void nsStyleContextData::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSiz tag = getter_AddRefs(NS_NewAtom("StyleContextData")); // get the size of an empty instance and add to the sizeof handler aSize = sizeof(*this); + // add the sizes of the individual style blobs + if (mData.mFont) aSize += sizeof(StyleFontBlob); + if (mData.mColor) aSize += sizeof(StyleColorBlob); + if (mData.mList) aSize += sizeof(StyleListBlob); + if (mData.mPosition) aSize += sizeof(StylePositionBlob); + if (mData.mText) aSize += sizeof(StyleTextBlob); + if (mData.mDisplay) aSize += sizeof(StyleDisplayBlob); + if (mData.mTable) aSize += sizeof(StyleTableBlob); + if (mData.mContent) aSize += sizeof(StyleContentBlob); + if (mData.mUserInterface) aSize += sizeof(StyleUserInterfaceBlob); + if (mData.mPrint) aSize += sizeof(StylePrintBlob); + if (mData.mMargin) aSize += sizeof(StyleMarginBlob); + if (mData.mPadding) aSize += sizeof(StylePaddingBlob); + if (mData.mBorder) aSize += sizeof(StyleBorderBlob); + if (mData.mOutline) aSize += sizeof(StyleOutlineBlob); +#ifdef INCLUDE_XUL + if (mData.mXUL) aSize += sizeof(StyleXULBlob); +#endif + //#insert new style structs here# + aSizeOfHandler->AddSize(tag,aSize); } -#endif //#ifdef SHARE_STYLECONTEXTS - -//---------------------------------------------------------------------- +//------------------------------------------------------------------------------ +// StyleContextImpl +//------------------------------------------------------------------------------ +// class StyleContextImpl : public nsIStyleContext, protected nsIMutableStyleContext { // you can't QI to nsIMutableStyleContext public: @@ -2527,20 +2392,34 @@ public: virtual PRBool Equals(const nsIStyleContext* aOther) const; virtual PRUint32 HashValue(void) const; + virtual nsresult WrapRemapStyle(nsIPresContext* aPresContext, PRBool aEnterRemapStyle); NS_IMETHOD RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse = PR_TRUE); + //--------------------------- + // Read/Write Style Data NS_IMETHOD GetStyle(nsStyleStructID aSID, nsStyleStruct& aStruct) const; - NS_IMETHOD SetStyle(nsStyleStructID aSID, const nsStyleStruct& aStruct); + inline virtual const nsStyleStruct* GetStyleData(nsStyleStructID aSID); - virtual const nsStyleStruct* GetStyleData(nsStyleStructID aSID); - virtual nsStyleStruct* GetMutableStyleData(nsStyleStructID aSID); +protected: + inline const nsStyleStruct* FetchInheritedStyleStruct(nsStyleStructID aSID) const { + return FetchInheritedStyleBlob(aSID)->GetData(); + }; + virtual StyleBlob* FetchInheritedStyleBlob(nsStyleStructID aSID) const; + virtual void ReadMutableStyleData(nsStyleStructID aSID, nsStyleStruct** aStyleStructPtr); + virtual nsresult WriteMutableStyleData(nsStyleStructID aSID, nsStyleStruct* aStyleStruct); + virtual nsresult WriteStyleData(nsStyleStructID aSID, const nsStyleStruct* aStyleStruct); + //--------------------------- +public: virtual void ForceUnique(void); virtual void RecalcAutomaticData(nsIPresContext* aPresContext); virtual void CalcBorderPaddingFor(const nsIFrame* aFrame, nsMargin& aBorderPadding) const; NS_IMETHOD CalcStyleDifference(nsIStyleContext* aOther, PRInt32& aHint,PRBool aStopAtFirstDifference = PR_FALSE) const; #ifdef SHARE_STYLECONTEXTS + //--------------------------- + // Style Context Sharing + // // evaluate and execute the style data sharing // - if nothing to share, it leaves the current style data intact, // otherwise it calls ShareStyleDataFrom to share another context's data @@ -2564,8 +2443,11 @@ public: // update the style set cache by adding this context to it // - NOTE: mStyleSet member must be set nsresult UpdateStyleSetCache( void ) const; -#endif +#endif // SHARE_STYLECONTEXTS + //--------------------------- + // Regression Data + // virtual void List(FILE* out, PRInt32 aIndent); virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); @@ -2590,32 +2472,13 @@ protected: nsISupportsArray* mRules; PRInt16 mDataCode; -#ifdef SHARE_STYLECONTEXTS - - nsStyleContextData* mStyleData; - -#else - - // the style data... - StyleFontImpl mFont; - StyleColorImpl mColor; - StyleListImpl mList; - StylePositionImpl mPosition; - StyleTextImpl mText; - StyleDisplayImpl mDisplay; - StyleTableImpl mTable; - StyleContentImpl mContent; - StyleUserInterfaceImpl mUserInterface; - StylePrintImpl mPrint; - StyleMarginImpl mMargin; - StylePaddingImpl mPadding; - StyleBorderImpl mBorder; - StyleOutlineImpl mOutline; -#ifdef INCLUDE_XUL - StyleXULImpl mXUL; +#ifdef LOG_WRITE_STYLE_DATA_CALLS +public: +#endif + nsStyleContextData* mStyleData; +#ifndef SHARE_STYLECONTEXTS + nsStyleContextData mStyleDataImpl; #endif - -#endif // #ifdef SHARE_STYLECONTEXTS // make sure we have valid style data nsresult EnsureStyleData(nsIPresContext* aPresContext); @@ -2636,6 +2499,10 @@ static PRBool HashStyleRule(nsISupports* aRule, void* aData) #pragma mark - #endif +//------------------------------------------------------------------------------ +// StyleContextImpl ctor +//------------------------------------------------------------------------------ +// StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent, nsIAtom* aPseudoTag, nsISupportsArray* aRules, @@ -2646,24 +2513,7 @@ StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent, mPseudoTag(aPseudoTag), mRules(aRules), mDataCode(-1), -#ifdef SHARE_STYLECONTEXTS mStyleData(nsnull) -#else - mFont(aPresContext->GetDefaultFontDeprecated(), aPresContext->GetDefaultFixedFontDeprecated()), - mColor(), - mSpacing(), - mList(), - mPosition(), - mText(), - mDisplay(), - mTable(), - mContent(), - mUserInterface(), -#ifdef INCLUDE_XUL - mXUL(), -#endif - mPrint() -#endif { NS_INIT_REFCNT(); NS_IF_ADDREF(mPseudoTag); @@ -2682,7 +2532,7 @@ StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent, } #ifdef SHARE_STYLECONTEXTS - // remember the style set + // remember the style set (for style context sharing) nsIPresShell* shell = nsnull; aPresContext->GetShell(&shell); if (shell) { @@ -2692,6 +2542,11 @@ StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent, #endif // SHARE_STYLECONTEXTS } + +//------------------------------------------------------------------------------ +// StyleContextImpl dtor +//------------------------------------------------------------------------------ +// StyleContextImpl::~StyleContextImpl() { NS_ASSERTION((nsnull == mChild) && (nsnull == mEmptyChild), "destructing context with children"); @@ -2711,6 +2566,7 @@ StyleContextImpl::~StyleContextImpl() } else { NS_ASSERTION(0, "StyleSet is not optional in a StyleContext's dtor..."); } + // release the style data so it can be reclaimed when no longer referenced NS_IF_RELEASE(mStyleData); #endif // SHARE_STYLECONTEXTS @@ -2719,6 +2575,11 @@ StyleContextImpl::~StyleContextImpl() NS_IMPL_ADDREF(StyleContextImpl) NS_IMPL_RELEASE(StyleContextImpl) + +//------------------------------------------------------------------------------ +// QueryInterface +//------------------------------------------------------------------------------ +// NS_IMETHODIMP StyleContextImpl::QueryInterface(const nsIID& aIID, void** aInstancePtr) { @@ -2740,12 +2601,20 @@ StyleContextImpl::QueryInterface(const nsIID& aIID, void** aInstancePtr) return NS_NOINTERFACE; } +//------------------------------------------------------------------------------ +// GetParent +//------------------------------------------------------------------------------ +// nsIStyleContext* StyleContextImpl::GetParent(void) const { NS_IF_ADDREF(mParent); return mParent; } +//------------------------------------------------------------------------------ +// AppendChild +//------------------------------------------------------------------------------ +// void StyleContextImpl::AppendChild(StyleContextImpl* aChild) { if (0 == aChild->GetStyleRuleCount()) { @@ -2772,6 +2641,10 @@ void StyleContextImpl::AppendChild(StyleContextImpl* aChild) } } +//------------------------------------------------------------------------------ +// RemoveChild +//------------------------------------------------------------------------------ +// void StyleContextImpl::RemoveChild(StyleContextImpl* aChild) { NS_ASSERTION((nsnull != aChild) && (this == aChild->mParent), "bad argument"); @@ -2810,6 +2683,10 @@ void StyleContextImpl::RemoveChild(StyleContextImpl* aChild) aChild->mPrevSibling = aChild; } +//------------------------------------------------------------------------------ +// GetStyleRules +//------------------------------------------------------------------------------ +// nsISupportsArray* StyleContextImpl::GetStyleRules(void) const { nsISupportsArray* result = mRules; @@ -2817,6 +2694,10 @@ nsISupportsArray* StyleContextImpl::GetStyleRules(void) const return result; } +//------------------------------------------------------------------------------ +// GetStyleRuleCount +//------------------------------------------------------------------------------ +// PRInt32 StyleContextImpl::GetStyleRuleCount(void) const { if (nsnull != mRules) { @@ -2828,6 +2709,10 @@ PRInt32 StyleContextImpl::GetStyleRuleCount(void) const return 0; } +//------------------------------------------------------------------------------ +// GetPseudoType +//------------------------------------------------------------------------------ +// NS_IMETHODIMP StyleContextImpl::GetPseudoType(nsIAtom*& aPseudoTag) const { @@ -2836,6 +2721,10 @@ StyleContextImpl::GetPseudoType(nsIAtom*& aPseudoTag) const return NS_OK; } +//------------------------------------------------------------------------------ +// FindChildWithRules +//------------------------------------------------------------------------------ +// NS_IMETHODIMP StyleContextImpl::FindChildWithRules(const nsIAtom* aPseudoTag, nsISupportsArray* aRules, @@ -2892,7 +2781,10 @@ StyleContextImpl::FindChildWithRules(const nsIAtom* aPseudoTag, return NS_OK; } - +//------------------------------------------------------------------------------ +// Equals +//------------------------------------------------------------------------------ +// PRBool StyleContextImpl::Equals(const nsIStyleContext* aOther) const { PRBool result = PR_TRUE; @@ -2925,271 +2817,62 @@ PRBool StyleContextImpl::Equals(const nsIStyleContext* aOther) const return result; } +//------------------------------------------------------------------------------ +// HashValue +//------------------------------------------------------------------------------ +// PRUint32 StyleContextImpl::HashValue(void) const { return mRuleHash; } -//========================================================================================================= -#ifdef DEBUG -// define this to get statistics on the number of calls -// to GetStyleData() and their depth in the Style tree. -//#define LOG_GET_STYLE_DATA_CALLS //XXX pierre -#endif - -#ifdef LOG_GET_STYLE_DATA_CALLS - -#ifdef XP_MAC -#include -#include -static bool MacKeyDown(unsigned char theKey) +//------------------------------------------------------------------------------ +// FetchInheritedStyleBlob +//------------------------------------------------------------------------------ +// For a given type of style data, get the first non-null pointer +// in the style context hierarchy, . When a pointer is null, it means +// that we are inheriting that particular style from the parent. Style +// contexts without parent have all their style data allocated. +// +// IMPORTANT: Do not use the GETDATA() macros in this function +// +StyleBlob* StyleContextImpl::FetchInheritedStyleBlob(nsStyleStructID aSID) const { - KeyMap map; - GetKeys(map); - return ((*((unsigned char *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0; -} -#endif - - -static bool IsTimeToDumpGetStyleDataCalls() -{ - bool timeToDump = false; -#ifdef XP_MAC - static unsigned long lastTicks = 0; - if (MacKeyDown(0x3b)) { // control key - if ((unsigned long)(::TickCount() - lastTicks) > 60) { - lastTicks = ::TickCount(); - timeToDump = true; - } - } -#endif - return timeToDump; -} - -enum LogCallType { - logCallType_GetStyleData = 0, - logCallType_GetMutableStyleData, - logCallType_GetStyle, - - logCallType_Max -}; - -static void LogGetStyleDataCall(nsStyleStructID aSID, LogCallType aLogCallType, nsIStyleContext* aStyleContext, bool aEnteringFunction) -{ -#define max_structs (eStyleStruct_Max + 1) -#define small_depth_threshold 8 - - static unsigned long calls[max_structs*logCallType_Max]; - static unsigned long callspercent[max_structs*logCallType_Max]; - static unsigned long depth[max_structs*logCallType_Max]; - static unsigned long maxdepth[max_structs*logCallType_Max]; - static unsigned long smalldepth[max_structs*logCallType_Max]; - static unsigned long microsecs[logCallType_Max]; - static unsigned long totalMicrosecs; - static UnsignedWide startMicrosecs; - static UnsignedWide endMicrosecs; - - if (!aEnteringFunction) { - ::Microseconds(&endMicrosecs); - totalMicrosecs += endMicrosecs.lo - startMicrosecs.lo; - microsecs[aLogCallType] += endMicrosecs.lo - startMicrosecs.lo; - return; - } - - - static bool resetCounters = true; - - if (IsTimeToDumpGetStyleDataCalls()) { - resetCounters = true; - - unsigned long totalCalls; - unsigned long totalMaxdepth; - unsigned long totalDepth; - for (short i = 0; i < (max_structs*logCallType_Max); i ++) { - - if (i%max_structs == 0) { - switch (i/max_structs) { - case 0: - printf("\n\n\n"); - printf("----GetStyleData--------------------------------------------------------------------------\n"); - printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold); - break; - case 1: - printf("----GetMutableStyleData-------------------------------------------------------------------\n"); - printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold); - break; - case 2: - printf("----GetStyle------------------------------------------------------------------------------\n"); - printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold); - break; - } - - totalCalls = totalMaxdepth = totalDepth = 0; - for (short j = i; j < i + max_structs; j++) { - totalCalls += calls[j]; - totalDepth += depth[j]; - if (totalMaxdepth < maxdepth[j]) { - totalMaxdepth = maxdepth[j]; - } - } - } - - switch (i%max_structs + 1) { - case eStyleStruct_Font: printf("eStyleStruct_Font "); break; - case eStyleStruct_Color: printf("eStyleStruct_Color "); break; - case eStyleStruct_List: printf("eStyleStruct_List "); break; - case eStyleStruct_Position: printf("eStyleStruct_Position "); break; - case eStyleStruct_Text: printf("eStyleStruct_Text "); break; - case eStyleStruct_Display: printf("eStyleStruct_Display "); break; - case eStyleStruct_Table: printf("eStyleStruct_Table "); break; - case eStyleStruct_Content: printf("eStyleStruct_Content "); break; - case eStyleStruct_UserInterface: printf("eStyleStruct_UserInterface "); break; - case eStyleStruct_Print: printf("eStyleStruct_Print "); break; - case eStyleStruct_Margin: printf("eStyleStruct_Margin "); break; - case eStyleStruct_Padding: printf("eStyleStruct_Padding "); break; - case eStyleStruct_Border: printf("eStyleStruct_Border "); break; - case eStyleStruct_Outline: printf("eStyleStruct_Outline "); break; - case eStyleStruct_BorderPaddingShortcut: printf("BorderPaddingShortcut "); break; -#ifdef INCLUDE_XUL - case eStyleStruct_XUL: printf("eStyleStruct_XUL "); break; -#endif - } - short percent = 100*calls[i]/totalCalls; - short avdepth = calls[i] == 0 ? 0 : round(float(depth[i])/float(calls[i])); - short smdepth = 100*smalldepth[i]/calls[i]; - if (percent == 0) { - printf(" %7ld - %3ld %3d %3d\n", calls[i], maxdepth[i], avdepth, smdepth); - } - else { - printf(" %7ld %2ld %3ld %3d %3d\n", calls[i], percent, maxdepth[i], avdepth, smdepth); - } - - if (i%max_structs + 1 == max_structs) { - short totaldepth = totalCalls == 0 ? 0 : round(float(totalDepth)/float(totalCalls)); - printf("TOTAL "); - printf(" %7ld 100 %3ld %3d %ld ms\n", totalCalls, totalMaxdepth, totaldepth, microsecs[i/max_structs]/1000); - } - - } - printf("------------------------------------------------------------------------------------------\n"); - printf("TOTAL time = %ld microsecs (= %ld ms)\n", totalMicrosecs, totalMicrosecs/1000); - printf("------------------------------------------------------------------------------------------\n\n\n"); - } - - if (resetCounters) { - resetCounters = false; - totalMicrosecs = 0; - for (short i = 0; i < logCallType_Max; i ++) { - microsecs[i] = 0L; - } - for (short i = 0; i < (max_structs*logCallType_Max); i ++) { - calls[i] = 0L; - depth[i] = 0L; - maxdepth[i] = 0L; - smalldepth[i] = 0L; - } - } + NS_PRECONDITION(aSID > 0 && aSID <= eStyleStruct_Max, "Invalid style struct id"); short index = aSID - 1; - index += max_structs * aLogCallType; - - calls[index]++; - - unsigned long curdepth = 0; - nsCOMPtr childContext; - nsCOMPtr parentContext; - childContext = aStyleContext; - parentContext = getter_AddRefs(childContext->GetParent()); - while (parentContext != nsnull) { - curdepth++; - parentContext = getter_AddRefs(childContext->GetParent()); - if (parentContext == childContext) { + StyleBlob* result = nsnull; + const StyleContextImpl* sc = this; + while (sc) { + result = sc->BLOBARRAY[index]; + if (result) { break; } - childContext = parentContext; + sc = sc->mParent; } - depth[index] += curdepth; - if (maxdepth[index] < curdepth) { - maxdepth[index] = curdepth; + if (result == nsnull) { + NS_WARNING("Did not find style blob"); + // Allocate the missing blob. This should never happen, but who knows? + BLOBARRAY[index] = mStyleData->AllocateOneBlob(aSID, nsnull); + result = BLOBARRAY[index]; } - if (curdepth <= small_depth_threshold) { - smalldepth[index]++; - } - - static short inCount = 0; - static short outCount = 0; - if (inCount++ % 1000 == 0) { - switch (outCount++) { - case 0: printf("still logging"); break; - case 20: printf("\n"); outCount = 0; break; - default: printf("."); fflush(stdout); break; - } - } - ::Microseconds(&startMicrosecs); + return result; } -#endif // LOG_GET_STYLE_DATA_CALLS -//========================================================================================================= +//------------------------------------------------------------------------------ +// GetStyleData +//------------------------------------------------------------------------------ +// const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID) { + NS_PRECONDITION(aSID > 0 && aSID <= eStyleStruct_Max, "Invalid style struct id"); + #ifdef LOG_GET_STYLE_DATA_CALLS LogGetStyleDataCall(aSID, logCallType_GetStyleData, this, true); #endif - nsStyleStruct* result = nsnull; + const nsStyleStruct* result = FetchInheritedStyleStruct(aSID); - switch (aSID) { - case eStyleStruct_Font: - result = & GETSCDATA(Font); - break; - case eStyleStruct_Color: - result = & GETSCDATA(Color); - break; - case eStyleStruct_List: - result = & GETSCDATA(List); - break; - case eStyleStruct_Position: - result = & GETSCDATA(Position); - break; - case eStyleStruct_Text: - result = & GETSCDATA(Text); - break; - case eStyleStruct_Display: - result = & GETSCDATA(Display); - break; - case eStyleStruct_Table: - result = & GETSCDATA(Table); - break; - case eStyleStruct_Content: - result = & GETSCDATA(Content); - break; - case eStyleStruct_UserInterface: - result = & GETSCDATA(UserInterface); - break; - case eStyleStruct_Print: - result = & GETSCDATA(Print); - break; - case eStyleStruct_Margin: - result = & GETSCDATA(Margin); - break; - case eStyleStruct_Padding: - result = & GETSCDATA(Padding); - break; - case eStyleStruct_Border: - result = & GETSCDATA(Border); - break; - case eStyleStruct_Outline: - result = & GETSCDATA(Outline); - break; -#ifdef INCLUDE_XUL - case eStyleStruct_XUL: - result = & GETSCDATA(XUL); - break; -#endif - default: - NS_ERROR("Invalid style struct id"); - break; - } #ifdef LOG_GET_STYLE_DATA_CALLS LogGetStyleDataCall(aSID, logCallType_GetStyleData, this, false); #endif @@ -3197,91 +2880,227 @@ const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID) return result; } -nsStyleStruct* StyleContextImpl::GetMutableStyleData(nsStyleStructID aSID) -{ -#ifdef LOG_GET_STYLE_DATA_CALLS - LogGetStyleDataCall(aSID, logCallType_GetMutableStyleData, this, true); +//------------------------------------------------------------------------------ +// GetNewMutableStyleStruct [static] +//------------------------------------------------------------------------------ +// Notes: +// - We can't get more than 4 mutable style structs of the same type at the same time. +// - Keep in sync with the comments in the declaration of ReadMutableStyleData() +// in nsIMutableStyleContext.h and nsIStyleContext.h +const short kStructIndexMax = 4; + +static STYLEDATA(Font) gStructFont[kStructIndexMax]; +static STYLEDATA(Color) gStructColor[kStructIndexMax]; +static STYLEDATA(List) gStructList[kStructIndexMax]; +static STYLEDATA(Position) gStructPosition[kStructIndexMax]; +static STYLEDATA(Text) gStructText[kStructIndexMax]; +static STYLEDATA(Display) gStructDisplay[kStructIndexMax]; +static STYLEDATA(Table) gStructTable[kStructIndexMax]; +static STYLEDATA(Content) gStructContent[kStructIndexMax]; +static STYLEDATA(UserInterface) gStructUserInterface[kStructIndexMax]; +static STYLEDATA(Print) gStructPrint[kStructIndexMax]; +static STYLEDATA(Margin) gStructMargin[kStructIndexMax]; +static STYLEDATA(Padding) gStructPadding[kStructIndexMax]; +static STYLEDATA(Border) gStructBorder[kStructIndexMax]; +static STYLEDATA(Outline) gStructOutline[kStructIndexMax]; +#ifdef INCLUDE_XUL +static STYLEDATA(XUL) gStructXUL[kStructIndexMax]; #endif +//#insert new style structs here# + +nsStyleStruct* gStructPointer[eStyleStruct_Max][kStructIndexMax]; +bool gStructBusy[eStyleStruct_Max][kStructIndexMax]; + + +static nsStyleStruct* GetNewMutableStyleStruct(nsStyleStructID aSID) { nsStyleStruct* result = nsnull; - switch (aSID) { - case eStyleStruct_Font: - result = & GETSCDATA(Font); - break; - case eStyleStruct_Color: - result = & GETSCDATA(Color); - break; - case eStyleStruct_List: - result = & GETSCDATA(List); - break; - case eStyleStruct_Position: - result = & GETSCDATA(Position); - break; - case eStyleStruct_Text: - result = & GETSCDATA(Text); - break; - case eStyleStruct_Display: - result = & GETSCDATA(Display); - break; - case eStyleStruct_Table: - result = & GETSCDATA(Table); - break; - case eStyleStruct_Content: - result = & GETSCDATA(Content); - break; - case eStyleStruct_UserInterface: - result = & GETSCDATA(UserInterface); - break; - case eStyleStruct_Print: - result = & GETSCDATA(Print); - break; - case eStyleStruct_Margin: - result = & GETSCDATA(Margin); - break; - case eStyleStruct_Padding: - result = & GETSCDATA(Padding); - break; - case eStyleStruct_Border: - result = & GETSCDATA(Border); - break; - case eStyleStruct_Outline: - result = & GETSCDATA(Outline); - break; + static bool initialized = false; + if (!initialized) { + initialized = true; + for (short structType = 0; structType < eStyleStruct_Max; structType++) { + nsStyleStructID structID = (nsStyleStructID)(structType + 1); + for (short structIndex = 0; structIndex < kStructIndexMax; structIndex++) { + nsStyleStruct* structPtr = nsnull; + switch (structID) { + case eStyleStruct_Font: structPtr = &gStructFont[structIndex]; break; + case eStyleStruct_Color: structPtr = &gStructColor[structIndex]; break; + case eStyleStruct_List: structPtr = &gStructList[structIndex]; break; + case eStyleStruct_Position: structPtr = &gStructPosition[structIndex]; break; + case eStyleStruct_Text: structPtr = &gStructText[structIndex]; break; + case eStyleStruct_Display: structPtr = &gStructDisplay[structIndex]; break; + case eStyleStruct_Table: structPtr = &gStructTable[structIndex]; break; + case eStyleStruct_Content: structPtr = &gStructContent[structIndex]; break; + case eStyleStruct_UserInterface: structPtr = &gStructUserInterface[structIndex]; break; + case eStyleStruct_Print: structPtr = &gStructPrint[structIndex]; break; + case eStyleStruct_Margin: structPtr = &gStructMargin[structIndex]; break; + case eStyleStruct_Padding: structPtr = &gStructPadding[structIndex]; break; + case eStyleStruct_Border: structPtr = &gStructBorder[structIndex]; break; + case eStyleStruct_Outline: structPtr = &gStructOutline[structIndex]; break; #ifdef INCLUDE_XUL - case eStyleStruct_XUL: - result = & GETSCDATA(XUL); - break; + case eStyleStruct_XUL: structPtr = &gStructXUL[structIndex]; break; #endif - default: - NS_ERROR("Invalid style struct id"); - break; + //#insert new style structs here# + default: + NS_ERROR("Invalid style struct id"); + break; + } + gStructPointer[structType][structIndex] = structPtr; + gStructBusy[structType][structIndex] = false; + } + } } + short structType = aSID - 1; + for (short structIndex = 0; structIndex < kStructIndexMax; structIndex++) { + if (!gStructBusy[structType][structIndex]) { + result = gStructPointer[structType][structIndex]; + gStructBusy[structType][structIndex] = true; + break; + } + } + if (!result) { + NS_ERROR("Reached maximum number of mutable style structs of a certain type"); + // Return something or we gonna crash: callers don't always check the returned pointer. + // By returning a structure which is already in use, we'll only have rendering errors. + // Anyhow, this is just a safety fallback, in case people in the future don't follow + // the instructions in "nsIMutableStyleContext.h" about the limit on mutable pointers + // that one can get at any single time. + result = gStructPointer[structType][0]; + } + return result; +} + +//------------------------------------------------------------------------------ +// ReleaseMutableStyleStruct [static] +//------------------------------------------------------------------------------ +// Retrieve the pointer we gave them and mark it free again. +// A linear search is fine: we have only 4 elements to iterate through. +// +static void ReleaseMutableStyleStruct(nsStyleStructID aSID, nsStyleStruct* aStyleStruct) +{ + short structType = aSID - 1; + for (short structIndex = 0; structIndex < kStructIndexMax; structIndex++) { + if (gStructPointer[structType][structIndex] == aStyleStruct) { + gStructBusy[structType][structIndex] = false; + return; + } + } + NS_ASSERTION(false, "Can't release mutable style struct"); +} + + +//------------------------------------------------------------------------------ +// ReadMutableStyleData +//------------------------------------------------------------------------------ +// Receive a style structure and fill it up with the inherited style. +// +void StyleContextImpl::ReadMutableStyleData(nsStyleStructID aSID, nsStyleStruct** aStyleStructPtr) +{ + NS_PRECONDITION(aSID > 0 && aSID <= eStyleStruct_Max, "Invalid style struct id"); + +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, logCallType_ReadMutableStyleData, this, true); +#endif +#ifdef LOG_STYLE_STRUCTS + mStyleData->mGotMutable[aSID] = true; +#endif + + nsStyleStruct* result = GetNewMutableStyleStruct(aSID); + const StyleBlob* current = FetchInheritedStyleBlob(aSID); + current->CopyTo(result); + +#if 0 // was there in the previous function that returned direct pointers to the style data if (nsnull != result) { if (0 == mDataCode) { // mDataCode = ++gLastDataCode; // XXX temp disable, this is still used but not needed to force unique } } -#ifdef LOG_GET_STYLE_DATA_CALLS - LogGetStyleDataCall(aSID, logCallType_GetMutableStyleData, this, false); #endif - return result; +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, logCallType_ReadMutableStyleData, this, false); +#endif + + *aStyleStructPtr = result; } + +//------------------------------------------------------------------------------ +// WriteStyleData +//------------------------------------------------------------------------------ +// Basic function to write a style structure. +// Check whether the style is any different from the inherited style and if so, +// allocate a new blob (if needed) and copy the new style into it. +// +nsresult StyleContextImpl::WriteStyleData(nsStyleStructID aSID, const nsStyleStruct* aStyleStruct) +{ + NS_PRECONDITION(aSID > 0 && aSID <= eStyleStruct_Max, "Invalid style struct id"); + + short index = aSID - 1; + const StyleBlob* current = FetchInheritedStyleBlob(aSID); + PRInt32 hint = current->CalcDifference(aStyleStruct); + + if (hint != NS_STYLE_HINT_NONE) { + if (!BLOBARRAY[index]) { + BLOBARRAY[index] = mStyleData->AllocateOneBlob(aSID, nsnull); + if (!BLOBARRAY[index]) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + BLOBARRAY[index]->SetFrom(aStyleStruct); + } + return NS_OK; +} + +//------------------------------------------------------------------------------ +// WriteMutableStyleData +//------------------------------------------------------------------------------ +// Write a style structure that was filled-up in ReadMutableStyleData and that +// might have been modified by the app. +// +nsresult StyleContextImpl::WriteMutableStyleData(nsStyleStructID aSID, nsStyleStruct* aStyleStruct) +{ + NS_PRECONDITION(aSID > 0 && aSID <= eStyleStruct_Max, "Invalid style struct id"); + +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, logCallType_WriteMutableStyleData, this, true); +#endif +#ifdef LOG_WRITE_STYLE_DATA_CALLS + LogWriteMutableStyleDataCall(aSID, aStyleStruct, this); +#endif + + WriteStyleData(aSID, aStyleStruct); + ReleaseMutableStyleStruct(aSID, aStyleStruct); + +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, logCallType_WriteMutableStyleData, this, false); +#endif + return NS_OK; +} + +//------------------------------------------------------------------------------ +// CalcBorderPaddingFor +//------------------------------------------------------------------------------ +// void StyleContextImpl::CalcBorderPaddingFor(const nsIFrame* aFrame, nsMargin& aBorderPadding) const { nsMargin border, padding; - if (!GETSCDATA(Border).GetBorder(border)) { - GETSCDATA(Border).CalcBorderFor(aFrame, border); + + if (!GETDATA(Border)->GetBorder(border)) { + GETDATA(Border)->CalcBorderFor(aFrame, border); } - if (!GETSCDATA(Padding).GetPadding(padding)) { - GETSCDATA(Padding).CalcPaddingFor(aFrame, padding); + if (!GETDATA(Padding)->GetPadding(padding)) { + GETDATA(Padding)->CalcPaddingFor(aFrame, padding); } aBorderPadding = border + padding; } +//------------------------------------------------------------------------------ +// GetStyle +//------------------------------------------------------------------------------ +// NS_IMETHODIMP StyleContextImpl::GetStyle(nsStyleStructID aSID, nsStyleStruct& aStruct) const { @@ -3289,139 +3108,39 @@ StyleContextImpl::GetStyle(nsStyleStructID aSID, nsStyleStruct& aStruct) const LogGetStyleDataCall(aSID, logCallType_GetStyle, (nsIStyleContext*)this, true); #endif - nsresult result = NS_OK; - switch (aSID) { - case eStyleStruct_Font: - GETSCDATA(Font).CopyTo((nsStyleFont&)aStruct); - break; - case eStyleStruct_Color: - GETSCDATA(Color).CopyTo((nsStyleColor&)aStruct); - break; - case eStyleStruct_List: - GETSCDATA(List).CopyTo((nsStyleList&)aStruct); - break; - case eStyleStruct_Position: - GETSCDATA(Position).CopyTo((nsStylePosition&)aStruct); - break; - case eStyleStruct_Text: - GETSCDATA(Text).CopyTo((nsStyleText&)aStruct); - break; - case eStyleStruct_Display: - GETSCDATA(Display).CopyTo((nsStyleDisplay&)aStruct); - break; - case eStyleStruct_Table: - GETSCDATA(Table).CopyTo((nsStyleTable&)aStruct); - break; - case eStyleStruct_Content: - GETSCDATA(Content).CopyTo((nsStyleContent&)aStruct); - break; - case eStyleStruct_UserInterface: - GETSCDATA(UserInterface).CopyTo((nsStyleUserInterface&)aStruct); - break; - case eStyleStruct_Print: - GETSCDATA(Print).CopyTo((nsStylePrint&)aStruct); - break; - case eStyleStruct_Margin: - GETSCDATA(Margin).CopyTo((nsStyleMargin&)aStruct); - break; - case eStyleStruct_Padding: - GETSCDATA(Padding).CopyTo((nsStylePadding&)aStruct); - break; - case eStyleStruct_Border: - GETSCDATA(Border).CopyTo((nsStyleBorder&)aStruct); - break; - case eStyleStruct_Outline: - GETSCDATA(Outline).CopyTo((nsStyleOutline&)aStruct); - break; -#ifdef INCLUDE_XUL - case eStyleStruct_XUL: - GETSCDATA(XUL).CopyTo((nsStyleXUL&)aStruct); - break; -#endif - case eStyleStruct_BorderPaddingShortcut: { - nsMargin border, padding; - if (GETSCDATA(Border).GetBorder(border)) { - if (GETSCDATA(Padding).GetPadding(padding)) { - border += padding; - ((nsStyleBorderPadding&)aStruct).SetBorderPadding(border); - } + if (aSID == eStyleStruct_BorderPaddingShortcut) { + nsMargin border, padding; + PRBool hasBorder = GETDATA(Border)->GetBorder(border); + PRBool hasPadding = GETDATA(Padding)->GetPadding(padding); + if (hasBorder) { + if (hasPadding) { + border += padding; } - break; + ((nsStyleBorderPadding&)aStruct).SetBorderPadding(border); } - default: - NS_ERROR("Invalid style struct id"); - result = NS_ERROR_INVALID_ARG; - break; + else { + if (hasPadding) { + ((nsStyleBorderPadding&)aStruct).SetBorderPadding(padding); + } + } + } + else { + NS_PRECONDITION(aSID > 0 && aSID <= eStyleStruct_Max, "Invalid style struct id"); + const StyleBlob* current = FetchInheritedStyleBlob(aSID); + current->CopyTo(&aStruct); + } + #ifdef LOG_GET_STYLE_DATA_CALLS LogGetStyleDataCall(aSID, logCallType_GetStyle, (nsIStyleContext*)this, false); #endif - - return result; + return NS_OK; } -NS_IMETHODIMP -StyleContextImpl::SetStyle(nsStyleStructID aSID, const nsStyleStruct& aStruct) -{ - nsresult result = NS_OK; - switch (aSID) { - case eStyleStruct_Font: - GETSCDATA(Font).SetFrom((const nsStyleFont&)aStruct); - break; - case eStyleStruct_Color: - GETSCDATA(Color).SetFrom((const nsStyleColor&)aStruct); - break; - case eStyleStruct_List: - GETSCDATA(List).SetFrom((const nsStyleList&)aStruct); - break; - case eStyleStruct_Position: - GETSCDATA(Position).SetFrom((const nsStylePosition&)aStruct); - break; - case eStyleStruct_Text: - GETSCDATA(Text).SetFrom((const nsStyleText&)aStruct); - break; - case eStyleStruct_Display: - GETSCDATA(Display).SetFrom((const nsStyleDisplay&)aStruct); - break; - case eStyleStruct_Table: - GETSCDATA(Table).SetFrom((const nsStyleTable&)aStruct); - break; - case eStyleStruct_Content: - GETSCDATA(Content).SetFrom((const nsStyleContent&)aStruct); - break; - case eStyleStruct_UserInterface: - GETSCDATA(UserInterface).SetFrom((const nsStyleUserInterface&)aStruct); - break; - case eStyleStruct_Print: - GETSCDATA(Print).SetFrom((const nsStylePrint&)aStruct); - break; - case eStyleStruct_Margin: - GETSCDATA(Margin).SetFrom((const nsStyleMargin&)aStruct); - break; - case eStyleStruct_Padding: - GETSCDATA(Padding).SetFrom((const nsStylePadding&)aStruct); - break; - case eStyleStruct_Border: - GETSCDATA(Border).SetFrom((const nsStyleBorder&)aStruct); - break; - case eStyleStruct_Outline: - GETSCDATA(Outline).SetFrom((const nsStyleOutline&)aStruct); - break; -#ifdef INCLUDE_XUL - case eStyleStruct_XUL: - GETSCDATA(XUL).SetFrom((const nsStyleXUL&)aStruct); - break; -#endif - default: - NS_ERROR("Invalid style struct id"); - result = NS_ERROR_INVALID_ARG; - break; - } - return result; -} - - - +//------------------------------------------------------------------------------ +// RemapStyle rules and helpers +//------------------------------------------------------------------------------ +// struct MapStyleData { MapStyleData(nsIMutableStyleContext* aStyleContext, nsIPresContext* aPresContext) { @@ -3448,6 +3167,184 @@ static PRBool MapStyleRule(nsISupports* aRule, void* aData) return PR_TRUE; } + +//-------------------------- +// EnsureBlockDisplay +// In order to enforce the floated/positioned element CSS2 rules, +// if the display type is not a block-type then we set it to a +// valid block display type. +// +static void EnsureBlockDisplay(/*in out*/PRUint8 &display) +{ + // see if the display value is already a block + switch (display) { + case NS_STYLE_DISPLAY_NONE : + // never change display:none *ever* + break; + + case NS_STYLE_DISPLAY_TABLE : + case NS_STYLE_DISPLAY_BLOCK : + // do not muck with these at all - already blocks + break; + + case NS_STYLE_DISPLAY_LIST_ITEM : + // do not change list items to blocks - retain the bullet/numbering + break; + + case NS_STYLE_DISPLAY_TABLE_ROW_GROUP : + case NS_STYLE_DISPLAY_TABLE_COLUMN : + case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP : + case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP : + case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP : + case NS_STYLE_DISPLAY_TABLE_ROW : + case NS_STYLE_DISPLAY_TABLE_CELL : + case NS_STYLE_DISPLAY_TABLE_CAPTION : + // special cases: don't do anything since these cannot really be floated anyway + break; + + case NS_STYLE_DISPLAY_INLINE_TABLE : + // make inline tables into tables + display = NS_STYLE_DISPLAY_TABLE; + break; + + default : + // make it a block + display = NS_STYLE_DISPLAY_BLOCK; + } +} + + +//------------------------------------------------------------------------------ +// WrapRemapStyle +//------------------------------------------------------------------------------ +// The way it works is... +// - When we enter RemapStyle(), we set the blob pointers that are null +// to point to the static blobs below. Then the app does all the +// remapping it wants, modifying as many of the style structs it needs. +// - When we exit RemapStyle(), we check whether each of the style structs are +// identical to our parent's. If it is, we set its blob to null (possibly +// deallocating the memory). If it is not, we keep it (possibly storing the +// data into a newly allocated blob). +// +nsresult StyleContextImpl::WrapRemapStyle(nsIPresContext* aPresContext, PRBool aEnterRemapStyle) +{ + static STYLEBLOB(Font) sFont; + static STYLEBLOB(Color) sColor; + static STYLEBLOB(List) sList; + static STYLEBLOB(Position) sPosition; + static STYLEBLOB(Text) sText; + static STYLEBLOB(Display) sDisplay; + static STYLEBLOB(Table) sTable; + static STYLEBLOB(Content) sContent; + static STYLEBLOB(UserInterface) sUserInterface; + static STYLEBLOB(Print) sPrint; + static STYLEBLOB(Margin) sMargin; + static STYLEBLOB(Padding) sPadding; + static STYLEBLOB(Border) sBorder; + static STYLEBLOB(Outline) sOutline; +#ifdef INCLUDE_XUL + static STYLEBLOB(XUL) sXUL; +#endif + //#insert new style structs here# + static StyleBlob* sBlobPtr[eStyleStruct_Max]; + + static PRBool initialized = PR_FALSE; + if (!initialized) { + initialized = PR_TRUE; + for (short i = 0; i < eStyleStruct_Max; i ++) { + StyleBlob* blobPtr = nsnull; + switch (i + 1) { + case eStyleStruct_Font: blobPtr = &sFont; break; + case eStyleStruct_Color: blobPtr = &sColor; break; + case eStyleStruct_List: blobPtr = &sList; break; + case eStyleStruct_Position: blobPtr = &sPosition; break; + case eStyleStruct_Text: blobPtr = &sText; break; + case eStyleStruct_Display: blobPtr = &sDisplay; break; + case eStyleStruct_Table: blobPtr = &sTable; break; + case eStyleStruct_Content: blobPtr = &sContent; break; + case eStyleStruct_UserInterface: blobPtr = &sUserInterface; break; + case eStyleStruct_Print: blobPtr = &sPrint; break; + case eStyleStruct_Margin: blobPtr = &sMargin; break; + case eStyleStruct_Padding: blobPtr = &sPadding; break; + case eStyleStruct_Border: blobPtr = &sBorder; break; + case eStyleStruct_Outline: blobPtr = &sOutline; break; +#ifdef INCLUDE_XUL + case eStyleStruct_XUL: blobPtr = &sXUL; break; +#endif + //#insert new style structs here# + default: + NS_ERROR("Invalid style struct id"); + break; + } + sBlobPtr[i] = blobPtr; + } + } + + if (aEnterRemapStyle) { + //------------------------ + // Entering RemapStyle()... + // Set the blob pointers that are null + // to point to the static blobs. +#ifdef DEBUG + if (mParent == nsnull) { + for (short i = 0; i < eStyleStruct_Max; i ++) { + if (BLOBARRAY[i] == nsnull) { + NS_ERROR("Parent context is null but style blob is not allocated"); + break; + } + } + } +#endif + for (short i = 0; i < eStyleStruct_Max; i ++) { + if (!BLOBARRAY[i]) { + BLOBARRAY[i] = sBlobPtr[i]; + } + nsStyleStructID structID = (nsStyleStructID)(i + 1); + const nsStyleStruct* parentStyle = nsnull; + if (mParent) { + parentStyle = mParent->FetchInheritedStyleStruct(structID); + } + BLOBARRAY[i]->ResetFrom(parentStyle, aPresContext); + } + } + else { + //------------------------ + // Exiting RemapStyle()... + // Check whether each of our style structs are identical to our parent's. + // If it is, we set its blob to null (possibly deallocating the memory). + // If it is not, we keep it (possibly storing the data into a newly allocated blob). + if (mParent != nsnull) { + PRInt32 hint; + for (short i = 0; i < eStyleStruct_Max; i ++) { + nsStyleStructID structID = (nsStyleStructID)(i + 1); + hint = BLOBARRAY[i]->CalcDifference(mParent->FetchInheritedStyleStruct(structID)); + if (hint == NS_STYLE_HINT_NONE) { + if (BLOBARRAY[i] == sBlobPtr[i]) { + BLOBARRAY[i] = nsnull; + } + else { + NS_IF_DELETE(BLOBARRAY[i]); + } + } + else { + if (BLOBARRAY[i] == sBlobPtr[i]) { + BLOBARRAY[i] = mStyleData->AllocateOneBlob(structID, nsnull); + if (!BLOBARRAY[i]) { + return NS_ERROR_OUT_OF_MEMORY; + } + BLOBARRAY[i]->SetFrom(sBlobPtr[i]->GetData()); + } + } + } + } + } + return NS_OK; +} + +//------------------------------------------------------------------------------ +// RemapStyle +//------------------------------------------------------------------------------ +// NS_IMETHODIMP StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) { @@ -3457,45 +3354,13 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) return NS_ERROR_UNEXPECTED; } - if (nsnull != mParent) { - GETSCDATA(Font).ResetFrom(&(mParent->GETSCDATA(Font)), aPresContext); - GETSCDATA(Color).ResetFrom(&(mParent->GETSCDATA(Color)), aPresContext); - GETSCDATA(List).ResetFrom(&(mParent->GETSCDATA(List)), aPresContext); - GETSCDATA(Position).ResetFrom(&(mParent->GETSCDATA(Position)), aPresContext); - GETSCDATA(Text).ResetFrom(&(mParent->GETSCDATA(Text)), aPresContext); - GETSCDATA(Display).ResetFrom(&(mParent->GETSCDATA(Display)), aPresContext); - GETSCDATA(Table).ResetFrom(&(mParent->GETSCDATA(Table)), aPresContext); - GETSCDATA(Content).ResetFrom(&(mParent->GETSCDATA(Content)), aPresContext); - GETSCDATA(UserInterface).ResetFrom(&(mParent->GETSCDATA(UserInterface)), aPresContext); - GETSCDATA(Print).ResetFrom(&(mParent->GETSCDATA(Print)), aPresContext); - GETSCDATA(Margin).ResetFrom(&(mParent->GETSCDATA(Margin)), aPresContext); - GETSCDATA(Padding).ResetFrom(&(mParent->GETSCDATA(Padding)), aPresContext); - GETSCDATA(Border).ResetFrom(&(mParent->GETSCDATA(Border)), aPresContext); - GETSCDATA(Outline).ResetFrom(&(mParent->GETSCDATA(Outline)), aPresContext); -#ifdef INCLUDE_XUL - GETSCDATA(XUL).ResetFrom(&(mParent->GETSCDATA(XUL)), aPresContext); -#endif - } - else { - GETSCDATA(Font).ResetFrom(nsnull, aPresContext); - GETSCDATA(Color).ResetFrom(nsnull, aPresContext); - GETSCDATA(List).ResetFrom(nsnull, aPresContext); - GETSCDATA(Position).ResetFrom(nsnull, aPresContext); - GETSCDATA(Text).ResetFrom(nsnull, aPresContext); - GETSCDATA(Display).ResetFrom(nsnull, aPresContext); - GETSCDATA(Table).ResetFrom(nsnull, aPresContext); - GETSCDATA(Content).ResetFrom(nsnull, aPresContext); - GETSCDATA(UserInterface).ResetFrom(nsnull, aPresContext); - GETSCDATA(Print).ResetFrom(nsnull, aPresContext); - GETSCDATA(Margin).ResetFrom(nsnull, aPresContext); - GETSCDATA(Padding).ResetFrom(nsnull, aPresContext); - GETSCDATA(Border).ResetFrom(nsnull, aPresContext); - GETSCDATA(Outline).ResetFrom(nsnull, aPresContext); -#ifdef INCLUDE_XUL - GETSCDATA(XUL).ResetFrom(nsnull, aPresContext); -#endif - } + //------------------------ + // Memory allocation + WrapRemapStyle(aPresContext, PR_TRUE); // Use a temporary set of blobs while we remap style + + //------------------------ + // Normal style remapping PRUint32 cnt = 0; if (mRules) { nsresult rv = mRules->Count(&cnt); @@ -3504,8 +3369,8 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) if (0 < cnt) { MapStyleData data(this, aPresContext); mRules->EnumerateForwards(MapStyleRuleFont, &data); - if (GETSCDATA(Font).mFlags & NS_STYLE_FONT_USE_FIXED) { - GETSCDATA(Font).mFont = GETSCDATA(Font).mFixedFont; + if (GETDATAPTR(Font)->mFlags & NS_STYLE_FONT_USE_FIXED) { + GETMUTABLEDATAPTR(Font)->mFont = GETDATAPTR(Font)->mFixedFont; } mRules->EnumerateForwards(MapStyleRule, &data); } @@ -3513,75 +3378,91 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) mDataCode = 0; } + //------------------------ // CSS2 specified fixups: // - these must be done after all declarations are mapped since they can cross style-structs - // 1) if float is not none, and display is not none, then we must set display to block + // #1 if float is not none, and display is not none, then we must set display to block // XXX - there are problems with following the spec here: what we will do instead of // following the letter of the spec is to make sure that floated elements are // some kind of block, not strictly 'block' - see EnsureBlockDisplay method - nsStyleDisplay *disp = (nsStyleDisplay *)GetMutableStyleData(eStyleStruct_Display); - if (disp) { - if (disp->mDisplay != NS_STYLE_DISPLAY_NONE && - disp->mFloats != NS_STYLE_FLOAT_NONE ) { - EnsureBlockDisplay(disp->mDisplay); + PRUint8 oldDisplay = GETDATAPTR(Display)->mDisplay; + PRUint8 oldFloats = GETDATAPTR(Display)->mFloats; + PRUint8 newDisplay = oldDisplay; + PRUint8 newFloats = oldFloats; + if (newDisplay != NS_STYLE_DISPLAY_NONE && newFloats != NS_STYLE_FLOAT_NONE ) { + EnsureBlockDisplay(newDisplay); + } + // #2 if position is 'absolute' or 'fixed' then display must be 'block and float must be 'none' + // XXX - see note for fixup #1 above... + if (GETDATAPTR(Position)->IsAbsolutelyPositioned()) { + if (newDisplay != NS_STYLE_DISPLAY_NONE) { + EnsureBlockDisplay(newDisplay); + newFloats = NS_STYLE_FLOAT_NONE; } } - // 2) if position is 'absolute' or 'fixed' then display must be 'block and float must be 'none' - // XXX - see note for fixup 1) above... - nsStylePosition *pos = (nsStylePosition *)GetStyleData(eStyleStruct_Position); - if (pos) { - if (pos->IsAbsolutelyPositioned()) { - if (disp) { - if(disp->mDisplay != NS_STYLE_DISPLAY_NONE) { - EnsureBlockDisplay(disp->mDisplay); - disp->mFloats = NS_STYLE_FLOAT_NONE; - } - } + if (newDisplay != oldDisplay || newFloats != oldFloats) { + nsMutableStyleDisplay display((nsIStyleContext*)this); + if (newDisplay != oldDisplay) { + display->mDisplay = newDisplay; + } + if (newFloats != oldFloats) { + display->mFloats = newFloats; } } + //------------------------ + // Table style remapping + PRUint8 displayType = GETDATAPTR(Display)->mDisplay; nsCompatibility quirkMode = eCompatibility_Standard; aPresContext->GetCompatibilityMode(&quirkMode); if (eCompatibility_NavQuirks == quirkMode) { - if (((GETSCDATA(Display).mDisplay == NS_STYLE_DISPLAY_TABLE) || - (GETSCDATA(Display).mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION)) && + if (((displayType == NS_STYLE_DISPLAY_TABLE) || + (displayType == NS_STYLE_DISPLAY_TABLE_CAPTION)) && (nsnull == mPseudoTag)) { - StyleContextImpl* holdParent = mParent; - mParent = nsnull; // cut off all inheritance. this really blows - - // XXX the style we do preserve is visibility, direction, language - PRUint8 visible = GETSCDATA(Display).mVisible; - PRUint8 direction = GETSCDATA(Display).mDirection; - nsCOMPtr language = GETSCDATA(Display).mLanguage; - // time to emulate a sub-document // This is ugly, but we need to map style once to determine display type // then reset and map it again so that all local style is preserved - if (GETSCDATA(Display).mDisplay != NS_STYLE_DISPLAY_TABLE) { - GETSCDATA(Font).ResetFrom(nsnull, aPresContext); - } - GETSCDATA(Color).ResetFrom(nsnull, aPresContext); - GETSCDATA(List).ResetFrom(nsnull, aPresContext); - GETSCDATA(Text).ResetFrom(nsnull, aPresContext); - GETSCDATA(Position).ResetFrom(nsnull, aPresContext); - GETSCDATA(Display).ResetFrom(nsnull, aPresContext); - GETSCDATA(Table).ResetFrom(nsnull, aPresContext); - GETSCDATA(Content).ResetFrom(nsnull, aPresContext); - GETSCDATA(UserInterface).ResetFrom(nsnull, aPresContext); - GETSCDATA(Print).ResetFrom(nsnull, aPresContext); - GETSCDATA(Margin).ResetFrom(nsnull, aPresContext); - GETSCDATA(Padding).ResetFrom(nsnull, aPresContext); - GETSCDATA(Border).ResetFrom(nsnull, aPresContext); - GETSCDATA(Outline).ResetFrom(nsnull, aPresContext); -#ifdef INCLUDE_XUL - GETSCDATA(XUL).ResetFrom(nsnull, aPresContext); -#endif - GETSCDATA(Display).mVisible = visible; - GETSCDATA(Display).mDirection = direction; - GETSCDATA(Display).mLanguage = language; + // XXX the style we do preserve is visibility, direction, language + PRUint8 visible = GETDATAPTR(Display)->mVisible; + PRUint8 direction = GETDATAPTR(Display)->mDirection; + nsCOMPtr language = GETDATAPTR(Display)->mLanguage; + + // cut off all inheritance. this really blows + StyleContextImpl* holdParent = mParent; + mParent = nsnull; + + // NOTE: We cut off the inheritance but we don't need to allocate the blobs + // that were inherited from the parent because we are inside RemapStyle(), + // meaning that we have all the blobs already. + + // Reset the blobs to default style + for (short i = 0; i < eStyleStruct_Max; i ++) { + nsStyleStructID structID = (nsStyleStructID)(i + 1); + if (BLOBARRAY[i]) { + if ((structID == eStyleStruct_Font) && (displayType == NS_STYLE_DISPLAY_TABLE)) { + // Inherit the font struct from the parent (tables only, not table captions)... + const nsStyleStruct* parentStyle = nsnull; + if (holdParent) { + parentStyle = holdParent->FetchInheritedStyleStruct(structID); + } + BLOBARRAY[i]->ResetFrom(parentStyle, aPresContext); + } + else { + // ... But reset all the other blobs + BLOBARRAY[i]->ResetFrom(nsnull, aPresContext); + } + } + } + + // Restore the style we preserved + GETMUTABLEDATAPTR(Display)->mVisible = visible; + GETMUTABLEDATAPTR(Display)->mDirection = direction; + GETMUTABLEDATAPTR(Display)->mLanguage = language; + + // Do the normal style remapping all over again PRUint32 numRules = 0; if (mRules) { nsresult rv = mRules->Count(&numRules); @@ -3590,22 +3471,24 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) if (0 < numRules) { MapStyleData data(this, aPresContext); mRules->EnumerateForwards(MapStyleRuleFont, &data); - if (GETSCDATA(Font).mFlags & NS_STYLE_FONT_USE_FIXED) { - GETSCDATA(Font).mFont = GETSCDATA(Font).mFixedFont; + if (GETDATAPTR(Font)->mFlags & NS_STYLE_FONT_USE_FIXED) { + GETMUTABLEDATAPTR(Font)->mFont = GETDATAPTR(Font)->mFixedFont; } mRules->EnumerateForwards(MapStyleRule, &data); } + // reset all font data for tables again - if (GETSCDATA(Display).mDisplay == NS_STYLE_DISPLAY_TABLE) { + if (GETDATAPTR(Display)->mDisplay == NS_STYLE_DISPLAY_TABLE) { // get the font-name to reset: this property we preserve - nsAutoString strName(GETSCDATA(Font).mFont.name); - nsAutoString strMixedName(GETSCDATA(Font).mFixedFont.name); + nsAutoString strName(GETDATAPTR(Font)->mFont.name); + nsAutoString strFixedName(GETDATAPTR(Font)->mFixedFont.name); - GETSCDATA(Font).ResetFrom(nsnull, aPresContext); + short index = eStyleStruct_Font - 1; + BLOBARRAY[index]->ResetFrom(nsnull, aPresContext); // now reset the font names back to original - GETSCDATA(Font).mFont.name = strName; - GETSCDATA(Font).mFixedFont.name = strMixedName; + GETMUTABLEDATAPTR(Font)->mFont.name = strName; + GETMUTABLEDATAPTR(Font)->mFixedFont.name = strFixedName; } mParent = holdParent; } @@ -3615,22 +3498,31 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) // so they don't inherit into tables, but instead align the // tables. We should keep doing this, because HTML alignment // is just weird, and we shouldn't force it to match CSS. - if (GETSCDATA(Display).mDisplay == NS_STYLE_DISPLAY_TABLE) { + if (displayType == NS_STYLE_DISPLAY_TABLE) { // -moz-center and -moz-right are used for HTML's alignment - if ((GETSCDATA(Text).mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_CENTER) || - (GETSCDATA(Text).mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_RIGHT)) + if ((GETDATAPTR(Text)->mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_CENTER) || + (GETDATAPTR(Text)->mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_RIGHT)) { - GETSCDATA(Text).mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT; + GETMUTABLEDATAPTR(Text)->mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT; } } } RecalcAutomaticData(aPresContext); + //------------------------ + // Memory deallocation + WrapRemapStyle(aPresContext, PR_FALSE); // Keep the blobs that have changed and dump the rest. + // Must be called before we recurse. + + //------------------------ + // Context is mapped, share it if we can #ifdef SHARE_STYLECONTEXTS nsresult result = ShareStyleData(); #endif + //------------------------ + // Recurse through children if (aRecurse) { if (nsnull != mChild) { StyleContextImpl* child = mChild; @@ -3650,6 +3542,10 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) return NS_OK; } +//------------------------------------------------------------------------------ +// ForceUnique +//------------------------------------------------------------------------------ +// void StyleContextImpl::ForceUnique(void) { if (mDataCode <= 0) { @@ -3657,17 +3553,25 @@ void StyleContextImpl::ForceUnique(void) } } +//------------------------------------------------------------------------------ +// RecalcAutomaticData +//------------------------------------------------------------------------------ +// void StyleContextImpl::RecalcAutomaticData(nsIPresContext* aPresContext) { if (NS_FAILED(EnsureStyleData(aPresContext))) { return /*NS_FAILURE*/; } - GETSCDATA(Margin).RecalcData(); - GETSCDATA(Padding).RecalcData(); - GETSCDATA(Border).RecalcData(GETSCDATA(Color).mColor); - GETSCDATA(Outline).RecalcData(); + GETBLOB(Margin)->RecalcData(); + GETBLOB(Padding)->RecalcData(); + GETBLOB(Border)->RecalcData(GETDATA(Color)->mColor); + GETBLOB(Outline)->RecalcData(); } +//------------------------------------------------------------------------------ +// CalcStyleDifference +//------------------------------------------------------------------------------ +// NS_IMETHODIMP StyleContextImpl::CalcStyleDifference(nsIStyleContext* aOther, PRInt32& aHint,PRBool aStopAtFirstDifference /*= PR_FALSE*/) const { @@ -3676,115 +3580,28 @@ StyleContextImpl::CalcStyleDifference(nsIStyleContext* aOther, PRInt32& aHint,PR } if (aOther) { - PRInt32 hint; - const StyleContextImpl* other = (const StyleContextImpl*)aOther; + PRInt32 hint = aHint = NS_STYLE_HINT_NONE; + const StyleContextImpl* otherContext = (const StyleContextImpl*)aOther; - aHint = GETSCDATA(Font).CalcDifference(other->GETSCDATA(Font)); - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Color).CalcDifference(other->GETSCDATA(Color)); + for (short i = 0; i < eStyleStruct_Max; i ++) { + nsStyleStructID structID = (nsStyleStructID)(i + 1); + const StyleBlob* myStyle = FetchInheritedStyleBlob(structID); + hint = myStyle->CalcDifference(otherContext->FetchInheritedStyleStruct(structID)); if (aHint < hint) { aHint = hint; } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Margin).CalcDifference(other->GETSCDATA(Margin)); - if (aHint < hint) { - aHint = hint; + if ((aStopAtFirstDifference && (aHint > NS_STYLE_HINT_NONE)) || (aHint == NS_STYLE_HINT_MAX)) { + return NS_OK; } } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Padding).CalcDifference(other->GETSCDATA(Padding)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Border).CalcDifference(other->GETSCDATA(Border)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Outline).CalcDifference(other->GETSCDATA(Outline)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(List).CalcDifference(other->GETSCDATA(List)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Position).CalcDifference(other->GETSCDATA(Position)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Text).CalcDifference(other->GETSCDATA(Text)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Display).CalcDifference(other->GETSCDATA(Display)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Table).CalcDifference(other->GETSCDATA(Table)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Content).CalcDifference(other->GETSCDATA(Content)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(UserInterface).CalcDifference(other->GETSCDATA(UserInterface)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Print).CalcDifference(other->GETSCDATA(Print)); - if (aHint < hint) { - aHint = hint; - } - } -#ifdef INCLUDE_XUL - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(XUL).CalcDifference(other->GETSCDATA(XUL)); - if (aHint < hint) { - aHint = hint; - } - } -#endif } return NS_OK; } - +//------------------------------------------------------------------------------ +// EnsureStyleData +//------------------------------------------------------------------------------ +// nsresult StyleContextImpl::EnsureStyleData(nsIPresContext* aPresContext) { nsresult rv = NS_OK; @@ -3794,35 +3611,39 @@ nsresult StyleContextImpl::EnsureStyleData(nsIPresContext* aPresContext) return NS_ERROR_FAILURE; } -#ifdef SHARE_STYLECONTEXTS // See if we already have data... if (NS_FAILED(HaveStyleData())) { // we were provided a pres context so create a new style data - mStyleData = nsStyleContextData::Create(aPresContext); +#ifdef SHARE_STYLECONTEXTS + mStyleData = nsStyleContextData::Create(this, aPresContext); +#else + mStyleData = &mStyleDataImpl; + if (NS_FAILED(mStyleData->AllocateStyleBlobs(this, aPresContext))) { + mStyleData = nsnull; + } +#endif if (nsnull == mStyleData) { rv = NS_ERROR_OUT_OF_MEMORY; } - } else { - // already have style data - OK! - rv = NS_OK; } -#endif //#ifdef SHARE_STYLECONTEXTS - return rv; } +//------------------------------------------------------------------------------ +// HaveStyleData +//------------------------------------------------------------------------------ +// nsresult StyleContextImpl::HaveStyleData(void) const { -#ifdef SHARE_STYLECONTEXTS return (nsnull == mStyleData) ? NS_ERROR_NULL_POINTER : NS_OK; -#else - return NS_OK; -#endif } +//------------------------------------------------------------------------------ +// ShareStyleData +//------------------------------------------------------------------------------ +// #ifdef SHARE_STYLECONTEXTS - nsresult StyleContextImpl::ShareStyleData(void) { nsresult result = NS_OK; @@ -3830,38 +3651,19 @@ nsresult StyleContextImpl::ShareStyleData(void) // Enable flag: this is TRUE by default, however the env. var. moz_disable_style_sharing // can be set to '1' to disable the sharing before the app is launched static char *disableSharing = PR_GetEnv("moz_disable_style_sharing"); - static PRBool bEnableSharing = (disableSharing == nsnull) || + static PRBool isSharingEnabled = (disableSharing == nsnull) || (*disableSharing != '1'); #ifdef DEBUG static PRBool bOnce = PR_FALSE; if(!bOnce){ - printf( "Style Data Sharing is %s\n", bEnableSharing ? "Enabled :)" : "Disabled :(" ); + printf( "Style Data Sharing is %s\n", isSharingEnabled ? "Enabled :)" : "Disabled :(" ); bOnce = PR_TRUE; } #endif - PRBool bSharingSupported = PR_TRUE; - if (bEnableSharing) { - // NOTE: sharing of style data for the GfxScrollFrame is problematic - // and is currently disabled. These pseudos indicate the use of a GfxScrollFrame - // so we check for them and disallow sharing when any are found. - // If you haen;t guessed it, this is a total hack until we can figure out - // why the GfxScrollFrame is not happy having its style data shared... - // (See bugzilla bug 39618 which also documents this problem) - if(mPseudoTag) { - if(mPseudoTag == nsLayoutAtoms::viewportPseudo || - mPseudoTag == nsLayoutAtoms::canvasPseudo || - mPseudoTag == nsLayoutAtoms::viewportScrollPseudo || - mPseudoTag == nsLayoutAtoms::scrolledContentPseudo || - mPseudoTag == nsLayoutAtoms::selectScrolledContentPseudo) { - bSharingSupported = PR_FALSE; - } else { - bSharingSupported = PR_TRUE; - } - } - } + PRBool isSharingSupported = CanShareStyleData(this); - if (bEnableSharing && bSharingSupported) { + if (isSharingEnabled && isSharingSupported) { NS_ASSERTION(mStyleSet, "Expected to have a style set ref..."); nsIStyleContext *matchingSC = nsnull; @@ -3883,6 +3685,7 @@ nsresult StyleContextImpl::ShareStyleData(void) return result; } } + // check if there is a matching context... result = mStyleSet->FindMatchingContext(this, &matchingSC); if ((NS_SUCCEEDED(result)) && @@ -3901,7 +3704,13 @@ nsresult StyleContextImpl::ShareStyleData(void) return result; } +#endif // SHARE_STYLECONTEXTS +//------------------------------------------------------------------------------ +// ShareStyleDataFrom +//------------------------------------------------------------------------------ +// +#ifdef SHARE_STYLECONTEXTS nsresult StyleContextImpl::ShareStyleDataFrom(nsIStyleContext*aStyleDataDonor) { nsresult rv = NS_OK; @@ -3921,7 +3730,13 @@ nsresult StyleContextImpl::ShareStyleDataFrom(nsIStyleContext*aStyleDataDonor) } return rv; } +#endif // SHARE_STYLECONTEXTS +//------------------------------------------------------------------------------ +// StyleDataMatches +//------------------------------------------------------------------------------ +// +#ifdef SHARE_STYLECONTEXTS #ifdef DEBUG long gFalsePos=0; long gScreenedByCRC=0; @@ -3977,13 +3792,25 @@ StyleContextImpl::StyleDataMatches(nsIStyleContext* aStyleContextToMatch, } return rv; } +#endif // SHARE_STYLECONTEXTS +//------------------------------------------------------------------------------ +// GetStyleContextKey +//------------------------------------------------------------------------------ +// +#ifdef SHARE_STYLECONTEXTS NS_IMETHODIMP StyleContextImpl::GetStyleContextKey(scKey &aKey) const { aKey = mStyleData->GetCRC32(); return NS_OK; } +#endif // SHARE_STYLECONTEXTS +//------------------------------------------------------------------------------ +// UpdateStyleSetCache +//------------------------------------------------------------------------------ +// +#ifdef SHARE_STYLECONTEXTS nsresult StyleContextImpl::UpdateStyleSetCache( void ) const { if (mStyleSet) { @@ -3993,9 +3820,12 @@ nsresult StyleContextImpl::UpdateStyleSetCache( void ) const return NS_ERROR_FAILURE; } } +#endif // SHARE_STYLECONTEXTS -#endif - +//------------------------------------------------------------------------------ +// Regression tests (List, SizeOf, DumpRegressionData) +//------------------------------------------------------------------------------ +// void StyleContextImpl::List(FILE* out, PRInt32 aIndent) { // Indent @@ -4071,43 +3901,41 @@ void StyleContextImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) static PRBool bDetailDumpDone = PR_FALSE; if (!bDetailDumpDone) { bDetailDumpDone = PR_TRUE; - PRUint32 totalSize=0; - printf( "Detailed StyleContextImpl dump: basic class sizes of members\n" ); - printf( "*************************************\n"); - printf( " - StyleFontImpl: %ld\n", (long)sizeof(GETSCDATA(Font)) ); - totalSize += (long)sizeof(GETSCDATA(Font)); - printf( " - StyleColorImpl: %ld\n", (long)sizeof(GETSCDATA(Color)) ); - totalSize += (long)sizeof(GETSCDATA(Color)); - printf( " - StyleListImpl: %ld\n", (long)sizeof(GETSCDATA(List)) ); - totalSize += (long)sizeof(GETSCDATA(List)); - printf( " - StylePositionImpl: %ld\n", (long)sizeof(GETSCDATA(Position)) ); - totalSize += (long)sizeof(GETSCDATA(Position)); - printf( " - StyleTextImpl: %ld\n", (long)sizeof(GETSCDATA(Text)) ); - totalSize += (long)sizeof(GETSCDATA(Text)); - printf( " - StyleDisplayImpl: %ld\n", (long)sizeof(GETSCDATA(Display)) ); - totalSize += (long)sizeof(GETSCDATA(Display)); - printf( " - StyleTableImpl: %ld\n", (long)sizeof(GETSCDATA(Table)) ); - totalSize += (long)sizeof(GETSCDATA(Table)); - printf( " - StyleContentImpl: %ld\n", (long)sizeof(GETSCDATA(Content)) ); - totalSize += (long)sizeof(GETSCDATA(Content)); - printf( " - StyleUserInterfaceImpl: %ld\n", (long)sizeof(GETSCDATA(UserInterface)) ); - totalSize += (long)sizeof(GETSCDATA(UserInterface)); - printf( " - StylePrintImpl: %ld\n", (long)sizeof(GETSCDATA(Print))); - totalSize += (long)sizeof(GETSCDATA(Print)); - printf( " - StyleMarginImpl: %ld\n", (long)sizeof(GETSCDATA(Margin))); - totalSize += (long)sizeof(GETSCDATA(Margin)); - printf( " - StylePaddingImpl: %ld\n", (long)sizeof(GETSCDATA(Padding))); - totalSize += (long)sizeof(GETSCDATA(Padding)); - printf( " - StyleBorderImpl: %ld\n", (long)sizeof(GETSCDATA(Border))); - totalSize += (long)sizeof(GETSCDATA(Border)); - printf( " - StyleOutlineImpl: %ld\n", (long)sizeof(GETSCDATA(Outline))); - totalSize += (long)sizeof(GETSCDATA(Outline)); + struct sizeInfo { + char* name; + long size; + }; + + static sizeInfo styleDataInfo[eStyleStruct_Max] = { + {"StyleFontBlob", sizeof(STYLEBLOB(Font))} + ,{"StyleColorBlob", sizeof(STYLEBLOB(Color))} + ,{"StyleListBlob", sizeof(STYLEBLOB(List))} + ,{"StylePositionBlob", sizeof(STYLEBLOB(Position))} + ,{"StyleTextBlob", sizeof(STYLEBLOB(Text))} + ,{"StyleDisplayBlob", sizeof(STYLEBLOB(Display))} + ,{"StyleTableBlob", sizeof(STYLEBLOB(Table))} + ,{"StyleContentBlob", sizeof(STYLEBLOB(Content))} + ,{"StyleUserInterfaceBlob", sizeof(STYLEBLOB(UserInterface))} + ,{"StylePrintBlob", sizeof(STYLEBLOB(Print))} + ,{"StyleMarginBlob", sizeof(STYLEBLOB(Margin))} + ,{"StylePaddingBlob", sizeof(STYLEBLOB(Padding))} + ,{"StyleBorderBlob", sizeof(STYLEBLOB(Border))} + ,{"StyleOutlineBlob", sizeof(STYLEBLOB(Outline))} #ifdef INCLUDE_XUL - printf( " - StyleXULImpl: %ld\n", (long)sizeof(GETSCDATA(XUL))); - totalSize += (long)sizeof(GETSCDATA(XUL)); + ,{"StyleXULBlob", sizeof(STYLEBLOB(XUL))} #endif - printf( " - Total: %ld\n", (long)totalSize); + //#insert new style structs here# + }; + + printf("Detailed StyleContextImpl dump: basic class sizes of members\n" ); + printf("*************************************\n"); + PRUint32 totalSize=0; + for (short i = 0; i < eStyleStruct_Max; i ++) { + printf(" - %-24s %ld\n", styleDataInfo[i].name, styleDataInfo[i].size); + totalSize += styleDataInfo[i].size; + } + printf(" - %-24s %ld\n", "Total", totalSize); printf( "*************************************\n"); } @@ -4126,6 +3954,9 @@ void StyleContextImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) tag = getter_AddRefs(NS_NewAtom("StyleContextImpl")); // get the size of an empty instance and add to the sizeof handler aSize = sizeof(*this); +#ifndef SHARE_STYLECONTEXTS + aSize -= sizeof(this->mStyleDataImpl); +#endif // add in the size of the member mPseudoTag if(mPseudoTag){ mPseudoTag->SizeOf(aSizeOfHandler, &localSize); @@ -4133,12 +3964,10 @@ void StyleContextImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) } aSizeOfHandler->AddSize(tag,aSize); -#ifdef SHARE_STYLECONTEXTS // count the style data seperately if (mStyleData) { mStyleData->SizeOf(aSizeOfHandler,localSize); } -#endif // size up the rules (if not already done) // XXX - overhead of the collection??? @@ -4187,169 +4016,178 @@ void StyleContextImpl::DumpRegressionData(nsIPresContext* aPresContext, FILE* ou // FONT IndentBy(out,aIndent); fprintf(out, "\n", - NS_ConvertUCS2toUTF8(GETSCDATA(Font).mFont.name).get(), - NS_ConvertUCS2toUTF8(GETSCDATA(Font).mFixedFont.name).get(), - GETSCDATA(Font).mFlags); + NS_ConvertUCS2toUTF8(GETDATA(Font)->mFont.name).get(), + NS_ConvertUCS2toUTF8(GETDATA(Font)->mFixedFont.name).get(), + GETDATA(Font)->mFlags); // COLOR IndentBy(out,aIndent); fprintf(out, "\n", - (long)GETSCDATA(Color).mColor, - (int)GETSCDATA(Color).mBackgroundAttachment, - (int)GETSCDATA(Color).mBackgroundFlags, - (int)GETSCDATA(Color).mBackgroundRepeat, - (long)GETSCDATA(Color).mBackgroundColor, - (long)GETSCDATA(Color).mBackgroundXPosition, - (long)GETSCDATA(Color).mBackgroundYPosition, - NS_ConvertUCS2toUTF8(GETSCDATA(Color).mBackgroundImage).get(), - (int)GETSCDATA(Color).mCursor, - NS_ConvertUCS2toUTF8(GETSCDATA(Color).mCursorImage).get(), - GETSCDATA(Color).mOpacity); + (long)GETDATA(Color)->mColor, + (int)GETDATA(Color)->mBackgroundAttachment, + (int)GETDATA(Color)->mBackgroundFlags, + (int)GETDATA(Color)->mBackgroundRepeat, + (long)GETDATA(Color)->mBackgroundColor, + (long)GETDATA(Color)->mBackgroundXPosition, + (long)GETDATA(Color)->mBackgroundYPosition, + NS_ConvertUCS2toUTF8(GETDATA(Color)->mBackgroundImage).get(), + (int)GETDATA(Color)->mCursor, + NS_ConvertUCS2toUTF8(GETDATA(Color)->mCursorImage).get(), + GETDATA(Color)->mOpacity); // SPACING (ie. margin, padding, border, outline) IndentBy(out,aIndent); fprintf(out, "mMargin.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Padding).mPadding.ToString(str); + GETDATA(Padding)->mPadding.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Border).mBorder.ToString(str); + GETDATA(Border)->mBorder.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Border).mBorderRadius.ToString(str); + GETDATA(Border)->mBorderRadius.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Outline).mOutlineRadius.ToString(str); + GETDATA(Outline)->mOutlineRadius.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Outline).mOutlineWidth.ToString(str); + GETDATA(Outline)->mOutlineWidth.ToString(str); fprintf(out, "%s", NS_ConvertUCS2toUTF8(str).get()); - fprintf(out, "%d", (int)GETSCDATA(Border).mFloatEdge); + fprintf(out, "%d", (int)GETDATA(Border)->mFloatEdge); fprintf(out, "\" />\n"); // LIST IndentBy(out,aIndent); fprintf(out, "\n", - (int)GETSCDATA(List).mListStyleType, - (int)GETSCDATA(List).mListStyleType, - NS_ConvertUCS2toUTF8(GETSCDATA(List).mListStyleImage).get()); + (int)GETDATA(List)->mListStyleType, + (int)GETDATA(List)->mListStyleType, + NS_ConvertUCS2toUTF8(GETDATA(List)->mListStyleImage).get()); // POSITION IndentBy(out,aIndent); - fprintf(out, "mPosition); + GETDATA(Position)->mOffset.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Position).mWidth.ToString(str); + GETDATA(Position)->mWidth.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Position).mMinWidth.ToString(str); + GETDATA(Position)->mMinWidth.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Position).mMaxWidth.ToString(str); + GETDATA(Position)->mMaxWidth.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Position).mHeight.ToString(str); + GETDATA(Position)->mHeight.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Position).mMinHeight.ToString(str); + GETDATA(Position)->mMinHeight.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Position).mMaxHeight.ToString(str); + GETDATA(Position)->mMaxHeight.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - fprintf(out, "%d ", (int)GETSCDATA(Position).mBoxSizing); - GETSCDATA(Position).mZIndex.ToString(str); + fprintf(out, "%d ", (int)GETDATA(Position)->mBoxSizing); + GETDATA(Position)->mZIndex.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); fprintf(out, "\" />\n"); // TEXT IndentBy(out,aIndent); fprintf(out, "mTextAlign, + (int)GETDATA(Text)->mTextDecoration, + (int)GETDATA(Text)->mTextTransform, + (int)GETDATA(Text)->mWhiteSpace); + GETDATA(Text)->mLetterSpacing.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Text).mLineHeight.ToString(str); + GETDATA(Text)->mLineHeight.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Text).mTextIndent.ToString(str); + GETDATA(Text)->mTextIndent.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Text).mWordSpacing.ToString(str); + GETDATA(Text)->mWordSpacing.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Text).mVerticalAlign.ToString(str); + GETDATA(Text)->mVerticalAlign.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); fprintf(out, "\" />\n"); // DISPLAY IndentBy(out,aIndent); fprintf(out, "\n", - (int)GETSCDATA(Display).mDirection, - (int)GETSCDATA(Display).mDisplay, - (int)GETSCDATA(Display).mFloats, - (int)GETSCDATA(Display).mBreakType, - (int)GETSCDATA(Display).mBreakBefore, - (int)GETSCDATA(Display).mBreakAfter, - (int)GETSCDATA(Display).mVisible, - (int)GETSCDATA(Display).mOverflow, - (int)GETSCDATA(Display).mClipFlags, - (long)GETSCDATA(Display).mClip.x, - (long)GETSCDATA(Display).mClip.y, - (long)GETSCDATA(Display).mClip.width, - (long)GETSCDATA(Display).mClip.height + (int)GETDATA(Display)->mDirection, + (int)GETDATA(Display)->mDisplay, + (int)GETDATA(Display)->mFloats, + (int)GETDATA(Display)->mBreakType, + (int)GETDATA(Display)->mBreakBefore, + (int)GETDATA(Display)->mBreakAfter, + (int)GETDATA(Display)->mVisible, + (int)GETDATA(Display)->mOverflow, + (int)GETDATA(Display)->mClipFlags, + (long)GETDATA(Display)->mClip.x, + (long)GETDATA(Display)->mClip.y, + (long)GETDATA(Display)->mClip.width, + (long)GETDATA(Display)->mClip.height ); // TABLE IndentBy(out,aIndent); fprintf(out, "mLayoutStrategy, + (int)GETDATA(Table)->mFrame, + (int)GETDATA(Table)->mRules, + (int)GETDATA(Table)->mBorderCollapse); + GETDATA(Table)->mBorderSpacingX.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Table).mBorderSpacingY.ToString(str); + GETDATA(Table)->mBorderSpacingY.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Table).mCellPadding.ToString(str); + GETDATA(Table)->mCellPadding.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); fprintf(out, "%d %d %ld %ld ", - (int)GETSCDATA(Table).mCaptionSide, - (int)GETSCDATA(Table).mEmptyCells, - (long)GETSCDATA(Table).mCols, - (long)GETSCDATA(Table).mSpan); - GETSCDATA(Table).mSpanWidth.ToString(str); + (int)GETDATA(Table)->mCaptionSide, + (int)GETDATA(Table)->mEmptyCells, + (long)GETDATA(Table)->mCols, + (long)GETDATA(Table)->mSpan); + GETDATA(Table)->mSpanWidth.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); fprintf(out, "\" />\n"); // CONTENT IndentBy(out,aIndent); fprintf(out, "ContentCount(), + (long)GETDATA(Content)->CounterIncrementCount(), + (long)GETDATA(Content)->CounterResetCount(), + (long)GETDATA(Content)->QuotesCount()); // XXX: iterate over the content, counters and quotes... - GETSCDATA(Content).mMarkerOffset.ToString(str); + GETDATA(Content)->mMarkerOffset.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); fprintf(out, "\" />\n"); // UI IndentBy(out,aIndent); fprintf(out, "\n", - (int)GETSCDATA(UserInterface).mUserInput, - (int)GETSCDATA(UserInterface).mUserModify, - (int)GETSCDATA(UserInterface).mUserSelect, - (int)GETSCDATA(UserInterface).mUserFocus, - (int)GETSCDATA(UserInterface).mKeyEquivalent, - (int)GETSCDATA(UserInterface).mResizer, - NS_ConvertUCS2toUTF8(GETSCDATA(UserInterface).mBehavior).get()); + (int)GETDATA(UserInterface)->mUserInput, + (int)GETDATA(UserInterface)->mUserModify, + (int)GETDATA(UserInterface)->mUserSelect, + (int)GETDATA(UserInterface)->mUserFocus, + (int)GETDATA(UserInterface)->mKeyEquivalent, + (int)GETDATA(UserInterface)->mResizer, + NS_ConvertUCS2toUTF8(GETDATA(UserInterface)->mBehavior).get()); // PRINT IndentBy(out,aIndent); fprintf(out, "mPageBreakBefore, + (int)GETDATA(Print)->mPageBreakAfter, + (int)GETDATA(Print)->mPageBreakInside, + NS_ConvertUCS2toUTF8(GETDATA(Print)->mPage).get(), + (long)GETDATA(Print)->mWidows, + (long)GETDATA(Print)->mOrphans, + (int)GETDATA(Print)->mMarks); + GETDATA(Print)->mSizeWidth.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); fprintf(out, "\" />\n"); + + // XUL +#ifdef INCLUDE_XUL + IndentBy(out,aIndent); + fprintf(out, "mBoxOrient); + fprintf(out, "\" />\n"); +#endif + //#insert new style structs here# } #endif @@ -4381,8 +4219,10 @@ NS_NewStyleContext(nsIStyleContext** aInstancePtrResult, } -//---------------------------------------------------------- - +//------------------------------------------------------------------------------ +// CRC Calculations +//------------------------------------------------------------------------------ +// #ifdef COMPUTE_STYLEDATA_CRC /************************************************************************* * The table lookup technique was adapted from the algorithm described * @@ -4473,41 +4313,6 @@ PRUint32 StyleStringCRC(PRUint32 aCrc, const nsString *aString) } #endif // #ifdef COMPUTE_STYLEDATA_CRC -void EnsureBlockDisplay(/*in out*/PRUint8 &display) -{ - // see if the display value is already a block - switch (display) { - case NS_STYLE_DISPLAY_NONE : - // never change display:none *ever* - break; - - case NS_STYLE_DISPLAY_TABLE : - case NS_STYLE_DISPLAY_BLOCK : - // do not muck with these at all - already blocks - break; - - case NS_STYLE_DISPLAY_LIST_ITEM : - // do not change list items to blocks - retain the bullet/numbering - break; - - case NS_STYLE_DISPLAY_TABLE_ROW_GROUP : - case NS_STYLE_DISPLAY_TABLE_COLUMN : - case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP : - case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP : - case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP : - case NS_STYLE_DISPLAY_TABLE_ROW : - case NS_STYLE_DISPLAY_TABLE_CELL : - case NS_STYLE_DISPLAY_TABLE_CAPTION : - // special cases: don't do anything since these cannot really be floated anyway - break; - - case NS_STYLE_DISPLAY_INLINE_TABLE : - // make inline tables into tables - display = NS_STYLE_DISPLAY_TABLE; - break; - - default : - // make it a block - display = NS_STYLE_DISPLAY_BLOCK; - } -} +#ifdef DEBUG //xxx pierre +#include "nsStyleContextDebug.cpp" +#endif diff --git a/mozilla/content/base/src/nsStyleSet.cpp b/mozilla/content/base/src/nsStyleSet.cpp index 4386d8df339..29edacec713 100644 --- a/mozilla/content/base/src/nsStyleSet.cpp +++ b/mozilla/content/base/src/nsStyleSet.cpp @@ -37,6 +37,7 @@ #include "nsICSSStyleSheet.h" #include "nsNetUtil.h" #include "nsIStyleRuleSupplier.h" +#include "nsISizeOfHandler.h" #ifdef MOZ_PERF_METRICS #include "nsITimeRecorder.h" @@ -49,18 +50,8 @@ #define STYLESET_STOP_TIMER(a) ((void)0) #endif -#include "nsISizeOfHandler.h" - static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID); -// - fast cache uses a CRC32 on the style context to quickly find sharing candidates. -// Enabling it by defining USE_FAST_CACHE makes style sharing significantly faster -// but introduces more code and logic, and is thus potentially more error-prone -// - Enabled by default: disable to determine if there are problems in the fast-cache -// NOTE: make sure the define COMPUTE_STYLEDATA_CRC is ON in nsStyleContext.cpp for -// this to be affective... -#define USE_FAST_CACHE - #ifdef USE_FAST_CACHE /////////////////////////////////////// // DEBUG defines for the fast cache: @@ -78,6 +69,7 @@ static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_I #ifdef USE_FAST_CACHE +#include "nsHashtable.h" PRBool PR_CALLBACK HashTableEnumDestroy(nsHashKey *aKey, void *aData, void* closure); PRBool PR_CALLBACK HashTableEnumDump(nsHashKey *aKey, void *aData, void* closure); PRBool PR_CALLBACK HashTableEnumTickle(nsHashKey *aKey, void *aData, void* closure); diff --git a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp index d9582cbdc74..79c16f427a6 100644 --- a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp +++ b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp @@ -2124,8 +2124,7 @@ MapBdoAttributesInto(const nsIHTMLMappedAttributes* aAttributes, // Get dir attribute aAttributes->GetAttribute(nsHTMLAtoms::dir, value); if (eHTMLUnit_Enumerated == value.GetUnit() ) { - nsStyleText* text = (nsStyleText*) - aStyleContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText text(aStyleContext); text->mUnicodeBidi = NS_STYLE_UNICODE_BIDI_OVERRIDE; } } @@ -2928,8 +2927,7 @@ nsGenericHTMLElement::MapCommonAttributesInto(const nsIHTMLMappedAttributes* aAt nsHTMLValue value; aAttributes->GetAttribute(nsHTMLAtoms::dir, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - nsStyleDisplay* display = (nsStyleDisplay*) - aStyleContext->GetMutableStyleData(eStyleStruct_Display); + nsMutableStyleDisplay display(aStyleContext); display->mDirection = value.GetIntValue(); #ifdef IBMBIDI display->mExplicitDirection = display->mDirection; @@ -2948,8 +2946,7 @@ nsGenericHTMLElement::MapCommonAttributesInto(const nsIHTMLMappedAttributes* aAt return; } } - nsStyleDisplay* display = (nsStyleDisplay*) - aStyleContext->GetMutableStyleData(eStyleStruct_Display); + nsMutableStyleDisplay display(aStyleContext); nsAutoString lang; value.GetStringValue(lang); gLangService->LookupLanguage(lang.GetUnicode(), @@ -2997,10 +2994,8 @@ nsGenericHTMLElement::MapImageAttributesInto(const nsIHTMLMappedAttributes* aAtt float p2t; aPresContext->GetScaledPixelsToTwips(&p2t); - nsStylePosition* pos = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); - nsStyleMargin* margin = (nsStyleMargin*) - aContext->GetMutableStyleData(eStyleStruct_Margin); + nsMutableStylePosition pos(aContext); + nsMutableStyleMargin margin(aContext); // width: value aAttributes->GetAttribute(nsHTMLAtoms::width, value); @@ -3074,12 +3069,9 @@ nsGenericHTMLElement::MapImageAlignAttributeInto(const nsIHTMLMappedAttributes* aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { PRUint8 align = (PRUint8)(value.GetIntValue()); - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); - nsStyleText* text = (nsStyleText*) - aContext->GetMutableStyleData(eStyleStruct_Text); - nsStyleMargin* margin = (nsStyleMargin*) - aContext->GetMutableStyleData(eStyleStruct_Margin); + nsMutableStyleDisplay display(aContext); + nsMutableStyleText text(aContext); + nsMutableStyleMargin margin(aContext); float p2t; aPresContext->GetScaledPixelsToTwips(&p2t); nsStyleCoord three(NSIntPixelsToTwips(3, p2t)); @@ -3141,8 +3133,7 @@ nsGenericHTMLElement::MapImageBorderAttributeInto(const nsIHTMLMappedAttributes* // Fixup border-padding sums: subtract out the old size and then // add in the new size. - nsStyleBorder* border = (nsStyleBorder*) - aContext->GetMutableStyleData(eStyleStruct_Border); + nsMutableStyleBorder border(aContext); nsStyleCoord coord; coord.SetCoordValue(twips); @@ -3218,8 +3209,7 @@ nsGenericHTMLElement::MapBackgroundAttributesInto(const nsIHTMLMappedAttributes* getter_AddRefs(docURL)); rv = NS_MakeAbsoluteURI(absURLSpec, spec, docURL); if (NS_SUCCEEDED(rv)) { - nsStyleColor* color = (nsStyleColor*) - aContext->GetMutableStyleData(eStyleStruct_Color); + nsMutableStyleColor color(aContext); color->mBackgroundImage = absURLSpec; color->mBackgroundFlags &= ~NS_STYLE_BG_IMAGE_NONE; color->mBackgroundRepeat = NS_STYLE_BG_REPEAT_XY; @@ -3233,8 +3223,7 @@ nsGenericHTMLElement::MapBackgroundAttributesInto(const nsIHTMLMappedAttributes* aPresContext->GetCompatibilityMode(&mode); if (eCompatibility_NavQuirks == mode && eHTMLUnit_Empty == value.GetUnit()) { - nsStyleColor* color; - color = (nsStyleColor*)aContext->GetMutableStyleData(eStyleStruct_Color); + nsMutableStyleColor color(aContext); color->mBackgroundImage.Truncate(); color->mBackgroundFlags &= ~NS_STYLE_BG_IMAGE_NONE; color->mBackgroundRepeat = NS_STYLE_BG_REPEAT_XY; @@ -3246,8 +3235,7 @@ nsGenericHTMLElement::MapBackgroundAttributesInto(const nsIHTMLMappedAttributes* if (NS_CONTENT_ATTR_HAS_VALUE == aAttributes->GetAttribute(nsHTMLAtoms::bgcolor, value)) { if ((eHTMLUnit_Color == value.GetUnit()) || (eHTMLUnit_ColorName == value.GetUnit())) { - nsStyleColor* color = (nsStyleColor*) - aContext->GetMutableStyleData(eStyleStruct_Color); + nsMutableStyleColor color(aContext); color->mBackgroundColor = value.GetColorValue(); color->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; } diff --git a/mozilla/content/html/content/src/nsHTMLBRElement.cpp b/mozilla/content/html/content/src/nsHTMLBRElement.cpp index 69f733ad537..184a9adca75 100644 --- a/mozilla/content/html/content/src/nsHTMLBRElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLBRElement.cpp @@ -182,12 +182,10 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, nsIMutableStyleContext* aContext, nsIPresContext* aPresContext) { - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); - nsHTMLValue value; aAttributes->GetAttribute(nsHTMLAtoms::clear, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { + nsMutableStyleDisplay display(aContext); display->mBreakType = value.GetIntValue(); } nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, diff --git a/mozilla/content/html/content/src/nsHTMLBodyElement.cpp b/mozilla/content/html/content/src/nsHTMLBodyElement.cpp index 25f001931f7..b73bdfae808 100644 --- a/mozilla/content/html/content/src/nsHTMLBodyElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLBodyElement.cpp @@ -273,7 +273,7 @@ BodyRule::MapFontStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext) { // set up the basefont (defaults to 3) - nsStyleFont* font = (nsStyleFont*)aContext->GetMutableStyleData(eStyleStruct_Font); + nsMutableStyleFont font(aContext); PRInt32 scaler; aPresContext->GetFontScaler(&scaler); float scaleFactor = nsStyleUtil::GetScalingFactor(scaler); @@ -295,9 +295,9 @@ BodyRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext) { if (mPart) { - nsStyleMargin* marginStyle = (nsStyleMargin*)(aContext->GetMutableStyleData(eStyleStruct_Margin)); + nsMutableStyleMargin marginStyle(aContext); - if (nsnull != marginStyle) { + { nsHTMLValue value; PRInt32 attrCount; float p2t; @@ -514,18 +514,12 @@ BodyFixupRule::MapStyleInto(nsIMutableStyleContext* aContext, // get the context data for the background information PRBool bFixedBackground = PR_FALSE; - nsStyleColor* canvasStyleColor; - nsStyleColor* htmlStyleColor; - nsStyleColor* bodyStyleColor; - bodyStyleColor = (nsStyleColor*)aContext->GetMutableStyleData(eStyleStruct_Color); - htmlStyleColor = (nsStyleColor*)parentContext->GetMutableStyleData(eStyleStruct_Color); - canvasStyleColor = (nsStyleColor*)canvasContext->GetMutableStyleData(eStyleStruct_Color); - nsStyleColor* styleColor = bodyStyleColor; // default to BODY - NS_ASSERTION(bodyStyleColor && htmlStyleColor && canvasStyleColor, "null context data"); - if (!(bodyStyleColor && htmlStyleColor && canvasStyleColor)){ - return NS_ERROR_FAILURE; - } + nsMutableStyleColor canvasStyleColor(canvasContext.get()); + nsMutableStyleColor htmlStyleColor(parentContext.get()); + nsMutableStyleColor bodyStyleColor(aContext); + + nsStyleColor* styleColor = bodyStyleColor.get(); // default to BODY // Use the CSS precedence rules for dealing with background: if the value // of the 'background' property for the HTML element is different from @@ -545,9 +539,9 @@ BodyFixupRule::MapStyleInto(nsIMutableStyleContext* aContext, // if HTML background is not transparent then we use its background for the canvas, // otherwise we use the BODY's background if (!(htmlStyleColor->BackgroundIsTransparent())) { - styleColor = htmlStyleColor; + styleColor = htmlStyleColor.get(); } else if (!(bodyStyleColor->BackgroundIsTransparent())) { - styleColor = bodyStyleColor; + styleColor = bodyStyleColor.get(); } else { PRBool isPaginated = PR_FALSE; aPresContext->IsPaginated(&isPaginated); @@ -575,7 +569,7 @@ BodyFixupRule::MapStyleInto(nsIMutableStyleContext* aContext, canvasStyleColor->mBackgroundAttachment == NS_STYLE_BG_ATTACHMENT_FIXED ? PR_TRUE : PR_FALSE; // only reset the background values if we used something other than the default canvas style - if (styleColor == htmlStyleColor || styleColor == bodyStyleColor) { + if (styleColor == htmlStyleColor.get() || styleColor == bodyStyleColor.get()) { // reset the background values for the context that was propogated styleColor->mBackgroundImage.SetLength(0); styleColor->mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; @@ -589,7 +583,7 @@ BodyFixupRule::MapStyleInto(nsIMutableStyleContext* aContext, // nsCSSStyleRule.cpp MapDeclarationColorInto) } - if (styleColor == bodyStyleColor) { + if (styleColor == bodyStyleColor.get()) { htmlStyleColor->mBackgroundFlags |= NS_STYLE_BG_PROPAGATED_TO_PARENT; } } @@ -598,11 +592,11 @@ BodyFixupRule::MapStyleInto(nsIMutableStyleContext* aContext, // use the nsStyleColor that we would have used before the fix to // bug 67478. nsStyleColor* documentStyleColor = styleColor; - if (bodyStyleColor != styleColor && htmlStyleColor != styleColor) { + if (bodyStyleColor.get() != styleColor && htmlStyleColor.get() != styleColor) { nsCompatibility mode; aPresContext->GetCompatibilityMode(&mode); if (eCompatibility_NavQuirks == mode) - documentStyleColor = bodyStyleColor; + documentStyleColor = bodyStyleColor.get(); } nsCOMPtr presShell; @@ -883,8 +877,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aAttributes->GetAttribute(nsHTMLAtoms::text, value); if ((eHTMLUnit_Color == value.GetUnit()) || (eHTMLUnit_ColorName == value.GetUnit())){ - nsStyleColor* color = (nsStyleColor*) - aContext->GetMutableStyleData(eStyleStruct_Color); + nsMutableStyleColor color(aContext); color->mColor = value.GetColorValue(); } diff --git a/mozilla/content/html/content/src/nsHTMLDirectoryElement.cpp b/mozilla/content/html/content/src/nsHTMLDirectoryElement.cpp index 961826667eb..49da5d13859 100644 --- a/mozilla/content/html/content/src/nsHTMLDirectoryElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLDirectoryElement.cpp @@ -188,8 +188,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, { if (nsnull != aAttributes) { nsHTMLValue value; - nsStyleList* list = (nsStyleList*) - aContext->GetMutableStyleData(eStyleStruct_List); + nsMutableStyleList list(aContext); // type: enum aAttributes->GetAttribute(nsHTMLAtoms::type, value); diff --git a/mozilla/content/html/content/src/nsHTMLDivElement.cpp b/mozilla/content/html/content/src/nsHTMLDivElement.cpp index 874714f9f8c..1a020d4e626 100644 --- a/mozilla/content/html/content/src/nsHTMLDivElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLDivElement.cpp @@ -199,8 +199,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, nsHTMLValue value; aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - nsStyleText* text = (nsStyleText*) - aContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText text(aContext); text->mTextAlign = value.GetIntValue(); } } diff --git a/mozilla/content/html/content/src/nsHTMLFontElement.cpp b/mozilla/content/html/content/src/nsHTMLFontElement.cpp index 2e9ba786014..219d3ececa8 100644 --- a/mozilla/content/html/content/src/nsHTMLFontElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLFontElement.cpp @@ -218,9 +218,8 @@ MapFontAttributesInto(const nsIHTMLMappedAttributes* aAttributes, { if (nsnull != aAttributes) { nsHTMLValue value; - nsStyleFont* font = (nsStyleFont*) - aContext->GetMutableStyleData(eStyleStruct_Font); - const nsStyleFont* parentFont = font; + nsMutableStyleFont font(aContext); + const nsStyleFont* parentFont = font.get(); nsIStyleContext* parentContext = aContext->GetParent(); if (nsnull != parentContext) { parentFont = (const nsStyleFont*) @@ -398,10 +397,8 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aAttributes->GetAttribute(nsHTMLAtoms::color, value)) { const nsStyleFont* font = (const nsStyleFont*) aContext->GetStyleData(eStyleStruct_Font); - nsStyleColor* color = (nsStyleColor*) - aContext->GetMutableStyleData(eStyleStruct_Color); - nsStyleText* text = (nsStyleText*) - aContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleColor color(aContext); + nsMutableStyleText text(aContext); if (((eHTMLUnit_Color == value.GetUnit())) || (eHTMLUnit_ColorName == value.GetUnit())) { color->mColor = value.GetColorValue(); diff --git a/mozilla/content/html/content/src/nsHTMLHRElement.cpp b/mozilla/content/html/content/src/nsHTMLHRElement.cpp index acf8bae427d..02a4c844d32 100644 --- a/mozilla/content/html/content/src/nsHTMLHRElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLHRElement.cpp @@ -207,8 +207,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (eHTMLUnit_Enumerated == value.GetUnit()) { // Map align attribute into auto side margins - nsStyleMargin* margin = (nsStyleMargin*) - aContext->GetMutableStyleData(eStyleStruct_Margin); + nsMutableStyleMargin margin(aContext); nsStyleCoord otto(eStyleUnit_Auto); nsStyleCoord zero(nscoord(0)); switch (value.GetIntValue()) { @@ -230,8 +229,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, // width: pixel, percent float p2t; aPresContext->GetScaledPixelsToTwips(&p2t); - nsStylePosition* pos = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); + nsMutableStylePosition pos(aContext); aAttributes->GetAttribute(nsHTMLAtoms::width, value); if (eHTMLUnit_Pixel == value.GetUnit()) { nscoord twips = NSIntPixelsToTwips(value.GetPixelValue(), p2t); diff --git a/mozilla/content/html/content/src/nsHTMLHeadingElement.cpp b/mozilla/content/html/content/src/nsHTMLHeadingElement.cpp index 1b38a395e03..bca2a3e8843 100644 --- a/mozilla/content/html/content/src/nsHTMLHeadingElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLHeadingElement.cpp @@ -182,8 +182,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, nsHTMLValue value; aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - nsStyleText* text = (nsStyleText*) - aContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText text(aContext); text->mTextAlign = value.GetIntValue(); } } diff --git a/mozilla/content/html/content/src/nsHTMLIFrameElement.cpp b/mozilla/content/html/content/src/nsHTMLIFrameElement.cpp index 2f1c1824d2d..4dd7a40a0aa 100644 --- a/mozilla/content/html/content/src/nsHTMLIFrameElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLIFrameElement.cpp @@ -282,8 +282,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, float p2t; aPresContext->GetScaledPixelsToTwips(&p2t); - nsStylePosition* pos = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); + nsMutableStylePosition pos(aContext); // width: value aAttributes->GetAttribute(nsHTMLAtoms::width, value); @@ -314,16 +313,13 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, if (NS_STYLE_FRAME_0 == frameborder || NS_STYLE_FRAME_NO == frameborder || NS_STYLE_FRAME_OFF == frameborder) { - nsStyleBorder* border = (nsStyleBorder*) - aContext->GetMutableStyleData(eStyleStruct_Border); - if (border) { - nsStyleCoord coord; - coord.SetCoordValue(0); - border->mBorder.SetTop(coord); - border->mBorder.SetRight(coord); - border->mBorder.SetBottom(coord); - border->mBorder.SetLeft(coord); - } + nsMutableStyleBorder border(aContext); + nsStyleCoord coord; + coord.SetCoordValue(0); + border->mBorder.SetTop(coord); + border->mBorder.SetRight(coord); + border->mBorder.SetBottom(coord); + border->mBorder.SetLeft(coord); } } } diff --git a/mozilla/content/html/content/src/nsHTMLImageElement.cpp b/mozilla/content/html/content/src/nsHTMLImageElement.cpp index 2f73637dcec..c5aa9348598 100644 --- a/mozilla/content/html/content/src/nsHTMLImageElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLImageElement.cpp @@ -573,10 +573,8 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { PRUint8 align = value.GetIntValue(); - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); - nsStyleText* text = (nsStyleText*) - aContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleDisplay display(aContext); + nsMutableStyleText text(aContext); switch (align) { case NS_STYLE_TEXT_ALIGN_LEFT: display->mFloats = NS_STYLE_FLOAT_LEFT; diff --git a/mozilla/content/html/content/src/nsHTMLInputElement.cpp b/mozilla/content/html/content/src/nsHTMLInputElement.cpp index e90e98868a5..0148df6c85e 100644 --- a/mozilla/content/html/content/src/nsHTMLInputElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLInputElement.cpp @@ -1361,10 +1361,8 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (eHTMLUnit_Enumerated == value.GetUnit()) { - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); - nsStyleText* text = (nsStyleText*) - aContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleDisplay display(aContext); + nsMutableStyleText text(aContext); switch (value.GetIntValue()) { case NS_STYLE_TEXT_ALIGN_LEFT: display->mFloats = NS_STYLE_FLOAT_LEFT; @@ -1394,7 +1392,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, nscoord pad = NSIntPixelsToTwips(3, p2t); // add left and right padding around the radio button via css - nsStyleMargin* margin = (nsStyleMargin*) aContext->GetMutableStyleData(eStyleStruct_Margin); + nsMutableStyleMargin margin(aContext); if (eStyleUnit_Null == margin->mMargin.GetLeftUnit()) { nsStyleCoord left(pad); margin->mMargin.SetLeft(left); diff --git a/mozilla/content/html/content/src/nsHTMLLIElement.cpp b/mozilla/content/html/content/src/nsHTMLLIElement.cpp index f0de10941ab..738ac88b7f9 100644 --- a/mozilla/content/html/content/src/nsHTMLLIElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLLIElement.cpp @@ -206,12 +206,11 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, { if (nsnull != aAttributes) { nsHTMLValue value; - nsStyleList* list = (nsStyleList*) - aContext->GetMutableStyleData(eStyleStruct_List); // type: enum aAttributes->GetAttribute(nsHTMLAtoms::type, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { + nsMutableStyleList list(aContext); list->mListStyleType = value.GetIntValue(); } } diff --git a/mozilla/content/html/content/src/nsHTMLMenuElement.cpp b/mozilla/content/html/content/src/nsHTMLMenuElement.cpp index 50c999aeea9..9e53db8da4a 100644 --- a/mozilla/content/html/content/src/nsHTMLMenuElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLMenuElement.cpp @@ -188,8 +188,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, { if (nsnull != aAttributes) { nsHTMLValue value; - nsStyleList* list = (nsStyleList*) - aContext->GetMutableStyleData(eStyleStruct_List); + nsMutableStyleList list(aContext); // type: enum aAttributes->GetAttribute(nsHTMLAtoms::type, value); diff --git a/mozilla/content/html/content/src/nsHTMLOListElement.cpp b/mozilla/content/html/content/src/nsHTMLOListElement.cpp index 22ffdd53d7f..f6dc2f539d9 100644 --- a/mozilla/content/html/content/src/nsHTMLOListElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLOListElement.cpp @@ -225,8 +225,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, { if (nsnull != aAttributes) { nsHTMLValue value; - nsStyleList* list = (nsStyleList*) - aContext->GetMutableStyleData(eStyleStruct_List); + nsMutableStyleList list(aContext); // type: enum aAttributes->GetAttribute(nsHTMLAtoms::type, value); diff --git a/mozilla/content/html/content/src/nsHTMLParagraphElement.cpp b/mozilla/content/html/content/src/nsHTMLParagraphElement.cpp index ee106b912cf..f47f68a5a21 100644 --- a/mozilla/content/html/content/src/nsHTMLParagraphElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLParagraphElement.cpp @@ -183,8 +183,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, nsHTMLValue value; aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - nsStyleText* text = (nsStyleText*) - aContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText text(aContext); text->mTextAlign = value.GetIntValue(); } } diff --git a/mozilla/content/html/content/src/nsHTMLPreElement.cpp b/mozilla/content/html/content/src/nsHTMLPreElement.cpp index 8ad4bd738ea..c2bc4225fb9 100644 --- a/mozilla/content/html/content/src/nsHTMLPreElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLPreElement.cpp @@ -185,8 +185,7 @@ MapFontAttributesInto(const nsIHTMLMappedAttributes* aAttributes, // variable: empty aAttributes->GetAttribute(nsHTMLAtoms::variable, value); if (value.GetUnit() == eHTMLUnit_Empty) { - nsStyleFont* font = (nsStyleFont*) - aContext->GetMutableStyleData(eStyleStruct_Font); + nsMutableStyleFont font(aContext); font->mFont.name.AssignWithConversion("serif"); } } @@ -203,34 +202,29 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, // wrap: empty aAttributes->GetAttribute(nsHTMLAtoms::wrap, value); if (value.GetUnit() != eHTMLUnit_Null) { - nsStyleText* text = (nsStyleText*) - aContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText text(aContext); text->mWhiteSpace = NS_STYLE_WHITESPACE_MOZ_PRE_WRAP; } // cols: int (nav4 attribute) aAttributes->GetAttribute(nsHTMLAtoms::cols, value); if (value.GetUnit() == eHTMLUnit_Integer) { - nsStylePosition* position = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); + nsMutableStylePosition position(aContext); position->mWidth.SetIntValue(value.GetIntValue(), eStyleUnit_Chars); // Force wrap property on since we want to wrap at a width // boundary not just a newline. - nsStyleText* text = (nsStyleText*) - aContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText text(aContext); text->mWhiteSpace = NS_STYLE_WHITESPACE_MOZ_PRE_WRAP; } // width: int (html4 attribute == nav4 cols) aAttributes->GetAttribute(nsHTMLAtoms::width, value); if (value.GetUnit() == eHTMLUnit_Integer) { - nsStylePosition* position = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); + nsMutableStylePosition position(aContext); position->mWidth.SetIntValue(value.GetIntValue(), eStyleUnit_Chars); // Force wrap property on since we want to wrap at a width // boundary not just a newline. - nsStyleText* text = (nsStyleText*) - aContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText text(aContext); text->mWhiteSpace = NS_STYLE_WHITESPACE_MOZ_PRE_WRAP; } diff --git a/mozilla/content/html/content/src/nsHTMLSelectElement.cpp b/mozilla/content/html/content/src/nsHTMLSelectElement.cpp index f8be5d22eea..764c25756e1 100644 --- a/mozilla/content/html/content/src/nsHTMLSelectElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLSelectElement.cpp @@ -1363,21 +1363,23 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (eHTMLUnit_Enumerated == value.GetUnit()) { - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); - nsStyleText* text = (nsStyleText*) - aContext->GetMutableStyleData(eStyleStruct_Text); switch (value.GetIntValue()) { - case NS_STYLE_TEXT_ALIGN_LEFT: + case NS_STYLE_TEXT_ALIGN_LEFT: { + nsMutableStyleDisplay display(aContext); display->mFloats = NS_STYLE_FLOAT_LEFT; break; - case NS_STYLE_TEXT_ALIGN_RIGHT: + } + case NS_STYLE_TEXT_ALIGN_RIGHT: { + nsMutableStyleDisplay display(aContext); display->mFloats = NS_STYLE_FLOAT_RIGHT; break; - default: + } + default: { + nsMutableStyleText text(aContext); text->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); break; + } } } diff --git a/mozilla/content/html/content/src/nsHTMLSpacerElement.cpp b/mozilla/content/html/content/src/nsHTMLSpacerElement.cpp index 5688351e551..4833f26124f 100644 --- a/mozilla/content/html/content/src/nsHTMLSpacerElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLSpacerElement.cpp @@ -204,10 +204,8 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, if (aAttributes && aPresContext && aContext) { nsHTMLValue value; - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); - nsStylePosition* position = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); + nsMutableStyleDisplay display(aContext); + nsMutableStylePosition position(aContext); aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (eHTMLUnit_Enumerated == value.GetUnit()) { switch (value.GetIntValue()) { diff --git a/mozilla/content/html/content/src/nsHTMLTableCaptionElement.cpp b/mozilla/content/html/content/src/nsHTMLTableCaptionElement.cpp index 3358771618d..9cc8b66a1b0 100644 --- a/mozilla/content/html/content/src/nsHTMLTableCaptionElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLTableCaptionElement.cpp @@ -192,9 +192,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, if (value.GetUnit() == eHTMLUnit_Enumerated) { PRUint8 align = value.GetIntValue(); - nsStyleTable* tableStyle = (nsStyleTable*) - aContext->GetMutableStyleData(eStyleStruct_Table); - + nsMutableStyleTable tableStyle(aContext); tableStyle->mCaptionSide = align; } } diff --git a/mozilla/content/html/content/src/nsHTMLTableCellElement.cpp b/mozilla/content/html/content/src/nsHTMLTableCellElement.cpp index 60776827129..6d6ec0bd11c 100644 --- a/mozilla/content/html/content/src/nsHTMLTableCellElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLTableCellElement.cpp @@ -460,56 +460,81 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, if (nsnull!=aAttributes) { nsHTMLValue value; nsHTMLValue widthValue; - nsStyleText* textStyle = nsnull; + + PRUint8 newTextAlign; + nsStyleCoord newVerticalAlign; + PRUint8 newWhiteSpace; + PRBool changedTextAlign = PR_FALSE; + PRBool changedVerticalAlign = PR_FALSE; + PRBool changedWhiteSpace = PR_FALSE; // align: enum aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); - textStyle->mTextAlign = value.GetIntValue(); + newTextAlign = value.GetIntValue(); + changedTextAlign = PR_TRUE; } // valign: enum aAttributes->GetAttribute(nsHTMLAtoms::valign, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - if (nsnull==textStyle) - textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); - textStyle->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); + newVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); + changedVerticalAlign = PR_TRUE; } - float p2t; - aPresContext->GetScaledPixelsToTwips(&p2t); - nsStylePosition* pos = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); - aAttributes->GetAttribute(nsHTMLAtoms::width, widthValue); + // width and height + { + nsStyleCoord newWidth; + nsStyleCoord newHeight; + PRBool changedWidth = PR_FALSE; + PRBool changedHeight = PR_FALSE; - if (widthValue.GetUnit() == eHTMLUnit_Pixel) { // width: pixel - nscoord width = widthValue.GetPixelValue(); + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); + aAttributes->GetAttribute(nsHTMLAtoms::width, widthValue); - if (width > 0) { - nscoord twips = NSIntPixelsToTwips(width, p2t); - pos->mWidth.SetCoordValue(twips); + if (widthValue.GetUnit() == eHTMLUnit_Pixel) { // width: pixel + nscoord width = widthValue.GetPixelValue(); + + if (width > 0) { + nscoord twips = NSIntPixelsToTwips(width, p2t); + newWidth.SetCoordValue(twips); + changedWidth = PR_TRUE; + } + // else, 0 implies AUTO for compatibility } - // else, 0 implies AUTO for compatibility - } - else if (widthValue.GetUnit() == eHTMLUnit_Percent) { // width: percent - float widthPercent = widthValue.GetPercentValue(); - if (widthPercent > 0.0f) { - pos->mWidth.SetPercentValue(widthPercent); + else if (widthValue.GetUnit() == eHTMLUnit_Percent) { // width: percent + float widthPercent = widthValue.GetPercentValue(); + if (widthPercent > 0.0f) { + newWidth.SetPercentValue(widthPercent); + changedWidth = PR_TRUE; + } + // else, 0 implies AUTO for compatibility } - // else, 0 implies AUTO for compatibility - } - // height: pixel - aAttributes->GetAttribute(nsHTMLAtoms::height, value); - if (value.GetUnit() == eHTMLUnit_Pixel) { // height: pixel - nscoord height = value.GetPixelValue(); - nscoord twips = NSIntPixelsToTwips(height, p2t); - pos->mHeight.SetCoordValue(twips); - } - else if (value.GetUnit() == eHTMLUnit_Percent) { // height: percent - float heightPercent = value.GetPercentValue(); - pos->mHeight.SetPercentValue(heightPercent); + // height: pixel + aAttributes->GetAttribute(nsHTMLAtoms::height, value); + if (value.GetUnit() == eHTMLUnit_Pixel) { // height: pixel + nscoord height = value.GetPixelValue(); + nscoord twips = NSIntPixelsToTwips(height, p2t); + newHeight.SetCoordValue(twips); + changedHeight = PR_TRUE; + } + else if (value.GetUnit() == eHTMLUnit_Percent) { // height: percent + float heightPercent = value.GetPercentValue(); + newHeight.SetPercentValue(heightPercent); + changedHeight = PR_TRUE; + } + + if (changedWidth || changedHeight) { + nsMutableStylePosition pos(aContext); + if (changedWidth) { + pos->mWidth = newWidth; + } + if (changedHeight) { + pos->mHeight = newHeight; + } + } } // nowrap @@ -520,12 +545,26 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, if (value.GetUnit() != eHTMLUnit_Null) { if (widthValue.GetUnit() != eHTMLUnit_Pixel) { - if (nsnull==textStyle) - textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); - textStyle->mWhiteSpace = NS_STYLE_WHITESPACE_NOWRAP; + newWhiteSpace = NS_STYLE_WHITESPACE_NOWRAP; + changedWhiteSpace = PR_TRUE; } } + // write style changes + if (changedTextAlign || changedVerticalAlign || changedWhiteSpace) { + nsMutableStyleText text(aContext); + if (changedTextAlign) { + text->mTextAlign = newTextAlign; + } + if (changedVerticalAlign) { + text->mVerticalAlign = newVerticalAlign; + } + if (changedWhiteSpace) { + text->mWhiteSpace = newWhiteSpace; + } + } + + // generic mapping nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aContext, aPresContext); nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, diff --git a/mozilla/content/html/content/src/nsHTMLTableColElement.cpp b/mozilla/content/html/content/src/nsHTMLTableColElement.cpp index d761f4c6490..697cc2aaf62 100644 --- a/mozilla/content/html/content/src/nsHTMLTableColElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLTableColElement.cpp @@ -236,15 +236,12 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, if (aAttributes) { nsHTMLValue value; - nsStyleText* textStyle = nsnull; // width aAttributes->GetAttribute(nsHTMLAtoms::width, value); if (value.GetUnit() != eHTMLUnit_Null) { - nsStylePosition* position = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); - + nsMutableStylePosition position(aContext); switch (value.GetUnit()) { case eHTMLUnit_Percent: position->mWidth.SetPercentValue(value.GetPercentValue()); @@ -264,26 +261,39 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, } } + PRUint8 newTextAlign; + nsStyleCoord newVerticalAlign; + PRBool changedTextAlign = PR_FALSE; + PRBool changedVerticalAlign = PR_FALSE; + // align: enum aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); - textStyle->mTextAlign = value.GetIntValue(); + newTextAlign = value.GetIntValue(); + changedTextAlign = PR_TRUE; } // valign: enum aAttributes->GetAttribute(nsHTMLAtoms::valign, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - if (nsnull==textStyle) - textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); - textStyle->mVerticalAlign.SetIntValue(value.GetIntValue(), - eStyleUnit_Enumerated); + newVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); + changedVerticalAlign = PR_TRUE; + } + + if (changedTextAlign || changedVerticalAlign) { + nsMutableStyleText text(aContext); + if (changedTextAlign) { + text->mTextAlign = newTextAlign; + } + if (changedVerticalAlign) { + text->mVerticalAlign = newVerticalAlign; + } } // span: int aAttributes->GetAttribute(nsHTMLAtoms::span, value); if (value.GetUnit() == eHTMLUnit_Integer) { - nsStyleTable *tableStyle = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); + nsMutableStyleTable tableStyle(aContext); tableStyle->mSpan = value.GetIntValue(); } } diff --git a/mozilla/content/html/content/src/nsHTMLTableColGroupElement.cpp b/mozilla/content/html/content/src/nsHTMLTableColGroupElement.cpp index d027c7115c5..3eabe2a2b57 100644 --- a/mozilla/content/html/content/src/nsHTMLTableColGroupElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLTableColGroupElement.cpp @@ -233,14 +233,12 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, if (nsnull != aAttributes) { nsHTMLValue value; - nsStyleText* textStyle = nsnull; // width aAttributes->GetAttribute(nsHTMLAtoms::width, value); if (value.GetUnit() != eHTMLUnit_Null) { - nsStylePosition* position = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); + nsMutableStylePosition position(aContext); switch (value.GetUnit()) { case eHTMLUnit_Percent: position->mWidth.SetPercentValue(value.GetPercentValue()); @@ -262,21 +260,34 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, } } + PRUint8 newTextAlign; + nsStyleCoord newVerticalAlign; + PRBool changedTextAlign = PR_FALSE; + PRBool changedVerticalAlign = PR_FALSE; + // align: enum aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); - textStyle->mTextAlign = value.GetIntValue(); + newTextAlign = value.GetIntValue(); + changedTextAlign = PR_TRUE; } // valign: enum aAttributes->GetAttribute(nsHTMLAtoms::valign, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - if (nsnull==textStyle) - textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); - textStyle->mVerticalAlign.SetIntValue(value.GetIntValue(), - eStyleUnit_Enumerated); + newVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); + changedVerticalAlign = PR_TRUE; + } + + if (changedTextAlign || changedVerticalAlign) { + nsMutableStyleText text(aContext); + if (changedTextAlign) { + text->mTextAlign = newTextAlign; + } + if (changedVerticalAlign) { + text->mVerticalAlign = newVerticalAlign; + } } } diff --git a/mozilla/content/html/content/src/nsHTMLTableElement.cpp b/mozilla/content/html/content/src/nsHTMLTableElement.cpp index 894a0e288f2..e96afc16272 100644 --- a/mozilla/content/html/content/src/nsHTMLTableElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLTableElement.cpp @@ -1151,10 +1151,8 @@ MapTableBorderInto(const nsIHTMLMappedAttributes* aAttributes, } if (borderValue.GetUnit() != eHTMLUnit_Null) { - nsStyleBorder* border = (nsStyleBorder*) - aContext->GetMutableStyleData(eStyleStruct_Border); - nsStyleTable *tableStyle = (nsStyleTable*) - aContext->GetMutableStyleData(eStyleStruct_Table); + nsMutableStyleBorder border(aContext); + nsMutableStyleTable tableStyle(aContext); nsStyleCoord twips; float p2t; @@ -1188,7 +1186,7 @@ MapTableBorderInto(const nsIHTMLMappedAttributes* aAttributes, border->mBorder.SetBottom(twips); border->mBorder.SetLeft(twips); // then account for the frame attribute - MapTableFrameInto(aAttributes, aContext, aPresContext, border, + MapTableFrameInto(aAttributes, aContext, aPresContext, border.get(), aBorderStyle); } } @@ -1219,7 +1217,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aPresContext->GetPixelsToTwips(&p2t); nscoord onePixel = NSIntPixelsToTwips(1, p2t); - nsStyleBorder* borderStyleData = (nsStyleBorder*)aContext->GetMutableStyleData(eStyleStruct_Border); + nsMutableStyleBorder borderStyleData(aContext); nsStyleCoord width; width.SetCoordValue(onePixel); @@ -1246,8 +1244,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aAttributes->GetAttribute(nsHTMLAtoms::width, value); if (value.GetUnit() != eHTMLUnit_Null) { - nsStylePosition* position = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); + nsMutableStylePosition position(aContext); switch (value.GetUnit()) { case eHTMLUnit_Percent: @@ -1273,8 +1270,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aAttributes->GetAttribute(nsHTMLAtoms::height, value); if (value.GetUnit() != eHTMLUnit_Null) { - nsStylePosition* position = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); + nsMutableStylePosition position(aContext); switch (value.GetUnit()) { case eHTMLUnit_Percent: position->mHeight.SetPercentValue(value.GetPercentValue()); @@ -1289,11 +1285,6 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, } } - nsStyleBorder* borderStyleData = (nsStyleBorder*) - aContext->GetMutableStyleData(eStyleStruct_Border); - nsStyleMargin* marginStyleData = (nsStyleMargin*) - aContext->GetMutableStyleData(eStyleStruct_Margin); - // default border style is the Nav4.6 extension which uses the // background color as the basis of the outset border. If the // table has a transparant background then it finds the closest @@ -1314,6 +1305,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, if ((eHTMLUnit_Color == value.GetUnit()) || (eHTMLUnit_ColorName == value.GetUnit())) { nscolor color = value.GetColorValue(); + nsMutableStyleBorder borderStyleData(aContext); borderStyleData->SetBorderColor(0, color); borderStyleData->SetBorderColor(1, color); borderStyleData->SetBorderColor(2, color); @@ -1326,6 +1318,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, // align; Check for enumerated type (it may be another type if // illegal) + nsMutableStyleMargin marginStyleData(aContext); aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { @@ -1336,8 +1329,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, marginStyleData->mMargin.SetRight(otto); } else { - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); + nsMutableStyleDisplay display(aContext); switch (value.GetIntValue()) { case NS_STYLE_TEXT_ALIGN_LEFT: @@ -1353,25 +1345,22 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, } } + { + nsMutableStyleTable tableStyle(aContext); + // layout - nsStyleTable* tableStyle=nsnull; aAttributes->GetAttribute(nsHTMLAtoms::layout, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { // it may be another type if illegal - tableStyle = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); tableStyle->mLayoutStrategy = value.GetIntValue(); } // cellpadding aAttributes->GetAttribute(nsHTMLAtoms::cellpadding, value); if (value.GetUnit() == eHTMLUnit_Pixel) { - if (nsnull==tableStyle) - tableStyle = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); tableStyle->mCellPadding.SetCoordValue(NSIntPixelsToTwips(value.GetPixelValue(), sp2t)); } else if (value.GetUnit() == eHTMLUnit_Percent) { - if (!tableStyle) - tableStyle = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); tableStyle->mCellPadding.SetPercentValue(value.GetPercentValue()); } @@ -1380,8 +1369,6 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aAttributes->GetAttribute(nsHTMLAtoms::cellspacing, value); if (value.GetUnit() == eHTMLUnit_Pixel) { - if (nsnull==tableStyle) - tableStyle = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); tableStyle->mBorderSpacingX.SetCoordValue(NSIntPixelsToTwips(value.GetPixelValue(), sp2t)); tableStyle->mBorderSpacingY.SetCoordValue(NSIntPixelsToTwips(value.GetPixelValue(), sp2t)); } @@ -1390,8 +1377,6 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aAttributes->GetAttribute(nsHTMLAtoms::cols, value); if (value.GetUnit() != eHTMLUnit_Null) { - if (!tableStyle) - tableStyle = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); if (value.GetUnit() == eHTMLUnit_Integer) tableStyle->mCols = value.GetIntValue(); else // COLS had no value, so it refers to all columns @@ -1402,8 +1387,6 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aAttributes->GetAttribute(nsHTMLAtoms::rules, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - if (nsnull==tableStyle) - tableStyle = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); tableStyle->mRules = value.GetIntValue(); } @@ -1430,6 +1413,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, marginStyleData->mMargin.SetBottom(vspace); } } + } //background: color nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aContext, diff --git a/mozilla/content/html/content/src/nsHTMLTableRowElement.cpp b/mozilla/content/html/content/src/nsHTMLTableRowElement.cpp index fc73bf11516..eb06528fbfa 100644 --- a/mozilla/content/html/content/src/nsHTMLTableRowElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLTableRowElement.cpp @@ -738,21 +738,34 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, if (aAttributes) { nsHTMLValue value; nsHTMLValue widthValue; - nsStyleText* textStyle = nsnull; + + PRUint8 newTextAlign; + nsStyleCoord newVerticalAlign; + PRBool changedTextAlign = PR_FALSE; + PRBool changedVerticalAlign = PR_FALSE; // align: enum aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); - textStyle->mTextAlign = value.GetIntValue(); + newTextAlign = value.GetIntValue(); + changedTextAlign = PR_TRUE; } // valign: enum aAttributes->GetAttribute(nsHTMLAtoms::valign, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - if (nsnull==textStyle) - textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); - textStyle->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); + newVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); + changedVerticalAlign = PR_TRUE; + } + + if (changedTextAlign || changedVerticalAlign) { + nsMutableStyleText text(aContext); + if (changedTextAlign) { + text->mTextAlign = newTextAlign; + } + if (changedVerticalAlign) { + text->mVerticalAlign = newVerticalAlign; + } } // height: pixel @@ -760,8 +773,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, if (value.GetUnit() == eHTMLUnit_Pixel) { float p2t; aPresContext->GetScaledPixelsToTwips(&p2t); - nsStylePosition* pos = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); + nsMutableStylePosition pos(aContext); nscoord twips = NSIntPixelsToTwips(value.GetPixelValue(), p2t); pos->mHeight.SetCoordValue(twips); } diff --git a/mozilla/content/html/content/src/nsHTMLTableSectionElement.cpp b/mozilla/content/html/content/src/nsHTMLTableSectionElement.cpp index be0c2cabb92..496d0a70b70 100644 --- a/mozilla/content/html/content/src/nsHTMLTableSectionElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLTableSectionElement.cpp @@ -325,22 +325,34 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, if (aAttributes) { nsHTMLValue value; nsHTMLValue widthValue; - nsStyleText* textStyle = nsnull; + + PRUint8 newTextAlign; + nsStyleCoord newVerticalAlign; + PRBool changedTextAlign = PR_FALSE; + PRBool changedVerticalAlign = PR_FALSE; // align: enum aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); - textStyle->mTextAlign = value.GetIntValue(); + newTextAlign = value.GetIntValue(); + changedTextAlign = PR_TRUE; } // valign: enum aAttributes->GetAttribute(nsHTMLAtoms::valign, value); if (value.GetUnit() == eHTMLUnit_Enumerated) { - if (nsnull==textStyle) - textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); - textStyle->mVerticalAlign.SetIntValue(value.GetIntValue(), - eStyleUnit_Enumerated); + newVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); + changedVerticalAlign = PR_TRUE; + } + + if (changedTextAlign || changedVerticalAlign) { + nsMutableStyleText text(aContext); + if (changedTextAlign) { + text->mTextAlign = newTextAlign; + } + if (changedVerticalAlign) { + text->mVerticalAlign = newVerticalAlign; + } } // height: pixel @@ -348,8 +360,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, if (value.GetUnit() == eHTMLUnit_Pixel) { float p2t; aPresContext->GetScaledPixelsToTwips(&p2t); - nsStylePosition* pos = (nsStylePosition*) - aContext->GetMutableStyleData(eStyleStruct_Position); + nsMutableStylePosition pos(aContext); nscoord twips = NSIntPixelsToTwips(value.GetPixelValue(), p2t); pos->mHeight.SetCoordValue(twips); } diff --git a/mozilla/content/html/content/src/nsHTMLTextAreaElement.cpp b/mozilla/content/html/content/src/nsHTMLTextAreaElement.cpp index 023fdc62d45..f87d554e926 100644 --- a/mozilla/content/html/content/src/nsHTMLTextAreaElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLTextAreaElement.cpp @@ -472,23 +472,22 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, aAttributes->GetAttribute(nsHTMLAtoms::align, value); if (eHTMLUnit_Enumerated == value.GetUnit()) { - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); - nsStyleText* text = (nsStyleText*) - aContext->GetMutableStyleData(eStyleStruct_Text); switch (value.GetIntValue()) { - case NS_STYLE_TEXT_ALIGN_LEFT: + case NS_STYLE_TEXT_ALIGN_LEFT: { + nsMutableStyleDisplay display(aContext); display->mFloats = NS_STYLE_FLOAT_LEFT; - break; - case NS_STYLE_TEXT_ALIGN_RIGHT: + } + case NS_STYLE_TEXT_ALIGN_RIGHT: { + nsMutableStyleDisplay display(aContext); display->mFloats = NS_STYLE_FLOAT_RIGHT; - break; - default: - text->mVerticalAlign.SetIntValue(value.GetIntValue(), - eStyleUnit_Enumerated); + } + default: { + nsMutableStyleText text(aContext); + text->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); break; + } } } diff --git a/mozilla/content/html/content/src/nsHTMLUListElement.cpp b/mozilla/content/html/content/src/nsHTMLUListElement.cpp index 83271b2cd7e..6396b13dbff 100644 --- a/mozilla/content/html/content/src/nsHTMLUListElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLUListElement.cpp @@ -206,8 +206,7 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes, { if (nsnull != aAttributes) { nsHTMLValue value; - nsStyleList* list = (nsStyleList*) - aContext->GetMutableStyleData(eStyleStruct_List); + nsMutableStyleList list(aContext); // type: enum aAttributes->GetAttribute(nsHTMLAtoms::type, value); diff --git a/mozilla/content/html/style/src/nsCSSStyleRule.cpp b/mozilla/content/html/style/src/nsCSSStyleRule.cpp index 111647eacf6..bfa54c6be5e 100644 --- a/mozilla/content/html/style/src/nsCSSStyleRule.cpp +++ b/mozilla/content/html/style/src/nsCSSStyleRule.cpp @@ -1790,7 +1790,7 @@ CSSStyleRuleImpl::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* return NS_OK; } -nsString& Unquote(nsString& aString) +static nsString& Unquote(nsString& aString) { PRUnichar start = aString.First(); PRUnichar end = aString.Last(); @@ -1811,8 +1811,8 @@ MapDeclarationFontInto(nsICSSDeclaration* aDeclaration, { if (nsnull != aDeclaration) { nsIStyleContext* parentContext = aContext->GetParent(); - nsStyleFont* font = (nsStyleFont*)aContext->GetMutableStyleData(eStyleStruct_Font); - const nsStyleFont* parentFont = font; + nsMutableStyleFont font(aContext); + const nsStyleFont* parentFont = font.get(); if (nsnull != parentContext) { parentFont = (const nsStyleFont*)parentContext->GetStyleData(eStyleStruct_Font); } @@ -2104,8 +2104,8 @@ MapDeclarationTextInto(nsICSSDeclaration* aDeclaration, if (NS_OK == aDeclaration->GetData(kCSSTextSID, (nsCSSStruct**)&ourText)) { if (nsnull != ourText) { // Get our text style and our parent's text style - nsStyleText* text = (nsStyleText*) aContext->GetMutableStyleData(eStyleStruct_Text); - const nsStyleText* parentText = text; + nsMutableStyleText text(aContext); + const nsStyleText* parentText = text.get(); if (nsnull != aParentContext) { parentText = (const nsStyleText*)aParentContext->GetStyleData(eStyleStruct_Text); } @@ -2209,10 +2209,8 @@ MapDeclarationDisplayInto(nsICSSDeclaration* aDeclaration, if (NS_OK == aDeclaration->GetData(kCSSDisplaySID, (nsCSSStruct**)&ourDisplay)) { if (nsnull != ourDisplay) { // Get our style and our parent's style - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); - - const nsStyleDisplay* parentDisplay = display; + nsMutableStyleDisplay display(aContext); + const nsStyleDisplay* parentDisplay = display.get(); if (nsnull != aParentContext) { parentDisplay = (const nsStyleDisplay*)aParentContext->GetStyleData(eStyleStruct_Display); } @@ -2349,9 +2347,8 @@ MapDeclarationColorInto(nsICSSDeclaration* aDeclaration, nsCSSColor* ourColor; if (NS_OK == aDeclaration->GetData(kCSSColorSID, (nsCSSStruct**)&ourColor)) { if (nsnull != ourColor) { - nsStyleColor* color = (nsStyleColor*)aContext->GetMutableStyleData(eStyleStruct_Color); - - const nsStyleColor* parentColor = color; + nsMutableStyleColor color(aContext); + const nsStyleColor* parentColor = color.get(); if (nsnull != aParentContext) { parentColor = (const nsStyleColor*)aParentContext->GetStyleData(eStyleStruct_Color); } @@ -2520,15 +2517,15 @@ MapDeclarationMarginInto(nsICSSDeclaration* aDeclaration, nsCSSMargin* ourMargin; if (NS_OK == aDeclaration->GetData(kCSSMarginSID, (nsCSSStruct**)&ourMargin)) { if (nsnull != ourMargin) { - nsStyleMargin* margin = (nsStyleMargin*)aContext->GetMutableStyleData(eStyleStruct_Margin); - nsStylePadding* padding = (nsStylePadding*)aContext->GetMutableStyleData(eStyleStruct_Padding); - nsStyleBorder* border = (nsStyleBorder*)aContext->GetMutableStyleData(eStyleStruct_Border); - nsStyleOutline* outline = (nsStyleOutline*)aContext->GetMutableStyleData(eStyleStruct_Outline); + nsMutableStyleMargin margin(aContext); + nsMutableStylePadding padding(aContext); + nsMutableStyleBorder border(aContext); + nsMutableStyleOutline outline(aContext); - const nsStyleMargin* parentMargin = margin; - const nsStylePadding* parentPadding = padding; - const nsStyleBorder* parentBorder = border; - const nsStyleOutline* parentOutline = outline; + const nsStyleMargin* parentMargin = margin.get(); + const nsStylePadding* parentPadding = padding.get(); + const nsStyleBorder* parentBorder = border.get(); + const nsStyleOutline* parentOutline = outline.get(); if (nsnull != aParentContext) { parentMargin = (const nsStyleMargin*)aParentContext->GetStyleData(eStyleStruct_Margin); parentPadding = (const nsStylePadding*)aParentContext->GetStyleData(eStyleStruct_Padding); @@ -2853,9 +2850,8 @@ MapDeclarationPositionInto(nsICSSDeclaration* aDeclaration, nsCSSPosition* ourPosition; if (NS_OK == aDeclaration->GetData(kCSSPositionSID, (nsCSSStruct**)&ourPosition)) { if (nsnull != ourPosition) { - nsStylePosition* position = (nsStylePosition*)aContext->GetMutableStyleData(eStyleStruct_Position); - - const nsStylePosition* parentPosition = position; + nsMutableStylePosition position(aContext); + const nsStylePosition* parentPosition = position.get(); if (nsnull != aParentContext) { parentPosition = (const nsStylePosition*)aParentContext->GetStyleData(eStyleStruct_Position); } @@ -2940,9 +2936,8 @@ MapDeclarationListInto(nsICSSDeclaration* aDeclaration, nsCSSList* ourList; if (NS_OK == aDeclaration->GetData(kCSSListSID, (nsCSSStruct**)&ourList)) { if (nsnull != ourList) { - nsStyleList* list = (nsStyleList*)aContext->GetMutableStyleData(eStyleStruct_List); - - const nsStyleList* parentList = list; + nsMutableStyleList list(aContext); + const nsStyleList* parentList = list.get(); if (nsnull != aParentContext) { parentList = (const nsStyleList*)aParentContext->GetStyleData(eStyleStruct_List); } @@ -2988,9 +2983,8 @@ MapDeclarationTableInto(nsICSSDeclaration* aDeclaration, nsCSSTable* ourTable; if (NS_OK == aDeclaration->GetData(kCSSTableSID, (nsCSSStruct**)&ourTable)) { if (nsnull != ourTable) { - nsStyleTable* table = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); - - const nsStyleTable* parentTable = table; + nsMutableStyleTable table(aContext); + const nsStyleTable* parentTable = table.get(); if (nsnull != aParentContext) { parentTable = (const nsStyleTable*)aParentContext->GetStyleData(eStyleStruct_Table); } @@ -3057,9 +3051,8 @@ MapDeclarationContentInto(nsICSSDeclaration* aDeclaration, nsCSSContent* ourContent; if (NS_OK == aDeclaration->GetData(kCSSContentSID, (nsCSSStruct**)&ourContent)) { if (ourContent) { - nsStyleContent* content = (nsStyleContent*)aContext->GetMutableStyleData(eStyleStruct_Content); - - const nsStyleContent* parentContent = content; + nsMutableStyleContent content(aContext); + const nsStyleContent* parentContent = content.get(); if (nsnull != aParentContext) { parentContent = (const nsStyleContent*)aParentContext->GetStyleData(eStyleStruct_Content); } @@ -3265,8 +3258,8 @@ MapDeclarationUIInto(nsICSSDeclaration* aDeclaration, if (NS_OK == aDeclaration->GetData(kCSSUserInterfaceSID, (nsCSSStruct**)&ourUI)) { if (nsnull != ourUI) { // Get our user interface style and our parent's user interface style - nsStyleUserInterface* ui = (nsStyleUserInterface*) aContext->GetMutableStyleData(eStyleStruct_UserInterface); - const nsStyleUserInterface* parentUI = ui; + nsMutableStyleUserInterface ui(aContext); + const nsStyleUserInterface* parentUI = ui.get(); if (nsnull != aParentContext) { parentUI = (const nsStyleUserInterface*)aParentContext->GetStyleData(eStyleStruct_UserInterface); } @@ -3367,8 +3360,8 @@ MapDeclarationPrintInto(nsICSSDeclaration* aDeclaration, nsIMutableStyleContext* aContext, nsIStyleContext* aParentContext, nsStyleFont* aFont, nsIPresContext* aPresContext) { - nsStylePrint* print = (nsStylePrint*)aContext->GetMutableStyleData(eStyleStruct_Print); - const nsStylePrint* parentPrint = print; + nsMutableStylePrint print(aContext); + const nsStylePrint* parentPrint = print.get(); if (nsnull != aParentContext) { parentPrint = (const nsStylePrint*)aParentContext->GetStyleData(eStyleStruct_Print); } @@ -3456,9 +3449,8 @@ MapDeclarationXULInto(nsICSSDeclaration* aDeclaration, nsCSSXUL* ourXUL; if (NS_OK == aDeclaration->GetData(kCSSXULSID, (nsCSSStruct**)&ourXUL)) { if (nsnull != ourXUL) { - nsStyleXUL* xul = (nsStyleXUL*)aContext->GetMutableStyleData(eStyleStruct_XUL); - - const nsStyleXUL* parentXUL = xul; + nsMutableStyleXUL xul(aContext); + const nsStyleXUL* parentXUL = xul.get(); if (nsnull != aParentContext) { parentXUL = (const nsStyleXUL*)aParentContext->GetStyleData(eStyleStruct_XUL); } @@ -3480,7 +3472,8 @@ void MapDeclarationInto(nsICSSDeclaration* aDeclaration, { if (nsnull != aDeclaration) { nsIStyleContext* parentContext = aContext->GetParent(); - nsStyleFont* font = (nsStyleFont*)aContext->GetMutableStyleData(eStyleStruct_Font); + nsMutableStyleFont mutableFont(aContext); + nsStyleFont* font = mutableFont.get(); MapDeclarationTextInto(aDeclaration, aContext, parentContext, font, aPresContext); MapDeclarationDisplayInto(aDeclaration, aContext, parentContext, font, aPresContext); diff --git a/mozilla/content/html/style/src/nsHTMLCSSStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLCSSStyleSheet.cpp index 2832bb9280b..da6c0468317 100644 --- a/mozilla/content/html/style/src/nsHTMLCSSStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsHTMLCSSStyleSheet.cpp @@ -132,44 +132,38 @@ CSSFirstLineRule::MapStyleInto(nsIMutableStyleContext* aContext, parentContext = aContext->GetParent(); // Disable border - nsStyleBorder* border = (nsStyleBorder*) - aContext->GetMutableStyleData(eStyleStruct_Border); - if (border) { - border->SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE); - border->SetBorderStyle(NS_SIDE_RIGHT, NS_STYLE_BORDER_STYLE_NONE); - border->SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE); - border->SetBorderStyle(NS_SIDE_LEFT, NS_STYLE_BORDER_STYLE_NONE); - } + nsMutableStyleBorder border(aContext); + border->SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE); + border->SetBorderStyle(NS_SIDE_RIGHT, NS_STYLE_BORDER_STYLE_NONE); + border->SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE); + border->SetBorderStyle(NS_SIDE_LEFT, NS_STYLE_BORDER_STYLE_NONE); // Undo any change made to "direction" - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); if (parentContext) { const nsStyleDisplay* parentDisplay = (const nsStyleDisplay*) parentContext->GetStyleData(eStyleStruct_Display); if (parentDisplay) { + nsMutableStyleDisplay display(aContext); display->mDirection = parentDisplay->mDirection; } } // Undo any change made to "cursor" - nsStyleColor* color = (nsStyleColor*) - aContext->GetMutableStyleData(eStyleStruct_Color); if (parentContext) { const nsStyleColor* parentColor = (const nsStyleColor*) parentContext->GetStyleData(eStyleStruct_Color); if (parentColor) { + nsMutableStyleColor color(aContext); color->mCursor = parentColor->mCursor; } } // Undo any change to quotes - nsStyleContent* content = (nsStyleContent*) - aContext->GetMutableStyleData(eStyleStruct_Content); if (parentContext) { const nsStyleContent* parentContent = (const nsStyleContent*) parentContext->GetStyleData(eStyleStruct_Content); if (parentContent) { + nsMutableStyleContent content(aContext); nsAutoString open, close; PRUint32 i, n = parentContent->QuotesCount(); content->AllocateQuotes(n); @@ -261,34 +255,31 @@ CSSFirstLetterRule::MapStyleInto(nsIMutableStyleContext* aContext, parentContext = aContext->GetParent(); // Undo any change made to "direction" - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); if (parentContext) { const nsStyleDisplay* parentDisplay = (const nsStyleDisplay*) parentContext->GetStyleData(eStyleStruct_Display); if (parentDisplay) { + nsMutableStyleDisplay display(aContext); display->mDirection = parentDisplay->mDirection; } } // Undo any change made to "cursor" - nsStyleColor* color = (nsStyleColor*) - aContext->GetMutableStyleData(eStyleStruct_Color); if (parentContext) { const nsStyleColor* parentColor = (const nsStyleColor*) parentContext->GetStyleData(eStyleStruct_Color); if (parentColor) { + nsMutableStyleColor color(aContext); color->mCursor = parentColor->mCursor; } } // Undo any change to quotes - nsStyleContent* content = (nsStyleContent*) - aContext->GetMutableStyleData(eStyleStruct_Content); if (parentContext) { const nsStyleContent* parentContent = (const nsStyleContent*) parentContext->GetStyleData(eStyleStruct_Content); if (parentContent) { + nsMutableStyleContent content(aContext); nsAutoString open, close; PRUint32 i, n = parentContent->QuotesCount(); content->AllocateQuotes(n); diff --git a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp index e5a7c9f8cc1..0328711047b 100644 --- a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp @@ -156,11 +156,8 @@ HTMLColorRule::MapFontStyleInto(nsIMutableStyleContext* aContext, nsIPresContext NS_IMETHODIMP HTMLColorRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext) { - nsStyleColor* styleColor = (nsStyleColor*)(aContext->GetMutableStyleData(eStyleStruct_Color)); - - if (nsnull != styleColor) { - styleColor->mColor = mColor; - } + nsMutableStyleColor styleColor(aContext); + styleColor->mColor = mColor; return NS_OK; } @@ -222,16 +219,13 @@ HTMLDocumentColorRule::~HTMLDocumentColorRule() NS_IMETHODIMP HTMLDocumentColorRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext) { - nsStyleColor* styleColor = (nsStyleColor*)(aContext->GetMutableStyleData(eStyleStruct_Color)); - - if (nsnull != styleColor) { - if (mForegroundSet) { - styleColor->mColor = mColor; - } - if (mBackgroundSet) { - styleColor->mBackgroundColor = mBackgroundColor; - styleColor->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; - } + nsMutableStyleColor styleColor(aContext); + if (mForegroundSet) { + styleColor->mColor = mColor; + } + if (mBackgroundSet) { + styleColor->mBackgroundColor = mBackgroundColor; + styleColor->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; } return NS_OK; } @@ -426,8 +420,7 @@ TableBackgroundRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresConte nsIStyleContext* parentContext = aContext->GetParent(); if (parentContext) { - nsStyleColor* styleColor; - styleColor = (nsStyleColor*)aContext->GetMutableStyleData(eStyleStruct_Color); + nsMutableStyleColor styleColor(aContext); const nsStyleColor* parentStyleColor; parentStyleColor = (const nsStyleColor*)parentContext->GetStyleData(eStyleStruct_Color); @@ -474,8 +467,8 @@ TableTHRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPre nsIStyleContext* parentContext = aContext->GetParent(); if (parentContext) { - nsStyleText* styleText = - (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText styleText(aContext); + if (NS_STYLE_TEXT_ALIGN_DEFAULT == styleText->mTextAlign) { const nsStyleText* parentStyleText = (const nsStyleText*)parentContext->GetStyleData(eStyleStruct_Text); diff --git a/mozilla/content/xul/content/src/nsXULElement.cpp b/mozilla/content/xul/content/src/nsXULElement.cpp index 32b8c85db84..69f59e98596 100644 --- a/mozilla/content/xul/content/src/nsXULElement.cpp +++ b/mozilla/content/xul/content/src/nsXULElement.cpp @@ -83,6 +83,7 @@ #include "nsIHTMLContentContainer.h" #include "nsIHTMLStyleSheet.h" #include "nsIJSScriptObject.h" +#include "nsIStyleContext.h" #include "nsIMutableStyleContext.h" #include "nsINameSpace.h" #include "nsINameSpaceManager.h" diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index 952875dc6f0..801086ed344 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -33,6 +33,7 @@ #include "nsIStyleRule.h" #include "nsIFrame.h" #include "nsIStyleContext.h" +#include "nsIMutableStyleContext.h" #include "nsHTMLAtoms.h" #include "nsIPresContext.h" #include "nsILinkHandler.h" @@ -1516,9 +1517,7 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShe if (display->mDisplay != displayValue) { // Reset the value - nsStyleDisplay* mutableDisplay = (nsStyleDisplay*) - pseudoStyleContext->GetMutableStyleData(eStyleStruct_Display); - + nsMutableStyleDisplay mutableDisplay(pseudoStyleContext); mutableDisplay->mDisplay = displayValue; } @@ -1528,9 +1527,7 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShe (const nsStylePosition*)pseudoStyleContext->GetStyleData(eStyleStruct_Position); if (NS_STYLE_POSITION_NORMAL != stylePosition->mPosition) { // Reset the value - nsStylePosition* mutablePosition = (nsStylePosition*) - pseudoStyleContext->GetMutableStyleData(eStyleStruct_Position); - + nsMutableStylePosition mutablePosition(pseudoStyleContext); mutablePosition->mPosition = NS_STYLE_POSITION_NORMAL; } @@ -2513,7 +2510,7 @@ void FixUpOuterTableFloat(nsIStyleContext* aOuterSC, nsIStyleContext* aInnerSC) { - nsStyleDisplay* outerStyleDisplay = (nsStyleDisplay*)aOuterSC->GetMutableStyleData(eStyleStruct_Display); + nsMutableStyleDisplay outerStyleDisplay(aOuterSC); nsStyleDisplay* innerStyleDisplay = (nsStyleDisplay*)aInnerSC->GetStyleData(eStyleStruct_Display); if (outerStyleDisplay->mFloats != innerStyleDisplay->mFloats) { outerStyleDisplay->mFloats = innerStyleDisplay->mFloats; @@ -3279,24 +3276,25 @@ PropagateBackgroundToParent(nsIStyleContext* aStyleContext, const nsStyleColor* aColor, nsIStyleContext* aParentStyleContext) { - nsStyleColor* mutableColor; - mutableColor = (nsStyleColor*)aParentStyleContext->GetMutableStyleData(eStyleStruct_Color); - - mutableColor->mBackgroundAttachment = aColor->mBackgroundAttachment; - mutableColor->mBackgroundFlags = aColor->mBackgroundFlags | NS_STYLE_BG_PROPAGATED_FROM_CHILD; - mutableColor->mBackgroundRepeat = aColor->mBackgroundRepeat; - mutableColor->mBackgroundColor = aColor->mBackgroundColor; - mutableColor->mBackgroundXPosition = aColor->mBackgroundXPosition; - mutableColor->mBackgroundYPosition = aColor->mBackgroundYPosition; - mutableColor->mBackgroundImage = aColor->mBackgroundImage; - + { + nsMutableStyleColor mutableColor(aParentStyleContext); + mutableColor->mBackgroundAttachment = aColor->mBackgroundAttachment; + mutableColor->mBackgroundFlags = aColor->mBackgroundFlags | NS_STYLE_BG_PROPAGATED_FROM_CHILD; + mutableColor->mBackgroundRepeat = aColor->mBackgroundRepeat; + mutableColor->mBackgroundColor = aColor->mBackgroundColor; + mutableColor->mBackgroundXPosition = aColor->mBackgroundXPosition; + mutableColor->mBackgroundYPosition = aColor->mBackgroundYPosition; + mutableColor->mBackgroundImage = aColor->mBackgroundImage; + } // Reset the BODY's background to transparent - mutableColor = (nsStyleColor*)aStyleContext->GetMutableStyleData(eStyleStruct_Color); - mutableColor->mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | - NS_STYLE_BG_IMAGE_NONE | - NS_STYLE_BG_PROPAGATED_TO_PARENT; - mutableColor->mBackgroundImage.SetLength(0); - mutableColor->mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; + { + nsMutableStyleColor mutableColor(aStyleContext); + mutableColor->mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | + NS_STYLE_BG_IMAGE_NONE | + NS_STYLE_BG_PROPAGATED_TO_PARENT; + mutableColor->mBackgroundImage.SetLength(0); + mutableColor->mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; + } } /** @@ -3484,7 +3482,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell, // Since we always create a block frame, we need to make sure that the // style context's display type is block level. - nsStyleDisplay* disp = (nsStyleDisplay*)styleContext->GetMutableStyleData(eStyleStruct_Display); + nsMutableStyleDisplay disp(styleContext); disp->mDisplay = NS_STYLE_DISPLAY_BLOCK; } @@ -3687,7 +3685,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell, getter_AddRefs(viewportPseudoStyle)); { // ensure that the viewport thinks it is a block frame, layout goes pootsy if it doesn't - nsStyleDisplay* display = (nsStyleDisplay*)viewportPseudoStyle->GetMutableStyleData(eStyleStruct_Display); + nsMutableStyleDisplay display(viewportPseudoStyle); display->mDisplay = NS_STYLE_DISPLAY_BLOCK; } @@ -4886,7 +4884,7 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresShell* aPresShell, } if (allowSubframes) { // make be display:none if frames are enabled - nsStyleDisplay* display = (nsStyleDisplay*)aStyleContext->GetMutableStyleData(eStyleStruct_Display); + nsMutableStyleDisplay display(aStyleContext); display->mDisplay = NS_STYLE_DISPLAY_NONE; aState.mFrameManager->SetUndisplayedContent(aContent, aStyleContext); } diff --git a/mozilla/layout/base/public/nsIMutableStyleContext.h b/mozilla/layout/base/public/nsIMutableStyleContext.h index d7fde2311cd..3da0eca0fe8 100644 --- a/mozilla/layout/base/public/nsIMutableStyleContext.h +++ b/mozilla/layout/base/public/nsIMutableStyleContext.h @@ -40,14 +40,92 @@ public: // Fill a style struct with data NS_IMETHOD GetStyle(nsStyleStructID aSID, nsStyleStruct& aStruct) const = 0; - NS_IMETHOD SetStyle(nsStyleStructID aSID, const nsStyleStruct& aStruct) = 0; - //------------------------------------------------ - // TEMP methods these are here only to ease the transition - // to the newer Get/SetStyle APIs above. Don't call these. - // get a style data struct by ID + // Get a pointer on the style data virtual const nsStyleStruct* GetStyleData(nsStyleStructID aSID) = 0; - virtual nsStyleStruct* GetMutableStyleData(nsStyleStructID aSID) = 0; + + // Modify the style data + // + // Calls to ReadMutableStyleData() and WriteMutableStyleData() must be balanced. + // To enforce this, they are not made public. You must use the helper classes below + // where the constructors and destructors call Read() and Write() for you. + // + // For instance, to change the opacity, you should do: + // + // nsMutableStyleColor color(myStyleContext); + // color->mOpacity = 0.5f; + // + // In some cases, you may want to put the block above between brackets {...} + // so that the |nsMutableStyleColor| destructor can be called and your changes + // written into the style context. + // + virtual void ReadMutableStyleData(nsStyleStructID aSID, nsStyleStruct** aStyleStructPtr) = 0; + virtual nsresult WriteMutableStyleData(nsStyleStructID aSID, nsStyleStruct* aStyleStruct) = 0; }; +template <class T, nsStyleStructID SID> +class basic_nsAutoMutableStyle +{ +protected: + T* mStyleStruct; + void* mContext; + PRBool mMutable; + +public: + basic_nsAutoMutableStyle(nsIMutableStyleContext* aContext) + : mContext(aContext), mMutable(PR_TRUE) + { + if (aContext) + aContext->ReadMutableStyleData(SID, &(nsStyleStruct*)mStyleStruct); + } + + basic_nsAutoMutableStyle(nsIStyleContext* aContext) + : mContext(aContext), mMutable(PR_FALSE) + { + if (aContext) + aContext->ReadMutableStyleData(SID, &(nsStyleStruct*)mStyleStruct); + } + + ~basic_nsAutoMutableStyle() + { + if (mContext) { + if (mMutable) { + nsIMutableStyleContext* context = + NS_STATIC_CAST(nsIMutableStyleContext*, mContext); + + context->WriteMutableStyleData(SID, mStyleStruct); + } + else { + nsIStyleContext* context = + NS_STATIC_CAST(nsIStyleContext*, mContext); + + context->WriteMutableStyleData(SID, mStyleStruct); + } + } + } + + T* get() { return mStyleStruct; } + T* operator->() { return get(); } + T& operator*() { return *get(); } + }; + +// Helper classes to modify the style data +typedef basic_nsAutoMutableStyle<nsStyleFont, eStyleStruct_Font> nsMutableStyleFont; +typedef basic_nsAutoMutableStyle<nsStyleColor, eStyleStruct_Color> nsMutableStyleColor; +typedef basic_nsAutoMutableStyle<nsStyleList, eStyleStruct_List> nsMutableStyleList; +typedef basic_nsAutoMutableStyle<nsStylePosition, eStyleStruct_Position> nsMutableStylePosition; +typedef basic_nsAutoMutableStyle<nsStyleText, eStyleStruct_Text> nsMutableStyleText; +typedef basic_nsAutoMutableStyle<nsStyleDisplay, eStyleStruct_Display> nsMutableStyleDisplay; +typedef basic_nsAutoMutableStyle<nsStyleTable, eStyleStruct_Table> nsMutableStyleTable; +typedef basic_nsAutoMutableStyle<nsStyleContent, eStyleStruct_Content> nsMutableStyleContent; +typedef basic_nsAutoMutableStyle<nsStyleUserInterface, eStyleStruct_UserInterface> nsMutableStyleUserInterface; +typedef basic_nsAutoMutableStyle<nsStylePrint, eStyleStruct_Print> nsMutableStylePrint; +typedef basic_nsAutoMutableStyle<nsStyleMargin, eStyleStruct_Margin> nsMutableStyleMargin; +typedef basic_nsAutoMutableStyle<nsStylePadding, eStyleStruct_Padding> nsMutableStylePadding; +typedef basic_nsAutoMutableStyle<nsStyleBorder, eStyleStruct_Border> nsMutableStyleBorder; +typedef basic_nsAutoMutableStyle<nsStyleOutline, eStyleStruct_Outline> nsMutableStyleOutline; +#ifdef INCLUDE_XUL +typedef basic_nsAutoMutableStyle<nsStyleXUL, eStyleStruct_XUL> nsMutableStyleXUL; +#endif + #endif /* nsIMutableStyleContext_h___ */ diff --git a/mozilla/layout/base/public/nsIStyleContext.h b/mozilla/layout/base/public/nsIStyleContext.h index bb34238ae68..f35587c9653 100644 --- a/mozilla/layout/base/public/nsIStyleContext.h +++ b/mozilla/layout/base/public/nsIStyleContext.h @@ -44,6 +44,7 @@ class nsIFrame; class nsIPresContext; class nsISupportsArray; class nsIStyleContext; +class nsAutoStyleStruct; inline void CalcSidesFor(const nsIFrame* aFrame, const nsStyleSides& aSides, @@ -52,8 +53,6 @@ inline void CalcSidesFor(const nsIFrame* aFrame, const nsStyleSides& aSides, nsMargin& aResult); -#define SHARE_STYLECONTEXTS - // The lifetime of these objects is managed by the nsIStyleContext. struct nsStyleFont : public nsStyleStruct { @@ -70,10 +69,14 @@ struct nsStyleFont : public nsStyleStruct { PRUint8 mFlags; // [inherited] See nsStyleConsts.h protected: - nsStyleFont(const nsFont& aVariableFont, const nsFont& aFixedFont); + nsStyleFont(const nsFont& aVariableFont, const nsFont& aFixedFont) + : mFont(aVariableFont), + mFixedFont(aFixedFont) + {} nsStyleFont(nsIPresContext* aPresContext); }; + struct nsStyleColor : public nsStyleStruct { nsStyleColor(void) {} ~nsStyleColor(void) {} @@ -133,6 +136,7 @@ struct nsStyleMargin: public nsStyleStruct { } } +friend class StyleMarginBlob; protected: PRPackedBool mHasCachedMargin; nsMargin mCachedMargin; @@ -164,6 +168,7 @@ struct nsStylePadding: public nsStyleStruct { } } +friend class StylePaddingBlob; protected: PRPackedBool mHasCachedPadding; nsMargin mCachedPadding; @@ -242,6 +247,7 @@ struct nsStyleBorder: public nsStyleStruct { } } +friend class StyleBorderBlob; protected: PRPackedBool mHasCachedBorder; nsMargin mCachedBorder; @@ -328,6 +334,7 @@ struct nsStyleOutline: public nsStyleStruct { mOutlineStyle |= (BORDER_COLOR_DEFINED | BORDER_COLOR_SPECIAL); } +friend class StyleOutlineBlob; protected: PRPackedBool mHasCachedOutline; nscoord mCachedOutlineWidth; @@ -341,8 +348,8 @@ protected: struct nsStyleList : public nsStyleStruct { - nsStyleList(void); - ~nsStyleList(void); + nsStyleList(void) {}; + ~nsStyleList(void) {}; PRUint8 mListStyleType; // [inherited] See nsStyleConsts.h PRUint8 mListStylePosition; // [inherited] @@ -350,8 +357,8 @@ struct nsStyleList : public nsStyleStruct { }; struct nsStylePosition : public nsStyleStruct { - nsStylePosition(void); - ~nsStylePosition(void); + nsStylePosition(void) {}; + ~nsStylePosition(void) {}; PRUint8 mPosition; // [reset] see nsStyleConsts.h @@ -374,8 +381,8 @@ struct nsStylePosition : public nsStyleStruct { }; struct nsStyleText : public nsStyleStruct { - nsStyleText(void); - ~nsStyleText(void); + nsStyleText(void) {}; + ~nsStyleText(void) {}; PRUint8 mTextAlign; // [inherited] see nsStyleConsts.h PRUint8 mTextDecoration; // [reset] see nsStyleConsts.h @@ -442,8 +449,8 @@ struct nsStyleDisplay : public nsStyleStruct { }; struct nsStyleTable: public nsStyleStruct { - nsStyleTable(void); - ~nsStyleTable(void); + nsStyleTable(void) {}; + ~nsStyleTable(void) {}; PRUint8 mLayoutStrategy;// [reset] see nsStyleConsts.h NS_STYLE_TABLE_LAYOUT_* PRUint8 mFrame; // [reset] see nsStyleConsts.h NS_STYLE_TABLE_FRAME_* @@ -485,8 +492,24 @@ struct nsStyleCounterData { #define DELETE_ARRAY_IF(array) if (array) { delete[] array; array = nsnull; } struct nsStyleContent: public nsStyleStruct { - nsStyleContent(void); - ~nsStyleContent(void); + nsStyleContent(void) { + //mMarkerOffset(), + mContentCount = 0; + mContents = nsnull; + mIncrementCount = 0; + mIncrements = nsnull; + mResetCount = 0; + mResets = nsnull; + mQuotesCount = 0; + mQuotes = nsnull; + } + + ~nsStyleContent(void) { + DELETE_ARRAY_IF(mContents); + DELETE_ARRAY_IF(mIncrements); + DELETE_ARRAY_IF(mResets); + DELETE_ARRAY_IF(mQuotes); + } PRUint32 ContentCount(void) const { return mContentCount; } // [reset] nsresult GetContentAt(PRUint32 aIndex, nsStyleContentType& aType, nsString& aContent) const { @@ -633,6 +656,7 @@ struct nsStyleContent: public nsStyleStruct { return NS_ERROR_ILLEGAL_VALUE; } +friend class StyleContentBlob; protected: PRUint32 mContentCount; nsStyleContentData* mContents; @@ -648,8 +672,8 @@ protected: }; struct nsStyleUserInterface: public nsStyleStruct { - nsStyleUserInterface(void); - ~nsStyleUserInterface(void); + nsStyleUserInterface(void) {}; + ~nsStyleUserInterface(void) {}; PRUint8 mUserInput; // [inherited] PRUint8 mUserModify; // [inherited] (modify-content) @@ -658,12 +682,11 @@ struct nsStyleUserInterface: public nsStyleStruct { PRUnichar mKeyEquivalent; // [reset] XXX what type should this be? PRUint8 mResizer; // [reset] nsString mBehavior; // [reset] absolute url string - }; struct nsStylePrint: public nsStyleStruct { - nsStylePrint(void); - ~nsStylePrint(void); + nsStylePrint(void) {}; + ~nsStylePrint(void) {}; PRUint8 mPageBreakBefore; // [reset] see nsStyleConsts.h NS_STYLE_PAGE_BREAK_* PRUint8 mPageBreakAfter; // [reset] see nsStyleConsts.h NS_STYLE_PAGE_BREAK_* @@ -678,8 +701,8 @@ struct nsStylePrint: public nsStyleStruct { #ifdef INCLUDE_XUL struct nsStyleXUL : public nsStyleStruct { - nsStyleXUL(); - ~nsStyleXUL(); + nsStyleXUL() {}; + ~nsStyleXUL() {}; // There will be seven more properties coming, // which is why we warrant our own struct. @@ -747,6 +770,8 @@ inline nsBorderEdges::nsBorderEdges() { 0x26a4d970, 0xa342, 0x11d1, \ {0x89, 0x74, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81} } + + class nsIStyleContext : public nsISupports { public: static const nsIID& GetIID() { static nsIID iid = NS_ISTYLECONTEXT_IID; return iid; } @@ -778,22 +803,16 @@ public: virtual void DumpRegressionData(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent) = 0; #endif -#ifdef SHARE_STYLECONTEXTS // sets aMatches to PR_TRUE if the style data of aStyleContextToMatch matches the // style data of this, PR_FALSE otherwise +#ifdef SHARE_STYLECONTEXTS NS_IMETHOD StyleDataMatches(nsIStyleContext* aStyleContextToMatch, PRBool *aMatches) = 0; NS_IMETHOD GetStyleContextKey(scKey &aKey) const = 0; #endif - // ------------------------------------------------------------- - // DEPRECATED METHODS - these are all going away, stop using them - // get a style data struct by ID, may return null - // Replace calls to this with calls to GetStyle(); + // Get a pointer on the style data virtual const nsStyleStruct* GetStyleData(nsStyleStructID aSID) = 0; - // get a style data struct by ID, may return null - virtual nsStyleStruct* GetMutableStyleData(nsStyleStructID aSID) = 0; - // call this to prevent context from getting shared virtual void ForceUnique(void) = 0; @@ -804,6 +823,25 @@ public: // utility function: more convenient than 2 calls to GetStyleData to get border and padding virtual void CalcBorderPaddingFor(const nsIFrame* aFrame, nsMargin& aBorderPadding) const = 0; + + // Modify the style data + // + // Calls to ReadMutableStyleData() and WriteMutableStyleData() must be balanced. + // To enforce this, they are not made public. You must use the helper classes + // that are defined in "nsIMutableStyleContext.h" where the constructors and + // destructors call Read() and Write() for you. + // + // For instance, to change the opacity, you should do: + // + // nsMutableStyleColor color(myStyleContext); + // color->mOpacity = 0.5f; + // + // In some cases, you may want to put the block above between brackets {...} + // so that the |nsMutableStyleColor| destructor can be called and your changes + // written into the style context. + // + virtual void ReadMutableStyleData(nsStyleStructID aSID, nsStyleStruct** aStyleStruct) = 0; + virtual nsresult WriteMutableStyleData(nsStyleStructID aSID, nsStyleStruct* aStyleStruct) = 0; }; diff --git a/mozilla/layout/base/public/nsIStyleSet.h b/mozilla/layout/base/public/nsIStyleSet.h index ae4e9186e61..6fcc587dd13 100644 --- a/mozilla/layout/base/public/nsIStyleSet.h +++ b/mozilla/layout/base/public/nsIStyleSet.h @@ -44,12 +44,16 @@ class nsISizeOfHandler; class nsICSSPseudoComparator; -#define SHARE_STYLECONTEXTS +//#define SHARE_STYLECONTEXTS #ifdef SHARE_STYLECONTEXTS -#include "nsHashtable.h" +#define USE_FAST_CACHE +// - Fast cache uses a CRC32 on the style context to quickly find sharing candidates. +// Enabling it by defining USE_FAST_CACHE makes style sharing significantly faster +// but introduces more code and logic, and is thus potentially more error-prone #endif + // IID for the nsIStyleSet interface {e59396b0-b244-11d1-8031-006008159b5a} #define NS_ISTYLE_SET_IID \ {0xe59396b0, 0xb244, 0x11d1, {0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}} diff --git a/mozilla/layout/base/public/nsStyleStruct.h b/mozilla/layout/base/public/nsStyleStruct.h index 2b0f00a9697..9bb8a28c4e9 100644 --- a/mozilla/layout/base/public/nsStyleStruct.h +++ b/mozilla/layout/base/public/nsStyleStruct.h @@ -19,9 +19,14 @@ * * Contributor(s): */ + #ifndef nsStyleStruct_h___ #define nsStyleStruct_h___ + +// If you add structures in that list, look for the comments tagged with +// the string //#insert new style structs here# in "nsStyleContext.cpp". +// You should also add a helper class in "nsIMutableStyleContext.h" enum nsStyleStructID { eStyleStruct_Font = 1, eStyleStruct_Color = 2, @@ -40,13 +45,14 @@ enum nsStyleStructID { #ifdef INCLUDE_XUL eStyleStruct_XUL = 15, eStyleStruct_Max = eStyleStruct_XUL, - eStyleStruct_BorderPaddingShortcut = 16 // only for use in GetStyle() #else eStyleStruct_Max = eStyleStruct_Outline, - eStyleStruct_BorderPaddingShortcut = 15 // only for use in GetStyle() #endif + eStyleStruct_BorderPaddingShortcut = 99 // only for use in GetStyle() }; +class nsIPresContext; + struct nsStyleStruct { }; diff --git a/mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp new file mode 100644 index 00000000000..9c42df3362c --- /dev/null +++ b/mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp @@ -0,0 +1,5043 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Pierre Phaneuf <pp@ludusdesign.com> + */ + +#ifndef ENDER_LITE + +#include "nsCOMPtr.h" +#include "nsGfxTextControlFrame.h" +#include "nsIContent.h" +#include "prtypes.h" +#include "nsIFrame.h" +#include "nsISupports.h" +#include "nsIAtom.h" +#include "nsIPresContext.h" +#include "nsIHTMLContent.h" +#include "nsHTMLIIDs.h" +#include "nsITextWidget.h" +#include "nsWidgetsCID.h" +#include "nsSize.h" +#include "nsString.h" +#include "nsHTMLAtoms.h" +#include "nsIStyleContext.h" +#include "nsFont.h" +#include "nsIDOMEvent.h" +#include "nsIFormControl.h" +#include "nsFormFrame.h" +#include "nsIFrameManager.h" +#include "nsIDOMHTMLInputElement.h" +#include "nsIDOMHTMLTextAreaElement.h" +#include "nsIDOMWindowInternal.h" +#include "nsIScrollbar.h" +#include "nsIScrollableFrame.h" +#include "nsIScriptGlobalObject.h" +#include "nsIDocShell.h" +#include "nsIWebShell.h" + +#include "nsCSSRendering.h" +#include "nsIDeviceContext.h" +#include "nsIFontMetrics.h" +#include "nsILookAndFeel.h" +#include "nsIComponentManager.h" + +#include "nsIBaseWindow.h" +#include "nsIMarkupDocumentViewer.h" +#include "nsIDocumentLoader.h" +#include "nsINameSpaceManager.h" +#include "nsIPref.h" +#include "nsIView.h" +#include "nsIScrollableView.h" +#include "nsIDocumentViewer.h" +#include "nsViewsCID.h" +#include "nsWidgetsCID.h" + +#include "nsIHTMLEditor.h" +#include "nsIEditorIMESupport.h" +#include "nsIDocumentEncoder.h" +#include "nsIEditorMailSupport.h" +#include "nsITransactionManager.h" +#include "nsEditorCID.h" +#include "nsIDOMNode.h" +#include "nsIDOMElement.h" +#include "nsIDOMNodeList.h" +#include "nsISelection.h" +#include "nsIDOMCharacterData.h" +#include "nsIDocument.h" +#include "nsIDOMDocument.h" +#include "nsIDOMHTMLDocument.h" +#include "nsIDOMEventReceiver.h" +#include "nsIPresShell.h" +#include "nsIEventStateManager.h" +#include "nsStyleUtil.h" +#include "nsLinebreakConverter.h" +#include "nsIDOMRange.h" + +// for anonymous content and frames +#include "nsHTMLParts.h" +#include "nsITextContent.h" + +//for editor controllers +#include "nsIEditorController.h" +#include "nsIController.h" +#include "nsIControllers.h" +#include "nsIDOMNSHTMLTextAreaElement.h" +#include "nsIDOMNSHTMLInputElement.h" +#include "nsIDOMXULCommandDispatcher.h" +#include "nsIMutableAccessible.h" +#include "nsIAccessibilityService.h" +#include "nsIServiceManager.h" +#include "nsIDOMNode.h" + +#include "nsINodeInfo.h" + +#include "nsLayoutAtoms.h" +#include "nsContentCID.h" + +static NS_DEFINE_CID(kTextNodeCID, NS_TEXTNODE_CID); +static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID); + +static NS_DEFINE_IID(kTextCID, NS_TEXTFIELD_CID); + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_IID(kWebShellCID, NS_WEB_SHELL_CID); +static NS_DEFINE_IID(kCViewCID, NS_VIEW_CID); +static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID); + +static NS_DEFINE_CID(kHTMLEditorCID, NS_HTMLEDITOR_CID); + +#define EMPTY_DOCUMENT "about:blank" +#define PASSWORD_REPLACEMENT_CHAR '*' + +//#define NOISY +const nscoord kSuggestedNotSet = -1; + +/*================== global functions =========================*/ +static nsIWidget * GetDeepestWidget(nsIView * aView) +{ + + PRInt32 count; + aView->GetChildCount(count); + if (0 != count) { + for (PRInt32 i=0;i<count;i++) { + nsIView * child; + aView->GetChild(i, child); + nsIWidget * widget = GetDeepestWidget(child); + if (widget) { + return widget; + } else { + aView->GetWidget(widget); + if (widget) { + nsCOMPtr<nsIScrollbar> scrollbar(do_QueryInterface(widget)); + if (scrollbar) { + NS_RELEASE(widget); + } else { + return widget; + } + } + } + } + } + + return nsnull; +} + +static void GetWidgetForView(nsIView *aView, nsIWidget *&aWidget) +{ + aWidget = nsnull; + nsIView *view = aView; + while (!aWidget && view) + { + view->GetWidget(aWidget); + if (!aWidget) + view->GetParent(view); + } +} + +nsresult +NS_NewGfxTextControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) +{ + NS_PRECONDITION(aNewFrame, "null OUT ptr"); + if (nsnull == aNewFrame) { + return NS_ERROR_NULL_POINTER; + } + *aNewFrame = new (aPresShell) nsGfxTextControlFrame; + if (nsnull == aNewFrame) { + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; +} + +nsGfxTextControlFrame::nsGfxTextControlFrame() +: mTempObserver(0), mDocObserver(0), + mCreatingViewer(PR_FALSE), + mNotifyOnInput(PR_FALSE), + mIsProcessing(PR_FALSE), + mNeedsStyleInit(PR_TRUE), + mDidSetFocus(PR_FALSE), + mGotSelectionState(PR_FALSE), + mSelectionWasCollapsed(PR_FALSE), + mIsInput(PR_TRUE), + mFramePresContext(nsnull), + mCachedState(nsnull), + mWeakReferent(this), + mFrameConstructor(nsnull), + mDisplayFrame(nsnull), + mPassThroughMouseEvents(eUninitialized) +{ +#ifdef DEBUG + mDebugTotalReflows=0; + mDebugResizeReflows=0; + mDebugResizeUnconstrained=0; + mDebugResizeReflowsThatChangedMySize=0; + mDebugReflowsThatMovedSubdoc=0; + mDebugTotalPaints=0; + mDebugPaintsSinceLastReflow=0; +#endif +} + +nsGfxTextControlFrame::~nsGfxTextControlFrame() +{ + nsresult result; + if (mDisplayFrame) { + mFrameConstructor->RemoveMappingsForFrameSubtree(mFramePresContext, + mDisplayFrame, nsnull); + mDisplayFrame->Destroy(mFramePresContext); + } + if (mTempObserver) + { + nsCOMPtr<nsIWebShell> webShell(do_QueryInterface(mDocShell)); + if (webShell) { + nsCOMPtr<nsIDocumentLoader> docLoader; + webShell->GetDocumentLoader(*getter_AddRefs(docLoader)); + if (docLoader) { + docLoader->RemoveObserver(mTempObserver); + } + } + mTempObserver->SetFrame(nsnull); + NS_RELEASE(mTempObserver); + } + + // remove the focus listener from the display content, if any + if (mDisplayContent && mFocusListenerForDisplayContent) + { + nsCOMPtr<nsIDOMEventReceiver> er; + result = mDisplayContent->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(er)); + if (NS_SUCCEEDED(result) && er) + { + er->RemoveEventListenerByIID(mFocusListenerForDisplayContent, NS_GET_IID(nsIDOMFocusListener)); + } + mFocusListenerForDisplayContent->SetFrame(nsnull); + NS_RELEASE(mFocusListenerForDisplayContent); + } + + // remove the drag listener from the frame's content node, if any + if (mContent && mListenerForContent) + { + // checking errors below does not good, I'm in a void method + // I only check the minimum required to be sure it all works right + nsCOMPtr<nsIDOMEventReceiver> contentER; + result = mContent->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(contentER)); + if (NS_SUCCEEDED(result) && contentER) + { + nsCOMPtr<nsIDOMDragListener> dragListenerForContent; + mListenerForContent->QueryInterface(NS_GET_IID(nsIDOMDragListener), getter_AddRefs(dragListenerForContent)); + if (dragListenerForContent) + { + contentER->RemoveEventListenerByIID(dragListenerForContent, NS_GET_IID(nsIDOMDragListener)); + } + } + mListenerForContent->SetFrame(nsnull); + NS_RELEASE(mListenerForContent); + } + + if (mEventListener) + { + if (mEditor) + { + // remove selection listener + nsCOMPtr<nsISelection> selection; + result = mEditor->GetSelection(getter_AddRefs(selection)); + if (NS_SUCCEEDED(result) && selection) + { + nsCOMPtr<nsISelectionListener> selListener = do_QueryInterface(mEventListener); + if (selListener) + selection->RemoveSelectionListener(selListener); + } + + // remove the txnListener + nsCOMPtr<nsITransactionManager> txnMgr; + result = mEditor->GetTransactionManager(getter_AddRefs(txnMgr)); + if (NS_SUCCEEDED(result) && txnMgr) + { + nsCOMPtr<nsITransactionListener> txnListener = do_QueryInterface(mEventListener); + if (txnListener) + txnMgr->RemoveListener(txnListener); + } + + // remove all other listeners from embedded document + nsCOMPtr<nsIDOMDocument>domDoc; + result = mEditor->GetDocument(getter_AddRefs(domDoc)); + if (NS_SUCCEEDED(result) && domDoc) + { + nsCOMPtr<nsIDOMEventReceiver> er; + result = domDoc->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(er)); + if (NS_SUCCEEDED(result) && er) + { + // remove key listener + nsCOMPtr<nsIDOMKeyListener>keyListener; + keyListener = do_QueryInterface(mEventListener); + if (keyListener) + er->RemoveEventListenerByIID(keyListener, NS_GET_IID(nsIDOMKeyListener)); + // remove mouse listener + nsCOMPtr<nsIDOMMouseListener>mouseListener; + mouseListener = do_QueryInterface(mEventListener); + if (mouseListener) + er->RemoveEventListenerByIID(mouseListener, NS_GET_IID(nsIDOMMouseListener)); + // remove focus listener + nsCOMPtr<nsIDOMFocusListener>focusListener; + focusListener = do_QueryInterface(mEventListener); + if (focusListener) + er->RemoveEventListenerByIID(focusListener, NS_GET_IID(nsIDOMFocusListener)); + } + } + } + } + + result = NS_OK; + // if there is a controller, remove the editor from it + if (mEditor) + { + nsCOMPtr<nsIDOMNSHTMLTextAreaElement> textAreaElement = do_QueryInterface(mContent); + nsCOMPtr<nsIDOMNSHTMLInputElement> inputElement = do_QueryInterface(mContent); + nsCOMPtr<nsIControllers> controllers; + if (textAreaElement) + result = textAreaElement->GetControllers(getter_AddRefs(controllers)); + else if (inputElement) + result = inputElement->GetControllers(getter_AddRefs(controllers)); + else + result = NS_ERROR_FAILURE; + if (NS_SUCCEEDED(result)) + { + PRUint32 count; + PRBool found = PR_FALSE; + result = controllers->GetControllerCount(&count); + NS_ASSERTION((NS_SUCCEEDED(result)), "bad result in gfx text control destructor"); + for (PRUint32 i = 0; i < count; i ++) + { + nsCOMPtr<nsIController> controller; + result = controllers->GetControllerAt(i, getter_AddRefs(controller)); + if (NS_SUCCEEDED(result) && controller) + { + nsCOMPtr<nsIEditorController> editController = do_QueryInterface(controller); + if (editController) + { + editController->SetCommandRefCon(nsnull); + found = PR_TRUE; + } + } + } + } + } + + mEditor = 0; // editor must be destroyed before the docshell! + nsCOMPtr<nsIBaseWindow> docShellWin(do_QueryInterface(mDocShell)); + if(docShellWin) + docShellWin->Destroy(); + docShellWin = nsnull; + mDocShell = nsnull; // This is where it was released before. Not sure if + // there is ordering depending on it. + if (mDocObserver) + { + nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDoc); + if (doc) + { + doc->RemoveObserver(mDocObserver); + } + mDocObserver->SetFrame(nsnull); + NS_RELEASE(mDocObserver); + } + + if (mCachedState) { + delete mCachedState; + mCachedState = nsnull; + } +#ifdef DEBUG +#if NOISY + printf("gfxTC: %p reflow stats at destructor:\n\ttotal\tresize\tunconst\tchanged\tmoved\n", this); + printf("\t%d\t%d\t%d\t%d\t%d\n", + mDebugTotalReflows, mDebugResizeReflows, + mDebugResizeUnconstrained, + mDebugResizeReflowsThatChangedMySize, mDebugReflowsThatMovedSubdoc); +#endif +#endif +} + +// Frames are not refcounted, no need to AddRef +NS_IMETHODIMP +nsGfxTextControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) +{ + NS_PRECONDITION(0 != aInstancePtr, "null ptr"); + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + + } else if (aIID.Equals(NS_GET_IID(nsIGfxTextControlFrame))) { + *aInstancePtr = (void*)(nsIGfxTextControlFrame*) this; + return NS_OK; + + } else if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*)(nsIStatefulFrame*) this; + return NS_OK; + } + + if (aIID.Equals(NS_GET_IID(nsIAccessible))) { + nsresult rv = NS_OK; + NS_WITH_SERVICE(nsIAccessibilityService, accService, "@mozilla.org/accessibilityService;1", &rv); + if (accService) { + nsCOMPtr<nsIDOMNode> node = do_QueryInterface(mContent); + nsIMutableAccessible* acc = nsnull; + accService->CreateMutableAccessible(node,&acc); + acc->SetName(NS_LITERAL_STRING("Text Field").get()); + acc->SetRole(NS_LITERAL_STRING("text").get()); + acc->SetIsLeaf(PR_TRUE); + *aInstancePtr = acc; + return NS_OK; + } + return NS_ERROR_FAILURE; + } + + return nsFormControlFrame::QueryInterface(aIID, aInstancePtr); +} + +NS_IMETHODIMP +nsGfxTextControlFrame::Init(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aContext, + nsIFrame* aPrevInFlow) +{ + mFramePresContext = aPresContext; + nsresult rv = nsFormControlFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); + if (NS_FAILED(rv)) return rv; + + // we are an input (hence single line)? + NS_ASSERTION(mContent, "Should have content here"); + nsCOMPtr<nsIDOMHTMLInputElement> contentAsInput = do_QueryInterface(mContent); + mIsInput = (contentAsInput.get() != nsnull); + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::GetEditor(nsIEditor **aEditor) +{ + NS_ENSURE_ARG_POINTER(aEditor); + + *aEditor = mEditor; + NS_IF_ADDREF(*aEditor); + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::GetFrameType(nsIAtom** aType) const +{ + NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer"); + *aType = NS_NewAtom("textControlFrame"); + return NS_OK; +} + + +NS_IMETHODIMP +nsGfxTextControlFrame::GetDocShell(nsIDocShell **aDocShell) +{ + NS_ENSURE_ARG_POINTER(aDocShell); + + *aDocShell = mDocShell; + NS_IF_ADDREF(*aDocShell); + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::SetInnerFocus() +{ + SetFocus(); + return NS_OK; +} + + +NS_IMETHODIMP +nsGfxTextControlFrame::GetFirstTextNode(nsIDOMCharacterData* *aFirstTextNode) +{ + *aFirstTextNode = nsnull; + + // get the doc + nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(mDoc); + if (!htmlDoc) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMHTMLElement> bodyElement; + htmlDoc->GetBody(getter_AddRefs(bodyElement)); + if (!bodyElement) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMNode> bodyNode = do_QueryInterface(bodyElement); + if (!bodyNode) return NS_ERROR_FAILURE; + + // for a text widget, the text of the document is in a single + // text node under the body. Let's make sure that's true. + nsCOMPtr<nsIDOMNodeList> childNodesList; + bodyNode->GetChildNodes(getter_AddRefs(childNodesList)); + if (!childNodesList) + { + NS_WARNING("Subdoc has no text node list"); + return NS_ERROR_FAILURE; + } + + PRUint32 numChildNodes = 0; + childNodesList->GetLength(&numChildNodes); +#if 0 + // editor can leave empty text node droppings around after deleting + // all the text in a widget, so disable this check for now. + if (numChildNodes != 1) + { + NS_WARNING("Found zero or several child nodes in a text widget doc!"); + return NS_ERROR_FAILURE; + } +#endif + + nsCOMPtr<nsIDOMNode> firstChild; + nsresult rv = bodyNode->GetFirstChild(getter_AddRefs(firstChild)); + if (NS_FAILED(rv)) return rv; + if (!firstChild) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMCharacterData> charDataNode = do_QueryInterface(firstChild, &rv); + if (NS_FAILED(rv)) return rv; + + NS_ADDREF(*aFirstTextNode = charDataNode); + return NS_OK; +} + + +nsresult +nsGfxTextControlFrame::SelectAllContents() +{ + nsresult rv; + + if (IsSingleLineInput()) + { + rv = SetSelectionRange(0, eSelectToEnd); + } + else + { + // we have to select all + rv = EnsureEditor(); + if (NS_FAILED(rv)) return rv; + + NS_ASSERTION(mEditor, "Should have an editor here"); + rv = mEditor->SelectAll(); + } + + return rv; +} + + +nsresult +nsGfxTextControlFrame::SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd) +{ + NS_ASSERTION(IsSingleLineInput(), "Should only call this on a single line input"); + NS_ASSERTION(mEditor, "Should have an editor here"); + NS_ASSERTION(mDoc, "Should have an editor here"); + + nsCOMPtr<nsIDOMCharacterData> firstTextNode; + nsresult rv = GetFirstTextNode(getter_AddRefs(firstTextNode)); + if (NS_FAILED(rv) || !firstTextNode) + { + // probably an empty document. not an error + return NS_OK; + } + + nsCOMPtr<nsIDOMNode> firstNode = do_QueryInterface(firstTextNode, &rv); + if (!firstNode) return rv; + + // constrain the selection to this node + PRUint32 nodeLengthU; + firstTextNode->GetLength(&nodeLengthU); + PRInt32 nodeLength = (PRInt32)nodeLengthU; + + nsCOMPtr<nsISelection> selection; + mEditor->GetSelection(getter_AddRefs(selection)); + if (!selection) return NS_ERROR_FAILURE; + + // are we setting both start and end? + if (aSelStart != eIgnoreSelect && aSelEnd != eIgnoreSelect) + { + if (aSelStart == eSelectToEnd || aSelStart > nodeLength) + aSelStart = nodeLength; + if (aSelStart < 0) + aSelStart = 0; + + if (aSelEnd == eSelectToEnd || aSelEnd > nodeLength) + aSelEnd = nodeLength; + if (aSelEnd < 0) + aSelEnd = 0; + + // remove existing ranges + selection->ClearSelection(); + + nsCOMPtr<nsIDOMRange> selectionRange(do_CreateInstance(kRangeCID,&rv)); + if (NS_FAILED(rv)) + return rv; + + selectionRange->SetStart(firstTextNode, aSelStart); + selectionRange->SetEnd(firstTextNode, aSelEnd); + + selection->AddRange(selectionRange); + } + else // we're setting either start or end but not both + { + // does a range exist? + nsCOMPtr<nsIDOMRange> firstRange; + selection->GetRangeAt(0, getter_AddRefs(firstRange)); + PRBool mustAdd = PR_FALSE; + PRInt32 selStart = 0, selEnd = 0; + + if (firstRange) + { + firstRange->GetStartOffset(&selStart); + firstRange->GetEndOffset(&selEnd); + } + else + { + // no range. Make a new one. + firstRange = do_CreateInstance(kRangeCID,&rv); + if (NS_FAILED(rv)) + return rv; + mustAdd = PR_TRUE; + } + + if (aSelStart == eSelectToEnd) + selStart = nodeLength; + else if (aSelStart != eIgnoreSelect) + selStart = aSelStart; + + if (aSelEnd == eSelectToEnd) + selEnd = nodeLength; + else if (aSelEnd != eIgnoreSelect) + selEnd = aSelEnd; + + // swap them + if (selEnd < selStart) + { + PRInt32 temp = selStart; + selStart = selEnd; + selEnd = temp; + } + + firstRange->SetStart(firstTextNode, selStart); + firstRange->SetEnd(firstTextNode, selEnd); + if (mustAdd) + selection->AddRange(firstRange); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::SetSelectionRange(PRInt32 aSelStart, PRInt32 aSelEnd) +{ + if (!IsSingleLineInput()) return NS_ERROR_NOT_IMPLEMENTED; + + // make sure we have an editor + nsresult rv = EnsureEditor(); + if (NS_FAILED(rv)) return rv; + + NS_ASSERTION(mEditor, "Should have an editor here"); + NS_ASSERTION(mDoc, "Should have an editor here"); + + return SetSelectionEndPoints(aSelStart, aSelEnd); +} + + +NS_IMETHODIMP +nsGfxTextControlFrame::SetSelectionStart(PRInt32 aSelectionStart) +{ + if (!IsSingleLineInput()) return NS_ERROR_NOT_IMPLEMENTED; + + // make sure we have an editor + nsresult rv = EnsureEditor(); + if (NS_FAILED(rv)) return rv; + + NS_ASSERTION(mEditor, "Should have an editor here"); + NS_ASSERTION(mDoc, "Should have an editor here"); + + return SetSelectionEndPoints(aSelectionStart, eIgnoreSelect); +} + +NS_IMETHODIMP +nsGfxTextControlFrame::SetSelectionEnd(PRInt32 aSelectionEnd) +{ + if (!IsSingleLineInput()) return NS_ERROR_NOT_IMPLEMENTED; + + // make sure we have an editor + nsresult rv = EnsureEditor(); + if (NS_FAILED(rv)) return rv; + + NS_ASSERTION(mEditor, "Should have an editor here"); + NS_ASSERTION(mDoc, "Should have an editor here"); + + return SetSelectionEndPoints(eIgnoreSelect, aSelectionEnd); +} + +NS_IMETHODIMP +nsGfxTextControlFrame::GetTextLength(PRInt32* aTextLength) +{ + if (!IsSingleLineInput()) return NS_ERROR_NOT_IMPLEMENTED; + + NS_ENSURE_ARG_POINTER(aTextLength); + *aTextLength = 0; + + nsresult rv = EnsureEditor(); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr<nsIDOMCharacterData> firstTextNode; + rv = GetFirstTextNode(getter_AddRefs(firstTextNode)); + if (NS_FAILED(rv) || !firstTextNode) + { + // just an empty field. not an error + return NS_OK; + } + + PRUint32 nodeLengthU; + firstTextNode->GetLength(&nodeLengthU); + *aTextLength = (PRInt32)nodeLengthU; + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd) +{ + if (!IsSingleLineInput()) return NS_ERROR_NOT_IMPLEMENTED; + + NS_ENSURE_ARG_POINTER((aSelectionStart && aSelectionEnd)); + + nsresult rv = EnsureEditor(); + if (NS_FAILED(rv)) return rv; + + NS_ASSERTION(mEditor, "Should have an editor here"); + NS_ASSERTION(mDoc, "Should have an editor here"); + + nsCOMPtr<nsISelection> selection; + mEditor->GetSelection(getter_AddRefs(selection)); + if (!selection) return NS_ERROR_FAILURE; + + // we should have only zero or one range + PRInt32 numRanges = 0; + selection->GetRangeCount(&numRanges); + if (numRanges > 1) + { + NS_ASSERTION(0, "Found more than on range in GetSelectionRange"); + } + + if (numRanges == 0) + { + *aSelectionStart = 0; + *aSelectionEnd = 0; + } + else + { + nsCOMPtr<nsIDOMRange> firstRange; + selection->GetRangeAt(0, getter_AddRefs(firstRange)); + if (!firstRange) return NS_ERROR_FAILURE; +#if 0 + // make sure this range is pointing at the first child + nsCOMPtr<nsIDOMCharacterData> firstTextNode; + rv = GetFirstTextNode(getter_AddRefs(firstTextNode)); + nsCOMPtr<nsIDOMNode> firstNode = do_QueryInterface(firstTextNode); + if (!firstNode) + { + *aSelectionStart = 0; + *aSelectionEnd = 0; + return NS_OK; + } + + nsCOMPtr<nsIDOMNode> rangeStartNode; + firstRange->GetStartParent(getter_AddRefs(rangeStartNode)); // maybe we should compare the end too? + if (rangeStartNode != firstNode) return NS_ERROR_FAILURE; +#endif + firstRange->GetStartOffset(aSelectionStart); + firstRange->GetEndOffset(aSelectionEnd); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::EnsureEditor() +{ + nsresult rv = NS_OK; + if (!mDocShell) + { + rv = CreateSubDoc(nsnull); + if (NS_FAILED(rv)) return rv; + } + return NS_OK; +} + + +NS_IMETHODIMP +nsGfxTextControlFrame::CreateEditor() +{ + nsresult result = NS_OK; + + mDocShell = nsnull; + mCreatingViewer = PR_FALSE; + + // create the stream observer + mTempObserver = new EnderTempObserver(); + if (!mTempObserver) { return NS_ERROR_OUT_OF_MEMORY; } + mTempObserver->SetFrame(this); + NS_ADDREF(mTempObserver); + + // create the document observer + mDocObserver = new nsEnderDocumentObserver(); + if (!mDocObserver) { return NS_ERROR_OUT_OF_MEMORY; } + mDocObserver->SetFrame(this); + NS_ADDREF(mDocObserver); + + // create the drag listener for the content node + if (mContent) + { + mListenerForContent = new nsEnderListenerForContent(); + if (!mListenerForContent) { return NS_ERROR_OUT_OF_MEMORY; } + mListenerForContent->SetFrame(this); + NS_ADDREF(mListenerForContent); + + // get the DOM event receiver + nsCOMPtr<nsIDOMEventReceiver> contentER; + result = mContent->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(contentER)); + if NS_FAILED(result) { return result; } + if (contentER) + { + nsCOMPtr<nsIDOMDragListener> dragListenerForContent; + mListenerForContent->QueryInterface(NS_GET_IID(nsIDOMDragListener), getter_AddRefs(dragListenerForContent)); + if (dragListenerForContent) + { + result = contentER->AddEventListenerByIID(dragListenerForContent, NS_GET_IID(nsIDOMDragListener)); + if NS_FAILED(result) { return result; } + } + } + } + + // create the focus listener for HTML Input display content + if (mDisplayContent) + { + mFocusListenerForDisplayContent = new nsEnderFocusListenerForDisplayContent(); + if (!mFocusListenerForDisplayContent) { return NS_ERROR_OUT_OF_MEMORY; } + mFocusListenerForDisplayContent->SetFrame(this); + NS_ADDREF(mFocusListenerForDisplayContent); + // get the DOM event receiver + nsCOMPtr<nsIDOMEventReceiver> er; + result = mDisplayContent->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(er)); + if (NS_SUCCEEDED(result) && er) + result = er->AddEventListenerByIID(mFocusListenerForDisplayContent, NS_GET_IID(nsIDOMFocusListener)); + // should check to see if mDisplayContent or mContent has focus and call CreateSubDoc instead if it does + // do something with result + } + + nsCOMPtr<nsIHTMLEditor> theEditor; + result = nsComponentManager::CreateInstance(kHTMLEditorCID, + nsnull, + NS_GET_IID(nsIHTMLEditor), getter_AddRefs(theEditor)); + if (NS_FAILED(result)) { return result; } + if (!theEditor) { return NS_ERROR_OUT_OF_MEMORY; } + mEditor = do_QueryInterface(theEditor); + if (!mEditor) { return NS_ERROR_NO_INTERFACE; } + return NS_OK; +} + + +NS_METHOD nsGfxTextControlFrame::HandleEvent(nsIPresContext* aPresContext, + nsGUIEvent* aEvent, + nsEventStatus* aEventStatus) +{ + NS_ENSURE_ARG_POINTER(aPresContext); + NS_ENSURE_ARG_POINTER(aEvent); + NS_ENSURE_ARG_POINTER(aEventStatus); + + if (nsEventStatus_eConsumeNoDefault == *aEventStatus) { + return NS_OK; + } + + *aEventStatus = nsEventStatus_eConsumeDoDefault; // this is the default + + /* the handling of mouse messages here has two purposes: + * 1) to create a subdoc if one doesn't exist on click, and to pass + * mouse messages along to the content of the subdoc in the case + * where we created it in response to a click. + * 2) to call MouseClicked + */ + switch (aEvent->message) { + case NS_MOUSE_LEFT_BUTTON_DOWN: + case NS_MOUSE_MIDDLE_BUTTON_DOWN: + case NS_MOUSE_RIGHT_BUTTON_DOWN: + // don't pass through a click if we're already handling a click + if (eGotDown != mPassThroughMouseEvents) + { + mPassThroughMouseEvents = eGotDown; + if (!mDocShell) { + NS_ENSURE_SUCCESS(CreateSubDoc(nsnull), NS_ERROR_FAILURE); + } + NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); + return RedispatchMouseEventToSubDoc(aPresContext, aEvent, aEventStatus, PR_TRUE); + } + break; + + case NS_MOUSE_LEFT_BUTTON_UP: + case NS_MOUSE_MIDDLE_BUTTON_UP: + case NS_MOUSE_RIGHT_BUTTON_UP: + // only pass through the mouseUp if we're the one who handled the mouseDown + if (eGotDown==mPassThroughMouseEvents) + { + mPassThroughMouseEvents = eGotUp; + NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); + return RedispatchMouseEventToSubDoc(aPresContext, aEvent, aEventStatus, PR_FALSE); + } + break; + + case NS_MOUSE_LEFT_CLICK: + case NS_MOUSE_MIDDLE_CLICK: + case NS_MOUSE_RIGHT_CLICK: + MouseClicked(aPresContext); + // only pass through the mouseClick if we're the one who handled the mouseUp + if (eGotUp==mPassThroughMouseEvents) + { + mPassThroughMouseEvents = eGotClick; + NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); + return RedispatchMouseEventToSubDoc(aPresContext, aEvent, aEventStatus, PR_FALSE); + } + break; + + case NS_MOUSE_LEFT_DOUBLECLICK: + case NS_MOUSE_MIDDLE_DOUBLECLICK: + case NS_MOUSE_RIGHT_DOUBLECLICK: + // XXX shouldn't this have the same check that we handled the mouse up + // XXX as did the single click events? + // XX Do we ever get here, i.e. are these messages obsolete anyway? + mPassThroughMouseEvents = eGotClick; + NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); + return RedispatchMouseEventToSubDoc(aPresContext, aEvent, aEventStatus, PR_FALSE); + break; + + case NS_MOUSE_MOVE: + // only pass through the mouseMove if we're the one who handled the mouseDown + if (eGotDown==mPassThroughMouseEvents) + { + if (mDocShell) { + return RedispatchMouseEventToSubDoc(aPresContext, aEvent, aEventStatus, PR_FALSE); + } + } + break; + + case NS_DRAGDROP_ENTER: + case NS_DRAGDROP_OVER_SYNTH: + case NS_DRAGDROP_DROP: + case NS_DRAGDROP_EXIT_SYNTH: + // currently unused + break; + + case NS_DRAGDROP_GESTURE: + // this currently seems to have no effect + NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); + return RedispatchMouseEventToSubDoc(aPresContext, aEvent, aEventStatus, PR_FALSE); + break; + + case NS_KEY_PRESS: + if (NS_KEY_EVENT == aEvent->eventStructType) { + nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent; + // XXX What is this all about? SHouldn't this all be handled + // XXX by XBL key bindings, rather than hardwired in here? + // XXX Even if it should be hardwired, why VK_RETURN and not VK_ENTER? + if (NS_VK_RETURN == keyEvent->keyCode) + { + EnterPressed(aPresContext); + *aEventStatus = nsEventStatus_eConsumeNoDefault; + } + else if (NS_VK_SPACE == keyEvent->keyCode) + { + MouseClicked(aPresContext); + } + } + break; + + case NS_FORM_SELECTED: + return UpdateTextControlCommands(NS_ConvertASCIItoUCS2("select")); + break; + } + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::RedispatchMouseEventToSubDoc(nsIPresContext* aPresContext, + nsGUIEvent* aEvent, + nsEventStatus* aEventStatus, + PRBool aAdjustForView) +{ + NS_ENSURE_ARG_POINTER(aPresContext); + NS_ENSURE_ARG_POINTER(aEvent); + NS_ENSURE_ARG_POINTER(aEventStatus); + + nsCOMPtr<nsIContentViewer> viewer; + NS_ENSURE_SUCCESS(mDocShell->GetContentViewer(getter_AddRefs(viewer)), NS_ERROR_FAILURE); + if (viewer) + { + nsCOMPtr<nsIDocumentViewer> docv; + viewer->QueryInterface(NS_GET_IID(nsIDocumentViewer), getter_AddRefs(docv)); + if (docv) + { + nsCOMPtr<nsIPresContext> cx; + NS_ENSURE_SUCCESS(docv->GetPresContext(*(getter_AddRefs(cx))), NS_ERROR_FAILURE); + if (cx) + { + nsCOMPtr<nsIPresShell> shell; + NS_ENSURE_SUCCESS(cx->GetShell(getter_AddRefs(shell)), NS_ERROR_FAILURE); + if (shell) + { + nsIFrame * rootFrame; + NS_ENSURE_SUCCESS(shell->GetRootFrame(&rootFrame), NS_ERROR_FAILURE); + + nsCOMPtr<nsIViewManager> vm; + NS_ENSURE_SUCCESS(shell->GetViewManager(getter_AddRefs(vm)), NS_ERROR_FAILURE); + if (vm) + { + // create a new mouse event + nsMouseEvent event; + event = *((nsMouseEvent*)aEvent); + // if we're told to, translate the event point based on the view of this text control + if (PR_TRUE==aAdjustForView) + { + nsIView * view = nsnull; + GetView(aPresContext, &view); + NS_ASSERTION(view, "text control frame has no view"); + if (!view) { return NS_ERROR_NULL_POINTER;} + nsRect viewBounds; + view->GetBounds(viewBounds); + event.point.x -= viewBounds.x; + event.point.y -= viewBounds.y; + } + // translate the event point based on this frame's border and padding + nsSize size; + GetSize(size); + nsRect subBounds; + nsMargin border; + nsMargin padding; + border.SizeTo(0, 0, 0, 0); + padding.SizeTo(0, 0, 0, 0); + const nsStyleBorder* borderStyle; + const nsStylePadding* paddingStyle; + GetStyleData(eStyleStruct_Border, (const nsStyleStruct *&)borderStyle); + GetStyleData(eStyleStruct_Border, (const nsStyleStruct *&)paddingStyle); + borderStyle->CalcBorderFor(this, border); + paddingStyle->CalcPaddingFor(this, padding); + CalcSizeOfSubDocInTwips(border, padding, size, subBounds); + event.point.x -= (border.left + padding.left); + if (0>event.point.x) { + event.point.x = 0; + } + else if (event.point.x > subBounds.width) { + event.point.x = subBounds.width-1; + } + event.point.y -= (border.top + padding.top); + if (0>event.point.y) { + event.point.y = 0; + } + else if (event.point.y > subBounds.height) { + event.point.x = subBounds.height-1; + } + + // translate the event point to pixels for consumption by the embedded view manager + nsCOMPtr<nsIDeviceContext> dc; + aPresContext->GetDeviceContext(getter_AddRefs(dc)); + NS_ASSERTION(dc, "text control frame has no dc"); + if (!dc) { return NS_ERROR_NULL_POINTER;} + float t2p; + dc->GetAppUnitsToDevUnits(t2p); + + event.point.x = NSTwipsToIntPixels(event.point.x, t2p); + event.point.y = NSTwipsToIntPixels(event.point.y, t2p); + NS_ENSURE_SUCCESS(vm->DispatchEvent(&event, aEventStatus), NS_ERROR_FAILURE); + } + } + } + } + } + return NS_OK; +} + +void +nsGfxTextControlFrame::EnterPressed(nsIPresContext* aPresContext) +{ + // Send out onChange event here to get http://maps working (bug 18501) + nsCOMPtr<nsIDOMFocusListener> fListener = do_QueryInterface(mEventListener); + if (fListener) { + fListener->Blur(nsnull); + } + + // Submit the form + if (mFormFrame && mFormFrame->CanSubmit(this)) { + nsIContent *formContent = nsnull; + + nsEventStatus status = nsEventStatus_eIgnore; + + mFormFrame->GetContent(&formContent); + if (nsnull != formContent) { + nsEvent event; + event.eventStructType = NS_EVENT; + event.message = NS_FORM_SUBMIT; + formContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); + NS_RELEASE(formContent); + } + + if (nsEventStatus_eConsumeNoDefault != status) { + mFormFrame->OnSubmit(aPresContext, this); + } + } +} + +nsWidgetInitData* +nsGfxTextControlFrame::GetWidgetInitData(nsIPresContext* aPresContext) +{ + return nsnull; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::GetText(nsString* aText, PRBool aInitialValue) +{ + nsresult result = NS_CONTENT_ATTR_NOT_THERE; + PRInt32 type; + GetType(&type); + if ((NS_FORM_INPUT_TEXT == type) || (NS_FORM_INPUT_PASSWORD == type)) + { + if (PR_TRUE==aInitialValue) + { + result = nsFormControlHelper::GetInputElementValue(mContent, aText, aInitialValue); + } + else + { + if (PR_TRUE==IsInitialized()) + { + if (mEditor) + { + nsCOMPtr<nsIEditorIMESupport> imeSupport = do_QueryInterface(mEditor); + if(imeSupport) + imeSupport->ForceCompositionEnd(); + nsString format; format.AssignWithConversion("text/plain"); + mEditor->OutputToString(*aText, format, 0); + } + // we've never built our editor, so the content attribute is the value + else + { + result = nsFormControlHelper::GetInputElementValue(mContent, aText, aInitialValue); + } + } + else { + if (mCachedState) { + *aText = *mCachedState; + result = NS_OK; + } else { + result = nsFormControlHelper::GetInputElementValue(mContent, aText, aInitialValue); + } + } + } + RemoveNewlines(*aText); + } + else + { + nsIDOMHTMLTextAreaElement* textArea = nsnull; + result = mContent->QueryInterface(NS_GET_IID(nsIDOMHTMLTextAreaElement), (void**)&textArea); + if ((NS_OK == result) && textArea) { + if (PR_TRUE == aInitialValue) { + result = textArea->GetDefaultValue(*aText); + } + else { + if(mEditor) { + nsCOMPtr<nsIEditorIMESupport> imeSupport = do_QueryInterface(mEditor); + if(imeSupport) + imeSupport->ForceCompositionEnd(); + } + result = textArea->GetValue(*aText); + } + NS_RELEASE(textArea); + } + } + return result; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aHint) +{ + nsresult result = NS_OK; + + if (nsHTMLAtoms::value == aAttribute) + { + if (mEditor) + mEditor->EnableUndo(PR_FALSE); // wipe out undo info + nsString value; + GetText(&value, PR_TRUE); // get the initial value from the content attribute + SetTextControlFrameState(value); // set new text value + if (mEditor) + mEditor->EnableUndo(PR_TRUE); // fire up a new txn stack + if (aHint != NS_STYLE_HINT_REFLOW) + nsFormFrame::StyleChangeReflow(aPresContext, this); + } + else if (nsHTMLAtoms::maxlength == aAttribute) + { + PRInt32 maxLength; + nsresult rv = GetMaxLength(&maxLength); + + nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor); + if (htmlEditor) + { + if (NS_CONTENT_ATTR_NOT_THERE != rv) + { // set the maxLength attribute + htmlEditor->SetMaxTextLength(maxLength); + // if maxLength>docLength, we need to truncate the doc content + } + else { // unset the maxLength attribute + htmlEditor->SetMaxTextLength(-1); + } + } + } + else if (mEditor && nsHTMLAtoms::readonly == aAttribute) + { + nsCOMPtr<nsISelectionController> selCon; + mEditor->GetSelectionController(getter_AddRefs(selCon)); + + nsresult rv = DoesAttributeExist(nsHTMLAtoms::readonly); + PRUint32 flags; + mEditor->GetFlags(&flags); + if (NS_CONTENT_ATTR_NOT_THERE != rv) + { // set readonly + flags |= nsIHTMLEditor::eEditorReadonlyMask; + if (selCon) + selCon->SetCaretEnabled(PR_FALSE); + } + else + { // unset readonly + flags &= ~(nsIHTMLEditor::eEditorReadonlyMask); + if (selCon) + selCon->SetCaretEnabled(PR_TRUE); + } + mEditor->SetFlags(flags); + } + else if (mEditor && nsHTMLAtoms::disabled == aAttribute) + { + nsCOMPtr<nsISelectionController> selCon; + mEditor->GetSelectionController(getter_AddRefs(selCon)); + nsCOMPtr<nsIPresShell> presShell; + presShell = do_QueryInterface(selCon); + + nsresult rv = DoesAttributeExist(nsHTMLAtoms::disabled); + PRUint32 flags; + mEditor->GetFlags(&flags); + if (NS_CONTENT_ATTR_NOT_THERE != rv) + { // set readonly + flags |= nsIHTMLEditor::eEditorDisabledMask; + selCon->SetCaretEnabled(PR_FALSE); + selCon->SetDisplaySelection(nsISelectionController::SELECTION_OFF); + } + else + { // unset readonly + flags &= ~(nsIHTMLEditor::eEditorDisabledMask); + selCon->SetCaretEnabled(PR_TRUE); + selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON); + } + mEditor->SetFlags(flags); + } + else if ((nsHTMLAtoms::size == aAttribute || + nsHTMLAtoms::rows == aAttribute) && aHint != NS_STYLE_HINT_REFLOW) { + nsFormFrame::StyleChangeReflow(aPresContext, this); + } + // Allow the base class to handle common attributes supported + // by all form elements... + else { + result = nsFormControlFrame::AttributeChanged(aPresContext, aChild, aNameSpaceID, aAttribute, aHint); + } + + return result; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::DoesAttributeExist(nsIAtom *aAtt) +{ + nsresult result = NS_CONTENT_ATTR_NOT_THERE; + nsIHTMLContent* content = nsnull; + mContent->QueryInterface(kIHTMLContentIID, (void**) &content); + if (nsnull != content) + { + nsHTMLValue value; + result = content->GetHTMLAttribute(aAtt, value); + NS_RELEASE(content); + } + return result; +} + +// aSizeOfSubdocContainer is in pixels, not twips +nsresult +nsGfxTextControlFrame::CreateSubDoc(nsRect *aSizeOfSubdocContainer) +{ + if (!mFramePresContext) { return NS_ERROR_NULL_POINTER; } + + nsresult rv = NS_OK; + + if (!IsInitialized() && !mCreatingViewer) + { + // if the editor hasn't been created yet, create it + if (!mEditor) + { + rv = CreateEditor(); + if (NS_FAILED(rv)) { return rv; } + nsCOMPtr<nsIDOMNSHTMLTextAreaElement> textAreaElement = do_QueryInterface(mContent); + nsCOMPtr<nsIDOMNSHTMLInputElement> inputElement = do_QueryInterface(mContent); + nsCOMPtr<nsIControllers> controllers; + if (textAreaElement) + textAreaElement->GetControllers(getter_AddRefs(controllers)); + else if (inputElement) + inputElement->GetControllers(getter_AddRefs(controllers)); + else + return rv = NS_ERROR_FAILURE; + + if (NS_SUCCEEDED(rv)) + { + PRUint32 count; + PRBool found = PR_FALSE; + rv = controllers->GetControllerCount(&count); + for (PRUint32 i = 0; i < count; i ++) + { + nsCOMPtr<nsIController> controller; + rv = controllers->GetControllerAt(i, getter_AddRefs(controller)); + if (NS_SUCCEEDED(rv) && controller) + { + nsCOMPtr<nsIEditorController> editController = do_QueryInterface(controller); + if (editController) + { + editController->SetCommandRefCon(mEditor); + found = PR_TRUE; + } + } + } + if (!found) + rv = NS_ERROR_FAILURE; + } + + NS_ASSERTION(mEditor, "null EDITOR after attempt to create."); + } + + // initialize the subdoc, if it hasn't already been constructed + // if the size is not 0 and there is a src, create the web shell + + if (!mDocShell) + { + nsSize size; + GetSize(size); + nsRect subBounds; + if (aSizeOfSubdocContainer) + { + subBounds = *aSizeOfSubdocContainer; + } + else + { + nsMargin border; + nsMargin padding; + border.SizeTo(0, 0, 0, 0); + padding.SizeTo(0, 0, 0, 0); + // Get the CSS border + const nsStyleBorder* borderStyle; + const nsStylePadding* paddingStyle; + GetStyleData(eStyleStruct_Border, (const nsStyleStruct *&)borderStyle); + GetStyleData(eStyleStruct_Border, (const nsStyleStruct *&)paddingStyle); + borderStyle->CalcBorderFor(this, border); + paddingStyle->CalcPaddingFor(this, padding); + CalcSizeOfSubDocInTwips(border, padding, size, subBounds); + float t2p; + mFramePresContext->GetTwipsToPixels(&t2p); + subBounds.x = NSToCoordRound(subBounds.x * t2p); + subBounds.y = NSToCoordRound(subBounds.y * t2p); + subBounds.width = NSToCoordRound(subBounds.width * t2p); + subBounds.height = NSToCoordRound(subBounds.height * t2p); + } + + rv = CreateDocShell(mFramePresContext, size); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); +#ifdef NOISY + printf("%p docshell in CreateSubDoc set to bounds: x=%d, y=%d, w=%d, h=%d\n", mDocShell.get(), subBounds.x, subBounds.y, subBounds.width, subBounds.height); +#endif + nsCOMPtr<nsIBaseWindow> docShellWin(do_QueryInterface(mDocShell)); + NS_ENSURE_TRUE(docShellWin, NS_ERROR_FAILURE); + docShellWin->SetPositionAndSize(subBounds.x, subBounds.y, + subBounds.width, subBounds.height, PR_FALSE); + } + mCreatingViewer=PR_TRUE; + + // create document + nsCOMPtr<nsIDocument> doc; + rv = NS_NewHTMLDocument(getter_AddRefs(doc)); + if (NS_FAILED(rv)) { return rv; } + if (!doc) { return NS_ERROR_NULL_POINTER; } + + nsCOMPtr<nsINodeInfoManager> nimgr; + rv = doc->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsINodeInfo> nodeInfo; + nimgr->GetNodeInfo(nsHTMLAtoms::html, nsnull, kNameSpaceID_None, + *getter_AddRefs(nodeInfo)); + + // create document content + nsCOMPtr<nsIHTMLContent> htmlElement; + nsCOMPtr<nsIHTMLContent> headElement; + nsCOMPtr<nsIHTMLContent> bodyElement; + // create the root + rv = NS_NewHTMLHtmlElement(getter_AddRefs(htmlElement), nodeInfo); + if (NS_FAILED(rv)) { return rv; } + if (!htmlElement) { return NS_ERROR_NULL_POINTER; } + // create the head + + nimgr->GetNodeInfo(NS_ConvertASCIItoUCS2("head"), nsnull, + kNameSpaceID_None, *getter_AddRefs(nodeInfo)); + + rv = NS_NewHTMLHeadElement(getter_AddRefs(headElement), nodeInfo); + if (NS_FAILED(rv)) { return rv; } + if (!headElement) { return NS_ERROR_NULL_POINTER; } + headElement->SetDocument(doc, PR_FALSE, PR_TRUE); + // create the body + + nimgr->GetNodeInfo(nsHTMLAtoms::body, nsnull, kNameSpaceID_None, + *getter_AddRefs(nodeInfo)); + + rv = NS_NewHTMLBodyElement(getter_AddRefs(bodyElement), nodeInfo); + if (NS_FAILED(rv)) { return rv; } + if (!bodyElement) { return NS_ERROR_NULL_POINTER; } + bodyElement->SetDocument(doc, PR_FALSE, PR_TRUE); + // put the head and body into the root + rv = htmlElement->AppendChildTo(headElement, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } + rv = htmlElement->AppendChildTo(bodyElement, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } + + // load the document into the docshell + nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc); + if (!domDoc) { return NS_ERROR_NULL_POINTER; } + nsCOMPtr<nsIDOMElement> htmlDOMElement = do_QueryInterface(htmlElement); + if (!htmlDOMElement) { return NS_ERROR_NULL_POINTER; } + rv = mDocShell->SetDocument(domDoc, htmlDOMElement); + + // force an incremental reflow of the text control + /* XXX: this is to get the view/docshell positioned correctly. + I don't know why it's required, it looks like this code positions the view and docshell + exactly the same way reflow does, but reflow works and the code above does not + when the text control is in a view which is scrolled. + */ + nsCOMPtr<nsIReflowCommand> cmd; + rv = NS_NewHTMLReflowCommand(getter_AddRefs(cmd), this, nsIReflowCommand::StyleChanged); + if (NS_FAILED(rv)) { return rv; } + if (!cmd) { return NS_ERROR_NULL_POINTER; } + nsCOMPtr<nsIPresShell> shell; + rv = mFramePresContext->GetShell(getter_AddRefs(shell)); + if (NS_FAILED(rv)) { return rv; } + if (!shell) { return NS_ERROR_NULL_POINTER; } + rv = shell->AppendReflowCommand(cmd); + } + return rv; +} + +void nsGfxTextControlFrame::CalcSizeOfSubDocInTwips(const nsMargin &aBorder, + const nsMargin &aPadding, + const nsSize &aFrameSize, + nsRect &aSubBounds) +{ + + // XXX: the point here is to make a single-line edit field as wide as it wants to be, + // so it will scroll horizontally if the characters take up more space than the field + aSubBounds.x = aBorder.left + aPadding.left; + aSubBounds.y = aBorder.top + aPadding.top; + aSubBounds.width = (aFrameSize.width - (aBorder.left + aPadding.left + aBorder.right + aPadding.right)); + if (aSubBounds.width<0) { + aSubBounds.width = 0; + } + aSubBounds.height = (aFrameSize.height - (aBorder.top + aPadding.top + aBorder.bottom + aPadding.bottom)); + if (aSubBounds.height<0) { + aSubBounds.height = 0; + } +} + +PRInt32 +nsGfxTextControlFrame::GetMaxNumValues() +{ + return 1; +} + +PRBool +nsGfxTextControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, + nsString* aValues, nsString* aNames) +{ + if (!aValues || !aNames) { return PR_FALSE; } + + nsAutoString name; + nsresult result = GetName(&name); + if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_NOT_THERE == result)) { + return PR_FALSE; + } + + aNames[0] = name; + aNumValues = 1; + + GetText(&(aValues[0]), PR_FALSE); + // XXX: error checking + return PR_TRUE; +} + + +void +nsGfxTextControlFrame::Reset(nsIPresContext* aPresContext) +{ + nsAutoString value; + nsresult valStatus = GetText(&value, PR_TRUE); + NS_ASSERTION((NS_SUCCEEDED(valStatus)), "GetText failed"); + if (NS_SUCCEEDED(valStatus)) + { + SetTextControlFrameState(value); + } +} + +NS_METHOD +nsGfxTextControlFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ +#ifdef NOISY + printf("%p paint layer %d at (%d, %d, %d, %d)\n", this, aWhichLayer, + aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); +#endif + if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) + { + nsAutoString text; text.AssignWithConversion(" "); + nsRect rect(0, 0, mRect.width, mRect.height); + PaintTextControl(aPresContext, aRenderingContext, aDirtyRect, + text, mStyleContext, rect); + } + return NS_OK; +} + +void +nsGfxTextControlFrame::PaintTextControlBackground(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + // we paint our own border, but everything else is painted by the mDocshell + if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) + { + nsAutoString text; text.AssignWithConversion(" "); + nsRect rect(0, 0, mRect.width, mRect.height); + PaintTextControl(aPresContext, aRenderingContext, aDirtyRect, + text, mStyleContext, rect); + } +} + +// stolen directly from nsContainerFrame +void +nsGfxTextControlFrame::PaintChild(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsIFrame* aFrame, + nsFramePaintLayer aWhichLayer) +{ + nsIView *pView; + aFrame->GetView(aPresContext, &pView); + if (nsnull == pView) { + nsRect kidRect; + aFrame->GetRect(kidRect); + nsFrameState state; + aFrame->GetFrameState(&state); + + // Compute the constrained damage area; set the overlap flag to + // PR_TRUE if any portion of the child frame intersects the + // dirty rect. + nsRect damageArea; + PRBool overlap; + if (NS_FRAME_OUTSIDE_CHILDREN & state) { + // If the child frame has children that leak out of our box + // then we don't constrain the damageArea to just the childs + // bounding rect. + damageArea = aDirtyRect; + overlap = PR_TRUE; + } + else { + // Compute the intersection of the dirty rect and the childs + // rect (both are in our coordinate space). This limits the + // damageArea to just the portion that intersects the childs + // rect. + overlap = damageArea.IntersectRect(aDirtyRect, kidRect); +#ifdef NS_DEBUG + if (!overlap && (0 == kidRect.width) && (0 == kidRect.height)) { + overlap = PR_TRUE; + } +#endif + } + + if (overlap) { + // Translate damage area into the kids coordinate + // system. Translate rendering context into the kids + // coordinate system. + damageArea.x -= kidRect.x; + damageArea.y -= kidRect.y; + aRenderingContext.PushState(); + aRenderingContext.Translate(kidRect.x, kidRect.y); + + // Paint the kid + aFrame->Paint(aPresContext, aRenderingContext, damageArea, aWhichLayer); + PRBool clipState; + aRenderingContext.PopState(clipState); + +#ifdef NS_DEBUG + // Draw a border around the child + if (nsIFrameDebug::GetShowFrameBorders() && !kidRect.IsEmpty()) { + aRenderingContext.SetColor(NS_RGB(255,0,0)); + aRenderingContext.DrawRect(kidRect); + } +#endif + } + } +} + +void +nsGfxTextControlFrame::PaintTextControl(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsString& aText, + nsIStyleContext* aStyleContext, + nsRect& aRect) +{ + // XXX: aText is currently unused! +#ifdef DEBUG + mDebugTotalPaints++; + mDebugPaintsSinceLastReflow++; +#endif + const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); + if (disp->IsVisible()) + { + nsCompatibility mode; + aPresContext->GetCompatibilityMode(&mode); + const nsStyleBorder* myBorder = (const nsStyleBorder*)aStyleContext->GetStyleData(eStyleStruct_Border); + PRIntn skipSides = 0; + nsRect rect(0, 0, mRect.width, mRect.height); + const nsStyleColor* color = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *color, *myBorder, 0, 0); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *myBorder, aStyleContext, skipSides); + if (!mDocShell) + { + if (mDisplayFrame) { + PaintChild(aPresContext, aRenderingContext, aDirtyRect, mDisplayFrame, NS_FRAME_PAINT_LAYER_FOREGROUND); + //mDisplayFrame->Paint(aPresContext, aRenderingContext, aDirtyRect, NS_FRAME_PAINT_LAYER_FOREGROUND); + } + } + } +#ifdef DEBUG +#ifdef NOISY + printf("gfxTC: %p totalPaints=%d, paintsSinceLastReflow=%d\n", + mDebugTotalPaints, mDebugPaintsSinceLastReflow); +#endif +#endif +} + +//XXX: this needs to be fixed for HTML output +void nsGfxTextControlFrame::GetTextControlFrameState(nsString& aValue) +{ + aValue.SetLength(0); // initialize out param + + if (mEditor && PR_TRUE==IsInitialized()) + { + nsString format; format.AssignWithConversion("text/plain"); + PRUint32 flags = 0; + + if (PR_TRUE==IsPlainTextControl()) { + flags |= nsIDocumentEncoder::OutputBodyOnly; + } + + nsFormControlHelper::nsHTMLTextWrap wrapProp; + nsresult result = nsFormControlHelper::GetWrapPropertyEnum(mContent, wrapProp); + if (NS_CONTENT_ATTR_NOT_THERE != result) + { + if (wrapProp == nsFormControlHelper::eHTMLTextWrap_Hard) + { + flags |= nsIDocumentEncoder::OutputFormatted; + } + } + + mEditor->OutputToString(aValue, format, flags); + } + // otherwise, just return our text attribute + else { + if (mCachedState) { + aValue = *mCachedState; + } else { + GetText(&aValue, PR_TRUE); + } + } +} + +void nsGfxTextControlFrame::SetTextControlFrameState(const nsString& aValue) +{ + if (mEditor && PR_TRUE==IsInitialized()) + { + nsAutoString currentValue; + nsAutoString format; format.AssignWithConversion("text/plain"); + nsresult result = mEditor->OutputToString(currentValue, format, 0); + if (PR_TRUE==IsSingleLineTextControl()) { + RemoveNewlines(currentValue); + } + if (PR_FALSE==currentValue.Equals(aValue)) // this is necessary to avoid infinite recursion + { + // \r is an illegal character in the dom, but people use them, + // so convert windows and mac platform linebreaks to \n: + // Unfortunately aValue is declared const, so we have to copy + // in order to do this substitution. + currentValue.Assign(aValue); + nsFormControlHelper::PlatformToDOMLineBreaks(currentValue); + + nsCOMPtr<nsIDOMDocument>domDoc; + result = mEditor->GetDocument(getter_AddRefs(domDoc)); + if (NS_FAILED(result)) return; + if (!domDoc) return; + + result = mEditor->SelectAll(); + nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor); + if (!htmlEditor) return; + + // get the flags, remove readonly and disabled, set the value, restore flags + PRUint32 flags, savedFlags; + mEditor->GetFlags(&savedFlags); + flags = savedFlags; + flags &= ~(nsIHTMLEditor::eEditorDisabledMask); + flags &= ~(nsIHTMLEditor::eEditorReadonlyMask); + mEditor->SetFlags(flags); + mEditor->SelectAll(); + mEditor->DeleteSelection(nsIEditor::eNone); + htmlEditor->InsertText(currentValue); + mEditor->SetFlags(savedFlags); + } + } + else { + if (mCachedState == nsnull) { + mCachedState = new nsString(aValue); + } else { + *mCachedState = aValue; + } + if (mDisplayContent) + { + const PRUnichar *text = mCachedState->GetUnicode(); + PRInt32 len = mCachedState->Length(); + mDisplayContent->SetText(text, len, PR_TRUE); + if (mContent) + { + nsIDocument *doc; + mContent->GetDocument(doc); + if (doc) + { + doc->ContentChanged(mContent, nsnull); + NS_RELEASE(doc); + } + } + } + } +} + +NS_IMETHODIMP +nsGfxTextControlFrame::ContentChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + nsISupports* aSubContent) +{ + // Generate a reflow command with this frame as the target frame + nsIReflowCommand* cmd; + nsresult rv; + + rv = NS_NewHTMLReflowCommand(&cmd, this, nsIReflowCommand::ContentChanged); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr<nsIPresShell> shell; + rv = aPresContext->GetShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv) && shell) { + rv = shell->AppendReflowCommand(cmd); + // we need this reflow to be synchronous because the text may have changed + // length. That would make the content and frame data out of synch, and + // can lead to a crash if we're asked to paint the text before this reflow + // fires. See bug 37264. + if (NS_SUCCEEDED(rv)) { + rv = shell->FlushPendingNotifications(); + } + } + NS_RELEASE(cmd); + } + + return rv; +} + + +NS_IMETHODIMP nsGfxTextControlFrame::SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue) +{ + if (!mIsProcessing) + { + mIsProcessing = PR_TRUE; + + if (nsHTMLAtoms::value == aName) + { + if (mEditor) { + mEditor->EnableUndo(PR_FALSE); // wipe out undo info + } + SetTextControlFrameState(aValue); // set new text value + if (mEditor) { + mEditor->EnableUndo(PR_TRUE); // fire up a new txn stack + } + } + else if (nsHTMLAtoms::select == aName) + { + // select all the text + SelectAllContents(); + } + else + { + return Inherited::SetProperty(aPresContext, aName, aValue); + } + mIsProcessing = PR_FALSE; + } + return NS_OK; +} + +NS_IMETHODIMP nsGfxTextControlFrame::GetProperty(nsIAtom* aName, nsAWritableString& aValue) +{ + // Return the value of the property from the widget it is not null. + // If widget is null, assume the widget is GFX-rendered and return a member variable instead. + + if (nsHTMLAtoms::value == aName) { + GetTextControlFrameState(aValue); + } + else { + return Inherited::GetProperty(aName, aValue); + } + + return NS_OK; +} + +void nsGfxTextControlFrame::SetFocus(PRBool aOn, PRBool aRepaint) +{ + // !! IF REMOVING THIS ANY CODE HERE + // !! READ HIDE THIS AND BELOW + // + // There are 3 cases where focus can get set: + // 1) from script + // 2) from tabbing into it + // 3) from clicking on it + // + // If removing any of this code PLEASE read comment below + + nsresult rv = EnsureEditor(); + if (NS_FAILED(rv)) return; + + if (aOn) + { + nsCOMPtr<nsIContentViewer> viewer; + mDocShell->GetContentViewer(getter_AddRefs(viewer)); + if (viewer) { + nsCOMPtr<nsIDocumentViewer> docv(do_QueryInterface(viewer)); + if (docv) { + nsCOMPtr<nsIPresContext> cx; + docv->GetPresContext(*getter_AddRefs(cx)); + if (cx) { + nsCOMPtr<nsIPresShell> shell; + cx->GetShell(getter_AddRefs(shell)); + if (shell) { + nsIFrame * rootFrame; + shell->GetRootFrame(&rootFrame); + + nsCOMPtr<nsIViewManager> vm; + shell->GetViewManager(getter_AddRefs(vm)); + if (nsnull != vm) { + nsIView *rootview = nsnull; + vm->GetRootView(rootview); + if (rootview) { + // instead of using the rootview's widget we must find the deepest + // the deepest view and use its widget + nsCOMPtr<nsIWidget> + widget(getter_AddRefs(GetDeepestWidget(rootview))); + if (widget) { + // XXX Here we need to remember whether we set focus on the widget + // Later this is used to decided to continue to dispatch a Focus + // notification into the DOM. So if we reach here, it means + // a Focus message will be dispatched to the nsEnderEventListner + // and setting this to true won't propigate into the DOM, because we + // got here via the DOM + // See: nsEnderEventListener::Focus + rv = widget->SetFocus(); + mDidSetFocus = PR_TRUE; + } + } + } + } + } + } + } + } + else + { + /* experimental code, since mDocshell->removeFocus is a noop */ + /* this code doesn't seem to have any effect either. bug 19392 + nsIView* view; + GetView(mFramePresContext, &view); + if (view) + { + nsCOMPtr<nsIWidget> widget; + view->GetWidget(*(getter_AddRefs(widget))); + if (widget) { + widget->SetFocus(); + } + } + */ + // since the embedded docshell is not in the docshell hierarchy, RemoveFocus has no effect + // that's why we find the widget attached to this and set focus on it explicitly + //mDocShell->RemoveFocus(); + } +} +/* --------------------- Ender methods ---------------------- */ + + +nsresult +nsGfxTextControlFrame::CreateDocShell(nsIPresContext* aPresContext, + const nsSize& aSize) +{ + nsresult rv; + + mDocShell = do_CreateInstance(kWebShellCID); + NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); + + // pass along marginwidth and marginheight so sub document can use it + mDocShell->SetMarginWidth(0); + mDocShell->SetMarginHeight(0); + + /* our parent must be a docshell. we need to get our prefs from our parent */ + nsCOMPtr<nsISupports> container; + aPresContext->GetContainer(getter_AddRefs(container)); + NS_ENSURE_TRUE(container, NS_ERROR_UNEXPECTED); + + nsCOMPtr<nsIDocShell> outerShell = do_QueryInterface(container); + NS_ENSURE_TRUE(outerShell, NS_ERROR_UNEXPECTED); + + float t2p; + aPresContext->GetTwipsToPixels(&t2p); + nsCOMPtr<nsIPresShell> presShell; + rv = aPresContext->GetShell(getter_AddRefs(presShell)); + if (NS_FAILED(rv)) { return rv; } + + // create, init, set the parent of the view + nsIView* view; + rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, NS_GET_IID(nsIView), + (void **)&view); + if (NS_FAILED(rv)) { return rv; } + + nsIView* parView; + nsPoint origin; + GetOffsetFromView(aPresContext, origin, &parView); + + nsRect viewBounds(origin.x, origin.y, aSize.width, aSize.height); +#ifdef NOISY + printf("%p view bounds: x=%d, y=%d, w=%d, h=%d\n", view, origin.x, origin.y, aSize.width, aSize.height); +#endif + + nsCOMPtr<nsIViewManager> viewMan; + presShell->GetViewManager(getter_AddRefs(viewMan)); + rv = view->Init(viewMan, viewBounds, parView); + if (NS_FAILED(rv)) { return rv; } + viewMan->InsertChild(parView, view, 0); + rv = view->CreateWidget(kCChildCID); + if (NS_FAILED(rv)) { return rv; } + SetView(aPresContext, view); + + // if the visibility is hidden, reflect that in the view + const nsStyleDisplay* display; + GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display)); + if (!display->IsVisible()) { + view->SetVisibility(nsViewVisibility_kHide); + } + + const nsStyleBorder* borderStyle; + GetStyleData(eStyleStruct_Border, (const nsStyleStruct *&)borderStyle); + nsMargin border; + borderStyle->CalcBorderFor(this, border); + + nsCOMPtr<nsIWidget> widget; + view->GetWidget(*getter_AddRefs(widget)); + + mDocShell->SetAllowPlugins(PR_FALSE); + nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell)); + + PRInt32 x = NSToCoordRound(border.left * t2p); + PRInt32 y = NSToCoordRound(border.top * t2p); + PRInt32 cx = NSToCoordRound((aSize.width - border.right) * t2p); + PRInt32 cy = NSToCoordRound((aSize.height - border.bottom) * t2p); + NS_ENSURE_SUCCESS(docShellAsWin->InitWindow(nsnull, widget, (x >= 0) ? x : 0, + (y >= 0) ? y : 0, cx, cy), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(docShellAsWin->Create(), NS_ERROR_FAILURE); + + // move the view to the proper location + viewMan->MoveViewTo(view, origin.x, origin.y); + + mDocShell->SetDocLoaderObserver(mTempObserver); + + PRInt32 type; + GetType(&type); + if ((PR_FALSE==IsSingleLineTextControl()) || (NS_FORM_INPUT_PASSWORD == type)) { + docShellAsWin->SetVisibility(PR_TRUE); + } + return NS_OK; +} + + +PRInt32 +nsGfxTextControlFrame::CalculateSizeNavQuirks (nsIPresContext* aPresContext, + nsIRenderingContext* aRendContext, + nsIFormControlFrame* aFrame, + const nsSize& aCSSSize, + nsInputDimensionSpec& aSpec, + nsSize& aDesiredSize, + nsSize& aMinSize, + PRBool& aWidthExplicit, + PRBool& aHeightExplicit, + nscoord& aRowHeight, + nsMargin& aBorder, + nsMargin& aPadding) +{ + nscoord charWidth = 0; + aWidthExplicit = PR_FALSE; + aHeightExplicit = PR_FALSE; + + aDesiredSize.width = CSS_NOTSET; + aDesiredSize.height = CSS_NOTSET; + + // Quirks does not use rowAttr + nsHTMLValue colAttr; + nsresult colStatus; + nsHTMLValue rowAttr; + nsresult rowStatus; + if (NS_ERROR_FAILURE == GetColRowSizeAttr(aFrame, + aSpec.mColSizeAttr, colAttr, colStatus, + aSpec.mRowSizeAttr, rowAttr, rowStatus)) { + return 0; + } + + // Get the Font Metrics for the Control + // without it we can't calculate the size + nsCOMPtr<nsIFontMetrics> fontMet; + nsresult res = nsFormControlHelper::GetFrameFontFM(aPresContext, aFrame, getter_AddRefs(fontMet)); + if (NS_SUCCEEDED(res) && fontMet) { + aRendContext->SetFont(fontMet); + + // Figure out the number of columns + // and set that as the default col size + if (NS_CONTENT_ATTR_HAS_VALUE == colStatus) { // col attr will provide width + PRInt32 col = ((colAttr.GetUnit() == eHTMLUnit_Pixel) ? colAttr.GetPixelValue() : colAttr.GetIntValue()); + col = (col <= 0) ? 1 : col; // XXX why a default of 1 char, why hide it + aSpec.mColDefaultSize = col; + } + charWidth = nsFormControlHelper::CalcNavQuirkSizing(aPresContext, + aRendContext, fontMet, + aFrame, aSpec, aDesiredSize); + aMinSize.width = aDesiredSize.width; + + // XXX I am commenting this out below to let CSS + // override the column setting - rods + + // If COLS was not set then check to see if CSS has the width set + //if (NS_CONTENT_ATTR_HAS_VALUE != colStatus) { // col attr will provide width + if (CSS_NOTSET != aCSSSize.width) { // css provides width + //NS_ASSERTION(aCSSSize.width >= 0, "form control's computed width is < 0"); + if (NS_INTRINSICSIZE != aCSSSize.width) { + aDesiredSize.width = aCSSSize.width; + aWidthExplicit = PR_TRUE; + } + } + //} + + aDesiredSize.height = aDesiredSize.height * aSpec.mRowDefaultSize; + if (CSS_NOTSET != aCSSSize.height) { // css provides height + NS_ASSERTION(aCSSSize.height > 0, "form control's computed height is <= 0"); + if (NS_INTRINSICSIZE != aCSSSize.height) { + aDesiredSize.height = aCSSSize.height; + aHeightExplicit = PR_TRUE; + } + } + + } else { + NS_ASSERTION(fontMet, "Couldn't get Font Metrics"); + aDesiredSize.width = 300; // arbitrary values + aDesiredSize.width = 1500; + } + + aRowHeight = aDesiredSize.height; + aMinSize.height = aDesiredSize.height; + + PRInt32 numRows = (aRowHeight > 0) ? (aDesiredSize.height / aRowHeight) : 0; + + return numRows; +} + +//------------------------------------------------------------------ +NS_IMETHODIMP +nsGfxTextControlFrame::ReflowNavQuirks(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus, + nsMargin& aBorder, + nsMargin& aPadding) +{ + // This calculates the reflow size + // get the css size and let the frame use or override it + nsSize styleSize; + GetStyleSize(aPresContext, aReflowState, styleSize); + + nsSize desiredSize; + nsSize minSize; + + PRBool widthExplicit, heightExplicit; + PRInt32 ignore; + PRInt32 type; + GetType(&type); + if ((NS_FORM_INPUT_TEXT == type) || (NS_FORM_INPUT_PASSWORD == type)) { + PRInt32 width = 0; + if (NS_CONTENT_ATTR_HAS_VALUE != GetSizeFromContent(&width)) { + width = GetDefaultColumnWidth(); + } + nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull, + nsnull, width, + PR_FALSE, nsnull, 1); + CalculateSizeNavQuirks(aPresContext, aReflowState.rendContext, this, styleSize, + textSpec, desiredSize, minSize, widthExplicit, + heightExplicit, ignore, aBorder, aPadding); + } else { + nsInputDimensionSpec areaSpec(nsHTMLAtoms::cols, PR_FALSE, nsnull, + nsnull, GetDefaultColumnWidth(), + PR_FALSE, nsHTMLAtoms::rows, 1); + CalculateSizeNavQuirks(aPresContext, aReflowState.rendContext, this, styleSize, + areaSpec, desiredSize, minSize, widthExplicit, + heightExplicit, ignore, aBorder, aPadding); + } + if (widthExplicit) { + desiredSize.width += aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right; + } + if (heightExplicit) { + desiredSize.height += aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom; + } + + aDesiredSize.width = desiredSize.width; + aDesiredSize.height = desiredSize.height; + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; + + if (aDesiredSize.maxElementSize) { + aDesiredSize.maxElementSize->width = widthExplicit?desiredSize.width:minSize.width; + aDesiredSize.maxElementSize->height = heightExplicit?desiredSize.height:minSize.height; + } + + // In Nav Quirks mode we only add in extra size for padding + nsMargin padding(0, 0, 0, 0); + const nsStylePadding* paddingStyle; + GetStyleData(nsStylePadding, (const nsStyleStruct *&)paddingStyle); + paddingStyle->CalcPaddingFor(this, padding); + + // Check to see if style was responsible + // for setting the height or the width + PRBool addBorder = PR_FALSE; + PRInt32 width; + if (NS_CONTENT_ATTR_HAS_VALUE == GetSizeFromContent(&width)) { + // if a size attr gets incorrectly + // put on a textarea it comes back as -1 + if (width > -1) { + addBorder = (width < GetDefaultColumnWidth()) && !widthExplicit; + } + } + + if (addBorder) { + if (CSS_NOTSET != styleSize.width || + CSS_NOTSET != styleSize.height) { // css provides width + nsMargin border(0, 0, 0, 0); + GetStyleData(nsStyleBorder, (const nsStyleStruct *&)borderStyle); + borderStyle->CalcBorderFor(this, border); + if (CSS_NOTSET != styleSize.width) { // css provides width + aDesiredSize.width += border.left + border.right; + } + if (CSS_NOTSET != styleSize.height) { // css provides heigth + aDesiredSize.height += border.top + border.bottom; + } + } + } + return NS_OK; +} + +nsresult +nsGfxTextControlFrame::GetColRowSizeAttr(nsIFormControlFrame* aFrame, + nsIAtom * aColSizeAttr, + nsHTMLValue & aColSize, + nsresult & aColStatus, + nsIAtom * aRowSizeAttr, + nsHTMLValue & aRowSize, + nsresult & aRowStatus) +{ + nsIContent* iContent = nsnull; + aFrame->GetFormContent((nsIContent*&) iContent); + if (!iContent) { + return NS_ERROR_FAILURE; + } + nsIHTMLContent* hContent = nsnull; + nsresult result = iContent->QueryInterface(kIHTMLContentIID, (void**)&hContent); + if ((NS_OK != result) || !hContent) { + NS_RELEASE(iContent); + return NS_ERROR_FAILURE; + } + + aColStatus = NS_CONTENT_ATTR_NOT_THERE; + if (nsnull != aColSizeAttr) { + aColStatus = hContent->GetHTMLAttribute(aColSizeAttr, aColSize); + } + + aRowStatus= NS_CONTENT_ATTR_NOT_THERE; + if (nsnull != aRowSizeAttr) { + aRowStatus = hContent->GetHTMLAttribute(aRowSizeAttr, aRowSize); + } + + NS_RELEASE(hContent); + NS_RELEASE(iContent); + + return NS_OK; +} + +PRInt32 +nsGfxTextControlFrame::CalculateSizeStandard (nsIPresContext* aPresContext, + nsIRenderingContext* aRendContext, + nsIFormControlFrame* aFrame, + const nsSize& aCSSSize, + nsInputDimensionSpec& aSpec, + nsSize& aDesiredSize, + nsSize& aMinSize, + PRBool& aWidthExplicit, + PRBool& aHeightExplicit, + nscoord& aRowHeight, + nsMargin& aBorder, + nsMargin& aPadding) +{ + nscoord charWidth = 0; + aWidthExplicit = PR_FALSE; + aHeightExplicit = PR_FALSE; + + aDesiredSize.width = CSS_NOTSET; + aDesiredSize.height = CSS_NOTSET; + + nsHTMLValue colAttr; + nsresult colStatus; + nsHTMLValue rowAttr; + nsresult rowStatus; + if (NS_ERROR_FAILURE == GetColRowSizeAttr(aFrame, + aSpec.mColSizeAttr, colAttr, colStatus, + aSpec.mRowSizeAttr, rowAttr, rowStatus)) { + return 0; + } + + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); + + // determine the width, char height, row height + if (NS_CONTENT_ATTR_HAS_VALUE == colStatus) { // col attr will provide width + PRInt32 col = ((colAttr.GetUnit() == eHTMLUnit_Pixel) ? colAttr.GetPixelValue() : colAttr.GetIntValue()); + col = (col <= 0) ? 1 : col; // XXX why a default of 1 char, why hide it + charWidth = nsFormControlHelper::GetTextSize(aPresContext, aFrame, col, aDesiredSize, aRendContext); + aMinSize.width = aDesiredSize.width; + } else { + charWidth = nsFormControlHelper::GetTextSize(aPresContext, aFrame, aSpec.mColDefaultSize, aDesiredSize, aRendContext); + aMinSize.width = aDesiredSize.width; + if (CSS_NOTSET != aCSSSize.width) { // css provides width + //NS_ASSERTION(aCSSSize.width >= 0, "form control's computed width is < 0"); + if (NS_INTRINSICSIZE != aCSSSize.width) { + aDesiredSize.width = aCSSSize.width; + aWidthExplicit = PR_TRUE; + } + } + } + + nscoord fontHeight = 0; + //nscoord fontLeading = 0; + // get leading + nsCOMPtr<nsIFontMetrics> fontMet; + nsresult res = nsFormControlHelper::GetFrameFontFM(aPresContext, aFrame, getter_AddRefs(fontMet)); + if (NS_SUCCEEDED(res) && fontMet) { + aRendContext->SetFont(fontMet); + fontMet->GetHeight(fontHeight); + // leading is NOT suppose to be added in + //fontMet->GetLeading(fontLeading); + //aDesiredSize.height += fontLeading; + } + aRowHeight = aDesiredSize.height; + aMinSize.height = aDesiredSize.height; + PRInt32 numRows = 0; + + if (NS_CONTENT_ATTR_HAS_VALUE == rowStatus) { // row attr will provide height + PRInt32 rowAttrInt = ((rowAttr.GetUnit() == eHTMLUnit_Pixel) + ? rowAttr.GetPixelValue() : rowAttr.GetIntValue()); + numRows = (rowAttrInt > 0) ? rowAttrInt : 1; + aDesiredSize.height = aDesiredSize.height * numRows; + } else { + aDesiredSize.height = aDesiredSize.height * aSpec.mRowDefaultSize; + if (CSS_NOTSET != aCSSSize.height) { // css provides height + NS_ASSERTION(aCSSSize.height > 0, "form control's computed height is <= 0"); + if (NS_INTRINSICSIZE != aCSSSize.height) { + aDesiredSize.height = aCSSSize.height; + aHeightExplicit = PR_TRUE; + } + } + } + + numRows = (aRowHeight > 0) ? (aDesiredSize.height / aRowHeight) : 0; + if (numRows == 1) { + PRInt32 type; + GetType(&type); + if (NS_FORM_TEXTAREA == type) { + aDesiredSize.height += fontHeight; + } + } + + return numRows; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::ReflowStandard(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus, + nsMargin& aBorder, + nsMargin& aPadding) +{ + // get the css size and let the frame use or override it + nsSize styleSize; + GetStyleSize(aPresContext, aReflowState, styleSize); + + nsSize desiredSize; + nsSize minSize; + + PRBool widthExplicit, heightExplicit; + PRInt32 ignore; + PRInt32 type; + GetType(&type); + if ((NS_FORM_INPUT_TEXT == type) || (NS_FORM_INPUT_PASSWORD == type)) { + PRInt32 width = 0; + if (NS_CONTENT_ATTR_HAS_VALUE != GetSizeFromContent(&width)) { + width = GetDefaultColumnWidth(); + } + nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull, + nsnull, width, + PR_FALSE, nsnull, 1); + CalculateSizeStandard(aPresContext, aReflowState.rendContext, this, styleSize, + textSpec, desiredSize, minSize, widthExplicit, + heightExplicit, ignore, aBorder, aPadding); + } else { + nsInputDimensionSpec areaSpec(nsHTMLAtoms::cols, PR_FALSE, nsnull, + nsnull, GetDefaultColumnWidth(), + PR_FALSE, nsHTMLAtoms::rows, 1); + CalculateSizeStandard(aPresContext, aReflowState.rendContext, this, styleSize, + areaSpec, desiredSize, minSize, widthExplicit, + heightExplicit, ignore, aBorder, aPadding); + } + + // CalculateSize makes calls in the nsFormControlHelper that figures + // out the entire size of the control when in NavQuirks mode. For the + // textarea, this means the scrollbar sizes hav already been added to + // its overall size and do not need to be added here. + if (NS_FORM_TEXTAREA == type) { + float p2t; + aPresContext->GetPixelsToTwips(&p2t); + + nscoord scrollbarWidth = 0; + nscoord scrollbarHeight = 0; + float scale; + nsCOMPtr<nsIDeviceContext> dx; + aPresContext->GetDeviceContext(getter_AddRefs(dx)); + if (dx) { + float sbWidth; + float sbHeight; + dx->GetCanonicalPixelScale(scale); + dx->GetScrollBarDimensions(sbWidth, sbHeight); + scrollbarWidth = PRInt32(sbWidth * scale); + scrollbarHeight = PRInt32(sbHeight * scale); + } else { + scrollbarWidth = GetScrollbarWidth(p2t); + scrollbarHeight = scrollbarWidth; + } + + if (!heightExplicit) { + desiredSize.height += scrollbarHeight; + minSize.height += scrollbarHeight; + } + if (!widthExplicit) { + desiredSize.width += scrollbarWidth; + minSize.width += scrollbarWidth; + } + } + desiredSize.width += aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom; + desiredSize.height += aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right; + + aDesiredSize.width = desiredSize.width; + aDesiredSize.height = desiredSize.height; + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; + + if (aDesiredSize.maxElementSize) { + aDesiredSize.maxElementSize->width = widthExplicit?desiredSize.width:minSize.width; + aDesiredSize.maxElementSize->height = heightExplicit?desiredSize.height:minSize.height; + } + + return NS_OK; + +} + +NS_IMETHODIMP +nsGfxTextControlFrame::Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + DO_GLOBAL_REFLOW_COUNT("nsGfxTextControlFrame", aReflowState.reason); +#ifdef DEBUG + mDebugTotalReflows++; + if (1==mDebugTotalReflows) { // first reflow, better be initial reflow! + NS_ASSERTION((eReflowReason_Initial == aReflowState.reason), "Frame got first reflow, but reason is not 'initial'"); + } + if (eReflowReason_Resize == aReflowState.reason) { + mDebugResizeReflows++; + } + if (aReflowState.availableWidth == NS_UNCONSTRAINEDSIZE) { + mDebugResizeUnconstrained++; + } + mDebugPaintsSinceLastReflow=0; +#endif + + NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, + ("enter nsGfxTextControlFrame::Reflow: aMaxSize=%d,%d", + aReflowState.availableWidth, aReflowState.availableHeight)); + + NS_PRECONDITION(mState & NS_FRAME_IN_REFLOW, "frame is not in reflow"); + // add ourself as an nsIFormControlFrame + if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + mPresContext = aPresContext; + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); + nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); + } +#ifdef NOISY + printf("gfxTCF: reflow reason=%d\n", aReflowState.reason); +#endif + + // Turning off optimization for now +#if 0 + nsresult skiprv = SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext, + aDesiredSize, aReflowState, aStatus); + if (NS_SUCCEEDED(skiprv)) { + return skiprv; + } +#endif + + // Figure out if we are doing Quirks or Standard + nsCompatibility mode; + aPresContext->GetCompatibilityMode(&mode); + + nsMargin border; + border.SizeTo(0, 0, 0, 0); + nsMargin padding; + padding.SizeTo(0, 0, 0, 0); + // Get the CSS border + const nsStyleBorder* borderStyle; + const nsStylePadding* paddingStyle; + GetStyleData(eStyleStruct_Border, (const nsStyleStruct *&)borderStyle); + GetStyleData(eStyleStruct_Padding, (const nsStyleStruct *&)paddingStyle); + borderStyle->CalcBorderFor(this, border); + paddingStyle->CalcPaddingFor(this, padding); + + // calculate the the desired size for the text control + // use the suggested size if it has been set + nsresult rv = NS_OK; + nsHTMLReflowState suggestedReflowState(aReflowState); + if ((kSuggestedNotSet != mSuggestedWidth) || + (kSuggestedNotSet != mSuggestedHeight)) { + // Honor the suggested width and/or height. + if (kSuggestedNotSet != mSuggestedWidth) { + suggestedReflowState.mComputedWidth = mSuggestedWidth; + aDesiredSize.width = mSuggestedWidth; + } + + if (kSuggestedNotSet != mSuggestedHeight) { + suggestedReflowState.mComputedHeight = mSuggestedHeight; + aDesiredSize.height = mSuggestedHeight; + } + rv = NS_OK; + + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; + + aStatus = NS_FRAME_COMPLETE; + } else { + + // this is the right way + // Quirks mode will NOT obey CSS border and padding + // GetDesiredSize calculates the size without CSS borders + // the nsLeafFrame::Reflow will add in the borders + if (eCompatibility_NavQuirks == mode) { + rv = ReflowNavQuirks(aPresContext, aDesiredSize, aReflowState, aStatus, border, padding); + } else { + rv = ReflowStandard(aPresContext, aDesiredSize, aReflowState, aStatus, border, padding); + } + + if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedWidth) { + if (aReflowState.mComputedWidth > aDesiredSize.width) { + aDesiredSize.width = aReflowState.mComputedWidth; + } + } + if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedHeight) { + if (aReflowState.mComputedHeight > aDesiredSize.height) { + aDesiredSize.height = aReflowState.mComputedHeight; + } + } + aStatus = NS_FRAME_COMPLETE; + } +#if DEBUG + nsRect myRect; + GetRect(myRect); + if ((aDesiredSize.width != myRect.width) || + (aDesiredSize.height != myRect.height)) { + mDebugResizeReflowsThatChangedMySize++; + } +#endif + + // Turning off optimization for now +#if 0 + SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize); +#endif + +#ifdef NOISY + printf ("exit nsGfxTextControlFrame::Reflow: size=%d,%d\n", + aDesiredSize.width, aDesiredSize.height); +#endif + + float t2p, p2t; + mFramePresContext->GetTwipsToPixels(&t2p); + mFramePresContext->GetPixelsToTwips(&p2t); + // resize the sub document within the defined rect + // the sub-document will fit inside the border + if (NS_SUCCEEDED(rv)) + { + nsRect subBounds; + nsRect subBoundsInPixels; + nsSize desiredSize(aDesiredSize.width, aDesiredSize.height); + CalcSizeOfSubDocInTwips(border, padding, desiredSize, subBounds); + subBoundsInPixels.x = NSToCoordRound(subBounds.x * t2p); + subBoundsInPixels.y = NSToCoordRound(subBounds.y * t2p); + subBoundsInPixels.width = NSToCoordRound(subBounds.width * t2p); + subBoundsInPixels.height = NSToCoordRound(subBounds.height * t2p); + if (eReflowReason_Initial == aReflowState.reason) + { + if (!mDocShell) + { // if we haven't already created a docshell, then create something to hold the initial text + PRInt32 type; + GetType(&type); + if ((PR_FALSE==IsSingleLineTextControl()) || (NS_FORM_INPUT_PASSWORD == type)) + { // password controls and multi-line text areas get their subdoc right away + rv = CreateSubDoc(&subBoundsInPixels); + } + else if (mDisplayFrame) + { +#ifdef NOISY + printf("Error in nsGfxTextControlFrame: already created display content on intial reflow!\n"); +#endif + } + else + { // single line text controls get a display frame rather than a subdoc. + // the subdoc will be created when the frame first gets focus + // create anonymous text content + nsCOMPtr<nsIContent> content(do_CreateInstance(kTextNodeCID,&result)); + if (NS_FAILED(rv)) { return rv; } + if (!content) { return NS_ERROR_NULL_POINTER; } + nsIDocument* doc; + mContent->GetDocument(doc); + content->SetDocument(doc, PR_FALSE, PR_TRUE); + NS_RELEASE(doc); + mContent->AppendChildTo(content, PR_FALSE); + + // set the value of the text node + content->QueryInterface(NS_GET_IID(nsITextContent), getter_AddRefs(mDisplayContent)); + if (!mDisplayContent) {return NS_ERROR_NO_INTERFACE; } + + // get the text value, either from input element attribute or cached state + nsAutoString value; + if (mCachedState) { + value.Assign(*mCachedState); + } + else + { + nsIHTMLContent *htmlContent = nsnull; + if (mContent) + { + mContent->QueryInterface(kIHTMLContentIID, (void**) &htmlContent); + if (htmlContent) + { + nsHTMLValue htmlValue; + if (NS_CONTENT_ATTR_HAS_VALUE == + htmlContent->GetHTMLAttribute(nsHTMLAtoms::value, htmlValue)) + { + if (eHTMLUnit_String == htmlValue.GetUnit()) + { + htmlValue.GetStringValue(value); + } + } + } + NS_RELEASE(htmlContent); + } + } + + PRInt32 len = value.Length(); + if (0<len) + { + // for password fields, set the display text to '*', one per character + // XXX: the replacement character should be controllable via CSS + // for normal text fields, set the display text normally + if (NS_FORM_INPUT_PASSWORD == type) + { + PRUnichar *initialPasswordText; + initialPasswordText = new PRUnichar[len+1]; + if (!initialPasswordText) { return NS_ERROR_NULL_POINTER; } + PRInt32 i=0; + for (; i<len; i++) { + initialPasswordText[i] = PASSWORD_REPLACEMENT_CHAR; + } + mDisplayContent->SetText(initialPasswordText, len, PR_TRUE); + delete [] initialPasswordText; + } + else + { + const PRUnichar *initialText; + initialText = value.GetUnicode(); + mDisplayContent->SetText(initialText, len, PR_TRUE); + } + } + + // create the pseudo frame for the anonymous content + if (mDisplayFrame) { + mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, mDisplayFrame, nsnull); + rv = mDisplayFrame->Destroy(aPresContext); + if (NS_FAILED(rv)) return rv; + } + + nsCOMPtr<nsIPresShell> shell; + aPresContext->GetShell(getter_AddRefs(shell)); + rv = NS_NewBlockFrame(shell, (nsIFrame**)&mDisplayFrame, NS_BLOCK_SPACE_MGR); + if (NS_FAILED(rv)) { return rv; } + if (!mDisplayFrame) { return NS_ERROR_NULL_POINTER; } + + // create the style context for the anonymous frame + nsCOMPtr<nsIStyleContext> styleContext; + rv = aPresContext->ResolvePseudoStyleContextFor(mContent, + nsHTMLAtoms::mozSingleLineTextControlFrame, + mStyleContext, + PR_FALSE, + getter_AddRefs(styleContext)); + if (NS_FAILED(rv)) { return rv; } + if (!styleContext) { return NS_ERROR_NULL_POINTER; } + + // create a text frame and put it inside the block frame + nsIFrame *textFrame; + rv = NS_NewTextFrame(shell, &textFrame); + if (NS_FAILED(rv)) { return rv; } + if (!textFrame) { return NS_ERROR_NULL_POINTER; } + nsCOMPtr<nsIStyleContext> textStyleContext; + rv = aPresContext->ResolvePseudoStyleContextFor(mContent, + nsHTMLAtoms::mozSingleLineTextControlFrame, + styleContext, + PR_FALSE, + getter_AddRefs(textStyleContext)); + if (NS_FAILED(rv)) { return rv; } + if (!textStyleContext) { return NS_ERROR_NULL_POINTER; } + textFrame->Init(aPresContext, content, mDisplayFrame, textStyleContext, nsnull); + textFrame->SetInitialChildList(aPresContext, nsnull, nsnull); + nsCOMPtr<nsIPresShell> presShell; + rv = aPresContext->GetShell(getter_AddRefs(presShell)); + if (NS_FAILED(rv)) { return rv; } + if (!presShell) { return NS_ERROR_NULL_POINTER; } + nsCOMPtr<nsIFrameManager> frameManager; + rv = presShell->GetFrameManager(getter_AddRefs(frameManager)); + if (NS_FAILED(rv)) { return rv; } + if (!frameManager) { return NS_ERROR_NULL_POINTER; } + frameManager->SetPrimaryFrameFor(content, textFrame); + + rv = mDisplayFrame->Init(aPresContext, content, this, styleContext, nsnull); + if (NS_FAILED(rv)) { return rv; } + + mDisplayFrame->SetInitialChildList(aPresContext, nsnull, textFrame); + } + } + } + nsCOMPtr<nsIBaseWindow> docShellWin(do_QueryInterface(mDocShell)); + if (docShellWin) + { + if (mDisplayFrame) + { + docShellWin->SetVisibility(PR_TRUE); + mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, mDisplayFrame, nsnull); + mDisplayFrame->Destroy(mFramePresContext); + mDisplayFrame = nsnull; + } +#ifdef NOISY + printf("%p docshell in reflow set to bounds: x=%d, y=%d, w=%d, h=%d\n", mDocShell.get(), subBoundsInPixels.x, subBoundsInPixels.y, subBoundsInPixels.width, subBoundsInPixels.height); +#endif +#ifdef DEBUG + mDebugReflowsThatMovedSubdoc++; +#endif + docShellWin->SetPositionAndSize(subBoundsInPixels.x, subBoundsInPixels.y, + subBoundsInPixels.width, subBoundsInPixels.height, PR_FALSE); + nsCOMPtr<nsIPresShell> presShell; + rv = aPresContext->GetShell(getter_AddRefs(presShell)); + if (NS_FAILED(rv)) { return rv; } + nsIView *view; + GetView(aPresContext, &view); + if (view) + { + nsCOMPtr<nsIViewManager> viewMan; + presShell->GetViewManager(getter_AddRefs(viewMan)); + nsIView* parView; + nsPoint origin; + GetOffsetFromView(aPresContext, origin, &parView); + viewMan->MoveViewTo(view, origin.x, origin.y); + } + } + else + { + // pass the reflow to mDisplayFrame, forcing him to fit +// mDisplayFrame->SetSuggestedSize(subBounds.width, subBounds.height); + if (mDisplayFrame) + { + // fix any possible pixel roundoff error (the docshell is sized in whole pixel units, + // and we need to make sure the text is painted in exactly the same place using either frame or shell.) + subBounds.x = NSToCoordRound(subBoundsInPixels.x * p2t); + subBounds.y = NSToCoordRound(subBoundsInPixels.y * p2t); + subBounds.width = NSToCoordRound(subBoundsInPixels.width * p2t); + subBounds.height = NSToCoordRound(subBoundsInPixels.height * p2t); + + // build the data structures for reflowing mDisplayFrame + nsSize availSize(subBounds.width, subBounds.height); + nsHTMLReflowMetrics kidSize(&availSize); + nsHTMLReflowState kidReflowState(aPresContext, aReflowState, mDisplayFrame, + availSize); + + // Send the WillReflow notification, and reflow the child frame + mDisplayFrame->WillReflow(aPresContext); + mDisplayFrame->MoveTo(aPresContext, subBounds.x, subBounds.y); + nsIView* view; + mDisplayFrame->GetView(aPresContext, &view); + if (view) { + nsContainerFrame::PositionFrameView(aPresContext, mDisplayFrame, view); + } + nsReflowStatus status; + rv = mDisplayFrame->Reflow(aPresContext, kidSize, kidReflowState, status); + // notice how status is ignored here +#ifdef NOISY + printf("%p mDisplayFrame resized to: x=%d, y=%d, w=%d, h=%d\n", mDisplayFrame, subBounds.x, subBounds.y, subBounds.width, subBounds.height); +#endif + mDisplayFrame->SetRect(aPresContext, subBounds); + // finish the reflow + mDisplayFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED); + } + } + } + +#ifdef NOISY + printf("at the time of the reflow, the frame looks like...\n"); + List(aPresContext, stdout, 0); +#endif + + NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, + ("exit nsGfxTextControlFrame::Reflow: size=%d,%d", + aDesiredSize.width, aDesiredSize.height)); + +// This code below will soon be changed over for NSPR logging +// It is used to figure out what font and font size the textarea or text field +// are and compares it to the know NavQuirks size +#ifdef DEBUG_rodsXXX +//#ifdef NS_DEBUG + { + const nsFont * font = nsnull; + nsresult res = GetFont(aPresContext, font); + if (NS_SUCCEEDED(res) & font != nsnull) { + nsCOMPtr<nsIDeviceContext> deviceContext; + aPresContext->GetDeviceContext(getter_AddRefs(deviceContext)); + + nsIFontMetrics* fontMet; + deviceContext->GetMetricsFor(font, fontMet); + } + + const nsFont& normal = aPresContext->GetDefaultFixedFontDeprecated(); + PRInt32 scaler; + aPresContext->GetFontScaler(&scaler); + float scaleFactor = nsStyleUtil::GetScalingFactor(scaler); + PRInt32 fontSize = nsStyleUtil::FindNextSmallerFontSize(font.size, (PRInt32)normal.size, + scaleFactor, aPresContext)+1; + PRBool doMeasure = PR_FALSE; + nsILookAndFeel::nsMetricNavFontID fontId; + + nsFont defFont(aPresContext->GetDefaultFixedFontDeprecated()); + if (font.name == defFont.name) { + fontId = nsILookAndFeel::eMetricSize_Courier; + doMeasure = PR_TRUE; + } else { + nsAutoString sansSerif("sans-serif"); + if (font.name == sansSerif) { + fontId = nsILookAndFeel::eMetricSize_SansSerif; + doMeasure = PR_TRUE; + } + } + NS_RELEASE(fontMet); + + if (doMeasure) { + nsCOMPtr<nsILookAndFeel> lf; + aPresContext->GetLookAndFeel(getter_AddRefs(lf)); + + PRInt32 type; + GetType(&type); + if (NS_FORM_TEXTAREA == type) { + if (fontSize > -1) { + nsSize size; + lf->GetNavSize(nsILookAndFeel::eMetricSize_TextArea, fontId, fontSize, size); + COMPARE_QUIRK_SIZE("nsGfxText(textarea)", size.width, size.height) // text area + } + } else { + if (fontSize > -1) { + nsSize size; + lf->GetNavSize(nsILookAndFeel::eMetricSize_TextField, fontId, fontSize, size); + COMPARE_QUIRK_SIZE("nsGfxText(field)", size.width, size.height) // text field + } + } + } + } +#endif +#ifdef DEBUG +#if NOISY + printf("gfxTC: %p reflow stats at end of reflow:\n\ttotal\tresize\tunconst\tchanged\tmoved\n", this); + printf("\t%d\t%d\t%d\t%d\t%d\n", + mDebugTotalReflows, mDebugResizeReflows, + mDebugResizeUnconstrained, + mDebugResizeReflowsThatChangedMySize, mDebugReflowsThatMovedSubdoc); +#endif +#endif + return NS_OK; +} + +nsresult +nsGfxTextControlFrame::RequiresWidget(PRBool &aRequiresWidget) +{ + aRequiresWidget = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::GetPresShellFor(nsIDocShell* aDocShell, nsIPresShell** aPresShell) +{ + NS_ENSURE_ARG(aDocShell); + NS_ENSURE_ARG_POINTER(aPresShell); + *aPresShell = nsnull; + + nsCOMPtr<nsIContentViewer> cv; + aDocShell->GetContentViewer(getter_AddRefs(cv)); + if (cv) + { + nsCOMPtr<nsIDocumentViewer> docv(do_QueryInterface(cv)); + if (docv) + { + nsCOMPtr<nsIPresContext> cx; + docv->GetPresContext(*getter_AddRefs(cx)); + if (cx) + { + NS_ENSURE_SUCCESS(cx->GetShell(aPresShell), NS_ERROR_FAILURE); + } + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::GetFirstNodeOfType(const nsString& aTag, nsIDOMDocument *aDOMDoc, nsIDOMNode **aNode) +{ + if (!aDOMDoc || !aNode) { return NS_ERROR_NULL_POINTER; } + *aNode=nsnull; + nsCOMPtr<nsIDOMNodeList>nodeList; + nsresult result = aDOMDoc->GetElementsByTagName(aTag, getter_AddRefs(nodeList)); + if ((NS_SUCCEEDED(result)) && nodeList) + { + PRUint32 count; + nodeList->GetLength(&count); + result = nodeList->Item(0, aNode); + if (!aNode) { result = NS_ERROR_NULL_POINTER; } + } + return result; +} + +nsresult +nsGfxTextControlFrame::GetFirstFrameForType(const nsString& aTag, nsIPresShell *aPresShell, + nsIDOMDocument *aDOMDoc, nsIFrame **aResult) +{ + if (!aPresShell || !aDOMDoc || !aResult) { return NS_ERROR_NULL_POINTER; } + nsresult result; + *aResult = nsnull; + nsCOMPtr<nsIDOMNode>node; + result = GetFirstNodeOfType(aTag, aDOMDoc, getter_AddRefs(node)); + if ((NS_SUCCEEDED(result)) && node) + { + nsCOMPtr<nsIContent>content = do_QueryInterface(node); + if (content) + { + result = aPresShell->GetPrimaryFrameFor(content, aResult); + } + } + return result; +} + +// XXX: wouldn't it be nice to get this from the style context! +PRBool nsGfxTextControlFrame::IsSingleLineTextControl() const +{ + PRInt32 type; + GetType(&type); + if ((NS_FORM_INPUT_TEXT==type) || (NS_FORM_INPUT_PASSWORD==type)) { + return PR_TRUE; + } + return PR_FALSE; +} + +// XXX: wouldn't it be nice to get this from the style context! +PRBool nsGfxTextControlFrame::IsPlainTextControl() const +{ + // need to check HTML attribute of mContent and/or CSS. + return PR_TRUE; +} + +PRBool nsGfxTextControlFrame::IsPasswordTextControl() const +{ + PRInt32 type; + GetType(&type); + if (NS_FORM_INPUT_PASSWORD==type) { + return PR_TRUE; + } + return PR_FALSE; +} + +// so we don't have to keep an extra flag around, just see if +// we've allocated the event listener or not. +PRBool nsGfxTextControlFrame::IsInitialized() const +{ + return (PRBool)(mEditor && mEventListener); +} + +PRInt32 +nsGfxTextControlFrame::GetWidthInCharacters() const +{ + // see if there's a COL attribute, if so it wins + nsCOMPtr<nsIHTMLContent> content; + nsresult result = mContent->QueryInterface(NS_GET_IID(nsIHTMLContent), getter_AddRefs(content)); + if (NS_SUCCEEDED(result) && content) + { + nsHTMLValue resultValue; + result = content->GetHTMLAttribute(nsHTMLAtoms::cols, resultValue); + if (NS_CONTENT_ATTR_NOT_THERE != result) + { + if (resultValue.GetUnit() == eHTMLUnit_Integer) + { + return (resultValue.GetIntValue()); + } + } + } + + // otherwise, see if CSS has a width specified. If so, work backwards to get the + // number of characters this width represents. + + + // otherwise, the default is just returned. + return GetDefaultColumnWidth(); +} + +NS_IMETHODIMP +nsGfxTextControlFrame::InstallEditor() +{ + nsresult result = NS_ERROR_NULL_POINTER; + if (mEditor) + { + nsCOMPtr<nsIPresShell> presShell; + result = GetPresShellFor(mDocShell, getter_AddRefs(presShell)); + if (NS_FAILED(result)) { return result; } + if (!presShell) { return NS_ERROR_NULL_POINTER; } + + // set the scrolling behavior + nsCOMPtr<nsIViewManager> vm; + presShell->GetViewManager(getter_AddRefs(vm)); + if (vm) + { + nsIScrollableView *sv=nsnull; + vm->GetRootScrollableView(&sv); + if (sv) { + if (PR_TRUE==IsSingleLineTextControl()) { + sv->SetScrollPreference(nsScrollPreference_kNeverScroll); + } else { + PRInt32 type; + GetType(&type); + if (NS_FORM_TEXTAREA == type) { + // use a local result value, since we don't care about errors here + nsScrollPreference scrollPref = nsScrollPreference_kAlwaysScroll; + nsFormControlHelper::nsHTMLTextWrap wrapProp; + nsresult wrapResult = nsFormControlHelper::GetWrapPropertyEnum(mContent, wrapProp); + if (NS_CONTENT_ATTR_NOT_THERE != wrapResult) { + if (wrapProp == nsFormControlHelper::eHTMLTextWrap_Soft || + wrapProp == nsFormControlHelper::eHTMLTextWrap_Hard) { + scrollPref = nsScrollPreference_kAuto; + } + } + sv->SetScrollPreference(scrollPref); + } + } + // views are not refcounted + } + } + + nsCOMPtr<nsIDocument> doc; + presShell->GetDocument(getter_AddRefs(doc)); + NS_ASSERTION(doc, "null document"); + if (!doc) { return NS_ERROR_NULL_POINTER; } + mDoc = do_QueryInterface(doc); + if (!mDoc) { return NS_ERROR_NULL_POINTER; } + if (mDocObserver) { + doc->AddObserver(mDocObserver); + } + + PRUint32 editorFlags = 0; + if (IsPlainTextControl()) + editorFlags |= nsIHTMLEditor::eEditorPlaintextMask; + if (IsSingleLineTextControl()) + editorFlags |= nsIHTMLEditor::eEditorSingleLineMask; + if (IsPasswordTextControl()) + editorFlags |= nsIHTMLEditor::eEditorPasswordMask; + + // initialize the editor + nsCOMPtr<nsISelectionController> selCon; + selCon = do_QueryInterface(presShell); + result = mEditor->Init(mDoc, presShell,nsnull, selCon, editorFlags); + if (NS_FAILED(result)) { return result; } + + nsCOMPtr<nsIPresShell> framePresShell; + mFramePresContext->GetShell(getter_AddRefs(framePresShell)); + nsCOMPtr<nsIDocument> frameDocument; + framePresShell->GetDocument(getter_AddRefs(frameDocument)); + + nsCOMPtr<nsIDocument> eDocument; + presShell->GetDocument(getter_AddRefs(eDocument)); + + // This allows the mousewheel code to scroll the main document + // when the pointer is over the editor control + + eDocument->SetParentDocument(frameDocument); + + // set data from the text control into the editor + result = InitializeTextControl(presShell, mDoc); + if (NS_FAILED(result)) { return result; } + + // install our own event handlers before the editor's event handlers + result = InstallEventListeners(); + if (NS_FAILED(result)) { return result; } + + // finish editor initialization, including event handler installation + result = mEditor->PostCreate(); + if (NS_FAILED(result)) { return result; } + + // check to see if mContent has focus, and if so tell the docshell. + nsCOMPtr<nsIEventStateManager> manager; + result = mFramePresContext->GetEventStateManager(getter_AddRefs(manager)); + if (NS_FAILED(result)) { return result; } + if (!manager) { return NS_ERROR_NULL_POINTER; } + + nsCOMPtr<nsIContent> focusContent; + result = manager->GetFocusedContent(getter_AddRefs(focusContent)); + if (NS_FAILED(result)) { return result; } + if (focusContent) + { + if (mContent == focusContent.get()) + { + // XXX DocShell redesign work + SetFocus(); + } + } + } + mCreatingViewer = PR_FALSE; + return result; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::InstallEventListeners() +{ + nsresult result; + + // get the DOM event receiver + nsCOMPtr<nsIDOMEventReceiver> er; + result = mDoc->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(er)); + if (!er) { result = NS_ERROR_NULL_POINTER; } + + // get the view from the docshell + nsCOMPtr<nsIPresShell> presShell; + result = GetPresShellFor(mDocShell, getter_AddRefs(presShell)); + if (NS_FAILED(result)) { return result; } + if (!presShell) { return NS_ERROR_NULL_POINTER; } + nsCOMPtr<nsIViewManager> vm; + presShell->GetViewManager(getter_AddRefs(vm)); + if (!vm) { return NS_ERROR_NULL_POINTER; } + nsIScrollableView *sv=nsnull; + vm->GetRootScrollableView(&sv); + if (!sv) { return NS_ERROR_NULL_POINTER; } + nsIView *view; + sv->QueryInterface(NS_GET_IID(nsIView), (void **)&view); + if (!view) { return NS_ERROR_NULL_POINTER; } + + // we need to hook up our listeners before the editor is initialized + result = NS_NewEnderEventListener(getter_AddRefs(mEventListener)); + if (NS_FAILED(result)) { return result ; } + if (!mEventListener) { return NS_ERROR_NULL_POINTER; } + mEventListener->SetFrame(this); + mEventListener->SetInnerPresShell(presShell); + mEventListener->SetPresContext(mFramePresContext); + mEventListener->SetView(view); + + nsCOMPtr<nsIDOMKeyListener> keyListener = do_QueryInterface(mEventListener); + if (!keyListener) { return NS_ERROR_NO_INTERFACE; } + result = er->AddEventListenerByIID(keyListener, NS_GET_IID(nsIDOMKeyListener)); + if (NS_FAILED(result)) { return result; } + + nsCOMPtr<nsIDOMMouseListener> mouseListener = do_QueryInterface(mEventListener); + if (!mouseListener) { return NS_ERROR_NO_INTERFACE; } + result = er->AddEventListenerByIID(mouseListener, NS_GET_IID(nsIDOMMouseListener)); + if (NS_FAILED(result)) { return result; } + + nsCOMPtr<nsIDOMFocusListener> focusListener = do_QueryInterface(mEventListener); + if (!focusListener) { return NS_ERROR_NO_INTERFACE; } + result = er->AddEventListenerByIID(focusListener, NS_GET_IID(nsIDOMFocusListener)); + if (NS_FAILED(result)) { return result; } + + // add the selection listener + if (mEditor && mEventListener) + { + nsCOMPtr<nsISelection>selection; + result = mEditor->GetSelection(getter_AddRefs(selection)); + if (NS_FAILED(result)) { return result; } + if (!selection) { return NS_ERROR_NULL_POINTER; } + nsCOMPtr<nsISelectionListener> selectionListener = do_QueryInterface(mEventListener); + if (!selectionListener) { return NS_ERROR_NO_INTERFACE; } + result = selection->AddSelectionListener(selectionListener); + if (NS_FAILED(result)) { return result; } + } + + // add the transation listener + if (mEditor && mEventListener) + { + nsCOMPtr<nsITransactionManager> txMgr; + result = mEditor->GetTransactionManager(getter_AddRefs(txMgr)); + if (NS_FAILED(result)) return result; + if (!txMgr) { return NS_ERROR_NULL_POINTER; } + + nsCOMPtr<nsITransactionListener> txnListener = do_QueryInterface(mEventListener); + if (!txnListener) { return NS_ERROR_NO_INTERFACE; } + result = txMgr->AddListener(txnListener); + if (NS_FAILED(result)) { return result; } + } + + return result; +} + +nsresult +nsGfxTextControlFrame::GetFirstFrameWithIID(nsIPresContext *aPresContext, const nsIID& aIID, nsIFrame *aRootFrame, void ** +aResultFrame) +{ + if (!aPresContext || !aRootFrame || !aResultFrame) + return NS_ERROR_NULL_POINTER; + + *aResultFrame = nsnull; + + // Check if the root frame implements the specified interface. + + nsresult result = aRootFrame->QueryInterface(aIID, aResultFrame); + + // Check for any error that may have been thrown. + // Ignore NS_NOINTERFACE since we want to continue traversal. + + if (NS_FAILED(result) && result != NS_NOINTERFACE) + return result; + + // Check to see if we are done. + + if (*aResultFrame) + return NS_OK; + + // We aren't done, so traverse down the root frame's children, + // calling this method recursively. + + nsIFrame *childFrame = nsnull; + + result = aRootFrame->FirstChild(aPresContext, nsnull, &childFrame); + + if (NS_FAILED(result)) + return result; + + while (childFrame) + { + result = GetFirstFrameWithIID(aPresContext, aIID, childFrame, aResultFrame); + + if (NS_FAILED(result)) + return result; + + if (*aResultFrame) + return NS_OK; + + result = childFrame->GetNextSibling(&childFrame); + + if (NS_FAILED(result)) + return result; + } + + // No frame was found that implemented the specified + // interface. Return NULL and NS_OK since no error + // occured during our traversal. + + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::InitializeTextControl(nsIPresShell *aPresShell, nsIDOMDocument *aDoc) +{ + nsresult result; + if (!aPresShell || !aDoc) { return NS_ERROR_NULL_POINTER; } + + /* needing a frame here is a hack. We can't remove this hack until we can + * set presContext info before style resolution on the docshell + */ + nsIFrame *frame; + result = aPresShell->GetRootFrame(&frame); + if (NS_FAILED(result)) { return result; } + if (!frame) { return NS_ERROR_NULL_POINTER; } + + PRInt32 type; + GetType(&type); + + nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor); + if (!htmlEditor) { return NS_ERROR_NO_INTERFACE; } + + nsCOMPtr<nsISelectionController> selCon; + selCon = do_QueryInterface(aPresShell); + + nsCOMPtr<nsIPresContext>presContext; + aPresShell->GetPresContext(getter_AddRefs(presContext)); + NS_ASSERTION(presContext, "null presentation context"); + if (!presContext) { return NS_ERROR_NULL_POINTER; } + + /* set all style that propogates from the text control to its content + * into the presContext for the docshell. + * what I would prefer to do is hand the docshell my own + * pres context at creation, rather than having it create its own. + */ + + const nsFont * font = nsnull; + nsresult res = GetFont(presContext, font); + if (NS_SUCCEEDED(res) && font != nsnull) { + //nsFont defFont = *font; + presContext->SetDefaultFont(*font); + presContext->SetDefaultFixedFont(*font); + } + + const nsStyleFont* controlFont; + GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)controlFont); + + + const nsStyleColor* controlColor; + GetStyleData(eStyleStruct_Color, (const nsStyleStruct *&)controlColor); + presContext->SetDefaultColor(controlColor->mColor); + presContext->SetDefaultBackgroundColor(controlColor->mBackgroundColor); + presContext->SetDefaultBackgroundImageRepeat(controlColor->mBackgroundRepeat); + presContext->SetDefaultBackgroundImageAttachment(controlColor->mBackgroundAttachment); + presContext->SetDefaultBackgroundImageOffset(controlColor->mBackgroundXPosition, controlColor->mBackgroundYPosition); + presContext->SetDefaultBackgroundImage(controlColor->mBackgroundImage); + + /* HACK: + * since I don't yet have a hook for setting info on the pres context before style is + * resolved, I need to call remap style on the root frame's style context. + * The above code for setting presContext data should happen on a presContext that + * I create and pass into the docshell, rather than having the docshell create its own + */ + nsCOMPtr<nsIStyleContext> sc; + result = frame->GetStyleContext(getter_AddRefs(sc)); + if (NS_FAILED(result)) { return result; } + if (nsnull==sc) { return NS_ERROR_NULL_POINTER; } + sc->RemapStyle(presContext); + + if (IsSingleLineTextControl()) + { + // We need to tweak the overflow property on the scrollframe to tell it + // that we want to hide the scrollbars! Note that this has to be done + // after the RemapStyle() above, otherwise our tweak will be blown away. + + nsIScrollableFrame *scrollFrame = nsnull; + + result = GetFirstFrameWithIID(presContext, NS_GET_IID(nsIScrollableFrame), frame, (void **)&scrollFrame); + + if (NS_FAILED(result)) + return result; + + if (scrollFrame) + { + nsIFrame *sFrame = nsnull; + + result = scrollFrame->QueryInterface(NS_GET_IID(nsIFrame), (void **)&sFrame); + + if (NS_FAILED(result) && result != NS_NOINTERFACE) + return result; + + if (sFrame) + { + nsCOMPtr<nsIStyleContext> scrollFrameStyleContext; + + result = sFrame->GetStyleContext(getter_AddRefs(scrollFrameStyleContext)); + + if (NS_FAILED(result)) + return result; + + if (scrollFrameStyleContext) + { + nsMutableStyleDisplay display(scrollFrameStyleContext); + display->mOverflow = NS_STYLE_OVERFLOW_SCROLLBARS_NONE; + } + } + } + } + + // end HACK + + // now that the style context is initialized, initialize the content + nsAutoString value; + if (mCachedState) { + value.Assign(*mCachedState); + delete mCachedState; + mCachedState = nsnull; + } else { + GetText(&value, PR_TRUE); + } + mEditor->EnableUndo(PR_FALSE); + + PRInt32 maxLength; + result = GetMaxLength(&maxLength); + if (NS_CONTENT_ATTR_NOT_THERE != result) { + htmlEditor->SetMaxTextLength(maxLength); + } + + nsCOMPtr<nsIEditorMailSupport> mailEditor = do_QueryInterface(mEditor); + if (mailEditor) + { + PRBool wrapToContainerWidth = PR_TRUE; + if (PR_TRUE==IsSingleLineTextControl()) + { // no wrapping for single line text controls + result = mailEditor->SetWrapWidth(-1); + wrapToContainerWidth = PR_FALSE; + } + else + { // if WRAP="OFF", turn wrapping off in the editor + nsFormControlHelper::nsHTMLTextWrap wrapProp; + result = nsFormControlHelper::GetWrapPropertyEnum(mContent, wrapProp); + if (NS_CONTENT_ATTR_NOT_THERE != result) + { + if (wrapProp == nsFormControlHelper::eHTMLTextWrap_Off) + { + result = mailEditor->SetWrapWidth(-1); + wrapToContainerWidth = PR_FALSE; + } + if (wrapProp == nsFormControlHelper::eHTMLTextWrap_Hard) + { + PRInt32 widthInCharacters = GetWidthInCharacters(); + result = mailEditor->SetWrapWidth(widthInCharacters); + wrapToContainerWidth = PR_FALSE; + } + } else { + result = mailEditor->SetWrapWidth(-1); + wrapToContainerWidth = PR_FALSE; + } + } + if (PR_TRUE==wrapToContainerWidth) + { // if we didn't set wrapping explicitly, turn on default wrapping here + result = mailEditor->SetWrapWidth(0); + } + NS_ASSERTION((NS_SUCCEEDED(result)), "error setting wrap width"); + if (NS_FAILED(result)) { return result; } + } + + nsCOMPtr<nsIEditor>editor = do_QueryInterface(mEditor); + NS_ASSERTION(editor, "bad QI to nsIEditor from mEditor"); + if (editor) + { + nsCOMPtr<nsISelection>selection; + result = editor->GetSelection(getter_AddRefs(selection)); + if (NS_FAILED(result)) { return result; } + if (!selection) { return NS_ERROR_NULL_POINTER; } + nsCOMPtr<nsIDOMNode>bodyNode; + result = GetFirstNodeOfType(NS_ConvertASCIItoUCS2("body"), aDoc, + getter_AddRefs(bodyNode)); + if (NS_SUCCEEDED(result) && bodyNode) + { + result = mEditor->SelectAll(); + if (NS_SUCCEEDED(result)) + { + if (0!=value.Length()) + { + result = htmlEditor->InsertText(value); + if (NS_FAILED(result)) { return result; } + // collapse selection to beginning of text + nsCOMPtr<nsIDOMNode>firstChild; + result = bodyNode->GetFirstChild(getter_AddRefs(firstChild)); + if (NS_FAILED(result)) { return result; } + selection->Collapse(firstChild, 0); + } + } + } + } + + // finish initializing editor + // turn in undo, *except* for password fields. + if (!IsPasswordTextControl()) + mEditor->EnableUndo(PR_TRUE); + + // set readonly and disabled states + if (mContent) + { + PRUint32 flags=0; + if (IsPlainTextControl()) { + flags |= nsIHTMLEditor::eEditorPlaintextMask; + } + if (IsSingleLineTextControl()) { + flags |= nsIHTMLEditor::eEditorSingleLineMask; + } + if (IsPasswordTextControl()) { + flags |= nsIHTMLEditor::eEditorPasswordMask; + } + nsCOMPtr<nsIContent> content; + result = mContent->QueryInterface(NS_GET_IID(nsIContent), getter_AddRefs(content)); + if (NS_SUCCEEDED(result) && content) + { + PRInt32 nameSpaceID; + content->GetNameSpaceID(nameSpaceID); + nsAutoString resultValue; + result = content->GetAttribute(nameSpaceID, nsHTMLAtoms::readonly, resultValue); + if (NS_CONTENT_ATTR_NOT_THERE != result) { + flags |= nsIHTMLEditor::eEditorReadonlyMask; + if (selCon) + selCon->SetCaretEnabled(PR_FALSE); + } + result = content->GetAttribute(nameSpaceID, nsHTMLAtoms::disabled, resultValue); + if (NS_CONTENT_ATTR_NOT_THERE != result) + { + flags |= nsIHTMLEditor::eEditorDisabledMask; + if (selCon) + { + selCon->SetCaretEnabled(PR_FALSE); + selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON); + } + } + } + mEditor->SetFlags(flags); + + // turn on oninput notifications now that I'm done manipulating the editable content + mNotifyOnInput = PR_TRUE; + } + return result; +} + +// this is where we propogate a content changed event +NS_IMETHODIMP +nsGfxTextControlFrame::InternalContentChanged() +{ + NS_PRECONDITION(mContent, "illegal to call unless we map to a content node"); + + if (!mContent) { return NS_ERROR_NULL_POINTER; } + + if (PR_FALSE==mNotifyOnInput) { + return NS_OK; // if notification is turned off, just return ok + } + + // Dispatch the change event + nsEventStatus status = nsEventStatus_eIgnore; + nsGUIEvent theEvent; + theEvent.eventStructType = NS_GUI_EVENT; + theEvent.widget = nsnull; + theEvent.message = NS_FORM_INPUT; + theEvent.flags = NS_EVENT_FLAG_INIT; + + // Have the content handle the event, propogating it according to normal DOM rules. + return mContent->HandleDOMEvent(mFramePresContext, &theEvent, nsnull, NS_EVENT_FLAG_INIT, &status); +} + +nsresult nsGfxTextControlFrame::UpdateTextControlCommands(const nsString& aCommand) +{ + nsresult rv = NS_OK; + + if (mEditor) + { + if (aCommand == NS_ConvertASCIItoUCS2("select")) // optimize select updates + { + nsCOMPtr<nsISelection> domSelection; + rv = mEditor->GetSelection(getter_AddRefs(domSelection)); + if (NS_FAILED(rv)) return rv; + if (!domSelection) return NS_ERROR_UNEXPECTED; + + PRBool selectionCollapsed; + domSelection->GetIsCollapsed(&selectionCollapsed); + if (mGotSelectionState && mSelectionWasCollapsed == selectionCollapsed) + { + return NS_OK; // no update necessary + } + else + { + mGotSelectionState = PR_TRUE; + mSelectionWasCollapsed = selectionCollapsed; + } + } + } + + nsCOMPtr<nsIContent> content; + rv = GetContent(getter_AddRefs(content)); + if (NS_FAILED(rv)) return rv; + if (!content) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDocument> doc; + rv = content->GetDocument(*getter_AddRefs(doc)); + if (NS_FAILED(rv)) return rv; + if (!doc) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObject; + rv = doc->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject)); + if (NS_FAILED(rv)) return rv; + if (!scriptGlobalObject) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(scriptGlobalObject); + if (!domWindow) return NS_ERROR_FAILURE; + + return domWindow->UpdateCommands(aCommand); +} + +void nsGfxTextControlFrame::RemoveNewlines(nsString &aString) +{ + // strip CR/LF and null + static const char badChars[] = {10, 13, 0}; + aString.StripChars(badChars); +} + +NS_IMETHODIMP +nsGfxTextControlFrame::GetAdditionalChildListName(PRInt32 aIndex, + nsIAtom **aListName) const +{ + if (aIndex == 0) { + *aListName = nsLayoutAtoms::editorDisplayList; + NS_IF_ADDREF(*aListName); + return NS_OK; + } + + return nsLeafFrame::GetAdditionalChildListName(aIndex, aListName); +} + +NS_IMETHODIMP +nsGfxTextControlFrame::FirstChild(nsIPresContext* aPresContext, + nsIAtom* aListName, + nsIFrame** aFirstChild) const +{ + if (nsLayoutAtoms::editorDisplayList) { + *aFirstChild = mDisplayFrame; + return NS_OK; + } + + return nsLeafFrame::FirstChild(aPresContext, aListName, aFirstChild); +} + +NS_IMETHODIMP +nsGfxTextControlFrame::Destroy(nsIPresContext* aPresContext) +{ + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); + + if (mDisplayFrame) { + mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, mDisplayFrame, nsnull); + mDisplayFrame->Destroy(aPresContext); + mDisplayFrame=nsnull; + } + return nsLeafFrame::Destroy(aPresContext); +} +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsGfxTextControlFrame::GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eTextType; + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::SaveState(nsIPresContext* aPresContext, nsIPresState** aState) +{ + // Construct a pres state. + NS_NewPresState(aState); // The addref happens here. + + nsString theString; + nsresult res = GetProperty(nsHTMLAtoms::value, theString); + if (NS_FAILED(res)) + return res; + + res = nsLinebreakConverter::ConvertStringLineBreaks(theString, + nsLinebreakConverter::eLinebreakPlatform, nsLinebreakConverter::eLinebreakContent); + NS_ASSERTION(NS_SUCCEEDED(res), "Converting linebreaks failed!"); + + (*aState)->SetStateProperty(NS_ConvertASCIItoUCS2("value"), theString); + return res; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::RestoreState(nsIPresContext* aPresContext, nsIPresState* aState) +{ + nsAutoString stateString; + aState->GetStateProperty(NS_ConvertASCIItoUCS2("value"), stateString); + nsresult res = SetProperty(aPresContext, nsHTMLAtoms::value, stateString); + return res; +} + +#ifdef NS_DEBUG +NS_IMETHODIMP +nsGfxTextControlFrame::List(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent) const +{ + IndentBy(out, aIndent); + ListTag(out); + nsIView* view; + GetView(aPresContext, &view); + if (nsnull != view) { + fprintf(out, " [view=%p]", view); + } + fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height); + if (0 != mState) { + fprintf(out, " [state=%08x]", mState); + } + fputs("<\n", out); + + // Dump out frames contained in interior web-shell + if (mDocShell) { + nsCOMPtr<nsIContentViewer> viewer; + mDocShell->GetContentViewer(getter_AddRefs(viewer)); + if (viewer) { + nsCOMPtr<nsIDocumentViewer> docv(do_QueryInterface(viewer)); + if (docv) { + nsCOMPtr<nsIPresContext> cx; + docv->GetPresContext(*getter_AddRefs(cx)); + if (cx) { + nsCOMPtr<nsIPresShell> shell; + cx->GetShell(getter_AddRefs(shell)); + if (shell) { + nsIFrame* rootFrame; + shell->GetRootFrame(&rootFrame); + if (rootFrame) { + nsIFrameDebug* frameDebug; + + if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) { + frameDebug->List(aPresContext, out, aIndent + 1); + } + nsCOMPtr<nsIDocument> doc; + docv->GetDocument(*getter_AddRefs(doc)); + if (doc) { + nsCOMPtr<nsIContent> rootContent(getter_AddRefs(doc->GetRootContent())); + if (rootContent) { + rootContent->List(out, aIndent + 1); + } + } + } + } + } + } + } + } + + IndentBy(out, aIndent); + fputs(">\n", out); + + if (mDisplayFrame) { + nsIFrameDebug* frameDebug; + + IndentBy(out, aIndent); + nsAutoString tmp; + fputs("<\n", out); + if (NS_SUCCEEDED(mDisplayFrame->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) { + frameDebug->List(aPresContext, out, aIndent + 1); + } + IndentBy(out, aIndent); + fputs(">\n", out); + } + + return NS_OK; +} +#endif + +/******************************************************************************* + * EnderFrameLoadingInfo + ******************************************************************************/ +class EnderFrameLoadingInfo : public nsISupports +{ +public: + EnderFrameLoadingInfo(const nsSize& aSize); + + // nsISupports interface... + NS_DECL_ISUPPORTS + +protected: + virtual ~EnderFrameLoadingInfo() {} + +public: + nsSize mFrameSize; +}; + +EnderFrameLoadingInfo::EnderFrameLoadingInfo(const nsSize& aSize) +{ + NS_INIT_REFCNT(); + + mFrameSize = aSize; +} + +/* + * Implementation of ISupports methods... + */ +NS_IMPL_ISUPPORTS(EnderFrameLoadingInfo,kISupportsIID); + + +#ifdef XP_MAC +#pragma mark - +#endif + +/******************************************************************************* + * nsEnderDocumentObserver + ******************************************************************************/ +NS_IMPL_ADDREF(nsEnderDocumentObserver); +NS_IMPL_RELEASE(nsEnderDocumentObserver); + +nsEnderDocumentObserver::nsEnderDocumentObserver() +{ + NS_INIT_REFCNT(); +} + +nsEnderDocumentObserver::~nsEnderDocumentObserver() +{ +} + +nsresult +nsEnderDocumentObserver::QueryInterface(const nsIID& aIID, + void** aInstancePtr) +{ + NS_PRECONDITION(nsnull != aInstancePtr, "null pointer"); + if (nsnull == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(NS_GET_IID(nsIDocumentObserver))) { + *aInstancePtr = (void*) ((nsIRequestObserver*)this); + AddRef(); + return NS_OK; + } + if (aIID.Equals(kISupportsIID)) { + *aInstancePtr = (void*) ((nsISupports*)((nsIDocumentObserver*)this)); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + + + +NS_IMETHODIMP +nsEnderDocumentObserver::SetFrame(nsGfxTextControlFrame *aFrame) +{ + mFrame = aFrame; + return NS_OK; +} + +NS_IMETHODIMP nsEnderDocumentObserver::BeginUpdate(nsIDocument *aDocument) +{ + return NS_OK; +} + +NS_IMETHODIMP nsEnderDocumentObserver::EndUpdate(nsIDocument *aDocument) +{ + return NS_OK; +} + +NS_IMETHODIMP nsEnderDocumentObserver::BeginLoad(nsIDocument *aDocument) +{ + return NS_OK; +} + +NS_IMETHODIMP nsEnderDocumentObserver::EndLoad(nsIDocument *aDocument) +{ + return NS_OK; +} + +NS_IMETHODIMP nsEnderDocumentObserver::BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell) +{ + return NS_OK; +} + +NS_IMETHODIMP nsEnderDocumentObserver::EndReflow(nsIDocument *aDocument, nsIPresShell* aShell) +{ return NS_OK; } + +NS_IMETHODIMP nsEnderDocumentObserver::ContentChanged(nsIDocument *aDocument, + nsIContent* aContent, + nsISupports* aSubContent) +{ + nsresult result = NS_OK; + if (mFrame) { + result = mFrame->InternalContentChanged(); + } + return result; +} + +NS_IMETHODIMP nsEnderDocumentObserver::ContentStatesChanged(nsIDocument* aDocument, + nsIContent* aContent1, + nsIContent* aContent2) +{ return NS_OK; } + +NS_IMETHODIMP nsEnderDocumentObserver::AttributeChanged(nsIDocument *aDocument, + nsIContent* aContent, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aHint) +{ return NS_OK; } + +NS_IMETHODIMP nsEnderDocumentObserver::ContentAppended(nsIDocument *aDocument, + nsIContent* aContainer, + PRInt32 aNewIndexInContainer) +{ + nsresult result = NS_OK; + if (mFrame) { + result = mFrame->InternalContentChanged(); + } + return result; +} + +NS_IMETHODIMP nsEnderDocumentObserver::ContentInserted(nsIDocument *aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer) +{ + nsresult result = NS_OK; + if (mFrame) { + result = mFrame->InternalContentChanged(); + } + return result; +} + +NS_IMETHODIMP nsEnderDocumentObserver::ContentReplaced(nsIDocument *aDocument, + nsIContent* aContainer, + nsIContent* aOldChild, + nsIContent* aNewChild, + PRInt32 aIndexInContainer) +{ + nsresult result = NS_OK; + if (mFrame) { + result = mFrame->InternalContentChanged(); + } + return result; +} + +NS_IMETHODIMP nsEnderDocumentObserver::ContentRemoved(nsIDocument *aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer) +{ + nsresult result = NS_OK; + if (mFrame) { + result = mFrame->InternalContentChanged(); + } + return result; +} + +NS_IMETHODIMP nsEnderDocumentObserver::StyleSheetAdded(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) +{ return NS_OK; } +NS_IMETHODIMP nsEnderDocumentObserver::StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) +{ return NS_OK; } +NS_IMETHODIMP nsEnderDocumentObserver::StyleSheetDisabledStateChanged(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + PRBool aDisabled) +{ return NS_OK; } +NS_IMETHODIMP nsEnderDocumentObserver::StyleRuleChanged(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) +{ return NS_OK; } +NS_IMETHODIMP nsEnderDocumentObserver::StyleRuleAdded(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ return NS_OK; } +NS_IMETHODIMP nsEnderDocumentObserver::StyleRuleRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ return NS_OK; } + +NS_IMETHODIMP nsEnderDocumentObserver::DocumentWillBeDestroyed(nsIDocument *aDocument) +{ + return NS_OK; +} + +#ifdef XP_MAC +#pragma mark - +#endif + + +/******************************************************************************* + * nsEnderEventListener + ******************************************************************************/ + +nsresult +NS_NewEnderEventListener(nsIEnderEventListener ** aInstancePtr) +{ + nsEnderEventListener* it = new nsEnderEventListener(); + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + return it->QueryInterface(NS_GET_IID(nsIEnderEventListener), (void **) aInstancePtr); +} + +NS_IMPL_ADDREF(nsEnderEventListener) + +NS_IMPL_RELEASE(nsEnderEventListener) + + +nsEnderEventListener::nsEnderEventListener() +: mView(nsnull) +, mSkipFocusDispatch(PR_FALSE) // needed for when mouse down set focus on native widgets +, mFirstDoOfFirstUndo(PR_TRUE) +{ + NS_INIT_REFCNT(); +} + +nsEnderEventListener::~nsEnderEventListener() +{ + // all refcounted objects are held as nsCOMPtrs, clear themselves +} + +NS_IMETHODIMP +nsEnderEventListener::SetFrame(nsGfxTextControlFrame *aFrame) +{ + mFrame.SetReference(aFrame->WeakReferent()); + if (aFrame) + { + aFrame->GetContent(getter_AddRefs(mContent)); + } + return NS_OK; +} + +nsresult +nsEnderEventListener::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (nsnull == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(kISupportsIID)) { + nsIDOMKeyListener *tmp = this; + nsISupports *tmp2 = tmp; + *aInstancePtr = (void*) tmp2; + NS_ADDREF_THIS(); + return NS_OK; + } + + if (aIID.Equals(NS_GET_IID(nsIDOMEventListener))) { + nsIDOMKeyListener *kl = (nsIDOMKeyListener*)this; + nsIDOMEventListener *temp = kl; + *aInstancePtr = (void*)temp; + NS_ADDREF_THIS(); + return NS_OK; + } + + if (aIID.Equals(NS_GET_IID(nsIDOMKeyListener))) { + *aInstancePtr = (void*)(nsIDOMKeyListener*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(NS_GET_IID(nsIDOMMouseListener))) { + *aInstancePtr = (void*)(nsIDOMMouseListener*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(NS_GET_IID(nsIDOMFocusListener))) { + *aInstancePtr = (void*)(nsIDOMFocusListener*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(NS_GET_IID(nsISelectionListener))) { + *aInstancePtr = (void*)(nsISelectionListener*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(NS_GET_IID(nsITransactionListener))) { + *aInstancePtr = (void*)(nsITransactionListener*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(NS_GET_IID(nsIEnderEventListener))) { + *aInstancePtr = (void*)(nsIEnderEventListener*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + + return NS_NOINTERFACE; +} + +nsresult +nsEnderEventListener::HandleEvent(nsIDOMEvent* aEvent) +{ + return NS_OK; +} + +/*================== nsIKeyListener =========================*/ + +nsresult +nsEnderEventListener::DispatchKeyEvent(nsIDOMKeyEvent* aOrigEvent, + PRInt32 aEventType) +{ + nsGfxTextControlFrame *gfxFrame = mFrame.Reference(); + if (!gfxFrame || !mContent || !mContext || !mView) + return NS_ERROR_NOT_INITIALIZED; + + nsKeyEvent newEvent; + newEvent.message = aEventType; + newEvent.eventStructType = NS_KEY_EVENT; + newEvent.widget = nsnull; + newEvent.flags = NS_EVENT_FLAG_INIT; + aOrigEvent->GetKeyCode(&(newEvent.keyCode)); + if (newEvent.message == NS_KEY_PRESS) + aOrigEvent->GetCharCode(&(newEvent.charCode)); + else + newEvent.charCode = 0; + aOrigEvent->GetShiftKey(&(newEvent.isShift)); + aOrigEvent->GetCtrlKey(&(newEvent.isControl)); + aOrigEvent->GetAltKey(&(newEvent.isAlt)); + aOrigEvent->GetMetaKey(&(newEvent.isMeta)); + + nsCOMPtr<nsIEventStateManager> manager; + nsresult result = mContext->GetEventStateManager(getter_AddRefs(manager)); + if (NS_FAILED(result)) + return result; + if (!manager) + return NS_ERROR_UNEXPECTED; + + nsEventStatus status = nsEventStatus_eIgnore; + +#ifndef SIMPLIFIED_EVENTS_FOR_KEY_UP_AND_DOWN + // 1. Give event to event manager for pre event state changes + // and generation of synthetic events. + result = manager->PreHandleEvent(mContext, &newEvent, gfxFrame, &status, mView); + + // 2. Give event to the DOM for third party and JS use. + if (NS_SUCCEEDED(result)) { + result = mContent->HandleDOMEvent(mContext, &newEvent, nsnull, + NS_EVENT_FLAG_INIT, &status); + } + + // 3. Give event to the frame for browser default processing + gfxFrame = mFrame.Reference(); // check for deletion + if (gfxFrame && NS_SUCCEEDED(result)) { + result = gfxFrame->HandleEvent(mContext, &newEvent, &status); + } + + // 4. Give event to event manager for post event state changes and + // generation of synthetic events. + gfxFrame = mFrame.Reference(); // check for deletion + if (gfxFrame && NS_SUCCEEDED(result)) { + result = manager->PostHandleEvent(mContext, &newEvent, gfxFrame, + &status, mView); + + } + + // Call consume focus events on the inner event state manager to prevent its + // PostHandleEvent from immediately blurring us. + nsCOMPtr<nsIPresContext> pc; + mInnerShell->GetPresContext(getter_AddRefs(pc)); + + nsCOMPtr<nsIEventStateManager> esm; + pc->GetEventStateManager(getter_AddRefs(esm)); + esm->ConsumeFocusEvents(PR_TRUE); + + if (newEvent.flags & NS_EVENT_FLAG_STOP_DISPATCH && aOrigEvent) { + aOrigEvent->PreventCapture(); + aOrigEvent->PreventBubble(); + } + + // Used to do this simplified version for KeyUp and KeyDown events. + // This seems bad ... we shouldn't try to second-guess what types + // of events the user might want to track. +#else /* SIMPLIFIED_EVENTS_FOR_KEY_UP_AND_DOWN */ + // 1. Give event to event manager for pre event state changes + // and generation of synthetic events. + result = aManager->PreHandleEvent(mContext, &newEvent, gfxFrame, &status, mView); + + // 2. Give event to the DOM for third party and JS use. + if (NS_SUCCEEDED(result)) { + result = mContent->HandleDOMEvent(mContext, &newEvent, nsnull, + NS_EVENT_FLAG_INIT, &status); + } + + // 3. In this case, the frame does no processing of the event + + // 4. Give event to event manager for post event state changes and + // generation of synthetic events. + gfxFrame = mFrame.Reference(); // check for deletion + if (gfxFrame && NS_SUCCEEDED(result)) { + result = aManager->PostHandleEvent(mContext, &newEvent, gfxFrame, &status, mView); + } +#endif /* SIMPLIFIED_EVENTS_FOR_KEY_UP_AND_DOWN */ + + return result; +} + +nsresult +nsEnderEventListener::KeyDown(nsIDOMEvent* aKeyEvent) +{ + nsCOMPtr<nsIDOMKeyEvent>keyEvent; + keyEvent = do_QueryInterface(aKeyEvent); + if (!keyEvent) { //non-key event passed to keydown. bad things. + return NS_OK; + } + + return DispatchKeyEvent(keyEvent, NS_KEY_DOWN); +} + +nsresult +nsEnderEventListener::KeyUp(nsIDOMEvent* aKeyEvent) +{ + nsCOMPtr<nsIDOMKeyEvent>keyEvent; + keyEvent = do_QueryInterface(aKeyEvent); + if (!keyEvent) { //non-key event passed to keydown. bad things. + return NS_OK; + } + + return DispatchKeyEvent(keyEvent, NS_KEY_UP); +} + +nsresult +nsEnderEventListener::KeyPress(nsIDOMEvent* aKeyEvent) +{ + nsCOMPtr<nsIDOMKeyEvent>keyEvent; + keyEvent = do_QueryInterface(aKeyEvent); + if (!keyEvent) { //non-key event passed to keydown. bad things. + return NS_OK; + } + + return DispatchKeyEvent(keyEvent, NS_KEY_PRESS); +} + +/*=============== nsIMouseListener ======================*/ + +nsresult +nsEnderEventListener::DispatchMouseEvent(nsIDOMMouseEvent *aEvent, PRInt32 aEventType) +{ + nsresult result = NS_OK; + + // The ESM has already dispatched the "click" event to DOM + // so we need to ignore it here or we will get double notifications + if (aEventType == NS_MOUSE_LEFT_CLICK || + aEventType == NS_MOUSE_MIDDLE_CLICK || + aEventType == NS_MOUSE_RIGHT_CLICK) { + return result; + } + + if (aEvent) + { + nsGfxTextControlFrame *gfxFrame = mFrame.Reference(); + if (gfxFrame) + { + // Dispatch the event + nsEventStatus status = nsEventStatus_eIgnore; + nsMouseEvent event; + event.eventStructType = NS_MOUSE_EVENT; + event.widget = nsnull; + event.flags = NS_EVENT_FLAG_INIT; + aEvent->GetShiftKey(&(event.isShift)); + aEvent->GetCtrlKey(&(event.isControl)); + aEvent->GetAltKey(&(event.isAlt)); + aEvent->GetMetaKey(&(event.isMeta)); + aEvent->GetClientX(&(event.refPoint.x)); + aEvent->GetClientY(&(event.refPoint.y)); + aEvent->GetScreenX(&(event.point.x)); + aEvent->GetScreenY(&(event.point.y)); + + PRInt32 clickCount; + aEvent->GetDetail(&clickCount); + event.clickCount = clickCount; + event.message = aEventType; + GetWidgetForView(mView, event.widget); + NS_ASSERTION(event.widget, "null widget in mouse event redispatch. right mouse click will crash!"); + + nsIEventStateManager *manager=nsnull; + result = mContext->GetEventStateManager(&manager); + if (NS_SUCCEEDED(result) && manager) + { + //1. Give event to event manager for pre event state changes and generation of synthetic events. + result = manager->PreHandleEvent(mContext, &event, gfxFrame, &status, mView); + + //2. Give event to the DOM for third party and JS use. + if (NS_SUCCEEDED(result)) { + result = mContent->HandleDOMEvent(mContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); + } + + //3. Give event to the frame for browser default processing + if (NS_SUCCEEDED(result)) { + result = gfxFrame->HandleEvent(mContext, &event, &status); + } + + //4. Give event to event manager for post event state changes and generation of synthetic events. + gfxFrame = mFrame.Reference(); // check for deletion + if (gfxFrame && NS_SUCCEEDED(result)) { + result = manager->PostHandleEvent(mContext, &event, gfxFrame, &status, mView); + } + NS_IF_RELEASE(manager); + + if ((aEventType == NS_MOUSE_LEFT_BUTTON_DOWN) || + (aEventType == NS_MOUSE_MIDDLE_BUTTON_DOWN) || + (aEventType == NS_MOUSE_RIGHT_BUTTON_DOWN)) + { + // Call consume focus events on the inner event state manager to prevent its + // PostHandleEvent from immediately blurring us. + nsCOMPtr<nsIPresContext> pc; + mInnerShell->GetPresContext(getter_AddRefs(pc)); + + nsCOMPtr<nsIEventStateManager> esm; + pc->GetEventStateManager(getter_AddRefs(esm)); + esm->ConsumeFocusEvents(PR_TRUE); + gfxFrame = mFrame.Reference(); // check for deletion + if (gfxFrame) { + gfxFrame->SetFocus(); + } + } + } + NS_IF_RELEASE(event.widget); + } + } + return result; +} + +// This makes sure the the mSkipFocusDispatch gets set to false +class SemiphoreFocusDispatch { + PRBool * mBool; +public: + SemiphoreFocusDispatch(PRBool * aBool) :mBool(NULL) { if (aBool) {mBool = aBool; *mBool = PR_TRUE;} } + ~SemiphoreFocusDispatch() { if (mBool) *mBool = PR_FALSE; } +}; + +nsresult +nsEnderEventListener::MouseDown(nsIDOMEvent* aEvent) +{ + SemiphoreFocusDispatch skipFocusDispatch(&mSkipFocusDispatch); + mSkipFocusDispatch = PR_TRUE; + + nsCOMPtr<nsIDOMMouseEvent>mouseEvent; + mouseEvent = do_QueryInterface(aEvent); + if (!mouseEvent) { //non-key event passed in. bad things. + return NS_OK; + } + + nsresult result = NS_OK; + + if (mContent && mContext && mView) + { + PRUint16 button; + mouseEvent->GetButton(&button); + PRInt32 eventType; + switch(button) + { + case 0: //XXX: I can't believe there isn't a symbol for this! + eventType = NS_MOUSE_LEFT_BUTTON_DOWN; + break; + case 1: //XXX: I can't believe there isn't a symbol for this! + eventType = NS_MOUSE_MIDDLE_BUTTON_DOWN; + // XXX See bug 23336: the ender event listener is superfluous, + // causing double mouse click events to get through. + // This is a temporary way of disabling it in the middle-click case. + // Arguably, the whole event listener should be disabled, + // or at least rewritten; we'll look into that post-M14. + return NS_OK; + case 2: //XXX: I can't believe there isn't a symbol for this! + // XXX See bug 27827 -- we need to disable right clicks + // just like we disabled middle clicks. + eventType = NS_MOUSE_RIGHT_BUTTON_DOWN; + return NS_OK; + default: + NS_ASSERTION(0, "bad button type"); + return NS_OK; + } + result = DispatchMouseEvent(mouseEvent, eventType); + } + mSkipFocusDispatch = PR_FALSE; + return result; +} + +nsresult +nsEnderEventListener::MouseUp(nsIDOMEvent* aEvent) +{ + nsCOMPtr<nsIDOMMouseEvent>mouseEvent; + mouseEvent = do_QueryInterface(aEvent); + if (!mouseEvent) { //non-mouse event passed in. bad things. + return NS_OK; + } + + nsresult result = NS_OK; + + if (mContent && mContext && mView) + { + PRUint16 button; + mouseEvent->GetButton(&button); + PRInt32 eventType; + switch(button) + { + case 0: + eventType = NS_MOUSE_LEFT_BUTTON_UP; + break; + case 1: + eventType = NS_MOUSE_MIDDLE_BUTTON_UP; + break; + case 2: + eventType = NS_MOUSE_RIGHT_BUTTON_UP; + break; + default: + NS_ASSERTION(0, "bad button type"); + return NS_OK; + } + result = DispatchMouseEvent(mouseEvent, eventType); + } + return result; +} + +nsresult +nsEnderEventListener::MouseClick(nsIDOMEvent* aEvent) +{ + nsCOMPtr<nsIDOMMouseEvent>mouseEvent; + mouseEvent = do_QueryInterface(aEvent); + if (!mouseEvent) { //non-mouse event passed in. bad things. + return NS_OK; + } + + nsresult result = NS_OK; + + if (mContent && mContext && mView) + { + // Dispatch the event + PRUint16 button; + mouseEvent->GetButton(&button); + PRInt32 eventType; + switch(button) + { + case 0: + eventType = NS_MOUSE_LEFT_CLICK; + break; + case 1: + eventType = NS_MOUSE_MIDDLE_CLICK; + break; + case 2: + eventType = NS_MOUSE_RIGHT_CLICK; + break; + default: + NS_ASSERTION(0, "bad button type"); + return NS_OK; + } + result = DispatchMouseEvent(mouseEvent, eventType); + } + return result; +} + +nsresult +nsEnderEventListener::MouseDblClick(nsIDOMEvent* aEvent) +{ + nsCOMPtr<nsIDOMMouseEvent>mouseEvent; + mouseEvent = do_QueryInterface(aEvent); + if (!mouseEvent) { //non-mouse event passed in. bad things. + return NS_OK; + } + + nsresult result = NS_OK; + + if (mContent && mContext && mView) + { + // Dispatch the event + PRUint16 button; + mouseEvent->GetButton(&button); + PRInt32 eventType; + switch(button) + { + case 0: + eventType = NS_MOUSE_LEFT_DOUBLECLICK; + break; + case 1: + eventType = NS_MOUSE_MIDDLE_DOUBLECLICK; + break; + case 2: + eventType = NS_MOUSE_RIGHT_DOUBLECLICK; + break; + default: + NS_ASSERTION(0, "bad button type"); + return NS_OK; + } + result = DispatchMouseEvent(mouseEvent, eventType); + } + + return result; +} + +nsresult +nsEnderEventListener::MouseOver(nsIDOMEvent* aEvent) +{ + /* + nsCOMPtr<nsIDOMMouseEvent>mouseEvent; + mouseEvent = do_QueryInterface(aEvent); + if (!mouseEvent) { //non-mouse event passed in. bad things. + return NS_OK; + } + + nsresult result = NS_OK; + + if (mContent && mContext && mView) + { + // XXX: Need to synthesize MouseEnter here + result = DispatchMouseEvent(mouseEvent, NS_MOUSE_MOVE); + } + + return result; + */ + return NS_OK; +} + +nsresult +nsEnderEventListener::MouseOut(nsIDOMEvent* aEvent) +{ + nsCOMPtr<nsIDOMMouseEvent>mouseEvent; + mouseEvent = do_QueryInterface(aEvent); + if (!mouseEvent) { //non-mouse event passed in. bad things. + return NS_OK; + } + + nsresult result = NS_OK; + + if (mContent && mContext && mView) + { + result = DispatchMouseEvent(mouseEvent, NS_MOUSE_EXIT); + } + + return result; +} + +/*=============== nsIFocusListener ======================*/ + +nsresult +nsEnderEventListener::Focus(nsIDOMEvent* aEvent) +{ + //Need to set text value for onchange + nsGfxTextControlFrame *gfxFrame = mFrame.Reference(); + + if (gfxFrame && mContent && mView) { + mTextValue.SetLength(0); + gfxFrame->GetText(&mTextValue, PR_FALSE); + } + + /* + // In this case, the focus has all ready been set because of the mouse down + // and setting it on the native widget causes an event to be dispatched + // and this listener then gets call. So we want to skip it here + // this is probably NOt need when native widgets are removed + if (mSkipFocusDispatch == PR_TRUE) { + return NS_OK; + } + + nsCOMPtr<nsIDOMUIEvent>uiEvent; + uiEvent = do_QueryInterface(aEvent); + if (!uiEvent) { + return NS_OK; + } + + nsresult result = NS_OK; + + nsGfxTextControlFrame *gfxFrame = mFrame.Reference(); + + // Here are notified that we received focus, this event + // may come as a result of JS or of the native Widget getting + // the focus set on it + // Check here to see if the GfxText was able to set focus, if it did + // the we want to skip this notification + // If this came from the DOM (and not the widget) then we DO + // want to do the notification + if (gfxFrame && mContent && mView && !gfxFrame->DidSetFocus()) + { + mTextValue = ""; + gfxFrame->GetText(&mTextValue, PR_FALSE); + // Dispatch the event + nsEventStatus status = nsEventStatus_eIgnore; + nsGUIEvent event; + event.eventStructType = NS_GUI_EVENT; + event.widget = nsnull; + event.message = NS_FOCUS_CONTENT; + event.flags = NS_EVENT_FLAG_INIT; + event.isShift = false; + event.isControl = false; + event.isAlt = false; + event.isMeta = false; + + nsIEventStateManager *manager=nsnull; + result = mContext->GetEventStateManager(&manager); + if (NS_SUCCEEDED(result) && manager) + { + //1. Give event to event manager for pre event state changes and generation of synthetic events. + result = manager->PreHandleEvent(mContext, &event, gfxFrame, &status, mView); + + //2. Give event to the DOM for third party and JS use. + if (NS_SUCCEEDED(result)) { + result = mContent->HandleDOMEvent(mContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); + } + + //3. In this case, the frame does no processing of the event + + //4. Give event to event manager for post event state changes and generation of synthetic events. + gfxFrame = mFrame.Reference(); // check for deletion + if (gfxFrame && NS_SUCCEEDED(result)) { + result = manager->PostHandleEvent(mContext, &event, gfxFrame, &status, mView); + } + NS_RELEASE(manager); + } + } +*/ + return NS_OK; +} + +nsresult +nsEnderEventListener::Blur(nsIDOMEvent* aEvent) +{ + // XXX We don't use aEvent, shouldn't matter what it is. + // In addition, EnterPressed calls Blur and passes null (Bug 18501) + // So, if we get a null, skip the QI for the time being. + if (aEvent) { + nsCOMPtr<nsIDOMUIEvent>uiEvent; + uiEvent = do_QueryInterface(aEvent); + if (!uiEvent) { + return NS_OK; + } + } + + nsGfxTextControlFrame *gfxFrame = mFrame.Reference(); + + if (gfxFrame && mContent && mView) { + nsString currentValue; + gfxFrame->GetText(&currentValue, PR_FALSE); + if (PR_FALSE==currentValue.Equals(mTextValue)) { + // Dispatch th1e change event + nsEventStatus status = nsEventStatus_eIgnore; + nsInputEvent event; + event.eventStructType = NS_INPUT_EVENT; + event.widget = nsnull; + event.message = NS_FORM_CHANGE; + event.flags = NS_EVENT_FLAG_INIT; + event.isShift = PR_FALSE; + event.isControl = PR_FALSE; + event.isAlt = PR_FALSE; + event.isMeta = PR_FALSE; + + // Have the content handle the event. + mContent->HandleDOMEvent(mContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); + } + } +/* + // XXX No longer dispatching event + // this notification has already taken place + // this causes two blur notifcations to be sent + // I removed this + // rods - 11/12/99 + // Dispatch the change event + nsEventStatus status = nsEventStatus_eIgnore; + nsGUIEvent event; + event.eventStructType = NS_GUI_EVENT; + event.widget = nsnull; + event.message = NS_BLUR_CONTENT; + event.flags = NS_EVENT_FLAG_INIT; + event.isShift = false; + event.isControl = false; + event.isAlt = false; + event.isMeta = false; + + gfxFrame->SetShouldSetFocus(); + + // Have the content handle the event. + mContent->HandleDOMEvent(mContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); + + } +*/ + return NS_OK; +} + +NS_IMETHODIMP +nsEnderEventListener::NotifySelectionChanged(nsIDOMDocument *, nsISelection *, short) +{ + nsGfxTextControlFrame *gfxFrame = mFrame.Reference(); + if (gfxFrame && mContent) + { + // Dispatch the event + nsEventStatus status = nsEventStatus_eIgnore; + nsGUIEvent event; + event.eventStructType = NS_GUI_EVENT; + event.widget = nsnull; + event.message = NS_FORM_SELECTED; + event.flags = NS_EVENT_FLAG_INIT; + + // Have the content handle the event. + mContent->HandleDOMEvent(mContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); + + // Now have the frame handle the event + gfxFrame->HandleEvent(mContext, &event, &status); + } + return NS_OK; +} + +NS_IMETHODIMP nsEnderEventListener::WillDo(nsITransactionManager *aManager, + nsITransaction *aTransaction, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsEnderEventListener::DidDo(nsITransactionManager *aManager, + nsITransaction *aTransaction, nsresult aDoResult) +{ + // we only need to update if the undo count is now 1 + nsGfxTextControlFrame *gfxFrame = mFrame.Reference(); + + if (gfxFrame) + { + PRInt32 undoCount; + aManager->GetNumberOfUndoItems(&undoCount); + if (undoCount == 1) + { + if (mFirstDoOfFirstUndo) + gfxFrame->UpdateTextControlCommands(NS_ConvertASCIItoUCS2("undo")); + + mFirstDoOfFirstUndo = PR_FALSE; + } + } + + return NS_OK; +} + +NS_IMETHODIMP nsEnderEventListener::WillUndo(nsITransactionManager *aManager, + nsITransaction *aTransaction, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsEnderEventListener::DidUndo(nsITransactionManager *aManager, + nsITransaction *aTransaction, nsresult aUndoResult) +{ + nsGfxTextControlFrame *gfxFrame = mFrame.Reference(); + if (gfxFrame) + { + PRInt32 undoCount; + aManager->GetNumberOfUndoItems(&undoCount); + if (undoCount == 0) + mFirstDoOfFirstUndo = PR_TRUE; // reset the state for the next do + + gfxFrame->UpdateTextControlCommands(NS_ConvertASCIItoUCS2("undo")); + } + + return NS_OK; +} + +NS_IMETHODIMP nsEnderEventListener::WillRedo(nsITransactionManager *aManager, + nsITransaction *aTransaction, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsEnderEventListener::DidRedo(nsITransactionManager *aManager, + nsITransaction *aTransaction, nsresult aRedoResult) +{ + nsGfxTextControlFrame *gfxFrame = mFrame.Reference(); + if (gfxFrame) + { + gfxFrame->UpdateTextControlCommands(NS_ConvertASCIItoUCS2("undo")); + } + + return NS_OK; +} + +NS_IMETHODIMP nsEnderEventListener::WillBeginBatch(nsITransactionManager *aManager, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsEnderEventListener::DidBeginBatch(nsITransactionManager *aManager, nsresult aResult) +{ + return NS_OK; +} + +NS_IMETHODIMP nsEnderEventListener::WillEndBatch(nsITransactionManager *aManager, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsEnderEventListener::DidEndBatch(nsITransactionManager *aManager, nsresult aResult) +{ + return NS_OK; +} + +NS_IMETHODIMP nsEnderEventListener::WillMerge(nsITransactionManager *aManager, + nsITransaction *aTopTransaction, nsITransaction *aTransactionToMerge, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsEnderEventListener::DidMerge(nsITransactionManager *aManager, + nsITransaction *aTopTransaction, nsITransaction *aTransactionToMerge, + PRBool aDidMerge, nsresult aMergeResult) +{ + return NS_OK; +} + +#ifdef XP_MAC +#pragma mark - +#endif + +/******************************************************************************* + * nsEnderFocusListenerForDisplayContent + ******************************************************************************/ + +NS_IMPL_ADDREF(nsEnderFocusListenerForDisplayContent); +NS_IMPL_RELEASE(nsEnderFocusListenerForDisplayContent); + +nsresult +nsEnderFocusListenerForDisplayContent::QueryInterface(const nsIID& aIID, + void** aInstancePtr) +{ + NS_PRECONDITION(nsnull != aInstancePtr, "null pointer"); + if (nsnull == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(NS_GET_IID(nsIDOMFocusListener))) { + *aInstancePtr = (void*) ((nsIDOMFocusListener*)this); + AddRef(); + return NS_OK; + } + if (aIID.Equals(kISupportsIID)) { + *aInstancePtr = (void*) ((nsISupports*)((nsIDOMFocusListener*)this)); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +nsEnderFocusListenerForDisplayContent::nsEnderFocusListenerForDisplayContent() : + mFrame(nsnull) +{ + NS_INIT_REFCNT(); +} + +nsEnderFocusListenerForDisplayContent::~nsEnderFocusListenerForDisplayContent() +{ +} + +nsresult +nsEnderFocusListenerForDisplayContent::HandleEvent(nsIDOMEvent* aEvent) +{ + return NS_OK; +} + + +nsresult +nsEnderFocusListenerForDisplayContent::Focus(nsIDOMEvent* aEvent) +{ + if (mFrame) + { + mFrame->CreateSubDoc(nsnull); + } + return NS_OK; +} + +nsresult +nsEnderFocusListenerForDisplayContent::Blur (nsIDOMEvent* aEvent) +{ + return NS_OK; +} + + +NS_IMETHODIMP +nsEnderFocusListenerForDisplayContent::SetFrame(nsGfxTextControlFrame *aFrame) +{ + mFrame = aFrame; // frames are not ref counted + return NS_OK; +} + +#ifdef XP_MAC +#pragma mark - +#endif + +/******************************************************************************* + * EnderTempObserver + ******************************************************************************/ +// XXX temp implementation + +NS_IMPL_ADDREF(EnderTempObserver); +NS_IMPL_RELEASE(EnderTempObserver); + +EnderTempObserver::EnderTempObserver() +{ + NS_INIT_REFCNT(); + mFirstCall = PR_TRUE; +} + +EnderTempObserver::~EnderTempObserver() +{ +} + +nsresult +EnderTempObserver::QueryInterface(const nsIID& aIID, + void** aInstancePtr) +{ + NS_PRECONDITION(nsnull != aInstancePtr, "null pointer"); + if (nsnull == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(NS_GET_IID(nsIDocumentLoaderObserver))) { + *aInstancePtr = (void*) ((nsIDocumentLoaderObserver*)this); + AddRef(); + return NS_OK; + } + if (aIID.Equals(kISupportsIID)) { + *aInstancePtr = (void*) ((nsISupports*)((nsIDocumentLoaderObserver*)this)); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + + +// document loader observer implementation +NS_IMETHODIMP +EnderTempObserver::OnStartDocumentLoad(nsIDocumentLoader* loader, + nsIURI* aURL, + const char* aCommand) +{ + return NS_OK; +} + +NS_IMETHODIMP +EnderTempObserver::OnEndDocumentLoad(nsIDocumentLoader* loader, + nsIChannel* channel, + nsresult aStatus) +{ + if (PR_TRUE==mFirstCall) + { + mFirstCall = PR_FALSE; + if (mFrame) { + mFrame->InstallEditor(); + } + } + return NS_OK; +} + +NS_IMETHODIMP +EnderTempObserver::OnStartURLLoad(nsIDocumentLoader* loader, + nsIChannel* channel) +{ + return NS_OK; +} + +NS_IMETHODIMP +EnderTempObserver::OnProgressURLLoad(nsIDocumentLoader* loader, + nsIChannel* channel, + PRUint32 aProgress, + PRUint32 aProgressMax) +{ + return NS_OK; +} + +NS_IMETHODIMP +EnderTempObserver::OnStatusURLLoad(nsIDocumentLoader* loader, + nsIChannel* channel, + nsString& aMsg) +{ + return NS_OK; +} + +NS_IMETHODIMP +EnderTempObserver::OnEndURLLoad(nsIDocumentLoader* loader, + nsIChannel* channel, + nsresult aStatus) +{ + return NS_OK; +} + + +NS_IMETHODIMP +EnderTempObserver::SetFrame(nsGfxTextControlFrame *aFrame) +{ + mFrame = aFrame; + return NS_OK; +} + + +#ifdef XP_MAC +#pragma mark - +#endif + +/******************************************************************************* + * nsEnderListenerForContent + ******************************************************************************/ + +NS_IMPL_ADDREF(nsEnderListenerForContent); +NS_IMPL_RELEASE(nsEnderListenerForContent); + +nsresult +nsEnderListenerForContent::QueryInterface(const nsIID& aIID, + void** aInstancePtr) +{ + NS_PRECONDITION(nsnull != aInstancePtr, "null pointer"); + if (nsnull == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(NS_GET_IID(nsIDOMMouseListener))) { + *aInstancePtr = (void*) ((nsIDOMMouseListener*)this); + AddRef(); + return NS_OK; + } + if (aIID.Equals(NS_GET_IID(nsIDOMDragListener))) { + *aInstancePtr = (void*) ((nsIDOMDragListener*)this); + AddRef(); + return NS_OK; + } + if (aIID.Equals(kISupportsIID)) { + *aInstancePtr = (void*) ((nsISupports*)((nsIDOMFocusListener*)this)); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +nsEnderListenerForContent::nsEnderListenerForContent() : + mFrame(nsnull) +{ + NS_INIT_REFCNT(); +} + +nsEnderListenerForContent::~nsEnderListenerForContent() +{ +} + +nsresult +nsEnderListenerForContent::HandleEvent(nsIDOMEvent* aEvent) +{ + return NS_OK; +} + +/* XXX: + drag events should be forwarded to the editor's own drag event listener? +*/ + +nsresult +nsEnderListenerForContent::DragGesture(nsIDOMEvent* aDragEvent) +{ + //printf("frame forContent DragGesture\n"); + // ...figure out if a drag should be started... + + // ...until we have this implemented, just eat the drag event so it + // ...doesn't leak out into the rest of the app/handlers. + aDragEvent->PreventBubble(); + + return NS_OK; +} + + +nsresult +nsEnderListenerForContent::DragEnter(nsIDOMEvent* aDragEvent) +{ + //printf("frame forContent DragEnter\n"); + // see nsTextEditorDragListener + return NS_OK; +} + + +nsresult +nsEnderListenerForContent::DragOver(nsIDOMEvent* aDragEvent) +{ + //printf("frame forContent DragOver\n"); + // see nsTextEditorDragListener + return NS_OK; +} + + +nsresult +nsEnderListenerForContent::DragExit(nsIDOMEvent* aDragEvent) +{ + //printf("frame forContent DragExit\n"); + // see nsTextEditorDragListener + return NS_OK; +} + + + +nsresult +nsEnderListenerForContent::DragDrop(nsIDOMEvent* aMouseEvent) +{ + //printf("frame forContent DragDrop\n"); + // see nsTextEditorDragListener + return NS_OK; +} + +NS_IMETHODIMP +nsEnderListenerForContent::SetFrame(nsGfxTextControlFrame *aFrame) +{ + mFrame = aFrame; // frames are not ref counted + return NS_OK; +} + +#endif diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp index 952875dc6f0..801086ed344 100644 --- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -33,6 +33,7 @@ #include "nsIStyleRule.h" #include "nsIFrame.h" #include "nsIStyleContext.h" +#include "nsIMutableStyleContext.h" #include "nsHTMLAtoms.h" #include "nsIPresContext.h" #include "nsILinkHandler.h" @@ -1516,9 +1517,7 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShe if (display->mDisplay != displayValue) { // Reset the value - nsStyleDisplay* mutableDisplay = (nsStyleDisplay*) - pseudoStyleContext->GetMutableStyleData(eStyleStruct_Display); - + nsMutableStyleDisplay mutableDisplay(pseudoStyleContext); mutableDisplay->mDisplay = displayValue; } @@ -1528,9 +1527,7 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShe (const nsStylePosition*)pseudoStyleContext->GetStyleData(eStyleStruct_Position); if (NS_STYLE_POSITION_NORMAL != stylePosition->mPosition) { // Reset the value - nsStylePosition* mutablePosition = (nsStylePosition*) - pseudoStyleContext->GetMutableStyleData(eStyleStruct_Position); - + nsMutableStylePosition mutablePosition(pseudoStyleContext); mutablePosition->mPosition = NS_STYLE_POSITION_NORMAL; } @@ -2513,7 +2510,7 @@ void FixUpOuterTableFloat(nsIStyleContext* aOuterSC, nsIStyleContext* aInnerSC) { - nsStyleDisplay* outerStyleDisplay = (nsStyleDisplay*)aOuterSC->GetMutableStyleData(eStyleStruct_Display); + nsMutableStyleDisplay outerStyleDisplay(aOuterSC); nsStyleDisplay* innerStyleDisplay = (nsStyleDisplay*)aInnerSC->GetStyleData(eStyleStruct_Display); if (outerStyleDisplay->mFloats != innerStyleDisplay->mFloats) { outerStyleDisplay->mFloats = innerStyleDisplay->mFloats; @@ -3279,24 +3276,25 @@ PropagateBackgroundToParent(nsIStyleContext* aStyleContext, const nsStyleColor* aColor, nsIStyleContext* aParentStyleContext) { - nsStyleColor* mutableColor; - mutableColor = (nsStyleColor*)aParentStyleContext->GetMutableStyleData(eStyleStruct_Color); - - mutableColor->mBackgroundAttachment = aColor->mBackgroundAttachment; - mutableColor->mBackgroundFlags = aColor->mBackgroundFlags | NS_STYLE_BG_PROPAGATED_FROM_CHILD; - mutableColor->mBackgroundRepeat = aColor->mBackgroundRepeat; - mutableColor->mBackgroundColor = aColor->mBackgroundColor; - mutableColor->mBackgroundXPosition = aColor->mBackgroundXPosition; - mutableColor->mBackgroundYPosition = aColor->mBackgroundYPosition; - mutableColor->mBackgroundImage = aColor->mBackgroundImage; - + { + nsMutableStyleColor mutableColor(aParentStyleContext); + mutableColor->mBackgroundAttachment = aColor->mBackgroundAttachment; + mutableColor->mBackgroundFlags = aColor->mBackgroundFlags | NS_STYLE_BG_PROPAGATED_FROM_CHILD; + mutableColor->mBackgroundRepeat = aColor->mBackgroundRepeat; + mutableColor->mBackgroundColor = aColor->mBackgroundColor; + mutableColor->mBackgroundXPosition = aColor->mBackgroundXPosition; + mutableColor->mBackgroundYPosition = aColor->mBackgroundYPosition; + mutableColor->mBackgroundImage = aColor->mBackgroundImage; + } // Reset the BODY's background to transparent - mutableColor = (nsStyleColor*)aStyleContext->GetMutableStyleData(eStyleStruct_Color); - mutableColor->mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | - NS_STYLE_BG_IMAGE_NONE | - NS_STYLE_BG_PROPAGATED_TO_PARENT; - mutableColor->mBackgroundImage.SetLength(0); - mutableColor->mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; + { + nsMutableStyleColor mutableColor(aStyleContext); + mutableColor->mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | + NS_STYLE_BG_IMAGE_NONE | + NS_STYLE_BG_PROPAGATED_TO_PARENT; + mutableColor->mBackgroundImage.SetLength(0); + mutableColor->mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; + } } /** @@ -3484,7 +3482,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell, // Since we always create a block frame, we need to make sure that the // style context's display type is block level. - nsStyleDisplay* disp = (nsStyleDisplay*)styleContext->GetMutableStyleData(eStyleStruct_Display); + nsMutableStyleDisplay disp(styleContext); disp->mDisplay = NS_STYLE_DISPLAY_BLOCK; } @@ -3687,7 +3685,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell, getter_AddRefs(viewportPseudoStyle)); { // ensure that the viewport thinks it is a block frame, layout goes pootsy if it doesn't - nsStyleDisplay* display = (nsStyleDisplay*)viewportPseudoStyle->GetMutableStyleData(eStyleStruct_Display); + nsMutableStyleDisplay display(viewportPseudoStyle); display->mDisplay = NS_STYLE_DISPLAY_BLOCK; } @@ -4886,7 +4884,7 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresShell* aPresShell, } if (allowSubframes) { // make <noframes> be display:none if frames are enabled - nsStyleDisplay* display = (nsStyleDisplay*)aStyleContext->GetMutableStyleData(eStyleStruct_Display); + nsMutableStyleDisplay display(aStyleContext); display->mDisplay = NS_STYLE_DISPLAY_NONE; aState.mFrameManager->SetUndisplayedContent(aContent, aStyleContext); } diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp index a74203acb0a..454052b9b8c 100644 --- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp @@ -26,6 +26,7 @@ #include "nsTableFrame.h" #include "nsIReflowCommand.h" #include "nsIStyleContext.h" +#include "nsIMutableStyleContext.h" #include "nsStyleConsts.h" #include "nsIPresContext.h" #include "nsIRenderingContext.h" @@ -868,6 +869,7 @@ void nsTableCellFrame::MapHTMLBorderStyle(nsIPresContext* aPresContext, /* The RULES code below has been disabled because collapsing borders have been disabled and RULES depend on collapsing borders + NOTE: The place where this function was called has been disabled too. const nsStyleTable* tableStyle; aTableFrame->GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle); @@ -930,30 +932,37 @@ void nsTableCellFrame::MapBorderPadding(nsIPresContext* aPresContext) tableFrame->GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle); const nsStylePadding* tablePaddingStyle; tableFrame->GetStyleData(eStyleStruct_Padding,(const nsStyleStruct *&)tablePaddingStyle); - nsStylePadding* paddingData = (nsStylePadding*)mStyleContext->GetMutableStyleData(eStyleStruct_Padding); + { + nsMutableStylePadding paddingData(mStyleContext); - float p2t; - aPresContext->GetPixelsToTwips(&p2t); + float p2t; + aPresContext->GetPixelsToTwips(&p2t); - // Get the table's cellpadding or use 2 pixels as the default if it is not set. - // This assumes that ua.css does not set padding for the cell. - nscoord defaultPadding = tableFrame->GetCellPadding(); - if (-1 == defaultPadding) { // not set in table - defaultPadding = NSIntPixelsToTwips(1, p2t); + // Get the table's cellpadding or use 2 pixels as the default if it is not set. + // This assumes that ua.css does not set padding for the cell. + nscoord defaultPadding = tableFrame->GetCellPadding(); + if (-1 == defaultPadding) { // not set in table + defaultPadding = NSIntPixelsToTwips(1, p2t); + } + + // if the padding is not already set, set it to the table's cellpadding + if (eStyleUnit_Null == paddingData->mPadding.GetTopUnit()) + paddingData->mPadding.SetTop(defaultPadding); + if (eStyleUnit_Null == paddingData->mPadding.GetRightUnit()) + paddingData->mPadding.SetRight(defaultPadding); + if (eStyleUnit_Null == paddingData->mPadding.GetBottomUnit()) + paddingData->mPadding.SetBottom(defaultPadding); + if (eStyleUnit_Null == paddingData->mPadding.GetLeftUnit()) + paddingData->mPadding.SetLeft(defaultPadding); } + /* MapHTMLBorderStyle() has been disabled because collapsing borders have been disabled + and the rules in MapHTMLBorderStyle() depend on collapsing borders - // if the padding is not already set, set it to the table's cellpadding - if (eStyleUnit_Null == paddingData->mPadding.GetTopUnit()) - paddingData->mPadding.SetTop(defaultPadding); - if (eStyleUnit_Null == paddingData->mPadding.GetRightUnit()) - paddingData->mPadding.SetRight(defaultPadding); - if (eStyleUnit_Null == paddingData->mPadding.GetBottomUnit()) - paddingData->mPadding.SetBottom(defaultPadding); - if (eStyleUnit_Null == paddingData->mPadding.GetLeftUnit()) - paddingData->mPadding.SetLeft(defaultPadding); - - nsStyleBorder* borderData = (nsStyleBorder*)mStyleContext->GetMutableStyleData(eStyleStruct_Border); - MapHTMLBorderStyle(aPresContext, *borderData, tableFrame); + { + nsMutableStyleBorder borderData(mStyleContext); + MapHTMLBorderStyle(aPresContext, *borderData, tableFrame); + } + */ MapVAlignAttribute(aPresContext, tableFrame); MapHAlignAttribute(aPresContext, tableFrame); @@ -980,14 +989,14 @@ void nsTableCellFrame::MapVAlignAttribute(nsIPresContext* aPresContext, nsTableF const nsStyleText* colTextStyle; colFrame->GetStyleData(eStyleStruct_Text,(const nsStyleStruct *&)colTextStyle); if (colTextStyle->mVerticalAlign.GetUnit() == eStyleUnit_Enumerated) { - nsStyleText* cellTextStyle = (nsStyleText*)mStyleContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText cellTextStyle(mStyleContext); cellTextStyle->mVerticalAlign.SetIntValue(colTextStyle->mVerticalAlign.GetIntValue(), eStyleUnit_Enumerated); return; // valign set from COL info } } // otherwise, set the vertical align attribute to the HTML default - nsStyleText* cellTextStyle = (nsStyleText*)mStyleContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText cellTextStyle(mStyleContext); cellTextStyle->mVerticalAlign.SetIntValue(NS_STYLE_VERTICAL_ALIGN_MIDDLE, eStyleUnit_Enumerated); } @@ -1012,7 +1021,7 @@ void nsTableCellFrame::MapHAlignAttribute(nsIPresContext* aPresContext, const nsStyleText* rowTextStyle; rowFrame->GetStyleData(eStyleStruct_Text,(const nsStyleStruct *&)rowTextStyle); if (NS_STYLE_TEXT_ALIGN_DEFAULT != rowTextStyle->mTextAlign) { - nsStyleText* cellTextStyle = (nsStyleText*)mStyleContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText cellTextStyle(mStyleContext); cellTextStyle->mTextAlign = rowTextStyle->mTextAlign; return; // halign set from ROW info } @@ -1025,18 +1034,18 @@ void nsTableCellFrame::MapHAlignAttribute(nsIPresContext* aPresContext, const nsStyleText* colTextStyle; colFrame->GetStyleData(eStyleStruct_Text,(const nsStyleStruct *&)colTextStyle); if (NS_STYLE_TEXT_ALIGN_DEFAULT != colTextStyle->mTextAlign) { - nsStyleText* cellTextStyle = (nsStyleText*)mStyleContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText cellTextStyle(mStyleContext); cellTextStyle->mTextAlign = colTextStyle->mTextAlign; return; // halign set from COL info } } // otherwise, set the text align to the HTML default (center for TH, left for TD) - nsStyleText* cellTextStyle = (nsStyleText*)mStyleContext->GetMutableStyleData(eStyleStruct_Text); nsIAtom* tag; if (mContent) { mContent->GetTag(tag); if (tag) { + nsMutableStyleText cellTextStyle(mStyleContext); cellTextStyle->mTextAlign = (nsHTMLAtoms::th == tag) ? NS_STYLE_TEXT_ALIGN_CENTER : NS_STYLE_TEXT_ALIGN_LEFT; diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index d42d9b01998..cd0b9a1721c 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -26,6 +26,7 @@ #include "nsTableBorderCollapser.h" #include "nsIRenderingContext.h" #include "nsIStyleContext.h" +#include "nsIMutableStyleContext.h" #include "nsStyleConsts.h" #include "nsIContent.h" #include "nsCellMap.h" @@ -668,16 +669,18 @@ void nsTableFrame::ProcessGroupRules(nsIPresContext* aPresContext) if (originates) { nsCOMPtr<nsIStyleContext> styleContext; cell->GetStyleContext(getter_AddRefs(styleContext)); - nsStyleBorder* border = (nsStyleBorder*)styleContext->GetMutableStyleData(eStyleStruct_Border); - if (rowX == startRow) { - border->SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE); - } - else if (rowX == endRow) { - border->SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE); - } - else { - border->SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE); - border->SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE); + { + nsMutableStyleBorder border(styleContext); + if (rowX == startRow) { + border->SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE); + } + else if (rowX == endRow) { + border->SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE); + } + else { + border->SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE); + border->SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE); + } } styleContext->RecalcAutomaticData(aPresContext); } @@ -3707,7 +3710,7 @@ void nsTableFrame::MapBorderMarginPadding(nsIPresContext* aPresContext) if (!table) return; - nsStyleBorder* borderData = (nsStyleBorder*)mStyleContext->GetMutableStyleData(eStyleStruct_Border); + nsMutableStyleBorder borderData(mStyleContext); border_result = table->GetAttribute(nsHTMLAtoms::border,border_value); if (border_result == NS_CONTENT_ATTR_HAS_VALUE) diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp index 36c09cbd098..4134ed42502 100644 --- a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp @@ -24,6 +24,7 @@ #include "nsTableFrame.h" #include "nsIReflowCommand.h" #include "nsIStyleContext.h" +#include "nsIMutableStyleContext.h" #include "nsStyleConsts.h" #include "nsIPresContext.h" #include "nsIRenderingContext.h" @@ -153,19 +154,20 @@ nsTableOuterFrame::AdjustZeroWidth() { // a 0 width table becomes auto PRBool makeAuto = PR_FALSE; - nsStylePosition* position = (nsStylePosition*)mStyleContext->GetMutableStyleData(eStyleStruct_Position); - if (position->mWidth.GetUnit() == eStyleUnit_Coord) { - if (0 >= position->mWidth.GetCoordValue()) { + nsStylePosition* posData = (nsStylePosition*)mStyleContext->GetStyleData(eStyleStruct_Position); + if (posData->mWidth.GetUnit() == eStyleUnit_Coord) { + if (0 >= posData->mWidth.GetCoordValue()) { makeAuto= PR_TRUE; } } - else if (position->mWidth.GetUnit() == eStyleUnit_Percent) { - if (0.0f >= position->mWidth.GetPercentValue()) { + else if (posData->mWidth.GetUnit() == eStyleUnit_Percent) { + if (0.0f >= posData->mWidth.GetPercentValue()) { makeAuto= PR_TRUE; } } if (makeAuto) { + nsMutableStylePosition position(mStyleContext); position->mWidth = nsStyleCoord(eStyleUnit_Auto); } return NS_OK; diff --git a/mozilla/layout/style/nsCSSStyleRule.cpp b/mozilla/layout/style/nsCSSStyleRule.cpp index 111647eacf6..bfa54c6be5e 100644 --- a/mozilla/layout/style/nsCSSStyleRule.cpp +++ b/mozilla/layout/style/nsCSSStyleRule.cpp @@ -1790,7 +1790,7 @@ CSSStyleRuleImpl::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* return NS_OK; } -nsString& Unquote(nsString& aString) +static nsString& Unquote(nsString& aString) { PRUnichar start = aString.First(); PRUnichar end = aString.Last(); @@ -1811,8 +1811,8 @@ MapDeclarationFontInto(nsICSSDeclaration* aDeclaration, { if (nsnull != aDeclaration) { nsIStyleContext* parentContext = aContext->GetParent(); - nsStyleFont* font = (nsStyleFont*)aContext->GetMutableStyleData(eStyleStruct_Font); - const nsStyleFont* parentFont = font; + nsMutableStyleFont font(aContext); + const nsStyleFont* parentFont = font.get(); if (nsnull != parentContext) { parentFont = (const nsStyleFont*)parentContext->GetStyleData(eStyleStruct_Font); } @@ -2104,8 +2104,8 @@ MapDeclarationTextInto(nsICSSDeclaration* aDeclaration, if (NS_OK == aDeclaration->GetData(kCSSTextSID, (nsCSSStruct**)&ourText)) { if (nsnull != ourText) { // Get our text style and our parent's text style - nsStyleText* text = (nsStyleText*) aContext->GetMutableStyleData(eStyleStruct_Text); - const nsStyleText* parentText = text; + nsMutableStyleText text(aContext); + const nsStyleText* parentText = text.get(); if (nsnull != aParentContext) { parentText = (const nsStyleText*)aParentContext->GetStyleData(eStyleStruct_Text); } @@ -2209,10 +2209,8 @@ MapDeclarationDisplayInto(nsICSSDeclaration* aDeclaration, if (NS_OK == aDeclaration->GetData(kCSSDisplaySID, (nsCSSStruct**)&ourDisplay)) { if (nsnull != ourDisplay) { // Get our style and our parent's style - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); - - const nsStyleDisplay* parentDisplay = display; + nsMutableStyleDisplay display(aContext); + const nsStyleDisplay* parentDisplay = display.get(); if (nsnull != aParentContext) { parentDisplay = (const nsStyleDisplay*)aParentContext->GetStyleData(eStyleStruct_Display); } @@ -2349,9 +2347,8 @@ MapDeclarationColorInto(nsICSSDeclaration* aDeclaration, nsCSSColor* ourColor; if (NS_OK == aDeclaration->GetData(kCSSColorSID, (nsCSSStruct**)&ourColor)) { if (nsnull != ourColor) { - nsStyleColor* color = (nsStyleColor*)aContext->GetMutableStyleData(eStyleStruct_Color); - - const nsStyleColor* parentColor = color; + nsMutableStyleColor color(aContext); + const nsStyleColor* parentColor = color.get(); if (nsnull != aParentContext) { parentColor = (const nsStyleColor*)aParentContext->GetStyleData(eStyleStruct_Color); } @@ -2520,15 +2517,15 @@ MapDeclarationMarginInto(nsICSSDeclaration* aDeclaration, nsCSSMargin* ourMargin; if (NS_OK == aDeclaration->GetData(kCSSMarginSID, (nsCSSStruct**)&ourMargin)) { if (nsnull != ourMargin) { - nsStyleMargin* margin = (nsStyleMargin*)aContext->GetMutableStyleData(eStyleStruct_Margin); - nsStylePadding* padding = (nsStylePadding*)aContext->GetMutableStyleData(eStyleStruct_Padding); - nsStyleBorder* border = (nsStyleBorder*)aContext->GetMutableStyleData(eStyleStruct_Border); - nsStyleOutline* outline = (nsStyleOutline*)aContext->GetMutableStyleData(eStyleStruct_Outline); + nsMutableStyleMargin margin(aContext); + nsMutableStylePadding padding(aContext); + nsMutableStyleBorder border(aContext); + nsMutableStyleOutline outline(aContext); - const nsStyleMargin* parentMargin = margin; - const nsStylePadding* parentPadding = padding; - const nsStyleBorder* parentBorder = border; - const nsStyleOutline* parentOutline = outline; + const nsStyleMargin* parentMargin = margin.get(); + const nsStylePadding* parentPadding = padding.get(); + const nsStyleBorder* parentBorder = border.get(); + const nsStyleOutline* parentOutline = outline.get(); if (nsnull != aParentContext) { parentMargin = (const nsStyleMargin*)aParentContext->GetStyleData(eStyleStruct_Margin); parentPadding = (const nsStylePadding*)aParentContext->GetStyleData(eStyleStruct_Padding); @@ -2853,9 +2850,8 @@ MapDeclarationPositionInto(nsICSSDeclaration* aDeclaration, nsCSSPosition* ourPosition; if (NS_OK == aDeclaration->GetData(kCSSPositionSID, (nsCSSStruct**)&ourPosition)) { if (nsnull != ourPosition) { - nsStylePosition* position = (nsStylePosition*)aContext->GetMutableStyleData(eStyleStruct_Position); - - const nsStylePosition* parentPosition = position; + nsMutableStylePosition position(aContext); + const nsStylePosition* parentPosition = position.get(); if (nsnull != aParentContext) { parentPosition = (const nsStylePosition*)aParentContext->GetStyleData(eStyleStruct_Position); } @@ -2940,9 +2936,8 @@ MapDeclarationListInto(nsICSSDeclaration* aDeclaration, nsCSSList* ourList; if (NS_OK == aDeclaration->GetData(kCSSListSID, (nsCSSStruct**)&ourList)) { if (nsnull != ourList) { - nsStyleList* list = (nsStyleList*)aContext->GetMutableStyleData(eStyleStruct_List); - - const nsStyleList* parentList = list; + nsMutableStyleList list(aContext); + const nsStyleList* parentList = list.get(); if (nsnull != aParentContext) { parentList = (const nsStyleList*)aParentContext->GetStyleData(eStyleStruct_List); } @@ -2988,9 +2983,8 @@ MapDeclarationTableInto(nsICSSDeclaration* aDeclaration, nsCSSTable* ourTable; if (NS_OK == aDeclaration->GetData(kCSSTableSID, (nsCSSStruct**)&ourTable)) { if (nsnull != ourTable) { - nsStyleTable* table = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); - - const nsStyleTable* parentTable = table; + nsMutableStyleTable table(aContext); + const nsStyleTable* parentTable = table.get(); if (nsnull != aParentContext) { parentTable = (const nsStyleTable*)aParentContext->GetStyleData(eStyleStruct_Table); } @@ -3057,9 +3051,8 @@ MapDeclarationContentInto(nsICSSDeclaration* aDeclaration, nsCSSContent* ourContent; if (NS_OK == aDeclaration->GetData(kCSSContentSID, (nsCSSStruct**)&ourContent)) { if (ourContent) { - nsStyleContent* content = (nsStyleContent*)aContext->GetMutableStyleData(eStyleStruct_Content); - - const nsStyleContent* parentContent = content; + nsMutableStyleContent content(aContext); + const nsStyleContent* parentContent = content.get(); if (nsnull != aParentContext) { parentContent = (const nsStyleContent*)aParentContext->GetStyleData(eStyleStruct_Content); } @@ -3265,8 +3258,8 @@ MapDeclarationUIInto(nsICSSDeclaration* aDeclaration, if (NS_OK == aDeclaration->GetData(kCSSUserInterfaceSID, (nsCSSStruct**)&ourUI)) { if (nsnull != ourUI) { // Get our user interface style and our parent's user interface style - nsStyleUserInterface* ui = (nsStyleUserInterface*) aContext->GetMutableStyleData(eStyleStruct_UserInterface); - const nsStyleUserInterface* parentUI = ui; + nsMutableStyleUserInterface ui(aContext); + const nsStyleUserInterface* parentUI = ui.get(); if (nsnull != aParentContext) { parentUI = (const nsStyleUserInterface*)aParentContext->GetStyleData(eStyleStruct_UserInterface); } @@ -3367,8 +3360,8 @@ MapDeclarationPrintInto(nsICSSDeclaration* aDeclaration, nsIMutableStyleContext* aContext, nsIStyleContext* aParentContext, nsStyleFont* aFont, nsIPresContext* aPresContext) { - nsStylePrint* print = (nsStylePrint*)aContext->GetMutableStyleData(eStyleStruct_Print); - const nsStylePrint* parentPrint = print; + nsMutableStylePrint print(aContext); + const nsStylePrint* parentPrint = print.get(); if (nsnull != aParentContext) { parentPrint = (const nsStylePrint*)aParentContext->GetStyleData(eStyleStruct_Print); } @@ -3456,9 +3449,8 @@ MapDeclarationXULInto(nsICSSDeclaration* aDeclaration, nsCSSXUL* ourXUL; if (NS_OK == aDeclaration->GetData(kCSSXULSID, (nsCSSStruct**)&ourXUL)) { if (nsnull != ourXUL) { - nsStyleXUL* xul = (nsStyleXUL*)aContext->GetMutableStyleData(eStyleStruct_XUL); - - const nsStyleXUL* parentXUL = xul; + nsMutableStyleXUL xul(aContext); + const nsStyleXUL* parentXUL = xul.get(); if (nsnull != aParentContext) { parentXUL = (const nsStyleXUL*)aParentContext->GetStyleData(eStyleStruct_XUL); } @@ -3480,7 +3472,8 @@ void MapDeclarationInto(nsICSSDeclaration* aDeclaration, { if (nsnull != aDeclaration) { nsIStyleContext* parentContext = aContext->GetParent(); - nsStyleFont* font = (nsStyleFont*)aContext->GetMutableStyleData(eStyleStruct_Font); + nsMutableStyleFont mutableFont(aContext); + nsStyleFont* font = mutableFont.get(); MapDeclarationTextInto(aDeclaration, aContext, parentContext, font, aPresContext); MapDeclarationDisplayInto(aDeclaration, aContext, parentContext, font, aPresContext); diff --git a/mozilla/layout/style/nsHTMLCSSStyleSheet.cpp b/mozilla/layout/style/nsHTMLCSSStyleSheet.cpp index 2832bb9280b..da6c0468317 100644 --- a/mozilla/layout/style/nsHTMLCSSStyleSheet.cpp +++ b/mozilla/layout/style/nsHTMLCSSStyleSheet.cpp @@ -132,44 +132,38 @@ CSSFirstLineRule::MapStyleInto(nsIMutableStyleContext* aContext, parentContext = aContext->GetParent(); // Disable border - nsStyleBorder* border = (nsStyleBorder*) - aContext->GetMutableStyleData(eStyleStruct_Border); - if (border) { - border->SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE); - border->SetBorderStyle(NS_SIDE_RIGHT, NS_STYLE_BORDER_STYLE_NONE); - border->SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE); - border->SetBorderStyle(NS_SIDE_LEFT, NS_STYLE_BORDER_STYLE_NONE); - } + nsMutableStyleBorder border(aContext); + border->SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE); + border->SetBorderStyle(NS_SIDE_RIGHT, NS_STYLE_BORDER_STYLE_NONE); + border->SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE); + border->SetBorderStyle(NS_SIDE_LEFT, NS_STYLE_BORDER_STYLE_NONE); // Undo any change made to "direction" - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); if (parentContext) { const nsStyleDisplay* parentDisplay = (const nsStyleDisplay*) parentContext->GetStyleData(eStyleStruct_Display); if (parentDisplay) { + nsMutableStyleDisplay display(aContext); display->mDirection = parentDisplay->mDirection; } } // Undo any change made to "cursor" - nsStyleColor* color = (nsStyleColor*) - aContext->GetMutableStyleData(eStyleStruct_Color); if (parentContext) { const nsStyleColor* parentColor = (const nsStyleColor*) parentContext->GetStyleData(eStyleStruct_Color); if (parentColor) { + nsMutableStyleColor color(aContext); color->mCursor = parentColor->mCursor; } } // Undo any change to quotes - nsStyleContent* content = (nsStyleContent*) - aContext->GetMutableStyleData(eStyleStruct_Content); if (parentContext) { const nsStyleContent* parentContent = (const nsStyleContent*) parentContext->GetStyleData(eStyleStruct_Content); if (parentContent) { + nsMutableStyleContent content(aContext); nsAutoString open, close; PRUint32 i, n = parentContent->QuotesCount(); content->AllocateQuotes(n); @@ -261,34 +255,31 @@ CSSFirstLetterRule::MapStyleInto(nsIMutableStyleContext* aContext, parentContext = aContext->GetParent(); // Undo any change made to "direction" - nsStyleDisplay* display = (nsStyleDisplay*) - aContext->GetMutableStyleData(eStyleStruct_Display); if (parentContext) { const nsStyleDisplay* parentDisplay = (const nsStyleDisplay*) parentContext->GetStyleData(eStyleStruct_Display); if (parentDisplay) { + nsMutableStyleDisplay display(aContext); display->mDirection = parentDisplay->mDirection; } } // Undo any change made to "cursor" - nsStyleColor* color = (nsStyleColor*) - aContext->GetMutableStyleData(eStyleStruct_Color); if (parentContext) { const nsStyleColor* parentColor = (const nsStyleColor*) parentContext->GetStyleData(eStyleStruct_Color); if (parentColor) { + nsMutableStyleColor color(aContext); color->mCursor = parentColor->mCursor; } } // Undo any change to quotes - nsStyleContent* content = (nsStyleContent*) - aContext->GetMutableStyleData(eStyleStruct_Content); if (parentContext) { const nsStyleContent* parentContent = (const nsStyleContent*) parentContext->GetStyleData(eStyleStruct_Content); if (parentContent) { + nsMutableStyleContent content(aContext); nsAutoString open, close; PRUint32 i, n = parentContent->QuotesCount(); content->AllocateQuotes(n); diff --git a/mozilla/layout/style/nsHTMLStyleSheet.cpp b/mozilla/layout/style/nsHTMLStyleSheet.cpp index e5a7c9f8cc1..0328711047b 100644 --- a/mozilla/layout/style/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/style/nsHTMLStyleSheet.cpp @@ -156,11 +156,8 @@ HTMLColorRule::MapFontStyleInto(nsIMutableStyleContext* aContext, nsIPresContext NS_IMETHODIMP HTMLColorRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext) { - nsStyleColor* styleColor = (nsStyleColor*)(aContext->GetMutableStyleData(eStyleStruct_Color)); - - if (nsnull != styleColor) { - styleColor->mColor = mColor; - } + nsMutableStyleColor styleColor(aContext); + styleColor->mColor = mColor; return NS_OK; } @@ -222,16 +219,13 @@ HTMLDocumentColorRule::~HTMLDocumentColorRule() NS_IMETHODIMP HTMLDocumentColorRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext) { - nsStyleColor* styleColor = (nsStyleColor*)(aContext->GetMutableStyleData(eStyleStruct_Color)); - - if (nsnull != styleColor) { - if (mForegroundSet) { - styleColor->mColor = mColor; - } - if (mBackgroundSet) { - styleColor->mBackgroundColor = mBackgroundColor; - styleColor->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; - } + nsMutableStyleColor styleColor(aContext); + if (mForegroundSet) { + styleColor->mColor = mColor; + } + if (mBackgroundSet) { + styleColor->mBackgroundColor = mBackgroundColor; + styleColor->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; } return NS_OK; } @@ -426,8 +420,7 @@ TableBackgroundRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresConte nsIStyleContext* parentContext = aContext->GetParent(); if (parentContext) { - nsStyleColor* styleColor; - styleColor = (nsStyleColor*)aContext->GetMutableStyleData(eStyleStruct_Color); + nsMutableStyleColor styleColor(aContext); const nsStyleColor* parentStyleColor; parentStyleColor = (const nsStyleColor*)parentContext->GetStyleData(eStyleStruct_Color); @@ -474,8 +467,8 @@ TableTHRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPre nsIStyleContext* parentContext = aContext->GetParent(); if (parentContext) { - nsStyleText* styleText = - (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText styleText(aContext); + if (NS_STYLE_TEXT_ALIGN_DEFAULT == styleText->mTextAlign) { const nsStyleText* parentStyleText = (const nsStyleText*)parentContext->GetStyleData(eStyleStruct_Text); diff --git a/mozilla/layout/style/nsStyleContext.cpp b/mozilla/layout/style/nsStyleContext.cpp index 83d3ecb8bc6..388abd7b793 100644 --- a/mozilla/layout/style/nsStyleContext.cpp +++ b/mozilla/layout/style/nsStyleContext.cpp @@ -56,42 +56,22 @@ #endif #ifdef DEBUG -// #define NOISY_DEBUG -#endif - -// -------------------------------------- -// Macros for getting style data structs -// - if using external data, get from -// the member style data instance -// - if internal, get the data member -#ifdef SHARE_STYLECONTEXTS -#define GETSCDATA(data) mStyleData->m##data -#else -#define GETSCDATA(data) m##data +//#define NOISY_DEBUG #endif -#ifdef SHARE_STYLECONTEXTS +#ifdef USE_FAST_CACHE // define COMPUTE_STYLEDATA_CRC to actually compute a valid CRC32 - // - if not defined then the CRC will simply be 0 (see StyleContextData::ComputeCRC) - // - this is to avoid the cost of computing a CRC if it is not being used - // by the style set in caching the style contexts (not using the FAST_CACHE) - // which is the current situation since the CRC can change when GetMutableStyleData - // is used to poke values into the style context data. + // - Fast cache uses a CRC32 on the style context to quickly find sharing candidates. + // Enabling it by defining USE_FAST_CACHE makes style sharing significantly faster. #define COMPUTE_STYLEDATA_CRC -#endif //SHARE_STYLECONTEXTS +#endif -#ifdef COMPUTE_STYLEDATA_CRC - // helpers for computing CRC32 on style data -static void gen_crc_table(); -static PRUint32 AccumulateCRC(PRUint32 crc_accum, const char *data_blk_ptr, int data_blk_size); -static PRUint32 StyleSideCRC(PRUint32 crc,const nsStyleSides *aStyleSides); -static PRUint32 StyleCoordCRC(PRUint32 crc, const nsStyleCoord* aCoord); -static PRUint32 StyleMarginCRC(PRUint32 crc, const nsMargin *aMargin); -static PRUint32 StyleStringCRC(PRUint32 aCrc, const nsString *aString); -#define STYLEDATA_NO_CRC (0) -#define STYLEDATA_DEFAULT_CRC (0xcafebabe) -#endif // COMPUTE_STYLEDATA_CRC + +//------------------------------------------------------------------------------ +// Helper functions +//------------------------------------------------------------------------------ +// inline PRBool IsFixedUnit(nsStyleUnit aUnit, PRBool aEnumOK) { @@ -100,254 +80,6 @@ inline PRBool IsFixedUnit(nsStyleUnit aUnit, PRBool aEnumOK) (aEnumOK && (aUnit == eStyleUnit_Enumerated))); } -static PRBool IsFixedData(const nsStyleSides& aSides, PRBool aEnumOK); -static nscoord CalcCoord(const nsStyleCoord& aCoord, - const nscoord* aEnumTable, - PRInt32 aNumEnums); - -// EnsureBlockDisplay: -// - if the display value (argument) is not a block-type -// then we set it to a valid block display value -// - For enforcing the floated/positioned element CSS2 rules -static void EnsureBlockDisplay(/*in out*/PRUint8 &display); - -// -------------------- -// nsStyleFont -// -nsStyleFont::nsStyleFont(const nsFont& aVariableFont, const nsFont& aFixedFont) - : mFont(aVariableFont), - mFixedFont(aFixedFont) -{ } - -struct StyleFontImpl : public nsStyleFont { - StyleFontImpl(const nsFont& aVariableFont, const nsFont& aFixedFont) - : nsStyleFont(aVariableFont, aFixedFont) - {} - - void ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleFont& aSource); - void CopyTo(nsStyleFont& aDest) const; - PRInt32 CalcDifference(const StyleFontImpl& aOther) const; - static PRInt32 CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2); - PRUint32 ComputeCRC32(PRUint32 crc) const; - -private: // These are not allowed - StyleFontImpl(const StyleFontImpl& aOther); - StyleFontImpl& operator=(const StyleFontImpl& aOther); -}; - -void StyleFontImpl::ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext) -{ - if (nsnull != aParent) { - mFont = aParent->mFont; - mFixedFont = aParent->mFixedFont; - mFlags = aParent->mFlags; - } - else { - aPresContext->GetDefaultFont(mFont); - aPresContext->GetDefaultFixedFont(mFixedFont); - mFlags = NS_STYLE_FONT_DEFAULT; - } -} - -void StyleFontImpl::SetFrom(const nsStyleFont& aSource) -{ - mFont = aSource.mFont; - mFixedFont = aSource.mFixedFont; - mFlags = aSource.mFlags; -} - -void StyleFontImpl::CopyTo(nsStyleFont& aDest) const -{ - aDest.mFont = mFont; - aDest.mFixedFont = mFixedFont; - aDest.mFlags = mFlags; -} - -PRInt32 StyleFontImpl::CalcDifference(const StyleFontImpl& aOther) const -{ - if (mFlags == aOther.mFlags) { - PRInt32 impact = CalcFontDifference(mFont, aOther.mFont); - if (impact < NS_STYLE_HINT_REFLOW) { - impact = CalcFontDifference(mFixedFont, aOther.mFixedFont); - } - return impact; - } - return NS_STYLE_HINT_REFLOW; -} - -PRInt32 StyleFontImpl::CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2) -{ - if ((aFont1.size == aFont2.size) && - (aFont1.style == aFont2.style) && - (aFont1.variant == aFont2.variant) && - (aFont1.weight == aFont2.weight) && - (aFont1.name == aFont2.name)) { - if ((aFont1.decorations == aFont2.decorations)) { - return NS_STYLE_HINT_NONE; - } - return NS_STYLE_HINT_VISUAL; - } - return NS_STYLE_HINT_REFLOW; -} - -PRUint32 StyleFontImpl::ComputeCRC32(PRUint32 aCrc) const -{ - PRUint32 crc = aCrc; - -#ifdef COMPUTE_STYLEDATA_CRC - crc = AccumulateCRC(crc,(const char *)&(mFont.size),sizeof(mFont.size)); - crc = AccumulateCRC(crc,(const char *)&(mFont.style),sizeof(mFont.style)); - crc = AccumulateCRC(crc,(const char *)&(mFont.variant),sizeof(mFont.variant)); - crc = AccumulateCRC(crc,(const char *)&(mFont.weight),sizeof(mFont.weight)); - crc = AccumulateCRC(crc,(const char *)&(mFont.decorations),sizeof(mFont.decorations)); - crc = StyleStringCRC(crc,&(mFont.name)); - crc = AccumulateCRC(crc,(const char *)&(mFixedFont.size),sizeof(mFixedFont.size)); - crc = AccumulateCRC(crc,(const char *)&(mFixedFont.style),sizeof(mFixedFont.style)); - crc = AccumulateCRC(crc,(const char *)&(mFixedFont.variant),sizeof(mFixedFont.variant)); - crc = AccumulateCRC(crc,(const char *)&(mFixedFont.weight),sizeof(mFixedFont.weight)); - crc = AccumulateCRC(crc,(const char *)&(mFixedFont.decorations),sizeof(mFixedFont.decorations)); - crc = StyleStringCRC(crc,&(mFixedFont.name)); - crc = AccumulateCRC(crc,(const char *)&mFlags,sizeof(mFlags)); -#endif - - return crc; -} - -#ifdef XP_MAC -#pragma mark - -#endif - -// -------------------- -// nsStyleColor -// - -struct StyleColorImpl: public nsStyleColor { - StyleColorImpl(void) { } - - void ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleColor& aSource); - void CopyTo(nsStyleColor& aDest) const; - PRInt32 CalcDifference(const StyleColorImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; - -private: // These are not allowed - StyleColorImpl(const StyleColorImpl& aOther); - StyleColorImpl& operator=(const StyleColorImpl& aOther); -}; - -void StyleColorImpl::ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext) -{ - if (nsnull != aParent) { - mColor = aParent->mColor; - mOpacity = aParent->mOpacity; - mCursor = aParent->mCursor; // fix for bugzilla bug 51113 - } - else { - if (nsnull != aPresContext) { - aPresContext->GetDefaultColor(&mColor); - } - else { - mColor = NS_RGB(0x00, 0x00, 0x00); - } - mOpacity = 1.0f; - mCursor = NS_STYLE_CURSOR_AUTO; // fix for bugzilla bug 51113 - } - - mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE; - if (nsnull != aPresContext) { - aPresContext->GetDefaultBackgroundColor(&mBackgroundColor); - aPresContext->GetDefaultBackgroundImageAttachment(&mBackgroundAttachment); - aPresContext->GetDefaultBackgroundImageRepeat(&mBackgroundRepeat); - aPresContext->GetDefaultBackgroundImageOffset(&mBackgroundXPosition, &mBackgroundYPosition); - aPresContext->GetDefaultBackgroundImage(mBackgroundImage); - } - else { - mBackgroundColor = NS_RGB(192,192,192); - mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; - mBackgroundRepeat = NS_STYLE_BG_REPEAT_XY; - mBackgroundXPosition = 0; - mBackgroundYPosition = 0; - } -} - -void StyleColorImpl::SetFrom(const nsStyleColor& aSource) -{ - mColor = aSource.mColor; - - mBackgroundAttachment = aSource.mBackgroundAttachment; - mBackgroundFlags = aSource.mBackgroundFlags; - mBackgroundRepeat = aSource.mBackgroundRepeat; - - mBackgroundColor = aSource.mBackgroundColor; - mBackgroundXPosition = aSource.mBackgroundXPosition; - mBackgroundYPosition = aSource.mBackgroundYPosition; - mBackgroundImage = aSource.mBackgroundImage; - - mCursor = aSource.mCursor; - mCursorImage = aSource.mCursorImage; - mOpacity = aSource.mOpacity; -} - -void StyleColorImpl::CopyTo(nsStyleColor& aDest) const -{ - aDest.mColor = mColor; - - aDest.mBackgroundAttachment = mBackgroundAttachment; - aDest.mBackgroundFlags = mBackgroundFlags; - aDest.mBackgroundRepeat = mBackgroundRepeat; - - aDest.mBackgroundColor = mBackgroundColor; - aDest.mBackgroundXPosition = mBackgroundXPosition; - aDest.mBackgroundYPosition = mBackgroundYPosition; - aDest.mBackgroundImage = mBackgroundImage; - - aDest.mCursor = mCursor; - aDest.mCursorImage = mCursorImage; - aDest.mOpacity = mOpacity; -} - -PRInt32 StyleColorImpl::CalcDifference(const StyleColorImpl& aOther) const -{ - if ((mColor == aOther.mColor) && - (mBackgroundAttachment == aOther.mBackgroundAttachment) && - (mBackgroundFlags == aOther.mBackgroundFlags) && - (mBackgroundRepeat == aOther.mBackgroundRepeat) && - (mBackgroundColor == aOther.mBackgroundColor) && - (mBackgroundXPosition == aOther.mBackgroundXPosition) && - (mBackgroundYPosition == aOther.mBackgroundYPosition) && - (mBackgroundImage == aOther.mBackgroundImage) && - (mCursor == aOther.mCursor) && - (mCursorImage == aOther.mCursorImage) && - (mOpacity == aOther.mOpacity)) { - return NS_STYLE_HINT_NONE; - } - return NS_STYLE_HINT_VISUAL; -} - -PRUint32 StyleColorImpl::ComputeCRC32(PRUint32 aCrc) const -{ - PRUint32 crc = aCrc; -#ifdef COMPUTE_STYLEDATA_CRC - crc = AccumulateCRC(crc,(const char *)&mColor,sizeof(mColor)); - crc = AccumulateCRC(crc,(const char *)&mBackgroundAttachment,sizeof(mBackgroundAttachment)); - crc = AccumulateCRC(crc,(const char *)&mBackgroundFlags,sizeof(mBackgroundFlags)); - crc = AccumulateCRC(crc,(const char *)&mBackgroundRepeat,sizeof(mBackgroundRepeat)); - crc = AccumulateCRC(crc,(const char *)&mBackgroundColor,sizeof(mBackgroundColor)); - crc = AccumulateCRC(crc,(const char *)&mBackgroundXPosition,sizeof(mBackgroundXPosition)); - crc = AccumulateCRC(crc,(const char *)&mBackgroundYPosition,sizeof(mBackgroundYPosition)); - crc = StyleStringCRC(crc,&mBackgroundImage); - crc = AccumulateCRC(crc,(const char *)&mCursor,sizeof(mCursor)); - crc = StyleStringCRC(crc,&mCursorImage); - crc = AccumulateCRC(crc,(const char *)&mOpacity,sizeof(mOpacity)); -#endif - return crc; -} - -#ifdef XP_MAC -#pragma mark - -#endif - static PRBool IsFixedData(const nsStyleSides& aSides, PRBool aEnumOK) { return PRBool(IsFixedUnit(aSides.GetLeftUnit(), aEnumOK) && @@ -380,46 +112,331 @@ static nscoord CalcCoord(const nsStyleCoord& aCoord, return 0; } +#ifdef COMPUTE_STYLEDATA_CRC +static void gen_crc_table(); +static PRUint32 AccumulateCRC(PRUint32 crc_accum, const char *data_blk_ptr, int data_blk_size); +static PRUint32 StyleSideCRC(PRUint32 crc,const nsStyleSides *aStyleSides); +static PRUint32 StyleCoordCRC(PRUint32 crc, const nsStyleCoord* aCoord); +static PRUint32 StyleMarginCRC(PRUint32 crc, const nsMargin *aMargin); +static PRUint32 StyleStringCRC(PRUint32 aCrc, const nsString *aString); +#define STYLEDATA_NO_CRC (0) +#define STYLEDATA_DEFAULT_CRC (0xcafebabe) +#endif + #ifdef XP_MAC #pragma mark - #endif -struct StyleMarginImpl: public nsStyleMargin { - StyleMarginImpl(void) - : nsStyleMargin() - {} +struct StyleBlob { + virtual ~StyleBlob(void) {} - void ResetFrom(const nsStyleMargin* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleMargin& aSource); - void CopyTo(nsStyleMargin& aDest) const; - void RecalcData(void); - PRInt32 CalcDifference(const StyleMarginImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) = 0; + virtual void CopyTo(nsStyleStruct* aDest) const = 0; + virtual void SetFrom(const nsStyleStruct* aSource) = 0; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const = 0; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const = 0; -private: // These are not allowed - StyleMarginImpl(const StyleMarginImpl& aOther); - StyleMarginImpl& operator=(const StyleMarginImpl& aOther); + inline virtual const nsStyleStruct* GetData(void) const = 0; }; -void StyleMarginImpl::ResetFrom(const nsStyleMargin* aParent, nsIPresContext* aPresContext) +//------------------------------------------------------------------------------ +// nsStyleFont +//------------------------------------------------------------------------------ +// +struct StyleFontBlob : public nsStyleFont, public StyleBlob { + StyleFontBlob(const nsFont& aVariableFont, const nsFont& aFixedFont) + : nsStyleFont(aVariableFont, aFixedFont) + {} + + StyleFontBlob(void) {} + virtual ~StyleFontBlob(void) {} + + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleFont*)this;}; + + static PRInt32 CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2); + +private: // These are not allowed + StyleFontBlob(const StyleFontBlob& aOther); + StyleFontBlob& operator=(const StyleFontBlob& aOther); +}; + +void StyleFontBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) +{ + const nsStyleFont* parent = (nsStyleFont*)aParent; + + if (nsnull != parent) { + mFont = parent->mFont; + mFixedFont = parent->mFixedFont; + mFlags = parent->mFlags; + } + else { + aPresContext->GetDefaultFont(mFont); + aPresContext->GetDefaultFixedFont(mFixedFont); + mFlags = NS_STYLE_FONT_DEFAULT; + } +} + +void StyleFontBlob::SetFrom(const nsStyleStruct* aSource) +{ + const nsStyleFont* source = (nsStyleFont*)aSource; + + mFont = source->mFont; + mFixedFont = source->mFixedFont; + mFlags = source->mFlags; +} + +void StyleFontBlob::CopyTo(nsStyleStruct* aDest) const +{ + nsStyleFont* dest = (nsStyleFont*)aDest; + + dest->mFont = mFont; + dest->mFixedFont = mFixedFont; + dest->mFlags = mFlags; +} + +PRInt32 StyleFontBlob::CalcDifference(const nsStyleStruct* aOther) const +{ + const nsStyleFont* other = (nsStyleFont*)aOther; + + if (mFlags == other->mFlags) { + PRInt32 impact = CalcFontDifference(mFont, other->mFont); + if (impact < NS_STYLE_HINT_REFLOW) { + impact = CalcFontDifference(mFixedFont, other->mFixedFont); + } + return impact; + } + return NS_STYLE_HINT_REFLOW; +} + +PRInt32 StyleFontBlob::CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2) +{ + if ((aFont1.size == aFont2.size) && + (aFont1.style == aFont2.style) && + (aFont1.variant == aFont2.variant) && + (aFont1.weight == aFont2.weight) && + (aFont1.name == aFont2.name)) { + if ((aFont1.decorations == aFont2.decorations)) { + return NS_STYLE_HINT_NONE; + } + return NS_STYLE_HINT_VISUAL; + } + return NS_STYLE_HINT_REFLOW; +} + +PRUint32 StyleFontBlob::ComputeCRC32(PRUint32 aCrc) const +{ + PRUint32 crc = aCrc; + +#ifdef COMPUTE_STYLEDATA_CRC + crc = AccumulateCRC(crc,(const char *)&(mFont.size),sizeof(mFont.size)); + crc = AccumulateCRC(crc,(const char *)&(mFont.style),sizeof(mFont.style)); + crc = AccumulateCRC(crc,(const char *)&(mFont.variant),sizeof(mFont.variant)); + crc = AccumulateCRC(crc,(const char *)&(mFont.weight),sizeof(mFont.weight)); + crc = AccumulateCRC(crc,(const char *)&(mFont.decorations),sizeof(mFont.decorations)); + crc = StyleStringCRC(crc,&(mFont.name)); + crc = AccumulateCRC(crc,(const char *)&(mFixedFont.size),sizeof(mFixedFont.size)); + crc = AccumulateCRC(crc,(const char *)&(mFixedFont.style),sizeof(mFixedFont.style)); + crc = AccumulateCRC(crc,(const char *)&(mFixedFont.variant),sizeof(mFixedFont.variant)); + crc = AccumulateCRC(crc,(const char *)&(mFixedFont.weight),sizeof(mFixedFont.weight)); + crc = AccumulateCRC(crc,(const char *)&(mFixedFont.decorations),sizeof(mFixedFont.decorations)); + crc = StyleStringCRC(crc,&(mFixedFont.name)); + crc = AccumulateCRC(crc,(const char *)&mFlags,sizeof(mFlags)); +#endif + + return crc; +} + +#ifdef XP_MAC +#pragma mark - +#endif + +//------------------------------------------------------------------------------ +// nsStyleColor +//------------------------------------------------------------------------------ +// +struct StyleColorBlob: public nsStyleColor, public StyleBlob { + StyleColorBlob(void) { } + virtual ~StyleColorBlob(void) {} + + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleColor*)this;}; + +private: // These are not allowed + StyleColorBlob(const StyleColorBlob& aOther); + StyleColorBlob& operator=(const StyleColorBlob& aOther); +}; + +void StyleColorBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) +{ + const nsStyleColor* parent = (nsStyleColor*)aParent; + + if (nsnull != parent) { + mColor = parent->mColor; + mOpacity = parent->mOpacity; + mCursor = parent->mCursor; // fix for bugzilla bug 51113 + } + else { + if (nsnull != aPresContext) { + aPresContext->GetDefaultColor(&mColor); + } + else { + mColor = NS_RGB(0x00, 0x00, 0x00); + } + mOpacity = 1.0f; + mCursor = NS_STYLE_CURSOR_AUTO; // fix for bugzilla bug 51113 + } + + mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE; + if (nsnull != aPresContext) { + aPresContext->GetDefaultBackgroundColor(&mBackgroundColor); + aPresContext->GetDefaultBackgroundImageAttachment(&mBackgroundAttachment); + aPresContext->GetDefaultBackgroundImageRepeat(&mBackgroundRepeat); + aPresContext->GetDefaultBackgroundImageOffset(&mBackgroundXPosition, &mBackgroundYPosition); + aPresContext->GetDefaultBackgroundImage(mBackgroundImage); + } + else { + mBackgroundColor = NS_RGB(192,192,192); + mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; + mBackgroundRepeat = NS_STYLE_BG_REPEAT_XY; + mBackgroundXPosition = 0; + mBackgroundYPosition = 0; + } +} + +void StyleColorBlob::SetFrom(const nsStyleStruct* aSource) +{ + const nsStyleColor* source = (nsStyleColor*)aSource; + + mColor = source->mColor; + + mBackgroundAttachment = source->mBackgroundAttachment; + mBackgroundFlags = source->mBackgroundFlags; + mBackgroundRepeat = source->mBackgroundRepeat; + + mBackgroundColor = source->mBackgroundColor; + mBackgroundXPosition = source->mBackgroundXPosition; + mBackgroundYPosition = source->mBackgroundYPosition; + mBackgroundImage = source->mBackgroundImage; + + mCursor = source->mCursor; + mCursorImage = source->mCursorImage; + mOpacity = source->mOpacity; +} + +void StyleColorBlob::CopyTo(nsStyleStruct* aDest) const +{ + nsStyleColor* dest = (nsStyleColor*)aDest; + + dest->mColor = mColor; + + dest->mBackgroundAttachment = mBackgroundAttachment; + dest->mBackgroundFlags = mBackgroundFlags; + dest->mBackgroundRepeat = mBackgroundRepeat; + + dest->mBackgroundColor = mBackgroundColor; + dest->mBackgroundXPosition = mBackgroundXPosition; + dest->mBackgroundYPosition = mBackgroundYPosition; + dest->mBackgroundImage = mBackgroundImage; + + dest->mCursor = mCursor; + dest->mCursorImage = mCursorImage; + dest->mOpacity = mOpacity; +} + +PRInt32 StyleColorBlob::CalcDifference(const nsStyleStruct* aOther) const +{ + const nsStyleColor* other = (nsStyleColor*)aOther; + + if ((mColor == other->mColor) && + (mBackgroundAttachment == other->mBackgroundAttachment) && + (mBackgroundFlags == other->mBackgroundFlags) && + (mBackgroundRepeat == other->mBackgroundRepeat) && + (mBackgroundColor == other->mBackgroundColor) && + (mBackgroundXPosition == other->mBackgroundXPosition) && + (mBackgroundYPosition == other->mBackgroundYPosition) && + (mBackgroundImage == other->mBackgroundImage) && + (mCursor == other->mCursor) && + (mCursorImage == other->mCursorImage) && + (mOpacity == other->mOpacity)) { + return NS_STYLE_HINT_NONE; + } + return NS_STYLE_HINT_VISUAL; +} + +PRUint32 StyleColorBlob::ComputeCRC32(PRUint32 aCrc) const +{ + PRUint32 crc = aCrc; +#ifdef COMPUTE_STYLEDATA_CRC + crc = AccumulateCRC(crc,(const char *)&mColor,sizeof(mColor)); + crc = AccumulateCRC(crc,(const char *)&mBackgroundAttachment,sizeof(mBackgroundAttachment)); + crc = AccumulateCRC(crc,(const char *)&mBackgroundFlags,sizeof(mBackgroundFlags)); + crc = AccumulateCRC(crc,(const char *)&mBackgroundRepeat,sizeof(mBackgroundRepeat)); + crc = AccumulateCRC(crc,(const char *)&mBackgroundColor,sizeof(mBackgroundColor)); + crc = AccumulateCRC(crc,(const char *)&mBackgroundXPosition,sizeof(mBackgroundXPosition)); + crc = AccumulateCRC(crc,(const char *)&mBackgroundYPosition,sizeof(mBackgroundYPosition)); + crc = StyleStringCRC(crc,&mBackgroundImage); + crc = AccumulateCRC(crc,(const char *)&mCursor,sizeof(mCursor)); + crc = StyleStringCRC(crc,&mCursorImage); + crc = AccumulateCRC(crc,(const char *)&mOpacity,sizeof(mOpacity)); +#endif + return crc; +} + + +#ifdef XP_MAC +#pragma mark - +#endif + +//------------------------------------------------------------------------------ +// nsStyleMargin +//------------------------------------------------------------------------------ +// +struct StyleMarginBlob: public nsStyleMargin, public StyleBlob { + StyleMarginBlob(void) {} + virtual ~StyleMarginBlob(void) {} + + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleMargin*)this;}; + + void RecalcData(void); + +private: // These are not allowed + StyleMarginBlob(const StyleMarginBlob& aOther); + StyleMarginBlob& operator=(const StyleMarginBlob& aOther); +}; + +void StyleMarginBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { // spacing values not inherited mMargin.Reset(); mHasCachedMargin = PR_FALSE; } -void StyleMarginImpl::SetFrom(const nsStyleMargin& aSource) +void StyleMarginBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStyleMargin*)this, &aSource, sizeof(nsStyleMargin)); + nsCRT::memcpy((nsStyleMargin*)this, aSource, sizeof(nsStyleMargin)); } -void StyleMarginImpl::CopyTo(nsStyleMargin& aDest) const +void StyleMarginBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStyleMargin*)this, sizeof(nsStyleMargin)); + nsCRT::memcpy(aDest, (const nsStyleMargin*)this, sizeof(nsStyleMargin)); } -void StyleMarginImpl::RecalcData(void) +void StyleMarginBlob::RecalcData(void) { if (IsFixedData(mMargin, PR_FALSE)) { nsStyleCoord coord; @@ -435,15 +452,17 @@ void StyleMarginImpl::RecalcData(void) } } -PRInt32 StyleMarginImpl::CalcDifference(const StyleMarginImpl& aOther) const +PRInt32 StyleMarginBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mMargin == aOther.mMargin) { + const nsStyleMargin* other = (nsStyleMargin*)aOther; + + if (mMargin == other->mMargin) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_REFLOW; } -PRUint32 StyleMarginImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleMarginBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; @@ -462,41 +481,46 @@ PRUint32 StyleMarginImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -struct StylePaddingImpl: public nsStylePadding { - StylePaddingImpl(void) - : nsStylePadding() - {} +//------------------------------------------------------------------------------ +// nsStylePadding +//------------------------------------------------------------------------------ +// +struct StylePaddingBlob: public nsStylePadding, public StyleBlob { + StylePaddingBlob(void) {} + virtual ~StylePaddingBlob(void) {} + + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStylePadding*)this;}; - void ResetFrom(const nsStylePadding* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStylePadding& aSource); - void CopyTo(nsStylePadding& aDest) const; void RecalcData(void); - PRInt32 CalcDifference(const StylePaddingImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; private: // These are not allowed - StylePaddingImpl(const StylePaddingImpl& aOther); - StylePaddingImpl& operator=(const StylePaddingImpl& aOther); + StylePaddingBlob(const StylePaddingBlob& aOther); + StylePaddingBlob& operator=(const StylePaddingBlob& aOther); }; -void StylePaddingImpl::ResetFrom(const nsStylePadding* aParent, nsIPresContext* aPresContext) +void StylePaddingBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { // spacing values not inherited mPadding.Reset(); mHasCachedPadding = PR_FALSE; } -void StylePaddingImpl::SetFrom(const nsStylePadding& aSource) +void StylePaddingBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStylePadding*)this, &aSource, sizeof(nsStylePadding)); + nsCRT::memcpy((nsStylePadding*)this, aSource, sizeof(nsStylePadding)); } -void StylePaddingImpl::CopyTo(nsStylePadding& aDest) const +void StylePaddingBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStylePadding*)this, sizeof(nsStylePadding)); + nsCRT::memcpy(aDest, (const nsStylePadding*)this, sizeof(nsStylePadding)); } -void StylePaddingImpl::RecalcData(void) +void StylePaddingBlob::RecalcData(void) { if (IsFixedData(mPadding, PR_FALSE)) { nsStyleCoord coord; @@ -512,15 +536,17 @@ void StylePaddingImpl::RecalcData(void) } } -PRInt32 StylePaddingImpl::CalcDifference(const StylePaddingImpl& aOther) const +PRInt32 StylePaddingBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mPadding == aOther.mPadding) { + const nsStylePadding* other = (nsStylePadding*)aOther; + + if (mPadding == other->mPadding) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_REFLOW; } -PRUint32 StylePaddingImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StylePaddingBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; @@ -539,28 +565,35 @@ PRUint32 StylePaddingImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -struct StyleBorderImpl: public nsStyleBorder { - StyleBorderImpl(void) - : nsStyleBorder(), mWidthsInitialized(PR_FALSE) +//------------------------------------------------------------------------------ +// nsStyleBorder +//------------------------------------------------------------------------------ +// +struct StyleBorderBlob: public nsStyleBorder, public StyleBlob { + StyleBorderBlob(void) + : mWidthsInitialized(PR_FALSE) {} + virtual ~StyleBorderBlob(void) {} + + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleBorder*)this;}; - void ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleBorder& aSource); - void CopyTo(nsStyleBorder& aDest) const; PRBool IsBorderSideVisible(PRUint8 aSide) const; void RecalcData(nscolor color); - PRInt32 CalcDifference(const StyleBorderImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; private: // These are not allowed - StyleBorderImpl(const StyleBorderImpl& aOther); - StyleBorderImpl& operator=(const StyleBorderImpl& aOther); + StyleBorderBlob(const StyleBorderBlob& aOther); + StyleBorderBlob& operator=(const StyleBorderBlob& aOther); // XXX remove with deprecated methods PRBool mWidthsInitialized; }; -void StyleBorderImpl::ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aPresContext) +void StyleBorderBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { // XXX support mBorderWidhts until deprecated methods are removed if (! mWidthsInitialized) { @@ -599,24 +632,24 @@ void StyleBorderImpl::ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aP mHasCachedBorder = PR_FALSE; } -void StyleBorderImpl::SetFrom(const nsStyleBorder& aSource) +void StyleBorderBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStyleBorder*)this, &aSource, sizeof(nsStyleBorder)); + nsCRT::memcpy((nsStyleBorder*)this, aSource, sizeof(nsStyleBorder)); } -void StyleBorderImpl::CopyTo(nsStyleBorder& aDest) const +void StyleBorderBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStyleBorder*)this, sizeof(nsStyleBorder)); + nsCRT::memcpy(aDest, (const nsStyleBorder*)this, sizeof(nsStyleBorder)); } -PRBool StyleBorderImpl::IsBorderSideVisible(PRUint8 aSide) const +PRBool StyleBorderBlob::IsBorderSideVisible(PRUint8 aSide) const { PRUint8 borderStyle = GetBorderStyle(aSide); return ((borderStyle != NS_STYLE_BORDER_STYLE_NONE) && (borderStyle != NS_STYLE_BORDER_STYLE_HIDDEN)); } -void StyleBorderImpl::RecalcData(nscolor aColor) +void StyleBorderBlob::RecalcData(nscolor aColor) { if (((!IsBorderSideVisible(NS_SIDE_LEFT))|| IsFixedUnit(mBorder.GetLeftUnit(), PR_TRUE)) && @@ -671,25 +704,27 @@ void StyleBorderImpl::RecalcData(nscolor aColor) } } -PRInt32 StyleBorderImpl::CalcDifference(const StyleBorderImpl& aOther) const +PRInt32 StyleBorderBlob::CalcDifference(const nsStyleStruct* aOther) const { - if ((mBorder == aOther.mBorder) && - (mFloatEdge == aOther.mFloatEdge)) { + const nsStyleBorder* other = (nsStyleBorder*)aOther; + + if ((mBorder == other->mBorder) && + (mFloatEdge == other->mFloatEdge)) { PRInt32 ix; for (ix = 0; ix < 4; ix++) { - if ((mBorderStyle[ix] != aOther.mBorderStyle[ix]) || - (mBorderColor[ix] != aOther.mBorderColor[ix])) { - if ((mBorderStyle[ix] != aOther.mBorderStyle[ix]) && + if ((mBorderStyle[ix] != other->mBorderStyle[ix]) || + (mBorderColor[ix] != other->mBorderColor[ix])) { + if ((mBorderStyle[ix] != other->mBorderStyle[ix]) && ((NS_STYLE_BORDER_STYLE_NONE == mBorderStyle[ix]) || - (NS_STYLE_BORDER_STYLE_NONE == aOther.mBorderStyle[ix]) || + (NS_STYLE_BORDER_STYLE_NONE == other->mBorderStyle[ix]) || (NS_STYLE_BORDER_STYLE_HIDDEN == mBorderStyle[ix]) || // bug 45754 - (NS_STYLE_BORDER_STYLE_HIDDEN == aOther.mBorderStyle[ix]))) { + (NS_STYLE_BORDER_STYLE_HIDDEN == other->mBorderStyle[ix]))) { return NS_STYLE_HINT_REFLOW; // border on or off } return NS_STYLE_HINT_VISUAL; } } - if (mBorderRadius != aOther.mBorderRadius) { + if (mBorderRadius != other->mBorderRadius) { return NS_STYLE_HINT_VISUAL; } return NS_STYLE_HINT_NONE; @@ -697,7 +732,7 @@ PRInt32 StyleBorderImpl::CalcDifference(const StyleBorderImpl& aOther) const return NS_STYLE_HINT_REFLOW; } -PRUint32 StyleBorderImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleBorderBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; @@ -720,27 +755,34 @@ PRUint32 StyleBorderImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -struct StyleOutlineImpl: public nsStyleOutline { - StyleOutlineImpl(void) - : nsStyleOutline(), mWidthsInitialized(PR_FALSE) +//------------------------------------------------------------------------------ +// nsStyleOutline +//------------------------------------------------------------------------------ +// +struct StyleOutlineBlob: public nsStyleOutline, public StyleBlob { + StyleOutlineBlob(void) + : mWidthsInitialized(PR_FALSE) {} + virtual ~StyleOutlineBlob(void) {} + + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleOutline*)this;}; - void ResetFrom(const nsStyleOutline* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleOutline& aSource); - void CopyTo(nsStyleOutline& aDest) const; void RecalcData(void); - PRInt32 CalcDifference(const StyleOutlineImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; private: // These are not allowed - StyleOutlineImpl(const StyleOutlineImpl& aOther); - StyleOutlineImpl& operator=(const StyleOutlineImpl& aOther); + StyleOutlineBlob(const StyleOutlineBlob& aOther); + StyleOutlineBlob& operator=(const StyleOutlineBlob& aOther); // XXX remove with deprecated methods PRBool mWidthsInitialized; }; -void StyleOutlineImpl::ResetFrom(const nsStyleOutline* aParent, nsIPresContext* aPresContext) +void StyleOutlineBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { // XXX support mBorderWidhts until deprecated methods are removed if (! mWidthsInitialized) { @@ -765,17 +807,17 @@ void StyleOutlineImpl::ResetFrom(const nsStyleOutline* aParent, nsIPresContext* mHasCachedOutline = PR_FALSE; } -void StyleOutlineImpl::SetFrom(const nsStyleOutline& aSource) +void StyleOutlineBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStyleOutline*)this, &aSource, sizeof(nsStyleOutline)); + nsCRT::memcpy((nsStyleOutline*)this, aSource, sizeof(nsStyleOutline)); } -void StyleOutlineImpl::CopyTo(nsStyleOutline& aDest) const +void StyleOutlineBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStyleOutline*)this, sizeof(nsStyleOutline)); + nsCRT::memcpy(aDest, (const nsStyleOutline*)this, sizeof(nsStyleOutline)); } -void StyleOutlineImpl::RecalcData(void) +void StyleOutlineBlob::RecalcData(void) { if ((NS_STYLE_BORDER_STYLE_NONE == GetOutlineStyle()) || IsFixedUnit(mOutlineWidth.GetUnit(), PR_TRUE)) { @@ -792,18 +834,20 @@ void StyleOutlineImpl::RecalcData(void) } } -PRInt32 StyleOutlineImpl::CalcDifference(const StyleOutlineImpl& aOther) const +PRInt32 StyleOutlineBlob::CalcDifference(const nsStyleStruct* aOther) const { - if ((mOutlineWidth != aOther.mOutlineWidth) || - (mOutlineStyle != aOther.mOutlineStyle) || - (mOutlineColor != aOther.mOutlineColor) || - (mOutlineRadius != aOther.mOutlineRadius)) { + const nsStyleOutline* other = (nsStyleOutline*)aOther; + + if ((mOutlineWidth != other->mOutlineWidth) || + (mOutlineStyle != other->mOutlineStyle) || + (mOutlineColor != other->mOutlineColor) || + (mOutlineRadius != other->mOutlineRadius)) { return NS_STYLE_HINT_VISUAL; // XXX: should be VISUAL: see bugs 9809 and 9816 } return NS_STYLE_HINT_NONE; } -PRUint32 StyleOutlineImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleOutlineBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; @@ -823,32 +867,35 @@ PRUint32 StyleOutlineImpl::ComputeCRC32(PRUint32 aCrc) const #ifdef XP_MAC #pragma mark - #endif -// -------------------- -// nsStyleList + +//------------------------------------------------------------------------------ +// nsStyleList +//------------------------------------------------------------------------------ // -nsStyleList::nsStyleList(void) { } -nsStyleList::~nsStyleList(void) { } +struct StyleListBlob: public nsStyleList, public StyleBlob { + StyleListBlob(void) {} + virtual ~StyleListBlob(void) {} -struct StyleListImpl: public nsStyleList { - StyleListImpl(void) { } - - void ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleList& aSource); - void CopyTo(nsStyleList& aDest) const; - PRInt32 CalcDifference(const StyleListImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleList*)this;}; private: // These are not allowed - StyleListImpl(const StyleListImpl& aOther); - StyleListImpl& operator=(const StyleListImpl& aOther); + StyleListBlob(const StyleListBlob& aOther); + StyleListBlob& operator=(const StyleListBlob& aOther); }; -void StyleListImpl::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext) +void StyleListBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { - if (nsnull != aParent) { - mListStyleType = aParent->mListStyleType; - mListStyleImage = aParent->mListStyleImage; - mListStylePosition = aParent->mListStylePosition; + const nsStyleList* parent = (nsStyleList*)aParent; + + if (nsnull != parent) { + mListStyleType = parent->mListStyleType; + mListStyleImage = parent->mListStyleImage; + mListStylePosition = parent->mListStylePosition; } else { mListStyleType = NS_STYLE_LIST_STYLE_BASIC; @@ -857,25 +904,31 @@ void StyleListImpl::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresC } } -void StyleListImpl::SetFrom(const nsStyleList& aSource) +void StyleListBlob::SetFrom(const nsStyleStruct* aSource) { - mListStyleType = aSource.mListStyleType; - mListStylePosition = aSource.mListStylePosition; - mListStyleImage = aSource.mListStyleImage; + const nsStyleList* source = (nsStyleList*)aSource; + + mListStyleType = source->mListStyleType; + mListStylePosition = source->mListStylePosition; + mListStyleImage = source->mListStyleImage; } -void StyleListImpl::CopyTo(nsStyleList& aDest) const +void StyleListBlob::CopyTo(nsStyleStruct* aDest) const { - aDest.mListStyleType = mListStyleType; - aDest.mListStylePosition = mListStylePosition; - aDest.mListStyleImage = mListStyleImage; + nsStyleList* dest = (nsStyleList*)aDest; + + dest->mListStyleType = mListStyleType; + dest->mListStylePosition = mListStylePosition; + dest->mListStyleImage = mListStyleImage; } -PRInt32 StyleListImpl::CalcDifference(const StyleListImpl& aOther) const +PRInt32 StyleListBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mListStylePosition == aOther.mListStylePosition) { - if (mListStyleImage == aOther.mListStyleImage) { - if (mListStyleType == aOther.mListStyleType) { + const nsStyleList* other = (nsStyleList*)aOther; + + if (mListStylePosition == other->mListStylePosition) { + if (mListStyleImage == other->mListStyleImage) { + if (mListStyleType == other->mListStyleType) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_REFLOW; @@ -885,7 +938,7 @@ PRInt32 StyleListImpl::CalcDifference(const StyleListImpl& aOther) const return NS_STYLE_HINT_REFLOW; } -PRUint32 StyleListImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleListBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -900,27 +953,27 @@ PRUint32 StyleListImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -// -------------------- -// nsStylePosition +//------------------------------------------------------------------------------ +// nsStylePosition +//------------------------------------------------------------------------------ // -nsStylePosition::nsStylePosition(void) { } -nsStylePosition::~nsStylePosition(void) { } +struct StylePositionBlob: public nsStylePosition, public StyleBlob { + StylePositionBlob(void) {} + virtual ~StylePositionBlob(void) {} -struct StylePositionImpl: public nsStylePosition { - StylePositionImpl(void) { } - - void ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStylePosition& aSource); - void CopyTo(nsStylePosition& aDest) const; - PRInt32 CalcDifference(const StylePositionImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStylePosition*)this;}; private: // These are not allowed - StylePositionImpl(const StylePositionImpl& aOther); - StylePositionImpl& operator=(const StylePositionImpl& aOther); + StylePositionBlob(const StylePositionBlob& aOther); + StylePositionBlob& operator=(const StylePositionBlob& aOther); }; -void StylePositionImpl::ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext) +void StylePositionBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { // positioning values not inherited mPosition = NS_STYLE_POSITION_NORMAL; @@ -939,28 +992,30 @@ void StylePositionImpl::ResetFrom(const nsStylePosition* aParent, nsIPresContext mZIndex.SetAutoValue(); } -void StylePositionImpl::SetFrom(const nsStylePosition& aSource) +void StylePositionBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStylePosition*)this, &aSource, sizeof(nsStylePosition)); + nsCRT::memcpy((nsStylePosition*)this, aSource, sizeof(nsStylePosition)); } -void StylePositionImpl::CopyTo(nsStylePosition& aDest) const +void StylePositionBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStylePosition*)this, sizeof(nsStylePosition)); + nsCRT::memcpy(aDest, (const nsStylePosition*)this, sizeof(nsStylePosition)); } -PRInt32 StylePositionImpl::CalcDifference(const StylePositionImpl& aOther) const +PRInt32 StylePositionBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mPosition == aOther.mPosition) { - if ((mOffset == aOther.mOffset) && - (mWidth == aOther.mWidth) && - (mMinWidth == aOther.mMinWidth) && - (mMaxWidth == aOther.mMaxWidth) && - (mHeight == aOther.mHeight) && - (mMinHeight == aOther.mMinHeight) && - (mMaxHeight == aOther.mMaxHeight) && - (mBoxSizing == aOther.mBoxSizing) && - (mZIndex == aOther.mZIndex)) { + const nsStylePosition* other = (nsStylePosition*)aOther; + + if (mPosition == other->mPosition) { + if ((mOffset == other->mOffset) && + (mWidth == other->mWidth) && + (mMinWidth == other->mMinWidth) && + (mMaxWidth == other->mMaxWidth) && + (mHeight == other->mHeight) && + (mMinHeight == other->mMinHeight) && + (mMaxHeight == other->mMaxHeight) && + (mBoxSizing == other->mBoxSizing) && + (mZIndex == other->mZIndex)) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_REFLOW; @@ -968,7 +1023,7 @@ PRInt32 StylePositionImpl::CalcDifference(const StylePositionImpl& aOther) const return NS_STYLE_HINT_FRAMECHANGE; } -PRUint32 StylePositionImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StylePositionBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -990,53 +1045,54 @@ PRUint32 StylePositionImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -// -------------------- -// nsStyleText +//------------------------------------------------------------------------------ +// nsStyleText +//------------------------------------------------------------------------------ // +struct StyleTextBlob: public nsStyleText, public StyleBlob { + StyleTextBlob(void) {} + virtual ~StyleTextBlob(void) {} -nsStyleText::nsStyleText(void) { } -nsStyleText::~nsStyleText(void) { } - -struct StyleTextImpl: public nsStyleText { - StyleTextImpl(void) { } - - void ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleText& aSource); - void CopyTo(nsStyleText& aDest) const; - PRInt32 CalcDifference(const StyleTextImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleText*)this;}; private: // These are not allowed - StyleTextImpl(const StyleTextImpl& aOther); - StyleTextImpl& operator=(const StyleTextImpl& aOther); + StyleTextBlob(const StyleTextBlob& aOther); + StyleTextBlob& operator=(const StyleTextBlob& aOther); }; -void StyleTextImpl::ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext) +void StyleTextBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { + const nsStyleText* parent = (nsStyleText*)aParent; + // These properties not inherited mTextDecoration = NS_STYLE_TEXT_DECORATION_NONE; mVerticalAlign.SetIntValue(NS_STYLE_VERTICAL_ALIGN_BASELINE, eStyleUnit_Enumerated); // mVerticalAlign.Reset(); TBI - if (nsnull != aParent) { - mTextAlign = aParent->mTextAlign; - mTextTransform = aParent->mTextTransform; - mWhiteSpace = aParent->mWhiteSpace; - mLetterSpacing = aParent->mLetterSpacing; + if (nsnull != parent) { + mTextAlign = parent->mTextAlign; + mTextTransform = parent->mTextTransform; + mWhiteSpace = parent->mWhiteSpace; + mLetterSpacing = parent->mLetterSpacing; // Inherit everything except percentage line-height values - nsStyleUnit unit = aParent->mLineHeight.GetUnit(); + nsStyleUnit unit = parent->mLineHeight.GetUnit(); if ((eStyleUnit_Normal == unit) || (eStyleUnit_Factor == unit) || (eStyleUnit_Coord == unit)) { - mLineHeight = aParent->mLineHeight; + mLineHeight = parent->mLineHeight; } else { mLineHeight.SetInheritValue(); } - mTextIndent = aParent->mTextIndent; - mWordSpacing = aParent->mWordSpacing; + mTextIndent = parent->mTextIndent; + mWordSpacing = parent->mWordSpacing; #ifdef IBMBIDI - mUnicodeBidi = aParent->mUnicodeBidi; + mUnicodeBidi = parent->mUnicodeBidi; #endif // IBMBIDI } else { @@ -1054,30 +1110,32 @@ void StyleTextImpl::ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresC } } -void StyleTextImpl::SetFrom(const nsStyleText& aSource) +void StyleTextBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStyleText*)this, &aSource, sizeof(nsStyleText)); + nsCRT::memcpy((nsStyleText*)this, aSource, sizeof(nsStyleText)); } -void StyleTextImpl::CopyTo(nsStyleText& aDest) const +void StyleTextBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStyleText*)this, sizeof(nsStyleText)); + nsCRT::memcpy(aDest, (const nsStyleText*)this, sizeof(nsStyleText)); } -PRInt32 StyleTextImpl::CalcDifference(const StyleTextImpl& aOther) const +PRInt32 StyleTextBlob::CalcDifference(const nsStyleStruct* aOther) const { - if ((mTextAlign == aOther.mTextAlign) && - (mTextTransform == aOther.mTextTransform) && - (mWhiteSpace == aOther.mWhiteSpace) && - (mLetterSpacing == aOther.mLetterSpacing) && - (mLineHeight == aOther.mLineHeight) && - (mTextIndent == aOther.mTextIndent) && - (mWordSpacing == aOther.mWordSpacing) && + const nsStyleText* other = (nsStyleText*)aOther; + + if ((mTextAlign == other->mTextAlign) && + (mTextTransform == other->mTextTransform) && + (mWhiteSpace == other->mWhiteSpace) && + (mLetterSpacing == other->mLetterSpacing) && + (mLineHeight == other->mLineHeight) && + (mTextIndent == other->mTextIndent) && + (mWordSpacing == other->mWordSpacing) && #ifdef IBMBIDI - (mUnicodeBidi == aOther.mUnicodeBidi) && + (mUnicodeBidi == other.mUnicodeBidi) && #endif // IBMBIDI - (mVerticalAlign == aOther.mVerticalAlign)) { - if (mTextDecoration == aOther.mTextDecoration) { + (mVerticalAlign == other->mVerticalAlign)) { + if (mTextDecoration == other->mTextDecoration) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_VISUAL; @@ -1085,7 +1143,7 @@ PRInt32 StyleTextImpl::CalcDifference(const StyleTextImpl& aOther) const return NS_STYLE_HINT_REFLOW; } -PRUint32 StyleTextImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleTextBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; @@ -1110,39 +1168,45 @@ PRUint32 StyleTextImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -// -------------------- -// nsStyleDisplay +//------------------------------------------------------------------------------ +// nsStyleDisplay +//------------------------------------------------------------------------------ // +struct StyleDisplayBlob: public nsStyleDisplay, public StyleBlob { + StyleDisplayBlob(void) {} + virtual ~StyleDisplayBlob(void) {} -struct StyleDisplayImpl: public nsStyleDisplay { - StyleDisplayImpl(void) { } - - void ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleDisplay& aSource); - void CopyTo(nsStyleDisplay& aDest) const; - PRInt32 CalcDifference(const StyleDisplayImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleDisplay*)this;}; private: // These are not allowed - StyleDisplayImpl(const StyleDisplayImpl& aOther); - StyleDisplayImpl& operator=(const StyleDisplayImpl& aOther); + StyleDisplayBlob(const StyleDisplayBlob& aOther); + StyleDisplayBlob& operator=(const StyleDisplayBlob& aOther); }; -void StyleDisplayImpl::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext) +void StyleDisplayBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { - if (nsnull != aParent) { - mDirection = aParent->mDirection; - mLanguage = aParent->mLanguage; - mVisible = aParent->mVisible; + const nsStyleDisplay* parent = (nsStyleDisplay*)aParent; + + if (nsnull != parent) { + mDirection = parent->mDirection; + mLanguage = parent->mLanguage; + mVisible = parent->mVisible; } else { #ifdef IBMBIDI PRUint32 mBidioptions; aPresContext->GetBidi(&mBidioptions); - if (GET_BIDI_OPTION_DIRECTION(mBidioptions) == IBMBIDI_TEXTDIRECTION_RTL) + if (GET_BIDI_OPTION_DIRECTION(mBidioptions) == IBMBIDI_TEXTDIRECTION_RTL) { mDirection = NS_STYLE_DIRECTION_RTL; - else + } + else { mDirection = NS_STYLE_DIRECTION_LTR; + } #else // ifdef IBMBIDI aPresContext->GetDefaultDirection(&mDirection); #endif // IBMBIDI @@ -1162,60 +1226,66 @@ void StyleDisplayImpl::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* #endif // IBMBIDI } -void StyleDisplayImpl::SetFrom(const nsStyleDisplay& aSource) +void StyleDisplayBlob::SetFrom(const nsStyleStruct* aSource) { - mDirection = aSource.mDirection; + const nsStyleDisplay* source = (nsStyleDisplay*)aSource; + + mDirection = source->mDirection; #ifdef IBMBIDI - mExplicitDirection = aSource.mExplicitDirection; + mExplicitDirection = source->mExplicitDirection; #endif // IBMBIDI - mDisplay = aSource.mDisplay; - mFloats = aSource.mFloats; - mBreakType = aSource.mBreakType; - mBreakBefore = aSource.mBreakBefore; - mBreakAfter = aSource.mBreakAfter; - mVisible = aSource.mVisible; - mOverflow = aSource.mOverflow; - mClipFlags = aSource.mClipFlags; - mClip = aSource.mClip; - mLanguage = aSource.mLanguage; + mDisplay = source->mDisplay; + mFloats = source->mFloats; + mBreakType = source->mBreakType; + mBreakBefore = source->mBreakBefore; + mBreakAfter = source->mBreakAfter; + mVisible = source->mVisible; + mOverflow = source->mOverflow; + mClipFlags = source->mClipFlags; + mClip = source->mClip; + mLanguage = source->mLanguage; } -void StyleDisplayImpl::CopyTo(nsStyleDisplay& aDest) const +void StyleDisplayBlob::CopyTo(nsStyleStruct* aDest) const { - aDest.mDirection = mDirection; + nsStyleDisplay* dest = (nsStyleDisplay*)aDest; + + dest->mDirection = mDirection; #ifdef IBMBIDI - aDest.mExplicitDirection = mExplicitDirection; + dest->mExplicitDirection = mExplicitDirection; #endif // IBMBIDI - aDest.mDisplay = mDisplay; - aDest.mFloats = mFloats; - aDest.mBreakType = mBreakType; - aDest.mBreakBefore = mBreakBefore; - aDest.mBreakAfter = mBreakAfter; - aDest.mVisible = mVisible; - aDest.mOverflow = mOverflow; - aDest.mClipFlags = mClipFlags; - aDest.mClip = mClip; - aDest.mLanguage = mLanguage; + dest->mDisplay = mDisplay; + dest->mFloats = mFloats; + dest->mBreakType = mBreakType; + dest->mBreakBefore = mBreakBefore; + dest->mBreakAfter = mBreakAfter; + dest->mVisible = mVisible; + dest->mOverflow = mOverflow; + dest->mClipFlags = mClipFlags; + dest->mClip = mClip; + dest->mLanguage = mLanguage; } -PRInt32 StyleDisplayImpl::CalcDifference(const StyleDisplayImpl& aOther) const +PRInt32 StyleDisplayBlob::CalcDifference(const nsStyleStruct* aOther) const { - if ((mDisplay == aOther.mDisplay) && - (mFloats == aOther.mFloats) && - (mOverflow == aOther.mOverflow)) { - if ((mDirection == aOther.mDirection) && - (mLanguage == aOther.mLanguage) && - (mBreakType == aOther.mBreakType) && - (mBreakBefore == aOther.mBreakBefore) && - (mBreakAfter == aOther.mBreakAfter)) { - if ((mVisible == aOther.mVisible) && - (mClipFlags == aOther.mClipFlags) && - (mClip == aOther.mClip)) { + const nsStyleDisplay* other = (nsStyleDisplay*)aOther; + + if ((mDisplay == other->mDisplay) && + (mFloats == other->mFloats) && + (mOverflow == other->mOverflow)) { + if ((mDirection == other->mDirection) && + (mLanguage == other->mLanguage) && + (mBreakType == other->mBreakType) && + (mBreakBefore == other->mBreakBefore) && + (mBreakAfter == other->mBreakAfter)) { + if ((mVisible == other->mVisible) && + (mClipFlags == other->mClipFlags) && + (mClip == other->mClip)) { return NS_STYLE_HINT_NONE; } - if ((mVisible != aOther.mVisible) && + if ((mVisible != other->mVisible) && ((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) || - (NS_STYLE_VISIBILITY_COLLAPSE == aOther.mVisible))) { + (NS_STYLE_VISIBILITY_COLLAPSE == other->mVisible))) { return NS_STYLE_HINT_REFLOW; } return NS_STYLE_HINT_VISUAL; @@ -1225,7 +1295,7 @@ PRInt32 StyleDisplayImpl::CalcDifference(const StyleDisplayImpl& aOther) const return NS_STYLE_HINT_FRAMECHANGE; } -PRUint32 StyleDisplayImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleDisplayBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -1250,34 +1320,35 @@ PRUint32 StyleDisplayImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -// -------------------- -// nsStyleTable +//------------------------------------------------------------------------------ +// nsStyleTable +//------------------------------------------------------------------------------ // +struct StyleTableBlob: public nsStyleTable, public StyleBlob { + StyleTableBlob(void); + virtual ~StyleTableBlob(void) {}; -nsStyleTable::nsStyleTable(void) { } -nsStyleTable::~nsStyleTable(void) { } - -struct StyleTableImpl: public nsStyleTable { - StyleTableImpl(void); - - void ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleTable& aSource); - void CopyTo(nsStyleTable& aDest) const; - PRInt32 CalcDifference(const StyleTableImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleTable*)this;}; private: // These are not allowed - StyleTableImpl(const StyleTableImpl& aOther); - StyleTableImpl& operator=(const StyleTableImpl& aOther); + StyleTableBlob(const StyleTableBlob& aOther); + StyleTableBlob& operator=(const StyleTableBlob& aOther); }; -StyleTableImpl::StyleTableImpl() +StyleTableBlob::StyleTableBlob() { ResetFrom(nsnull, nsnull); } -void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext) +void StyleTableBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { + const nsStyleTable* parent = (nsStyleTable*)aParent; + // values not inherited mLayoutStrategy = NS_STYLE_TABLE_LAYOUT_AUTO; mCols = NS_STYLE_TABLE_COLS_NONE; @@ -1286,13 +1357,13 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre mCellPadding.Reset(); mSpan = 1; - if (aParent) { // handle inherited properties - mBorderCollapse = aParent->mBorderCollapse; - mEmptyCells = aParent->mEmptyCells; - mCaptionSide = aParent->mCaptionSide; - mBorderSpacingX = aParent->mBorderSpacingX; - mBorderSpacingY = aParent->mBorderSpacingY; - mSpanWidth = aParent->mSpanWidth; + if (parent) { // handle inherited properties + mBorderCollapse = parent->mBorderCollapse; + mEmptyCells = parent->mEmptyCells; + mCaptionSide = parent->mCaptionSide; + mBorderSpacingX = parent->mBorderSpacingX; + mBorderSpacingY = parent->mBorderSpacingY; + mSpanWidth = parent->mSpanWidth; } else { mBorderCollapse = NS_STYLE_BORDER_SEPARATE; @@ -1312,30 +1383,32 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre } } -void StyleTableImpl::SetFrom(const nsStyleTable& aSource) +void StyleTableBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStyleTable*)this, &aSource, sizeof(nsStyleTable)); + nsCRT::memcpy((nsStyleTable*)this, aSource, sizeof(nsStyleTable)); } -void StyleTableImpl::CopyTo(nsStyleTable& aDest) const +void StyleTableBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStyleTable*)this, sizeof(nsStyleTable)); + nsCRT::memcpy(aDest, (const nsStyleTable*)this, sizeof(nsStyleTable)); } -PRInt32 StyleTableImpl::CalcDifference(const StyleTableImpl& aOther) const +PRInt32 StyleTableBlob::CalcDifference(const nsStyleStruct* aOther) const { - if ((mLayoutStrategy == aOther.mLayoutStrategy) && - (mFrame == aOther.mFrame) && - (mRules == aOther.mRules) && - (mBorderCollapse == aOther.mBorderCollapse) && - (mBorderSpacingX == aOther.mBorderSpacingX) && - (mBorderSpacingY == aOther.mBorderSpacingY) && - (mCellPadding == aOther.mCellPadding) && - (mCaptionSide == aOther.mCaptionSide) && - (mCols == aOther.mCols) && - (mSpan == aOther.mSpan) && - (mSpanWidth == aOther.mSpanWidth)) { - if (mEmptyCells == aOther.mEmptyCells) { + const nsStyleTable* other = (nsStyleTable*)aOther; + + if ((mLayoutStrategy == other->mLayoutStrategy) && + (mFrame == other->mFrame) && + (mRules == other->mRules) && + (mBorderCollapse == other->mBorderCollapse) && + (mBorderSpacingX == other->mBorderSpacingX) && + (mBorderSpacingY == other->mBorderSpacingY) && + (mCellPadding == other->mCellPadding) && + (mCaptionSide == other->mCaptionSide) && + (mCols == other->mCols) && + (mSpan == other->mSpan) && + (mSpanWidth == other->mSpanWidth)) { + if (mEmptyCells == other->mEmptyCells) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_VISUAL; @@ -1343,7 +1416,7 @@ PRInt32 StyleTableImpl::CalcDifference(const StyleTableImpl& aOther) const return NS_STYLE_HINT_REFLOW; } -PRUint32 StyleTableImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleTableBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -1367,49 +1440,31 @@ PRUint32 StyleTableImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -//----------------------- -// nsStyleContent +//------------------------------------------------------------------------------ +// nsStyleContent +//------------------------------------------------------------------------------ // +struct StyleContentBlob: public nsStyleContent, public StyleBlob { + StyleContentBlob(void) {}; + virtual ~StyleContentBlob(void) {}; -nsStyleContent::nsStyleContent(void) - : mMarkerOffset(), - mContentCount(0), - mContents(nsnull), - mIncrementCount(0), - mIncrements(nsnull), - mResetCount(0), - mResets(nsnull), - mQuotesCount(0), - mQuotes(nsnull) -{ -} - -nsStyleContent::~nsStyleContent(void) -{ - DELETE_ARRAY_IF(mContents); - DELETE_ARRAY_IF(mIncrements); - DELETE_ARRAY_IF(mResets); - DELETE_ARRAY_IF(mQuotes); -} - - -struct StyleContentImpl: public nsStyleContent { - StyleContentImpl(void) : nsStyleContent() { }; - - void ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleContent& aSource); - void CopyTo(nsStyleContent& aDest) const; - PRInt32 CalcDifference(const StyleContentImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleContent*)this;}; private: // These are not allowed - StyleContentImpl(const StyleContentImpl& aOther); - StyleContentImpl& operator=(const StyleContentImpl& aOther); + StyleContentBlob(const StyleContentBlob& aOther); + StyleContentBlob& operator=(const StyleContentBlob& aOther); }; void -StyleContentImpl::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext) +StyleContentBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { + const nsStyleContent* parent = (nsStyleContent*)aParent; + // reset data mMarkerOffset.Reset(); mContentCount = 0; @@ -1420,11 +1475,11 @@ StyleContentImpl::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPr DELETE_ARRAY_IF(mResets); // inherited data - if (aParent) { - if (NS_SUCCEEDED(AllocateQuotes(aParent->mQuotesCount))) { + if (parent) { + if (NS_SUCCEEDED(AllocateQuotes(parent->mQuotesCount))) { PRUint32 ix = (mQuotesCount * 2); while (0 < ix--) { - mQuotes[ix] = aParent->mQuotes[ix]; + mQuotes[ix] = parent->mQuotes[ix]; } } } @@ -1434,105 +1489,111 @@ StyleContentImpl::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPr } } -void StyleContentImpl::SetFrom(const nsStyleContent& aSource) +void StyleContentBlob::SetFrom(const nsStyleStruct* aSource) { - mMarkerOffset = aSource.mMarkerOffset; + const nsStyleContent* source = (nsStyleContent*)aSource; + + mMarkerOffset = source->mMarkerOffset; PRUint32 index; - if (NS_SUCCEEDED(AllocateContents(aSource.ContentCount()))) { + if (NS_SUCCEEDED(AllocateContents(source->ContentCount()))) { for (index = 0; index < mContentCount; index++) { - aSource.GetContentAt(index, mContents[index].mType, mContents[index].mContent); + source->GetContentAt(index, mContents[index].mType, mContents[index].mContent); } } - if (NS_SUCCEEDED(AllocateCounterIncrements(aSource.CounterIncrementCount()))) { + if (NS_SUCCEEDED(AllocateCounterIncrements(source->CounterIncrementCount()))) { for (index = 0; index < mIncrementCount; index++) { - aSource.GetCounterIncrementAt(index, mIncrements[index].mCounter, + source->GetCounterIncrementAt(index, mIncrements[index].mCounter, mIncrements[index].mValue); } } - if (NS_SUCCEEDED(AllocateCounterResets(aSource.CounterResetCount()))) { + if (NS_SUCCEEDED(AllocateCounterResets(source->CounterResetCount()))) { for (index = 0; index < mResetCount; index++) { - aSource.GetCounterResetAt(index, mResets[index].mCounter, + source->GetCounterResetAt(index, mResets[index].mCounter, mResets[index].mValue); } } - if (NS_SUCCEEDED(AllocateQuotes(aSource.QuotesCount()))) { + if (NS_SUCCEEDED(AllocateQuotes(source->QuotesCount()))) { PRUint32 count = (mQuotesCount * 2); for (index = 0; index < count; index += 2) { - aSource.GetQuotesAt(index, mQuotes[index], mQuotes[index + 1]); + source->GetQuotesAt(index, mQuotes[index], mQuotes[index + 1]); } } } -void StyleContentImpl::CopyTo(nsStyleContent& aDest) const +void StyleContentBlob::CopyTo(nsStyleStruct* aDest) const { - aDest.mMarkerOffset = mMarkerOffset; + nsStyleContent* dest = (nsStyleContent*)aDest; + + dest->mMarkerOffset = mMarkerOffset; PRUint32 index; - if (NS_SUCCEEDED(aDest.AllocateContents(mContentCount))) { + if (NS_SUCCEEDED(dest->AllocateContents(mContentCount))) { for (index = 0; index < mContentCount; index++) { - aDest.SetContentAt(index, mContents[index].mType, + dest->SetContentAt(index, mContents[index].mType, mContents[index].mContent); } } - if (NS_SUCCEEDED(aDest.AllocateCounterIncrements(mIncrementCount))) { + if (NS_SUCCEEDED(dest->AllocateCounterIncrements(mIncrementCount))) { for (index = 0; index < mIncrementCount; index++) { - aDest.SetCounterIncrementAt(index, mIncrements[index].mCounter, + dest->SetCounterIncrementAt(index, mIncrements[index].mCounter, mIncrements[index].mValue); } } - if (NS_SUCCEEDED(aDest.AllocateCounterResets(mResetCount))) { + if (NS_SUCCEEDED(dest->AllocateCounterResets(mResetCount))) { for (index = 0; index < mResetCount; index++) { - aDest.SetCounterResetAt(index, mResets[index].mCounter, + dest->SetCounterResetAt(index, mResets[index].mCounter, mResets[index].mValue); } } - if (NS_SUCCEEDED(aDest.AllocateQuotes(mQuotesCount))) { + if (NS_SUCCEEDED(dest->AllocateQuotes(mQuotesCount))) { PRUint32 count = (mQuotesCount * 2); for (index = 0; index < count; index += 2) { - aDest.SetQuotesAt(index, mQuotes[index], mQuotes[index + 1]); + dest->SetQuotesAt(index, mQuotes[index], mQuotes[index + 1]); } } } PRInt32 -StyleContentImpl::CalcDifference(const StyleContentImpl& aOther) const +StyleContentBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mContentCount == aOther.mContentCount) { - if ((mMarkerOffset == aOther.mMarkerOffset) && - (mIncrementCount == aOther.mIncrementCount) && - (mResetCount == aOther.mResetCount) && - (mQuotesCount == aOther.mQuotesCount)) { + const nsStyleContent* other = (nsStyleContent*)aOther; + + if (mContentCount == other->mContentCount) { + if ((mMarkerOffset == other->mMarkerOffset) && + (mIncrementCount == other->mIncrementCount) && + (mResetCount == other->mResetCount) && + (mQuotesCount == other->mQuotesCount)) { PRUint32 ix = mContentCount; while (0 < ix--) { - if ((mContents[ix].mType != aOther.mContents[ix].mType) || - (mContents[ix].mContent != aOther.mContents[ix].mContent)) { + if ((mContents[ix].mType != other->mContents[ix].mType) || + (mContents[ix].mContent != other->mContents[ix].mContent)) { return NS_STYLE_HINT_REFLOW; } } ix = mIncrementCount; while (0 < ix--) { - if ((mIncrements[ix].mValue != aOther.mIncrements[ix].mValue) || - (mIncrements[ix].mCounter != aOther.mIncrements[ix].mCounter)) { + if ((mIncrements[ix].mValue != other->mIncrements[ix].mValue) || + (mIncrements[ix].mCounter != other->mIncrements[ix].mCounter)) { return NS_STYLE_HINT_REFLOW; } } ix = mResetCount; while (0 < ix--) { - if ((mResets[ix].mValue != aOther.mResets[ix].mValue) || - (mResets[ix].mCounter != aOther.mResets[ix].mCounter)) { + if ((mResets[ix].mValue != other->mResets[ix].mValue) || + (mResets[ix].mCounter != other->mResets[ix].mCounter)) { return NS_STYLE_HINT_REFLOW; } } ix = (mQuotesCount * 2); while (0 < ix--) { - if (mQuotes[ix] != aOther.mQuotes[ix]) { + if (mQuotes[ix] != other->mQuotes[ix]) { return NS_STYLE_HINT_REFLOW; } } @@ -1543,7 +1604,7 @@ StyleContentImpl::CalcDifference(const StyleContentImpl& aOther) const return NS_STYLE_HINT_FRAMECHANGE; } -PRUint32 StyleContentImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleContentBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -1573,33 +1634,34 @@ PRUint32 StyleContentImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -//----------------------- -// nsStyleUserInterface +//------------------------------------------------------------------------------ +// nsStyleUserInterface +//------------------------------------------------------------------------------ // +struct StyleUserInterfaceBlob: public nsStyleUserInterface, public StyleBlob { + StyleUserInterfaceBlob(void) {} + virtual ~StyleUserInterfaceBlob(void) {} -nsStyleUserInterface::nsStyleUserInterface(void) { } -nsStyleUserInterface::~nsStyleUserInterface(void) { } - -struct StyleUserInterfaceImpl: public nsStyleUserInterface { - StyleUserInterfaceImpl(void) { } - - void ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleUserInterface& aSource); - void CopyTo(nsStyleUserInterface& aDest) const; - PRInt32 CalcDifference(const StyleUserInterfaceImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleUserInterface*)this;}; private: // These are not allowed - StyleUserInterfaceImpl(const StyleUserInterfaceImpl& aOther); - StyleUserInterfaceImpl& operator=(const StyleUserInterfaceImpl& aOther); + StyleUserInterfaceBlob(const StyleUserInterfaceBlob& aOther); + StyleUserInterfaceBlob& operator=(const StyleUserInterfaceBlob& aOther); }; -void StyleUserInterfaceImpl::ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext) +void StyleUserInterfaceBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { - if (aParent) { - mUserInput = aParent->mUserInput; - mUserModify = aParent->mUserModify; - mUserFocus = aParent->mUserFocus; + const nsStyleUserInterface* parent = (nsStyleUserInterface*)aParent; + + if (parent) { + mUserInput = parent->mUserInput; + mUserModify = parent->mUserModify; + mUserFocus = parent->mUserFocus; } else { mUserInput = NS_STYLE_USER_INPUT_AUTO; @@ -1613,57 +1675,63 @@ void StyleUserInterfaceImpl::ResetFrom(const nsStyleUserInterface* aParent, nsIP mBehavior.SetLength(0); } -void StyleUserInterfaceImpl::SetFrom(const nsStyleUserInterface& aSource) +void StyleUserInterfaceBlob::SetFrom(const nsStyleStruct* aSource) { - mUserInput = aSource.mUserInput; - mUserModify = aSource.mUserModify; - mUserFocus = aSource.mUserFocus; + const nsStyleUserInterface* source = (nsStyleUserInterface*)aSource; - mUserSelect = aSource.mUserSelect; - mKeyEquivalent = aSource.mKeyEquivalent; - mResizer = aSource.mResizer; - mBehavior = aSource.mBehavior; + mUserInput = source->mUserInput; + mUserModify = source->mUserModify; + mUserFocus = source->mUserFocus; + + mUserSelect = source->mUserSelect; + mKeyEquivalent = source->mKeyEquivalent; + mResizer = source->mResizer; + mBehavior = source->mBehavior; } -void StyleUserInterfaceImpl::CopyTo(nsStyleUserInterface& aDest) const +void StyleUserInterfaceBlob::CopyTo(nsStyleStruct* aDest) const { - aDest.mUserInput = mUserInput; - aDest.mUserModify = mUserModify; - aDest.mUserFocus = mUserFocus; + nsStyleUserInterface* dest = (nsStyleUserInterface*)aDest; - aDest.mUserSelect = mUserSelect; - aDest.mKeyEquivalent = mKeyEquivalent; - aDest.mResizer = mResizer; - aDest.mBehavior = mBehavior; + dest->mUserInput = mUserInput; + dest->mUserModify = mUserModify; + dest->mUserFocus = mUserFocus; + + dest->mUserSelect = mUserSelect; + dest->mKeyEquivalent = mKeyEquivalent; + dest->mResizer = mResizer; + dest->mBehavior = mBehavior; } -PRInt32 StyleUserInterfaceImpl::CalcDifference(const StyleUserInterfaceImpl& aOther) const +PRInt32 StyleUserInterfaceBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mBehavior != aOther.mBehavior) + const nsStyleUserInterface* other = (nsStyleUserInterface*)aOther; + + if (mBehavior != other->mBehavior) return NS_STYLE_HINT_FRAMECHANGE; - if ((mUserInput == aOther.mUserInput) && - (mResizer == aOther.mResizer)) { - if ((mUserModify == aOther.mUserModify) && - (mUserSelect == aOther.mUserSelect)) { - if ((mKeyEquivalent == aOther.mKeyEquivalent) && - (mUserFocus == aOther.mUserFocus) && - (mResizer == aOther.mResizer)) { + if ((mUserInput == other->mUserInput) && + (mResizer == other->mResizer)) { + if ((mUserModify == other->mUserModify) && + (mUserSelect == other->mUserSelect)) { + if ((mKeyEquivalent == other->mKeyEquivalent) && + (mUserFocus == other->mUserFocus) && + (mResizer == other->mResizer)) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_CONTENT; } return NS_STYLE_HINT_VISUAL; } - if ((mUserInput != aOther.mUserInput) && + if ((mUserInput != other->mUserInput) && ((NS_STYLE_USER_INPUT_NONE == mUserInput) || - (NS_STYLE_USER_INPUT_NONE == aOther.mUserInput))) { + (NS_STYLE_USER_INPUT_NONE == other->mUserInput))) { return NS_STYLE_HINT_FRAMECHANGE; } return NS_STYLE_HINT_VISUAL; } -PRUint32 StyleUserInterfaceImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleUserInterfaceBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -1684,38 +1752,39 @@ PRUint32 StyleUserInterfaceImpl::ComputeCRC32(PRUint32 aCrc) const #pragma mark - #endif -//----------------------- -// nsStylePrint +//------------------------------------------------------------------------------ +// nsStylePrint +//------------------------------------------------------------------------------ // +struct StylePrintBlob: public nsStylePrint, public StyleBlob { + StylePrintBlob(void) {} + virtual ~StylePrintBlob(void) {} -nsStylePrint::nsStylePrint(void) { } -nsStylePrint::~nsStylePrint(void) { } - -struct StylePrintImpl: public nsStylePrint { - StylePrintImpl(void) { } - - void ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStylePrint& aSource); - void CopyTo(nsStylePrint& aDest) const; - PRInt32 CalcDifference(const StylePrintImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStylePrint*)this;}; private: // These are not allowed - StylePrintImpl(const StylePrintImpl& aOther); - StylePrintImpl& operator=(const StylePrintImpl& aOther); + StylePrintBlob(const StylePrintBlob& aOther); + StylePrintBlob& operator=(const StylePrintBlob& aOther); }; -void StylePrintImpl::ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext) +void StylePrintBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { - if (aParent) { - mPageBreakBefore = aParent->mPageBreakBefore; - mPageBreakAfter = aParent->mPageBreakAfter; - mPageBreakInside = aParent->mPageBreakInside; - mWidows = aParent->mWidows; - mOrphans = aParent->mOrphans; - mMarks = aParent->mMarks; - mSizeWidth = aParent->mSizeWidth; - mSizeHeight = aParent->mSizeHeight; + const nsStylePrint* parent = (nsStylePrint*)aParent; + + if (parent) { + mPageBreakBefore = parent->mPageBreakBefore; + mPageBreakAfter = parent->mPageBreakAfter; + mPageBreakInside = parent->mPageBreakInside; + mWidows = parent->mWidows; + mOrphans = parent->mOrphans; + mMarks = parent->mMarks; + mSizeWidth = parent->mSizeWidth; + mSizeHeight = parent->mSizeHeight; } else { mPageBreakBefore = NS_STYLE_PAGE_BREAK_AUTO; @@ -1729,36 +1798,58 @@ void StylePrintImpl::ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPre } } -void StylePrintImpl::SetFrom(const nsStylePrint& aSource) +void StylePrintBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStylePrint*)this, &aSource, sizeof(nsStylePrint)); + const nsStylePrint* source = (nsStylePrint*)aSource; + + mPageBreakBefore = source->mPageBreakBefore; + mPageBreakAfter = source->mPageBreakAfter; + mPageBreakInside = source->mPageBreakInside; + mPage = source->mPage; + mWidows = source->mWidows; + mOrphans = source->mOrphans; + mMarks = source->mMarks; + mSizeWidth = source->mSizeWidth; + mSizeHeight = source->mSizeHeight; } -void StylePrintImpl::CopyTo(nsStylePrint& aDest) const +void StylePrintBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStylePrint*)this, sizeof(nsStylePrint)); + nsStylePrint* dest = (nsStylePrint*)aDest; + + dest->mPageBreakBefore = mPageBreakBefore; + dest->mPageBreakAfter = mPageBreakAfter; + dest->mPageBreakInside = mPageBreakInside; + dest->mPage = mPage; + dest->mWidows = mWidows; + dest->mOrphans = mOrphans; + dest->mMarks = mMarks; + dest->mSizeWidth = mSizeWidth; + dest->mSizeHeight = mSizeHeight; } -PRInt32 StylePrintImpl::CalcDifference(const StylePrintImpl& aOther) const +PRInt32 StylePrintBlob::CalcDifference(const nsStyleStruct* aOther) const { - if ((mPageBreakBefore == aOther.mPageBreakBefore) - && (mPageBreakAfter == aOther.mPageBreakAfter) - && (mPageBreakInside == aOther.mPageBreakInside) - && (mWidows == aOther.mWidows) - && (mOrphans == aOther.mOrphans) - && (mMarks == aOther.mMarks) - && (mSizeWidth == aOther.mSizeWidth) - && (mSizeHeight == aOther.mSizeHeight)) { + const nsStylePrint* other = (nsStylePrint*)aOther; + + if ((mPageBreakBefore == other->mPageBreakBefore) + && (mPageBreakAfter == other->mPageBreakAfter) + && (mPageBreakInside == other->mPageBreakInside) + && (mWidows == other->mWidows) + && (mOrphans == other->mOrphans) + && (mMarks == other->mMarks) + && (mSizeWidth == other->mSizeWidth) + && (mSizeHeight == other->mSizeHeight)) { return NS_STYLE_HINT_NONE; } - if (mMarks != aOther.mMarks) { + if (mMarks != other->mMarks) { return NS_STYLE_HINT_VISUAL; } return NS_STYLE_HINT_REFLOW; } -PRUint32 StylePrintImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StylePrintBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -1781,49 +1872,55 @@ PRUint32 StylePrintImpl::ComputeCRC32(PRUint32 aCrc) const #endif #ifdef INCLUDE_XUL -// -------------------- -// nsStyleXUL +//------------------------------------------------------------------------------ +// nsStyleXUL +//------------------------------------------------------------------------------ // -nsStyleXUL::nsStyleXUL() { } -nsStyleXUL::~nsStyleXUL() { } +struct StyleXULBlob: public nsStyleXUL, public StyleBlob { + StyleXULBlob() {} + virtual ~StyleXULBlob() {} -struct StyleXULImpl: public nsStyleXUL { - StyleXULImpl() { } - - void ResetFrom(const nsStyleXUL* aParent, nsIPresContext* aPresContext); - void SetFrom(const nsStyleXUL& aSource); - void CopyTo(nsStyleXUL& aDest) const; - PRInt32 CalcDifference(const StyleXULImpl& aOther) const; - PRUint32 ComputeCRC32(PRUint32 aCrc) const; + virtual void ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext); + virtual void SetFrom(const nsStyleStruct* aSource); + virtual void CopyTo(nsStyleStruct* aDest) const; + virtual PRInt32 CalcDifference(const nsStyleStruct* aOther) const; + virtual PRUint32 ComputeCRC32(PRUint32 aCrc) const; + inline virtual const nsStyleStruct* GetData(void) const {return (const nsStyleXUL*)this;}; private: // These are not allowed - StyleXULImpl(const StyleXULImpl& aOther); - StyleXULImpl& operator=(const StyleXULImpl& aOther); + StyleXULBlob(const StyleXULBlob& aOther); + StyleXULBlob& operator=(const StyleXULBlob& aOther); }; -void StyleXULImpl::ResetFrom(const nsStyleXUL* aParent, nsIPresContext* aPresContext) +void StyleXULBlob::ResetFrom(const nsStyleStruct* aParent, nsIPresContext* aPresContext) { mBoxOrient = NS_STYLE_BOX_ORIENT_HORIZONTAL; } -void StyleXULImpl::SetFrom(const nsStyleXUL& aSource) +void StyleXULBlob::SetFrom(const nsStyleStruct* aSource) { - nsCRT::memcpy((nsStyleXUL*)this, &aSource, sizeof(nsStyleXUL)); + const nsStyleXUL* source = (nsStyleXUL*)aSource; + + mBoxOrient = source->mBoxOrient; } -void StyleXULImpl::CopyTo(nsStyleXUL& aDest) const +void StyleXULBlob::CopyTo(nsStyleStruct* aDest) const { - nsCRT::memcpy(&aDest, (const nsStyleXUL*)this, sizeof(nsStyleXUL)); + nsStyleXUL* dest = (nsStyleXUL*)aDest; + + dest->mBoxOrient = mBoxOrient; } -PRInt32 StyleXULImpl::CalcDifference(const StyleXULImpl& aOther) const +PRInt32 StyleXULBlob::CalcDifference(const nsStyleStruct* aOther) const { - if (mBoxOrient == aOther.mBoxOrient) + const nsStyleXUL* other = (nsStyleXUL*)aOther; + + if (mBoxOrient == other->mBoxOrient) return NS_STYLE_HINT_NONE; return NS_STYLE_HINT_REFLOW; } -PRUint32 StyleXULImpl::ComputeCRC32(PRUint32 aCrc) const +PRUint32 StyleXULBlob::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; #ifdef COMPUTE_STYLEDATA_CRC @@ -1831,246 +1928,86 @@ PRUint32 StyleXULImpl::ComputeCRC32(PRUint32 aCrc) const #endif return crc; } +#endif // INCLUDE_XUL #ifdef XP_MAC #pragma mark - #endif -#endif // INCLUDE_XUL -//---------------------------------------------------------------------- +//------------------------------------------------------------------------------ +// nsStyleContextData +//------------------------------------------------------------------------------ +// -#ifdef SHARE_STYLECONTEXTS +// --------------------- +// Macros for getting style data (StyleXXXBlob and nsStyleXXX) +// +#define STYLEDATA(type) nsStyle##type +#define STYLEBLOB(type) Style##type##Blob +#define BLOBARRAY mStyleData->mBlobArray +#define GETDATA(type) ((const nsStyle##type##*)FetchInheritedStyleStruct(eStyleStruct_##type)) +#define GETBLOB(type) ((STYLEBLOB(##type##)*)FetchInheritedStyleBlob(eStyleStruct_##type)) -//======================== -#ifdef DEBUG -// define this to get stats on the use of the |nsStyleStruct|s inside a |nsStyleContextData|. //XXX pierre + // Use the macro below with extreme caution. The only place where + // we want, and where we *can*, access the data pointers directly + // for modification (ie. non-const pointers) is in RemapStyle() + // because we are then garanteed to have the blobs in place. + // Everywhere else, the pointers can be null. + // + // On a related note... We never want to cast the pointer returned + // by FetchInheritedStyleStruct() to a non-const pointer because it + // would modify the parent's style (or the grand-parent's style) + // but not the current context's style. +#define GETMUTABLEDATAPTR(type) ((nsStyle##type##*)BLOBARRAY[eStyleStruct_##type - 1]->GetData()) + + // Same warning as above, except that it returns a const pointer. + // It's just a faster alternative to GETDATA() for use inside + // RemapStyle() only. +#define GETDATAPTR(type) ((const nsStyle##type##*)BLOBARRAY[eStyleStruct_##type - 1]->GetData()) + + +// --------------------- +// Debug definitions +// +#ifdef DEBUG //xxx pierre + // Define this to get stats on the use of the + // nsStyleStructs inside a nsStyleContextData. //#define LOG_STYLE_STRUCTS -#endif + + // Define this to get statistics on the number of calls + // to GetStyleData() and their depth in the Style tree. +//#define LOG_GET_STYLE_DATA_CALLS + + // Define this to get statistics on the number of calls + // to WriteMutableStyleData(). +//#define LOG_WRITE_STYLE_DATA_CALLS + #ifdef LOG_STYLE_STRUCTS -// StyleFontImpl mFont; -struct StyleFontImplLog: public StyleFontImpl { - StyleFontImplLog(const nsFont& aVariableFont, const nsFont& aFixedFont) - : StyleFontImpl(aVariableFont, aFixedFont), - mInternalFont(aVariableFont, aFixedFont) - {} - void ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext); - StyleFontImpl mInternalFont; - bool mSetFromParent; -}; +class StyleFontImplLog; +class StyleColorImplLog; +class StyleListImplLog; +class StylePositionImplLog; +class StyleTextImplLog; +class StyleDisplayImplLog; +class StyleTableImplLog; +class StyleContentImplLog; +class StyleUserInterfaceImplLog; +class StylePrintImplLog; +class StyleMarginImplLog; +class StylePaddingImplLog; +class StyleBorderImplLog; +class StyleOutlineImplLog; +#undef STYLEBLOB(data) +#define STYLEBLOB(data) Style##data##ImplLog +#endif //LOG_STYLE_STRUCTS -void StyleFontImplLog::ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext) -{ - StyleFontImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalFont); - mSetFromParent = (aParent != nsnull); -} +#endif //DEBUG -// StyleColorImpl mColor; -struct StyleColorImplLog: public StyleColorImpl { - void ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext); - StyleColorImpl mInternalColor; - bool mSetFromParent; -}; - -void StyleColorImplLog::ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext) -{ - StyleColorImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalColor); - mSetFromParent = (aParent != nsnull); -} - -// StyleListImpl mList; -struct StyleListImplLog: public StyleListImpl { - void ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext); - StyleListImpl mInternalList; - bool mSetFromParent; -}; - -void StyleListImplLog::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext) -{ - StyleListImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalList); - mSetFromParent = (aParent != nsnull); -} - -// StylePositionImpl mPosition; -struct StylePositionImplLog: public StylePositionImpl { - void ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext); - StylePositionImpl mInternalPosition; - bool mSetFromParent; -}; - -void StylePositionImplLog::ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext) -{ - StylePositionImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalPosition); - mSetFromParent = (aParent != nsnull); -} - -// StyleTextImpl mText; -struct StyleTextImplLog: public StyleTextImpl { - void ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext); - StyleTextImpl mInternalText; - bool mSetFromParent; -}; - -void StyleTextImplLog::ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext) -{ - StyleTextImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalText); - mSetFromParent = (aParent != nsnull); -} - -// StyleDisplayImpl mDisplay; -struct StyleDisplayImplLog: public StyleDisplayImpl { - void ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext); - StyleDisplayImpl mInternalDisplay; - bool mSetFromParent; -}; - -void StyleDisplayImplLog::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext) -{ - StyleDisplayImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalDisplay); - mSetFromParent = (aParent != nsnull); -} - -// StyleTableImpl mTable; -struct StyleTableImplLog: public StyleTableImpl { - void ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext); - StyleTableImpl mInternalTable; - bool mSetFromParent; -}; - -void StyleTableImplLog::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext) -{ - StyleTableImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalTable); - mSetFromParent = (aParent != nsnull); -} - -// StyleContentImpl mContent; -struct StyleContentImplLog: public StyleContentImpl { - void ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext); - StyleContentImpl mInternalContent; - bool mSetFromParent; -}; - -void StyleContentImplLog::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext) -{ - StyleContentImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalContent); - mSetFromParent = (aParent != nsnull); -} - -// StyleUserInterfaceImpl mUserInterface; -struct StyleUserInterfaceImplLog: public StyleUserInterfaceImpl { - void ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext); - StyleUserInterfaceImpl mInternalUserInterface; - bool mSetFromParent; -}; - -void StyleUserInterfaceImplLog::ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext) -{ - StyleUserInterfaceImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalUserInterface); - mSetFromParent = (aParent != nsnull); -} - -// StylePrintImpl mPrint; -struct StylePrintImplLog: public StylePrintImpl { - void ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext); - StylePrintImpl mInternalPrint; - bool mSetFromParent; -}; - -void StylePrintImplLog::ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext) -{ - StylePrintImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalPrint); - mSetFromParent = (aParent != nsnull); -} - -// StyleMarginImpl mMargin; -struct StyleMarginImplLog: public StyleMarginImpl { - void ResetFrom(const nsStyleMargin* aParent, nsIPresContext* aPresContext); - StyleMarginImpl mInternalMargin; - bool mSetFromParent; -}; - -void StyleMarginImplLog::ResetFrom(const nsStyleMargin* aParent, nsIPresContext* aPresContext) -{ - StyleMarginImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalMargin); - mSetFromParent = (aParent != nsnull); -} - -// StylePaddingImpl mPadding; -struct StylePaddingImplLog: public StylePaddingImpl { - void ResetFrom(const nsStylePadding* aParent, nsIPresContext* aPresContext); - StylePaddingImpl mInternalPadding; - bool mSetFromParent; -}; - -void StylePaddingImplLog::ResetFrom(const nsStylePadding* aParent, nsIPresContext* aPresContext) -{ - StylePaddingImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalPadding); - mSetFromParent = (aParent != nsnull); -} - -// StyleBorderImpl mBorder; -struct StyleBorderImplLog: public StyleBorderImpl { - void ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aPresContext); - StyleBorderImpl mInternalBorder; - bool mSetFromParent; -}; - -void StyleBorderImplLog::ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aPresContext) -{ - StyleBorderImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalBorder); - mSetFromParent = (aParent != nsnull); -} - -// StyleOutlineImpl mOutline; -struct StyleOutlineImplLog: public StyleOutlineImpl { - void ResetFrom(const nsStyleOutline* aParent, nsIPresContext* aPresContext); - StyleOutlineImpl mInternalOutline; - bool mSetFromParent; -}; - -void StyleOutlineImplLog::ResetFrom(const nsStyleOutline* aParent, nsIPresContext* aPresContext) -{ - StyleOutlineImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalOutline); - mSetFromParent = (aParent != nsnull); -} - -#ifdef INCLUDE_XUL -// StyleXULImpl mXUL; -struct StyleXULImplLog: public StyleXULImpl { - void ResetFrom(const nsStyleXUL* aParent, nsIPresContext* aPresContext); - StyleXULImpl mInternalXUL; - bool mSetFromParent; -}; - -void StyleXULImplLog::ResetFrom(const nsStyleXUL* aParent, nsIPresContext* aPresContext) -{ - StyleXULImpl::ResetFrom(aParent, aPresContext); - CopyTo(mInternalXUL); - mSetFromParent = (aParent != nsnull); -} -#endif // INCLUDE_XUL - -#ifdef XP_MAC -#pragma mark - -#endif - -#endif // LOG_STYLE_STRUCTS -//======================== +// --------------------- +// nsStyleContextData +// class nsStyleContextData { public: @@ -2079,91 +2016,96 @@ public: void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); +private: // all data and methods private: only friends have access + #ifdef LOG_STYLE_STRUCTS public: -#else -private: // all data and methods private: only friends have access +#endif +#ifdef LOG_WRITE_STYLE_DATA_CALLS +public: #endif - static nsStyleContextData *Create(nsIPresContext *aPresContext); - - nsStyleContextData(nsIPresContext *aPresContext); +#ifdef SHARE_STYLECONTEXTS + static nsStyleContextData *Create(nsIStyleContext* aStyleContext, nsIPresContext *aPresContext); +#endif + static StyleBlob* AllocateOneBlob(nsStyleStructID aSID, nsIPresContext *aPresContext); + nsresult AllocateStyleBlobs(nsIStyleContext* aStyleContext, nsIPresContext *aPresContext); + void DeleteStyleBlobs(); + + nsStyleContextData(); ~nsStyleContextData(void); - PRUint32 ComputeCRC32(PRUint32 aCrc) const; - void SetCRC32(void) { - mCRC = ComputeCRC32(0); - if (mCRC==STYLEDATA_NO_CRC) - mCRC = STYLEDATA_DEFAULT_CRC; - } - PRUint32 GetCRC32(void) const { return mCRC; } - - PRUint32 AddRef(void); - PRUint32 Release(void); - // the style data... // - StyleContextImpl gets friend-access // -#ifdef LOG_STYLE_STRUCTS - StyleFontImplLog mFont; - StyleColorImplLog mColor; - StyleListImplLog mList; - StylePositionImplLog mPosition; - StyleTextImplLog mText; - StyleDisplayImplLog mDisplay; - StyleTableImplLog mTable; - StyleContentImplLog mContent; - StyleUserInterfaceImplLog mUserInterface; - StylePrintImplLog mPrint; - StyleMarginImplLog mMargin; - StylePaddingImplLog mPadding; - StyleBorderImplLog mBorder; - StyleOutlineImplLog mOutline; + union { + StyleBlob* mBlobArray[eStyleStruct_Max]; + struct { + STYLEBLOB(Font)* mFont; + STYLEBLOB(Color)* mColor; + STYLEBLOB(List)* mList; + STYLEBLOB(Position)* mPosition; + STYLEBLOB(Text)* mText; + STYLEBLOB(Display)* mDisplay; + STYLEBLOB(Table)* mTable; + STYLEBLOB(Content)* mContent; + STYLEBLOB(UserInterface)* mUserInterface; + STYLEBLOB(Print)* mPrint; + STYLEBLOB(Margin)* mMargin; + STYLEBLOB(Padding)* mPadding; + STYLEBLOB(Border)* mBorder; + STYLEBLOB(Outline)* mOutline; #ifdef INCLUDE_XUL - StyleXULImplLog mXUL; -#endif -#else - StyleFontImpl mFont; - StyleColorImpl mColor; - StyleListImpl mList; - StylePositionImpl mPosition; - StyleTextImpl mText; - StyleDisplayImpl mDisplay; - StyleTableImpl mTable; - StyleContentImpl mContent; - StyleUserInterfaceImpl mUserInterface; - StylePrintImpl mPrint; - StyleMarginImpl mMargin; - StylePaddingImpl mPadding; - StyleBorderImpl mBorder; - StyleOutlineImpl mOutline; -#ifdef INCLUDE_XUL - StyleXULImpl mXUL; -#endif + STYLEBLOB(XUL)* mXUL; #endif + //#insert new style structs here# + } mData; + }; - PRUint32 mRefCnt; - PRUint32 mCRC; - +#ifdef SHARE_STYLECONTEXTS + PRUint32 mRefCnt; + inline PRUint32 AddRef(void); + inline PRUint32 Release(void); #ifdef DEBUG - static PRUint32 gInstanceCount; + static PRUint32 gInstanceCount; +#endif +#ifdef COMPUTE_STYLEDATA_CRC + PRUint32 mCRC; + PRUint32 ComputeCRC32(PRUint32 aCrc) const; + PRUint32 GetCRC32(void) const { return mCRC; } + void SetCRC32(void) { + mCRC = ComputeCRC32(0); + if (mCRC==STYLEDATA_NO_CRC) { + mCRC = STYLEDATA_DEFAULT_CRC; + } + } +#endif // COMPUTE_STYLEDATA_CRC +#endif // SHARE_STYLECONTEXTS + +#ifdef LOG_STYLE_STRUCTS + PRBool mGotMutable[eStyleStruct_Max]; #endif }; -#ifndef DEBUG -inline +#ifdef DEBUG //xxx pierre +#include "nsStyleContextDebug.h" #endif -PRUint32 nsStyleContextData::AddRef(void) + +#ifdef SHARE_STYLECONTEXTS +// --------------------- +// AddRef +// +inline PRUint32 nsStyleContextData::AddRef(void) { ++mRefCnt; NS_LOG_ADDREF(this,mRefCnt,"nsStyleContextData",sizeof(*this)); return mRefCnt; } -#ifndef DEBUG -inline -#endif -PRUint32 nsStyleContextData::Release(void) +// --------------------- +// Release +// +inline PRUint32 nsStyleContextData::Release(void) { NS_ASSERTION(mRefCnt > 0, "RefCount error in nsStyleContextData"); --mRefCnt; @@ -2182,305 +2124,207 @@ PRUint32 nsStyleContextData::Release(void) /*static*/ PRUint32 nsStyleContextData::gInstanceCount; #endif // DEBUG -nsStyleContextData *nsStyleContextData::Create(nsIPresContext *aPresContext) +// --------------------- +// Create +// +nsStyleContextData *nsStyleContextData::Create(nsIStyleContext* aStyleContext, nsIPresContext *aPresContext) { NS_ASSERTION(aPresContext != nsnull, "parameter cannot be null"); nsStyleContextData *pData = nsnull; if (aPresContext) { - pData = new nsStyleContextData(aPresContext); + pData = new nsStyleContextData(); if (pData) { - NS_ADDREF(pData); + if (NS_SUCCEEDED(pData->AllocateStyleBlobs(aStyleContext, aPresContext))) { +#ifdef SHARE_STYLECONTEXTS + NS_ADDREF(pData); #ifdef NOISY_DEBUG - printf("new nsStyleContextData instance: (%ld) CRC=%lu\n", + printf("new nsStyleContextData instance: (%ld) CRC=%lu\n", (long)(++gInstanceCount), (unsigned long)pData->ComputeCRC32(0)); #endif // NOISY_DEBUG +#endif // SHARE_STYLECONTEXTS + } + else { + delete pData; + pData = nsnull; + } } } return pData; } +#endif //SHARE_STYLECONTEXTS -nsStyleContextData::nsStyleContextData(nsIPresContext *aPresContext) -: mFont(aPresContext->GetDefaultFontDeprecated(), - aPresContext->GetDefaultFixedFontDeprecated()), - mRefCnt(0), mCRC(0) + +// --------------------- +// nsStyleContextData ctor +// +nsStyleContextData::nsStyleContextData() { -} - -//========================================================================================================= - -#ifdef LOG_STYLE_STRUCTS //XXX pierre - -#ifdef XP_MAC -#include <Events.h> -static bool MacKeyDown(unsigned char theKey) -{ - KeyMap map; - GetKeys(map); - return ((*((unsigned char *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0; -} +#ifdef SHARE_STYLECONTEXTS + mRefCnt = 0; +#ifdef COMPUTE_STYLEDATA_CRC + mCRC = 0; +#endif #endif - -static bool IsTimeToDumpStyleStructs() -{ - bool timeToDump = false; -#ifdef XP_MAC - static unsigned long lastTicks = 0; - if (MacKeyDown(0x3b)) { // control key - if ((unsigned long)(::TickCount() - lastTicks) > 60) { - lastTicks = ::TickCount(); - timeToDump = true; - } - } + for (short i = 0; i < eStyleStruct_Max; i ++) { + mBlobArray[i] = nsnull; +#ifdef LOG_STYLE_STRUCTS + mGotMutable[i] = PR_FALSE; #endif - return timeToDump; + } } -static void LogStyleStructs(nsStyleContextData* aStyleContextData) + +// --------------------- +// AllocateOneBlob +// +StyleBlob* nsStyleContextData::AllocateOneBlob(nsStyleStructID aSID, nsIPresContext *aPresContext) { -#define max_structs eStyleStruct_Max - - static unsigned long totalCount = 0; - static unsigned long defaultStruct[max_structs]; - static unsigned long setFromParent[max_structs]; - - static bool resetCounters = true; - - if (IsTimeToDumpStyleStructs()) { - resetCounters = true; - printf("\n\n\n"); - printf("-------------------------------------------------------------------------------------------------------------\n"); - printf("Count of nsStyleContextData: %ld\n", totalCount); - printf("-------------------------------------------------------------------------------------------------------------\n"); - printf(" unchanged unchanged%c set-from-parent%c size-of-struct potential-gain-Kb\n", '%', '%'); - unsigned long totalFootprint = 0; - unsigned long totalPotentialGain = 0; - for (short i = 0; i < max_structs; i ++) { - short index = i+1; - short sizeOfStruct = 0; - unsigned long footprint = 0; - unsigned long potentialGain = 0; - switch (index) { - case eStyleStruct_Font: printf("eStyleStruct_Font "); sizeOfStruct = sizeof(StyleFontImpl); break; - case eStyleStruct_Color: printf("eStyleStruct_Color "); sizeOfStruct = sizeof(StyleColorImpl); break; - case eStyleStruct_List: printf("eStyleStruct_List "); sizeOfStruct = sizeof(StyleListImpl); break; - case eStyleStruct_Position: printf("eStyleStruct_Position "); sizeOfStruct = sizeof(StylePositionImpl); break; - case eStyleStruct_Text: printf("eStyleStruct_Text "); sizeOfStruct = sizeof(StyleTextImpl); break; - case eStyleStruct_Display: printf("eStyleStruct_Display "); sizeOfStruct = sizeof(StyleDisplayImpl); break; - case eStyleStruct_Table: printf("eStyleStruct_Table "); sizeOfStruct = sizeof(StyleTableImpl); break; - case eStyleStruct_Content: printf("eStyleStruct_Content "); sizeOfStruct = sizeof(StyleContentImpl); break; - case eStyleStruct_UserInterface: printf("eStyleStruct_UserInterface "); sizeOfStruct = sizeof(StyleUserInterfaceImpl); break; - case eStyleStruct_Print: printf("eStyleStruct_Print "); sizeOfStruct = sizeof(StylePrintImpl); break; - case eStyleStruct_Margin: printf("eStyleStruct_Margin "); sizeOfStruct = sizeof(StyleMarginImpl); break; - case eStyleStruct_Padding: printf("eStyleStruct_Padding "); sizeOfStruct = sizeof(StylePaddingImpl); break; - case eStyleStruct_Border: printf("eStyleStruct_Border "); sizeOfStruct = sizeof(StyleBorderImpl); break; - case eStyleStruct_Outline: printf("eStyleStruct_Outline "); sizeOfStruct = sizeof(StyleOutlineImpl); break; -#ifdef INCLUDE_XUL - case eStyleStruct_XUL: printf("eStyleStruct_XUL "); sizeOfStruct = sizeof(StyleXULImpl); break; -#endif + StyleBlob* result = nsnull; + switch (aSID) { + case eStyleStruct_Font: + if (aPresContext) { + result = new STYLEBLOB(Font)(aPresContext->GetDefaultFontDeprecated(), aPresContext->GetDefaultFixedFontDeprecated()); } - short percentDefault = (totalCount == 0 ? 0 : ((100 * defaultStruct[i]) / totalCount)); - short percentFromParent = (defaultStruct[i] == 0 ? 0 : ((100 * setFromParent[i]) / defaultStruct[i])); - - footprint = totalCount * sizeOfStruct; - totalFootprint += footprint; - - potentialGain = defaultStruct[i] * sizeOfStruct; - totalPotentialGain += potentialGain; - - printf(" %7ld %3d %3d %5d %5d\n", defaultStruct[i], percentDefault, percentFromParent, sizeOfStruct, potentialGain / 1024); - } - printf("-------------------------------------------------------------------------------------------------------------\n"); - printf("Current footprint: %4ld Kb\n", totalFootprint / 1024); - printf("Potential gain: %4ld Kb (or %d%c)\n", totalPotentialGain / 1024, totalPotentialGain*100/totalFootprint, '%'); - printf("Would remain: %4ld Kb\n", (totalFootprint - totalPotentialGain) / 1024); - printf("-------------------------------------------------------------------------------------------------------------\n"); - printf("These stats come from the nsStyleContextData structures that have been deleted since the last output.\n"); - printf("To get the stats for a particular page: load page, dump stats, load 'about:blank', dump stats again.\n"); - printf("-------------------------------------------------------------------------------------------------------------\n"); - printf("\n\n\n"); - } - - if (resetCounters) { - resetCounters = false; - totalCount = 0; - for (short i = 0; i < max_structs; i ++) { - defaultStruct[i] = 0L; - setFromParent[i] = 0L; - } - } - - if (!aStyleContextData) { - printf ("*** aStyleContextData is nil\n"); - return; - } - - totalCount++; - for (short i = 0; i < max_structs; i ++) { - short index = i+1; - switch (index) { - case eStyleStruct_Font: - if (aStyleContextData->mFont.CalcDifference(aStyleContextData->mFont.mInternalFont) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mFont.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Color: - if (aStyleContextData->mColor.CalcDifference(aStyleContextData->mColor.mInternalColor) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mColor.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_List: - if (aStyleContextData->mList.CalcDifference(aStyleContextData->mList.mInternalList) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mList.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Position: - if (aStyleContextData->mPosition.CalcDifference(aStyleContextData->mPosition.mInternalPosition) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mPosition.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Text: - if (aStyleContextData->mText.CalcDifference(aStyleContextData->mText.mInternalText) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mText.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Display: - if (aStyleContextData->mDisplay.CalcDifference(aStyleContextData->mDisplay.mInternalDisplay) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mDisplay.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Table: - if (aStyleContextData->mTable.CalcDifference(aStyleContextData->mTable.mInternalTable) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mTable.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Content: - if (aStyleContextData->mContent.CalcDifference(aStyleContextData->mContent.mInternalContent) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mContent.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_UserInterface: - if (aStyleContextData->mUserInterface.CalcDifference(aStyleContextData->mUserInterface.mInternalUserInterface) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mUserInterface.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Print: - if (aStyleContextData->mPrint.CalcDifference(aStyleContextData->mPrint.mInternalPrint) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mPrint.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Margin: - if (aStyleContextData->mMargin.CalcDifference(aStyleContextData->mMargin.mInternalMargin) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mMargin.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Padding: - if (aStyleContextData->mPadding.CalcDifference(aStyleContextData->mPadding.mInternalPadding) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mPadding.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Border: - if (aStyleContextData->mBorder.CalcDifference(aStyleContextData->mBorder.mInternalBorder) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mBorder.mSetFromParent) - setFromParent[i]++; - } - break; - case eStyleStruct_Outline: - if (aStyleContextData->mOutline.CalcDifference(aStyleContextData->mOutline.mInternalOutline) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mOutline.mSetFromParent) - setFromParent[i]++; - } - break; + else { + result = new STYLEBLOB(Font); + } + break; + case eStyleStruct_Color: result = new STYLEBLOB(Color); break; + case eStyleStruct_List: result = new STYLEBLOB(List); break; + case eStyleStruct_Position: result = new STYLEBLOB(Position); break; + case eStyleStruct_Text: result = new STYLEBLOB(Text); break; + case eStyleStruct_Display: result = new STYLEBLOB(Display); break; + case eStyleStruct_Table: result = new STYLEBLOB(Table); break; + case eStyleStruct_Content: result = new STYLEBLOB(Content); break; + case eStyleStruct_UserInterface: result = new STYLEBLOB(UserInterface); break; + case eStyleStruct_Print: result = new STYLEBLOB(Print); break; + case eStyleStruct_Margin: result = new STYLEBLOB(Margin); break; + case eStyleStruct_Padding: result = new STYLEBLOB(Padding); break; + case eStyleStruct_Border: result = new STYLEBLOB(Border); break; + case eStyleStruct_Outline: result = new STYLEBLOB(Outline); break; #ifdef INCLUDE_XUL - case eStyleStruct_XUL: - if (aStyleContextData->mXUL.CalcDifference(aStyleContextData->mXUL.mInternalXUL) == NS_STYLE_HINT_NONE) { - defaultStruct[i]++; - if (aStyleContextData->mXUL.mSetFromParent) - setFromParent[i]++; - } - break; + case eStyleStruct_XUL: result = new STYLEBLOB(XUL); break; #endif + //#insert new style structs here# + default: + NS_ERROR("Invalid style struct id"); + break; + } + NS_ASSERTION(result != nsnull, "Out of mem"); + return result; +} + +// --------------------- +// CanShareStyleData +// Sharing of style data for the GfxScrollFrame is problematic +// and is currently disabled. These pseudos indicate the use of a GfxScrollFrame +// so we check for them and disallow sharing when any are found. +// If you haven't guessed it, this is a total hack until we can figure out +// why the GfxScrollFrame is not happy having its style data shared... +// (See bugzilla bug 39618 which also documents this problem) +// +static PRBool CanShareStyleData(nsIStyleContext* aStyleContext) +{ + PRBool isSharingSupported = PR_TRUE; + + nsIAtom* pseudoTag; + aStyleContext->GetPseudoType(pseudoTag); + if (pseudoTag) { + if (pseudoTag == nsLayoutAtoms::viewportPseudo || + pseudoTag == nsLayoutAtoms::canvasPseudo || + pseudoTag == nsLayoutAtoms::viewportScrollPseudo || + pseudoTag == nsLayoutAtoms::scrolledContentPseudo || + pseudoTag == nsLayoutAtoms::selectScrolledContentPseudo) { + isSharingSupported = PR_FALSE; + } else { + isSharingSupported = PR_TRUE; + } + } + NS_IF_RELEASE(pseudoTag); + + return isSharingSupported; +} + + +// --------------------- +// AllocateStyleBlobs +// +nsresult nsStyleContextData::AllocateStyleBlobs(nsIStyleContext* aStyleContext, nsIPresContext *aPresContext) +{ + short i; + + // clear the pointers: we'll inherit from the parent (if we have a parent) + for (i = 0; i < eStyleStruct_Max; i ++) { + mBlobArray[i] = nsnull; + } + + if (CanShareStyleData(aStyleContext)) { + nsIStyleContext* parent = aStyleContext->GetParent(); + if (parent != nsnull) { + NS_RELEASE(parent); + return NS_OK; } } - static short inCount = 0; - static short outCount = 0; - if (inCount++ % 1000 == 0) { - switch (outCount++) { - case 0: printf("still logging"); break; - case 20: printf("\n"); outCount = 0; break; - default: printf("."); fflush(stdout); break; + // no parent: allocate the blobs + for (i = 0; i < eStyleStruct_Max; i ++) { + nsStyleStructID structID = (nsStyleStructID)(i + 1); + mBlobArray[i] = AllocateOneBlob(structID, aPresContext); + if (!mBlobArray[i]) { + return NS_ERROR_OUT_OF_MEMORY; } } + return NS_OK; +} + +// --------------------- +// DeleteStyleBlobs +// +#define NS_IF_DELETE(ptr) \ + if (nsnull != ptr) { delete ptr; ptr = nsnull; } + +void nsStyleContextData::DeleteStyleBlobs() { + for (short i = 0; i < eStyleStruct_Max; i ++) { + NS_IF_DELETE(mBlobArray[i]); + } } -#endif // LOG_STYLE_STRUCTS - -//========================================================================================================= +// --------------------- +// nsStyleContextData dtor +// nsStyleContextData::~nsStyleContextData(void) { +#ifdef SHARE_STYLECONTEXTS NS_ASSERTION(0 == mRefCnt, "RefCount error in ~nsStyleContextData"); +#endif // debug here... #ifdef LOG_STYLE_STRUCTS LogStyleStructs(this); #endif + DeleteStyleBlobs(); } +// --------------------- +// ComputeCRC32 +// +#ifdef COMPUTE_STYLEDATA_CRC PRUint32 nsStyleContextData::ComputeCRC32(PRUint32 aCrc) const { PRUint32 crc = aCrc; -#ifdef COMPUTE_STYLEDATA_CRC - // have each style struct compute its own CRC, propogating the previous value... - crc = mFont.ComputeCRC32(crc); - crc = mColor.ComputeCRC32(crc); - crc = mList.ComputeCRC32(crc); - crc = mPosition.ComputeCRC32(crc); - crc = mText.ComputeCRC32(crc); - crc = mDisplay.ComputeCRC32(crc); - crc = mTable.ComputeCRC32(crc); - crc = mContent.ComputeCRC32(crc); - crc = mUserInterface.ComputeCRC32(crc); - crc = mPrint.ComputeCRC32(crc); - crc = mMargin.ComputeCRC32(crc); - crc = mPadding.ComputeCRC32(crc); - crc = mBorder.ComputeCRC32(crc); - crc = mOutline.ComputeCRC32(crc); -#ifdef INCLUDE_XUL - crc = mXUL.ComputeCRC32(crc); -#endif -#else - crc = 0; -#endif - + // have each style blob compute its own CRC, propagating the previous value... + for (short i = 0; i < eStyleStruct_Max; i ++) { + if (mBlobArray[i]) { + crc = mBlobArray[i]->ComputeCRC32(crc); + } + } return crc; } +#endif +// --------------------- +// SizeOf +// void nsStyleContextData::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) { NS_ASSERTION(aSizeOfHandler, "SizeOfHandler cannot be null in SizeOf"); @@ -2497,13 +2341,34 @@ void nsStyleContextData::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSiz tag = getter_AddRefs(NS_NewAtom("StyleContextData")); // get the size of an empty instance and add to the sizeof handler aSize = sizeof(*this); + // add the sizes of the individual style blobs + if (mData.mFont) aSize += sizeof(StyleFontBlob); + if (mData.mColor) aSize += sizeof(StyleColorBlob); + if (mData.mList) aSize += sizeof(StyleListBlob); + if (mData.mPosition) aSize += sizeof(StylePositionBlob); + if (mData.mText) aSize += sizeof(StyleTextBlob); + if (mData.mDisplay) aSize += sizeof(StyleDisplayBlob); + if (mData.mTable) aSize += sizeof(StyleTableBlob); + if (mData.mContent) aSize += sizeof(StyleContentBlob); + if (mData.mUserInterface) aSize += sizeof(StyleUserInterfaceBlob); + if (mData.mPrint) aSize += sizeof(StylePrintBlob); + if (mData.mMargin) aSize += sizeof(StyleMarginBlob); + if (mData.mPadding) aSize += sizeof(StylePaddingBlob); + if (mData.mBorder) aSize += sizeof(StyleBorderBlob); + if (mData.mOutline) aSize += sizeof(StyleOutlineBlob); +#ifdef INCLUDE_XUL + if (mData.mXUL) aSize += sizeof(StyleXULBlob); +#endif + //#insert new style structs here# + aSizeOfHandler->AddSize(tag,aSize); } -#endif //#ifdef SHARE_STYLECONTEXTS - -//---------------------------------------------------------------------- +//------------------------------------------------------------------------------ +// StyleContextImpl +//------------------------------------------------------------------------------ +// class StyleContextImpl : public nsIStyleContext, protected nsIMutableStyleContext { // you can't QI to nsIMutableStyleContext public: @@ -2527,20 +2392,34 @@ public: virtual PRBool Equals(const nsIStyleContext* aOther) const; virtual PRUint32 HashValue(void) const; + virtual nsresult WrapRemapStyle(nsIPresContext* aPresContext, PRBool aEnterRemapStyle); NS_IMETHOD RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse = PR_TRUE); + //--------------------------- + // Read/Write Style Data NS_IMETHOD GetStyle(nsStyleStructID aSID, nsStyleStruct& aStruct) const; - NS_IMETHOD SetStyle(nsStyleStructID aSID, const nsStyleStruct& aStruct); + inline virtual const nsStyleStruct* GetStyleData(nsStyleStructID aSID); - virtual const nsStyleStruct* GetStyleData(nsStyleStructID aSID); - virtual nsStyleStruct* GetMutableStyleData(nsStyleStructID aSID); +protected: + inline const nsStyleStruct* FetchInheritedStyleStruct(nsStyleStructID aSID) const { + return FetchInheritedStyleBlob(aSID)->GetData(); + }; + virtual StyleBlob* FetchInheritedStyleBlob(nsStyleStructID aSID) const; + virtual void ReadMutableStyleData(nsStyleStructID aSID, nsStyleStruct** aStyleStructPtr); + virtual nsresult WriteMutableStyleData(nsStyleStructID aSID, nsStyleStruct* aStyleStruct); + virtual nsresult WriteStyleData(nsStyleStructID aSID, const nsStyleStruct* aStyleStruct); + //--------------------------- +public: virtual void ForceUnique(void); virtual void RecalcAutomaticData(nsIPresContext* aPresContext); virtual void CalcBorderPaddingFor(const nsIFrame* aFrame, nsMargin& aBorderPadding) const; NS_IMETHOD CalcStyleDifference(nsIStyleContext* aOther, PRInt32& aHint,PRBool aStopAtFirstDifference = PR_FALSE) const; #ifdef SHARE_STYLECONTEXTS + //--------------------------- + // Style Context Sharing + // // evaluate and execute the style data sharing // - if nothing to share, it leaves the current style data intact, // otherwise it calls ShareStyleDataFrom to share another context's data @@ -2564,8 +2443,11 @@ public: // update the style set cache by adding this context to it // - NOTE: mStyleSet member must be set nsresult UpdateStyleSetCache( void ) const; -#endif +#endif // SHARE_STYLECONTEXTS + //--------------------------- + // Regression Data + // virtual void List(FILE* out, PRInt32 aIndent); virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); @@ -2590,32 +2472,13 @@ protected: nsISupportsArray* mRules; PRInt16 mDataCode; -#ifdef SHARE_STYLECONTEXTS - - nsStyleContextData* mStyleData; - -#else - - // the style data... - StyleFontImpl mFont; - StyleColorImpl mColor; - StyleListImpl mList; - StylePositionImpl mPosition; - StyleTextImpl mText; - StyleDisplayImpl mDisplay; - StyleTableImpl mTable; - StyleContentImpl mContent; - StyleUserInterfaceImpl mUserInterface; - StylePrintImpl mPrint; - StyleMarginImpl mMargin; - StylePaddingImpl mPadding; - StyleBorderImpl mBorder; - StyleOutlineImpl mOutline; -#ifdef INCLUDE_XUL - StyleXULImpl mXUL; +#ifdef LOG_WRITE_STYLE_DATA_CALLS +public: +#endif + nsStyleContextData* mStyleData; +#ifndef SHARE_STYLECONTEXTS + nsStyleContextData mStyleDataImpl; #endif - -#endif // #ifdef SHARE_STYLECONTEXTS // make sure we have valid style data nsresult EnsureStyleData(nsIPresContext* aPresContext); @@ -2636,6 +2499,10 @@ static PRBool HashStyleRule(nsISupports* aRule, void* aData) #pragma mark - #endif +//------------------------------------------------------------------------------ +// StyleContextImpl ctor +//------------------------------------------------------------------------------ +// StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent, nsIAtom* aPseudoTag, nsISupportsArray* aRules, @@ -2646,24 +2513,7 @@ StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent, mPseudoTag(aPseudoTag), mRules(aRules), mDataCode(-1), -#ifdef SHARE_STYLECONTEXTS mStyleData(nsnull) -#else - mFont(aPresContext->GetDefaultFontDeprecated(), aPresContext->GetDefaultFixedFontDeprecated()), - mColor(), - mSpacing(), - mList(), - mPosition(), - mText(), - mDisplay(), - mTable(), - mContent(), - mUserInterface(), -#ifdef INCLUDE_XUL - mXUL(), -#endif - mPrint() -#endif { NS_INIT_REFCNT(); NS_IF_ADDREF(mPseudoTag); @@ -2682,7 +2532,7 @@ StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent, } #ifdef SHARE_STYLECONTEXTS - // remember the style set + // remember the style set (for style context sharing) nsIPresShell* shell = nsnull; aPresContext->GetShell(&shell); if (shell) { @@ -2692,6 +2542,11 @@ StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent, #endif // SHARE_STYLECONTEXTS } + +//------------------------------------------------------------------------------ +// StyleContextImpl dtor +//------------------------------------------------------------------------------ +// StyleContextImpl::~StyleContextImpl() { NS_ASSERTION((nsnull == mChild) && (nsnull == mEmptyChild), "destructing context with children"); @@ -2711,6 +2566,7 @@ StyleContextImpl::~StyleContextImpl() } else { NS_ASSERTION(0, "StyleSet is not optional in a StyleContext's dtor..."); } + // release the style data so it can be reclaimed when no longer referenced NS_IF_RELEASE(mStyleData); #endif // SHARE_STYLECONTEXTS @@ -2719,6 +2575,11 @@ StyleContextImpl::~StyleContextImpl() NS_IMPL_ADDREF(StyleContextImpl) NS_IMPL_RELEASE(StyleContextImpl) + +//------------------------------------------------------------------------------ +// QueryInterface +//------------------------------------------------------------------------------ +// NS_IMETHODIMP StyleContextImpl::QueryInterface(const nsIID& aIID, void** aInstancePtr) { @@ -2740,12 +2601,20 @@ StyleContextImpl::QueryInterface(const nsIID& aIID, void** aInstancePtr) return NS_NOINTERFACE; } +//------------------------------------------------------------------------------ +// GetParent +//------------------------------------------------------------------------------ +// nsIStyleContext* StyleContextImpl::GetParent(void) const { NS_IF_ADDREF(mParent); return mParent; } +//------------------------------------------------------------------------------ +// AppendChild +//------------------------------------------------------------------------------ +// void StyleContextImpl::AppendChild(StyleContextImpl* aChild) { if (0 == aChild->GetStyleRuleCount()) { @@ -2772,6 +2641,10 @@ void StyleContextImpl::AppendChild(StyleContextImpl* aChild) } } +//------------------------------------------------------------------------------ +// RemoveChild +//------------------------------------------------------------------------------ +// void StyleContextImpl::RemoveChild(StyleContextImpl* aChild) { NS_ASSERTION((nsnull != aChild) && (this == aChild->mParent), "bad argument"); @@ -2810,6 +2683,10 @@ void StyleContextImpl::RemoveChild(StyleContextImpl* aChild) aChild->mPrevSibling = aChild; } +//------------------------------------------------------------------------------ +// GetStyleRules +//------------------------------------------------------------------------------ +// nsISupportsArray* StyleContextImpl::GetStyleRules(void) const { nsISupportsArray* result = mRules; @@ -2817,6 +2694,10 @@ nsISupportsArray* StyleContextImpl::GetStyleRules(void) const return result; } +//------------------------------------------------------------------------------ +// GetStyleRuleCount +//------------------------------------------------------------------------------ +// PRInt32 StyleContextImpl::GetStyleRuleCount(void) const { if (nsnull != mRules) { @@ -2828,6 +2709,10 @@ PRInt32 StyleContextImpl::GetStyleRuleCount(void) const return 0; } +//------------------------------------------------------------------------------ +// GetPseudoType +//------------------------------------------------------------------------------ +// NS_IMETHODIMP StyleContextImpl::GetPseudoType(nsIAtom*& aPseudoTag) const { @@ -2836,6 +2721,10 @@ StyleContextImpl::GetPseudoType(nsIAtom*& aPseudoTag) const return NS_OK; } +//------------------------------------------------------------------------------ +// FindChildWithRules +//------------------------------------------------------------------------------ +// NS_IMETHODIMP StyleContextImpl::FindChildWithRules(const nsIAtom* aPseudoTag, nsISupportsArray* aRules, @@ -2892,7 +2781,10 @@ StyleContextImpl::FindChildWithRules(const nsIAtom* aPseudoTag, return NS_OK; } - +//------------------------------------------------------------------------------ +// Equals +//------------------------------------------------------------------------------ +// PRBool StyleContextImpl::Equals(const nsIStyleContext* aOther) const { PRBool result = PR_TRUE; @@ -2925,271 +2817,62 @@ PRBool StyleContextImpl::Equals(const nsIStyleContext* aOther) const return result; } +//------------------------------------------------------------------------------ +// HashValue +//------------------------------------------------------------------------------ +// PRUint32 StyleContextImpl::HashValue(void) const { return mRuleHash; } -//========================================================================================================= -#ifdef DEBUG -// define this to get statistics on the number of calls -// to GetStyleData() and their depth in the Style tree. -//#define LOG_GET_STYLE_DATA_CALLS //XXX pierre -#endif - -#ifdef LOG_GET_STYLE_DATA_CALLS - -#ifdef XP_MAC -#include <Events.h> -#include <Timer.h> -static bool MacKeyDown(unsigned char theKey) +//------------------------------------------------------------------------------ +// FetchInheritedStyleBlob +//------------------------------------------------------------------------------ +// For a given type of style data, get the first non-null pointer +// in the style context hierarchy, . When a pointer is null, it means +// that we are inheriting that particular style from the parent. Style +// contexts without parent have all their style data allocated. +// +// IMPORTANT: Do not use the GETDATA() macros in this function +// +StyleBlob* StyleContextImpl::FetchInheritedStyleBlob(nsStyleStructID aSID) const { - KeyMap map; - GetKeys(map); - return ((*((unsigned char *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0; -} -#endif - - -static bool IsTimeToDumpGetStyleDataCalls() -{ - bool timeToDump = false; -#ifdef XP_MAC - static unsigned long lastTicks = 0; - if (MacKeyDown(0x3b)) { // control key - if ((unsigned long)(::TickCount() - lastTicks) > 60) { - lastTicks = ::TickCount(); - timeToDump = true; - } - } -#endif - return timeToDump; -} - -enum LogCallType { - logCallType_GetStyleData = 0, - logCallType_GetMutableStyleData, - logCallType_GetStyle, - - logCallType_Max -}; - -static void LogGetStyleDataCall(nsStyleStructID aSID, LogCallType aLogCallType, nsIStyleContext* aStyleContext, bool aEnteringFunction) -{ -#define max_structs (eStyleStruct_Max + 1) -#define small_depth_threshold 8 - - static unsigned long calls[max_structs*logCallType_Max]; - static unsigned long callspercent[max_structs*logCallType_Max]; - static unsigned long depth[max_structs*logCallType_Max]; - static unsigned long maxdepth[max_structs*logCallType_Max]; - static unsigned long smalldepth[max_structs*logCallType_Max]; - static unsigned long microsecs[logCallType_Max]; - static unsigned long totalMicrosecs; - static UnsignedWide startMicrosecs; - static UnsignedWide endMicrosecs; - - if (!aEnteringFunction) { - ::Microseconds(&endMicrosecs); - totalMicrosecs += endMicrosecs.lo - startMicrosecs.lo; - microsecs[aLogCallType] += endMicrosecs.lo - startMicrosecs.lo; - return; - } - - - static bool resetCounters = true; - - if (IsTimeToDumpGetStyleDataCalls()) { - resetCounters = true; - - unsigned long totalCalls; - unsigned long totalMaxdepth; - unsigned long totalDepth; - for (short i = 0; i < (max_structs*logCallType_Max); i ++) { - - if (i%max_structs == 0) { - switch (i/max_structs) { - case 0: - printf("\n\n\n"); - printf("----GetStyleData--------------------------------------------------------------------------\n"); - printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold); - break; - case 1: - printf("----GetMutableStyleData-------------------------------------------------------------------\n"); - printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold); - break; - case 2: - printf("----GetStyle------------------------------------------------------------------------------\n"); - printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold); - break; - } - - totalCalls = totalMaxdepth = totalDepth = 0; - for (short j = i; j < i + max_structs; j++) { - totalCalls += calls[j]; - totalDepth += depth[j]; - if (totalMaxdepth < maxdepth[j]) { - totalMaxdepth = maxdepth[j]; - } - } - } - - switch (i%max_structs + 1) { - case eStyleStruct_Font: printf("eStyleStruct_Font "); break; - case eStyleStruct_Color: printf("eStyleStruct_Color "); break; - case eStyleStruct_List: printf("eStyleStruct_List "); break; - case eStyleStruct_Position: printf("eStyleStruct_Position "); break; - case eStyleStruct_Text: printf("eStyleStruct_Text "); break; - case eStyleStruct_Display: printf("eStyleStruct_Display "); break; - case eStyleStruct_Table: printf("eStyleStruct_Table "); break; - case eStyleStruct_Content: printf("eStyleStruct_Content "); break; - case eStyleStruct_UserInterface: printf("eStyleStruct_UserInterface "); break; - case eStyleStruct_Print: printf("eStyleStruct_Print "); break; - case eStyleStruct_Margin: printf("eStyleStruct_Margin "); break; - case eStyleStruct_Padding: printf("eStyleStruct_Padding "); break; - case eStyleStruct_Border: printf("eStyleStruct_Border "); break; - case eStyleStruct_Outline: printf("eStyleStruct_Outline "); break; - case eStyleStruct_BorderPaddingShortcut: printf("BorderPaddingShortcut "); break; -#ifdef INCLUDE_XUL - case eStyleStruct_XUL: printf("eStyleStruct_XUL "); break; -#endif - } - short percent = 100*calls[i]/totalCalls; - short avdepth = calls[i] == 0 ? 0 : round(float(depth[i])/float(calls[i])); - short smdepth = 100*smalldepth[i]/calls[i]; - if (percent == 0) { - printf(" %7ld - %3ld %3d %3d\n", calls[i], maxdepth[i], avdepth, smdepth); - } - else { - printf(" %7ld %2ld %3ld %3d %3d\n", calls[i], percent, maxdepth[i], avdepth, smdepth); - } - - if (i%max_structs + 1 == max_structs) { - short totaldepth = totalCalls == 0 ? 0 : round(float(totalDepth)/float(totalCalls)); - printf("TOTAL "); - printf(" %7ld 100 %3ld %3d %ld ms\n", totalCalls, totalMaxdepth, totaldepth, microsecs[i/max_structs]/1000); - } - - } - printf("------------------------------------------------------------------------------------------\n"); - printf("TOTAL time = %ld microsecs (= %ld ms)\n", totalMicrosecs, totalMicrosecs/1000); - printf("------------------------------------------------------------------------------------------\n\n\n"); - } - - if (resetCounters) { - resetCounters = false; - totalMicrosecs = 0; - for (short i = 0; i < logCallType_Max; i ++) { - microsecs[i] = 0L; - } - for (short i = 0; i < (max_structs*logCallType_Max); i ++) { - calls[i] = 0L; - depth[i] = 0L; - maxdepth[i] = 0L; - smalldepth[i] = 0L; - } - } + NS_PRECONDITION(aSID > 0 && aSID <= eStyleStruct_Max, "Invalid style struct id"); short index = aSID - 1; - index += max_structs * aLogCallType; - - calls[index]++; - - unsigned long curdepth = 0; - nsCOMPtr<nsIStyleContext> childContext; - nsCOMPtr<nsIStyleContext> parentContext; - childContext = aStyleContext; - parentContext = getter_AddRefs(childContext->GetParent()); - while (parentContext != nsnull) { - curdepth++; - parentContext = getter_AddRefs(childContext->GetParent()); - if (parentContext == childContext) { + StyleBlob* result = nsnull; + const StyleContextImpl* sc = this; + while (sc) { + result = sc->BLOBARRAY[index]; + if (result) { break; } - childContext = parentContext; + sc = sc->mParent; } - depth[index] += curdepth; - if (maxdepth[index] < curdepth) { - maxdepth[index] = curdepth; + if (result == nsnull) { + NS_WARNING("Did not find style blob"); + // Allocate the missing blob. This should never happen, but who knows? + BLOBARRAY[index] = mStyleData->AllocateOneBlob(aSID, nsnull); + result = BLOBARRAY[index]; } - if (curdepth <= small_depth_threshold) { - smalldepth[index]++; - } - - static short inCount = 0; - static short outCount = 0; - if (inCount++ % 1000 == 0) { - switch (outCount++) { - case 0: printf("still logging"); break; - case 20: printf("\n"); outCount = 0; break; - default: printf("."); fflush(stdout); break; - } - } - ::Microseconds(&startMicrosecs); + return result; } -#endif // LOG_GET_STYLE_DATA_CALLS -//========================================================================================================= +//------------------------------------------------------------------------------ +// GetStyleData +//------------------------------------------------------------------------------ +// const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID) { + NS_PRECONDITION(aSID > 0 && aSID <= eStyleStruct_Max, "Invalid style struct id"); + #ifdef LOG_GET_STYLE_DATA_CALLS LogGetStyleDataCall(aSID, logCallType_GetStyleData, this, true); #endif - nsStyleStruct* result = nsnull; + const nsStyleStruct* result = FetchInheritedStyleStruct(aSID); - switch (aSID) { - case eStyleStruct_Font: - result = & GETSCDATA(Font); - break; - case eStyleStruct_Color: - result = & GETSCDATA(Color); - break; - case eStyleStruct_List: - result = & GETSCDATA(List); - break; - case eStyleStruct_Position: - result = & GETSCDATA(Position); - break; - case eStyleStruct_Text: - result = & GETSCDATA(Text); - break; - case eStyleStruct_Display: - result = & GETSCDATA(Display); - break; - case eStyleStruct_Table: - result = & GETSCDATA(Table); - break; - case eStyleStruct_Content: - result = & GETSCDATA(Content); - break; - case eStyleStruct_UserInterface: - result = & GETSCDATA(UserInterface); - break; - case eStyleStruct_Print: - result = & GETSCDATA(Print); - break; - case eStyleStruct_Margin: - result = & GETSCDATA(Margin); - break; - case eStyleStruct_Padding: - result = & GETSCDATA(Padding); - break; - case eStyleStruct_Border: - result = & GETSCDATA(Border); - break; - case eStyleStruct_Outline: - result = & GETSCDATA(Outline); - break; -#ifdef INCLUDE_XUL - case eStyleStruct_XUL: - result = & GETSCDATA(XUL); - break; -#endif - default: - NS_ERROR("Invalid style struct id"); - break; - } #ifdef LOG_GET_STYLE_DATA_CALLS LogGetStyleDataCall(aSID, logCallType_GetStyleData, this, false); #endif @@ -3197,91 +2880,227 @@ const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID) return result; } -nsStyleStruct* StyleContextImpl::GetMutableStyleData(nsStyleStructID aSID) -{ -#ifdef LOG_GET_STYLE_DATA_CALLS - LogGetStyleDataCall(aSID, logCallType_GetMutableStyleData, this, true); +//------------------------------------------------------------------------------ +// GetNewMutableStyleStruct [static] +//------------------------------------------------------------------------------ +// Notes: +// - We can't get more than 4 mutable style structs of the same type at the same time. +// - Keep in sync with the comments in the declaration of ReadMutableStyleData() +// in nsIMutableStyleContext.h and nsIStyleContext.h +const short kStructIndexMax = 4; + +static STYLEDATA(Font) gStructFont[kStructIndexMax]; +static STYLEDATA(Color) gStructColor[kStructIndexMax]; +static STYLEDATA(List) gStructList[kStructIndexMax]; +static STYLEDATA(Position) gStructPosition[kStructIndexMax]; +static STYLEDATA(Text) gStructText[kStructIndexMax]; +static STYLEDATA(Display) gStructDisplay[kStructIndexMax]; +static STYLEDATA(Table) gStructTable[kStructIndexMax]; +static STYLEDATA(Content) gStructContent[kStructIndexMax]; +static STYLEDATA(UserInterface) gStructUserInterface[kStructIndexMax]; +static STYLEDATA(Print) gStructPrint[kStructIndexMax]; +static STYLEDATA(Margin) gStructMargin[kStructIndexMax]; +static STYLEDATA(Padding) gStructPadding[kStructIndexMax]; +static STYLEDATA(Border) gStructBorder[kStructIndexMax]; +static STYLEDATA(Outline) gStructOutline[kStructIndexMax]; +#ifdef INCLUDE_XUL +static STYLEDATA(XUL) gStructXUL[kStructIndexMax]; #endif +//#insert new style structs here# + +nsStyleStruct* gStructPointer[eStyleStruct_Max][kStructIndexMax]; +bool gStructBusy[eStyleStruct_Max][kStructIndexMax]; + + +static nsStyleStruct* GetNewMutableStyleStruct(nsStyleStructID aSID) { nsStyleStruct* result = nsnull; - switch (aSID) { - case eStyleStruct_Font: - result = & GETSCDATA(Font); - break; - case eStyleStruct_Color: - result = & GETSCDATA(Color); - break; - case eStyleStruct_List: - result = & GETSCDATA(List); - break; - case eStyleStruct_Position: - result = & GETSCDATA(Position); - break; - case eStyleStruct_Text: - result = & GETSCDATA(Text); - break; - case eStyleStruct_Display: - result = & GETSCDATA(Display); - break; - case eStyleStruct_Table: - result = & GETSCDATA(Table); - break; - case eStyleStruct_Content: - result = & GETSCDATA(Content); - break; - case eStyleStruct_UserInterface: - result = & GETSCDATA(UserInterface); - break; - case eStyleStruct_Print: - result = & GETSCDATA(Print); - break; - case eStyleStruct_Margin: - result = & GETSCDATA(Margin); - break; - case eStyleStruct_Padding: - result = & GETSCDATA(Padding); - break; - case eStyleStruct_Border: - result = & GETSCDATA(Border); - break; - case eStyleStruct_Outline: - result = & GETSCDATA(Outline); - break; + static bool initialized = false; + if (!initialized) { + initialized = true; + for (short structType = 0; structType < eStyleStruct_Max; structType++) { + nsStyleStructID structID = (nsStyleStructID)(structType + 1); + for (short structIndex = 0; structIndex < kStructIndexMax; structIndex++) { + nsStyleStruct* structPtr = nsnull; + switch (structID) { + case eStyleStruct_Font: structPtr = &gStructFont[structIndex]; break; + case eStyleStruct_Color: structPtr = &gStructColor[structIndex]; break; + case eStyleStruct_List: structPtr = &gStructList[structIndex]; break; + case eStyleStruct_Position: structPtr = &gStructPosition[structIndex]; break; + case eStyleStruct_Text: structPtr = &gStructText[structIndex]; break; + case eStyleStruct_Display: structPtr = &gStructDisplay[structIndex]; break; + case eStyleStruct_Table: structPtr = &gStructTable[structIndex]; break; + case eStyleStruct_Content: structPtr = &gStructContent[structIndex]; break; + case eStyleStruct_UserInterface: structPtr = &gStructUserInterface[structIndex]; break; + case eStyleStruct_Print: structPtr = &gStructPrint[structIndex]; break; + case eStyleStruct_Margin: structPtr = &gStructMargin[structIndex]; break; + case eStyleStruct_Padding: structPtr = &gStructPadding[structIndex]; break; + case eStyleStruct_Border: structPtr = &gStructBorder[structIndex]; break; + case eStyleStruct_Outline: structPtr = &gStructOutline[structIndex]; break; #ifdef INCLUDE_XUL - case eStyleStruct_XUL: - result = & GETSCDATA(XUL); - break; + case eStyleStruct_XUL: structPtr = &gStructXUL[structIndex]; break; #endif - default: - NS_ERROR("Invalid style struct id"); - break; + //#insert new style structs here# + default: + NS_ERROR("Invalid style struct id"); + break; + } + gStructPointer[structType][structIndex] = structPtr; + gStructBusy[structType][structIndex] = false; + } + } } + short structType = aSID - 1; + for (short structIndex = 0; structIndex < kStructIndexMax; structIndex++) { + if (!gStructBusy[structType][structIndex]) { + result = gStructPointer[structType][structIndex]; + gStructBusy[structType][structIndex] = true; + break; + } + } + if (!result) { + NS_ERROR("Reached maximum number of mutable style structs of a certain type"); + // Return something or we gonna crash: callers don't always check the returned pointer. + // By returning a structure which is already in use, we'll only have rendering errors. + // Anyhow, this is just a safety fallback, in case people in the future don't follow + // the instructions in "nsIMutableStyleContext.h" about the limit on mutable pointers + // that one can get at any single time. + result = gStructPointer[structType][0]; + } + return result; +} + +//------------------------------------------------------------------------------ +// ReleaseMutableStyleStruct [static] +//------------------------------------------------------------------------------ +// Retrieve the pointer we gave them and mark it free again. +// A linear search is fine: we have only 4 elements to iterate through. +// +static void ReleaseMutableStyleStruct(nsStyleStructID aSID, nsStyleStruct* aStyleStruct) +{ + short structType = aSID - 1; + for (short structIndex = 0; structIndex < kStructIndexMax; structIndex++) { + if (gStructPointer[structType][structIndex] == aStyleStruct) { + gStructBusy[structType][structIndex] = false; + return; + } + } + NS_ASSERTION(false, "Can't release mutable style struct"); +} + + +//------------------------------------------------------------------------------ +// ReadMutableStyleData +//------------------------------------------------------------------------------ +// Receive a style structure and fill it up with the inherited style. +// +void StyleContextImpl::ReadMutableStyleData(nsStyleStructID aSID, nsStyleStruct** aStyleStructPtr) +{ + NS_PRECONDITION(aSID > 0 && aSID <= eStyleStruct_Max, "Invalid style struct id"); + +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, logCallType_ReadMutableStyleData, this, true); +#endif +#ifdef LOG_STYLE_STRUCTS + mStyleData->mGotMutable[aSID] = true; +#endif + + nsStyleStruct* result = GetNewMutableStyleStruct(aSID); + const StyleBlob* current = FetchInheritedStyleBlob(aSID); + current->CopyTo(result); + +#if 0 // was there in the previous function that returned direct pointers to the style data if (nsnull != result) { if (0 == mDataCode) { // mDataCode = ++gLastDataCode; // XXX temp disable, this is still used but not needed to force unique } } -#ifdef LOG_GET_STYLE_DATA_CALLS - LogGetStyleDataCall(aSID, logCallType_GetMutableStyleData, this, false); #endif - return result; +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, logCallType_ReadMutableStyleData, this, false); +#endif + + *aStyleStructPtr = result; } + +//------------------------------------------------------------------------------ +// WriteStyleData +//------------------------------------------------------------------------------ +// Basic function to write a style structure. +// Check whether the style is any different from the inherited style and if so, +// allocate a new blob (if needed) and copy the new style into it. +// +nsresult StyleContextImpl::WriteStyleData(nsStyleStructID aSID, const nsStyleStruct* aStyleStruct) +{ + NS_PRECONDITION(aSID > 0 && aSID <= eStyleStruct_Max, "Invalid style struct id"); + + short index = aSID - 1; + const StyleBlob* current = FetchInheritedStyleBlob(aSID); + PRInt32 hint = current->CalcDifference(aStyleStruct); + + if (hint != NS_STYLE_HINT_NONE) { + if (!BLOBARRAY[index]) { + BLOBARRAY[index] = mStyleData->AllocateOneBlob(aSID, nsnull); + if (!BLOBARRAY[index]) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + BLOBARRAY[index]->SetFrom(aStyleStruct); + } + return NS_OK; +} + +//------------------------------------------------------------------------------ +// WriteMutableStyleData +//------------------------------------------------------------------------------ +// Write a style structure that was filled-up in ReadMutableStyleData and that +// might have been modified by the app. +// +nsresult StyleContextImpl::WriteMutableStyleData(nsStyleStructID aSID, nsStyleStruct* aStyleStruct) +{ + NS_PRECONDITION(aSID > 0 && aSID <= eStyleStruct_Max, "Invalid style struct id"); + +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, logCallType_WriteMutableStyleData, this, true); +#endif +#ifdef LOG_WRITE_STYLE_DATA_CALLS + LogWriteMutableStyleDataCall(aSID, aStyleStruct, this); +#endif + + WriteStyleData(aSID, aStyleStruct); + ReleaseMutableStyleStruct(aSID, aStyleStruct); + +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, logCallType_WriteMutableStyleData, this, false); +#endif + return NS_OK; +} + +//------------------------------------------------------------------------------ +// CalcBorderPaddingFor +//------------------------------------------------------------------------------ +// void StyleContextImpl::CalcBorderPaddingFor(const nsIFrame* aFrame, nsMargin& aBorderPadding) const { nsMargin border, padding; - if (!GETSCDATA(Border).GetBorder(border)) { - GETSCDATA(Border).CalcBorderFor(aFrame, border); + + if (!GETDATA(Border)->GetBorder(border)) { + GETDATA(Border)->CalcBorderFor(aFrame, border); } - if (!GETSCDATA(Padding).GetPadding(padding)) { - GETSCDATA(Padding).CalcPaddingFor(aFrame, padding); + if (!GETDATA(Padding)->GetPadding(padding)) { + GETDATA(Padding)->CalcPaddingFor(aFrame, padding); } aBorderPadding = border + padding; } +//------------------------------------------------------------------------------ +// GetStyle +//------------------------------------------------------------------------------ +// NS_IMETHODIMP StyleContextImpl::GetStyle(nsStyleStructID aSID, nsStyleStruct& aStruct) const { @@ -3289,139 +3108,39 @@ StyleContextImpl::GetStyle(nsStyleStructID aSID, nsStyleStruct& aStruct) const LogGetStyleDataCall(aSID, logCallType_GetStyle, (nsIStyleContext*)this, true); #endif - nsresult result = NS_OK; - switch (aSID) { - case eStyleStruct_Font: - GETSCDATA(Font).CopyTo((nsStyleFont&)aStruct); - break; - case eStyleStruct_Color: - GETSCDATA(Color).CopyTo((nsStyleColor&)aStruct); - break; - case eStyleStruct_List: - GETSCDATA(List).CopyTo((nsStyleList&)aStruct); - break; - case eStyleStruct_Position: - GETSCDATA(Position).CopyTo((nsStylePosition&)aStruct); - break; - case eStyleStruct_Text: - GETSCDATA(Text).CopyTo((nsStyleText&)aStruct); - break; - case eStyleStruct_Display: - GETSCDATA(Display).CopyTo((nsStyleDisplay&)aStruct); - break; - case eStyleStruct_Table: - GETSCDATA(Table).CopyTo((nsStyleTable&)aStruct); - break; - case eStyleStruct_Content: - GETSCDATA(Content).CopyTo((nsStyleContent&)aStruct); - break; - case eStyleStruct_UserInterface: - GETSCDATA(UserInterface).CopyTo((nsStyleUserInterface&)aStruct); - break; - case eStyleStruct_Print: - GETSCDATA(Print).CopyTo((nsStylePrint&)aStruct); - break; - case eStyleStruct_Margin: - GETSCDATA(Margin).CopyTo((nsStyleMargin&)aStruct); - break; - case eStyleStruct_Padding: - GETSCDATA(Padding).CopyTo((nsStylePadding&)aStruct); - break; - case eStyleStruct_Border: - GETSCDATA(Border).CopyTo((nsStyleBorder&)aStruct); - break; - case eStyleStruct_Outline: - GETSCDATA(Outline).CopyTo((nsStyleOutline&)aStruct); - break; -#ifdef INCLUDE_XUL - case eStyleStruct_XUL: - GETSCDATA(XUL).CopyTo((nsStyleXUL&)aStruct); - break; -#endif - case eStyleStruct_BorderPaddingShortcut: { - nsMargin border, padding; - if (GETSCDATA(Border).GetBorder(border)) { - if (GETSCDATA(Padding).GetPadding(padding)) { - border += padding; - ((nsStyleBorderPadding&)aStruct).SetBorderPadding(border); - } + if (aSID == eStyleStruct_BorderPaddingShortcut) { + nsMargin border, padding; + PRBool hasBorder = GETDATA(Border)->GetBorder(border); + PRBool hasPadding = GETDATA(Padding)->GetPadding(padding); + if (hasBorder) { + if (hasPadding) { + border += padding; } - break; + ((nsStyleBorderPadding&)aStruct).SetBorderPadding(border); } - default: - NS_ERROR("Invalid style struct id"); - result = NS_ERROR_INVALID_ARG; - break; + else { + if (hasPadding) { + ((nsStyleBorderPadding&)aStruct).SetBorderPadding(padding); + } + } + } + else { + NS_PRECONDITION(aSID > 0 && aSID <= eStyleStruct_Max, "Invalid style struct id"); + const StyleBlob* current = FetchInheritedStyleBlob(aSID); + current->CopyTo(&aStruct); + } + #ifdef LOG_GET_STYLE_DATA_CALLS LogGetStyleDataCall(aSID, logCallType_GetStyle, (nsIStyleContext*)this, false); #endif - - return result; + return NS_OK; } -NS_IMETHODIMP -StyleContextImpl::SetStyle(nsStyleStructID aSID, const nsStyleStruct& aStruct) -{ - nsresult result = NS_OK; - switch (aSID) { - case eStyleStruct_Font: - GETSCDATA(Font).SetFrom((const nsStyleFont&)aStruct); - break; - case eStyleStruct_Color: - GETSCDATA(Color).SetFrom((const nsStyleColor&)aStruct); - break; - case eStyleStruct_List: - GETSCDATA(List).SetFrom((const nsStyleList&)aStruct); - break; - case eStyleStruct_Position: - GETSCDATA(Position).SetFrom((const nsStylePosition&)aStruct); - break; - case eStyleStruct_Text: - GETSCDATA(Text).SetFrom((const nsStyleText&)aStruct); - break; - case eStyleStruct_Display: - GETSCDATA(Display).SetFrom((const nsStyleDisplay&)aStruct); - break; - case eStyleStruct_Table: - GETSCDATA(Table).SetFrom((const nsStyleTable&)aStruct); - break; - case eStyleStruct_Content: - GETSCDATA(Content).SetFrom((const nsStyleContent&)aStruct); - break; - case eStyleStruct_UserInterface: - GETSCDATA(UserInterface).SetFrom((const nsStyleUserInterface&)aStruct); - break; - case eStyleStruct_Print: - GETSCDATA(Print).SetFrom((const nsStylePrint&)aStruct); - break; - case eStyleStruct_Margin: - GETSCDATA(Margin).SetFrom((const nsStyleMargin&)aStruct); - break; - case eStyleStruct_Padding: - GETSCDATA(Padding).SetFrom((const nsStylePadding&)aStruct); - break; - case eStyleStruct_Border: - GETSCDATA(Border).SetFrom((const nsStyleBorder&)aStruct); - break; - case eStyleStruct_Outline: - GETSCDATA(Outline).SetFrom((const nsStyleOutline&)aStruct); - break; -#ifdef INCLUDE_XUL - case eStyleStruct_XUL: - GETSCDATA(XUL).SetFrom((const nsStyleXUL&)aStruct); - break; -#endif - default: - NS_ERROR("Invalid style struct id"); - result = NS_ERROR_INVALID_ARG; - break; - } - return result; -} - - - +//------------------------------------------------------------------------------ +// RemapStyle rules and helpers +//------------------------------------------------------------------------------ +// struct MapStyleData { MapStyleData(nsIMutableStyleContext* aStyleContext, nsIPresContext* aPresContext) { @@ -3448,6 +3167,184 @@ static PRBool MapStyleRule(nsISupports* aRule, void* aData) return PR_TRUE; } + +//-------------------------- +// EnsureBlockDisplay +// In order to enforce the floated/positioned element CSS2 rules, +// if the display type is not a block-type then we set it to a +// valid block display type. +// +static void EnsureBlockDisplay(/*in out*/PRUint8 &display) +{ + // see if the display value is already a block + switch (display) { + case NS_STYLE_DISPLAY_NONE : + // never change display:none *ever* + break; + + case NS_STYLE_DISPLAY_TABLE : + case NS_STYLE_DISPLAY_BLOCK : + // do not muck with these at all - already blocks + break; + + case NS_STYLE_DISPLAY_LIST_ITEM : + // do not change list items to blocks - retain the bullet/numbering + break; + + case NS_STYLE_DISPLAY_TABLE_ROW_GROUP : + case NS_STYLE_DISPLAY_TABLE_COLUMN : + case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP : + case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP : + case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP : + case NS_STYLE_DISPLAY_TABLE_ROW : + case NS_STYLE_DISPLAY_TABLE_CELL : + case NS_STYLE_DISPLAY_TABLE_CAPTION : + // special cases: don't do anything since these cannot really be floated anyway + break; + + case NS_STYLE_DISPLAY_INLINE_TABLE : + // make inline tables into tables + display = NS_STYLE_DISPLAY_TABLE; + break; + + default : + // make it a block + display = NS_STYLE_DISPLAY_BLOCK; + } +} + + +//------------------------------------------------------------------------------ +// WrapRemapStyle +//------------------------------------------------------------------------------ +// The way it works is... +// - When we enter RemapStyle(), we set the blob pointers that are null +// to point to the static blobs below. Then the app does all the +// remapping it wants, modifying as many of the style structs it needs. +// - When we exit RemapStyle(), we check whether each of the style structs are +// identical to our parent's. If it is, we set its blob to null (possibly +// deallocating the memory). If it is not, we keep it (possibly storing the +// data into a newly allocated blob). +// +nsresult StyleContextImpl::WrapRemapStyle(nsIPresContext* aPresContext, PRBool aEnterRemapStyle) +{ + static STYLEBLOB(Font) sFont; + static STYLEBLOB(Color) sColor; + static STYLEBLOB(List) sList; + static STYLEBLOB(Position) sPosition; + static STYLEBLOB(Text) sText; + static STYLEBLOB(Display) sDisplay; + static STYLEBLOB(Table) sTable; + static STYLEBLOB(Content) sContent; + static STYLEBLOB(UserInterface) sUserInterface; + static STYLEBLOB(Print) sPrint; + static STYLEBLOB(Margin) sMargin; + static STYLEBLOB(Padding) sPadding; + static STYLEBLOB(Border) sBorder; + static STYLEBLOB(Outline) sOutline; +#ifdef INCLUDE_XUL + static STYLEBLOB(XUL) sXUL; +#endif + //#insert new style structs here# + static StyleBlob* sBlobPtr[eStyleStruct_Max]; + + static PRBool initialized = PR_FALSE; + if (!initialized) { + initialized = PR_TRUE; + for (short i = 0; i < eStyleStruct_Max; i ++) { + StyleBlob* blobPtr = nsnull; + switch (i + 1) { + case eStyleStruct_Font: blobPtr = &sFont; break; + case eStyleStruct_Color: blobPtr = &sColor; break; + case eStyleStruct_List: blobPtr = &sList; break; + case eStyleStruct_Position: blobPtr = &sPosition; break; + case eStyleStruct_Text: blobPtr = &sText; break; + case eStyleStruct_Display: blobPtr = &sDisplay; break; + case eStyleStruct_Table: blobPtr = &sTable; break; + case eStyleStruct_Content: blobPtr = &sContent; break; + case eStyleStruct_UserInterface: blobPtr = &sUserInterface; break; + case eStyleStruct_Print: blobPtr = &sPrint; break; + case eStyleStruct_Margin: blobPtr = &sMargin; break; + case eStyleStruct_Padding: blobPtr = &sPadding; break; + case eStyleStruct_Border: blobPtr = &sBorder; break; + case eStyleStruct_Outline: blobPtr = &sOutline; break; +#ifdef INCLUDE_XUL + case eStyleStruct_XUL: blobPtr = &sXUL; break; +#endif + //#insert new style structs here# + default: + NS_ERROR("Invalid style struct id"); + break; + } + sBlobPtr[i] = blobPtr; + } + } + + if (aEnterRemapStyle) { + //------------------------ + // Entering RemapStyle()... + // Set the blob pointers that are null + // to point to the static blobs. +#ifdef DEBUG + if (mParent == nsnull) { + for (short i = 0; i < eStyleStruct_Max; i ++) { + if (BLOBARRAY[i] == nsnull) { + NS_ERROR("Parent context is null but style blob is not allocated"); + break; + } + } + } +#endif + for (short i = 0; i < eStyleStruct_Max; i ++) { + if (!BLOBARRAY[i]) { + BLOBARRAY[i] = sBlobPtr[i]; + } + nsStyleStructID structID = (nsStyleStructID)(i + 1); + const nsStyleStruct* parentStyle = nsnull; + if (mParent) { + parentStyle = mParent->FetchInheritedStyleStruct(structID); + } + BLOBARRAY[i]->ResetFrom(parentStyle, aPresContext); + } + } + else { + //------------------------ + // Exiting RemapStyle()... + // Check whether each of our style structs are identical to our parent's. + // If it is, we set its blob to null (possibly deallocating the memory). + // If it is not, we keep it (possibly storing the data into a newly allocated blob). + if (mParent != nsnull) { + PRInt32 hint; + for (short i = 0; i < eStyleStruct_Max; i ++) { + nsStyleStructID structID = (nsStyleStructID)(i + 1); + hint = BLOBARRAY[i]->CalcDifference(mParent->FetchInheritedStyleStruct(structID)); + if (hint == NS_STYLE_HINT_NONE) { + if (BLOBARRAY[i] == sBlobPtr[i]) { + BLOBARRAY[i] = nsnull; + } + else { + NS_IF_DELETE(BLOBARRAY[i]); + } + } + else { + if (BLOBARRAY[i] == sBlobPtr[i]) { + BLOBARRAY[i] = mStyleData->AllocateOneBlob(structID, nsnull); + if (!BLOBARRAY[i]) { + return NS_ERROR_OUT_OF_MEMORY; + } + BLOBARRAY[i]->SetFrom(sBlobPtr[i]->GetData()); + } + } + } + } + } + return NS_OK; +} + +//------------------------------------------------------------------------------ +// RemapStyle +//------------------------------------------------------------------------------ +// NS_IMETHODIMP StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) { @@ -3457,45 +3354,13 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) return NS_ERROR_UNEXPECTED; } - if (nsnull != mParent) { - GETSCDATA(Font).ResetFrom(&(mParent->GETSCDATA(Font)), aPresContext); - GETSCDATA(Color).ResetFrom(&(mParent->GETSCDATA(Color)), aPresContext); - GETSCDATA(List).ResetFrom(&(mParent->GETSCDATA(List)), aPresContext); - GETSCDATA(Position).ResetFrom(&(mParent->GETSCDATA(Position)), aPresContext); - GETSCDATA(Text).ResetFrom(&(mParent->GETSCDATA(Text)), aPresContext); - GETSCDATA(Display).ResetFrom(&(mParent->GETSCDATA(Display)), aPresContext); - GETSCDATA(Table).ResetFrom(&(mParent->GETSCDATA(Table)), aPresContext); - GETSCDATA(Content).ResetFrom(&(mParent->GETSCDATA(Content)), aPresContext); - GETSCDATA(UserInterface).ResetFrom(&(mParent->GETSCDATA(UserInterface)), aPresContext); - GETSCDATA(Print).ResetFrom(&(mParent->GETSCDATA(Print)), aPresContext); - GETSCDATA(Margin).ResetFrom(&(mParent->GETSCDATA(Margin)), aPresContext); - GETSCDATA(Padding).ResetFrom(&(mParent->GETSCDATA(Padding)), aPresContext); - GETSCDATA(Border).ResetFrom(&(mParent->GETSCDATA(Border)), aPresContext); - GETSCDATA(Outline).ResetFrom(&(mParent->GETSCDATA(Outline)), aPresContext); -#ifdef INCLUDE_XUL - GETSCDATA(XUL).ResetFrom(&(mParent->GETSCDATA(XUL)), aPresContext); -#endif - } - else { - GETSCDATA(Font).ResetFrom(nsnull, aPresContext); - GETSCDATA(Color).ResetFrom(nsnull, aPresContext); - GETSCDATA(List).ResetFrom(nsnull, aPresContext); - GETSCDATA(Position).ResetFrom(nsnull, aPresContext); - GETSCDATA(Text).ResetFrom(nsnull, aPresContext); - GETSCDATA(Display).ResetFrom(nsnull, aPresContext); - GETSCDATA(Table).ResetFrom(nsnull, aPresContext); - GETSCDATA(Content).ResetFrom(nsnull, aPresContext); - GETSCDATA(UserInterface).ResetFrom(nsnull, aPresContext); - GETSCDATA(Print).ResetFrom(nsnull, aPresContext); - GETSCDATA(Margin).ResetFrom(nsnull, aPresContext); - GETSCDATA(Padding).ResetFrom(nsnull, aPresContext); - GETSCDATA(Border).ResetFrom(nsnull, aPresContext); - GETSCDATA(Outline).ResetFrom(nsnull, aPresContext); -#ifdef INCLUDE_XUL - GETSCDATA(XUL).ResetFrom(nsnull, aPresContext); -#endif - } + //------------------------ + // Memory allocation + WrapRemapStyle(aPresContext, PR_TRUE); // Use a temporary set of blobs while we remap style + + //------------------------ + // Normal style remapping PRUint32 cnt = 0; if (mRules) { nsresult rv = mRules->Count(&cnt); @@ -3504,8 +3369,8 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) if (0 < cnt) { MapStyleData data(this, aPresContext); mRules->EnumerateForwards(MapStyleRuleFont, &data); - if (GETSCDATA(Font).mFlags & NS_STYLE_FONT_USE_FIXED) { - GETSCDATA(Font).mFont = GETSCDATA(Font).mFixedFont; + if (GETDATAPTR(Font)->mFlags & NS_STYLE_FONT_USE_FIXED) { + GETMUTABLEDATAPTR(Font)->mFont = GETDATAPTR(Font)->mFixedFont; } mRules->EnumerateForwards(MapStyleRule, &data); } @@ -3513,75 +3378,91 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) mDataCode = 0; } + //------------------------ // CSS2 specified fixups: // - these must be done after all declarations are mapped since they can cross style-structs - // 1) if float is not none, and display is not none, then we must set display to block + // #1 if float is not none, and display is not none, then we must set display to block // XXX - there are problems with following the spec here: what we will do instead of // following the letter of the spec is to make sure that floated elements are // some kind of block, not strictly 'block' - see EnsureBlockDisplay method - nsStyleDisplay *disp = (nsStyleDisplay *)GetMutableStyleData(eStyleStruct_Display); - if (disp) { - if (disp->mDisplay != NS_STYLE_DISPLAY_NONE && - disp->mFloats != NS_STYLE_FLOAT_NONE ) { - EnsureBlockDisplay(disp->mDisplay); + PRUint8 oldDisplay = GETDATAPTR(Display)->mDisplay; + PRUint8 oldFloats = GETDATAPTR(Display)->mFloats; + PRUint8 newDisplay = oldDisplay; + PRUint8 newFloats = oldFloats; + if (newDisplay != NS_STYLE_DISPLAY_NONE && newFloats != NS_STYLE_FLOAT_NONE ) { + EnsureBlockDisplay(newDisplay); + } + // #2 if position is 'absolute' or 'fixed' then display must be 'block and float must be 'none' + // XXX - see note for fixup #1 above... + if (GETDATAPTR(Position)->IsAbsolutelyPositioned()) { + if (newDisplay != NS_STYLE_DISPLAY_NONE) { + EnsureBlockDisplay(newDisplay); + newFloats = NS_STYLE_FLOAT_NONE; } } - // 2) if position is 'absolute' or 'fixed' then display must be 'block and float must be 'none' - // XXX - see note for fixup 1) above... - nsStylePosition *pos = (nsStylePosition *)GetStyleData(eStyleStruct_Position); - if (pos) { - if (pos->IsAbsolutelyPositioned()) { - if (disp) { - if(disp->mDisplay != NS_STYLE_DISPLAY_NONE) { - EnsureBlockDisplay(disp->mDisplay); - disp->mFloats = NS_STYLE_FLOAT_NONE; - } - } + if (newDisplay != oldDisplay || newFloats != oldFloats) { + nsMutableStyleDisplay display((nsIStyleContext*)this); + if (newDisplay != oldDisplay) { + display->mDisplay = newDisplay; + } + if (newFloats != oldFloats) { + display->mFloats = newFloats; } } + //------------------------ + // Table style remapping + PRUint8 displayType = GETDATAPTR(Display)->mDisplay; nsCompatibility quirkMode = eCompatibility_Standard; aPresContext->GetCompatibilityMode(&quirkMode); if (eCompatibility_NavQuirks == quirkMode) { - if (((GETSCDATA(Display).mDisplay == NS_STYLE_DISPLAY_TABLE) || - (GETSCDATA(Display).mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION)) && + if (((displayType == NS_STYLE_DISPLAY_TABLE) || + (displayType == NS_STYLE_DISPLAY_TABLE_CAPTION)) && (nsnull == mPseudoTag)) { - StyleContextImpl* holdParent = mParent; - mParent = nsnull; // cut off all inheritance. this really blows - - // XXX the style we do preserve is visibility, direction, language - PRUint8 visible = GETSCDATA(Display).mVisible; - PRUint8 direction = GETSCDATA(Display).mDirection; - nsCOMPtr<nsILanguageAtom> language = GETSCDATA(Display).mLanguage; - // time to emulate a sub-document // This is ugly, but we need to map style once to determine display type // then reset and map it again so that all local style is preserved - if (GETSCDATA(Display).mDisplay != NS_STYLE_DISPLAY_TABLE) { - GETSCDATA(Font).ResetFrom(nsnull, aPresContext); - } - GETSCDATA(Color).ResetFrom(nsnull, aPresContext); - GETSCDATA(List).ResetFrom(nsnull, aPresContext); - GETSCDATA(Text).ResetFrom(nsnull, aPresContext); - GETSCDATA(Position).ResetFrom(nsnull, aPresContext); - GETSCDATA(Display).ResetFrom(nsnull, aPresContext); - GETSCDATA(Table).ResetFrom(nsnull, aPresContext); - GETSCDATA(Content).ResetFrom(nsnull, aPresContext); - GETSCDATA(UserInterface).ResetFrom(nsnull, aPresContext); - GETSCDATA(Print).ResetFrom(nsnull, aPresContext); - GETSCDATA(Margin).ResetFrom(nsnull, aPresContext); - GETSCDATA(Padding).ResetFrom(nsnull, aPresContext); - GETSCDATA(Border).ResetFrom(nsnull, aPresContext); - GETSCDATA(Outline).ResetFrom(nsnull, aPresContext); -#ifdef INCLUDE_XUL - GETSCDATA(XUL).ResetFrom(nsnull, aPresContext); -#endif - GETSCDATA(Display).mVisible = visible; - GETSCDATA(Display).mDirection = direction; - GETSCDATA(Display).mLanguage = language; + // XXX the style we do preserve is visibility, direction, language + PRUint8 visible = GETDATAPTR(Display)->mVisible; + PRUint8 direction = GETDATAPTR(Display)->mDirection; + nsCOMPtr<nsILanguageAtom> language = GETDATAPTR(Display)->mLanguage; + + // cut off all inheritance. this really blows + StyleContextImpl* holdParent = mParent; + mParent = nsnull; + + // NOTE: We cut off the inheritance but we don't need to allocate the blobs + // that were inherited from the parent because we are inside RemapStyle(), + // meaning that we have all the blobs already. + + // Reset the blobs to default style + for (short i = 0; i < eStyleStruct_Max; i ++) { + nsStyleStructID structID = (nsStyleStructID)(i + 1); + if (BLOBARRAY[i]) { + if ((structID == eStyleStruct_Font) && (displayType == NS_STYLE_DISPLAY_TABLE)) { + // Inherit the font struct from the parent (tables only, not table captions)... + const nsStyleStruct* parentStyle = nsnull; + if (holdParent) { + parentStyle = holdParent->FetchInheritedStyleStruct(structID); + } + BLOBARRAY[i]->ResetFrom(parentStyle, aPresContext); + } + else { + // ... But reset all the other blobs + BLOBARRAY[i]->ResetFrom(nsnull, aPresContext); + } + } + } + + // Restore the style we preserved + GETMUTABLEDATAPTR(Display)->mVisible = visible; + GETMUTABLEDATAPTR(Display)->mDirection = direction; + GETMUTABLEDATAPTR(Display)->mLanguage = language; + + // Do the normal style remapping all over again PRUint32 numRules = 0; if (mRules) { nsresult rv = mRules->Count(&numRules); @@ -3590,22 +3471,24 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) if (0 < numRules) { MapStyleData data(this, aPresContext); mRules->EnumerateForwards(MapStyleRuleFont, &data); - if (GETSCDATA(Font).mFlags & NS_STYLE_FONT_USE_FIXED) { - GETSCDATA(Font).mFont = GETSCDATA(Font).mFixedFont; + if (GETDATAPTR(Font)->mFlags & NS_STYLE_FONT_USE_FIXED) { + GETMUTABLEDATAPTR(Font)->mFont = GETDATAPTR(Font)->mFixedFont; } mRules->EnumerateForwards(MapStyleRule, &data); } + // reset all font data for tables again - if (GETSCDATA(Display).mDisplay == NS_STYLE_DISPLAY_TABLE) { + if (GETDATAPTR(Display)->mDisplay == NS_STYLE_DISPLAY_TABLE) { // get the font-name to reset: this property we preserve - nsAutoString strName(GETSCDATA(Font).mFont.name); - nsAutoString strMixedName(GETSCDATA(Font).mFixedFont.name); + nsAutoString strName(GETDATAPTR(Font)->mFont.name); + nsAutoString strFixedName(GETDATAPTR(Font)->mFixedFont.name); - GETSCDATA(Font).ResetFrom(nsnull, aPresContext); + short index = eStyleStruct_Font - 1; + BLOBARRAY[index]->ResetFrom(nsnull, aPresContext); // now reset the font names back to original - GETSCDATA(Font).mFont.name = strName; - GETSCDATA(Font).mFixedFont.name = strMixedName; + GETMUTABLEDATAPTR(Font)->mFont.name = strName; + GETMUTABLEDATAPTR(Font)->mFixedFont.name = strFixedName; } mParent = holdParent; } @@ -3615,22 +3498,31 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) // so they don't inherit into tables, but instead align the // tables. We should keep doing this, because HTML alignment // is just weird, and we shouldn't force it to match CSS. - if (GETSCDATA(Display).mDisplay == NS_STYLE_DISPLAY_TABLE) { + if (displayType == NS_STYLE_DISPLAY_TABLE) { // -moz-center and -moz-right are used for HTML's alignment - if ((GETSCDATA(Text).mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_CENTER) || - (GETSCDATA(Text).mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_RIGHT)) + if ((GETDATAPTR(Text)->mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_CENTER) || + (GETDATAPTR(Text)->mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_RIGHT)) { - GETSCDATA(Text).mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT; + GETMUTABLEDATAPTR(Text)->mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT; } } } RecalcAutomaticData(aPresContext); + //------------------------ + // Memory deallocation + WrapRemapStyle(aPresContext, PR_FALSE); // Keep the blobs that have changed and dump the rest. + // Must be called before we recurse. + + //------------------------ + // Context is mapped, share it if we can #ifdef SHARE_STYLECONTEXTS nsresult result = ShareStyleData(); #endif + //------------------------ + // Recurse through children if (aRecurse) { if (nsnull != mChild) { StyleContextImpl* child = mChild; @@ -3650,6 +3542,10 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse) return NS_OK; } +//------------------------------------------------------------------------------ +// ForceUnique +//------------------------------------------------------------------------------ +// void StyleContextImpl::ForceUnique(void) { if (mDataCode <= 0) { @@ -3657,17 +3553,25 @@ void StyleContextImpl::ForceUnique(void) } } +//------------------------------------------------------------------------------ +// RecalcAutomaticData +//------------------------------------------------------------------------------ +// void StyleContextImpl::RecalcAutomaticData(nsIPresContext* aPresContext) { if (NS_FAILED(EnsureStyleData(aPresContext))) { return /*NS_FAILURE*/; } - GETSCDATA(Margin).RecalcData(); - GETSCDATA(Padding).RecalcData(); - GETSCDATA(Border).RecalcData(GETSCDATA(Color).mColor); - GETSCDATA(Outline).RecalcData(); + GETBLOB(Margin)->RecalcData(); + GETBLOB(Padding)->RecalcData(); + GETBLOB(Border)->RecalcData(GETDATA(Color)->mColor); + GETBLOB(Outline)->RecalcData(); } +//------------------------------------------------------------------------------ +// CalcStyleDifference +//------------------------------------------------------------------------------ +// NS_IMETHODIMP StyleContextImpl::CalcStyleDifference(nsIStyleContext* aOther, PRInt32& aHint,PRBool aStopAtFirstDifference /*= PR_FALSE*/) const { @@ -3676,115 +3580,28 @@ StyleContextImpl::CalcStyleDifference(nsIStyleContext* aOther, PRInt32& aHint,PR } if (aOther) { - PRInt32 hint; - const StyleContextImpl* other = (const StyleContextImpl*)aOther; + PRInt32 hint = aHint = NS_STYLE_HINT_NONE; + const StyleContextImpl* otherContext = (const StyleContextImpl*)aOther; - aHint = GETSCDATA(Font).CalcDifference(other->GETSCDATA(Font)); - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Color).CalcDifference(other->GETSCDATA(Color)); + for (short i = 0; i < eStyleStruct_Max; i ++) { + nsStyleStructID structID = (nsStyleStructID)(i + 1); + const StyleBlob* myStyle = FetchInheritedStyleBlob(structID); + hint = myStyle->CalcDifference(otherContext->FetchInheritedStyleStruct(structID)); if (aHint < hint) { aHint = hint; } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Margin).CalcDifference(other->GETSCDATA(Margin)); - if (aHint < hint) { - aHint = hint; + if ((aStopAtFirstDifference && (aHint > NS_STYLE_HINT_NONE)) || (aHint == NS_STYLE_HINT_MAX)) { + return NS_OK; } } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Padding).CalcDifference(other->GETSCDATA(Padding)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Border).CalcDifference(other->GETSCDATA(Border)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Outline).CalcDifference(other->GETSCDATA(Outline)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(List).CalcDifference(other->GETSCDATA(List)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Position).CalcDifference(other->GETSCDATA(Position)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Text).CalcDifference(other->GETSCDATA(Text)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Display).CalcDifference(other->GETSCDATA(Display)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Table).CalcDifference(other->GETSCDATA(Table)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Content).CalcDifference(other->GETSCDATA(Content)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(UserInterface).CalcDifference(other->GETSCDATA(UserInterface)); - if (aHint < hint) { - aHint = hint; - } - } - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(Print).CalcDifference(other->GETSCDATA(Print)); - if (aHint < hint) { - aHint = hint; - } - } -#ifdef INCLUDE_XUL - if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK; - if (aHint < NS_STYLE_HINT_MAX) { - hint = GETSCDATA(XUL).CalcDifference(other->GETSCDATA(XUL)); - if (aHint < hint) { - aHint = hint; - } - } -#endif } return NS_OK; } - +//------------------------------------------------------------------------------ +// EnsureStyleData +//------------------------------------------------------------------------------ +// nsresult StyleContextImpl::EnsureStyleData(nsIPresContext* aPresContext) { nsresult rv = NS_OK; @@ -3794,35 +3611,39 @@ nsresult StyleContextImpl::EnsureStyleData(nsIPresContext* aPresContext) return NS_ERROR_FAILURE; } -#ifdef SHARE_STYLECONTEXTS // See if we already have data... if (NS_FAILED(HaveStyleData())) { // we were provided a pres context so create a new style data - mStyleData = nsStyleContextData::Create(aPresContext); +#ifdef SHARE_STYLECONTEXTS + mStyleData = nsStyleContextData::Create(this, aPresContext); +#else + mStyleData = &mStyleDataImpl; + if (NS_FAILED(mStyleData->AllocateStyleBlobs(this, aPresContext))) { + mStyleData = nsnull; + } +#endif if (nsnull == mStyleData) { rv = NS_ERROR_OUT_OF_MEMORY; } - } else { - // already have style data - OK! - rv = NS_OK; } -#endif //#ifdef SHARE_STYLECONTEXTS - return rv; } +//------------------------------------------------------------------------------ +// HaveStyleData +//------------------------------------------------------------------------------ +// nsresult StyleContextImpl::HaveStyleData(void) const { -#ifdef SHARE_STYLECONTEXTS return (nsnull == mStyleData) ? NS_ERROR_NULL_POINTER : NS_OK; -#else - return NS_OK; -#endif } +//------------------------------------------------------------------------------ +// ShareStyleData +//------------------------------------------------------------------------------ +// #ifdef SHARE_STYLECONTEXTS - nsresult StyleContextImpl::ShareStyleData(void) { nsresult result = NS_OK; @@ -3830,38 +3651,19 @@ nsresult StyleContextImpl::ShareStyleData(void) // Enable flag: this is TRUE by default, however the env. var. moz_disable_style_sharing // can be set to '1' to disable the sharing before the app is launched static char *disableSharing = PR_GetEnv("moz_disable_style_sharing"); - static PRBool bEnableSharing = (disableSharing == nsnull) || + static PRBool isSharingEnabled = (disableSharing == nsnull) || (*disableSharing != '1'); #ifdef DEBUG static PRBool bOnce = PR_FALSE; if(!bOnce){ - printf( "Style Data Sharing is %s\n", bEnableSharing ? "Enabled :)" : "Disabled :(" ); + printf( "Style Data Sharing is %s\n", isSharingEnabled ? "Enabled :)" : "Disabled :(" ); bOnce = PR_TRUE; } #endif - PRBool bSharingSupported = PR_TRUE; - if (bEnableSharing) { - // NOTE: sharing of style data for the GfxScrollFrame is problematic - // and is currently disabled. These pseudos indicate the use of a GfxScrollFrame - // so we check for them and disallow sharing when any are found. - // If you haen;t guessed it, this is a total hack until we can figure out - // why the GfxScrollFrame is not happy having its style data shared... - // (See bugzilla bug 39618 which also documents this problem) - if(mPseudoTag) { - if(mPseudoTag == nsLayoutAtoms::viewportPseudo || - mPseudoTag == nsLayoutAtoms::canvasPseudo || - mPseudoTag == nsLayoutAtoms::viewportScrollPseudo || - mPseudoTag == nsLayoutAtoms::scrolledContentPseudo || - mPseudoTag == nsLayoutAtoms::selectScrolledContentPseudo) { - bSharingSupported = PR_FALSE; - } else { - bSharingSupported = PR_TRUE; - } - } - } + PRBool isSharingSupported = CanShareStyleData(this); - if (bEnableSharing && bSharingSupported) { + if (isSharingEnabled && isSharingSupported) { NS_ASSERTION(mStyleSet, "Expected to have a style set ref..."); nsIStyleContext *matchingSC = nsnull; @@ -3883,6 +3685,7 @@ nsresult StyleContextImpl::ShareStyleData(void) return result; } } + // check if there is a matching context... result = mStyleSet->FindMatchingContext(this, &matchingSC); if ((NS_SUCCEEDED(result)) && @@ -3901,7 +3704,13 @@ nsresult StyleContextImpl::ShareStyleData(void) return result; } +#endif // SHARE_STYLECONTEXTS +//------------------------------------------------------------------------------ +// ShareStyleDataFrom +//------------------------------------------------------------------------------ +// +#ifdef SHARE_STYLECONTEXTS nsresult StyleContextImpl::ShareStyleDataFrom(nsIStyleContext*aStyleDataDonor) { nsresult rv = NS_OK; @@ -3921,7 +3730,13 @@ nsresult StyleContextImpl::ShareStyleDataFrom(nsIStyleContext*aStyleDataDonor) } return rv; } +#endif // SHARE_STYLECONTEXTS +//------------------------------------------------------------------------------ +// StyleDataMatches +//------------------------------------------------------------------------------ +// +#ifdef SHARE_STYLECONTEXTS #ifdef DEBUG long gFalsePos=0; long gScreenedByCRC=0; @@ -3977,13 +3792,25 @@ StyleContextImpl::StyleDataMatches(nsIStyleContext* aStyleContextToMatch, } return rv; } +#endif // SHARE_STYLECONTEXTS +//------------------------------------------------------------------------------ +// GetStyleContextKey +//------------------------------------------------------------------------------ +// +#ifdef SHARE_STYLECONTEXTS NS_IMETHODIMP StyleContextImpl::GetStyleContextKey(scKey &aKey) const { aKey = mStyleData->GetCRC32(); return NS_OK; } +#endif // SHARE_STYLECONTEXTS +//------------------------------------------------------------------------------ +// UpdateStyleSetCache +//------------------------------------------------------------------------------ +// +#ifdef SHARE_STYLECONTEXTS nsresult StyleContextImpl::UpdateStyleSetCache( void ) const { if (mStyleSet) { @@ -3993,9 +3820,12 @@ nsresult StyleContextImpl::UpdateStyleSetCache( void ) const return NS_ERROR_FAILURE; } } +#endif // SHARE_STYLECONTEXTS -#endif - +//------------------------------------------------------------------------------ +// Regression tests (List, SizeOf, DumpRegressionData) +//------------------------------------------------------------------------------ +// void StyleContextImpl::List(FILE* out, PRInt32 aIndent) { // Indent @@ -4071,43 +3901,41 @@ void StyleContextImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) static PRBool bDetailDumpDone = PR_FALSE; if (!bDetailDumpDone) { bDetailDumpDone = PR_TRUE; - PRUint32 totalSize=0; - printf( "Detailed StyleContextImpl dump: basic class sizes of members\n" ); - printf( "*************************************\n"); - printf( " - StyleFontImpl: %ld\n", (long)sizeof(GETSCDATA(Font)) ); - totalSize += (long)sizeof(GETSCDATA(Font)); - printf( " - StyleColorImpl: %ld\n", (long)sizeof(GETSCDATA(Color)) ); - totalSize += (long)sizeof(GETSCDATA(Color)); - printf( " - StyleListImpl: %ld\n", (long)sizeof(GETSCDATA(List)) ); - totalSize += (long)sizeof(GETSCDATA(List)); - printf( " - StylePositionImpl: %ld\n", (long)sizeof(GETSCDATA(Position)) ); - totalSize += (long)sizeof(GETSCDATA(Position)); - printf( " - StyleTextImpl: %ld\n", (long)sizeof(GETSCDATA(Text)) ); - totalSize += (long)sizeof(GETSCDATA(Text)); - printf( " - StyleDisplayImpl: %ld\n", (long)sizeof(GETSCDATA(Display)) ); - totalSize += (long)sizeof(GETSCDATA(Display)); - printf( " - StyleTableImpl: %ld\n", (long)sizeof(GETSCDATA(Table)) ); - totalSize += (long)sizeof(GETSCDATA(Table)); - printf( " - StyleContentImpl: %ld\n", (long)sizeof(GETSCDATA(Content)) ); - totalSize += (long)sizeof(GETSCDATA(Content)); - printf( " - StyleUserInterfaceImpl: %ld\n", (long)sizeof(GETSCDATA(UserInterface)) ); - totalSize += (long)sizeof(GETSCDATA(UserInterface)); - printf( " - StylePrintImpl: %ld\n", (long)sizeof(GETSCDATA(Print))); - totalSize += (long)sizeof(GETSCDATA(Print)); - printf( " - StyleMarginImpl: %ld\n", (long)sizeof(GETSCDATA(Margin))); - totalSize += (long)sizeof(GETSCDATA(Margin)); - printf( " - StylePaddingImpl: %ld\n", (long)sizeof(GETSCDATA(Padding))); - totalSize += (long)sizeof(GETSCDATA(Padding)); - printf( " - StyleBorderImpl: %ld\n", (long)sizeof(GETSCDATA(Border))); - totalSize += (long)sizeof(GETSCDATA(Border)); - printf( " - StyleOutlineImpl: %ld\n", (long)sizeof(GETSCDATA(Outline))); - totalSize += (long)sizeof(GETSCDATA(Outline)); + struct sizeInfo { + char* name; + long size; + }; + + static sizeInfo styleDataInfo[eStyleStruct_Max] = { + {"StyleFontBlob", sizeof(STYLEBLOB(Font))} + ,{"StyleColorBlob", sizeof(STYLEBLOB(Color))} + ,{"StyleListBlob", sizeof(STYLEBLOB(List))} + ,{"StylePositionBlob", sizeof(STYLEBLOB(Position))} + ,{"StyleTextBlob", sizeof(STYLEBLOB(Text))} + ,{"StyleDisplayBlob", sizeof(STYLEBLOB(Display))} + ,{"StyleTableBlob", sizeof(STYLEBLOB(Table))} + ,{"StyleContentBlob", sizeof(STYLEBLOB(Content))} + ,{"StyleUserInterfaceBlob", sizeof(STYLEBLOB(UserInterface))} + ,{"StylePrintBlob", sizeof(STYLEBLOB(Print))} + ,{"StyleMarginBlob", sizeof(STYLEBLOB(Margin))} + ,{"StylePaddingBlob", sizeof(STYLEBLOB(Padding))} + ,{"StyleBorderBlob", sizeof(STYLEBLOB(Border))} + ,{"StyleOutlineBlob", sizeof(STYLEBLOB(Outline))} #ifdef INCLUDE_XUL - printf( " - StyleXULImpl: %ld\n", (long)sizeof(GETSCDATA(XUL))); - totalSize += (long)sizeof(GETSCDATA(XUL)); + ,{"StyleXULBlob", sizeof(STYLEBLOB(XUL))} #endif - printf( " - Total: %ld\n", (long)totalSize); + //#insert new style structs here# + }; + + printf("Detailed StyleContextImpl dump: basic class sizes of members\n" ); + printf("*************************************\n"); + PRUint32 totalSize=0; + for (short i = 0; i < eStyleStruct_Max; i ++) { + printf(" - %-24s %ld\n", styleDataInfo[i].name, styleDataInfo[i].size); + totalSize += styleDataInfo[i].size; + } + printf(" - %-24s %ld\n", "Total", totalSize); printf( "*************************************\n"); } @@ -4126,6 +3954,9 @@ void StyleContextImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) tag = getter_AddRefs(NS_NewAtom("StyleContextImpl")); // get the size of an empty instance and add to the sizeof handler aSize = sizeof(*this); +#ifndef SHARE_STYLECONTEXTS + aSize -= sizeof(this->mStyleDataImpl); +#endif // add in the size of the member mPseudoTag if(mPseudoTag){ mPseudoTag->SizeOf(aSizeOfHandler, &localSize); @@ -4133,12 +3964,10 @@ void StyleContextImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) } aSizeOfHandler->AddSize(tag,aSize); -#ifdef SHARE_STYLECONTEXTS // count the style data seperately if (mStyleData) { mStyleData->SizeOf(aSizeOfHandler,localSize); } -#endif // size up the rules (if not already done) // XXX - overhead of the collection??? @@ -4187,169 +4016,178 @@ void StyleContextImpl::DumpRegressionData(nsIPresContext* aPresContext, FILE* ou // FONT IndentBy(out,aIndent); fprintf(out, "<font %s %s %d />\n", - NS_ConvertUCS2toUTF8(GETSCDATA(Font).mFont.name).get(), - NS_ConvertUCS2toUTF8(GETSCDATA(Font).mFixedFont.name).get(), - GETSCDATA(Font).mFlags); + NS_ConvertUCS2toUTF8(GETDATA(Font)->mFont.name).get(), + NS_ConvertUCS2toUTF8(GETDATA(Font)->mFixedFont.name).get(), + GETDATA(Font)->mFlags); // COLOR IndentBy(out,aIndent); fprintf(out, "<color data=\"%ld %d %d %d %ld %ld %ld %s %d %s %f\"/>\n", - (long)GETSCDATA(Color).mColor, - (int)GETSCDATA(Color).mBackgroundAttachment, - (int)GETSCDATA(Color).mBackgroundFlags, - (int)GETSCDATA(Color).mBackgroundRepeat, - (long)GETSCDATA(Color).mBackgroundColor, - (long)GETSCDATA(Color).mBackgroundXPosition, - (long)GETSCDATA(Color).mBackgroundYPosition, - NS_ConvertUCS2toUTF8(GETSCDATA(Color).mBackgroundImage).get(), - (int)GETSCDATA(Color).mCursor, - NS_ConvertUCS2toUTF8(GETSCDATA(Color).mCursorImage).get(), - GETSCDATA(Color).mOpacity); + (long)GETDATA(Color)->mColor, + (int)GETDATA(Color)->mBackgroundAttachment, + (int)GETDATA(Color)->mBackgroundFlags, + (int)GETDATA(Color)->mBackgroundRepeat, + (long)GETDATA(Color)->mBackgroundColor, + (long)GETDATA(Color)->mBackgroundXPosition, + (long)GETDATA(Color)->mBackgroundYPosition, + NS_ConvertUCS2toUTF8(GETDATA(Color)->mBackgroundImage).get(), + (int)GETDATA(Color)->mCursor, + NS_ConvertUCS2toUTF8(GETDATA(Color)->mCursorImage).get(), + GETDATA(Color)->mOpacity); // SPACING (ie. margin, padding, border, outline) IndentBy(out,aIndent); fprintf(out, "<spacing data=\""); - GETSCDATA(Margin).mMargin.ToString(str); + GETDATA(Margin)->mMargin.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Padding).mPadding.ToString(str); + GETDATA(Padding)->mPadding.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Border).mBorder.ToString(str); + GETDATA(Border)->mBorder.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Border).mBorderRadius.ToString(str); + GETDATA(Border)->mBorderRadius.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Outline).mOutlineRadius.ToString(str); + GETDATA(Outline)->mOutlineRadius.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Outline).mOutlineWidth.ToString(str); + GETDATA(Outline)->mOutlineWidth.ToString(str); fprintf(out, "%s", NS_ConvertUCS2toUTF8(str).get()); - fprintf(out, "%d", (int)GETSCDATA(Border).mFloatEdge); + fprintf(out, "%d", (int)GETDATA(Border)->mFloatEdge); fprintf(out, "\" />\n"); // LIST IndentBy(out,aIndent); fprintf(out, "<list data=\"%d %d %s\" />\n", - (int)GETSCDATA(List).mListStyleType, - (int)GETSCDATA(List).mListStyleType, - NS_ConvertUCS2toUTF8(GETSCDATA(List).mListStyleImage).get()); + (int)GETDATA(List)->mListStyleType, + (int)GETDATA(List)->mListStyleType, + NS_ConvertUCS2toUTF8(GETDATA(List)->mListStyleImage).get()); // POSITION IndentBy(out,aIndent); - fprintf(out, "<position data=\"%d ", (int)GETSCDATA(Position).mPosition); - GETSCDATA(Position).mOffset.ToString(str); + fprintf(out, "<position data=\"%d ", (int)GETDATA(Position)->mPosition); + GETDATA(Position)->mOffset.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Position).mWidth.ToString(str); + GETDATA(Position)->mWidth.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Position).mMinWidth.ToString(str); + GETDATA(Position)->mMinWidth.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Position).mMaxWidth.ToString(str); + GETDATA(Position)->mMaxWidth.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Position).mHeight.ToString(str); + GETDATA(Position)->mHeight.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Position).mMinHeight.ToString(str); + GETDATA(Position)->mMinHeight.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Position).mMaxHeight.ToString(str); + GETDATA(Position)->mMaxHeight.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - fprintf(out, "%d ", (int)GETSCDATA(Position).mBoxSizing); - GETSCDATA(Position).mZIndex.ToString(str); + fprintf(out, "%d ", (int)GETDATA(Position)->mBoxSizing); + GETDATA(Position)->mZIndex.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); fprintf(out, "\" />\n"); // TEXT IndentBy(out,aIndent); fprintf(out, "<text data=\"%d %d %d %d ", - (int)GETSCDATA(Text).mTextAlign, - (int)GETSCDATA(Text).mTextDecoration, - (int)GETSCDATA(Text).mTextTransform, - (int)GETSCDATA(Text).mWhiteSpace); - GETSCDATA(Text).mLetterSpacing.ToString(str); + (int)GETDATA(Text)->mTextAlign, + (int)GETDATA(Text)->mTextDecoration, + (int)GETDATA(Text)->mTextTransform, + (int)GETDATA(Text)->mWhiteSpace); + GETDATA(Text)->mLetterSpacing.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Text).mLineHeight.ToString(str); + GETDATA(Text)->mLineHeight.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Text).mTextIndent.ToString(str); + GETDATA(Text)->mTextIndent.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Text).mWordSpacing.ToString(str); + GETDATA(Text)->mWordSpacing.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Text).mVerticalAlign.ToString(str); + GETDATA(Text)->mVerticalAlign.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); fprintf(out, "\" />\n"); // DISPLAY IndentBy(out,aIndent); fprintf(out, "<display data=\"%d %d %d %d %d %d %d %d %d %ld %ld %ld %ld\" />\n", - (int)GETSCDATA(Display).mDirection, - (int)GETSCDATA(Display).mDisplay, - (int)GETSCDATA(Display).mFloats, - (int)GETSCDATA(Display).mBreakType, - (int)GETSCDATA(Display).mBreakBefore, - (int)GETSCDATA(Display).mBreakAfter, - (int)GETSCDATA(Display).mVisible, - (int)GETSCDATA(Display).mOverflow, - (int)GETSCDATA(Display).mClipFlags, - (long)GETSCDATA(Display).mClip.x, - (long)GETSCDATA(Display).mClip.y, - (long)GETSCDATA(Display).mClip.width, - (long)GETSCDATA(Display).mClip.height + (int)GETDATA(Display)->mDirection, + (int)GETDATA(Display)->mDisplay, + (int)GETDATA(Display)->mFloats, + (int)GETDATA(Display)->mBreakType, + (int)GETDATA(Display)->mBreakBefore, + (int)GETDATA(Display)->mBreakAfter, + (int)GETDATA(Display)->mVisible, + (int)GETDATA(Display)->mOverflow, + (int)GETDATA(Display)->mClipFlags, + (long)GETDATA(Display)->mClip.x, + (long)GETDATA(Display)->mClip.y, + (long)GETDATA(Display)->mClip.width, + (long)GETDATA(Display)->mClip.height ); // TABLE IndentBy(out,aIndent); fprintf(out, "<table data=\"%d %d %d %d ", - (int)GETSCDATA(Table).mLayoutStrategy, - (int)GETSCDATA(Table).mFrame, - (int)GETSCDATA(Table).mRules, - (int)GETSCDATA(Table).mBorderCollapse); - GETSCDATA(Table).mBorderSpacingX.ToString(str); + (int)GETDATA(Table)->mLayoutStrategy, + (int)GETDATA(Table)->mFrame, + (int)GETDATA(Table)->mRules, + (int)GETDATA(Table)->mBorderCollapse); + GETDATA(Table)->mBorderSpacingX.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Table).mBorderSpacingY.ToString(str); + GETDATA(Table)->mBorderSpacingY.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); - GETSCDATA(Table).mCellPadding.ToString(str); + GETDATA(Table)->mCellPadding.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); fprintf(out, "%d %d %ld %ld ", - (int)GETSCDATA(Table).mCaptionSide, - (int)GETSCDATA(Table).mEmptyCells, - (long)GETSCDATA(Table).mCols, - (long)GETSCDATA(Table).mSpan); - GETSCDATA(Table).mSpanWidth.ToString(str); + (int)GETDATA(Table)->mCaptionSide, + (int)GETDATA(Table)->mEmptyCells, + (long)GETDATA(Table)->mCols, + (long)GETDATA(Table)->mSpan); + GETDATA(Table)->mSpanWidth.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); fprintf(out, "\" />\n"); // CONTENT IndentBy(out,aIndent); fprintf(out, "<content data=\"%ld %ld %ld %ld ", - (long)GETSCDATA(Content).ContentCount(), - (long)GETSCDATA(Content).CounterIncrementCount(), - (long)GETSCDATA(Content).CounterResetCount(), - (long)GETSCDATA(Content).QuotesCount()); + (long)GETDATA(Content)->ContentCount(), + (long)GETDATA(Content)->CounterIncrementCount(), + (long)GETDATA(Content)->CounterResetCount(), + (long)GETDATA(Content)->QuotesCount()); // XXX: iterate over the content, counters and quotes... - GETSCDATA(Content).mMarkerOffset.ToString(str); + GETDATA(Content)->mMarkerOffset.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); fprintf(out, "\" />\n"); // UI IndentBy(out,aIndent); fprintf(out, "<UI data=\"%d %d %d %d %d %d %s\" />\n", - (int)GETSCDATA(UserInterface).mUserInput, - (int)GETSCDATA(UserInterface).mUserModify, - (int)GETSCDATA(UserInterface).mUserSelect, - (int)GETSCDATA(UserInterface).mUserFocus, - (int)GETSCDATA(UserInterface).mKeyEquivalent, - (int)GETSCDATA(UserInterface).mResizer, - NS_ConvertUCS2toUTF8(GETSCDATA(UserInterface).mBehavior).get()); + (int)GETDATA(UserInterface)->mUserInput, + (int)GETDATA(UserInterface)->mUserModify, + (int)GETDATA(UserInterface)->mUserSelect, + (int)GETDATA(UserInterface)->mUserFocus, + (int)GETDATA(UserInterface)->mKeyEquivalent, + (int)GETDATA(UserInterface)->mResizer, + NS_ConvertUCS2toUTF8(GETDATA(UserInterface)->mBehavior).get()); // PRINT IndentBy(out,aIndent); fprintf(out, "<print data=\"%d %d %d %s %ld %ld %d ", - (int)GETSCDATA(Print).mPageBreakBefore, - (int)GETSCDATA(Print).mPageBreakAfter, - (int)GETSCDATA(Print).mPageBreakInside, - NS_ConvertUCS2toUTF8(GETSCDATA(Print).mPage).get(), - (long)GETSCDATA(Print).mWidows, - (long)GETSCDATA(Print).mOrphans, - (int)GETSCDATA(Print).mMarks); - GETSCDATA(Print).mSizeWidth.ToString(str); + (int)GETDATA(Print)->mPageBreakBefore, + (int)GETDATA(Print)->mPageBreakAfter, + (int)GETDATA(Print)->mPageBreakInside, + NS_ConvertUCS2toUTF8(GETDATA(Print)->mPage).get(), + (long)GETDATA(Print)->mWidows, + (long)GETDATA(Print)->mOrphans, + (int)GETDATA(Print)->mMarks); + GETDATA(Print)->mSizeWidth.ToString(str); fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get()); fprintf(out, "\" />\n"); + + // XUL +#ifdef INCLUDE_XUL + IndentBy(out,aIndent); + fprintf(out, "<xul data=\"%d", + (int)GETDATA(XUL)->mBoxOrient); + fprintf(out, "\" />\n"); +#endif + //#insert new style structs here# } #endif @@ -4381,8 +4219,10 @@ NS_NewStyleContext(nsIStyleContext** aInstancePtrResult, } -//---------------------------------------------------------- - +//------------------------------------------------------------------------------ +// CRC Calculations +//------------------------------------------------------------------------------ +// #ifdef COMPUTE_STYLEDATA_CRC /************************************************************************* * The table lookup technique was adapted from the algorithm described * @@ -4473,41 +4313,6 @@ PRUint32 StyleStringCRC(PRUint32 aCrc, const nsString *aString) } #endif // #ifdef COMPUTE_STYLEDATA_CRC -void EnsureBlockDisplay(/*in out*/PRUint8 &display) -{ - // see if the display value is already a block - switch (display) { - case NS_STYLE_DISPLAY_NONE : - // never change display:none *ever* - break; - - case NS_STYLE_DISPLAY_TABLE : - case NS_STYLE_DISPLAY_BLOCK : - // do not muck with these at all - already blocks - break; - - case NS_STYLE_DISPLAY_LIST_ITEM : - // do not change list items to blocks - retain the bullet/numbering - break; - - case NS_STYLE_DISPLAY_TABLE_ROW_GROUP : - case NS_STYLE_DISPLAY_TABLE_COLUMN : - case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP : - case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP : - case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP : - case NS_STYLE_DISPLAY_TABLE_ROW : - case NS_STYLE_DISPLAY_TABLE_CELL : - case NS_STYLE_DISPLAY_TABLE_CAPTION : - // special cases: don't do anything since these cannot really be floated anyway - break; - - case NS_STYLE_DISPLAY_INLINE_TABLE : - // make inline tables into tables - display = NS_STYLE_DISPLAY_TABLE; - break; - - default : - // make it a block - display = NS_STYLE_DISPLAY_BLOCK; - } -} +#ifdef DEBUG //xxx pierre +#include "nsStyleContextDebug.cpp" +#endif diff --git a/mozilla/layout/style/nsStyleSet.cpp b/mozilla/layout/style/nsStyleSet.cpp index 4386d8df339..29edacec713 100644 --- a/mozilla/layout/style/nsStyleSet.cpp +++ b/mozilla/layout/style/nsStyleSet.cpp @@ -37,6 +37,7 @@ #include "nsICSSStyleSheet.h" #include "nsNetUtil.h" #include "nsIStyleRuleSupplier.h" +#include "nsISizeOfHandler.h" #ifdef MOZ_PERF_METRICS #include "nsITimeRecorder.h" @@ -49,18 +50,8 @@ #define STYLESET_STOP_TIMER(a) ((void)0) #endif -#include "nsISizeOfHandler.h" - static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID); -// - fast cache uses a CRC32 on the style context to quickly find sharing candidates. -// Enabling it by defining USE_FAST_CACHE makes style sharing significantly faster -// but introduces more code and logic, and is thus potentially more error-prone -// - Enabled by default: disable to determine if there are problems in the fast-cache -// NOTE: make sure the define COMPUTE_STYLEDATA_CRC is ON in nsStyleContext.cpp for -// this to be affective... -#define USE_FAST_CACHE - #ifdef USE_FAST_CACHE /////////////////////////////////////// // DEBUG defines for the fast cache: @@ -78,6 +69,7 @@ static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_I #ifdef USE_FAST_CACHE +#include "nsHashtable.h" PRBool PR_CALLBACK HashTableEnumDestroy(nsHashKey *aKey, void *aData, void* closure); PRBool PR_CALLBACK HashTableEnumDump(nsHashKey *aKey, void *aData, void* closure); PRBool PR_CALLBACK HashTableEnumTickle(nsHashKey *aKey, void *aData, void* closure); diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp index a74203acb0a..454052b9b8c 100644 --- a/mozilla/layout/tables/nsTableCellFrame.cpp +++ b/mozilla/layout/tables/nsTableCellFrame.cpp @@ -26,6 +26,7 @@ #include "nsTableFrame.h" #include "nsIReflowCommand.h" #include "nsIStyleContext.h" +#include "nsIMutableStyleContext.h" #include "nsStyleConsts.h" #include "nsIPresContext.h" #include "nsIRenderingContext.h" @@ -868,6 +869,7 @@ void nsTableCellFrame::MapHTMLBorderStyle(nsIPresContext* aPresContext, /* The RULES code below has been disabled because collapsing borders have been disabled and RULES depend on collapsing borders + NOTE: The place where this function was called has been disabled too. const nsStyleTable* tableStyle; aTableFrame->GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle); @@ -930,30 +932,37 @@ void nsTableCellFrame::MapBorderPadding(nsIPresContext* aPresContext) tableFrame->GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle); const nsStylePadding* tablePaddingStyle; tableFrame->GetStyleData(eStyleStruct_Padding,(const nsStyleStruct *&)tablePaddingStyle); - nsStylePadding* paddingData = (nsStylePadding*)mStyleContext->GetMutableStyleData(eStyleStruct_Padding); + { + nsMutableStylePadding paddingData(mStyleContext); - float p2t; - aPresContext->GetPixelsToTwips(&p2t); + float p2t; + aPresContext->GetPixelsToTwips(&p2t); - // Get the table's cellpadding or use 2 pixels as the default if it is not set. - // This assumes that ua.css does not set padding for the cell. - nscoord defaultPadding = tableFrame->GetCellPadding(); - if (-1 == defaultPadding) { // not set in table - defaultPadding = NSIntPixelsToTwips(1, p2t); + // Get the table's cellpadding or use 2 pixels as the default if it is not set. + // This assumes that ua.css does not set padding for the cell. + nscoord defaultPadding = tableFrame->GetCellPadding(); + if (-1 == defaultPadding) { // not set in table + defaultPadding = NSIntPixelsToTwips(1, p2t); + } + + // if the padding is not already set, set it to the table's cellpadding + if (eStyleUnit_Null == paddingData->mPadding.GetTopUnit()) + paddingData->mPadding.SetTop(defaultPadding); + if (eStyleUnit_Null == paddingData->mPadding.GetRightUnit()) + paddingData->mPadding.SetRight(defaultPadding); + if (eStyleUnit_Null == paddingData->mPadding.GetBottomUnit()) + paddingData->mPadding.SetBottom(defaultPadding); + if (eStyleUnit_Null == paddingData->mPadding.GetLeftUnit()) + paddingData->mPadding.SetLeft(defaultPadding); } + /* MapHTMLBorderStyle() has been disabled because collapsing borders have been disabled + and the rules in MapHTMLBorderStyle() depend on collapsing borders - // if the padding is not already set, set it to the table's cellpadding - if (eStyleUnit_Null == paddingData->mPadding.GetTopUnit()) - paddingData->mPadding.SetTop(defaultPadding); - if (eStyleUnit_Null == paddingData->mPadding.GetRightUnit()) - paddingData->mPadding.SetRight(defaultPadding); - if (eStyleUnit_Null == paddingData->mPadding.GetBottomUnit()) - paddingData->mPadding.SetBottom(defaultPadding); - if (eStyleUnit_Null == paddingData->mPadding.GetLeftUnit()) - paddingData->mPadding.SetLeft(defaultPadding); - - nsStyleBorder* borderData = (nsStyleBorder*)mStyleContext->GetMutableStyleData(eStyleStruct_Border); - MapHTMLBorderStyle(aPresContext, *borderData, tableFrame); + { + nsMutableStyleBorder borderData(mStyleContext); + MapHTMLBorderStyle(aPresContext, *borderData, tableFrame); + } + */ MapVAlignAttribute(aPresContext, tableFrame); MapHAlignAttribute(aPresContext, tableFrame); @@ -980,14 +989,14 @@ void nsTableCellFrame::MapVAlignAttribute(nsIPresContext* aPresContext, nsTableF const nsStyleText* colTextStyle; colFrame->GetStyleData(eStyleStruct_Text,(const nsStyleStruct *&)colTextStyle); if (colTextStyle->mVerticalAlign.GetUnit() == eStyleUnit_Enumerated) { - nsStyleText* cellTextStyle = (nsStyleText*)mStyleContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText cellTextStyle(mStyleContext); cellTextStyle->mVerticalAlign.SetIntValue(colTextStyle->mVerticalAlign.GetIntValue(), eStyleUnit_Enumerated); return; // valign set from COL info } } // otherwise, set the vertical align attribute to the HTML default - nsStyleText* cellTextStyle = (nsStyleText*)mStyleContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText cellTextStyle(mStyleContext); cellTextStyle->mVerticalAlign.SetIntValue(NS_STYLE_VERTICAL_ALIGN_MIDDLE, eStyleUnit_Enumerated); } @@ -1012,7 +1021,7 @@ void nsTableCellFrame::MapHAlignAttribute(nsIPresContext* aPresContext, const nsStyleText* rowTextStyle; rowFrame->GetStyleData(eStyleStruct_Text,(const nsStyleStruct *&)rowTextStyle); if (NS_STYLE_TEXT_ALIGN_DEFAULT != rowTextStyle->mTextAlign) { - nsStyleText* cellTextStyle = (nsStyleText*)mStyleContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText cellTextStyle(mStyleContext); cellTextStyle->mTextAlign = rowTextStyle->mTextAlign; return; // halign set from ROW info } @@ -1025,18 +1034,18 @@ void nsTableCellFrame::MapHAlignAttribute(nsIPresContext* aPresContext, const nsStyleText* colTextStyle; colFrame->GetStyleData(eStyleStruct_Text,(const nsStyleStruct *&)colTextStyle); if (NS_STYLE_TEXT_ALIGN_DEFAULT != colTextStyle->mTextAlign) { - nsStyleText* cellTextStyle = (nsStyleText*)mStyleContext->GetMutableStyleData(eStyleStruct_Text); + nsMutableStyleText cellTextStyle(mStyleContext); cellTextStyle->mTextAlign = colTextStyle->mTextAlign; return; // halign set from COL info } } // otherwise, set the text align to the HTML default (center for TH, left for TD) - nsStyleText* cellTextStyle = (nsStyleText*)mStyleContext->GetMutableStyleData(eStyleStruct_Text); nsIAtom* tag; if (mContent) { mContent->GetTag(tag); if (tag) { + nsMutableStyleText cellTextStyle(mStyleContext); cellTextStyle->mTextAlign = (nsHTMLAtoms::th == tag) ? NS_STYLE_TEXT_ALIGN_CENTER : NS_STYLE_TEXT_ALIGN_LEFT; diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index d42d9b01998..cd0b9a1721c 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -26,6 +26,7 @@ #include "nsTableBorderCollapser.h" #include "nsIRenderingContext.h" #include "nsIStyleContext.h" +#include "nsIMutableStyleContext.h" #include "nsStyleConsts.h" #include "nsIContent.h" #include "nsCellMap.h" @@ -668,16 +669,18 @@ void nsTableFrame::ProcessGroupRules(nsIPresContext* aPresContext) if (originates) { nsCOMPtr<nsIStyleContext> styleContext; cell->GetStyleContext(getter_AddRefs(styleContext)); - nsStyleBorder* border = (nsStyleBorder*)styleContext->GetMutableStyleData(eStyleStruct_Border); - if (rowX == startRow) { - border->SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE); - } - else if (rowX == endRow) { - border->SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE); - } - else { - border->SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE); - border->SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE); + { + nsMutableStyleBorder border(styleContext); + if (rowX == startRow) { + border->SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE); + } + else if (rowX == endRow) { + border->SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE); + } + else { + border->SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE); + border->SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE); + } } styleContext->RecalcAutomaticData(aPresContext); } @@ -3707,7 +3710,7 @@ void nsTableFrame::MapBorderMarginPadding(nsIPresContext* aPresContext) if (!table) return; - nsStyleBorder* borderData = (nsStyleBorder*)mStyleContext->GetMutableStyleData(eStyleStruct_Border); + nsMutableStyleBorder borderData(mStyleContext); border_result = table->GetAttribute(nsHTMLAtoms::border,border_value); if (border_result == NS_CONTENT_ATTR_HAS_VALUE) diff --git a/mozilla/layout/tables/nsTableOuterFrame.cpp b/mozilla/layout/tables/nsTableOuterFrame.cpp index 36c09cbd098..4134ed42502 100644 --- a/mozilla/layout/tables/nsTableOuterFrame.cpp +++ b/mozilla/layout/tables/nsTableOuterFrame.cpp @@ -24,6 +24,7 @@ #include "nsTableFrame.h" #include "nsIReflowCommand.h" #include "nsIStyleContext.h" +#include "nsIMutableStyleContext.h" #include "nsStyleConsts.h" #include "nsIPresContext.h" #include "nsIRenderingContext.h" @@ -153,19 +154,20 @@ nsTableOuterFrame::AdjustZeroWidth() { // a 0 width table becomes auto PRBool makeAuto = PR_FALSE; - nsStylePosition* position = (nsStylePosition*)mStyleContext->GetMutableStyleData(eStyleStruct_Position); - if (position->mWidth.GetUnit() == eStyleUnit_Coord) { - if (0 >= position->mWidth.GetCoordValue()) { + nsStylePosition* posData = (nsStylePosition*)mStyleContext->GetStyleData(eStyleStruct_Position); + if (posData->mWidth.GetUnit() == eStyleUnit_Coord) { + if (0 >= posData->mWidth.GetCoordValue()) { makeAuto= PR_TRUE; } } - else if (position->mWidth.GetUnit() == eStyleUnit_Percent) { - if (0.0f >= position->mWidth.GetPercentValue()) { + else if (posData->mWidth.GetUnit() == eStyleUnit_Percent) { + if (0.0f >= posData->mWidth.GetPercentValue()) { makeAuto= PR_TRUE; } } if (makeAuto) { + nsMutableStylePosition position(mStyleContext); position->mWidth = nsStyleCoord(eStyleUnit_Auto); } return NS_OK; diff --git a/mozilla/layout/xul/base/src/outliner/src/nsOutlinerBodyFrame.h b/mozilla/layout/xul/base/src/outliner/src/nsOutlinerBodyFrame.h index 82611ee190b..eb451822294 100644 --- a/mozilla/layout/xul/base/src/outliner/src/nsOutlinerBodyFrame.h +++ b/mozilla/layout/xul/base/src/outliner/src/nsOutlinerBodyFrame.h @@ -28,6 +28,7 @@ #include "nsICSSPseudoComparator.h" #include "nsIScrollbarMediator.h" #include "nsIWidget.h" +#include "nsHashtable.h" #ifdef USE_IMG2 #include "imgIDecoderObserver.h" diff --git a/mozilla/layout/xul/base/src/tree/src/nsTreeBodyFrame.h b/mozilla/layout/xul/base/src/tree/src/nsTreeBodyFrame.h index 82611ee190b..eb451822294 100644 --- a/mozilla/layout/xul/base/src/tree/src/nsTreeBodyFrame.h +++ b/mozilla/layout/xul/base/src/tree/src/nsTreeBodyFrame.h @@ -28,6 +28,7 @@ #include "nsICSSPseudoComparator.h" #include "nsIScrollbarMediator.h" #include "nsIWidget.h" +#include "nsHashtable.h" #ifdef USE_IMG2 #include "imgIDecoderObserver.h"