/* -*- 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.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ #include "nsICSSDeclaration.h" #include "nsString.h" #include "nsCRT.h" #include "nsCSSProps.h" #include "nsCSSPropIDs.h" #include "nsUnitConversion.h" static NS_DEFINE_IID(kCSSFontSID, NS_CSS_FONT_SID); static NS_DEFINE_IID(kCSSColorSID, NS_CSS_COLOR_SID); static NS_DEFINE_IID(kCSSTextSID, NS_CSS_TEXT_SID); static NS_DEFINE_IID(kCSSMarginSID, NS_CSS_MARGIN_SID); static NS_DEFINE_IID(kCSSPositionSID, NS_CSS_POSITION_SID); static NS_DEFINE_IID(kCSSListSID, NS_CSS_LIST_SID); static NS_DEFINE_IID(kICSSDeclarationIID, NS_ICSS_DECLARATION_IID); nsCSSValue::nsCSSValue(void) : mUnit(eCSSUnit_Null) { mValue.mInt = 0; } nsCSSValue::nsCSSValue(PRInt32 aValue, nsCSSUnit aUnit) : mUnit(aUnit) { mValue.mInt = aValue; } nsCSSValue::nsCSSValue(float aValue, nsCSSUnit aUnit) : mUnit(aUnit) { mValue.mFloat = aValue; } nsCSSValue::nsCSSValue(const nsString& aValue) : mUnit(eCSSUnit_String) { mValue.mString = aValue.ToNewString(); } nsCSSValue::nsCSSValue(nscolor aValue) : mUnit(eCSSUnit_Color) { mValue.mColor = aValue; } nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) : mUnit(aCopy.mUnit) { if (eCSSUnit_String == mUnit) { if (nsnull != aCopy.mValue.mString) { mValue.mString = (aCopy.mValue.mString)->ToNewString(); } else { mValue.mString = nsnull; } } else if ((eCSSUnit_Absolute <= mUnit) && (mUnit <= eCSSUnit_Enumerated)) { mValue.mInt = aCopy.mValue.mInt; } else if (eCSSUnit_Color == mUnit){ mValue.mColor = aCopy.mValue.mColor; } else { mValue.mFloat = aCopy.mValue.mFloat; } } nsCSSValue::~nsCSSValue(void) { Reset(); } nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy) { Reset(); mUnit = aCopy.mUnit; if (eCSSUnit_String == mUnit) { if (nsnull != aCopy.mValue.mString) { mValue.mString = (aCopy.mValue.mString)->ToNewString(); } } else if ((eCSSUnit_Absolute <= mUnit) && (mUnit <= eCSSUnit_Enumerated)) { mValue.mInt = aCopy.mValue.mInt; } else if (eCSSUnit_Color == mUnit){ mValue.mColor = aCopy.mValue.mColor; } else { mValue.mFloat = aCopy.mValue.mFloat; } return *this; } PRBool nsCSSValue::operator==(const nsCSSValue& aOther) const { if (mUnit == aOther.mUnit) { if (eCSSUnit_String == mUnit) { if (nsnull == mValue.mString) { if (nsnull == aOther.mValue.mString) { return PR_TRUE; } } else if (nsnull != aOther.mValue.mString) { return mValue.mString->Equals(*(aOther.mValue.mString)); } } else if ((eCSSUnit_Absolute <= mUnit) && (mUnit < eCSSUnit_Percent)) { return PRBool(mValue.mInt == aOther.mValue.mInt); } else if (eCSSUnit_Color == mUnit){ return PRBool(mValue.mColor == aOther.mValue.mColor); } else { return PRBool(mValue.mFloat == aOther.mValue.mFloat); } } return PR_FALSE; } nscoord nsCSSValue::GetLengthTwips(void) const { NS_ASSERTION(IsFixedLengthUnit(), "not a fixed length unit"); if (IsFixedLengthUnit()) { switch (mUnit) { case eCSSUnit_Inch: return (nscoord)NS_INCHES_TO_TWIPS(mValue.mFloat); case eCSSUnit_Foot: return (nscoord)NS_FEET_TO_TWIPS(mValue.mFloat); case eCSSUnit_Mile: return (nscoord)NS_MILES_TO_TWIPS(mValue.mFloat); case eCSSUnit_Millimeter: return (nscoord)NS_MILLIMETERS_TO_TWIPS(mValue.mFloat); case eCSSUnit_Centimeter: return (nscoord)NS_CENTIMETERS_TO_TWIPS(mValue.mFloat); case eCSSUnit_Meter: return (nscoord)NS_METERS_TO_TWIPS(mValue.mFloat); case eCSSUnit_Kilometer: return (nscoord)NS_KILOMETERS_TO_TWIPS(mValue.mFloat); case eCSSUnit_Point: return (nscoord)NS_POINTS_TO_TWIPS_FLOAT(mValue.mFloat); case eCSSUnit_Pica: return (nscoord)NS_PICAS_TO_TWIPS(mValue.mFloat); case eCSSUnit_Didot: return (nscoord)NS_DIDOTS_TO_TWIPS(mValue.mFloat); case eCSSUnit_Cicero: return (nscoord)NS_CICEROS_TO_TWIPS(mValue.mFloat); } } return 0; } void nsCSSValue::Reset(void) { if ((eCSSUnit_String == mUnit) && (nsnull != mValue.mString)) { delete mValue.mString; } mUnit = eCSSUnit_Null; mValue.mInt = 0; }; void nsCSSValue::Set(PRInt32 aValue, nsCSSUnit aUnit) { Reset(); mUnit = aUnit; mValue.mInt = aValue; } void nsCSSValue::Set(float aValue, nsCSSUnit aUnit) { Reset(); mUnit = aUnit; mValue.mFloat = aValue; } void nsCSSValue::Set(const nsString& aValue) { Reset(); mUnit = eCSSUnit_String; mValue.mString = aValue.ToNewString(); } void nsCSSValue::Set(nscolor aValue) { Reset(); mUnit = eCSSUnit_Color; mValue.mColor = aValue; } void nsCSSValue::AppendToString(nsString& aBuffer, PRInt32 aPropID) const { if (eCSSUnit_Null == mUnit) { return; } if (-1 < aPropID) { aBuffer.Append(nsCSSProps::kNameTable[aPropID].name); aBuffer.Append(": "); } if (eCSSUnit_String == mUnit) { if (nsnull != mValue.mString) { aBuffer.Append('"'); aBuffer.Append(*(mValue.mString)); aBuffer.Append('"'); } else { aBuffer.Append("null str"); } } else if ((eCSSUnit_Absolute <= mUnit) && (mUnit <= eCSSUnit_Enumerated)) { aBuffer.Append(mValue.mInt, 10); aBuffer.Append("[0x"); aBuffer.Append(mValue.mInt, 16); aBuffer.Append(']'); } else if (eCSSUnit_Color == mUnit){ aBuffer.Append("(0x"); aBuffer.Append(NS_GET_R(mValue.mColor), 16); aBuffer.Append(" 0x"); aBuffer.Append(NS_GET_G(mValue.mColor), 16); aBuffer.Append(" 0x"); aBuffer.Append(NS_GET_B(mValue.mColor), 16); aBuffer.Append(" 0x"); aBuffer.Append(NS_GET_A(mValue.mColor), 16); aBuffer.Append(')'); } else if (eCSSUnit_Percent <= mUnit) { aBuffer.Append(mValue.mFloat); } switch (mUnit) { case eCSSUnit_Null: break; case eCSSUnit_Auto: aBuffer.Append("auto"); break; case eCSSUnit_String: break; case eCSSUnit_Absolute: aBuffer.Append("abs"); break; case eCSSUnit_Enumerated: aBuffer.Append("enum"); break; case eCSSUnit_Color: aBuffer.Append("rbga"); break; case eCSSUnit_Percent: aBuffer.Append("%"); break; case eCSSUnit_Number: aBuffer.Append("#"); break; case eCSSUnit_Inch: aBuffer.Append("in"); break; case eCSSUnit_Foot: aBuffer.Append("ft"); break; case eCSSUnit_Mile: aBuffer.Append("mi"); break; case eCSSUnit_Millimeter: aBuffer.Append("mm"); break; case eCSSUnit_Centimeter: aBuffer.Append("cm"); break; case eCSSUnit_Meter: aBuffer.Append("m"); break; case eCSSUnit_Kilometer: aBuffer.Append("km"); break; case eCSSUnit_Point: aBuffer.Append("pt"); break; case eCSSUnit_Pica: aBuffer.Append("pc"); break; case eCSSUnit_Didot: aBuffer.Append("dt"); break; case eCSSUnit_Cicero: aBuffer.Append("cc"); break; case eCSSUnit_EM: aBuffer.Append("em"); break; case eCSSUnit_EN: aBuffer.Append("en"); break; case eCSSUnit_XHeight: aBuffer.Append("ex"); break; case eCSSUnit_CapHeight: aBuffer.Append("cap"); break; case eCSSUnit_Pixel: aBuffer.Append("px"); break; } aBuffer.Append(' '); } void nsCSSValue::ToString(nsString& aBuffer, PRInt32 aPropID) const { aBuffer.SetLength(0); AppendToString(aBuffer, aPropID); } const nsID& nsCSSFont::GetID(void) { return kCSSFontSID; } void nsCSSFont::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; mFamily.AppendToString(buffer, PROP_FONT_FAMILY); mStyle.AppendToString(buffer, PROP_FONT_STYLE); mVariant.AppendToString(buffer, PROP_FONT_VARIANT); mWeight.AppendToString(buffer, PROP_FONT_WEIGHT); mSize.AppendToString(buffer, PROP_FONT_SIZE); fputs(buffer, out); } const nsID& nsCSSColor::GetID(void) { return kCSSColorSID; } void nsCSSColor::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; mColor.AppendToString(buffer, PROP_COLOR); mBackColor.AppendToString(buffer, PROP_BACKGROUND_COLOR); mBackImage.AppendToString(buffer, PROP_BACKGROUND_IMAGE); mBackRepeat.AppendToString(buffer, PROP_BACKGROUND_REPEAT); mBackAttachment.AppendToString(buffer, PROP_BACKGROUND_ATTACHMENT); mBackPositionX.AppendToString(buffer, PROP_BACKGROUND_X_POSITION); mBackPositionY.AppendToString(buffer, PROP_BACKGROUND_Y_POSITION); mBackFilter.AppendToString(buffer, PROP_BACKGROUND_FILTER); fputs(buffer, out); } const nsID& nsCSSText::GetID(void) { return kCSSTextSID; } void nsCSSText::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; mWordSpacing.AppendToString(buffer, PROP_WORD_SPACING); mLetterSpacing.AppendToString(buffer, PROP_LETTER_SPACING); mDecoration.AppendToString(buffer, PROP_TEXT_DECORATION); mVertAlign.AppendToString(buffer, PROP_VERTICAL_ALIGN); mTransform.AppendToString(buffer, PROP_TEXT_TRANSFORM); mHorzAlign.AppendToString(buffer, PROP_TEXT_ALIGN); mIndent.AppendToString(buffer, PROP_TEXT_INDENT); mLineHeight.AppendToString(buffer, PROP_LINE_HEIGHT); mWhiteSpace.AppendToString(buffer, PROP_WHITE_SPACE); fputs(buffer, out); } void nsCSSRect::List(FILE* out, PRInt32 aPropID, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; if (-1 < aPropID) { buffer.Append(nsCSSProps::kNameTable[aPropID].name); buffer.Append(": "); } mTop.AppendToString(buffer); mRight.AppendToString(buffer); mBottom.AppendToString(buffer); mLeft.AppendToString(buffer); fputs(buffer, out); } nsCSSMargin::nsCSSMargin(void) : mMargin(nsnull), mPadding(nsnull), mBorder(nsnull), mColor(nsnull), mStyle(nsnull) { } nsCSSMargin::~nsCSSMargin(void) { if (nsnull != mMargin) { delete mMargin; } if (nsnull != mPadding) { delete mPadding; } if (nsnull != mBorder) { delete mBorder; } if (nsnull != mColor) { delete mColor; } if (nsnull != mStyle) { delete mStyle; } } const nsID& nsCSSMargin::GetID(void) { return kCSSMarginSID; } void nsCSSMargin::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); if (nsnull != mMargin) { mMargin->List(out, PROP_MARGIN, aIndent); } if (nsnull != mPadding) { mPadding->List(out, PROP_PADDING, aIndent); } if (nsnull != mBorder) { mBorder->List(out, PROP_BORDER_WIDTH, aIndent); } if (nsnull != mColor) { mColor->List(out, PROP_BORDER_COLOR, aIndent); } if (nsnull != mStyle) { mStyle->List(out, PROP_BORDER_STYLE, aIndent); } } nsCSSPosition::nsCSSPosition(void) : mClip(nsnull) { } nsCSSPosition::~nsCSSPosition(void) { if (nsnull != mClip) { delete mClip; } } const nsID& nsCSSPosition::GetID(void) { return kCSSPositionSID; } void nsCSSPosition::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; mPosition.AppendToString(buffer, PROP_POSITION); mWidth.AppendToString(buffer, PROP_WIDTH); mHeight.AppendToString(buffer, PROP_HEIGHT); mLeft.AppendToString(buffer, PROP_LEFT); mTop.AppendToString(buffer, PROP_TOP); fputs(buffer, out); if (nsnull != mClip) { mClip->List(out, PROP_CLIP); } buffer.SetLength(0); mOverflow.AppendToString(buffer, PROP_OVERFLOW); mZIndex.AppendToString(buffer, PROP_OVERFLOW); mVisibility.AppendToString(buffer, PROP_VISIBILITY); mFloat.AppendToString(buffer, PROP_FLOAT); mClear.AppendToString(buffer, PROP_CLEAR); mDisplay.AppendToString(buffer, PROP_DISPLAY); mFilter.AppendToString(buffer, PROP_FILTER); fputs(buffer, out); } const nsID& nsCSSList::GetID(void) { return kCSSListSID; } void nsCSSList::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; mType.AppendToString(buffer, PROP_LIST_STYLE_TYPE); mImage.AppendToString(buffer, PROP_LIST_STYLE_IMAGE); mPosition.AppendToString(buffer, PROP_LIST_STYLE_POSITION); fputs(buffer, out); } class CSSDeclarationImpl : public nsICSSDeclaration { public: void* operator new(size_t size); CSSDeclarationImpl(void); ~CSSDeclarationImpl(void); NS_DECL_ISUPPORTS nsresult GetData(const nsID& aSID, nsCSSStruct** aData); nsresult EnsureData(const nsID& aSID, nsCSSStruct** aData); nsresult AddValue(const char* aProperty, const nsCSSValue& aValue); nsresult AddValue(PRInt32 aProperty, const nsCSSValue& aValue); nsresult GetValue(const char* aProperty, nsCSSValue& aValue); nsresult GetValue(PRInt32 aProperty, nsCSSValue& aValue); void List(FILE* out = stdout, PRInt32 aIndent = 0) const; private: CSSDeclarationImpl(const CSSDeclarationImpl& aCopy); CSSDeclarationImpl& operator=(const CSSDeclarationImpl& aCopy); PRBool operator==(const CSSDeclarationImpl& aCopy) const; protected: nsCSSFont* mFont; nsCSSColor* mColor; nsCSSText* mText; nsCSSMargin* mMargin; nsCSSPosition* mPosition; nsCSSList* mList; }; void* CSSDeclarationImpl::operator new(size_t size) { void* result = new char[size]; nsCRT::zero(result, size); return result; } CSSDeclarationImpl::CSSDeclarationImpl(void) { NS_INIT_REFCNT(); } CSSDeclarationImpl::~CSSDeclarationImpl(void) { if (nsnull != mFont) { delete mFont; } if (nsnull != mColor) { delete mColor; } if (nsnull != mText) { delete mText; } if (nsnull != mMargin) { delete mMargin; } if (nsnull != mPosition) { delete mPosition; } if (nsnull != mList) { delete mList; } } NS_IMPL_ISUPPORTS(CSSDeclarationImpl, kICSSDeclarationIID); nsresult CSSDeclarationImpl::GetData(const nsID& aSID, nsCSSStruct** aDataPtr) { if (nsnull == aDataPtr) { return NS_ERROR_NULL_POINTER; } if (aSID.Equals(kCSSFontSID)) { *aDataPtr = mFont; } else if (aSID.Equals(kCSSColorSID)) { *aDataPtr = mColor; } else if (aSID.Equals(kCSSTextSID)) { *aDataPtr = mText; } else if (aSID.Equals(kCSSMarginSID)) { *aDataPtr = mMargin; } else if (aSID.Equals(kCSSPositionSID)) { *aDataPtr = mPosition; } else if (aSID.Equals(kCSSListSID)) { *aDataPtr = mList; } else { return NS_NOINTERFACE; } return NS_OK; } nsresult CSSDeclarationImpl::EnsureData(const nsID& aSID, nsCSSStruct** aDataPtr) { if (nsnull == aDataPtr) { return NS_ERROR_NULL_POINTER; } if (aSID.Equals(kCSSFontSID)) { if (nsnull == mFont) { mFont = new nsCSSFont(); } *aDataPtr = mFont; } else if (aSID.Equals(kCSSColorSID)) { if (nsnull == mColor) { mColor = new nsCSSColor(); } *aDataPtr = mColor; } else if (aSID.Equals(kCSSTextSID)) { if (nsnull == mText) { mText = new nsCSSText(); } *aDataPtr = mText; } else if (aSID.Equals(kCSSMarginSID)) { if (nsnull == mMargin) { mMargin = new nsCSSMargin(); } *aDataPtr = mMargin; } else if (aSID.Equals(kCSSPositionSID)) { if (nsnull == mPosition) { mPosition = new nsCSSPosition(); } *aDataPtr = mPosition; } else if (aSID.Equals(kCSSListSID)) { if (nsnull == mList) { mList = new nsCSSList(); } *aDataPtr = mList; } else { return NS_NOINTERFACE; } if (nsnull == *aDataPtr) { return NS_ERROR_OUT_OF_MEMORY; } return NS_OK; } nsresult CSSDeclarationImpl::AddValue(const char* aProperty, const nsCSSValue& aValue) { return AddValue(nsCSSProps::LookupName(aProperty), aValue); } nsresult CSSDeclarationImpl::AddValue(PRInt32 aProperty, const nsCSSValue& aValue) { nsresult result = NS_OK; switch (aProperty) { // nsCSSFont case PROP_FONT_FAMILY: case PROP_FONT_STYLE: case PROP_FONT_VARIANT: case PROP_FONT_WEIGHT: case PROP_FONT_SIZE: if (nsnull == mFont) { mFont = new nsCSSFont(); } if (nsnull != mFont) { switch (aProperty) { case PROP_FONT_FAMILY: mFont->mFamily = aValue; break; case PROP_FONT_STYLE: mFont->mStyle = aValue; break; case PROP_FONT_VARIANT: mFont->mVariant = aValue; break; case PROP_FONT_WEIGHT: mFont->mWeight = aValue; break; case PROP_FONT_SIZE: mFont->mSize = aValue; break; } } else { result = NS_ERROR_OUT_OF_MEMORY; } break; // nsCSSColor case PROP_COLOR: case PROP_BACKGROUND_COLOR: case PROP_BACKGROUND_IMAGE: case PROP_BACKGROUND_REPEAT: case PROP_BACKGROUND_ATTACHMENT: case PROP_BACKGROUND_X_POSITION: case PROP_BACKGROUND_Y_POSITION: case PROP_BACKGROUND_FILTER: if (nsnull == mColor) { mColor = new nsCSSColor(); } if (nsnull != mColor) { switch (aProperty) { case PROP_COLOR: mColor->mColor = aValue; break; case PROP_BACKGROUND_COLOR: mColor->mBackColor = aValue; break; case PROP_BACKGROUND_IMAGE: mColor->mBackImage = aValue; break; case PROP_BACKGROUND_REPEAT: mColor->mBackRepeat = aValue; break; case PROP_BACKGROUND_ATTACHMENT: mColor->mBackAttachment = aValue; break; case PROP_BACKGROUND_X_POSITION: mColor->mBackPositionX = aValue; break; case PROP_BACKGROUND_Y_POSITION: mColor->mBackPositionY = aValue; break; case PROP_BACKGROUND_FILTER: mColor->mBackFilter = aValue; break; } } else { result = NS_ERROR_OUT_OF_MEMORY; } break; // nsCSSText case PROP_WORD_SPACING: case PROP_LETTER_SPACING: case PROP_TEXT_DECORATION: case PROP_VERTICAL_ALIGN: case PROP_TEXT_TRANSFORM: case PROP_TEXT_ALIGN: case PROP_TEXT_INDENT: case PROP_LINE_HEIGHT: case PROP_WHITE_SPACE: if (nsnull == mText) { mText = new nsCSSText(); } if (nsnull != mText) { switch (aProperty) { case PROP_WORD_SPACING: mText->mWordSpacing = aValue; break; case PROP_LETTER_SPACING: mText->mLetterSpacing = aValue; break; case PROP_TEXT_DECORATION: mText->mDecoration = aValue; break; case PROP_VERTICAL_ALIGN: mText->mVertAlign = aValue; break; case PROP_TEXT_TRANSFORM: mText->mTransform = aValue; break; case PROP_TEXT_ALIGN: mText->mHorzAlign = aValue; break; case PROP_TEXT_INDENT: mText->mIndent = aValue; break; case PROP_LINE_HEIGHT: mText->mLineHeight = aValue; break; case PROP_WHITE_SPACE: mText->mWhiteSpace = aValue; break; } } else { result = NS_ERROR_OUT_OF_MEMORY; } break; // nsCSSMargin case PROP_MARGIN_TOP: case PROP_MARGIN_RIGHT: case PROP_MARGIN_BOTTOM: case PROP_MARGIN_LEFT: if (nsnull == mMargin) { mMargin = new nsCSSMargin(); } if (nsnull != mMargin) { if (nsnull == mMargin->mMargin) { mMargin->mMargin = new nsCSSRect(); } if (nsnull != mMargin->mMargin) { switch (aProperty) { case PROP_MARGIN_TOP: mMargin->mMargin->mTop = aValue; break; case PROP_MARGIN_RIGHT: mMargin->mMargin->mRight = aValue; break; case PROP_MARGIN_BOTTOM: mMargin->mMargin->mBottom = aValue; break; case PROP_MARGIN_LEFT: mMargin->mMargin->mLeft = aValue; break; } } else { result = NS_ERROR_OUT_OF_MEMORY; } } else { result = NS_ERROR_OUT_OF_MEMORY; } break; case PROP_PADDING_TOP: case PROP_PADDING_RIGHT: case PROP_PADDING_BOTTOM: case PROP_PADDING_LEFT: if (nsnull == mMargin) { mMargin = new nsCSSMargin(); } if (nsnull != mMargin) { if (nsnull == mMargin->mPadding) { mMargin->mPadding = new nsCSSRect(); } if (nsnull != mMargin->mPadding) { switch (aProperty) { case PROP_PADDING_TOP: mMargin->mPadding->mTop = aValue; break; case PROP_PADDING_RIGHT: mMargin->mPadding->mRight = aValue; break; case PROP_PADDING_BOTTOM: mMargin->mPadding->mBottom = aValue; break; case PROP_PADDING_LEFT: mMargin->mPadding->mLeft = aValue; break; } } else { result = NS_ERROR_OUT_OF_MEMORY; } } else { result = NS_ERROR_OUT_OF_MEMORY; } break; case PROP_BORDER_TOP_WIDTH: case PROP_BORDER_RIGHT_WIDTH: case PROP_BORDER_BOTTOM_WIDTH: case PROP_BORDER_LEFT_WIDTH: if (nsnull == mMargin) { mMargin = new nsCSSMargin(); } if (nsnull != mMargin) { if (nsnull == mMargin->mBorder) { mMargin->mBorder = new nsCSSRect(); } if (nsnull != mMargin->mBorder) { switch (aProperty) { case PROP_BORDER_TOP_WIDTH: mMargin->mBorder->mTop = aValue; break; case PROP_BORDER_RIGHT_WIDTH: mMargin->mBorder->mRight = aValue; break; case PROP_BORDER_BOTTOM_WIDTH: mMargin->mBorder->mBottom = aValue; break; case PROP_BORDER_LEFT_WIDTH: mMargin->mBorder->mLeft = aValue; break; } } else { result = NS_ERROR_OUT_OF_MEMORY; } } else { result = NS_ERROR_OUT_OF_MEMORY; } break; case PROP_BORDER_TOP_COLOR: case PROP_BORDER_RIGHT_COLOR: case PROP_BORDER_BOTTOM_COLOR: case PROP_BORDER_LEFT_COLOR: if (nsnull == mMargin) { mMargin = new nsCSSMargin(); } if (nsnull != mMargin) { if (nsnull == mMargin->mColor) { mMargin->mColor = new nsCSSRect(); } if (nsnull != mMargin->mColor) { switch (aProperty) { case PROP_BORDER_TOP_COLOR: mMargin->mColor->mTop = aValue; break; case PROP_BORDER_RIGHT_COLOR: mMargin->mColor->mRight = aValue; break; case PROP_BORDER_BOTTOM_COLOR: mMargin->mColor->mBottom = aValue; break; case PROP_BORDER_LEFT_COLOR: mMargin->mColor->mLeft = aValue; break; } } else { result = NS_ERROR_OUT_OF_MEMORY; } } else { result = NS_ERROR_OUT_OF_MEMORY; } break; case PROP_BORDER_TOP_STYLE: case PROP_BORDER_RIGHT_STYLE: case PROP_BORDER_BOTTOM_STYLE: case PROP_BORDER_LEFT_STYLE: if (nsnull == mMargin) { mMargin = new nsCSSMargin(); } if (nsnull != mMargin) { if (nsnull == mMargin->mStyle) { mMargin->mStyle = new nsCSSRect(); } if (nsnull != mMargin->mStyle) { switch (aProperty) { case PROP_BORDER_TOP_STYLE: mMargin->mStyle->mTop = aValue; break; case PROP_BORDER_RIGHT_STYLE: mMargin->mStyle->mRight = aValue; break; case PROP_BORDER_BOTTOM_STYLE: mMargin->mStyle->mBottom = aValue; break; case PROP_BORDER_LEFT_STYLE: mMargin->mStyle->mLeft = aValue; break; } } else { result = NS_ERROR_OUT_OF_MEMORY; } } else { result = NS_ERROR_OUT_OF_MEMORY; } break; // nsCSSPosition case PROP_POSITION: case PROP_WIDTH: case PROP_HEIGHT: case PROP_LEFT: case PROP_TOP: case PROP_OVERFLOW: case PROP_Z_INDEX: case PROP_VISIBILITY: case PROP_FLOAT: case PROP_CLEAR: case PROP_DISPLAY: case PROP_FILTER: if (nsnull == mPosition) { mPosition = new nsCSSPosition(); } if (nsnull != mPosition) { switch (aProperty) { case PROP_POSITION: mPosition->mPosition = aValue; break; case PROP_WIDTH: mPosition->mWidth = aValue; break; case PROP_HEIGHT: mPosition->mHeight = aValue; break; case PROP_LEFT: mPosition->mLeft = aValue; break; case PROP_TOP: mPosition->mTop = aValue; break; case PROP_OVERFLOW: mPosition->mOverflow = aValue; break; case PROP_Z_INDEX: mPosition->mZIndex = aValue; break; case PROP_VISIBILITY: mPosition->mVisibility = aValue; break; case PROP_FLOAT: mPosition->mFloat = aValue; break; case PROP_CLEAR: mPosition->mClear = aValue; break; case PROP_DISPLAY: mPosition->mDisplay = aValue; break; case PROP_FILTER: mPosition->mFilter = aValue; break; } } else { result = NS_ERROR_OUT_OF_MEMORY; } break; case PROP_CLIP_TOP: case PROP_CLIP_RIGHT: case PROP_CLIP_BOTTOM: case PROP_CLIP_LEFT: if (nsnull == mPosition) { mPosition = new nsCSSPosition(); } if (nsnull != mPosition) { if (nsnull == mPosition->mClip) { mPosition->mClip = new nsCSSRect(); } if (nsnull != mPosition->mClip) { switch(aProperty) { case PROP_CLIP_TOP: mPosition->mClip->mTop = aValue; break; case PROP_CLIP_RIGHT: mPosition->mClip->mRight = aValue; break; case PROP_CLIP_BOTTOM: mPosition->mClip->mBottom = aValue; break; case PROP_CLIP_LEFT: mPosition->mClip->mLeft = aValue; break; } } else { result = NS_ERROR_OUT_OF_MEMORY; } } else { result = NS_ERROR_OUT_OF_MEMORY; } break; // nsCSSList case PROP_LIST_STYLE_TYPE: case PROP_LIST_STYLE_IMAGE: case PROP_LIST_STYLE_POSITION: if (nsnull == mList) { mList = new nsCSSList(); } if (nsnull != mList) { switch (aProperty) { case PROP_LIST_STYLE_TYPE: mList->mType = aValue; break; case PROP_LIST_STYLE_IMAGE: mList->mImage = aValue; break; case PROP_LIST_STYLE_POSITION: mList->mPosition = aValue; break; } } else { result = NS_ERROR_OUT_OF_MEMORY; } break; case PROP_BACKGROUND: case PROP_BORDER: case PROP_CLIP: case PROP_FONT: case PROP_LIST_STYLE: case PROP_MARGIN: case PROP_PADDING: case PROP_BACKGROUND_POSITION: case PROP_BORDER_TOP: case PROP_BORDER_RIGHT: case PROP_BORDER_BOTTOM: case PROP_BORDER_LEFT: case PROP_BORDER_COLOR: case PROP_BORDER_STYLE: case PROP_BORDER_WIDTH: NS_ERROR("can't query for shorthand properties"); default: result = NS_ERROR_ILLEGAL_VALUE; break; } return result; } nsresult CSSDeclarationImpl::GetValue(const char* aProperty, nsCSSValue& aValue) { return GetValue(nsCSSProps::LookupName(aProperty), aValue); } nsresult CSSDeclarationImpl::GetValue(PRInt32 aProperty, nsCSSValue& aValue) { nsresult result = NS_OK; switch (aProperty) { // nsCSSFont case PROP_FONT_FAMILY: case PROP_FONT_STYLE: case PROP_FONT_VARIANT: case PROP_FONT_WEIGHT: case PROP_FONT_SIZE: if (nsnull != mFont) { switch (aProperty) { case PROP_FONT_FAMILY: aValue = mFont->mFamily; break; case PROP_FONT_STYLE: aValue = mFont->mStyle; break; case PROP_FONT_VARIANT: aValue = mFont->mVariant; break; case PROP_FONT_WEIGHT: aValue = mFont->mWeight; break; case PROP_FONT_SIZE: aValue = mFont->mSize; break; } } else { aValue.Reset(); } break; // nsCSSColor case PROP_COLOR: case PROP_BACKGROUND_COLOR: case PROP_BACKGROUND_IMAGE: case PROP_BACKGROUND_REPEAT: case PROP_BACKGROUND_ATTACHMENT: case PROP_BACKGROUND_X_POSITION: case PROP_BACKGROUND_Y_POSITION: case PROP_BACKGROUND_FILTER: if (nsnull != mColor) { switch (aProperty) { case PROP_COLOR: aValue = mColor->mColor; break; case PROP_BACKGROUND_COLOR: aValue = mColor->mBackColor; break; case PROP_BACKGROUND_IMAGE: aValue = mColor->mBackImage; break; case PROP_BACKGROUND_REPEAT: aValue = mColor->mBackRepeat; break; case PROP_BACKGROUND_ATTACHMENT: aValue = mColor->mBackAttachment; break; case PROP_BACKGROUND_X_POSITION: aValue = mColor->mBackPositionX; break; case PROP_BACKGROUND_Y_POSITION: aValue = mColor->mBackPositionY; break; case PROP_BACKGROUND_FILTER: aValue = mColor->mBackFilter; break; } } else { aValue.Reset(); } break; // nsCSSText case PROP_WORD_SPACING: case PROP_LETTER_SPACING: case PROP_TEXT_DECORATION: case PROP_VERTICAL_ALIGN: case PROP_TEXT_TRANSFORM: case PROP_TEXT_ALIGN: case PROP_TEXT_INDENT: case PROP_LINE_HEIGHT: case PROP_WHITE_SPACE: if (nsnull != mText) { switch (aProperty) { case PROP_WORD_SPACING: aValue = mText->mWordSpacing; break; case PROP_LETTER_SPACING: aValue = mText->mLetterSpacing; break; case PROP_TEXT_DECORATION: aValue = mText->mDecoration; break; case PROP_VERTICAL_ALIGN: aValue = mText->mVertAlign; break; case PROP_TEXT_TRANSFORM: aValue = mText->mTransform; break; case PROP_TEXT_ALIGN: aValue = mText->mHorzAlign; break; case PROP_TEXT_INDENT: aValue = mText->mIndent; break; case PROP_LINE_HEIGHT: aValue = mText->mLineHeight; break; case PROP_WHITE_SPACE: aValue = mText->mWhiteSpace; break; } } else { aValue.Reset(); } break; // nsCSSMargin case PROP_MARGIN_TOP: case PROP_MARGIN_RIGHT: case PROP_MARGIN_BOTTOM: case PROP_MARGIN_LEFT: if ((nsnull != mMargin) && (nsnull != mMargin->mMargin)) { switch (aProperty) { case PROP_MARGIN_TOP: aValue = mMargin->mMargin->mTop; break; case PROP_MARGIN_RIGHT: aValue = mMargin->mMargin->mRight; break; case PROP_MARGIN_BOTTOM: aValue = mMargin->mMargin->mBottom; break; case PROP_MARGIN_LEFT: aValue = mMargin->mMargin->mLeft; break; } } else { aValue.Reset(); } break; case PROP_PADDING_TOP: case PROP_PADDING_RIGHT: case PROP_PADDING_BOTTOM: case PROP_PADDING_LEFT: if ((nsnull != mMargin) && (nsnull != mMargin->mPadding)) { switch (aProperty) { case PROP_PADDING_TOP: aValue = mMargin->mPadding->mTop; break; case PROP_PADDING_RIGHT: aValue = mMargin->mPadding->mRight; break; case PROP_PADDING_BOTTOM: aValue = mMargin->mPadding->mBottom; break; case PROP_PADDING_LEFT: aValue = mMargin->mPadding->mLeft; break; } } else { aValue.Reset(); } break; case PROP_BORDER_TOP_WIDTH: case PROP_BORDER_RIGHT_WIDTH: case PROP_BORDER_BOTTOM_WIDTH: case PROP_BORDER_LEFT_WIDTH: if ((nsnull != mMargin) && (nsnull != mMargin->mBorder)) { switch (aProperty) { case PROP_BORDER_TOP_WIDTH: aValue = mMargin->mBorder->mTop; break; case PROP_BORDER_RIGHT_WIDTH: aValue = mMargin->mBorder->mRight; break; case PROP_BORDER_BOTTOM_WIDTH: aValue = mMargin->mBorder->mBottom; break; case PROP_BORDER_LEFT_WIDTH: aValue = mMargin->mBorder->mLeft; break; } } else { aValue.Reset(); } break; case PROP_BORDER_TOP_COLOR: case PROP_BORDER_RIGHT_COLOR: case PROP_BORDER_BOTTOM_COLOR: case PROP_BORDER_LEFT_COLOR: if ((nsnull != mMargin) && (nsnull != mMargin->mColor)) { switch (aProperty) { case PROP_BORDER_TOP_COLOR: aValue = mMargin->mColor->mTop; break; case PROP_BORDER_RIGHT_COLOR: aValue = mMargin->mColor->mRight; break; case PROP_BORDER_BOTTOM_COLOR: aValue = mMargin->mColor->mBottom; break; case PROP_BORDER_LEFT_COLOR: aValue = mMargin->mColor->mLeft; break; } } else { aValue.Reset(); } break; case PROP_BORDER_TOP_STYLE: case PROP_BORDER_RIGHT_STYLE: case PROP_BORDER_BOTTOM_STYLE: case PROP_BORDER_LEFT_STYLE: if ((nsnull != mMargin) && (nsnull != mMargin->mStyle)) { switch (aProperty) { case PROP_BORDER_TOP_STYLE: aValue = mMargin->mStyle->mTop; break; case PROP_BORDER_RIGHT_STYLE: aValue = mMargin->mStyle->mRight; break; case PROP_BORDER_BOTTOM_STYLE: aValue = mMargin->mStyle->mBottom; break; case PROP_BORDER_LEFT_STYLE: aValue = mMargin->mStyle->mLeft; break; } } else { aValue.Reset(); } break; // nsCSSPosition case PROP_POSITION: case PROP_WIDTH: case PROP_HEIGHT: case PROP_LEFT: case PROP_TOP: case PROP_OVERFLOW: case PROP_Z_INDEX: case PROP_VISIBILITY: case PROP_FLOAT: case PROP_CLEAR: case PROP_DISPLAY: case PROP_FILTER: if (nsnull != mPosition) { switch (aProperty) { case PROP_POSITION: aValue = mPosition->mPosition; break; case PROP_WIDTH: aValue = mPosition->mWidth; break; case PROP_HEIGHT: aValue = mPosition->mHeight; break; case PROP_LEFT: aValue = mPosition->mLeft; break; case PROP_TOP: aValue = mPosition->mTop; break; case PROP_OVERFLOW: aValue = mPosition->mOverflow; break; case PROP_Z_INDEX: aValue = mPosition->mZIndex; break; case PROP_VISIBILITY: aValue = mPosition->mVisibility; break; case PROP_FLOAT: aValue = mPosition->mFloat; break; case PROP_CLEAR: aValue = mPosition->mClear; break; case PROP_DISPLAY: aValue = mPosition->mDisplay; break; case PROP_FILTER: aValue = mPosition->mFilter; break; } } else { aValue.Reset(); } break; case PROP_CLIP_TOP: case PROP_CLIP_RIGHT: case PROP_CLIP_BOTTOM: case PROP_CLIP_LEFT: if ((nsnull != mPosition) && (nsnull != mPosition->mClip)) { switch(aProperty) { case PROP_CLIP_TOP: aValue = mPosition->mClip->mTop; break; case PROP_CLIP_RIGHT: aValue = mPosition->mClip->mRight; break; case PROP_CLIP_BOTTOM: aValue = mPosition->mClip->mBottom; break; case PROP_CLIP_LEFT: aValue = mPosition->mClip->mLeft; break; } } else { aValue.Reset(); } break; // nsCSSList case PROP_LIST_STYLE_TYPE: case PROP_LIST_STYLE_IMAGE: case PROP_LIST_STYLE_POSITION: if (nsnull != mList) { switch (aProperty) { case PROP_LIST_STYLE_TYPE: aValue = mList->mType; break; case PROP_LIST_STYLE_IMAGE: aValue = mList->mImage; break; case PROP_LIST_STYLE_POSITION: aValue = mList->mPosition; break; } } else { aValue.Reset(); } break; case PROP_BACKGROUND: case PROP_BORDER: case PROP_CLIP: case PROP_FONT: case PROP_LIST_STYLE: case PROP_MARGIN: case PROP_PADDING: case PROP_BACKGROUND_POSITION: case PROP_BORDER_TOP: case PROP_BORDER_RIGHT: case PROP_BORDER_BOTTOM: case PROP_BORDER_LEFT: case PROP_BORDER_COLOR: case PROP_BORDER_STYLE: case PROP_BORDER_WIDTH: NS_ERROR("can't query for shorthand properties"); default: result = NS_ERROR_ILLEGAL_VALUE; break; } return result; } void CSSDeclarationImpl::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); fputs("{ ", out); if (nsnull != mFont) { mFont->List(out); } if (nsnull != mColor) { mColor->List(out); } if (nsnull != mText) { mText->List(out); } if (nsnull != mMargin) { mMargin->List(out); } if (nsnull != mPosition) { mPosition->List(out); } if (nsnull != mList) { mList->List(out); } fputs("}", out); } NS_HTML nsresult NS_NewCSSDeclaration(nsICSSDeclaration** aInstancePtrResult) { if (aInstancePtrResult == nsnull) { return NS_ERROR_NULL_POINTER; } CSSDeclarationImpl *it = new CSSDeclarationImpl(); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } return it->QueryInterface(kICSSDeclarationIID, (void **) aInstancePtrResult); } /* font =========== 'font-family', string (list) 'font-style', enum 'font-variant' enum (ie: small caps) 'font-weight' enum 'font-size' abs, pct, enum, +-1 color/background ============= color: color background-color: color background-image: url(string) background-repeat: enum background-attachment: enum background-position-x -y: abs, pct, enum (left/top center right/bottom (pct?)) text ======= word-spacing: abs, "normal" letter-spacing: abs, "normal" text-decoration: enum vertical-align: enum, pct text-transform: enum text-align: enum text-indent: abs, pct line-height: "normal", abs, pct, number-factor white-space: enum margin ======= margin-top -right -bottom -left: "auto", abs, pct padding-top -right -bottom -left: abs, pct border-top -right -bottom -left-width: enum, abs border-top -right -bottom -left-color: color border-top -right -bottom -left-style: enum size ======= position: enum width: abs, pct, "auto" height: abs, pct, "auto" left: abs, pct, "auto" top: abs, pct, "auto" clip: shape, "auto" (shape: rect - abs, auto) overflow: enum z-index: int, auto visibity: enum float: enum clear: enum display: enum filter: string list ======== list-style-type: enum list-style-image: url, "none" list-style-position: enum (bool? in/out) */