From 2faa2566a003c59c2f90f1a7d3c43b01b6523602 Mon Sep 17 00:00:00 2001 From: "dbaron%dbaron.org" Date: Wed, 28 Jul 2004 07:08:41 +0000 Subject: [PATCH] Move things that aren't author stylesheets out of nsDocument's mStyleSheets array to simplify stylesheet management code. Add a level of the cascade for style attributes and ensure that there's only one rule processor per level of the cascade, and simplify the logic of nsCSSRuleProcessor creation. b=252578 r+sr=bzbarsky --- chrome/src/nsChromeRegistry.cpp | 4 +- content/base/public/nsIDocument.h | 26 +- content/base/public/nsIDocumentObserver.h | 22 +- content/base/public/nsIStyleSheet.h | 17 +- content/base/src/nsDocument.cpp | 201 +++++++++------ content/base/src/nsDocument.h | 26 +- content/base/src/nsDocumentViewer.cpp | 10 +- content/base/src/nsStyleSet.cpp | 243 ++++++++---------- content/base/src/nsStyleSet.h | 15 +- content/html/document/src/nsHTMLDocument.cpp | 72 ------ content/html/document/src/nsHTMLDocument.h | 8 - content/html/style/public/nsICSSStyleSheet.h | 10 +- content/html/style/src/Makefile.in | 1 - content/html/style/src/nsCSSLoader.cpp | 5 +- ...leRuleProcessor.h => nsCSSRuleProcessor.h} | 65 +++-- content/html/style/src/nsCSSStyleSheet.cpp | 235 +++++------------ .../html/style/src/nsHTMLCSSStyleSheet.cpp | 12 - content/html/style/src/nsHTMLStyleSheet.cpp | 9 - content/html/style/src/nsHTMLStyleSheet.h | 2 - content/xbl/src/nsBindingManager.cpp | 12 - content/xbl/src/nsXBLBinding.cpp | 4 +- content/xbl/src/nsXBLPrototypeBinding.cpp | 6 +- content/xbl/src/nsXBLPrototypeBinding.h | 2 +- content/xbl/src/nsXBLPrototypeResources.cpp | 12 +- content/xbl/src/nsXBLPrototypeResources.h | 4 +- content/xbl/src/nsXBLResourceLoader.cpp | 16 +- content/xml/document/src/nsXMLContentSink.cpp | 8 +- content/xml/document/src/nsXMLDocument.cpp | 86 ------- content/xml/document/src/nsXMLDocument.h | 16 +- content/xul/document/src/nsXULDocument.cpp | 6 +- editor/libeditor/base/nsStyleSheetTxns.cpp | 2 +- layout/base/nsDocumentViewer.cpp | 10 +- layout/base/nsPresShell.cpp | 22 +- layout/html/base/src/nsPresShell.cpp | 22 +- layout/mathml/base/src/nsMathMLFrame.cpp | 3 +- layout/style/nsCSSLoader.cpp | 5 +- layout/style/nsCSSRuleProcessor.h | 92 +++++++ layout/style/nsCSSStyleSheet.cpp | 235 +++++------------ layout/style/nsHTMLCSSStyleSheet.cpp | 12 - layout/style/nsHTMLStyleSheet.cpp | 9 - layout/style/nsHTMLStyleSheet.h | 2 - layout/style/nsICSSStyleSheet.h | 10 +- layout/style/nsIStyleSheet.h | 17 +- layout/style/nsStyleSet.cpp | 243 ++++++++---------- layout/style/nsStyleSet.h | 15 +- rdf/chrome/src/nsChromeRegistry.cpp | 4 +- 46 files changed, 767 insertions(+), 1091 deletions(-) rename content/html/style/src/{nsICSSStyleRuleProcessor.h => nsCSSRuleProcessor.h} (54%) create mode 100644 layout/style/nsCSSRuleProcessor.h diff --git a/chrome/src/nsChromeRegistry.cpp b/chrome/src/nsChromeRegistry.cpp index 4401ec25316c..acb8d2be930f 100644 --- a/chrome/src/nsChromeRegistry.cpp +++ b/chrome/src/nsChromeRegistry.cpp @@ -1428,13 +1428,13 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow) nsCOMArray oldSheets; nsCOMArray newSheets; - PRInt32 count = document->GetNumberOfStyleSheets(PR_FALSE); + PRInt32 count = document->GetNumberOfStyleSheets(); // Iterate over the style sheets. PRInt32 i; for (i = 0; i < count; i++) { // Get the style sheet - nsIStyleSheet *styleSheet = document->GetStyleSheetAt(i, PR_FALSE); + nsIStyleSheet *styleSheet = document->GetStyleSheetAt(i); if (!oldSheets.AppendObject(styleSheet)) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 7e327e648e20..9c75da3dc86f 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -88,9 +88,10 @@ class nsHTMLStyleSheet; class nsIHTMLCSSStyleSheet; // IID for the nsIDocument interface +// c59c70e5-28d1-494b-9f8e-c18368d09ebc #define NS_IDOCUMENT_IID \ -{ 0x6a462127, 0x6382, 0x4b33, \ - { 0x89, 0x34, 0x51, 0x47, 0x2a, 0xd6, 0x21, 0xa7 } } +{ 0xc59c70e5, 0x28d1, 0x494b, \ + { 0x9f, 0x8e, 0xc1, 0x83, 0x68, 0xd0, 0x9e, 0xbc } } // The base value for the content ID counter. // This counter is used by the document to @@ -362,25 +363,18 @@ public: /** * Get the number of stylesheets * - * @param aIncludeSpecialSheets if this is set to true, all sheets - * that are document sheets (including "special" sheets like - * attribute sheets and inline style sheets) will be returned. If - * false, only "normal" stylesheets will be returned * @return the number of stylesheets * @throws no exceptions */ - virtual PRInt32 GetNumberOfStyleSheets(PRBool aIncludeSpecialSheets) const = 0; + virtual PRInt32 GetNumberOfStyleSheets() const = 0; /** * Get a particular stylesheet * @param aIndex the index the stylesheet lives at. This is zero-based - * @param aIncludeSpecialSheets see GetNumberOfStyleSheets. If this - * is false, not all sheets will be returnable * @return the stylesheet at aIndex. Null if aIndex is out of range. * @throws no exceptions */ - virtual nsIStyleSheet* GetStyleSheetAt(PRInt32 aIndex, - PRBool aIncludeSpecialSheets) const = 0; + virtual nsIStyleSheet* GetStyleSheetAt(PRInt32 aIndex) const = 0; /** * Insert a sheet at a particular spot in the stylesheet list (zero-based) @@ -413,7 +407,7 @@ public: /** * Add a stylesheet to the document */ - virtual void AddStyleSheet(nsIStyleSheet* aSheet, PRUint32 aFlags) = 0; + virtual void AddStyleSheet(nsIStyleSheet* aSheet) = 0; /** * Remove a stylesheet from the document @@ -427,6 +421,14 @@ public: virtual void SetStyleSheetApplicableState(nsIStyleSheet* aSheet, PRBool aApplicable) = 0; + /** + * Just like the style sheet API, but for "catalog" sheets, + * extra sheets inserted at the UA level. + */ + virtual PRInt32 GetNumberOfCatalogStyleSheets() const = 0; + virtual nsIStyleSheet* GetCatalogStyleSheetAt(PRInt32 aIndex) const = 0; + virtual void AddCatalogStyleSheet(nsIStyleSheet* aSheet) = 0; + /** * Get this document's CSSLoader. May return null in error * conditions (OOM) diff --git a/content/base/public/nsIDocumentObserver.h b/content/base/public/nsIDocumentObserver.h index c7c6695b74ec..583ff2d8572f 100644 --- a/content/base/public/nsIDocumentObserver.h +++ b/content/base/public/nsIDocumentObserver.h @@ -227,9 +227,12 @@ public: * * @param aDocument The document being observed * @param aStyleSheet the StyleSheet that has been added + * @param aDocumentSheet True if sheet is in document's style sheet list, + * false if sheet is not (i.e., UA or user sheet) */ virtual void StyleSheetAdded(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet) = 0; + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet) = 0; /** * A StyleSheet has just been removed from the document. This @@ -239,9 +242,12 @@ public: * * @param aDocument The document being observed * @param aStyleSheet the StyleSheet that has been removed + * @param aDocumentSheet True if sheet is in document's style sheet list, + * false if sheet is not (i.e., UA or user sheet) */ virtual void StyleSheetRemoved(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet) = 0; + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet) = 0; /** * A StyleSheet has just changed its applicable state. @@ -360,9 +366,11 @@ public: nsIContent* aChild, \ PRInt32 aIndexInContainer); \ virtual void StyleSheetAdded(nsIDocument* aDocument, \ - nsIStyleSheet* aStyleSheet); \ + nsIStyleSheet* aStyleSheet, \ + PRBool aDocumentSheet); \ virtual void StyleSheetRemoved(nsIDocument* aDocument, \ - nsIStyleSheet* aStyleSheet); \ + nsIStyleSheet* aStyleSheet, \ + PRBool aDocumentSheet); \ virtual void StyleSheetApplicableStateChanged(nsIDocument* aDocument, \ nsIStyleSheet* aStyleSheet,\ PRBool aApplicable); \ @@ -463,12 +471,14 @@ _class::ContentRemoved(nsIDocument* aDocument, \ #define NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(_class) \ void \ _class::StyleSheetAdded(nsIDocument* aDocument, \ - nsIStyleSheet* aStyleSheet) \ + nsIStyleSheet* aStyleSheet, \ + PRBool aDocumentSheet) \ { \ } \ void \ _class::StyleSheetRemoved(nsIDocument* aDocument, \ - nsIStyleSheet* aStyleSheet) \ + nsIStyleSheet* aStyleSheet, \ + PRBool aDocumentSheet) \ { \ } \ void \ diff --git a/content/base/public/nsIStyleSheet.h b/content/base/public/nsIStyleSheet.h index 98be248cc2e0..3827372b54b8 100644 --- a/content/base/public/nsIStyleSheet.h +++ b/content/base/public/nsIStyleSheet.h @@ -50,10 +50,19 @@ class nsIContent; class nsIDocument; class nsIStyleRuleProcessor; -// IID for the nsIStyleSheet interface {8c4a80a0-ad6a-11d1-8031-006008159b5a} +// IID for the nsIStyleSheet interface +// 6fbfb2cb-a1c0-4576-9354-a4af4e0029ad #define NS_ISTYLE_SHEET_IID \ -{0x8c4a80a0, 0xad6a, 0x11d1, {0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}} +{0x6fbfb2cb, 0xa1c0, 0x4576, {0x93, 0x54, 0xa4, 0xaf, 0x4e, 0x00, 0x29, 0xad}} +/** + * A style sheet is a thing associated with a document that has style + * rules. Those style rules can be reached in one of two ways, depending + * on which level of the nsStyleSet it is in: + * 1) It can be |QueryInterface|d to nsIStyleRuleProcessor + * 2) It can be |QueryInterface|d to nsICSSStyleSheet, with which the + * |nsStyleSet| uses an |nsCSSRuleProcessor| to access the rules. + */ class nsIStyleSheet : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISTYLE_SHEET_IID) @@ -93,10 +102,6 @@ public: NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const = 0; // may be null NS_IMETHOD SetOwningDocument(nsIDocument* aDocument) = 0; - // style rule processor access - NS_IMETHOD GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* aPrevProcessor) = 0; - #ifdef DEBUG virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; #endif diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 81971543269a..683f1172580b 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -200,12 +200,12 @@ nsDOMStyleSheetList::GetLength(PRUint32* aLength) // observer notification to figure out if new ones have // been added or removed. if (-1 == mLength) { - mLength = mDocument->GetNumberOfStyleSheets(PR_FALSE); + mLength = mDocument->GetNumberOfStyleSheets(); #ifdef DEBUG PRInt32 i; for (i = 0; i < mLength; i++) { - nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(i, PR_FALSE); + nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(i); nsCOMPtr domss(do_QueryInterface(sheet)); NS_ASSERTION(domss, "All \"normal\" sheets implement nsIDOMStyleSheet"); } @@ -225,9 +225,9 @@ nsDOMStyleSheetList::Item(PRUint32 aIndex, nsIDOMStyleSheet** aReturn) { *aReturn = nsnull; if (mDocument) { - PRInt32 count = mDocument->GetNumberOfStyleSheets(PR_FALSE); + PRInt32 count = mDocument->GetNumberOfStyleSheets(); if (aIndex < (PRUint32)count) { - nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(aIndex, PR_FALSE); + nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(aIndex); NS_ASSERTION(sheet, "Must have a sheet"); return CallQueryInterface(sheet, aReturn); } @@ -247,9 +247,10 @@ nsDOMStyleSheetList::DocumentWillBeDestroyed(nsIDocument *aDocument) void nsDOMStyleSheetList::StyleSheetAdded(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet) + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet) { - if (-1 != mLength) { + if (aDocumentSheet && -1 != mLength) { nsCOMPtr domss(do_QueryInterface(aStyleSheet)); if (domss) { mLength++; @@ -259,9 +260,10 @@ nsDOMStyleSheetList::StyleSheetAdded(nsIDocument *aDocument, void nsDOMStyleSheetList::StyleSheetRemoved(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet) + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet) { - if (-1 != mLength) { + if (aDocumentSheet && -1 != mLength) { nsCOMPtr domss(do_QueryInterface(aStyleSheet)); if (domss) { mLength--; @@ -572,6 +574,14 @@ nsDocument::~nsDocument() while (--indx >= 0) { mStyleSheets[indx]->SetOwningDocument(nsnull); } + indx = mCatalogSheets.Count(); + while (--indx >= 0) { + mCatalogSheets[indx]->SetOwningDocument(nsnull); + } + if (mAttrStyleSheet) + mAttrStyleSheet->SetOwningDocument(nsnull); + if (mStyleAttrStyleSheet) + mStyleAttrStyleSheet->SetOwningDocument(nsnull); if (mChildNodes) { mChildNodes->DropReference(); @@ -798,12 +808,31 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI) // XXX Tell observers? } + indx = mCatalogSheets.Count(); + while (--indx >= 0) { + nsIStyleSheet* sheet = mCatalogSheets[indx]; + sheet->SetOwningDocument(nsnull); + + PRBool applicable; + sheet->GetApplicable(applicable); + if (applicable) { + for (PRInt32 i = 0, i_end = mPresShells.Count(); i < i_end; ++i) { + NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(i))->StyleSet()-> + RemoveStyleSheet(nsStyleSet::eAgentSheet, sheet); + } + } + + // XXX Tell observers? + } + + // Release all the sheets mStyleSheets.Clear(); + // NOTE: We don't release the catalog sheets. It doesn't really matter + // now, but it could in the future -- in which case not releasing them + // is probably the right thing to do. - // Now reset our inline style and attribute sheets. Note that we - // already set their owning document to null in the loop above, but - // we'll reset it when we call AddStyleSheet on them. + // Now reset our inline style and attribute sheets. nsresult rv; nsStyleSet::sheetType attrSheetType = GetAttrSheetType(); if (mAttrStyleSheet) { @@ -821,10 +850,15 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI) // Don't use AddStyleSheet, since it'll put the sheet into style // sets in the document level, which is not desirable here. - InternalAddStyleSheet(mAttrStyleSheet, 0); mAttrStyleSheet->SetOwningDocument(this); if (mStyleAttrStyleSheet) { + // Remove this sheet from all style sets + PRInt32 count = mPresShells.Count(); + for (indx = 0; indx < count; ++indx) { + NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(indx))->StyleSet()-> + RemoveStyleSheet(nsStyleSet::eStyleAttrSheet, mStyleAttrStyleSheet); + } rv = mStyleAttrStyleSheet->Reset(aURI); } else { rv = NS_NewHTMLCSSStyleSheet(getter_AddRefs(mStyleAttrStyleSheet), aURI, @@ -834,7 +868,6 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI) // The loop over style sets below will handle putting this sheet // into style sets as needed. - InternalAddStyleSheet(mStyleAttrStyleSheet, 0); mStyleAttrStyleSheet->SetOwningDocument(this); // Now set up our style sets @@ -863,27 +896,34 @@ nsDocument::FillStyleSet(nsStyleSet* aStyleSet) "Style set already has a HTML preshint sheet?"); NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::eDocSheet) == 0, "Style set already has document sheets?"); + NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::eStyleAttrSheet) == 0, + "Style set already has style attr sheets?"); NS_PRECONDITION(mStyleAttrStyleSheet, "No style attr stylesheet?"); NS_PRECONDITION(mAttrStyleSheet, "No attr stylesheet?"); - NS_PRECONDITION(mAttrStyleSheet == GetStyleSheetAt(0, PR_TRUE), - "Unexpected first sheet"); - // First, place the attribute style sheet in the style set. Prepend it, - // since it should be the most significant sheet in its level. - aStyleSet->PrependStyleSheet(GetAttrSheetType(), mAttrStyleSheet); + aStyleSet->AppendStyleSheet(GetAttrSheetType(), mAttrStyleSheet); - // Now that we've handled the attribute sheet, do the other sheets. The - // attribute sheet should be at position 0, hence the loop termination - // condition. - PRInt32 index; - PRBool sheetApplicable; - for (index = GetNumberOfStyleSheets(PR_TRUE) - 1; index > 0; --index) { - nsIStyleSheet* sheet = GetStyleSheetAt(index, PR_TRUE); + aStyleSet->AppendStyleSheet(nsStyleSet::eStyleAttrSheet, + mStyleAttrStyleSheet); + + PRInt32 i; + for (i = mStyleSheets.Count() - 1; i >= 0; --i) { + nsIStyleSheet* sheet = mStyleSheets[i]; + PRBool sheetApplicable; sheet->GetApplicable(sheetApplicable); if (sheetApplicable) { aStyleSet->AddDocStyleSheet(sheet, this); } } + + for (i = mCatalogSheets.Count() - 1; i >= 0; --i) { + nsIStyleSheet* sheet = mCatalogSheets[i]; + PRBool sheetApplicable; + sheet->GetApplicable(sheetApplicable); + if (sheetApplicable) { + aStyleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet); + } + } } nsresult @@ -1172,6 +1212,8 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAString& aData) if (aHeaderField == nsHTMLAtoms::headerDefaultStyle) { // switch alternate style sheets based on default + // XXXldb What if we don't have all the sheets yet? Should this use + // the DOM API for preferred stylesheet set that's "coming soon"? nsAutoString type; nsAutoString title; PRInt32 index; @@ -1463,56 +1505,24 @@ nsDocument::GetChildCount() const } PRInt32 -nsDocument::InternalGetNumberOfStyleSheets() const +nsDocument::GetNumberOfStyleSheets() const { return mStyleSheets.Count(); } -PRInt32 -nsDocument::GetNumberOfStyleSheets(PRBool aIncludeSpecialSheets) const -{ - if (aIncludeSpecialSheets) { - return mStyleSheets.Count(); - } - - return InternalGetNumberOfStyleSheets(); -} - nsIStyleSheet* -nsDocument::InternalGetStyleSheetAt(PRInt32 aIndex) const +nsDocument::GetStyleSheetAt(PRInt32 aIndex) const { - NS_ASSERTION(aIndex >= 0 && aIndex < mStyleSheets.Count(), "Invalid index"); + NS_ENSURE_TRUE(0 <= aIndex && aIndex < mStyleSheets.Count(), nsnull); return mStyleSheets[aIndex]; } -nsIStyleSheet* -nsDocument::GetStyleSheetAt(PRInt32 aIndex, PRBool aIncludeSpecialSheets) const -{ - if (aIncludeSpecialSheets) { - if (aIndex < 0 || aIndex >= mStyleSheets.Count()) { - NS_ERROR("Index out of range"); - return nsnull; - } - - return mStyleSheets[aIndex]; - } - - return InternalGetStyleSheetAt(aIndex); -} - PRInt32 nsDocument::GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const { return mStyleSheets.IndexOf(aSheet); } -// subclass hooks for sheet ordering -void -nsDocument::InternalAddStyleSheet(nsIStyleSheet* aSheet, PRUint32 aFlags) -{ - mStyleSheets.AppendObject(aSheet); -} - void nsDocument::AddStyleSheetToStyleSets(nsIStyleSheet* aSheet) { @@ -1525,10 +1535,10 @@ nsDocument::AddStyleSheetToStyleSets(nsIStyleSheet* aSheet) } void -nsDocument::AddStyleSheet(nsIStyleSheet* aSheet, PRUint32 aFlags) +nsDocument::AddStyleSheet(nsIStyleSheet* aSheet) { NS_PRECONDITION(aSheet, "null arg"); - InternalAddStyleSheet(aSheet, aFlags); + mStyleSheets.AppendObject(aSheet); aSheet->SetOwningDocument(this); PRBool applicable; @@ -1544,19 +1554,16 @@ nsDocument::AddStyleSheet(nsIStyleSheet* aSheet, PRUint32 aFlags) nsIDocumentObserver* observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i)); - observer->StyleSheetAdded(this, aSheet); + observer->StyleSheetAdded(this, aSheet, PR_TRUE); } } void nsDocument::RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet) { - PRInt32 count = mPresShells.Count(); - PRInt32 indx; - for (indx = 0; indx < count; ++indx) { - NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(indx))->StyleSet()-> + for (PRInt32 i = 0, i_end = mPresShells.Count(); i < i_end; ++i) + NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(i))->StyleSet()-> RemoveStyleSheet(nsStyleSet::eDocSheet, aSheet); - } } void @@ -1584,7 +1591,7 @@ nsDocument::RemoveStyleSheet(nsIStyleSheet* aSheet) nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(indx)); - observer->StyleSheetRemoved(this, aSheet); + observer->StyleSheetRemoved(this, aSheet, PR_TRUE); } } @@ -1635,7 +1642,7 @@ nsDocument::UpdateStyleSheets(nsCOMArray& aOldSheets, nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(obsIndx)); - observer->StyleSheetAdded(this, newSheet); + observer->StyleSheetAdded(this, newSheet, PR_TRUE); } } } @@ -1648,19 +1655,11 @@ nsDocument::UpdateStyleSheets(nsCOMArray& aOldSheets, } } - -void -nsDocument::InternalInsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex) -{ - // subclass hook for sheet ordering - mStyleSheets.InsertObjectAt(aSheet, aIndex); -} - void nsDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex) { NS_PRECONDITION(aSheet, "null ptr"); - InternalInsertStyleSheetAt(aSheet, aIndex); + mStyleSheets.InsertObjectAt(aSheet, aIndex); aSheet->SetOwningDocument(this); @@ -1678,7 +1677,7 @@ nsDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex) nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i)); - observer->StyleSheetAdded(this, aSheet); + observer->StyleSheetAdded(this, aSheet, PR_TRUE); } } @@ -1711,6 +1710,48 @@ nsDocument::SetStyleSheetApplicableState(nsIStyleSheet* aSheet, } } +// These three functions are a lot like the implementation of the +// corresponding API for regular stylesheets. + +PRInt32 +nsDocument::GetNumberOfCatalogStyleSheets() const +{ + return mCatalogSheets.Count(); +} + +nsIStyleSheet* +nsDocument::GetCatalogStyleSheetAt(PRInt32 aIndex) const +{ + NS_ENSURE_TRUE(0 <= aIndex && aIndex < mCatalogSheets.Count(), nsnull); + return mCatalogSheets[aIndex]; +} + +void +nsDocument::AddCatalogStyleSheet(nsIStyleSheet* aSheet) +{ + mCatalogSheets.AppendObject(aSheet); + aSheet->SetOwningDocument(this); + + PRBool applicable; + aSheet->GetApplicable(applicable); + + if (applicable) { + // This is like |AddStyleSheetToStyleSets|, but for an agent sheet. + for (PRInt32 i = 0, i_end = mPresShells.Count(); i < i_end; ++i) + NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(i))->StyleSet()-> + AppendStyleSheet(nsStyleSet::eAgentSheet, aSheet); + } + + // if an observer removes itself, we're ok (not if it removes others though) + PRInt32 i; + for (i = mObservers.Count() - 1; i >= 0; --i) { + nsIDocumentObserver* observer = + NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i)); + + observer->StyleSheetAdded(this, aSheet, PR_FALSE); + } +} + nsIScriptGlobalObject* nsDocument::GetScriptGlobalObject() const { diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index 9729c9809ca6..4232aa746d4e 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -158,9 +158,11 @@ public: // nsIDocumentObserver virtual void DocumentWillBeDestroyed(nsIDocument *aDocument); virtual void StyleSheetAdded(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet); + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet); virtual void StyleSheetRemoved(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet); + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet); protected: PRInt32 mLength; @@ -304,11 +306,10 @@ public: * Get the style sheets owned by this document. * These are ordered, highest priority last */ - virtual PRInt32 GetNumberOfStyleSheets(PRBool aIncludeSpecialSheets) const; - virtual nsIStyleSheet* GetStyleSheetAt(PRInt32 aIndex, - PRBool aIncludeSpecialSheets) const; + virtual PRInt32 GetNumberOfStyleSheets() const; + virtual nsIStyleSheet* GetStyleSheetAt(PRInt32 aIndex) const; virtual PRInt32 GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const; - virtual void AddStyleSheet(nsIStyleSheet* aSheet, PRUint32 aFlags); + virtual void AddStyleSheet(nsIStyleSheet* aSheet); virtual void RemoveStyleSheet(nsIStyleSheet* aSheet); virtual void UpdateStyleSheets(nsCOMArray& aOldSheets, @@ -320,6 +321,11 @@ public: virtual void SetStyleSheetApplicableState(nsIStyleSheet* aSheet, PRBool aApplicable); + virtual PRInt32 GetNumberOfCatalogStyleSheets() const; + virtual nsIStyleSheet* GetCatalogStyleSheetAt(PRInt32 aIndex) const; + virtual void AddCatalogStyleSheet(nsIStyleSheet* aSheet); + + /** * Get this document's attribute stylesheet. May return null if * there isn't one. @@ -503,13 +509,6 @@ public: nsIContent **aResult); protected: - // subclass hooks for sheet ordering - virtual void InternalAddStyleSheet(nsIStyleSheet* aSheet, - PRUint32 aFlags); - virtual void InternalInsertStyleSheetAt(nsIStyleSheet* aSheet, - PRInt32 aIndex); - virtual nsIStyleSheet* InternalGetStyleSheetAt(PRInt32 aIndex) const; - virtual PRInt32 InternalGetNumberOfStyleSheets() const; void RetrieveRelevantHeaders(nsIChannel *aChannel); @@ -551,6 +550,7 @@ protected: nsCOMArray mChildren; nsCOMArray mStyleSheets; + nsCOMArray mCatalogSheets; // Basically always has at least 1 entry nsAutoVoidArray mObservers; diff --git a/content/base/src/nsDocumentViewer.cpp b/content/base/src/nsDocumentViewer.cpp index 77a209c08047..8405d6b5770d 100644 --- a/content/base/src/nsDocumentViewer.cpp +++ b/content/base/src/nsDocumentViewer.cpp @@ -1752,7 +1752,7 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, } if (sheet) - styleSet->PrependStyleSheet(nsStyleSet::eUserSheet, sheet); + styleSet->AppendStyleSheet(nsStyleSet::eUserSheet, sheet); // Append chrome sheets (scrollbars + forms). PRBool shouldOverride = PR_FALSE; @@ -1783,7 +1783,7 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, cssLoader->LoadAgentSheet(uri, getter_AddRefs(csssheet)); if (!sheet) continue; - styleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, csssheet); + styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, csssheet); shouldOverride = PR_TRUE; } nsMemory::Free(str); @@ -1794,17 +1794,17 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, if (!shouldOverride) { sheet = nsLayoutStylesheetCache::ScrollbarsSheet(); if (sheet) { - styleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet); + styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet); } } sheet = nsLayoutStylesheetCache::FormsSheet(); if (sheet) { - styleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet); + styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet); } if (mUAStyleSheet) { - styleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, mUAStyleSheet); + styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, mUAStyleSheet); } // Caller will handle calling EndUpdate, per contract. diff --git a/content/base/src/nsStyleSet.cpp b/content/base/src/nsStyleSet.cpp index abf263de3e5e..d61bbc6d694a 100644 --- a/content/base/src/nsStyleSet.cpp +++ b/content/base/src/nsStyleSet.cpp @@ -45,6 +45,7 @@ #include "nsICSSStyleRule.h" #include "nsCSSAnonBoxes.h" #include "nsCSSPseudoElements.h" +#include "nsCSSRuleProcessor.h" #include "nsIContent.h" #include "nsIFrame.h" @@ -90,42 +91,33 @@ nsStyleSet::Init(nsIPresContext *aPresContext) return NS_OK; } -struct RuleProcessorEnumData { - RuleProcessorEnumData(nsCOMArray *aRuleProcessors) - : mRuleProcessors(aRuleProcessors), - mPrevProcessor(nsnull) - {} - - nsCOMArray* mRuleProcessors; - nsIStyleRuleProcessor* mPrevProcessor; -}; - -static PRBool -EnumRuleProcessor(nsIStyleSheet *aSheet, void* aData) -{ - RuleProcessorEnumData* data = (RuleProcessorEnumData*)aData; - - nsCOMPtr processor; - nsresult result = aSheet->GetStyleRuleProcessor(*getter_AddRefs(processor), - data->mPrevProcessor); - if (NS_SUCCEEDED(result) && processor) { - if (processor != data->mPrevProcessor) { - if (!data->mRuleProcessors->AppendObject(processor)) - return PR_FALSE; - data->mPrevProcessor = processor; // ref is held by array - } - } - return PR_TRUE; -} - nsresult -nsStyleSet::GatherRuleProcessors(PRInt32 aType) +nsStyleSet::GatherRuleProcessors(sheetType aType) { - mRuleProcessors[aType].Clear(); + mRuleProcessors[aType] = nsnull; if (mSheets[aType].Count()) { - RuleProcessorEnumData data(&mRuleProcessors[aType]); - if (!mSheets[aType].EnumerateBackwards(EnumRuleProcessor, &data)) - return NS_ERROR_OUT_OF_MEMORY; + switch (aType) { + case eAgentSheet: + case eUserSheet: + case eDocSheet: + case eOverrideSheet: { + // levels containing CSS stylesheets + nsCOMArray& sheets = mSheets[aType]; + nsCOMArray cssSheets(sheets.Count()); + for (PRInt32 i = 0, i_end = sheets.Count(); i < i_end; ++i) { + nsCOMPtr cssSheet = do_QueryInterface(sheets[i]); + NS_ASSERTION(cssSheet, "not a CSS sheet"); + cssSheets.AppendObject(cssSheet); + } + mRuleProcessors[aType] = new nsCSSRuleProcessor(cssSheets); + } break; + + default: + // levels containing non-CSS stylesheets + NS_ASSERTION(mSheets[aType].Count() == 1, "only one sheet per level"); + mRuleProcessors[aType] = do_QueryInterface(mSheets[aType][0]); + break; + } } return NS_OK; @@ -217,23 +209,18 @@ nsStyleSet::AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument) nsCOMArray& docSheets = mSheets[eDocSheet]; docSheets.RemoveObject(aSheet); - // lowest index last + // lowest index first PRInt32 newDocIndex = aDocument->GetIndexOfStyleSheet(aSheet); PRInt32 count = docSheets.Count(); - for (PRInt32 index = 0; index < count; index++) { + PRInt32 index; + for (index = 0; index < count; index++) { nsIStyleSheet* sheet = docSheets.ObjectAt(index); PRInt32 sheetDocIndex = aDocument->GetIndexOfStyleSheet(sheet); - if (sheetDocIndex < newDocIndex) { - if (!docSheets.InsertObjectAt(aSheet, index)) - return NS_ERROR_OUT_OF_MEMORY; - - index = count; // break loop - } - } - if (docSheets.Count() == count) { // didn't insert it - if (!docSheets.AppendObject(aSheet)) - return NS_ERROR_OUT_OF_MEMORY; + if (sheetDocIndex > newDocIndex) + break; } + if (!docSheets.InsertObjectAt(aSheet, index)) + return NS_ERROR_OUT_OF_MEMORY; if (!mBatching) return GatherRuleProcessors(eDocSheet); @@ -261,7 +248,7 @@ nsStyleSet::EndUpdate() for (int i = 0; i < eSheetTypeCount; ++i) { if (mDirty & (1 << i)) { - nsresult rv = GatherRuleProcessors(i); + nsresult rv = GatherRuleProcessors(sheetType(i)); NS_ENSURE_SUCCESS(rv, rv); } } @@ -302,12 +289,11 @@ nsStyleSet::EnableQuirkStyleSheet(PRBool aEnable) NS_ASSERTION(mQuirkStyleSheet, "no quirk stylesheet"); if (mQuirkStyleSheet) { #ifdef DEBUG_dbaron_off // XXX Make this |DEBUG| once it stops firing. - PRInt32 count = mRuleProcessors[eAgentSheet].Count() PRBool applicableNow; mQuirkStyleSheet->GetApplicable(applicableNow); - NS_ASSERTION(count == 0 || aEnable == applicableNow, + NS_ASSERTION(!mRuleProcessors[eAgentSheet] || aEnable == applicableNow, "enabling/disabling quirk stylesheet too late or incomplete quirk stylesheet"); - if (count != 0 && aEnable == applicableNow) + if (mRuleProcessors[eAgentSheet] && aEnable == applicableNow) printf("WARNING: We set the quirks mode too many times.\n"); // we do! #endif mQuirkStyleSheet->SetEnabled(aEnable); @@ -442,47 +428,36 @@ nsStyleSet::FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc, SheetCount(eHTMLPresHintSheet) == 0, "Can't have both types of preshint sheets at once!"); - nsRuleNode* lastAgentRN = nsnull; - if (mRuleProcessors[eAgentSheet].Count()) { - mRuleProcessors[eAgentSheet].EnumerateForwards(aCollectorFunc, aData); - lastAgentRN = mRuleWalker->GetCurrentNode(); - } + if (mRuleProcessors[eAgentSheet]) + (*aCollectorFunc)(mRuleProcessors[eAgentSheet], aData); + nsRuleNode* lastAgentRN = mRuleWalker->GetCurrentNode(); - nsRuleNode* lastPresHintRN = lastAgentRN; - if (mRuleProcessors[ePresHintSheet].Count()) { - mRuleProcessors[ePresHintSheet].EnumerateForwards(aCollectorFunc, aData); - lastPresHintRN = mRuleWalker->GetCurrentNode(); - } + if (mRuleProcessors[ePresHintSheet]) + (*aCollectorFunc)(mRuleProcessors[ePresHintSheet], aData); + nsRuleNode* lastPresHintRN = mRuleWalker->GetCurrentNode(); - nsRuleNode* lastUserRN = lastPresHintRN; - if (mRuleProcessors[eUserSheet].Count()) { - mRuleProcessors[eUserSheet].EnumerateForwards(aCollectorFunc, aData); - lastUserRN = mRuleWalker->GetCurrentNode(); - } + if (mRuleProcessors[eUserSheet]) + (*aCollectorFunc)(mRuleProcessors[eUserSheet], aData); + nsRuleNode* lastUserRN = mRuleWalker->GetCurrentNode(); - nsRuleNode* lastHTMLPresHintRN = lastUserRN; - if (mRuleProcessors[eHTMLPresHintSheet].Count()) { - mRuleProcessors[eHTMLPresHintSheet].EnumerateForwards(aCollectorFunc, aData); - lastHTMLPresHintRN = mRuleWalker->GetCurrentNode(); - } + if (mRuleProcessors[eHTMLPresHintSheet]) + (*aCollectorFunc)(mRuleProcessors[eHTMLPresHintSheet], aData); + nsRuleNode* lastHTMLPresHintRN = mRuleWalker->GetCurrentNode(); - nsRuleNode* lastDocRN = lastHTMLPresHintRN; PRBool useRuleProcessors = PR_TRUE; if (mStyleRuleSupplier) { // We can supply additional document-level sheets that should be walked. mStyleRuleSupplier->WalkRules(this, aCollectorFunc, aData); mStyleRuleSupplier->UseDocumentRules(aData->mContent, &useRuleProcessors); } - if (useRuleProcessors && mRuleProcessors[eDocSheet].Count()) { - mRuleProcessors[eDocSheet].EnumerateForwards(aCollectorFunc, aData); - } - lastDocRN = mRuleWalker->GetCurrentNode(); + if (useRuleProcessors && mRuleProcessors[eDocSheet]) // NOTE: different + (*aCollectorFunc)(mRuleProcessors[eDocSheet], aData); + if (mRuleProcessors[eStyleAttrSheet]) + (*aCollectorFunc)(mRuleProcessors[eStyleAttrSheet], aData); - nsRuleNode* lastOvrRN = lastDocRN; - if (mRuleProcessors[eOverrideSheet].Count()) { - mRuleProcessors[eOverrideSheet].EnumerateForwards(aCollectorFunc, aData); - lastOvrRN = mRuleWalker->GetCurrentNode(); - } + if (mRuleProcessors[eOverrideSheet]) + (*aCollectorFunc)(mRuleProcessors[eOverrideSheet], aData); + nsRuleNode* lastOvrRN = mRuleWalker->GetCurrentNode(); // There should be no important rules in the preshint or HTMLpreshint level AddImportantRules(lastOvrRN, lastHTMLPresHintRN); // doc and override @@ -509,17 +484,14 @@ nsStyleSet::WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc, SheetCount(eHTMLPresHintSheet) == 0, "Can't have both types of preshint sheets at once!"); - // Walk the agent rules first. - mRuleProcessors[eAgentSheet].EnumerateForwards(aFunc, aData); - - // Walk preshint rules. - mRuleProcessors[ePresHintSheet].EnumerateForwards(aFunc, aData); - - // Walk the user rules next. - mRuleProcessors[eUserSheet].EnumerateForwards(aFunc, aData); - - // Walk HTML preshint rules. - mRuleProcessors[eHTMLPresHintSheet].EnumerateForwards(aFunc, aData); + if (mRuleProcessors[eAgentSheet]) + (*aFunc)(mRuleProcessors[eAgentSheet], aData); + if (mRuleProcessors[ePresHintSheet]) + (*aFunc)(mRuleProcessors[ePresHintSheet], aData); + if (mRuleProcessors[eUserSheet]) + (*aFunc)(mRuleProcessors[eUserSheet], aData); + if (mRuleProcessors[eHTMLPresHintSheet]) + (*aFunc)(mRuleProcessors[eHTMLPresHintSheet], aData); PRBool useRuleProcessors = PR_TRUE; if (mStyleRuleSupplier) { @@ -527,13 +499,12 @@ nsStyleSet::WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc, mStyleRuleSupplier->WalkRules(this, aFunc, aData); mStyleRuleSupplier->UseDocumentRules(aData->mContent, &useRuleProcessors); } - - // Now walk the doc rules. - if (useRuleProcessors) - mRuleProcessors[eDocSheet].EnumerateForwards(aFunc, aData); - - // Walk the override rules last. - mRuleProcessors[eOverrideSheet].EnumerateForwards(aFunc, aData); + if (useRuleProcessors && mRuleProcessors[eDocSheet]) // NOTE: different + (*aFunc)(mRuleProcessors[eDocSheet], aData); + if (mRuleProcessors[eStyleAttrSheet]) + (*aFunc)(mRuleProcessors[eStyleAttrSheet], aData); + if (mRuleProcessors[eOverrideSheet]) + (*aFunc)(mRuleProcessors[eOverrideSheet], aData); } PRBool nsStyleSet::BuildDefaultStyleData(nsIPresContext* aPresContext) @@ -581,12 +552,13 @@ nsStyleSet::ResolveStyleFor(nsIContent* aContent, "content must be element"); if (aContent && presContext) { - if (mRuleProcessors[eAgentSheet].Count() || - mRuleProcessors[ePresHintSheet].Count() || - mRuleProcessors[eUserSheet].Count() || - mRuleProcessors[eHTMLPresHintSheet].Count() || - mRuleProcessors[eDocSheet].Count() || - mRuleProcessors[eOverrideSheet].Count()) { + if (mRuleProcessors[eAgentSheet] || + mRuleProcessors[ePresHintSheet] || + mRuleProcessors[eUserSheet] || + mRuleProcessors[eHTMLPresHintSheet] || + mRuleProcessors[eDocSheet] || + mRuleProcessors[eStyleAttrSheet] || + mRuleProcessors[eOverrideSheet]) { RulesMatchingData data(presContext, aContent, mRuleWalker); FileRules(EnumRulesMatching, &data); result = GetContext(presContext, aParentContext, nsnull).get(); @@ -606,12 +578,13 @@ nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext) nsIPresContext *presContext = PresContext(); if (presContext) { - if (mRuleProcessors[eAgentSheet].Count() || - mRuleProcessors[ePresHintSheet].Count() || - mRuleProcessors[eUserSheet].Count() || - mRuleProcessors[eHTMLPresHintSheet].Count() || - mRuleProcessors[eDocSheet].Count() || - mRuleProcessors[eOverrideSheet].Count()) { + if (mRuleProcessors[eAgentSheet] || + mRuleProcessors[ePresHintSheet] || + mRuleProcessors[eUserSheet] || + mRuleProcessors[eHTMLPresHintSheet] || + mRuleProcessors[eDocSheet] || + mRuleProcessors[eStyleAttrSheet] || + mRuleProcessors[eOverrideSheet]) { result = GetContext(presContext, aParentContext, nsCSSAnonBoxes::mozNonElement).get(); NS_ASSERTION(mRuleWalker->AtRoot(), "rule walker must be at root"); @@ -660,12 +633,13 @@ nsStyleSet::ResolvePseudoStyleFor(nsIContent* aParentContent, "content (if non-null) must be element"); if (aPseudoTag && presContext) { - if (mRuleProcessors[eAgentSheet].Count() || - mRuleProcessors[ePresHintSheet].Count() || - mRuleProcessors[eUserSheet].Count() || - mRuleProcessors[eHTMLPresHintSheet].Count() || - mRuleProcessors[eDocSheet].Count() || - mRuleProcessors[eOverrideSheet].Count()) { + if (mRuleProcessors[eAgentSheet] || + mRuleProcessors[ePresHintSheet] || + mRuleProcessors[eUserSheet] || + mRuleProcessors[eHTMLPresHintSheet] || + mRuleProcessors[eDocSheet] || + mRuleProcessors[eStyleAttrSheet] || + mRuleProcessors[eOverrideSheet]) { PseudoRulesMatchingData data(presContext, aParentContent, aPseudoTag, aComparator, mRuleWalker); FileRules(EnumPseudoRulesMatching, &data); @@ -694,12 +668,13 @@ nsStyleSet::ProbePseudoStyleFor(nsIContent* aParentContent, "content (if non-null) must be element"); if (aPseudoTag && presContext) { - if (mRuleProcessors[eAgentSheet].Count() || - mRuleProcessors[ePresHintSheet].Count() || - mRuleProcessors[eUserSheet].Count() || - mRuleProcessors[eHTMLPresHintSheet].Count() || - mRuleProcessors[eDocSheet].Count() || - mRuleProcessors[eOverrideSheet].Count()) { + if (mRuleProcessors[eAgentSheet] || + mRuleProcessors[ePresHintSheet] || + mRuleProcessors[eUserSheet] || + mRuleProcessors[eHTMLPresHintSheet] || + mRuleProcessors[eDocSheet] || + mRuleProcessors[eStyleAttrSheet] || + mRuleProcessors[eOverrideSheet]) { PseudoRulesMatchingData data(presContext, aParentContent, aPseudoTag, nsnull, mRuleWalker); FileRules(EnumPseudoRulesMatching, &data); @@ -853,12 +828,13 @@ nsStyleSet::HasStateDependentStyle(nsIPresContext* aPresContext, nsReStyleHint result = nsReStyleHint(0); if (aContent->IsContentOfType(nsIContent::eELEMENT) && - (mRuleProcessors[eAgentSheet].Count() || - mRuleProcessors[ePresHintSheet].Count() || - mRuleProcessors[eUserSheet].Count() || - mRuleProcessors[eHTMLPresHintSheet].Count() || - mRuleProcessors[eDocSheet].Count() || - mRuleProcessors[eOverrideSheet].Count())) { + (mRuleProcessors[eAgentSheet] || + mRuleProcessors[ePresHintSheet] || + mRuleProcessors[eUserSheet] || + mRuleProcessors[eHTMLPresHintSheet] || + mRuleProcessors[eDocSheet] || + mRuleProcessors[eStyleAttrSheet] || + mRuleProcessors[eOverrideSheet])) { StatefulData data(aPresContext, aContent, aStateMask); WalkRuleProcessors(SheetHasStatefulStyle, &data); result = data.mHint; @@ -898,12 +874,13 @@ nsStyleSet::HasAttributeDependentStyle(nsIPresContext* aPresContext, nsReStyleHint result = nsReStyleHint(0); if (aContent->IsContentOfType(nsIContent::eELEMENT) && - (mRuleProcessors[eAgentSheet].Count() || - mRuleProcessors[ePresHintSheet].Count() || - mRuleProcessors[eUserSheet].Count() || - mRuleProcessors[eHTMLPresHintSheet].Count() || - mRuleProcessors[eDocSheet].Count() || - mRuleProcessors[eOverrideSheet].Count())) { + (mRuleProcessors[eAgentSheet] || + mRuleProcessors[ePresHintSheet] || + mRuleProcessors[eUserSheet] || + mRuleProcessors[eHTMLPresHintSheet] || + mRuleProcessors[eDocSheet] || + mRuleProcessors[eStyleAttrSheet] || + mRuleProcessors[eOverrideSheet])) { AttributeData data(aPresContext, aContent, aAttribute, aModType); WalkRuleProcessors(SheetHasAttributeStyle, &data); result = data.mHint; diff --git a/content/base/src/nsStyleSet.h b/content/base/src/nsStyleSet.h index 1f0723e74cdb..81bdf4076697 100644 --- a/content/base/src/nsStyleSet.h +++ b/content/base/src/nsStyleSet.h @@ -153,13 +153,16 @@ class nsStyleSet // APIs to manipulate the style sheet lists. // All sheet types are ordered most-significant-first. enum sheetType { - eAgentSheet, + eAgentSheet, // CSS ePresHintSheet, - eUserSheet, + eUserSheet, // CSS eHTMLPresHintSheet, - eDocSheet, - eOverrideSheet, + eDocSheet, // CSS + eStyleAttrSheet, + eOverrideSheet, // CSS eSheetTypeCount + // be sure to keep the number of bits in |mDirty| below updated when + // changing the number of sheet types }; nsresult AppendStyleSheet(sheetType aType, nsIStyleSheet *aSheet); @@ -190,7 +193,7 @@ class nsStyleSet PRBool BuildDefaultStyleData(nsIPresContext* aPresContext); // Update the rule processor list after a change to the style sheet list. - nsresult GatherRuleProcessors(PRInt32 aType); + nsresult GatherRuleProcessors(sheetType aType); void AddImportantRules(nsRuleNode* aCurrLevelNode, nsRuleNode* aLastPrevLevelNode); @@ -229,7 +232,7 @@ class nsStyleSet nsCOMArray mSheets[eSheetTypeCount]; - nsCOMArray mRuleProcessors[eSheetTypeCount]; + nsCOMPtr mRuleProcessors[eSheetTypeCount]; // cached instance for enabling/disabling nsCOMPtr mQuirkStyleSheet; diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index a33655cd97b0..261748c46877 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -49,7 +49,6 @@ #include "nsIXMLContentSink.h" #include "nsHTMLParts.h" #include "nsHTMLStyleSheet.h" -#include "nsIHTMLCSSStyleSheet.h" #include "nsHTMLAtoms.h" #include "nsLayoutAtoms.h" #include "nsIPresShell.h" @@ -1069,77 +1068,6 @@ nsHTMLDocument::GetImageMap(const nsAString& aMapName) return nsnull; } -// subclass hooks for sheet ordering -void -nsHTMLDocument::InternalAddStyleSheet(nsIStyleSheet* aSheet, PRUint32 aFlags) -{ - if (aSheet == mAttrStyleSheet) { // always first - NS_ASSERTION(mStyleSheets.Count() == 0 || - mAttrStyleSheet != mStyleSheets[0], - "Adding attr sheet twice!"); - mStyleSheets.InsertObjectAt(aSheet, 0); - } - else if (aSheet == mStyleAttrStyleSheet) { // always last - NS_ASSERTION(mStyleSheets.Count() == 0 || - mStyleSheets[mStyleSheets.Count() - 1] != mStyleAttrStyleSheet, - "Adding style attr sheet twice!"); - mStyleSheets.AppendObject(aSheet); - } - else { - PRInt32 count = mStyleSheets.Count(); - if (count != 0 && mStyleAttrStyleSheet == mStyleSheets[count - 1]) { - // keep attr sheet last - mStyleSheets.InsertObjectAt(aSheet, count - 1); - } - else { - mStyleSheets.AppendObject(aSheet); - } - } -} - -void -nsHTMLDocument::InternalInsertStyleSheetAt(nsIStyleSheet* aSheet, - PRInt32 aIndex) -{ - NS_ASSERTION(0 <= aIndex && - aIndex <= ( - mStyleSheets.Count() - /* Don't count Attribute stylesheet */ - - 1 - /* No insertion allowed after StyleAttr stylesheet */ - - ((mStyleAttrStyleSheet && - mStyleSheets.Count() > 0 && - mStyleAttrStyleSheet == - mStyleSheets[mStyleSheets.Count() - 1]) ? 1: 0) - ), - "index out of bounds"); - - // offset one for the attr style sheet - mStyleSheets.InsertObjectAt(aSheet, aIndex + 1); -} - -nsIStyleSheet* -nsHTMLDocument::InternalGetStyleSheetAt(PRInt32 aIndex) const -{ - PRInt32 count = InternalGetNumberOfStyleSheets(); - if (aIndex >= 0 && aIndex < count) { - return mStyleSheets[aIndex + 1]; - } else { - NS_ERROR("Index out of range"); - return nsnull; - } -} - -PRInt32 -nsHTMLDocument::InternalGetNumberOfStyleSheets() const -{ - PRInt32 count = mStyleSheets.Count(); - if (count != 0 && mStyleAttrStyleSheet == mStyleSheets[count - 1]) - --count; - --count; // for the attr sheet - NS_ASSERTION(count >= 0, "Why did we end up with a negative count?"); - return count; -} nsICSSLoader* nsHTMLDocument::GetCSSLoader() diff --git a/content/html/document/src/nsHTMLDocument.h b/content/html/document/src/nsHTMLDocument.h index 390ff0b2c0d2..b564cc3d6c62 100644 --- a/content/html/document/src/nsHTMLDocument.h +++ b/content/html/document/src/nsHTMLDocument.h @@ -51,7 +51,6 @@ #include "nsIRDFService.h" #include "pldhash.h" #include "nsIHttpChannel.h" -#include "nsIHTMLCSSStyleSheet.h" #include "nsHTMLStyleSheet.h" // Document.Write() related @@ -225,13 +224,6 @@ protected: nsIContent *MatchId(nsIContent *aContent, const nsAString& aId); - virtual void InternalAddStyleSheet(nsIStyleSheet* aSheet, - PRUint32 aFlags); - virtual void InternalInsertStyleSheetAt(nsIStyleSheet* aSheet, - PRInt32 aIndex); - virtual nsIStyleSheet* InternalGetStyleSheetAt(PRInt32 aIndex) const; - virtual PRInt32 InternalGetNumberOfStyleSheets() const; - static PRBool MatchLinks(nsIContent *aContent, PRInt32 aNamespaceID, nsIAtom* aAtom, const nsAString& aData); static PRBool MatchAnchors(nsIContent *aContent, PRInt32 aNamespaceID, diff --git a/content/html/style/public/nsICSSStyleSheet.h b/content/html/style/public/nsICSSStyleSheet.h index 69cfd08daee2..e3cfd04cf1d8 100644 --- a/content/html/style/public/nsICSSStyleSheet.h +++ b/content/html/style/public/nsICSSStyleSheet.h @@ -43,14 +43,15 @@ class nsICSSRule; class nsIDOMNode; class nsINameSpace; -class nsICSSStyleRuleProcessor; +class nsCSSRuleProcessor; class nsIMediaList; class nsICSSGroupRule; class nsICSSImportRule; -// IID for the nsICSSStyleSheet interface {8f83b0f0-b21a-11d1-8031-006008159b5a} +// IID for the nsICSSStyleSheet interface +// d148e93e-7f1d-4f95-853f-ac356eba3d70 #define NS_ICSS_STYLE_SHEET_IID \ -{0x8f83b0f0, 0xb21a, 0x11d1, {0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}} +{0xd148e93e, 0x7f1d, 0x4f95, {0x85, 0x3f, 0xac, 0x35, 0x6e, 0xba, 0x3d, 0x70}} class nsICSSStyleSheet : public nsIStyleSheet { public: @@ -101,7 +102,8 @@ public: NS_IMETHOD IsModified(PRBool* aModified) const = 0; // returns the mDirty status of the sheet NS_IMETHOD SetModified(PRBool aModified) = 0; - NS_IMETHOD DropRuleProcessorReference(nsICSSStyleRuleProcessor* aProcessor) = 0; + NS_IMETHOD AddRuleProcessor(nsCSSRuleProcessor* aProcessor) = 0; + NS_IMETHOD DropRuleProcessor(nsCSSRuleProcessor* aProcessor) = 0; }; // XXX for backwards compatibility and convenience diff --git a/content/html/style/src/Makefile.in b/content/html/style/src/Makefile.in index 07970b86d9eb..afe1593461bb 100644 --- a/content/html/style/src/Makefile.in +++ b/content/html/style/src/Makefile.in @@ -96,7 +96,6 @@ CPPSRCS = \ EXPORTS = \ nsDOMCSSDeclaration.h \ nsCSSValue.h \ - nsICSSStyleRuleProcessor.h \ nsICSSRule.h \ nsICSSGroupRule.h \ nsICSSStyleRule.h \ diff --git a/content/html/style/src/nsCSSLoader.cpp b/content/html/style/src/nsCSSLoader.cpp index f3ca679466d7..397f9444914a 100644 --- a/content/html/style/src/nsCSSLoader.cpp +++ b/content/html/style/src/nsCSSLoader.cpp @@ -1149,7 +1149,7 @@ CSSLoaderImpl::InsertSheetInDoc(nsICSSStyleSheet* aSheet, // XXX Need to cancel pending sheet loads for this element, if any - PRInt32 sheetCount = aDocument->GetNumberOfStyleSheets(PR_FALSE); + PRInt32 sheetCount = aDocument->GetNumberOfStyleSheets(); /* * Start the walk at the _end_ of the list, since in the typical @@ -1161,8 +1161,7 @@ CSSLoaderImpl::InsertSheetInDoc(nsICSSStyleSheet* aSheet, */ PRInt32 insertionPoint; for (insertionPoint = sheetCount - 1; insertionPoint >= 0; --insertionPoint) { - nsIStyleSheet *curSheet = aDocument->GetStyleSheetAt(insertionPoint, - PR_FALSE); + nsIStyleSheet *curSheet = aDocument->GetStyleSheetAt(insertionPoint); NS_ASSERTION(curSheet, "There must be a sheet here!"); nsCOMPtr domSheet = do_QueryInterface(curSheet); NS_ASSERTION(domSheet, "All the \"normal\" sheets implement nsIDOMStyleSheet"); diff --git a/content/html/style/src/nsICSSStyleRuleProcessor.h b/content/html/style/src/nsCSSRuleProcessor.h similarity index 54% rename from content/html/style/src/nsICSSStyleRuleProcessor.h rename to content/html/style/src/nsCSSRuleProcessor.h index d03153015a1f..95430f451925 100644 --- a/content/html/style/src/nsICSSStyleRuleProcessor.h +++ b/content/html/style/src/nsCSSRuleProcessor.h @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +// vim:cindent:tabstop=2:expandtab:shiftwidth=2: /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -20,6 +21,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * L. David Baron * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -34,36 +36,57 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -#ifndef nsICSSStyleRuleProcessor_h___ -#define nsICSSStyleRuleProcessor_h___ + +#ifndef nsCSSRuleProcessor_h_ +#define nsCSSRuleProcessor_h_ #include "nsIStyleRuleProcessor.h" +struct RuleCascadeData; class nsICSSStyleSheet; -// IID for the nsICSSStyleRuleProcessor interface {98bf169c-7b7c-11d3-ba05-001083023c2b} -#define NS_ICSS_STYLE_RULE_PROCESSOR_IID \ -{0x98bf169c, 0x7b7c, 0x11d3, {0xba, 0x05, 0x00, 0x10, 0x83, 0x02, 0x3c, 0x2b}} - -/* The CSS style rule processor provides a mechanism for sibling style sheets - * to combine their rule processing in order to allow proper cascading to happen. +/** + * The CSS style rule processor provides a mechanism for sibling style + * sheets to combine their rule processing in order to allow proper + * cascading to happen. * - * When queried for a rule processor, a CSS style sheet will append itself to - * the previous CSS processor if present, and return nsnull. Otherwise it will - * create a new processor for itself. - * - * CSS style rule processors keep a live reference on all style sheets bound to them - * The CSS style sheets keep a weak reference on all the processors that they are - * bound to (many to many). The CSS style sheet is told when the rule processor is - * going away (via DropRuleProcessorReference). + * CSS style rule processors keep a live reference on all style sheets + * bound to them. The CSS style sheets keep a weak reference to all the + * processors that they are bound to (many to many). The CSS style sheet + * is told when the rule processor is going away (via DropRuleProcessor). */ -class nsICSSStyleRuleProcessor: public nsIStyleRuleProcessor { + +class nsCSSRuleProcessor: public nsIStyleRuleProcessor { public: - NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICSS_STYLE_RULE_PROCESSOR_IID) + nsCSSRuleProcessor(const nsCOMArray& aSheets); + virtual ~nsCSSRuleProcessor(); - NS_IMETHOD AppendStyleSheet(nsICSSStyleSheet* aStyleSheet) = 0; + NS_DECL_ISUPPORTS - NS_IMETHOD ClearRuleCascades(void) = 0; +public: + nsresult ClearRuleCascades(); + + // nsIStyleRuleProcessor + NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData, + nsIAtom* aMedium); + + NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData, + nsIAtom* aMedium); + + NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData, + nsIAtom* aMedium, + nsReStyleHint* aResult); + + NS_IMETHOD HasAttributeDependentStyle(AttributeRuleProcessorData* aData, + nsIAtom* aMedium, + nsReStyleHint* aResult); + +protected: + RuleCascadeData* GetRuleCascade(nsIPresContext* aPresContext, nsIAtom* aMedium); + + nsCOMArray mSheets; + + RuleCascadeData* mRuleCascades; }; -#endif /* nsICSSStyleRuleProcessor_h___ */ +#endif /* nsCSSRuleProcessor_h_ */ diff --git a/content/html/style/src/nsCSSStyleSheet.cpp b/content/html/style/src/nsCSSStyleSheet.cpp index 5263d7049e4e..fa680c2349f4 100644 --- a/content/html/style/src/nsCSSStyleSheet.cpp +++ b/content/html/style/src/nsCSSStyleSheet.cpp @@ -53,7 +53,7 @@ #include "pldhash.h" #include "nsHashtable.h" #include "nsICSSPseudoComparator.h" -#include "nsICSSStyleRuleProcessor.h" +#include "nsCSSRuleProcessor.h" #include "nsICSSStyleRule.h" #include "nsICSSNameSpaceRule.h" #include "nsICSSMediaRule.h" @@ -107,13 +107,17 @@ struct RuleValue { * |RuleHash|, to act as rule/selector pairs. |Add| is called when * they are added to the |RuleHash|, and can be considered the second * half of the constructor. + * + * |RuleValue|s are added to the rule hash from highest weight/order + * to lowest (since this is the fast way to build a singly linked + * list), so the index used to remember the order is backwards. */ RuleValue(nsICSSStyleRule* aRule, nsCSSSelector* aSelector) : mRule(aRule), mSelector(aSelector) {} - RuleValue* Add(PRInt32 aIndex, RuleValue *aNext) + RuleValue* Add(PRInt32 aBackwardIndex, RuleValue *aNext) { - mIndex = aIndex; + mBackwardIndex = aBackwardIndex; mNext = aNext; return this; } @@ -136,7 +140,7 @@ struct RuleValue { nsICSSStyleRule* mRule; nsCSSSelector* mSelector; // which of |mRule|'s selectors - PRInt32 mIndex; // High index means low weight/order. + PRInt32 mBackwardIndex; // High index means low weight/order. RuleValue* mNext; }; @@ -603,9 +607,9 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, // Merge the lists while there are still multiple lists to merge. while (valueCount > 1) { PRInt32 valueIndex = 0; - PRInt32 highestRuleIndex = mEnumList[valueIndex]->mIndex; + PRInt32 highestRuleIndex = mEnumList[valueIndex]->mBackwardIndex; for (PRInt32 index = 1; index < valueCount; ++index) { - PRInt32 ruleIndex = mEnumList[index]->mIndex; + PRInt32 ruleIndex = mEnumList[index]->mBackwardIndex; if (ruleIndex > highestRuleIndex) { valueIndex = index; highestRuleIndex = ruleIndex; @@ -719,48 +723,6 @@ RuleCascadeData::AttributeListFor(nsIAtom* aAttribute) return entry->mSelectors; } -// ------------------------------- -// CSS Style Rule processor -// - -class CSSRuleProcessor: public nsICSSStyleRuleProcessor { -public: - CSSRuleProcessor(void); - virtual ~CSSRuleProcessor(void); - - NS_DECL_ISUPPORTS - -public: - // nsICSSStyleRuleProcessor - NS_IMETHOD AppendStyleSheet(nsICSSStyleSheet* aStyleSheet); - - NS_IMETHOD ClearRuleCascades(void); - - // nsIStyleRuleProcessor - NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData, - nsIAtom* aMedium); - - NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData, - nsIAtom* aMedium); - - NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData, - nsIAtom* aMedium, - nsReStyleHint* aResult); - - NS_IMETHOD HasAttributeDependentStyle(AttributeRuleProcessorData* aData, - nsIAtom* aMedium, - nsReStyleHint* aResult); - -protected: - RuleCascadeData* GetRuleCascade(nsIPresContext* aPresContext, nsIAtom* aMedium); - - static PRBool CascadeSheetRulesInto(nsISupports* aSheet, void* aData); - - nsISupportsArray* mSheets; - - RuleCascadeData* mRuleCascades; -}; - // ------------------------------- // CSS Style Sheet Inner Data Container // @@ -795,6 +757,7 @@ public: class CSSImportsCollectionImpl; class CSSRuleListImpl; class DOMMediaListImpl; +static PRBool CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData); class CSSStyleSheetImpl : public nsICSSStyleSheet, public nsIDOMCSSStyleSheet, @@ -836,9 +799,8 @@ public: NS_IMETHOD SetOwnerRule(nsICSSImportRule* aOwnerRule); NS_IMETHOD GetOwnerRule(nsICSSImportRule** aOwnerRule); - NS_IMETHOD GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* aPrevProcessor); - NS_IMETHOD DropRuleProcessorReference(nsICSSStyleRuleProcessor* aProcessor); + NS_IMETHOD AddRuleProcessor(nsCSSRuleProcessor* aProcessor); + NS_IMETHOD DropRuleProcessor(nsCSSRuleProcessor* aProcessor); NS_IMETHOD ContainsStyleSheet(nsIURI* aURL, PRBool& aContains, nsIStyleSheet** aTheChild=nsnull); @@ -920,8 +882,8 @@ protected: nsAutoVoidArray* mRuleProcessors; - friend class CSSRuleProcessor; friend class DOMMediaListImpl; + friend PRBool CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData); }; @@ -1696,57 +1658,30 @@ NS_IMPL_RELEASE(CSSStyleSheetImpl) NS_IMETHODIMP -CSSStyleSheetImpl::GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* aPrevProcessor) +CSSStyleSheetImpl::AddRuleProcessor(nsCSSRuleProcessor* aProcessor) { - nsresult result = NS_OK; - nsICSSStyleRuleProcessor* cssProcessor = nsnull; - - if (aPrevProcessor) { - result = aPrevProcessor->QueryInterface(NS_GET_IID(nsICSSStyleRuleProcessor), (void**)&cssProcessor); + if (! mRuleProcessors) { + mRuleProcessors = new nsAutoVoidArray(); + if (!mRuleProcessors) + return NS_ERROR_OUT_OF_MEMORY; } - if (! cssProcessor) { - CSSRuleProcessor* processor = new CSSRuleProcessor(); - if (processor) { - result = processor->QueryInterface(NS_GET_IID(nsICSSStyleRuleProcessor), (void**)&cssProcessor); - if (NS_FAILED(result)) { - delete processor; - cssProcessor = nsnull; - } - } - else { - result = NS_ERROR_OUT_OF_MEMORY; - } - } - if (NS_SUCCEEDED(result) && cssProcessor) { - cssProcessor->AppendStyleSheet(this); - if (! mRuleProcessors) { - mRuleProcessors = new nsAutoVoidArray(); - } - if (mRuleProcessors) { - NS_ASSERTION(-1 == mRuleProcessors->IndexOf(cssProcessor), "processor already registered"); - mRuleProcessors->AppendElement(cssProcessor); // weak ref - } - } - aProcessor = cssProcessor; + NS_ASSERTION(-1 == mRuleProcessors->IndexOf(aProcessor), + "processor already registered"); + mRuleProcessors->AppendElement(aProcessor); // weak ref return NS_OK; } NS_IMETHODIMP -CSSStyleSheetImpl::DropRuleProcessorReference(nsICSSStyleRuleProcessor* aProcessor) +CSSStyleSheetImpl::DropRuleProcessor(nsCSSRuleProcessor* aProcessor) { - NS_ASSERTION(mRuleProcessors, "no rule processors registered"); - if (mRuleProcessors) { - NS_ASSERTION(-1 != mRuleProcessors->IndexOf(aProcessor), "not a registered processor"); - mRuleProcessors->RemoveElement(aProcessor); - } - return NS_OK; + if (!mRuleProcessors) + return NS_ERROR_FAILURE; + return mRuleProcessors->RemoveElement(aProcessor) + ? NS_OK + : NS_ERROR_FAILURE; } - - - NS_IMETHODIMP CSSStyleSheetImpl::SetURL(nsIURI* aURL) { @@ -2367,7 +2302,8 @@ void CSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const static PRBool PR_CALLBACK EnumClearRuleCascades(void* aProcessor, void* aData) { - nsICSSStyleRuleProcessor* processor = (nsICSSStyleRuleProcessor*)aProcessor; + nsCSSRuleProcessor* processor = + NS_STATIC_CAST(nsCSSRuleProcessor*, aProcessor); processor->ClearRuleCascades(); return PR_TRUE; } @@ -3011,72 +2947,23 @@ NS_NewCSSStyleSheet(nsICSSStyleSheet** aInstancePtrResult) // CSS Style rule processor implementation // -CSSRuleProcessor::CSSRuleProcessor(void) - : mSheets(nsnull), +nsCSSRuleProcessor::nsCSSRuleProcessor(const nsCOMArray& aSheets) + : mSheets(aSheets), mRuleCascades(nsnull) { + for (PRInt32 i = mSheets.Count() - 1; i >= 0; --i) + mSheets[i]->AddRuleProcessor(this); } -static PRBool -DropProcessorReference(nsISupports* aSheet, void* aProcessor) +nsCSSRuleProcessor::~nsCSSRuleProcessor(void) { - nsICSSStyleSheet* sheet = (nsICSSStyleSheet*)aSheet; - nsICSSStyleRuleProcessor* processor = (nsICSSStyleRuleProcessor*)aProcessor; - sheet->DropRuleProcessorReference(processor); - return PR_TRUE; -} - -CSSRuleProcessor::~CSSRuleProcessor(void) -{ - if (mSheets) { - mSheets->EnumerateForwards(DropProcessorReference, this); - NS_RELEASE(mSheets); - } + for (PRInt32 i = mSheets.Count() - 1; i >= 0; --i) + mSheets[i]->DropRuleProcessor(this); + mSheets.Clear(); ClearRuleCascades(); } -NS_IMPL_ADDREF(CSSRuleProcessor) -NS_IMPL_RELEASE(CSSRuleProcessor) - -nsresult -CSSRuleProcessor::QueryInterface(REFNSIID aIID, void** aInstancePtrResult) -{ - if (NULL == aInstancePtrResult) { - return NS_ERROR_NULL_POINTER; - } - - static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); - if (aIID.Equals(NS_GET_IID(nsICSSStyleRuleProcessor))) { - *aInstancePtrResult = (void*)this; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(NS_GET_IID(nsIStyleRuleProcessor))) { - *aInstancePtrResult = (void*)this; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kISupportsIID)) { - *aInstancePtrResult = (void*)this; - NS_ADDREF_THIS(); - return NS_OK; - } - return NS_NOINTERFACE; -} - - -NS_IMETHODIMP -CSSRuleProcessor::AppendStyleSheet(nsICSSStyleSheet* aStyleSheet) -{ - nsresult result = NS_OK; - if (! mSheets) { - result = NS_NewISupportsArray(&mSheets); - } - if (mSheets) { - mSheets->AppendElement(aStyleSheet); - } - return result; -} +NS_IMPL_ISUPPORTS1(nsCSSRuleProcessor, nsIStyleRuleProcessor) MOZ_DECL_CTOR_COUNTER(RuleProcessorData) @@ -3869,8 +3756,8 @@ static void ContentEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector, } NS_IMETHODIMP -CSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData, - nsIAtom* aMedium) +nsCSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData, + nsIAtom* aMedium) { NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT), "content must be element"); @@ -3939,8 +3826,8 @@ static void PseudoEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector, } NS_IMETHODIMP -CSSRuleProcessor::RulesMatching(PseudoRuleProcessorData* aData, - nsIAtom* aMedium) +nsCSSRuleProcessor::RulesMatching(PseudoRuleProcessorData* aData, + nsIAtom* aMedium) { NS_PRECONDITION(!aData->mContent || aData->mContent->IsContentOfType(nsIContent::eELEMENT), @@ -3987,9 +3874,9 @@ PR_STATIC_CALLBACK(PRBool) StateEnumFunc(void* aSelector, void* aData) } NS_IMETHODIMP -CSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData, - nsIAtom* aMedium, - nsReStyleHint* aResult) +nsCSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData, + nsIAtom* aMedium, + nsReStyleHint* aResult) { NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT), "content must be element"); @@ -4038,9 +3925,9 @@ PR_STATIC_CALLBACK(PRBool) AttributeEnumFunc(void* aSelector, void* aData) } NS_IMETHODIMP -CSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData, - nsIAtom* aMedium, - nsReStyleHint* aResult) +nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData, + nsIAtom* aMedium, + nsReStyleHint* aResult) { NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT), "content must be element"); @@ -4087,7 +3974,7 @@ CSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData, } NS_IMETHODIMP -CSSRuleProcessor::ClearRuleCascades(void) +nsCSSRuleProcessor::ClearRuleCascades(void) { RuleCascadeData *data = mRuleCascades; mRuleCascades = nsnull; @@ -4229,19 +4116,18 @@ InsertRuleByWeight(nsISupports* aRule, void* aData) } -PRBool -CSSRuleProcessor::CascadeSheetRulesInto(nsISupports* aSheet, void* aData) +static PRBool +CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData) { - nsICSSStyleSheet* iSheet = (nsICSSStyleSheet*)aSheet; - CSSStyleSheetImpl* sheet = (CSSStyleSheetImpl*)iSheet; - CascadeEnumData* data = (CascadeEnumData*)aData; + CSSStyleSheetImpl* sheet = NS_STATIC_CAST(CSSStyleSheetImpl*, aSheet); + CascadeEnumData* data = NS_STATIC_CAST(CascadeEnumData*, aData); PRBool bSheetApplicable = PR_TRUE; sheet->GetApplicable(bSheetApplicable); if (bSheetApplicable && sheet->UseForMedium(data->mMedium)) { - CSSStyleSheetImpl* child = sheet->mFirstChild; + CSSStyleSheetImpl* child = sheet->mFirstChild; while (child) { - CascadeSheetRulesInto((nsICSSStyleSheet*)child, data); + CascadeSheetRulesInto(child, data); child = child->mNext; } @@ -4311,7 +4197,8 @@ static void PutRulesInList(nsObjectHashtable* aRuleArrays, } RuleCascadeData* -CSSRuleProcessor::GetRuleCascade(nsIPresContext* aPresContext, nsIAtom* aMedium) +nsCSSRuleProcessor::GetRuleCascade(nsIPresContext* aPresContext, + nsIAtom* aMedium) { RuleCascadeData **cascadep = &mRuleCascades; RuleCascadeData *cascade; @@ -4321,15 +4208,17 @@ CSSRuleProcessor::GetRuleCascade(nsIPresContext* aPresContext, nsIAtom* aMedium) cascadep = &cascade->mNext; } - if (mSheets) { + if (mSheets.Count() != 0) { cascade = new RuleCascadeData(aMedium, eCompatibility_NavQuirks == aPresContext->CompatibilityMode()); if (cascade) { CascadeEnumData data(aMedium, cascade->mRuleHash.Arena()); - mSheets->EnumerateForwards(CascadeSheetRulesInto, &data); + mSheets.EnumerateForwards(CascadeSheetRulesInto, &data); nsVoidArray weightedRules; PutRulesInList(&data.mRuleArrays, &weightedRules); + // Put things into the rule hash backwards because it's easier to + // build a singly linked list lowest-first that way. if (!weightedRules.EnumerateBackwards(AddRule, cascade)) { delete cascade; cascade = nsnull; diff --git a/content/html/style/src/nsHTMLCSSStyleSheet.cpp b/content/html/style/src/nsHTMLCSSStyleSheet.cpp index 9007bb5856a9..df2ce33f833b 100644 --- a/content/html/style/src/nsHTMLCSSStyleSheet.cpp +++ b/content/html/style/src/nsHTMLCSSStyleSheet.cpp @@ -367,9 +367,6 @@ public: NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; NS_IMETHOD SetOwningDocument(nsIDocument* aDocument); - NS_IMETHOD GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* aPrevProcessor); - // nsIStyleRuleProcessor api NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData, nsIAtom* aMedium); @@ -434,15 +431,6 @@ NS_IMPL_ISUPPORTS3(HTMLCSSStyleSheetImpl, nsIStyleSheet, nsIStyleRuleProcessor) -NS_IMETHODIMP -HTMLCSSStyleSheetImpl::GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* /*aPrevProcessor*/) -{ - aProcessor = this; - NS_ADDREF(aProcessor); - return NS_OK; -} - NS_IMETHODIMP HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData, nsIAtom* aMedium) diff --git a/content/html/style/src/nsHTMLStyleSheet.cpp b/content/html/style/src/nsHTMLStyleSheet.cpp index 4b9bc5511b31..c13273303805 100644 --- a/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/content/html/style/src/nsHTMLStyleSheet.cpp @@ -499,15 +499,6 @@ nsHTMLStyleSheet::~nsHTMLStyleSheet() NS_IMPL_ISUPPORTS2(nsHTMLStyleSheet, nsIStyleSheet, nsIStyleRuleProcessor) -NS_IMETHODIMP -nsHTMLStyleSheet::GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* /*aPrevProcessor*/) -{ - aProcessor = this; - NS_ADDREF(aProcessor); - return NS_OK; -} - static nsresult GetBodyColor(nsIPresContext* aPresContext, nscolor* aColor) { nsCOMPtr doc; diff --git a/content/html/style/src/nsHTMLStyleSheet.h b/content/html/style/src/nsHTMLStyleSheet.h index d5c0a769c8af..4ab5d18d3e04 100644 --- a/content/html/style/src/nsHTMLStyleSheet.h +++ b/content/html/style/src/nsHTMLStyleSheet.h @@ -68,8 +68,6 @@ public: NS_IMETHOD GetParentSheet(nsIStyleSheet*& aParent) const; // will be null NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; NS_IMETHOD SetOwningDocument(nsIDocument* aDocumemt); - NS_IMETHOD GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* aPrevProcessor); #ifdef DEBUG virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; #endif diff --git a/content/xbl/src/nsBindingManager.cpp b/content/xbl/src/nsBindingManager.cpp index cd3b5d15090f..fa7ca038053c 100644 --- a/content/xbl/src/nsBindingManager.cpp +++ b/content/xbl/src/nsBindingManager.cpp @@ -1271,18 +1271,6 @@ nsBindingManager::WalkRules(nsStyleSet* aStyleSet, // Null out the scoped root that we set repeatedly in the other |WalkRules|. aData->mScopedRoot = nsnull; - if (parent) { - // We cut ourselves off, but we still need to walk the document's attribute sheet - // so that inline style continues to work on anonymous content. - nsIDocument* doc = content->GetDocument(); - if (doc) { - nsCOMPtr inlineCSS( - do_QueryInterface(doc->GetInlineStyleSheet())); - if (inlineCSS) - (*aFunc)(inlineCSS, aData); - } - } - return NS_OK; } diff --git a/content/xbl/src/nsXBLBinding.cpp b/content/xbl/src/nsXBLBinding.cpp index e1dfceba9376..b06bfa2e5321 100644 --- a/content/xbl/src/nsXBLBinding.cpp +++ b/content/xbl/src/nsXBLBinding.cpp @@ -1068,9 +1068,9 @@ nsXBLBinding::WalkRules(nsIStyleRuleProcessor::EnumFunc aFunc, void* aData) return rv; } - nsCOMArray *rules = mPrototypeBinding->GetRuleProcessors(); + nsIStyleRuleProcessor *rules = mPrototypeBinding->GetRuleProcessor(); if (rules) - rules->EnumerateForwards(aFunc, aData); + (*aFunc)(rules, aData); return rv; } diff --git a/content/xbl/src/nsXBLPrototypeBinding.cpp b/content/xbl/src/nsXBLPrototypeBinding.cpp index e9f842387d14..f0758773e421 100644 --- a/content/xbl/src/nsXBLPrototypeBinding.cpp +++ b/content/xbl/src/nsXBLPrototypeBinding.cpp @@ -912,11 +912,11 @@ nsXBLPrototypeBinding::SetInitialAttributes(nsIContent* aBoundElement, nsIConten } } -nsCOMArray* -nsXBLPrototypeBinding::GetRuleProcessors() +nsIStyleRuleProcessor* +nsXBLPrototypeBinding::GetRuleProcessor() { if (mResources) { - return &mResources->mRuleProcessors; + return mResources->mRuleProcessor; } return nsnull; diff --git a/content/xbl/src/nsXBLPrototypeBinding.h b/content/xbl/src/nsXBLPrototypeBinding.h index c870a6299733..cb1c9d3d25d6 100644 --- a/content/xbl/src/nsXBLPrototypeBinding.h +++ b/content/xbl/src/nsXBLPrototypeBinding.h @@ -117,7 +117,7 @@ public: void SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent); - nsCOMArray* GetRuleProcessors(); + nsIStyleRuleProcessor* GetRuleProcessor(); nsCOMArray* GetStyleSheets(); PRBool HasInsertionPoints() { return mInsertionPointTable != nsnull; } diff --git a/content/xbl/src/nsXBLPrototypeResources.cpp b/content/xbl/src/nsXBLPrototypeResources.cpp index 6ec1fec643fd..a739eabeaa07 100644 --- a/content/xbl/src/nsXBLPrototypeResources.cpp +++ b/content/xbl/src/nsXBLPrototypeResources.cpp @@ -49,6 +49,7 @@ #include "nsICSSLoader.h" #include "nsIURI.h" #include "nsLayoutCID.h" +#include "nsCSSRuleProcessor.h" static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID); @@ -116,12 +117,11 @@ nsXBLPrototypeResources::FlushSkinSheets() // We have scoped stylesheets. Reload any chrome stylesheets we // encounter. (If they aren't skin sheets, it doesn't matter, since // they'll still be in the chrome cache. - mRuleProcessors.Clear(); + mRuleProcessor = nsnull; nsCOMArray oldSheets(mStyleSheetList); mStyleSheetList.Clear(); - nsCOMPtr prevProcessor; PRInt32 i; PRInt32 count = oldSheets.Count(); for (i = 0; i < count; i++) { @@ -140,14 +140,8 @@ nsXBLPrototypeResources::FlushSkinSheets() } mStyleSheetList.AppendObject(newSheet); - - nsCOMPtr processor; - newSheet->GetStyleRuleProcessor(*getter_AddRefs(processor), prevProcessor); - if (processor != prevProcessor) { - mRuleProcessors.AppendObject(processor); - prevProcessor = processor; - } } + mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList); return NS_OK; } diff --git a/content/xbl/src/nsXBLPrototypeResources.h b/content/xbl/src/nsXBLPrototypeResources.h index 5809f3a00e96..1672ff55a2b6 100644 --- a/content/xbl/src/nsXBLPrototypeResources.h +++ b/content/xbl/src/nsXBLPrototypeResources.h @@ -71,7 +71,9 @@ public: // MEMBER VARIABLES nsXBLResourceLoader* mLoader; // A loader object. Exists only long enough to load resources, and then it dies. nsCOMArray mStyleSheetList; // A list of loaded stylesheets for this binding. - nsCOMArray mRuleProcessors; // The list of stylesheets converted to rule processors. + + // The list of stylesheets converted to a rule processor. + nsCOMPtr mRuleProcessor; }; #endif diff --git a/content/xbl/src/nsXBLResourceLoader.cpp b/content/xbl/src/nsXBLResourceLoader.cpp index 52fb79af4830..c58f881a6646 100644 --- a/content/xbl/src/nsXBLResourceLoader.cpp +++ b/content/xbl/src/nsXBLResourceLoader.cpp @@ -56,6 +56,7 @@ #include "nsFrameManager.h" #include "nsStyleContext.h" #include "nsXBLPrototypeBinding.h" +#include "nsCSSRuleProcessor.h" NS_IMPL_ISUPPORTS1(nsXBLResourceLoader, nsICSSLoaderObserver) @@ -185,19 +186,8 @@ nsXBLResourceLoader::StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aNotify) if (mPendingSheets == 0) { // All stylesheets are loaded. - nsCOMPtr prevProcessor; - mResources->mRuleProcessors.Clear(); - PRInt32 count = mResources->mStyleSheetList.Count(); - for (PRInt32 i = 0; i < count; i++) { - nsICSSStyleSheet* sheet = mResources->mStyleSheetList[i]; - - nsCOMPtr processor; - sheet->GetStyleRuleProcessor(*getter_AddRefs(processor), prevProcessor); - if (processor != prevProcessor) { - mResources->mRuleProcessors.AppendObject(processor); - prevProcessor = processor; - } - } + mResources->mRuleProcessor = + new nsCSSRuleProcessor(mResources->mStyleSheetList); // XXX Check for mPendingScripts when scripts also come online. if (!mInLoadResourcesFunc) diff --git a/content/xml/document/src/nsXMLContentSink.cpp b/content/xml/document/src/nsXMLContentSink.cpp index ea04bd23a487..ec5aab0e06fc 100644 --- a/content/xml/document/src/nsXMLContentSink.cpp +++ b/content/xml/document/src/nsXMLContentSink.cpp @@ -871,9 +871,9 @@ NS_NewMathMLElement(nsIContent** aResult, nsINodeInfo* aNodeInfo) PRBool enabled; if (cssLoader && NS_SUCCEEDED(cssLoader->GetEnabled(&enabled)) && enabled) { PRBool alreadyLoaded = PR_FALSE; - PRInt32 sheetCount = doc->GetNumberOfStyleSheets(PR_TRUE); + PRInt32 sheetCount = doc->GetNumberOfCatalogStyleSheets(); for (PRInt32 i = 0; i < sheetCount; i++) { - nsIStyleSheet* sheet = doc->GetStyleSheetAt(i, PR_TRUE); + nsIStyleSheet* sheet = doc->GetCatalogStyleSheetAt(i); NS_ASSERTION(sheet, "unexpected null stylesheet in the document"); if (sheet) { nsCOMPtr uri; @@ -900,7 +900,7 @@ NS_NewMathMLElement(nsIContent** aResult, nsINodeInfo* aNodeInfo) #endif if (sheet) { doc->BeginUpdate(UPDATE_STYLE); - doc->AddStyleSheet(sheet, NS_STYLESHEET_FROM_CATALOG); + doc->AddCatalogStyleSheet(sheet); doc->EndUpdate(UPDATE_STYLE); } } @@ -1157,7 +1157,7 @@ nsXMLContentSink::HandleDoctypeDecl(const nsAString & aSubset, #endif if (sheet) { mDocument->BeginUpdate(UPDATE_STYLE); - mDocument->AddStyleSheet(sheet, NS_STYLESHEET_FROM_CATALOG); + mDocument->AddCatalogStyleSheet(sheet); mDocument->EndUpdate(UPDATE_STYLE); } } diff --git a/content/xml/document/src/nsXMLDocument.cpp b/content/xml/document/src/nsXMLDocument.cpp index ad9a613f8f52..bbbe38dab9a3 100644 --- a/content/xml/document/src/nsXMLDocument.cpp +++ b/content/xml/document/src/nsXMLDocument.cpp @@ -644,92 +644,6 @@ nsXMLDocument::EndLoad() nsDocument::EndLoad(); } -// subclass hook for sheet ordering -void -nsXMLDocument::InternalAddStyleSheet(nsIStyleSheet* aSheet, PRUint32 aFlags) -{ - // XXXbz this catalog stuff should be in the UA level in the cascade! - if (aFlags & NS_STYLESHEET_FROM_CATALOG) { - // always after other catalog sheets - mStyleSheets.InsertObjectAt(aSheet, mCatalogSheetCount); - ++mCatalogSheetCount; - } - else if (aSheet == mAttrStyleSheet) { // always after catalog sheets - NS_ASSERTION(mStyleSheets.Count() == 0 || - mAttrStyleSheet != mStyleSheets[0], - "Adding attr sheet twice!"); - mStyleSheets.InsertObjectAt(aSheet, mCatalogSheetCount); - } - else if (aSheet == mStyleAttrStyleSheet) { // always last - NS_ASSERTION(mStyleSheets.Count() == 0 || - mStyleSheets[mStyleSheets.Count() - 1] != mStyleAttrStyleSheet, - "Adding style attr sheet twice!"); - mStyleSheets.AppendObject(aSheet); - } - else { - PRInt32 count = mStyleSheets.Count(); - if (count != 0 && mStyleAttrStyleSheet == mStyleSheets[count - 1]) { - // keep attr sheet last - mStyleSheets.InsertObjectAt(aSheet, count - 1); - } - else { - mStyleSheets.AppendObject(aSheet); - } - } -} - -void -nsXMLDocument::InternalInsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex) -{ - NS_ASSERTION(0 <= aIndex && - aIndex <= ( - mStyleSheets.Count() - /* Don't count Attribute stylesheet */ - - 1 - /* Don't count catalog sheets */ - - mCatalogSheetCount - /* No insertion allowed after StyleAttr stylesheet */ - - (mStyleAttrStyleSheet ? 1: 0) - ), - "index out of bounds"); - // offset w.r.t. catalog style sheets and the attr style sheet - mStyleSheets.InsertObjectAt(aSheet, aIndex + mCatalogSheetCount + 1); -} - -nsIStyleSheet* -nsXMLDocument::InternalGetStyleSheetAt(PRInt32 aIndex) const -{ - PRInt32 count = InternalGetNumberOfStyleSheets(); - - if (aIndex >= 0 && aIndex < count) { - return mStyleSheets[aIndex + mCatalogSheetCount + 1]; - } else { - NS_ERROR("Index out of range"); - return nsnull; - } -} - -PRInt32 -nsXMLDocument::InternalGetNumberOfStyleSheets() const -{ - PRInt32 count = mStyleSheets.Count(); - - if (count != 0 && mStyleAttrStyleSheet == mStyleSheets[count - 1]) { - // subtract the inline style sheet - --count; - } - - if (count != 0 && mAttrStyleSheet == mStyleSheets[mCatalogSheetCount]) { - // subtract the attr sheet - --count; - } - - count -= mCatalogSheetCount; - - NS_ASSERTION(count >= 0, "How did we get a negative count?"); - - return count; -} // nsIDOMNode interface diff --git a/content/xml/document/src/nsXMLDocument.h b/content/xml/document/src/nsXMLDocument.h index 4981d446271b..890a95d8709f 100644 --- a/content/xml/document/src/nsXMLDocument.h +++ b/content/xml/document/src/nsXMLDocument.h @@ -61,10 +61,7 @@ public: nsXMLDocument(); virtual ~nsXMLDocument(); - NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); - - NS_IMETHOD_(nsrefcnt) AddRef(void); - NS_IMETHOD_(nsrefcnt) Release(void); + NS_DECL_ISUPPORTS_INHERITED virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup); @@ -98,19 +95,8 @@ public: virtual nsresult Init(); protected: - // subclass hooks for sheet ordering - virtual void InternalAddStyleSheet(nsIStyleSheet* aSheet, PRUint32 aFlags); - virtual void InternalInsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex); - virtual nsIStyleSheet* InternalGetStyleSheetAt(PRInt32 aIndex) const; - virtual PRInt32 InternalGetNumberOfStyleSheets() const; - virtual nsresult GetLoadGroup(nsILoadGroup **aLoadGroup); - // For additional catalog sheets (if any) needed to layout the XML vocabulary - // of the document. Catalog sheets are kept at the beginning of our array of - // style sheets and this counter is used as an offset to distinguish them - PRInt32 mCatalogSheetCount; - nsCOMPtr mEventQService; nsCOMPtr mScriptContext; diff --git a/content/xul/document/src/nsXULDocument.cpp b/content/xul/document/src/nsXULDocument.cpp index 97d141383438..ba120f1ca673 100644 --- a/content/xul/document/src/nsXULDocument.cpp +++ b/content/xul/document/src/nsXULDocument.cpp @@ -432,6 +432,8 @@ nsXULDocument::~nsXULDocument() // from happening. if (mIsPopup) { mStyleSheets.Clear(); + mStyleAttrStyleSheet = nsnull; + mAttrStyleSheet = nsnull; } // This is done in nsDocument::~nsDocument() too, but since this @@ -721,7 +723,7 @@ nsXULDocument::EndLoad() continue; } - AddStyleSheet(sheet, 0); + AddStyleSheet(sheet); } } @@ -3577,7 +3579,7 @@ nsXULDocument::AddPrototypeSheets() // prototype's list, but until then, don't propagate the failure // from LoadAgentSheet (and thus exit the loop). if (NS_SUCCEEDED(rv)) { - AddStyleSheet(sheet, 0); + AddStyleSheet(sheet); } } diff --git a/editor/libeditor/base/nsStyleSheetTxns.cpp b/editor/libeditor/base/nsStyleSheetTxns.cpp index 16bd686a81da..e5f1e91dc2ee 100644 --- a/editor/libeditor/base/nsStyleSheetTxns.cpp +++ b/editor/libeditor/base/nsStyleSheetTxns.cpp @@ -55,7 +55,7 @@ AddStyleSheet(nsIEditor* aEditor, nsIStyleSheet* aSheet) nsCOMPtr doc = do_QueryInterface(domDoc); if (doc) { doc->BeginUpdate(UPDATE_STYLE); - doc->AddStyleSheet(aSheet, 0); + doc->AddStyleSheet(aSheet); doc->EndUpdate(UPDATE_STYLE); } } diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 77a209c08047..8405d6b5770d 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -1752,7 +1752,7 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, } if (sheet) - styleSet->PrependStyleSheet(nsStyleSet::eUserSheet, sheet); + styleSet->AppendStyleSheet(nsStyleSet::eUserSheet, sheet); // Append chrome sheets (scrollbars + forms). PRBool shouldOverride = PR_FALSE; @@ -1783,7 +1783,7 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, cssLoader->LoadAgentSheet(uri, getter_AddRefs(csssheet)); if (!sheet) continue; - styleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, csssheet); + styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, csssheet); shouldOverride = PR_TRUE; } nsMemory::Free(str); @@ -1794,17 +1794,17 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, if (!shouldOverride) { sheet = nsLayoutStylesheetCache::ScrollbarsSheet(); if (sheet) { - styleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet); + styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet); } } sheet = nsLayoutStylesheetCache::FormsSheet(); if (sheet) { - styleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet); + styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet); } if (mUAStyleSheet) { - styleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, mUAStyleSheet); + styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, mUAStyleSheet); } // Caller will handle calling EndUpdate, per contract. diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index d4c6c07d7745..f278777829b8 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -1281,9 +1281,11 @@ public: virtual void ContentRemoved(nsIDocument* aDocument, nsIContent* aContainer, nsIContent* aChild, PRInt32 aIndexInContainer); virtual void StyleSheetAdded(nsIDocument* aDocument, - nsIStyleSheet* aStyleSheet); + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet); virtual void StyleSheetRemoved(nsIDocument* aDocument, - nsIStyleSheet* aStyleSheet); + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet); virtual void StyleSheetApplicableStateChanged(nsIDocument* aDocument, nsIStyleSheet* aStyleSheet, PRBool aApplicable); @@ -2075,11 +2077,11 @@ PresShell::SelectAlternateStyleSheet(const nsString& aSheetTitle) { if (mDocument && mStyleSet) { mStyleSet->BeginUpdate(); - PRInt32 count = mDocument->GetNumberOfStyleSheets(PR_FALSE); + PRInt32 count = mDocument->GetNumberOfStyleSheets(); PRInt32 index; NS_NAMED_LITERAL_STRING(textHtml,"text/html"); for (index = 0; index < count; index++) { - nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(index, PR_FALSE); + nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(index); PRBool complete; sheet->GetComplete(complete); if (complete) { @@ -2111,11 +2113,11 @@ PresShell::ListAlternateStyleSheets(nsStringArray& aTitleList) { // XXX should this be returning incomplete sheets? Probably. if (mDocument) { - PRInt32 count = mDocument->GetNumberOfStyleSheets(PR_FALSE); + PRInt32 count = mDocument->GetNumberOfStyleSheets(); PRInt32 index; NS_NAMED_LITERAL_STRING(textHtml,"text/html"); for (index = 0; index < count; index++) { - nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(index, PR_FALSE); + nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(index); if (sheet) { nsAutoString type; sheet->GetType(type); @@ -5268,7 +5270,8 @@ PresShell::ReconstructStyleData() void PresShell::StyleSheetAdded(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet) + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet) { // We only care when enabled sheets are added NS_PRECONDITION(aStyleSheet, "Must have a style sheet!"); @@ -5282,7 +5285,8 @@ PresShell::StyleSheetAdded(nsIDocument *aDocument, void PresShell::StyleSheetRemoved(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet) + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet) { // We only care when enabled sheets are removed NS_PRECONDITION(aStyleSheet, "Must have a style sheet!"); @@ -6100,7 +6104,7 @@ PresShell::SetAgentStyleSheets(const nsCOMArray& aSheets) nsresult PresShell::AddOverrideStyleSheet(nsIStyleSheet *aSheet) { - return mStyleSet->AppendStyleSheet(nsStyleSet::eOverrideSheet, aSheet); + return mStyleSet->PrependStyleSheet(nsStyleSet::eOverrideSheet, aSheet); } nsresult diff --git a/layout/html/base/src/nsPresShell.cpp b/layout/html/base/src/nsPresShell.cpp index d4c6c07d7745..f278777829b8 100644 --- a/layout/html/base/src/nsPresShell.cpp +++ b/layout/html/base/src/nsPresShell.cpp @@ -1281,9 +1281,11 @@ public: virtual void ContentRemoved(nsIDocument* aDocument, nsIContent* aContainer, nsIContent* aChild, PRInt32 aIndexInContainer); virtual void StyleSheetAdded(nsIDocument* aDocument, - nsIStyleSheet* aStyleSheet); + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet); virtual void StyleSheetRemoved(nsIDocument* aDocument, - nsIStyleSheet* aStyleSheet); + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet); virtual void StyleSheetApplicableStateChanged(nsIDocument* aDocument, nsIStyleSheet* aStyleSheet, PRBool aApplicable); @@ -2075,11 +2077,11 @@ PresShell::SelectAlternateStyleSheet(const nsString& aSheetTitle) { if (mDocument && mStyleSet) { mStyleSet->BeginUpdate(); - PRInt32 count = mDocument->GetNumberOfStyleSheets(PR_FALSE); + PRInt32 count = mDocument->GetNumberOfStyleSheets(); PRInt32 index; NS_NAMED_LITERAL_STRING(textHtml,"text/html"); for (index = 0; index < count; index++) { - nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(index, PR_FALSE); + nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(index); PRBool complete; sheet->GetComplete(complete); if (complete) { @@ -2111,11 +2113,11 @@ PresShell::ListAlternateStyleSheets(nsStringArray& aTitleList) { // XXX should this be returning incomplete sheets? Probably. if (mDocument) { - PRInt32 count = mDocument->GetNumberOfStyleSheets(PR_FALSE); + PRInt32 count = mDocument->GetNumberOfStyleSheets(); PRInt32 index; NS_NAMED_LITERAL_STRING(textHtml,"text/html"); for (index = 0; index < count; index++) { - nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(index, PR_FALSE); + nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(index); if (sheet) { nsAutoString type; sheet->GetType(type); @@ -5268,7 +5270,8 @@ PresShell::ReconstructStyleData() void PresShell::StyleSheetAdded(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet) + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet) { // We only care when enabled sheets are added NS_PRECONDITION(aStyleSheet, "Must have a style sheet!"); @@ -5282,7 +5285,8 @@ PresShell::StyleSheetAdded(nsIDocument *aDocument, void PresShell::StyleSheetRemoved(nsIDocument *aDocument, - nsIStyleSheet* aStyleSheet) + nsIStyleSheet* aStyleSheet, + PRBool aDocumentSheet) { // We only care when enabled sheets are removed NS_PRECONDITION(aStyleSheet, "Must have a style sheet!"); @@ -6100,7 +6104,7 @@ PresShell::SetAgentStyleSheets(const nsCOMArray& aSheets) nsresult PresShell::AddOverrideStyleSheet(nsIStyleSheet *aSheet) { - return mStyleSet->AppendStyleSheet(nsStyleSet::eOverrideSheet, aSheet); + return mStyleSet->PrependStyleSheet(nsStyleSet::eOverrideSheet, aSheet); } nsresult diff --git a/layout/mathml/base/src/nsMathMLFrame.cpp b/layout/mathml/base/src/nsMathMLFrame.cpp index 1cdd4a5c8e5d..3ca40e48737e 100644 --- a/layout/mathml/base/src/nsMathMLFrame.cpp +++ b/layout/mathml/base/src/nsMathMLFrame.cpp @@ -563,7 +563,8 @@ GetMathMLAttributeStyleSheet(nsIPresContext* aPresContext, cssSheet->SetComplete(); // insert the stylesheet into the styleset without notifying observers - styleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, cssSheet); + // XXX Should this be at a different level? + styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, cssSheet); *aSheet = cssSheet; NS_ADDREF(*aSheet); } diff --git a/layout/style/nsCSSLoader.cpp b/layout/style/nsCSSLoader.cpp index f3ca679466d7..397f9444914a 100644 --- a/layout/style/nsCSSLoader.cpp +++ b/layout/style/nsCSSLoader.cpp @@ -1149,7 +1149,7 @@ CSSLoaderImpl::InsertSheetInDoc(nsICSSStyleSheet* aSheet, // XXX Need to cancel pending sheet loads for this element, if any - PRInt32 sheetCount = aDocument->GetNumberOfStyleSheets(PR_FALSE); + PRInt32 sheetCount = aDocument->GetNumberOfStyleSheets(); /* * Start the walk at the _end_ of the list, since in the typical @@ -1161,8 +1161,7 @@ CSSLoaderImpl::InsertSheetInDoc(nsICSSStyleSheet* aSheet, */ PRInt32 insertionPoint; for (insertionPoint = sheetCount - 1; insertionPoint >= 0; --insertionPoint) { - nsIStyleSheet *curSheet = aDocument->GetStyleSheetAt(insertionPoint, - PR_FALSE); + nsIStyleSheet *curSheet = aDocument->GetStyleSheetAt(insertionPoint); NS_ASSERTION(curSheet, "There must be a sheet here!"); nsCOMPtr domSheet = do_QueryInterface(curSheet); NS_ASSERTION(domSheet, "All the \"normal\" sheets implement nsIDOMStyleSheet"); diff --git a/layout/style/nsCSSRuleProcessor.h b/layout/style/nsCSSRuleProcessor.h new file mode 100644 index 000000000000..95430f451925 --- /dev/null +++ b/layout/style/nsCSSRuleProcessor.h @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +// vim:cindent:tabstop=2:expandtab:shiftwidth=2: +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * L. David Baron + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsCSSRuleProcessor_h_ +#define nsCSSRuleProcessor_h_ + +#include "nsIStyleRuleProcessor.h" + +struct RuleCascadeData; +class nsICSSStyleSheet; + +/** + * The CSS style rule processor provides a mechanism for sibling style + * sheets to combine their rule processing in order to allow proper + * cascading to happen. + * + * CSS style rule processors keep a live reference on all style sheets + * bound to them. The CSS style sheets keep a weak reference to all the + * processors that they are bound to (many to many). The CSS style sheet + * is told when the rule processor is going away (via DropRuleProcessor). + */ + +class nsCSSRuleProcessor: public nsIStyleRuleProcessor { +public: + nsCSSRuleProcessor(const nsCOMArray& aSheets); + virtual ~nsCSSRuleProcessor(); + + NS_DECL_ISUPPORTS + +public: + nsresult ClearRuleCascades(); + + // nsIStyleRuleProcessor + NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData, + nsIAtom* aMedium); + + NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData, + nsIAtom* aMedium); + + NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData, + nsIAtom* aMedium, + nsReStyleHint* aResult); + + NS_IMETHOD HasAttributeDependentStyle(AttributeRuleProcessorData* aData, + nsIAtom* aMedium, + nsReStyleHint* aResult); + +protected: + RuleCascadeData* GetRuleCascade(nsIPresContext* aPresContext, nsIAtom* aMedium); + + nsCOMArray mSheets; + + RuleCascadeData* mRuleCascades; +}; + +#endif /* nsCSSRuleProcessor_h_ */ diff --git a/layout/style/nsCSSStyleSheet.cpp b/layout/style/nsCSSStyleSheet.cpp index 5263d7049e4e..fa680c2349f4 100644 --- a/layout/style/nsCSSStyleSheet.cpp +++ b/layout/style/nsCSSStyleSheet.cpp @@ -53,7 +53,7 @@ #include "pldhash.h" #include "nsHashtable.h" #include "nsICSSPseudoComparator.h" -#include "nsICSSStyleRuleProcessor.h" +#include "nsCSSRuleProcessor.h" #include "nsICSSStyleRule.h" #include "nsICSSNameSpaceRule.h" #include "nsICSSMediaRule.h" @@ -107,13 +107,17 @@ struct RuleValue { * |RuleHash|, to act as rule/selector pairs. |Add| is called when * they are added to the |RuleHash|, and can be considered the second * half of the constructor. + * + * |RuleValue|s are added to the rule hash from highest weight/order + * to lowest (since this is the fast way to build a singly linked + * list), so the index used to remember the order is backwards. */ RuleValue(nsICSSStyleRule* aRule, nsCSSSelector* aSelector) : mRule(aRule), mSelector(aSelector) {} - RuleValue* Add(PRInt32 aIndex, RuleValue *aNext) + RuleValue* Add(PRInt32 aBackwardIndex, RuleValue *aNext) { - mIndex = aIndex; + mBackwardIndex = aBackwardIndex; mNext = aNext; return this; } @@ -136,7 +140,7 @@ struct RuleValue { nsICSSStyleRule* mRule; nsCSSSelector* mSelector; // which of |mRule|'s selectors - PRInt32 mIndex; // High index means low weight/order. + PRInt32 mBackwardIndex; // High index means low weight/order. RuleValue* mNext; }; @@ -603,9 +607,9 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, // Merge the lists while there are still multiple lists to merge. while (valueCount > 1) { PRInt32 valueIndex = 0; - PRInt32 highestRuleIndex = mEnumList[valueIndex]->mIndex; + PRInt32 highestRuleIndex = mEnumList[valueIndex]->mBackwardIndex; for (PRInt32 index = 1; index < valueCount; ++index) { - PRInt32 ruleIndex = mEnumList[index]->mIndex; + PRInt32 ruleIndex = mEnumList[index]->mBackwardIndex; if (ruleIndex > highestRuleIndex) { valueIndex = index; highestRuleIndex = ruleIndex; @@ -719,48 +723,6 @@ RuleCascadeData::AttributeListFor(nsIAtom* aAttribute) return entry->mSelectors; } -// ------------------------------- -// CSS Style Rule processor -// - -class CSSRuleProcessor: public nsICSSStyleRuleProcessor { -public: - CSSRuleProcessor(void); - virtual ~CSSRuleProcessor(void); - - NS_DECL_ISUPPORTS - -public: - // nsICSSStyleRuleProcessor - NS_IMETHOD AppendStyleSheet(nsICSSStyleSheet* aStyleSheet); - - NS_IMETHOD ClearRuleCascades(void); - - // nsIStyleRuleProcessor - NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData, - nsIAtom* aMedium); - - NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData, - nsIAtom* aMedium); - - NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData, - nsIAtom* aMedium, - nsReStyleHint* aResult); - - NS_IMETHOD HasAttributeDependentStyle(AttributeRuleProcessorData* aData, - nsIAtom* aMedium, - nsReStyleHint* aResult); - -protected: - RuleCascadeData* GetRuleCascade(nsIPresContext* aPresContext, nsIAtom* aMedium); - - static PRBool CascadeSheetRulesInto(nsISupports* aSheet, void* aData); - - nsISupportsArray* mSheets; - - RuleCascadeData* mRuleCascades; -}; - // ------------------------------- // CSS Style Sheet Inner Data Container // @@ -795,6 +757,7 @@ public: class CSSImportsCollectionImpl; class CSSRuleListImpl; class DOMMediaListImpl; +static PRBool CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData); class CSSStyleSheetImpl : public nsICSSStyleSheet, public nsIDOMCSSStyleSheet, @@ -836,9 +799,8 @@ public: NS_IMETHOD SetOwnerRule(nsICSSImportRule* aOwnerRule); NS_IMETHOD GetOwnerRule(nsICSSImportRule** aOwnerRule); - NS_IMETHOD GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* aPrevProcessor); - NS_IMETHOD DropRuleProcessorReference(nsICSSStyleRuleProcessor* aProcessor); + NS_IMETHOD AddRuleProcessor(nsCSSRuleProcessor* aProcessor); + NS_IMETHOD DropRuleProcessor(nsCSSRuleProcessor* aProcessor); NS_IMETHOD ContainsStyleSheet(nsIURI* aURL, PRBool& aContains, nsIStyleSheet** aTheChild=nsnull); @@ -920,8 +882,8 @@ protected: nsAutoVoidArray* mRuleProcessors; - friend class CSSRuleProcessor; friend class DOMMediaListImpl; + friend PRBool CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData); }; @@ -1696,57 +1658,30 @@ NS_IMPL_RELEASE(CSSStyleSheetImpl) NS_IMETHODIMP -CSSStyleSheetImpl::GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* aPrevProcessor) +CSSStyleSheetImpl::AddRuleProcessor(nsCSSRuleProcessor* aProcessor) { - nsresult result = NS_OK; - nsICSSStyleRuleProcessor* cssProcessor = nsnull; - - if (aPrevProcessor) { - result = aPrevProcessor->QueryInterface(NS_GET_IID(nsICSSStyleRuleProcessor), (void**)&cssProcessor); + if (! mRuleProcessors) { + mRuleProcessors = new nsAutoVoidArray(); + if (!mRuleProcessors) + return NS_ERROR_OUT_OF_MEMORY; } - if (! cssProcessor) { - CSSRuleProcessor* processor = new CSSRuleProcessor(); - if (processor) { - result = processor->QueryInterface(NS_GET_IID(nsICSSStyleRuleProcessor), (void**)&cssProcessor); - if (NS_FAILED(result)) { - delete processor; - cssProcessor = nsnull; - } - } - else { - result = NS_ERROR_OUT_OF_MEMORY; - } - } - if (NS_SUCCEEDED(result) && cssProcessor) { - cssProcessor->AppendStyleSheet(this); - if (! mRuleProcessors) { - mRuleProcessors = new nsAutoVoidArray(); - } - if (mRuleProcessors) { - NS_ASSERTION(-1 == mRuleProcessors->IndexOf(cssProcessor), "processor already registered"); - mRuleProcessors->AppendElement(cssProcessor); // weak ref - } - } - aProcessor = cssProcessor; + NS_ASSERTION(-1 == mRuleProcessors->IndexOf(aProcessor), + "processor already registered"); + mRuleProcessors->AppendElement(aProcessor); // weak ref return NS_OK; } NS_IMETHODIMP -CSSStyleSheetImpl::DropRuleProcessorReference(nsICSSStyleRuleProcessor* aProcessor) +CSSStyleSheetImpl::DropRuleProcessor(nsCSSRuleProcessor* aProcessor) { - NS_ASSERTION(mRuleProcessors, "no rule processors registered"); - if (mRuleProcessors) { - NS_ASSERTION(-1 != mRuleProcessors->IndexOf(aProcessor), "not a registered processor"); - mRuleProcessors->RemoveElement(aProcessor); - } - return NS_OK; + if (!mRuleProcessors) + return NS_ERROR_FAILURE; + return mRuleProcessors->RemoveElement(aProcessor) + ? NS_OK + : NS_ERROR_FAILURE; } - - - NS_IMETHODIMP CSSStyleSheetImpl::SetURL(nsIURI* aURL) { @@ -2367,7 +2302,8 @@ void CSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const static PRBool PR_CALLBACK EnumClearRuleCascades(void* aProcessor, void* aData) { - nsICSSStyleRuleProcessor* processor = (nsICSSStyleRuleProcessor*)aProcessor; + nsCSSRuleProcessor* processor = + NS_STATIC_CAST(nsCSSRuleProcessor*, aProcessor); processor->ClearRuleCascades(); return PR_TRUE; } @@ -3011,72 +2947,23 @@ NS_NewCSSStyleSheet(nsICSSStyleSheet** aInstancePtrResult) // CSS Style rule processor implementation // -CSSRuleProcessor::CSSRuleProcessor(void) - : mSheets(nsnull), +nsCSSRuleProcessor::nsCSSRuleProcessor(const nsCOMArray& aSheets) + : mSheets(aSheets), mRuleCascades(nsnull) { + for (PRInt32 i = mSheets.Count() - 1; i >= 0; --i) + mSheets[i]->AddRuleProcessor(this); } -static PRBool -DropProcessorReference(nsISupports* aSheet, void* aProcessor) +nsCSSRuleProcessor::~nsCSSRuleProcessor(void) { - nsICSSStyleSheet* sheet = (nsICSSStyleSheet*)aSheet; - nsICSSStyleRuleProcessor* processor = (nsICSSStyleRuleProcessor*)aProcessor; - sheet->DropRuleProcessorReference(processor); - return PR_TRUE; -} - -CSSRuleProcessor::~CSSRuleProcessor(void) -{ - if (mSheets) { - mSheets->EnumerateForwards(DropProcessorReference, this); - NS_RELEASE(mSheets); - } + for (PRInt32 i = mSheets.Count() - 1; i >= 0; --i) + mSheets[i]->DropRuleProcessor(this); + mSheets.Clear(); ClearRuleCascades(); } -NS_IMPL_ADDREF(CSSRuleProcessor) -NS_IMPL_RELEASE(CSSRuleProcessor) - -nsresult -CSSRuleProcessor::QueryInterface(REFNSIID aIID, void** aInstancePtrResult) -{ - if (NULL == aInstancePtrResult) { - return NS_ERROR_NULL_POINTER; - } - - static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); - if (aIID.Equals(NS_GET_IID(nsICSSStyleRuleProcessor))) { - *aInstancePtrResult = (void*)this; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(NS_GET_IID(nsIStyleRuleProcessor))) { - *aInstancePtrResult = (void*)this; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kISupportsIID)) { - *aInstancePtrResult = (void*)this; - NS_ADDREF_THIS(); - return NS_OK; - } - return NS_NOINTERFACE; -} - - -NS_IMETHODIMP -CSSRuleProcessor::AppendStyleSheet(nsICSSStyleSheet* aStyleSheet) -{ - nsresult result = NS_OK; - if (! mSheets) { - result = NS_NewISupportsArray(&mSheets); - } - if (mSheets) { - mSheets->AppendElement(aStyleSheet); - } - return result; -} +NS_IMPL_ISUPPORTS1(nsCSSRuleProcessor, nsIStyleRuleProcessor) MOZ_DECL_CTOR_COUNTER(RuleProcessorData) @@ -3869,8 +3756,8 @@ static void ContentEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector, } NS_IMETHODIMP -CSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData, - nsIAtom* aMedium) +nsCSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData, + nsIAtom* aMedium) { NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT), "content must be element"); @@ -3939,8 +3826,8 @@ static void PseudoEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector, } NS_IMETHODIMP -CSSRuleProcessor::RulesMatching(PseudoRuleProcessorData* aData, - nsIAtom* aMedium) +nsCSSRuleProcessor::RulesMatching(PseudoRuleProcessorData* aData, + nsIAtom* aMedium) { NS_PRECONDITION(!aData->mContent || aData->mContent->IsContentOfType(nsIContent::eELEMENT), @@ -3987,9 +3874,9 @@ PR_STATIC_CALLBACK(PRBool) StateEnumFunc(void* aSelector, void* aData) } NS_IMETHODIMP -CSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData, - nsIAtom* aMedium, - nsReStyleHint* aResult) +nsCSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData, + nsIAtom* aMedium, + nsReStyleHint* aResult) { NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT), "content must be element"); @@ -4038,9 +3925,9 @@ PR_STATIC_CALLBACK(PRBool) AttributeEnumFunc(void* aSelector, void* aData) } NS_IMETHODIMP -CSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData, - nsIAtom* aMedium, - nsReStyleHint* aResult) +nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData, + nsIAtom* aMedium, + nsReStyleHint* aResult) { NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT), "content must be element"); @@ -4087,7 +3974,7 @@ CSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData, } NS_IMETHODIMP -CSSRuleProcessor::ClearRuleCascades(void) +nsCSSRuleProcessor::ClearRuleCascades(void) { RuleCascadeData *data = mRuleCascades; mRuleCascades = nsnull; @@ -4229,19 +4116,18 @@ InsertRuleByWeight(nsISupports* aRule, void* aData) } -PRBool -CSSRuleProcessor::CascadeSheetRulesInto(nsISupports* aSheet, void* aData) +static PRBool +CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData) { - nsICSSStyleSheet* iSheet = (nsICSSStyleSheet*)aSheet; - CSSStyleSheetImpl* sheet = (CSSStyleSheetImpl*)iSheet; - CascadeEnumData* data = (CascadeEnumData*)aData; + CSSStyleSheetImpl* sheet = NS_STATIC_CAST(CSSStyleSheetImpl*, aSheet); + CascadeEnumData* data = NS_STATIC_CAST(CascadeEnumData*, aData); PRBool bSheetApplicable = PR_TRUE; sheet->GetApplicable(bSheetApplicable); if (bSheetApplicable && sheet->UseForMedium(data->mMedium)) { - CSSStyleSheetImpl* child = sheet->mFirstChild; + CSSStyleSheetImpl* child = sheet->mFirstChild; while (child) { - CascadeSheetRulesInto((nsICSSStyleSheet*)child, data); + CascadeSheetRulesInto(child, data); child = child->mNext; } @@ -4311,7 +4197,8 @@ static void PutRulesInList(nsObjectHashtable* aRuleArrays, } RuleCascadeData* -CSSRuleProcessor::GetRuleCascade(nsIPresContext* aPresContext, nsIAtom* aMedium) +nsCSSRuleProcessor::GetRuleCascade(nsIPresContext* aPresContext, + nsIAtom* aMedium) { RuleCascadeData **cascadep = &mRuleCascades; RuleCascadeData *cascade; @@ -4321,15 +4208,17 @@ CSSRuleProcessor::GetRuleCascade(nsIPresContext* aPresContext, nsIAtom* aMedium) cascadep = &cascade->mNext; } - if (mSheets) { + if (mSheets.Count() != 0) { cascade = new RuleCascadeData(aMedium, eCompatibility_NavQuirks == aPresContext->CompatibilityMode()); if (cascade) { CascadeEnumData data(aMedium, cascade->mRuleHash.Arena()); - mSheets->EnumerateForwards(CascadeSheetRulesInto, &data); + mSheets.EnumerateForwards(CascadeSheetRulesInto, &data); nsVoidArray weightedRules; PutRulesInList(&data.mRuleArrays, &weightedRules); + // Put things into the rule hash backwards because it's easier to + // build a singly linked list lowest-first that way. if (!weightedRules.EnumerateBackwards(AddRule, cascade)) { delete cascade; cascade = nsnull; diff --git a/layout/style/nsHTMLCSSStyleSheet.cpp b/layout/style/nsHTMLCSSStyleSheet.cpp index 9007bb5856a9..df2ce33f833b 100644 --- a/layout/style/nsHTMLCSSStyleSheet.cpp +++ b/layout/style/nsHTMLCSSStyleSheet.cpp @@ -367,9 +367,6 @@ public: NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; NS_IMETHOD SetOwningDocument(nsIDocument* aDocument); - NS_IMETHOD GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* aPrevProcessor); - // nsIStyleRuleProcessor api NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData, nsIAtom* aMedium); @@ -434,15 +431,6 @@ NS_IMPL_ISUPPORTS3(HTMLCSSStyleSheetImpl, nsIStyleSheet, nsIStyleRuleProcessor) -NS_IMETHODIMP -HTMLCSSStyleSheetImpl::GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* /*aPrevProcessor*/) -{ - aProcessor = this; - NS_ADDREF(aProcessor); - return NS_OK; -} - NS_IMETHODIMP HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData, nsIAtom* aMedium) diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp index 4b9bc5511b31..c13273303805 100644 --- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -499,15 +499,6 @@ nsHTMLStyleSheet::~nsHTMLStyleSheet() NS_IMPL_ISUPPORTS2(nsHTMLStyleSheet, nsIStyleSheet, nsIStyleRuleProcessor) -NS_IMETHODIMP -nsHTMLStyleSheet::GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* /*aPrevProcessor*/) -{ - aProcessor = this; - NS_ADDREF(aProcessor); - return NS_OK; -} - static nsresult GetBodyColor(nsIPresContext* aPresContext, nscolor* aColor) { nsCOMPtr doc; diff --git a/layout/style/nsHTMLStyleSheet.h b/layout/style/nsHTMLStyleSheet.h index d5c0a769c8af..4ab5d18d3e04 100644 --- a/layout/style/nsHTMLStyleSheet.h +++ b/layout/style/nsHTMLStyleSheet.h @@ -68,8 +68,6 @@ public: NS_IMETHOD GetParentSheet(nsIStyleSheet*& aParent) const; // will be null NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const; NS_IMETHOD SetOwningDocument(nsIDocument* aDocumemt); - NS_IMETHOD GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* aPrevProcessor); #ifdef DEBUG virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; #endif diff --git a/layout/style/nsICSSStyleSheet.h b/layout/style/nsICSSStyleSheet.h index 69cfd08daee2..e3cfd04cf1d8 100644 --- a/layout/style/nsICSSStyleSheet.h +++ b/layout/style/nsICSSStyleSheet.h @@ -43,14 +43,15 @@ class nsICSSRule; class nsIDOMNode; class nsINameSpace; -class nsICSSStyleRuleProcessor; +class nsCSSRuleProcessor; class nsIMediaList; class nsICSSGroupRule; class nsICSSImportRule; -// IID for the nsICSSStyleSheet interface {8f83b0f0-b21a-11d1-8031-006008159b5a} +// IID for the nsICSSStyleSheet interface +// d148e93e-7f1d-4f95-853f-ac356eba3d70 #define NS_ICSS_STYLE_SHEET_IID \ -{0x8f83b0f0, 0xb21a, 0x11d1, {0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}} +{0xd148e93e, 0x7f1d, 0x4f95, {0x85, 0x3f, 0xac, 0x35, 0x6e, 0xba, 0x3d, 0x70}} class nsICSSStyleSheet : public nsIStyleSheet { public: @@ -101,7 +102,8 @@ public: NS_IMETHOD IsModified(PRBool* aModified) const = 0; // returns the mDirty status of the sheet NS_IMETHOD SetModified(PRBool aModified) = 0; - NS_IMETHOD DropRuleProcessorReference(nsICSSStyleRuleProcessor* aProcessor) = 0; + NS_IMETHOD AddRuleProcessor(nsCSSRuleProcessor* aProcessor) = 0; + NS_IMETHOD DropRuleProcessor(nsCSSRuleProcessor* aProcessor) = 0; }; // XXX for backwards compatibility and convenience diff --git a/layout/style/nsIStyleSheet.h b/layout/style/nsIStyleSheet.h index 98be248cc2e0..3827372b54b8 100644 --- a/layout/style/nsIStyleSheet.h +++ b/layout/style/nsIStyleSheet.h @@ -50,10 +50,19 @@ class nsIContent; class nsIDocument; class nsIStyleRuleProcessor; -// IID for the nsIStyleSheet interface {8c4a80a0-ad6a-11d1-8031-006008159b5a} +// IID for the nsIStyleSheet interface +// 6fbfb2cb-a1c0-4576-9354-a4af4e0029ad #define NS_ISTYLE_SHEET_IID \ -{0x8c4a80a0, 0xad6a, 0x11d1, {0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}} +{0x6fbfb2cb, 0xa1c0, 0x4576, {0x93, 0x54, 0xa4, 0xaf, 0x4e, 0x00, 0x29, 0xad}} +/** + * A style sheet is a thing associated with a document that has style + * rules. Those style rules can be reached in one of two ways, depending + * on which level of the nsStyleSet it is in: + * 1) It can be |QueryInterface|d to nsIStyleRuleProcessor + * 2) It can be |QueryInterface|d to nsICSSStyleSheet, with which the + * |nsStyleSet| uses an |nsCSSRuleProcessor| to access the rules. + */ class nsIStyleSheet : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISTYLE_SHEET_IID) @@ -93,10 +102,6 @@ public: NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const = 0; // may be null NS_IMETHOD SetOwningDocument(nsIDocument* aDocument) = 0; - // style rule processor access - NS_IMETHOD GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor, - nsIStyleRuleProcessor* aPrevProcessor) = 0; - #ifdef DEBUG virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; #endif diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index abf263de3e5e..d61bbc6d694a 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -45,6 +45,7 @@ #include "nsICSSStyleRule.h" #include "nsCSSAnonBoxes.h" #include "nsCSSPseudoElements.h" +#include "nsCSSRuleProcessor.h" #include "nsIContent.h" #include "nsIFrame.h" @@ -90,42 +91,33 @@ nsStyleSet::Init(nsIPresContext *aPresContext) return NS_OK; } -struct RuleProcessorEnumData { - RuleProcessorEnumData(nsCOMArray *aRuleProcessors) - : mRuleProcessors(aRuleProcessors), - mPrevProcessor(nsnull) - {} - - nsCOMArray* mRuleProcessors; - nsIStyleRuleProcessor* mPrevProcessor; -}; - -static PRBool -EnumRuleProcessor(nsIStyleSheet *aSheet, void* aData) -{ - RuleProcessorEnumData* data = (RuleProcessorEnumData*)aData; - - nsCOMPtr processor; - nsresult result = aSheet->GetStyleRuleProcessor(*getter_AddRefs(processor), - data->mPrevProcessor); - if (NS_SUCCEEDED(result) && processor) { - if (processor != data->mPrevProcessor) { - if (!data->mRuleProcessors->AppendObject(processor)) - return PR_FALSE; - data->mPrevProcessor = processor; // ref is held by array - } - } - return PR_TRUE; -} - nsresult -nsStyleSet::GatherRuleProcessors(PRInt32 aType) +nsStyleSet::GatherRuleProcessors(sheetType aType) { - mRuleProcessors[aType].Clear(); + mRuleProcessors[aType] = nsnull; if (mSheets[aType].Count()) { - RuleProcessorEnumData data(&mRuleProcessors[aType]); - if (!mSheets[aType].EnumerateBackwards(EnumRuleProcessor, &data)) - return NS_ERROR_OUT_OF_MEMORY; + switch (aType) { + case eAgentSheet: + case eUserSheet: + case eDocSheet: + case eOverrideSheet: { + // levels containing CSS stylesheets + nsCOMArray& sheets = mSheets[aType]; + nsCOMArray cssSheets(sheets.Count()); + for (PRInt32 i = 0, i_end = sheets.Count(); i < i_end; ++i) { + nsCOMPtr cssSheet = do_QueryInterface(sheets[i]); + NS_ASSERTION(cssSheet, "not a CSS sheet"); + cssSheets.AppendObject(cssSheet); + } + mRuleProcessors[aType] = new nsCSSRuleProcessor(cssSheets); + } break; + + default: + // levels containing non-CSS stylesheets + NS_ASSERTION(mSheets[aType].Count() == 1, "only one sheet per level"); + mRuleProcessors[aType] = do_QueryInterface(mSheets[aType][0]); + break; + } } return NS_OK; @@ -217,23 +209,18 @@ nsStyleSet::AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument) nsCOMArray& docSheets = mSheets[eDocSheet]; docSheets.RemoveObject(aSheet); - // lowest index last + // lowest index first PRInt32 newDocIndex = aDocument->GetIndexOfStyleSheet(aSheet); PRInt32 count = docSheets.Count(); - for (PRInt32 index = 0; index < count; index++) { + PRInt32 index; + for (index = 0; index < count; index++) { nsIStyleSheet* sheet = docSheets.ObjectAt(index); PRInt32 sheetDocIndex = aDocument->GetIndexOfStyleSheet(sheet); - if (sheetDocIndex < newDocIndex) { - if (!docSheets.InsertObjectAt(aSheet, index)) - return NS_ERROR_OUT_OF_MEMORY; - - index = count; // break loop - } - } - if (docSheets.Count() == count) { // didn't insert it - if (!docSheets.AppendObject(aSheet)) - return NS_ERROR_OUT_OF_MEMORY; + if (sheetDocIndex > newDocIndex) + break; } + if (!docSheets.InsertObjectAt(aSheet, index)) + return NS_ERROR_OUT_OF_MEMORY; if (!mBatching) return GatherRuleProcessors(eDocSheet); @@ -261,7 +248,7 @@ nsStyleSet::EndUpdate() for (int i = 0; i < eSheetTypeCount; ++i) { if (mDirty & (1 << i)) { - nsresult rv = GatherRuleProcessors(i); + nsresult rv = GatherRuleProcessors(sheetType(i)); NS_ENSURE_SUCCESS(rv, rv); } } @@ -302,12 +289,11 @@ nsStyleSet::EnableQuirkStyleSheet(PRBool aEnable) NS_ASSERTION(mQuirkStyleSheet, "no quirk stylesheet"); if (mQuirkStyleSheet) { #ifdef DEBUG_dbaron_off // XXX Make this |DEBUG| once it stops firing. - PRInt32 count = mRuleProcessors[eAgentSheet].Count() PRBool applicableNow; mQuirkStyleSheet->GetApplicable(applicableNow); - NS_ASSERTION(count == 0 || aEnable == applicableNow, + NS_ASSERTION(!mRuleProcessors[eAgentSheet] || aEnable == applicableNow, "enabling/disabling quirk stylesheet too late or incomplete quirk stylesheet"); - if (count != 0 && aEnable == applicableNow) + if (mRuleProcessors[eAgentSheet] && aEnable == applicableNow) printf("WARNING: We set the quirks mode too many times.\n"); // we do! #endif mQuirkStyleSheet->SetEnabled(aEnable); @@ -442,47 +428,36 @@ nsStyleSet::FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc, SheetCount(eHTMLPresHintSheet) == 0, "Can't have both types of preshint sheets at once!"); - nsRuleNode* lastAgentRN = nsnull; - if (mRuleProcessors[eAgentSheet].Count()) { - mRuleProcessors[eAgentSheet].EnumerateForwards(aCollectorFunc, aData); - lastAgentRN = mRuleWalker->GetCurrentNode(); - } + if (mRuleProcessors[eAgentSheet]) + (*aCollectorFunc)(mRuleProcessors[eAgentSheet], aData); + nsRuleNode* lastAgentRN = mRuleWalker->GetCurrentNode(); - nsRuleNode* lastPresHintRN = lastAgentRN; - if (mRuleProcessors[ePresHintSheet].Count()) { - mRuleProcessors[ePresHintSheet].EnumerateForwards(aCollectorFunc, aData); - lastPresHintRN = mRuleWalker->GetCurrentNode(); - } + if (mRuleProcessors[ePresHintSheet]) + (*aCollectorFunc)(mRuleProcessors[ePresHintSheet], aData); + nsRuleNode* lastPresHintRN = mRuleWalker->GetCurrentNode(); - nsRuleNode* lastUserRN = lastPresHintRN; - if (mRuleProcessors[eUserSheet].Count()) { - mRuleProcessors[eUserSheet].EnumerateForwards(aCollectorFunc, aData); - lastUserRN = mRuleWalker->GetCurrentNode(); - } + if (mRuleProcessors[eUserSheet]) + (*aCollectorFunc)(mRuleProcessors[eUserSheet], aData); + nsRuleNode* lastUserRN = mRuleWalker->GetCurrentNode(); - nsRuleNode* lastHTMLPresHintRN = lastUserRN; - if (mRuleProcessors[eHTMLPresHintSheet].Count()) { - mRuleProcessors[eHTMLPresHintSheet].EnumerateForwards(aCollectorFunc, aData); - lastHTMLPresHintRN = mRuleWalker->GetCurrentNode(); - } + if (mRuleProcessors[eHTMLPresHintSheet]) + (*aCollectorFunc)(mRuleProcessors[eHTMLPresHintSheet], aData); + nsRuleNode* lastHTMLPresHintRN = mRuleWalker->GetCurrentNode(); - nsRuleNode* lastDocRN = lastHTMLPresHintRN; PRBool useRuleProcessors = PR_TRUE; if (mStyleRuleSupplier) { // We can supply additional document-level sheets that should be walked. mStyleRuleSupplier->WalkRules(this, aCollectorFunc, aData); mStyleRuleSupplier->UseDocumentRules(aData->mContent, &useRuleProcessors); } - if (useRuleProcessors && mRuleProcessors[eDocSheet].Count()) { - mRuleProcessors[eDocSheet].EnumerateForwards(aCollectorFunc, aData); - } - lastDocRN = mRuleWalker->GetCurrentNode(); + if (useRuleProcessors && mRuleProcessors[eDocSheet]) // NOTE: different + (*aCollectorFunc)(mRuleProcessors[eDocSheet], aData); + if (mRuleProcessors[eStyleAttrSheet]) + (*aCollectorFunc)(mRuleProcessors[eStyleAttrSheet], aData); - nsRuleNode* lastOvrRN = lastDocRN; - if (mRuleProcessors[eOverrideSheet].Count()) { - mRuleProcessors[eOverrideSheet].EnumerateForwards(aCollectorFunc, aData); - lastOvrRN = mRuleWalker->GetCurrentNode(); - } + if (mRuleProcessors[eOverrideSheet]) + (*aCollectorFunc)(mRuleProcessors[eOverrideSheet], aData); + nsRuleNode* lastOvrRN = mRuleWalker->GetCurrentNode(); // There should be no important rules in the preshint or HTMLpreshint level AddImportantRules(lastOvrRN, lastHTMLPresHintRN); // doc and override @@ -509,17 +484,14 @@ nsStyleSet::WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc, SheetCount(eHTMLPresHintSheet) == 0, "Can't have both types of preshint sheets at once!"); - // Walk the agent rules first. - mRuleProcessors[eAgentSheet].EnumerateForwards(aFunc, aData); - - // Walk preshint rules. - mRuleProcessors[ePresHintSheet].EnumerateForwards(aFunc, aData); - - // Walk the user rules next. - mRuleProcessors[eUserSheet].EnumerateForwards(aFunc, aData); - - // Walk HTML preshint rules. - mRuleProcessors[eHTMLPresHintSheet].EnumerateForwards(aFunc, aData); + if (mRuleProcessors[eAgentSheet]) + (*aFunc)(mRuleProcessors[eAgentSheet], aData); + if (mRuleProcessors[ePresHintSheet]) + (*aFunc)(mRuleProcessors[ePresHintSheet], aData); + if (mRuleProcessors[eUserSheet]) + (*aFunc)(mRuleProcessors[eUserSheet], aData); + if (mRuleProcessors[eHTMLPresHintSheet]) + (*aFunc)(mRuleProcessors[eHTMLPresHintSheet], aData); PRBool useRuleProcessors = PR_TRUE; if (mStyleRuleSupplier) { @@ -527,13 +499,12 @@ nsStyleSet::WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc, mStyleRuleSupplier->WalkRules(this, aFunc, aData); mStyleRuleSupplier->UseDocumentRules(aData->mContent, &useRuleProcessors); } - - // Now walk the doc rules. - if (useRuleProcessors) - mRuleProcessors[eDocSheet].EnumerateForwards(aFunc, aData); - - // Walk the override rules last. - mRuleProcessors[eOverrideSheet].EnumerateForwards(aFunc, aData); + if (useRuleProcessors && mRuleProcessors[eDocSheet]) // NOTE: different + (*aFunc)(mRuleProcessors[eDocSheet], aData); + if (mRuleProcessors[eStyleAttrSheet]) + (*aFunc)(mRuleProcessors[eStyleAttrSheet], aData); + if (mRuleProcessors[eOverrideSheet]) + (*aFunc)(mRuleProcessors[eOverrideSheet], aData); } PRBool nsStyleSet::BuildDefaultStyleData(nsIPresContext* aPresContext) @@ -581,12 +552,13 @@ nsStyleSet::ResolveStyleFor(nsIContent* aContent, "content must be element"); if (aContent && presContext) { - if (mRuleProcessors[eAgentSheet].Count() || - mRuleProcessors[ePresHintSheet].Count() || - mRuleProcessors[eUserSheet].Count() || - mRuleProcessors[eHTMLPresHintSheet].Count() || - mRuleProcessors[eDocSheet].Count() || - mRuleProcessors[eOverrideSheet].Count()) { + if (mRuleProcessors[eAgentSheet] || + mRuleProcessors[ePresHintSheet] || + mRuleProcessors[eUserSheet] || + mRuleProcessors[eHTMLPresHintSheet] || + mRuleProcessors[eDocSheet] || + mRuleProcessors[eStyleAttrSheet] || + mRuleProcessors[eOverrideSheet]) { RulesMatchingData data(presContext, aContent, mRuleWalker); FileRules(EnumRulesMatching, &data); result = GetContext(presContext, aParentContext, nsnull).get(); @@ -606,12 +578,13 @@ nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext) nsIPresContext *presContext = PresContext(); if (presContext) { - if (mRuleProcessors[eAgentSheet].Count() || - mRuleProcessors[ePresHintSheet].Count() || - mRuleProcessors[eUserSheet].Count() || - mRuleProcessors[eHTMLPresHintSheet].Count() || - mRuleProcessors[eDocSheet].Count() || - mRuleProcessors[eOverrideSheet].Count()) { + if (mRuleProcessors[eAgentSheet] || + mRuleProcessors[ePresHintSheet] || + mRuleProcessors[eUserSheet] || + mRuleProcessors[eHTMLPresHintSheet] || + mRuleProcessors[eDocSheet] || + mRuleProcessors[eStyleAttrSheet] || + mRuleProcessors[eOverrideSheet]) { result = GetContext(presContext, aParentContext, nsCSSAnonBoxes::mozNonElement).get(); NS_ASSERTION(mRuleWalker->AtRoot(), "rule walker must be at root"); @@ -660,12 +633,13 @@ nsStyleSet::ResolvePseudoStyleFor(nsIContent* aParentContent, "content (if non-null) must be element"); if (aPseudoTag && presContext) { - if (mRuleProcessors[eAgentSheet].Count() || - mRuleProcessors[ePresHintSheet].Count() || - mRuleProcessors[eUserSheet].Count() || - mRuleProcessors[eHTMLPresHintSheet].Count() || - mRuleProcessors[eDocSheet].Count() || - mRuleProcessors[eOverrideSheet].Count()) { + if (mRuleProcessors[eAgentSheet] || + mRuleProcessors[ePresHintSheet] || + mRuleProcessors[eUserSheet] || + mRuleProcessors[eHTMLPresHintSheet] || + mRuleProcessors[eDocSheet] || + mRuleProcessors[eStyleAttrSheet] || + mRuleProcessors[eOverrideSheet]) { PseudoRulesMatchingData data(presContext, aParentContent, aPseudoTag, aComparator, mRuleWalker); FileRules(EnumPseudoRulesMatching, &data); @@ -694,12 +668,13 @@ nsStyleSet::ProbePseudoStyleFor(nsIContent* aParentContent, "content (if non-null) must be element"); if (aPseudoTag && presContext) { - if (mRuleProcessors[eAgentSheet].Count() || - mRuleProcessors[ePresHintSheet].Count() || - mRuleProcessors[eUserSheet].Count() || - mRuleProcessors[eHTMLPresHintSheet].Count() || - mRuleProcessors[eDocSheet].Count() || - mRuleProcessors[eOverrideSheet].Count()) { + if (mRuleProcessors[eAgentSheet] || + mRuleProcessors[ePresHintSheet] || + mRuleProcessors[eUserSheet] || + mRuleProcessors[eHTMLPresHintSheet] || + mRuleProcessors[eDocSheet] || + mRuleProcessors[eStyleAttrSheet] || + mRuleProcessors[eOverrideSheet]) { PseudoRulesMatchingData data(presContext, aParentContent, aPseudoTag, nsnull, mRuleWalker); FileRules(EnumPseudoRulesMatching, &data); @@ -853,12 +828,13 @@ nsStyleSet::HasStateDependentStyle(nsIPresContext* aPresContext, nsReStyleHint result = nsReStyleHint(0); if (aContent->IsContentOfType(nsIContent::eELEMENT) && - (mRuleProcessors[eAgentSheet].Count() || - mRuleProcessors[ePresHintSheet].Count() || - mRuleProcessors[eUserSheet].Count() || - mRuleProcessors[eHTMLPresHintSheet].Count() || - mRuleProcessors[eDocSheet].Count() || - mRuleProcessors[eOverrideSheet].Count())) { + (mRuleProcessors[eAgentSheet] || + mRuleProcessors[ePresHintSheet] || + mRuleProcessors[eUserSheet] || + mRuleProcessors[eHTMLPresHintSheet] || + mRuleProcessors[eDocSheet] || + mRuleProcessors[eStyleAttrSheet] || + mRuleProcessors[eOverrideSheet])) { StatefulData data(aPresContext, aContent, aStateMask); WalkRuleProcessors(SheetHasStatefulStyle, &data); result = data.mHint; @@ -898,12 +874,13 @@ nsStyleSet::HasAttributeDependentStyle(nsIPresContext* aPresContext, nsReStyleHint result = nsReStyleHint(0); if (aContent->IsContentOfType(nsIContent::eELEMENT) && - (mRuleProcessors[eAgentSheet].Count() || - mRuleProcessors[ePresHintSheet].Count() || - mRuleProcessors[eUserSheet].Count() || - mRuleProcessors[eHTMLPresHintSheet].Count() || - mRuleProcessors[eDocSheet].Count() || - mRuleProcessors[eOverrideSheet].Count())) { + (mRuleProcessors[eAgentSheet] || + mRuleProcessors[ePresHintSheet] || + mRuleProcessors[eUserSheet] || + mRuleProcessors[eHTMLPresHintSheet] || + mRuleProcessors[eDocSheet] || + mRuleProcessors[eStyleAttrSheet] || + mRuleProcessors[eOverrideSheet])) { AttributeData data(aPresContext, aContent, aAttribute, aModType); WalkRuleProcessors(SheetHasAttributeStyle, &data); result = data.mHint; diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index 1f0723e74cdb..81bdf4076697 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -153,13 +153,16 @@ class nsStyleSet // APIs to manipulate the style sheet lists. // All sheet types are ordered most-significant-first. enum sheetType { - eAgentSheet, + eAgentSheet, // CSS ePresHintSheet, - eUserSheet, + eUserSheet, // CSS eHTMLPresHintSheet, - eDocSheet, - eOverrideSheet, + eDocSheet, // CSS + eStyleAttrSheet, + eOverrideSheet, // CSS eSheetTypeCount + // be sure to keep the number of bits in |mDirty| below updated when + // changing the number of sheet types }; nsresult AppendStyleSheet(sheetType aType, nsIStyleSheet *aSheet); @@ -190,7 +193,7 @@ class nsStyleSet PRBool BuildDefaultStyleData(nsIPresContext* aPresContext); // Update the rule processor list after a change to the style sheet list. - nsresult GatherRuleProcessors(PRInt32 aType); + nsresult GatherRuleProcessors(sheetType aType); void AddImportantRules(nsRuleNode* aCurrLevelNode, nsRuleNode* aLastPrevLevelNode); @@ -229,7 +232,7 @@ class nsStyleSet nsCOMArray mSheets[eSheetTypeCount]; - nsCOMArray mRuleProcessors[eSheetTypeCount]; + nsCOMPtr mRuleProcessors[eSheetTypeCount]; // cached instance for enabling/disabling nsCOMPtr mQuirkStyleSheet; diff --git a/rdf/chrome/src/nsChromeRegistry.cpp b/rdf/chrome/src/nsChromeRegistry.cpp index 7414cdb050d5..b9466a453cd5 100644 --- a/rdf/chrome/src/nsChromeRegistry.cpp +++ b/rdf/chrome/src/nsChromeRegistry.cpp @@ -1449,13 +1449,13 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow) nsCOMArray oldSheets; nsCOMArray newSheets; - PRInt32 count = document->GetNumberOfStyleSheets(PR_FALSE); + PRInt32 count = document->GetNumberOfStyleSheets(); // Iterate over the style sheets. PRInt32 i; for (i = 0; i < count; i++) { // Get the style sheet - nsIStyleSheet *styleSheet = document->GetStyleSheetAt(i, PR_FALSE); + nsIStyleSheet *styleSheet = document->GetStyleSheetAt(i); if (!oldSheets.AppendObject(styleSheet)) { return NS_ERROR_OUT_OF_MEMORY;