pjs/layout/style/nsStyleContext.cpp

2663 строки
76 KiB
C++
Исходник Обычный вид История

1998-04-14 00:24:54 +04:00
/* -*- 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/
1998-04-14 00:24:54 +04:00
*
* 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.
1998-04-14 00:24:54 +04:00
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
1998-04-14 00:24:54 +04:00
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* IBM Corporation
*
* This Original Code has been modified by IBM Corporation.
* Modifications made by IBM described herein are
* Copyright (c) International Business Machines
* Corporation, 2000
*
* Modifications to Mozilla code or documentation
* identified per MPL Section 3.3
*
* Date Modified by Description of modification
* 03/20/2000 IBM Corp. BiDi - ability to change the default direction of the browser
*
1998-04-14 00:24:54 +04:00
*/
#include "nsIStyleContext.h"
#include "nsIMutableStyleContext.h"
1998-04-14 00:24:54 +04:00
#include "nsStyleConsts.h"
#include "nsString.h"
#include "nsUnitConversion.h"
#include "nsIPresContext.h"
#include "nsIStyleRule.h"
#include "nsISupportsArray.h"
#include "nsCRT.h"
#include "nsIFrame.h"
#include "nsCOMPtr.h"
#include "nsIStyleSet.h"
#include "nsISizeOfHandler.h"
#include "nsIPresShell.h"
1998-04-14 00:24:54 +04:00
static NS_DEFINE_IID(kIStyleContextIID, NS_ISTYLECONTEXT_IID);
1999-04-02 22:48:55 +04:00
#define DELETE_ARRAY_IF(array) if (array) { delete[] array; array = nsnull; }
1998-04-21 04:02:44 +04:00
//#ifdef DEBUG_SC_SHARING
1998-04-21 04:02:44 +04:00
// --------------------
// nsStyleFont
//
nsStyleFont::nsStyleFont(void)
: mFont(nsnull, NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL, NS_FONT_DECORATION_NONE, 0),
mFixedFont(nsnull, NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL, NS_FONT_DECORATION_NONE, 0)
{}
nsStyleFont::nsStyleFont(const nsFont& aVariableFont, const nsFont& aFixedFont)
: mFont(aVariableFont),
mFixedFont(aFixedFont)
{ }
1998-04-14 00:24:54 +04:00
nsStyleFont::~nsStyleFont(void) { }
1998-04-14 00:24:54 +04:00
struct StyleFontImpl : public nsStyleFont {
StyleFontImpl(const nsFont& aVariableFont, const nsFont& aFixedFont)
: nsStyleFont(aVariableFont, aFixedFont)
1998-04-14 00:24:54 +04:00
{}
void ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleFont& aSource);
void CopyTo(nsStyleFont& aDest) const;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleFontImpl& aOther) const;
static PRInt32 CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2);
1998-04-14 00:24:54 +04:00
private: // These are not allowed
StyleFontImpl(const StyleFontImpl& aOther);
StyleFontImpl& operator=(const StyleFontImpl& aOther);
};
void StyleFontImpl::ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext)
1998-04-14 00:24:54 +04:00
{
if (nsnull != aParent) {
mFont = aParent->mFont;
mFixedFont = aParent->mFixedFont;
1998-07-23 21:57:16 +04:00
mFlags = aParent->mFlags;
}
else {
aPresContext->GetDefaultFont(mFont);
aPresContext->GetDefaultFixedFont(mFixedFont);
1998-07-23 21:57:16 +04:00
mFlags = NS_STYLE_FONT_DEFAULT;
}
1998-04-14 00:24:54 +04:00
}
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;
}
1999-02-27 10:11:42 +03:00
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;
1999-02-27 10:11:42 +03:00
}
return NS_STYLE_HINT_REFLOW;
}
1998-04-21 04:02:44 +04:00
// --------------------
// nsStyleColor
//
nsStyleColor::nsStyleColor(void) { }
nsStyleColor::~nsStyleColor(void) { }
1998-04-14 00:24:54 +04:00
struct StyleColorImpl: public nsStyleColor {
StyleColorImpl(void) { }
1998-04-14 00:24:54 +04:00
void ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleColor& aSource);
void CopyTo(nsStyleColor& aDest) const;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleColorImpl& aOther) const;
1998-04-14 00:24:54 +04:00
private: // These are not allowed
StyleColorImpl(const StyleColorImpl& aOther);
StyleColorImpl& operator=(const StyleColorImpl& aOther);
};
void StyleColorImpl::ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext)
1998-04-14 00:24:54 +04:00
{
if (nsnull != aParent) {
mColor = aParent->mColor;
1999-03-25 09:34:57 +03:00
mOpacity = aParent->mOpacity;
}
else {
if (nsnull != aPresContext) {
aPresContext->GetDefaultColor(&mColor);
}
else {
mColor = NS_RGB(0x00, 0x00, 0x00);
}
1999-03-25 09:34:57 +03:00
mOpacity = 1.0f;
}
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;
}
1998-11-18 05:23:39 +03:00
mCursor = NS_STYLE_CURSOR_AUTO;
1998-04-14 00:24:54 +04:00
}
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;
}
1999-02-27 10:11:42 +03:00
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;
}
1998-04-14 00:24:54 +04:00
1998-04-21 04:02:44 +04:00
// --------------------
// nsStyleSpacing
//
// XXX this is here to support deprecated calc spacing methods only
static nscoord kBorderWidths[3];
static PRBool kWidthsInitialized = PR_FALSE;
nsStyleSpacing::nsStyleSpacing(void) { }
#define NS_SPACING_MARGIN 0
#define NS_SPACING_PADDING 1
#define NS_SPACING_BORDER 2
static nscoord CalcSideFor(const nsIFrame* aFrame, const nsStyleCoord& aCoord,
PRUint8 aSpacing, PRUint8 aSide,
const nscoord* aEnumTable, PRInt32 aNumEnums)
{
nscoord result = 0;
switch (aCoord.GetUnit()) {
case eStyleUnit_Auto:
1999-02-18 06:24:58 +03:00
// Auto margins are handled by layout
break;
case eStyleUnit_Inherit:
nsIFrame* parentFrame;
aFrame->GetParent(&parentFrame); // XXX may not be direct parent...
if (nsnull != parentFrame) {
nsIStyleContext* parentContext;
parentFrame->GetStyleContext(&parentContext);
if (nsnull != parentContext) {
const nsStyleSpacing* parentSpacing = (const nsStyleSpacing*)parentContext->GetStyleData(eStyleStruct_Spacing);
nsMargin parentMargin;
switch (aSpacing) {
case NS_SPACING_MARGIN: parentSpacing->CalcMarginFor(parentFrame, parentMargin);
break;
case NS_SPACING_PADDING: parentSpacing->CalcPaddingFor(parentFrame, parentMargin);
break;
case NS_SPACING_BORDER: parentSpacing->CalcBorderFor(parentFrame, parentMargin);
break;
}
switch (aSide) {
case NS_SIDE_LEFT: result = parentMargin.left; break;
case NS_SIDE_TOP: result = parentMargin.top; break;
case NS_SIDE_RIGHT: result = parentMargin.right; break;
case NS_SIDE_BOTTOM: result = parentMargin.bottom; break;
}
NS_RELEASE(parentContext);
}
}
1998-10-27 06:03:02 +03:00
break;
case eStyleUnit_Percent:
{
nscoord baseWidth = 0;
PRBool isBase = PR_FALSE;
nsIFrame* frame;
aFrame->GetParent(&frame);
while (nsnull != frame) {
frame->IsPercentageBase(isBase);
if (isBase) {
nsSize size;
frame->GetSize(size);
1998-05-19 01:04:26 +04:00
baseWidth = size.width; // not really width, need to subtract out padding...
break;
}
frame->GetParent(&frame);
}
result = (nscoord)((float)baseWidth * aCoord.GetPercentValue());
}
break;
case eStyleUnit_Coord:
result = aCoord.GetCoordValue();
break;
case eStyleUnit_Enumerated:
if (nsnull != aEnumTable) {
PRInt32 value = aCoord.GetIntValue();
if ((0 <= value) && (value < aNumEnums)) {
return aEnumTable[aCoord.GetIntValue()];
}
}
break;
case eStyleUnit_Null:
case eStyleUnit_Normal:
case eStyleUnit_Integer:
case eStyleUnit_Proportional:
default:
result = 0;
break;
}
1998-09-22 06:08:45 +04:00
if ((NS_SPACING_PADDING == aSpacing) || (NS_SPACING_BORDER == aSpacing)) {
if (result < 0) {
result = 0;
}
}
return result;
}
static void CalcSidesFor(const nsIFrame* aFrame, const nsStyleSides& aSides,
PRUint8 aSpacing,
const nscoord* aEnumTable, PRInt32 aNumEnums,
nsMargin& aResult)
{
nsStyleCoord coord;
aResult.left = CalcSideFor(aFrame, aSides.GetLeft(coord), aSpacing, NS_SIDE_LEFT,
aEnumTable, aNumEnums);
aResult.top = CalcSideFor(aFrame, aSides.GetTop(coord), aSpacing, NS_SIDE_TOP,
aEnumTable, aNumEnums);
aResult.right = CalcSideFor(aFrame, aSides.GetRight(coord), aSpacing, NS_SIDE_RIGHT,
aEnumTable, aNumEnums);
aResult.bottom = CalcSideFor(aFrame, aSides.GetBottom(coord), aSpacing, NS_SIDE_BOTTOM,
aEnumTable, aNumEnums);
}
void nsStyleSpacing::CalcMarginFor(const nsIFrame* aFrame, nsMargin& aMargin) const
{
if (mHasCachedMargin) {
aMargin = mCachedMargin;
}
else {
CalcSidesFor(aFrame, mMargin, NS_SPACING_MARGIN, nsnull, 0, aMargin);
}
}
void nsStyleSpacing::CalcPaddingFor(const nsIFrame* aFrame, nsMargin& aPadding) const
{
if (mHasCachedPadding) {
aPadding = mCachedPadding;
}
else {
CalcSidesFor(aFrame, mPadding, NS_SPACING_PADDING, nsnull, 0, aPadding);
}
}
void nsStyleSpacing::CalcBorderFor(const nsIFrame* aFrame, nsMargin& aBorder) const
{
if (mHasCachedBorder) {
aBorder = mCachedBorder;
}
else {
CalcSidesFor(aFrame, mBorder, NS_SPACING_BORDER, kBorderWidths, 3, aBorder);
}
}
void nsStyleSpacing::CalcBorderPaddingFor(const nsIFrame* aFrame, nsMargin& aBorderPadding) const
1998-04-21 04:02:44 +04:00
{
if (mHasCachedPadding && mHasCachedBorder) {
aBorderPadding = mCachedBorderPadding;
}
else {
nsMargin border;
CalcBorderFor(aFrame, border);
CalcPaddingFor(aFrame, aBorderPadding);
aBorderPadding += border;
}
1998-04-21 04:02:44 +04:00
}
PRBool nsStyleSpacing::GetMargin(nsMargin& aMargin) const
{
if (mHasCachedMargin) {
aMargin = mCachedMargin;
return PR_TRUE;
}
return PR_FALSE;
}
PRBool nsStyleSpacing::GetPadding(nsMargin& aPadding) const
{
if (mHasCachedPadding) {
aPadding = mCachedPadding;
return PR_TRUE;
}
return PR_FALSE;
}
PRBool nsStyleSpacing::GetBorder(nsMargin& aBorder) const
{
if (mHasCachedBorder) {
aBorder = mCachedBorder;
return PR_TRUE;
}
return PR_FALSE;
}
PRBool nsStyleSpacing::GetBorderPadding(nsMargin& aBorderPadding) const
{
if (mHasCachedPadding && mHasCachedBorder) {
aBorderPadding = mCachedBorderPadding;
return PR_TRUE;
}
return PR_FALSE;
}
#define BORDER_COLOR_DEFINED 0x80
#define BORDER_COLOR_SPECIAL 0x40
#define BORDER_STYLE_MASK 0x3F
PRUint8 nsStyleSpacing::GetBorderStyle(PRUint8 aSide) const
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
return (mBorderStyle[aSide] & BORDER_STYLE_MASK);
}
void nsStyleSpacing::SetBorderStyle(PRUint8 aSide, PRUint8 aStyle)
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
mBorderStyle[aSide] &= ~BORDER_STYLE_MASK;
mBorderStyle[aSide] |= (aStyle & BORDER_STYLE_MASK);
}
PRBool nsStyleSpacing::GetBorderColor(PRUint8 aSide, nscolor& aColor) const
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
if ((mBorderStyle[aSide] & BORDER_COLOR_SPECIAL) == 0) {
aColor = mBorderColor[aSide];
return PR_TRUE;
}
return PR_FALSE;
}
void nsStyleSpacing::SetBorderColor(PRUint8 aSide, nscolor aColor)
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
mBorderColor[aSide] = aColor;
mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
mBorderStyle[aSide] |= BORDER_COLOR_DEFINED;
}
void nsStyleSpacing::SetBorderTransparent(PRUint8 aSide)
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
mBorderStyle[aSide] |= (BORDER_COLOR_DEFINED | BORDER_COLOR_SPECIAL);
}
void nsStyleSpacing::UnsetBorderColor(PRUint8 aSide)
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
mBorderStyle[aSide] &= BORDER_STYLE_MASK;
}
PRBool nsStyleSpacing::GetOutlineWidth(nscoord& aWidth) const
{
if (mHasCachedOutline) {
aWidth = mCachedOutlineWidth;
return PR_TRUE;
}
return PR_FALSE;
}
PRUint8 nsStyleSpacing::GetOutlineStyle(void) const
{
return (mOutlineStyle & BORDER_STYLE_MASK);
}
void nsStyleSpacing::SetOutlineStyle(PRUint8 aStyle)
{
mOutlineStyle &= ~BORDER_STYLE_MASK;
mOutlineStyle |= (aStyle & BORDER_STYLE_MASK);
}
PRBool nsStyleSpacing::GetOutlineColor(nscolor& aColor) const
{
if ((mOutlineStyle & BORDER_COLOR_SPECIAL) == 0) {
aColor = mOutlineColor;
return PR_TRUE;
}
return PR_FALSE;
}
void nsStyleSpacing::SetOutlineColor(nscolor aColor)
{
mOutlineColor = aColor;
mOutlineStyle &= ~BORDER_COLOR_SPECIAL;
mOutlineStyle |= BORDER_COLOR_DEFINED;
}
void nsStyleSpacing::SetOutlineInvert(void)
{
mOutlineStyle |= (BORDER_COLOR_DEFINED | BORDER_COLOR_SPECIAL);
}
1998-04-21 04:02:44 +04:00
struct StyleSpacingImpl: public nsStyleSpacing {
StyleSpacingImpl(void)
: nsStyleSpacing()
{}
void ResetFrom(const nsStyleSpacing* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleSpacing& aSource);
void CopyTo(nsStyleSpacing& aDest) const;
void RecalcData(nsIPresContext* aPresContext, nscolor color);
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleSpacingImpl& aOther) const;
1998-04-21 04:02:44 +04:00
};
void StyleSpacingImpl::ResetFrom(const nsStyleSpacing* aParent, nsIPresContext* aPresContext)
1998-04-21 04:02:44 +04:00
{
// XXX support kBorderWidhts until deprecated methods are removed
if (! kWidthsInitialized) {
float pixelsToTwips = 20.0f;
if (aPresContext) {
aPresContext->GetPixelsToTwips(&pixelsToTwips);
}
kBorderWidths[NS_STYLE_BORDER_WIDTH_THIN] = NSIntPixelsToTwips(1, pixelsToTwips);
kBorderWidths[NS_STYLE_BORDER_WIDTH_MEDIUM] = NSIntPixelsToTwips(3, pixelsToTwips);
kBorderWidths[NS_STYLE_BORDER_WIDTH_THICK] = NSIntPixelsToTwips(5, pixelsToTwips);
kWidthsInitialized = PR_TRUE;
}
1998-04-21 04:02:44 +04:00
// spacing values not inherited
mMargin.Reset();
mPadding.Reset();
nsStyleCoord medium(NS_STYLE_BORDER_WIDTH_MEDIUM, eStyleUnit_Enumerated);
mBorder.SetLeft(medium);
mBorder.SetTop(medium);
mBorder.SetRight(medium);
mBorder.SetBottom(medium);
mBorderStyle[0] = NS_STYLE_BORDER_STYLE_NONE;
mBorderStyle[1] = NS_STYLE_BORDER_STYLE_NONE;
mBorderStyle[2] = NS_STYLE_BORDER_STYLE_NONE;
mBorderStyle[3] = NS_STYLE_BORDER_STYLE_NONE;
mBorderColor[0] = NS_RGB(0, 0, 0);
mBorderColor[1] = NS_RGB(0, 0, 0);
mBorderColor[2] = NS_RGB(0, 0, 0);
mBorderColor[3] = NS_RGB(0, 0, 0);
mBorderRadius.Reset();
mOutlineRadius.Reset();
mOutlineWidth = medium;
mOutlineStyle = NS_STYLE_BORDER_STYLE_NONE;
mOutlineColor = NS_RGB(0, 0, 0);
mFloatEdge = NS_STYLE_FLOAT_EDGE_CONTENT;
mHasCachedMargin = PR_FALSE;
mHasCachedPadding = PR_FALSE;
mHasCachedBorder = PR_FALSE;
mHasCachedOutline = PR_FALSE;
1998-04-21 04:02:44 +04:00
}
void StyleSpacingImpl::SetFrom(const nsStyleSpacing& aSource)
{
nsCRT::memcpy((nsStyleSpacing*)this, &aSource, sizeof(nsStyleSpacing));
}
void StyleSpacingImpl::CopyTo(nsStyleSpacing& aDest) const
{
nsCRT::memcpy(&aDest, (const nsStyleSpacing*)this, sizeof(nsStyleSpacing));
}
inline PRBool IsFixedUnit(nsStyleUnit aUnit, PRBool aEnumOK)
{
return PRBool((aUnit == eStyleUnit_Null) ||
(aUnit == eStyleUnit_Coord) ||
(aEnumOK && (aUnit == eStyleUnit_Enumerated)));
}
1998-04-21 04:02:44 +04:00
static PRBool IsFixedData(const nsStyleSides& aSides, PRBool aEnumOK)
1998-04-21 04:02:44 +04:00
{
return PRBool(IsFixedUnit(aSides.GetLeftUnit(), aEnumOK) &&
IsFixedUnit(aSides.GetTopUnit(), aEnumOK) &&
IsFixedUnit(aSides.GetRightUnit(), aEnumOK) &&
IsFixedUnit(aSides.GetBottomUnit(), aEnumOK));
1998-04-21 04:02:44 +04:00
}
static nscoord CalcCoord(const nsStyleCoord& aCoord,
const nscoord* aEnumTable,
PRInt32 aNumEnums)
{
switch (aCoord.GetUnit()) {
case eStyleUnit_Null:
return 0;
case eStyleUnit_Coord:
return aCoord.GetCoordValue();
case eStyleUnit_Enumerated:
if (nsnull != aEnumTable) {
PRInt32 value = aCoord.GetIntValue();
if ((0 <= value) && (value < aNumEnums)) {
return aEnumTable[aCoord.GetIntValue()];
}
}
break;
default:
NS_ERROR("bad unit type");
break;
}
return 0;
}
1998-04-21 04:02:44 +04:00
void StyleSpacingImpl::RecalcData(nsIPresContext* aPresContext, nscolor aColor)
{
nscoord borderWidths[3];
float pixelsToTwips = 20.0f;
if (aPresContext) {
aPresContext->GetPixelsToTwips(&pixelsToTwips);
}
borderWidths[NS_STYLE_BORDER_WIDTH_THIN] = NSIntPixelsToTwips(1, pixelsToTwips);
borderWidths[NS_STYLE_BORDER_WIDTH_MEDIUM] = NSIntPixelsToTwips(3, pixelsToTwips);
borderWidths[NS_STYLE_BORDER_WIDTH_THICK] = NSIntPixelsToTwips(5, pixelsToTwips);
if (IsFixedData(mMargin, PR_FALSE)) {
nsStyleCoord coord;
mCachedMargin.left = CalcCoord(mMargin.GetLeft(coord), nsnull, 0);
mCachedMargin.top = CalcCoord(mMargin.GetTop(coord), nsnull, 0);
mCachedMargin.right = CalcCoord(mMargin.GetRight(coord), nsnull, 0);
mCachedMargin.bottom = CalcCoord(mMargin.GetBottom(coord), nsnull, 0);
mHasCachedMargin = PR_TRUE;
}
else {
mHasCachedMargin = PR_FALSE;
}
1998-04-21 04:02:44 +04:00
if (IsFixedData(mPadding, PR_FALSE)) {
nsStyleCoord coord;
mCachedPadding.left = CalcCoord(mPadding.GetLeft(coord), nsnull, 0);
mCachedPadding.top = CalcCoord(mPadding.GetTop(coord), nsnull, 0);
mCachedPadding.right = CalcCoord(mPadding.GetRight(coord), nsnull, 0);
mCachedPadding.bottom = CalcCoord(mPadding.GetBottom(coord), nsnull, 0);
mHasCachedPadding = PR_TRUE;
}
else {
mHasCachedPadding = PR_FALSE;
}
if (((NS_STYLE_BORDER_STYLE_NONE == GetBorderStyle(NS_SIDE_LEFT))||
IsFixedUnit(mBorder.GetLeftUnit(), PR_TRUE)) &&
((NS_STYLE_BORDER_STYLE_NONE == GetBorderStyle(NS_SIDE_TOP)) ||
IsFixedUnit(mBorder.GetTopUnit(), PR_TRUE)) &&
((NS_STYLE_BORDER_STYLE_NONE == GetBorderStyle(NS_SIDE_RIGHT)) ||
IsFixedUnit(mBorder.GetRightUnit(), PR_TRUE)) &&
((NS_STYLE_BORDER_STYLE_NONE == GetBorderStyle(NS_SIDE_BOTTOM)) ||
IsFixedUnit(mBorder.GetBottomUnit(), PR_TRUE))) {
nsStyleCoord coord;
if (NS_STYLE_BORDER_STYLE_NONE == GetBorderStyle(NS_SIDE_LEFT)) {
mCachedBorder.left = 0;
}
else {
mCachedBorder.left = CalcCoord(mBorder.GetLeft(coord), borderWidths, 3);
}
if (NS_STYLE_BORDER_STYLE_NONE == GetBorderStyle(NS_SIDE_TOP)) {
mCachedBorder.top = 0;
}
else {
mCachedBorder.top = CalcCoord(mBorder.GetTop(coord), borderWidths, 3);
}
if (NS_STYLE_BORDER_STYLE_NONE == GetBorderStyle(NS_SIDE_RIGHT)) {
mCachedBorder.right = 0;
}
else {
mCachedBorder.right = CalcCoord(mBorder.GetRight(coord), borderWidths, 3);
}
if (NS_STYLE_BORDER_STYLE_NONE == GetBorderStyle(NS_SIDE_BOTTOM)) {
mCachedBorder.bottom = 0;
}
else {
mCachedBorder.bottom = CalcCoord(mBorder.GetBottom(coord), borderWidths, 3);
}
mHasCachedBorder = PR_TRUE;
}
else {
mHasCachedBorder = PR_FALSE;
}
if (mHasCachedBorder && mHasCachedPadding) {
mCachedBorderPadding = mCachedPadding;
mCachedBorderPadding += mCachedBorder;
}
if ((mBorderStyle[NS_SIDE_TOP] & BORDER_COLOR_DEFINED) == 0) {
mBorderColor[NS_SIDE_TOP] = aColor;
}
if ((mBorderStyle[NS_SIDE_BOTTOM] & BORDER_COLOR_DEFINED) == 0) {
mBorderColor[NS_SIDE_BOTTOM] = aColor;
}
if ((mBorderStyle[NS_SIDE_LEFT]& BORDER_COLOR_DEFINED) == 0) {
mBorderColor[NS_SIDE_LEFT] = aColor;
}
if ((mBorderStyle[NS_SIDE_RIGHT] & BORDER_COLOR_DEFINED) == 0) {
mBorderColor[NS_SIDE_RIGHT] = aColor;
}
1998-04-21 04:02:44 +04:00
if ((NS_STYLE_BORDER_STYLE_NONE == GetOutlineStyle()) ||
IsFixedUnit(mOutlineWidth.GetUnit(), PR_TRUE)) {
if (NS_STYLE_BORDER_STYLE_NONE == GetOutlineStyle()) {
mCachedOutlineWidth = 0;
}
else {
mCachedOutlineWidth = CalcCoord(mOutlineWidth, borderWidths, 3);
}
mHasCachedOutline = PR_TRUE;
}
else {
mHasCachedOutline = PR_FALSE;
}
1998-04-21 04:02:44 +04:00
}
1999-02-27 10:11:42 +03:00
PRInt32 StyleSpacingImpl::CalcDifference(const StyleSpacingImpl& aOther) const
{
if ((mMargin == aOther.mMargin) &&
(mPadding == aOther.mPadding) &&
(mBorder == aOther.mBorder) &&
1999-09-17 04:57:06 +04:00
(mFloatEdge == aOther.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]) &&
((NS_STYLE_BORDER_STYLE_NONE == mBorderStyle[ix]) ||
(NS_STYLE_BORDER_STYLE_NONE == aOther.mBorderStyle[ix]))) {
1999-05-19 03:03:29 +04:00
return NS_STYLE_HINT_REFLOW; // border on or off
}
1999-02-27 10:11:42 +03:00
return NS_STYLE_HINT_VISUAL;
}
}
if (mBorderRadius != aOther.mBorderRadius) {
return NS_STYLE_HINT_VISUAL;
}
if ((mOutlineWidth != aOther.mOutlineWidth) ||
(mOutlineStyle != aOther.mOutlineStyle) ||
(mOutlineColor != aOther.mOutlineColor) ||
(mOutlineRadius != aOther.mOutlineRadius)) {
Landing changes Vidur made while the tree was closed for beta1 work, here's a list of the changes. r=me [1] Cutting down the size of content. Made nsIJSScriptObject inherit from nsIScriptObjectOwner [2] Cutting down the size of content. Made nsITextContent inherit from nsIContent. [3] Cutting down the size of content. Moved implementation of nsIDOMReceiver to nsListenerManager. This is not true aggregation since it isn't transitive, but it's OK for now. It will be necessary for nsListenerManager to have a reference to its content in the future anyway, so the transitivity could be done. dom/public/nsDOMPropEnums.h,v - bug 12559 dom/public/nsIJSScriptObject.h,v - [1] dom/public/html/MANIFEST,v - bug 12559 dom/public/html/Makefile.in,v - bug 12559 dom/public/html/makefile.win,v - bug 12559 dom/public/html/nsIDOMHTMLInputElement.h,v - bug 17544 dom/public/idl/html/HTMLAnchorElement.idl,v - bug 12559 dom/public/idl/html/HTMLAreaElement.idl,v - bug 12559 dom/public/idl/html/HTMLInputElement.idl,v - bug 17544 dom/src/base/nsGlobalWindow.cpp,v - bug 30700 dom/src/base/nsGlobalWindow.h,v - [1] dom/src/base/nsLocation.cpp,v - [1] dom/src/html/nsJSHTMLAnchorElement.cpp,v - bug 12559 dom/src/html/nsJSHTMLAreaElement.cpp,v - bug 12559 dom/src/html/nsJSHTMLInputElement.cpp,v - bug 17544 layout/base/public/nsIDocument.h,v - bug 27953 layout/base/public/nsITextContent.h,v - [2] layout/base/src/nsCommentNode.cpp,v - [2] layout/base/src/nsDocument.cpp,v - bug 27953 layout/base/src/nsDocument.h,v - bug 27953 layout/base/src/nsDocumentViewer.cpp,v - bug 27953 layout/base/src/nsGenericDOMDataNode.cpp,v - [3] layout/base/src/nsGenericDOMDataNode.h,v - [3] layout/base/src/nsGenericElement.cpp,v - [3] layout/base/src/nsGenericElement.h,v - [3] layout/base/src/nsNameSpaceManager.cpp,v - bug 7834 layout/base/src/nsStyleContext.cpp,v - outline property shouldn't reflow layout/base/src/nsTextNode.cpp,v - [2] layout/events/src/nsEventListenerManager.cpp,v - [3] layout/events/src/nsEventListenerManager.h,v - [3] layout/html/base/src/nsGfxScrollFrame.cpp,v - nsString->nsAutoString layout/html/content/src/nsAttributeContent.cpp,v - [2] layout/html/content/src/nsHTMLAnchorElement.cpp,v - [1][3] layout/html/content/src/nsHTMLAppletElement.cpp,v - [1][3] layout/html/content/src/nsHTMLAreaElement.cpp,v - [1][3] layout/html/content/src/nsHTMLBRElement.cpp,v - [1][3] layout/html/content/src/nsHTMLBaseElement.cpp,v - [1][3] layout/html/content/src/nsHTMLBaseFontElement.cpp,v - [1][3] layout/html/content/src/nsHTMLBodyElement.cpp,v - [1][3] layout/html/content/src/nsHTMLButtonElement.cpp,v - [1][3] layout/html/content/src/nsHTMLDListElement.cpp,v - [1][3] layout/html/content/src/nsHTMLDelElement.cpp,v - [1][3] layout/html/content/src/nsHTMLDirectoryElement.cpp,v - [1][3] layout/html/content/src/nsHTMLDivElement.cpp,v - [1][3] layout/html/content/src/nsHTMLEmbedElement.cpp,v - [1][3] layout/html/content/src/nsHTMLFieldSetElement.cpp,v - [1][3] layout/html/content/src/nsHTMLFontElement.cpp,v - [1][3] layout/html/content/src/nsHTMLFormElement.cpp,v - [1][3] layout/html/content/src/nsHTMLFrameElement.cpp,v - [1][3] layout/html/content/src/nsHTMLFrameSetElement.cpp,v - [1][3] layout/html/content/src/nsHTMLHRElement.cpp,v - [1][3] layout/html/content/src/nsHTMLHeadElement.cpp,v - [1][3] layout/html/content/src/nsHTMLHeadingElement.cpp,v - [1][3] layout/html/content/src/nsHTMLHtmlElement.cpp,v - [1][3] layout/html/content/src/nsHTMLIFrameElement.cpp,v - [1][3] layout/html/content/src/nsHTMLImageElement.cpp,v - [1][3] layout/html/content/src/nsHTMLInputElement.cpp,v - [1][3] layout/html/content/src/nsHTMLInsElement.cpp,v - [1][3] layout/html/content/src/nsHTMLIsIndexElement.cpp,v - [1][3] layout/html/content/src/nsHTMLLIElement.cpp,v - [1][3] layout/html/content/src/nsHTMLLabelElement.cpp,v - [1][3] layout/html/content/src/nsHTMLLayerElement.cpp,v - [1][3] layout/html/content/src/nsHTMLLegendElement.cpp,v - [1][3] layout/html/content/src/nsHTMLLinkElement.cpp,v - [1][3] layout/html/content/src/nsHTMLMapElement.cpp,v - [1][3] layout/html/content/src/nsHTMLMenuElement.cpp,v - [1][3] layout/html/content/src/nsHTMLMetaElement.cpp,v - [1][3] layout/html/content/src/nsHTMLModElement.cpp,v - [1][3] layout/html/content/src/nsHTMLOListElement.cpp,v - [1][3] layout/html/content/src/nsHTMLObjectElement.cpp,v - [1][3] layout/html/content/src/nsHTMLOptGroupElement.cpp,v - [1][3] layout/html/content/src/nsHTMLOptionElement.cpp,v - [1][3] layout/html/content/src/nsHTMLParagraphElement.cpp,v - [1][3] layout/html/content/src/nsHTMLParamElement.cpp,v - [1][3] layout/html/content/src/nsHTMLPreElement.cpp,v - [1][3] layout/html/content/src/nsHTMLQuoteElement.cpp,v - [1][3] layout/html/content/src/nsHTMLScriptElement.cpp,v - [1][3] layout/html/content/src/nsHTMLSelectElement.cpp,v - [1][3] layout/html/content/src/nsHTMLSpacerElement.cpp,v - [1][3] layout/html/content/src/nsHTMLSpanElement.cpp,v - [1][3] layout/html/content/src/nsHTMLStyleElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableCaptionElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableCellElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableColElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableColGroupElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableRowElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableSectionElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTextAreaElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTitleElement.cpp,v - [1][3] layout/html/content/src/nsHTMLUListElement.cpp,v - [1][3] layout/html/content/src/nsHTMLWBRElement.cpp,v - [1][3] layout/html/document/src/nsHTMLDocument.cpp,v - bug 27953 layout/html/document/src/nsHTMLDocument.h,v - bug 27953 layout/xml/content/src/nsXMLCDATASection.cpp,v - [1][2] layout/xml/content/src/nsXMLDocumentType.cpp,v - [1][2] layout/xml/content/src/nsXMLElement.h,v - [1][2] layout/xml/content/src/nsXMLEntity.cpp,v - [1][2] layout/xml/content/src/nsXMLNotation.cpp,v - [1][2] layout/xml/content/src/nsXMLProcessingInstruction.cpp,v - [1][2] layout/xul/base/src/nsBoxFrame.cpp,v - nsString->nsAutoString layout/xul/base/src/nsSliderFrame.cpp,v - nsString->nsAutoString netwerk/protocol/http/src/nsHTTPRequest.cpp,v - nsString->nsAutoString rdf/content/src/nsXULDocument.cpp,v - bug 27953 rdf/content/src/nsXULDocument.h,v - bug 27953 rdf/content/src/nsXULElement.h,v - [1] xpcom/base/IIDS.h,v - bug 12559
2000-03-17 16:27:00 +03:00
return NS_STYLE_HINT_VISUAL; // XXX: should be VISUAL: see bugs 9809 and 9816
}
1999-02-27 10:11:42 +03:00
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_REFLOW;
}
1998-04-21 04:02:44 +04:00
// --------------------
// nsStyleList
//
nsStyleList::nsStyleList(void) { }
nsStyleList::~nsStyleList(void) { }
1998-04-14 00:24:54 +04:00
struct StyleListImpl: public nsStyleList {
StyleListImpl(void) { }
1998-04-14 00:24:54 +04:00
void ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleList& aSource);
void CopyTo(nsStyleList& aDest) const;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleListImpl& aOther) const;
1998-04-14 00:24:54 +04:00
};
void StyleListImpl::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext)
1998-04-14 00:24:54 +04:00
{
if (nsnull != aParent) {
mListStyleType = aParent->mListStyleType;
mListStyleImage = aParent->mListStyleImage;
mListStylePosition = aParent->mListStylePosition;
}
else {
mListStyleType = NS_STYLE_LIST_STYLE_BASIC;
mListStylePosition = NS_STYLE_LIST_STYLE_POSITION_OUTSIDE;
mListStyleImage.Truncate();
}
1998-04-14 00:24:54 +04:00
}
void StyleListImpl::SetFrom(const nsStyleList& aSource)
{
mListStyleType = aSource.mListStyleType;
mListStylePosition = aSource.mListStylePosition;
mListStyleImage = aSource.mListStyleImage;
}
void StyleListImpl::CopyTo(nsStyleList& aDest) const
{
aDest.mListStyleType = mListStyleType;
aDest.mListStylePosition = mListStylePosition;
aDest.mListStyleImage = mListStyleImage;
}
1999-02-27 10:11:42 +03:00
PRInt32 StyleListImpl::CalcDifference(const StyleListImpl& aOther) const
{
if (mListStylePosition == aOther.mListStylePosition) {
if (mListStyleImage == aOther.mListStyleImage) {
if (mListStyleType == aOther.mListStyleType) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_REFLOW;
1999-02-27 10:11:42 +03:00
}
return NS_STYLE_HINT_REFLOW;
1999-02-27 10:11:42 +03:00
}
return NS_STYLE_HINT_REFLOW;
}
1998-04-23 03:29:01 +04:00
// --------------------
// nsStylePosition
//
nsStylePosition::nsStylePosition(void) { }
1998-04-23 03:29:01 +04:00
struct StylePositionImpl: public nsStylePosition {
StylePositionImpl(void) { }
1998-04-23 03:29:01 +04:00
void ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStylePosition& aSource);
void CopyTo(nsStylePosition& aDest) const;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StylePositionImpl& aOther) const;
1998-04-23 03:29:01 +04:00
private: // These are not allowed
StylePositionImpl(const StylePositionImpl& aOther);
StylePositionImpl& operator=(const StylePositionImpl& aOther);
};
void StylePositionImpl::ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext)
1998-04-23 03:29:01 +04:00
{
// positioning values not inherited
mPosition = NS_STYLE_POSITION_NORMAL;
nsStyleCoord autoCoord(eStyleUnit_Auto);
mOffset.SetLeft(autoCoord);
mOffset.SetTop(autoCoord);
mOffset.SetRight(autoCoord);
mOffset.SetBottom(autoCoord);
mWidth.SetAutoValue();
mMinWidth.SetCoordValue(0);
mMaxWidth.Reset();
mHeight.SetAutoValue();
mMinHeight.SetCoordValue(0);
mMaxHeight.Reset();
mBoxSizing = NS_STYLE_BOX_SIZING_CONTENT;
mZIndex.SetAutoValue();
1998-04-23 03:29:01 +04:00
}
void StylePositionImpl::SetFrom(const nsStylePosition& aSource)
{
nsCRT::memcpy((nsStylePosition*)this, &aSource, sizeof(nsStylePosition));
}
void StylePositionImpl::CopyTo(nsStylePosition& aDest) const
{
nsCRT::memcpy(&aDest, (const nsStylePosition*)this, sizeof(nsStylePosition));
}
1999-02-27 10:11:42 +03:00
PRInt32 StylePositionImpl::CalcDifference(const StylePositionImpl& 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) &&
1999-02-27 10:11:42 +03:00
(mZIndex == aOther.mZIndex)) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_REFLOW;
}
return NS_STYLE_HINT_FRAMECHANGE;
}
1998-04-21 04:02:44 +04:00
// --------------------
// nsStyleText
1998-04-21 04:02:44 +04:00
//
1998-04-14 00:24:54 +04:00
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;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleTextImpl& aOther) const;
};
void StyleTextImpl::ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext)
{
// 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;
// Inherit everything except percentage line-height values
nsStyleUnit unit = aParent->mLineHeight.GetUnit();
if ((eStyleUnit_Normal == unit) || (eStyleUnit_Factor == unit) ||
(eStyleUnit_Coord == unit)) {
mLineHeight = aParent->mLineHeight;
}
else {
mLineHeight.SetInheritValue();
}
mTextIndent = aParent->mTextIndent;
mWordSpacing = aParent->mWordSpacing;
}
else {
mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT;
mTextTransform = NS_STYLE_TEXT_TRANSFORM_NONE;
mWhiteSpace = NS_STYLE_WHITESPACE_NORMAL;
mLetterSpacing.SetNormalValue();
mLineHeight.SetNormalValue();
mTextIndent.SetCoordValue(0);
mWordSpacing.SetNormalValue();
}
}
void StyleTextImpl::SetFrom(const nsStyleText& aSource)
{
nsCRT::memcpy((nsStyleText*)this, &aSource, sizeof(nsStyleText));
}
void StyleTextImpl::CopyTo(nsStyleText& aDest) const
{
nsCRT::memcpy(&aDest, (const nsStyleText*)this, sizeof(nsStyleText));
1998-04-14 00:24:54 +04:00
}
1999-02-27 10:11:42 +03:00
PRInt32 StyleTextImpl::CalcDifference(const StyleTextImpl& aOther) const
{
if ((mTextAlign == aOther.mTextAlign) &&
(mTextTransform == aOther.mTextTransform) &&
(mWhiteSpace == aOther.mWhiteSpace) &&
(mLetterSpacing == aOther.mLetterSpacing) &&
(mLineHeight == aOther.mLineHeight) &&
(mTextIndent == aOther.mTextIndent) &&
(mWordSpacing == aOther.mWordSpacing) &&
(mVerticalAlign == aOther.mVerticalAlign)) {
if (mTextDecoration == aOther.mTextDecoration) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_VISUAL;
}
return NS_STYLE_HINT_REFLOW;
}
// --------------------
// nsStyleDisplay
//
1998-04-14 00:24:54 +04:00
nsStyleDisplay::nsStyleDisplay(void) { }
struct StyleDisplayImpl: public nsStyleDisplay {
StyleDisplayImpl(void) { }
1998-04-14 00:24:54 +04:00
void ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleDisplay& aSource);
void CopyTo(nsStyleDisplay& aDest) const;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleDisplayImpl& aOther) const;
1998-04-14 00:24:54 +04:00
};
void StyleDisplayImpl::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext)
1998-04-14 00:24:54 +04:00
{
if (nsnull != aParent) {
mDirection = aParent->mDirection;
mLanguage = aParent->mLanguage;
mVisible = aParent->mVisible;
}
else {
aPresContext->GetDefaultDirection(&mDirection);
aPresContext->GetLanguage(getter_AddRefs(mLanguage));
1999-02-02 06:24:23 +03:00
mVisible = NS_STYLE_VISIBILITY_VISIBLE;
}
mDisplay = NS_STYLE_DISPLAY_INLINE;
mFloats = NS_STYLE_FLOAT_NONE;
mBreakType = NS_STYLE_CLEAR_NONE;
mBreakBefore = PR_FALSE;
mBreakAfter = PR_FALSE;
mOverflow = NS_STYLE_OVERFLOW_VISIBLE;
mClipFlags = NS_STYLE_CLIP_AUTO;
mClip.SetRect(0,0,0,0);
1998-04-14 00:24:54 +04:00
}
void StyleDisplayImpl::SetFrom(const nsStyleDisplay& aSource)
{
mDirection = aSource.mDirection;
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;
}
void StyleDisplayImpl::CopyTo(nsStyleDisplay& aDest) const
{
aDest.mDirection = mDirection;
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;
}
1999-02-27 10:11:42 +03:00
PRInt32 StyleDisplayImpl::CalcDifference(const StyleDisplayImpl& aOther) const
{
if ((mDisplay == aOther.mDisplay) &&
(mFloats == aOther.mFloats) &&
(mOverflow == aOther.mOverflow)) {
if ((mDirection == aOther.mDirection) &&
(mLanguage == aOther.mLanguage) &&
1999-02-27 10:11:42 +03:00
(mBreakType == aOther.mBreakType) &&
(mBreakBefore == aOther.mBreakBefore) &&
(mBreakAfter == aOther.mBreakAfter)) {
if ((mVisible == aOther.mVisible) &&
(mClipFlags == aOther.mClipFlags) &&
(mClip == aOther.mClip)) {
return NS_STYLE_HINT_NONE;
}
if ((mVisible != aOther.mVisible) &&
((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) ||
(NS_STYLE_VISIBILITY_COLLAPSE == aOther.mVisible))) {
return NS_STYLE_HINT_REFLOW;
}
1999-02-27 10:11:42 +03:00
return NS_STYLE_HINT_VISUAL;
}
return NS_STYLE_HINT_REFLOW;
}
return NS_STYLE_HINT_FRAMECHANGE;
}
// --------------------
// nsStyleTable
//
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;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleTableImpl& aOther) const;
};
StyleTableImpl::StyleTableImpl()
{
ResetFrom(nsnull, nsnull);
}
void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext)
{
// values not inherited
mLayoutStrategy = NS_STYLE_TABLE_LAYOUT_AUTO;
mCols = NS_STYLE_TABLE_COLS_NONE;
mFrame = NS_STYLE_TABLE_FRAME_NONE;
mRules = NS_STYLE_TABLE_RULES_ALL;
mCellPadding.Reset();
1999-04-02 22:48:55 +04:00
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;
}
else {
mBorderCollapse = NS_STYLE_BORDER_SEPARATE;
nsCompatibility compatMode = eCompatibility_Standard;
if (aPresContext) {
aPresContext->GetCompatibilityMode(&compatMode);
}
mEmptyCells = (compatMode == eCompatibility_NavQuirks
? NS_STYLE_TABLE_EMPTY_CELLS_HIDE // bug 33244
: NS_STYLE_TABLE_EMPTY_CELLS_SHOW);
1999-04-02 22:48:55 +04:00
mCaptionSide = NS_SIDE_TOP;
mBorderSpacingX.Reset();
mBorderSpacingY.Reset();
mSpanWidth.Reset();
}
}
void StyleTableImpl::SetFrom(const nsStyleTable& aSource)
{
nsCRT::memcpy((nsStyleTable*)this, &aSource, sizeof(nsStyleTable));
}
void StyleTableImpl::CopyTo(nsStyleTable& aDest) const
{
nsCRT::memcpy(&aDest, (const nsStyleTable*)this, sizeof(nsStyleTable));
}
1999-02-27 10:11:42 +03:00
PRInt32 StyleTableImpl::CalcDifference(const StyleTableImpl& 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) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_VISUAL;
}
return NS_STYLE_HINT_REFLOW;
}
1999-04-02 22:48:55 +04:00
//-----------------------
// nsStyleContent
//
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);
}
nsresult
nsStyleContent::GetContentAt(PRUint32 aIndex, nsStyleContentType& aType, nsString& aContent) const
{
if (aIndex < mContentCount) {
aType = mContents[aIndex].mType;
aContent = mContents[aIndex].mContent;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::AllocateContents(PRUint32 aCount)
{
if (aCount != mContentCount) {
DELETE_ARRAY_IF(mContents);
if (aCount) {
mContents = new nsStyleContentData[aCount];
if (! mContents) {
mContentCount = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
}
mContentCount = aCount;
}
return NS_OK;
}
nsresult
nsStyleContent::SetContentAt(PRUint32 aIndex, nsStyleContentType aType, const nsString& aContent)
{
if (aIndex < mContentCount) {
mContents[aIndex].mType = aType;
if (aType < eStyleContentType_OpenQuote) {
mContents[aIndex].mContent = aContent;
}
else {
mContents[aIndex].mContent.Truncate();
}
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::GetCounterIncrementAt(PRUint32 aIndex, nsString& aCounter, PRInt32& aIncrement) const
{
if (aIndex < mIncrementCount) {
aCounter = mIncrements[aIndex].mCounter;
aIncrement = mIncrements[aIndex].mValue;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::AllocateCounterIncrements(PRUint32 aCount)
{
if (aCount != mIncrementCount) {
DELETE_ARRAY_IF(mIncrements);
if (aCount) {
mIncrements = new nsStyleCounterData[aCount];
if (! mIncrements) {
mIncrementCount = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
}
mIncrementCount = aCount;
}
return NS_OK;
}
nsresult
nsStyleContent::SetCounterIncrementAt(PRUint32 aIndex, const nsString& aCounter, PRInt32 aIncrement)
{
if (aIndex < mIncrementCount) {
mIncrements[aIndex].mCounter = aCounter;
mIncrements[aIndex].mValue = aIncrement;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::GetCounterResetAt(PRUint32 aIndex, nsString& aCounter, PRInt32& aValue) const
{
if (aIndex < mResetCount) {
aCounter = mResets[aIndex].mCounter;
aValue = mResets[aIndex].mValue;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::AllocateCounterResets(PRUint32 aCount)
{
if (aCount != mResetCount) {
DELETE_ARRAY_IF(mResets);
if (aCount) {
mResets = new nsStyleCounterData[aCount];
if (! mResets) {
mResetCount = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
}
mResetCount = aCount;
}
return NS_OK;
}
nsresult
nsStyleContent::SetCounterResetAt(PRUint32 aIndex, const nsString& aCounter, PRInt32 aValue)
{
if (aIndex < mResetCount) {
mResets[aIndex].mCounter = aCounter;
mResets[aIndex].mValue = aValue;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::GetQuotesAt(PRUint32 aIndex, nsString& aOpen, nsString& aClose) const
{
if (aIndex < mQuotesCount) {
aIndex *= 2;
aOpen = mQuotes[aIndex];
aClose = mQuotes[++aIndex];
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::AllocateQuotes(PRUint32 aCount)
{
if (aCount != mQuotesCount) {
DELETE_ARRAY_IF(mQuotes);
if (aCount) {
mQuotes = new nsString[aCount * 2];
if (! mQuotes) {
mQuotesCount = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
}
mQuotesCount = aCount;
}
return NS_OK;
}
nsresult
nsStyleContent::SetQuotesAt(PRUint32 aIndex, const nsString& aOpen, const nsString& aClose)
{
if (aIndex < mQuotesCount) {
aIndex *= 2;
mQuotes[aIndex] = aOpen;
mQuotes[++aIndex] = aClose;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
struct StyleContentImpl: public nsStyleContent {
StyleContentImpl(void) : nsStyleContent() { };
void ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleContent& aSource);
void CopyTo(nsStyleContent& aDest) const;
1999-04-02 22:48:55 +04:00
PRInt32 CalcDifference(const StyleContentImpl& aOther) const;
};
void
StyleContentImpl::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext)
{
// reset data
mMarkerOffset.Reset();
mContentCount = 0;
DELETE_ARRAY_IF(mContents);
mIncrementCount = 0;
DELETE_ARRAY_IF(mIncrements);
mResetCount = 0;
DELETE_ARRAY_IF(mResets);
// inherited data
if (aParent) {
if (NS_SUCCEEDED(AllocateQuotes(aParent->mQuotesCount))) {
PRUint32 ix = (mQuotesCount * 2);
while (0 < ix--) {
mQuotes[ix] = aParent->mQuotes[ix];
1999-04-02 22:48:55 +04:00
}
}
}
else {
mQuotesCount = 0;
DELETE_ARRAY_IF(mQuotes);
}
}
void StyleContentImpl::SetFrom(const nsStyleContent& aSource)
{
mMarkerOffset = aSource.mMarkerOffset;
PRUint32 index;
if (NS_SUCCEEDED(AllocateContents(aSource.ContentCount()))) {
for (index = 0; index < mContentCount; index++) {
aSource.GetContentAt(index, mContents[index].mType, mContents[index].mContent);
}
}
if (NS_SUCCEEDED(AllocateCounterIncrements(aSource.CounterIncrementCount()))) {
for (index = 0; index < mIncrementCount; index++) {
aSource.GetCounterIncrementAt(index, mIncrements[index].mCounter,
mIncrements[index].mValue);
}
}
if (NS_SUCCEEDED(AllocateCounterResets(aSource.CounterResetCount()))) {
for (index = 0; index < mResetCount; index++) {
aSource.GetCounterResetAt(index, mResets[index].mCounter,
mResets[index].mValue);
}
}
if (NS_SUCCEEDED(AllocateQuotes(aSource.QuotesCount()))) {
PRUint32 count = (mQuotesCount * 2);
for (index = 0; index < count; index += 2) {
aSource.GetQuotesAt(index, mQuotes[index], mQuotes[index + 1]);
}
}
}
void StyleContentImpl::CopyTo(nsStyleContent& aDest) const
{
aDest.mMarkerOffset = mMarkerOffset;
PRUint32 index;
if (NS_SUCCEEDED(aDest.AllocateContents(mContentCount))) {
for (index = 0; index < mContentCount; index++) {
aDest.SetContentAt(index, mContents[index].mType,
mContents[index].mContent);
}
}
if (NS_SUCCEEDED(aDest.AllocateCounterIncrements(mIncrementCount))) {
for (index = 0; index < mIncrementCount; index++) {
aDest.SetCounterIncrementAt(index, mIncrements[index].mCounter,
mIncrements[index].mValue);
}
}
if (NS_SUCCEEDED(aDest.AllocateCounterResets(mResetCount))) {
for (index = 0; index < mResetCount; index++) {
aDest.SetCounterResetAt(index, mResets[index].mCounter,
mResets[index].mValue);
}
}
if (NS_SUCCEEDED(aDest.AllocateQuotes(mQuotesCount))) {
PRUint32 count = (mQuotesCount * 2);
for (index = 0; index < count; index += 2) {
aDest.SetQuotesAt(index, mQuotes[index], mQuotes[index + 1]);
}
}
}
1999-04-02 22:48:55 +04:00
PRInt32
StyleContentImpl::CalcDifference(const StyleContentImpl& aOther) const
{
if (mContentCount == aOther.mContentCount) {
if ((mMarkerOffset == aOther.mMarkerOffset) &&
(mIncrementCount == aOther.mIncrementCount) &&
(mResetCount == aOther.mResetCount) &&
(mQuotesCount == aOther.mQuotesCount)) {
PRUint32 ix = mContentCount;
while (0 < ix--) {
if ((mContents[ix].mType != aOther.mContents[ix].mType) ||
(mContents[ix].mContent != aOther.mContents[ix].mContent)) {
1999-04-02 22:48:55 +04:00
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)) {
1999-04-02 22:48:55 +04:00
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)) {
1999-04-02 22:48:55 +04:00
return NS_STYLE_HINT_REFLOW;
}
}
ix = (mQuotesCount * 2);
while (0 < ix--) {
if (mQuotes[ix] != aOther.mQuotes[ix]) {
1999-04-02 22:48:55 +04:00
return NS_STYLE_HINT_REFLOW;
}
}
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_REFLOW;
}
return NS_STYLE_HINT_FRAMECHANGE;
}
//-----------------------
// nsStyleUserInterface
//
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;
private: // These are not allowed
StyleUserInterfaceImpl(const StyleUserInterfaceImpl& aOther);
StyleUserInterfaceImpl& operator=(const StyleUserInterfaceImpl& aOther);
};
void StyleUserInterfaceImpl::ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext)
{
if (aParent) {
mUserInput = aParent->mUserInput;
mUserModify = aParent->mUserModify;
mUserFocus = aParent->mUserFocus;
}
else {
mUserInput = NS_STYLE_USER_INPUT_AUTO;
mUserModify = NS_STYLE_USER_MODIFY_READ_ONLY;
mUserFocus = NS_STYLE_USER_FOCUS_NONE;
}
mUserSelect = NS_STYLE_USER_SELECT_AUTO;
mKeyEquivalent = PRUnichar(0); // XXX what type should this be?
mResizer = NS_STYLE_RESIZER_AUTO;
2000-04-16 00:15:37 +04:00
mBehavior.SetLength(0);
}
void StyleUserInterfaceImpl::SetFrom(const nsStyleUserInterface& aSource)
{
mUserInput = aSource.mUserInput;
mUserModify = aSource.mUserModify;
mUserFocus = aSource.mUserFocus;
mUserSelect = aSource.mUserSelect;
mKeyEquivalent = aSource.mKeyEquivalent;
mResizer = aSource.mResizer;
mBehavior = aSource.mBehavior;
}
void StyleUserInterfaceImpl::CopyTo(nsStyleUserInterface& aDest) const
{
aDest.mUserInput = mUserInput;
aDest.mUserModify = mUserModify;
aDest.mUserFocus = mUserFocus;
aDest.mUserSelect = mUserSelect;
aDest.mKeyEquivalent = mKeyEquivalent;
aDest.mResizer = mResizer;
aDest.mBehavior = mBehavior;
}
PRInt32 StyleUserInterfaceImpl::CalcDifference(const StyleUserInterfaceImpl& aOther) const
{
if (mBehavior != aOther.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)) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_CONTENT;
}
return NS_STYLE_HINT_VISUAL;
}
if ((mUserInput != aOther.mUserInput) &&
((NS_STYLE_USER_INPUT_NONE == mUserInput) ||
(NS_STYLE_USER_INPUT_NONE == aOther.mUserInput))) {
return NS_STYLE_HINT_FRAMECHANGE;
}
return NS_STYLE_HINT_VISUAL;
}
//-----------------------
// nsStylePrint
//
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;
private: // These are not allowed
StylePrintImpl(const StylePrintImpl& aOther);
StylePrintImpl& operator=(const StylePrintImpl& aOther);
};
void StylePrintImpl::ResetFrom(const nsStylePrint* 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;
}
else {
mPageBreakBefore = NS_STYLE_PAGE_BREAK_AUTO;
mPageBreakAfter = NS_STYLE_PAGE_BREAK_AUTO;
mPageBreakInside = NS_STYLE_PAGE_BREAK_AUTO;
mWidows = 2;
mOrphans = 2;
mMarks = NS_STYLE_PAGE_MARKS_NONE;
mSizeWidth.SetAutoValue();
mSizeHeight.SetAutoValue();
}
}
void StylePrintImpl::SetFrom(const nsStylePrint& aSource)
{
nsCRT::memcpy((nsStylePrint*)this, &aSource, sizeof(nsStylePrint));
}
void StylePrintImpl::CopyTo(nsStylePrint& aDest) const
{
nsCRT::memcpy(&aDest, (const nsStylePrint*)this, sizeof(nsStylePrint));
}
PRInt32 StylePrintImpl::CalcDifference(const StylePrintImpl& 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)) {
return NS_STYLE_HINT_NONE;
}
if (mMarks != aOther.mMarks) {
return NS_STYLE_HINT_VISUAL;
}
return NS_STYLE_HINT_REFLOW;
}
1998-04-14 00:24:54 +04:00
//----------------------------------------------------------------------
class StyleContextImpl : public nsIStyleContext,
protected nsIMutableStyleContext { // you can't QI to nsIMutableStyleContext
1998-04-14 00:24:54 +04:00
public:
StyleContextImpl(nsIStyleContext* aParent, nsIAtom* aPseudoTag,
nsISupportsArray* aRules,
nsIPresContext* aPresContext);
virtual ~StyleContextImpl();
1998-04-14 00:24:54 +04:00
1999-02-26 23:02:06 +03:00
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
1998-04-14 00:24:54 +04:00
NS_DECL_ISUPPORTS
virtual nsIStyleContext* GetParent(void) const;
virtual nsISupportsArray* GetStyleRules(void) const;
1998-05-21 00:32:57 +04:00
virtual PRInt32 GetStyleRuleCount(void) const;
NS_IMETHOD GetPseudoType(nsIAtom*& aPseudoTag) const;
1998-04-14 00:24:54 +04:00
NS_IMETHOD FindChildWithRules(const nsIAtom* aPseudoTag, nsISupportsArray* aRules,
nsIStyleContext*& aResult);
1998-04-14 00:24:54 +04:00
virtual PRBool Equals(const nsIStyleContext* aOther) const;
virtual PRUint32 HashValue(void) const;
NS_IMETHOD RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse = PR_TRUE);
NS_IMETHOD GetStyle(nsStyleStructID aSID, nsStyleStruct& aStruct) const;
NS_IMETHOD SetStyle(nsStyleStructID aSID, const nsStyleStruct& aStruct);
virtual const nsStyleStruct* GetStyleData(nsStyleStructID aSID);
virtual nsStyleStruct* GetMutableStyleData(nsStyleStructID aSID);
1998-04-14 00:24:54 +04:00
virtual void ForceUnique(void);
virtual void RecalcAutomaticData(nsIPresContext* aPresContext);
1999-02-27 10:11:42 +03:00
NS_IMETHOD CalcStyleDifference(nsIStyleContext* aOther, PRInt32& aHint) const;
1998-04-14 00:24:54 +04:00
1998-05-19 01:04:26 +04:00
virtual void List(FILE* out, PRInt32 aIndent);
virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize);
protected:
void AppendChild(StyleContextImpl* aChild);
1998-10-27 06:03:02 +03:00
void RemoveChild(StyleContextImpl* aChild);
StyleContextImpl* mParent;
StyleContextImpl* mChild;
StyleContextImpl* mEmptyChild;
StyleContextImpl* mPrevSibling;
StyleContextImpl* mNextSibling;
nsIAtom* mPseudoTag;
1998-10-08 05:27:38 +04:00
PRUint32 mRuleHash;
1998-04-14 00:24:54 +04:00
nsISupportsArray* mRules;
PRInt32 mDataCode;
1998-04-14 00:24:54 +04:00
// the style data...
StyleFontImpl mFont;
StyleColorImpl mColor;
StyleSpacingImpl mSpacing;
StyleListImpl mList;
StylePositionImpl mPosition;
StyleTextImpl mText;
StyleDisplayImpl mDisplay;
StyleTableImpl mTable;
StyleContentImpl mContent;
StyleUserInterfaceImpl mUserInterface;
StylePrintImpl mPrint;
nsCOMPtr<nsIStyleSet> mStyleSet;
1998-04-14 00:24:54 +04:00
};
static PRInt32 gLastDataCode;
static PRBool HashStyleRule(nsISupports* aRule, void* aData)
1998-10-08 05:27:38 +04:00
{
*((PRUint32*)aData) ^= PRUint32(aRule);
return PR_TRUE;
}
StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent,
nsIAtom* aPseudoTag,
nsISupportsArray* aRules,
1998-04-14 00:24:54 +04:00
nsIPresContext* aPresContext)
: mParent((StyleContextImpl*)aParent),
mChild(nsnull),
1998-10-08 05:27:38 +04:00
mEmptyChild(nsnull),
mPseudoTag(aPseudoTag),
1998-04-14 00:24:54 +04:00
mRules(aRules),
mDataCode(-1),
mFont(aPresContext->GetDefaultFontDeprecated(), aPresContext->GetDefaultFixedFontDeprecated()),
1998-04-14 00:24:54 +04:00
mColor(),
1998-04-21 04:02:44 +04:00
mSpacing(),
1998-04-14 00:24:54 +04:00
mList(),
mPosition(),
mText(),
mDisplay(),
mTable(),
mContent(),
mUserInterface(),
mPrint()
1998-04-14 00:24:54 +04:00
{
NS_INIT_REFCNT();
NS_IF_ADDREF(mPseudoTag);
1998-04-14 00:24:54 +04:00
NS_IF_ADDREF(mRules);
mNextSibling = this;
mPrevSibling = this;
if (nsnull != mParent) {
NS_ADDREF(mParent);
mParent->AppendChild(this);
1998-04-14 00:24:54 +04:00
}
1998-10-08 05:27:38 +04:00
mRuleHash = 0;
if (nsnull != mRules) {
mRules->EnumerateForwards(HashStyleRule, &mRuleHash);
}
#ifdef DEBUG_SC_SHARING
// add this instance to the style set
nsIPresShell* shell = nsnull;
aPresContext->GetShell(&shell);
if (shell) {
shell->GetStyleSet( getter_AddRefs(mStyleSet) );
if (mStyleSet) {
// add it to the set: the set does NOT addref or release
// NOTE: QI here is not a good idea - this is the constructor so we are not whole yet...
mStyleSet->AddStyleContext((nsIStyleContext *)this);
}
NS_RELEASE( shell );
}
#endif // DEBUG_SC_SHARING
1998-04-14 00:24:54 +04:00
}
StyleContextImpl::~StyleContextImpl()
{
NS_ASSERTION((nsnull == mChild) && (nsnull == mEmptyChild), "destructing context with children");
1999-04-02 22:48:55 +04:00
if (mParent) {
mParent->RemoveChild(this);
NS_RELEASE(mParent);
}
NS_IF_RELEASE(mPseudoTag);
1998-04-14 00:24:54 +04:00
NS_IF_RELEASE(mRules);
#ifdef DEBUG_SC_SHARING
// remove this instance from the style set (remember, the set does not AddRef or Release us)
if (mStyleSet) {
mStyleSet->RemoveStyleContext((nsIStyleContext *)this);
}
#endif // DEBUG_SC_SHARING
1999-04-28 02:08:48 +04:00
}
NS_IMPL_ADDREF(StyleContextImpl)
NS_IMPL_RELEASE(StyleContextImpl)
NS_IMETHODIMP
StyleContextImpl::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_PRECONDITION(nsnull != aInstancePtr, "null pointer");
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(NS_GET_IID(nsIStyleContext))) {
*aInstancePtr = (void*)(nsIStyleContext*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) (nsISupports*)(nsIStyleContext*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
1998-04-14 00:24:54 +04:00
nsIStyleContext* StyleContextImpl::GetParent(void) const
{
NS_IF_ADDREF(mParent);
return mParent;
}
void StyleContextImpl::AppendChild(StyleContextImpl* aChild)
{
if (0 == aChild->GetStyleRuleCount()) {
if (nsnull == mEmptyChild) {
mEmptyChild = aChild;
}
else {
aChild->mNextSibling = mEmptyChild;
aChild->mPrevSibling = mEmptyChild->mPrevSibling;
mEmptyChild->mPrevSibling->mNextSibling = aChild;
mEmptyChild->mPrevSibling = aChild;
}
}
else {
1998-10-08 05:27:38 +04:00
if (nsnull == mChild) {
mChild = aChild;
}
else {
aChild->mNextSibling = mChild;
aChild->mPrevSibling = mChild->mPrevSibling;
mChild->mPrevSibling->mNextSibling = aChild;
mChild->mPrevSibling = aChild;
}
}
}
1998-10-27 06:03:02 +03:00
void StyleContextImpl::RemoveChild(StyleContextImpl* aChild)
{
NS_ASSERTION((nsnull != aChild) && (this == aChild->mParent), "bad argument");
1998-10-27 06:03:02 +03:00
if ((nsnull == aChild) || (this != aChild->mParent)) {
1998-10-27 06:03:02 +03:00
return;
}
if (0 == aChild->GetStyleRuleCount()) { // is empty
if (aChild->mPrevSibling != aChild) { // has siblings
if (mEmptyChild == aChild) {
mEmptyChild = mEmptyChild->mNextSibling;
}
}
else {
NS_ASSERTION(mEmptyChild == aChild, "bad sibling pointers");
mEmptyChild = nsnull;
}
1998-10-27 06:03:02 +03:00
}
else { // isn't empty
if (aChild->mPrevSibling != aChild) { // has siblings
1998-10-27 06:03:02 +03:00
if (mChild == aChild) {
mChild = mChild->mNextSibling;
}
}
else {
NS_ASSERTION(mChild == aChild, "bad sibling pointers");
if (mChild == aChild) {
mChild = nsnull;
}
}
}
aChild->mPrevSibling->mNextSibling = aChild->mNextSibling;
aChild->mNextSibling->mPrevSibling = aChild->mPrevSibling;
aChild->mNextSibling = aChild;
aChild->mPrevSibling = aChild;
1998-10-27 06:03:02 +03:00
}
1998-04-14 00:24:54 +04:00
nsISupportsArray* StyleContextImpl::GetStyleRules(void) const
{
nsISupportsArray* result = mRules;
NS_IF_ADDREF(result);
return result;
1998-04-14 00:24:54 +04:00
}
1998-05-21 00:32:57 +04:00
PRInt32 StyleContextImpl::GetStyleRuleCount(void) const
{
if (nsnull != mRules) {
PRUint32 cnt;
nsresult rv = mRules->Count(&cnt);
if (NS_FAILED(rv)) return 0; // XXX error?
return cnt;
1998-05-21 00:32:57 +04:00
}
return 0;
}
NS_IMETHODIMP
StyleContextImpl::GetPseudoType(nsIAtom*& aPseudoTag) const
{
aPseudoTag = mPseudoTag;
NS_IF_ADDREF(aPseudoTag);
return NS_OK;
}
NS_IMETHODIMP
StyleContextImpl::FindChildWithRules(const nsIAtom* aPseudoTag,
nsISupportsArray* aRules,
nsIStyleContext*& aResult)
{
aResult = nsnull;
1998-10-08 05:27:38 +04:00
if ((nsnull != mChild) || (nsnull != mEmptyChild)) {
StyleContextImpl* child;
PRInt32 ruleCount;
if (aRules) {
PRUint32 cnt;
nsresult rv = aRules->Count(&cnt);
if (NS_FAILED(rv)) return rv;
ruleCount = cnt;
}
else
ruleCount = 0;
1998-10-08 05:27:38 +04:00
if (0 == ruleCount) {
if (nsnull != mEmptyChild) {
child = mEmptyChild;
do {
if ((0 == child->mDataCode) && // only look at children with un-twiddled data
(aPseudoTag == child->mPseudoTag)) {
aResult = child;
break;
}
child = child->mNextSibling;
} while (child != mEmptyChild);
}
1998-10-08 05:27:38 +04:00
}
else if (nsnull != mChild) {
PRUint32 hash = 0;
aRules->EnumerateForwards(HashStyleRule, &hash);
child = mChild;
1998-10-08 05:27:38 +04:00
do {
PRUint32 cnt;
1998-10-08 05:27:38 +04:00
if ((0 == child->mDataCode) && // only look at children with un-twiddled data
(child->mRuleHash == hash) &&
(child->mPseudoTag == aPseudoTag) &&
(nsnull != child->mRules) &&
NS_SUCCEEDED(child->mRules->Count(&cnt)) &&
(PRInt32)cnt == ruleCount) {
1998-10-08 05:27:38 +04:00
if (child->mRules->Equals(aRules)) {
aResult = child;
1998-10-08 05:27:38 +04:00
break;
}
}
1998-10-08 05:27:38 +04:00
child = child->mNextSibling;
} while (child != mChild);
}
}
NS_IF_ADDREF(aResult);
return NS_OK;
}
1998-04-14 00:24:54 +04:00
PRBool StyleContextImpl::Equals(const nsIStyleContext* aOther) const
{
PRBool result = PR_TRUE;
const StyleContextImpl* other = (StyleContextImpl*)aOther;
if (other != this) {
if (mParent != other->mParent) {
result = PR_FALSE;
}
else if (mDataCode != other->mDataCode) {
result = PR_FALSE;
}
else if (mPseudoTag != other->mPseudoTag) {
result = PR_FALSE;
}
1998-04-14 00:24:54 +04:00
else {
if ((nsnull != mRules) && (nsnull != other->mRules)) {
if (mRuleHash == other->mRuleHash) {
result = mRules->Equals(other->mRules);
}
else {
result = PR_FALSE;
}
1998-04-14 00:24:54 +04:00
}
else {
result = PRBool((nsnull == mRules) && (nsnull == other->mRules));
}
}
}
return result;
}
PRUint32 StyleContextImpl::HashValue(void) const
{
1998-10-08 05:27:38 +04:00
return mRuleHash;
1998-04-14 00:24:54 +04:00
}
const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID)
1998-04-14 00:24:54 +04:00
{
nsStyleStruct* result = nsnull;
switch (aSID) {
case eStyleStruct_Font:
result = &mFont;
break;
case eStyleStruct_Color:
result = &mColor;
break;
case eStyleStruct_Spacing:
result = &mSpacing;
break;
case eStyleStruct_List:
result = &mList;
break;
case eStyleStruct_Position:
result = &mPosition;
break;
case eStyleStruct_Text:
result = &mText;
break;
case eStyleStruct_Display:
result = &mDisplay;
break;
case eStyleStruct_Table:
result = &mTable;
break;
case eStyleStruct_Content:
result = &mContent;
break;
case eStyleStruct_UserInterface:
result = &mUserInterface;
1999-04-02 22:48:55 +04:00
break;
case eStyleStruct_Print:
result = &mPrint;
break;
default:
NS_ERROR("Invalid style struct id");
break;
}
return result;
1998-04-14 00:24:54 +04:00
}
nsStyleStruct* StyleContextImpl::GetMutableStyleData(nsStyleStructID aSID)
{
nsStyleStruct* result = nsnull;
switch (aSID) {
case eStyleStruct_Font:
result = &mFont;
break;
case eStyleStruct_Color:
result = &mColor;
break;
case eStyleStruct_Spacing:
result = &mSpacing;
break;
case eStyleStruct_List:
result = &mList;
break;
case eStyleStruct_Position:
result = &mPosition;
break;
case eStyleStruct_Text:
result = &mText;
break;
case eStyleStruct_Display:
result = &mDisplay;
break;
case eStyleStruct_Table:
result = &mTable;
break;
case eStyleStruct_Content:
result = &mContent;
break;
case eStyleStruct_UserInterface:
result = &mUserInterface;
1999-04-02 22:48:55 +04:00
break;
case eStyleStruct_Print:
result = &mPrint;
break;
default:
NS_ERROR("Invalid style struct id");
break;
}
if (nsnull != result) {
if (0 == mDataCode) {
// mDataCode = ++gLastDataCode; // XXX temp disable, this is still used but not needed to force unique
}
}
return result;
}
NS_IMETHODIMP
StyleContextImpl::GetStyle(nsStyleStructID aSID, nsStyleStruct& aStruct) const
{
nsresult result = NS_OK;
switch (aSID) {
case eStyleStruct_Font:
mFont.CopyTo((nsStyleFont&)aStruct);
break;
case eStyleStruct_Color:
mColor.CopyTo((nsStyleColor&)aStruct);
break;
case eStyleStruct_Spacing:
mSpacing.CopyTo((nsStyleSpacing&)aStruct);
break;
case eStyleStruct_List:
mList.CopyTo((nsStyleList&)aStruct);
break;
case eStyleStruct_Position:
mPosition.CopyTo((nsStylePosition&)aStruct);
break;
case eStyleStruct_Text:
mText.CopyTo((nsStyleText&)aStruct);
break;
case eStyleStruct_Display:
mDisplay.CopyTo((nsStyleDisplay&)aStruct);
break;
case eStyleStruct_Table:
mTable.CopyTo((nsStyleTable&)aStruct);
break;
case eStyleStruct_Content:
mContent.CopyTo((nsStyleContent&)aStruct);
break;
case eStyleStruct_UserInterface:
mUserInterface.CopyTo((nsStyleUserInterface&)aStruct);
break;
case eStyleStruct_Print:
mPrint.CopyTo((nsStylePrint&)aStruct);
break;
default:
NS_ERROR("Invalid style struct id");
result = NS_ERROR_INVALID_ARG;
break;
}
return result;
}
NS_IMETHODIMP
StyleContextImpl::SetStyle(nsStyleStructID aSID, const nsStyleStruct& aStruct)
{
nsresult result = NS_OK;
switch (aSID) {
case eStyleStruct_Font:
mFont.SetFrom((const nsStyleFont&)aStruct);
break;
case eStyleStruct_Color:
mColor.SetFrom((const nsStyleColor&)aStruct);
break;
case eStyleStruct_Spacing:
mSpacing.SetFrom((const nsStyleSpacing&)aStruct);
break;
case eStyleStruct_List:
mList.SetFrom((const nsStyleList&)aStruct);
break;
case eStyleStruct_Position:
mPosition.SetFrom((const nsStylePosition&)aStruct);
break;
case eStyleStruct_Text:
mText.SetFrom((const nsStyleText&)aStruct);
break;
case eStyleStruct_Display:
mDisplay.SetFrom((const nsStyleDisplay&)aStruct);
break;
case eStyleStruct_Table:
mTable.SetFrom((const nsStyleTable&)aStruct);
break;
case eStyleStruct_Content:
mContent.SetFrom((const nsStyleContent&)aStruct);
break;
case eStyleStruct_UserInterface:
mUserInterface.SetFrom((const nsStyleUserInterface&)aStruct);
break;
case eStyleStruct_Print:
mPrint.SetFrom((const nsStylePrint&)aStruct);
break;
default:
NS_ERROR("Invalid style struct id");
result = NS_ERROR_INVALID_ARG;
break;
}
return result;
}
struct MapStyleData {
MapStyleData(nsIMutableStyleContext* aStyleContext, nsIPresContext* aPresContext)
{
mStyleContext = aStyleContext;
mPresContext = aPresContext;
}
nsIMutableStyleContext* mStyleContext;
nsIPresContext* mPresContext;
};
static PRBool MapStyleRuleFont(nsISupports* aRule, void* aData)
{
nsIStyleRule* rule = (nsIStyleRule*)aRule;
MapStyleData* data = (MapStyleData*)aData;
rule->MapFontStyleInto(data->mStyleContext, data->mPresContext);
return PR_TRUE;
}
static PRBool MapStyleRule(nsISupports* aRule, void* aData)
{
nsIStyleRule* rule = (nsIStyleRule*)aRule;
MapStyleData* data = (MapStyleData*)aData;
1998-09-05 07:52:30 +04:00
rule->MapStyleInto(data->mStyleContext, data->mPresContext);
return PR_TRUE;
}
1998-09-25 03:56:30 +04:00
NS_IMETHODIMP
StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse)
1998-04-14 00:24:54 +04:00
{
mDataCode = -1;
if (nsnull != mParent) {
mFont.ResetFrom(&(mParent->mFont), aPresContext);
mColor.ResetFrom(&(mParent->mColor), aPresContext);
mSpacing.ResetFrom(&(mParent->mSpacing), aPresContext);
mList.ResetFrom(&(mParent->mList), aPresContext);
mPosition.ResetFrom(&(mParent->mPosition), aPresContext);
mText.ResetFrom(&(mParent->mText), aPresContext);
mDisplay.ResetFrom(&(mParent->mDisplay), aPresContext);
mTable.ResetFrom(&(mParent->mTable), aPresContext);
mContent.ResetFrom(&(mParent->mContent), aPresContext);
mUserInterface.ResetFrom(&(mParent->mUserInterface), aPresContext);
mPrint.ResetFrom(&(mParent->mPrint), aPresContext);
}
else {
mFont.ResetFrom(nsnull, aPresContext);
mColor.ResetFrom(nsnull, aPresContext);
mSpacing.ResetFrom(nsnull, aPresContext);
mList.ResetFrom(nsnull, aPresContext);
mPosition.ResetFrom(nsnull, aPresContext);
mText.ResetFrom(nsnull, aPresContext);
mDisplay.ResetFrom(nsnull, aPresContext);
mTable.ResetFrom(nsnull, aPresContext);
mContent.ResetFrom(nsnull, aPresContext);
mUserInterface.ResetFrom(nsnull, aPresContext);
mPrint.ResetFrom(nsnull, aPresContext);
}
PRUint32 cnt = 0;
if (mRules) {
nsresult rv = mRules->Count(&cnt);
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
}
if (0 < cnt) {
1998-09-05 07:52:30 +04:00
MapStyleData data(this, aPresContext);
mRules->EnumerateForwards(MapStyleRuleFont, &data);
1999-07-07 05:22:04 +04:00
if (mFont.mFlags & NS_STYLE_FONT_USE_FIXED) {
mFont.mFont = mFont.mFixedFont;
}
mRules->EnumerateForwards(MapStyleRule, &data);
}
if (-1 == mDataCode) {
mDataCode = 0;
}
nsCompatibility quirkMode = eCompatibility_Standard;
aPresContext->GetCompatibilityMode(&quirkMode);
if (eCompatibility_NavQuirks == quirkMode) {
if (((mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE) ||
(mDisplay.mDisplay == 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 = mDisplay.mVisible;
PRUint8 direction = mDisplay.mDirection;
nsCOMPtr<nsILanguageAtom> language = mDisplay.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 (mDisplay.mDisplay != NS_STYLE_DISPLAY_TABLE) {
mFont.ResetFrom(nsnull, aPresContext);
}
mColor.ResetFrom(nsnull, aPresContext);
mSpacing.ResetFrom(nsnull, aPresContext);
mList.ResetFrom(nsnull, aPresContext);
mText.ResetFrom(nsnull, aPresContext);
mPosition.ResetFrom(nsnull, aPresContext);
mDisplay.ResetFrom(nsnull, aPresContext);
mTable.ResetFrom(nsnull, aPresContext);
mContent.ResetFrom(nsnull, aPresContext);
mUserInterface.ResetFrom(nsnull, aPresContext);
mPrint.ResetFrom(nsnull, aPresContext);
mDisplay.mVisible = visible;
mDisplay.mDirection = direction;
mDisplay.mLanguage = language;
PRUint32 numRules = 0;
if (mRules) {
nsresult rv = mRules->Count(&numRules);
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
}
if (0 < numRules) {
MapStyleData data(this, aPresContext);
mRules->EnumerateForwards(MapStyleRuleFont, &data);
1999-07-07 05:22:04 +04:00
if (mFont.mFlags & NS_STYLE_FONT_USE_FIXED) {
mFont.mFont = mFont.mFixedFont;
}
mRules->EnumerateForwards(MapStyleRule, &data);
}
// reset all font data for tables again
if (mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE) {
// get the font-name to reset: this property we preserve
nsAutoString strName(mFont.mFont.name);
nsAutoString strMixedName(mFont.mFixedFont.name);
mFont.ResetFrom(nsnull, aPresContext);
// now reset the font names back to original
mFont.mFont.name = strName;
mFont.mFixedFont.name = strMixedName;
}
mParent = holdParent;
}
}
1998-10-27 06:03:02 +03:00
RecalcAutomaticData(aPresContext);
if (aRecurse) {
if (nsnull != mChild) {
StyleContextImpl* child = mChild;
do {
child->RemapStyle(aPresContext);
child = child->mNextSibling;
} while (mChild != child);
}
if (nsnull != mEmptyChild) {
StyleContextImpl* child = mEmptyChild;
do {
child->RemapStyle(aPresContext);
child = child->mNextSibling;
} while (mEmptyChild != child);
}
1998-10-27 06:03:02 +03:00
}
1998-09-25 03:56:30 +04:00
return NS_OK;
}
void StyleContextImpl::ForceUnique(void)
{
if (mDataCode <= 0) {
mDataCode = ++gLastDataCode;
}
1998-04-14 00:24:54 +04:00
}
void StyleContextImpl::RecalcAutomaticData(nsIPresContext* aPresContext)
1998-04-21 04:02:44 +04:00
{
mSpacing.RecalcData(aPresContext, mColor.mColor);
1999-02-27 10:11:42 +03:00
}
1999-02-27 10:11:42 +03:00
NS_IMETHODIMP
StyleContextImpl::CalcStyleDifference(nsIStyleContext* aOther, PRInt32& aHint) const
{
if (aOther) {
PRInt32 hint;
const StyleContextImpl* other = (const StyleContextImpl*)aOther;
aHint = mFont.CalcDifference(other->mFont);
if (aHint < NS_STYLE_HINT_MAX) {
hint = mColor.CalcDifference(other->mColor);
if (aHint < hint) {
aHint = hint;
}
}
if (aHint < NS_STYLE_HINT_MAX) {
hint = mSpacing.CalcDifference(other->mSpacing);
if (aHint < hint) {
aHint = hint;
}
}
if (aHint < NS_STYLE_HINT_MAX) {
hint = mList.CalcDifference(other->mList);
if (aHint < hint) {
aHint = hint;
}
}
if (aHint < NS_STYLE_HINT_MAX) {
hint = mPosition.CalcDifference(other->mPosition);
if (aHint < hint) {
aHint = hint;
}
}
if (aHint < NS_STYLE_HINT_MAX) {
hint = mText.CalcDifference(other->mText);
if (aHint < hint) {
aHint = hint;
}
}
if (aHint < NS_STYLE_HINT_MAX) {
hint = mDisplay.CalcDifference(other->mDisplay);
if (aHint < hint) {
aHint = hint;
}
}
if (aHint < NS_STYLE_HINT_MAX) {
hint = mTable.CalcDifference(other->mTable);
1999-02-27 10:11:42 +03:00
if (aHint < hint) {
aHint = hint;
}
}
1999-04-02 22:48:55 +04:00
if (aHint < NS_STYLE_HINT_MAX) {
hint = mContent.CalcDifference(other->mContent);
if (aHint < hint) {
aHint = hint;
1999-04-02 22:48:55 +04:00
}
}
if (aHint < NS_STYLE_HINT_MAX) {
hint = mUserInterface.CalcDifference(other->mUserInterface);
1999-04-02 22:48:55 +04:00
if (aHint < hint) {
aHint = hint;
}
}
if (aHint < NS_STYLE_HINT_MAX) {
hint = mPrint.CalcDifference(other->mPrint);
if (aHint < hint) {
aHint = hint;
}
}
1999-02-27 10:11:42 +03:00
}
return NS_OK;
1998-04-14 00:24:54 +04:00
}
1999-02-27 10:11:42 +03:00
1998-05-19 01:04:26 +04:00
void StyleContextImpl::List(FILE* out, PRInt32 aIndent)
{
// Indent
PRInt32 ix;
for (ix = aIndent; --ix >= 0; ) fputs(" ", out);
1999-04-28 02:08:48 +04:00
fprintf(out, "%p(%d) ", this, mRefCnt);
if (nsnull != mPseudoTag) {
nsAutoString buffer;
mPseudoTag->ToString(buffer);
fputs(buffer, out);
fputs(" ", out);
}
PRInt32 count = GetStyleRuleCount();
1998-05-19 01:04:26 +04:00
if (0 < count) {
fputs("{\n", out);
for (ix = 0; ix < count; ix++) {
nsIStyleRule* rule = (nsIStyleRule*)mRules->ElementAt(ix);
1998-05-19 01:04:26 +04:00
rule->List(out, aIndent + 1);
NS_RELEASE(rule);
}
for (ix = aIndent; --ix >= 0; ) fputs(" ", out);
1998-05-19 01:04:26 +04:00
fputs("}\n", out);
}
else {
fputs("{}\n", out);
}
1998-06-26 09:49:01 +04:00
if (nsnull != mChild) {
StyleContextImpl* child = mChild;
do {
child->List(out, aIndent + 1);
child = child->mNextSibling;
1998-06-26 09:49:01 +04:00
} while (mChild != child);
}
1998-10-08 05:27:38 +04:00
if (nsnull != mEmptyChild) {
StyleContextImpl* child = mEmptyChild;
do {
child->List(out, aIndent + 1);
child = child->mNextSibling;
} while (mEmptyChild != child);
1998-10-08 05:27:38 +04:00
}
1998-05-19 01:04:26 +04:00
}
/******************************************************************************
* SizeOf method:
*
* Self (reported as StyleContextImpl's size):
* 1) sizeof(*this) which gets all of the data members
* 2) adds in the size of the PseudoTag, if there is one
*
* Contained / Aggregated data (not reported as StyleContextImpl's size):
* 1) the Style Rules in mRules are not counted as part of sizeof(*this)
* (though the size of the nsISupportsArray ptr. is) so we need to
* count the rules seperately. For each rule in the mRules collection
* we call the SizeOf method and let it report itself.
*
* Children / siblings / parents:
* 1) We recurse over the mChild and mEmptyChild instances if they exist.
* These instances will then be accumulated seperately (not part of
* the containing instance's size)
* 2) We recurse over the siblings of the Child and Empty Child instances
* and count then seperately as well.
* 3) We recurse over our direct siblings (if any).
*
******************************************************************************/
void StyleContextImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize)
{
NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null");
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(mFont) );
totalSize += (long)sizeof(mFont);
printf( " - StyleColorImpl: %ld\n", (long)sizeof(mColor) );
totalSize += (long)sizeof(mColor);
printf( " - StyleSpacingImpl: %ld\n", (long)sizeof(mSpacing) );
totalSize += (long)sizeof(mSpacing);
printf( " - StyleListImpl: %ld\n", (long)sizeof(mList) );
totalSize += (long)sizeof(mList);
printf( " - StylePositionImpl: %ld\n", (long)sizeof(mPosition) );
totalSize += (long)sizeof(mPosition);
printf( " - StyleTextImpl: %ld\n", (long)sizeof(mText) );
totalSize += (long)sizeof(mText);
printf( " - StyleDisplayImpl: %ld\n", (long)sizeof(mDisplay) );
totalSize += (long)sizeof(mDisplay);
printf( " - StyleTableImpl: %ld\n", (long)sizeof(mTable) );
totalSize += (long)sizeof(mTable);
printf( " - StyleContentImpl: %ld\n", (long)sizeof(mContent) );
totalSize += (long)sizeof(mContent);
printf( " - StyleUserInterfaceImpl: %ld\n", (long)sizeof(mUserInterface) );
totalSize += (long)sizeof(mUserInterface);
printf( " - StylePrintImpl: %ld\n", (long)sizeof(mPrint));
totalSize += (long)sizeof(mPrint);
printf( " - Total: %ld\n", (long)totalSize);
printf( "*************************************\n");
}
// first get the unique items collection
UNIQUE_STYLE_ITEMS(uniqueItems);
if(! uniqueItems->AddItem((void*)this) ){
// object has already been accounted for
return;
}
PRUint32 localSize=0;
// get or create a tag for this instance
nsCOMPtr<nsIAtom> tag;
tag = getter_AddRefs(NS_NewAtom("StyleContextImpl"));
// get the size of an empty instance and add to the sizeof handler
aSize = sizeof(*this);
// add in the size of the member mPseudoTag
if(mPseudoTag){
mPseudoTag->SizeOf(aSizeOfHandler, &localSize);
aSize += localSize;
}
aSizeOfHandler->AddSize(tag,aSize);
// size up the rules (if not already done)
// XXX - overhead of the collection???
if(mRules && uniqueItems->AddItem(mRules)){
PRUint32 curRule, ruleCount;
mRules->Count(&ruleCount);
if (ruleCount > 0) {
for (curRule = 0; curRule < ruleCount; curRule++) {
nsIStyleRule* rule = (nsIStyleRule*)mRules->ElementAt(curRule);
NS_ASSERTION(rule, "null entry in Rules list is bad news");
rule->SizeOf(aSizeOfHandler, localSize);
NS_RELEASE(rule);
}
}
}
// now follow up with the child (and empty child) recursion
if (nsnull != mChild) {
StyleContextImpl* child = mChild;
do {
child->SizeOf(aSizeOfHandler, localSize);
child = child->mNextSibling;
} while (mChild != child);
}
if (nsnull != mEmptyChild) {
StyleContextImpl* child = mEmptyChild;
do {
child->SizeOf(aSizeOfHandler, localSize);
child = child->mNextSibling;
} while (mEmptyChild != child);
}
// and finally our direct siblings (if any)
if (nsnull != mNextSibling) {
mNextSibling->SizeOf(aSizeOfHandler, localSize);
}
}
1998-04-14 00:24:54 +04:00
NS_LAYOUT nsresult
NS_NewStyleContext(nsIStyleContext** aInstancePtrResult,
nsIStyleContext* aParentContext,
nsIAtom* aPseudoTag,
1998-04-14 00:24:54 +04:00
nsISupportsArray* aRules,
nsIPresContext* aPresContext)
1998-04-14 00:24:54 +04:00
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
StyleContextImpl* context = new StyleContextImpl(aParentContext, aPseudoTag,
aRules, aPresContext);
1998-04-14 00:24:54 +04:00
if (nsnull == context) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult result = context->QueryInterface(kIStyleContextIID, (void **) aInstancePtrResult);
context->RemapStyle(aPresContext); // remap after initial ref-count is set
return result;
1998-04-14 00:24:54 +04:00
}