diff --git a/content/base/src/nsContentList.h b/content/base/src/nsContentList.h index cd4a280d889..be96ee119a9 100644 --- a/content/base/src/nsContentList.h +++ b/content/base/src/nsContentList.h @@ -93,6 +93,16 @@ public: NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled) { return NS_OK; } + NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) { return NS_OK; } + NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) { return NS_OK; } + NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) { return NS_OK; } NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument); protected: diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index cb8a76fc07c..d348c785e4f 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -123,6 +123,16 @@ public: NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled) { return NS_OK; } + NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) { return NS_OK; } + NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) { return NS_OK; } + NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) { return NS_OK; } NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument); // nsIScriptObjectOwner interface @@ -438,12 +448,7 @@ nsDocument::~nsDocument() index = mStyleSheets.Count(); while (--index >= 0) { nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(index); - nsICSSStyleSheet* css; - nsresult rv = sheet->QueryInterface(kICSSStyleSheetIID, (void **)&css); - if (NS_SUCCEEDED(rv)) { - css->SetDocument(nsnull); - NS_RELEASE(css); - } + sheet->SetOwningDocument(nsnull); NS_RELEASE(sheet); } @@ -541,12 +546,7 @@ nsDocument::StartDocumentLoad(nsIURL *aURL, PRInt32 index = mStyleSheets.Count(); while (--index >= 0) { nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(index); - nsICSSStyleSheet* css; - nsresult rv = sheet->QueryInterface(kICSSStyleSheetIID, (void **)&css); - if (NS_SUCCEEDED(rv)) { - css->SetDocument(nsnull); - NS_RELEASE(css); - } + sheet->SetOwningDocument(nsnull); NS_RELEASE(sheet); } mStyleSheets.Clear(); @@ -718,33 +718,34 @@ void nsDocument::AddStyleSheet(nsIStyleSheet* aSheet) NS_PRECONDITION(nsnull != aSheet, "null arg"); mStyleSheets.AppendElement(aSheet); NS_ADDREF(aSheet); - nsICSSStyleSheet* css; - nsresult rv = aSheet->QueryInterface(kICSSStyleSheetIID, (void **)&css); - if (NS_SUCCEEDED(rv)) { - css->SetDocument(this); - NS_RELEASE(css); - } + aSheet->SetOwningDocument(this); - PRInt32 count = mPresShells.Count(); - PRInt32 index; - for (index = 0; index < count; index++) { - nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(index); - nsIStyleSet* set = shell->GetStyleSet(); - if (nsnull != set) { - AddStyleSheetToSet(aSheet, set); - NS_RELEASE(set); + PRBool enabled = PR_TRUE; + aSheet->GetEnabled(enabled); + + if (enabled) { + PRInt32 count = mPresShells.Count(); + PRInt32 index; + for (index = 0; index < count; index++) { + nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(index); + nsIStyleSet* set = shell->GetStyleSet(); + if (nsnull != set) { + AddStyleSheetToSet(aSheet, set); + NS_RELEASE(set); + } } - } - count = mObservers.Count(); - for (index = 0; index < count; index++) { - nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index); - observer->StyleSheetAdded(this, aSheet); + // XXX should observers be notified for disabled sheets??? I think not, but I could be wrong + count = mObservers.Count(); + for (index = 0; index < count; index++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index); + observer->StyleSheetAdded(this, aSheet); + } } } void nsDocument::SetStyleSheetDisabledState(nsIStyleSheet* aSheet, - PRBool mDisabled) + PRBool aDisabled) { NS_PRECONDITION(nsnull != aSheet, "null arg"); PRInt32 count; @@ -757,7 +758,7 @@ void nsDocument::SetStyleSheetDisabledState(nsIStyleSheet* aSheet, nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(index); nsIStyleSet* set = shell->GetStyleSet(); if (nsnull != set) { - if (mDisabled) { + if (aDisabled) { set->RemoveDocStyleSheet(aSheet); } else { @@ -771,7 +772,7 @@ void nsDocument::SetStyleSheetDisabledState(nsIStyleSheet* aSheet, count = mObservers.Count(); for (index = 0; index < count; index++) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index); - observer->StyleSheetDisabledStateChanged(this, aSheet, mDisabled); + observer->StyleSheetDisabledStateChanged(this, aSheet, aDisabled); } } @@ -929,6 +930,42 @@ nsDocument::AttributeChanged(nsIContent* aChild, return NS_OK; } + +NS_IMETHODIMP +nsDocument::StyleRuleChanged(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule, + PRInt32 aHint) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->StyleRuleChanged(this, aStyleSheet, aStyleRule, aHint); + } + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::StyleRuleAdded(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->StyleRuleAdded(this, aStyleSheet, aStyleRule); + } + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::StyleRuleRemoved(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->StyleRuleRemoved(this, aStyleSheet, aStyleRule); + } + return NS_OK; +} + + nsresult nsDocument::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject) { nsresult res = NS_OK; diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index d901bc97458..666fb2c95c8 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -175,6 +175,14 @@ public: nsIContent* aChild, PRInt32 aIndexInContainer); + NS_IMETHOD StyleRuleChanged(nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint); // See nsStyleConsts fot hint values + NS_IMETHOD StyleRuleAdded(nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + NS_IMETHOD StyleRuleRemoved(nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + /** * Returns the Selection Object */ diff --git a/content/base/src/nsStyleSet.cpp b/content/base/src/nsStyleSet.cpp index 2a62721ab2e..0c370f78606 100644 --- a/content/base/src/nsStyleSet.cpp +++ b/content/base/src/nsStyleSet.cpp @@ -87,14 +87,14 @@ public: nsIStyleContext* aParentContext, PRBool aForceUnique = PR_FALSE); - NS_IMETHODIMP ConstructFrame(nsIPresContext* aPresContext, + NS_IMETHOD ConstructFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIFrame*& aFrameSubTree); + NS_IMETHOD ReconstructFrames(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParentFrame, - nsIFrame*& aFrameSubTree); - NS_IMETHOD ReconstructFrames(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsIFrame* aFrameSubTree); + nsIFrame* aFrameSubTree); NS_IMETHOD ContentAppended(nsIPresContext* aPresContext, nsIContent* aContainer, PRInt32 aNewIndexInContainer); @@ -122,6 +122,18 @@ public: // xxx style rules enumeration + // Style change notifications + NS_IMETHOD StyleRuleChanged(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint); // See nsStyleConsts fot hint values + NS_IMETHOD StyleRuleAdded(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + NS_IMETHOD StyleRuleRemoved(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + virtual void List(FILE* out = stdout, PRInt32 aIndent = 0); private: @@ -727,7 +739,31 @@ StyleSetImpl::AttributeChanged(nsIPresContext* aPresContext, } -// xxx style rules enumeration +// Style change notifications +NS_IMETHODIMP +StyleSetImpl::StyleRuleChanged(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) +{ + return mFrameConstructor->StyleRuleChanged(aPresContext, aStyleSheet, aStyleRule, aHint); +} + +NS_IMETHODIMP +StyleSetImpl::StyleRuleAdded(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + return mFrameConstructor->StyleRuleAdded(aPresContext, aStyleSheet, aStyleRule); +} + +NS_IMETHODIMP +StyleSetImpl::StyleRuleRemoved(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + return mFrameConstructor->StyleRuleRemoved(aPresContext, aStyleSheet, aStyleRule); +} void StyleSetImpl::List(FILE* out, PRInt32 aIndent, nsISupportsArray* aSheets) { diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index 065a5eed10c..01e3a0ac9bd 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -197,7 +197,7 @@ static nsresult EnsureWritableAttributes(nsIHTMLContent* aContent, nsMapAttributesFunc mapFunc; result = aContent->GetAttributeMappingFunction(mapFunc); if (NS_OK == result) { - result = NS_NewHTMLAttributes(&aAttributes, mapFunc); + result = NS_NewHTMLAttributes(&aAttributes, nsnull, mapFunc); if (NS_OK == result) { aAttributes->AddContentRef(); } @@ -366,6 +366,7 @@ nsGenericHTMLElement::SetDocument(nsIDocument* aDocument, PRBool aDeep) if ((nsnull != mDocument) && (nsnull != mAttributes)) { nsIHTMLStyleSheet* sheet = GetAttrStyleSheet(mDocument); if (nsnull != sheet) { + mAttributes->SetStyleSheet(sheet); sheet->SetAttributesFor(htmlContent, mAttributes); // sync attributes with sheet NS_RELEASE(sheet); } diff --git a/content/html/content/src/nsHTMLBodyElement.cpp b/content/html/content/src/nsHTMLBodyElement.cpp index 725b8b1075f..ac2ea44ac49 100644 --- a/content/html/content/src/nsHTMLBodyElement.cpp +++ b/content/html/content/src/nsHTMLBodyElement.cpp @@ -42,7 +42,73 @@ static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID); static NS_DEFINE_IID(kIDOMHTMLBodyElementIID, NS_IDOMHTMLBODYELEMENT_IID); static NS_DEFINE_IID(kIHTMLContentContainerIID, NS_IHTMLCONTENTCONTAINER_IID); -class BodyRule; +//---------------------------------------------------------------------- + +class nsHTMLBodyElement; + +class BodyRule: public nsIStyleRule { +public: + BodyRule(nsHTMLBodyElement* aPart, nsIHTMLStyleSheet* aSheet); + ~BodyRule(); + + NS_DECL_ISUPPORTS + + NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aResult) const; + NS_IMETHOD HashValue(PRUint32& aValue) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; + + // Strength is an out-of-band weighting, always 0 here + NS_IMETHOD GetStrength(PRInt32& aStrength); + + NS_IMETHOD MapStyleInto(nsIStyleContext* aContext, + nsIPresContext* aPresContext); + + NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + nsHTMLBodyElement* mPart; // not ref-counted, cleared by content + nsIHTMLStyleSheet* mSheet; // not ref-counted, cleared by content +}; + +//---------------------------------------------------------------------- + +// special subclass of inner class to override set document +class nsBodyInner: public nsGenericHTMLContainerElement +{ +public: + nsBodyInner(); + ~nsBodyInner(); + + nsresult SetDocument(nsIDocument* aDocument, PRBool aDeep); + + BodyRule* mStyleRule; +}; + +nsBodyInner::nsBodyInner() + : nsGenericHTMLContainerElement(), + mStyleRule(nsnull) +{ +} + +nsBodyInner::~nsBodyInner() +{ + if (nsnull != mStyleRule) { + mStyleRule->mPart = nsnull; + mStyleRule->mSheet = nsnull; + NS_RELEASE(mStyleRule); + } +} + +nsresult nsBodyInner::SetDocument(nsIDocument* aDocument, PRBool aDeep) +{ + if (nsnull != mStyleRule) { + mStyleRule->mPart = nsnull; + mStyleRule->mSheet = nsnull; + NS_RELEASE(mStyleRule); // destroy old style rule since the sheet will probably change + } + return nsGenericHTMLContainerElement::SetDocument(aDocument, aDeep); +} + +//---------------------------------------------------------------------- class nsHTMLBodyElement : public nsIDOMHTMLBodyElement, public nsIScriptObjectOwner, @@ -92,38 +158,19 @@ public: NS_IMPL_IHTMLCONTENT_USING_GENERIC2(mInner) protected: - nsGenericHTMLContainerElement mInner; - BodyRule* mStyleRule; + nsBodyInner mInner; friend BodyRule; }; -class BodyRule: public nsIStyleRule { -public: - BodyRule(nsHTMLBodyElement* aPart); - ~BodyRule(); - - NS_DECL_ISUPPORTS - - NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aResult) const; - NS_IMETHOD HashValue(PRUint32& aValue) const; - // Strength is an out-of-band weighting, always 0 here - NS_IMETHOD GetStrength(PRInt32& aStrength); - - NS_IMETHOD MapStyleInto(nsIStyleContext* aContext, - nsIPresContext* aPresContext); - - NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; - - nsHTMLBodyElement* mPart; -}; //---------------------------------------------------------------------- -BodyRule::BodyRule(nsHTMLBodyElement* aPart) +BodyRule::BodyRule(nsHTMLBodyElement* aPart, nsIHTMLStyleSheet* aSheet) { NS_INIT_REFCNT(); mPart = aPart; + mSheet = aSheet; } BodyRule::~BodyRule() @@ -146,6 +193,14 @@ BodyRule::HashValue(PRUint32& aValue) const return NS_OK; } +NS_IMETHODIMP +BodyRule::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, useful for mapping CSS ! important // always 0 here NS_IMETHODIMP @@ -244,7 +299,6 @@ NS_NewHTMLBodyElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag) } nsHTMLBodyElement::nsHTMLBodyElement(nsIAtom* aTag) - : mStyleRule(nsnull) { NS_INIT_REFCNT(); mInner.Init(this, aTag); @@ -252,10 +306,6 @@ nsHTMLBodyElement::nsHTMLBodyElement(nsIAtom* aTag) nsHTMLBodyElement::~nsHTMLBodyElement() { - if (nsnull != mStyleRule) { - mStyleRule->mPart = nsnull; - NS_RELEASE(mStyleRule); - } } NS_IMPL_ADDREF(nsHTMLBodyElement) @@ -454,14 +504,39 @@ nsHTMLBodyElement::HandleDOMEvent(nsIPresContext& aPresContext, aFlags, aEventStatus); } + +static nsIHTMLStyleSheet* GetAttrStyleSheet(nsIDocument* aDocument) +{ + nsIHTMLStyleSheet* sheet = nsnull; + nsIHTMLContentContainer* htmlContainer; + + if (nsnull != aDocument) { + if (NS_OK == aDocument->QueryInterface(kIHTMLContentContainerIID, (void**)&htmlContainer)) { + htmlContainer->GetAttributeStyleSheet(&sheet); + NS_RELEASE(htmlContainer); + } + } + NS_ASSERTION(nsnull != sheet, "can't get attribute style sheet"); + return sheet; +} + NS_IMETHODIMP nsHTMLBodyElement::GetStyleRule(nsIStyleRule*& aResult) { - if (nsnull == mStyleRule) { - mStyleRule = new BodyRule(this); - NS_IF_ADDREF(mStyleRule); + if (nsnull == mInner.mStyleRule) { + nsIHTMLStyleSheet* sheet = nsnull; + + if (nsnull != mInner.mDocument) { // find style sheet + sheet = GetAttrStyleSheet(mInner.mDocument); + } + + mInner.mStyleRule = new BodyRule(this, sheet); + NS_IF_RELEASE(sheet); + NS_IF_ADDREF(mInner.mStyleRule); } - NS_IF_ADDREF(mStyleRule); - aResult = mStyleRule; + NS_IF_ADDREF(mInner.mStyleRule); + aResult = mInner.mStyleRule; return NS_OK; } + + diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index 93741f32f95..ec67affea0f 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -131,8 +131,14 @@ nsHTMLDocument::~nsHTMLDocument() NS_IF_RELEASE(mEmbeds); NS_IF_RELEASE(mLinks); NS_IF_RELEASE(mAnchors); - NS_IF_RELEASE(mAttrStyleSheet); - NS_IF_RELEASE(mStyleAttrStyleSheet); + if (nsnull != mAttrStyleSheet) { + mAttrStyleSheet->SetOwningDocument(nsnull); + NS_RELEASE(mAttrStyleSheet); + } + if (nsnull != mStyleAttrStyleSheet) { + mStyleAttrStyleSheet->SetOwningDocument(nsnull); + NS_RELEASE(mStyleAttrStyleSheet); + } NS_IF_RELEASE(mParser); for (i = 0; i < mImageMaps.Count(); i++) { nsIImageMap* map = (nsIImageMap*)mImageMaps.ElementAt(i); @@ -208,8 +214,14 @@ nsHTMLDocument::StartDocumentLoad(nsIURL *aURL, nsIWebShell* webShell; - NS_IF_RELEASE(mAttrStyleSheet); - NS_IF_RELEASE(mStyleAttrStyleSheet); + if (nsnull != mAttrStyleSheet) { + mAttrStyleSheet->SetOwningDocument(nsnull); + NS_RELEASE(mAttrStyleSheet); + } + if (nsnull != mStyleAttrStyleSheet) { + mStyleAttrStyleSheet->SetOwningDocument(nsnull); + NS_RELEASE(mStyleAttrStyleSheet); + } static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID); static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID); @@ -231,10 +243,10 @@ nsHTMLDocument::StartDocumentLoad(nsIURL *aURL, #endif if (NS_OK == rv) { - if (NS_OK == NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL)) { + if (NS_OK == NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL, this)) { AddStyleSheet(mAttrStyleSheet); // tell the world about our new style sheet } - if (NS_OK == NS_NewHTMLCSSStyleSheet(&mStyleAttrStyleSheet, aURL)) { + if (NS_OK == NS_NewHTMLCSSStyleSheet(&mStyleAttrStyleSheet, aURL, this)) { AddStyleSheet(mStyleAttrStyleSheet); // tell the world about our new style sheet } diff --git a/content/html/document/src/nsImageDocument.cpp b/content/html/document/src/nsImageDocument.cpp index 3f8a617f533..336cf2dca33 100644 --- a/content/html/document/src/nsImageDocument.cpp +++ b/content/html/document/src/nsImageDocument.cpp @@ -195,7 +195,7 @@ nsImageDocument::StartDocumentLoad(nsIURL* aURL, // Create style attribute style sheet nsresult rv; nsIHTMLCSSStyleSheet* styleAttrSheet; - rv = NS_NewHTMLCSSStyleSheet(&styleAttrSheet, aURL); + rv = NS_NewHTMLCSSStyleSheet(&styleAttrSheet, aURL, this); if (NS_OK != rv) { return rv; } @@ -203,7 +203,7 @@ nsImageDocument::StartDocumentLoad(nsIURL* aURL, NS_RELEASE(styleAttrSheet); // Create html attribute style sheet - rv = NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL); + rv = NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL, this); if (NS_OK != rv) { return rv; } diff --git a/content/html/document/src/nsMarkupDocument.cpp b/content/html/document/src/nsMarkupDocument.cpp index 7184e3fb915..e6121b9b224 100644 --- a/content/html/document/src/nsMarkupDocument.cpp +++ b/content/html/document/src/nsMarkupDocument.cpp @@ -192,10 +192,17 @@ void nsMarkupDocument::StyleSheetsToXIF(nsXIFConverter& aConverter) if (sheet != nsnull) { - nsIURL& sheetURL = *sheet->GetURL(); + nsIURL* sheetURL = nsnull; + sheet->GetURL(sheetURL); - if (!(sheetURL == docURL)) + if (nsnull == sheetURL) { break; + } + if (!(*sheetURL == docURL)) { + NS_RELEASE(sheetURL); + break; + } + NS_RELEASE(sheetURL); nsresult isCss = sheet->QueryInterface(kICSSStyleSheetIID, (void**)&cssSheet); if ((isCss == NS_OK) && (cssSheet != nsnull)) diff --git a/content/html/style/public/nsICSSParser.h b/content/html/style/public/nsICSSParser.h index 957e5fef2bd..1827c87b485 100644 --- a/content/html/style/public/nsICSSParser.h +++ b/content/html/style/public/nsICSSParser.h @@ -21,7 +21,7 @@ #include "nslayout.h" #include "nsISupports.h" class nsIStyleRule; -class nsIStyleSheet; +class nsICSSStyleSheet; class nsIUnicharInputStream; class nsIURL; class nsString; @@ -40,11 +40,11 @@ public: // Set a style sheet for the parser to fill in. The style sheet must // implement the nsICSSStyleSheet interface - NS_IMETHOD SetStyleSheet(nsIStyleSheet* aSheet) = 0; + NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet) = 0; NS_IMETHOD Parse(nsIUnicharInputStream* aInput, - nsIURL* aInputURL, - nsIStyleSheet*& aResult) = 0; + nsIURL* aInputURL, + nsICSSStyleSheet*& aResult) = 0; // Parse declarations assuming that the outer curly braces have // already been accounted for. aBaseURL is the base url to use for diff --git a/content/html/style/src/nsCSSParser.cpp b/content/html/style/src/nsCSSParser.cpp index 543f1df1b0a..6ae8f0c3014 100644 --- a/content/html/style/src/nsCSSParser.cpp +++ b/content/html/style/src/nsCSSParser.cpp @@ -198,11 +198,11 @@ public: NS_IMETHOD GetInfoMask(PRUint32& aResult); - NS_IMETHOD SetStyleSheet(nsIStyleSheet* aSheet); + NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet); NS_IMETHOD Parse(nsIUnicharInputStream* aInput, - nsIURL* aInputURL, - nsIStyleSheet*& aResult); + nsIURL* aInputURL, + nsICSSStyleSheet*& aResult); NS_IMETHOD ParseDeclarations(const nsString& aDeclaration, nsIURL* aBaseURL, @@ -364,32 +364,27 @@ CSSParserImpl::GetInfoMask(PRUint32& aResult) } NS_METHOD -CSSParserImpl::SetStyleSheet(nsIStyleSheet* aSheet) +CSSParserImpl::SetStyleSheet(nsICSSStyleSheet* aSheet) { NS_PRECONDITION(nsnull != aSheet, "null ptr"); if (nsnull == aSheet) { return NS_ERROR_NULL_POINTER; } - // Make sure the sheet supports the correct interface! - static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID); - nsICSSStyleSheet* cssSheet; - nsresult rv = aSheet->QueryInterface(kICSSStyleSheetIID, (void**)&cssSheet); - if (NS_OK != rv) { - return rv; + if (aSheet != mSheet) { + // Switch to using the new sheet + NS_IF_RELEASE(mSheet); + mSheet = aSheet; + NS_ADDREF(mSheet); } - // Switch to using the new sheet - NS_IF_RELEASE(mSheet); - mSheet = cssSheet; - return NS_OK; } NS_METHOD CSSParserImpl::Parse(nsIUnicharInputStream* aInput, nsIURL* aInputURL, - nsIStyleSheet*& aResult) + nsICSSStyleSheet*& aResult) { if (nsnull == mSheet) { NS_NewCSSStyleSheet(&mSheet, aInputURL); @@ -425,9 +420,8 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput, mScanner = nsnull; NS_IF_RELEASE(mURL); - nsIStyleSheet* sheet = nsnull; - mSheet->QueryInterface(kIStyleSheetIID, (void**)&sheet); - aResult = sheet; + aResult = mSheet; + NS_ADDREF(aResult); return NS_OK; } @@ -711,15 +705,11 @@ NS_IMETHODIMP CSSParserImpl::ProcessImport(const nsString& aURLSpec) nsICSSParser* parser; rv = NS_NewCSSParser(&parser); if (NS_OK == rv) { - nsIStyleSheet* childSheet = nsnull; + nsICSSStyleSheet* childSheet = nsnull; rv = parser->Parse(uin, url, childSheet); NS_RELEASE(parser); if ((NS_OK == rv) && (nsnull != childSheet)) { - nsICSSStyleSheet* cssChild = nsnull; - if (NS_OK == childSheet->QueryInterface(kICSSStyleSheetIID, (void**)&cssChild)) { - mSheet->AppendStyleSheet(cssChild); - NS_RELEASE(cssChild); - } + mSheet->AppendStyleSheet(childSheet); } NS_IF_RELEASE(childSheet); } diff --git a/content/html/style/src/nsCSSStyleRule.cpp b/content/html/style/src/nsCSSStyleRule.cpp index dd7eec2b653..0638978d2ef 100644 --- a/content/html/style/src/nsCSSStyleRule.cpp +++ b/content/html/style/src/nsCSSStyleRule.cpp @@ -17,9 +17,10 @@ */ #include "nsICSSStyleRule.h" #include "nsICSSDeclaration.h" -#include "nsIStyleSheet.h" +#include "nsICSSStyleSheet.h" #include "nsIStyleContext.h" #include "nsIPresContext.h" +#include "nsIDocument.h" #include "nsIDeviceContext.h" #include "nsIArena.h" #include "nsIAtom.h" @@ -31,8 +32,8 @@ #include "nsStyleUtil.h" #include "nsIFontMetrics.h" #include "nsIDOMCSSStyleSheet.h" +#include "nsIDOMCSSRule.h" #include "nsIDOMCSSStyleRule.h" -#include "nsIDOMCSSStyleRuleSimple.h" #include "nsIDOMCSSStyleDeclaration.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptObjectOwner.h" @@ -45,8 +46,8 @@ static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); static NS_DEFINE_IID(kICSSDeclarationIID, NS_ICSS_DECLARATION_IID); static NS_DEFINE_IID(kICSSStyleRuleIID, NS_ICSS_STYLE_RULE_IID); static NS_DEFINE_IID(kIDOMCSSStyleSheetIID, NS_IDOMCSSSTYLESHEET_IID); +static NS_DEFINE_IID(kIDOMCSSRuleIID, NS_IDOMCSSRULE_IID); static NS_DEFINE_IID(kIDOMCSSStyleRuleIID, NS_IDOMCSSSTYLERULE_IID); -static NS_DEFINE_IID(kIDOMCSSStyleRuleSimpleIID, NS_IDOMCSSSTYLERULESIMPLE_IID); static NS_DEFINE_IID(kIDOMCSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID); static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); @@ -162,15 +163,19 @@ static void MapDeclarationInto(nsICSSDeclaration* aDeclaration, nsIStyleContext* aContext, nsIPresContext* aPresContext); +class CSSStyleRuleImpl; + class CSSImportantRule : public nsIStyleRule { public: - CSSImportantRule(nsICSSDeclaration* aDeclaration); + CSSImportantRule(nsICSSStyleSheet* aSheet, nsICSSDeclaration* aDeclaration); NS_DECL_ISUPPORTS NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aResult) const; NS_IMETHOD HashValue(PRUint32& aValue) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; + // Strength is an out-of-band weighting, useful for mapping CSS ! important NS_IMETHOD GetStrength(PRInt32& aStrength); @@ -182,10 +187,14 @@ protected: ~CSSImportantRule(void); nsICSSDeclaration* mDeclaration; + nsICSSStyleSheet* mSheet; + +friend CSSStyleRuleImpl; }; -CSSImportantRule::CSSImportantRule(nsICSSDeclaration* aDeclaration) - : mDeclaration(aDeclaration) +CSSImportantRule::CSSImportantRule(nsICSSStyleSheet* aSheet, nsICSSDeclaration* aDeclaration) + : mSheet(aSheet), + mDeclaration(aDeclaration) { NS_INIT_REFCNT(); NS_IF_ADDREF(mDeclaration); @@ -212,6 +221,14 @@ CSSImportantRule::HashValue(PRUint32& aValue) const return NS_OK; } +NS_IMETHODIMP +CSSImportantRule::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, useful for mapping CSS ! important NS_IMETHODIMP CSSImportantRule::GetStrength(PRInt32& aStrength) @@ -299,7 +316,18 @@ nsresult DOMCSSDeclarationImpl::StylePropertyChanged(const nsString& aPropertyName, PRInt32 aHint) { - // XXX TBI + nsIStyleSheet* sheet = nsnull; + if (nsnull != mRule) { + mRule->GetStyleSheet(sheet); + if (nsnull != sheet) { + nsIDocument* doc = nsnull; + sheet->GetOwningDocument(doc); + if (nsnull != doc) { + doc->StyleRuleChanged(sheet, mRule, aHint); + } + } + } + return NS_OK; } @@ -316,7 +344,7 @@ DOMCSSDeclarationImpl::GetParent(nsISupports **aParent) // -- nsCSSStyleRule ------------------------------- class CSSStyleRuleImpl : public nsICSSStyleRule, - public nsIDOMCSSStyleRuleSimple, + public nsIDOMCSSStyleRule, public nsIScriptObjectOwner { public: void* operator new(size_t size); @@ -346,20 +374,24 @@ public: virtual nsIStyleRule* GetImportantRule(void); - virtual nsIStyleSheet* GetStyleSheet(void); - virtual void SetStyleSheet(nsIStyleSheet *aSheet); + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; + NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet); NS_IMETHOD MapStyleInto(nsIStyleContext* aContext, nsIPresContext* aPresContext); NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; - // nsIDOMCSSStyleRule interface - NS_IMETHOD GetType(nsString& aType); + // nsIDOMCSSRule interface + NS_IMETHOD GetType(PRUint16* aType); + NS_IMETHOD GetCssText(nsString& aCssText); + NS_IMETHOD SetCssText(const nsString& aCssText); + NS_IMETHOD GetSheet(nsIDOMCSSStyleSheet** aSheet); - // nsIDOMCSSStyleRuleSimple interface + // nsIDOMCSSStyleRule interface NS_IMETHOD GetSelectorText(nsString& aSelectorText); NS_IMETHOD SetSelectorText(const nsString& aSelectorText); NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle); + NS_IMETHOD SetStyle(nsIDOMCSSStyleDeclaration* aStyle); // nsIScriptObjectOwner interface NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); @@ -377,13 +409,13 @@ protected: PRUint32 mInHeap : 1; PRUint32 mRefCnt : 31; - nsCSSSelector mSelector; - nsICSSDeclaration* mDeclaration; - PRInt32 mWeight; - CSSImportantRule* mImportantRule; - nsIStyleSheet* mStyleSheet; - DOMCSSDeclarationImpl *mDOMDeclaration; - void* mScriptObject; + nsCSSSelector mSelector; + nsICSSDeclaration* mDeclaration; + PRInt32 mWeight; + CSSImportantRule* mImportantRule; + nsICSSStyleSheet* mSheet; + DOMCSSDeclarationImpl* mDOMDeclaration; + void* mScriptObject; #ifdef DEBUG_REFS PRInt32 mInstance; #endif @@ -453,7 +485,10 @@ CSSStyleRuleImpl::~CSSStyleRuleImpl() delete selector; } NS_IF_RELEASE(mDeclaration); - NS_IF_RELEASE(mImportantRule); + if (nsnull != mImportantRule) { + mImportantRule->mSheet = nsnull; + NS_RELEASE(mImportantRule); + } if (nsnull != mDOMDeclaration) { mDOMDeclaration->DropReference(); } @@ -505,14 +540,14 @@ nsresult CSSStyleRuleImpl::QueryInterface(const nsIID& aIID, NS_ADDREF_THIS(); return NS_OK; } - if (aIID.Equals(kIDOMCSSStyleRuleIID)) { - nsIDOMCSSStyleRule *tmp = this; + if (aIID.Equals(kIDOMCSSRuleIID)) { + nsIDOMCSSRule *tmp = this; *aInstancePtrResult = (void*) tmp; NS_ADDREF_THIS(); return NS_OK; } - if (aIID.Equals(kIDOMCSSStyleRuleSimpleIID)) { - nsIDOMCSSStyleRuleSimple *tmp = this; + if (aIID.Equals(kIDOMCSSStyleRuleIID)) { + nsIDOMCSSStyleRule *tmp = this; *aInstancePtrResult = (void*) tmp; NS_ADDREF_THIS(); return NS_OK; @@ -637,10 +672,12 @@ nsICSSDeclaration* CSSStyleRuleImpl::GetDeclaration(void) const void CSSStyleRuleImpl::SetDeclaration(nsICSSDeclaration* aDeclaration) { - NS_IF_RELEASE(mImportantRule); - NS_IF_RELEASE(mDeclaration); - mDeclaration = aDeclaration; - NS_IF_ADDREF(mDeclaration); + if (mDeclaration != aDeclaration) { + NS_IF_RELEASE(mImportantRule); + NS_IF_RELEASE(mDeclaration); + mDeclaration = aDeclaration; + NS_IF_ADDREF(mDeclaration); + } } PRInt32 CSSStyleRuleImpl::GetWeight(void) const @@ -659,7 +696,7 @@ nsIStyleRule* CSSStyleRuleImpl::GetImportantRule(void) nsICSSDeclaration* important; mDeclaration->GetImportantValues(important); if (nsnull != important) { - mImportantRule = new CSSImportantRule(important); + mImportantRule = new CSSImportantRule(mSheet, important); NS_ADDREF(mImportantRule); NS_RELEASE(important); } @@ -668,19 +705,25 @@ nsIStyleRule* CSSStyleRuleImpl::GetImportantRule(void) return mImportantRule; } -nsIStyleSheet* CSSStyleRuleImpl::GetStyleSheet(void) +NS_IMETHODIMP +CSSStyleRuleImpl::GetStyleSheet(nsIStyleSheet*& aSheet) const { - NS_IF_ADDREF(mStyleSheet); - - return mStyleSheet; + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; } -void CSSStyleRuleImpl::SetStyleSheet(nsIStyleSheet *aSheet) +NS_IMETHODIMP +CSSStyleRuleImpl::SetStyleSheet(nsICSSStyleSheet* aSheet) { - // XXX We don't reference count this up reference. The style sheet + // We don't reference count this up reference. The style sheet // will tell us when it's going away or when we're detached from // it. - mStyleSheet = aSheet; + mSheet = aSheet; + if (nsnull != mImportantRule) { // we're responsible for this guy too + mImportantRule->mSheet = aSheet; + } + return NS_OK; } nscoord CalcLength(const nsCSSValue& aValue, @@ -1284,8 +1327,8 @@ void MapDeclarationInto(nsICSSDeclaration* aDeclaration, } else if (eCSSUnit_Inherit == ourColor->mBackPositionX.GetUnit()) { color->mBackgroundXPosition = parentColor->mBackgroundXPosition; - color->mBackgroundFlags &= ~NS_STYLE_BG_X_POSITION_LENGTH; - color->mBackgroundFlags |= (parentColor->mBackgroundFlags & NS_STYLE_BG_X_POSITION_PERCENT); + color->mBackgroundFlags &= ~(NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT); + color->mBackgroundFlags |= (parentColor->mBackgroundFlags & (NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT)); } if (eCSSUnit_Percent == ourColor->mBackPositionY.GetUnit()) { @@ -1306,8 +1349,8 @@ void MapDeclarationInto(nsICSSDeclaration* aDeclaration, } else if (eCSSUnit_Inherit == ourColor->mBackPositionY.GetUnit()) { color->mBackgroundYPosition = parentColor->mBackgroundYPosition; - color->mBackgroundFlags &= ~NS_STYLE_BG_Y_POSITION_LENGTH; - color->mBackgroundFlags |= (parentColor->mBackgroundFlags & NS_STYLE_BG_Y_POSITION_PERCENT); + color->mBackgroundFlags &= ~(NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT); + color->mBackgroundFlags |= (parentColor->mBackgroundFlags & (NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT)); } // opacity: factor, percent, inherit @@ -1693,14 +1736,37 @@ CSSStyleRuleImpl::List(FILE* out, PRInt32 aIndent) const } NS_IMETHODIMP -CSSStyleRuleImpl::GetType(nsString& aType) +CSSStyleRuleImpl::GetType(PRUint16* aType) { - // XXX Need to define the different types - aType.SetString("simple"); + *aType = nsIDOMCSSRule::STYLE_RULE; return NS_OK; } +NS_IMETHODIMP +CSSStyleRuleImpl::GetCssText(nsString& aCssText) +{ + // XXX TBI + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleRuleImpl::SetCssText(const nsString& aCssText) +{ + // XXX TBI + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleRuleImpl::GetSheet(nsIDOMCSSStyleSheet** aSheet) +{ + if (nsnull != mSheet) { + return mSheet->QueryInterface(kIDOMCSSStyleSheetIID, (void**)aSheet); + } + *aSheet = nsnull; + return NS_OK; +} + NS_IMETHODIMP CSSStyleRuleImpl::GetSelectorText(nsString& aSelectorText) { @@ -1763,6 +1829,13 @@ CSSStyleRuleImpl::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) return NS_OK; } +NS_IMETHODIMP +CSSStyleRuleImpl::SetStyle(nsIDOMCSSStyleDeclaration* aStyle) +{ + // XXX TBI + return NS_OK; +} + NS_IMETHODIMP CSSStyleRuleImpl::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject) { @@ -1773,10 +1846,10 @@ CSSStyleRuleImpl::GetScriptObject(nsIScriptContext *aContext, void** aScriptObje nsISupports *supports = (nsISupports *)(nsICSSStyleRule *)this; // XXX Parent should be the style sheet // XXX Should be done through factory - res = NS_NewScriptCSSStyleRuleSimple(aContext, - supports, - (nsISupports *)global, - (void**)&mScriptObject); + res = NS_NewScriptCSSStyleRule(aContext, + supports, + (nsISupports *)global, + (void**)&mScriptObject); } *aScriptObject = mScriptObject; diff --git a/content/html/style/src/nsCSSStyleSheet.cpp b/content/html/style/src/nsCSSStyleSheet.cpp index b87a220207d..b29516d0d3d 100644 --- a/content/html/style/src/nsCSSStyleSheet.cpp +++ b/content/html/style/src/nsCSSStyleSheet.cpp @@ -30,12 +30,14 @@ #include "nsHTMLAtoms.h" #include "nsIFrame.h" #include "nsString.h" +#include "nsVoidArray.h" #include "nsIPtr.h" #include "nsHTMLIIDs.h" #include "nsIDOMStyleSheetCollection.h" #include "nsIDOMCSSStyleSheet.h" #include "nsIDOMCSSStyleRule.h" #include "nsIDOMCSSStyleRuleCollection.h" +#include "nsIDOMNode.h" #include "nsIScriptObjectOwner.h" #include "nsIScriptGlobalObject.h" #include "nsICSSParser.h" @@ -540,6 +542,25 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); + // basic style sheet data + NS_IMETHOD GetURL(nsIURL*& aURL) const; + NS_IMETHOD GetTitle(nsString& aTitle) const; + NS_IMETHOD SetTitle(const nsString& aTitle); + NS_IMETHOD GetType(nsString& aType) const; + NS_IMETHOD GetMediumCount(PRInt32& aCount) const; + NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsString& aMedium) const; + NS_IMETHOD AppendMedium(const nsString& aMedium); + + NS_IMETHOD GetEnabled(PRBool& aEnabled) const; + NS_IMETHOD SetEnabled(PRBool aEnabled); + + // style sheet owner info + NS_IMETHOD GetParentSheet(nsIStyleSheet*& aParent) const; // may be null + NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; + NS_IMETHOD SetOwningDocument(nsIDocument* aDocument); + NS_IMETHOD SetOwningNode(nsIDOMNode* aOwningNode); + + virtual PRInt32 RulesMatching(nsIPresContext* aPresContext, nsIContent* aContent, nsIStyleContext* aParentContext, @@ -551,9 +572,7 @@ public: nsIStyleContext* aParentContext, nsISupportsArray* aResults); - virtual nsIURL* GetURL(void); - - virtual PRBool ContainsStyleSheet(nsIURL* aURL); + virtual PRBool ContainsStyleSheet(nsIURL* aURL) const; virtual void AppendStyleSheet(nsICSSStyleSheet* aSheet); @@ -561,32 +580,29 @@ public: virtual void PrependStyleRule(nsICSSStyleRule* aRule); virtual void AppendStyleRule(nsICSSStyleRule* aRule); - virtual PRInt32 StyleRuleCount(void); - virtual nsresult GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule); + virtual PRInt32 StyleRuleCount(void) const; + virtual nsresult GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule) const; - virtual PRInt32 StyleSheetCount(); - virtual nsresult GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet); - - virtual void SetDocument(nsIDocument *aDocument); + virtual PRInt32 StyleSheetCount(void) const; + virtual nsresult GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const; virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; // nsIDOMStyleSheet interface + NS_IMETHOD GetType(nsString& aType); NS_IMETHOD GetDisabled(PRBool* aDisabled); NS_IMETHOD SetDisabled(PRBool aDisabled); NS_IMETHOD GetReadOnly(PRBool* aReadOnly); // nsIDOMCSSStyleSheet interface - NS_IMETHOD GetOwningElement(nsIDOMHTMLElement** aOwningElement); - NS_IMETHOD GetParentStyleSheet(nsIDOMCSSStyleSheet** aParentStyleSheet); + NS_IMETHOD GetOwningNode(nsIDOMNode** aOwningNode); + NS_IMETHOD GetParentStyleSheet(nsIDOMStyleSheet** aParentStyleSheet); NS_IMETHOD GetHref(nsString& aHref); NS_IMETHOD GetTitle(nsString& aTitle); - NS_IMETHOD GetImports(nsIDOMStyleSheetCollection** aImports); - NS_IMETHOD GetRules(nsIDOMCSSStyleRuleCollection** aRules); - NS_IMETHOD AddRule(const nsString& aSelector, const nsString& aDeclaration, PRUint32 aIndex, PRUint32* aReturn); - NS_IMETHOD AddImport(const nsString& aUrl, PRUint32 aIndex, PRUint32* aReturn); - NS_IMETHOD RemoveRule(PRUint32 aIndex); - NS_IMETHOD RemoveImport(PRUint32 aIndex); + NS_IMETHOD GetMedia(nsString& aMedia); + NS_IMETHOD GetCssRules(nsIDOMCSSStyleRuleCollection** aCssRules); + NS_IMETHOD InsertRule(const nsString& aRule, PRUint32 aIndex, PRUint32* aReturn); + NS_IMETHOD DeleteRule(PRUint32 aIndex); // nsIScriptObjectOwner interface NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); @@ -608,6 +624,8 @@ protected: PRUint32 mRefCnt : 31; nsIURLPtr mURL; + nsString mTitle; + nsVoidArray mMedia; nsICSSStyleSheetPtr mFirstChild; nsISupportsArrayPtr mOrderedRules; nsISupportsArrayPtr mWeightedRules; @@ -617,8 +635,9 @@ protected: CSSStyleRuleCollectionImpl* mRuleCollection; CSSImportsCollectionImpl* mImportsCollection; nsIDocument* mDocument; + nsIDOMNode* mOwningNode; PRBool mDisabled; - void * mScriptObject; + void* mScriptObject; }; @@ -662,7 +681,8 @@ static PRInt32 gInstanceCount; CSSStyleSheetImpl::CSSStyleSheetImpl(nsIURL* aURL) : nsICSSStyleSheet(), - mURL(nsnull), mFirstChild(nsnull), + mURL(nsnull), mTitle(), mMedia(), + mFirstChild(nsnull), mOrderedRules(nsnull), mWeightedRules(nsnull), mNext(nsnull), mRuleHash(nsnull) @@ -673,6 +693,7 @@ CSSStyleSheetImpl::CSSStyleSheetImpl(nsIURL* aURL) mRuleCollection = nsnull; mImportsCollection = nsnull; mDocument = nsnull; + mOwningNode = nsnull; mDisabled = PR_FALSE; mScriptObject = nsnull; #ifdef DEBUG_REFS @@ -698,6 +719,11 @@ CSSStyleSheetImpl::~CSSStyleSheetImpl() --gInstanceCount; fprintf(stdout, "%d - CSSStyleSheet\n", gInstanceCount); #endif + PRInt32 count = mMedia.Count(); + while (0 < count) { + nsString* medium = (nsString*)mMedia.ElementAt(--count); + delete medium; + } if (mFirstChild.IsNotNull()) { nsICSSStyleSheet* child = mFirstChild; while (nsnull != child) { @@ -1084,12 +1110,122 @@ PRInt32 CSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, return matchCount; } -nsIURL* CSSStyleSheetImpl::GetURL(void) +NS_IMETHODIMP +CSSStyleSheetImpl::GetURL(nsIURL*& aURL) const { - return mURL.AddRef(); + nsIURL* url = mURL; + aURL = mURL; + NS_IF_ADDREF(aURL); + return NS_OK; } -PRBool CSSStyleSheetImpl::ContainsStyleSheet(nsIURL* aURL) +NS_IMETHODIMP +CSSStyleSheetImpl::GetTitle(nsString& aTitle) const +{ + aTitle = mTitle; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::SetTitle(const nsString& aTitle) +{ + mTitle = aTitle; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetType(nsString& aType) const +{ + aType.Truncate(); + aType.Append("text/css"); + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetMediumCount(PRInt32& aCount) const +{ + aCount = mMedia.Count(); + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetMediumAt(PRInt32 aIndex, nsString& aMedium) const +{ + nsString* medium = (nsString*)mMedia.ElementAt(aIndex); + if (nsnull != medium) { + aMedium = *medium; + return NS_OK; + } + aMedium.Truncate(); + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::AppendMedium(const nsString& aMedium) +{ + nsString* medium = new nsString(aMedium); + mMedia.AppendElement(medium); + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetEnabled(PRBool& aEnabled) const +{ + aEnabled = ((PR_TRUE == mDisabled) ? PR_FALSE : PR_TRUE); + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::SetEnabled(PRBool aEnabled) +{ + PRBool oldState = mDisabled; + mDisabled = ((PR_TRUE == aEnabled) ? PR_FALSE : PR_TRUE); + + if ((nsnull != mDocument) && (mDisabled != oldState)) { + mDocument->SetStyleSheetDisabledState(this, mDisabled); + } + + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetParentSheet(nsIStyleSheet*& aParent) const +{ + NS_IF_ADDREF(mParent); + aParent = mParent; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetOwningDocument(nsIDocument*& aDocument) const +{ + nsIDocument* doc = mDocument; + CSSStyleSheetImpl* parent = (CSSStyleSheetImpl*)mParent; + while ((nsnull == doc) && (nsnull != parent)) { + doc = parent->mDocument; + parent = (CSSStyleSheetImpl*)(parent->mParent); + } + + NS_IF_ADDREF(doc); + aDocument = doc; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::SetOwningDocument(nsIDocument* aDocument) +{ // not ref counted + mDocument = aDocument; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::SetOwningNode(nsIDOMNode* aOwningNode) +{ // not ref counted + mOwningNode = aOwningNode; + return NS_OK; +} + +PRBool CSSStyleSheetImpl::ContainsStyleSheet(nsIURL* aURL) const { NS_PRECONDITION(nsnull != aURL, "null arg"); @@ -1182,7 +1318,7 @@ void CSSStyleSheetImpl::AppendStyleRule(nsICSSStyleRule* aRule) aRule->SetStyleSheet(this); } -PRInt32 CSSStyleSheetImpl::StyleRuleCount(void) +PRInt32 CSSStyleSheetImpl::StyleRuleCount(void) const { if (mOrderedRules.IsNotNull()) { return mOrderedRules->Count(); @@ -1190,7 +1326,7 @@ PRInt32 CSSStyleSheetImpl::StyleRuleCount(void) return 0; } -nsresult CSSStyleSheetImpl::GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule) +nsresult CSSStyleSheetImpl::GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule) const { nsresult result = NS_ERROR_ILLEGAL_VALUE; @@ -1206,7 +1342,7 @@ nsresult CSSStyleSheetImpl::GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRu return result; } -PRInt32 CSSStyleSheetImpl::StyleSheetCount() +PRInt32 CSSStyleSheetImpl::StyleSheetCount(void) const { // XXX Far from an ideal way to do this, but the hope is that // it won't be done too often. If it is, we might want to @@ -1223,7 +1359,7 @@ PRInt32 CSSStyleSheetImpl::StyleSheetCount() return count; } -nsresult CSSStyleSheetImpl::GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) +nsresult CSSStyleSheetImpl::GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const { // XXX Ughh...an O(n^2) method for doing iteration. Again, we hope // that this isn't done too often. If it is, we need to change the @@ -1243,13 +1379,6 @@ nsresult CSSStyleSheetImpl::GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& a return NS_OK; } -void CSSStyleSheetImpl::SetDocument(nsIDocument *aDocument) -{ - // This reference is not reference counted and should not be - // released. The document will tell us when it goes away. - mDocument = aDocument; -} - void CSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const { nsAutoString buffer; @@ -1303,6 +1432,15 @@ void CSSStyleSheetImpl::BuildHash(void) } } + // nsIDOMStyleSheet interface +NS_IMETHODIMP +CSSStyleSheetImpl::GetType(nsString& aType) +{ + aType.Truncate(); + aType.Append("text/css"); + return NS_OK; +} + NS_IMETHODIMP CSSStyleSheetImpl::GetDisabled(PRBool* aDisabled) { @@ -1313,13 +1451,13 @@ CSSStyleSheetImpl::GetDisabled(PRBool* aDisabled) NS_IMETHODIMP CSSStyleSheetImpl::SetDisabled(PRBool aDisabled) { - - if ((nsnull != mDocument) && (mDisabled != aDisabled)) { - mDocument->SetStyleSheetDisabledState(this, aDisabled); - } - + PRBool oldState = mDisabled; mDisabled = aDisabled; + if ((nsnull != mDocument) && (mDisabled != oldState)) { + mDocument->SetStyleSheetDisabledState(this, mDisabled); + } + return NS_OK; } @@ -1332,18 +1470,18 @@ CSSStyleSheetImpl::GetReadOnly(PRBool* aReadOnly) } NS_IMETHODIMP -CSSStyleSheetImpl::GetOwningElement(nsIDOMHTMLElement** aOwningElement) +CSSStyleSheetImpl::GetOwningNode(nsIDOMNode** aOwningNode) { - // XXX TBI - *aOwningElement = nsnull; + NS_IF_ADDREF(mOwningNode); + *aOwningNode = mOwningNode; return NS_OK; } NS_IMETHODIMP -CSSStyleSheetImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet** aParentStyleSheet) +CSSStyleSheetImpl::GetParentStyleSheet(nsIDOMStyleSheet** aParentStyleSheet) { if (nsnull != mParent) { - return mParent->QueryInterface(kIDOMCSSStyleSheetIID, (void **)aParentStyleSheet); + return mParent->QueryInterface(kIDOMStyleSheetIID, (void **)aParentStyleSheet); } else { *aParentStyleSheet = nsnull; @@ -1364,32 +1502,31 @@ CSSStyleSheetImpl::GetHref(nsString& aHref) return NS_OK; } -NS_IMETHODIMP +NS_IMETHODIMP CSSStyleSheetImpl::GetTitle(nsString& aTitle) { - // XX TBI + aTitle = mTitle; return NS_OK; } -NS_IMETHODIMP -CSSStyleSheetImpl::GetImports(nsIDOMStyleSheetCollection** aImports) +NS_IMETHODIMP +CSSStyleSheetImpl::GetMedia(nsString& aMedia) { - if (nsnull == mImportsCollection) { - mImportsCollection = new CSSImportsCollectionImpl(this); - if (nsnull == mImportsCollection) { - return NS_ERROR_OUT_OF_MEMORY; + aMedia.Truncate(); + PRInt32 count = mMedia.Count(); + PRInt32 index = 0; + while (index < count) { + nsString* medium = (nsString*)mMedia.ElementAt(index++); + aMedia.Append(*medium); + if (index < count) { + aMedia.Append(", "); } - NS_ADDREF(mImportsCollection); } - - *aImports = mImportsCollection; - NS_ADDREF(mImportsCollection); - return NS_OK; } NS_IMETHODIMP -CSSStyleSheetImpl::GetRules(nsIDOMCSSStyleRuleCollection** aRules) +CSSStyleSheetImpl::GetCssRules(nsIDOMCSSStyleRuleCollection** aCssRules) { if (nsnull == mRuleCollection) { mRuleCollection = new CSSStyleRuleCollectionImpl(this); @@ -1399,37 +1536,31 @@ CSSStyleSheetImpl::GetRules(nsIDOMCSSStyleRuleCollection** aRules) NS_ADDREF(mRuleCollection); } - *aRules = mRuleCollection; + *aCssRules = mRuleCollection; NS_ADDREF(mRuleCollection); return NS_OK; } NS_IMETHODIMP -CSSStyleSheetImpl::AddRule(const nsString& aSelector, - const nsString& aDeclaration, - PRUint32 aIndex, - PRUint32* aReturn) +CSSStyleSheetImpl::InsertRule(const nsString& aRule, + PRUint32 aIndex, + PRUint32* aReturn) { nsICSSParser* css; nsresult result = NS_NewCSSParser(&css); if (NS_OK == result) { - nsAutoString str; - str.SetString(aSelector); - // XXX Can we assume that the braces aren't there? - str.Append(" { "); - str.Append(aDeclaration); - str.Append(" } "); - + nsAutoString str(aRule); nsIUnicharInputStream* input = nsnull; result = NS_NewStringUnicharInputStream(&input, &str); if (NS_OK == result) { - nsIStyleSheet *tmp; + nsICSSStyleSheet* tmp; css->SetStyleSheet(this); // XXX Currently, the parser will append the rule to the // style sheet. We shouldn't ignore the index. result = css->Parse(input, mURL, tmp); - NS_ASSERTION(tmp = this, "parser incorrectly created a new stylesheet"); + NS_ASSERTION(tmp == this, "parser incorrectly created a new stylesheet"); + NS_RELEASE(tmp); NS_RELEASE(input); *aReturn = mOrderedRules->Count(); } @@ -1441,21 +1572,9 @@ CSSStyleSheetImpl::AddRule(const nsString& aSelector, } NS_IMETHODIMP -CSSStyleSheetImpl::AddImport(const nsString& aUrl, PRUint32 aIndex, PRUint32* aReturn) -{ - nsICSSParser* css; - nsresult result = NS_NewCSSParser(&css); - if (NS_OK == result) { - css->SetStyleSheet(this); - result = css->ProcessImport(aUrl); - } - - return result; -} - -NS_IMETHODIMP -CSSStyleSheetImpl::RemoveRule(PRUint32 aIndex) +CSSStyleSheetImpl::DeleteRule(PRUint32 aIndex) { + // XXX TBI: handle @rule types nsICSSStyleRule *rule; rule = (nsICSSStyleRule *)mOrderedRules->ElementAt(aIndex); @@ -1469,36 +1588,6 @@ CSSStyleSheetImpl::RemoveRule(PRUint32 aIndex) return NS_OK; } -NS_IMETHODIMP -CSSStyleSheetImpl::RemoveImport(PRUint32 aIndex) -{ - if (mFirstChild.IsNotNull()) { - nsICSSStyleSheet* prev = nsnull; - nsICSSStyleSheet* child = mFirstChild; - while ((nsnull != child) && (0 != aIndex)) { - prev = child; - child = ((CSSStyleSheetImpl*)child)->mNext; - --aIndex; - } - - if ((nsnull != child) && (0 == aIndex)) { - // Hold on to the child while we clean it up - NS_ADDREF(child); - if (nsnull == prev) { - mFirstChild.SetAddRef(((CSSStyleSheetImpl*)child)->mNext); - } - else { - ((CSSStyleSheetImpl*)prev)->mNext.SetAddRef(((CSSStyleSheetImpl*)child)->mNext); - } - ((CSSStyleSheetImpl*)child)->mNext.SetAddRef(nsnull); - ((CSSStyleSheetImpl*)child)->mParent = nsnull; - NS_RELEASE(child); - } - } - - return NS_OK; -} - NS_IMETHODIMP CSSStyleSheetImpl::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject) { diff --git a/content/html/style/src/nsDOMCSSDeclaration.cpp b/content/html/style/src/nsDOMCSSDeclaration.cpp index 90e01e5a4b9..600a29cc4be 100644 --- a/content/html/style/src/nsDOMCSSDeclaration.cpp +++ b/content/html/style/src/nsDOMCSSDeclaration.cpp @@ -37,6 +37,7 @@ nsDOMCSSDeclaration::~nsDOMCSSDeclaration() NS_IMPL_ADDREF(nsDOMCSSDeclaration); NS_IMPL_RELEASE(nsDOMCSSDeclaration); +static NS_DEFINE_IID(kIDOMCSS2PropertiesIID, NS_IDOMCSS2PROPERTIES_IID); static NS_DEFINE_IID(kIDOMCSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID); static NS_DEFINE_IID(kICSSStyleRuleIID, NS_ICSS_STYLE_RULE_IID); static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); @@ -50,6 +51,12 @@ nsDOMCSSDeclaration::QueryInterface(REFNSIID aIID, if (nsnull == aInstancePtr) { return NS_ERROR_NULL_POINTER; } + if (aIID.Equals(kIDOMCSS2PropertiesIID)) { + nsIDOMCSS2Properties *tmp = this; + AddRef(); + *aInstancePtr = (void*) tmp; + return NS_OK; + } if (aIID.Equals(kIDOMCSSStyleDeclarationIID)) { nsIDOMCSSStyleDeclaration *tmp = this; AddRef(); @@ -83,12 +90,12 @@ nsDOMCSSDeclaration::GetScriptObject(nsIScriptContext* aContext, res = GetParent(&parent); if (NS_OK == res) { - nsISupports *supports = (nsISupports *)(nsIDOMCSSStyleDeclaration *)this; + nsISupports *supports = (nsISupports *)(nsIDOMCSS2Properties *)this; // XXX Should be done through factory - res = NS_NewScriptCSSStyleDeclaration(aContext, - supports, - parent, - (void**)&mScriptObject); + res = NS_NewScriptCSS2Properties(aContext, + supports, + parent, + (void**)&mScriptObject); NS_RELEASE(parent); } } @@ -104,6 +111,20 @@ nsDOMCSSDeclaration::SetScriptObject(void* aScriptObject) return NS_OK; } +NS_IMETHODIMP +nsDOMCSSDeclaration::GetCssText(nsString& aCssText) +{ + // XXX TBI + return NS_OK; +} + +NS_IMETHODIMP +nsDOMCSSDeclaration::SetCssText(const nsString& aCssText) +{ + // XXX TBI + return NS_OK; +} + NS_IMETHODIMP nsDOMCSSDeclaration::GetLength(PRUint32* aLength) { @@ -649,6 +670,18 @@ nsDOMCSSDeclaration::SetCounterReset(const nsString& aCounterReset) return SetProperty("counter-reset", aCounterReset, ""); } +NS_IMETHODIMP +nsDOMCSSDeclaration::GetCssFloat(nsString& aCssFloat) +{ + return GetPropertyValue("float", aCssFloat); +} + +NS_IMETHODIMP +nsDOMCSSDeclaration::SetCssFloat(const nsString& aCssFloat) +{ + return SetProperty("float", aCssFloat, ""); +} + NS_IMETHODIMP nsDOMCSSDeclaration::GetCue(nsString& aCue) { @@ -745,18 +778,6 @@ nsDOMCSSDeclaration::SetEmptyCells(const nsString& aEmptyCells) return SetProperty("empty-cells", aEmptyCells, ""); } -NS_IMETHODIMP -nsDOMCSSDeclaration::GetStyleFloat(nsString& aStyleFloat) -{ - return GetPropertyValue("style-float", aStyleFloat); -} - -NS_IMETHODIMP -nsDOMCSSDeclaration::SetStyleFloat(const nsString& aStyleFloat) -{ - return SetProperty("style-float", aStyleFloat, ""); -} - NS_IMETHODIMP nsDOMCSSDeclaration::GetFont(nsString& aFont) { diff --git a/content/html/style/src/nsDOMCSSDeclaration.h b/content/html/style/src/nsDOMCSSDeclaration.h index acae956973a..606a5172c5a 100644 --- a/content/html/style/src/nsDOMCSSDeclaration.h +++ b/content/html/style/src/nsDOMCSSDeclaration.h @@ -20,12 +20,12 @@ #define nsDOMCSSSDeclaration_h___ #include "nsISupports.h" -#include "nsIDOMCSSStyleDeclaration.h" +#include "nsIDOMCSS2Properties.h" #include "nsIScriptObjectOwner.h" class nsICSSDeclaration; -class nsDOMCSSDeclaration : public nsIDOMCSSStyleDeclaration, +class nsDOMCSSDeclaration : public nsIDOMCSS2Properties, public nsIScriptObjectOwner { public: @@ -34,6 +34,8 @@ public: NS_DECL_ISUPPORTS NS_DECL_IDOMCSSSTYLEDECLARATION + + NS_DECL_IDOMCSS2PROPERTIES // nsIScriptObjectOwner interface NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); diff --git a/content/html/style/src/nsHTMLAttributes.cpp b/content/html/style/src/nsHTMLAttributes.cpp index 80321b0df46..f981f59d675 100644 --- a/content/html/style/src/nsHTMLAttributes.cpp +++ b/content/html/style/src/nsHTMLAttributes.cpp @@ -17,6 +17,7 @@ */ #include "nsIHTMLAttributes.h" +#include "nsIHTMLStyleSheet.h" #include "nsIStyleRule.h" #include "nsString.h" #include "nsISupportsArray.h" @@ -171,7 +172,7 @@ public: void* operator new(size_t size, nsIArena* aArena); void operator delete(void* ptr); - HTMLAttributesImpl(nsMapAttributesFunc aMapFunc); + HTMLAttributesImpl(nsIHTMLStyleSheet* aSheet, nsMapAttributesFunc aMapFunc); HTMLAttributesImpl(const HTMLAttributesImpl& aCopy); ~HTMLAttributesImpl(void); @@ -212,6 +213,8 @@ public: // nsIStyleRule NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aResult) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; + NS_IMETHOD SetStyleSheet(nsIHTMLStyleSheet* aSheet); // Strength is an out-of-band weighting, always 0 here NS_IMETHOD GetStrength(PRInt32& aStrength); NS_IMETHOD MapStyleInto(nsIStyleContext* aContext, nsIPresContext* aPresContext); @@ -231,11 +234,12 @@ protected: PRUint32 mInHeap : 1; PRUint32 mRefCnt : 31; - PRInt32 mContentRefCount; - PRInt32 mCount; - HTMLAttribute mFirst; - nsIAtom* mID; - nsIAtom* mClass; + nsIHTMLStyleSheet* mSheet; + PRInt32 mContentRefCount; + PRInt32 mCount; + HTMLAttribute mFirst; + nsIAtom* mID; + nsIAtom* mClass; nsMapAttributesFunc mMapper; #ifdef DEBUG_REFS @@ -285,8 +289,10 @@ void HTMLAttributesImpl::operator delete(void* ptr) } -HTMLAttributesImpl::HTMLAttributesImpl(nsMapAttributesFunc aMapFunc) - : mFirst(), +HTMLAttributesImpl::HTMLAttributesImpl(nsIHTMLStyleSheet* aSheet, + nsMapAttributesFunc aMapFunc) + : mSheet(aSheet), + mFirst(), mCount(0), mID(nsnull), mClass(nsnull), @@ -302,7 +308,8 @@ HTMLAttributesImpl::HTMLAttributesImpl(nsMapAttributesFunc aMapFunc) } HTMLAttributesImpl::HTMLAttributesImpl(const HTMLAttributesImpl& aCopy) - : mFirst(aCopy.mFirst), + : mSheet(aCopy.mSheet), + mFirst(aCopy.mFirst), mCount(aCopy.mCount), mID(aCopy.mID), mClass(aCopy.mClass), @@ -803,6 +810,21 @@ HTMLAttributesImpl::MapStyleInto(nsIStyleContext* aContext, nsIPresContext* aPre return NS_OK; } +NS_IMETHODIMP +HTMLAttributesImpl::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + +NS_IMETHODIMP +HTMLAttributesImpl::SetStyleSheet(nsIHTMLStyleSheet* aSheet) +{ // this is not ref-counted, sheet sets to null when it goes away + mSheet = aSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, always 0 here NS_IMETHODIMP HTMLAttributesImpl::GetStrength(PRInt32& aStrength) @@ -840,13 +862,14 @@ HTMLAttributesImpl::List(FILE* out, PRInt32 aIndent) const } extern NS_HTML nsresult - NS_NewHTMLAttributes(nsIHTMLAttributes** aInstancePtrResult, nsMapAttributesFunc aMapFunc) + NS_NewHTMLAttributes(nsIHTMLAttributes** aInstancePtrResult, nsIHTMLStyleSheet* aSheet, + nsMapAttributesFunc aMapFunc) { if (aInstancePtrResult == nsnull) { return NS_ERROR_NULL_POINTER; } - HTMLAttributesImpl *it = new HTMLAttributesImpl(aMapFunc); + HTMLAttributesImpl *it = new HTMLAttributesImpl(aSheet, aMapFunc); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/content/html/style/src/nsHTMLCSSStyleSheet.cpp b/content/html/style/src/nsHTMLCSSStyleSheet.cpp index 38d23a3789f..771c4b3d2a6 100644 --- a/content/html/style/src/nsHTMLCSSStyleSheet.cpp +++ b/content/html/style/src/nsHTMLCSSStyleSheet.cpp @@ -29,6 +29,7 @@ #include "nsICSSStyleRule.h" #include "nsIStyleContext.h" #include "nsIPresContext.h" +#include "nsIDocument.h" static NS_DEFINE_IID(kIHTMLCSSStyleSheetIID, NS_IHTML_CSS_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); @@ -37,22 +38,26 @@ static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); class BodyFixupRule : public nsIStyleRule { public: - BodyFixupRule(); + BodyFixupRule(nsIHTMLCSSStyleSheet* aSheet); ~BodyFixupRule(); NS_DECL_ISUPPORTS NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aValue) const; NS_IMETHOD HashValue(PRUint32& aValue) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; // Strength is an out-of-band weighting, always 0 here NS_IMETHOD GetStrength(PRInt32& aStrength); NS_IMETHOD MapStyleInto(nsIStyleContext* aContext, nsIPresContext* aPresContext); NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + nsIHTMLCSSStyleSheet* mSheet; }; -BodyFixupRule::BodyFixupRule() +BodyFixupRule::BodyFixupRule(nsIHTMLCSSStyleSheet* aSheet) + : mSheet(aSheet) { NS_INIT_REFCNT(); } @@ -77,6 +82,14 @@ BodyFixupRule::HashValue(PRUint32& aValue) const return NS_OK; } +NS_IMETHODIMP +BodyFixupRule::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, always MaxInt here NS_IMETHODIMP BodyFixupRule::GetStrength(PRInt32& aStrength) @@ -115,12 +128,27 @@ public: void* operator new(size_t size, nsIArena* aArena); void operator delete(void* ptr); - HTMLCSSStyleSheetImpl(nsIURL* aURL); + HTMLCSSStyleSheetImpl(nsIURL* aURL, nsIDocument* aDocument); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); + // basic style sheet data + NS_IMETHOD GetURL(nsIURL*& aURL) const; + NS_IMETHOD GetTitle(nsString& aTitle) const; + NS_IMETHOD GetType(nsString& aType) const; + NS_IMETHOD GetMediumCount(PRInt32& aCount) const; + NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsString& aMedium) const; + + NS_IMETHOD GetEnabled(PRBool& aEnabled) const; + NS_IMETHOD SetEnabled(PRBool aEnabled); + + // style sheet owner info + NS_IMETHOD GetParentSheet(nsIStyleSheet*& aParent) const; // will be null + NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; + NS_IMETHOD SetOwningDocument(nsIDocument* aDocument); + virtual PRInt32 RulesMatching(nsIPresContext* aPresContext, nsIContent* aContent, nsIStyleContext* aParentContext, @@ -132,8 +160,6 @@ public: nsIStyleContext* aParentContext, nsISupportsArray* aResults); - virtual nsIURL* GetURL(void); - // XXX style rule enumerations virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; @@ -150,8 +176,9 @@ protected: PRUint32 mInHeap : 1; PRUint32 mRefCnt : 31; - nsIURL* mURL; - nsIStyleRule* mBodyRule; + nsIURL* mURL; + nsIDocument* mDocument; + BodyFixupRule* mBodyRule; }; @@ -191,9 +218,10 @@ void HTMLCSSStyleSheetImpl::operator delete(void* ptr) -HTMLCSSStyleSheetImpl::HTMLCSSStyleSheetImpl(nsIURL* aURL) +HTMLCSSStyleSheetImpl::HTMLCSSStyleSheetImpl(nsIURL* aURL, nsIDocument* aDocument) : nsIHTMLCSSStyleSheet(), mURL(aURL), + mDocument(aDocument), mBodyRule(nsnull) { NS_INIT_REFCNT(); @@ -203,7 +231,10 @@ HTMLCSSStyleSheetImpl::HTMLCSSStyleSheetImpl(nsIURL* aURL) HTMLCSSStyleSheetImpl::~HTMLCSSStyleSheetImpl() { NS_RELEASE(mURL); - NS_IF_RELEASE(mBodyRule); + if (nsnull != mBodyRule) { + mBodyRule->mSheet = nsnull; + NS_RELEASE(mBodyRule); + } } NS_IMPL_ADDREF(HTMLCSSStyleSheetImpl) @@ -274,11 +305,8 @@ PRInt32 HTMLCSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, htmlContent->GetTag(tag); if (tag == nsHTMLAtoms::body) { if (nsnull == mBodyRule) { - BodyFixupRule* bodyRule = new BodyFixupRule(); - if ((nsnull != bodyRule) && - (NS_OK != bodyRule->QueryInterface(kIStyleRuleIID, (void**)&mBodyRule))) { - delete bodyRule; - } + mBodyRule = new BodyFixupRule(this); + NS_IF_ADDREF(mBodyRule); } if (nsnull != mBodyRule) { aResults->AppendElement(mBodyRule); @@ -301,10 +329,78 @@ PRInt32 HTMLCSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, return 0; } -nsIURL* HTMLCSSStyleSheetImpl::GetURL(void) +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetURL(nsIURL*& aURL) const { - NS_ADDREF(mURL); - return mURL; + NS_IF_ADDREF(mURL); + aURL = mURL; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetTitle(nsString& aTitle) const +{ + aTitle.Truncate(); + aTitle.Append("Internal HTML/CSS Style Sheet"); + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetType(nsString& aType) const +{ + aType.Truncate(); + aType.Append("text/html"); + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetMediumCount(PRInt32& aCount) const +{ + aCount = 0; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetMediumAt(PRInt32 aIndex, nsString& aMedium) const +{ + aMedium.Truncate(); + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetEnabled(PRBool& aEnabled) const +{ + aEnabled = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::SetEnabled(PRBool aEnabled) +{ // these can't be disabled + return NS_OK; +} + +// style sheet owner info +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetParentSheet(nsIStyleSheet*& aParent) const +{ + aParent = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetOwningDocument(nsIDocument*& aDocument) const +{ + NS_IF_ADDREF(mDocument); + aDocument = mDocument; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::SetOwningDocument(nsIDocument* aDocument) +{ + mDocument = aDocument; + return NS_OK; } void HTMLCSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const @@ -322,13 +418,14 @@ void HTMLCSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const } NS_HTML nsresult - NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURL* aURL) + NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURL* aURL, + nsIDocument* aDocument) { if (aInstancePtrResult == nsnull) { return NS_ERROR_NULL_POINTER; } - HTMLCSSStyleSheetImpl* it = new HTMLCSSStyleSheetImpl(aURL); + HTMLCSSStyleSheetImpl* it = new HTMLCSSStyleSheetImpl(aURL, aDocument); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/content/html/style/src/nsHTMLStyleSheet.cpp b/content/html/style/src/nsHTMLStyleSheet.cpp index 228eddc7ace..7a0e9b51915 100644 --- a/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/content/html/style/src/nsHTMLStyleSheet.cpp @@ -53,13 +53,14 @@ static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID); class HTMLAnchorRule : public nsIStyleRule { public: - HTMLAnchorRule(); + HTMLAnchorRule(nsIHTMLStyleSheet* aSheet); ~HTMLAnchorRule(); NS_DECL_ISUPPORTS NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aValue) const; NS_IMETHOD HashValue(PRUint32& aValue) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; // Strength is an out-of-band weighting, always 0 here NS_IMETHOD GetStrength(PRInt32& aStrength); @@ -67,10 +68,12 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; - nscolor mColor; + nscolor mColor; + nsIHTMLStyleSheet* mSheet; }; -HTMLAnchorRule::HTMLAnchorRule() +HTMLAnchorRule::HTMLAnchorRule(nsIHTMLStyleSheet* aSheet) + : mSheet(aSheet) { NS_INIT_REFCNT(); } @@ -95,6 +98,14 @@ HTMLAnchorRule::HashValue(PRUint32& aValue) const return NS_OK; } +NS_IMETHODIMP +HTMLAnchorRule::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, always 0 here NS_IMETHODIMP HTMLAnchorRule::GetStrength(PRInt32& aStrength) @@ -201,12 +212,28 @@ public: void* operator new(size_t size, nsIArena* aArena); void operator delete(void* ptr); - HTMLStyleSheetImpl(nsIURL* aURL); + HTMLStyleSheetImpl(nsIURL* aURL, nsIDocument* aDocument); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); + // nsIStyleSheet api + NS_IMETHOD GetURL(nsIURL*& aURL) const; + NS_IMETHOD GetTitle(nsString& aTitle) const; + NS_IMETHOD GetType(nsString& aType) const; + NS_IMETHOD GetMediumCount(PRInt32& aCount) const; + NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsString& aMedium) const; + + NS_IMETHOD GetEnabled(PRBool& aEnabled) const; + NS_IMETHOD SetEnabled(PRBool aEnabled); + + // style sheet owner info + NS_IMETHOD GetParentSheet(nsIStyleSheet*& aParent) const; // will be null + NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; + + NS_IMETHOD SetOwningDocument(nsIDocument* aDocumemt); + virtual PRInt32 RulesMatching(nsIPresContext* aPresContext, nsIContent* aContent, nsIStyleContext* aParentContext, @@ -218,8 +245,6 @@ public: nsIStyleContext* aParentContext, nsISupportsArray* aResults); - virtual nsIURL* GetURL(void); - NS_IMETHOD SetLinkColor(nscolor aColor); NS_IMETHOD SetActiveLinkColor(nscolor aColor); NS_IMETHOD SetVisitedLinkColor(nscolor aColor); @@ -278,7 +303,17 @@ public: nsIAtom* aAttribute, PRInt32 aHint); - // XXX style rule enumerations + // Style change notifications + NS_IMETHOD StyleRuleChanged(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint); // See nsStyleConsts fot hint values + NS_IMETHOD StyleRuleAdded(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + NS_IMETHOD StyleRuleRemoved(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; @@ -361,11 +396,12 @@ protected: PRUint32 mInHeap : 1; PRUint32 mRefCnt : 31; - nsIURL* mURL; - HTMLAnchorRule* mLinkRule; - HTMLAnchorRule* mVisitedRule; - HTMLAnchorRule* mActiveRule; - nsHashtable mAttrTable; + nsIURL* mURL; + nsIDocument* mDocument; + HTMLAnchorRule* mLinkRule; + HTMLAnchorRule* mVisitedRule; + HTMLAnchorRule* mActiveRule; + nsHashtable mAttrTable; nsIHTMLAttributes* mRecycledAttrs; }; @@ -406,9 +442,10 @@ void HTMLStyleSheetImpl::operator delete(void* ptr) -HTMLStyleSheetImpl::HTMLStyleSheetImpl(nsIURL* aURL) +HTMLStyleSheetImpl::HTMLStyleSheetImpl(nsIURL* aURL, nsIDocument* aDocument) : nsIHTMLStyleSheet(), mURL(aURL), + mDocument(aDocument), mLinkRule(nsnull), mVisitedRule(nsnull), mActiveRule(nsnull), @@ -421,9 +458,18 @@ HTMLStyleSheetImpl::HTMLStyleSheetImpl(nsIURL* aURL) HTMLStyleSheetImpl::~HTMLStyleSheetImpl() { NS_RELEASE(mURL); - NS_IF_RELEASE(mLinkRule); - NS_IF_RELEASE(mVisitedRule); - NS_IF_RELEASE(mActiveRule); + if (nsnull != mLinkRule) { + mLinkRule->mSheet = nsnull; + NS_RELEASE(mLinkRule); + } + if (nsnull != mVisitedRule) { + mVisitedRule->mSheet = nsnull; + NS_RELEASE(mVisitedRule); + } + if (nsnull != mActiveRule) { + mActiveRule->mSheet = nsnull; + NS_RELEASE(mActiveRule); + } NS_IF_RELEASE(mRecycledAttrs); } @@ -556,17 +602,85 @@ PRInt32 HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, } -nsIURL* HTMLStyleSheetImpl::GetURL(void) + // nsIStyleSheet api +NS_IMETHODIMP +HTMLStyleSheetImpl::GetURL(nsIURL*& aURL) const { - NS_ADDREF(mURL); - return mURL; + NS_IF_ADDREF(mURL); + aURL = mURL; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetTitle(nsString& aTitle) const +{ + aTitle.Truncate(); + aTitle.Append("Internal HTML Style Sheet"); + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetType(nsString& aType) const +{ + aType.Truncate(); + aType.Append("text/html"); + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetMediumCount(PRInt32& aCount) const +{ + aCount = 0; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetMediumAt(PRInt32 aIndex, nsString& aMedium) const +{ + aMedium.Truncate(); + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetEnabled(PRBool& aEnabled) const +{ + aEnabled = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::SetEnabled(PRBool aEnabled) +{ // these can't be disabled + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetParentSheet(nsIStyleSheet*& aParent) const +{ + aParent = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetOwningDocument(nsIDocument*& aDocument) const +{ + NS_IF_ADDREF(mDocument); + aDocument = mDocument; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::SetOwningDocument(nsIDocument* aDocument) +{ + mDocument = aDocument; + return NS_OK; } NS_IMETHODIMP HTMLStyleSheetImpl::SetLinkColor(nscolor aColor) { if (nsnull == mLinkRule) { - mLinkRule = new HTMLAnchorRule(); + mLinkRule = new HTMLAnchorRule(this); if (nsnull == mLinkRule) { return NS_ERROR_OUT_OF_MEMORY; } @@ -579,7 +693,7 @@ NS_IMETHODIMP HTMLStyleSheetImpl::SetLinkColor(nscolor aColor) NS_IMETHODIMP HTMLStyleSheetImpl::SetActiveLinkColor(nscolor aColor) { if (nsnull == mActiveRule) { - mActiveRule = new HTMLAnchorRule(); + mActiveRule = new HTMLAnchorRule(this); if (nsnull == mActiveRule) { return NS_ERROR_OUT_OF_MEMORY; } @@ -592,7 +706,7 @@ NS_IMETHODIMP HTMLStyleSheetImpl::SetActiveLinkColor(nscolor aColor) NS_IMETHODIMP HTMLStyleSheetImpl::SetVisitedLinkColor(nscolor aColor) { if (nsnull == mVisitedRule) { - mVisitedRule = new HTMLAnchorRule(); + mVisitedRule = new HTMLAnchorRule(this); if (nsnull == mVisitedRule) { return NS_ERROR_OUT_OF_MEMORY; } @@ -712,7 +826,7 @@ HTMLStyleSheetImpl::EnsureSingleAttributes(nsIHTMLAttributes*& aAttributes, aSingleAttrs->SetMappingFunction(aMapFunc); } else { - result = NS_NewHTMLAttributes(&aSingleAttrs, aMapFunc); + result = NS_NewHTMLAttributes(&aSingleAttrs, this, aMapFunc); } } else { @@ -2403,6 +2517,77 @@ HTMLStyleSheetImpl::AttributeChanged(nsIPresContext* aPresContext, return result; } + // Style change notifications +NS_IMETHODIMP +HTMLStyleSheetImpl::StyleRuleChanged(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) +{ + nsIPresShell* shell = aPresContext->GetShell(); + nsIFrame* frame = shell->GetRootFrame(); + + PRBool reframe = PR_FALSE; + PRBool reflow = PR_FALSE; + PRBool render = PR_FALSE; + PRBool restyle = PR_FALSE; + switch (aHint) { + default: + case NS_STYLE_HINT_UNKNOWN: + case NS_STYLE_HINT_FRAMECHANGE: + reframe = PR_TRUE; + case NS_STYLE_HINT_REFLOW: + reflow = PR_TRUE; + case NS_STYLE_HINT_VISUAL: + render = PR_TRUE; + case NS_STYLE_HINT_CONTENT: + restyle = PR_TRUE; + break; + case NS_STYLE_HINT_AURAL: + break; + } + + if (restyle) { + nsIStyleContext* sc; + frame->GetStyleContext(sc); + sc->RemapStyle(aPresContext); + NS_RELEASE(sc); + } + + // XXX hack, skip the root and scrolling frames + frame->FirstChild(nsnull, frame); + frame->FirstChild(nsnull, frame); + if (reframe) { + NS_NOTYETIMPLEMENTED("frame change reflow"); + } + else if (reflow) { + StyleChangeReflow(aPresContext, frame, nsnull); + } + else if (render) { + ApplyRenderingChangeToTree(aPresContext, frame); + } + + NS_RELEASE(shell); + + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::StyleRuleAdded(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::StyleRuleRemoved(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + return NS_OK; +} + void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const { @@ -2419,13 +2604,14 @@ void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const } NS_HTML nsresult -NS_NewHTMLStyleSheet(nsIHTMLStyleSheet** aInstancePtrResult, nsIURL* aURL) +NS_NewHTMLStyleSheet(nsIHTMLStyleSheet** aInstancePtrResult, nsIURL* aURL, + nsIDocument* aDocument) { if (aInstancePtrResult == nsnull) { return NS_ERROR_NULL_POINTER; } - HTMLStyleSheetImpl *it = new HTMLStyleSheetImpl(aURL); + HTMLStyleSheetImpl *it = new HTMLStyleSheetImpl(aURL, aDocument); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/content/html/style/src/nsICSSStyleRule.h b/content/html/style/src/nsICSSStyleRule.h index dc68d7b0483..f4329a1bd6e 100644 --- a/content/html/style/src/nsICSSStyleRule.h +++ b/content/html/style/src/nsICSSStyleRule.h @@ -25,7 +25,7 @@ class nsIAtom; class nsIArena; class nsString; class nsICSSDeclaration; -class nsIStyleSheet; +class nsICSSStyleSheet; struct nsCSSSelector { public: @@ -66,8 +66,7 @@ public: virtual nsIStyleRule* GetImportantRule(void) = 0; - virtual nsIStyleSheet* GetStyleSheet(void) = 0; - virtual void SetStyleSheet(nsIStyleSheet *aSheet) = 0; + NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet) = 0; }; extern NS_HTML nsresult diff --git a/content/html/style/src/nsIHTMLAttributes.h b/content/html/style/src/nsIHTMLAttributes.h index 0e259169dd3..139f9a3c6e7 100644 --- a/content/html/style/src/nsIHTMLAttributes.h +++ b/content/html/style/src/nsIHTMLAttributes.h @@ -25,6 +25,7 @@ class nsIAtom; class nsISizeOfHandler; class nsISupportsArray; +class nsIHTMLStyleSheet; // IID for the nsIHTMLAttributes interface {a18f85f0-c058-11d1-8031-006008159b5a} @@ -66,6 +67,7 @@ public: NS_IMETHOD Clone(nsIHTMLAttributes** aInstancePtrResult) = 0; NS_IMETHOD Reset(void) = 0; NS_IMETHOD SetMappingFunction(nsMapAttributesFunc aMapFunc) = 0; + NS_IMETHOD SetStyleSheet(nsIHTMLStyleSheet* aSheet) = 0; /** * Add this object's size information to the sizeof handler. @@ -76,7 +78,9 @@ public: }; extern NS_HTML nsresult - NS_NewHTMLAttributes(nsIHTMLAttributes** aInstancePtrResult, nsMapAttributesFunc aMapFunc); + NS_NewHTMLAttributes(nsIHTMLAttributes** aInstancePtrResult, + nsIHTMLStyleSheet* aSheet, + nsMapAttributesFunc aMapFunc); #endif /* nsIHTMLAttributes_h___ */ diff --git a/content/html/style/src/nsIHTMLCSSStyleSheet.h b/content/html/style/src/nsIHTMLCSSStyleSheet.h index 9d39c40f5c6..0820df6b817 100644 --- a/content/html/style/src/nsIHTMLCSSStyleSheet.h +++ b/content/html/style/src/nsIHTMLCSSStyleSheet.h @@ -31,6 +31,7 @@ public: }; extern NS_HTML nsresult - NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURL* aURL); + NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURL* aURL, + nsIDocument* aDocument); #endif /* nsIHTMLCSSStyleSheet_h___ */ diff --git a/content/xml/document/src/nsXMLContentSink.cpp b/content/xml/document/src/nsXMLContentSink.cpp index 5bedc97bb92..1ccce3aac1f 100644 --- a/content/xml/document/src/nsXMLContentSink.cpp +++ b/content/xml/document/src/nsXMLContentSink.cpp @@ -18,7 +18,6 @@ */ #include "nsXMLContentSink.h" -#include "nsIStyleSheet.h" #include "nsIUnicharInputStream.h" #include "nsIDocument.h" #include "nsIXMLDocument.h" @@ -38,6 +37,7 @@ #include "nsVoidArray.h" #include "nsCRT.h" #include "nsICSSParser.h" +#include "nsICSSStyleSheet.h" #include "nsHTMLAtoms.h" #include "nsIScriptContext.h" #include "nsIScriptContextOwner.h" @@ -695,36 +695,19 @@ nsXMLContentSink::AddComment(const nsIParserNode& aNode) // XXX Borrowed from HTMLContentSink. Should be shared. nsresult nsXMLContentSink::LoadStyleSheet(nsIURL* aURL, - nsIUnicharInputStream* aUIN, - PRBool aInline) + nsIUnicharInputStream* aUIN) { /* XXX use repository */ nsICSSParser* parser; nsresult rv = NS_NewCSSParser(&parser); if (NS_OK == rv) { - if (aInline && (nsnull != mStyleSheet)) { - parser->SetStyleSheet(mStyleSheet); - // XXX we do probably need to trigger a style change reflow - // when we are finished if this is adding data to the same sheet - } - nsIStyleSheet* sheet = nsnull; + nsICSSStyleSheet* sheet = nsnull; // XXX note: we are ignoring rv until the error code stuff in the // input routines is converted to use nsresult's parser->Parse(aUIN, aURL, sheet); if (nsnull != sheet) { - if (aInline) { - if (nsnull == mStyleSheet) { - // Add in the sheet the first time; if we update the sheet - // with new data (mutliple style tags in the same document) - // then the sheet will be updated by the css parser and - // therefore we don't need to add it to the document) - mDocument->AddStyleSheet(sheet); - mStyleSheet = sheet; - } - } - else { - mDocument->AddStyleSheet(sheet); - } + mDocument->AddStyleSheet(sheet); + NS_RELEASE(sheet); rv = NS_OK; } else { rv = NS_ERROR_OUT_OF_MEMORY;/* XXX */ @@ -827,7 +810,7 @@ nsXMLContentSink::AddProcessingInstruction(const nsIParserNode& aNode) return result; } - result = LoadStyleSheet(url, uin, PR_FALSE); + result = LoadStyleSheet(url, uin); NS_RELEASE(uin); NS_RELEASE(url); } diff --git a/content/xml/document/src/nsXMLContentSink.h b/content/xml/document/src/nsXMLContentSink.h index 5724fd9213a..64f099ce797 100644 --- a/content/xml/document/src/nsXMLContentSink.h +++ b/content/xml/document/src/nsXMLContentSink.h @@ -32,7 +32,6 @@ class nsIContent; class nsVoidArray; class nsIXMLDocument; class nsIUnicharInputStream; -class nsIStyleSheet; typedef enum { eXMLContentSinkState_InProlog, @@ -79,8 +78,7 @@ protected: void StartLayout(); nsresult LoadStyleSheet(nsIURL* aURL, - nsIUnicharInputStream* aUIN, - PRBool aInline); + nsIUnicharInputStream* aUIN); nsresult FlushText(PRBool aCreateTextNode=PR_TRUE, PRBool* aDidFlush=nsnull); @@ -119,7 +117,6 @@ protected: PRInt32 mNestLevel; nsVoidArray* mContentStack; - nsIStyleSheet* mStyleSheet; nsScrollPreference mOriginalScrollPreference; PRUnichar* mText; diff --git a/content/xml/document/src/nsXMLDocument.cpp b/content/xml/document/src/nsXMLDocument.cpp index 7b81022a553..228f0487fcc 100644 --- a/content/xml/document/src/nsXMLDocument.cpp +++ b/content/xml/document/src/nsXMLDocument.cpp @@ -85,7 +85,10 @@ nsXMLDocument::~nsXMLDocument() } mNameSpaces = nsnull; } - NS_IF_RELEASE(mAttrStyleSheet); + if (nsnull != mAttrStyleSheet) { + mAttrStyleSheet->SetOwningDocument(nsnull); + NS_RELEASE(mAttrStyleSheet); + } if (nsnull != mProlog) { delete mProlog; } @@ -136,6 +139,11 @@ nsXMLDocument::StartDocumentLoad(nsIURL *aUrl, return rv; } + if (nsnull != mAttrStyleSheet) { + mAttrStyleSheet->SetOwningDocument(nsnull); + NS_RELEASE(mAttrStyleSheet); + } + nsIWebShell* webShell; static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID); @@ -154,7 +162,7 @@ nsXMLDocument::StartDocumentLoad(nsIURL *aUrl, if (NS_OK == rv) { // For the HTML content within a document - if (NS_OK == NS_NewHTMLStyleSheet(&mAttrStyleSheet, aUrl)) { + if (NS_OK == NS_NewHTMLStyleSheet(&mAttrStyleSheet, aUrl, this)) { AddStyleSheet(mAttrStyleSheet); // tell the world about our new style sheet } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index b82fe864981..50cd0545c57 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -21,6 +21,7 @@ #include "nsIDocument.h" #include "nsIDocumentObserver.h" #include "nsIStyleSet.h" +#include "nsICSSStyleSheet.h" // XXX for UA sheet loading hack, can this go away please? #include "nsIStyleContext.h" #include "nsFrame.h" #include "nsIReflowCommand.h" @@ -193,6 +194,16 @@ public: NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled); + NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint); + NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument); // nsIPresShell @@ -232,6 +243,8 @@ public: protected: ~PresShell(); + nsresult ReconstructFrames(void); + #ifdef NS_DEBUG void VerifyIncrementalReflow(); #endif @@ -902,17 +915,8 @@ PresShell::ContentRemoved(nsIDocument *aDocument, return rv; } -NS_IMETHODIMP -PresShell::StyleSheetAdded(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet) -{ - return NS_OK; -} - -NS_IMETHODIMP -PresShell::StyleSheetDisabledStateChanged(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet, - PRBool aDisabled) +nsresult +PresShell::ReconstructFrames(void) { nsresult rv = NS_OK; if (nsnull != mRootFrame) { @@ -934,6 +938,57 @@ PresShell::StyleSheetDisabledStateChanged(nsIDocument *aDocument, return rv; } +NS_IMETHODIMP +PresShell::StyleSheetAdded(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) +{ + return ReconstructFrames(); +} + +NS_IMETHODIMP +PresShell::StyleSheetDisabledStateChanged(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + PRBool aDisabled) +{ + return ReconstructFrames(); +} + +NS_IMETHODIMP +PresShell::StyleRuleChanged(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) +{ + EnterReflowLock(); + nsresult rv = mStyleSet->StyleRuleChanged(mPresContext, aStyleSheet, + aStyleRule, aHint); + ExitReflowLock(); + return rv; +} + +NS_IMETHODIMP +PresShell::StyleRuleAdded(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + EnterReflowLock(); + nsresult rv = mStyleSet->StyleRuleAdded(mPresContext, aStyleSheet, aStyleRule); + ExitReflowLock(); + return rv; +} + +NS_IMETHODIMP +PresShell::StyleRuleRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + EnterReflowLock(); + nsresult rv = mStyleSet->StyleRuleRemoved(mPresContext, aStyleSheet, aStyleRule); + ExitReflowLock(); + return rv; +} + + NS_IMETHODIMP PresShell::DocumentWillBeDestroyed(nsIDocument *aDocument) { @@ -1116,8 +1171,8 @@ NS_IMETHODIMP PresShell :: ResizeReflow(nsIView *aView, nscoord aWidth, nscoord #include "nsIScrollableView.h" #include "nsIDeviceContext.h" #include "nsIURL.h" -#include "nsICSSParser.h" -#include "nsIStyleSheet.h" +//#include "nsICSSParser.h" +//#include "nsIStyleSheet.h" static NS_DEFINE_IID(kViewManagerCID, NS_VIEW_MANAGER_CID); static NS_DEFINE_IID(kIViewManagerIID, NS_IVIEWMANAGER_IID); diff --git a/layout/base/src/nsContentList.h b/layout/base/src/nsContentList.h index cd4a280d889..be96ee119a9 100644 --- a/layout/base/src/nsContentList.h +++ b/layout/base/src/nsContentList.h @@ -93,6 +93,16 @@ public: NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled) { return NS_OK; } + NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) { return NS_OK; } + NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) { return NS_OK; } + NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) { return NS_OK; } NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument); protected: diff --git a/layout/base/src/nsDocument.cpp b/layout/base/src/nsDocument.cpp index cb8a76fc07c..d348c785e4f 100644 --- a/layout/base/src/nsDocument.cpp +++ b/layout/base/src/nsDocument.cpp @@ -123,6 +123,16 @@ public: NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled) { return NS_OK; } + NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) { return NS_OK; } + NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) { return NS_OK; } + NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) { return NS_OK; } NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument); // nsIScriptObjectOwner interface @@ -438,12 +448,7 @@ nsDocument::~nsDocument() index = mStyleSheets.Count(); while (--index >= 0) { nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(index); - nsICSSStyleSheet* css; - nsresult rv = sheet->QueryInterface(kICSSStyleSheetIID, (void **)&css); - if (NS_SUCCEEDED(rv)) { - css->SetDocument(nsnull); - NS_RELEASE(css); - } + sheet->SetOwningDocument(nsnull); NS_RELEASE(sheet); } @@ -541,12 +546,7 @@ nsDocument::StartDocumentLoad(nsIURL *aURL, PRInt32 index = mStyleSheets.Count(); while (--index >= 0) { nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(index); - nsICSSStyleSheet* css; - nsresult rv = sheet->QueryInterface(kICSSStyleSheetIID, (void **)&css); - if (NS_SUCCEEDED(rv)) { - css->SetDocument(nsnull); - NS_RELEASE(css); - } + sheet->SetOwningDocument(nsnull); NS_RELEASE(sheet); } mStyleSheets.Clear(); @@ -718,33 +718,34 @@ void nsDocument::AddStyleSheet(nsIStyleSheet* aSheet) NS_PRECONDITION(nsnull != aSheet, "null arg"); mStyleSheets.AppendElement(aSheet); NS_ADDREF(aSheet); - nsICSSStyleSheet* css; - nsresult rv = aSheet->QueryInterface(kICSSStyleSheetIID, (void **)&css); - if (NS_SUCCEEDED(rv)) { - css->SetDocument(this); - NS_RELEASE(css); - } + aSheet->SetOwningDocument(this); - PRInt32 count = mPresShells.Count(); - PRInt32 index; - for (index = 0; index < count; index++) { - nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(index); - nsIStyleSet* set = shell->GetStyleSet(); - if (nsnull != set) { - AddStyleSheetToSet(aSheet, set); - NS_RELEASE(set); + PRBool enabled = PR_TRUE; + aSheet->GetEnabled(enabled); + + if (enabled) { + PRInt32 count = mPresShells.Count(); + PRInt32 index; + for (index = 0; index < count; index++) { + nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(index); + nsIStyleSet* set = shell->GetStyleSet(); + if (nsnull != set) { + AddStyleSheetToSet(aSheet, set); + NS_RELEASE(set); + } } - } - count = mObservers.Count(); - for (index = 0; index < count; index++) { - nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index); - observer->StyleSheetAdded(this, aSheet); + // XXX should observers be notified for disabled sheets??? I think not, but I could be wrong + count = mObservers.Count(); + for (index = 0; index < count; index++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index); + observer->StyleSheetAdded(this, aSheet); + } } } void nsDocument::SetStyleSheetDisabledState(nsIStyleSheet* aSheet, - PRBool mDisabled) + PRBool aDisabled) { NS_PRECONDITION(nsnull != aSheet, "null arg"); PRInt32 count; @@ -757,7 +758,7 @@ void nsDocument::SetStyleSheetDisabledState(nsIStyleSheet* aSheet, nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(index); nsIStyleSet* set = shell->GetStyleSet(); if (nsnull != set) { - if (mDisabled) { + if (aDisabled) { set->RemoveDocStyleSheet(aSheet); } else { @@ -771,7 +772,7 @@ void nsDocument::SetStyleSheetDisabledState(nsIStyleSheet* aSheet, count = mObservers.Count(); for (index = 0; index < count; index++) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index); - observer->StyleSheetDisabledStateChanged(this, aSheet, mDisabled); + observer->StyleSheetDisabledStateChanged(this, aSheet, aDisabled); } } @@ -929,6 +930,42 @@ nsDocument::AttributeChanged(nsIContent* aChild, return NS_OK; } + +NS_IMETHODIMP +nsDocument::StyleRuleChanged(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule, + PRInt32 aHint) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->StyleRuleChanged(this, aStyleSheet, aStyleRule, aHint); + } + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::StyleRuleAdded(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->StyleRuleAdded(this, aStyleSheet, aStyleRule); + } + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::StyleRuleRemoved(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->StyleRuleRemoved(this, aStyleSheet, aStyleRule); + } + return NS_OK; +} + + nsresult nsDocument::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject) { nsresult res = NS_OK; diff --git a/layout/base/src/nsDocument.h b/layout/base/src/nsDocument.h index d901bc97458..666fb2c95c8 100644 --- a/layout/base/src/nsDocument.h +++ b/layout/base/src/nsDocument.h @@ -175,6 +175,14 @@ public: nsIContent* aChild, PRInt32 aIndexInContainer); + NS_IMETHOD StyleRuleChanged(nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint); // See nsStyleConsts fot hint values + NS_IMETHOD StyleRuleAdded(nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + NS_IMETHOD StyleRuleRemoved(nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + /** * Returns the Selection Object */ diff --git a/layout/base/src/nsStyleSet.cpp b/layout/base/src/nsStyleSet.cpp index 2a62721ab2e..0c370f78606 100644 --- a/layout/base/src/nsStyleSet.cpp +++ b/layout/base/src/nsStyleSet.cpp @@ -87,14 +87,14 @@ public: nsIStyleContext* aParentContext, PRBool aForceUnique = PR_FALSE); - NS_IMETHODIMP ConstructFrame(nsIPresContext* aPresContext, + NS_IMETHOD ConstructFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIFrame*& aFrameSubTree); + NS_IMETHOD ReconstructFrames(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParentFrame, - nsIFrame*& aFrameSubTree); - NS_IMETHOD ReconstructFrames(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsIFrame* aFrameSubTree); + nsIFrame* aFrameSubTree); NS_IMETHOD ContentAppended(nsIPresContext* aPresContext, nsIContent* aContainer, PRInt32 aNewIndexInContainer); @@ -122,6 +122,18 @@ public: // xxx style rules enumeration + // Style change notifications + NS_IMETHOD StyleRuleChanged(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint); // See nsStyleConsts fot hint values + NS_IMETHOD StyleRuleAdded(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + NS_IMETHOD StyleRuleRemoved(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + virtual void List(FILE* out = stdout, PRInt32 aIndent = 0); private: @@ -727,7 +739,31 @@ StyleSetImpl::AttributeChanged(nsIPresContext* aPresContext, } -// xxx style rules enumeration +// Style change notifications +NS_IMETHODIMP +StyleSetImpl::StyleRuleChanged(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) +{ + return mFrameConstructor->StyleRuleChanged(aPresContext, aStyleSheet, aStyleRule, aHint); +} + +NS_IMETHODIMP +StyleSetImpl::StyleRuleAdded(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + return mFrameConstructor->StyleRuleAdded(aPresContext, aStyleSheet, aStyleRule); +} + +NS_IMETHODIMP +StyleSetImpl::StyleRuleRemoved(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + return mFrameConstructor->StyleRuleRemoved(aPresContext, aStyleSheet, aStyleRule); +} void StyleSetImpl::List(FILE* out, PRInt32 aIndent, nsISupportsArray* aSheets) { diff --git a/layout/html/base/src/nsPresShell.cpp b/layout/html/base/src/nsPresShell.cpp index b82fe864981..50cd0545c57 100644 --- a/layout/html/base/src/nsPresShell.cpp +++ b/layout/html/base/src/nsPresShell.cpp @@ -21,6 +21,7 @@ #include "nsIDocument.h" #include "nsIDocumentObserver.h" #include "nsIStyleSet.h" +#include "nsICSSStyleSheet.h" // XXX for UA sheet loading hack, can this go away please? #include "nsIStyleContext.h" #include "nsFrame.h" #include "nsIReflowCommand.h" @@ -193,6 +194,16 @@ public: NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled); + NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint); + NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument); // nsIPresShell @@ -232,6 +243,8 @@ public: protected: ~PresShell(); + nsresult ReconstructFrames(void); + #ifdef NS_DEBUG void VerifyIncrementalReflow(); #endif @@ -902,17 +915,8 @@ PresShell::ContentRemoved(nsIDocument *aDocument, return rv; } -NS_IMETHODIMP -PresShell::StyleSheetAdded(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet) -{ - return NS_OK; -} - -NS_IMETHODIMP -PresShell::StyleSheetDisabledStateChanged(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet, - PRBool aDisabled) +nsresult +PresShell::ReconstructFrames(void) { nsresult rv = NS_OK; if (nsnull != mRootFrame) { @@ -934,6 +938,57 @@ PresShell::StyleSheetDisabledStateChanged(nsIDocument *aDocument, return rv; } +NS_IMETHODIMP +PresShell::StyleSheetAdded(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) +{ + return ReconstructFrames(); +} + +NS_IMETHODIMP +PresShell::StyleSheetDisabledStateChanged(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + PRBool aDisabled) +{ + return ReconstructFrames(); +} + +NS_IMETHODIMP +PresShell::StyleRuleChanged(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) +{ + EnterReflowLock(); + nsresult rv = mStyleSet->StyleRuleChanged(mPresContext, aStyleSheet, + aStyleRule, aHint); + ExitReflowLock(); + return rv; +} + +NS_IMETHODIMP +PresShell::StyleRuleAdded(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + EnterReflowLock(); + nsresult rv = mStyleSet->StyleRuleAdded(mPresContext, aStyleSheet, aStyleRule); + ExitReflowLock(); + return rv; +} + +NS_IMETHODIMP +PresShell::StyleRuleRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + EnterReflowLock(); + nsresult rv = mStyleSet->StyleRuleRemoved(mPresContext, aStyleSheet, aStyleRule); + ExitReflowLock(); + return rv; +} + + NS_IMETHODIMP PresShell::DocumentWillBeDestroyed(nsIDocument *aDocument) { @@ -1116,8 +1171,8 @@ NS_IMETHODIMP PresShell :: ResizeReflow(nsIView *aView, nscoord aWidth, nscoord #include "nsIScrollableView.h" #include "nsIDeviceContext.h" #include "nsIURL.h" -#include "nsICSSParser.h" -#include "nsIStyleSheet.h" +//#include "nsICSSParser.h" +//#include "nsIStyleSheet.h" static NS_DEFINE_IID(kViewManagerCID, NS_VIEW_MANAGER_CID); static NS_DEFINE_IID(kIViewManagerIID, NS_IVIEWMANAGER_IID); diff --git a/layout/html/content/src/nsGenericElement.cpp b/layout/html/content/src/nsGenericElement.cpp index ece61183fb9..e69de29bb2d 100644 --- a/layout/html/content/src/nsGenericElement.cpp +++ b/layout/html/content/src/nsGenericElement.cpp @@ -1,1978 +0,0 @@ -/* -*- 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 "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * The Original Code is Mozilla Communicator client code. - * - * The Initial Developer of the Original Code is Netscape Communications - * Corporation. Portions created by Netscape are Copyright (C) 1998 - * Netscape Communications Corporation. All Rights Reserved. - */ -#include "nsGenericElement.h" - - -#include "nsIAtom.h" -#include "nsIDocument.h" -#include "nsIDOMAttr.h" -#include "nsIDOMEventReceiver.h" -#include "nsIDOMNamedNodeMap.h" -#include "nsIDOMNodeList.h" -#include "nsIEventListenerManager.h" -#include "nsILinkHandler.h" -#include "nsIScriptContextOwner.h" -#include "nsIScriptGlobalObject.h" -#include "nsIScriptObjectOwner.h" -#include "nsISizeOfHandler.h" -#include "nsISupportsArray.h" -#include "nsIURL.h" -#include "nsFrame.h" -#include "nsIPresShell.h" -#include "nsIView.h" -#include "nsIViewManager.h" -#include "nsString.h" -#include "nsDOMEventsIIDs.h" -#include "nsIEventStateManager.h" -#include "nsDOMEvent.h" -#include "nsIPrivateDOMEvent.h" -#include "nsDOMCID.h" -#include "nsIServiceManager.h" -#include "nsIDOMScriptObjectFactory.h" -#include "nsIDOMCSSStyleDeclaration.h" -#include "nsDOMCSSDeclaration.h" -#include "prprf.h" -#include "prmem.h" - -#include "nsHTMLAtoms.h" -#include "nsIHTMLAttributes.h" - -NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); -NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); -NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID); -NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); -NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID); -NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); -NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID); - -static NS_DEFINE_IID(kIDOMAttrIID, NS_IDOMATTR_IID); -static NS_DEFINE_IID(kIDOMNamedNodeMapIID, NS_IDOMNAMEDNODEMAP_IID); -static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID); -static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID); -static NS_DEFINE_IID(kIDOMCSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID); -static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMNODE_IID); - -//---------------------------------------------------------------------- - -nsDOMAttribute::nsDOMAttribute(const nsString& aName, const nsString& aValue) - : mName(aName), mValue(aValue) -{ - mRefCnt = 1; - mScriptObject = nsnull; -} - -nsDOMAttribute::~nsDOMAttribute() -{ -} - -nsresult -nsDOMAttribute::QueryInterface(REFNSIID aIID, void** aInstancePtr) -{ - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - if (aIID.Equals(kIDOMAttrIID)) { - nsIDOMAttr* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kIScriptObjectOwnerIID)) { - nsIScriptObjectOwner* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kISupportsIID)) { - nsIDOMAttr* tmp1 = this; - nsISupports* tmp2 = tmp1; - *aInstancePtr = (void*)tmp2; - NS_ADDREF_THIS(); - return NS_OK; - } - return NS_NOINTERFACE; -} - -NS_IMPL_ADDREF(nsDOMAttribute) - -NS_IMPL_RELEASE(nsDOMAttribute) - -nsresult -nsDOMAttribute::GetScriptObject(nsIScriptContext *aContext, - void** aScriptObject) -{ - nsresult res = NS_OK; - if (nsnull == mScriptObject) { - res = NS_NewScriptAttr(aContext, - (nsISupports *)(nsIDOMAttr *)this, - nsnull, - (void **)&mScriptObject); - } - *aScriptObject = mScriptObject; - return res; -} - -nsresult -nsDOMAttribute::SetScriptObject(void *aScriptObject) -{ - mScriptObject = aScriptObject; - return NS_OK; -} - -nsresult -nsDOMAttribute::GetName(nsString& aName) -{ - aName = mName; - return NS_OK; -} - -nsresult -nsDOMAttribute::GetValue(nsString& aValue) -{ - aValue = mValue; - return NS_OK; -} - -nsresult -nsDOMAttribute::SetValue(const nsString& aValue) -{ - mValue = aValue; - return NS_OK; -} - -nsresult -nsDOMAttribute::GetSpecified(PRBool* aSpecified) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -nsDOMAttribute::GetNodeName(nsString& aNodeName) -{ - return GetName(aNodeName); -} - -NS_IMETHODIMP -nsDOMAttribute::GetNodeValue(nsString& aNodeValue) -{ - return GetValue(aNodeValue); -} - -NS_IMETHODIMP -nsDOMAttribute::SetNodeValue(const nsString& aNodeValue) -{ - // You can't actually do this, but we'll fail silently - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetNodeType(PRUint16* aNodeType) -{ - *aNodeType = (PRUint16)nsIDOMNode::ATTRIBUTE_NODE; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetParentNode(nsIDOMNode** aParentNode) -{ - *aParentNode = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetChildNodes(nsIDOMNodeList** aChildNodes) -{ - *aChildNodes = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::HasChildNodes(PRBool* aHasChildNodes) -{ - *aHasChildNodes = PR_FALSE; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetFirstChild(nsIDOMNode** aFirstChild) -{ - *aFirstChild = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetLastChild(nsIDOMNode** aLastChild) -{ - *aLastChild = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetPreviousSibling(nsIDOMNode** aPreviousSibling) -{ - *aPreviousSibling = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetNextSibling(nsIDOMNode** aNextSibling) -{ - *aNextSibling = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetAttributes(nsIDOMNamedNodeMap** aAttributes) -{ - *aAttributes = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsDOMAttribute::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsDOMAttribute::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsDOMAttribute::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsDOMAttribute::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) -{ - nsDOMAttribute* newAttr = new nsDOMAttribute(mName, mValue); - if (nsnull == newAttr) { - return NS_ERROR_OUT_OF_MEMORY; - } - - *aReturn = newAttr; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetOwnerDocument(nsIDOMDocument** aOwnerDocument) -{ - // XXX TBI - return NS_OK; -} - -//---------------------------------------------------------------------- - -nsDOMAttributeMap::nsDOMAttributeMap(nsIContent* aContent) - : mContent(aContent) -{ - mRefCnt = 1; - NS_ADDREF(mContent); - mScriptObject = nsnull; -} - -nsDOMAttributeMap::~nsDOMAttributeMap() -{ - NS_RELEASE(mContent); -} - -nsresult -nsDOMAttributeMap::QueryInterface(REFNSIID aIID, void** aInstancePtr) -{ - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - if (aIID.Equals(kIDOMNamedNodeMapIID)) { - nsIDOMNamedNodeMap* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kIScriptObjectOwnerIID)) { - nsIScriptObjectOwner* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kISupportsIID)) { - nsIDOMNamedNodeMap* tmp1 = this; - nsISupports* tmp2 = tmp1; - *aInstancePtr = (void*)tmp2; - NS_ADDREF_THIS(); - return NS_OK; - } - return NS_NOINTERFACE; -} - -NS_IMPL_ADDREF(nsDOMAttributeMap) - -NS_IMPL_RELEASE(nsDOMAttributeMap) - -nsresult -nsDOMAttributeMap::GetScriptObject(nsIScriptContext *aContext, - void** aScriptObject) -{ - nsresult res = NS_OK; - if (nsnull == mScriptObject) { - res = NS_NewScriptNamedNodeMap(aContext, - (nsISupports *)(nsIDOMNamedNodeMap *)this, - nsnull, - (void**)&mScriptObject); - } - *aScriptObject = mScriptObject; - return res; -} - -nsresult -nsDOMAttributeMap::SetScriptObject(void *aScriptObject) -{ - mScriptObject = aScriptObject; - return NS_OK; -} - -nsresult -nsDOMAttributeMap::GetNamedItem(const nsString &aAttrName, - nsIDOMNode** aAttribute) -{ - nsAutoString value; - mContent->GetAttribute(aAttrName, value); - *aAttribute = (nsIDOMNode *) new nsDOMAttribute(aAttrName, value); - return NS_OK; -} - -nsresult -nsDOMAttributeMap::SetNamedItem(nsIDOMNode *aNode, nsIDOMNode **aReturn) -{ - nsIDOMAttr *attribute; - nsAutoString name, value; - nsresult err; - - if (NS_OK != (err = aNode->QueryInterface(kIDOMAttrIID, - (void **)&attribute))) { - return err; - } - - attribute->GetName(name); - attribute->GetValue(value); - NS_RELEASE(attribute); - - mContent->SetAttribute(name, value, PR_TRUE); - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttributeMap::RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn) -{ - nsresult res = GetNamedItem(aName, aReturn); - if (NS_OK == res) { - nsAutoString upper; - aName.ToUpperCase(upper); - nsIAtom* attr = NS_NewAtom(upper); - mContent->UnsetAttribute(attr, PR_TRUE); - } - - return res; -} - -nsresult -nsDOMAttributeMap::Item(PRUint32 aIndex, nsIDOMNode** aReturn) -{ - nsresult res = NS_ERROR_FAILURE; - nsAutoString name, value; - nsISupportsArray *attributes = nsnull; - if (NS_OK == NS_NewISupportsArray(&attributes)) { - PRInt32 count; - mContent->GetAllAttributeNames(attributes, count); - if (count > 0) { - if ((PRInt32)aIndex < count) { - nsISupports *att = attributes->ElementAt(aIndex); - static NS_DEFINE_IID(kIAtom, NS_IATOM_IID); - nsIAtom *atName = nsnull; - if (nsnull != att && NS_OK == att->QueryInterface(kIAtom, (void**)&atName)) { - atName->ToString(name); - if (NS_CONTENT_ATTR_NOT_THERE != mContent->GetAttribute(name, value)) { - *aReturn = (nsIDOMNode *)new nsDOMAttribute(name, value); - res = NS_OK; - } - NS_RELEASE(atName); - } - } - } - NS_RELEASE(attributes); - } - - return res; -} - -nsresult -nsDOMAttributeMap::GetLength(PRUint32 *aLength) -{ - PRInt32 n; - nsresult rv = mContent->GetAttributeCount(n); - *aLength = PRUint32(n); - return rv; -} - -//---------------------------------------------------------------------- - -nsChildContentList::nsChildContentList(nsIContent *aContent) -{ - NS_INIT_REFCNT(); - // This reference is not reference-counted. The content - // object tells us when its about to go away. - mContent = aContent; - mScriptObject = nsnull; -} - -NS_IMPL_ADDREF(nsChildContentList); -NS_IMPL_RELEASE(nsChildContentList); - -nsresult -nsChildContentList::QueryInterface(REFNSIID aIID, void** aInstancePtr) -{ - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - if (aIID.Equals(kIDOMNodeListIID)) { - nsIDOMNodeList* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kIScriptObjectOwnerIID)) { - nsIScriptObjectOwner* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kISupportsIID)) { - nsIDOMNodeList* tmp1 = this; - nsISupports* tmp2 = tmp1; - *aInstancePtr = (void*)tmp2; - NS_ADDREF_THIS(); - return NS_OK; - } - return NS_NOINTERFACE; -} - -nsresult -nsChildContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject) -{ - nsresult res = NS_OK; - if (nsnull == mScriptObject) { - res = NS_NewScriptNodeList(aContext, (nsISupports *)(nsIDOMNodeList *)this, mContent, (void**)&mScriptObject); - } - *aScriptObject = mScriptObject; - return res; -} - -nsresult -nsChildContentList::SetScriptObject(void *aScriptObject) -{ - mScriptObject = aScriptObject; - return NS_OK; -} - -NS_IMETHODIMP -nsChildContentList::GetLength(PRUint32* aLength) -{ - if (nsnull != mContent) { - PRInt32 length; - mContent->ChildCount(length); - *aLength = (PRUint32)length; - } - else { - *aLength = 0; - } - return NS_OK; -} - -NS_IMETHODIMP -nsChildContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn) -{ - nsIContent *content; - nsresult res = NS_OK; - - if (nsnull != mContent) { - mContent->ChildAt(aIndex, content); - if (nsnull != content) { - res = content->QueryInterface(kIDOMNodeIID, (void**)aReturn); - NS_RELEASE(content); - } - else { - *aReturn = nsnull; - } - } - else { - *aReturn = nsnull; - } - - return res; -} - -void -nsChildContentList::DropReference() -{ - mContent = nsnull; -} - -//---------------------------------------------------------------------- - -// XXX Currently, the script object factory is global. The way we -// obtain it should, at least, be made thread-safe later. Ideally, -// we'd find a better way. -nsIDOMScriptObjectFactory* nsGenericElement::gScriptObjectFactory = nsnull; - -static NS_DEFINE_IID(kIDOMScriptObjectFactoryIID, NS_IDOM_SCRIPT_OBJECT_FACTORY_IID); -static NS_DEFINE_IID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID); - -nsresult -nsGenericElement::GetScriptObjectFactory(nsIDOMScriptObjectFactory **aResult) -{ - nsresult result = NS_OK; - - if (nsnull == gScriptObjectFactory) { - result = nsServiceManager::GetService(kDOMScriptObjectFactoryCID, - kIDOMScriptObjectFactoryIID, - (nsISupports **)&gScriptObjectFactory); - if (result != NS_OK) { - return result; - } - } - - *aResult = gScriptObjectFactory; - NS_ADDREF(gScriptObjectFactory); - return result; -} - -nsGenericElement::nsGenericElement() -{ - mDocument = nsnull; - mParent = nsnull; - mTag = nsnull; - mContent = nsnull; - mDOMSlots = nsnull; - mListenerManager = nsnull; -} - -nsGenericElement::~nsGenericElement() -{ - NS_IF_RELEASE(mTag); - NS_IF_RELEASE(mListenerManager); - if (nsnull != mDOMSlots) { - if (nsnull != mDOMSlots->mChildNodes) { - mDOMSlots->mChildNodes->DropReference(); - NS_RELEASE(mDOMSlots->mChildNodes); - } - if (nsnull != mDOMSlots->mStyle) { - mDOMSlots->mStyle->DropReference(); - NS_RELEASE(mDOMSlots->mStyle); - } - // XXX Should really be arena managed - PR_DELETE(mDOMSlots); - } -} - -nsDOMSlots * -nsGenericElement::GetDOMSlots() -{ - if (nsnull == mDOMSlots) { - mDOMSlots = PR_NEW(nsDOMSlots); - mDOMSlots->mScriptObject = nsnull; - mDOMSlots->mChildNodes = nsnull; - mDOMSlots->mStyle = nsnull; - } - - return mDOMSlots; -} - -void -nsGenericElement::Init(nsIContent* aOuterContentObject, - nsIAtom* aTag) -{ - NS_ASSERTION((nsnull == mContent) && (nsnull != aOuterContentObject), - "null ptr"); - mContent = aOuterContentObject; - mTag = aTag; - NS_IF_ADDREF(aTag); -} - -nsresult -nsGenericElement::GetNodeName(nsString& aNodeName) -{ - return GetTagName(aNodeName); -} - -nsresult -nsGenericElement::GetNodeValue(nsString& aNodeValue) -{ - aNodeValue.Truncate(); - return NS_OK; -} - -nsresult -nsGenericElement::SetNodeValue(const nsString& aNodeValue) -{ - return NS_OK; -} - -nsresult -nsGenericElement::GetNodeType(PRUint16* aNodeType) -{ - *aNodeType = (PRUint16)nsIDOMNode::ELEMENT_NODE; - return NS_OK; -} - -nsresult -nsGenericElement::GetParentNode(nsIDOMNode** aParentNode) -{ - if (nsnull != mParent) { - nsresult res = mParent->QueryInterface(kIDOMNodeIID, (void**)aParentNode); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); - return res; - } - else { - *aParentNode = nsnull; - } - return NS_OK; -} - -nsresult -nsGenericElement::GetPreviousSibling(nsIDOMNode** aNode) -{ - if (nsnull != mParent) { - PRInt32 pos; - mParent->IndexOf(mContent, pos); - if (pos > -1) { - nsIContent* prev; - mParent->ChildAt(--pos, prev); - if (nsnull != prev) { - nsresult res = prev->QueryInterface(kIDOMNodeIID, (void**)aNode); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); - NS_RELEASE(prev); // balance the AddRef in ChildAt() - return res; - } - } - } - *aNode = nsnull; - return NS_OK; -} - -nsresult -nsGenericElement::GetNextSibling(nsIDOMNode** aNextSibling) -{ - if (nsnull != mParent) { - PRInt32 pos; - mParent->IndexOf(mContent, pos); - if (pos > -1 ) { - nsIContent* prev; - mParent->ChildAt(++pos, prev); - if (nsnull != prev) { - nsresult res = prev->QueryInterface(kIDOMNodeIID,(void**)aNextSibling); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); - NS_RELEASE(prev); // balance the AddRef in ChildAt() - return res; - } - } - } - *aNextSibling = nsnull; - return NS_OK; -} - -nsresult -nsGenericElement::GetOwnerDocument(nsIDOMDocument** aOwnerDocument) -{ - // XXX Actually the owner document is the document in whose context - // the element has been created. We should be able to get at it - // whether or not we are attached to the document. - if (nsnull != mDocument) { - return mDocument->QueryInterface(kIDOMDocumentIID, (void **)aOwnerDocument); - } - else { - *aOwnerDocument = nsnull; - return NS_OK; - } -} - -nsresult -nsGenericElement::GetAttributes(nsIDOMNamedNodeMap** aAttributes) -{ - NS_PRECONDITION(nsnull != aAttributes, "null pointer argument"); - // XXX Should we create a new one every time or should we - // cache one after we create it? If we find that this is - // something that's called often, we might need to do the - // latter. - *aAttributes = new nsDOMAttributeMap(mContent); - - return NS_OK; -} - -nsresult -nsGenericElement::GetTagName(nsString& aTagName) -{ - aTagName.Truncate(); - if (nsnull != mTag) { - mTag->ToString(aTagName); - } - return NS_OK; -} - -nsresult -nsGenericElement::GetDOMAttribute(const nsString& aName, nsString& aReturn) -{ - mContent->GetAttribute(aName, aReturn); - return NS_OK; -} - -nsresult -nsGenericElement::SetDOMAttribute(const nsString& aName, - const nsString& aValue) -{ - mContent->SetAttribute(aName, aValue, PR_TRUE); - return NS_OK; -} - -nsresult -nsGenericElement::RemoveAttribute(const nsString& aName) -{ - nsAutoString upper; - aName.ToUpperCase(upper); - nsIAtom* attr = NS_NewAtom(upper); - mContent->UnsetAttribute(attr, PR_TRUE); - NS_RELEASE(attr); - return NS_OK; -} - -nsresult -nsGenericElement::GetAttributeNode(const nsString& aName, - nsIDOMAttr** aReturn) -{ - nsAutoString value; - if (NS_CONTENT_ATTR_NOT_THERE != mContent->GetAttribute(aName, value)) { - *aReturn = new nsDOMAttribute(aName, value); - } - return NS_OK; -} - -nsresult -nsGenericElement::SetAttributeNode(nsIDOMAttr* aAttribute, - nsIDOMAttr** aReturn) -{ - NS_PRECONDITION(nsnull != aAttribute, "null attribute"); - - nsresult res = NS_ERROR_FAILURE; - - if (nsnull != aAttribute) { - nsAutoString name, value; - res = aAttribute->GetName(name); - if (NS_OK == res) { - res = aAttribute->GetValue(value); - if (NS_OK == res) { - mContent->SetAttribute(name, value, PR_TRUE); - } - } - } - return res; -} - -nsresult -nsGenericElement::RemoveAttributeNode(nsIDOMAttr* aAttribute, - nsIDOMAttr** aReturn) -{ - NS_PRECONDITION(nsnull != aAttribute, "null attribute"); - - nsresult res = NS_ERROR_FAILURE; - - if (nsnull != aAttribute) { - nsAutoString name; - res = aAttribute->GetName(name); - if (NS_OK == res) { - nsAutoString upper; - name.ToUpperCase(upper); - nsIAtom* attr = NS_NewAtom(upper); - mContent->UnsetAttribute(attr, PR_TRUE); - } - } - - return res; -} - -nsresult -nsGenericElement::GetElementsByTagName(const nsString& aTagname, - nsIDOMNodeList** aReturn) -{ - return NS_ERROR_NOT_IMPLEMENTED;/* XXX */ -} - -nsresult -nsGenericElement::Normalize() -{ - return NS_ERROR_NOT_IMPLEMENTED;/* XXX */ -} - - -nsresult -nsGenericElement::GetDocument(nsIDocument*& aResult) const -{ - NS_IF_ADDREF(mDocument); - aResult = mDocument; - return NS_OK; -} - - -void -nsGenericElement::SetDocumentInChildrenOf(nsIContent* aContent, - nsIDocument* aDocument) -{ - PRInt32 i, n; - aContent->ChildCount(n); - for (i = 0; i < n; i++) { - nsIContent* child; - aContent->ChildAt(i, child); - if (nsnull != child) { - child->SetDocument(aDocument, PR_TRUE); - NS_RELEASE(child); - } - } -} - -nsresult -nsGenericElement::SetDocument(nsIDocument* aDocument, PRBool aDeep) -{ - // If we were part of a document, make sure we get rid of the - // script context reference to our script object so that our - // script object can be freed (or collected). - if ((nsnull != mDocument) && (nsnull != mDOMSlots) && - (nsnull != mDOMSlots->mScriptObject)) { - nsIScriptContextOwner *owner = mDocument->GetScriptContextOwner(); - if (nsnull != owner) { - nsIScriptContext *context; - if (NS_OK == owner->GetScriptContext(&context)) { - context->RemoveReference((void *)&mDOMSlots->mScriptObject, - mDOMSlots->mScriptObject); - NS_RELEASE(context); - } - NS_RELEASE(owner); - } - } - - mDocument = aDocument; - - // If we already have a script object and now we're being added - // to a document, make sure that the script context adds a - // reference to our script object. This will ensure that it - // won't be freed (or collected) out from under us. - if ((nsnull != mDocument) && (nsnull != mDOMSlots) && - (nsnull != mDOMSlots->mScriptObject)) { - nsIScriptContextOwner *owner = mDocument->GetScriptContextOwner(); - if (nsnull != owner) { - nsIScriptContext *context; - if (NS_OK == owner->GetScriptContext(&context)) { - nsAutoString tag; - char tagBuf[50]; - - mTag->ToString(tag); - tag.ToCString(tagBuf, sizeof(tagBuf)); - context->AddNamedReference((void *)&mDOMSlots->mScriptObject, - mDOMSlots->mScriptObject, - tagBuf); - NS_RELEASE(context); - } - NS_RELEASE(owner); - } - } - - if (PR_TRUE == aDeep) { - SetDocumentInChildrenOf(mContent, aDocument); - } - - return NS_OK; -} - - -nsresult -nsGenericElement::GetParent(nsIContent*& aResult) const -{ - NS_IF_ADDREF(mParent); - aResult = mParent; - return NS_OK;; -} - -nsresult -nsGenericElement::SetParent(nsIContent* aParent) -{ - mParent = aParent; - return NS_OK; -} - -nsresult -nsGenericElement::GetTag(nsIAtom*& aResult) const -{ - NS_IF_ADDREF(mTag); - aResult = mTag; - return NS_OK; -} - - -nsresult -nsGenericElement::HandleDOMEvent(nsIPresContext& aPresContext, - nsEvent* aEvent, - nsIDOMEvent** aDOMEvent, - PRUint32 aFlags, - nsEventStatus& aEventStatus) -{ - nsresult ret = NS_OK; - - nsIDOMEvent* domEvent = nsnull; - if (DOM_EVENT_INIT == aFlags) { - aDOMEvent = &domEvent; - } - - //Capturing stage - - //Local handling stage - if (nsnull != mListenerManager) { - mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aEventStatus); - } - - //Bubbling stage - if ((DOM_EVENT_CAPTURE != aFlags) && (mParent != nsnull)) { - ret = mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, - DOM_EVENT_BUBBLE, aEventStatus); - } - - if (DOM_EVENT_INIT == aFlags) { - // We're leaving the DOM event loop so if we created a DOM event, - // release here. - if (nsnull != *aDOMEvent) { - nsrefcnt rc; - NS_RELEASE2(*aDOMEvent, rc); - if (0 != rc) { - // Okay, so someone in the DOM loop (a listener, JS object) - // still has a ref to the DOM Event but the internal data - // hasn't been malloc'd. Force a copy of the data here so the - // DOM Event is still valid. - nsIPrivateDOMEvent *privateEvent; - if (NS_OK == (*aDOMEvent)->QueryInterface(kIPrivateDOMEventIID, (void**)&privateEvent)) { - privateEvent->DuplicatePrivateData(); - NS_RELEASE(privateEvent); - } - } - } - aDOMEvent = nsnull; - } - return ret; -} - -//---------------------------------------------------------------------- - -nsresult -nsGenericElement::RenderFrame() -{ - nsPoint offset; - nsRect bounds; - - // Trigger damage repairs for each frame that maps the given content - PRInt32 i, n; - n = mDocument->GetNumberOfShells(); - for (i = 0; i < n; i++) { - nsIPresShell* shell; - shell = mDocument->GetShellAt(i); - nsIFrame* frame; - frame = shell->FindFrameWithContent(mContent); - while (nsnull != frame) { - nsIViewManager* vm; - nsIView* view; - - // Determine damaged area and tell view manager to redraw it - frame->GetRect(bounds); - bounds.x = bounds.y = 0; - - // XXX We should tell the frame the damage area and let it invalidate - // itself. Add some API calls to nsIFrame to allow a caller to invalidate - // parts of the frame... - frame->GetOffsetFromView(offset, view); - view->GetViewManager(vm); - bounds.x += offset.x; - bounds.y += offset.y; - - vm->UpdateView(view, bounds, NS_VMREFRESH_IMMEDIATE); - NS_RELEASE(vm); - - // If frame has a next-in-flow, repaint it too - frame->GetNextInFlow(frame); - } - NS_RELEASE(shell); - } - - return NS_OK; -} - -//---------------------------------------------------------------------- - -// nsIScriptObjectOwner implementation - -nsresult -nsGenericElement::GetScriptObject(nsIScriptContext* aContext, - void** aScriptObject) -{ - nsresult res = NS_OK; - nsDOMSlots *slots = GetDOMSlots(); - - if (nsnull == slots->mScriptObject) { - nsIDOMScriptObjectFactory *factory; - - res = GetScriptObjectFactory(&factory); - if (NS_OK != res) { - return res; - } - - nsAutoString tag; - mTag->ToString(tag); - res = factory->NewScriptElement(tag, aContext, mContent, - mParent, (void**)&slots->mScriptObject); - NS_RELEASE(factory); - - char tagBuf[50]; - tag.ToCString(tagBuf, sizeof(tagBuf)); - if (nsnull != mDocument) { - aContext->AddNamedReference((void *)&slots->mScriptObject, - slots->mScriptObject, - tagBuf); - } - } - *aScriptObject = slots->mScriptObject; - return res; -} - -nsresult -nsGenericElement::SetScriptObject(void *aScriptObject) -{ - nsDOMSlots *slots = GetDOMSlots(); - - slots->mScriptObject = aScriptObject; - return NS_OK; -} - -//---------------------------------------------------------------------- - -// nsIDOMEventReceiver implementation - -nsresult -nsGenericElement::GetListenerManager(nsIEventListenerManager** aResult) -{ - if (nsnull != mListenerManager) { - NS_ADDREF(mListenerManager); - *aResult = mListenerManager; - return NS_OK; - } - nsresult rv = NS_NewEventListenerManager(aResult); - if (NS_OK == rv) { - mListenerManager = *aResult; - NS_ADDREF(mListenerManager); - } - return rv; -} - -nsresult -nsGenericElement::GetNewListenerManager(nsIEventListenerManager** aResult) -{ - return NS_NewEventListenerManager(aResult); -} - -nsresult -nsGenericElement::AddEventListener(nsIDOMEventListener* aListener, - const nsIID& aIID) -{ - nsIEventListenerManager *manager; - - if (NS_OK == GetListenerManager(&manager)) { - manager->AddEventListener(aListener, aIID); - NS_RELEASE(manager); - return NS_OK; - } - return NS_ERROR_FAILURE; -} - -nsresult -nsGenericElement::RemoveEventListener(nsIDOMEventListener* aListener, - const nsIID& aIID) -{ - if (nsnull != mListenerManager) { - mListenerManager->RemoveEventListener(aListener, aIID); - return NS_OK; - } - return NS_ERROR_FAILURE; -} - -//---------------------------------------------------------------------- - -// nsIJSScriptObject implementation - -PRBool -nsGenericElement::AddProperty(JSContext *aContext, jsval aID, jsval *aVp) -{ - return PR_TRUE; -} - -PRBool -nsGenericElement::DeleteProperty(JSContext *aContext, jsval aID, jsval *aVp) -{ - return PR_TRUE; -} - -PRBool -nsGenericElement::GetProperty(JSContext *aContext, jsval aID, jsval *aVp) -{ - return PR_TRUE; -} - -PRBool -nsGenericElement::SetProperty(JSContext *aContext, jsval aID, jsval *aVp) -{ - nsIScriptObjectOwner *owner; - - if (NS_OK != mContent->QueryInterface(kIScriptObjectOwnerIID, (void **)&owner)) { - return PR_FALSE; - } - - if (JS_TypeOfValue(aContext, *aVp) == JSTYPE_FUNCTION && JSVAL_IS_STRING(aID)) { - nsAutoString propName, prefix; - propName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID))); - prefix.SetString(propName, 2); - if (prefix == "on") { - nsIEventListenerManager *manager = nsnull; - - if (propName == "onmousedown" || propName == "onmouseup" || propName == "onclick" || - propName == "onmouseover" || propName == "onmouseout") { - if (NS_OK == GetListenerManager(&manager)) { - nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMMouseListenerIID)) { - NS_RELEASE(manager); - return PR_FALSE; - } - } - } - else if (propName == "onkeydown" || propName == "onkeyup" || propName == "onkeypress") { - if (NS_OK == GetListenerManager(&manager)) { - nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMKeyListenerIID)) { - NS_RELEASE(manager); - return PR_FALSE; - } - } - } - else if (propName == "onmousemove") { - if (NS_OK == GetListenerManager(&manager)) { - nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMMouseMotionListenerIID)) { - NS_RELEASE(manager); - return PR_FALSE; - } - } - } - else if (propName == "onfocus" || propName == "onblur") { - if (NS_OK == GetListenerManager(&manager)) { - nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMFocusListenerIID)) { - NS_RELEASE(manager); - return PR_FALSE; - } - } - } - else if (propName == "onsubmit" || propName == "onreset" || propName == "onchange") { - if (NS_OK == GetListenerManager(&manager)) { - nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMFormListenerIID)) { - NS_RELEASE(manager); - return PR_FALSE; - } - } - } - else if (propName == "onload" || propName == "onunload" || propName == "onabort" || - propName == "onerror") { - if (NS_OK == GetListenerManager(&manager)) { - nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMLoadListenerIID)) { - NS_RELEASE(manager); - return PR_FALSE; - } - } - } - else if (propName == "onpaint") { - if (NS_OK == GetListenerManager(&manager)) { - nsIScriptContext *mScriptCX = (nsIScriptContext *) - JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, - kIDOMPaintListenerIID)) { - NS_RELEASE(manager); - return PR_FALSE; - } - } - } - NS_IF_RELEASE(manager); - } - } - - NS_IF_RELEASE(owner); - - return PR_TRUE; -} - -PRBool -nsGenericElement::EnumerateProperty(JSContext *aContext) -{ - return PR_TRUE; -} - -PRBool -nsGenericElement::Resolve(JSContext *aContext, jsval aID) -{ - return PR_TRUE; -} - -PRBool -nsGenericElement::Convert(JSContext *aContext, jsval aID) -{ - return PR_TRUE; -} - -void -nsGenericElement::Finalize(JSContext *aContext) -{ -} - -//---------------------------------------------------------------------- - -// nsISupports implementation - -NS_IMETHODIMP -nsGenericElement::QueryInterface(REFNSIID aIID,void** aInstancePtr) -{ - return mContent->QueryInterface(aIID, aInstancePtr); -} - -NS_IMETHODIMP_(nsrefcnt) -nsGenericElement::AddRef() -{ - return NS_ADDREF(mContent); -} - -NS_IMETHODIMP_(nsrefcnt) -nsGenericElement::Release() -{ - nsIContent* content = mContent; - - // Release the copy since the macro will null the pointer. - return NS_RELEASE(content); -} - -//---------------------------------------------------------------------- - -void -nsGenericElement::TriggerLink(nsIPresContext& aPresContext, - nsLinkVerb aVerb, - const nsString& aBase, - const nsString& aURLSpec, - const nsString& aTargetSpec, - PRBool aClick) -{ - nsILinkHandler* handler; - nsresult rv = aPresContext.GetLinkHandler(&handler); - if (NS_SUCCEEDED(rv) && (nsnull != handler)) { - // Resolve url to an absolute url - nsIURL* docURL = nsnull; - nsIDocument* doc; - rv = GetDocument(doc); - if (NS_SUCCEEDED(rv) && (nsnull != doc)) { - docURL = doc->GetDocumentURL(); - NS_RELEASE(doc); - } - - nsAutoString absURLSpec; - if (aURLSpec.Length() > 0) { - nsresult rv = NS_MakeAbsoluteURL(docURL, aBase, aURLSpec, absURLSpec); - } - else { - absURLSpec = aURLSpec; - } - - NS_IF_RELEASE(docURL); - - // Now pass on absolute url to the click handler - if (aClick) { - handler->OnLinkClick(mContent, aVerb, absURLSpec, aTargetSpec); - } - else { - handler->OnOverLink(mContent, absURLSpec, aTargetSpec); - } - NS_RELEASE(handler); - } -} - -nsresult -nsGenericElement::AddScriptEventListener(nsIAtom* aAttribute, - const nsString& aValue, - REFNSIID aIID) -{ - nsresult ret = NS_OK; - nsIScriptContext* context; - nsIScriptContextOwner* owner; - - if (nsnull != mDocument) { - owner = mDocument->GetScriptContextOwner(); - if (NS_OK == owner->GetScriptContext(&context)) { - if (nsHTMLAtoms::body == mTag || nsHTMLAtoms::frameset == mTag) { - nsIDOMEventReceiver *receiver; - nsIScriptGlobalObject *global = context->GetGlobalObject(); - - if (nsnull != global && NS_OK == global->QueryInterface(kIDOMEventReceiverIID, (void**)&receiver)) { - nsIEventListenerManager *manager; - if (NS_OK == receiver->GetListenerManager(&manager)) { - nsIScriptObjectOwner *mObjectOwner; - if (NS_OK == global->QueryInterface(kIScriptObjectOwnerIID, (void**)&mObjectOwner)) { - ret = manager->AddScriptEventListener(context, mObjectOwner, aAttribute, aValue, aIID); - NS_RELEASE(mObjectOwner); - } - NS_RELEASE(manager); - } - NS_RELEASE(receiver); - } - NS_IF_RELEASE(global); - } - else { - nsIEventListenerManager *manager; - if (NS_OK == GetListenerManager(&manager)) { - nsIScriptObjectOwner* owner; - if (NS_OK == mContent->QueryInterface(kIScriptObjectOwnerIID, - (void**) &owner)) { - ret = manager->AddScriptEventListener(context, owner, - aAttribute, aValue, aIID); - NS_RELEASE(owner); - } - NS_RELEASE(manager); - } - } - NS_RELEASE(context); - } - NS_RELEASE(owner); - } - return ret; -} - -//---------------------------------------------------------------------- - -// Nothing for now, though XMLContent might want to define this -// to deal with certain types of attributes with the HTML namespace -static void -MapAttributesInto(nsIHTMLAttributes* aAttributes, - nsIStyleContext* aContext, - nsIPresContext* aPresContext) -{ -} - -// XXX This routine was copied from EnsureWriteableAttributes and -// modified slightly. Could be shared code. -static nsresult EnsureWritableAttributes(nsIContent* aContent, - nsIHTMLAttributes*& aAttributes, - PRBool aCreate) -{ - nsresult result = NS_OK; - - if (nsnull == aAttributes) { - if (PR_TRUE == aCreate) { - if (NS_OK == result) { - result = NS_NewHTMLAttributes(&aAttributes, &MapAttributesInto); - if (NS_OK == result) { - aAttributes->AddContentRef(); - } - } - } - } - else { - // To allow for the case where the attribute set is shared - // between content. - PRInt32 contentRefCount; - aAttributes->GetContentRefCount(contentRefCount); - if (1 < contentRefCount) { - nsIHTMLAttributes* attrs; - result = aAttributes->Clone(&attrs); - if (NS_OK == result) { - aAttributes->ReleaseContentRef(); - NS_RELEASE(aAttributes); - aAttributes = attrs; - aAttributes->AddContentRef(); - } - } - } - return result; -} - -static void ReleaseAttributes(nsIHTMLAttributes*& aAttributes) -{ - aAttributes->ReleaseContentRef(); - NS_RELEASE(aAttributes); -} - -nsGenericContainerElement::nsGenericContainerElement() -{ - mAttributes = nsnull; -} - -nsGenericContainerElement::~nsGenericContainerElement() -{ - PRInt32 n = mChildren.Count(); - for (PRInt32 i = 0; i < n; i++) { - nsIContent* kid = (nsIContent *)mChildren.ElementAt(i); - NS_RELEASE(kid); - } - if (nsnull != mAttributes) { - ReleaseAttributes(mAttributes); - } -} - -nsresult -nsGenericContainerElement::CopyInnerTo(nsIContent* aSrcContent, - nsGenericContainerElement* aDst) -{ - aDst->mContent = aSrcContent; - // XXX should the node's document be set? - // XXX copy attributes not yet impelemented - // XXX deep copy? - return NS_OK; -} - -nsresult -nsGenericContainerElement::GetChildNodes(nsIDOMNodeList** aChildNodes) -{ - nsDOMSlots *slots = GetDOMSlots(); - - if (nsnull == slots->mChildNodes) { - slots->mChildNodes = new nsChildContentList(mContent); - NS_ADDREF(slots->mChildNodes); - } - - return slots->mChildNodes->QueryInterface(kIDOMNodeListIID, (void **)aChildNodes); -} - -nsresult -nsGenericContainerElement::HasChildNodes(PRBool* aReturn) -{ - if (0 != mChildren.Count()) { - *aReturn = PR_TRUE; - } - else { - *aReturn = PR_FALSE; - } - return NS_OK; -} - -nsresult -nsGenericContainerElement::GetFirstChild(nsIDOMNode** aNode) -{ - nsIContent *child = (nsIContent *)mChildren.ElementAt(0); - if (nsnull != child) { - nsresult res = child->QueryInterface(kIDOMNodeIID, (void**)aNode); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); // must be a DOM Node - return res; - } - aNode = nsnull; - return NS_OK; -} - -nsresult -nsGenericContainerElement::GetLastChild(nsIDOMNode** aNode) -{ - nsIContent *child = (nsIContent *)mChildren.ElementAt(mChildren.Count()-1); - if (nsnull != child) { - nsresult res = child->QueryInterface(kIDOMNodeIID, (void**)aNode); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); // must be a DOM Node - return res; - } - aNode = nsnull; - return NS_OK; -} - -// XXX It's possible that newChild has already been inserted in the -// tree; if this is the case then we need to remove it from where it -// was before placing it in it's new home - -nsresult -nsGenericContainerElement::InsertBefore(nsIDOMNode* aNewChild, - nsIDOMNode* aRefChild, - nsIDOMNode** aReturn) -{ - if (nsnull == aNewChild) { - *aReturn = nsnull; - return NS_OK;/* XXX wrong error value */ - } - - // Get the nsIContent interface for the new content - nsIContent* newContent = nsnull; - nsresult res = aNewChild->QueryInterface(kIContentIID, (void**)&newContent); - NS_ASSERTION(NS_OK == res, "New child must be an nsIContent"); - if (NS_OK == res) { - if (nsnull == aRefChild) { - // Append the new child to the end - SetDocumentInChildrenOf(newContent, mDocument); - res = AppendChildTo(newContent, PR_TRUE); - } - else { - // Get the index of where to insert the new child - nsIContent* refContent = nsnull; - res = aRefChild->QueryInterface(kIContentIID, (void**)&refContent); - NS_ASSERTION(NS_OK == res, "Ref child must be an nsIContent"); - if (NS_OK == res) { - PRInt32 pos; - IndexOf(refContent, pos); - if (pos >= 0) { - SetDocumentInChildrenOf(newContent, mDocument); - res = InsertChildAt(newContent, pos, PR_TRUE); - } - NS_RELEASE(refContent); - } - } - NS_RELEASE(newContent); - - *aReturn = aNewChild; - NS_ADDREF(aNewChild); - } - else { - *aReturn = nsnull; - } - - return res; -} - -nsresult -nsGenericContainerElement::ReplaceChild(nsIDOMNode* aNewChild, - nsIDOMNode* aOldChild, - nsIDOMNode** aReturn) -{ - nsIContent* content = nsnull; - *aReturn = nsnull; - nsresult res = aOldChild->QueryInterface(kIContentIID, (void**)&content); - NS_ASSERTION(NS_OK == res, "Must be an nsIContent"); - if (NS_OK == res) { - PRInt32 pos; - IndexOf(content, pos); - if (pos >= 0) { - nsIContent* newContent = nsnull; - nsresult res = aNewChild->QueryInterface(kIContentIID, (void**)&newContent); - NS_ASSERTION(NS_OK == res, "Must be an nsIContent"); - if (NS_OK == res) { - res = ReplaceChildAt(newContent, pos, PR_TRUE); - NS_RELEASE(newContent); - } - *aReturn = aOldChild; - NS_ADDREF(aOldChild); - } - NS_RELEASE(content); - } - - return res; -} - -nsresult -nsGenericContainerElement::RemoveChild(nsIDOMNode* aOldChild, - nsIDOMNode** aReturn) -{ - nsIContent* content = nsnull; - *aReturn = nsnull; - nsresult res = aOldChild->QueryInterface(kIContentIID, (void**)&content); - NS_ASSERTION(NS_OK == res, "Must be an nsIContent"); - if (NS_OK == res) { - PRInt32 pos; - IndexOf(content, pos); - if (pos >= 0) { - res = RemoveChildAt(pos, PR_TRUE); - *aReturn = aOldChild; - NS_ADDREF(aOldChild); - } - NS_RELEASE(content); - } - - return res; -} - -nsresult -nsGenericContainerElement::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) -{ - return InsertBefore(aNewChild, nsnull, aReturn); -} - - -nsresult -nsGenericContainerElement::SetAttribute(const nsString& aName, - const nsString& aValue, - PRBool aNotify) -{ - nsresult rv = NS_OK;; - - nsIAtom* attr = NS_NewAtom(aName); - rv = EnsureWritableAttributes(mContent, mAttributes, PR_TRUE); - if (NS_SUCCEEDED(rv)) { - PRInt32 count; - rv = mAttributes->SetAttribute(attr, aValue, count); - if (0 == count) { - ReleaseAttributes(mAttributes); - } - if (NS_SUCCEEDED(rv) && aNotify && (nsnull != mDocument)) { - mDocument->AttributeChanged(mContent, attr, NS_STYLE_HINT_UNKNOWN); - } - } - NS_RELEASE(attr); - - return rv; -} - -nsresult -nsGenericContainerElement::GetAttribute(const nsString& aName, - nsString& aResult) const -{ - nsresult rv = NS_OK;; - - nsIAtom* attr = NS_NewAtom(aName); - nsHTMLValue value; - char cbuf[20]; - nscolor color; - if (nsnull != mAttributes) { - rv = mAttributes->GetAttribute(attr, value); - if (NS_CONTENT_ATTR_HAS_VALUE == rv) { - // XXX Again this is code that is copied from nsGenericHTMLElement - // and could potentially be shared. In any case, we don't expect - // anything that's not a string. - // Provide default conversions for most everything - switch (value.GetUnit()) { - case eHTMLUnit_Empty: - aResult.Truncate(); - break; - - case eHTMLUnit_String: - case eHTMLUnit_Null: - value.GetStringValue(aResult); - break; - - case eHTMLUnit_Integer: - aResult.Truncate(); - aResult.Append(value.GetIntValue(), 10); - break; - - case eHTMLUnit_Pixel: - aResult.Truncate(); - aResult.Append(value.GetPixelValue(), 10); - break; - - case eHTMLUnit_Percent: - aResult.Truncate(0); - aResult.Append(PRInt32(value.GetPercentValue() * 100.0f), 10); - aResult.Append('%'); - break; - - case eHTMLUnit_Color: - color = nscolor(value.GetColorValue()); - PR_snprintf(cbuf, sizeof(cbuf), "#%02x%02x%02x", - NS_GET_R(color), NS_GET_G(color), NS_GET_B(color)); - aResult.Truncate(0); - aResult.Append(cbuf); - break; - - default: - case eHTMLUnit_Enumerated: - NS_NOTREACHED("no default enumerated value to string conversion"); - rv = NS_CONTENT_ATTR_NOT_THERE; - break; - } - } - } - else { - rv = NS_CONTENT_ATTR_NOT_THERE; - } - NS_RELEASE(attr); - - return rv; -} - -nsresult -nsGenericContainerElement::UnsetAttribute(nsIAtom* aAttribute, PRBool aNotify) -{ - nsresult rv = NS_OK;; - - rv = EnsureWritableAttributes(mContent, mAttributes, PR_FALSE); - if (nsnull != mAttributes) { - PRInt32 count; - rv = mAttributes->UnsetAttribute(aAttribute, count); - if (0 == count) { - ReleaseAttributes(mAttributes); - } - - if (NS_SUCCEEDED(rv) && aNotify && (nsnull != mDocument)) { - mDocument->AttributeChanged(mContent, aAttribute, NS_STYLE_HINT_UNKNOWN); - } - } - - return rv; -} - -nsresult -nsGenericContainerElement::GetAllAttributeNames(nsISupportsArray* aArray, - PRInt32& aCount) const -{ - if (nsnull != mAttributes) { - return mAttributes->GetAllAttributeNames(aArray, aCount); - } - aCount = 0; - return NS_OK; -} - -nsresult -nsGenericContainerElement::GetAttributeCount(PRInt32& aResult) const -{ - if (nsnull != mAttributes) { - return mAttributes->Count(aResult); - } - aResult = 0; - return NS_OK; -} - -void -nsGenericContainerElement::ListAttributes(FILE* out) const -{ - nsISupportsArray* attrs; - if (NS_OK == NS_NewISupportsArray(&attrs)) { - PRInt32 index, count; - GetAllAttributeNames(attrs, count); - for (index = 0; index < count; index++) { - // name - nsIAtom* attr = (nsIAtom*)attrs->ElementAt(index); - nsAutoString buffer; - attr->ToString(buffer); - - // value - nsAutoString value; - GetAttribute(buffer, value); - buffer.Append("="); - buffer.Append(value); - - fputs(" ", out); - fputs(buffer, out); - NS_RELEASE(attr); - } - NS_RELEASE(attrs); - } -} - -nsresult -nsGenericContainerElement::List(FILE* out, PRInt32 aIndent) const -{ - NS_PRECONDITION(nsnull != mDocument, "bad content"); - - PRInt32 index; - for (index = aIndent; --index >= 0; ) fputs(" ", out); - - nsIAtom* tag; - GetTag(tag); - if (tag != nsnull) { - nsAutoString buf; - tag->ToString(buf); - fputs(buf, out); - NS_RELEASE(tag); - } - - ListAttributes(out); - - nsIContent* hc = mContent; - nsrefcnt r = NS_ADDREF(hc) - 1; - NS_RELEASE(hc); - fprintf(out, " refcount=%d<", r); - - PRBool canHaveKids; - mContent->CanContainChildren(canHaveKids); - if (canHaveKids) { - fputs("\n", out); - PRInt32 kids; - mContent->ChildCount(kids); - for (index = 0; index < kids; index++) { - nsIContent* kid; - mContent->ChildAt(index, kid); - kid->List(out, aIndent + 1); - NS_RELEASE(kid); - } - for (index = aIndent; --index >= 0; ) fputs(" ", out); - } - fputs(">\n", out); - - return NS_OK; -} - -nsresult -nsGenericContainerElement::SizeOf(nsISizeOfHandler* aHandler) const -{ - aHandler->Add(sizeof(*this)); - return NS_OK; -} - -nsresult -nsGenericContainerElement::CanContainChildren(PRBool& aResult) const -{ - aResult = PR_TRUE; - return NS_OK; -} - -nsresult -nsGenericContainerElement::ChildCount(PRInt32& aCount) const -{ - aCount = mChildren.Count(); - return NS_OK; -} - -nsresult -nsGenericContainerElement::ChildAt(PRInt32 aIndex, - nsIContent*& aResult) const -{ - nsIContent *child = (nsIContent *)mChildren.ElementAt(aIndex); - if (nsnull != child) { - NS_ADDREF(child); - } - aResult = child; - return NS_OK; -} - -nsresult -nsGenericContainerElement::IndexOf(nsIContent* aPossibleChild, - PRInt32& aIndex) const -{ - NS_PRECONDITION(nsnull != aPossibleChild, "null ptr"); - aIndex = mChildren.IndexOf(aPossibleChild); - return NS_OK; -} - -nsresult -nsGenericContainerElement::InsertChildAt(nsIContent* aKid, - PRInt32 aIndex, - PRBool aNotify) -{ - NS_PRECONDITION(nsnull != aKid, "null ptr"); - PRBool rv = mChildren.InsertElementAt(aKid, aIndex);/* XXX fix up void array api to use nsresult's*/ - if (rv) { - NS_ADDREF(aKid); - aKid->SetParent(mContent); - nsIDocument* doc = mDocument; - if (nsnull != doc) { - aKid->SetDocument(doc, PR_FALSE); - if (aNotify) { - doc->ContentInserted(mContent, aKid, aIndex); - } - } - } - return NS_OK; -} - -nsresult -nsGenericContainerElement::ReplaceChildAt(nsIContent* aKid, - PRInt32 aIndex, - PRBool aNotify) -{ - NS_PRECONDITION(nsnull != aKid, "null ptr"); - nsIContent* oldKid = (nsIContent *)mChildren.ElementAt(aIndex); - PRBool rv = mChildren.ReplaceElementAt(aKid, aIndex); - if (rv) { - NS_ADDREF(aKid); - aKid->SetParent(mContent); - nsIDocument* doc = mDocument; - if (nsnull != doc) { - aKid->SetDocument(doc, PR_FALSE); - if (aNotify) { - doc->ContentReplaced(mContent, oldKid, aKid, aIndex); - } - } - oldKid->SetDocument(nsnull, PR_TRUE); - oldKid->SetParent(nsnull); - NS_RELEASE(oldKid); - } - return NS_OK; -} - -nsresult -nsGenericContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify) -{ - NS_PRECONDITION((nsnull != aKid) && (aKid != mContent), "null ptr"); - PRBool rv = mChildren.AppendElement(aKid); - if (rv) { - NS_ADDREF(aKid); - aKid->SetParent(mContent); - nsIDocument* doc = mDocument; - if (nsnull != doc) { - aKid->SetDocument(doc, PR_FALSE); - if (aNotify) { - doc->ContentAppended(mContent, mChildren.Count() - 1); - } - } - } - return NS_OK; -} - -nsresult -nsGenericContainerElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify) -{ - nsIContent* oldKid = (nsIContent *)mChildren.ElementAt(aIndex); - if (nsnull != oldKid ) { - nsIDocument* doc = mDocument; - PRBool rv = mChildren.RemoveElementAt(aIndex); - if (aNotify) { - if (nsnull != doc) { - doc->ContentRemoved(mContent, oldKid, aIndex); - } - } - oldKid->SetDocument(nsnull, PR_TRUE); - oldKid->SetParent(nsnull); - NS_RELEASE(oldKid); - } - - return NS_OK; -} - -// XXX To be implemented -nsresult -nsGenericContainerElement::BeginConvertToXIF(nsXIFConverter& aConverter) const -{ - return NS_OK; -} - -nsresult -nsGenericContainerElement::ConvertContentToXIF(nsXIFConverter& aConverter) const -{ - return NS_OK; -} - -nsresult -nsGenericContainerElement::FinishConvertToXIF(nsXIFConverter& aConverter) const -{ - return NS_OK; -} diff --git a/layout/html/content/src/nsGenericHTMLElement.cpp b/layout/html/content/src/nsGenericHTMLElement.cpp index 065a5eed10c..01e3a0ac9bd 100644 --- a/layout/html/content/src/nsGenericHTMLElement.cpp +++ b/layout/html/content/src/nsGenericHTMLElement.cpp @@ -197,7 +197,7 @@ static nsresult EnsureWritableAttributes(nsIHTMLContent* aContent, nsMapAttributesFunc mapFunc; result = aContent->GetAttributeMappingFunction(mapFunc); if (NS_OK == result) { - result = NS_NewHTMLAttributes(&aAttributes, mapFunc); + result = NS_NewHTMLAttributes(&aAttributes, nsnull, mapFunc); if (NS_OK == result) { aAttributes->AddContentRef(); } @@ -366,6 +366,7 @@ nsGenericHTMLElement::SetDocument(nsIDocument* aDocument, PRBool aDeep) if ((nsnull != mDocument) && (nsnull != mAttributes)) { nsIHTMLStyleSheet* sheet = GetAttrStyleSheet(mDocument); if (nsnull != sheet) { + mAttributes->SetStyleSheet(sheet); sheet->SetAttributesFor(htmlContent, mAttributes); // sync attributes with sheet NS_RELEASE(sheet); } diff --git a/layout/html/content/src/nsHTMLBodyElement.cpp b/layout/html/content/src/nsHTMLBodyElement.cpp index 725b8b1075f..ac2ea44ac49 100644 --- a/layout/html/content/src/nsHTMLBodyElement.cpp +++ b/layout/html/content/src/nsHTMLBodyElement.cpp @@ -42,7 +42,73 @@ static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID); static NS_DEFINE_IID(kIDOMHTMLBodyElementIID, NS_IDOMHTMLBODYELEMENT_IID); static NS_DEFINE_IID(kIHTMLContentContainerIID, NS_IHTMLCONTENTCONTAINER_IID); -class BodyRule; +//---------------------------------------------------------------------- + +class nsHTMLBodyElement; + +class BodyRule: public nsIStyleRule { +public: + BodyRule(nsHTMLBodyElement* aPart, nsIHTMLStyleSheet* aSheet); + ~BodyRule(); + + NS_DECL_ISUPPORTS + + NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aResult) const; + NS_IMETHOD HashValue(PRUint32& aValue) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; + + // Strength is an out-of-band weighting, always 0 here + NS_IMETHOD GetStrength(PRInt32& aStrength); + + NS_IMETHOD MapStyleInto(nsIStyleContext* aContext, + nsIPresContext* aPresContext); + + NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + nsHTMLBodyElement* mPart; // not ref-counted, cleared by content + nsIHTMLStyleSheet* mSheet; // not ref-counted, cleared by content +}; + +//---------------------------------------------------------------------- + +// special subclass of inner class to override set document +class nsBodyInner: public nsGenericHTMLContainerElement +{ +public: + nsBodyInner(); + ~nsBodyInner(); + + nsresult SetDocument(nsIDocument* aDocument, PRBool aDeep); + + BodyRule* mStyleRule; +}; + +nsBodyInner::nsBodyInner() + : nsGenericHTMLContainerElement(), + mStyleRule(nsnull) +{ +} + +nsBodyInner::~nsBodyInner() +{ + if (nsnull != mStyleRule) { + mStyleRule->mPart = nsnull; + mStyleRule->mSheet = nsnull; + NS_RELEASE(mStyleRule); + } +} + +nsresult nsBodyInner::SetDocument(nsIDocument* aDocument, PRBool aDeep) +{ + if (nsnull != mStyleRule) { + mStyleRule->mPart = nsnull; + mStyleRule->mSheet = nsnull; + NS_RELEASE(mStyleRule); // destroy old style rule since the sheet will probably change + } + return nsGenericHTMLContainerElement::SetDocument(aDocument, aDeep); +} + +//---------------------------------------------------------------------- class nsHTMLBodyElement : public nsIDOMHTMLBodyElement, public nsIScriptObjectOwner, @@ -92,38 +158,19 @@ public: NS_IMPL_IHTMLCONTENT_USING_GENERIC2(mInner) protected: - nsGenericHTMLContainerElement mInner; - BodyRule* mStyleRule; + nsBodyInner mInner; friend BodyRule; }; -class BodyRule: public nsIStyleRule { -public: - BodyRule(nsHTMLBodyElement* aPart); - ~BodyRule(); - - NS_DECL_ISUPPORTS - - NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aResult) const; - NS_IMETHOD HashValue(PRUint32& aValue) const; - // Strength is an out-of-band weighting, always 0 here - NS_IMETHOD GetStrength(PRInt32& aStrength); - - NS_IMETHOD MapStyleInto(nsIStyleContext* aContext, - nsIPresContext* aPresContext); - - NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; - - nsHTMLBodyElement* mPart; -}; //---------------------------------------------------------------------- -BodyRule::BodyRule(nsHTMLBodyElement* aPart) +BodyRule::BodyRule(nsHTMLBodyElement* aPart, nsIHTMLStyleSheet* aSheet) { NS_INIT_REFCNT(); mPart = aPart; + mSheet = aSheet; } BodyRule::~BodyRule() @@ -146,6 +193,14 @@ BodyRule::HashValue(PRUint32& aValue) const return NS_OK; } +NS_IMETHODIMP +BodyRule::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, useful for mapping CSS ! important // always 0 here NS_IMETHODIMP @@ -244,7 +299,6 @@ NS_NewHTMLBodyElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag) } nsHTMLBodyElement::nsHTMLBodyElement(nsIAtom* aTag) - : mStyleRule(nsnull) { NS_INIT_REFCNT(); mInner.Init(this, aTag); @@ -252,10 +306,6 @@ nsHTMLBodyElement::nsHTMLBodyElement(nsIAtom* aTag) nsHTMLBodyElement::~nsHTMLBodyElement() { - if (nsnull != mStyleRule) { - mStyleRule->mPart = nsnull; - NS_RELEASE(mStyleRule); - } } NS_IMPL_ADDREF(nsHTMLBodyElement) @@ -454,14 +504,39 @@ nsHTMLBodyElement::HandleDOMEvent(nsIPresContext& aPresContext, aFlags, aEventStatus); } + +static nsIHTMLStyleSheet* GetAttrStyleSheet(nsIDocument* aDocument) +{ + nsIHTMLStyleSheet* sheet = nsnull; + nsIHTMLContentContainer* htmlContainer; + + if (nsnull != aDocument) { + if (NS_OK == aDocument->QueryInterface(kIHTMLContentContainerIID, (void**)&htmlContainer)) { + htmlContainer->GetAttributeStyleSheet(&sheet); + NS_RELEASE(htmlContainer); + } + } + NS_ASSERTION(nsnull != sheet, "can't get attribute style sheet"); + return sheet; +} + NS_IMETHODIMP nsHTMLBodyElement::GetStyleRule(nsIStyleRule*& aResult) { - if (nsnull == mStyleRule) { - mStyleRule = new BodyRule(this); - NS_IF_ADDREF(mStyleRule); + if (nsnull == mInner.mStyleRule) { + nsIHTMLStyleSheet* sheet = nsnull; + + if (nsnull != mInner.mDocument) { // find style sheet + sheet = GetAttrStyleSheet(mInner.mDocument); + } + + mInner.mStyleRule = new BodyRule(this, sheet); + NS_IF_RELEASE(sheet); + NS_IF_ADDREF(mInner.mStyleRule); } - NS_IF_ADDREF(mStyleRule); - aResult = mStyleRule; + NS_IF_ADDREF(mInner.mStyleRule); + aResult = mInner.mStyleRule; return NS_OK; } + + diff --git a/layout/html/document/src/nsHTMLDocument.cpp b/layout/html/document/src/nsHTMLDocument.cpp index 93741f32f95..ec67affea0f 100644 --- a/layout/html/document/src/nsHTMLDocument.cpp +++ b/layout/html/document/src/nsHTMLDocument.cpp @@ -131,8 +131,14 @@ nsHTMLDocument::~nsHTMLDocument() NS_IF_RELEASE(mEmbeds); NS_IF_RELEASE(mLinks); NS_IF_RELEASE(mAnchors); - NS_IF_RELEASE(mAttrStyleSheet); - NS_IF_RELEASE(mStyleAttrStyleSheet); + if (nsnull != mAttrStyleSheet) { + mAttrStyleSheet->SetOwningDocument(nsnull); + NS_RELEASE(mAttrStyleSheet); + } + if (nsnull != mStyleAttrStyleSheet) { + mStyleAttrStyleSheet->SetOwningDocument(nsnull); + NS_RELEASE(mStyleAttrStyleSheet); + } NS_IF_RELEASE(mParser); for (i = 0; i < mImageMaps.Count(); i++) { nsIImageMap* map = (nsIImageMap*)mImageMaps.ElementAt(i); @@ -208,8 +214,14 @@ nsHTMLDocument::StartDocumentLoad(nsIURL *aURL, nsIWebShell* webShell; - NS_IF_RELEASE(mAttrStyleSheet); - NS_IF_RELEASE(mStyleAttrStyleSheet); + if (nsnull != mAttrStyleSheet) { + mAttrStyleSheet->SetOwningDocument(nsnull); + NS_RELEASE(mAttrStyleSheet); + } + if (nsnull != mStyleAttrStyleSheet) { + mStyleAttrStyleSheet->SetOwningDocument(nsnull); + NS_RELEASE(mStyleAttrStyleSheet); + } static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID); static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID); @@ -231,10 +243,10 @@ nsHTMLDocument::StartDocumentLoad(nsIURL *aURL, #endif if (NS_OK == rv) { - if (NS_OK == NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL)) { + if (NS_OK == NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL, this)) { AddStyleSheet(mAttrStyleSheet); // tell the world about our new style sheet } - if (NS_OK == NS_NewHTMLCSSStyleSheet(&mStyleAttrStyleSheet, aURL)) { + if (NS_OK == NS_NewHTMLCSSStyleSheet(&mStyleAttrStyleSheet, aURL, this)) { AddStyleSheet(mStyleAttrStyleSheet); // tell the world about our new style sheet } diff --git a/layout/html/document/src/nsImageDocument.cpp b/layout/html/document/src/nsImageDocument.cpp index 3f8a617f533..336cf2dca33 100644 --- a/layout/html/document/src/nsImageDocument.cpp +++ b/layout/html/document/src/nsImageDocument.cpp @@ -195,7 +195,7 @@ nsImageDocument::StartDocumentLoad(nsIURL* aURL, // Create style attribute style sheet nsresult rv; nsIHTMLCSSStyleSheet* styleAttrSheet; - rv = NS_NewHTMLCSSStyleSheet(&styleAttrSheet, aURL); + rv = NS_NewHTMLCSSStyleSheet(&styleAttrSheet, aURL, this); if (NS_OK != rv) { return rv; } @@ -203,7 +203,7 @@ nsImageDocument::StartDocumentLoad(nsIURL* aURL, NS_RELEASE(styleAttrSheet); // Create html attribute style sheet - rv = NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL); + rv = NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL, this); if (NS_OK != rv) { return rv; } diff --git a/layout/html/document/src/nsMarkupDocument.cpp b/layout/html/document/src/nsMarkupDocument.cpp index 7184e3fb915..e6121b9b224 100644 --- a/layout/html/document/src/nsMarkupDocument.cpp +++ b/layout/html/document/src/nsMarkupDocument.cpp @@ -192,10 +192,17 @@ void nsMarkupDocument::StyleSheetsToXIF(nsXIFConverter& aConverter) if (sheet != nsnull) { - nsIURL& sheetURL = *sheet->GetURL(); + nsIURL* sheetURL = nsnull; + sheet->GetURL(sheetURL); - if (!(sheetURL == docURL)) + if (nsnull == sheetURL) { break; + } + if (!(*sheetURL == docURL)) { + NS_RELEASE(sheetURL); + break; + } + NS_RELEASE(sheetURL); nsresult isCss = sheet->QueryInterface(kICSSStyleSheetIID, (void**)&cssSheet); if ((isCss == NS_OK) && (cssSheet != nsnull)) diff --git a/layout/html/style/public/nsICSSParser.h b/layout/html/style/public/nsICSSParser.h index 957e5fef2bd..1827c87b485 100644 --- a/layout/html/style/public/nsICSSParser.h +++ b/layout/html/style/public/nsICSSParser.h @@ -21,7 +21,7 @@ #include "nslayout.h" #include "nsISupports.h" class nsIStyleRule; -class nsIStyleSheet; +class nsICSSStyleSheet; class nsIUnicharInputStream; class nsIURL; class nsString; @@ -40,11 +40,11 @@ public: // Set a style sheet for the parser to fill in. The style sheet must // implement the nsICSSStyleSheet interface - NS_IMETHOD SetStyleSheet(nsIStyleSheet* aSheet) = 0; + NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet) = 0; NS_IMETHOD Parse(nsIUnicharInputStream* aInput, - nsIURL* aInputURL, - nsIStyleSheet*& aResult) = 0; + nsIURL* aInputURL, + nsICSSStyleSheet*& aResult) = 0; // Parse declarations assuming that the outer curly braces have // already been accounted for. aBaseURL is the base url to use for diff --git a/layout/html/style/src/nsCSSParser.cpp b/layout/html/style/src/nsCSSParser.cpp index 543f1df1b0a..6ae8f0c3014 100644 --- a/layout/html/style/src/nsCSSParser.cpp +++ b/layout/html/style/src/nsCSSParser.cpp @@ -198,11 +198,11 @@ public: NS_IMETHOD GetInfoMask(PRUint32& aResult); - NS_IMETHOD SetStyleSheet(nsIStyleSheet* aSheet); + NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet); NS_IMETHOD Parse(nsIUnicharInputStream* aInput, - nsIURL* aInputURL, - nsIStyleSheet*& aResult); + nsIURL* aInputURL, + nsICSSStyleSheet*& aResult); NS_IMETHOD ParseDeclarations(const nsString& aDeclaration, nsIURL* aBaseURL, @@ -364,32 +364,27 @@ CSSParserImpl::GetInfoMask(PRUint32& aResult) } NS_METHOD -CSSParserImpl::SetStyleSheet(nsIStyleSheet* aSheet) +CSSParserImpl::SetStyleSheet(nsICSSStyleSheet* aSheet) { NS_PRECONDITION(nsnull != aSheet, "null ptr"); if (nsnull == aSheet) { return NS_ERROR_NULL_POINTER; } - // Make sure the sheet supports the correct interface! - static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID); - nsICSSStyleSheet* cssSheet; - nsresult rv = aSheet->QueryInterface(kICSSStyleSheetIID, (void**)&cssSheet); - if (NS_OK != rv) { - return rv; + if (aSheet != mSheet) { + // Switch to using the new sheet + NS_IF_RELEASE(mSheet); + mSheet = aSheet; + NS_ADDREF(mSheet); } - // Switch to using the new sheet - NS_IF_RELEASE(mSheet); - mSheet = cssSheet; - return NS_OK; } NS_METHOD CSSParserImpl::Parse(nsIUnicharInputStream* aInput, nsIURL* aInputURL, - nsIStyleSheet*& aResult) + nsICSSStyleSheet*& aResult) { if (nsnull == mSheet) { NS_NewCSSStyleSheet(&mSheet, aInputURL); @@ -425,9 +420,8 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput, mScanner = nsnull; NS_IF_RELEASE(mURL); - nsIStyleSheet* sheet = nsnull; - mSheet->QueryInterface(kIStyleSheetIID, (void**)&sheet); - aResult = sheet; + aResult = mSheet; + NS_ADDREF(aResult); return NS_OK; } @@ -711,15 +705,11 @@ NS_IMETHODIMP CSSParserImpl::ProcessImport(const nsString& aURLSpec) nsICSSParser* parser; rv = NS_NewCSSParser(&parser); if (NS_OK == rv) { - nsIStyleSheet* childSheet = nsnull; + nsICSSStyleSheet* childSheet = nsnull; rv = parser->Parse(uin, url, childSheet); NS_RELEASE(parser); if ((NS_OK == rv) && (nsnull != childSheet)) { - nsICSSStyleSheet* cssChild = nsnull; - if (NS_OK == childSheet->QueryInterface(kICSSStyleSheetIID, (void**)&cssChild)) { - mSheet->AppendStyleSheet(cssChild); - NS_RELEASE(cssChild); - } + mSheet->AppendStyleSheet(childSheet); } NS_IF_RELEASE(childSheet); } diff --git a/layout/html/style/src/nsCSSStyleRule.cpp b/layout/html/style/src/nsCSSStyleRule.cpp index dd7eec2b653..0638978d2ef 100644 --- a/layout/html/style/src/nsCSSStyleRule.cpp +++ b/layout/html/style/src/nsCSSStyleRule.cpp @@ -17,9 +17,10 @@ */ #include "nsICSSStyleRule.h" #include "nsICSSDeclaration.h" -#include "nsIStyleSheet.h" +#include "nsICSSStyleSheet.h" #include "nsIStyleContext.h" #include "nsIPresContext.h" +#include "nsIDocument.h" #include "nsIDeviceContext.h" #include "nsIArena.h" #include "nsIAtom.h" @@ -31,8 +32,8 @@ #include "nsStyleUtil.h" #include "nsIFontMetrics.h" #include "nsIDOMCSSStyleSheet.h" +#include "nsIDOMCSSRule.h" #include "nsIDOMCSSStyleRule.h" -#include "nsIDOMCSSStyleRuleSimple.h" #include "nsIDOMCSSStyleDeclaration.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptObjectOwner.h" @@ -45,8 +46,8 @@ static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); static NS_DEFINE_IID(kICSSDeclarationIID, NS_ICSS_DECLARATION_IID); static NS_DEFINE_IID(kICSSStyleRuleIID, NS_ICSS_STYLE_RULE_IID); static NS_DEFINE_IID(kIDOMCSSStyleSheetIID, NS_IDOMCSSSTYLESHEET_IID); +static NS_DEFINE_IID(kIDOMCSSRuleIID, NS_IDOMCSSRULE_IID); static NS_DEFINE_IID(kIDOMCSSStyleRuleIID, NS_IDOMCSSSTYLERULE_IID); -static NS_DEFINE_IID(kIDOMCSSStyleRuleSimpleIID, NS_IDOMCSSSTYLERULESIMPLE_IID); static NS_DEFINE_IID(kIDOMCSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID); static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); @@ -162,15 +163,19 @@ static void MapDeclarationInto(nsICSSDeclaration* aDeclaration, nsIStyleContext* aContext, nsIPresContext* aPresContext); +class CSSStyleRuleImpl; + class CSSImportantRule : public nsIStyleRule { public: - CSSImportantRule(nsICSSDeclaration* aDeclaration); + CSSImportantRule(nsICSSStyleSheet* aSheet, nsICSSDeclaration* aDeclaration); NS_DECL_ISUPPORTS NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aResult) const; NS_IMETHOD HashValue(PRUint32& aValue) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; + // Strength is an out-of-band weighting, useful for mapping CSS ! important NS_IMETHOD GetStrength(PRInt32& aStrength); @@ -182,10 +187,14 @@ protected: ~CSSImportantRule(void); nsICSSDeclaration* mDeclaration; + nsICSSStyleSheet* mSheet; + +friend CSSStyleRuleImpl; }; -CSSImportantRule::CSSImportantRule(nsICSSDeclaration* aDeclaration) - : mDeclaration(aDeclaration) +CSSImportantRule::CSSImportantRule(nsICSSStyleSheet* aSheet, nsICSSDeclaration* aDeclaration) + : mSheet(aSheet), + mDeclaration(aDeclaration) { NS_INIT_REFCNT(); NS_IF_ADDREF(mDeclaration); @@ -212,6 +221,14 @@ CSSImportantRule::HashValue(PRUint32& aValue) const return NS_OK; } +NS_IMETHODIMP +CSSImportantRule::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, useful for mapping CSS ! important NS_IMETHODIMP CSSImportantRule::GetStrength(PRInt32& aStrength) @@ -299,7 +316,18 @@ nsresult DOMCSSDeclarationImpl::StylePropertyChanged(const nsString& aPropertyName, PRInt32 aHint) { - // XXX TBI + nsIStyleSheet* sheet = nsnull; + if (nsnull != mRule) { + mRule->GetStyleSheet(sheet); + if (nsnull != sheet) { + nsIDocument* doc = nsnull; + sheet->GetOwningDocument(doc); + if (nsnull != doc) { + doc->StyleRuleChanged(sheet, mRule, aHint); + } + } + } + return NS_OK; } @@ -316,7 +344,7 @@ DOMCSSDeclarationImpl::GetParent(nsISupports **aParent) // -- nsCSSStyleRule ------------------------------- class CSSStyleRuleImpl : public nsICSSStyleRule, - public nsIDOMCSSStyleRuleSimple, + public nsIDOMCSSStyleRule, public nsIScriptObjectOwner { public: void* operator new(size_t size); @@ -346,20 +374,24 @@ public: virtual nsIStyleRule* GetImportantRule(void); - virtual nsIStyleSheet* GetStyleSheet(void); - virtual void SetStyleSheet(nsIStyleSheet *aSheet); + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; + NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet); NS_IMETHOD MapStyleInto(nsIStyleContext* aContext, nsIPresContext* aPresContext); NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; - // nsIDOMCSSStyleRule interface - NS_IMETHOD GetType(nsString& aType); + // nsIDOMCSSRule interface + NS_IMETHOD GetType(PRUint16* aType); + NS_IMETHOD GetCssText(nsString& aCssText); + NS_IMETHOD SetCssText(const nsString& aCssText); + NS_IMETHOD GetSheet(nsIDOMCSSStyleSheet** aSheet); - // nsIDOMCSSStyleRuleSimple interface + // nsIDOMCSSStyleRule interface NS_IMETHOD GetSelectorText(nsString& aSelectorText); NS_IMETHOD SetSelectorText(const nsString& aSelectorText); NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle); + NS_IMETHOD SetStyle(nsIDOMCSSStyleDeclaration* aStyle); // nsIScriptObjectOwner interface NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); @@ -377,13 +409,13 @@ protected: PRUint32 mInHeap : 1; PRUint32 mRefCnt : 31; - nsCSSSelector mSelector; - nsICSSDeclaration* mDeclaration; - PRInt32 mWeight; - CSSImportantRule* mImportantRule; - nsIStyleSheet* mStyleSheet; - DOMCSSDeclarationImpl *mDOMDeclaration; - void* mScriptObject; + nsCSSSelector mSelector; + nsICSSDeclaration* mDeclaration; + PRInt32 mWeight; + CSSImportantRule* mImportantRule; + nsICSSStyleSheet* mSheet; + DOMCSSDeclarationImpl* mDOMDeclaration; + void* mScriptObject; #ifdef DEBUG_REFS PRInt32 mInstance; #endif @@ -453,7 +485,10 @@ CSSStyleRuleImpl::~CSSStyleRuleImpl() delete selector; } NS_IF_RELEASE(mDeclaration); - NS_IF_RELEASE(mImportantRule); + if (nsnull != mImportantRule) { + mImportantRule->mSheet = nsnull; + NS_RELEASE(mImportantRule); + } if (nsnull != mDOMDeclaration) { mDOMDeclaration->DropReference(); } @@ -505,14 +540,14 @@ nsresult CSSStyleRuleImpl::QueryInterface(const nsIID& aIID, NS_ADDREF_THIS(); return NS_OK; } - if (aIID.Equals(kIDOMCSSStyleRuleIID)) { - nsIDOMCSSStyleRule *tmp = this; + if (aIID.Equals(kIDOMCSSRuleIID)) { + nsIDOMCSSRule *tmp = this; *aInstancePtrResult = (void*) tmp; NS_ADDREF_THIS(); return NS_OK; } - if (aIID.Equals(kIDOMCSSStyleRuleSimpleIID)) { - nsIDOMCSSStyleRuleSimple *tmp = this; + if (aIID.Equals(kIDOMCSSStyleRuleIID)) { + nsIDOMCSSStyleRule *tmp = this; *aInstancePtrResult = (void*) tmp; NS_ADDREF_THIS(); return NS_OK; @@ -637,10 +672,12 @@ nsICSSDeclaration* CSSStyleRuleImpl::GetDeclaration(void) const void CSSStyleRuleImpl::SetDeclaration(nsICSSDeclaration* aDeclaration) { - NS_IF_RELEASE(mImportantRule); - NS_IF_RELEASE(mDeclaration); - mDeclaration = aDeclaration; - NS_IF_ADDREF(mDeclaration); + if (mDeclaration != aDeclaration) { + NS_IF_RELEASE(mImportantRule); + NS_IF_RELEASE(mDeclaration); + mDeclaration = aDeclaration; + NS_IF_ADDREF(mDeclaration); + } } PRInt32 CSSStyleRuleImpl::GetWeight(void) const @@ -659,7 +696,7 @@ nsIStyleRule* CSSStyleRuleImpl::GetImportantRule(void) nsICSSDeclaration* important; mDeclaration->GetImportantValues(important); if (nsnull != important) { - mImportantRule = new CSSImportantRule(important); + mImportantRule = new CSSImportantRule(mSheet, important); NS_ADDREF(mImportantRule); NS_RELEASE(important); } @@ -668,19 +705,25 @@ nsIStyleRule* CSSStyleRuleImpl::GetImportantRule(void) return mImportantRule; } -nsIStyleSheet* CSSStyleRuleImpl::GetStyleSheet(void) +NS_IMETHODIMP +CSSStyleRuleImpl::GetStyleSheet(nsIStyleSheet*& aSheet) const { - NS_IF_ADDREF(mStyleSheet); - - return mStyleSheet; + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; } -void CSSStyleRuleImpl::SetStyleSheet(nsIStyleSheet *aSheet) +NS_IMETHODIMP +CSSStyleRuleImpl::SetStyleSheet(nsICSSStyleSheet* aSheet) { - // XXX We don't reference count this up reference. The style sheet + // We don't reference count this up reference. The style sheet // will tell us when it's going away or when we're detached from // it. - mStyleSheet = aSheet; + mSheet = aSheet; + if (nsnull != mImportantRule) { // we're responsible for this guy too + mImportantRule->mSheet = aSheet; + } + return NS_OK; } nscoord CalcLength(const nsCSSValue& aValue, @@ -1284,8 +1327,8 @@ void MapDeclarationInto(nsICSSDeclaration* aDeclaration, } else if (eCSSUnit_Inherit == ourColor->mBackPositionX.GetUnit()) { color->mBackgroundXPosition = parentColor->mBackgroundXPosition; - color->mBackgroundFlags &= ~NS_STYLE_BG_X_POSITION_LENGTH; - color->mBackgroundFlags |= (parentColor->mBackgroundFlags & NS_STYLE_BG_X_POSITION_PERCENT); + color->mBackgroundFlags &= ~(NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT); + color->mBackgroundFlags |= (parentColor->mBackgroundFlags & (NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT)); } if (eCSSUnit_Percent == ourColor->mBackPositionY.GetUnit()) { @@ -1306,8 +1349,8 @@ void MapDeclarationInto(nsICSSDeclaration* aDeclaration, } else if (eCSSUnit_Inherit == ourColor->mBackPositionY.GetUnit()) { color->mBackgroundYPosition = parentColor->mBackgroundYPosition; - color->mBackgroundFlags &= ~NS_STYLE_BG_Y_POSITION_LENGTH; - color->mBackgroundFlags |= (parentColor->mBackgroundFlags & NS_STYLE_BG_Y_POSITION_PERCENT); + color->mBackgroundFlags &= ~(NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT); + color->mBackgroundFlags |= (parentColor->mBackgroundFlags & (NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT)); } // opacity: factor, percent, inherit @@ -1693,14 +1736,37 @@ CSSStyleRuleImpl::List(FILE* out, PRInt32 aIndent) const } NS_IMETHODIMP -CSSStyleRuleImpl::GetType(nsString& aType) +CSSStyleRuleImpl::GetType(PRUint16* aType) { - // XXX Need to define the different types - aType.SetString("simple"); + *aType = nsIDOMCSSRule::STYLE_RULE; return NS_OK; } +NS_IMETHODIMP +CSSStyleRuleImpl::GetCssText(nsString& aCssText) +{ + // XXX TBI + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleRuleImpl::SetCssText(const nsString& aCssText) +{ + // XXX TBI + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleRuleImpl::GetSheet(nsIDOMCSSStyleSheet** aSheet) +{ + if (nsnull != mSheet) { + return mSheet->QueryInterface(kIDOMCSSStyleSheetIID, (void**)aSheet); + } + *aSheet = nsnull; + return NS_OK; +} + NS_IMETHODIMP CSSStyleRuleImpl::GetSelectorText(nsString& aSelectorText) { @@ -1763,6 +1829,13 @@ CSSStyleRuleImpl::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) return NS_OK; } +NS_IMETHODIMP +CSSStyleRuleImpl::SetStyle(nsIDOMCSSStyleDeclaration* aStyle) +{ + // XXX TBI + return NS_OK; +} + NS_IMETHODIMP CSSStyleRuleImpl::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject) { @@ -1773,10 +1846,10 @@ CSSStyleRuleImpl::GetScriptObject(nsIScriptContext *aContext, void** aScriptObje nsISupports *supports = (nsISupports *)(nsICSSStyleRule *)this; // XXX Parent should be the style sheet // XXX Should be done through factory - res = NS_NewScriptCSSStyleRuleSimple(aContext, - supports, - (nsISupports *)global, - (void**)&mScriptObject); + res = NS_NewScriptCSSStyleRule(aContext, + supports, + (nsISupports *)global, + (void**)&mScriptObject); } *aScriptObject = mScriptObject; diff --git a/layout/html/style/src/nsCSSStyleSheet.cpp b/layout/html/style/src/nsCSSStyleSheet.cpp index b87a220207d..b29516d0d3d 100644 --- a/layout/html/style/src/nsCSSStyleSheet.cpp +++ b/layout/html/style/src/nsCSSStyleSheet.cpp @@ -30,12 +30,14 @@ #include "nsHTMLAtoms.h" #include "nsIFrame.h" #include "nsString.h" +#include "nsVoidArray.h" #include "nsIPtr.h" #include "nsHTMLIIDs.h" #include "nsIDOMStyleSheetCollection.h" #include "nsIDOMCSSStyleSheet.h" #include "nsIDOMCSSStyleRule.h" #include "nsIDOMCSSStyleRuleCollection.h" +#include "nsIDOMNode.h" #include "nsIScriptObjectOwner.h" #include "nsIScriptGlobalObject.h" #include "nsICSSParser.h" @@ -540,6 +542,25 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); + // basic style sheet data + NS_IMETHOD GetURL(nsIURL*& aURL) const; + NS_IMETHOD GetTitle(nsString& aTitle) const; + NS_IMETHOD SetTitle(const nsString& aTitle); + NS_IMETHOD GetType(nsString& aType) const; + NS_IMETHOD GetMediumCount(PRInt32& aCount) const; + NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsString& aMedium) const; + NS_IMETHOD AppendMedium(const nsString& aMedium); + + NS_IMETHOD GetEnabled(PRBool& aEnabled) const; + NS_IMETHOD SetEnabled(PRBool aEnabled); + + // style sheet owner info + NS_IMETHOD GetParentSheet(nsIStyleSheet*& aParent) const; // may be null + NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; + NS_IMETHOD SetOwningDocument(nsIDocument* aDocument); + NS_IMETHOD SetOwningNode(nsIDOMNode* aOwningNode); + + virtual PRInt32 RulesMatching(nsIPresContext* aPresContext, nsIContent* aContent, nsIStyleContext* aParentContext, @@ -551,9 +572,7 @@ public: nsIStyleContext* aParentContext, nsISupportsArray* aResults); - virtual nsIURL* GetURL(void); - - virtual PRBool ContainsStyleSheet(nsIURL* aURL); + virtual PRBool ContainsStyleSheet(nsIURL* aURL) const; virtual void AppendStyleSheet(nsICSSStyleSheet* aSheet); @@ -561,32 +580,29 @@ public: virtual void PrependStyleRule(nsICSSStyleRule* aRule); virtual void AppendStyleRule(nsICSSStyleRule* aRule); - virtual PRInt32 StyleRuleCount(void); - virtual nsresult GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule); + virtual PRInt32 StyleRuleCount(void) const; + virtual nsresult GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule) const; - virtual PRInt32 StyleSheetCount(); - virtual nsresult GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet); - - virtual void SetDocument(nsIDocument *aDocument); + virtual PRInt32 StyleSheetCount(void) const; + virtual nsresult GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const; virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; // nsIDOMStyleSheet interface + NS_IMETHOD GetType(nsString& aType); NS_IMETHOD GetDisabled(PRBool* aDisabled); NS_IMETHOD SetDisabled(PRBool aDisabled); NS_IMETHOD GetReadOnly(PRBool* aReadOnly); // nsIDOMCSSStyleSheet interface - NS_IMETHOD GetOwningElement(nsIDOMHTMLElement** aOwningElement); - NS_IMETHOD GetParentStyleSheet(nsIDOMCSSStyleSheet** aParentStyleSheet); + NS_IMETHOD GetOwningNode(nsIDOMNode** aOwningNode); + NS_IMETHOD GetParentStyleSheet(nsIDOMStyleSheet** aParentStyleSheet); NS_IMETHOD GetHref(nsString& aHref); NS_IMETHOD GetTitle(nsString& aTitle); - NS_IMETHOD GetImports(nsIDOMStyleSheetCollection** aImports); - NS_IMETHOD GetRules(nsIDOMCSSStyleRuleCollection** aRules); - NS_IMETHOD AddRule(const nsString& aSelector, const nsString& aDeclaration, PRUint32 aIndex, PRUint32* aReturn); - NS_IMETHOD AddImport(const nsString& aUrl, PRUint32 aIndex, PRUint32* aReturn); - NS_IMETHOD RemoveRule(PRUint32 aIndex); - NS_IMETHOD RemoveImport(PRUint32 aIndex); + NS_IMETHOD GetMedia(nsString& aMedia); + NS_IMETHOD GetCssRules(nsIDOMCSSStyleRuleCollection** aCssRules); + NS_IMETHOD InsertRule(const nsString& aRule, PRUint32 aIndex, PRUint32* aReturn); + NS_IMETHOD DeleteRule(PRUint32 aIndex); // nsIScriptObjectOwner interface NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); @@ -608,6 +624,8 @@ protected: PRUint32 mRefCnt : 31; nsIURLPtr mURL; + nsString mTitle; + nsVoidArray mMedia; nsICSSStyleSheetPtr mFirstChild; nsISupportsArrayPtr mOrderedRules; nsISupportsArrayPtr mWeightedRules; @@ -617,8 +635,9 @@ protected: CSSStyleRuleCollectionImpl* mRuleCollection; CSSImportsCollectionImpl* mImportsCollection; nsIDocument* mDocument; + nsIDOMNode* mOwningNode; PRBool mDisabled; - void * mScriptObject; + void* mScriptObject; }; @@ -662,7 +681,8 @@ static PRInt32 gInstanceCount; CSSStyleSheetImpl::CSSStyleSheetImpl(nsIURL* aURL) : nsICSSStyleSheet(), - mURL(nsnull), mFirstChild(nsnull), + mURL(nsnull), mTitle(), mMedia(), + mFirstChild(nsnull), mOrderedRules(nsnull), mWeightedRules(nsnull), mNext(nsnull), mRuleHash(nsnull) @@ -673,6 +693,7 @@ CSSStyleSheetImpl::CSSStyleSheetImpl(nsIURL* aURL) mRuleCollection = nsnull; mImportsCollection = nsnull; mDocument = nsnull; + mOwningNode = nsnull; mDisabled = PR_FALSE; mScriptObject = nsnull; #ifdef DEBUG_REFS @@ -698,6 +719,11 @@ CSSStyleSheetImpl::~CSSStyleSheetImpl() --gInstanceCount; fprintf(stdout, "%d - CSSStyleSheet\n", gInstanceCount); #endif + PRInt32 count = mMedia.Count(); + while (0 < count) { + nsString* medium = (nsString*)mMedia.ElementAt(--count); + delete medium; + } if (mFirstChild.IsNotNull()) { nsICSSStyleSheet* child = mFirstChild; while (nsnull != child) { @@ -1084,12 +1110,122 @@ PRInt32 CSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, return matchCount; } -nsIURL* CSSStyleSheetImpl::GetURL(void) +NS_IMETHODIMP +CSSStyleSheetImpl::GetURL(nsIURL*& aURL) const { - return mURL.AddRef(); + nsIURL* url = mURL; + aURL = mURL; + NS_IF_ADDREF(aURL); + return NS_OK; } -PRBool CSSStyleSheetImpl::ContainsStyleSheet(nsIURL* aURL) +NS_IMETHODIMP +CSSStyleSheetImpl::GetTitle(nsString& aTitle) const +{ + aTitle = mTitle; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::SetTitle(const nsString& aTitle) +{ + mTitle = aTitle; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetType(nsString& aType) const +{ + aType.Truncate(); + aType.Append("text/css"); + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetMediumCount(PRInt32& aCount) const +{ + aCount = mMedia.Count(); + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetMediumAt(PRInt32 aIndex, nsString& aMedium) const +{ + nsString* medium = (nsString*)mMedia.ElementAt(aIndex); + if (nsnull != medium) { + aMedium = *medium; + return NS_OK; + } + aMedium.Truncate(); + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::AppendMedium(const nsString& aMedium) +{ + nsString* medium = new nsString(aMedium); + mMedia.AppendElement(medium); + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetEnabled(PRBool& aEnabled) const +{ + aEnabled = ((PR_TRUE == mDisabled) ? PR_FALSE : PR_TRUE); + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::SetEnabled(PRBool aEnabled) +{ + PRBool oldState = mDisabled; + mDisabled = ((PR_TRUE == aEnabled) ? PR_FALSE : PR_TRUE); + + if ((nsnull != mDocument) && (mDisabled != oldState)) { + mDocument->SetStyleSheetDisabledState(this, mDisabled); + } + + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetParentSheet(nsIStyleSheet*& aParent) const +{ + NS_IF_ADDREF(mParent); + aParent = mParent; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetOwningDocument(nsIDocument*& aDocument) const +{ + nsIDocument* doc = mDocument; + CSSStyleSheetImpl* parent = (CSSStyleSheetImpl*)mParent; + while ((nsnull == doc) && (nsnull != parent)) { + doc = parent->mDocument; + parent = (CSSStyleSheetImpl*)(parent->mParent); + } + + NS_IF_ADDREF(doc); + aDocument = doc; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::SetOwningDocument(nsIDocument* aDocument) +{ // not ref counted + mDocument = aDocument; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::SetOwningNode(nsIDOMNode* aOwningNode) +{ // not ref counted + mOwningNode = aOwningNode; + return NS_OK; +} + +PRBool CSSStyleSheetImpl::ContainsStyleSheet(nsIURL* aURL) const { NS_PRECONDITION(nsnull != aURL, "null arg"); @@ -1182,7 +1318,7 @@ void CSSStyleSheetImpl::AppendStyleRule(nsICSSStyleRule* aRule) aRule->SetStyleSheet(this); } -PRInt32 CSSStyleSheetImpl::StyleRuleCount(void) +PRInt32 CSSStyleSheetImpl::StyleRuleCount(void) const { if (mOrderedRules.IsNotNull()) { return mOrderedRules->Count(); @@ -1190,7 +1326,7 @@ PRInt32 CSSStyleSheetImpl::StyleRuleCount(void) return 0; } -nsresult CSSStyleSheetImpl::GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule) +nsresult CSSStyleSheetImpl::GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule) const { nsresult result = NS_ERROR_ILLEGAL_VALUE; @@ -1206,7 +1342,7 @@ nsresult CSSStyleSheetImpl::GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRu return result; } -PRInt32 CSSStyleSheetImpl::StyleSheetCount() +PRInt32 CSSStyleSheetImpl::StyleSheetCount(void) const { // XXX Far from an ideal way to do this, but the hope is that // it won't be done too often. If it is, we might want to @@ -1223,7 +1359,7 @@ PRInt32 CSSStyleSheetImpl::StyleSheetCount() return count; } -nsresult CSSStyleSheetImpl::GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) +nsresult CSSStyleSheetImpl::GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const { // XXX Ughh...an O(n^2) method for doing iteration. Again, we hope // that this isn't done too often. If it is, we need to change the @@ -1243,13 +1379,6 @@ nsresult CSSStyleSheetImpl::GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& a return NS_OK; } -void CSSStyleSheetImpl::SetDocument(nsIDocument *aDocument) -{ - // This reference is not reference counted and should not be - // released. The document will tell us when it goes away. - mDocument = aDocument; -} - void CSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const { nsAutoString buffer; @@ -1303,6 +1432,15 @@ void CSSStyleSheetImpl::BuildHash(void) } } + // nsIDOMStyleSheet interface +NS_IMETHODIMP +CSSStyleSheetImpl::GetType(nsString& aType) +{ + aType.Truncate(); + aType.Append("text/css"); + return NS_OK; +} + NS_IMETHODIMP CSSStyleSheetImpl::GetDisabled(PRBool* aDisabled) { @@ -1313,13 +1451,13 @@ CSSStyleSheetImpl::GetDisabled(PRBool* aDisabled) NS_IMETHODIMP CSSStyleSheetImpl::SetDisabled(PRBool aDisabled) { - - if ((nsnull != mDocument) && (mDisabled != aDisabled)) { - mDocument->SetStyleSheetDisabledState(this, aDisabled); - } - + PRBool oldState = mDisabled; mDisabled = aDisabled; + if ((nsnull != mDocument) && (mDisabled != oldState)) { + mDocument->SetStyleSheetDisabledState(this, mDisabled); + } + return NS_OK; } @@ -1332,18 +1470,18 @@ CSSStyleSheetImpl::GetReadOnly(PRBool* aReadOnly) } NS_IMETHODIMP -CSSStyleSheetImpl::GetOwningElement(nsIDOMHTMLElement** aOwningElement) +CSSStyleSheetImpl::GetOwningNode(nsIDOMNode** aOwningNode) { - // XXX TBI - *aOwningElement = nsnull; + NS_IF_ADDREF(mOwningNode); + *aOwningNode = mOwningNode; return NS_OK; } NS_IMETHODIMP -CSSStyleSheetImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet** aParentStyleSheet) +CSSStyleSheetImpl::GetParentStyleSheet(nsIDOMStyleSheet** aParentStyleSheet) { if (nsnull != mParent) { - return mParent->QueryInterface(kIDOMCSSStyleSheetIID, (void **)aParentStyleSheet); + return mParent->QueryInterface(kIDOMStyleSheetIID, (void **)aParentStyleSheet); } else { *aParentStyleSheet = nsnull; @@ -1364,32 +1502,31 @@ CSSStyleSheetImpl::GetHref(nsString& aHref) return NS_OK; } -NS_IMETHODIMP +NS_IMETHODIMP CSSStyleSheetImpl::GetTitle(nsString& aTitle) { - // XX TBI + aTitle = mTitle; return NS_OK; } -NS_IMETHODIMP -CSSStyleSheetImpl::GetImports(nsIDOMStyleSheetCollection** aImports) +NS_IMETHODIMP +CSSStyleSheetImpl::GetMedia(nsString& aMedia) { - if (nsnull == mImportsCollection) { - mImportsCollection = new CSSImportsCollectionImpl(this); - if (nsnull == mImportsCollection) { - return NS_ERROR_OUT_OF_MEMORY; + aMedia.Truncate(); + PRInt32 count = mMedia.Count(); + PRInt32 index = 0; + while (index < count) { + nsString* medium = (nsString*)mMedia.ElementAt(index++); + aMedia.Append(*medium); + if (index < count) { + aMedia.Append(", "); } - NS_ADDREF(mImportsCollection); } - - *aImports = mImportsCollection; - NS_ADDREF(mImportsCollection); - return NS_OK; } NS_IMETHODIMP -CSSStyleSheetImpl::GetRules(nsIDOMCSSStyleRuleCollection** aRules) +CSSStyleSheetImpl::GetCssRules(nsIDOMCSSStyleRuleCollection** aCssRules) { if (nsnull == mRuleCollection) { mRuleCollection = new CSSStyleRuleCollectionImpl(this); @@ -1399,37 +1536,31 @@ CSSStyleSheetImpl::GetRules(nsIDOMCSSStyleRuleCollection** aRules) NS_ADDREF(mRuleCollection); } - *aRules = mRuleCollection; + *aCssRules = mRuleCollection; NS_ADDREF(mRuleCollection); return NS_OK; } NS_IMETHODIMP -CSSStyleSheetImpl::AddRule(const nsString& aSelector, - const nsString& aDeclaration, - PRUint32 aIndex, - PRUint32* aReturn) +CSSStyleSheetImpl::InsertRule(const nsString& aRule, + PRUint32 aIndex, + PRUint32* aReturn) { nsICSSParser* css; nsresult result = NS_NewCSSParser(&css); if (NS_OK == result) { - nsAutoString str; - str.SetString(aSelector); - // XXX Can we assume that the braces aren't there? - str.Append(" { "); - str.Append(aDeclaration); - str.Append(" } "); - + nsAutoString str(aRule); nsIUnicharInputStream* input = nsnull; result = NS_NewStringUnicharInputStream(&input, &str); if (NS_OK == result) { - nsIStyleSheet *tmp; + nsICSSStyleSheet* tmp; css->SetStyleSheet(this); // XXX Currently, the parser will append the rule to the // style sheet. We shouldn't ignore the index. result = css->Parse(input, mURL, tmp); - NS_ASSERTION(tmp = this, "parser incorrectly created a new stylesheet"); + NS_ASSERTION(tmp == this, "parser incorrectly created a new stylesheet"); + NS_RELEASE(tmp); NS_RELEASE(input); *aReturn = mOrderedRules->Count(); } @@ -1441,21 +1572,9 @@ CSSStyleSheetImpl::AddRule(const nsString& aSelector, } NS_IMETHODIMP -CSSStyleSheetImpl::AddImport(const nsString& aUrl, PRUint32 aIndex, PRUint32* aReturn) -{ - nsICSSParser* css; - nsresult result = NS_NewCSSParser(&css); - if (NS_OK == result) { - css->SetStyleSheet(this); - result = css->ProcessImport(aUrl); - } - - return result; -} - -NS_IMETHODIMP -CSSStyleSheetImpl::RemoveRule(PRUint32 aIndex) +CSSStyleSheetImpl::DeleteRule(PRUint32 aIndex) { + // XXX TBI: handle @rule types nsICSSStyleRule *rule; rule = (nsICSSStyleRule *)mOrderedRules->ElementAt(aIndex); @@ -1469,36 +1588,6 @@ CSSStyleSheetImpl::RemoveRule(PRUint32 aIndex) return NS_OK; } -NS_IMETHODIMP -CSSStyleSheetImpl::RemoveImport(PRUint32 aIndex) -{ - if (mFirstChild.IsNotNull()) { - nsICSSStyleSheet* prev = nsnull; - nsICSSStyleSheet* child = mFirstChild; - while ((nsnull != child) && (0 != aIndex)) { - prev = child; - child = ((CSSStyleSheetImpl*)child)->mNext; - --aIndex; - } - - if ((nsnull != child) && (0 == aIndex)) { - // Hold on to the child while we clean it up - NS_ADDREF(child); - if (nsnull == prev) { - mFirstChild.SetAddRef(((CSSStyleSheetImpl*)child)->mNext); - } - else { - ((CSSStyleSheetImpl*)prev)->mNext.SetAddRef(((CSSStyleSheetImpl*)child)->mNext); - } - ((CSSStyleSheetImpl*)child)->mNext.SetAddRef(nsnull); - ((CSSStyleSheetImpl*)child)->mParent = nsnull; - NS_RELEASE(child); - } - } - - return NS_OK; -} - NS_IMETHODIMP CSSStyleSheetImpl::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject) { diff --git a/layout/html/style/src/nsDOMCSSDeclaration.cpp b/layout/html/style/src/nsDOMCSSDeclaration.cpp index 90e01e5a4b9..600a29cc4be 100644 --- a/layout/html/style/src/nsDOMCSSDeclaration.cpp +++ b/layout/html/style/src/nsDOMCSSDeclaration.cpp @@ -37,6 +37,7 @@ nsDOMCSSDeclaration::~nsDOMCSSDeclaration() NS_IMPL_ADDREF(nsDOMCSSDeclaration); NS_IMPL_RELEASE(nsDOMCSSDeclaration); +static NS_DEFINE_IID(kIDOMCSS2PropertiesIID, NS_IDOMCSS2PROPERTIES_IID); static NS_DEFINE_IID(kIDOMCSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID); static NS_DEFINE_IID(kICSSStyleRuleIID, NS_ICSS_STYLE_RULE_IID); static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); @@ -50,6 +51,12 @@ nsDOMCSSDeclaration::QueryInterface(REFNSIID aIID, if (nsnull == aInstancePtr) { return NS_ERROR_NULL_POINTER; } + if (aIID.Equals(kIDOMCSS2PropertiesIID)) { + nsIDOMCSS2Properties *tmp = this; + AddRef(); + *aInstancePtr = (void*) tmp; + return NS_OK; + } if (aIID.Equals(kIDOMCSSStyleDeclarationIID)) { nsIDOMCSSStyleDeclaration *tmp = this; AddRef(); @@ -83,12 +90,12 @@ nsDOMCSSDeclaration::GetScriptObject(nsIScriptContext* aContext, res = GetParent(&parent); if (NS_OK == res) { - nsISupports *supports = (nsISupports *)(nsIDOMCSSStyleDeclaration *)this; + nsISupports *supports = (nsISupports *)(nsIDOMCSS2Properties *)this; // XXX Should be done through factory - res = NS_NewScriptCSSStyleDeclaration(aContext, - supports, - parent, - (void**)&mScriptObject); + res = NS_NewScriptCSS2Properties(aContext, + supports, + parent, + (void**)&mScriptObject); NS_RELEASE(parent); } } @@ -104,6 +111,20 @@ nsDOMCSSDeclaration::SetScriptObject(void* aScriptObject) return NS_OK; } +NS_IMETHODIMP +nsDOMCSSDeclaration::GetCssText(nsString& aCssText) +{ + // XXX TBI + return NS_OK; +} + +NS_IMETHODIMP +nsDOMCSSDeclaration::SetCssText(const nsString& aCssText) +{ + // XXX TBI + return NS_OK; +} + NS_IMETHODIMP nsDOMCSSDeclaration::GetLength(PRUint32* aLength) { @@ -649,6 +670,18 @@ nsDOMCSSDeclaration::SetCounterReset(const nsString& aCounterReset) return SetProperty("counter-reset", aCounterReset, ""); } +NS_IMETHODIMP +nsDOMCSSDeclaration::GetCssFloat(nsString& aCssFloat) +{ + return GetPropertyValue("float", aCssFloat); +} + +NS_IMETHODIMP +nsDOMCSSDeclaration::SetCssFloat(const nsString& aCssFloat) +{ + return SetProperty("float", aCssFloat, ""); +} + NS_IMETHODIMP nsDOMCSSDeclaration::GetCue(nsString& aCue) { @@ -745,18 +778,6 @@ nsDOMCSSDeclaration::SetEmptyCells(const nsString& aEmptyCells) return SetProperty("empty-cells", aEmptyCells, ""); } -NS_IMETHODIMP -nsDOMCSSDeclaration::GetStyleFloat(nsString& aStyleFloat) -{ - return GetPropertyValue("style-float", aStyleFloat); -} - -NS_IMETHODIMP -nsDOMCSSDeclaration::SetStyleFloat(const nsString& aStyleFloat) -{ - return SetProperty("style-float", aStyleFloat, ""); -} - NS_IMETHODIMP nsDOMCSSDeclaration::GetFont(nsString& aFont) { diff --git a/layout/html/style/src/nsDOMCSSDeclaration.h b/layout/html/style/src/nsDOMCSSDeclaration.h index acae956973a..606a5172c5a 100644 --- a/layout/html/style/src/nsDOMCSSDeclaration.h +++ b/layout/html/style/src/nsDOMCSSDeclaration.h @@ -20,12 +20,12 @@ #define nsDOMCSSSDeclaration_h___ #include "nsISupports.h" -#include "nsIDOMCSSStyleDeclaration.h" +#include "nsIDOMCSS2Properties.h" #include "nsIScriptObjectOwner.h" class nsICSSDeclaration; -class nsDOMCSSDeclaration : public nsIDOMCSSStyleDeclaration, +class nsDOMCSSDeclaration : public nsIDOMCSS2Properties, public nsIScriptObjectOwner { public: @@ -34,6 +34,8 @@ public: NS_DECL_ISUPPORTS NS_DECL_IDOMCSSSTYLEDECLARATION + + NS_DECL_IDOMCSS2PROPERTIES // nsIScriptObjectOwner interface NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); diff --git a/layout/html/style/src/nsHTMLAttributes.cpp b/layout/html/style/src/nsHTMLAttributes.cpp index 80321b0df46..f981f59d675 100644 --- a/layout/html/style/src/nsHTMLAttributes.cpp +++ b/layout/html/style/src/nsHTMLAttributes.cpp @@ -17,6 +17,7 @@ */ #include "nsIHTMLAttributes.h" +#include "nsIHTMLStyleSheet.h" #include "nsIStyleRule.h" #include "nsString.h" #include "nsISupportsArray.h" @@ -171,7 +172,7 @@ public: void* operator new(size_t size, nsIArena* aArena); void operator delete(void* ptr); - HTMLAttributesImpl(nsMapAttributesFunc aMapFunc); + HTMLAttributesImpl(nsIHTMLStyleSheet* aSheet, nsMapAttributesFunc aMapFunc); HTMLAttributesImpl(const HTMLAttributesImpl& aCopy); ~HTMLAttributesImpl(void); @@ -212,6 +213,8 @@ public: // nsIStyleRule NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aResult) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; + NS_IMETHOD SetStyleSheet(nsIHTMLStyleSheet* aSheet); // Strength is an out-of-band weighting, always 0 here NS_IMETHOD GetStrength(PRInt32& aStrength); NS_IMETHOD MapStyleInto(nsIStyleContext* aContext, nsIPresContext* aPresContext); @@ -231,11 +234,12 @@ protected: PRUint32 mInHeap : 1; PRUint32 mRefCnt : 31; - PRInt32 mContentRefCount; - PRInt32 mCount; - HTMLAttribute mFirst; - nsIAtom* mID; - nsIAtom* mClass; + nsIHTMLStyleSheet* mSheet; + PRInt32 mContentRefCount; + PRInt32 mCount; + HTMLAttribute mFirst; + nsIAtom* mID; + nsIAtom* mClass; nsMapAttributesFunc mMapper; #ifdef DEBUG_REFS @@ -285,8 +289,10 @@ void HTMLAttributesImpl::operator delete(void* ptr) } -HTMLAttributesImpl::HTMLAttributesImpl(nsMapAttributesFunc aMapFunc) - : mFirst(), +HTMLAttributesImpl::HTMLAttributesImpl(nsIHTMLStyleSheet* aSheet, + nsMapAttributesFunc aMapFunc) + : mSheet(aSheet), + mFirst(), mCount(0), mID(nsnull), mClass(nsnull), @@ -302,7 +308,8 @@ HTMLAttributesImpl::HTMLAttributesImpl(nsMapAttributesFunc aMapFunc) } HTMLAttributesImpl::HTMLAttributesImpl(const HTMLAttributesImpl& aCopy) - : mFirst(aCopy.mFirst), + : mSheet(aCopy.mSheet), + mFirst(aCopy.mFirst), mCount(aCopy.mCount), mID(aCopy.mID), mClass(aCopy.mClass), @@ -803,6 +810,21 @@ HTMLAttributesImpl::MapStyleInto(nsIStyleContext* aContext, nsIPresContext* aPre return NS_OK; } +NS_IMETHODIMP +HTMLAttributesImpl::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + +NS_IMETHODIMP +HTMLAttributesImpl::SetStyleSheet(nsIHTMLStyleSheet* aSheet) +{ // this is not ref-counted, sheet sets to null when it goes away + mSheet = aSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, always 0 here NS_IMETHODIMP HTMLAttributesImpl::GetStrength(PRInt32& aStrength) @@ -840,13 +862,14 @@ HTMLAttributesImpl::List(FILE* out, PRInt32 aIndent) const } extern NS_HTML nsresult - NS_NewHTMLAttributes(nsIHTMLAttributes** aInstancePtrResult, nsMapAttributesFunc aMapFunc) + NS_NewHTMLAttributes(nsIHTMLAttributes** aInstancePtrResult, nsIHTMLStyleSheet* aSheet, + nsMapAttributesFunc aMapFunc) { if (aInstancePtrResult == nsnull) { return NS_ERROR_NULL_POINTER; } - HTMLAttributesImpl *it = new HTMLAttributesImpl(aMapFunc); + HTMLAttributesImpl *it = new HTMLAttributesImpl(aSheet, aMapFunc); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/layout/html/style/src/nsHTMLCSSStyleSheet.cpp b/layout/html/style/src/nsHTMLCSSStyleSheet.cpp index 38d23a3789f..771c4b3d2a6 100644 --- a/layout/html/style/src/nsHTMLCSSStyleSheet.cpp +++ b/layout/html/style/src/nsHTMLCSSStyleSheet.cpp @@ -29,6 +29,7 @@ #include "nsICSSStyleRule.h" #include "nsIStyleContext.h" #include "nsIPresContext.h" +#include "nsIDocument.h" static NS_DEFINE_IID(kIHTMLCSSStyleSheetIID, NS_IHTML_CSS_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); @@ -37,22 +38,26 @@ static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); class BodyFixupRule : public nsIStyleRule { public: - BodyFixupRule(); + BodyFixupRule(nsIHTMLCSSStyleSheet* aSheet); ~BodyFixupRule(); NS_DECL_ISUPPORTS NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aValue) const; NS_IMETHOD HashValue(PRUint32& aValue) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; // Strength is an out-of-band weighting, always 0 here NS_IMETHOD GetStrength(PRInt32& aStrength); NS_IMETHOD MapStyleInto(nsIStyleContext* aContext, nsIPresContext* aPresContext); NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + nsIHTMLCSSStyleSheet* mSheet; }; -BodyFixupRule::BodyFixupRule() +BodyFixupRule::BodyFixupRule(nsIHTMLCSSStyleSheet* aSheet) + : mSheet(aSheet) { NS_INIT_REFCNT(); } @@ -77,6 +82,14 @@ BodyFixupRule::HashValue(PRUint32& aValue) const return NS_OK; } +NS_IMETHODIMP +BodyFixupRule::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, always MaxInt here NS_IMETHODIMP BodyFixupRule::GetStrength(PRInt32& aStrength) @@ -115,12 +128,27 @@ public: void* operator new(size_t size, nsIArena* aArena); void operator delete(void* ptr); - HTMLCSSStyleSheetImpl(nsIURL* aURL); + HTMLCSSStyleSheetImpl(nsIURL* aURL, nsIDocument* aDocument); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); + // basic style sheet data + NS_IMETHOD GetURL(nsIURL*& aURL) const; + NS_IMETHOD GetTitle(nsString& aTitle) const; + NS_IMETHOD GetType(nsString& aType) const; + NS_IMETHOD GetMediumCount(PRInt32& aCount) const; + NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsString& aMedium) const; + + NS_IMETHOD GetEnabled(PRBool& aEnabled) const; + NS_IMETHOD SetEnabled(PRBool aEnabled); + + // style sheet owner info + NS_IMETHOD GetParentSheet(nsIStyleSheet*& aParent) const; // will be null + NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; + NS_IMETHOD SetOwningDocument(nsIDocument* aDocument); + virtual PRInt32 RulesMatching(nsIPresContext* aPresContext, nsIContent* aContent, nsIStyleContext* aParentContext, @@ -132,8 +160,6 @@ public: nsIStyleContext* aParentContext, nsISupportsArray* aResults); - virtual nsIURL* GetURL(void); - // XXX style rule enumerations virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; @@ -150,8 +176,9 @@ protected: PRUint32 mInHeap : 1; PRUint32 mRefCnt : 31; - nsIURL* mURL; - nsIStyleRule* mBodyRule; + nsIURL* mURL; + nsIDocument* mDocument; + BodyFixupRule* mBodyRule; }; @@ -191,9 +218,10 @@ void HTMLCSSStyleSheetImpl::operator delete(void* ptr) -HTMLCSSStyleSheetImpl::HTMLCSSStyleSheetImpl(nsIURL* aURL) +HTMLCSSStyleSheetImpl::HTMLCSSStyleSheetImpl(nsIURL* aURL, nsIDocument* aDocument) : nsIHTMLCSSStyleSheet(), mURL(aURL), + mDocument(aDocument), mBodyRule(nsnull) { NS_INIT_REFCNT(); @@ -203,7 +231,10 @@ HTMLCSSStyleSheetImpl::HTMLCSSStyleSheetImpl(nsIURL* aURL) HTMLCSSStyleSheetImpl::~HTMLCSSStyleSheetImpl() { NS_RELEASE(mURL); - NS_IF_RELEASE(mBodyRule); + if (nsnull != mBodyRule) { + mBodyRule->mSheet = nsnull; + NS_RELEASE(mBodyRule); + } } NS_IMPL_ADDREF(HTMLCSSStyleSheetImpl) @@ -274,11 +305,8 @@ PRInt32 HTMLCSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, htmlContent->GetTag(tag); if (tag == nsHTMLAtoms::body) { if (nsnull == mBodyRule) { - BodyFixupRule* bodyRule = new BodyFixupRule(); - if ((nsnull != bodyRule) && - (NS_OK != bodyRule->QueryInterface(kIStyleRuleIID, (void**)&mBodyRule))) { - delete bodyRule; - } + mBodyRule = new BodyFixupRule(this); + NS_IF_ADDREF(mBodyRule); } if (nsnull != mBodyRule) { aResults->AppendElement(mBodyRule); @@ -301,10 +329,78 @@ PRInt32 HTMLCSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, return 0; } -nsIURL* HTMLCSSStyleSheetImpl::GetURL(void) +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetURL(nsIURL*& aURL) const { - NS_ADDREF(mURL); - return mURL; + NS_IF_ADDREF(mURL); + aURL = mURL; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetTitle(nsString& aTitle) const +{ + aTitle.Truncate(); + aTitle.Append("Internal HTML/CSS Style Sheet"); + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetType(nsString& aType) const +{ + aType.Truncate(); + aType.Append("text/html"); + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetMediumCount(PRInt32& aCount) const +{ + aCount = 0; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetMediumAt(PRInt32 aIndex, nsString& aMedium) const +{ + aMedium.Truncate(); + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetEnabled(PRBool& aEnabled) const +{ + aEnabled = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::SetEnabled(PRBool aEnabled) +{ // these can't be disabled + return NS_OK; +} + +// style sheet owner info +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetParentSheet(nsIStyleSheet*& aParent) const +{ + aParent = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetOwningDocument(nsIDocument*& aDocument) const +{ + NS_IF_ADDREF(mDocument); + aDocument = mDocument; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::SetOwningDocument(nsIDocument* aDocument) +{ + mDocument = aDocument; + return NS_OK; } void HTMLCSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const @@ -322,13 +418,14 @@ void HTMLCSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const } NS_HTML nsresult - NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURL* aURL) + NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURL* aURL, + nsIDocument* aDocument) { if (aInstancePtrResult == nsnull) { return NS_ERROR_NULL_POINTER; } - HTMLCSSStyleSheetImpl* it = new HTMLCSSStyleSheetImpl(aURL); + HTMLCSSStyleSheetImpl* it = new HTMLCSSStyleSheetImpl(aURL, aDocument); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/layout/html/style/src/nsHTMLStyleSheet.cpp b/layout/html/style/src/nsHTMLStyleSheet.cpp index 228eddc7ace..7a0e9b51915 100644 --- a/layout/html/style/src/nsHTMLStyleSheet.cpp +++ b/layout/html/style/src/nsHTMLStyleSheet.cpp @@ -53,13 +53,14 @@ static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID); class HTMLAnchorRule : public nsIStyleRule { public: - HTMLAnchorRule(); + HTMLAnchorRule(nsIHTMLStyleSheet* aSheet); ~HTMLAnchorRule(); NS_DECL_ISUPPORTS NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aValue) const; NS_IMETHOD HashValue(PRUint32& aValue) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; // Strength is an out-of-band weighting, always 0 here NS_IMETHOD GetStrength(PRInt32& aStrength); @@ -67,10 +68,12 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; - nscolor mColor; + nscolor mColor; + nsIHTMLStyleSheet* mSheet; }; -HTMLAnchorRule::HTMLAnchorRule() +HTMLAnchorRule::HTMLAnchorRule(nsIHTMLStyleSheet* aSheet) + : mSheet(aSheet) { NS_INIT_REFCNT(); } @@ -95,6 +98,14 @@ HTMLAnchorRule::HashValue(PRUint32& aValue) const return NS_OK; } +NS_IMETHODIMP +HTMLAnchorRule::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, always 0 here NS_IMETHODIMP HTMLAnchorRule::GetStrength(PRInt32& aStrength) @@ -201,12 +212,28 @@ public: void* operator new(size_t size, nsIArena* aArena); void operator delete(void* ptr); - HTMLStyleSheetImpl(nsIURL* aURL); + HTMLStyleSheetImpl(nsIURL* aURL, nsIDocument* aDocument); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); + // nsIStyleSheet api + NS_IMETHOD GetURL(nsIURL*& aURL) const; + NS_IMETHOD GetTitle(nsString& aTitle) const; + NS_IMETHOD GetType(nsString& aType) const; + NS_IMETHOD GetMediumCount(PRInt32& aCount) const; + NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsString& aMedium) const; + + NS_IMETHOD GetEnabled(PRBool& aEnabled) const; + NS_IMETHOD SetEnabled(PRBool aEnabled); + + // style sheet owner info + NS_IMETHOD GetParentSheet(nsIStyleSheet*& aParent) const; // will be null + NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; + + NS_IMETHOD SetOwningDocument(nsIDocument* aDocumemt); + virtual PRInt32 RulesMatching(nsIPresContext* aPresContext, nsIContent* aContent, nsIStyleContext* aParentContext, @@ -218,8 +245,6 @@ public: nsIStyleContext* aParentContext, nsISupportsArray* aResults); - virtual nsIURL* GetURL(void); - NS_IMETHOD SetLinkColor(nscolor aColor); NS_IMETHOD SetActiveLinkColor(nscolor aColor); NS_IMETHOD SetVisitedLinkColor(nscolor aColor); @@ -278,7 +303,17 @@ public: nsIAtom* aAttribute, PRInt32 aHint); - // XXX style rule enumerations + // Style change notifications + NS_IMETHOD StyleRuleChanged(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint); // See nsStyleConsts fot hint values + NS_IMETHOD StyleRuleAdded(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + NS_IMETHOD StyleRuleRemoved(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; @@ -361,11 +396,12 @@ protected: PRUint32 mInHeap : 1; PRUint32 mRefCnt : 31; - nsIURL* mURL; - HTMLAnchorRule* mLinkRule; - HTMLAnchorRule* mVisitedRule; - HTMLAnchorRule* mActiveRule; - nsHashtable mAttrTable; + nsIURL* mURL; + nsIDocument* mDocument; + HTMLAnchorRule* mLinkRule; + HTMLAnchorRule* mVisitedRule; + HTMLAnchorRule* mActiveRule; + nsHashtable mAttrTable; nsIHTMLAttributes* mRecycledAttrs; }; @@ -406,9 +442,10 @@ void HTMLStyleSheetImpl::operator delete(void* ptr) -HTMLStyleSheetImpl::HTMLStyleSheetImpl(nsIURL* aURL) +HTMLStyleSheetImpl::HTMLStyleSheetImpl(nsIURL* aURL, nsIDocument* aDocument) : nsIHTMLStyleSheet(), mURL(aURL), + mDocument(aDocument), mLinkRule(nsnull), mVisitedRule(nsnull), mActiveRule(nsnull), @@ -421,9 +458,18 @@ HTMLStyleSheetImpl::HTMLStyleSheetImpl(nsIURL* aURL) HTMLStyleSheetImpl::~HTMLStyleSheetImpl() { NS_RELEASE(mURL); - NS_IF_RELEASE(mLinkRule); - NS_IF_RELEASE(mVisitedRule); - NS_IF_RELEASE(mActiveRule); + if (nsnull != mLinkRule) { + mLinkRule->mSheet = nsnull; + NS_RELEASE(mLinkRule); + } + if (nsnull != mVisitedRule) { + mVisitedRule->mSheet = nsnull; + NS_RELEASE(mVisitedRule); + } + if (nsnull != mActiveRule) { + mActiveRule->mSheet = nsnull; + NS_RELEASE(mActiveRule); + } NS_IF_RELEASE(mRecycledAttrs); } @@ -556,17 +602,85 @@ PRInt32 HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, } -nsIURL* HTMLStyleSheetImpl::GetURL(void) + // nsIStyleSheet api +NS_IMETHODIMP +HTMLStyleSheetImpl::GetURL(nsIURL*& aURL) const { - NS_ADDREF(mURL); - return mURL; + NS_IF_ADDREF(mURL); + aURL = mURL; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetTitle(nsString& aTitle) const +{ + aTitle.Truncate(); + aTitle.Append("Internal HTML Style Sheet"); + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetType(nsString& aType) const +{ + aType.Truncate(); + aType.Append("text/html"); + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetMediumCount(PRInt32& aCount) const +{ + aCount = 0; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetMediumAt(PRInt32 aIndex, nsString& aMedium) const +{ + aMedium.Truncate(); + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetEnabled(PRBool& aEnabled) const +{ + aEnabled = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::SetEnabled(PRBool aEnabled) +{ // these can't be disabled + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetParentSheet(nsIStyleSheet*& aParent) const +{ + aParent = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetOwningDocument(nsIDocument*& aDocument) const +{ + NS_IF_ADDREF(mDocument); + aDocument = mDocument; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::SetOwningDocument(nsIDocument* aDocument) +{ + mDocument = aDocument; + return NS_OK; } NS_IMETHODIMP HTMLStyleSheetImpl::SetLinkColor(nscolor aColor) { if (nsnull == mLinkRule) { - mLinkRule = new HTMLAnchorRule(); + mLinkRule = new HTMLAnchorRule(this); if (nsnull == mLinkRule) { return NS_ERROR_OUT_OF_MEMORY; } @@ -579,7 +693,7 @@ NS_IMETHODIMP HTMLStyleSheetImpl::SetLinkColor(nscolor aColor) NS_IMETHODIMP HTMLStyleSheetImpl::SetActiveLinkColor(nscolor aColor) { if (nsnull == mActiveRule) { - mActiveRule = new HTMLAnchorRule(); + mActiveRule = new HTMLAnchorRule(this); if (nsnull == mActiveRule) { return NS_ERROR_OUT_OF_MEMORY; } @@ -592,7 +706,7 @@ NS_IMETHODIMP HTMLStyleSheetImpl::SetActiveLinkColor(nscolor aColor) NS_IMETHODIMP HTMLStyleSheetImpl::SetVisitedLinkColor(nscolor aColor) { if (nsnull == mVisitedRule) { - mVisitedRule = new HTMLAnchorRule(); + mVisitedRule = new HTMLAnchorRule(this); if (nsnull == mVisitedRule) { return NS_ERROR_OUT_OF_MEMORY; } @@ -712,7 +826,7 @@ HTMLStyleSheetImpl::EnsureSingleAttributes(nsIHTMLAttributes*& aAttributes, aSingleAttrs->SetMappingFunction(aMapFunc); } else { - result = NS_NewHTMLAttributes(&aSingleAttrs, aMapFunc); + result = NS_NewHTMLAttributes(&aSingleAttrs, this, aMapFunc); } } else { @@ -2403,6 +2517,77 @@ HTMLStyleSheetImpl::AttributeChanged(nsIPresContext* aPresContext, return result; } + // Style change notifications +NS_IMETHODIMP +HTMLStyleSheetImpl::StyleRuleChanged(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) +{ + nsIPresShell* shell = aPresContext->GetShell(); + nsIFrame* frame = shell->GetRootFrame(); + + PRBool reframe = PR_FALSE; + PRBool reflow = PR_FALSE; + PRBool render = PR_FALSE; + PRBool restyle = PR_FALSE; + switch (aHint) { + default: + case NS_STYLE_HINT_UNKNOWN: + case NS_STYLE_HINT_FRAMECHANGE: + reframe = PR_TRUE; + case NS_STYLE_HINT_REFLOW: + reflow = PR_TRUE; + case NS_STYLE_HINT_VISUAL: + render = PR_TRUE; + case NS_STYLE_HINT_CONTENT: + restyle = PR_TRUE; + break; + case NS_STYLE_HINT_AURAL: + break; + } + + if (restyle) { + nsIStyleContext* sc; + frame->GetStyleContext(sc); + sc->RemapStyle(aPresContext); + NS_RELEASE(sc); + } + + // XXX hack, skip the root and scrolling frames + frame->FirstChild(nsnull, frame); + frame->FirstChild(nsnull, frame); + if (reframe) { + NS_NOTYETIMPLEMENTED("frame change reflow"); + } + else if (reflow) { + StyleChangeReflow(aPresContext, frame, nsnull); + } + else if (render) { + ApplyRenderingChangeToTree(aPresContext, frame); + } + + NS_RELEASE(shell); + + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::StyleRuleAdded(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::StyleRuleRemoved(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + return NS_OK; +} + void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const { @@ -2419,13 +2604,14 @@ void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const } NS_HTML nsresult -NS_NewHTMLStyleSheet(nsIHTMLStyleSheet** aInstancePtrResult, nsIURL* aURL) +NS_NewHTMLStyleSheet(nsIHTMLStyleSheet** aInstancePtrResult, nsIURL* aURL, + nsIDocument* aDocument) { if (aInstancePtrResult == nsnull) { return NS_ERROR_NULL_POINTER; } - HTMLStyleSheetImpl *it = new HTMLStyleSheetImpl(aURL); + HTMLStyleSheetImpl *it = new HTMLStyleSheetImpl(aURL, aDocument); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/layout/html/style/src/nsICSSStyleRule.h b/layout/html/style/src/nsICSSStyleRule.h index dc68d7b0483..f4329a1bd6e 100644 --- a/layout/html/style/src/nsICSSStyleRule.h +++ b/layout/html/style/src/nsICSSStyleRule.h @@ -25,7 +25,7 @@ class nsIAtom; class nsIArena; class nsString; class nsICSSDeclaration; -class nsIStyleSheet; +class nsICSSStyleSheet; struct nsCSSSelector { public: @@ -66,8 +66,7 @@ public: virtual nsIStyleRule* GetImportantRule(void) = 0; - virtual nsIStyleSheet* GetStyleSheet(void) = 0; - virtual void SetStyleSheet(nsIStyleSheet *aSheet) = 0; + NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet) = 0; }; extern NS_HTML nsresult diff --git a/layout/html/style/src/nsICSSStyleSheet.h b/layout/html/style/src/nsICSSStyleSheet.h index cebe76e6ea5..e69de29bb2d 100644 --- a/layout/html/style/src/nsICSSStyleSheet.h +++ b/layout/html/style/src/nsICSSStyleSheet.h @@ -1,53 +0,0 @@ -/* -*- 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. - */ -#ifndef nsICSSStyleSheet_h___ -#define nsICSSStyleSheet_h___ - -#include "nslayout.h" -#include "nsIStyleSheet.h" - -class nsICSSStyleRule; -class nsIDocument; - -// IID for the nsICSSStyleSheet interface {8f83b0f0-b21a-11d1-8031-006008159b5a} -#define NS_ICSS_STYLE_SHEET_IID \ -{0x8f83b0f0, 0xb21a, 0x11d1, {0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}} - -class nsICSSStyleSheet : public nsIStyleSheet { -public: - virtual PRBool ContainsStyleSheet(nsIURL* aURL) = 0; - - virtual void AppendStyleSheet(nsICSSStyleSheet* aSheet) = 0; - - // XXX do these belong here or are they generic? - virtual void PrependStyleRule(nsICSSStyleRule* aRule) = 0; - virtual void AppendStyleRule(nsICSSStyleRule* aRule) = 0; - - virtual PRInt32 StyleRuleCount(void) = 0; - virtual nsresult GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule) = 0; - - virtual PRInt32 StyleSheetCount() = 0; - virtual nsresult GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) = 0; - - virtual void SetDocument(nsIDocument* aDocument) = 0; -}; - -extern NS_HTML nsresult - NS_NewCSSStyleSheet(nsICSSStyleSheet** aInstancePtrResult, nsIURL* aURL); - -#endif /* nsICSSStyleSheet_h___ */ diff --git a/layout/html/style/src/nsIHTMLAttributes.h b/layout/html/style/src/nsIHTMLAttributes.h index 0e259169dd3..139f9a3c6e7 100644 --- a/layout/html/style/src/nsIHTMLAttributes.h +++ b/layout/html/style/src/nsIHTMLAttributes.h @@ -25,6 +25,7 @@ class nsIAtom; class nsISizeOfHandler; class nsISupportsArray; +class nsIHTMLStyleSheet; // IID for the nsIHTMLAttributes interface {a18f85f0-c058-11d1-8031-006008159b5a} @@ -66,6 +67,7 @@ public: NS_IMETHOD Clone(nsIHTMLAttributes** aInstancePtrResult) = 0; NS_IMETHOD Reset(void) = 0; NS_IMETHOD SetMappingFunction(nsMapAttributesFunc aMapFunc) = 0; + NS_IMETHOD SetStyleSheet(nsIHTMLStyleSheet* aSheet) = 0; /** * Add this object's size information to the sizeof handler. @@ -76,7 +78,9 @@ public: }; extern NS_HTML nsresult - NS_NewHTMLAttributes(nsIHTMLAttributes** aInstancePtrResult, nsMapAttributesFunc aMapFunc); + NS_NewHTMLAttributes(nsIHTMLAttributes** aInstancePtrResult, + nsIHTMLStyleSheet* aSheet, + nsMapAttributesFunc aMapFunc); #endif /* nsIHTMLAttributes_h___ */ diff --git a/layout/html/style/src/nsIHTMLCSSStyleSheet.h b/layout/html/style/src/nsIHTMLCSSStyleSheet.h index 9d39c40f5c6..0820df6b817 100644 --- a/layout/html/style/src/nsIHTMLCSSStyleSheet.h +++ b/layout/html/style/src/nsIHTMLCSSStyleSheet.h @@ -31,6 +31,7 @@ public: }; extern NS_HTML nsresult - NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURL* aURL); + NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURL* aURL, + nsIDocument* aDocument); #endif /* nsIHTMLCSSStyleSheet_h___ */ diff --git a/layout/html/style/src/nsIHTMLStyleSheet.h b/layout/html/style/src/nsIHTMLStyleSheet.h index d888afc2d45..724be483541 100644 --- a/layout/html/style/src/nsIHTMLStyleSheet.h +++ b/layout/html/style/src/nsIHTMLStyleSheet.h @@ -27,6 +27,7 @@ class nsString; class nsHTMLValue; class nsIHTMLAttributes; class nsIHTMLContent; +class nsIDocument; // IID for the nsIHTMLStyleSheet interface {bddbd1b0-c5cc-11d1-8031-006008159b5a} #define NS_IHTML_STYLE_SHEET_IID \ @@ -57,6 +58,7 @@ public: }; extern NS_HTML nsresult - NS_NewHTMLStyleSheet(nsIHTMLStyleSheet** aInstancePtrResult, nsIURL* aURL); + NS_NewHTMLStyleSheet(nsIHTMLStyleSheet** aInstancePtrResult, nsIURL* aURL, + nsIDocument* aDocument); #endif /* nsIHTMLStyleSheet_h___ */ diff --git a/layout/html/tests/TestCSSParser.cpp b/layout/html/tests/TestCSSParser.cpp index f3d1f3340fd..2deda7b1180 100644 --- a/layout/html/tests/TestCSSParser.cpp +++ b/layout/html/tests/TestCSSParser.cpp @@ -17,7 +17,7 @@ */ #include #include "nsICSSParser.h" -#include "nsIStyleSheet.h" +#include "nsICSSStyleSheet.h" #include "nsIStyleRule.h" #include "nsIURL.h" #include "nsIInputStream.h" @@ -128,7 +128,7 @@ int main(int argc, char** argv) } // Parse the input and produce a style set - nsIStyleSheet* sheet; + nsICSSStyleSheet* sheet; rv = css->Parse(uin, url, sheet); if (NS_OK == rv) { if (verbose) { diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 543f1df1b0a..6ae8f0c3014 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -198,11 +198,11 @@ public: NS_IMETHOD GetInfoMask(PRUint32& aResult); - NS_IMETHOD SetStyleSheet(nsIStyleSheet* aSheet); + NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet); NS_IMETHOD Parse(nsIUnicharInputStream* aInput, - nsIURL* aInputURL, - nsIStyleSheet*& aResult); + nsIURL* aInputURL, + nsICSSStyleSheet*& aResult); NS_IMETHOD ParseDeclarations(const nsString& aDeclaration, nsIURL* aBaseURL, @@ -364,32 +364,27 @@ CSSParserImpl::GetInfoMask(PRUint32& aResult) } NS_METHOD -CSSParserImpl::SetStyleSheet(nsIStyleSheet* aSheet) +CSSParserImpl::SetStyleSheet(nsICSSStyleSheet* aSheet) { NS_PRECONDITION(nsnull != aSheet, "null ptr"); if (nsnull == aSheet) { return NS_ERROR_NULL_POINTER; } - // Make sure the sheet supports the correct interface! - static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID); - nsICSSStyleSheet* cssSheet; - nsresult rv = aSheet->QueryInterface(kICSSStyleSheetIID, (void**)&cssSheet); - if (NS_OK != rv) { - return rv; + if (aSheet != mSheet) { + // Switch to using the new sheet + NS_IF_RELEASE(mSheet); + mSheet = aSheet; + NS_ADDREF(mSheet); } - // Switch to using the new sheet - NS_IF_RELEASE(mSheet); - mSheet = cssSheet; - return NS_OK; } NS_METHOD CSSParserImpl::Parse(nsIUnicharInputStream* aInput, nsIURL* aInputURL, - nsIStyleSheet*& aResult) + nsICSSStyleSheet*& aResult) { if (nsnull == mSheet) { NS_NewCSSStyleSheet(&mSheet, aInputURL); @@ -425,9 +420,8 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput, mScanner = nsnull; NS_IF_RELEASE(mURL); - nsIStyleSheet* sheet = nsnull; - mSheet->QueryInterface(kIStyleSheetIID, (void**)&sheet); - aResult = sheet; + aResult = mSheet; + NS_ADDREF(aResult); return NS_OK; } @@ -711,15 +705,11 @@ NS_IMETHODIMP CSSParserImpl::ProcessImport(const nsString& aURLSpec) nsICSSParser* parser; rv = NS_NewCSSParser(&parser); if (NS_OK == rv) { - nsIStyleSheet* childSheet = nsnull; + nsICSSStyleSheet* childSheet = nsnull; rv = parser->Parse(uin, url, childSheet); NS_RELEASE(parser); if ((NS_OK == rv) && (nsnull != childSheet)) { - nsICSSStyleSheet* cssChild = nsnull; - if (NS_OK == childSheet->QueryInterface(kICSSStyleSheetIID, (void**)&cssChild)) { - mSheet->AppendStyleSheet(cssChild); - NS_RELEASE(cssChild); - } + mSheet->AppendStyleSheet(childSheet); } NS_IF_RELEASE(childSheet); } diff --git a/layout/style/nsCSSStyleRule.cpp b/layout/style/nsCSSStyleRule.cpp index dd7eec2b653..0638978d2ef 100644 --- a/layout/style/nsCSSStyleRule.cpp +++ b/layout/style/nsCSSStyleRule.cpp @@ -17,9 +17,10 @@ */ #include "nsICSSStyleRule.h" #include "nsICSSDeclaration.h" -#include "nsIStyleSheet.h" +#include "nsICSSStyleSheet.h" #include "nsIStyleContext.h" #include "nsIPresContext.h" +#include "nsIDocument.h" #include "nsIDeviceContext.h" #include "nsIArena.h" #include "nsIAtom.h" @@ -31,8 +32,8 @@ #include "nsStyleUtil.h" #include "nsIFontMetrics.h" #include "nsIDOMCSSStyleSheet.h" +#include "nsIDOMCSSRule.h" #include "nsIDOMCSSStyleRule.h" -#include "nsIDOMCSSStyleRuleSimple.h" #include "nsIDOMCSSStyleDeclaration.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptObjectOwner.h" @@ -45,8 +46,8 @@ static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); static NS_DEFINE_IID(kICSSDeclarationIID, NS_ICSS_DECLARATION_IID); static NS_DEFINE_IID(kICSSStyleRuleIID, NS_ICSS_STYLE_RULE_IID); static NS_DEFINE_IID(kIDOMCSSStyleSheetIID, NS_IDOMCSSSTYLESHEET_IID); +static NS_DEFINE_IID(kIDOMCSSRuleIID, NS_IDOMCSSRULE_IID); static NS_DEFINE_IID(kIDOMCSSStyleRuleIID, NS_IDOMCSSSTYLERULE_IID); -static NS_DEFINE_IID(kIDOMCSSStyleRuleSimpleIID, NS_IDOMCSSSTYLERULESIMPLE_IID); static NS_DEFINE_IID(kIDOMCSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID); static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); @@ -162,15 +163,19 @@ static void MapDeclarationInto(nsICSSDeclaration* aDeclaration, nsIStyleContext* aContext, nsIPresContext* aPresContext); +class CSSStyleRuleImpl; + class CSSImportantRule : public nsIStyleRule { public: - CSSImportantRule(nsICSSDeclaration* aDeclaration); + CSSImportantRule(nsICSSStyleSheet* aSheet, nsICSSDeclaration* aDeclaration); NS_DECL_ISUPPORTS NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aResult) const; NS_IMETHOD HashValue(PRUint32& aValue) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; + // Strength is an out-of-band weighting, useful for mapping CSS ! important NS_IMETHOD GetStrength(PRInt32& aStrength); @@ -182,10 +187,14 @@ protected: ~CSSImportantRule(void); nsICSSDeclaration* mDeclaration; + nsICSSStyleSheet* mSheet; + +friend CSSStyleRuleImpl; }; -CSSImportantRule::CSSImportantRule(nsICSSDeclaration* aDeclaration) - : mDeclaration(aDeclaration) +CSSImportantRule::CSSImportantRule(nsICSSStyleSheet* aSheet, nsICSSDeclaration* aDeclaration) + : mSheet(aSheet), + mDeclaration(aDeclaration) { NS_INIT_REFCNT(); NS_IF_ADDREF(mDeclaration); @@ -212,6 +221,14 @@ CSSImportantRule::HashValue(PRUint32& aValue) const return NS_OK; } +NS_IMETHODIMP +CSSImportantRule::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, useful for mapping CSS ! important NS_IMETHODIMP CSSImportantRule::GetStrength(PRInt32& aStrength) @@ -299,7 +316,18 @@ nsresult DOMCSSDeclarationImpl::StylePropertyChanged(const nsString& aPropertyName, PRInt32 aHint) { - // XXX TBI + nsIStyleSheet* sheet = nsnull; + if (nsnull != mRule) { + mRule->GetStyleSheet(sheet); + if (nsnull != sheet) { + nsIDocument* doc = nsnull; + sheet->GetOwningDocument(doc); + if (nsnull != doc) { + doc->StyleRuleChanged(sheet, mRule, aHint); + } + } + } + return NS_OK; } @@ -316,7 +344,7 @@ DOMCSSDeclarationImpl::GetParent(nsISupports **aParent) // -- nsCSSStyleRule ------------------------------- class CSSStyleRuleImpl : public nsICSSStyleRule, - public nsIDOMCSSStyleRuleSimple, + public nsIDOMCSSStyleRule, public nsIScriptObjectOwner { public: void* operator new(size_t size); @@ -346,20 +374,24 @@ public: virtual nsIStyleRule* GetImportantRule(void); - virtual nsIStyleSheet* GetStyleSheet(void); - virtual void SetStyleSheet(nsIStyleSheet *aSheet); + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; + NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet); NS_IMETHOD MapStyleInto(nsIStyleContext* aContext, nsIPresContext* aPresContext); NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; - // nsIDOMCSSStyleRule interface - NS_IMETHOD GetType(nsString& aType); + // nsIDOMCSSRule interface + NS_IMETHOD GetType(PRUint16* aType); + NS_IMETHOD GetCssText(nsString& aCssText); + NS_IMETHOD SetCssText(const nsString& aCssText); + NS_IMETHOD GetSheet(nsIDOMCSSStyleSheet** aSheet); - // nsIDOMCSSStyleRuleSimple interface + // nsIDOMCSSStyleRule interface NS_IMETHOD GetSelectorText(nsString& aSelectorText); NS_IMETHOD SetSelectorText(const nsString& aSelectorText); NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle); + NS_IMETHOD SetStyle(nsIDOMCSSStyleDeclaration* aStyle); // nsIScriptObjectOwner interface NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); @@ -377,13 +409,13 @@ protected: PRUint32 mInHeap : 1; PRUint32 mRefCnt : 31; - nsCSSSelector mSelector; - nsICSSDeclaration* mDeclaration; - PRInt32 mWeight; - CSSImportantRule* mImportantRule; - nsIStyleSheet* mStyleSheet; - DOMCSSDeclarationImpl *mDOMDeclaration; - void* mScriptObject; + nsCSSSelector mSelector; + nsICSSDeclaration* mDeclaration; + PRInt32 mWeight; + CSSImportantRule* mImportantRule; + nsICSSStyleSheet* mSheet; + DOMCSSDeclarationImpl* mDOMDeclaration; + void* mScriptObject; #ifdef DEBUG_REFS PRInt32 mInstance; #endif @@ -453,7 +485,10 @@ CSSStyleRuleImpl::~CSSStyleRuleImpl() delete selector; } NS_IF_RELEASE(mDeclaration); - NS_IF_RELEASE(mImportantRule); + if (nsnull != mImportantRule) { + mImportantRule->mSheet = nsnull; + NS_RELEASE(mImportantRule); + } if (nsnull != mDOMDeclaration) { mDOMDeclaration->DropReference(); } @@ -505,14 +540,14 @@ nsresult CSSStyleRuleImpl::QueryInterface(const nsIID& aIID, NS_ADDREF_THIS(); return NS_OK; } - if (aIID.Equals(kIDOMCSSStyleRuleIID)) { - nsIDOMCSSStyleRule *tmp = this; + if (aIID.Equals(kIDOMCSSRuleIID)) { + nsIDOMCSSRule *tmp = this; *aInstancePtrResult = (void*) tmp; NS_ADDREF_THIS(); return NS_OK; } - if (aIID.Equals(kIDOMCSSStyleRuleSimpleIID)) { - nsIDOMCSSStyleRuleSimple *tmp = this; + if (aIID.Equals(kIDOMCSSStyleRuleIID)) { + nsIDOMCSSStyleRule *tmp = this; *aInstancePtrResult = (void*) tmp; NS_ADDREF_THIS(); return NS_OK; @@ -637,10 +672,12 @@ nsICSSDeclaration* CSSStyleRuleImpl::GetDeclaration(void) const void CSSStyleRuleImpl::SetDeclaration(nsICSSDeclaration* aDeclaration) { - NS_IF_RELEASE(mImportantRule); - NS_IF_RELEASE(mDeclaration); - mDeclaration = aDeclaration; - NS_IF_ADDREF(mDeclaration); + if (mDeclaration != aDeclaration) { + NS_IF_RELEASE(mImportantRule); + NS_IF_RELEASE(mDeclaration); + mDeclaration = aDeclaration; + NS_IF_ADDREF(mDeclaration); + } } PRInt32 CSSStyleRuleImpl::GetWeight(void) const @@ -659,7 +696,7 @@ nsIStyleRule* CSSStyleRuleImpl::GetImportantRule(void) nsICSSDeclaration* important; mDeclaration->GetImportantValues(important); if (nsnull != important) { - mImportantRule = new CSSImportantRule(important); + mImportantRule = new CSSImportantRule(mSheet, important); NS_ADDREF(mImportantRule); NS_RELEASE(important); } @@ -668,19 +705,25 @@ nsIStyleRule* CSSStyleRuleImpl::GetImportantRule(void) return mImportantRule; } -nsIStyleSheet* CSSStyleRuleImpl::GetStyleSheet(void) +NS_IMETHODIMP +CSSStyleRuleImpl::GetStyleSheet(nsIStyleSheet*& aSheet) const { - NS_IF_ADDREF(mStyleSheet); - - return mStyleSheet; + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; } -void CSSStyleRuleImpl::SetStyleSheet(nsIStyleSheet *aSheet) +NS_IMETHODIMP +CSSStyleRuleImpl::SetStyleSheet(nsICSSStyleSheet* aSheet) { - // XXX We don't reference count this up reference. The style sheet + // We don't reference count this up reference. The style sheet // will tell us when it's going away or when we're detached from // it. - mStyleSheet = aSheet; + mSheet = aSheet; + if (nsnull != mImportantRule) { // we're responsible for this guy too + mImportantRule->mSheet = aSheet; + } + return NS_OK; } nscoord CalcLength(const nsCSSValue& aValue, @@ -1284,8 +1327,8 @@ void MapDeclarationInto(nsICSSDeclaration* aDeclaration, } else if (eCSSUnit_Inherit == ourColor->mBackPositionX.GetUnit()) { color->mBackgroundXPosition = parentColor->mBackgroundXPosition; - color->mBackgroundFlags &= ~NS_STYLE_BG_X_POSITION_LENGTH; - color->mBackgroundFlags |= (parentColor->mBackgroundFlags & NS_STYLE_BG_X_POSITION_PERCENT); + color->mBackgroundFlags &= ~(NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT); + color->mBackgroundFlags |= (parentColor->mBackgroundFlags & (NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT)); } if (eCSSUnit_Percent == ourColor->mBackPositionY.GetUnit()) { @@ -1306,8 +1349,8 @@ void MapDeclarationInto(nsICSSDeclaration* aDeclaration, } else if (eCSSUnit_Inherit == ourColor->mBackPositionY.GetUnit()) { color->mBackgroundYPosition = parentColor->mBackgroundYPosition; - color->mBackgroundFlags &= ~NS_STYLE_BG_Y_POSITION_LENGTH; - color->mBackgroundFlags |= (parentColor->mBackgroundFlags & NS_STYLE_BG_Y_POSITION_PERCENT); + color->mBackgroundFlags &= ~(NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT); + color->mBackgroundFlags |= (parentColor->mBackgroundFlags & (NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT)); } // opacity: factor, percent, inherit @@ -1693,14 +1736,37 @@ CSSStyleRuleImpl::List(FILE* out, PRInt32 aIndent) const } NS_IMETHODIMP -CSSStyleRuleImpl::GetType(nsString& aType) +CSSStyleRuleImpl::GetType(PRUint16* aType) { - // XXX Need to define the different types - aType.SetString("simple"); + *aType = nsIDOMCSSRule::STYLE_RULE; return NS_OK; } +NS_IMETHODIMP +CSSStyleRuleImpl::GetCssText(nsString& aCssText) +{ + // XXX TBI + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleRuleImpl::SetCssText(const nsString& aCssText) +{ + // XXX TBI + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleRuleImpl::GetSheet(nsIDOMCSSStyleSheet** aSheet) +{ + if (nsnull != mSheet) { + return mSheet->QueryInterface(kIDOMCSSStyleSheetIID, (void**)aSheet); + } + *aSheet = nsnull; + return NS_OK; +} + NS_IMETHODIMP CSSStyleRuleImpl::GetSelectorText(nsString& aSelectorText) { @@ -1763,6 +1829,13 @@ CSSStyleRuleImpl::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) return NS_OK; } +NS_IMETHODIMP +CSSStyleRuleImpl::SetStyle(nsIDOMCSSStyleDeclaration* aStyle) +{ + // XXX TBI + return NS_OK; +} + NS_IMETHODIMP CSSStyleRuleImpl::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject) { @@ -1773,10 +1846,10 @@ CSSStyleRuleImpl::GetScriptObject(nsIScriptContext *aContext, void** aScriptObje nsISupports *supports = (nsISupports *)(nsICSSStyleRule *)this; // XXX Parent should be the style sheet // XXX Should be done through factory - res = NS_NewScriptCSSStyleRuleSimple(aContext, - supports, - (nsISupports *)global, - (void**)&mScriptObject); + res = NS_NewScriptCSSStyleRule(aContext, + supports, + (nsISupports *)global, + (void**)&mScriptObject); } *aScriptObject = mScriptObject; diff --git a/layout/style/nsCSSStyleSheet.cpp b/layout/style/nsCSSStyleSheet.cpp index b87a220207d..b29516d0d3d 100644 --- a/layout/style/nsCSSStyleSheet.cpp +++ b/layout/style/nsCSSStyleSheet.cpp @@ -30,12 +30,14 @@ #include "nsHTMLAtoms.h" #include "nsIFrame.h" #include "nsString.h" +#include "nsVoidArray.h" #include "nsIPtr.h" #include "nsHTMLIIDs.h" #include "nsIDOMStyleSheetCollection.h" #include "nsIDOMCSSStyleSheet.h" #include "nsIDOMCSSStyleRule.h" #include "nsIDOMCSSStyleRuleCollection.h" +#include "nsIDOMNode.h" #include "nsIScriptObjectOwner.h" #include "nsIScriptGlobalObject.h" #include "nsICSSParser.h" @@ -540,6 +542,25 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); + // basic style sheet data + NS_IMETHOD GetURL(nsIURL*& aURL) const; + NS_IMETHOD GetTitle(nsString& aTitle) const; + NS_IMETHOD SetTitle(const nsString& aTitle); + NS_IMETHOD GetType(nsString& aType) const; + NS_IMETHOD GetMediumCount(PRInt32& aCount) const; + NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsString& aMedium) const; + NS_IMETHOD AppendMedium(const nsString& aMedium); + + NS_IMETHOD GetEnabled(PRBool& aEnabled) const; + NS_IMETHOD SetEnabled(PRBool aEnabled); + + // style sheet owner info + NS_IMETHOD GetParentSheet(nsIStyleSheet*& aParent) const; // may be null + NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; + NS_IMETHOD SetOwningDocument(nsIDocument* aDocument); + NS_IMETHOD SetOwningNode(nsIDOMNode* aOwningNode); + + virtual PRInt32 RulesMatching(nsIPresContext* aPresContext, nsIContent* aContent, nsIStyleContext* aParentContext, @@ -551,9 +572,7 @@ public: nsIStyleContext* aParentContext, nsISupportsArray* aResults); - virtual nsIURL* GetURL(void); - - virtual PRBool ContainsStyleSheet(nsIURL* aURL); + virtual PRBool ContainsStyleSheet(nsIURL* aURL) const; virtual void AppendStyleSheet(nsICSSStyleSheet* aSheet); @@ -561,32 +580,29 @@ public: virtual void PrependStyleRule(nsICSSStyleRule* aRule); virtual void AppendStyleRule(nsICSSStyleRule* aRule); - virtual PRInt32 StyleRuleCount(void); - virtual nsresult GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule); + virtual PRInt32 StyleRuleCount(void) const; + virtual nsresult GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule) const; - virtual PRInt32 StyleSheetCount(); - virtual nsresult GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet); - - virtual void SetDocument(nsIDocument *aDocument); + virtual PRInt32 StyleSheetCount(void) const; + virtual nsresult GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const; virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; // nsIDOMStyleSheet interface + NS_IMETHOD GetType(nsString& aType); NS_IMETHOD GetDisabled(PRBool* aDisabled); NS_IMETHOD SetDisabled(PRBool aDisabled); NS_IMETHOD GetReadOnly(PRBool* aReadOnly); // nsIDOMCSSStyleSheet interface - NS_IMETHOD GetOwningElement(nsIDOMHTMLElement** aOwningElement); - NS_IMETHOD GetParentStyleSheet(nsIDOMCSSStyleSheet** aParentStyleSheet); + NS_IMETHOD GetOwningNode(nsIDOMNode** aOwningNode); + NS_IMETHOD GetParentStyleSheet(nsIDOMStyleSheet** aParentStyleSheet); NS_IMETHOD GetHref(nsString& aHref); NS_IMETHOD GetTitle(nsString& aTitle); - NS_IMETHOD GetImports(nsIDOMStyleSheetCollection** aImports); - NS_IMETHOD GetRules(nsIDOMCSSStyleRuleCollection** aRules); - NS_IMETHOD AddRule(const nsString& aSelector, const nsString& aDeclaration, PRUint32 aIndex, PRUint32* aReturn); - NS_IMETHOD AddImport(const nsString& aUrl, PRUint32 aIndex, PRUint32* aReturn); - NS_IMETHOD RemoveRule(PRUint32 aIndex); - NS_IMETHOD RemoveImport(PRUint32 aIndex); + NS_IMETHOD GetMedia(nsString& aMedia); + NS_IMETHOD GetCssRules(nsIDOMCSSStyleRuleCollection** aCssRules); + NS_IMETHOD InsertRule(const nsString& aRule, PRUint32 aIndex, PRUint32* aReturn); + NS_IMETHOD DeleteRule(PRUint32 aIndex); // nsIScriptObjectOwner interface NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); @@ -608,6 +624,8 @@ protected: PRUint32 mRefCnt : 31; nsIURLPtr mURL; + nsString mTitle; + nsVoidArray mMedia; nsICSSStyleSheetPtr mFirstChild; nsISupportsArrayPtr mOrderedRules; nsISupportsArrayPtr mWeightedRules; @@ -617,8 +635,9 @@ protected: CSSStyleRuleCollectionImpl* mRuleCollection; CSSImportsCollectionImpl* mImportsCollection; nsIDocument* mDocument; + nsIDOMNode* mOwningNode; PRBool mDisabled; - void * mScriptObject; + void* mScriptObject; }; @@ -662,7 +681,8 @@ static PRInt32 gInstanceCount; CSSStyleSheetImpl::CSSStyleSheetImpl(nsIURL* aURL) : nsICSSStyleSheet(), - mURL(nsnull), mFirstChild(nsnull), + mURL(nsnull), mTitle(), mMedia(), + mFirstChild(nsnull), mOrderedRules(nsnull), mWeightedRules(nsnull), mNext(nsnull), mRuleHash(nsnull) @@ -673,6 +693,7 @@ CSSStyleSheetImpl::CSSStyleSheetImpl(nsIURL* aURL) mRuleCollection = nsnull; mImportsCollection = nsnull; mDocument = nsnull; + mOwningNode = nsnull; mDisabled = PR_FALSE; mScriptObject = nsnull; #ifdef DEBUG_REFS @@ -698,6 +719,11 @@ CSSStyleSheetImpl::~CSSStyleSheetImpl() --gInstanceCount; fprintf(stdout, "%d - CSSStyleSheet\n", gInstanceCount); #endif + PRInt32 count = mMedia.Count(); + while (0 < count) { + nsString* medium = (nsString*)mMedia.ElementAt(--count); + delete medium; + } if (mFirstChild.IsNotNull()) { nsICSSStyleSheet* child = mFirstChild; while (nsnull != child) { @@ -1084,12 +1110,122 @@ PRInt32 CSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, return matchCount; } -nsIURL* CSSStyleSheetImpl::GetURL(void) +NS_IMETHODIMP +CSSStyleSheetImpl::GetURL(nsIURL*& aURL) const { - return mURL.AddRef(); + nsIURL* url = mURL; + aURL = mURL; + NS_IF_ADDREF(aURL); + return NS_OK; } -PRBool CSSStyleSheetImpl::ContainsStyleSheet(nsIURL* aURL) +NS_IMETHODIMP +CSSStyleSheetImpl::GetTitle(nsString& aTitle) const +{ + aTitle = mTitle; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::SetTitle(const nsString& aTitle) +{ + mTitle = aTitle; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetType(nsString& aType) const +{ + aType.Truncate(); + aType.Append("text/css"); + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetMediumCount(PRInt32& aCount) const +{ + aCount = mMedia.Count(); + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetMediumAt(PRInt32 aIndex, nsString& aMedium) const +{ + nsString* medium = (nsString*)mMedia.ElementAt(aIndex); + if (nsnull != medium) { + aMedium = *medium; + return NS_OK; + } + aMedium.Truncate(); + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::AppendMedium(const nsString& aMedium) +{ + nsString* medium = new nsString(aMedium); + mMedia.AppendElement(medium); + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetEnabled(PRBool& aEnabled) const +{ + aEnabled = ((PR_TRUE == mDisabled) ? PR_FALSE : PR_TRUE); + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::SetEnabled(PRBool aEnabled) +{ + PRBool oldState = mDisabled; + mDisabled = ((PR_TRUE == aEnabled) ? PR_FALSE : PR_TRUE); + + if ((nsnull != mDocument) && (mDisabled != oldState)) { + mDocument->SetStyleSheetDisabledState(this, mDisabled); + } + + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetParentSheet(nsIStyleSheet*& aParent) const +{ + NS_IF_ADDREF(mParent); + aParent = mParent; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::GetOwningDocument(nsIDocument*& aDocument) const +{ + nsIDocument* doc = mDocument; + CSSStyleSheetImpl* parent = (CSSStyleSheetImpl*)mParent; + while ((nsnull == doc) && (nsnull != parent)) { + doc = parent->mDocument; + parent = (CSSStyleSheetImpl*)(parent->mParent); + } + + NS_IF_ADDREF(doc); + aDocument = doc; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::SetOwningDocument(nsIDocument* aDocument) +{ // not ref counted + mDocument = aDocument; + return NS_OK; +} + +NS_IMETHODIMP +CSSStyleSheetImpl::SetOwningNode(nsIDOMNode* aOwningNode) +{ // not ref counted + mOwningNode = aOwningNode; + return NS_OK; +} + +PRBool CSSStyleSheetImpl::ContainsStyleSheet(nsIURL* aURL) const { NS_PRECONDITION(nsnull != aURL, "null arg"); @@ -1182,7 +1318,7 @@ void CSSStyleSheetImpl::AppendStyleRule(nsICSSStyleRule* aRule) aRule->SetStyleSheet(this); } -PRInt32 CSSStyleSheetImpl::StyleRuleCount(void) +PRInt32 CSSStyleSheetImpl::StyleRuleCount(void) const { if (mOrderedRules.IsNotNull()) { return mOrderedRules->Count(); @@ -1190,7 +1326,7 @@ PRInt32 CSSStyleSheetImpl::StyleRuleCount(void) return 0; } -nsresult CSSStyleSheetImpl::GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule) +nsresult CSSStyleSheetImpl::GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRule) const { nsresult result = NS_ERROR_ILLEGAL_VALUE; @@ -1206,7 +1342,7 @@ nsresult CSSStyleSheetImpl::GetStyleRuleAt(PRInt32 aIndex, nsICSSStyleRule*& aRu return result; } -PRInt32 CSSStyleSheetImpl::StyleSheetCount() +PRInt32 CSSStyleSheetImpl::StyleSheetCount(void) const { // XXX Far from an ideal way to do this, but the hope is that // it won't be done too often. If it is, we might want to @@ -1223,7 +1359,7 @@ PRInt32 CSSStyleSheetImpl::StyleSheetCount() return count; } -nsresult CSSStyleSheetImpl::GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) +nsresult CSSStyleSheetImpl::GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const { // XXX Ughh...an O(n^2) method for doing iteration. Again, we hope // that this isn't done too often. If it is, we need to change the @@ -1243,13 +1379,6 @@ nsresult CSSStyleSheetImpl::GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& a return NS_OK; } -void CSSStyleSheetImpl::SetDocument(nsIDocument *aDocument) -{ - // This reference is not reference counted and should not be - // released. The document will tell us when it goes away. - mDocument = aDocument; -} - void CSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const { nsAutoString buffer; @@ -1303,6 +1432,15 @@ void CSSStyleSheetImpl::BuildHash(void) } } + // nsIDOMStyleSheet interface +NS_IMETHODIMP +CSSStyleSheetImpl::GetType(nsString& aType) +{ + aType.Truncate(); + aType.Append("text/css"); + return NS_OK; +} + NS_IMETHODIMP CSSStyleSheetImpl::GetDisabled(PRBool* aDisabled) { @@ -1313,13 +1451,13 @@ CSSStyleSheetImpl::GetDisabled(PRBool* aDisabled) NS_IMETHODIMP CSSStyleSheetImpl::SetDisabled(PRBool aDisabled) { - - if ((nsnull != mDocument) && (mDisabled != aDisabled)) { - mDocument->SetStyleSheetDisabledState(this, aDisabled); - } - + PRBool oldState = mDisabled; mDisabled = aDisabled; + if ((nsnull != mDocument) && (mDisabled != oldState)) { + mDocument->SetStyleSheetDisabledState(this, mDisabled); + } + return NS_OK; } @@ -1332,18 +1470,18 @@ CSSStyleSheetImpl::GetReadOnly(PRBool* aReadOnly) } NS_IMETHODIMP -CSSStyleSheetImpl::GetOwningElement(nsIDOMHTMLElement** aOwningElement) +CSSStyleSheetImpl::GetOwningNode(nsIDOMNode** aOwningNode) { - // XXX TBI - *aOwningElement = nsnull; + NS_IF_ADDREF(mOwningNode); + *aOwningNode = mOwningNode; return NS_OK; } NS_IMETHODIMP -CSSStyleSheetImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet** aParentStyleSheet) +CSSStyleSheetImpl::GetParentStyleSheet(nsIDOMStyleSheet** aParentStyleSheet) { if (nsnull != mParent) { - return mParent->QueryInterface(kIDOMCSSStyleSheetIID, (void **)aParentStyleSheet); + return mParent->QueryInterface(kIDOMStyleSheetIID, (void **)aParentStyleSheet); } else { *aParentStyleSheet = nsnull; @@ -1364,32 +1502,31 @@ CSSStyleSheetImpl::GetHref(nsString& aHref) return NS_OK; } -NS_IMETHODIMP +NS_IMETHODIMP CSSStyleSheetImpl::GetTitle(nsString& aTitle) { - // XX TBI + aTitle = mTitle; return NS_OK; } -NS_IMETHODIMP -CSSStyleSheetImpl::GetImports(nsIDOMStyleSheetCollection** aImports) +NS_IMETHODIMP +CSSStyleSheetImpl::GetMedia(nsString& aMedia) { - if (nsnull == mImportsCollection) { - mImportsCollection = new CSSImportsCollectionImpl(this); - if (nsnull == mImportsCollection) { - return NS_ERROR_OUT_OF_MEMORY; + aMedia.Truncate(); + PRInt32 count = mMedia.Count(); + PRInt32 index = 0; + while (index < count) { + nsString* medium = (nsString*)mMedia.ElementAt(index++); + aMedia.Append(*medium); + if (index < count) { + aMedia.Append(", "); } - NS_ADDREF(mImportsCollection); } - - *aImports = mImportsCollection; - NS_ADDREF(mImportsCollection); - return NS_OK; } NS_IMETHODIMP -CSSStyleSheetImpl::GetRules(nsIDOMCSSStyleRuleCollection** aRules) +CSSStyleSheetImpl::GetCssRules(nsIDOMCSSStyleRuleCollection** aCssRules) { if (nsnull == mRuleCollection) { mRuleCollection = new CSSStyleRuleCollectionImpl(this); @@ -1399,37 +1536,31 @@ CSSStyleSheetImpl::GetRules(nsIDOMCSSStyleRuleCollection** aRules) NS_ADDREF(mRuleCollection); } - *aRules = mRuleCollection; + *aCssRules = mRuleCollection; NS_ADDREF(mRuleCollection); return NS_OK; } NS_IMETHODIMP -CSSStyleSheetImpl::AddRule(const nsString& aSelector, - const nsString& aDeclaration, - PRUint32 aIndex, - PRUint32* aReturn) +CSSStyleSheetImpl::InsertRule(const nsString& aRule, + PRUint32 aIndex, + PRUint32* aReturn) { nsICSSParser* css; nsresult result = NS_NewCSSParser(&css); if (NS_OK == result) { - nsAutoString str; - str.SetString(aSelector); - // XXX Can we assume that the braces aren't there? - str.Append(" { "); - str.Append(aDeclaration); - str.Append(" } "); - + nsAutoString str(aRule); nsIUnicharInputStream* input = nsnull; result = NS_NewStringUnicharInputStream(&input, &str); if (NS_OK == result) { - nsIStyleSheet *tmp; + nsICSSStyleSheet* tmp; css->SetStyleSheet(this); // XXX Currently, the parser will append the rule to the // style sheet. We shouldn't ignore the index. result = css->Parse(input, mURL, tmp); - NS_ASSERTION(tmp = this, "parser incorrectly created a new stylesheet"); + NS_ASSERTION(tmp == this, "parser incorrectly created a new stylesheet"); + NS_RELEASE(tmp); NS_RELEASE(input); *aReturn = mOrderedRules->Count(); } @@ -1441,21 +1572,9 @@ CSSStyleSheetImpl::AddRule(const nsString& aSelector, } NS_IMETHODIMP -CSSStyleSheetImpl::AddImport(const nsString& aUrl, PRUint32 aIndex, PRUint32* aReturn) -{ - nsICSSParser* css; - nsresult result = NS_NewCSSParser(&css); - if (NS_OK == result) { - css->SetStyleSheet(this); - result = css->ProcessImport(aUrl); - } - - return result; -} - -NS_IMETHODIMP -CSSStyleSheetImpl::RemoveRule(PRUint32 aIndex) +CSSStyleSheetImpl::DeleteRule(PRUint32 aIndex) { + // XXX TBI: handle @rule types nsICSSStyleRule *rule; rule = (nsICSSStyleRule *)mOrderedRules->ElementAt(aIndex); @@ -1469,36 +1588,6 @@ CSSStyleSheetImpl::RemoveRule(PRUint32 aIndex) return NS_OK; } -NS_IMETHODIMP -CSSStyleSheetImpl::RemoveImport(PRUint32 aIndex) -{ - if (mFirstChild.IsNotNull()) { - nsICSSStyleSheet* prev = nsnull; - nsICSSStyleSheet* child = mFirstChild; - while ((nsnull != child) && (0 != aIndex)) { - prev = child; - child = ((CSSStyleSheetImpl*)child)->mNext; - --aIndex; - } - - if ((nsnull != child) && (0 == aIndex)) { - // Hold on to the child while we clean it up - NS_ADDREF(child); - if (nsnull == prev) { - mFirstChild.SetAddRef(((CSSStyleSheetImpl*)child)->mNext); - } - else { - ((CSSStyleSheetImpl*)prev)->mNext.SetAddRef(((CSSStyleSheetImpl*)child)->mNext); - } - ((CSSStyleSheetImpl*)child)->mNext.SetAddRef(nsnull); - ((CSSStyleSheetImpl*)child)->mParent = nsnull; - NS_RELEASE(child); - } - } - - return NS_OK; -} - NS_IMETHODIMP CSSStyleSheetImpl::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject) { diff --git a/layout/style/nsDOMCSSDeclaration.cpp b/layout/style/nsDOMCSSDeclaration.cpp index 90e01e5a4b9..600a29cc4be 100644 --- a/layout/style/nsDOMCSSDeclaration.cpp +++ b/layout/style/nsDOMCSSDeclaration.cpp @@ -37,6 +37,7 @@ nsDOMCSSDeclaration::~nsDOMCSSDeclaration() NS_IMPL_ADDREF(nsDOMCSSDeclaration); NS_IMPL_RELEASE(nsDOMCSSDeclaration); +static NS_DEFINE_IID(kIDOMCSS2PropertiesIID, NS_IDOMCSS2PROPERTIES_IID); static NS_DEFINE_IID(kIDOMCSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID); static NS_DEFINE_IID(kICSSStyleRuleIID, NS_ICSS_STYLE_RULE_IID); static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); @@ -50,6 +51,12 @@ nsDOMCSSDeclaration::QueryInterface(REFNSIID aIID, if (nsnull == aInstancePtr) { return NS_ERROR_NULL_POINTER; } + if (aIID.Equals(kIDOMCSS2PropertiesIID)) { + nsIDOMCSS2Properties *tmp = this; + AddRef(); + *aInstancePtr = (void*) tmp; + return NS_OK; + } if (aIID.Equals(kIDOMCSSStyleDeclarationIID)) { nsIDOMCSSStyleDeclaration *tmp = this; AddRef(); @@ -83,12 +90,12 @@ nsDOMCSSDeclaration::GetScriptObject(nsIScriptContext* aContext, res = GetParent(&parent); if (NS_OK == res) { - nsISupports *supports = (nsISupports *)(nsIDOMCSSStyleDeclaration *)this; + nsISupports *supports = (nsISupports *)(nsIDOMCSS2Properties *)this; // XXX Should be done through factory - res = NS_NewScriptCSSStyleDeclaration(aContext, - supports, - parent, - (void**)&mScriptObject); + res = NS_NewScriptCSS2Properties(aContext, + supports, + parent, + (void**)&mScriptObject); NS_RELEASE(parent); } } @@ -104,6 +111,20 @@ nsDOMCSSDeclaration::SetScriptObject(void* aScriptObject) return NS_OK; } +NS_IMETHODIMP +nsDOMCSSDeclaration::GetCssText(nsString& aCssText) +{ + // XXX TBI + return NS_OK; +} + +NS_IMETHODIMP +nsDOMCSSDeclaration::SetCssText(const nsString& aCssText) +{ + // XXX TBI + return NS_OK; +} + NS_IMETHODIMP nsDOMCSSDeclaration::GetLength(PRUint32* aLength) { @@ -649,6 +670,18 @@ nsDOMCSSDeclaration::SetCounterReset(const nsString& aCounterReset) return SetProperty("counter-reset", aCounterReset, ""); } +NS_IMETHODIMP +nsDOMCSSDeclaration::GetCssFloat(nsString& aCssFloat) +{ + return GetPropertyValue("float", aCssFloat); +} + +NS_IMETHODIMP +nsDOMCSSDeclaration::SetCssFloat(const nsString& aCssFloat) +{ + return SetProperty("float", aCssFloat, ""); +} + NS_IMETHODIMP nsDOMCSSDeclaration::GetCue(nsString& aCue) { @@ -745,18 +778,6 @@ nsDOMCSSDeclaration::SetEmptyCells(const nsString& aEmptyCells) return SetProperty("empty-cells", aEmptyCells, ""); } -NS_IMETHODIMP -nsDOMCSSDeclaration::GetStyleFloat(nsString& aStyleFloat) -{ - return GetPropertyValue("style-float", aStyleFloat); -} - -NS_IMETHODIMP -nsDOMCSSDeclaration::SetStyleFloat(const nsString& aStyleFloat) -{ - return SetProperty("style-float", aStyleFloat, ""); -} - NS_IMETHODIMP nsDOMCSSDeclaration::GetFont(nsString& aFont) { diff --git a/layout/style/nsDOMCSSDeclaration.h b/layout/style/nsDOMCSSDeclaration.h index acae956973a..606a5172c5a 100644 --- a/layout/style/nsDOMCSSDeclaration.h +++ b/layout/style/nsDOMCSSDeclaration.h @@ -20,12 +20,12 @@ #define nsDOMCSSSDeclaration_h___ #include "nsISupports.h" -#include "nsIDOMCSSStyleDeclaration.h" +#include "nsIDOMCSS2Properties.h" #include "nsIScriptObjectOwner.h" class nsICSSDeclaration; -class nsDOMCSSDeclaration : public nsIDOMCSSStyleDeclaration, +class nsDOMCSSDeclaration : public nsIDOMCSS2Properties, public nsIScriptObjectOwner { public: @@ -34,6 +34,8 @@ public: NS_DECL_ISUPPORTS NS_DECL_IDOMCSSSTYLEDECLARATION + + NS_DECL_IDOMCSS2PROPERTIES // nsIScriptObjectOwner interface NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); diff --git a/layout/style/nsHTMLCSSStyleSheet.cpp b/layout/style/nsHTMLCSSStyleSheet.cpp index 38d23a3789f..771c4b3d2a6 100644 --- a/layout/style/nsHTMLCSSStyleSheet.cpp +++ b/layout/style/nsHTMLCSSStyleSheet.cpp @@ -29,6 +29,7 @@ #include "nsICSSStyleRule.h" #include "nsIStyleContext.h" #include "nsIPresContext.h" +#include "nsIDocument.h" static NS_DEFINE_IID(kIHTMLCSSStyleSheetIID, NS_IHTML_CSS_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); @@ -37,22 +38,26 @@ static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); class BodyFixupRule : public nsIStyleRule { public: - BodyFixupRule(); + BodyFixupRule(nsIHTMLCSSStyleSheet* aSheet); ~BodyFixupRule(); NS_DECL_ISUPPORTS NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aValue) const; NS_IMETHOD HashValue(PRUint32& aValue) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; // Strength is an out-of-band weighting, always 0 here NS_IMETHOD GetStrength(PRInt32& aStrength); NS_IMETHOD MapStyleInto(nsIStyleContext* aContext, nsIPresContext* aPresContext); NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + nsIHTMLCSSStyleSheet* mSheet; }; -BodyFixupRule::BodyFixupRule() +BodyFixupRule::BodyFixupRule(nsIHTMLCSSStyleSheet* aSheet) + : mSheet(aSheet) { NS_INIT_REFCNT(); } @@ -77,6 +82,14 @@ BodyFixupRule::HashValue(PRUint32& aValue) const return NS_OK; } +NS_IMETHODIMP +BodyFixupRule::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, always MaxInt here NS_IMETHODIMP BodyFixupRule::GetStrength(PRInt32& aStrength) @@ -115,12 +128,27 @@ public: void* operator new(size_t size, nsIArena* aArena); void operator delete(void* ptr); - HTMLCSSStyleSheetImpl(nsIURL* aURL); + HTMLCSSStyleSheetImpl(nsIURL* aURL, nsIDocument* aDocument); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); + // basic style sheet data + NS_IMETHOD GetURL(nsIURL*& aURL) const; + NS_IMETHOD GetTitle(nsString& aTitle) const; + NS_IMETHOD GetType(nsString& aType) const; + NS_IMETHOD GetMediumCount(PRInt32& aCount) const; + NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsString& aMedium) const; + + NS_IMETHOD GetEnabled(PRBool& aEnabled) const; + NS_IMETHOD SetEnabled(PRBool aEnabled); + + // style sheet owner info + NS_IMETHOD GetParentSheet(nsIStyleSheet*& aParent) const; // will be null + NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; + NS_IMETHOD SetOwningDocument(nsIDocument* aDocument); + virtual PRInt32 RulesMatching(nsIPresContext* aPresContext, nsIContent* aContent, nsIStyleContext* aParentContext, @@ -132,8 +160,6 @@ public: nsIStyleContext* aParentContext, nsISupportsArray* aResults); - virtual nsIURL* GetURL(void); - // XXX style rule enumerations virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; @@ -150,8 +176,9 @@ protected: PRUint32 mInHeap : 1; PRUint32 mRefCnt : 31; - nsIURL* mURL; - nsIStyleRule* mBodyRule; + nsIURL* mURL; + nsIDocument* mDocument; + BodyFixupRule* mBodyRule; }; @@ -191,9 +218,10 @@ void HTMLCSSStyleSheetImpl::operator delete(void* ptr) -HTMLCSSStyleSheetImpl::HTMLCSSStyleSheetImpl(nsIURL* aURL) +HTMLCSSStyleSheetImpl::HTMLCSSStyleSheetImpl(nsIURL* aURL, nsIDocument* aDocument) : nsIHTMLCSSStyleSheet(), mURL(aURL), + mDocument(aDocument), mBodyRule(nsnull) { NS_INIT_REFCNT(); @@ -203,7 +231,10 @@ HTMLCSSStyleSheetImpl::HTMLCSSStyleSheetImpl(nsIURL* aURL) HTMLCSSStyleSheetImpl::~HTMLCSSStyleSheetImpl() { NS_RELEASE(mURL); - NS_IF_RELEASE(mBodyRule); + if (nsnull != mBodyRule) { + mBodyRule->mSheet = nsnull; + NS_RELEASE(mBodyRule); + } } NS_IMPL_ADDREF(HTMLCSSStyleSheetImpl) @@ -274,11 +305,8 @@ PRInt32 HTMLCSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, htmlContent->GetTag(tag); if (tag == nsHTMLAtoms::body) { if (nsnull == mBodyRule) { - BodyFixupRule* bodyRule = new BodyFixupRule(); - if ((nsnull != bodyRule) && - (NS_OK != bodyRule->QueryInterface(kIStyleRuleIID, (void**)&mBodyRule))) { - delete bodyRule; - } + mBodyRule = new BodyFixupRule(this); + NS_IF_ADDREF(mBodyRule); } if (nsnull != mBodyRule) { aResults->AppendElement(mBodyRule); @@ -301,10 +329,78 @@ PRInt32 HTMLCSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, return 0; } -nsIURL* HTMLCSSStyleSheetImpl::GetURL(void) +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetURL(nsIURL*& aURL) const { - NS_ADDREF(mURL); - return mURL; + NS_IF_ADDREF(mURL); + aURL = mURL; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetTitle(nsString& aTitle) const +{ + aTitle.Truncate(); + aTitle.Append("Internal HTML/CSS Style Sheet"); + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetType(nsString& aType) const +{ + aType.Truncate(); + aType.Append("text/html"); + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetMediumCount(PRInt32& aCount) const +{ + aCount = 0; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetMediumAt(PRInt32 aIndex, nsString& aMedium) const +{ + aMedium.Truncate(); + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetEnabled(PRBool& aEnabled) const +{ + aEnabled = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::SetEnabled(PRBool aEnabled) +{ // these can't be disabled + return NS_OK; +} + +// style sheet owner info +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetParentSheet(nsIStyleSheet*& aParent) const +{ + aParent = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::GetOwningDocument(nsIDocument*& aDocument) const +{ + NS_IF_ADDREF(mDocument); + aDocument = mDocument; + return NS_OK; +} + +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::SetOwningDocument(nsIDocument* aDocument) +{ + mDocument = aDocument; + return NS_OK; } void HTMLCSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const @@ -322,13 +418,14 @@ void HTMLCSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const } NS_HTML nsresult - NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURL* aURL) + NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURL* aURL, + nsIDocument* aDocument) { if (aInstancePtrResult == nsnull) { return NS_ERROR_NULL_POINTER; } - HTMLCSSStyleSheetImpl* it = new HTMLCSSStyleSheetImpl(aURL); + HTMLCSSStyleSheetImpl* it = new HTMLCSSStyleSheetImpl(aURL, aDocument); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp index 228eddc7ace..7a0e9b51915 100644 --- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -53,13 +53,14 @@ static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID); class HTMLAnchorRule : public nsIStyleRule { public: - HTMLAnchorRule(); + HTMLAnchorRule(nsIHTMLStyleSheet* aSheet); ~HTMLAnchorRule(); NS_DECL_ISUPPORTS NS_IMETHOD Equals(const nsIStyleRule* aRule, PRBool& aValue) const; NS_IMETHOD HashValue(PRUint32& aValue) const; + NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; // Strength is an out-of-band weighting, always 0 here NS_IMETHOD GetStrength(PRInt32& aStrength); @@ -67,10 +68,12 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; - nscolor mColor; + nscolor mColor; + nsIHTMLStyleSheet* mSheet; }; -HTMLAnchorRule::HTMLAnchorRule() +HTMLAnchorRule::HTMLAnchorRule(nsIHTMLStyleSheet* aSheet) + : mSheet(aSheet) { NS_INIT_REFCNT(); } @@ -95,6 +98,14 @@ HTMLAnchorRule::HashValue(PRUint32& aValue) const return NS_OK; } +NS_IMETHODIMP +HTMLAnchorRule::GetStyleSheet(nsIStyleSheet*& aSheet) const +{ + NS_IF_ADDREF(mSheet); + aSheet = mSheet; + return NS_OK; +} + // Strength is an out-of-band weighting, always 0 here NS_IMETHODIMP HTMLAnchorRule::GetStrength(PRInt32& aStrength) @@ -201,12 +212,28 @@ public: void* operator new(size_t size, nsIArena* aArena); void operator delete(void* ptr); - HTMLStyleSheetImpl(nsIURL* aURL); + HTMLStyleSheetImpl(nsIURL* aURL, nsIDocument* aDocument); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); + // nsIStyleSheet api + NS_IMETHOD GetURL(nsIURL*& aURL) const; + NS_IMETHOD GetTitle(nsString& aTitle) const; + NS_IMETHOD GetType(nsString& aType) const; + NS_IMETHOD GetMediumCount(PRInt32& aCount) const; + NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsString& aMedium) const; + + NS_IMETHOD GetEnabled(PRBool& aEnabled) const; + NS_IMETHOD SetEnabled(PRBool aEnabled); + + // style sheet owner info + NS_IMETHOD GetParentSheet(nsIStyleSheet*& aParent) const; // will be null + NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; + + NS_IMETHOD SetOwningDocument(nsIDocument* aDocumemt); + virtual PRInt32 RulesMatching(nsIPresContext* aPresContext, nsIContent* aContent, nsIStyleContext* aParentContext, @@ -218,8 +245,6 @@ public: nsIStyleContext* aParentContext, nsISupportsArray* aResults); - virtual nsIURL* GetURL(void); - NS_IMETHOD SetLinkColor(nscolor aColor); NS_IMETHOD SetActiveLinkColor(nscolor aColor); NS_IMETHOD SetVisitedLinkColor(nscolor aColor); @@ -278,7 +303,17 @@ public: nsIAtom* aAttribute, PRInt32 aHint); - // XXX style rule enumerations + // Style change notifications + NS_IMETHOD StyleRuleChanged(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint); // See nsStyleConsts fot hint values + NS_IMETHOD StyleRuleAdded(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + NS_IMETHOD StyleRuleRemoved(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; @@ -361,11 +396,12 @@ protected: PRUint32 mInHeap : 1; PRUint32 mRefCnt : 31; - nsIURL* mURL; - HTMLAnchorRule* mLinkRule; - HTMLAnchorRule* mVisitedRule; - HTMLAnchorRule* mActiveRule; - nsHashtable mAttrTable; + nsIURL* mURL; + nsIDocument* mDocument; + HTMLAnchorRule* mLinkRule; + HTMLAnchorRule* mVisitedRule; + HTMLAnchorRule* mActiveRule; + nsHashtable mAttrTable; nsIHTMLAttributes* mRecycledAttrs; }; @@ -406,9 +442,10 @@ void HTMLStyleSheetImpl::operator delete(void* ptr) -HTMLStyleSheetImpl::HTMLStyleSheetImpl(nsIURL* aURL) +HTMLStyleSheetImpl::HTMLStyleSheetImpl(nsIURL* aURL, nsIDocument* aDocument) : nsIHTMLStyleSheet(), mURL(aURL), + mDocument(aDocument), mLinkRule(nsnull), mVisitedRule(nsnull), mActiveRule(nsnull), @@ -421,9 +458,18 @@ HTMLStyleSheetImpl::HTMLStyleSheetImpl(nsIURL* aURL) HTMLStyleSheetImpl::~HTMLStyleSheetImpl() { NS_RELEASE(mURL); - NS_IF_RELEASE(mLinkRule); - NS_IF_RELEASE(mVisitedRule); - NS_IF_RELEASE(mActiveRule); + if (nsnull != mLinkRule) { + mLinkRule->mSheet = nsnull; + NS_RELEASE(mLinkRule); + } + if (nsnull != mVisitedRule) { + mVisitedRule->mSheet = nsnull; + NS_RELEASE(mVisitedRule); + } + if (nsnull != mActiveRule) { + mActiveRule->mSheet = nsnull; + NS_RELEASE(mActiveRule); + } NS_IF_RELEASE(mRecycledAttrs); } @@ -556,17 +602,85 @@ PRInt32 HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, } -nsIURL* HTMLStyleSheetImpl::GetURL(void) + // nsIStyleSheet api +NS_IMETHODIMP +HTMLStyleSheetImpl::GetURL(nsIURL*& aURL) const { - NS_ADDREF(mURL); - return mURL; + NS_IF_ADDREF(mURL); + aURL = mURL; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetTitle(nsString& aTitle) const +{ + aTitle.Truncate(); + aTitle.Append("Internal HTML Style Sheet"); + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetType(nsString& aType) const +{ + aType.Truncate(); + aType.Append("text/html"); + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetMediumCount(PRInt32& aCount) const +{ + aCount = 0; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetMediumAt(PRInt32 aIndex, nsString& aMedium) const +{ + aMedium.Truncate(); + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetEnabled(PRBool& aEnabled) const +{ + aEnabled = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::SetEnabled(PRBool aEnabled) +{ // these can't be disabled + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetParentSheet(nsIStyleSheet*& aParent) const +{ + aParent = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::GetOwningDocument(nsIDocument*& aDocument) const +{ + NS_IF_ADDREF(mDocument); + aDocument = mDocument; + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::SetOwningDocument(nsIDocument* aDocument) +{ + mDocument = aDocument; + return NS_OK; } NS_IMETHODIMP HTMLStyleSheetImpl::SetLinkColor(nscolor aColor) { if (nsnull == mLinkRule) { - mLinkRule = new HTMLAnchorRule(); + mLinkRule = new HTMLAnchorRule(this); if (nsnull == mLinkRule) { return NS_ERROR_OUT_OF_MEMORY; } @@ -579,7 +693,7 @@ NS_IMETHODIMP HTMLStyleSheetImpl::SetLinkColor(nscolor aColor) NS_IMETHODIMP HTMLStyleSheetImpl::SetActiveLinkColor(nscolor aColor) { if (nsnull == mActiveRule) { - mActiveRule = new HTMLAnchorRule(); + mActiveRule = new HTMLAnchorRule(this); if (nsnull == mActiveRule) { return NS_ERROR_OUT_OF_MEMORY; } @@ -592,7 +706,7 @@ NS_IMETHODIMP HTMLStyleSheetImpl::SetActiveLinkColor(nscolor aColor) NS_IMETHODIMP HTMLStyleSheetImpl::SetVisitedLinkColor(nscolor aColor) { if (nsnull == mVisitedRule) { - mVisitedRule = new HTMLAnchorRule(); + mVisitedRule = new HTMLAnchorRule(this); if (nsnull == mVisitedRule) { return NS_ERROR_OUT_OF_MEMORY; } @@ -712,7 +826,7 @@ HTMLStyleSheetImpl::EnsureSingleAttributes(nsIHTMLAttributes*& aAttributes, aSingleAttrs->SetMappingFunction(aMapFunc); } else { - result = NS_NewHTMLAttributes(&aSingleAttrs, aMapFunc); + result = NS_NewHTMLAttributes(&aSingleAttrs, this, aMapFunc); } } else { @@ -2403,6 +2517,77 @@ HTMLStyleSheetImpl::AttributeChanged(nsIPresContext* aPresContext, return result; } + // Style change notifications +NS_IMETHODIMP +HTMLStyleSheetImpl::StyleRuleChanged(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) +{ + nsIPresShell* shell = aPresContext->GetShell(); + nsIFrame* frame = shell->GetRootFrame(); + + PRBool reframe = PR_FALSE; + PRBool reflow = PR_FALSE; + PRBool render = PR_FALSE; + PRBool restyle = PR_FALSE; + switch (aHint) { + default: + case NS_STYLE_HINT_UNKNOWN: + case NS_STYLE_HINT_FRAMECHANGE: + reframe = PR_TRUE; + case NS_STYLE_HINT_REFLOW: + reflow = PR_TRUE; + case NS_STYLE_HINT_VISUAL: + render = PR_TRUE; + case NS_STYLE_HINT_CONTENT: + restyle = PR_TRUE; + break; + case NS_STYLE_HINT_AURAL: + break; + } + + if (restyle) { + nsIStyleContext* sc; + frame->GetStyleContext(sc); + sc->RemapStyle(aPresContext); + NS_RELEASE(sc); + } + + // XXX hack, skip the root and scrolling frames + frame->FirstChild(nsnull, frame); + frame->FirstChild(nsnull, frame); + if (reframe) { + NS_NOTYETIMPLEMENTED("frame change reflow"); + } + else if (reflow) { + StyleChangeReflow(aPresContext, frame, nsnull); + } + else if (render) { + ApplyRenderingChangeToTree(aPresContext, frame); + } + + NS_RELEASE(shell); + + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::StyleRuleAdded(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + return NS_OK; +} + +NS_IMETHODIMP +HTMLStyleSheetImpl::StyleRuleRemoved(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + return NS_OK; +} + void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const { @@ -2419,13 +2604,14 @@ void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const } NS_HTML nsresult -NS_NewHTMLStyleSheet(nsIHTMLStyleSheet** aInstancePtrResult, nsIURL* aURL) +NS_NewHTMLStyleSheet(nsIHTMLStyleSheet** aInstancePtrResult, nsIURL* aURL, + nsIDocument* aDocument) { if (aInstancePtrResult == nsnull) { return NS_ERROR_NULL_POINTER; } - HTMLStyleSheetImpl *it = new HTMLStyleSheetImpl(aURL); + HTMLStyleSheetImpl *it = new HTMLStyleSheetImpl(aURL, aDocument); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/layout/style/nsICSSParser.h b/layout/style/nsICSSParser.h index 957e5fef2bd..1827c87b485 100644 --- a/layout/style/nsICSSParser.h +++ b/layout/style/nsICSSParser.h @@ -21,7 +21,7 @@ #include "nslayout.h" #include "nsISupports.h" class nsIStyleRule; -class nsIStyleSheet; +class nsICSSStyleSheet; class nsIUnicharInputStream; class nsIURL; class nsString; @@ -40,11 +40,11 @@ public: // Set a style sheet for the parser to fill in. The style sheet must // implement the nsICSSStyleSheet interface - NS_IMETHOD SetStyleSheet(nsIStyleSheet* aSheet) = 0; + NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet) = 0; NS_IMETHOD Parse(nsIUnicharInputStream* aInput, - nsIURL* aInputURL, - nsIStyleSheet*& aResult) = 0; + nsIURL* aInputURL, + nsICSSStyleSheet*& aResult) = 0; // Parse declarations assuming that the outer curly braces have // already been accounted for. aBaseURL is the base url to use for diff --git a/layout/style/nsICSSStyleRule.h b/layout/style/nsICSSStyleRule.h index dc68d7b0483..f4329a1bd6e 100644 --- a/layout/style/nsICSSStyleRule.h +++ b/layout/style/nsICSSStyleRule.h @@ -25,7 +25,7 @@ class nsIAtom; class nsIArena; class nsString; class nsICSSDeclaration; -class nsIStyleSheet; +class nsICSSStyleSheet; struct nsCSSSelector { public: @@ -66,8 +66,7 @@ public: virtual nsIStyleRule* GetImportantRule(void) = 0; - virtual nsIStyleSheet* GetStyleSheet(void) = 0; - virtual void SetStyleSheet(nsIStyleSheet *aSheet) = 0; + NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet) = 0; }; extern NS_HTML nsresult diff --git a/layout/style/nsIHTMLCSSStyleSheet.h b/layout/style/nsIHTMLCSSStyleSheet.h index 9d39c40f5c6..0820df6b817 100644 --- a/layout/style/nsIHTMLCSSStyleSheet.h +++ b/layout/style/nsIHTMLCSSStyleSheet.h @@ -31,6 +31,7 @@ public: }; extern NS_HTML nsresult - NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURL* aURL); + NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURL* aURL, + nsIDocument* aDocument); #endif /* nsIHTMLCSSStyleSheet_h___ */ diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 2a62721ab2e..0c370f78606 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -87,14 +87,14 @@ public: nsIStyleContext* aParentContext, PRBool aForceUnique = PR_FALSE); - NS_IMETHODIMP ConstructFrame(nsIPresContext* aPresContext, + NS_IMETHOD ConstructFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIFrame*& aFrameSubTree); + NS_IMETHOD ReconstructFrames(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParentFrame, - nsIFrame*& aFrameSubTree); - NS_IMETHOD ReconstructFrames(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsIFrame* aFrameSubTree); + nsIFrame* aFrameSubTree); NS_IMETHOD ContentAppended(nsIPresContext* aPresContext, nsIContent* aContainer, PRInt32 aNewIndexInContainer); @@ -122,6 +122,18 @@ public: // xxx style rules enumeration + // Style change notifications + NS_IMETHOD StyleRuleChanged(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint); // See nsStyleConsts fot hint values + NS_IMETHOD StyleRuleAdded(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + NS_IMETHOD StyleRuleRemoved(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + virtual void List(FILE* out = stdout, PRInt32 aIndent = 0); private: @@ -727,7 +739,31 @@ StyleSetImpl::AttributeChanged(nsIPresContext* aPresContext, } -// xxx style rules enumeration +// Style change notifications +NS_IMETHODIMP +StyleSetImpl::StyleRuleChanged(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) +{ + return mFrameConstructor->StyleRuleChanged(aPresContext, aStyleSheet, aStyleRule, aHint); +} + +NS_IMETHODIMP +StyleSetImpl::StyleRuleAdded(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + return mFrameConstructor->StyleRuleAdded(aPresContext, aStyleSheet, aStyleRule); +} + +NS_IMETHODIMP +StyleSetImpl::StyleRuleRemoved(nsIPresContext* aPresContext, + nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + return mFrameConstructor->StyleRuleRemoved(aPresContext, aStyleSheet, aStyleRule); +} void StyleSetImpl::List(FILE* out, PRInt32 aIndent, nsISupportsArray* aSheets) { diff --git a/layout/xml/document/src/nsXMLContentSink.cpp b/layout/xml/document/src/nsXMLContentSink.cpp index 5bedc97bb92..1ccce3aac1f 100644 --- a/layout/xml/document/src/nsXMLContentSink.cpp +++ b/layout/xml/document/src/nsXMLContentSink.cpp @@ -18,7 +18,6 @@ */ #include "nsXMLContentSink.h" -#include "nsIStyleSheet.h" #include "nsIUnicharInputStream.h" #include "nsIDocument.h" #include "nsIXMLDocument.h" @@ -38,6 +37,7 @@ #include "nsVoidArray.h" #include "nsCRT.h" #include "nsICSSParser.h" +#include "nsICSSStyleSheet.h" #include "nsHTMLAtoms.h" #include "nsIScriptContext.h" #include "nsIScriptContextOwner.h" @@ -695,36 +695,19 @@ nsXMLContentSink::AddComment(const nsIParserNode& aNode) // XXX Borrowed from HTMLContentSink. Should be shared. nsresult nsXMLContentSink::LoadStyleSheet(nsIURL* aURL, - nsIUnicharInputStream* aUIN, - PRBool aInline) + nsIUnicharInputStream* aUIN) { /* XXX use repository */ nsICSSParser* parser; nsresult rv = NS_NewCSSParser(&parser); if (NS_OK == rv) { - if (aInline && (nsnull != mStyleSheet)) { - parser->SetStyleSheet(mStyleSheet); - // XXX we do probably need to trigger a style change reflow - // when we are finished if this is adding data to the same sheet - } - nsIStyleSheet* sheet = nsnull; + nsICSSStyleSheet* sheet = nsnull; // XXX note: we are ignoring rv until the error code stuff in the // input routines is converted to use nsresult's parser->Parse(aUIN, aURL, sheet); if (nsnull != sheet) { - if (aInline) { - if (nsnull == mStyleSheet) { - // Add in the sheet the first time; if we update the sheet - // with new data (mutliple style tags in the same document) - // then the sheet will be updated by the css parser and - // therefore we don't need to add it to the document) - mDocument->AddStyleSheet(sheet); - mStyleSheet = sheet; - } - } - else { - mDocument->AddStyleSheet(sheet); - } + mDocument->AddStyleSheet(sheet); + NS_RELEASE(sheet); rv = NS_OK; } else { rv = NS_ERROR_OUT_OF_MEMORY;/* XXX */ @@ -827,7 +810,7 @@ nsXMLContentSink::AddProcessingInstruction(const nsIParserNode& aNode) return result; } - result = LoadStyleSheet(url, uin, PR_FALSE); + result = LoadStyleSheet(url, uin); NS_RELEASE(uin); NS_RELEASE(url); } diff --git a/layout/xml/document/src/nsXMLContentSink.h b/layout/xml/document/src/nsXMLContentSink.h index 5724fd9213a..64f099ce797 100644 --- a/layout/xml/document/src/nsXMLContentSink.h +++ b/layout/xml/document/src/nsXMLContentSink.h @@ -32,7 +32,6 @@ class nsIContent; class nsVoidArray; class nsIXMLDocument; class nsIUnicharInputStream; -class nsIStyleSheet; typedef enum { eXMLContentSinkState_InProlog, @@ -79,8 +78,7 @@ protected: void StartLayout(); nsresult LoadStyleSheet(nsIURL* aURL, - nsIUnicharInputStream* aUIN, - PRBool aInline); + nsIUnicharInputStream* aUIN); nsresult FlushText(PRBool aCreateTextNode=PR_TRUE, PRBool* aDidFlush=nsnull); @@ -119,7 +117,6 @@ protected: PRInt32 mNestLevel; nsVoidArray* mContentStack; - nsIStyleSheet* mStyleSheet; nsScrollPreference mOriginalScrollPreference; PRUnichar* mText; diff --git a/layout/xml/document/src/nsXMLDocument.cpp b/layout/xml/document/src/nsXMLDocument.cpp index 7b81022a553..228f0487fcc 100644 --- a/layout/xml/document/src/nsXMLDocument.cpp +++ b/layout/xml/document/src/nsXMLDocument.cpp @@ -85,7 +85,10 @@ nsXMLDocument::~nsXMLDocument() } mNameSpaces = nsnull; } - NS_IF_RELEASE(mAttrStyleSheet); + if (nsnull != mAttrStyleSheet) { + mAttrStyleSheet->SetOwningDocument(nsnull); + NS_RELEASE(mAttrStyleSheet); + } if (nsnull != mProlog) { delete mProlog; } @@ -136,6 +139,11 @@ nsXMLDocument::StartDocumentLoad(nsIURL *aUrl, return rv; } + if (nsnull != mAttrStyleSheet) { + mAttrStyleSheet->SetOwningDocument(nsnull); + NS_RELEASE(mAttrStyleSheet); + } + nsIWebShell* webShell; static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID); @@ -154,7 +162,7 @@ nsXMLDocument::StartDocumentLoad(nsIURL *aUrl, if (NS_OK == rv) { // For the HTML content within a document - if (NS_OK == NS_NewHTMLStyleSheet(&mAttrStyleSheet, aUrl)) { + if (NS_OK == NS_NewHTMLStyleSheet(&mAttrStyleSheet, aUrl, this)) { AddStyleSheet(mAttrStyleSheet); // tell the world about our new style sheet } diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp index 045f47579e8..d5b995304f8 100644 --- a/uriloader/base/nsDocLoader.cpp +++ b/uriloader/base/nsDocLoader.cpp @@ -46,6 +46,7 @@ #include "nsIDocument.h" #include "nsIDocumentViewer.h" #include "nsICSSParser.h" +#include "nsICSSStyleSheet.h" #include "nsLayoutCID.h" /* Forward declarations.... */ @@ -197,7 +198,7 @@ public: nsIContentViewer** aDocViewer); }; -static nsIStyleSheet* gUAStyleSheet; +static nsICSSStyleSheet* gUAStyleSheet; nsDocFactoryImpl::nsDocFactoryImpl() { @@ -535,7 +536,7 @@ nsresult nsDocFactoryImpl::InitUAStyleSheet() NS_RELEASE(in); } else { -// printf("open of %s failed: error=%x\n", UA_CSS_URL, ec); + printf("open of %s failed: error=%x\n", UA_CSS_URL, ec); rv = NS_ERROR_ILLEGAL_VALUE; // XXX need a better error code here } diff --git a/webshell/src/nsDocLoader.cpp b/webshell/src/nsDocLoader.cpp index 045f47579e8..d5b995304f8 100644 --- a/webshell/src/nsDocLoader.cpp +++ b/webshell/src/nsDocLoader.cpp @@ -46,6 +46,7 @@ #include "nsIDocument.h" #include "nsIDocumentViewer.h" #include "nsICSSParser.h" +#include "nsICSSStyleSheet.h" #include "nsLayoutCID.h" /* Forward declarations.... */ @@ -197,7 +198,7 @@ public: nsIContentViewer** aDocViewer); }; -static nsIStyleSheet* gUAStyleSheet; +static nsICSSStyleSheet* gUAStyleSheet; nsDocFactoryImpl::nsDocFactoryImpl() { @@ -535,7 +536,7 @@ nsresult nsDocFactoryImpl::InitUAStyleSheet() NS_RELEASE(in); } else { -// printf("open of %s failed: error=%x\n", UA_CSS_URL, ec); + printf("open of %s failed: error=%x\n", UA_CSS_URL, ec); rv = NS_ERROR_ILLEGAL_VALUE; // XXX need a better error code here }