Consolidate and deCOMtaminate parsing and storage of media lists. b=156716 r+sr=bzbarsky

This commit is contained in:
dbaron@dbaron.org
2005-03-30 00:36:57 +00:00
parent 33d8293e9d
commit b1497c8162
24 changed files with 442 additions and 634 deletions

View File

@@ -622,9 +622,9 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
nsresult nsresult
nsContentSink::ProcessLink(nsIContent* aElement, nsContentSink::ProcessLink(nsIContent* aElement,
const nsAString& aHref, const nsAString& aRel, const nsSubstring& aHref, const nsSubstring& aRel,
const nsAString& aTitle, const nsAString& aType, const nsSubstring& aTitle, const nsSubstring& aType,
const nsAString& aMedia) const nsSubstring& aMedia)
{ {
// XXX seems overkill to generate this string array // XXX seems overkill to generate this string array
nsStringArray linkTypes; nsStringArray linkTypes;
@@ -648,11 +648,11 @@ nsContentSink::ProcessLink(nsIContent* aElement,
nsresult nsresult
nsContentSink::ProcessStyleLink(nsIContent* aElement, nsContentSink::ProcessStyleLink(nsIContent* aElement,
const nsAString& aHref, const nsSubstring& aHref,
PRBool aAlternate, PRBool aAlternate,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aType, const nsSubstring& aType,
const nsAString& aMedia) const nsSubstring& aMedia)
{ {
if (aAlternate && aTitle.IsEmpty()) { if (aAlternate && aTitle.IsEmpty()) {
// alternates must have title return without error, for now // alternates must have title return without error, for now

View File

@@ -82,16 +82,16 @@ protected:
nsIContent* aContent = nsnull); nsIContent* aContent = nsnull);
nsresult ProcessLinkHeader(nsIContent* aElement, nsresult ProcessLinkHeader(nsIContent* aElement,
const nsAString& aLinkData); const nsAString& aLinkData);
nsresult ProcessLink(nsIContent* aElement, const nsAString& aHref, nsresult ProcessLink(nsIContent* aElement, const nsSubstring& aHref,
const nsAString& aRel, const nsAString& aTitle, const nsSubstring& aRel, const nsSubstring& aTitle,
const nsAString& aType, const nsAString& aMedia); const nsSubstring& aType, const nsSubstring& aMedia);
virtual nsresult ProcessStyleLink(nsIContent* aElement, virtual nsresult ProcessStyleLink(nsIContent* aElement,
const nsAString& aHref, const nsSubstring& aHref,
PRBool aAlternate, PRBool aAlternate,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aType, const nsSubstring& aType,
const nsAString& aMedia); const nsSubstring& aMedia);
nsresult ProcessMETATag(nsIContent* aContent); nsresult ProcessMETATag(nsIContent* aContent);

View File

@@ -609,11 +609,11 @@ nsXMLContentSink::LoadXSLStyleSheet(nsIURI* aUrl)
nsresult nsresult
nsXMLContentSink::ProcessStyleLink(nsIContent* aElement, nsXMLContentSink::ProcessStyleLink(nsIContent* aElement,
const nsAString& aHref, const nsSubstring& aHref,
PRBool aAlternate, PRBool aAlternate,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aType, const nsSubstring& aType,
const nsAString& aMedia) const nsSubstring& aMedia)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
mPrettyPrintXML = PR_FALSE; mPrettyPrintXML = PR_FALSE;

View File

@@ -130,11 +130,11 @@ protected:
// nsContentSink override // nsContentSink override
virtual nsresult ProcessStyleLink(nsIContent* aElement, virtual nsresult ProcessStyleLink(nsIContent* aElement,
const nsAString& aHref, const nsSubstring& aHref,
PRBool aAlternate, PRBool aAlternate,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aType, const nsSubstring& aType,
const nsAString& aMedia); const nsSubstring& aMedia);
nsresult LoadXSLStyleSheet(nsIURI* aUrl); nsresult LoadXSLStyleSheet(nsIURI* aUrl);

View File

@@ -102,11 +102,11 @@ protected:
// nsContentSink overrides // nsContentSink overrides
virtual nsresult ProcessStyleLink(nsIContent* aElement, virtual nsresult ProcessStyleLink(nsIContent* aElement,
const nsAString& aHref, const nsSubstring& aHref,
PRBool aAlternate, PRBool aAlternate,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aType, const nsSubstring& aType,
const nsAString& aMedia); const nsSubstring& aMedia);
nsresult LoadXSLStyleSheet(nsIURI* aUrl); nsresult LoadXSLStyleSheet(nsIURI* aUrl);
void StartLayout(); void StartLayout();
@@ -336,11 +336,11 @@ nsXMLFragmentContentSink::ReportError(const PRUnichar* aErrorText,
nsresult nsresult
nsXMLFragmentContentSink::ProcessStyleLink(nsIContent* aElement, nsXMLFragmentContentSink::ProcessStyleLink(nsIContent* aElement,
const nsAString& aHref, const nsSubstring& aHref,
PRBool aAlternate, PRBool aAlternate,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aType, const nsSubstring& aType,
const nsAString& aMedia) const nsSubstring& aMedia)
{ {
// don't process until moved to document // don't process until moved to document
return NS_OK; return NS_OK;

View File

@@ -102,7 +102,6 @@ EXPORTS = \
nsIComputedDOMStyle.h \ nsIComputedDOMStyle.h \
nsIHTMLCSSStyleSheet.h \ nsIHTMLCSSStyleSheet.h \
nsIInspectorCSSUtils.h \ nsIInspectorCSSUtils.h \
nsIMediaList.h \
nsIStyleRule.h \ nsIStyleRule.h \
nsIStyleRuleProcessor.h \ nsIStyleRuleProcessor.h \
nsIStyleRuleSupplier.h \ nsIStyleRuleSupplier.h \

View File

@@ -59,7 +59,6 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "nsCOMArray.h" #include "nsCOMArray.h"
#include "nsISupportsArray.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsContentPolicyUtils.h" #include "nsContentPolicyUtils.h"
@@ -76,7 +75,7 @@
#include "nsIXULPrototypeCache.h" #include "nsIXULPrototypeCache.h"
#endif #endif
#include "nsIDOMMediaList.h" #include "nsIMediaList.h"
#include "nsIDOMStyleSheet.h" #include "nsIDOMStyleSheet.h"
#include "nsIDOMCSSStyleSheet.h" #include "nsIDOMCSSStyleSheet.h"
#include "nsIDOMCSSImportRule.h" #include "nsIDOMCSSImportRule.h"
@@ -133,7 +132,7 @@ static const char* const gStateStrings[] = {
NS_IMPL_ISUPPORTS1(SheetLoadData, nsIUnicharStreamLoaderObserver) NS_IMPL_ISUPPORTS1(SheetLoadData, nsIUnicharStreamLoaderObserver)
SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader, SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
const nsAString& aTitle, const nsSubstring& aTitle,
nsIParser* aParserToUnblock, nsIParser* aParserToUnblock,
nsIURI* aURI, nsIURI* aURI,
nsICSSStyleSheet* aSheet, nsICSSStyleSheet* aSheet,
@@ -811,85 +810,6 @@ static PRBool IsChromeURI(nsIURI* aURI)
} }
#endif #endif
typedef nsresult (*nsStringEnumFunc)(const nsAString& aSubString, void *aData);
static nsresult EnumerateMediaString(const nsAString& aStringList, nsStringEnumFunc aFunc, void* aData)
{
nsresult status = NS_OK;
nsAutoString stringList(aStringList); // copy to work buffer
nsAutoString subStr;
stringList.Append(kNullCh); // put an extra null at the end
PRUnichar* start = stringList.BeginWriting();
PRUnichar* end = start;
while (NS_SUCCEEDED(status) && (kNullCh != *start)) {
PRBool quoted = PR_FALSE;
while ((kNullCh != *start) && nsCRT::IsAsciiSpace(*start)) { // skip leading space
start++;
}
if ((kApostrophe == *start) || (kQuote == *start)) { // quoted string
PRUnichar quote = *start++;
quoted = PR_TRUE;
end = start;
while (kNullCh != *end) {
if (quote == *end) { // found closing quote
*end++ = kNullCh; // end string here
while ((kNullCh != *end) && (kComma != *end)) { // keep going until comma
end++;
}
break;
}
end++;
}
}
else { // non-quoted string or ended
end = start;
while ((kNullCh != *end) && (kComma != *end)) { // look for comma
end++;
}
*end = kNullCh; // end string here
}
// truncate at first non letter, digit or hyphen
PRUnichar* test = start;
while (test <= end) {
if ((PR_FALSE == nsCRT::IsAsciiAlpha(*test)) &&
(PR_FALSE == nsCRT::IsAsciiDigit(*test)) && (kMinus != *test)) {
*test = kNullCh;
break;
}
test++;
}
subStr = start;
if (PR_FALSE == quoted) {
subStr.CompressWhitespace(PR_FALSE, PR_TRUE);
}
if (!subStr.IsEmpty()) {
status = (*aFunc)(subStr, aData);
}
start = ++end;
}
return status;
}
static nsresult MediumEnumFunc(const nsAString& aSubString, void* aData)
{
nsCOMPtr<nsIAtom> medium = do_GetAtom(aSubString);
NS_ENSURE_TRUE(medium, NS_ERROR_OUT_OF_MEMORY);
((nsICSSStyleSheet*)aData)->AppendMedium(medium);
return NS_OK;
}
PRBool PRBool
CSSLoaderImpl::IsAlternate(const nsAString& aTitle) CSSLoaderImpl::IsAlternate(const nsAString& aTitle)
{ {
@@ -1064,27 +984,32 @@ CSSLoaderImpl::CreateSheet(nsIURI* aURI,
*/ */
nsresult nsresult
CSSLoaderImpl::PrepareSheet(nsICSSStyleSheet* aSheet, CSSLoaderImpl::PrepareSheet(nsICSSStyleSheet* aSheet,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aMedia, const nsSubstring& aMediaString,
nsISupportsArray* aMediaArr) nsMediaList* aMediaList)
{ {
NS_PRECONDITION(aSheet, "Must have a sheet!"); NS_PRECONDITION(aSheet, "Must have a sheet!");
NS_PRECONDITION(aMedia.IsEmpty() || !aMediaArr,
"Can't have media array _and_ media string!");
nsresult rv = NS_OK; nsresult rv;
aSheet->ClearMedia(); nsCOMPtr<nsMediaList> mediaList(aMediaList);
if (!aMedia.IsEmpty()) {
rv = EnumerateMediaString(aMedia, MediumEnumFunc, aSheet); if (!aMediaString.IsEmpty()) {
} else if (aMediaArr) { NS_ASSERTION(!aMediaList,
PRUint32 count; "must not provide both aMediaString and aMediaList");
aMediaArr->Count(&count); mediaList = new nsMediaList();
for (PRUint32 i = 0; i < count; ++i) { NS_ENSURE_TRUE(mediaList, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIAtom> medium = do_QueryElementAt(aMediaArr, i); nsCOMPtr<nsICSSParser> mediumParser;
NS_ASSERTION(medium, "Null medium in media array!"); nsresult rv = GetParserFor(nsnull, getter_AddRefs(mediumParser));
aSheet->AppendMedium(medium); NS_ENSURE_SUCCESS(rv, rv);
} // We have aMediaString only when linked from link elements, style
// elements, or PIs, so pass PR_TRUE.
rv = mediumParser->ParseMediaList(aMediaString, nsnull, 0, mediaList,
PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
RecycleParser(mediumParser);
} }
rv = aSheet->SetMedia(mediaList);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
aSheet->SetTitle(aTitle); aSheet->SetTitle(aTitle);
@@ -1576,8 +1501,8 @@ NS_IMETHODIMP
CSSLoaderImpl::LoadInlineStyle(nsIContent* aElement, CSSLoaderImpl::LoadInlineStyle(nsIContent* aElement,
nsIUnicharInputStream* aStream, nsIUnicharInputStream* aStream,
PRUint32 aLineNumber, PRUint32 aLineNumber,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aMedia, const nsSubstring& aMedia,
nsIParser* aParserToUnblock, nsIParser* aParserToUnblock,
PRBool& aCompleted, PRBool& aCompleted,
nsICSSLoaderObserver* aObserver) nsICSSLoaderObserver* aObserver)
@@ -1630,8 +1555,8 @@ CSSLoaderImpl::LoadInlineStyle(nsIContent* aElement,
NS_IMETHODIMP NS_IMETHODIMP
CSSLoaderImpl::LoadStyleLink(nsIContent* aElement, CSSLoaderImpl::LoadStyleLink(nsIContent* aElement,
nsIURI* aURL, nsIURI* aURL,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aMedia, const nsSubstring& aMedia,
nsIParser* aParserToUnblock, nsIParser* aParserToUnblock,
PRBool& aCompleted, PRBool& aCompleted,
nsICSSLoaderObserver* aObserver) nsICSSLoaderObserver* aObserver)
@@ -1718,7 +1643,7 @@ CSSLoaderImpl::LoadStyleLink(nsIContent* aElement,
NS_IMETHODIMP NS_IMETHODIMP
CSSLoaderImpl::LoadChildSheet(nsICSSStyleSheet* aParentSheet, CSSLoaderImpl::LoadChildSheet(nsICSSStyleSheet* aParentSheet,
nsIURI* aURL, nsIURI* aURL,
nsISupportsArray* aMedia, nsMediaList* aMedia,
nsICSSImportRule* aParentRule) nsICSSImportRule* aParentRule)
{ {
LOG(("CSSLoaderImpl::LoadChildSheet")); LOG(("CSSLoaderImpl::LoadChildSheet"));
@@ -1805,7 +1730,7 @@ CSSLoaderImpl::LoadChildSheet(nsICSSStyleSheet* aParentSheet,
state, getter_AddRefs(sheet)); state, getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
const nsAString& empty = EmptyString(); const nsSubstring& empty = EmptyString();
rv = PrepareSheet(sheet, empty, empty, aMedia); rv = PrepareSheet(sheet, empty, empty, aMedia);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@@ -1877,7 +1802,7 @@ CSSLoaderImpl::InternalLoadAgentSheet(nsIURI* aURL,
getter_AddRefs(sheet)); getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
const nsAString& empty = EmptyString(); const nsSubstring& empty = EmptyString();
rv = PrepareSheet(sheet, empty, empty, nsnull); rv = PrepareSheet(sheet, empty, empty, nsnull);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);

View File

@@ -62,6 +62,7 @@ class CSSLoaderImpl;
#include "nsURIHashKey.h" #include "nsURIHashKey.h"
#include "nsInterfaceHashtable.h" #include "nsInterfaceHashtable.h"
#include "nsDataHashtable.h" #include "nsDataHashtable.h"
class nsMediaList;
/** /**
* OVERALL ARCHITECTURE * OVERALL ARCHITECTURE
@@ -101,7 +102,7 @@ public:
virtual ~SheetLoadData(void); virtual ~SheetLoadData(void);
// Data for loading a sheet linked from a document // Data for loading a sheet linked from a document
SheetLoadData(CSSLoaderImpl* aLoader, SheetLoadData(CSSLoaderImpl* aLoader,
const nsAString& aTitle, const nsSubstring& aTitle,
nsIParser* aParserToUnblock, nsIParser* aParserToUnblock,
nsIURI* aURI, nsIURI* aURI,
nsICSSStyleSheet* aSheet, nsICSSStyleSheet* aSheet,
@@ -232,23 +233,23 @@ public:
NS_IMETHOD LoadInlineStyle(nsIContent* aElement, NS_IMETHOD LoadInlineStyle(nsIContent* aElement,
nsIUnicharInputStream* aStream, nsIUnicharInputStream* aStream,
PRUint32 aLineNumber, PRUint32 aLineNumber,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aMedia, const nsSubstring& aMedia,
nsIParser* aParserToUnblock, nsIParser* aParserToUnblock,
PRBool& aCompleted, PRBool& aCompleted,
nsICSSLoaderObserver* aObserver); nsICSSLoaderObserver* aObserver);
NS_IMETHOD LoadStyleLink(nsIContent* aElement, NS_IMETHOD LoadStyleLink(nsIContent* aElement,
nsIURI* aURL, nsIURI* aURL,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aMedia, const nsSubstring& aMedia,
nsIParser* aParserToUnblock, nsIParser* aParserToUnblock,
PRBool& aCompleted, PRBool& aCompleted,
nsICSSLoaderObserver* aObserver); nsICSSLoaderObserver* aObserver);
NS_IMETHOD LoadChildSheet(nsICSSStyleSheet* aParentSheet, NS_IMETHOD LoadChildSheet(nsICSSStyleSheet* aParentSheet,
nsIURI* aURL, nsIURI* aURL,
nsISupportsArray* aMedia, nsMediaList* aMedia,
nsICSSImportRule* aRule); nsICSSImportRule* aRule);
NS_IMETHOD LoadAgentSheet(nsIURI* aURL, nsICSSStyleSheet** aSheet); NS_IMETHOD LoadAgentSheet(nsIURI* aURL, nsICSSStyleSheet** aSheet);
@@ -288,12 +289,12 @@ private:
StyleSheetState& aSheetState, StyleSheetState& aSheetState,
nsICSSStyleSheet** aSheet); nsICSSStyleSheet** aSheet);
// Pass in either a media string or the array of media from the // Pass in either a media string or the nsMediaList from the
// CSSParser. Don't pass both. // CSSParser. Don't pass both.
nsresult PrepareSheet(nsICSSStyleSheet* aSheet, nsresult PrepareSheet(nsICSSStyleSheet* aSheet,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aMedia, const nsSubstring& aMediaString,
nsISupportsArray* aMediaArr); nsMediaList* aMediaList);
nsresult InsertSheetInDoc(nsICSSStyleSheet* aSheet, nsresult InsertSheetInDoc(nsICSSStyleSheet* aSheet,
nsIContent* aLinkingContent, nsIContent* aLinkingContent,

View File

@@ -74,6 +74,7 @@
#include "nsContentErrors.h" #include "nsContentErrors.h"
#include "nsUnitConversion.h" #include "nsUnitConversion.h"
#include "nsPrintfCString.h" #include "nsPrintfCString.h"
#include "nsIMediaList.h"
#include "prprf.h" #include "prprf.h"
#include "math.h" #include "math.h"
@@ -133,13 +134,27 @@ public:
nsCSSDeclaration* aDeclaration, nsCSSDeclaration* aDeclaration,
PRBool* aChanged); PRBool* aChanged);
NS_IMETHOD ParseMediaList(const nsSubstring& aBuffer,
nsIURI* aURL, // for error reporting
PRUint32 aLineNumber, // for error reporting
nsMediaList* aMediaList,
PRBool aHTMLMode);
void AppendRule(nsICSSRule* aRule); void AppendRule(nsICSSRule* aRule);
protected: protected:
nsresult InitScanner(nsIUnicharInputStream* aInput, nsIURI* aSheetURI, nsresult InitScanner(nsIUnicharInputStream* aInput, nsIURI* aSheetURI,
PRUint32 aLineNumber, nsIURI* aBaseURI); PRUint32 aLineNumber, nsIURI* aBaseURI);
// the caller must hold on to aBuffer until parsing is done
nsresult InitScanner(const nsAString& aBuffer, nsIURI* aSheetURI,
PRUint32 aLineNumber, nsIURI* aBaseURI);
nsresult ReleaseScanner(void); nsresult ReleaseScanner(void);
nsresult DoParseMediaList(const nsSubstring& aBuffer,
nsIURI* aURL, // for error reporting
PRUint32 aLineNumber, // for error reporting
nsMediaList* aMediaList);
PRBool GetToken(nsresult& aErrorCode, PRBool aSkipWS); PRBool GetToken(nsresult& aErrorCode, PRBool aSkipWS);
PRBool GetURLToken(nsresult& aErrorCode, PRBool aSkipWS); PRBool GetURLToken(nsresult& aErrorCode, PRBool aSkipWS);
void UngetToken(); void UngetToken();
@@ -160,10 +175,11 @@ protected:
PRBool ParseCharsetRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); PRBool ParseCharsetRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool ParseImportRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); PRBool ParseImportRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
PRBool GatherURL(nsresult& aErrorCode, nsString& aURL); PRBool GatherURL(nsresult& aErrorCode, nsString& aURL);
PRBool GatherMedia(nsresult& aErrorCode, nsISupportsArray* aMediaAtoms); PRBool GatherMedia(nsresult& aErrorCode, nsMediaList* aMedia,
PRUnichar aStopSymbol);
PRBool ProcessImport(nsresult& aErrorCode, PRBool ProcessImport(nsresult& aErrorCode,
const nsString& aURLSpec, const nsString& aURLSpec,
nsISupportsArray* aMedia, nsMediaList* aMedia,
RuleAppendFunc aAppendFunc, RuleAppendFunc aAppendFunc,
void* aProcessData); void* aProcessData);
PRBool ParseGroupRule(nsresult& aErrorCode, nsICSSGroupRule* aRule, RuleAppendFunc aAppendFunc, void* aProcessData); PRBool ParseGroupRule(nsresult& aErrorCode, nsICSSGroupRule* aRule, RuleAppendFunc aAppendFunc, void* aProcessData);
@@ -374,6 +390,10 @@ protected:
PRPackedBool mSVGMode; PRPackedBool mSVGMode;
#endif #endif
// True for parsing media lists for HTML attributes, where we have to
// ignore CSS comments.
PRPackedBool mHTMLMediaMode;
// True if tagnames and attributes are case-sensitive // True if tagnames and attributes are case-sensitive
PRPackedBool mCaseSensitive; PRPackedBool mCaseSensitive;
@@ -471,6 +491,7 @@ CSSParserImpl::CSSParserImpl()
#ifdef MOZ_SVG #ifdef MOZ_SVG
mSVGMode(PR_FALSE), mSVGMode(PR_FALSE),
#endif #endif
mHTMLMediaMode(PR_FALSE),
mCaseSensitive(PR_FALSE), mCaseSensitive(PR_FALSE),
mParsingCompoundProperty(PR_FALSE) mParsingCompoundProperty(PR_FALSE)
#ifdef DEBUG #ifdef DEBUG
@@ -552,6 +573,22 @@ CSSParserImpl::InitScanner(nsIUnicharInputStream* aInput, nsIURI* aSheetURI,
return NS_OK; return NS_OK;
} }
nsresult
CSSParserImpl::InitScanner(const nsAString& aBuffer, nsIURI* aSheetURI,
PRUint32 aLineNumber, nsIURI* aBaseURI)
{
// Having it not own the string is OK since the caller will hold on to
// the stream until we're done parsing.
nsCOMPtr<nsIUnicharInputStream> input;
nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input),
&aBuffer, PR_FALSE);
if (NS_FAILED(rv)) {
return rv;
}
return InitScanner(input, aSheetURI, aLineNumber, aBaseURI);
}
nsresult nsresult
CSSParserImpl::ReleaseScanner(void) CSSParserImpl::ReleaseScanner(void)
{ {
@@ -660,16 +697,8 @@ CSSParserImpl::ParseStyleAttribute(const nsAString& aAttributeValue,
{ {
NS_ASSERTION(nsnull != aBaseURL, "need base URL"); NS_ASSERTION(nsnull != aBaseURL, "need base URL");
nsCOMPtr<nsIUnicharInputStream> input; nsresult rv =
// Style attribute parsing can't make the stream outlive this InitScanner(aAttributeValue, aDocURL, 0, aBaseURL); // XXX line number
// function call, so having it not own the string is OK.
nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input),
&aAttributeValue, PR_FALSE);
if (NS_FAILED(rv)) {
return rv;
}
rv = InitScanner(input, aDocURL, 0, aBaseURL); // XXX line number
if (! NS_SUCCEEDED(rv)) { if (! NS_SUCCEEDED(rv)) {
return rv; return rv;
} }
@@ -723,16 +752,7 @@ CSSParserImpl::ParseAndAppendDeclaration(const nsAString& aBuffer,
// NS_ASSERTION(nsnull != aBaseURL, "need base URL"); // NS_ASSERTION(nsnull != aBaseURL, "need base URL");
*aChanged = PR_FALSE; *aChanged = PR_FALSE;
nsCOMPtr<nsIUnicharInputStream> input; nsresult rv = InitScanner(aBuffer, aSheetURL, 0, aBaseURL);
// Parsing a single declaration block can't make the stream outlive this
// function call, so having it not own the string is OK.
nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input),
&aBuffer, PR_FALSE);
if (NS_FAILED(rv)) {
return rv;
}
rv = InitScanner(input, aSheetURL, 0, aBaseURL);
if (! NS_SUCCEEDED(rv)) { if (! NS_SUCCEEDED(rv)) {
return rv; return rv;
} }
@@ -779,16 +799,7 @@ CSSParserImpl::ParseRule(const nsAString& aRule,
NS_ASSERTION(nsnull != aBaseURL, "need base URL"); NS_ASSERTION(nsnull != aBaseURL, "need base URL");
NS_ENSURE_ARG_POINTER(aResult); NS_ENSURE_ARG_POINTER(aResult);
nsCOMPtr<nsIUnicharInputStream> input; nsresult rv = InitScanner(aRule, aSheetURL, 0, aBaseURL);
// Parsing a single rule can't make the stream outlive this
// function call, so having it not own the string is OK.
nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input),
&aRule, PR_FALSE);
if (NS_FAILED(rv)) {
return rv;
}
rv = InitScanner(input, aSheetURL, 0, aBaseURL);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@@ -835,16 +846,7 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
NS_ASSERTION(nsnull != aDeclaration, "Need declaration to parse into!"); NS_ASSERTION(nsnull != aDeclaration, "Need declaration to parse into!");
*aChanged = PR_FALSE; *aChanged = PR_FALSE;
nsCOMPtr<nsIUnicharInputStream> input; nsresult rv = InitScanner(aPropValue, aSheetURL, 0, aBaseURL);
// Parsing a single property value can't make the stream outlive this
// function call, so having it not own the string is OK.
nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input),
&aPropValue, PR_FALSE);
if (NS_FAILED(rv)) {
return rv;
}
rv = InitScanner(input, aSheetURL, 0, aBaseURL);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@@ -889,6 +891,79 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
ReleaseScanner(); ReleaseScanner();
return result; return result;
} }
NS_IMETHODIMP
CSSParserImpl::ParseMediaList(const nsSubstring& aBuffer,
nsIURI* aURL, // for error reporting
PRUint32 aLineNumber, // for error reporting
nsMediaList* aMediaList,
PRBool aHTMLMode)
{
aMediaList->Clear();
nsresult rv;
if (aHTMLMode) {
mHTMLMediaMode = PR_TRUE;
// XXXldb We need to make the scanner not skip CSS comments! (Or
// should we?)
// Follow the parsing rules in
// http://www.w3.org/TR/1999/REC-html401-19991224/types.html#type-media-descriptors
for (PRUint32 sub = 0, sub_end; sub < aBuffer.Length(); sub = sub_end + 1) {
sub_end = aBuffer.FindChar(PRUnichar(','), sub);
if (sub_end == -1)
sub_end = aBuffer.Length();
PRUint32 parse_start, parse_end;
for (parse_start = sub;
parse_start < sub_end && nsCRT::IsAsciiSpace(aBuffer[parse_start]);
++parse_start)
;
for (parse_end = parse_start;
parse_end < sub_end &&
(nsCRT::IsAsciiAlpha(aBuffer[parse_end]) ||
nsCRT::IsAsciiDigit(aBuffer[parse_end]) ||
aBuffer[parse_end] == PRUnichar('-'));
++parse_end)
;
DoParseMediaList(Substring(aBuffer, parse_start, parse_end - parse_start),
aURL, aLineNumber, aMediaList);
}
mHTMLMediaMode = PR_FALSE;
} else {
rv = DoParseMediaList(aBuffer, aURL, aLineNumber, aMediaList);
}
return rv;
}
// All parameters but the first are the same as for |ParseMediaList|,
// but for HTML we get the buffer in chunks according to the HTML spec's
// parsing rules instead of in one piece.
nsresult
CSSParserImpl::DoParseMediaList(const nsSubstring& aBuffer,
nsIURI* aURL, // for error reporting
PRUint32 aLineNumber, // for error reporting
nsMediaList* aMediaList)
{
// fake base URL since media lists don't have URLs in them
nsresult rv = InitScanner(aBuffer, aURL, aLineNumber, aURL);
if (NS_FAILED(rv)) {
return rv;
}
if (!GatherMedia(rv, aMediaList, PRUnichar(0)) && !mHTMLMediaMode) {
OUTPUT_ERROR();
}
CLEAR_ERROR();
ReleaseScanner();
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
PRBool CSSParserImpl::GetToken(nsresult& aErrorCode, PRBool aSkipWS) PRBool CSSParserImpl::GetToken(nsresult& aErrorCode, PRBool aSkipWS)
@@ -1110,80 +1185,68 @@ PRBool CSSParserImpl::GatherURL(nsresult& aErrorCode, nsString& aURL)
} }
PRBool CSSParserImpl::GatherMedia(nsresult& aErrorCode, PRBool CSSParserImpl::GatherMedia(nsresult& aErrorCode,
nsISupportsArray* aMediaAtoms) nsMediaList* aMedia,
PRUnichar aStopSymbol)
{ {
PRBool expectIdent = PR_TRUE;
for (;;) { for (;;) {
if (!GetToken(aErrorCode, PR_TRUE)) { if (!GetToken(aErrorCode, PR_TRUE)) {
REPORT_UNEXPECTED_EOF(PEGatherMediaEOF); REPORT_UNEXPECTED_EOF(PEGatherMediaEOF);
break; break;
} }
if (eCSSToken_Symbol == mToken.mType) { if (eCSSToken_Ident != mToken.mType) {
PRUnichar symbol = mToken.mSymbol;
if ((';' == symbol) || ('{' == symbol)) {
UngetToken();
return PR_TRUE;
} else if (',' != symbol) {
REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotComma);
UngetToken();
break;
} else if (expectIdent) {
REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotIdent); REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotIdent);
UngetToken(); UngetToken();
break; break;
} }
else {
expectIdent = PR_TRUE;
}
}
else if (eCSSToken_Ident == mToken.mType) {
if (expectIdent) {
ToLowerCase(mToken.mIdent); // case insensitive from CSS - must be lower cased ToLowerCase(mToken.mIdent); // case insensitive from CSS - must be lower cased
nsCOMPtr<nsIAtom> medium = do_GetAtom(mToken.mIdent); nsCOMPtr<nsIAtom> medium = do_GetAtom(mToken.mIdent);
aMediaAtoms->AppendElement(medium); aMedia->AppendAtom(medium);
expectIdent = PR_FALSE;
if (!GetToken(aErrorCode, PR_TRUE)) {
if (aStopSymbol == PRUnichar(0))
return PR_TRUE;
REPORT_UNEXPECTED_EOF(PEGatherMediaEOF);
break;
} }
else {
if (eCSSToken_Symbol == mToken.mType &&
mToken.mSymbol == aStopSymbol) {
UngetToken();
return PR_TRUE;
} else if (eCSSToken_Symbol != mToken.mType ||
mToken.mSymbol != ',') {
REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotComma); REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotComma);
UngetToken(); UngetToken();
break; break;
} }
} }
else {
if (expectIdent)
REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotIdent);
else
REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotComma);
UngetToken();
break;
}
}
aMediaAtoms->Clear();
return PR_FALSE; return PR_FALSE;
} }
// Parse a CSS2 import rule: "@import STRING | URL [medium [, mdeium]]" // Parse a CSS2 import rule: "@import STRING | URL [medium [, medium]]"
PRBool CSSParserImpl::ParseImportRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aData) PRBool CSSParserImpl::ParseImportRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aData)
{ {
nsAutoString url; nsCOMPtr<nsMediaList> media = new nsMediaList();
nsCOMPtr<nsISupportsArray> media;
aErrorCode = NS_NewISupportsArray(getter_AddRefs(media));
if (!media) { if (!media) {
// Out of memory aErrorCode = NS_ERROR_OUT_OF_MEMORY;
return PR_FALSE; return PR_FALSE;
} }
nsAutoString url;
if (!GatherURL(aErrorCode, url)) { if (!GatherURL(aErrorCode, url)) {
REPORT_UNEXPECTED_TOKEN(PEImportNotURI); REPORT_UNEXPECTED_TOKEN(PEImportNotURI);
return PR_FALSE; return PR_FALSE;
} }
if (!GatherMedia(aErrorCode, media) || if (!ExpectSymbol(aErrorCode, ';', PR_TRUE)) {
if (!GatherMedia(aErrorCode, media, ';') ||
!ExpectSymbol(aErrorCode, ';', PR_TRUE)) { !ExpectSymbol(aErrorCode, ';', PR_TRUE)) {
REPORT_UNEXPECTED_TOKEN(PEImportUnexpected); REPORT_UNEXPECTED_TOKEN(PEImportUnexpected);
// don't advance section, simply ignore invalid @import // don't advance section, simply ignore invalid @import
return PR_FALSE; return PR_FALSE;
} }
NS_ASSERTION(media->Count() != 0, "media list must be nonempty");
}
ProcessImport(aErrorCode, url, media, aAppendFunc, aData); ProcessImport(aErrorCode, url, media, aAppendFunc, aData);
return PR_TRUE; return PR_TRUE;
@@ -1192,7 +1255,7 @@ PRBool CSSParserImpl::ParseImportRule(nsresult& aErrorCode, RuleAppendFunc aAppe
PRBool CSSParserImpl::ProcessImport(nsresult& aErrorCode, PRBool CSSParserImpl::ProcessImport(nsresult& aErrorCode,
const nsString& aURLSpec, const nsString& aURLSpec,
nsISupportsArray* aMedia, nsMediaList* aMedia,
RuleAppendFunc aAppendFunc, RuleAppendFunc aAppendFunc,
void* aData) void* aData)
{ {
@@ -1271,14 +1334,15 @@ PRBool CSSParserImpl::ParseMediaRule(nsresult& aErrorCode,
RuleAppendFunc aAppendFunc, RuleAppendFunc aAppendFunc,
void* aData) void* aData)
{ {
nsCOMPtr<nsISupportsArray> media; nsCOMPtr<nsMediaList> media = new nsMediaList();
aErrorCode = NS_NewISupportsArray(getter_AddRefs(media)); if (!media) {
if (media) { aErrorCode = NS_ERROR_OUT_OF_MEMORY;
if (GatherMedia(aErrorCode, media)) { return PR_FALSE;
}
if (GatherMedia(aErrorCode, media, '{')) {
NS_ASSERTION(media->Count() != 0, "media list must be nonempty");
// XXXbz this could use better error reporting throughout the method // XXXbz this could use better error reporting throughout the method
PRUint32 count;
media->Count(&count);
if (count > 0) {
nsRefPtr<nsCSSMediaRule> rule(new nsCSSMediaRule()); nsRefPtr<nsCSSMediaRule> rule(new nsCSSMediaRule());
// Append first, so when we do SetMedia() the rule // Append first, so when we do SetMedia() the rule
// knows what its stylesheet is. // knows what its stylesheet is.
@@ -1287,8 +1351,6 @@ PRBool CSSParserImpl::ParseMediaRule(nsresult& aErrorCode,
return PR_TRUE; return PR_TRUE;
} }
} }
}
}
return PR_FALSE; return PR_FALSE;
} }

View File

@@ -341,7 +341,7 @@ class CSSImportRuleImpl : public nsCSSRule,
public nsIDOMCSSImportRule public nsIDOMCSSImportRule
{ {
public: public:
CSSImportRuleImpl(nsISupportsArray* aMedia); CSSImportRuleImpl(nsMediaList* aMedia);
CSSImportRuleImpl(const CSSImportRuleImpl& aCopy); CSSImportRuleImpl(const CSSImportRuleImpl& aCopy);
virtual ~CSSImportRuleImpl(void); virtual ~CSSImportRuleImpl(void);
@@ -375,31 +375,31 @@ public:
protected: protected:
nsString mURLSpec; nsString mURLSpec;
nsCOMPtr<nsIMediaList> mMedia; nsCOMPtr<nsMediaList> mMedia;
nsCOMPtr<nsICSSStyleSheet> mChildSheet; nsCOMPtr<nsICSSStyleSheet> mChildSheet;
}; };
CSSImportRuleImpl::CSSImportRuleImpl(nsISupportsArray* aMedia) CSSImportRuleImpl::CSSImportRuleImpl(nsMediaList* aMedia)
: nsCSSRule(), : nsCSSRule()
mURLSpec() , mURLSpec()
, mMedia(aMedia)
{ {
// XXXbz This is really silly.... the mMedia we create here will be // XXXbz This is really silly.... the mMedia here will be replaced
// clobbered if we manage to load a sheet. Which should really // with itself if we manage to load a sheet. Which should really
// never fail nowadays, in sane cases. // never fail nowadays, in sane cases.
NS_NewMediaList(aMedia, nsnull, getter_AddRefs(mMedia));
} }
CSSImportRuleImpl::CSSImportRuleImpl(const CSSImportRuleImpl& aCopy) CSSImportRuleImpl::CSSImportRuleImpl(const CSSImportRuleImpl& aCopy)
: nsCSSRule(aCopy), : nsCSSRule(aCopy),
mURLSpec(aCopy.mURLSpec) mURLSpec(aCopy.mURLSpec)
{ {
nsCOMPtr<nsICSSStyleSheet> sheet; nsCOMPtr<nsICSSStyleSheet> sheet;
if (aCopy.mChildSheet) { if (aCopy.mChildSheet) {
aCopy.mChildSheet->Clone(nsnull, this, nsnull, nsnull, aCopy.mChildSheet->Clone(nsnull, this, nsnull, nsnull,
getter_AddRefs(sheet)); getter_AddRefs(sheet));
} }
SetSheet(sheet); SetSheet(sheet);
// SetSheet sets mMedia appropriately
} }
CSSImportRuleImpl::~CSSImportRuleImpl(void) CSSImportRuleImpl::~CSSImportRuleImpl(void)
@@ -522,7 +522,7 @@ CSSImportRuleImpl::SetSheet(nsICSSStyleSheet* aSheet)
nsresult nsresult
NS_NewCSSImportRule(nsICSSImportRule** aInstancePtrResult, NS_NewCSSImportRule(nsICSSImportRule** aInstancePtrResult,
const nsString& aURLSpec, const nsString& aURLSpec,
nsISupportsArray* aMedia) nsMediaList* aMedia)
{ {
NS_ENSURE_ARG_POINTER(aInstancePtrResult); NS_ENSURE_ARG_POINTER(aInstancePtrResult);
@@ -930,14 +930,18 @@ nsCSSMediaRule::nsCSSMediaRule(const nsCSSMediaRule& aCopy)
: nsCSSGroupRule(aCopy) : nsCSSGroupRule(aCopy)
{ {
if (aCopy.mMedia) { if (aCopy.mMedia) {
NS_NewMediaList(aCopy.mMedia, aCopy.mSheet, getter_AddRefs(mMedia)); aCopy.mMedia->Clone(getter_AddRefs(mMedia));
if (mMedia) {
// XXXldb This doesn't really make sense.
mMedia->SetStyleSheet(aCopy.mSheet);
}
} }
} }
nsCSSMediaRule::~nsCSSMediaRule() nsCSSMediaRule::~nsCSSMediaRule()
{ {
if (mMedia) { if (mMedia) {
mMedia->DropReference(); mMedia->SetStyleSheet(nsnull);
} }
} }
@@ -959,14 +963,9 @@ NS_IMETHODIMP
nsCSSMediaRule::SetStyleSheet(nsICSSStyleSheet* aSheet) nsCSSMediaRule::SetStyleSheet(nsICSSStyleSheet* aSheet)
{ {
if (mMedia) { if (mMedia) {
nsresult rv; // Set to null so it knows it's leaving one sheet and joining another.
nsCOMPtr<nsISupportsArray> oldMedia(do_QueryInterface(mMedia, &rv)); mMedia->SetStyleSheet(nsnull);
if (NS_FAILED(rv)) mMedia->SetStyleSheet(aSheet);
return rv;
mMedia->DropReference();
rv = NS_NewMediaList(oldMedia, aSheet, getter_AddRefs(mMedia));
if (NS_FAILED(rv))
return rv;
} }
return nsCSSGroupRule::SetStyleSheet(aSheet); return nsCSSGroupRule::SetStyleSheet(aSheet);
@@ -983,17 +982,9 @@ nsCSSMediaRule::List(FILE* out, PRInt32 aIndent) const
fputs("@media ", out); fputs("@media ", out);
if (mMedia) { if (mMedia) {
PRUint32 index = 0; nsAutoString mediaText;
PRUint32 count; mMedia->GetText(mediaText);
mMedia->Count(&count); fputs(NS_LossyConvertUCS2toASCII(mediaText).get(), out);
while (index < count) {
nsCOMPtr<nsIAtom> medium = dont_AddRef((nsIAtom*)mMedia->ElementAt(index++));
medium->ToString(buffer);
fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out);
if (index < count) {
fputs(", ", out);
}
}
} }
return nsCSSGroupRule::List(out, aIndent); return nsCSSGroupRule::List(out, aIndent);
@@ -1019,9 +1010,12 @@ nsCSSMediaRule::Clone(nsICSSRule*& aClone) const
} }
nsresult nsresult
nsCSSMediaRule::SetMedia(nsISupportsArray* aMedia) nsCSSMediaRule::SetMedia(nsMediaList* aMedia)
{ {
return NS_NewMediaList(aMedia, mSheet, getter_AddRefs(mMedia)); mMedia = aMedia;
if (aMedia)
mMedia->SetStyleSheet(mSheet);
return NS_OK;
} }
// nsIDOMCSSRule methods // nsIDOMCSSRule methods
@@ -1035,22 +1029,12 @@ nsCSSMediaRule::GetType(PRUint16* aType)
NS_IMETHODIMP NS_IMETHODIMP
nsCSSMediaRule::GetCssText(nsAString& aCssText) nsCSSMediaRule::GetCssText(nsAString& aCssText)
{ {
PRUint32 index;
PRUint32 count;
aCssText.AssignLiteral("@media "); aCssText.AssignLiteral("@media ");
// get all the media // get all the media
if (mMedia) { if (mMedia) {
mMedia->Count(&count); nsAutoString mediaText;
for (index = 0; index < count; index++) { mMedia->GetText(mediaText);
nsCOMPtr<nsIAtom> medium = dont_AddRef((nsIAtom*)mMedia->ElementAt(index)); aCssText.Append(mediaText);
if (medium) {
nsAutoString tempString;
if (index > 0)
aCssText.AppendLiteral(", ");
medium->ToString(tempString);
aCssText.Append(tempString);
}
}
} }
return nsCSSGroupRule::AppendRulesToCssText(aCssText); return nsCSSGroupRule::AppendRulesToCssText(aCssText);
@@ -1110,9 +1094,7 @@ NS_IMETHODIMP_(PRBool)
nsCSSMediaRule::UseForPresentation(nsPresContext* aPresContext) nsCSSMediaRule::UseForPresentation(nsPresContext* aPresContext)
{ {
if (mMedia) { if (mMedia) {
PRBool matches = PR_FALSE; return mMedia->Matches(aPresContext);
mMedia->MatchesMedium(aPresContext->Medium(), &matches);
return matches;
} }
return PR_TRUE; return PR_TRUE;
} }

View File

@@ -50,7 +50,7 @@
#include "nsString.h" #include "nsString.h"
class CSSGroupRuleRuleListImpl; class CSSGroupRuleRuleListImpl;
class nsIMediaList; class nsMediaList;
#define DECL_STYLE_RULE_INHERIT \ #define DECL_STYLE_RULE_INHERIT \
NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; \ NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aSheet) const; \
@@ -134,10 +134,10 @@ public:
NS_IMETHOD_(PRBool) UseForPresentation(nsPresContext* aPresContext); NS_IMETHOD_(PRBool) UseForPresentation(nsPresContext* aPresContext);
// @media rule methods // @media rule methods
nsresult SetMedia(nsISupportsArray* aMedia); nsresult SetMedia(nsMediaList* aMedia);
protected: protected:
nsCOMPtr<nsIMediaList> mMedia; nsCOMPtr<nsMediaList> mMedia;
}; };
class nsCSSDocumentRule : public nsCSSGroupRule, class nsCSSDocumentRule : public nsCSSGroupRule,

View File

@@ -807,102 +807,38 @@ CSSRuleListImpl::Item(PRUint32 aIndex, nsIDOMCSSRule** aReturn)
return result; return result;
} }
class DOMMediaListImpl : public nsIDOMMediaList, NS_INTERFACE_MAP_BEGIN(nsMediaList)
public nsIMediaList
{
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMMEDIALIST
NS_FORWARD_NSISUPPORTSARRAY(mArray->)
NS_FORWARD_NSICOLLECTION(mArray->);
NS_FORWARD_NSISERIALIZABLE(mArray->); // XXXbe temporary
NS_IMETHOD_(PRBool) operator==(const nsISupportsArray& other) {
return PR_FALSE;
}
NS_IMETHOD_(nsISupports*) operator[](PRUint32 aIndex) {
return mArray->ElementAt(aIndex);
}
// nsIMediaList methods
NS_DECL_NSIMEDIALIST
DOMMediaListImpl(nsISupportsArray *aArray, nsCSSStyleSheet *aStyleSheet);
virtual ~DOMMediaListImpl();
private:
nsresult Delete(const nsAString & aOldMedium);
nsresult Append(const nsAString & aOldMedium);
nsCOMPtr<nsISupportsArray> mArray;
// not refcounted; sheet will let us know when it goes away
// mStyleSheet is the sheet that needs to be dirtied when this medialist
// changes
nsCSSStyleSheet* mStyleSheet;
};
// QueryInterface implementation for DOMMediaListImpl
NS_INTERFACE_MAP_BEGIN(DOMMediaListImpl)
NS_INTERFACE_MAP_ENTRY(nsIDOMMediaList) NS_INTERFACE_MAP_ENTRY(nsIDOMMediaList)
NS_INTERFACE_MAP_ENTRY(nsIMediaList) NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsISupportsArray)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMediaList)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(MediaList) NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(MediaList)
NS_INTERFACE_MAP_ENTRY(nsISerializable)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsMediaList)
NS_IMPL_ADDREF(DOMMediaListImpl) NS_IMPL_RELEASE(nsMediaList)
NS_IMPL_RELEASE(DOMMediaListImpl)
DOMMediaListImpl::DOMMediaListImpl(nsISupportsArray *aArray, nsMediaList::nsMediaList()
nsCSSStyleSheet *aStyleSheet) : mStyleSheet(nsnull)
: mArray(aArray), mStyleSheet(aStyleSheet)
{ {
NS_ABORT_IF_FALSE(mArray, "This can't be used without an array!!");
} }
DOMMediaListImpl::~DOMMediaListImpl() nsMediaList::~nsMediaList()
{ {
} }
nsresult nsresult
NS_NewMediaList(nsISupportsArray* aArray, nsMediaList::GetText(nsAString& aMediaText)
nsICSSStyleSheet* aSheet,
nsIMediaList** aInstancePtrResult)
{
NS_ASSERTION(aInstancePtrResult, "Null out param.");
DOMMediaListImpl* medialist = new DOMMediaListImpl(aArray, NS_STATIC_CAST(nsCSSStyleSheet*, aSheet));
*aInstancePtrResult = medialist;
NS_ENSURE_TRUE(medialist, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aInstancePtrResult);
return NS_OK;
}
NS_IMETHODIMP
DOMMediaListImpl::GetText(nsAString& aMediaText)
{ {
aMediaText.Truncate(); aMediaText.Truncate();
PRUint32 cnt; for (PRInt32 i = 0, i_end = mArray.Count(); i < i_end; ++i) {
nsresult rv = Count(&cnt); nsIAtom* medium = mArray[i];
if (NS_FAILED(rv)) return rv;
PRInt32 count = cnt, index = 0;
while (index < count) {
nsCOMPtr<nsIAtom> medium;
QueryElementAt(index++, NS_GET_IID(nsIAtom), getter_AddRefs(medium));
NS_ENSURE_TRUE(medium, NS_ERROR_FAILURE); NS_ENSURE_TRUE(medium, NS_ERROR_FAILURE);
nsAutoString buffer; nsAutoString buffer;
medium->ToString(buffer); medium->ToString(buffer);
aMediaText.Append(buffer); aMediaText.Append(buffer);
if (index < count) { if (i + 1 < i_end) {
aMediaText.AppendLiteral(", "); aMediaText.AppendLiteral(", ");
} }
} }
@@ -912,36 +848,24 @@ DOMMediaListImpl::GetText(nsAString& aMediaText)
// XXXbz this is so ill-defined in the spec, it's not clear quite what // XXXbz this is so ill-defined in the spec, it's not clear quite what
// it should be doing.... // it should be doing....
NS_IMETHODIMP nsresult
DOMMediaListImpl::SetText(const nsAString& aMediaText) nsMediaList::SetText(const nsAString& aMediaText)
{ {
nsresult rv = Clear(); nsCOMPtr<nsICSSParser> parser;
nsresult rv = NS_NewCSSParser(getter_AddRefs(parser));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsAutoString buf(aMediaText); PRBool htmlMode = PR_FALSE;
PRInt32 n = buf.FindChar(','); nsCOMPtr<nsIDOMStyleSheet> domSheet =
do_QueryInterface(NS_STATIC_CAST(nsICSSStyleSheet*, mStyleSheet));
do { if (domSheet) {
if (n < 0) nsCOMPtr<nsIDOMNode> node;
n = buf.Length(); domSheet->GetOwnerNode(getter_AddRefs(node));
htmlMode = !!node;
nsAutoString tmp;
buf.Left(tmp, n);
tmp.CompressWhitespace();
if (!tmp.IsEmpty()) {
rv = Append(tmp);
NS_ENSURE_SUCCESS(rv, rv);
} }
buf.Cut(0, n + 1); return parser->ParseMediaList(nsString(aMediaText), nsnull, 0,
this, htmlMode);
n = buf.FindChar(',');
} while (!buf.IsEmpty());
return rv;
} }
/* /*
@@ -949,32 +873,38 @@ DOMMediaListImpl::SetText(const nsAString& aMediaText)
* "all" medium or contain no media at all, which is the same as * "all" medium or contain no media at all, which is the same as
* containing "all" * containing "all"
*/ */
NS_IMETHODIMP PRBool
DOMMediaListImpl::MatchesMedium(nsIAtom* aMedium, PRBool* aMatch) nsMediaList::Matches(nsPresContext* aPresContext)
{ {
NS_ENSURE_ARG_POINTER(aMatch); if (-1 != mArray.IndexOf(aPresContext->Medium()) ||
*aMatch = PR_FALSE; -1 != mArray.IndexOf(nsLayoutAtoms::all))
*aMatch = (-1 != IndexOf(aMedium)) || return PR_TRUE;
(-1 != IndexOf(nsLayoutAtoms::all)); return mArray.Count() == 0;
if (*aMatch) }
nsresult
nsMediaList::SetStyleSheet(nsICSSStyleSheet *aSheet)
{
NS_ASSERTION(aSheet == mStyleSheet || !aSheet || !mStyleSheet,
"multiple style sheets competing for one media list");
mStyleSheet = NS_STATIC_CAST(nsCSSStyleSheet*, aSheet);
return NS_OK; return NS_OK;
PRUint32 count; }
nsresult rv = Count(&count);
if(NS_FAILED(rv)) nsresult
return rv; nsMediaList::Clone(nsMediaList** aResult)
*aMatch = (count == 0); {
nsRefPtr<nsMediaList> result = new nsMediaList();
if (!result)
return NS_ERROR_OUT_OF_MEMORY;
if (!result->mArray.AppendObjects(mArray))
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult = result);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
DOMMediaListImpl::DropReference() nsMediaList::GetMediaText(nsAString& aMediaText)
{
mStyleSheet = nsnull;
return NS_OK;
}
NS_IMETHODIMP
DOMMediaListImpl::GetMediaText(nsAString& aMediaText)
{ {
return GetText(aMediaText); return GetText(aMediaText);
} }
@@ -1003,7 +933,7 @@ DOMMediaListImpl::GetMediaText(nsAString& aMediaText)
NS_IMETHODIMP NS_IMETHODIMP
DOMMediaListImpl::SetMediaText(const nsAString& aMediaText) nsMediaList::SetMediaText(const nsAString& aMediaText)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsIDocument> doc;
@@ -1020,41 +950,29 @@ DOMMediaListImpl::SetMediaText(const nsAString& aMediaText)
} }
NS_IMETHODIMP NS_IMETHODIMP
DOMMediaListImpl::GetLength(PRUint32* aLength) nsMediaList::GetLength(PRUint32* aLength)
{ {
NS_ENSURE_ARG_POINTER(aLength); NS_ENSURE_ARG_POINTER(aLength);
PRUint32 cnt; *aLength = mArray.Count();
nsresult rv = Count(&cnt);
if (NS_FAILED(rv)) return rv;
*aLength = cnt;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
DOMMediaListImpl::Item(PRUint32 aIndex, nsAString& aReturn) nsMediaList::Item(PRUint32 aIndex, nsAString& aReturn)
{ {
nsCOMPtr<nsISupports> tmp(dont_AddRef(ElementAt(aIndex))); PRInt32 index = aIndex;
if (0 <= index && index < Count()) {
if (tmp) { MediumAt(aIndex)->ToString(aReturn);
nsCOMPtr<nsIAtom> medium(do_QueryInterface(tmp));
NS_ENSURE_TRUE(medium, NS_ERROR_FAILURE);
nsAutoString buffer;
medium->ToString(buffer);
aReturn.Assign(buffer);
} else { } else {
aReturn.Truncate(); SetDOMStringToNull(aReturn);
} }
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
DOMMediaListImpl::DeleteMedium(const nsAString& aOldMedium) nsMediaList::DeleteMedium(const nsAString& aOldMedium)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsIDocument> doc;
@@ -1071,7 +989,7 @@ DOMMediaListImpl::DeleteMedium(const nsAString& aOldMedium)
} }
NS_IMETHODIMP NS_IMETHODIMP
DOMMediaListImpl::AppendMedium(const nsAString& aNewMedium) nsMediaList::AppendMedium(const nsAString& aNewMedium)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsIDocument> doc;
@@ -1088,7 +1006,7 @@ DOMMediaListImpl::AppendMedium(const nsAString& aNewMedium)
} }
nsresult nsresult
DOMMediaListImpl::Delete(const nsAString& aOldMedium) nsMediaList::Delete(const nsAString& aOldMedium)
{ {
if (aOldMedium.IsEmpty()) if (aOldMedium.IsEmpty())
return NS_ERROR_DOM_NOT_FOUND_ERR; return NS_ERROR_DOM_NOT_FOUND_ERR;
@@ -1096,19 +1014,19 @@ DOMMediaListImpl::Delete(const nsAString& aOldMedium)
nsCOMPtr<nsIAtom> old = do_GetAtom(aOldMedium); nsCOMPtr<nsIAtom> old = do_GetAtom(aOldMedium);
NS_ENSURE_TRUE(old, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(old, NS_ERROR_OUT_OF_MEMORY);
PRInt32 indx = IndexOf(old); PRInt32 indx = mArray.IndexOf(old);
if (indx < 0) { if (indx < 0) {
return NS_ERROR_DOM_NOT_FOUND_ERR; return NS_ERROR_DOM_NOT_FOUND_ERR;
} }
RemoveElementAt(indx); mArray.RemoveObjectAt(indx);
return NS_OK; return NS_OK;
} }
nsresult nsresult
DOMMediaListImpl::Append(const nsAString& aNewMedium) nsMediaList::Append(const nsAString& aNewMedium)
{ {
if (aNewMedium.IsEmpty()) if (aNewMedium.IsEmpty())
return NS_ERROR_DOM_NOT_FOUND_ERR; return NS_ERROR_DOM_NOT_FOUND_ERR;
@@ -1116,13 +1034,13 @@ DOMMediaListImpl::Append(const nsAString& aNewMedium)
nsCOMPtr<nsIAtom> media = do_GetAtom(aNewMedium); nsCOMPtr<nsIAtom> media = do_GetAtom(aNewMedium);
NS_ENSURE_TRUE(media, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(media, NS_ERROR_OUT_OF_MEMORY);
PRInt32 indx = IndexOf(media); PRInt32 indx = mArray.IndexOf(media);
if (indx >= 0) { if (indx >= 0) {
RemoveElementAt(indx); mArray.RemoveObjectAt(indx);
} }
AppendElement(media); mArray.AppendObject(media);
return NS_OK; return NS_OK;
} }
@@ -1410,10 +1328,7 @@ nsCSSStyleSheet::nsCSSStyleSheet(const nsCSSStyleSheet& aCopy,
} }
if (aCopy.mMedia) { if (aCopy.mMedia) {
nsCOMPtr<nsISupportsArray> tmp; aCopy.mMedia->Clone(getter_AddRefs(mMedia));
(NS_STATIC_CAST(nsISupportsArray *, aCopy.mMedia))->Clone(getter_AddRefs(tmp));
mMedia = new DOMMediaListImpl(tmp, this);
NS_IF_ADDREF(mMedia);
} }
if (aCopy.mFirstChild) { if (aCopy.mFirstChild) {
@@ -1459,8 +1374,8 @@ nsCSSStyleSheet::~nsCSSStyleSheet()
NS_RELEASE(mImportsCollection); NS_RELEASE(mImportsCollection);
} }
if (mMedia) { if (mMedia) {
mMedia->DropReference(); mMedia->SetStyleSheet(nsnull);
NS_RELEASE(mMedia); mMedia = nsnull;
} }
mInner->RemoveSheet(this); mInner->RemoveSheet(this);
// XXX The document reference is not reference counted and should // XXX The document reference is not reference counted and should
@@ -1559,75 +1474,20 @@ nsCSSStyleSheet::GetType(nsString& aType) const
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsCSSStyleSheet::GetMediumCount(PRInt32& aCount) const
{
if (mMedia) {
PRUint32 cnt;
nsresult rv = mMedia->Count(&cnt);
if (NS_FAILED(rv)) return rv;
aCount = cnt;
}
else
aCount = 0;
return NS_OK;
}
NS_IMETHODIMP
nsCSSStyleSheet::GetMediumAt(PRInt32 aIndex, nsIAtom*& aMedium) const
{
nsIAtom* medium = nsnull;
if (nsnull != mMedia) {
medium = (nsIAtom*)mMedia->ElementAt(aIndex);
}
if (nsnull != medium) {
aMedium = medium;
return NS_OK;
}
aMedium = nsnull;
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP_(PRBool) NS_IMETHODIMP_(PRBool)
nsCSSStyleSheet::UseForMedium(nsIAtom* aMedium) const nsCSSStyleSheet::UseForMedium(nsPresContext* aPresContext) const
{ {
if (mMedia) { if (mMedia) {
PRBool matches = PR_FALSE; return mMedia->Matches(aPresContext);
mMedia->MatchesMedium(aMedium, &matches);
return matches;
} }
return PR_TRUE; return PR_TRUE;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsCSSStyleSheet::AppendMedium(nsIAtom* aMedium) nsCSSStyleSheet::SetMedia(nsMediaList* aMedia)
{ {
nsresult result = NS_OK; mMedia = aMedia;
if (!mMedia) {
nsCOMPtr<nsISupportsArray> tmp;
result = NS_NewISupportsArray(getter_AddRefs(tmp));
NS_ENSURE_SUCCESS(result, result);
mMedia = new DOMMediaListImpl(tmp, this);
NS_ENSURE_TRUE(mMedia, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(mMedia);
}
if (mMedia) {
mMedia->AppendElement(aMedium);
}
return result;
}
NS_IMETHODIMP
nsCSSStyleSheet::ClearMedia()
{
if (mMedia) {
mMedia->Clear();
}
return NS_OK; return NS_OK;
} }
@@ -2099,18 +1959,9 @@ void nsCSSStyleSheet::List(FILE* out, PRInt32 aIndent) const
if (mMedia) { if (mMedia) {
fputs(" media: ", out); fputs(" media: ", out);
index = 0;
PRUint32 count;
mMedia->Count(&count);
nsAutoString buffer; nsAutoString buffer;
while (index < PRInt32(count)) { mMedia->GetText(buffer);
nsCOMPtr<nsIAtom> medium = dont_AddRef((nsIAtom*)mMedia->ElementAt(index++)); fputs(NS_ConvertUTF16toUTF8(buffer).get(), out);
medium->ToString(buffer);
fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out);
if (index < PRInt32(count)) {
fputs(", ", out);
}
}
} }
fputs("\n", out); fputs("\n", out);
@@ -2271,16 +2122,13 @@ nsCSSStyleSheet::GetMedia(nsIDOMMediaList** aMedia)
*aMedia = nsnull; *aMedia = nsnull;
if (!mMedia) { if (!mMedia) {
nsCOMPtr<nsISupportsArray> tmp; mMedia = new nsMediaList();
NS_NewISupportsArray(getter_AddRefs(tmp)); NS_ENSURE_TRUE(mMedia, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_TRUE(tmp, NS_ERROR_NULL_POINTER); mMedia->SetStyleSheet(this);
mMedia = new DOMMediaListImpl(tmp, this);
NS_IF_ADDREF(mMedia);
} }
*aMedia = mMedia; *aMedia = mMedia;
NS_IF_ADDREF(*aMedia); NS_ADDREF(*aMedia);
return NS_OK; return NS_OK;
} }
@@ -3926,7 +3774,7 @@ CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData)
PRBool bSheetApplicable = PR_TRUE; PRBool bSheetApplicable = PR_TRUE;
sheet->GetApplicable(bSheetApplicable); sheet->GetApplicable(bSheetApplicable);
if (bSheetApplicable && sheet->UseForMedium(data->mPresContext->Medium())) { if (bSheetApplicable && sheet->UseForMedium(data->mPresContext)) {
nsCSSStyleSheet* child = sheet->mFirstChild; nsCSSStyleSheet* child = sheet->mFirstChild;
while (child) { while (child) {
CascadeSheetRulesInto(child, data); CascadeSheetRulesInto(child, data);

View File

@@ -52,6 +52,7 @@
class nsIURI; class nsIURI;
class nsISupportsArray; class nsISupportsArray;
class nsMediaList;
// ------------------------------- // -------------------------------
// CSS Style Sheet Inner Data Container // CSS Style Sheet Inner Data Container
@@ -84,7 +85,6 @@ public:
class CSSImportsCollectionImpl; class CSSImportsCollectionImpl;
class CSSRuleListImpl; class CSSRuleListImpl;
class DOMMediaListImpl;
static PRBool CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData); static PRBool CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData);
class nsCSSStyleSheet : public nsICSSStyleSheet, class nsCSSStyleSheet : public nsICSSStyleSheet,
@@ -101,9 +101,7 @@ public:
NS_IMETHOD GetBaseURI(nsIURI** aBaseURI) const; NS_IMETHOD GetBaseURI(nsIURI** aBaseURI) const;
NS_IMETHOD GetTitle(nsString& aTitle) const; NS_IMETHOD GetTitle(nsString& aTitle) const;
NS_IMETHOD GetType(nsString& aType) const; NS_IMETHOD GetType(nsString& aType) const;
NS_IMETHOD GetMediumCount(PRInt32& aCount) const; NS_IMETHOD_(PRBool) UseForMedium(nsPresContext* aPresContext) const;
NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsIAtom*& aMedium) const;
NS_IMETHOD_(PRBool) UseForMedium(nsIAtom* aMedium) const;
NS_IMETHOD_(PRBool) HasRules() const; NS_IMETHOD_(PRBool) HasRules() const;
NS_IMETHOD GetApplicable(PRBool& aApplicable) const; NS_IMETHOD GetApplicable(PRBool& aApplicable) const;
NS_IMETHOD SetEnabled(PRBool aEnabled); NS_IMETHOD SetEnabled(PRBool aEnabled);
@@ -133,8 +131,7 @@ public:
NS_IMETHOD GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const; NS_IMETHOD GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const;
NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI); NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI);
NS_IMETHOD SetTitle(const nsAString& aTitle); NS_IMETHOD SetTitle(const nsAString& aTitle);
NS_IMETHOD AppendMedium(nsIAtom* aMedium); NS_IMETHOD SetMedia(nsMediaList* aMedia);
NS_IMETHOD ClearMedia();
NS_IMETHOD SetOwningNode(nsIDOMNode* aOwningNode); NS_IMETHOD SetOwningNode(nsIDOMNode* aOwningNode);
NS_IMETHOD SetOwnerRule(nsICSSImportRule* aOwnerRule); NS_IMETHOD SetOwnerRule(nsICSSImportRule* aOwnerRule);
NS_IMETHOD GetOwnerRule(nsICSSImportRule** aOwnerRule); NS_IMETHOD GetOwnerRule(nsICSSImportRule** aOwnerRule);
@@ -181,7 +178,7 @@ protected:
protected: protected:
nsString mTitle; nsString mTitle;
DOMMediaListImpl* mMedia; nsCOMPtr<nsMediaList> mMedia;
nsCSSStyleSheet* mFirstChild; nsCSSStyleSheet* mFirstChild;
nsCSSStyleSheet* mNext; nsCSSStyleSheet* mNext;
nsICSSStyleSheet* mParent; // weak ref nsICSSStyleSheet* mParent; // weak ref
@@ -198,7 +195,7 @@ protected:
nsAutoVoidArray* mRuleProcessors; nsAutoVoidArray* mRuleProcessors;
friend class DOMMediaListImpl; friend class nsMediaList;
friend PRBool CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData); friend PRBool CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData);
}; };

View File

@@ -335,9 +335,7 @@ public:
NS_IMETHOD GetBaseURI(nsIURI** aBaseURL) const; NS_IMETHOD GetBaseURI(nsIURI** aBaseURL) const;
NS_IMETHOD GetTitle(nsString& aTitle) const; NS_IMETHOD GetTitle(nsString& aTitle) const;
NS_IMETHOD GetType(nsString& aType) const; NS_IMETHOD GetType(nsString& aType) const;
NS_IMETHOD GetMediumCount(PRInt32& aCount) const; NS_IMETHOD_(PRBool) UseForMedium(nsPresContext* aPresContext) const;
NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsIAtom*& aMedium) const;
NS_IMETHOD_(PRBool) UseForMedium(nsIAtom* aMedium) const;
NS_IMETHOD_(PRBool) HasRules() const; NS_IMETHOD_(PRBool) HasRules() const;
NS_IMETHOD GetApplicable(PRBool& aApplicable) const; NS_IMETHOD GetApplicable(PRBool& aApplicable) const;
@@ -532,22 +530,8 @@ HTMLCSSStyleSheetImpl::GetType(nsString& aType) const
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::GetMediumCount(PRInt32& aCount) const
{
aCount = 0;
return NS_OK;
}
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::GetMediumAt(PRInt32 aIndex, nsIAtom*& aMedium) const
{
aMedium = nsnull;
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP_(PRBool) NS_IMETHODIMP_(PRBool)
HTMLCSSStyleSheetImpl::UseForMedium(nsIAtom* aMedium) const HTMLCSSStyleSheetImpl::UseForMedium(nsPresContext* aPresContext) const
{ {
return PR_TRUE; // works for all media return PR_TRUE; // works for all media
} }

View File

@@ -581,22 +581,8 @@ nsHTMLStyleSheet::GetType(nsString& aType) const
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsHTMLStyleSheet::GetMediumCount(PRInt32& aCount) const
{
aCount = 0;
return NS_OK;
}
NS_IMETHODIMP
nsHTMLStyleSheet::GetMediumAt(PRInt32 aIndex, nsIAtom*& aMedium) const
{
aMedium = nsnull;
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP_(PRBool) NS_IMETHODIMP_(PRBool)
nsHTMLStyleSheet::UseForMedium(nsIAtom* aMedium) const nsHTMLStyleSheet::UseForMedium(nsPresContext* aPresContext) const
{ {
return PR_TRUE; // works for all media return PR_TRUE; // works for all media
} }

View File

@@ -58,9 +58,7 @@ public:
NS_IMETHOD GetBaseURI(nsIURI** aBaseURL) const; NS_IMETHOD GetBaseURI(nsIURI** aBaseURL) const;
NS_IMETHOD GetTitle(nsString& aTitle) const; NS_IMETHOD GetTitle(nsString& aTitle) const;
NS_IMETHOD GetType(nsString& aType) const; NS_IMETHOD GetType(nsString& aType) const;
NS_IMETHOD GetMediumCount(PRInt32& aCount) const; NS_IMETHOD_(PRBool) UseForMedium(nsPresContext* aPresContext) const;
NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsIAtom*& aMedium) const;
NS_IMETHOD_(PRBool) UseForMedium(nsIAtom* aMedium) const;
NS_IMETHOD_(PRBool) HasRules() const; NS_IMETHOD_(PRBool) HasRules() const;
NS_IMETHOD GetApplicable(PRBool& aApplicable) const; NS_IMETHOD GetApplicable(PRBool& aApplicable) const;
NS_IMETHOD SetEnabled(PRBool aEnabled); NS_IMETHOD SetEnabled(PRBool aEnabled);

View File

@@ -42,7 +42,7 @@
class nsIAtom; class nsIAtom;
class nsIURI; class nsIURI;
class nsISupportsArray; class nsMediaList;
// IID for the nsICSSImportRule interface {33824a60-1a09-11d3-805a-006008159b5a} // IID for the nsICSSImportRule interface {33824a60-1a09-11d3-805a-006008159b5a}
#define NS_ICSS_IMPORT_RULE_IID \ #define NS_ICSS_IMPORT_RULE_IID \
@@ -63,6 +63,6 @@ public:
nsresult nsresult
NS_NewCSSImportRule(nsICSSImportRule** aInstancePtrResult, NS_NewCSSImportRule(nsICSSImportRule** aInstancePtrResult,
const nsString& aURLSpec, nsISupportsArray* aMedia); const nsString& aURLSpec, nsMediaList* aMedia);
#endif /* nsICSSImportRule_h___ */ #endif /* nsICSSImportRule_h___ */

View File

@@ -38,7 +38,7 @@
#define nsICSSLoader_h___ #define nsICSSLoader_h___
#include "nsISupports.h" #include "nsISupports.h"
#include "nsAString.h" #include "nsSubstring.h"
#include "nsCompatibility.h" #include "nsCompatibility.h"
#include "nsICSSImportRule.h" #include "nsICSSImportRule.h"
@@ -52,11 +52,12 @@ class nsIParser;
class nsIDocument; class nsIDocument;
class nsIUnicharInputStream; class nsIUnicharInputStream;
class nsICSSLoaderObserver; class nsICSSLoaderObserver;
class nsISupportsArray; class nsMediaList;
// IID for the nsICSSLoader interface {a6e82061-46c9-4af6-8fd3-97ec5a7ba649} // IID for the nsICSSLoader interface
// 6c50f676-c764-4f2f-b62b-99d1076b44e9
#define NS_ICSS_LOADER_IID \ #define NS_ICSS_LOADER_IID \
{0xa6e82061, 0x46c9, 0x4af6, {0x8f, 0xd3, 0x97, 0xec, 0x5a, 0x7b, 0xa6, 0x49}} {0x6c50f676, 0xc764, 0x4f2f, {0xb6, 0x2b, 0x99, 0xd1, 0x07, 0x6b, 0x44, 0xe9}}
typedef void (*nsCSSLoaderCallbackFunc)(nsICSSStyleSheet* aSheet, void *aData, PRBool aDidNotify); typedef void (*nsCSSLoaderCallbackFunc)(nsICSSStyleSheet* aSheet, void *aData, PRBool aDidNotify);
@@ -87,8 +88,8 @@ public:
NS_IMETHOD LoadInlineStyle(nsIContent* aElement, NS_IMETHOD LoadInlineStyle(nsIContent* aElement,
nsIUnicharInputStream* aStream, nsIUnicharInputStream* aStream,
PRUint32 aLineNumber, PRUint32 aLineNumber,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aMedia, const nsSubstring& aMedia,
nsIParser* aParserToUnblock, nsIParser* aParserToUnblock,
PRBool& aCompleted, PRBool& aCompleted,
nsICSSLoaderObserver* aObserver) = 0; nsICSSLoaderObserver* aObserver) = 0;
@@ -100,8 +101,8 @@ public:
// will be marked complete when complete // will be marked complete when complete
NS_IMETHOD LoadStyleLink(nsIContent* aElement, NS_IMETHOD LoadStyleLink(nsIContent* aElement,
nsIURI* aURL, nsIURI* aURL,
const nsAString& aTitle, const nsSubstring& aTitle,
const nsAString& aMedia, const nsSubstring& aMedia,
nsIParser* aParserToUnblock, nsIParser* aParserToUnblock,
PRBool& aCompleted, PRBool& aCompleted,
nsICSSLoaderObserver* aObserver) = 0; nsICSSLoaderObserver* aObserver) = 0;
@@ -109,7 +110,7 @@ public:
// Load a child style sheet (@import) // Load a child style sheet (@import)
NS_IMETHOD LoadChildSheet(nsICSSStyleSheet* aParentSheet, NS_IMETHOD LoadChildSheet(nsICSSStyleSheet* aParentSheet,
nsIURI* aURL, nsIURI* aURL,
nsISupportsArray* aMedia, nsMediaList* aMedia,
nsICSSImportRule* aRule) = 0; nsICSSImportRule* aRule) = 0;
// Load a user agent or user sheet. The sheet is loaded // Load a user agent or user sheet. The sheet is loaded

View File

@@ -49,10 +49,11 @@ class nsCSSDeclaration;
class nsICSSLoader; class nsICSSLoader;
class nsICSSRule; class nsICSSRule;
class nsISupportsArray; class nsISupportsArray;
class nsMediaList;
#define NS_ICSS_PARSER_IID \ #define NS_ICSS_PARSER_IID \
{ 0xcc9c0610, 0x968c, 0x11d1, \ { 0x94d1d921, 0xd6f6, 0x435f, \
{0x93, 0x23, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} } {0xa5, 0xe8, 0x85, 0x3f, 0x6e, 0x34, 0x57, 0xf6} }
// Rule processing function // Rule processing function
typedef void (*PR_CALLBACK RuleAppendFunc) (nsICSSRule* aRule, void* aData); typedef void (*PR_CALLBACK RuleAppendFunc) (nsICSSRule* aRule, void* aData);
@@ -113,6 +114,19 @@ public:
nsIURI* aBaseURL, nsIURI* aBaseURL,
nsCSSDeclaration* aDeclaration, nsCSSDeclaration* aDeclaration,
PRBool* aChanged) = 0; PRBool* aChanged) = 0;
/**
* Parse aBuffer into a media list |aMediaList|, which must be
* non-null, replacing its current contents. If aHTMLMode is true,
* parse according to HTML rules, with commas as the most important
* delimiter. Otherwise, parse according to CSS rules, with
* parentheses and strings more important than commas.
*/
NS_IMETHOD ParseMediaList(const nsSubstring& aBuffer,
nsIURI* aURL, // for error reporting
PRUint32 aLineNumber, // for error reporting
nsMediaList* aMediaList,
PRBool aHTMLMode) = 0;
}; };
nsresult nsresult

View File

@@ -44,14 +44,14 @@ class nsICSSRule;
class nsIDOMNode; class nsIDOMNode;
class nsXMLNameSpaceMap; class nsXMLNameSpaceMap;
class nsCSSRuleProcessor; class nsCSSRuleProcessor;
class nsIMediaList; class nsMediaList;
class nsICSSGroupRule; class nsICSSGroupRule;
class nsICSSImportRule; class nsICSSImportRule;
// IID for the nsICSSStyleSheet interface // IID for the nsICSSStyleSheet interface
// 37f9b0f0-5d00-4abc-9246-35473031ffd7 // 446df065-af5e-46b8-b32f-289bf5906876
#define NS_ICSS_STYLE_SHEET_IID \ #define NS_ICSS_STYLE_SHEET_IID \
{0x37f9b0f0, 0x5d00, 0x4abc, {0x92, 0x46, 0x35, 0x47, 0x30, 0x31, 0xff, 0xd7}} {0x446df065, 0xaf5e, 0x46b8, {0xb3, 0x2f, 0x28, 0x9b, 0xf5, 0x90, 0x68, 0x76}}
class nsICSSStyleSheet : public nsIStyleSheet { class nsICSSStyleSheet : public nsIStyleSheet {
public: public:
@@ -84,8 +84,7 @@ public:
*/ */
NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) = 0; NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) = 0;
NS_IMETHOD SetTitle(const nsAString& aTitle) = 0; NS_IMETHOD SetTitle(const nsAString& aTitle) = 0;
NS_IMETHOD AppendMedium(nsIAtom* aMedium) = 0; NS_IMETHOD SetMedia(nsMediaList* aMedia) = 0;
NS_IMETHOD ClearMedia(void) = 0;
NS_IMETHOD SetOwningNode(nsIDOMNode* aOwningNode) = 0; NS_IMETHOD SetOwningNode(nsIDOMNode* aOwningNode) = 0;
NS_IMETHOD SetOwnerRule(nsICSSImportRule* aOwnerRule) = 0; NS_IMETHOD SetOwnerRule(nsICSSImportRule* aOwnerRule) = 0;

View File

@@ -35,33 +35,49 @@
* the terms of any one of the MPL, the GPL or the LGPL. * the terms of any one of the MPL, the GPL or the LGPL.
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#ifndef nsIMediaList_h___ #ifndef nsIMediaList_h_
#define nsIMediaList_h___ #define nsIMediaList_h_
#include "nsISupportsArray.h" #include "nsIDOMMediaList.h"
#include "nsAString.h"
#include "nsCOMArray.h"
#include "nsIAtom.h"
class nsPresContext;
class nsICSSStyleSheet;
class nsCSSStyleSheet;
// IID for the nsIMediaList interface {c8c2bbce-1dd1-11b2-a108-f7290a0e6da2} class nsMediaList : public nsIDOMMediaList {
#define NS_IMEDIA_LIST_IID \
{0xc8c2bbce, 0x1dd1, 0x11b2, {0xa1, 0x08, 0xf7, 0x29, 0x0a, 0x0e, 0x6d, 0xa2}}
class nsIMediaList : public nsISupportsArray {
public: public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMEDIA_LIST_IID) nsMediaList();
NS_IMETHOD GetText(nsAString& aMediaText) = 0; NS_DECL_ISUPPORTS
NS_IMETHOD SetText(const nsAString& aMediaText) = 0;
NS_IMETHOD MatchesMedium(nsIAtom* aMedium, PRBool* aMatch) = 0; NS_DECL_NSIDOMMEDIALIST
NS_IMETHOD DropReference(void) = 0;
nsresult GetText(nsAString& aMediaText);
nsresult SetText(const nsAString& aMediaText);
PRBool Matches(nsPresContext* aPresContext);
nsresult SetStyleSheet(nsICSSStyleSheet* aSheet);
nsresult AppendAtom(nsIAtom* aMediumAtom) {
return mArray.AppendObject(aMediumAtom) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
nsresult Clone(nsMediaList** aResult);
PRInt32 Count() { return mArray.Count(); }
nsIAtom* MediumAt(PRInt32 aIndex) { return mArray[aIndex]; }
void Clear() { mArray.Clear(); }
private:
~nsMediaList();
nsresult Delete(const nsAString & aOldMedium);
nsresult Append(const nsAString & aOldMedium);
nsCOMArray<nsIAtom> mArray;
// not refcounted; sheet will let us know when it goes away
// mStyleSheet is the sheet that needs to be dirtied when this medialist
// changes
nsCSSStyleSheet* mStyleSheet;
}; };
#endif /* !defined(nsIMediaList_h_) */
/* Use this macro when declaring classes that implement this interface. */
#define NS_DECL_NSIMEDIALIST \
NS_IMETHOD GetText(nsAString& aMediaText); \
NS_IMETHOD SetText(const nsAString& aMediaText); \
NS_IMETHOD MatchesMedium(nsIAtom* aMedium, PRBool* aMatch); \
NS_IMETHOD DropReference(void);
nsresult
NS_NewMediaList(nsISupportsArray* aArray, nsICSSStyleSheet* aSheet,
nsIMediaList** aInstancePtrResult);
#endif /* nsICSSLoader_h___ */

View File

@@ -51,9 +51,9 @@ class nsIDocument;
class nsIStyleRuleProcessor; class nsIStyleRuleProcessor;
// IID for the nsIStyleSheet interface // IID for the nsIStyleSheet interface
// 6fbfb2cb-a1c0-4576-9354-a4af4e0029ad // 93eea32f-681b-4405-b908-3933cf1d5091
#define NS_ISTYLE_SHEET_IID \ #define NS_ISTYLE_SHEET_IID \
{0x6fbfb2cb, 0xa1c0, 0x4576, {0x93, 0x54, 0xa4, 0xaf, 0x4e, 0x00, 0x29, 0xad}} {0x93eea32f, 0x681b, 0x4405, {0xb9, 0x08, 0x39, 0x33, 0xcf, 0x1d, 0x50, 0x91}}
/** /**
* A style sheet is a thing associated with a document that has style * A style sheet is a thing associated with a document that has style
@@ -72,9 +72,7 @@ public:
NS_IMETHOD GetBaseURI(nsIURI** aBaseURI) const = 0; NS_IMETHOD GetBaseURI(nsIURI** aBaseURI) const = 0;
NS_IMETHOD GetTitle(nsString& aTitle) const = 0; NS_IMETHOD GetTitle(nsString& aTitle) const = 0;
NS_IMETHOD GetType(nsString& aType) const = 0; NS_IMETHOD GetType(nsString& aType) const = 0;
NS_IMETHOD GetMediumCount(PRInt32& aCount) const = 0; NS_IMETHOD_(PRBool) UseForMedium(nsPresContext* aPresContext) const = 0;
NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsIAtom*& aMedium) const = 0;
NS_IMETHOD_(PRBool) UseForMedium(nsIAtom* aMedium) const = 0;
NS_IMETHOD_(PRBool) HasRules() const = 0; NS_IMETHOD_(PRBool) HasRules() const = 0;
/** /**

View File

@@ -41,7 +41,6 @@
#include "nsString.h" #include "nsString.h"
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsIStyleRule.h" #include "nsIStyleRule.h"
#include "nsISupportsArray.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"

View File

@@ -44,7 +44,6 @@
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsIDeviceContext.h" #include "nsIDeviceContext.h"
#include "nsIStyleRule.h" #include "nsIStyleRule.h"
#include "nsISupportsArray.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"