Implement @-moz-document at-rule for site-specific rules, particularly in user stylesheets. b=238099 r+sr=bzbarsky

This commit is contained in:
dbaron%dbaron.org 2004-08-05 18:26:14 +00:00
Родитель 80a91c9e77
Коммит d35f39cc02
34 изменённых файлов: 1910 добавлений и 1042 удалений

Просмотреть файл

@ -179,11 +179,9 @@ public:
// populate rule node tree with nsIStyleRule*
// rules are ordered, those with higher precedence are farthest from the root of the tree
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium) = 0;
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData) = 0;
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium) = 0;
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData) = 0;
/**
* Test whether style is dependent on content state. This test is
@ -193,7 +191,6 @@ public:
* Event states are defined in nsIEventStateManager.h.
*/
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult) = 0;
/**
@ -202,7 +199,6 @@ public:
* the side of reporting more dependencies than really exist.
*/
NS_IMETHOD HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult) = 0;
};

Просмотреть файл

@ -329,23 +329,13 @@ nsStyleSet::EnableQuirkStyleSheet(PRBool aEnable)
}
}
struct RulesMatchingData : public ElementRuleProcessorData {
RulesMatchingData(nsPresContext* aPresContext,
nsIContent* aContent,
nsRuleWalker* aRuleWalker)
: ElementRuleProcessorData(aPresContext, aContent, aRuleWalker),
mMedium(aPresContext->Medium())
{
}
nsIAtom* mMedium;
};
static PRBool
EnumRulesMatching(nsIStyleRuleProcessor* aProcessor, void* aData)
{
RulesMatchingData* data = (RulesMatchingData*)aData;
ElementRuleProcessorData* data =
NS_STATIC_CAST(ElementRuleProcessorData*, aData);
aProcessor->RulesMatching(data, data->mMedium);
aProcessor->RulesMatching(data);
return PR_TRUE;
}
@ -588,7 +578,7 @@ nsStyleSet::ResolveStyleFor(nsIContent* aContent,
mRuleProcessors[eDocSheet] ||
mRuleProcessors[eStyleAttrSheet] ||
mRuleProcessors[eOverrideSheet]) {
RulesMatchingData data(presContext, aContent, mRuleWalker);
ElementRuleProcessorData data(presContext, aContent, mRuleWalker);
FileRules(EnumRulesMatching, &data);
result = GetContext(presContext, aParentContext, nsnull).get();
@ -624,26 +614,13 @@ nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext)
}
struct PseudoRulesMatchingData : public PseudoRuleProcessorData {
PseudoRulesMatchingData(nsPresContext* aPresContext,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker)
: PseudoRuleProcessorData(aPresContext, aParentContent, aPseudoTag,
aComparator, aRuleWalker),
mMedium(aPresContext->Medium())
{
}
nsIAtom* mMedium;
};
static PRBool
EnumPseudoRulesMatching(nsIStyleRuleProcessor* aProcessor, void* aData)
{
PseudoRulesMatchingData* data = (PseudoRulesMatchingData*)aData;
PseudoRuleProcessorData* data =
NS_STATIC_CAST(PseudoRuleProcessorData*, aData);
aProcessor->RulesMatching(data, data->mMedium);
aProcessor->RulesMatching(data);
return PR_TRUE;
}
@ -669,7 +646,7 @@ nsStyleSet::ResolvePseudoStyleFor(nsIContent* aParentContent,
mRuleProcessors[eDocSheet] ||
mRuleProcessors[eStyleAttrSheet] ||
mRuleProcessors[eOverrideSheet]) {
PseudoRulesMatchingData data(presContext, aParentContent, aPseudoTag,
PseudoRuleProcessorData data(presContext, aParentContent, aPseudoTag,
aComparator, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data);
@ -704,7 +681,7 @@ nsStyleSet::ProbePseudoStyleFor(nsIContent* aParentContent,
mRuleProcessors[eDocSheet] ||
mRuleProcessors[eStyleAttrSheet] ||
mRuleProcessors[eOverrideSheet]) {
PseudoRulesMatchingData data(presContext, aParentContent, aPseudoTag,
PseudoRuleProcessorData data(presContext, aParentContent, aPseudoTag,
nsnull, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data);
@ -831,10 +808,8 @@ struct StatefulData : public StateRuleProcessorData {
StatefulData(nsPresContext* aPresContext,
nsIContent* aContent, PRInt32 aStateMask)
: StateRuleProcessorData(aPresContext, aContent, aStateMask),
mMedium(aPresContext->Medium()),
mHint(nsReStyleHint(0))
{}
nsIAtom* mMedium;
nsReStyleHint mHint;
};
@ -843,7 +818,7 @@ static PRBool SheetHasStatefulStyle(nsIStyleRuleProcessor* aProcessor,
{
StatefulData* data = (StatefulData*)aData;
nsReStyleHint hint;
aProcessor->HasStateDependentStyle(data, data->mMedium, &hint);
aProcessor->HasStateDependentStyle(data, &hint);
data->mHint = nsReStyleHint(data->mHint | hint);
return PR_TRUE; // continue
}
@ -876,10 +851,8 @@ struct AttributeData : public AttributeRuleProcessorData {
AttributeData(nsPresContext* aPresContext,
nsIContent* aContent, nsIAtom* aAttribute, PRInt32 aModType)
: AttributeRuleProcessorData(aPresContext, aContent, aAttribute, aModType),
mMedium(aPresContext->Medium()),
mHint(nsReStyleHint(0))
{}
nsIAtom* mMedium;
nsReStyleHint mHint;
};
@ -888,7 +861,7 @@ SheetHasAttributeStyle(nsIStyleRuleProcessor* aProcessor, void *aData)
{
AttributeData* data = (AttributeData*)aData;
nsReStyleHint hint;
aProcessor->HasAttributeDependentStyle(data, data->mMedium, &hint);
aProcessor->HasAttributeDependentStyle(data, &hint);
data->mHint = nsReStyleHint(data->mHint | hint);
return PR_TRUE; // continue
}

Просмотреть файл

@ -101,7 +101,6 @@ EXPORTS = \
nsICSSStyleRule.h \
nsICSSStyleRuleDOMWrapper.h \
nsICSSImportRule.h \
nsICSSMediaRule.h \
nsICSSNameSpaceRule.h \
nsCSSStruct.h \
nsICSSOMFactory.h \

Просмотреть файл

@ -45,7 +45,7 @@
#include "nsICSSLoader.h"
#include "nsICSSStyleRule.h"
#include "nsICSSImportRule.h"
#include "nsICSSMediaRule.h"
#include "nsCSSRules.h"
#include "nsICSSNameSpaceRule.h"
#include "nsIUnicharInputStream.h"
#include "nsICSSStyleSheet.h"
@ -151,13 +151,16 @@ protected:
PRBool ParseAtRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ParseCharsetRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ParseImportRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool GatherURL(nsresult& aErrorCode, nsString& aURL);
PRBool GatherMedia(nsresult& aErrorCode, nsISupportsArray* aMediaAtoms);
PRBool ProcessImport(nsresult& aErrorCode,
const nsString& aURLSpec,
nsISupportsArray* aMedia,
RuleAppendFunc aAppendFunc,
void* aProcessData);
PRBool ParseGroupRule(nsresult& aErrorCode, nsICSSGroupRule* aRule, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ParseMediaRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ParseMozDocumentRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ParseNameSpaceRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ProcessNameSpace(nsresult& aErrorCode, const nsString& aPrefix,
const nsString& aURLSpec, RuleAppendFunc aAppendFunc,
@ -979,6 +982,12 @@ PRBool CSSParserImpl::ParseAtRule(nsresult& aErrorCode, RuleAppendFunc aAppendFu
return PR_TRUE;
}
}
if (mToken.mIdent.LowerCaseEqualsLiteral("-moz-document")) {
if (ParseMozDocumentRule(aErrorCode, aAppendFunc, aData)) {
mSection = eCSSSection_General;
return PR_TRUE;
}
}
if (mToken.mIdent.LowerCaseEqualsLiteral("font-face")) {
if (ParseFontFaceRule(aErrorCode, aAppendFunc, aData)) {
mSection = eCSSSection_General;
@ -1029,6 +1038,29 @@ PRBool CSSParserImpl::ParseCharsetRule(nsresult& aErrorCode, RuleAppendFunc aApp
return PR_TRUE;
}
PRBool CSSParserImpl::GatherURL(nsresult& aErrorCode, nsString& aURL)
{
if (!GetToken(aErrorCode, PR_TRUE)) {
return PR_FALSE;
}
if (eCSSToken_String == mToken.mType) {
aURL = mToken.mIdent;
return PR_TRUE;
}
else if (eCSSToken_Function == mToken.mType &&
mToken.mIdent.LowerCaseEqualsLiteral("url") &&
ExpectSymbol(aErrorCode, '(', PR_FALSE) &&
GetURLToken(aErrorCode, PR_TRUE) &&
(eCSSToken_String == mToken.mType ||
eCSSToken_URL == mToken.mType)) {
aURL = mToken.mIdent;
if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) {
return PR_TRUE;
}
}
return PR_FALSE;
}
PRBool CSSParserImpl::GatherMedia(nsresult& aErrorCode,
nsISupportsArray* aMediaAtoms)
{
@ -1089,10 +1121,6 @@ PRBool CSSParserImpl::GatherMedia(nsresult& aErrorCode,
// Parse a CSS2 import rule: "@import STRING | URL [medium [, mdeium]]"
PRBool CSSParserImpl::ParseImportRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aData)
{
if (!GetToken(aErrorCode, PR_TRUE)) {
REPORT_UNEXPECTED_EOF(NS_LITERAL_STRING("URI in @import rule"));
return PR_FALSE;
}
nsAutoString url;
nsCOMPtr<nsISupportsArray> media;
aErrorCode = NS_NewISupportsArray(getter_AddRefs(media));
@ -1100,38 +1128,23 @@ PRBool CSSParserImpl::ParseImportRule(nsresult& aErrorCode, RuleAppendFunc aAppe
// Out of memory
return PR_FALSE;
}
if (!GatherURL(aErrorCode, url)) {
REPORT_UNEXPECTED_TOKEN(
NS_LITERAL_STRING("Expected URI in @import rule but found"));
return PR_FALSE;
}
if (eCSSToken_String == mToken.mType) {
url = mToken.mIdent;
if (GatherMedia(aErrorCode, media)) {
if (ExpectSymbol(aErrorCode, ';', PR_TRUE)) {
ProcessImport(aErrorCode, url, media, aAppendFunc, aData);
return PR_TRUE;
}
}
if (!GatherMedia(aErrorCode, media) ||
!ExpectSymbol(aErrorCode, ';', PR_TRUE)) {
REPORT_UNEXPECTED_TOKEN(
NS_LITERAL_STRING("Unexpected token within @import:"));
// don't advance section, simply ignore invalid @import
return PR_FALSE;
}
else if ((eCSSToken_Function == mToken.mType) &&
(mToken.mIdent.LowerCaseEqualsLiteral("url"))) {
if (ExpectSymbol(aErrorCode, '(', PR_FALSE)) {
if (GetURLToken(aErrorCode, PR_TRUE)) {
if ((eCSSToken_String == mToken.mType) || (eCSSToken_URL == mToken.mType)) {
url = mToken.mIdent;
if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) {
if (GatherMedia(aErrorCode, media)) {
if (ExpectSymbol(aErrorCode, ';', PR_TRUE)) {
ProcessImport(aErrorCode, url, media, aAppendFunc, aData);
return PR_TRUE;
}
}
}
}
}
}
}
REPORT_UNEXPECTED_TOKEN(
NS_LITERAL_STRING("Unexpected token within @import:"));
// don't advance section, simply ignore invalid @import
return PR_FALSE;
ProcessImport(aErrorCode, url, media, aAppendFunc, aData);
return PR_TRUE;
}
@ -1165,8 +1178,55 @@ PRBool CSSParserImpl::ProcessImport(nsresult& aErrorCode,
return PR_TRUE;
}
// Parse the {} part of an @media or @-moz-document rule.
PRBool CSSParserImpl::ParseGroupRule(nsresult& aErrorCode,
nsICSSGroupRule* aRule,
RuleAppendFunc aAppendFunc,
void* aData)
{
// XXXbz this could use better error reporting throughout the method
if (!ExpectSymbol(aErrorCode, '{', PR_TRUE)) {
return PR_FALSE;
}
// push rule on stack, loop over children
if (!PushGroup(aRule)) {
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
return PR_FALSE;
}
nsCSSSection holdSection = mSection;
mSection = eCSSSection_General;
for (;;) {
// Get next non-whitespace token
if (! GetToken(aErrorCode, PR_TRUE)) {
REPORT_UNEXPECTED_EOF(NS_LITERAL_STRING("end of @media or @-moz-document rule"));
break;
}
if (mToken.IsSymbol('}')) { // done!
UngetToken();
break;
}
if (eCSSToken_AtKeyword == mToken.mType) {
SkipAtRule(aErrorCode); // group rules cannot contain @rules
continue;
}
UngetToken();
ParseRuleSet(aErrorCode, AppendRuleToSheet, this);
}
PopGroup();
if (!ExpectSymbol(aErrorCode, '}', PR_TRUE)) {
mSection = holdSection;
return PR_FALSE;
}
(*aAppendFunc)(aRule, aData);
return PR_TRUE;
}
// Parse a CSS2 media rule: "@media medium [, medium] { ... }"
PRBool CSSParserImpl::ParseMediaRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc,
PRBool CSSParserImpl::ParseMediaRule(nsresult& aErrorCode,
RuleAppendFunc aAppendFunc,
void* aData)
{
nsCOMPtr<nsISupportsArray> media;
@ -1176,48 +1236,13 @@ PRBool CSSParserImpl::ParseMediaRule(nsresult& aErrorCode, RuleAppendFunc aAppen
// XXXbz this could use better error reporting throughout the method
PRUint32 count;
media->Count(&count);
if (count > 0 &&
ExpectSymbol(aErrorCode, '{', PR_TRUE)) {
// push media rule on stack, loop over children
nsCOMPtr<nsICSSMediaRule> rule;
NS_NewCSSMediaRule(getter_AddRefs(rule));
if (rule) {
if (PushGroup(rule)) {
nsCSSSection holdSection = mSection;
mSection = eCSSSection_General;
for (;;) {
// Get next non-whitespace token
if (! GetToken(aErrorCode, PR_TRUE)) {
REPORT_UNEXPECTED_EOF(NS_LITERAL_STRING("end of @media rule"));
break;
}
if (mToken.IsSymbol('}')) { // done!
UngetToken();
break;
}
if (eCSSToken_AtKeyword == mToken.mType) {
SkipAtRule(aErrorCode); // @media cannot contain @rules
continue;
}
UngetToken();
ParseRuleSet(aErrorCode, AppendRuleToSheet, this);
}
PopGroup();
if (ExpectSymbol(aErrorCode, '}', PR_TRUE)) {
// Append first, so when we do SetMedia() the rule
// knows what its stylesheet is.
(*aAppendFunc)(rule, aData);
rule->SetMedia(media);
return PR_TRUE;
}
mSection = holdSection;
}
}
else { // failed to create rule, backup and skip block
UngetToken();
if (count > 0) {
nsRefPtr<nsCSSMediaRule> rule(new nsCSSMediaRule());
// Append first, so when we do SetMedia() the rule
// knows what its stylesheet is.
if (rule && ParseGroupRule(aErrorCode, rule, aAppendFunc, aData)) {
rule->SetMedia(media);
return PR_TRUE;
}
}
}
@ -1226,6 +1251,72 @@ PRBool CSSParserImpl::ParseMediaRule(nsresult& aErrorCode, RuleAppendFunc aAppen
return PR_FALSE;
}
// Parse a @-moz-document rule. This is like an @media rule, but instead
// of a medium it has a nonempty list of items where each item is either
// url(), url-prefix(), or domain().
PRBool CSSParserImpl::ParseMozDocumentRule(nsresult& aErrorCode,
RuleAppendFunc aAppendFunc,
void* aData)
{
nsCSSDocumentRule::URL *urls = nsnull;
nsCSSDocumentRule::URL **next = &urls;
do {
if (!GetToken(aErrorCode, PR_TRUE) ||
eCSSToken_Function != mToken.mType ||
!(mToken.mIdent.LowerCaseEqualsLiteral("url") ||
mToken.mIdent.LowerCaseEqualsLiteral("url-prefix") ||
mToken.mIdent.LowerCaseEqualsLiteral("domain"))) {
REPORT_UNEXPECTED_TOKEN(
NS_LITERAL_STRING("Expected url(), url-prefix(), or domain() in @-moz-document rule but found"));
delete urls;
return PR_FALSE;
}
nsCSSDocumentRule::URL *cur = *next = new nsCSSDocumentRule::URL;
if (!cur) {
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
delete urls;
return PR_FALSE;
}
next = &cur->next;
if (mToken.mIdent.LowerCaseEqualsLiteral("url")) {
cur->func = nsCSSDocumentRule::eURL;
} else if (mToken.mIdent.LowerCaseEqualsLiteral("url-prefix")) {
cur->func = nsCSSDocumentRule::eURLPrefix;
} else if (mToken.mIdent.LowerCaseEqualsLiteral("domain")) {
cur->func = nsCSSDocumentRule::eDomain;
}
if (!ExpectSymbol(aErrorCode, '(', PR_FALSE) ||
!GetURLToken(aErrorCode, PR_TRUE) ||
(eCSSToken_String != mToken.mType &&
eCSSToken_URL != mToken.mType)) {
REPORT_UNEXPECTED_TOKEN(
NS_LITERAL_STRING("Expected URI in @-moz-document rule but found"));
delete urls;
return PR_FALSE;
}
if (!ExpectSymbol(aErrorCode, ')', PR_TRUE)) {
delete urls;
return PR_FALSE;
}
// We could try to make the URL (as long as it's not domain())
// canonical and absolute with NS_NewURI and GetSpec, but I'm
// inclined to think we shouldn't.
CopyUTF16toUTF8(mToken.mIdent, cur->url);
} while (ExpectSymbol(aErrorCode, ',', PR_TRUE));
nsRefPtr<nsCSSDocumentRule> rule(new nsCSSDocumentRule());
if (!rule) {
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
delete urls;
return PR_FALSE;
}
rule->SetURLs(urls);
return ParseGroupRule(aErrorCode, rule, aAppendFunc, aData);
}
// Parse a CSS3 namespace rule: "@namespace [prefix] STRING | URL;"
PRBool CSSParserImpl::ParseNameSpaceRule(nsresult& aErrorCode,
RuleAppendFunc aAppendFunc,

Просмотреть файл

@ -60,13 +60,6 @@ nsCSSRule::~nsCSSRule(void)
NS_IMPL_ADDREF(nsCSSRule)
NS_IMPL_RELEASE(nsCSSRule)
NS_IMETHODIMP
nsCSSRule::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_NOTREACHED("nsCSSRule::QueryInterface");
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsCSSRule::GetStyleSheet(nsIStyleSheet*& aSheet) const
{

Просмотреть файл

@ -51,7 +51,13 @@ public:
nsCSSRule(const nsCSSRule& aCopy);
virtual ~nsCSSRule(void);
NS_DECL_ISUPPORTS
// for implementing nsISupports
nsrefcnt AddRef();
nsrefcnt Release();
protected:
nsAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
public:
NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const;
NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet);

Просмотреть файл

@ -67,26 +67,22 @@ public:
nsresult ClearRuleCascades();
// nsIStyleRuleProcessor
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult);
NS_IMETHOD HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult);
protected:
RuleCascadeData* GetRuleCascade(nsPresContext* aPresContext, nsIAtom* aMedium);
RuleCascadeData* GetRuleCascade(nsPresContext* aPresContext);
nsCOMArray<nsICSSStyleSheet> mSheets;
RuleCascadeData* mRuleCascades;
RuleCascadeData* mRuleCascades;
};
#endif /* nsCSSRuleProcessor_h_ */

Просмотреть файл

@ -35,8 +35,8 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCSSRules.h"
#include "nsICSSImportRule.h"
#include "nsICSSMediaRule.h"
#include "nsICSSNameSpaceRule.h"
#include "nsString.h"
@ -53,24 +53,19 @@
#include "nsIDOMCSSRule.h"
#include "nsIDOMCSSImportRule.h"
#include "nsIDOMCSSMediaRule.h"
#include "nsIDOMCSSMozDocumentRule.h"
#include "nsIDOMCSSCharsetRule.h"
#include "nsIMediaList.h"
#include "nsIDOMMediaList.h"
#include "nsIDOMCSSRuleList.h"
#include "nsIDOMStyleSheet.h"
#include "nsIDocument.h"
#include "nsPresContext.h"
#include "nsContentUtils.h"
#include "nsStyleConsts.h"
#include "nsDOMError.h"
#define DECL_STYLE_RULE_INHERIT \
NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; \
NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet); \
NS_IMETHOD SetParentRule(nsICSSGroupRule* aRule); \
NS_IMETHOD GetDOMRule(nsIDOMCSSRule** aDOMRule); \
NS_IMETHOD MapRuleInfoInto(nsRuleData* aRuleData);
#define IMPL_STYLE_RULE_INHERIT(_class, super) \
NS_IMETHODIMP _class::GetStyleSheet(nsIStyleSheet*& aSheet) const { return super::GetStyleSheet(aSheet); } \
NS_IMETHODIMP _class::SetStyleSheet(nsICSSStyleSheet* aSheet) { return super::SetStyleSheet(aSheet); } \
@ -625,61 +620,9 @@ CSSImportRuleImpl::GetStyleSheet(nsIDOMCSSStyleSheet * *aStyleSheet)
return CallQueryInterface(mChildSheet, aStyleSheet);
}
// -------------------------------------------
// nsICSSMediaRule
//
class CSSMediaRuleImpl : public nsCSSRule,
public nsICSSMediaRule,
public nsIDOMCSSMediaRule
{
public:
CSSMediaRuleImpl(void);
CSSMediaRuleImpl(const CSSMediaRuleImpl& aCopy);
virtual ~CSSMediaRuleImpl(void);
NS_DECL_ISUPPORTS_INHERITED
DECL_STYLE_RULE_INHERIT
// nsIStyleRule methods
#ifdef DEBUG
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
#endif
// nsICSSRule methods
NS_IMETHOD GetType(PRInt32& aType) const;
NS_IMETHOD Clone(nsICSSRule*& aClone) const;
// nsICSSMediaRule methods
NS_IMETHOD SetMedia(nsISupportsArray* aMedia);
NS_IMETHOD_(PRBool) UseForMedium(nsIAtom* aMedium) const;
// nsICSSGroupRule methods
NS_IMETHOD AppendStyleRule(nsICSSRule* aRule);
NS_IMETHOD StyleRuleCount(PRInt32& aCount) const;
NS_IMETHOD GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const;
NS_IMETHOD EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const;
NS_IMETHOD DeleteStyleRuleAt(PRUint32 aIndex);
NS_IMETHOD InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules);
NS_IMETHOD ReplaceStyleRule(nsICSSRule *aOld, nsICSSRule *aNew);
// nsIDOMCSSRule interface
NS_DECL_NSIDOMCSSRULE
// nsIDOMCSSMediaRule interface
NS_DECL_NSIDOMCSSMEDIARULE
protected:
nsCOMPtr<nsIMediaList> mMedia;
nsCOMPtr<nsISupportsArray> mRules;
CSSGroupRuleRuleListImpl* mRuleCollection;
};
CSSMediaRuleImpl::CSSMediaRuleImpl(void)
: nsCSSRule(),
mMedia(nsnull),
mRules(nsnull),
mRuleCollection(nsnull)
nsCSSGroupRule::nsCSSGroupRule()
: nsCSSRule()
, mRuleCollection(nsnull)
{
}
@ -700,37 +643,27 @@ CloneRuleInto(nsISupports* aRule, void* aArray)
static PRBool
SetParentRuleReference(nsISupports* aRule, void* aParentRule)
{
nsICSSRule* rule = (nsICSSRule*)aRule;
nsICSSGroupRule* parentRule = (nsICSSGroupRule*)aParentRule;
nsICSSRule* rule = NS_STATIC_CAST(nsICSSRule*, aRule);
nsCSSGroupRule* parentRule = NS_STATIC_CAST(nsCSSGroupRule*, aParentRule);
rule->SetParentRule(parentRule);
return PR_TRUE;
}
CSSMediaRuleImpl::CSSMediaRuleImpl(const CSSMediaRuleImpl& aCopy)
: nsCSSRule(aCopy),
mMedia(nsnull),
mRules(nsnull),
mRuleCollection(nsnull)
nsCSSGroupRule::nsCSSGroupRule(const nsCSSGroupRule& aCopy)
: nsCSSRule(aCopy)
, mRuleCollection(nsnull) // lazily constructed
{
if (aCopy.mMedia) {
NS_NewMediaList(aCopy.mMedia, aCopy.mSheet, getter_AddRefs(mMedia));
}
if (aCopy.mRules) {
NS_NewISupportsArray(getter_AddRefs(mRules));
if (mRules) {
aCopy.mRules->EnumerateForwards(CloneRuleInto, mRules);
mRules->EnumerateForwards(SetParentRuleReference,
NS_STATIC_CAST(nsICSSGroupRule*, this));
mRules->EnumerateForwards(SetParentRuleReference, this);
}
}
}
CSSMediaRuleImpl::~CSSMediaRuleImpl(void)
nsCSSGroupRule::~nsCSSGroupRule()
{
if (mMedia) {
mMedia->DropReference();
}
if (mRules) {
mRules->EnumerateForwards(SetParentRuleReference, nsnull);
}
@ -740,21 +673,7 @@ CSSMediaRuleImpl::~CSSMediaRuleImpl(void)
}
}
NS_IMPL_ADDREF_INHERITED(CSSMediaRuleImpl, nsCSSRule)
NS_IMPL_RELEASE_INHERITED(CSSMediaRuleImpl, nsCSSRule)
// QueryInterface implementation for CSSMediaRuleImpl
NS_INTERFACE_MAP_BEGIN(CSSMediaRuleImpl)
NS_INTERFACE_MAP_ENTRY(nsICSSMediaRule)
NS_INTERFACE_MAP_ENTRY(nsICSSRule)
NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICSSMediaRule)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSMediaRule)
NS_INTERFACE_MAP_END
IMPL_STYLE_RULE_INHERIT2(CSSMediaRuleImpl, nsCSSRule)
IMPL_STYLE_RULE_INHERIT2(nsCSSGroupRule, nsCSSRule)
static PRBool
SetStyleSheetReference(nsISupports* aRule, void* aSheet)
@ -766,11 +685,279 @@ SetStyleSheetReference(nsISupports* aRule, void* aSheet)
}
NS_IMETHODIMP
CSSMediaRuleImpl::SetStyleSheet(nsICSSStyleSheet* aSheet)
nsCSSGroupRule::SetStyleSheet(nsICSSStyleSheet* aSheet)
{
if (mRules) {
mRules->EnumerateForwards(SetStyleSheetReference, aSheet);
}
return nsCSSRule::SetStyleSheet(aSheet);
}
#ifdef DEBUG
nsresult
nsCSSGroupRule::List(FILE* out, PRInt32 aIndent) const
{
fputs(" {\n", out);
if (mRules) {
PRUint32 index = 0;
PRUint32 count;
mRules->Count(&count);
while (index < count) {
nsCOMPtr<nsICSSRule> rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(index++));
rule->List(out, aIndent + 1);
}
}
fputs("}\n", out);
return NS_OK;
}
#endif
NS_IMETHODIMP
nsCSSGroupRule::AppendStyleRule(nsICSSRule* aRule)
{
nsresult result = NS_OK;
if (!mRules) {
result = NS_NewISupportsArray(getter_AddRefs(mRules));
}
if (NS_SUCCEEDED(result) && mRules) {
mRules->AppendElement(aRule);
aRule->SetStyleSheet(mSheet);
aRule->SetParentRule(this);
if (mSheet) {
// XXXldb Shouldn't we be using |WillDirty| and |DidDirty| (and
// shouldn't |SetModified| be removed?
mSheet->SetModified(PR_TRUE);
}
}
return result;
}
NS_IMETHODIMP
nsCSSGroupRule::StyleRuleCount(PRInt32& aCount) const
{
if (mRules) {
PRUint32 count;
mRules->Count(&count);
aCount = (PRInt32)count;
}
else {
aCount = 0;
}
return NS_OK;
}
NS_IMETHODIMP
nsCSSGroupRule::GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const
{
if (mRules) {
PRInt32 count = 0;
nsresult rv = StyleRuleCount(count);
NS_ENSURE_SUCCESS(rv, rv);
if (aIndex >= count) {
aRule = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
aRule = (nsICSSRule*)mRules->ElementAt(aIndex);
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
nsCSSGroupRule::EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const
{
if (mRules) {
return ((mRules->EnumerateForwards(aFunc, aData)) ? NS_OK : NS_ENUMERATOR_FALSE);
}
return NS_OK;
}
/*
* The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt)
* should never be called unless you have first called WillDirty() on
* the parents tylesheet. After they are called, DidDirty() needs to
* be called on the sheet
*/
NS_IMETHODIMP
nsCSSGroupRule::DeleteStyleRuleAt(PRUint32 aIndex)
{
NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE);
nsCOMPtr<nsICSSRule> rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(aIndex));
if (rule) {
rule->SetStyleSheet(nsnull);
rule->SetParentRule(nsnull);
}
return mRules->DeleteElementAt(aIndex);
}
NS_IMETHODIMP
nsCSSGroupRule::InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules)
{
NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE);
aRules->EnumerateForwards(SetStyleSheetReference, mSheet);
aRules->EnumerateForwards(SetParentRuleReference, this);
// There is no xpcom-compatible version of InsertElementsAt.... :(
if (! mRules->InsertElementsAt(aRules, aIndex)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
nsCSSGroupRule::ReplaceStyleRule(nsICSSRule* aOld, nsICSSRule* aNew)
{
PRInt32 index = mRules->IndexOf(aOld);
NS_ENSURE_TRUE(index != -1, NS_ERROR_UNEXPECTED);
mRules->ReplaceElementAt(aNew, index);
aNew->SetStyleSheet(mSheet);
aNew->SetParentRule(this);
aOld->SetStyleSheet(nsnull);
aOld->SetParentRule(nsnull);
return NS_OK;
}
nsresult
nsCSSGroupRule::AppendRulesToCssText(nsAString& aCssText)
{
aCssText.AppendLiteral(" {\n");
// get all the rules
if (mRules) {
PRUint32 count;
mRules->Count(&count);
for (PRUint32 index = 0; index < count; index++) {
nsCOMPtr<nsICSSRule> rule;
mRules->GetElementAt(index, getter_AddRefs(rule));
nsCOMPtr<nsIDOMCSSRule> domRule;
rule->GetDOMRule(getter_AddRefs(domRule));
if (domRule) {
nsAutoString cssText;
domRule->GetCssText(cssText);
aCssText.Append(NS_LITERAL_STRING(" ") +
cssText +
NS_LITERAL_STRING("\n"));
}
}
}
aCssText.AppendLiteral("}");
return NS_OK;
}
nsresult
nsCSSGroupRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
{
if (mSheet) {
return CallQueryInterface(mSheet, aSheet);
}
*aSheet = nsnull;
return NS_OK;
}
nsresult
nsCSSGroupRule::GetParentRule(nsIDOMCSSRule** aParentRule)
{
if (mParentRule) {
return mParentRule->GetDOMRule(aParentRule);
}
*aParentRule = nsnull;
return NS_OK;
}
// nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods
nsresult
nsCSSGroupRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
{
if (!mRuleCollection) {
mRuleCollection = new CSSGroupRuleRuleListImpl(this);
if (!mRuleCollection) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mRuleCollection);
}
return CallQueryInterface(mRuleCollection, aRuleList);
}
nsresult
nsCSSGroupRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
{
NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
if (!mRules) {
nsresult rv = NS_NewISupportsArray(getter_AddRefs(mRules));
if (NS_FAILED(rv))
return rv;
}
PRUint32 count;
mRules->Count(&count);
if (aIndex > count)
return NS_ERROR_DOM_INDEX_SIZE_ERR;
return mSheet->InsertRuleIntoGroup(aRule, this, aIndex, _retval);
}
nsresult
nsCSSGroupRule::DeleteRule(PRUint32 aIndex)
{
NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
if (!mRules) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
PRUint32 count;
mRules->Count(&count);
if (aIndex >= count)
return NS_ERROR_DOM_INDEX_SIZE_ERR;
return mSheet->DeleteRuleFromGroup(this, aIndex);
}
// -------------------------------------------
// nsICSSMediaRule
//
nsCSSMediaRule::nsCSSMediaRule()
{
}
nsCSSMediaRule::nsCSSMediaRule(const nsCSSMediaRule& aCopy)
: nsCSSGroupRule(aCopy)
{
if (aCopy.mMedia) {
NS_NewMediaList(aCopy.mMedia, aCopy.mSheet, getter_AddRefs(mMedia));
}
}
nsCSSMediaRule::~nsCSSMediaRule()
{
if (mMedia) {
mMedia->DropReference();
}
}
NS_IMPL_ADDREF_INHERITED(nsCSSMediaRule, nsCSSRule)
NS_IMPL_RELEASE_INHERITED(nsCSSMediaRule, nsCSSRule)
// QueryInterface implementation for nsCSSMediaRule
NS_INTERFACE_MAP_BEGIN(nsCSSMediaRule)
NS_INTERFACE_MAP_ENTRY(nsICSSGroupRule)
NS_INTERFACE_MAP_ENTRY(nsICSSRule)
NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsCSSGroupRule)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSMediaRule)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsCSSMediaRule::SetStyleSheet(nsICSSStyleSheet* aSheet)
{
if (mMedia) {
nsresult rv;
nsCOMPtr<nsISupportsArray> oldMedia(do_QueryInterface(mMedia, &rv));
@ -782,12 +969,12 @@ CSSMediaRuleImpl::SetStyleSheet(nsICSSStyleSheet* aSheet)
return rv;
}
return nsCSSRule::SetStyleSheet(aSheet);
return nsCSSGroupRule::SetStyleSheet(aSheet);
}
#ifdef DEBUG
NS_IMETHODIMP
CSSMediaRuleImpl::List(FILE* out, PRInt32 aIndent) const
nsCSSMediaRule::List(FILE* out, PRInt32 aIndent) const
{
for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
@ -808,33 +995,22 @@ CSSMediaRuleImpl::List(FILE* out, PRInt32 aIndent) const
}
}
}
fputs(" {\n", out);
if (mRules) {
PRUint32 index = 0;
PRUint32 count;
mRules->Count(&count);
while (index < count) {
nsCOMPtr<nsICSSRule> rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(index++));
rule->List(out, aIndent + 1);
}
}
fputs("}\n", out);
return NS_OK;
return nsCSSGroupRule::List(out, aIndent);
}
#endif
NS_IMETHODIMP
CSSMediaRuleImpl::GetType(PRInt32& aType) const
nsCSSMediaRule::GetType(PRInt32& aType) const
{
aType = nsICSSRule::MEDIA_RULE;
return NS_OK;
}
NS_IMETHODIMP
CSSMediaRuleImpl::Clone(nsICSSRule*& aClone) const
nsCSSMediaRule::Clone(nsICSSRule*& aClone) const
{
CSSMediaRuleImpl* clone = new CSSMediaRuleImpl(*this);
nsCSSMediaRule* clone = new nsCSSMediaRule(*this);
if (clone) {
return CallQueryInterface(clone, &aClone);
}
@ -842,157 +1018,22 @@ CSSMediaRuleImpl::Clone(nsICSSRule*& aClone) const
return NS_ERROR_OUT_OF_MEMORY;
}
// nsICSSMediaRule methods
NS_IMETHODIMP
CSSMediaRuleImpl::SetMedia(nsISupportsArray* aMedia)
nsresult
nsCSSMediaRule::SetMedia(nsISupportsArray* aMedia)
{
return NS_NewMediaList(aMedia, mSheet, getter_AddRefs(mMedia));
}
NS_IMETHODIMP_(PRBool)
CSSMediaRuleImpl::UseForMedium(nsIAtom* aMedium) const
{
if (mMedia) {
PRBool matches = PR_FALSE;
mMedia->MatchesMedium(aMedium, &matches);
return matches;
}
return PR_TRUE;
}
NS_IMETHODIMP
CSSMediaRuleImpl::AppendStyleRule(nsICSSRule* aRule)
{
nsresult result = NS_OK;
if (!mRules) {
result = NS_NewISupportsArray(getter_AddRefs(mRules));
}
if (NS_SUCCEEDED(result) && mRules) {
mRules->AppendElement(aRule);
aRule->SetStyleSheet(mSheet);
aRule->SetParentRule(this);
if (mSheet) {
// XXXldb Shouldn't we be using |WillDirty| and |DidDirty| (and
// shouldn't |SetModified| be removed?
mSheet->SetModified(PR_TRUE);
}
}
return result;
}
NS_IMETHODIMP
CSSMediaRuleImpl::StyleRuleCount(PRInt32& aCount) const
{
if (mRules) {
PRUint32 count;
mRules->Count(&count);
aCount = (PRInt32)count;
}
else {
aCount = 0;
}
return NS_OK;
}
NS_IMETHODIMP
CSSMediaRuleImpl::GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const
{
if (mRules) {
PRInt32 count = 0;
nsresult rv = StyleRuleCount(count);
NS_ENSURE_SUCCESS(rv, rv);
if (aIndex >= count) {
aRule = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
aRule = (nsICSSRule*)mRules->ElementAt(aIndex);
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
CSSMediaRuleImpl::EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const
{
if (mRules) {
return ((mRules->EnumerateForwards(aFunc, aData)) ? NS_OK : NS_ENUMERATOR_FALSE);
}
return NS_OK;
}
/*
* The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt)
* should never be called unless you have first called WillDirty() on
* the parents tylesheet. After they are called, DidDirty() needs to
* be called on the sheet
*/
NS_IMETHODIMP
CSSMediaRuleImpl::DeleteStyleRuleAt(PRUint32 aIndex)
{
NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE);
nsCOMPtr<nsICSSRule> rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(aIndex));
if (rule) {
rule->SetStyleSheet(nsnull);
rule->SetParentRule(nsnull);
}
return mRules->DeleteElementAt(aIndex);
}
NS_IMETHODIMP
CSSMediaRuleImpl::InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules)
{
NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE);
aRules->EnumerateForwards(SetStyleSheetReference, mSheet);
aRules->EnumerateForwards(SetParentRuleReference,
NS_STATIC_CAST(nsICSSGroupRule*, this));
// There is no xpcom-compatible version of InsertElementsAt.... :(
if (! mRules->InsertElementsAt(aRules, aIndex)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
CSSMediaRuleImpl::ReplaceStyleRule(nsICSSRule* aOld, nsICSSRule* aNew)
{
PRInt32 index = mRules->IndexOf(aOld);
NS_ENSURE_TRUE(index != -1, NS_ERROR_UNEXPECTED);
mRules->ReplaceElementAt(aNew, index);
aNew->SetStyleSheet(mSheet);
aNew->SetParentRule(this);
aOld->SetStyleSheet(nsnull);
aOld->SetParentRule(nsnull);
return NS_OK;
}
nsresult
NS_NewCSSMediaRule(nsICSSMediaRule** aInstancePtrResult)
{
if (! aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
CSSMediaRuleImpl* it = new CSSMediaRuleImpl();
if (! it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return CallQueryInterface(it, aInstancePtrResult);
}
// nsIDOMCSSRule methods
NS_IMETHODIMP
CSSMediaRuleImpl::GetType(PRUint16* aType)
nsCSSMediaRule::GetType(PRUint16* aType)
{
*aType = nsIDOMCSSRule::MEDIA_RULE;
return NS_OK;
}
NS_IMETHODIMP
CSSMediaRuleImpl::GetCssText(nsAString& aCssText)
nsCSSMediaRule::GetCssText(nsAString& aCssText)
{
PRUint32 index;
PRUint32 count;
@ -1012,60 +1053,30 @@ CSSMediaRuleImpl::GetCssText(nsAString& aCssText)
}
}
aCssText.AppendLiteral(" {\n");
// get all the rules
if (mRules) {
mRules->Count(&count);
for (index = 0; index < count; index++) {
nsCOMPtr<nsICSSRule> rule;
mRules->GetElementAt(index, getter_AddRefs(rule));
nsCOMPtr<nsIDOMCSSRule> domRule;
rule->GetDOMRule(getter_AddRefs(domRule));
if (domRule) {
nsAutoString cssText;
domRule->GetCssText(cssText);
aCssText.Append(NS_LITERAL_STRING(" ") +
cssText +
NS_LITERAL_STRING("\n"));
}
}
}
aCssText.AppendLiteral("}");
return NS_OK;
return nsCSSGroupRule::AppendRulesToCssText(aCssText);
}
NS_IMETHODIMP
CSSMediaRuleImpl::SetCssText(const nsAString& aCssText)
nsCSSMediaRule::SetCssText(const nsAString& aCssText)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
CSSMediaRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
nsCSSMediaRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
{
if (mSheet) {
return CallQueryInterface(mSheet, aSheet);
}
*aSheet = nsnull;
return NS_OK;
return nsCSSGroupRule::GetParentStyleSheet(aSheet);
}
NS_IMETHODIMP
CSSMediaRuleImpl::GetParentRule(nsIDOMCSSRule** aParentRule)
nsCSSMediaRule::GetParentRule(nsIDOMCSSRule** aParentRule)
{
if (mParentRule) {
return mParentRule->GetDOMRule(aParentRule);
}
*aParentRule = nsnull;
return NS_OK;
return nsCSSGroupRule::GetParentRule(aParentRule);
}
// nsIDOMCSSMediaRule methods
NS_IMETHODIMP
CSSMediaRuleImpl::GetMedia(nsIDOMMediaList* *aMedia)
nsCSSMediaRule::GetMedia(nsIDOMMediaList* *aMedia)
{
NS_ENSURE_ARG_POINTER(aMedia);
if (!mMedia) {
@ -1077,54 +1088,225 @@ CSSMediaRuleImpl::GetMedia(nsIDOMMediaList* *aMedia)
}
NS_IMETHODIMP
CSSMediaRuleImpl::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
nsCSSMediaRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
{
if (!mRuleCollection) {
mRuleCollection = new CSSGroupRuleRuleListImpl(this);
if (!mRuleCollection) {
return NS_ERROR_OUT_OF_MEMORY;
return nsCSSGroupRule::GetCssRules(aRuleList);
}
NS_IMETHODIMP
nsCSSMediaRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
{
return nsCSSGroupRule::InsertRule(aRule, aIndex, _retval);
}
NS_IMETHODIMP
nsCSSMediaRule::DeleteRule(PRUint32 aIndex)
{
return nsCSSGroupRule::DeleteRule(aIndex);
}
// nsICSSGroupRule interface
NS_IMETHODIMP_(PRBool)
nsCSSMediaRule::UseForPresentation(nsPresContext* aPresContext)
{
if (mMedia) {
PRBool matches = PR_FALSE;
mMedia->MatchesMedium(aPresContext->Medium(), &matches);
return matches;
}
return PR_TRUE;
}
nsCSSDocumentRule::nsCSSDocumentRule(void)
{
}
nsCSSDocumentRule::nsCSSDocumentRule(const nsCSSDocumentRule& aCopy)
: nsCSSGroupRule(aCopy)
, mURLs(new URL(*aCopy.mURLs))
{
}
nsCSSDocumentRule::~nsCSSDocumentRule(void)
{
}
NS_IMPL_ADDREF_INHERITED(nsCSSDocumentRule, nsCSSRule)
NS_IMPL_RELEASE_INHERITED(nsCSSDocumentRule, nsCSSRule)
// QueryInterface implementation for nsCSSDocumentRule
NS_INTERFACE_MAP_BEGIN(nsCSSDocumentRule)
NS_INTERFACE_MAP_ENTRY(nsICSSGroupRule)
NS_INTERFACE_MAP_ENTRY(nsICSSRule)
NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsCSSGroupRule)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSMozDocumentRule)
NS_INTERFACE_MAP_END
#ifdef DEBUG
NS_IMETHODIMP
nsCSSDocumentRule::List(FILE* out, PRInt32 aIndent) const
{
for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
nsCAutoString str;
str.AssignLiteral("@-moz-document ");
for (URL *url = mURLs; url; url = url->next) {
switch (url->func) {
case eURL:
str.AppendLiteral("url(\"");
break;
case eURLPrefix:
str.AppendLiteral("url-prefix(\"");
break;
case eDomain:
str.AppendLiteral("domain(\"");
break;
}
NS_ADDREF(mRuleCollection);
nsCAutoString escapedURL(url->url);
escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes
str.Append(escapedURL);
str.AppendLiteral("\"), ");
}
str.Cut(str.Length() - 2, 1); // remove last ,
fputs(str.get(), out);
return CallQueryInterface(mRuleCollection, aRuleList);
return nsCSSGroupRule::List(out, aIndent);
}
#endif
NS_IMETHODIMP
nsCSSDocumentRule::GetType(PRInt32& aType) const
{
aType = nsICSSRule::DOCUMENT_RULE;
return NS_OK;
}
NS_IMETHODIMP
CSSMediaRuleImpl::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
nsCSSDocumentRule::Clone(nsICSSRule*& aClone) const
{
NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
if (!mRules) {
nsresult rv = NS_NewISupportsArray(getter_AddRefs(mRules));
if (NS_FAILED(rv))
return rv;
nsCSSDocumentRule* clone = new nsCSSDocumentRule(*this);
if (clone) {
return CallQueryInterface(clone, &aClone);
}
aClone = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
PRUint32 count;
mRules->Count(&count);
if (aIndex > count)
return NS_ERROR_DOM_INDEX_SIZE_ERR;
return mSheet->InsertRuleIntoGroup(aRule, this, aIndex, _retval);
// nsIDOMCSSRule methods
NS_IMETHODIMP
nsCSSDocumentRule::GetType(PRUint16* aType)
{
// XXX What should really happen here?
*aType = nsIDOMCSSRule::UNKNOWN_RULE;
return NS_OK;
}
NS_IMETHODIMP
CSSMediaRuleImpl::DeleteRule(PRUint32 aIndex)
nsCSSDocumentRule::GetCssText(nsAString& aCssText)
{
NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
if (!mRules) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
aCssText.AssignLiteral("@-moz-document ");
for (URL *url = mURLs; url; url = url->next) {
switch (url->func) {
case eURL:
aCssText.AppendLiteral("url(\"");
break;
case eURLPrefix:
aCssText.AppendLiteral("url-prefix(\"");
break;
case eDomain:
aCssText.AppendLiteral("domain(\"");
break;
}
nsCAutoString escapedURL(url->url);
escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes
AppendUTF8toUTF16(escapedURL, aCssText);
aCssText.AppendLiteral("\"), ");
}
PRUint32 count;
mRules->Count(&count);
if (aIndex >= count)
return NS_ERROR_DOM_INDEX_SIZE_ERR;
aCssText.Cut(aCssText.Length() - 2, 1); // remove last ,
return mSheet->DeleteRuleFromGroup(this, aIndex);
return nsCSSGroupRule::AppendRulesToCssText(aCssText);
}
NS_IMETHODIMP
nsCSSDocumentRule::SetCssText(const nsAString& aCssText)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsCSSDocumentRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
{
return nsCSSGroupRule::GetParentStyleSheet(aSheet);
}
NS_IMETHODIMP
nsCSSDocumentRule::GetParentRule(nsIDOMCSSRule** aParentRule)
{
return nsCSSGroupRule::GetParentRule(aParentRule);
}
NS_IMETHODIMP
nsCSSDocumentRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
{
return nsCSSGroupRule::GetCssRules(aRuleList);
}
NS_IMETHODIMP
nsCSSDocumentRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
{
return nsCSSGroupRule::InsertRule(aRule, aIndex, _retval);
}
NS_IMETHODIMP
nsCSSDocumentRule::DeleteRule(PRUint32 aIndex)
{
return nsCSSGroupRule::DeleteRule(aIndex);
}
// nsICSSGroupRule interface
NS_IMETHODIMP_(PRBool)
nsCSSDocumentRule::UseForPresentation(nsPresContext* aPresContext)
{
nsIURI *docURI = aPresContext->GetDocument()->GetDocumentURI();
nsCAutoString docURISpec;
if (docURI)
docURI->GetSpec(docURISpec);
for (URL *url = mURLs; url; url = url->next) {
switch (url->func) {
case eURL: {
if (docURISpec == url->url)
return PR_TRUE;
} break;
case eURLPrefix: {
if (StringBeginsWith(docURISpec, url->url))
return PR_TRUE;
} break;
case eDomain: {
nsCAutoString host;
if (docURI)
docURI->GetHost(host);
PRInt32 lenDiff = host.Length() - url->url.Length();
if (lenDiff == 0) {
if (host == url->url)
return PR_TRUE;
} else {
if (StringEndsWith(host, url->url) &&
host.CharAt(lenDiff - 1) == '.')
return PR_TRUE;
}
} break;
}
}
return PR_FALSE;
}
// -------------------------------------------
// nsICSSNameSpaceRule
//
@ -1294,6 +1476,7 @@ NS_NewCSSNameSpaceRule(nsICSSNameSpaceRule** aInstancePtrResult,
NS_IMETHODIMP
CSSNameSpaceRuleImpl::GetType(PRUint16* aType)
{
// XXX What should really happen here?
*aType = nsIDOMCSSRule::UNKNOWN_RULE;
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,199 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
// vim:cindent:ts=2:et:sw=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) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* L. David Baron <dbaron@dbaron.org>
* Boris Zbarsky <bzbarsky@mit.edu>
*
* 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 nsCSSRules_h_
#define nsCSSRules_h_
#include "nsCSSRule.h"
#include "nsICSSGroupRule.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsISupportsArray.h"
#include "nsIDOMCSSMediaRule.h"
#include "nsIDOMCSSMozDocumentRule.h"
#include "nsString.h"
class CSSGroupRuleRuleListImpl;
class nsIMediaList;
#define DECL_STYLE_RULE_INHERIT \
NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; \
NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet); \
NS_IMETHOD SetParentRule(nsICSSGroupRule* aRule); \
NS_IMETHOD GetDOMRule(nsIDOMCSSRule** aDOMRule); \
NS_IMETHOD MapRuleInfoInto(nsRuleData* aRuleData);
// inherits from nsCSSRule and also implements methods on nsICSSGroupRule
// so they can be shared between nsCSSMediaRule and nsCSSDocumentRule
class nsCSSGroupRule : public nsCSSRule, public nsICSSGroupRule
{
protected:
nsCSSGroupRule();
nsCSSGroupRule(const nsCSSGroupRule& aCopy);
~nsCSSGroupRule();
// implement part of nsIStyleRule and nsICSSRule
DECL_STYLE_RULE_INHERIT
// to help implement nsIStyleRule
#ifdef DEBUG
nsresult List(FILE* out = stdout, PRInt32 aIndent = 0) const;
#endif
public:
// implement nsICSSGroupRule
NS_IMETHOD AppendStyleRule(nsICSSRule* aRule);
NS_IMETHOD StyleRuleCount(PRInt32& aCount) const;
NS_IMETHOD GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const;
NS_IMETHOD EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const;
NS_IMETHOD DeleteStyleRuleAt(PRUint32 aIndex);
NS_IMETHOD InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules);
NS_IMETHOD ReplaceStyleRule(nsICSSRule *aOld, nsICSSRule *aNew);
protected:
// to help implement nsIDOMCSSRule
nsresult AppendRulesToCssText(nsAString& aCssText);
// to implement methods on nsIDOMCSSRule
nsresult GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet);
nsresult GetParentRule(nsIDOMCSSRule** aParentRule);
// to implement common methods on nsIDOMCSSMediaRule and
// nsIDOMCSSMozDocumentRule
nsresult GetCssRules(nsIDOMCSSRuleList* *aRuleList);
nsresult InsertRule(const nsAString & aRule, PRUint32 aIndex,
PRUint32* _retval);
nsresult DeleteRule(PRUint32 aIndex);
nsCOMPtr<nsISupportsArray> mRules;
CSSGroupRuleRuleListImpl* mRuleCollection;
};
class nsCSSMediaRule : public nsCSSGroupRule,
public nsIDOMCSSMediaRule
{
public:
nsCSSMediaRule();
nsCSSMediaRule(const nsCSSMediaRule& aCopy);
virtual ~nsCSSMediaRule();
NS_DECL_ISUPPORTS_INHERITED
// nsIStyleRule methods
#ifdef DEBUG
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
#endif
// nsICSSRule methods
NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet); //override nsCSSGroupRule
NS_IMETHOD GetType(PRInt32& aType) const;
NS_IMETHOD Clone(nsICSSRule*& aClone) const;
// nsIDOMCSSRule interface
NS_DECL_NSIDOMCSSRULE
// nsIDOMCSSMediaRule interface
NS_DECL_NSIDOMCSSMEDIARULE
// rest of nsICSSGroupRule interface
NS_IMETHOD_(PRBool) UseForPresentation(nsPresContext* aPresContext);
// @media rule methods
nsresult SetMedia(nsISupportsArray* aMedia);
protected:
nsCOMPtr<nsIMediaList> mMedia;
};
class nsCSSDocumentRule : public nsCSSGroupRule,
public nsIDOMCSSMozDocumentRule
{
public:
nsCSSDocumentRule(void);
nsCSSDocumentRule(const nsCSSDocumentRule& aCopy);
virtual ~nsCSSDocumentRule(void);
NS_DECL_ISUPPORTS_INHERITED
// nsIStyleRule methods
#ifdef DEBUG
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
#endif
// nsICSSRule methods
NS_IMETHOD GetType(PRInt32& aType) const;
NS_IMETHOD Clone(nsICSSRule*& aClone) const;
// nsIDOMCSSRule interface
NS_DECL_NSIDOMCSSRULE
// nsIDOMCSSMozDocumentRule interface
NS_DECL_NSIDOMCSSMOZDOCUMENTRULE
// rest of nsICSSGroupRule interface
NS_IMETHOD_(PRBool) UseForPresentation(nsPresContext* aPresContext);
enum Function {
eURL,
eURLPrefix,
eDomain
};
struct URL {
nsCSSDocumentRule::Function func;
nsCString url;
URL *next;
URL() : next(nsnull) {}
URL(const URL& aOther)
: func(aOther.func)
, url(aOther.url)
, next(new URL(*aOther.next))
{
}
~URL() { delete next; }
};
void SetURLs(URL *aURLs) { mURLs = aURLs; }
protected:
nsAutoPtr<URL> mURLs; // linked list of |struct URL| above.
};
#endif /* !defined(nsCSSRules_h_) */

Просмотреть файл

@ -55,7 +55,7 @@
#include "nsCSSRuleProcessor.h"
#include "nsICSSStyleRule.h"
#include "nsICSSNameSpaceRule.h"
#include "nsICSSMediaRule.h"
#include "nsICSSGroupRule.h"
#include "nsIMediaList.h"
#include "nsIStyledContent.h"
#include "nsIDocument.h"
@ -3589,13 +3589,12 @@ static void ContentEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector,
}
NS_IMETHODIMP
nsCSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData,
nsIAtom* aMedium)
nsCSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData)
{
NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT),
"content must be element");
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext);
if (cascade) {
nsIStyledContent* styledContent = aData->mStyledContent;
@ -3659,14 +3658,13 @@ static void PseudoEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector,
}
NS_IMETHODIMP
nsCSSRuleProcessor::RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium)
nsCSSRuleProcessor::RulesMatching(PseudoRuleProcessorData* aData)
{
NS_PRECONDITION(!aData->mContent ||
aData->mContent->IsContentOfType(nsIContent::eELEMENT),
"content (if present) must be element");
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext);
if (cascade) {
cascade->mRuleHash.EnumerateTagRules(aData->mPseudoTag,
@ -3708,13 +3706,12 @@ PR_STATIC_CALLBACK(PRBool) StateEnumFunc(void* aSelector, void* aData)
NS_IMETHODIMP
nsCSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult)
{
NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT),
"content must be element");
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext);
// Look up the content node in the state rule list, which points to
// any (CSS2 definition) simple selector (whether or not it is the
@ -3759,7 +3756,6 @@ PR_STATIC_CALLBACK(PRBool) AttributeEnumFunc(void* aSelector, void* aData)
NS_IMETHODIMP
nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult)
{
NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT),
@ -3779,7 +3775,7 @@ nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData
}
// XXX What about XLinks?
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext);
// We do the same thing for attributes that we do for state selectors
// (see HasStateDependentStyle), except that instead of one big list
@ -3900,14 +3896,14 @@ RuleArraysDestroy(nsHashKey *aKey, void *aData, void *aClosure)
}
struct CascadeEnumData {
CascadeEnumData(nsIAtom* aMedium, PLArenaPool& aArena)
: mMedium(aMedium),
CascadeEnumData(nsPresContext* aPresContext, PLArenaPool& aArena)
: mPresContext(aPresContext),
mRuleArrays(nsnull, nsnull, RuleArraysDestroy, nsnull, 64),
mArena(aArena)
{
}
nsIAtom* mMedium;
nsPresContext* mPresContext;
nsObjectHashtable mRuleArrays; // of nsAutoVoidArray
PLArenaPool& mArena;
};
@ -3939,11 +3935,11 @@ InsertRuleByWeight(nsISupports* aRule, void* aData)
rules->AppendElement(info);
}
}
else if (nsICSSRule::MEDIA_RULE == type) {
nsICSSMediaRule* mediaRule = (nsICSSMediaRule*)rule;
if (mediaRule->UseForMedium(data->mMedium)) {
mediaRule->EnumerateRulesForwards(InsertRuleByWeight, aData);
}
else if (nsICSSRule::MEDIA_RULE == type ||
nsICSSRule::DOCUMENT_RULE == type) {
nsICSSGroupRule* groupRule = (nsICSSGroupRule*)rule;
if (groupRule->UseForPresentation(data->mPresContext))
groupRule->EnumerateRulesForwards(InsertRuleByWeight, aData);
}
return PR_TRUE;
}
@ -3957,7 +3953,7 @@ CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData)
PRBool bSheetApplicable = PR_TRUE;
sheet->GetApplicable(bSheetApplicable);
if (bSheetApplicable && sheet->UseForMedium(data->mMedium)) {
if (bSheetApplicable && sheet->UseForMedium(data->mPresContext->Medium())) {
nsCSSStyleSheet* child = sheet->mFirstChild;
while (child) {
CascadeSheetRulesInto(child, data);
@ -4030,22 +4026,28 @@ static void PutRulesInList(nsObjectHashtable* aRuleArrays,
}
RuleCascadeData*
nsCSSRuleProcessor::GetRuleCascade(nsPresContext* aPresContext,
nsIAtom* aMedium)
nsCSSRuleProcessor::GetRuleCascade(nsPresContext* aPresContext)
{
// Having RuleCascadeData objects be per-medium works for now since
// nsCSSRuleProcessor objects are per-document. (For a given set
// of stylesheets they can vary based on medium (@media) or document
// (@-moz-document).) Things will get a little more complicated if
// we implement media queries, though.
RuleCascadeData **cascadep = &mRuleCascades;
RuleCascadeData *cascade;
nsIAtom *medium = aPresContext->Medium();
while ((cascade = *cascadep)) {
if (cascade->mMedium == aMedium)
if (cascade->mMedium == medium)
return cascade;
cascadep = &cascade->mNext;
}
if (mSheets.Count() != 0) {
cascade = new RuleCascadeData(aMedium,
cascade = new RuleCascadeData(medium,
eCompatibility_NavQuirks == aPresContext->CompatibilityMode());
if (cascade) {
CascadeEnumData data(aMedium, cascade->mRuleHash.Arena());
CascadeEnumData data(aPresContext, cascade->mRuleHash.Arena());
mSheets.EnumerateForwards(CascadeSheetRulesInto, &data);
nsVoidArray weightedRules;
PutRulesInList(&data.mRuleArrays, &weightedRules);

Просмотреть файл

@ -368,18 +368,14 @@ public:
NS_IMETHOD SetOwningDocument(nsIDocument* aDocument);
// nsIStyleRuleProcessor api
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult);
NS_IMETHOD HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult);
#ifdef DEBUG
@ -432,8 +428,7 @@ NS_IMPL_ISUPPORTS3(HTMLCSSStyleSheetImpl,
nsIStyleRuleProcessor)
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium)
HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData)
{
nsIStyledContent *styledContent = aData->mStyledContent;
@ -449,8 +444,7 @@ HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
}
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium)
HTMLCSSStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData)
{
// We only want to add these rules if there are real :first-letter or
// :first-line rules that cause a pseudo-element frame to be created.
@ -500,7 +494,6 @@ HTMLCSSStyleSheetImpl::Init(nsIURI* aURL, nsIDocument* aDocument)
// Test if style is dependent on content state
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult)
{
*aResult = nsReStyleHint(0);
@ -510,7 +503,6 @@ HTMLCSSStyleSheetImpl::HasStateDependentStyle(StateRuleProcessorData* aData,
// Test if style is dependent on attribute
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult)
{
*aResult = nsReStyleHint(0);

Просмотреть файл

@ -516,8 +516,7 @@ static nsresult GetBodyColor(nsPresContext* aPresContext, nscolor* aColor)
}
NS_IMETHODIMP
nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium)
nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData)
{
nsIStyledContent *styledContent = aData->mStyledContent;
@ -599,7 +598,6 @@ nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData,
// Test if style is dependent on content state
NS_IMETHODIMP
nsHTMLStyleSheet::HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult)
{
if (mActiveRule &&
@ -617,7 +615,6 @@ nsHTMLStyleSheet::HasStateDependentStyle(StateRuleProcessorData* aData,
NS_IMETHODIMP
nsHTMLStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult)
{
// Result is true for |href| changes on HTML links if we have link rules.
@ -646,8 +643,7 @@ nsHTMLStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
NS_IMETHODIMP
nsHTMLStyleSheet::RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium)
nsHTMLStyleSheet::RulesMatching(PseudoRuleProcessorData* aData)
{
nsIAtom* pseudoTag = aData->mPseudoTag;
if (pseudoTag == nsCSSAnonBoxes::tableCol) {

Просмотреть файл

@ -73,15 +73,11 @@ public:
#endif
// nsIStyleRuleProcessor API
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult);
NS_IMETHOD HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult);
nsresult Init(nsIURI* aURL, nsIDocument* aDocument);

Просмотреть файл

@ -41,6 +41,7 @@
#include "nsISupportsArray.h"
class nsIAtom;
class nsPresContext;
// IID for the nsICSSGroupRule interface {5af048aa-1af0-11d3-9d83-0060088f9ff7}
#define NS_ICSS_GROUP_RULE_IID \
@ -65,6 +66,8 @@ public:
NS_IMETHOD DeleteStyleRuleAt(PRUint32 aIndex) = 0;
NS_IMETHOD InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules) = 0;
NS_IMETHOD ReplaceStyleRule(nsICSSRule* aOld, nsICSSRule* aNew) = 0;
NS_IMETHOD_(PRBool) UseForPresentation(nsPresContext* aPresContext) = 0;
};

Просмотреть файл

@ -60,7 +60,8 @@ public:
FONT_FACE_RULE = 4,
PAGE_RULE = 5,
CHARSET_RULE = 6,
NAMESPACE_RULE = 7
NAMESPACE_RULE = 7,
DOCUMENT_RULE = 8
};
NS_IMETHOD GetType(PRInt32& aType) const = 0;

Просмотреть файл

@ -62,6 +62,7 @@ XPIDLSRCS = \
nsIDOMCSSFontFaceRule.idl \
nsIDOMCSSImportRule.idl \
nsIDOMCSSMediaRule.idl \
nsIDOMCSSMozDocumentRule.idl \
nsIDOMCSSPageRule.idl \
nsIDOMCSSStyleRule.idl \
nsIDOMCSSUnknownRule.idl \

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -12,18 +12,18 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
* The Original Code is nsIDOMCSSMozDocumentRule.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* L. David Baron <dbaron@dbaron.org> (original author)
*
* 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"),
* either 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
@ -34,27 +34,22 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsICSSMediaRule_h___
#define nsICSSMediaRule_h___
#include "nsICSSGroupRule.h"
//#include "nsString.h"
#include "nsIDOMCSSRule.idl"
class nsIAtom;
/**
* Modified version of nsIDOMCSSMediaRule for @-moz-document rules.
*/
[scriptable, uuid(4eb9adac-afaf-4b8a-8640-7340863c1587)]
interface nsIDOMCSSMozDocumentRule : nsIDOMCSSRule
{
readonly attribute nsIDOMCSSRuleList cssRules;
// IID for the nsICSSMediaRule interface {2c1d0110-1a09-11d3-805a-006008159b5a}
#define NS_ICSS_MEDIA_RULE_IID \
{0x2c1d0110, 0x1a09, 0x11d3, {0x80, 0x5a, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
unsigned long insertRule(in DOMString rule,
in unsigned long index)
raises(DOMException);
void deleteRule(in unsigned long index)
raises(DOMException);
class nsICSSMediaRule : public nsICSSGroupRule {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICSS_MEDIA_RULE_IID)
NS_IMETHOD SetMedia(nsISupportsArray* aMedia) = 0;
NS_IMETHOD_(PRBool) UseForMedium(nsIAtom* aMedium) const = 0;
// XXX Add access to the URL list.
};
nsresult
NS_NewCSSMediaRule(nsICSSMediaRule** aInstancePtrResult);
#endif /* nsICSSMediaRule_h___ */

Просмотреть файл

@ -194,7 +194,8 @@ enum nsDOMClassInfoID {
// We are now trying to preserve binary compat in classinfo. No
// more putting things in those categories up there. New entries
// are to be added right before eDOMClassInfoIDCount
// are to be added right before eDOMClassInfoIDCount (or, for now,
// before the MOZ_SVG ifdefs, since they're off by default).
// Rect object used by getComputedStyle
eDOMClassInfo_CSSRect_id,
@ -234,6 +235,8 @@ enum nsDOMClassInfoID {
eDOMClassInfo_TreeColumns_id,
#endif
eDOMClassInfo_CSSMozDocumentRule_id,
#ifdef MOZ_SVG
// The SVG document
eDOMClassInfo_SVGDocument_id,

Просмотреть файл

@ -274,6 +274,7 @@
#include "nsIDOMCSSCharsetRule.h"
#include "nsIDOMCSSImportRule.h"
#include "nsIDOMCSSMediaRule.h"
#include "nsIDOMCSSMozDocumentRule.h"
#include "nsIDOMCSSPrimitiveValue.h"
#include "nsIDOMCSSStyleRule.h"
#include "nsIDOMCSSStyleSheet.h"
@ -789,6 +790,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
ARRAY_SCRIPTABLE_FLAGS)
#endif
NS_DEFINE_CLASSINFO_DATA(CSSMozDocumentRule, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
#ifdef MOZ_SVG
// SVG document
NS_DEFINE_CLASSINFO_DATA(SVGDocument, nsDocumentSH,
@ -2137,6 +2141,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_END
#endif
DOM_CLASSINFO_MAP_BEGIN(CSSMozDocumentRule, nsIDOMCSSMozDocumentRule)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSMozDocumentRule)
DOM_CLASSINFO_MAP_END
#ifdef MOZ_SVG
#define DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGElement) \

Просмотреть файл

@ -45,7 +45,7 @@
#include "nsICSSLoader.h"
#include "nsICSSStyleRule.h"
#include "nsICSSImportRule.h"
#include "nsICSSMediaRule.h"
#include "nsCSSRules.h"
#include "nsICSSNameSpaceRule.h"
#include "nsIUnicharInputStream.h"
#include "nsICSSStyleSheet.h"
@ -151,13 +151,16 @@ protected:
PRBool ParseAtRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ParseCharsetRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ParseImportRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool GatherURL(nsresult& aErrorCode, nsString& aURL);
PRBool GatherMedia(nsresult& aErrorCode, nsISupportsArray* aMediaAtoms);
PRBool ProcessImport(nsresult& aErrorCode,
const nsString& aURLSpec,
nsISupportsArray* aMedia,
RuleAppendFunc aAppendFunc,
void* aProcessData);
PRBool ParseGroupRule(nsresult& aErrorCode, nsICSSGroupRule* aRule, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ParseMediaRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ParseMozDocumentRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ParseNameSpaceRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ProcessNameSpace(nsresult& aErrorCode, const nsString& aPrefix,
const nsString& aURLSpec, RuleAppendFunc aAppendFunc,
@ -979,6 +982,12 @@ PRBool CSSParserImpl::ParseAtRule(nsresult& aErrorCode, RuleAppendFunc aAppendFu
return PR_TRUE;
}
}
if (mToken.mIdent.LowerCaseEqualsLiteral("-moz-document")) {
if (ParseMozDocumentRule(aErrorCode, aAppendFunc, aData)) {
mSection = eCSSSection_General;
return PR_TRUE;
}
}
if (mToken.mIdent.LowerCaseEqualsLiteral("font-face")) {
if (ParseFontFaceRule(aErrorCode, aAppendFunc, aData)) {
mSection = eCSSSection_General;
@ -1029,6 +1038,29 @@ PRBool CSSParserImpl::ParseCharsetRule(nsresult& aErrorCode, RuleAppendFunc aApp
return PR_TRUE;
}
PRBool CSSParserImpl::GatherURL(nsresult& aErrorCode, nsString& aURL)
{
if (!GetToken(aErrorCode, PR_TRUE)) {
return PR_FALSE;
}
if (eCSSToken_String == mToken.mType) {
aURL = mToken.mIdent;
return PR_TRUE;
}
else if (eCSSToken_Function == mToken.mType &&
mToken.mIdent.LowerCaseEqualsLiteral("url") &&
ExpectSymbol(aErrorCode, '(', PR_FALSE) &&
GetURLToken(aErrorCode, PR_TRUE) &&
(eCSSToken_String == mToken.mType ||
eCSSToken_URL == mToken.mType)) {
aURL = mToken.mIdent;
if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) {
return PR_TRUE;
}
}
return PR_FALSE;
}
PRBool CSSParserImpl::GatherMedia(nsresult& aErrorCode,
nsISupportsArray* aMediaAtoms)
{
@ -1089,10 +1121,6 @@ PRBool CSSParserImpl::GatherMedia(nsresult& aErrorCode,
// Parse a CSS2 import rule: "@import STRING | URL [medium [, mdeium]]"
PRBool CSSParserImpl::ParseImportRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aData)
{
if (!GetToken(aErrorCode, PR_TRUE)) {
REPORT_UNEXPECTED_EOF(NS_LITERAL_STRING("URI in @import rule"));
return PR_FALSE;
}
nsAutoString url;
nsCOMPtr<nsISupportsArray> media;
aErrorCode = NS_NewISupportsArray(getter_AddRefs(media));
@ -1100,38 +1128,23 @@ PRBool CSSParserImpl::ParseImportRule(nsresult& aErrorCode, RuleAppendFunc aAppe
// Out of memory
return PR_FALSE;
}
if (!GatherURL(aErrorCode, url)) {
REPORT_UNEXPECTED_TOKEN(
NS_LITERAL_STRING("Expected URI in @import rule but found"));
return PR_FALSE;
}
if (eCSSToken_String == mToken.mType) {
url = mToken.mIdent;
if (GatherMedia(aErrorCode, media)) {
if (ExpectSymbol(aErrorCode, ';', PR_TRUE)) {
ProcessImport(aErrorCode, url, media, aAppendFunc, aData);
return PR_TRUE;
}
}
if (!GatherMedia(aErrorCode, media) ||
!ExpectSymbol(aErrorCode, ';', PR_TRUE)) {
REPORT_UNEXPECTED_TOKEN(
NS_LITERAL_STRING("Unexpected token within @import:"));
// don't advance section, simply ignore invalid @import
return PR_FALSE;
}
else if ((eCSSToken_Function == mToken.mType) &&
(mToken.mIdent.LowerCaseEqualsLiteral("url"))) {
if (ExpectSymbol(aErrorCode, '(', PR_FALSE)) {
if (GetURLToken(aErrorCode, PR_TRUE)) {
if ((eCSSToken_String == mToken.mType) || (eCSSToken_URL == mToken.mType)) {
url = mToken.mIdent;
if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) {
if (GatherMedia(aErrorCode, media)) {
if (ExpectSymbol(aErrorCode, ';', PR_TRUE)) {
ProcessImport(aErrorCode, url, media, aAppendFunc, aData);
return PR_TRUE;
}
}
}
}
}
}
}
REPORT_UNEXPECTED_TOKEN(
NS_LITERAL_STRING("Unexpected token within @import:"));
// don't advance section, simply ignore invalid @import
return PR_FALSE;
ProcessImport(aErrorCode, url, media, aAppendFunc, aData);
return PR_TRUE;
}
@ -1165,8 +1178,55 @@ PRBool CSSParserImpl::ProcessImport(nsresult& aErrorCode,
return PR_TRUE;
}
// Parse the {} part of an @media or @-moz-document rule.
PRBool CSSParserImpl::ParseGroupRule(nsresult& aErrorCode,
nsICSSGroupRule* aRule,
RuleAppendFunc aAppendFunc,
void* aData)
{
// XXXbz this could use better error reporting throughout the method
if (!ExpectSymbol(aErrorCode, '{', PR_TRUE)) {
return PR_FALSE;
}
// push rule on stack, loop over children
if (!PushGroup(aRule)) {
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
return PR_FALSE;
}
nsCSSSection holdSection = mSection;
mSection = eCSSSection_General;
for (;;) {
// Get next non-whitespace token
if (! GetToken(aErrorCode, PR_TRUE)) {
REPORT_UNEXPECTED_EOF(NS_LITERAL_STRING("end of @media or @-moz-document rule"));
break;
}
if (mToken.IsSymbol('}')) { // done!
UngetToken();
break;
}
if (eCSSToken_AtKeyword == mToken.mType) {
SkipAtRule(aErrorCode); // group rules cannot contain @rules
continue;
}
UngetToken();
ParseRuleSet(aErrorCode, AppendRuleToSheet, this);
}
PopGroup();
if (!ExpectSymbol(aErrorCode, '}', PR_TRUE)) {
mSection = holdSection;
return PR_FALSE;
}
(*aAppendFunc)(aRule, aData);
return PR_TRUE;
}
// Parse a CSS2 media rule: "@media medium [, medium] { ... }"
PRBool CSSParserImpl::ParseMediaRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc,
PRBool CSSParserImpl::ParseMediaRule(nsresult& aErrorCode,
RuleAppendFunc aAppendFunc,
void* aData)
{
nsCOMPtr<nsISupportsArray> media;
@ -1176,48 +1236,13 @@ PRBool CSSParserImpl::ParseMediaRule(nsresult& aErrorCode, RuleAppendFunc aAppen
// XXXbz this could use better error reporting throughout the method
PRUint32 count;
media->Count(&count);
if (count > 0 &&
ExpectSymbol(aErrorCode, '{', PR_TRUE)) {
// push media rule on stack, loop over children
nsCOMPtr<nsICSSMediaRule> rule;
NS_NewCSSMediaRule(getter_AddRefs(rule));
if (rule) {
if (PushGroup(rule)) {
nsCSSSection holdSection = mSection;
mSection = eCSSSection_General;
for (;;) {
// Get next non-whitespace token
if (! GetToken(aErrorCode, PR_TRUE)) {
REPORT_UNEXPECTED_EOF(NS_LITERAL_STRING("end of @media rule"));
break;
}
if (mToken.IsSymbol('}')) { // done!
UngetToken();
break;
}
if (eCSSToken_AtKeyword == mToken.mType) {
SkipAtRule(aErrorCode); // @media cannot contain @rules
continue;
}
UngetToken();
ParseRuleSet(aErrorCode, AppendRuleToSheet, this);
}
PopGroup();
if (ExpectSymbol(aErrorCode, '}', PR_TRUE)) {
// Append first, so when we do SetMedia() the rule
// knows what its stylesheet is.
(*aAppendFunc)(rule, aData);
rule->SetMedia(media);
return PR_TRUE;
}
mSection = holdSection;
}
}
else { // failed to create rule, backup and skip block
UngetToken();
if (count > 0) {
nsRefPtr<nsCSSMediaRule> rule(new nsCSSMediaRule());
// Append first, so when we do SetMedia() the rule
// knows what its stylesheet is.
if (rule && ParseGroupRule(aErrorCode, rule, aAppendFunc, aData)) {
rule->SetMedia(media);
return PR_TRUE;
}
}
}
@ -1226,6 +1251,72 @@ PRBool CSSParserImpl::ParseMediaRule(nsresult& aErrorCode, RuleAppendFunc aAppen
return PR_FALSE;
}
// Parse a @-moz-document rule. This is like an @media rule, but instead
// of a medium it has a nonempty list of items where each item is either
// url(), url-prefix(), or domain().
PRBool CSSParserImpl::ParseMozDocumentRule(nsresult& aErrorCode,
RuleAppendFunc aAppendFunc,
void* aData)
{
nsCSSDocumentRule::URL *urls = nsnull;
nsCSSDocumentRule::URL **next = &urls;
do {
if (!GetToken(aErrorCode, PR_TRUE) ||
eCSSToken_Function != mToken.mType ||
!(mToken.mIdent.LowerCaseEqualsLiteral("url") ||
mToken.mIdent.LowerCaseEqualsLiteral("url-prefix") ||
mToken.mIdent.LowerCaseEqualsLiteral("domain"))) {
REPORT_UNEXPECTED_TOKEN(
NS_LITERAL_STRING("Expected url(), url-prefix(), or domain() in @-moz-document rule but found"));
delete urls;
return PR_FALSE;
}
nsCSSDocumentRule::URL *cur = *next = new nsCSSDocumentRule::URL;
if (!cur) {
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
delete urls;
return PR_FALSE;
}
next = &cur->next;
if (mToken.mIdent.LowerCaseEqualsLiteral("url")) {
cur->func = nsCSSDocumentRule::eURL;
} else if (mToken.mIdent.LowerCaseEqualsLiteral("url-prefix")) {
cur->func = nsCSSDocumentRule::eURLPrefix;
} else if (mToken.mIdent.LowerCaseEqualsLiteral("domain")) {
cur->func = nsCSSDocumentRule::eDomain;
}
if (!ExpectSymbol(aErrorCode, '(', PR_FALSE) ||
!GetURLToken(aErrorCode, PR_TRUE) ||
(eCSSToken_String != mToken.mType &&
eCSSToken_URL != mToken.mType)) {
REPORT_UNEXPECTED_TOKEN(
NS_LITERAL_STRING("Expected URI in @-moz-document rule but found"));
delete urls;
return PR_FALSE;
}
if (!ExpectSymbol(aErrorCode, ')', PR_TRUE)) {
delete urls;
return PR_FALSE;
}
// We could try to make the URL (as long as it's not domain())
// canonical and absolute with NS_NewURI and GetSpec, but I'm
// inclined to think we shouldn't.
CopyUTF16toUTF8(mToken.mIdent, cur->url);
} while (ExpectSymbol(aErrorCode, ',', PR_TRUE));
nsRefPtr<nsCSSDocumentRule> rule(new nsCSSDocumentRule());
if (!rule) {
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
delete urls;
return PR_FALSE;
}
rule->SetURLs(urls);
return ParseGroupRule(aErrorCode, rule, aAppendFunc, aData);
}
// Parse a CSS3 namespace rule: "@namespace [prefix] STRING | URL;"
PRBool CSSParserImpl::ParseNameSpaceRule(nsresult& aErrorCode,
RuleAppendFunc aAppendFunc,

Просмотреть файл

@ -60,13 +60,6 @@ nsCSSRule::~nsCSSRule(void)
NS_IMPL_ADDREF(nsCSSRule)
NS_IMPL_RELEASE(nsCSSRule)
NS_IMETHODIMP
nsCSSRule::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_NOTREACHED("nsCSSRule::QueryInterface");
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsCSSRule::GetStyleSheet(nsIStyleSheet*& aSheet) const
{

Просмотреть файл

@ -51,7 +51,13 @@ public:
nsCSSRule(const nsCSSRule& aCopy);
virtual ~nsCSSRule(void);
NS_DECL_ISUPPORTS
// for implementing nsISupports
nsrefcnt AddRef();
nsrefcnt Release();
protected:
nsAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
public:
NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const;
NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet);

Просмотреть файл

@ -67,26 +67,22 @@ public:
nsresult ClearRuleCascades();
// nsIStyleRuleProcessor
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult);
NS_IMETHOD HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult);
protected:
RuleCascadeData* GetRuleCascade(nsPresContext* aPresContext, nsIAtom* aMedium);
RuleCascadeData* GetRuleCascade(nsPresContext* aPresContext);
nsCOMArray<nsICSSStyleSheet> mSheets;
RuleCascadeData* mRuleCascades;
RuleCascadeData* mRuleCascades;
};
#endif /* nsCSSRuleProcessor_h_ */

Просмотреть файл

@ -35,8 +35,8 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCSSRules.h"
#include "nsICSSImportRule.h"
#include "nsICSSMediaRule.h"
#include "nsICSSNameSpaceRule.h"
#include "nsString.h"
@ -53,24 +53,19 @@
#include "nsIDOMCSSRule.h"
#include "nsIDOMCSSImportRule.h"
#include "nsIDOMCSSMediaRule.h"
#include "nsIDOMCSSMozDocumentRule.h"
#include "nsIDOMCSSCharsetRule.h"
#include "nsIMediaList.h"
#include "nsIDOMMediaList.h"
#include "nsIDOMCSSRuleList.h"
#include "nsIDOMStyleSheet.h"
#include "nsIDocument.h"
#include "nsPresContext.h"
#include "nsContentUtils.h"
#include "nsStyleConsts.h"
#include "nsDOMError.h"
#define DECL_STYLE_RULE_INHERIT \
NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; \
NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet); \
NS_IMETHOD SetParentRule(nsICSSGroupRule* aRule); \
NS_IMETHOD GetDOMRule(nsIDOMCSSRule** aDOMRule); \
NS_IMETHOD MapRuleInfoInto(nsRuleData* aRuleData);
#define IMPL_STYLE_RULE_INHERIT(_class, super) \
NS_IMETHODIMP _class::GetStyleSheet(nsIStyleSheet*& aSheet) const { return super::GetStyleSheet(aSheet); } \
NS_IMETHODIMP _class::SetStyleSheet(nsICSSStyleSheet* aSheet) { return super::SetStyleSheet(aSheet); } \
@ -625,61 +620,9 @@ CSSImportRuleImpl::GetStyleSheet(nsIDOMCSSStyleSheet * *aStyleSheet)
return CallQueryInterface(mChildSheet, aStyleSheet);
}
// -------------------------------------------
// nsICSSMediaRule
//
class CSSMediaRuleImpl : public nsCSSRule,
public nsICSSMediaRule,
public nsIDOMCSSMediaRule
{
public:
CSSMediaRuleImpl(void);
CSSMediaRuleImpl(const CSSMediaRuleImpl& aCopy);
virtual ~CSSMediaRuleImpl(void);
NS_DECL_ISUPPORTS_INHERITED
DECL_STYLE_RULE_INHERIT
// nsIStyleRule methods
#ifdef DEBUG
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
#endif
// nsICSSRule methods
NS_IMETHOD GetType(PRInt32& aType) const;
NS_IMETHOD Clone(nsICSSRule*& aClone) const;
// nsICSSMediaRule methods
NS_IMETHOD SetMedia(nsISupportsArray* aMedia);
NS_IMETHOD_(PRBool) UseForMedium(nsIAtom* aMedium) const;
// nsICSSGroupRule methods
NS_IMETHOD AppendStyleRule(nsICSSRule* aRule);
NS_IMETHOD StyleRuleCount(PRInt32& aCount) const;
NS_IMETHOD GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const;
NS_IMETHOD EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const;
NS_IMETHOD DeleteStyleRuleAt(PRUint32 aIndex);
NS_IMETHOD InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules);
NS_IMETHOD ReplaceStyleRule(nsICSSRule *aOld, nsICSSRule *aNew);
// nsIDOMCSSRule interface
NS_DECL_NSIDOMCSSRULE
// nsIDOMCSSMediaRule interface
NS_DECL_NSIDOMCSSMEDIARULE
protected:
nsCOMPtr<nsIMediaList> mMedia;
nsCOMPtr<nsISupportsArray> mRules;
CSSGroupRuleRuleListImpl* mRuleCollection;
};
CSSMediaRuleImpl::CSSMediaRuleImpl(void)
: nsCSSRule(),
mMedia(nsnull),
mRules(nsnull),
mRuleCollection(nsnull)
nsCSSGroupRule::nsCSSGroupRule()
: nsCSSRule()
, mRuleCollection(nsnull)
{
}
@ -700,37 +643,27 @@ CloneRuleInto(nsISupports* aRule, void* aArray)
static PRBool
SetParentRuleReference(nsISupports* aRule, void* aParentRule)
{
nsICSSRule* rule = (nsICSSRule*)aRule;
nsICSSGroupRule* parentRule = (nsICSSGroupRule*)aParentRule;
nsICSSRule* rule = NS_STATIC_CAST(nsICSSRule*, aRule);
nsCSSGroupRule* parentRule = NS_STATIC_CAST(nsCSSGroupRule*, aParentRule);
rule->SetParentRule(parentRule);
return PR_TRUE;
}
CSSMediaRuleImpl::CSSMediaRuleImpl(const CSSMediaRuleImpl& aCopy)
: nsCSSRule(aCopy),
mMedia(nsnull),
mRules(nsnull),
mRuleCollection(nsnull)
nsCSSGroupRule::nsCSSGroupRule(const nsCSSGroupRule& aCopy)
: nsCSSRule(aCopy)
, mRuleCollection(nsnull) // lazily constructed
{
if (aCopy.mMedia) {
NS_NewMediaList(aCopy.mMedia, aCopy.mSheet, getter_AddRefs(mMedia));
}
if (aCopy.mRules) {
NS_NewISupportsArray(getter_AddRefs(mRules));
if (mRules) {
aCopy.mRules->EnumerateForwards(CloneRuleInto, mRules);
mRules->EnumerateForwards(SetParentRuleReference,
NS_STATIC_CAST(nsICSSGroupRule*, this));
mRules->EnumerateForwards(SetParentRuleReference, this);
}
}
}
CSSMediaRuleImpl::~CSSMediaRuleImpl(void)
nsCSSGroupRule::~nsCSSGroupRule()
{
if (mMedia) {
mMedia->DropReference();
}
if (mRules) {
mRules->EnumerateForwards(SetParentRuleReference, nsnull);
}
@ -740,21 +673,7 @@ CSSMediaRuleImpl::~CSSMediaRuleImpl(void)
}
}
NS_IMPL_ADDREF_INHERITED(CSSMediaRuleImpl, nsCSSRule)
NS_IMPL_RELEASE_INHERITED(CSSMediaRuleImpl, nsCSSRule)
// QueryInterface implementation for CSSMediaRuleImpl
NS_INTERFACE_MAP_BEGIN(CSSMediaRuleImpl)
NS_INTERFACE_MAP_ENTRY(nsICSSMediaRule)
NS_INTERFACE_MAP_ENTRY(nsICSSRule)
NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICSSMediaRule)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSMediaRule)
NS_INTERFACE_MAP_END
IMPL_STYLE_RULE_INHERIT2(CSSMediaRuleImpl, nsCSSRule)
IMPL_STYLE_RULE_INHERIT2(nsCSSGroupRule, nsCSSRule)
static PRBool
SetStyleSheetReference(nsISupports* aRule, void* aSheet)
@ -766,11 +685,279 @@ SetStyleSheetReference(nsISupports* aRule, void* aSheet)
}
NS_IMETHODIMP
CSSMediaRuleImpl::SetStyleSheet(nsICSSStyleSheet* aSheet)
nsCSSGroupRule::SetStyleSheet(nsICSSStyleSheet* aSheet)
{
if (mRules) {
mRules->EnumerateForwards(SetStyleSheetReference, aSheet);
}
return nsCSSRule::SetStyleSheet(aSheet);
}
#ifdef DEBUG
nsresult
nsCSSGroupRule::List(FILE* out, PRInt32 aIndent) const
{
fputs(" {\n", out);
if (mRules) {
PRUint32 index = 0;
PRUint32 count;
mRules->Count(&count);
while (index < count) {
nsCOMPtr<nsICSSRule> rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(index++));
rule->List(out, aIndent + 1);
}
}
fputs("}\n", out);
return NS_OK;
}
#endif
NS_IMETHODIMP
nsCSSGroupRule::AppendStyleRule(nsICSSRule* aRule)
{
nsresult result = NS_OK;
if (!mRules) {
result = NS_NewISupportsArray(getter_AddRefs(mRules));
}
if (NS_SUCCEEDED(result) && mRules) {
mRules->AppendElement(aRule);
aRule->SetStyleSheet(mSheet);
aRule->SetParentRule(this);
if (mSheet) {
// XXXldb Shouldn't we be using |WillDirty| and |DidDirty| (and
// shouldn't |SetModified| be removed?
mSheet->SetModified(PR_TRUE);
}
}
return result;
}
NS_IMETHODIMP
nsCSSGroupRule::StyleRuleCount(PRInt32& aCount) const
{
if (mRules) {
PRUint32 count;
mRules->Count(&count);
aCount = (PRInt32)count;
}
else {
aCount = 0;
}
return NS_OK;
}
NS_IMETHODIMP
nsCSSGroupRule::GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const
{
if (mRules) {
PRInt32 count = 0;
nsresult rv = StyleRuleCount(count);
NS_ENSURE_SUCCESS(rv, rv);
if (aIndex >= count) {
aRule = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
aRule = (nsICSSRule*)mRules->ElementAt(aIndex);
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
nsCSSGroupRule::EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const
{
if (mRules) {
return ((mRules->EnumerateForwards(aFunc, aData)) ? NS_OK : NS_ENUMERATOR_FALSE);
}
return NS_OK;
}
/*
* The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt)
* should never be called unless you have first called WillDirty() on
* the parents tylesheet. After they are called, DidDirty() needs to
* be called on the sheet
*/
NS_IMETHODIMP
nsCSSGroupRule::DeleteStyleRuleAt(PRUint32 aIndex)
{
NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE);
nsCOMPtr<nsICSSRule> rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(aIndex));
if (rule) {
rule->SetStyleSheet(nsnull);
rule->SetParentRule(nsnull);
}
return mRules->DeleteElementAt(aIndex);
}
NS_IMETHODIMP
nsCSSGroupRule::InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules)
{
NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE);
aRules->EnumerateForwards(SetStyleSheetReference, mSheet);
aRules->EnumerateForwards(SetParentRuleReference, this);
// There is no xpcom-compatible version of InsertElementsAt.... :(
if (! mRules->InsertElementsAt(aRules, aIndex)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
nsCSSGroupRule::ReplaceStyleRule(nsICSSRule* aOld, nsICSSRule* aNew)
{
PRInt32 index = mRules->IndexOf(aOld);
NS_ENSURE_TRUE(index != -1, NS_ERROR_UNEXPECTED);
mRules->ReplaceElementAt(aNew, index);
aNew->SetStyleSheet(mSheet);
aNew->SetParentRule(this);
aOld->SetStyleSheet(nsnull);
aOld->SetParentRule(nsnull);
return NS_OK;
}
nsresult
nsCSSGroupRule::AppendRulesToCssText(nsAString& aCssText)
{
aCssText.AppendLiteral(" {\n");
// get all the rules
if (mRules) {
PRUint32 count;
mRules->Count(&count);
for (PRUint32 index = 0; index < count; index++) {
nsCOMPtr<nsICSSRule> rule;
mRules->GetElementAt(index, getter_AddRefs(rule));
nsCOMPtr<nsIDOMCSSRule> domRule;
rule->GetDOMRule(getter_AddRefs(domRule));
if (domRule) {
nsAutoString cssText;
domRule->GetCssText(cssText);
aCssText.Append(NS_LITERAL_STRING(" ") +
cssText +
NS_LITERAL_STRING("\n"));
}
}
}
aCssText.AppendLiteral("}");
return NS_OK;
}
nsresult
nsCSSGroupRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
{
if (mSheet) {
return CallQueryInterface(mSheet, aSheet);
}
*aSheet = nsnull;
return NS_OK;
}
nsresult
nsCSSGroupRule::GetParentRule(nsIDOMCSSRule** aParentRule)
{
if (mParentRule) {
return mParentRule->GetDOMRule(aParentRule);
}
*aParentRule = nsnull;
return NS_OK;
}
// nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods
nsresult
nsCSSGroupRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
{
if (!mRuleCollection) {
mRuleCollection = new CSSGroupRuleRuleListImpl(this);
if (!mRuleCollection) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mRuleCollection);
}
return CallQueryInterface(mRuleCollection, aRuleList);
}
nsresult
nsCSSGroupRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
{
NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
if (!mRules) {
nsresult rv = NS_NewISupportsArray(getter_AddRefs(mRules));
if (NS_FAILED(rv))
return rv;
}
PRUint32 count;
mRules->Count(&count);
if (aIndex > count)
return NS_ERROR_DOM_INDEX_SIZE_ERR;
return mSheet->InsertRuleIntoGroup(aRule, this, aIndex, _retval);
}
nsresult
nsCSSGroupRule::DeleteRule(PRUint32 aIndex)
{
NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
if (!mRules) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
PRUint32 count;
mRules->Count(&count);
if (aIndex >= count)
return NS_ERROR_DOM_INDEX_SIZE_ERR;
return mSheet->DeleteRuleFromGroup(this, aIndex);
}
// -------------------------------------------
// nsICSSMediaRule
//
nsCSSMediaRule::nsCSSMediaRule()
{
}
nsCSSMediaRule::nsCSSMediaRule(const nsCSSMediaRule& aCopy)
: nsCSSGroupRule(aCopy)
{
if (aCopy.mMedia) {
NS_NewMediaList(aCopy.mMedia, aCopy.mSheet, getter_AddRefs(mMedia));
}
}
nsCSSMediaRule::~nsCSSMediaRule()
{
if (mMedia) {
mMedia->DropReference();
}
}
NS_IMPL_ADDREF_INHERITED(nsCSSMediaRule, nsCSSRule)
NS_IMPL_RELEASE_INHERITED(nsCSSMediaRule, nsCSSRule)
// QueryInterface implementation for nsCSSMediaRule
NS_INTERFACE_MAP_BEGIN(nsCSSMediaRule)
NS_INTERFACE_MAP_ENTRY(nsICSSGroupRule)
NS_INTERFACE_MAP_ENTRY(nsICSSRule)
NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsCSSGroupRule)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSMediaRule)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsCSSMediaRule::SetStyleSheet(nsICSSStyleSheet* aSheet)
{
if (mMedia) {
nsresult rv;
nsCOMPtr<nsISupportsArray> oldMedia(do_QueryInterface(mMedia, &rv));
@ -782,12 +969,12 @@ CSSMediaRuleImpl::SetStyleSheet(nsICSSStyleSheet* aSheet)
return rv;
}
return nsCSSRule::SetStyleSheet(aSheet);
return nsCSSGroupRule::SetStyleSheet(aSheet);
}
#ifdef DEBUG
NS_IMETHODIMP
CSSMediaRuleImpl::List(FILE* out, PRInt32 aIndent) const
nsCSSMediaRule::List(FILE* out, PRInt32 aIndent) const
{
for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
@ -808,33 +995,22 @@ CSSMediaRuleImpl::List(FILE* out, PRInt32 aIndent) const
}
}
}
fputs(" {\n", out);
if (mRules) {
PRUint32 index = 0;
PRUint32 count;
mRules->Count(&count);
while (index < count) {
nsCOMPtr<nsICSSRule> rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(index++));
rule->List(out, aIndent + 1);
}
}
fputs("}\n", out);
return NS_OK;
return nsCSSGroupRule::List(out, aIndent);
}
#endif
NS_IMETHODIMP
CSSMediaRuleImpl::GetType(PRInt32& aType) const
nsCSSMediaRule::GetType(PRInt32& aType) const
{
aType = nsICSSRule::MEDIA_RULE;
return NS_OK;
}
NS_IMETHODIMP
CSSMediaRuleImpl::Clone(nsICSSRule*& aClone) const
nsCSSMediaRule::Clone(nsICSSRule*& aClone) const
{
CSSMediaRuleImpl* clone = new CSSMediaRuleImpl(*this);
nsCSSMediaRule* clone = new nsCSSMediaRule(*this);
if (clone) {
return CallQueryInterface(clone, &aClone);
}
@ -842,157 +1018,22 @@ CSSMediaRuleImpl::Clone(nsICSSRule*& aClone) const
return NS_ERROR_OUT_OF_MEMORY;
}
// nsICSSMediaRule methods
NS_IMETHODIMP
CSSMediaRuleImpl::SetMedia(nsISupportsArray* aMedia)
nsresult
nsCSSMediaRule::SetMedia(nsISupportsArray* aMedia)
{
return NS_NewMediaList(aMedia, mSheet, getter_AddRefs(mMedia));
}
NS_IMETHODIMP_(PRBool)
CSSMediaRuleImpl::UseForMedium(nsIAtom* aMedium) const
{
if (mMedia) {
PRBool matches = PR_FALSE;
mMedia->MatchesMedium(aMedium, &matches);
return matches;
}
return PR_TRUE;
}
NS_IMETHODIMP
CSSMediaRuleImpl::AppendStyleRule(nsICSSRule* aRule)
{
nsresult result = NS_OK;
if (!mRules) {
result = NS_NewISupportsArray(getter_AddRefs(mRules));
}
if (NS_SUCCEEDED(result) && mRules) {
mRules->AppendElement(aRule);
aRule->SetStyleSheet(mSheet);
aRule->SetParentRule(this);
if (mSheet) {
// XXXldb Shouldn't we be using |WillDirty| and |DidDirty| (and
// shouldn't |SetModified| be removed?
mSheet->SetModified(PR_TRUE);
}
}
return result;
}
NS_IMETHODIMP
CSSMediaRuleImpl::StyleRuleCount(PRInt32& aCount) const
{
if (mRules) {
PRUint32 count;
mRules->Count(&count);
aCount = (PRInt32)count;
}
else {
aCount = 0;
}
return NS_OK;
}
NS_IMETHODIMP
CSSMediaRuleImpl::GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const
{
if (mRules) {
PRInt32 count = 0;
nsresult rv = StyleRuleCount(count);
NS_ENSURE_SUCCESS(rv, rv);
if (aIndex >= count) {
aRule = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
aRule = (nsICSSRule*)mRules->ElementAt(aIndex);
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
CSSMediaRuleImpl::EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const
{
if (mRules) {
return ((mRules->EnumerateForwards(aFunc, aData)) ? NS_OK : NS_ENUMERATOR_FALSE);
}
return NS_OK;
}
/*
* The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt)
* should never be called unless you have first called WillDirty() on
* the parents tylesheet. After they are called, DidDirty() needs to
* be called on the sheet
*/
NS_IMETHODIMP
CSSMediaRuleImpl::DeleteStyleRuleAt(PRUint32 aIndex)
{
NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE);
nsCOMPtr<nsICSSRule> rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(aIndex));
if (rule) {
rule->SetStyleSheet(nsnull);
rule->SetParentRule(nsnull);
}
return mRules->DeleteElementAt(aIndex);
}
NS_IMETHODIMP
CSSMediaRuleImpl::InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules)
{
NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE);
aRules->EnumerateForwards(SetStyleSheetReference, mSheet);
aRules->EnumerateForwards(SetParentRuleReference,
NS_STATIC_CAST(nsICSSGroupRule*, this));
// There is no xpcom-compatible version of InsertElementsAt.... :(
if (! mRules->InsertElementsAt(aRules, aIndex)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
CSSMediaRuleImpl::ReplaceStyleRule(nsICSSRule* aOld, nsICSSRule* aNew)
{
PRInt32 index = mRules->IndexOf(aOld);
NS_ENSURE_TRUE(index != -1, NS_ERROR_UNEXPECTED);
mRules->ReplaceElementAt(aNew, index);
aNew->SetStyleSheet(mSheet);
aNew->SetParentRule(this);
aOld->SetStyleSheet(nsnull);
aOld->SetParentRule(nsnull);
return NS_OK;
}
nsresult
NS_NewCSSMediaRule(nsICSSMediaRule** aInstancePtrResult)
{
if (! aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
CSSMediaRuleImpl* it = new CSSMediaRuleImpl();
if (! it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return CallQueryInterface(it, aInstancePtrResult);
}
// nsIDOMCSSRule methods
NS_IMETHODIMP
CSSMediaRuleImpl::GetType(PRUint16* aType)
nsCSSMediaRule::GetType(PRUint16* aType)
{
*aType = nsIDOMCSSRule::MEDIA_RULE;
return NS_OK;
}
NS_IMETHODIMP
CSSMediaRuleImpl::GetCssText(nsAString& aCssText)
nsCSSMediaRule::GetCssText(nsAString& aCssText)
{
PRUint32 index;
PRUint32 count;
@ -1012,60 +1053,30 @@ CSSMediaRuleImpl::GetCssText(nsAString& aCssText)
}
}
aCssText.AppendLiteral(" {\n");
// get all the rules
if (mRules) {
mRules->Count(&count);
for (index = 0; index < count; index++) {
nsCOMPtr<nsICSSRule> rule;
mRules->GetElementAt(index, getter_AddRefs(rule));
nsCOMPtr<nsIDOMCSSRule> domRule;
rule->GetDOMRule(getter_AddRefs(domRule));
if (domRule) {
nsAutoString cssText;
domRule->GetCssText(cssText);
aCssText.Append(NS_LITERAL_STRING(" ") +
cssText +
NS_LITERAL_STRING("\n"));
}
}
}
aCssText.AppendLiteral("}");
return NS_OK;
return nsCSSGroupRule::AppendRulesToCssText(aCssText);
}
NS_IMETHODIMP
CSSMediaRuleImpl::SetCssText(const nsAString& aCssText)
nsCSSMediaRule::SetCssText(const nsAString& aCssText)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
CSSMediaRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
nsCSSMediaRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
{
if (mSheet) {
return CallQueryInterface(mSheet, aSheet);
}
*aSheet = nsnull;
return NS_OK;
return nsCSSGroupRule::GetParentStyleSheet(aSheet);
}
NS_IMETHODIMP
CSSMediaRuleImpl::GetParentRule(nsIDOMCSSRule** aParentRule)
nsCSSMediaRule::GetParentRule(nsIDOMCSSRule** aParentRule)
{
if (mParentRule) {
return mParentRule->GetDOMRule(aParentRule);
}
*aParentRule = nsnull;
return NS_OK;
return nsCSSGroupRule::GetParentRule(aParentRule);
}
// nsIDOMCSSMediaRule methods
NS_IMETHODIMP
CSSMediaRuleImpl::GetMedia(nsIDOMMediaList* *aMedia)
nsCSSMediaRule::GetMedia(nsIDOMMediaList* *aMedia)
{
NS_ENSURE_ARG_POINTER(aMedia);
if (!mMedia) {
@ -1077,54 +1088,225 @@ CSSMediaRuleImpl::GetMedia(nsIDOMMediaList* *aMedia)
}
NS_IMETHODIMP
CSSMediaRuleImpl::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
nsCSSMediaRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
{
if (!mRuleCollection) {
mRuleCollection = new CSSGroupRuleRuleListImpl(this);
if (!mRuleCollection) {
return NS_ERROR_OUT_OF_MEMORY;
return nsCSSGroupRule::GetCssRules(aRuleList);
}
NS_IMETHODIMP
nsCSSMediaRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
{
return nsCSSGroupRule::InsertRule(aRule, aIndex, _retval);
}
NS_IMETHODIMP
nsCSSMediaRule::DeleteRule(PRUint32 aIndex)
{
return nsCSSGroupRule::DeleteRule(aIndex);
}
// nsICSSGroupRule interface
NS_IMETHODIMP_(PRBool)
nsCSSMediaRule::UseForPresentation(nsPresContext* aPresContext)
{
if (mMedia) {
PRBool matches = PR_FALSE;
mMedia->MatchesMedium(aPresContext->Medium(), &matches);
return matches;
}
return PR_TRUE;
}
nsCSSDocumentRule::nsCSSDocumentRule(void)
{
}
nsCSSDocumentRule::nsCSSDocumentRule(const nsCSSDocumentRule& aCopy)
: nsCSSGroupRule(aCopy)
, mURLs(new URL(*aCopy.mURLs))
{
}
nsCSSDocumentRule::~nsCSSDocumentRule(void)
{
}
NS_IMPL_ADDREF_INHERITED(nsCSSDocumentRule, nsCSSRule)
NS_IMPL_RELEASE_INHERITED(nsCSSDocumentRule, nsCSSRule)
// QueryInterface implementation for nsCSSDocumentRule
NS_INTERFACE_MAP_BEGIN(nsCSSDocumentRule)
NS_INTERFACE_MAP_ENTRY(nsICSSGroupRule)
NS_INTERFACE_MAP_ENTRY(nsICSSRule)
NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsCSSGroupRule)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSMozDocumentRule)
NS_INTERFACE_MAP_END
#ifdef DEBUG
NS_IMETHODIMP
nsCSSDocumentRule::List(FILE* out, PRInt32 aIndent) const
{
for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
nsCAutoString str;
str.AssignLiteral("@-moz-document ");
for (URL *url = mURLs; url; url = url->next) {
switch (url->func) {
case eURL:
str.AppendLiteral("url(\"");
break;
case eURLPrefix:
str.AppendLiteral("url-prefix(\"");
break;
case eDomain:
str.AppendLiteral("domain(\"");
break;
}
NS_ADDREF(mRuleCollection);
nsCAutoString escapedURL(url->url);
escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes
str.Append(escapedURL);
str.AppendLiteral("\"), ");
}
str.Cut(str.Length() - 2, 1); // remove last ,
fputs(str.get(), out);
return CallQueryInterface(mRuleCollection, aRuleList);
return nsCSSGroupRule::List(out, aIndent);
}
#endif
NS_IMETHODIMP
nsCSSDocumentRule::GetType(PRInt32& aType) const
{
aType = nsICSSRule::DOCUMENT_RULE;
return NS_OK;
}
NS_IMETHODIMP
CSSMediaRuleImpl::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
nsCSSDocumentRule::Clone(nsICSSRule*& aClone) const
{
NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
if (!mRules) {
nsresult rv = NS_NewISupportsArray(getter_AddRefs(mRules));
if (NS_FAILED(rv))
return rv;
nsCSSDocumentRule* clone = new nsCSSDocumentRule(*this);
if (clone) {
return CallQueryInterface(clone, &aClone);
}
aClone = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
PRUint32 count;
mRules->Count(&count);
if (aIndex > count)
return NS_ERROR_DOM_INDEX_SIZE_ERR;
return mSheet->InsertRuleIntoGroup(aRule, this, aIndex, _retval);
// nsIDOMCSSRule methods
NS_IMETHODIMP
nsCSSDocumentRule::GetType(PRUint16* aType)
{
// XXX What should really happen here?
*aType = nsIDOMCSSRule::UNKNOWN_RULE;
return NS_OK;
}
NS_IMETHODIMP
CSSMediaRuleImpl::DeleteRule(PRUint32 aIndex)
nsCSSDocumentRule::GetCssText(nsAString& aCssText)
{
NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
if (!mRules) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
aCssText.AssignLiteral("@-moz-document ");
for (URL *url = mURLs; url; url = url->next) {
switch (url->func) {
case eURL:
aCssText.AppendLiteral("url(\"");
break;
case eURLPrefix:
aCssText.AppendLiteral("url-prefix(\"");
break;
case eDomain:
aCssText.AppendLiteral("domain(\"");
break;
}
nsCAutoString escapedURL(url->url);
escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes
AppendUTF8toUTF16(escapedURL, aCssText);
aCssText.AppendLiteral("\"), ");
}
PRUint32 count;
mRules->Count(&count);
if (aIndex >= count)
return NS_ERROR_DOM_INDEX_SIZE_ERR;
aCssText.Cut(aCssText.Length() - 2, 1); // remove last ,
return mSheet->DeleteRuleFromGroup(this, aIndex);
return nsCSSGroupRule::AppendRulesToCssText(aCssText);
}
NS_IMETHODIMP
nsCSSDocumentRule::SetCssText(const nsAString& aCssText)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsCSSDocumentRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
{
return nsCSSGroupRule::GetParentStyleSheet(aSheet);
}
NS_IMETHODIMP
nsCSSDocumentRule::GetParentRule(nsIDOMCSSRule** aParentRule)
{
return nsCSSGroupRule::GetParentRule(aParentRule);
}
NS_IMETHODIMP
nsCSSDocumentRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
{
return nsCSSGroupRule::GetCssRules(aRuleList);
}
NS_IMETHODIMP
nsCSSDocumentRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
{
return nsCSSGroupRule::InsertRule(aRule, aIndex, _retval);
}
NS_IMETHODIMP
nsCSSDocumentRule::DeleteRule(PRUint32 aIndex)
{
return nsCSSGroupRule::DeleteRule(aIndex);
}
// nsICSSGroupRule interface
NS_IMETHODIMP_(PRBool)
nsCSSDocumentRule::UseForPresentation(nsPresContext* aPresContext)
{
nsIURI *docURI = aPresContext->GetDocument()->GetDocumentURI();
nsCAutoString docURISpec;
if (docURI)
docURI->GetSpec(docURISpec);
for (URL *url = mURLs; url; url = url->next) {
switch (url->func) {
case eURL: {
if (docURISpec == url->url)
return PR_TRUE;
} break;
case eURLPrefix: {
if (StringBeginsWith(docURISpec, url->url))
return PR_TRUE;
} break;
case eDomain: {
nsCAutoString host;
if (docURI)
docURI->GetHost(host);
PRInt32 lenDiff = host.Length() - url->url.Length();
if (lenDiff == 0) {
if (host == url->url)
return PR_TRUE;
} else {
if (StringEndsWith(host, url->url) &&
host.CharAt(lenDiff - 1) == '.')
return PR_TRUE;
}
} break;
}
}
return PR_FALSE;
}
// -------------------------------------------
// nsICSSNameSpaceRule
//
@ -1294,6 +1476,7 @@ NS_NewCSSNameSpaceRule(nsICSSNameSpaceRule** aInstancePtrResult,
NS_IMETHODIMP
CSSNameSpaceRuleImpl::GetType(PRUint16* aType)
{
// XXX What should really happen here?
*aType = nsIDOMCSSRule::UNKNOWN_RULE;
return NS_OK;
}

199
layout/style/nsCSSRules.h Normal file
Просмотреть файл

@ -0,0 +1,199 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
// vim:cindent:ts=2:et:sw=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) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* L. David Baron <dbaron@dbaron.org>
* Boris Zbarsky <bzbarsky@mit.edu>
*
* 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 nsCSSRules_h_
#define nsCSSRules_h_
#include "nsCSSRule.h"
#include "nsICSSGroupRule.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsISupportsArray.h"
#include "nsIDOMCSSMediaRule.h"
#include "nsIDOMCSSMozDocumentRule.h"
#include "nsString.h"
class CSSGroupRuleRuleListImpl;
class nsIMediaList;
#define DECL_STYLE_RULE_INHERIT \
NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; \
NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet); \
NS_IMETHOD SetParentRule(nsICSSGroupRule* aRule); \
NS_IMETHOD GetDOMRule(nsIDOMCSSRule** aDOMRule); \
NS_IMETHOD MapRuleInfoInto(nsRuleData* aRuleData);
// inherits from nsCSSRule and also implements methods on nsICSSGroupRule
// so they can be shared between nsCSSMediaRule and nsCSSDocumentRule
class nsCSSGroupRule : public nsCSSRule, public nsICSSGroupRule
{
protected:
nsCSSGroupRule();
nsCSSGroupRule(const nsCSSGroupRule& aCopy);
~nsCSSGroupRule();
// implement part of nsIStyleRule and nsICSSRule
DECL_STYLE_RULE_INHERIT
// to help implement nsIStyleRule
#ifdef DEBUG
nsresult List(FILE* out = stdout, PRInt32 aIndent = 0) const;
#endif
public:
// implement nsICSSGroupRule
NS_IMETHOD AppendStyleRule(nsICSSRule* aRule);
NS_IMETHOD StyleRuleCount(PRInt32& aCount) const;
NS_IMETHOD GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const;
NS_IMETHOD EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const;
NS_IMETHOD DeleteStyleRuleAt(PRUint32 aIndex);
NS_IMETHOD InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules);
NS_IMETHOD ReplaceStyleRule(nsICSSRule *aOld, nsICSSRule *aNew);
protected:
// to help implement nsIDOMCSSRule
nsresult AppendRulesToCssText(nsAString& aCssText);
// to implement methods on nsIDOMCSSRule
nsresult GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet);
nsresult GetParentRule(nsIDOMCSSRule** aParentRule);
// to implement common methods on nsIDOMCSSMediaRule and
// nsIDOMCSSMozDocumentRule
nsresult GetCssRules(nsIDOMCSSRuleList* *aRuleList);
nsresult InsertRule(const nsAString & aRule, PRUint32 aIndex,
PRUint32* _retval);
nsresult DeleteRule(PRUint32 aIndex);
nsCOMPtr<nsISupportsArray> mRules;
CSSGroupRuleRuleListImpl* mRuleCollection;
};
class nsCSSMediaRule : public nsCSSGroupRule,
public nsIDOMCSSMediaRule
{
public:
nsCSSMediaRule();
nsCSSMediaRule(const nsCSSMediaRule& aCopy);
virtual ~nsCSSMediaRule();
NS_DECL_ISUPPORTS_INHERITED
// nsIStyleRule methods
#ifdef DEBUG
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
#endif
// nsICSSRule methods
NS_IMETHOD SetStyleSheet(nsICSSStyleSheet* aSheet); //override nsCSSGroupRule
NS_IMETHOD GetType(PRInt32& aType) const;
NS_IMETHOD Clone(nsICSSRule*& aClone) const;
// nsIDOMCSSRule interface
NS_DECL_NSIDOMCSSRULE
// nsIDOMCSSMediaRule interface
NS_DECL_NSIDOMCSSMEDIARULE
// rest of nsICSSGroupRule interface
NS_IMETHOD_(PRBool) UseForPresentation(nsPresContext* aPresContext);
// @media rule methods
nsresult SetMedia(nsISupportsArray* aMedia);
protected:
nsCOMPtr<nsIMediaList> mMedia;
};
class nsCSSDocumentRule : public nsCSSGroupRule,
public nsIDOMCSSMozDocumentRule
{
public:
nsCSSDocumentRule(void);
nsCSSDocumentRule(const nsCSSDocumentRule& aCopy);
virtual ~nsCSSDocumentRule(void);
NS_DECL_ISUPPORTS_INHERITED
// nsIStyleRule methods
#ifdef DEBUG
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
#endif
// nsICSSRule methods
NS_IMETHOD GetType(PRInt32& aType) const;
NS_IMETHOD Clone(nsICSSRule*& aClone) const;
// nsIDOMCSSRule interface
NS_DECL_NSIDOMCSSRULE
// nsIDOMCSSMozDocumentRule interface
NS_DECL_NSIDOMCSSMOZDOCUMENTRULE
// rest of nsICSSGroupRule interface
NS_IMETHOD_(PRBool) UseForPresentation(nsPresContext* aPresContext);
enum Function {
eURL,
eURLPrefix,
eDomain
};
struct URL {
nsCSSDocumentRule::Function func;
nsCString url;
URL *next;
URL() : next(nsnull) {}
URL(const URL& aOther)
: func(aOther.func)
, url(aOther.url)
, next(new URL(*aOther.next))
{
}
~URL() { delete next; }
};
void SetURLs(URL *aURLs) { mURLs = aURLs; }
protected:
nsAutoPtr<URL> mURLs; // linked list of |struct URL| above.
};
#endif /* !defined(nsCSSRules_h_) */

Просмотреть файл

@ -55,7 +55,7 @@
#include "nsCSSRuleProcessor.h"
#include "nsICSSStyleRule.h"
#include "nsICSSNameSpaceRule.h"
#include "nsICSSMediaRule.h"
#include "nsICSSGroupRule.h"
#include "nsIMediaList.h"
#include "nsIStyledContent.h"
#include "nsIDocument.h"
@ -3589,13 +3589,12 @@ static void ContentEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector,
}
NS_IMETHODIMP
nsCSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData,
nsIAtom* aMedium)
nsCSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData)
{
NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT),
"content must be element");
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext);
if (cascade) {
nsIStyledContent* styledContent = aData->mStyledContent;
@ -3659,14 +3658,13 @@ static void PseudoEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector,
}
NS_IMETHODIMP
nsCSSRuleProcessor::RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium)
nsCSSRuleProcessor::RulesMatching(PseudoRuleProcessorData* aData)
{
NS_PRECONDITION(!aData->mContent ||
aData->mContent->IsContentOfType(nsIContent::eELEMENT),
"content (if present) must be element");
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext);
if (cascade) {
cascade->mRuleHash.EnumerateTagRules(aData->mPseudoTag,
@ -3708,13 +3706,12 @@ PR_STATIC_CALLBACK(PRBool) StateEnumFunc(void* aSelector, void* aData)
NS_IMETHODIMP
nsCSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult)
{
NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT),
"content must be element");
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext);
// Look up the content node in the state rule list, which points to
// any (CSS2 definition) simple selector (whether or not it is the
@ -3759,7 +3756,6 @@ PR_STATIC_CALLBACK(PRBool) AttributeEnumFunc(void* aSelector, void* aData)
NS_IMETHODIMP
nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult)
{
NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT),
@ -3779,7 +3775,7 @@ nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData
}
// XXX What about XLinks?
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext);
// We do the same thing for attributes that we do for state selectors
// (see HasStateDependentStyle), except that instead of one big list
@ -3900,14 +3896,14 @@ RuleArraysDestroy(nsHashKey *aKey, void *aData, void *aClosure)
}
struct CascadeEnumData {
CascadeEnumData(nsIAtom* aMedium, PLArenaPool& aArena)
: mMedium(aMedium),
CascadeEnumData(nsPresContext* aPresContext, PLArenaPool& aArena)
: mPresContext(aPresContext),
mRuleArrays(nsnull, nsnull, RuleArraysDestroy, nsnull, 64),
mArena(aArena)
{
}
nsIAtom* mMedium;
nsPresContext* mPresContext;
nsObjectHashtable mRuleArrays; // of nsAutoVoidArray
PLArenaPool& mArena;
};
@ -3939,11 +3935,11 @@ InsertRuleByWeight(nsISupports* aRule, void* aData)
rules->AppendElement(info);
}
}
else if (nsICSSRule::MEDIA_RULE == type) {
nsICSSMediaRule* mediaRule = (nsICSSMediaRule*)rule;
if (mediaRule->UseForMedium(data->mMedium)) {
mediaRule->EnumerateRulesForwards(InsertRuleByWeight, aData);
}
else if (nsICSSRule::MEDIA_RULE == type ||
nsICSSRule::DOCUMENT_RULE == type) {
nsICSSGroupRule* groupRule = (nsICSSGroupRule*)rule;
if (groupRule->UseForPresentation(data->mPresContext))
groupRule->EnumerateRulesForwards(InsertRuleByWeight, aData);
}
return PR_TRUE;
}
@ -3957,7 +3953,7 @@ CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData)
PRBool bSheetApplicable = PR_TRUE;
sheet->GetApplicable(bSheetApplicable);
if (bSheetApplicable && sheet->UseForMedium(data->mMedium)) {
if (bSheetApplicable && sheet->UseForMedium(data->mPresContext->Medium())) {
nsCSSStyleSheet* child = sheet->mFirstChild;
while (child) {
CascadeSheetRulesInto(child, data);
@ -4030,22 +4026,28 @@ static void PutRulesInList(nsObjectHashtable* aRuleArrays,
}
RuleCascadeData*
nsCSSRuleProcessor::GetRuleCascade(nsPresContext* aPresContext,
nsIAtom* aMedium)
nsCSSRuleProcessor::GetRuleCascade(nsPresContext* aPresContext)
{
// Having RuleCascadeData objects be per-medium works for now since
// nsCSSRuleProcessor objects are per-document. (For a given set
// of stylesheets they can vary based on medium (@media) or document
// (@-moz-document).) Things will get a little more complicated if
// we implement media queries, though.
RuleCascadeData **cascadep = &mRuleCascades;
RuleCascadeData *cascade;
nsIAtom *medium = aPresContext->Medium();
while ((cascade = *cascadep)) {
if (cascade->mMedium == aMedium)
if (cascade->mMedium == medium)
return cascade;
cascadep = &cascade->mNext;
}
if (mSheets.Count() != 0) {
cascade = new RuleCascadeData(aMedium,
cascade = new RuleCascadeData(medium,
eCompatibility_NavQuirks == aPresContext->CompatibilityMode());
if (cascade) {
CascadeEnumData data(aMedium, cascade->mRuleHash.Arena());
CascadeEnumData data(aPresContext, cascade->mRuleHash.Arena());
mSheets.EnumerateForwards(CascadeSheetRulesInto, &data);
nsVoidArray weightedRules;
PutRulesInList(&data.mRuleArrays, &weightedRules);

Просмотреть файл

@ -368,18 +368,14 @@ public:
NS_IMETHOD SetOwningDocument(nsIDocument* aDocument);
// nsIStyleRuleProcessor api
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult);
NS_IMETHOD HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult);
#ifdef DEBUG
@ -432,8 +428,7 @@ NS_IMPL_ISUPPORTS3(HTMLCSSStyleSheetImpl,
nsIStyleRuleProcessor)
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium)
HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData)
{
nsIStyledContent *styledContent = aData->mStyledContent;
@ -449,8 +444,7 @@ HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
}
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium)
HTMLCSSStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData)
{
// We only want to add these rules if there are real :first-letter or
// :first-line rules that cause a pseudo-element frame to be created.
@ -500,7 +494,6 @@ HTMLCSSStyleSheetImpl::Init(nsIURI* aURL, nsIDocument* aDocument)
// Test if style is dependent on content state
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult)
{
*aResult = nsReStyleHint(0);
@ -510,7 +503,6 @@ HTMLCSSStyleSheetImpl::HasStateDependentStyle(StateRuleProcessorData* aData,
// Test if style is dependent on attribute
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult)
{
*aResult = nsReStyleHint(0);

Просмотреть файл

@ -516,8 +516,7 @@ static nsresult GetBodyColor(nsPresContext* aPresContext, nscolor* aColor)
}
NS_IMETHODIMP
nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium)
nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData)
{
nsIStyledContent *styledContent = aData->mStyledContent;
@ -599,7 +598,6 @@ nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData,
// Test if style is dependent on content state
NS_IMETHODIMP
nsHTMLStyleSheet::HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult)
{
if (mActiveRule &&
@ -617,7 +615,6 @@ nsHTMLStyleSheet::HasStateDependentStyle(StateRuleProcessorData* aData,
NS_IMETHODIMP
nsHTMLStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult)
{
// Result is true for |href| changes on HTML links if we have link rules.
@ -646,8 +643,7 @@ nsHTMLStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
NS_IMETHODIMP
nsHTMLStyleSheet::RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium)
nsHTMLStyleSheet::RulesMatching(PseudoRuleProcessorData* aData)
{
nsIAtom* pseudoTag = aData->mPseudoTag;
if (pseudoTag == nsCSSAnonBoxes::tableCol) {

Просмотреть файл

@ -73,15 +73,11 @@ public:
#endif
// nsIStyleRuleProcessor API
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult);
NS_IMETHOD HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult);
nsresult Init(nsIURI* aURL, nsIDocument* aDocument);

Просмотреть файл

@ -41,6 +41,7 @@
#include "nsISupportsArray.h"
class nsIAtom;
class nsPresContext;
// IID for the nsICSSGroupRule interface {5af048aa-1af0-11d3-9d83-0060088f9ff7}
#define NS_ICSS_GROUP_RULE_IID \
@ -65,6 +66,8 @@ public:
NS_IMETHOD DeleteStyleRuleAt(PRUint32 aIndex) = 0;
NS_IMETHOD InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules) = 0;
NS_IMETHOD ReplaceStyleRule(nsICSSRule* aOld, nsICSSRule* aNew) = 0;
NS_IMETHOD_(PRBool) UseForPresentation(nsPresContext* aPresContext) = 0;
};

Просмотреть файл

@ -60,7 +60,8 @@ public:
FONT_FACE_RULE = 4,
PAGE_RULE = 5,
CHARSET_RULE = 6,
NAMESPACE_RULE = 7
NAMESPACE_RULE = 7,
DOCUMENT_RULE = 8
};
NS_IMETHOD GetType(PRInt32& aType) const = 0;

Просмотреть файл

@ -179,11 +179,9 @@ public:
// populate rule node tree with nsIStyleRule*
// rules are ordered, those with higher precedence are farthest from the root of the tree
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium) = 0;
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData) = 0;
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium) = 0;
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData) = 0;
/**
* Test whether style is dependent on content state. This test is
@ -193,7 +191,6 @@ public:
* Event states are defined in nsIEventStateManager.h.
*/
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult) = 0;
/**
@ -202,7 +199,6 @@ public:
* the side of reporting more dependencies than really exist.
*/
NS_IMETHOD HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
nsIAtom* aMedium,
nsReStyleHint* aResult) = 0;
};

Просмотреть файл

@ -329,23 +329,13 @@ nsStyleSet::EnableQuirkStyleSheet(PRBool aEnable)
}
}
struct RulesMatchingData : public ElementRuleProcessorData {
RulesMatchingData(nsPresContext* aPresContext,
nsIContent* aContent,
nsRuleWalker* aRuleWalker)
: ElementRuleProcessorData(aPresContext, aContent, aRuleWalker),
mMedium(aPresContext->Medium())
{
}
nsIAtom* mMedium;
};
static PRBool
EnumRulesMatching(nsIStyleRuleProcessor* aProcessor, void* aData)
{
RulesMatchingData* data = (RulesMatchingData*)aData;
ElementRuleProcessorData* data =
NS_STATIC_CAST(ElementRuleProcessorData*, aData);
aProcessor->RulesMatching(data, data->mMedium);
aProcessor->RulesMatching(data);
return PR_TRUE;
}
@ -588,7 +578,7 @@ nsStyleSet::ResolveStyleFor(nsIContent* aContent,
mRuleProcessors[eDocSheet] ||
mRuleProcessors[eStyleAttrSheet] ||
mRuleProcessors[eOverrideSheet]) {
RulesMatchingData data(presContext, aContent, mRuleWalker);
ElementRuleProcessorData data(presContext, aContent, mRuleWalker);
FileRules(EnumRulesMatching, &data);
result = GetContext(presContext, aParentContext, nsnull).get();
@ -624,26 +614,13 @@ nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext)
}
struct PseudoRulesMatchingData : public PseudoRuleProcessorData {
PseudoRulesMatchingData(nsPresContext* aPresContext,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker)
: PseudoRuleProcessorData(aPresContext, aParentContent, aPseudoTag,
aComparator, aRuleWalker),
mMedium(aPresContext->Medium())
{
}
nsIAtom* mMedium;
};
static PRBool
EnumPseudoRulesMatching(nsIStyleRuleProcessor* aProcessor, void* aData)
{
PseudoRulesMatchingData* data = (PseudoRulesMatchingData*)aData;
PseudoRuleProcessorData* data =
NS_STATIC_CAST(PseudoRuleProcessorData*, aData);
aProcessor->RulesMatching(data, data->mMedium);
aProcessor->RulesMatching(data);
return PR_TRUE;
}
@ -669,7 +646,7 @@ nsStyleSet::ResolvePseudoStyleFor(nsIContent* aParentContent,
mRuleProcessors[eDocSheet] ||
mRuleProcessors[eStyleAttrSheet] ||
mRuleProcessors[eOverrideSheet]) {
PseudoRulesMatchingData data(presContext, aParentContent, aPseudoTag,
PseudoRuleProcessorData data(presContext, aParentContent, aPseudoTag,
aComparator, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data);
@ -704,7 +681,7 @@ nsStyleSet::ProbePseudoStyleFor(nsIContent* aParentContent,
mRuleProcessors[eDocSheet] ||
mRuleProcessors[eStyleAttrSheet] ||
mRuleProcessors[eOverrideSheet]) {
PseudoRulesMatchingData data(presContext, aParentContent, aPseudoTag,
PseudoRuleProcessorData data(presContext, aParentContent, aPseudoTag,
nsnull, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data);
@ -831,10 +808,8 @@ struct StatefulData : public StateRuleProcessorData {
StatefulData(nsPresContext* aPresContext,
nsIContent* aContent, PRInt32 aStateMask)
: StateRuleProcessorData(aPresContext, aContent, aStateMask),
mMedium(aPresContext->Medium()),
mHint(nsReStyleHint(0))
{}
nsIAtom* mMedium;
nsReStyleHint mHint;
};
@ -843,7 +818,7 @@ static PRBool SheetHasStatefulStyle(nsIStyleRuleProcessor* aProcessor,
{
StatefulData* data = (StatefulData*)aData;
nsReStyleHint hint;
aProcessor->HasStateDependentStyle(data, data->mMedium, &hint);
aProcessor->HasStateDependentStyle(data, &hint);
data->mHint = nsReStyleHint(data->mHint | hint);
return PR_TRUE; // continue
}
@ -876,10 +851,8 @@ struct AttributeData : public AttributeRuleProcessorData {
AttributeData(nsPresContext* aPresContext,
nsIContent* aContent, nsIAtom* aAttribute, PRInt32 aModType)
: AttributeRuleProcessorData(aPresContext, aContent, aAttribute, aModType),
mMedium(aPresContext->Medium()),
mHint(nsReStyleHint(0))
{}
nsIAtom* mMedium;
nsReStyleHint mHint;
};
@ -888,7 +861,7 @@ SheetHasAttributeStyle(nsIStyleRuleProcessor* aProcessor, void *aData)
{
AttributeData* data = (AttributeData*)aData;
nsReStyleHint hint;
aProcessor->HasAttributeDependentStyle(data, data->mMedium, &hint);
aProcessor->HasAttributeDependentStyle(data, &hint);
data->mHint = nsReStyleHint(data->mHint | hint);
return PR_TRUE; // continue
}

Просмотреть файл

@ -28,6 +28,14 @@
* marquee { -moz-binding: none; }
*
*/
/*
* example: make search fields on www.mozilla.org white-on-black
*
* @-moz-document url-prefix(http://www.mozilla.org/) {
* #q { background: white ! important; color: black ! important; }
* }
*/
/*
* For more examples see http://www.mozilla.org/unix/customizing.html