/* -*- 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" #include "nsVoidArray.h" #include "nsStyleConsts.h" //#define DEBUG_REFS struct CSSColorEntry{ PRUint8 r; PRUint8 g; PRUint8 b; char *name; }; static CSSColorEntry css_rgb_table[] = { { 0, 0, 0, "black" }, { 0, 0, 128, "navy" }, { 0, 0, 139, "darkblue" }, { 0, 0, 205, "mediumblue" }, { 0, 0, 255, "blue" }, { 0, 100, 0, "darkgreen" }, { 0, 128, 0, "green" }, { 0, 128, 128, "teal" }, { 0, 139, 139, "darkcyan" }, { 0, 191, 255, "deepskyblue" }, { 0, 206, 209, "darkturquoise" }, { 0, 250, 154, "mediumspringgreen" }, { 0, 255, 0, "lime" }, { 0, 255, 127, "springgreen" }, { 0, 255, 255, "aqua" }, { 0, 255, 255, "cyan" }, { 25, 25, 112, "midnightblue" }, { 30, 144, 255, "dodgerblue" }, { 32, 178, 170, "lightseagreen" }, { 34, 139, 34, "forestgreen" }, { 46, 139, 87, "seagreen" }, { 47, 79, 79, "darkslategray" }, { 50, 205, 50, "limegreen" }, { 60, 179, 113, "mediumseagreen" }, { 64, 224, 208, "turquoise" }, { 65, 105, 225, "royalblue" }, { 70, 130, 180, "steelblue" }, { 72, 61, 139, "darkslateblue" }, { 72, 209, 204, "mediumturquoise" }, { 75, 0, 130, "indigo" }, { 85, 107, 47, "darkolivegreen" }, { 95, 158, 160, "cadetblue" }, {100, 149, 237, "cornflowerblue" }, {102, 205, 170, "mediumaquamarine" }, {105, 105, 105, "dimgray" }, {106, 90, 205, "slateblue" }, {107, 142, 35, "olivedrab" }, {112, 128, 144, "slategray" }, {119, 136, 153, "lightslategray" }, {123, 104, 238, "mediumslateblue" }, {124, 252, 0, "lawngreen" }, {127, 255, 0, "chartreuse" }, {127, 255, 212, "aquamarine" }, {128, 0, 0, "maroon" }, {128, 0, 128, "purple" }, {128, 128, 0, "olive" }, {128, 128, 128, "gray" }, {135, 206, 235, "skyblue" }, {135, 206, 250, "lightskyblue" }, {138, 43, 226, "blueviolet" }, {139, 0, 0, "darkred" }, {139, 0, 139, "darkmagenta" }, {139, 69, 19, "saddlebrown" }, {143, 188, 143, "darkseagreen" }, {144, 238, 144, "lightgreen" }, {147, 112, 219, "mediumpurple" }, {148, 0, 211, "darkviolet" }, {152, 251, 152, "palegreen" }, {153, 50, 204, "darkorchid" }, {154, 205, 50, "yellowgreen" }, {160, 82, 45, "sienna" }, {165, 42, 42, "brown" }, {169, 169, 169, "darkgray" }, {173, 216, 230, "lightblue" }, {173, 255, 47, "greenyellow" }, {175, 238, 238, "paleturquoise" }, {176, 196, 222, "lightsteelblue" }, {176, 224, 230, "powderblue" }, {178, 34, 34, "firebrick" }, {184, 134, 11, "darkgoldenrod" }, {186, 85, 211, "mediumorchid" }, {188, 143, 143, "rosybrown" }, {189, 183, 107, "darkkhaki" }, {192, 192, 192, "silver" }, {199, 21, 133, "mediumvioletred" }, {205, 92, 92, "indianred" }, {205, 133, 63, "peru" }, {210, 105, 30, "chocolate" }, {210, 180, 140, "tan" }, {211, 211, 211, "lightgrey" }, {216, 191, 216, "thistle" }, {218, 112, 214, "orchid" }, {218, 165, 32, "goldenrod" }, {219, 112, 147, "palevioletred" }, {220, 20, 60, "crimson" }, {220, 220, 220, "gainsboro" }, {221, 160, 221, "plum" }, {222, 184, 135, "burlywood" }, {224, 255, 255, "lightcyan" }, {230, 230, 250, "lavender" }, {233, 150, 122, "darksalmon" }, {238, 130, 238, "violet" }, {238, 232, 170, "palegoldenrod" }, {240, 128, 128, "lightcoral" }, {240, 230, 140, "khaki" }, {240, 248, 255, "aliceblue" }, {240, 255, 240, "honeydew" }, {240, 255, 255, "azure" }, {244, 164, 96, "sandybrown" }, {245, 222, 179, "wheat" }, {245, 245, 220, "beige" }, {245, 245, 245, "whitesmoke" }, {245, 255, 250, "mintcream" }, {248, 248, 255, "ghostwhite" }, {250, 128, 114, "salmon" }, {250, 235, 215, "antiquewhite" }, {250, 240, 230, "linen" }, {250, 250, 210, "lightgoldenrodyellow" }, {253, 245, 230, "oldlace" }, {255, 0, 0, "red" }, {255, 0, 255, "fuchsia" }, {255, 0, 255, "magenta" }, {255, 20, 147, "deeppink" }, {255, 69, 0, "orangered" }, {255, 99, 71, "tomato" }, {255, 105, 180, "hotpink" }, {255, 127, 80, "coral" }, {255, 140, 0, "darkorange" }, {255, 160, 122, "lightsalmon" }, {255, 165, 0, "orange" }, {255, 182, 193, "lightpink" }, {255, 192, 203, "pink" }, {255, 215, 0, "gold" }, {255, 218, 185, "peachpuff" }, {255, 222, 173, "navajowhite" }, {255, 228, 181, "moccasin" }, {255, 228, 196, "bisque" }, {255, 228, 225, "mistyrose" }, {255, 235, 205, "blanchedalmond" }, {255, 239, 213, "papayawhip" }, {255, 240, 245, "lavenderblush" }, {255, 245, 238, "seashell" }, {255, 248, 220, "cornsilk" }, {255, 250, 205, "lemonchiffon" }, {255, 250, 240, "floralwhite" }, {255, 250, 250, "snow" }, {255, 255, 0, "yellow" }, {255, 255, 224, "lightyellow" }, {255, 255, 240, "ivory" }, {255, 255, 255, "white" }, }; static NS_DEFINE_IID(kCSSFontSID, NS_CSS_FONT_SID); static NS_DEFINE_IID(kCSSColorSID, NS_CSS_COLOR_SID); static NS_DEFINE_IID(kCSSDisplaySID, NS_CSS_DISPLAY_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(kCSSTableSID, NS_CSS_TABLE_SID); static NS_DEFINE_IID(kCSSBreaksSID, NS_CSS_BREAKS_SID); static NS_DEFINE_IID(kCSSPageSID, NS_CSS_PAGE_SID); static NS_DEFINE_IID(kCSSContentSID, NS_CSS_CONTENT_SID); static NS_DEFINE_IID(kCSSAuralSID, NS_CSS_AURAL_SID); static NS_DEFINE_IID(kICSSDeclarationIID, NS_ICSS_DECLARATION_IID); // --- nsCSSFont ----------------- 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); mSizeAdjust.AppendToString(buffer, PROP_FONT_SIZE_ADJUST); mStretch.AppendToString(buffer, PROP_FONT_STRETCH); fputs(buffer, out); } // --- nsCSSColor ----------------- 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); mCursor.AppendToString(buffer, PROP_CURSOR); mCursorImage.AppendToString(buffer, PROP_CURSOR_IMAGE); mOpacity.AppendToString(buffer, PROP_OPACITY); fputs(buffer, out); } // --- nsCSSText ----------------- nsCSSShadow::nsCSSShadow(void) : mNext(nsnull) { } nsCSSShadow::~nsCSSShadow(void) { if (nsnull != mNext) { delete mNext; } } // --- nsCSSText ----------------- nsCSSText::nsCSSText(void) : mTextShadow(nsnull) { } nsCSSText::~nsCSSText(void) { if (nsnull != mTextShadow) { delete mTextShadow; } } 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); mVerticalAlign.AppendToString(buffer, PROP_VERTICAL_ALIGN); mTextTransform.AppendToString(buffer, PROP_TEXT_TRANSFORM); mTextAlign.AppendToString(buffer, PROP_TEXT_ALIGN); mTextIndent.AppendToString(buffer, PROP_TEXT_INDENT); if (nsnull != mTextShadow) { if (eCSSUnit_Color == mTextShadow->mColor.GetUnit()) { nsCSSShadow* shadow = mTextShadow; while (nsnull != shadow) { shadow->mColor.AppendToString(buffer, PROP_TEXT_SHADOW_COLOR); shadow->mXOffset.AppendToString(buffer, PROP_TEXT_SHADOW_X); shadow->mYOffset.AppendToString(buffer, PROP_TEXT_SHADOW_Y); shadow->mRadius.AppendToString(buffer, PROP_TEXT_SHADOW_RADIUS); shadow = shadow->mNext; } } else { mTextShadow->mColor.AppendToString(buffer, PROP_TEXT_SHADOW); } } mUnicodeBidi.AppendToString(buffer, PROP_UNICODE_BIDI); mLineHeight.AppendToString(buffer, PROP_LINE_HEIGHT); mWhiteSpace.AppendToString(buffer, PROP_WHITE_SPACE); fputs(buffer, out); } // --- nsCSSRect ----------------- 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); } void nsCSSRect::List(FILE* out, PRInt32 aIndent, PRIntn aTRBL[]) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; if (eCSSUnit_Null != mTop.GetUnit()) { buffer.Append(nsCSSProps::kNameTable[aTRBL[0]].name); buffer.Append(": "); mTop.AppendToString(buffer); } if (eCSSUnit_Null != mRight.GetUnit()) { buffer.Append(nsCSSProps::kNameTable[aTRBL[1]].name); buffer.Append(": "); mRight.AppendToString(buffer); } if (eCSSUnit_Null != mBottom.GetUnit()) { buffer.Append(nsCSSProps::kNameTable[aTRBL[2]].name); buffer.Append(": "); mBottom.AppendToString(buffer); } if (eCSSUnit_Null != mLeft.GetUnit()) { buffer.Append(nsCSSProps::kNameTable[aTRBL[3]].name); buffer.Append(": "); mLeft.AppendToString(buffer); } fputs(buffer, out); } // --- nsCSSDisplay ----------------- nsCSSDisplay::nsCSSDisplay(void) : mClip(nsnull) { } nsCSSDisplay::~nsCSSDisplay(void) { if (nsnull != mClip) { delete mClip; } } const nsID& nsCSSDisplay::GetID(void) { return kCSSDisplaySID; } void nsCSSDisplay::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; mDirection.AppendToString(buffer, PROP_DIRECTION); mDisplay.AppendToString(buffer, PROP_DISPLAY); mFloat.AppendToString(buffer, PROP_FLOAT); mClear.AppendToString(buffer, PROP_CLEAR); mVisibility.AppendToString(buffer, PROP_VISIBILITY); mFilter.AppendToString(buffer, PROP_FILTER); fputs(buffer, out); if (nsnull != mClip) { mClip->List(out, PROP_CLIP); } buffer.SetLength(0); mOverflow.AppendToString(buffer, PROP_OVERFLOW); fputs(buffer, out); } // --- nsCSSMargin ----------------- nsCSSMargin::nsCSSMargin(void) : mMargin(nsnull), mPadding(nsnull), mBorderWidth(nsnull), mBorderColor(nsnull), mBorderStyle(nsnull) { } nsCSSMargin::~nsCSSMargin(void) { if (nsnull != mMargin) { delete mMargin; } if (nsnull != mPadding) { delete mPadding; } if (nsnull != mBorderWidth) { delete mBorderWidth; } if (nsnull != mBorderColor) { delete mBorderColor; } if (nsnull != mBorderStyle) { delete mBorderStyle; } } const nsID& nsCSSMargin::GetID(void) { return kCSSMarginSID; } void nsCSSMargin::List(FILE* out, PRInt32 aIndent) const { if (nsnull != mMargin) { static PRIntn trbl[] = { PROP_MARGIN_TOP, PROP_MARGIN_RIGHT, PROP_MARGIN_BOTTOM, PROP_MARGIN_LEFT }; mMargin->List(out, aIndent, trbl); } if (nsnull != mPadding) { static PRIntn trbl[] = { PROP_PADDING_TOP, PROP_PADDING_RIGHT, PROP_PADDING_BOTTOM, PROP_PADDING_LEFT }; mPadding->List(out, aIndent, trbl); } if (nsnull != mBorderWidth) { static PRIntn trbl[] = { PROP_BORDER_TOP_WIDTH, PROP_BORDER_RIGHT_WIDTH, PROP_BORDER_BOTTOM_WIDTH, PROP_BORDER_LEFT_WIDTH }; mBorderWidth->List(out, aIndent, trbl); } if (nsnull != mBorderColor) { mBorderColor->List(out, PROP_BORDER_COLOR, aIndent); } if (nsnull != mBorderStyle) { mBorderStyle->List(out, PROP_BORDER_STYLE, aIndent); } for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; mOutlineWidth.AppendToString(buffer, PROP_OUTLINE_WIDTH); mOutlineColor.AppendToString(buffer, PROP_OUTLINE_COLOR); mOutlineStyle.AppendToString(buffer, PROP_OUTLINE_STYLE); fputs(buffer, out); } // --- nsCSSPosition ----------------- nsCSSPosition::nsCSSPosition(void) : mOffset(nsnull) { } nsCSSPosition::~nsCSSPosition(void) { if (nsnull != mOffset) { delete mOffset; } } 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); mMinWidth.AppendToString(buffer, PROP_MIN_WIDTH); mMaxWidth.AppendToString(buffer, PROP_MAX_WIDTH); mHeight.AppendToString(buffer, PROP_HEIGHT); mMinHeight.AppendToString(buffer, PROP_MIN_HEIGHT); mMaxHeight.AppendToString(buffer, PROP_MAX_HEIGHT); mZIndex.AppendToString(buffer, PROP_Z_INDEX); fputs(buffer, out); if (nsnull != mOffset) { static PRIntn trbl[] = { PROP_TOP, PROP_RIGHT, PROP_BOTTOM, PROP_LEFT }; mOffset->List(out, aIndent, trbl); } } // --- nsCSSList ----------------- 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); } // --- nsCSSTable ----------------- const nsID& nsCSSTable::GetID(void) { return kCSSTableSID; } void nsCSSTable::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; mBorderCollapse.AppendToString(buffer, PROP_BORDER_COLLAPSE); mBorderSpacing.AppendToString(buffer, PROP_BORDER_SPACING); mCaptionSide.AppendToString(buffer, PROP_CAPTION_SIDE); mEmptyCells.AppendToString(buffer, PROP_EMPTY_CELLS); mLayout.AppendToString(buffer, PROP_TABLE_LAYOUT); fputs(buffer, out); } // --- nsCSSBreaks ----------------- const nsID& nsCSSBreaks::GetID(void) { return kCSSBreaksSID; } void nsCSSBreaks::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; mOrphans.AppendToString(buffer, PROP_ORPHANS); mWidows.AppendToString(buffer, PROP_WIDOWS); mPage.AppendToString(buffer, PROP_PAGE); mPageBreakAfter.AppendToString(buffer, PROP_PAGE_BREAK_AFTER); mPageBreakBefore.AppendToString(buffer, PROP_PAGE_BREAK_BEFORE); mPageBreakInside.AppendToString(buffer, PROP_PAGE_BREAK_INSIDE); fputs(buffer, out); } // --- nsCSSPage ----------------- const nsID& nsCSSPage::GetID(void) { return kCSSPageSID; } void nsCSSPage::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; mMarks.AppendToString(buffer, PROP_MARKS); mSize.AppendToString(buffer, PROP_SIZE); fputs(buffer, out); } // --- nsCSSContent ----------------- const nsID& nsCSSContent::GetID(void) { return kCSSContentSID; } void nsCSSContent::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; mContent.AppendToString(buffer, PROP_CONTENT); mCounterIncrement.AppendToString(buffer, PROP_COUNTER_INCREMENT); mCounterReset.AppendToString(buffer, PROP_COUNTER_RESET); mMarkerOffset.AppendToString(buffer, PROP_MARKER_OFFSET); mQuotes.AppendToString(buffer, PROP_QUOTES); fputs(buffer, out); } // --- nsCSSAural ----------------- const nsID& nsCSSAural::GetID(void) { return kCSSAuralSID; } void nsCSSAural::List(FILE* out, PRInt32 aIndent) const { for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out); nsAutoString buffer; mAzimuth.AppendToString(buffer, PROP_AZIMUTH); mElevation.AppendToString(buffer, PROP_ELEVATION); mCueAfter.AppendToString(buffer, PROP_CUE_AFTER); mCueBefore.AppendToString(buffer, PROP_CUE_BEFORE); mPauseAfter.AppendToString(buffer, PROP_PAUSE_AFTER); mPauseBefore.AppendToString(buffer, PROP_PAUSE_BEFORE); mPitch.AppendToString(buffer, PROP_PITCH); mPitchRange.AppendToString(buffer, PROP_PITCH_RANGE); mPlayDuring.AppendToString(buffer, PROP_PLAY_DURING); mRichness.AppendToString(buffer, PROP_RICHNESS); mSpeak.AppendToString(buffer, PROP_SPEAK); mSpeakHeader.AppendToString(buffer, PROP_SPEAK_HEADER); mSpeakNumeral.AppendToString(buffer, PROP_SPEAK_NUMERAL); mSpeakPunctuation.AppendToString(buffer, PROP_SPEAK_PUNCTUATION); mSpeechRate.AppendToString(buffer, PROP_SPEECH_RATE); mStress.AppendToString(buffer, PROP_STRESS); mVoiceFamily.AppendToString(buffer, PROP_VOICE_FAMILY); mVolume.AppendToString(buffer, PROP_VOLUME); fputs(buffer, out); } // --- nsCSSDeclaration ----------------- 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 AppendValue(const char* aProperty, const nsCSSValue& aValue); nsresult AppendValue(PRInt32 aProperty, const nsCSSValue& aValue); nsresult SetValueImportant(const char* aProperty); nsresult SetValueImportant(PRInt32 aProperty); nsresult AppendComment(const nsString& aComment); nsresult GetValue(const char* aProperty, nsCSSValue& aValue); nsresult GetValue(PRInt32 aProperty, nsCSSValue& aValue); nsresult GetValue(PRInt32 aProperty, nsString& aValue); nsresult GetValue(const nsString& aProperty, nsString& aValue); nsresult GetImportantValues(nsICSSDeclaration*& aResult); nsresult GetValueIsImportant(const char *aProperty, PRBool& aIsImportant); PRBool AppendValueToString(PRInt32 aProperty, nsString& aResult); PRBool AppendValueToString(PRInt32 aProperty, const nsCSSValue& aValue, nsString& aResult); virtual nsresult ToString(nsString& aString); void List(FILE* out = stdout, PRInt32 aIndent = 0) const; nsresult Count(PRUint32* aCount); nsresult GetNthProperty(PRUint32 aIndex, nsString& aReturn); 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; nsCSSDisplay* mDisplay; nsCSSTable* mTable; nsCSSBreaks* mBreaks; nsCSSPage* mPage; nsCSSContent* mContent; nsCSSAural* mAural; CSSDeclarationImpl* mImportant; nsVoidArray* mOrder; nsVoidArray* mComments; }; #ifdef DEBUG_REFS static PRInt32 gInstanceCount; #endif void* CSSDeclarationImpl::operator new(size_t size) { void* result = new char[size]; nsCRT::zero(result, size); return result; } CSSDeclarationImpl::CSSDeclarationImpl(void) { NS_INIT_REFCNT(); #ifdef DEBUG_REFS ++gInstanceCount; fprintf(stdout, "%d + CSSDeclaration\n", gInstanceCount); #endif } #define CSS_IF_DELETE(ptr) if (nsnull != ptr) delete ptr; CSSDeclarationImpl::~CSSDeclarationImpl(void) { CSS_IF_DELETE(mFont); CSS_IF_DELETE(mColor); CSS_IF_DELETE(mText); CSS_IF_DELETE(mMargin); CSS_IF_DELETE(mPosition); CSS_IF_DELETE(mList); CSS_IF_DELETE(mDisplay); CSS_IF_DELETE(mTable); CSS_IF_DELETE(mBreaks); CSS_IF_DELETE(mPage); CSS_IF_DELETE(mContent); CSS_IF_DELETE(mAural); NS_IF_RELEASE(mImportant); if (nsnull != mOrder) { delete mOrder; } if (nsnull != mComments) { PRInt32 index = mComments->Count(); while (0 < --index) { nsString* comment = (nsString*)mComments->ElementAt(index); delete comment; } delete mComments; } #ifdef DEBUG_REFS --gInstanceCount; fprintf(stdout, "%d - CSSDeclaration\n", gInstanceCount); #endif } NS_IMPL_ISUPPORTS(CSSDeclarationImpl, kICSSDeclarationIID); #define CSS_IF_GET_ELSE(sid,ptr,result) \ if (sid.Equals(kCSS##ptr##SID)) { *result = m##ptr; } else nsresult CSSDeclarationImpl::GetData(const nsID& aSID, nsCSSStruct** aDataPtr) { if (nsnull == aDataPtr) { return NS_ERROR_NULL_POINTER; } CSS_IF_GET_ELSE(aSID, Font, aDataPtr) CSS_IF_GET_ELSE(aSID, Color, aDataPtr) CSS_IF_GET_ELSE(aSID, Display, aDataPtr) CSS_IF_GET_ELSE(aSID, Text, aDataPtr) CSS_IF_GET_ELSE(aSID, Margin, aDataPtr) CSS_IF_GET_ELSE(aSID, Position, aDataPtr) CSS_IF_GET_ELSE(aSID, List, aDataPtr) CSS_IF_GET_ELSE(aSID, Table, aDataPtr) CSS_IF_GET_ELSE(aSID, Breaks, aDataPtr) CSS_IF_GET_ELSE(aSID, Page, aDataPtr) CSS_IF_GET_ELSE(aSID, Content, aDataPtr) CSS_IF_GET_ELSE(aSID, Aural, aDataPtr) { return NS_NOINTERFACE; } return NS_OK; } #define CSS_IF_ENSURE_ELSE(sid,ptr,result) \ if (sid.Equals(kCSS##ptr##SID)) { \ if (nsnull == m##ptr) { m##ptr = new nsCSS##ptr(); } \ *result = m##ptr; \ } else nsresult CSSDeclarationImpl::EnsureData(const nsID& aSID, nsCSSStruct** aDataPtr) { if (nsnull == aDataPtr) { return NS_ERROR_NULL_POINTER; } CSS_IF_ENSURE_ELSE(aSID, Font, aDataPtr) CSS_IF_ENSURE_ELSE(aSID, Color, aDataPtr) CSS_IF_ENSURE_ELSE(aSID, Display, aDataPtr) CSS_IF_ENSURE_ELSE(aSID, Text, aDataPtr) CSS_IF_ENSURE_ELSE(aSID, Margin, aDataPtr) CSS_IF_ENSURE_ELSE(aSID, Position, aDataPtr) CSS_IF_ENSURE_ELSE(aSID, List, aDataPtr) CSS_IF_ENSURE_ELSE(aSID, Table, aDataPtr) CSS_IF_ENSURE_ELSE(aSID, Breaks, aDataPtr) CSS_IF_ENSURE_ELSE(aSID, Page, aDataPtr) CSS_IF_ENSURE_ELSE(aSID, Content, aDataPtr) CSS_IF_ENSURE_ELSE(aSID, Aural, aDataPtr) { return NS_NOINTERFACE; } if (nsnull == *aDataPtr) { return NS_ERROR_OUT_OF_MEMORY; } return NS_OK; } nsresult CSSDeclarationImpl::AppendValue(const char* aProperty, const nsCSSValue& aValue) { return AppendValue(nsCSSProps::LookupName(aProperty), aValue); } #define CSS_ENSURE(data) \ if (nsnull == m##data) { \ m##data = new nsCSS##data(); \ } \ if (nsnull == m##data) { \ result = NS_ERROR_OUT_OF_MEMORY; \ } \ else #define CSS_ENSURE_RECT(data) \ if (nsnull == data) { \ data = new nsCSSRect(); \ } \ if (nsnull == data) { \ result = NS_ERROR_OUT_OF_MEMORY; \ } \ else nsresult CSSDeclarationImpl::AppendValue(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: case PROP_FONT_SIZE_ADJUST: case PROP_FONT_STRETCH: CSS_ENSURE(Font) { 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; case PROP_FONT_SIZE_ADJUST: mFont->mSizeAdjust = aValue; break; case PROP_FONT_STRETCH: mFont->mStretch = aValue; break; } } 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: case PROP_CURSOR: case PROP_CURSOR_IMAGE: case PROP_OPACITY: CSS_ENSURE(Color) { 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; case PROP_CURSOR: mColor->mCursor = aValue; break; case PROP_CURSOR_IMAGE: mColor->mCursorImage = aValue; break; case PROP_OPACITY: mColor->mOpacity = aValue; break; } } 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_UNICODE_BIDI: case PROP_LINE_HEIGHT: case PROP_WHITE_SPACE: CSS_ENSURE(Text) { 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->mVerticalAlign = aValue; break; case PROP_TEXT_TRANSFORM: mText->mTextTransform = aValue; break; case PROP_TEXT_ALIGN: mText->mTextAlign = aValue; break; case PROP_TEXT_INDENT: mText->mTextIndent = aValue; break; case PROP_UNICODE_BIDI: mText->mUnicodeBidi = aValue; break; case PROP_LINE_HEIGHT: mText->mLineHeight = aValue; break; case PROP_WHITE_SPACE: mText->mWhiteSpace = aValue; break; } } break; // nsCSSDisplay case PROP_FLOAT: case PROP_CLEAR: case PROP_DISPLAY: case PROP_DIRECTION: case PROP_VISIBILITY: case PROP_OVERFLOW: case PROP_FILTER: CSS_ENSURE(Display) { switch (aProperty) { case PROP_FLOAT: mDisplay->mFloat = aValue; break; case PROP_CLEAR: mDisplay->mClear = aValue; break; case PROP_DISPLAY: mDisplay->mDisplay = aValue; break; case PROP_DIRECTION: mDisplay->mDirection = aValue; break; case PROP_VISIBILITY: mDisplay->mVisibility = aValue; break; case PROP_OVERFLOW: mDisplay->mOverflow = aValue; break; case PROP_FILTER: mDisplay->mFilter = aValue; break; } } break; case PROP_CLIP_TOP: case PROP_CLIP_RIGHT: case PROP_CLIP_BOTTOM: case PROP_CLIP_LEFT: CSS_ENSURE(Display) { CSS_ENSURE_RECT(mDisplay->mClip) { switch(aProperty) { case PROP_CLIP_TOP: mDisplay->mClip->mTop = aValue; break; case PROP_CLIP_RIGHT: mDisplay->mClip->mRight = aValue; break; case PROP_CLIP_BOTTOM: mDisplay->mClip->mBottom = aValue; break; case PROP_CLIP_LEFT: mDisplay->mClip->mLeft = aValue; break; } } } break; // nsCSSMargin case PROP_MARGIN_TOP: case PROP_MARGIN_RIGHT: case PROP_MARGIN_BOTTOM: case PROP_MARGIN_LEFT: CSS_ENSURE(Margin) { CSS_ENSURE_RECT(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; } } } break; case PROP_PADDING_TOP: case PROP_PADDING_RIGHT: case PROP_PADDING_BOTTOM: case PROP_PADDING_LEFT: CSS_ENSURE(Margin) { CSS_ENSURE_RECT(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; } } } break; case PROP_BORDER_TOP_WIDTH: case PROP_BORDER_RIGHT_WIDTH: case PROP_BORDER_BOTTOM_WIDTH: case PROP_BORDER_LEFT_WIDTH: CSS_ENSURE(Margin) { CSS_ENSURE_RECT(mMargin->mBorderWidth) { switch (aProperty) { case PROP_BORDER_TOP_WIDTH: mMargin->mBorderWidth->mTop = aValue; break; case PROP_BORDER_RIGHT_WIDTH: mMargin->mBorderWidth->mRight = aValue; break; case PROP_BORDER_BOTTOM_WIDTH: mMargin->mBorderWidth->mBottom = aValue; break; case PROP_BORDER_LEFT_WIDTH: mMargin->mBorderWidth->mLeft = aValue; break; } } } break; case PROP_BORDER_TOP_COLOR: case PROP_BORDER_RIGHT_COLOR: case PROP_BORDER_BOTTOM_COLOR: case PROP_BORDER_LEFT_COLOR: CSS_ENSURE(Margin) { CSS_ENSURE_RECT(mMargin->mBorderColor) { switch (aProperty) { case PROP_BORDER_TOP_COLOR: mMargin->mBorderColor->mTop = aValue; break; case PROP_BORDER_RIGHT_COLOR: mMargin->mBorderColor->mRight = aValue; break; case PROP_BORDER_BOTTOM_COLOR: mMargin->mBorderColor->mBottom = aValue; break; case PROP_BORDER_LEFT_COLOR: mMargin->mBorderColor->mLeft = aValue; break; } } } break; case PROP_BORDER_TOP_STYLE: case PROP_BORDER_RIGHT_STYLE: case PROP_BORDER_BOTTOM_STYLE: case PROP_BORDER_LEFT_STYLE: CSS_ENSURE(Margin) { CSS_ENSURE_RECT(mMargin->mBorderStyle) { switch (aProperty) { case PROP_BORDER_TOP_STYLE: mMargin->mBorderStyle->mTop = aValue; break; case PROP_BORDER_RIGHT_STYLE: mMargin->mBorderStyle->mRight = aValue; break; case PROP_BORDER_BOTTOM_STYLE: mMargin->mBorderStyle->mBottom = aValue; break; case PROP_BORDER_LEFT_STYLE: mMargin->mBorderStyle->mLeft = aValue; break; } } } break; case PROP_OUTLINE_WIDTH: case PROP_OUTLINE_COLOR: case PROP_OUTLINE_STYLE: CSS_ENSURE(Margin) { switch (aProperty) { case PROP_OUTLINE_WIDTH: mMargin->mOutlineWidth = aValue; break; case PROP_OUTLINE_COLOR: mMargin->mOutlineColor = aValue; break; case PROP_OUTLINE_STYLE: mMargin->mOutlineStyle = aValue; break; } } break; // nsCSSPosition case PROP_POSITION: case PROP_WIDTH: case PROP_MIN_WIDTH: case PROP_MAX_WIDTH: case PROP_HEIGHT: case PROP_MIN_HEIGHT: case PROP_MAX_HEIGHT: case PROP_Z_INDEX: CSS_ENSURE(Position) { switch (aProperty) { case PROP_POSITION: mPosition->mPosition = aValue; break; case PROP_WIDTH: mPosition->mWidth = aValue; break; case PROP_MIN_WIDTH: mPosition->mMinWidth = aValue; break; case PROP_MAX_WIDTH: mPosition->mMaxWidth = aValue; break; case PROP_HEIGHT: mPosition->mHeight = aValue; break; case PROP_MIN_HEIGHT: mPosition->mMinHeight = aValue; break; case PROP_MAX_HEIGHT: mPosition->mMaxHeight = aValue; break; case PROP_Z_INDEX: mPosition->mZIndex = aValue; break; } } break; case PROP_TOP: case PROP_RIGHT: case PROP_BOTTOM: case PROP_LEFT: CSS_ENSURE(Position) { CSS_ENSURE_RECT(mPosition->mOffset) { switch (aProperty) { case PROP_TOP: mPosition->mOffset->mTop = aValue; break; case PROP_RIGHT: mPosition->mOffset->mRight= aValue; break; case PROP_BOTTOM: mPosition->mOffset->mBottom = aValue; break; case PROP_LEFT: mPosition->mOffset->mLeft = aValue; break; } } } break; // nsCSSList case PROP_LIST_STYLE_TYPE: case PROP_LIST_STYLE_IMAGE: case PROP_LIST_STYLE_POSITION: CSS_ENSURE(List) { 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; } } break; // nsCSSTable case PROP_BORDER_COLLAPSE: case PROP_BORDER_SPACING: case PROP_CAPTION_SIDE: case PROP_EMPTY_CELLS: case PROP_TABLE_LAYOUT: CSS_ENSURE(Table) { switch (aProperty) { case PROP_BORDER_COLLAPSE: mTable->mBorderCollapse = aValue; break; case PROP_BORDER_SPACING: mTable->mBorderSpacing = aValue; break; case PROP_CAPTION_SIDE: mTable->mCaptionSide = aValue; break; case PROP_EMPTY_CELLS: mTable->mEmptyCells = aValue; break; case PROP_TABLE_LAYOUT: mTable->mLayout = aValue; break; } } break; // nsCSSBreaks case PROP_ORPHANS: case PROP_WIDOWS: case PROP_PAGE: case PROP_PAGE_BREAK_AFTER: case PROP_PAGE_BREAK_BEFORE: case PROP_PAGE_BREAK_INSIDE: CSS_ENSURE(Breaks) { switch (aProperty) { case PROP_ORPHANS: mBreaks->mOrphans = aValue; break; case PROP_WIDOWS: mBreaks->mWidows = aValue; break; case PROP_PAGE: mBreaks->mPage = aValue; break; case PROP_PAGE_BREAK_AFTER: mBreaks->mPageBreakAfter = aValue; break; case PROP_PAGE_BREAK_BEFORE: mBreaks->mPageBreakBefore = aValue; break; case PROP_PAGE_BREAK_INSIDE: mBreaks->mPageBreakInside = aValue; break; } } break; // nsCSSPage case PROP_MARKS: case PROP_SIZE: CSS_ENSURE(Page) { switch (aProperty) { case PROP_MARKS: mPage->mMarks = aValue; break; case PROP_SIZE: mPage->mSize = aValue; break; } } break; // nsCSSContent case PROP_CONTENT: case PROP_COUNTER_INCREMENT: case PROP_COUNTER_RESET: case PROP_MARKER_OFFSET: case PROP_QUOTES: CSS_ENSURE(Content) { switch (aProperty) { case PROP_CONTENT: mContent->mContent = aValue; break; case PROP_COUNTER_INCREMENT: mContent->mCounterIncrement = aValue; break; case PROP_COUNTER_RESET: mContent->mCounterReset = aValue; break; case PROP_MARKER_OFFSET: mContent->mMarkerOffset = aValue; break; case PROP_QUOTES: mContent->mQuotes = aValue; break; } } break; // nsCSSAural case PROP_AZIMUTH: case PROP_ELEVATION: case PROP_CUE_AFTER: case PROP_CUE_BEFORE: case PROP_PAUSE_AFTER: case PROP_PAUSE_BEFORE: case PROP_PITCH: case PROP_PITCH_RANGE: case PROP_PLAY_DURING: case PROP_RICHNESS: case PROP_SPEAK: case PROP_SPEAK_HEADER: case PROP_SPEAK_NUMERAL: case PROP_SPEAK_PUNCTUATION: case PROP_SPEECH_RATE: case PROP_STRESS: case PROP_VOICE_FAMILY: case PROP_VOLUME: CSS_ENSURE(Aural) { switch (aProperty) { case PROP_AZIMUTH: mAural->mAzimuth = aValue; break; case PROP_ELEVATION: mAural->mElevation = aValue; break; case PROP_CUE_AFTER: mAural->mCueAfter = aValue; break; case PROP_CUE_BEFORE: mAural->mCueBefore = aValue; break; case PROP_PAUSE_AFTER: mAural->mPauseAfter = aValue; break; case PROP_PAUSE_BEFORE: mAural->mPauseBefore = aValue; break; case PROP_PITCH: mAural->mPitch = aValue; break; case PROP_PITCH_RANGE: mAural->mPitchRange = aValue; break; case PROP_PLAY_DURING: mAural->mPlayDuring = aValue; break; case PROP_RICHNESS: mAural->mRichness = aValue; break; case PROP_SPEAK: mAural->mSpeak = aValue; break; case PROP_SPEAK_HEADER: mAural->mSpeakHeader = aValue; break; case PROP_SPEAK_NUMERAL: mAural->mSpeakNumeral = aValue; break; case PROP_SPEAK_PUNCTUATION: mAural->mSpeakPunctuation = aValue; break; case PROP_SPEECH_RATE: mAural->mSpeechRate = aValue; break; case PROP_STRESS: mAural->mStress = aValue; break; case PROP_VOICE_FAMILY: mAural->mVoiceFamily = aValue; break; case PROP_VOLUME: mAural->mVolume = aValue; break; } } break; // Shorthands case PROP_BACKGROUND: case PROP_BORDER: case PROP_CLIP: case PROP_CUE: case PROP_FONT: case PROP_LIST_STYLE: case PROP_MARGIN: case PROP_OUTLINE: case PROP_PADDING: case PROP_PAUSE: case PROP_TEXT_SHADOW: 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; } if (NS_OK == result) { if (nsnull == mOrder) { mOrder = new nsVoidArray(); } if (nsnull != mOrder) { PRInt32 index = mOrder->IndexOf((void*)aProperty); if (-1 != index) { mOrder->RemoveElementAt(index); } if (eCSSUnit_Null != aValue.GetUnit()) { mOrder->AppendElement((void*)aProperty); } } if (nsnull != mImportant) { // remove from important nsCSSValue null; mImportant->AppendValue(aProperty, null); } } return result; } nsresult CSSDeclarationImpl::SetValueImportant(const char* aProperty) { return SetValueImportant(nsCSSProps::LookupName(aProperty)); } #define CSS_ENSURE_IMPORTANT(data) \ if (nsnull == mImportant->m##data) { \ mImportant->m##data = new nsCSS##data(); \ } \ if (nsnull == mImportant->m##data) { \ result = NS_ERROR_OUT_OF_MEMORY; \ } \ else #define CSS_CASE_IMPORTANT(prop,data) \ case prop: mImportant->data = data; data.Reset(); break nsresult CSSDeclarationImpl::SetValueImportant(PRInt32 aProperty) { nsresult result = NS_OK; if (nsnull == mImportant) { mImportant = new CSSDeclarationImpl(); if (nsnull != mImportant) { NS_ADDREF(mImportant); } else { result = NS_ERROR_OUT_OF_MEMORY; } } if (NS_OK == result) { switch (aProperty) { // nsCSSFont case PROP_FONT_FAMILY: case PROP_FONT_STYLE: case PROP_FONT_VARIANT: case PROP_FONT_WEIGHT: case PROP_FONT_SIZE: case PROP_FONT_SIZE_ADJUST: case PROP_FONT_STRETCH: if (nsnull != mFont) { CSS_ENSURE_IMPORTANT(Font) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_FONT_FAMILY, mFont->mFamily); CSS_CASE_IMPORTANT(PROP_FONT_STYLE, mFont->mStyle); CSS_CASE_IMPORTANT(PROP_FONT_VARIANT, mFont->mVariant); CSS_CASE_IMPORTANT(PROP_FONT_WEIGHT, mFont->mWeight); CSS_CASE_IMPORTANT(PROP_FONT_SIZE, mFont->mSize); CSS_CASE_IMPORTANT(PROP_FONT_SIZE_ADJUST, mFont->mSizeAdjust); CSS_CASE_IMPORTANT(PROP_FONT_STRETCH, mFont->mStretch); } } } 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: case PROP_CURSOR: case PROP_CURSOR_IMAGE: case PROP_OPACITY: if (nsnull != mColor) { CSS_ENSURE_IMPORTANT(Color) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_COLOR, mColor->mColor); CSS_CASE_IMPORTANT(PROP_BACKGROUND_COLOR, mColor->mBackColor); CSS_CASE_IMPORTANT(PROP_BACKGROUND_IMAGE, mColor->mBackImage); CSS_CASE_IMPORTANT(PROP_BACKGROUND_REPEAT, mColor->mBackRepeat); CSS_CASE_IMPORTANT(PROP_BACKGROUND_ATTACHMENT, mColor->mBackAttachment); CSS_CASE_IMPORTANT(PROP_BACKGROUND_X_POSITION, mColor->mBackPositionX); CSS_CASE_IMPORTANT(PROP_BACKGROUND_Y_POSITION, mColor->mBackPositionY); CSS_CASE_IMPORTANT(PROP_BACKGROUND_FILTER, mColor->mBackFilter); CSS_CASE_IMPORTANT(PROP_CURSOR, mColor->mCursor); CSS_CASE_IMPORTANT(PROP_CURSOR_IMAGE, mColor->mCursorImage); CSS_CASE_IMPORTANT(PROP_OPACITY, mColor->mOpacity); } } } 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_UNICODE_BIDI: case PROP_LINE_HEIGHT: case PROP_WHITE_SPACE: if (nsnull != mText) { CSS_ENSURE_IMPORTANT(Text) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_WORD_SPACING, mText->mWordSpacing); CSS_CASE_IMPORTANT(PROP_LETTER_SPACING, mText->mLetterSpacing); CSS_CASE_IMPORTANT(PROP_TEXT_DECORATION, mText->mDecoration); CSS_CASE_IMPORTANT(PROP_VERTICAL_ALIGN, mText->mVerticalAlign); CSS_CASE_IMPORTANT(PROP_TEXT_TRANSFORM, mText->mTextTransform); CSS_CASE_IMPORTANT(PROP_TEXT_ALIGN, mText->mTextAlign); CSS_CASE_IMPORTANT(PROP_TEXT_INDENT, mText->mTextIndent); CSS_CASE_IMPORTANT(PROP_UNICODE_BIDI, mText->mUnicodeBidi); CSS_CASE_IMPORTANT(PROP_LINE_HEIGHT, mText->mLineHeight); CSS_CASE_IMPORTANT(PROP_WHITE_SPACE, mText->mWhiteSpace); } } } break; case PROP_TEXT_SHADOW: if (nsnull != mText) { if (nsnull != mText->mTextShadow) { CSS_ENSURE_IMPORTANT(Text) { if (nsnull != mImportant->mText->mTextShadow) { delete mImportant->mText->mTextShadow; } mImportant->mText->mTextShadow = mText->mTextShadow; mText->mTextShadow = nsnull; } } } break; // nsCSSDisplay case PROP_DIRECTION: case PROP_DISPLAY: case PROP_FLOAT: case PROP_CLEAR: case PROP_OVERFLOW: case PROP_VISIBILITY: case PROP_FILTER: if (nsnull != mDisplay) { CSS_ENSURE_IMPORTANT(Display) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_DIRECTION, mDisplay->mDirection); CSS_CASE_IMPORTANT(PROP_DISPLAY, mDisplay->mDisplay); CSS_CASE_IMPORTANT(PROP_FLOAT, mDisplay->mFloat); CSS_CASE_IMPORTANT(PROP_CLEAR, mDisplay->mClear); CSS_CASE_IMPORTANT(PROP_OVERFLOW, mDisplay->mOverflow); CSS_CASE_IMPORTANT(PROP_VISIBILITY, mDisplay->mVisibility); CSS_CASE_IMPORTANT(PROP_FILTER, mDisplay->mFilter); } } } break; case PROP_CLIP_TOP: case PROP_CLIP_RIGHT: case PROP_CLIP_BOTTOM: case PROP_CLIP_LEFT: if (nsnull != mDisplay) { if (nsnull != mDisplay->mClip) { CSS_ENSURE_IMPORTANT(Display) { CSS_ENSURE_RECT(mImportant->mDisplay->mClip) { switch(aProperty) { CSS_CASE_IMPORTANT(PROP_CLIP_TOP, mDisplay->mClip->mTop); CSS_CASE_IMPORTANT(PROP_CLIP_RIGHT, mDisplay->mClip->mRight); CSS_CASE_IMPORTANT(PROP_CLIP_BOTTOM, mDisplay->mClip->mBottom); CSS_CASE_IMPORTANT(PROP_CLIP_LEFT, mDisplay->mClip->mLeft); } } } } } break; // nsCSSMargin case PROP_MARGIN_TOP: case PROP_MARGIN_RIGHT: case PROP_MARGIN_BOTTOM: case PROP_MARGIN_LEFT: if (nsnull != mMargin) { if (nsnull != mMargin->mMargin) { CSS_ENSURE_IMPORTANT(Margin) { CSS_ENSURE_RECT(mImportant->mMargin->mMargin) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_MARGIN_TOP, mMargin->mMargin->mTop); CSS_CASE_IMPORTANT(PROP_MARGIN_RIGHT, mMargin->mMargin->mRight); CSS_CASE_IMPORTANT(PROP_MARGIN_BOTTOM, mMargin->mMargin->mBottom); CSS_CASE_IMPORTANT(PROP_MARGIN_LEFT, mMargin->mMargin->mLeft); } } } } } break; case PROP_PADDING_TOP: case PROP_PADDING_RIGHT: case PROP_PADDING_BOTTOM: case PROP_PADDING_LEFT: if (nsnull != mMargin) { if (nsnull != mMargin->mPadding) { CSS_ENSURE_IMPORTANT(Margin) { CSS_ENSURE_RECT(mImportant->mMargin->mPadding) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_PADDING_TOP, mMargin->mPadding->mTop); CSS_CASE_IMPORTANT(PROP_PADDING_RIGHT, mMargin->mPadding->mRight); CSS_CASE_IMPORTANT(PROP_PADDING_BOTTOM, mMargin->mPadding->mBottom); CSS_CASE_IMPORTANT(PROP_PADDING_LEFT, mMargin->mPadding->mLeft); } } } } } break; case PROP_BORDER_TOP_WIDTH: case PROP_BORDER_RIGHT_WIDTH: case PROP_BORDER_BOTTOM_WIDTH: case PROP_BORDER_LEFT_WIDTH: if (nsnull != mMargin) { if (nsnull != mMargin->mBorderWidth) { CSS_ENSURE_IMPORTANT(Margin) { CSS_ENSURE_RECT(mImportant->mMargin->mBorderWidth) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_BORDER_TOP_WIDTH, mMargin->mBorderWidth->mTop); CSS_CASE_IMPORTANT(PROP_BORDER_RIGHT_WIDTH, mMargin->mBorderWidth->mRight); CSS_CASE_IMPORTANT(PROP_BORDER_BOTTOM_WIDTH, mMargin->mBorderWidth->mBottom); CSS_CASE_IMPORTANT(PROP_BORDER_LEFT_WIDTH, mMargin->mBorderWidth->mLeft); } } } } } break; case PROP_BORDER_TOP_COLOR: case PROP_BORDER_RIGHT_COLOR: case PROP_BORDER_BOTTOM_COLOR: case PROP_BORDER_LEFT_COLOR: if (nsnull != mMargin) { if (nsnull != mMargin->mBorderColor) { CSS_ENSURE_IMPORTANT(Margin) { CSS_ENSURE_RECT(mImportant->mMargin->mBorderColor) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_BORDER_TOP_COLOR, mMargin->mBorderColor->mTop); CSS_CASE_IMPORTANT(PROP_BORDER_RIGHT_COLOR, mMargin->mBorderColor->mRight); CSS_CASE_IMPORTANT(PROP_BORDER_BOTTOM_COLOR, mMargin->mBorderColor->mBottom); CSS_CASE_IMPORTANT(PROP_BORDER_LEFT_COLOR, mMargin->mBorderColor->mLeft); } } } } } break; case PROP_BORDER_TOP_STYLE: case PROP_BORDER_RIGHT_STYLE: case PROP_BORDER_BOTTOM_STYLE: case PROP_BORDER_LEFT_STYLE: if (nsnull != mMargin) { if (nsnull != mMargin->mBorderStyle) { CSS_ENSURE_IMPORTANT(Margin) { CSS_ENSURE_RECT(mImportant->mMargin->mBorderStyle) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_BORDER_TOP_STYLE, mMargin->mBorderStyle->mTop); CSS_CASE_IMPORTANT(PROP_BORDER_RIGHT_STYLE, mMargin->mBorderStyle->mRight); CSS_CASE_IMPORTANT(PROP_BORDER_BOTTOM_STYLE, mMargin->mBorderStyle->mBottom); CSS_CASE_IMPORTANT(PROP_BORDER_LEFT_STYLE, mMargin->mBorderStyle->mLeft); } } } } } break; case PROP_OUTLINE_WIDTH: case PROP_OUTLINE_COLOR: case PROP_OUTLINE_STYLE: if (nsnull != mMargin) { CSS_ENSURE_IMPORTANT(Margin) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_OUTLINE_WIDTH, mMargin->mOutlineWidth); CSS_CASE_IMPORTANT(PROP_OUTLINE_COLOR, mMargin->mOutlineColor); CSS_CASE_IMPORTANT(PROP_OUTLINE_STYLE, mMargin->mOutlineStyle); } } } break; // nsCSSPosition case PROP_POSITION: case PROP_WIDTH: case PROP_MIN_WIDTH: case PROP_MAX_WIDTH: case PROP_HEIGHT: case PROP_MIN_HEIGHT: case PROP_MAX_HEIGHT: case PROP_Z_INDEX: if (nsnull != mPosition) { CSS_ENSURE_IMPORTANT(Position) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_POSITION, mPosition->mPosition); CSS_CASE_IMPORTANT(PROP_WIDTH, mPosition->mWidth); CSS_CASE_IMPORTANT(PROP_MIN_WIDTH, mPosition->mMinWidth); CSS_CASE_IMPORTANT(PROP_MAX_WIDTH, mPosition->mMaxWidth); CSS_CASE_IMPORTANT(PROP_HEIGHT, mPosition->mHeight); CSS_CASE_IMPORTANT(PROP_MIN_HEIGHT, mPosition->mMinHeight); CSS_CASE_IMPORTANT(PROP_MAX_HEIGHT, mPosition->mMaxHeight); CSS_CASE_IMPORTANT(PROP_Z_INDEX, mPosition->mZIndex); } } } break; case PROP_TOP: case PROP_RIGHT: case PROP_BOTTOM: case PROP_LEFT: if (nsnull != mPosition) { if (nsnull != mPosition->mOffset) { CSS_ENSURE_IMPORTANT(Position) { CSS_ENSURE_RECT(mImportant->mPosition->mOffset) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_TOP, mPosition->mOffset->mTop); CSS_CASE_IMPORTANT(PROP_RIGHT, mPosition->mOffset->mRight); CSS_CASE_IMPORTANT(PROP_BOTTOM, mPosition->mOffset->mBottom); CSS_CASE_IMPORTANT(PROP_LEFT, mPosition->mOffset->mLeft); } } } } } break; // nsCSSList case PROP_LIST_STYLE_TYPE: case PROP_LIST_STYLE_IMAGE: case PROP_LIST_STYLE_POSITION: if (nsnull != mList) { CSS_ENSURE_IMPORTANT(List) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_LIST_STYLE_TYPE, mList->mType); CSS_CASE_IMPORTANT(PROP_LIST_STYLE_IMAGE, mList->mImage); CSS_CASE_IMPORTANT(PROP_LIST_STYLE_POSITION, mList->mPosition); } } } break; // nsCSSTable case PROP_BORDER_COLLAPSE: case PROP_BORDER_SPACING: case PROP_CAPTION_SIDE: case PROP_EMPTY_CELLS: case PROP_TABLE_LAYOUT: if (nsnull != mTable) { CSS_ENSURE_IMPORTANT(Table) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_BORDER_COLLAPSE, mTable->mBorderCollapse); CSS_CASE_IMPORTANT(PROP_BORDER_SPACING, mTable->mBorderSpacing); CSS_CASE_IMPORTANT(PROP_CAPTION_SIDE, mTable->mCaptionSide); CSS_CASE_IMPORTANT(PROP_EMPTY_CELLS, mTable->mEmptyCells); CSS_CASE_IMPORTANT(PROP_TABLE_LAYOUT, mTable->mLayout); } } } break; // nsCSSBreaks case PROP_ORPHANS: case PROP_WIDOWS: case PROP_PAGE: case PROP_PAGE_BREAK_AFTER: case PROP_PAGE_BREAK_BEFORE: case PROP_PAGE_BREAK_INSIDE: if (nsnull != mBreaks) { CSS_ENSURE_IMPORTANT(Breaks) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_ORPHANS, mBreaks->mOrphans); CSS_CASE_IMPORTANT(PROP_WIDOWS, mBreaks->mWidows); CSS_CASE_IMPORTANT(PROP_PAGE, mBreaks->mPage); CSS_CASE_IMPORTANT(PROP_PAGE_BREAK_AFTER, mBreaks->mPageBreakAfter); CSS_CASE_IMPORTANT(PROP_PAGE_BREAK_BEFORE, mBreaks->mPageBreakBefore); CSS_CASE_IMPORTANT(PROP_PAGE_BREAK_INSIDE, mBreaks->mPageBreakInside); } } } break; // nsCSSPage case PROP_MARKS: case PROP_SIZE: if (nsnull != mPage) { CSS_ENSURE_IMPORTANT(Page) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_MARKS, mPage->mMarks); CSS_CASE_IMPORTANT(PROP_SIZE, mPage->mSize); } } } break; // nsCSSContent case PROP_CONTENT: case PROP_COUNTER_INCREMENT: case PROP_COUNTER_RESET: case PROP_MARKER_OFFSET: case PROP_QUOTES: if (nsnull != mContent) { CSS_ENSURE_IMPORTANT(Content) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_CONTENT, mContent->mContent); CSS_CASE_IMPORTANT(PROP_COUNTER_INCREMENT, mContent->mCounterIncrement); CSS_CASE_IMPORTANT(PROP_COUNTER_RESET, mContent->mCounterReset); CSS_CASE_IMPORTANT(PROP_MARKER_OFFSET, mContent->mMarkerOffset); CSS_CASE_IMPORTANT(PROP_QUOTES, mContent->mQuotes); } } } break; // nsCSSAural case PROP_AZIMUTH: case PROP_ELEVATION: case PROP_CUE_AFTER: case PROP_CUE_BEFORE: case PROP_PAUSE_AFTER: case PROP_PAUSE_BEFORE: case PROP_PITCH: case PROP_PITCH_RANGE: case PROP_PLAY_DURING: case PROP_RICHNESS: case PROP_SPEAK: case PROP_SPEAK_HEADER: case PROP_SPEAK_NUMERAL: case PROP_SPEAK_PUNCTUATION: case PROP_SPEECH_RATE: case PROP_STRESS: case PROP_VOICE_FAMILY: case PROP_VOLUME: if (nsnull != mAural) { CSS_ENSURE_IMPORTANT(Aural) { switch (aProperty) { CSS_CASE_IMPORTANT(PROP_AZIMUTH, mAural->mAzimuth); CSS_CASE_IMPORTANT(PROP_ELEVATION, mAural->mElevation); CSS_CASE_IMPORTANT(PROP_CUE_AFTER, mAural->mCueAfter); CSS_CASE_IMPORTANT(PROP_CUE_BEFORE, mAural->mCueBefore); CSS_CASE_IMPORTANT(PROP_PAUSE_AFTER, mAural->mPauseAfter); CSS_CASE_IMPORTANT(PROP_PAUSE_BEFORE, mAural->mPauseBefore); CSS_CASE_IMPORTANT(PROP_PITCH, mAural->mPitch); CSS_CASE_IMPORTANT(PROP_PITCH_RANGE, mAural->mPitchRange); CSS_CASE_IMPORTANT(PROP_PLAY_DURING, mAural->mPlayDuring); CSS_CASE_IMPORTANT(PROP_RICHNESS, mAural->mRichness); CSS_CASE_IMPORTANT(PROP_SPEAK, mAural->mSpeak); CSS_CASE_IMPORTANT(PROP_SPEAK_HEADER, mAural->mSpeakHeader); CSS_CASE_IMPORTANT(PROP_SPEAK_NUMERAL, mAural->mSpeakNumeral); CSS_CASE_IMPORTANT(PROP_SPEAK_PUNCTUATION, mAural->mSpeakPunctuation); CSS_CASE_IMPORTANT(PROP_SPEECH_RATE, mAural->mSpeechRate); CSS_CASE_IMPORTANT(PROP_STRESS, mAural->mStress); CSS_CASE_IMPORTANT(PROP_VOICE_FAMILY, mAural->mVoiceFamily); CSS_CASE_IMPORTANT(PROP_VOLUME, mAural->mVolume); } } } break; // Shorthands case PROP_BACKGROUND: SetValueImportant(PROP_BACKGROUND_COLOR); SetValueImportant(PROP_BACKGROUND_IMAGE); SetValueImportant(PROP_BACKGROUND_REPEAT); SetValueImportant(PROP_BACKGROUND_ATTACHMENT); SetValueImportant(PROP_BACKGROUND_X_POSITION); SetValueImportant(PROP_BACKGROUND_Y_POSITION); SetValueImportant(PROP_BACKGROUND_FILTER); break; case PROP_BORDER: SetValueImportant(PROP_BORDER_TOP_WIDTH); SetValueImportant(PROP_BORDER_RIGHT_WIDTH); SetValueImportant(PROP_BORDER_BOTTOM_WIDTH); SetValueImportant(PROP_BORDER_LEFT_WIDTH); SetValueImportant(PROP_BORDER_TOP_STYLE); SetValueImportant(PROP_BORDER_RIGHT_STYLE); SetValueImportant(PROP_BORDER_BOTTOM_STYLE); SetValueImportant(PROP_BORDER_LEFT_STYLE); SetValueImportant(PROP_BORDER_TOP_COLOR); SetValueImportant(PROP_BORDER_RIGHT_COLOR); SetValueImportant(PROP_BORDER_BOTTOM_COLOR); SetValueImportant(PROP_BORDER_LEFT_COLOR); break; case PROP_CLIP: SetValueImportant(PROP_CLIP_TOP); SetValueImportant(PROP_CLIP_RIGHT); SetValueImportant(PROP_CLIP_BOTTOM); SetValueImportant(PROP_CLIP_LEFT); break; case PROP_CUE: SetValueImportant(PROP_CUE_AFTER); SetValueImportant(PROP_CUE_BEFORE); break; case PROP_FONT: SetValueImportant(PROP_FONT_FAMILY); SetValueImportant(PROP_FONT_STYLE); SetValueImportant(PROP_FONT_VARIANT); SetValueImportant(PROP_FONT_WEIGHT); SetValueImportant(PROP_FONT_SIZE); SetValueImportant(PROP_LINE_HEIGHT); break; case PROP_LIST_STYLE: SetValueImportant(PROP_LIST_STYLE_TYPE); SetValueImportant(PROP_LIST_STYLE_IMAGE); SetValueImportant(PROP_LIST_STYLE_POSITION); break; case PROP_MARGIN: SetValueImportant(PROP_MARGIN_TOP); SetValueImportant(PROP_MARGIN_RIGHT); SetValueImportant(PROP_MARGIN_BOTTOM); SetValueImportant(PROP_MARGIN_LEFT); break; case PROP_OUTLINE: SetValueImportant(PROP_OUTLINE_COLOR); SetValueImportant(PROP_OUTLINE_STYLE); SetValueImportant(PROP_OUTLINE_WIDTH); break; case PROP_PADDING: SetValueImportant(PROP_PADDING_TOP); SetValueImportant(PROP_PADDING_RIGHT); SetValueImportant(PROP_PADDING_BOTTOM); SetValueImportant(PROP_PADDING_LEFT); break; case PROP_PAUSE: SetValueImportant(PROP_PAUSE_AFTER); SetValueImportant(PROP_PAUSE_BEFORE); break; case PROP_BACKGROUND_POSITION: SetValueImportant(PROP_BACKGROUND_X_POSITION); SetValueImportant(PROP_BACKGROUND_Y_POSITION); break; case PROP_BORDER_TOP: SetValueImportant(PROP_BORDER_TOP_WIDTH); SetValueImportant(PROP_BORDER_TOP_STYLE); SetValueImportant(PROP_BORDER_TOP_COLOR); break; case PROP_BORDER_RIGHT: SetValueImportant(PROP_BORDER_RIGHT_WIDTH); SetValueImportant(PROP_BORDER_RIGHT_STYLE); SetValueImportant(PROP_BORDER_RIGHT_COLOR); break; case PROP_BORDER_BOTTOM: SetValueImportant(PROP_BORDER_BOTTOM_WIDTH); SetValueImportant(PROP_BORDER_BOTTOM_STYLE); SetValueImportant(PROP_BORDER_BOTTOM_COLOR); break; case PROP_BORDER_LEFT: SetValueImportant(PROP_BORDER_LEFT_WIDTH); SetValueImportant(PROP_BORDER_LEFT_STYLE); SetValueImportant(PROP_BORDER_LEFT_COLOR); break; case PROP_BORDER_COLOR: SetValueImportant(PROP_BORDER_TOP_COLOR); SetValueImportant(PROP_BORDER_RIGHT_COLOR); SetValueImportant(PROP_BORDER_BOTTOM_COLOR); SetValueImportant(PROP_BORDER_LEFT_COLOR); break; case PROP_BORDER_STYLE: SetValueImportant(PROP_BORDER_TOP_STYLE); SetValueImportant(PROP_BORDER_RIGHT_STYLE); SetValueImportant(PROP_BORDER_BOTTOM_STYLE); SetValueImportant(PROP_BORDER_LEFT_STYLE); break; case PROP_BORDER_WIDTH: SetValueImportant(PROP_BORDER_TOP_WIDTH); SetValueImportant(PROP_BORDER_RIGHT_WIDTH); SetValueImportant(PROP_BORDER_BOTTOM_WIDTH); SetValueImportant(PROP_BORDER_LEFT_WIDTH); break; default: result = NS_ERROR_ILLEGAL_VALUE; break; } } return result; } nsresult CSSDeclarationImpl::AppendComment(const nsString& aComment) { nsresult result = NS_ERROR_OUT_OF_MEMORY; if (nsnull == mOrder) { mOrder = new nsVoidArray(); } if (nsnull == mComments) { mComments = new nsVoidArray(); } if ((nsnull != mComments) && (nsnull != mOrder)) { mComments->AppendElement(new nsString(aComment)); mOrder->AppendElement((void*)-mComments->Count()); result = NS_OK; } 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: case PROP_FONT_SIZE_ADJUST: case PROP_FONT_STRETCH: 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; case PROP_FONT_SIZE_ADJUST: aValue = mFont->mSizeAdjust; break; case PROP_FONT_STRETCH: aValue = mFont->mStretch; 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: case PROP_CURSOR: case PROP_CURSOR_IMAGE: case PROP_OPACITY: 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; case PROP_CURSOR: aValue = mColor->mCursor; break; case PROP_CURSOR_IMAGE: aValue = mColor->mCursorImage; break; case PROP_OPACITY: aValue = mColor->mOpacity; 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_UNICODE_BIDI: 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->mVerticalAlign; break; case PROP_TEXT_TRANSFORM: aValue = mText->mTextTransform; break; case PROP_TEXT_ALIGN: aValue = mText->mTextAlign; break; case PROP_TEXT_INDENT: aValue = mText->mTextIndent; break; case PROP_UNICODE_BIDI: aValue = mText->mUnicodeBidi; break; case PROP_LINE_HEIGHT: aValue = mText->mLineHeight; break; case PROP_WHITE_SPACE: aValue = mText->mWhiteSpace; break; } } else { aValue.Reset(); } break; case PROP_TEXT_SHADOW_COLOR: case PROP_TEXT_SHADOW_X: case PROP_TEXT_SHADOW_Y: case PROP_TEXT_SHADOW_RADIUS: if ((nsnull != mText) && (nsnull != mText->mTextShadow)) { switch (aProperty) { case PROP_TEXT_SHADOW_COLOR: aValue = mText->mTextShadow->mColor; break; case PROP_TEXT_SHADOW_X: aValue = mText->mTextShadow->mXOffset; break; case PROP_TEXT_SHADOW_Y: aValue = mText->mTextShadow->mYOffset; break; case PROP_TEXT_SHADOW_RADIUS: aValue = mText->mTextShadow->mRadius; break; } } break; // nsCSSDisplay case PROP_FLOAT: case PROP_CLEAR: case PROP_DISPLAY: case PROP_DIRECTION: case PROP_VISIBILITY: case PROP_OVERFLOW: case PROP_FILTER: if (nsnull != mDisplay) { switch (aProperty) { case PROP_FLOAT: aValue = mDisplay->mFloat; break; case PROP_CLEAR: aValue = mDisplay->mClear; break; case PROP_DISPLAY: aValue = mDisplay->mDisplay; break; case PROP_DIRECTION: aValue = mDisplay->mDirection; break; case PROP_VISIBILITY: aValue = mDisplay->mVisibility; break; case PROP_OVERFLOW: aValue = mDisplay->mOverflow; break; case PROP_FILTER: aValue = mDisplay->mFilter; break; } } else { aValue.Reset(); } break; case PROP_CLIP_TOP: case PROP_CLIP_RIGHT: case PROP_CLIP_BOTTOM: case PROP_CLIP_LEFT: if ((nsnull != mDisplay) && (nsnull != mDisplay->mClip)) { switch(aProperty) { case PROP_CLIP_TOP: aValue = mDisplay->mClip->mTop; break; case PROP_CLIP_RIGHT: aValue = mDisplay->mClip->mRight; break; case PROP_CLIP_BOTTOM: aValue = mDisplay->mClip->mBottom; break; case PROP_CLIP_LEFT: aValue = mDisplay->mClip->mLeft; 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->mBorderWidth)) { switch (aProperty) { case PROP_BORDER_TOP_WIDTH: aValue = mMargin->mBorderWidth->mTop; break; case PROP_BORDER_RIGHT_WIDTH: aValue = mMargin->mBorderWidth->mRight; break; case PROP_BORDER_BOTTOM_WIDTH: aValue = mMargin->mBorderWidth->mBottom; break; case PROP_BORDER_LEFT_WIDTH: aValue = mMargin->mBorderWidth->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->mBorderColor)) { switch (aProperty) { case PROP_BORDER_TOP_COLOR: aValue = mMargin->mBorderColor->mTop; break; case PROP_BORDER_RIGHT_COLOR: aValue = mMargin->mBorderColor->mRight; break; case PROP_BORDER_BOTTOM_COLOR: aValue = mMargin->mBorderColor->mBottom; break; case PROP_BORDER_LEFT_COLOR: aValue = mMargin->mBorderColor->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->mBorderStyle)) { switch (aProperty) { case PROP_BORDER_TOP_STYLE: aValue = mMargin->mBorderStyle->mTop; break; case PROP_BORDER_RIGHT_STYLE: aValue = mMargin->mBorderStyle->mRight; break; case PROP_BORDER_BOTTOM_STYLE: aValue = mMargin->mBorderStyle->mBottom; break; case PROP_BORDER_LEFT_STYLE: aValue = mMargin->mBorderStyle->mLeft; break; } } else { aValue.Reset(); } break; case PROP_OUTLINE_WIDTH: case PROP_OUTLINE_COLOR: case PROP_OUTLINE_STYLE: if (nsnull != mMargin) { switch (aProperty) { case PROP_OUTLINE_WIDTH: aValue = mMargin->mOutlineWidth; break; case PROP_OUTLINE_COLOR: aValue = mMargin->mOutlineColor; break; case PROP_OUTLINE_STYLE: aValue = mMargin->mOutlineStyle; break; } } else { aValue.Reset(); } break; // nsCSSPosition case PROP_POSITION: case PROP_WIDTH: case PROP_MIN_WIDTH: case PROP_MAX_WIDTH: case PROP_HEIGHT: case PROP_MIN_HEIGHT: case PROP_MAX_HEIGHT: case PROP_Z_INDEX: if (nsnull != mPosition) { switch (aProperty) { case PROP_POSITION: aValue = mPosition->mPosition; break; case PROP_WIDTH: aValue = mPosition->mWidth; break; case PROP_MIN_WIDTH: aValue = mPosition->mMinWidth; break; case PROP_MAX_WIDTH: aValue = mPosition->mMaxWidth; break; case PROP_HEIGHT: aValue = mPosition->mHeight; break; case PROP_MIN_HEIGHT: aValue = mPosition->mMinHeight; break; case PROP_MAX_HEIGHT: aValue = mPosition->mMaxHeight; break; case PROP_Z_INDEX: aValue = mPosition->mZIndex; break; } } else { aValue.Reset(); } break; case PROP_TOP: case PROP_RIGHT: case PROP_BOTTOM: case PROP_LEFT: if ((nsnull != mPosition) && (nsnull != mPosition->mOffset)) { switch (aProperty) { case PROP_TOP: aValue = mPosition->mOffset->mTop; break; case PROP_RIGHT: aValue = mPosition->mOffset->mRight; break; case PROP_BOTTOM: aValue = mPosition->mOffset->mBottom; break; case PROP_LEFT: aValue = mPosition->mOffset->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; // nsCSSTable case PROP_BORDER_COLLAPSE: case PROP_BORDER_SPACING: case PROP_CAPTION_SIDE: case PROP_EMPTY_CELLS: case PROP_TABLE_LAYOUT: if (nsnull != mTable) { switch (aProperty) { case PROP_BORDER_COLLAPSE: aValue = mTable->mBorderCollapse; break; case PROP_BORDER_SPACING: aValue = mTable->mBorderSpacing; break; case PROP_CAPTION_SIDE: aValue = mTable->mCaptionSide; break; case PROP_EMPTY_CELLS: aValue = mTable->mEmptyCells; break; case PROP_TABLE_LAYOUT: aValue = mTable->mLayout; break; } } else { aValue.Reset(); } break; // nsCSSBreaks case PROP_ORPHANS: case PROP_WIDOWS: case PROP_PAGE: case PROP_PAGE_BREAK_AFTER: case PROP_PAGE_BREAK_BEFORE: case PROP_PAGE_BREAK_INSIDE: if (nsnull != mBreaks) { switch (aProperty) { case PROP_ORPHANS: aValue = mBreaks->mOrphans; break; case PROP_WIDOWS: aValue = mBreaks->mWidows; break; case PROP_PAGE: aValue = mBreaks->mPage; break; case PROP_PAGE_BREAK_AFTER: aValue = mBreaks->mPageBreakAfter; break; case PROP_PAGE_BREAK_BEFORE: aValue = mBreaks->mPageBreakBefore; break; case PROP_PAGE_BREAK_INSIDE: aValue = mBreaks->mPageBreakInside; break; } } else { aValue.Reset(); } break; // nsCSSPage case PROP_MARKS: case PROP_SIZE: if (nsnull != mPage) { switch (aProperty) { case PROP_MARKS: aValue = mPage->mMarks; break; case PROP_SIZE: aValue = mPage->mSize; break; } } else { aValue.Reset(); } break; // nsCSSContent case PROP_CONTENT: case PROP_COUNTER_INCREMENT: case PROP_COUNTER_RESET: case PROP_MARKER_OFFSET: case PROP_QUOTES: if (nsnull != mContent) { switch (aProperty) { case PROP_CONTENT: aValue = mContent->mContent; break; case PROP_COUNTER_INCREMENT: aValue = mContent->mCounterIncrement; break; case PROP_COUNTER_RESET: aValue = mContent->mCounterReset; break; case PROP_MARKER_OFFSET: aValue = mContent->mMarkerOffset; break; case PROP_QUOTES: aValue = mContent->mQuotes; break; } } else { aValue.Reset(); } break; // nsCSSAural case PROP_AZIMUTH: case PROP_ELEVATION: case PROP_CUE_AFTER: case PROP_CUE_BEFORE: case PROP_PAUSE_AFTER: case PROP_PAUSE_BEFORE: case PROP_PITCH: case PROP_PITCH_RANGE: case PROP_PLAY_DURING: case PROP_RICHNESS: case PROP_SPEAK: case PROP_SPEAK_HEADER: case PROP_SPEAK_NUMERAL: case PROP_SPEAK_PUNCTUATION: case PROP_SPEECH_RATE: case PROP_STRESS: case PROP_VOICE_FAMILY: case PROP_VOLUME: if (nsnull != mAural) { switch (aProperty) { case PROP_AZIMUTH: aValue = mAural->mAzimuth; break; case PROP_ELEVATION: aValue = mAural->mElevation; break; case PROP_CUE_AFTER: aValue = mAural->mCueAfter; break; case PROP_CUE_BEFORE: aValue = mAural->mCueBefore; break; case PROP_PAUSE_AFTER: aValue = mAural->mPauseAfter; break; case PROP_PAUSE_BEFORE: aValue = mAural->mPauseBefore; break; case PROP_PITCH: aValue = mAural->mPitch; break; case PROP_PITCH_RANGE: aValue = mAural->mPitchRange; break; case PROP_PLAY_DURING: aValue = mAural->mPlayDuring; break; case PROP_RICHNESS: aValue = mAural->mRichness; break; case PROP_SPEAK: aValue = mAural->mSpeak; break; case PROP_SPEAK_HEADER: aValue = mAural->mSpeakHeader; break; case PROP_SPEAK_NUMERAL: aValue = mAural->mSpeakNumeral; break; case PROP_SPEAK_PUNCTUATION: aValue = mAural->mSpeakPunctuation; break; case PROP_SPEECH_RATE: aValue = mAural->mSpeechRate; break; case PROP_STRESS: aValue = mAural->mStress; break; case PROP_VOICE_FAMILY: aValue = mAural->mVoiceFamily; break; case PROP_VOLUME: aValue = mAural->mVolume; break; } } else { aValue.Reset(); } break; // Shorthands case PROP_BACKGROUND: case PROP_BORDER: case PROP_CLIP: case PROP_CUE: case PROP_FONT: case PROP_LIST_STYLE: case PROP_MARGIN: case PROP_OUTLINE: case PROP_PADDING: case PROP_PAUSE: case PROP_TEXT_SHADOW: 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; } // XXX shouldn't this get moved to color code? static const char* RGBToCSSString(nscolor aColor) { const char* result = nsnull; PRInt32 r = NS_GET_R(aColor); PRInt32 g = NS_GET_G(aColor); PRInt32 b = NS_GET_B(aColor); PRInt32 index = 0; PRInt32 count = sizeof(css_rgb_table)/sizeof(CSSColorEntry); CSSColorEntry* entry = nsnull; for (index = 0; index < count; index++) { entry = &css_rgb_table[index]; if (entry->r == r) { if (entry->g == g && entry->b == b) { result = entry->name; break; } } else if (entry->r > r) { break; } } return result; } nsresult CSSDeclarationImpl::GetValue(const nsString& aProperty, nsString& aValue) { char prop[50]; aProperty.ToCString(prop, sizeof(prop)); PRInt32 propID = nsCSSProps::LookupName(prop); return GetValue(propID, aValue); } PRBool CSSDeclarationImpl::AppendValueToString(PRInt32 aProperty, nsString& aResult) { nsCSSValue value; GetValue(aProperty, value); return AppendValueToString(aProperty, value, aResult); } PRBool CSSDeclarationImpl::AppendValueToString(PRInt32 aProperty, const nsCSSValue& aValue, nsString& aResult) { nsCSSUnit unit = aValue.GetUnit(); if (eCSSUnit_Null == unit) { return PR_FALSE; } if (eCSSUnit_String == unit) { nsAutoString buffer; aValue.GetStringValue(buffer); aResult.Append(buffer); } else if (eCSSUnit_Integer == unit) { aResult.Append(aValue.GetIntValue(), 10); } else if (eCSSUnit_Enumerated == unit) { if (PROP_TEXT_DECORATION == aProperty) { PRInt32 intValue = aValue.GetIntValue(); if (NS_STYLE_TEXT_DECORATION_NONE != intValue) { PRInt32 mask; for (mask = NS_STYLE_TEXT_DECORATION_UNDERLINE; mask <= NS_STYLE_TEXT_DECORATION_BLINK; mask <<= 1) { if ((mask & intValue) == mask) { aResult.Append(nsCSSProps::LookupProperty(aProperty, mask)); intValue &= ~mask; if (0 != intValue) { // more left aResult.Append(' '); } } } } else { aResult.Append(nsCSSProps::LookupProperty(aProperty, NS_STYLE_TEXT_DECORATION_NONE)); } } else { const char* name = nsCSSProps::LookupProperty(aProperty, aValue.GetIntValue()); if (name != nsnull) { aResult.Append(name); } } } else if (eCSSUnit_Color == unit){ nscolor color = aValue.GetColorValue(); const char* name = RGBToCSSString(color); if (name != nsnull) aResult.Append(name); else { aResult.Append("rgb("); aResult.Append(NS_GET_R(color), 10); aResult.Append(","); aResult.Append(NS_GET_G(color), 10); aResult.Append(","); aResult.Append(NS_GET_B(color), 10); aResult.Append(')'); } } else if (eCSSUnit_Percent == unit) { aResult.Append(aValue.GetPercentValue() * 100.0f); } else if (eCSSUnit_Percent < unit) { // length unit aResult.Append(aValue.GetFloatValue()); } switch (unit) { case eCSSUnit_Null: break; case eCSSUnit_Auto: aResult.Append("auto"); break; case eCSSUnit_Inherit: aResult.Append("inherit"); break; case eCSSUnit_None: aResult.Append("none"); break; case eCSSUnit_Normal: aResult.Append("normal"); break; case eCSSUnit_String: break; case eCSSUnit_Integer: break; case eCSSUnit_Enumerated: break; case eCSSUnit_Color: break; case eCSSUnit_Percent: aResult.Append("%"); break; case eCSSUnit_Number: break; case eCSSUnit_Inch: aResult.Append("in"); break; case eCSSUnit_Foot: aResult.Append("ft"); break; case eCSSUnit_Mile: aResult.Append("mi"); break; case eCSSUnit_Millimeter: aResult.Append("mm"); break; case eCSSUnit_Centimeter: aResult.Append("cm"); break; case eCSSUnit_Meter: aResult.Append("m"); break; case eCSSUnit_Kilometer: aResult.Append("km"); break; case eCSSUnit_Point: aResult.Append("pt"); break; case eCSSUnit_Pica: aResult.Append("pc"); break; case eCSSUnit_Didot: aResult.Append("dt"); break; case eCSSUnit_Cicero: aResult.Append("cc"); break; case eCSSUnit_EM: aResult.Append("em"); break; case eCSSUnit_EN: aResult.Append("en"); break; case eCSSUnit_XHeight: aResult.Append("ex"); break; case eCSSUnit_CapHeight: aResult.Append("cap"); break; case eCSSUnit_Pixel: aResult.Append("px"); break; } return PR_TRUE; } #define HAS_VALUE(strct,data) \ ((nsnull != strct) && (eCSSUnit_Null != strct->data.GetUnit())) #define HAS_RECT(strct,rect) \ ((nsnull != strct) && (nsnull != strct->rect) && \ (eCSSUnit_Null != strct->rect->mTop.GetUnit()) && \ (eCSSUnit_Null != strct->rect->mRight.GetUnit()) && \ (eCSSUnit_Null != strct->rect->mBottom.GetUnit()) && \ (eCSSUnit_Null != strct->rect->mLeft.GetUnit())) nsresult CSSDeclarationImpl::GetValue(PRInt32 aProperty, nsString& aValue) { aValue.Truncate(0); // shorthands switch (aProperty) { case PROP_BACKGROUND: if (AppendValueToString(PROP_BACKGROUND_COLOR, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_BACKGROUND_IMAGE, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_BACKGROUND_REPEAT, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_BACKGROUND_ATTACHMENT, aValue)) aValue.Append(' '); if (HAS_VALUE(mColor,mBackPositionX) && HAS_VALUE(mColor,mBackPositionY)) { AppendValueToString(PROP_BACKGROUND_X_POSITION, aValue); aValue.Append(' '); AppendValueToString(PROP_BACKGROUND_Y_POSITION, aValue); } break; case PROP_BORDER: if (AppendValueToString(PROP_BORDER_TOP_WIDTH, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_BORDER_TOP_STYLE, aValue)) aValue.Append(' '); AppendValueToString(PROP_BORDER_TOP_COLOR, aValue); break; case PROP_CLIP: if (HAS_RECT(mDisplay,mClip)) { aValue.Append("rect("); AppendValueToString(PROP_CLIP_TOP, aValue); aValue.Append(' '); AppendValueToString(PROP_CLIP_RIGHT, aValue); aValue.Append(' '); AppendValueToString(PROP_CLIP_BOTTOM, aValue); aValue.Append(' '); AppendValueToString(PROP_CLIP_LEFT, aValue); aValue.Append(")"); } break; case PROP_CUE: if (HAS_VALUE(mAural,mCueAfter) && HAS_VALUE(mAural,mCueBefore)) { AppendValueToString(PROP_CUE_AFTER, aValue); aValue.Append(' '); AppendValueToString(PROP_CUE_BEFORE, aValue); } break; case PROP_FONT: if (HAS_VALUE(mFont,mSize)) { if (AppendValueToString(PROP_FONT_STYLE, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_FONT_VARIANT, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_FONT_WEIGHT, aValue)) aValue.Append(' '); AppendValueToString(PROP_FONT_SIZE, aValue); if (HAS_VALUE(mText,mLineHeight)) { aValue.Append('/'); AppendValueToString(PROP_LINE_HEIGHT, aValue); } aValue.Append(' '); AppendValueToString(PROP_FONT_FAMILY, aValue); } break; case PROP_LIST_STYLE: if (AppendValueToString(PROP_LIST_STYLE_TYPE, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_LIST_STYLE_POSITION, aValue)) aValue.Append(' '); AppendValueToString(PROP_LIST_STYLE_IMAGE, aValue); break; case PROP_MARGIN: if (HAS_RECT(mMargin,mMargin)) { AppendValueToString(PROP_MARGIN_TOP, aValue); aValue.Append(' '); AppendValueToString(PROP_MARGIN_RIGHT, aValue); aValue.Append(' '); AppendValueToString(PROP_MARGIN_BOTTOM, aValue); aValue.Append(' '); AppendValueToString(PROP_MARGIN_LEFT, aValue); } break; case PROP_OUTLINE: if (AppendValueToString(PROP_OUTLINE_COLOR, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_OUTLINE_STYLE, aValue)) aValue.Append(' '); AppendValueToString(PROP_OUTLINE_WIDTH, aValue); break; case PROP_PADDING: if (HAS_RECT(mMargin,mPadding)) { AppendValueToString(PROP_PADDING_TOP, aValue); aValue.Append(' '); AppendValueToString(PROP_PADDING_RIGHT, aValue); aValue.Append(' '); AppendValueToString(PROP_PADDING_BOTTOM, aValue); aValue.Append(' '); AppendValueToString(PROP_PADDING_LEFT, aValue); } break; case PROP_PAUSE: if (HAS_VALUE(mAural,mPauseAfter) && HAS_VALUE(mAural,mPauseBefore)) { AppendValueToString(PROP_PAUSE_AFTER, aValue); aValue.Append(' '); AppendValueToString(PROP_PAUSE_BEFORE, aValue); } break; case PROP_TEXT_SHADOW: if ((nsnull != mText) && (nsnull != mText->mTextShadow)) { if (eCSSUnit_Color == mText->mTextShadow->mColor.GetUnit()) { nsCSSShadow* shadow = mText->mTextShadow; while (nsnull != shadow) { if (AppendValueToString(PROP_TEXT_SHADOW_COLOR, shadow->mColor, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_TEXT_SHADOW_X, shadow->mXOffset, aValue)) { aValue.Append(' '); AppendValueToString(PROP_TEXT_SHADOW_Y, shadow->mYOffset, aValue); aValue.Append(' '); } if (AppendValueToString(PROP_TEXT_SHADOW_RADIUS, shadow->mRadius, aValue)) aValue.Append(' '); shadow = shadow->mNext; } } else { // none or inherit AppendValueToString(PROP_TEXT_SHADOW_COLOR, aValue); } } break; case PROP_BACKGROUND_POSITION: if (HAS_VALUE(mColor,mBackPositionX) && HAS_VALUE(mColor,mBackPositionY)) { AppendValueToString(PROP_BACKGROUND_X_POSITION, aValue); aValue.Append(' '); AppendValueToString(PROP_BACKGROUND_Y_POSITION, aValue); } break; case PROP_BORDER_TOP: if (AppendValueToString(PROP_BORDER_TOP_WIDTH, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_BORDER_TOP_STYLE, aValue)) aValue.Append(' '); AppendValueToString(PROP_BORDER_TOP_COLOR, aValue); break; case PROP_BORDER_RIGHT: if (AppendValueToString(PROP_BORDER_RIGHT_WIDTH, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_BORDER_RIGHT_STYLE, aValue)) aValue.Append(' '); AppendValueToString(PROP_BORDER_RIGHT_COLOR, aValue); break; case PROP_BORDER_BOTTOM: if (AppendValueToString(PROP_BORDER_BOTTOM_WIDTH, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_BORDER_BOTTOM_STYLE, aValue)) aValue.Append(' '); AppendValueToString(PROP_BORDER_BOTTOM_COLOR, aValue); break; case PROP_BORDER_LEFT: if (AppendValueToString(PROP_BORDER_LEFT_WIDTH, aValue)) aValue.Append(' '); if (AppendValueToString(PROP_BORDER_LEFT_STYLE, aValue)) aValue.Append(' '); AppendValueToString(PROP_BORDER_LEFT_COLOR, aValue); break; case PROP_BORDER_COLOR: if (HAS_RECT(mMargin,mBorderColor)) { AppendValueToString(PROP_BORDER_TOP_COLOR, aValue); aValue.Append(' '); AppendValueToString(PROP_BORDER_RIGHT_COLOR, aValue); aValue.Append(' '); AppendValueToString(PROP_BORDER_BOTTOM_COLOR, aValue); aValue.Append(' '); AppendValueToString(PROP_BORDER_LEFT_COLOR, aValue); } break; case PROP_BORDER_STYLE: if (HAS_RECT(mMargin,mBorderStyle)) { AppendValueToString(PROP_BORDER_TOP_STYLE, aValue); aValue.Append(' '); AppendValueToString(PROP_BORDER_RIGHT_STYLE, aValue); aValue.Append(' '); AppendValueToString(PROP_BORDER_BOTTOM_STYLE, aValue); aValue.Append(' '); AppendValueToString(PROP_BORDER_LEFT_STYLE, aValue); } break; case PROP_BORDER_WIDTH: if (HAS_RECT(mMargin,mBorderWidth)) { AppendValueToString(PROP_BORDER_TOP_WIDTH, aValue); aValue.Append(' '); AppendValueToString(PROP_BORDER_RIGHT_WIDTH, aValue); aValue.Append(' '); AppendValueToString(PROP_BORDER_BOTTOM_WIDTH, aValue); aValue.Append(' '); AppendValueToString(PROP_BORDER_LEFT_WIDTH, aValue); } break; default: AppendValueToString(aProperty, aValue); break; } return NS_OK; } nsresult CSSDeclarationImpl::GetImportantValues(nsICSSDeclaration*& aResult) { if (nsnull != mImportant) { aResult = mImportant; NS_ADDREF(aResult); } else { aResult = nsnull; } return NS_OK; } nsresult CSSDeclarationImpl::GetValueIsImportant(const char *aProperty, PRBool& aIsImportant) { nsCSSValue val; if (nsnull != mImportant) { mImportant->GetValue(aProperty, val); if (eCSSUnit_Null != val.GetUnit()) { aIsImportant = PR_TRUE; } else { aIsImportant = PR_FALSE; } } else { aIsImportant = PR_FALSE; } return NS_OK; } nsresult CSSDeclarationImpl::ToString(nsString& aString) { if (nsnull != mOrder) { PRInt32 count = mOrder->Count(); PRInt32 index; for (index = 0; index < count; index++) { PRInt32 property = (PRInt32)mOrder->ElementAt(index); if (0 <= property) { aString.Append(nsCSSProps::kNameTable[property].name); aString.Append(": "); nsAutoString value; GetValue(property, value); aString.Append(value); if (index < count) { aString.Append("; "); } } else { // is comment aString.Append("/* "); nsString* comment = (nsString*)mComments->ElementAt((-1) - property); aString.Append(*comment); aString.Append(" */ "); } } } return NS_OK; } 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 != mDisplay) { mDisplay->List(out); } if (nsnull != mMargin) { mMargin->List(out); } if (nsnull != mPosition) { mPosition->List(out); } if (nsnull != mList) { mList->List(out); } if (nsnull != mTable) { mTable->List(out); } if (nsnull != mBreaks) { mBreaks->List(out); } if (nsnull != mPage) { mPage->List(out); } if (nsnull != mContent) { mContent->List(out); } if (nsnull != mAural) { mAural->List(out); } fputs("}", out); if (nsnull != mImportant) { fputs(" ! important ", out); mImportant->List(out, 0); } } nsresult CSSDeclarationImpl::Count(PRUint32* aCount) { if (nsnull != mOrder) { *aCount = (PRUint32)mOrder->Count(); } else { *aCount = 0; } return NS_OK; } nsresult CSSDeclarationImpl::GetNthProperty(PRUint32 aIndex, nsString& aReturn) { aReturn.SetLength(0); if (nsnull != mOrder) { PRInt32 property = (PRInt32)mOrder->ElementAt(aIndex); if (0 <= property) { aReturn.Append(nsCSSProps::kNameTable[property].name); } } return NS_OK; } NS_HTML nsresult NS_NewCSSDeclaration(nsICSSDeclaration** aInstancePtrResult) { if (aInstancePtrResult == nsnull) { return NS_ERROR_NULL_POINTER; } CSSDeclarationImpl *it; NS_NEWXPCOM(it, CSSDeclarationImpl); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } return it->QueryInterface(kICSSDeclarationIID, (void **) aInstancePtrResult); }