diff --git a/mozilla/content/base/public/nsIStyleRuleSupplier.h b/mozilla/content/base/public/nsIStyleRuleSupplier.h index 08278facaa9..45da063535a 100644 --- a/mozilla/content/base/public/nsIStyleRuleSupplier.h +++ b/mozilla/content/base/public/nsIStyleRuleSupplier.h @@ -20,6 +20,9 @@ class nsIStyleRuleSupplier : public nsISupports { nsISupportsArrayEnumFunc aFunc, void* aData, nsIContent* aContent)=0; NS_IMETHOD MatchesScopedRoot(nsIContent* aContent, PRBool* aResult)=0; + + NS_IMETHOD AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData, nsIContent* aContent, + PRBool* aAffects)=0; }; #endif /* _nsIStyleRuleSupplier_h */ diff --git a/mozilla/content/base/src/nsStyleSet.cpp b/mozilla/content/base/src/nsStyleSet.cpp index 8628adb3df8..9f30dfb1fd6 100644 --- a/mozilla/content/base/src/nsStyleSet.cpp +++ b/mozilla/content/base/src/nsStyleSet.cpp @@ -1937,15 +1937,22 @@ StyleSetImpl::AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent, pair.attribute = aAttribute; pair.content = aContent; - /* check until we find a sheet that will be affected */ - if ((mDocSheets && !mDocSheets->EnumerateForwards(EnumAffectsStyle, &pair)) || - (mOverrideSheets && !mOverrideSheets->EnumerateForwards(EnumAffectsStyle, - &pair)) || - (mBackstopSheets && !mBackstopSheets->EnumerateForwards(EnumAffectsStyle, - &pair))) { - aAffects = PR_TRUE; - } else { - aAffects = PR_FALSE; + /* scoped sheets should be checked first, since - if present - they will contain + the bulk of the applicable rules for the content node. */ + if (mStyleRuleSupplier) + mStyleRuleSupplier->AttributeAffectsStyle(EnumAffectsStyle, &pair, aContent, &aAffects); + + if (!aAffects) { + /* check until we find a sheet that will be affected */ + if ((mDocSheets && !mDocSheets->EnumerateForwards(EnumAffectsStyle, &pair)) || + (mOverrideSheets && !mOverrideSheets->EnumerateForwards(EnumAffectsStyle, + &pair)) || + (mBackstopSheets && !mBackstopSheets->EnumerateForwards(EnumAffectsStyle, + &pair))) { + aAffects = PR_TRUE; + } else { + aAffects = PR_FALSE; + } } return NS_OK; diff --git a/mozilla/content/xbl/public/nsIXBLBinding.h b/mozilla/content/xbl/public/nsIXBLBinding.h index a0e48d5ddb5..bd1c00a5590 100644 --- a/mozilla/content/xbl/public/nsIXBLBinding.h +++ b/mozilla/content/xbl/public/nsIXBLBinding.h @@ -102,6 +102,7 @@ public: NS_IMETHOD InheritsStyle(PRBool* aResult)=0; NS_IMETHOD WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData)=0; + NS_IMETHOD AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData, PRBool* aAffects)=0; NS_IMETHOD MarkForDeath()=0; NS_IMETHOD MarkedForDeath(PRBool* aResult)=0; diff --git a/mozilla/content/xbl/public/nsIXBLPrototypeBinding.h b/mozilla/content/xbl/public/nsIXBLPrototypeBinding.h index c3216905ef9..40355d55ad8 100644 --- a/mozilla/content/xbl/public/nsIXBLPrototypeBinding.h +++ b/mozilla/content/xbl/public/nsIXBLPrototypeBinding.h @@ -77,6 +77,7 @@ public: NS_IMETHOD SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent)=0; NS_IMETHOD GetRuleProcessors(nsISupportsArray** aResult)=0; + NS_IMETHOD GetStyleSheets(nsISupportsArray** aResult)=0; NS_IMETHOD HasInsertionPoints(PRBool* aResult)=0; NS_IMETHOD HasStyleSheets(PRBool* aResult)=0; diff --git a/mozilla/content/xbl/src/nsBindingManager.cpp b/mozilla/content/xbl/src/nsBindingManager.cpp index 6e4601d9da7..f558f5105ce 100644 --- a/mozilla/content/xbl/src/nsBindingManager.cpp +++ b/mozilla/content/xbl/src/nsBindingManager.cpp @@ -348,6 +348,7 @@ public: nsISupportsArrayEnumFunc aFunc, void* aData, nsIContent* aContent); NS_IMETHOD MatchesScopedRoot(nsIContent* aContent, PRBool* aResult); + NS_IMETHOD AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData, nsIContent* aContent, PRBool* aAffects); // nsIDocumentObserver NS_IMETHOD BeginUpdate(nsIDocument* aDocument) { return NS_OK; } @@ -411,6 +412,9 @@ protected: void WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData, nsIContent* aParent, nsIContent* aCurrContent); + void AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData, + nsIContent* aParent, nsIContent* aCurrContent, PRBool* aAffects); + nsresult GetNestedInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult); // MEMBER VARIABLES @@ -1246,6 +1250,47 @@ nsBindingManager::WalkRules(nsIStyleSet* aStyleSet, return NS_OK; } +void +nsBindingManager::AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData, + nsIContent* aParent, nsIContent* aCurrContent, PRBool* aAffects) +{ + nsCOMPtr binding; + GetBinding(aCurrContent, getter_AddRefs(binding)); + if (binding) { + binding->AttributeAffectsStyle(aFunc, aData, aAffects); + } + + if (*aAffects) + return; + + if (aParent != aCurrContent) { + nsCOMPtr par; + GetEnclosingScope(aCurrContent, getter_AddRefs(par)); + if (par) + AttributeAffectsStyle(aFunc, aData, aParent, par, aAffects); + } +} + + +NS_IMETHODIMP +nsBindingManager::AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData, + nsIContent* aContent, PRBool* aAffects) +{ + *aAffects = PR_FALSE; + if (!aContent) + return NS_OK; + + nsCOMPtr parent; + GetOutermostStyleScope(aContent, getter_AddRefs(parent)); + + AttributeAffectsStyle(aFunc, aData, parent, aContent, aAffects); + + if (*aAffects) + return NS_OK; + + return NS_OK; +} + NS_IMETHODIMP nsBindingManager::ShouldBuildChildFrames(nsIContent* aContent, PRBool* aResult) { diff --git a/mozilla/content/xbl/src/nsXBLBinding.cpp b/mozilla/content/xbl/src/nsXBLBinding.cpp index 4895078d460..4b2ae7f43b2 100644 --- a/mozilla/content/xbl/src/nsXBLBinding.cpp +++ b/mozilla/content/xbl/src/nsXBLBinding.cpp @@ -1490,6 +1490,31 @@ nsXBLBinding::WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData) return rv; } +NS_IMETHODIMP +nsXBLBinding::AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData, PRBool* aAffects) +{ + nsresult rv = NS_OK; + if (mNextBinding) { + rv = mNextBinding->AttributeAffectsStyle(aFunc, aData, aAffects); + if (NS_FAILED(rv)) + return rv; + + if (*aAffects) + return NS_OK; + } + + nsCOMPtr sheets; + mPrototypeBinding->GetStyleSheets(getter_AddRefs(sheets)); + if (sheets) { + if (!sheets->EnumerateForwards(aFunc, aData)) + *aAffects = PR_TRUE; + else + *aAffects = PR_FALSE; + } + + return rv; +} + // Internal helper methods //////////////////////////////////////////////////////////////// NS_IMETHODIMP diff --git a/mozilla/content/xbl/src/nsXBLBinding.h b/mozilla/content/xbl/src/nsXBLBinding.h index a24d0e9edee..ac59235609c 100644 --- a/mozilla/content/xbl/src/nsXBLBinding.h +++ b/mozilla/content/xbl/src/nsXBLBinding.h @@ -95,6 +95,7 @@ class nsXBLBinding: public nsIXBLBinding NS_IMETHOD InheritsStyle(PRBool* aResult); NS_IMETHOD WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData); + NS_IMETHOD AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData, PRBool* aAffects); NS_IMETHOD MarkForDeath(); NS_IMETHOD MarkedForDeath(PRBool* aResult); diff --git a/mozilla/content/xbl/src/nsXBLPrototypeBinding.cpp b/mozilla/content/xbl/src/nsXBLPrototypeBinding.cpp index e5e85dc5ad6..ecc291ab5dd 100644 --- a/mozilla/content/xbl/src/nsXBLPrototypeBinding.cpp +++ b/mozilla/content/xbl/src/nsXBLPrototypeBinding.cpp @@ -1043,6 +1043,14 @@ nsXBLPrototypeBinding::GetRuleProcessors(nsISupportsArray** aResult) return NS_OK; } +NS_IMETHODIMP +nsXBLPrototypeBinding::GetStyleSheets(nsISupportsArray** aResult) +{ + *aResult = mStyleSheetList; + NS_IF_ADDREF(*aResult); + return NS_OK; +} + NS_IMETHODIMP nsXBLPrototypeBinding::ShouldBuildChildFrames(PRBool* aResult) { diff --git a/mozilla/content/xbl/src/nsXBLPrototypeBinding.h b/mozilla/content/xbl/src/nsXBLPrototypeBinding.h index c832dea8f86..4bf4e9b0ad5 100644 --- a/mozilla/content/xbl/src/nsXBLPrototypeBinding.h +++ b/mozilla/content/xbl/src/nsXBLPrototypeBinding.h @@ -81,6 +81,7 @@ class nsXBLPrototypeBinding: public nsIXBLPrototypeBinding, public nsICSSLoaderO NS_IMETHOD SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent); NS_IMETHOD GetRuleProcessors(nsISupportsArray** aResult); + NS_IMETHOD GetStyleSheets(nsISupportsArray** aResult); NS_IMETHOD HasInsertionPoints(PRBool* aResult) { *aResult = (mInsertionPointTable != nsnull); return NS_OK; }; NS_IMETHOD HasStyleSheets(PRBool* aResult) { *aResult = (mStyleSheetList != nsnull); return NS_OK; }; diff --git a/mozilla/layout/style/nsIStyleRuleSupplier.h b/mozilla/layout/style/nsIStyleRuleSupplier.h index 08278facaa9..45da063535a 100644 --- a/mozilla/layout/style/nsIStyleRuleSupplier.h +++ b/mozilla/layout/style/nsIStyleRuleSupplier.h @@ -20,6 +20,9 @@ class nsIStyleRuleSupplier : public nsISupports { nsISupportsArrayEnumFunc aFunc, void* aData, nsIContent* aContent)=0; NS_IMETHOD MatchesScopedRoot(nsIContent* aContent, PRBool* aResult)=0; + + NS_IMETHOD AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData, nsIContent* aContent, + PRBool* aAffects)=0; }; #endif /* _nsIStyleRuleSupplier_h */ diff --git a/mozilla/layout/style/nsStyleSet.cpp b/mozilla/layout/style/nsStyleSet.cpp index 8628adb3df8..9f30dfb1fd6 100644 --- a/mozilla/layout/style/nsStyleSet.cpp +++ b/mozilla/layout/style/nsStyleSet.cpp @@ -1937,15 +1937,22 @@ StyleSetImpl::AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent, pair.attribute = aAttribute; pair.content = aContent; - /* check until we find a sheet that will be affected */ - if ((mDocSheets && !mDocSheets->EnumerateForwards(EnumAffectsStyle, &pair)) || - (mOverrideSheets && !mOverrideSheets->EnumerateForwards(EnumAffectsStyle, - &pair)) || - (mBackstopSheets && !mBackstopSheets->EnumerateForwards(EnumAffectsStyle, - &pair))) { - aAffects = PR_TRUE; - } else { - aAffects = PR_FALSE; + /* scoped sheets should be checked first, since - if present - they will contain + the bulk of the applicable rules for the content node. */ + if (mStyleRuleSupplier) + mStyleRuleSupplier->AttributeAffectsStyle(EnumAffectsStyle, &pair, aContent, &aAffects); + + if (!aAffects) { + /* check until we find a sheet that will be affected */ + if ((mDocSheets && !mDocSheets->EnumerateForwards(EnumAffectsStyle, &pair)) || + (mOverrideSheets && !mOverrideSheets->EnumerateForwards(EnumAffectsStyle, + &pair)) || + (mBackstopSheets && !mBackstopSheets->EnumerateForwards(EnumAffectsStyle, + &pair))) { + aAffects = PR_TRUE; + } else { + aAffects = PR_FALSE; + } } return NS_OK;