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
Родитель dda0b57a91
Коммит 4b1913ff77
24 изменённых файлов: 442 добавлений и 634 удалений

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -59,7 +59,6 @@
#include "nsContentUtils.h"
#include "nsCRT.h"
#include "nsCOMArray.h"
#include "nsISupportsArray.h"
#include "nsCOMPtr.h"
#include "nsIScriptSecurityManager.h"
#include "nsContentPolicyUtils.h"
@ -76,7 +75,7 @@
#include "nsIXULPrototypeCache.h"
#endif
#include "nsIDOMMediaList.h"
#include "nsIMediaList.h"
#include "nsIDOMStyleSheet.h"
#include "nsIDOMCSSStyleSheet.h"
#include "nsIDOMCSSImportRule.h"
@ -133,7 +132,7 @@ static const char* const gStateStrings[] = {
NS_IMPL_ISUPPORTS1(SheetLoadData, nsIUnicharStreamLoaderObserver)
SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
const nsAString& aTitle,
const nsSubstring& aTitle,
nsIParser* aParserToUnblock,
nsIURI* aURI,
nsICSSStyleSheet* aSheet,
@ -811,85 +810,6 @@ static PRBool IsChromeURI(nsIURI* aURI)
}
#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
CSSLoaderImpl::IsAlternate(const nsAString& aTitle)
{
@ -1064,27 +984,32 @@ CSSLoaderImpl::CreateSheet(nsIURI* aURI,
*/
nsresult
CSSLoaderImpl::PrepareSheet(nsICSSStyleSheet* aSheet,
const nsAString& aTitle,
const nsAString& aMedia,
nsISupportsArray* aMediaArr)
const nsSubstring& aTitle,
const nsSubstring& aMediaString,
nsMediaList* aMediaList)
{
NS_PRECONDITION(aSheet, "Must have a sheet!");
NS_PRECONDITION(aMedia.IsEmpty() || !aMediaArr,
"Can't have media array _and_ media string!");
nsresult rv = NS_OK;
aSheet->ClearMedia();
if (!aMedia.IsEmpty()) {
rv = EnumerateMediaString(aMedia, MediumEnumFunc, aSheet);
} else if (aMediaArr) {
PRUint32 count;
aMediaArr->Count(&count);
for (PRUint32 i = 0; i < count; ++i) {
nsCOMPtr<nsIAtom> medium = do_QueryElementAt(aMediaArr, i);
NS_ASSERTION(medium, "Null medium in media array!");
aSheet->AppendMedium(medium);
}
nsresult rv;
nsCOMPtr<nsMediaList> mediaList(aMediaList);
if (!aMediaString.IsEmpty()) {
NS_ASSERTION(!aMediaList,
"must not provide both aMediaString and aMediaList");
mediaList = new nsMediaList();
NS_ENSURE_TRUE(mediaList, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsICSSParser> mediumParser;
nsresult rv = GetParserFor(nsnull, getter_AddRefs(mediumParser));
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);
aSheet->SetTitle(aTitle);
@ -1576,8 +1501,8 @@ NS_IMETHODIMP
CSSLoaderImpl::LoadInlineStyle(nsIContent* aElement,
nsIUnicharInputStream* aStream,
PRUint32 aLineNumber,
const nsAString& aTitle,
const nsAString& aMedia,
const nsSubstring& aTitle,
const nsSubstring& aMedia,
nsIParser* aParserToUnblock,
PRBool& aCompleted,
nsICSSLoaderObserver* aObserver)
@ -1630,8 +1555,8 @@ CSSLoaderImpl::LoadInlineStyle(nsIContent* aElement,
NS_IMETHODIMP
CSSLoaderImpl::LoadStyleLink(nsIContent* aElement,
nsIURI* aURL,
const nsAString& aTitle,
const nsAString& aMedia,
const nsSubstring& aTitle,
const nsSubstring& aMedia,
nsIParser* aParserToUnblock,
PRBool& aCompleted,
nsICSSLoaderObserver* aObserver)
@ -1718,7 +1643,7 @@ CSSLoaderImpl::LoadStyleLink(nsIContent* aElement,
NS_IMETHODIMP
CSSLoaderImpl::LoadChildSheet(nsICSSStyleSheet* aParentSheet,
nsIURI* aURL,
nsISupportsArray* aMedia,
nsMediaList* aMedia,
nsICSSImportRule* aParentRule)
{
LOG(("CSSLoaderImpl::LoadChildSheet"));
@ -1805,7 +1730,7 @@ CSSLoaderImpl::LoadChildSheet(nsICSSStyleSheet* aParentSheet,
state, getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
const nsAString& empty = EmptyString();
const nsSubstring& empty = EmptyString();
rv = PrepareSheet(sheet, empty, empty, aMedia);
NS_ENSURE_SUCCESS(rv, rv);
@ -1877,7 +1802,7 @@ CSSLoaderImpl::InternalLoadAgentSheet(nsIURI* aURL,
getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
const nsAString& empty = EmptyString();
const nsSubstring& empty = EmptyString();
rv = PrepareSheet(sheet, empty, empty, nsnull);
NS_ENSURE_SUCCESS(rv, rv);

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

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

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

@ -74,6 +74,7 @@
#include "nsContentErrors.h"
#include "nsUnitConversion.h"
#include "nsPrintfCString.h"
#include "nsIMediaList.h"
#include "prprf.h"
#include "math.h"
@ -133,13 +134,27 @@ public:
nsCSSDeclaration* aDeclaration,
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);
protected:
nsresult InitScanner(nsIUnicharInputStream* aInput, nsIURI* aSheetURI,
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 DoParseMediaList(const nsSubstring& aBuffer,
nsIURI* aURL, // for error reporting
PRUint32 aLineNumber, // for error reporting
nsMediaList* aMediaList);
PRBool GetToken(nsresult& aErrorCode, PRBool aSkipWS);
PRBool GetURLToken(nsresult& aErrorCode, PRBool aSkipWS);
void UngetToken();
@ -160,10 +175,11 @@ protected:
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 GatherMedia(nsresult& aErrorCode, nsMediaList* aMedia,
PRUnichar aStopSymbol);
PRBool ProcessImport(nsresult& aErrorCode,
const nsString& aURLSpec,
nsISupportsArray* aMedia,
nsMediaList* aMedia,
RuleAppendFunc aAppendFunc,
void* aProcessData);
PRBool ParseGroupRule(nsresult& aErrorCode, nsICSSGroupRule* aRule, RuleAppendFunc aAppendFunc, void* aProcessData);
@ -374,6 +390,10 @@ protected:
PRPackedBool mSVGMode;
#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
PRPackedBool mCaseSensitive;
@ -471,6 +491,7 @@ CSSParserImpl::CSSParserImpl()
#ifdef MOZ_SVG
mSVGMode(PR_FALSE),
#endif
mHTMLMediaMode(PR_FALSE),
mCaseSensitive(PR_FALSE),
mParsingCompoundProperty(PR_FALSE)
#ifdef DEBUG
@ -552,6 +573,22 @@ CSSParserImpl::InitScanner(nsIUnicharInputStream* aInput, nsIURI* aSheetURI,
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
CSSParserImpl::ReleaseScanner(void)
{
@ -660,16 +697,8 @@ CSSParserImpl::ParseStyleAttribute(const nsAString& aAttributeValue,
{
NS_ASSERTION(nsnull != aBaseURL, "need base URL");
nsCOMPtr<nsIUnicharInputStream> input;
// Style attribute parsing 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),
&aAttributeValue, PR_FALSE);
if (NS_FAILED(rv)) {
return rv;
}
rv = InitScanner(input, aDocURL, 0, aBaseURL); // XXX line number
nsresult rv =
InitScanner(aAttributeValue, aDocURL, 0, aBaseURL); // XXX line number
if (! NS_SUCCEEDED(rv)) {
return rv;
}
@ -723,16 +752,7 @@ CSSParserImpl::ParseAndAppendDeclaration(const nsAString& aBuffer,
// NS_ASSERTION(nsnull != aBaseURL, "need base URL");
*aChanged = PR_FALSE;
nsCOMPtr<nsIUnicharInputStream> input;
// 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);
nsresult rv = InitScanner(aBuffer, aSheetURL, 0, aBaseURL);
if (! NS_SUCCEEDED(rv)) {
return rv;
}
@ -779,16 +799,7 @@ CSSParserImpl::ParseRule(const nsAString& aRule,
NS_ASSERTION(nsnull != aBaseURL, "need base URL");
NS_ENSURE_ARG_POINTER(aResult);
nsCOMPtr<nsIUnicharInputStream> input;
// 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);
nsresult rv = InitScanner(aRule, aSheetURL, 0, aBaseURL);
if (NS_FAILED(rv)) {
return rv;
}
@ -835,16 +846,7 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
NS_ASSERTION(nsnull != aDeclaration, "Need declaration to parse into!");
*aChanged = PR_FALSE;
nsCOMPtr<nsIUnicharInputStream> input;
// 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);
nsresult rv = InitScanner(aPropValue, aSheetURL, 0, aBaseURL);
if (NS_FAILED(rv)) {
return rv;
}
@ -889,6 +891,79 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
ReleaseScanner();
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)
@ -1110,79 +1185,67 @@ PRBool CSSParserImpl::GatherURL(nsresult& aErrorCode, nsString& aURL)
}
PRBool CSSParserImpl::GatherMedia(nsresult& aErrorCode,
nsISupportsArray* aMediaAtoms)
nsMediaList* aMedia,
PRUnichar aStopSymbol)
{
PRBool expectIdent = PR_TRUE;
for (;;) {
if (!GetToken(aErrorCode, PR_TRUE)) {
REPORT_UNEXPECTED_EOF(PEGatherMediaEOF);
break;
}
if (eCSSToken_Symbol == mToken.mType) {
PRUnichar symbol = mToken.mSymbol;
if ((';' == symbol) || ('{' == symbol)) {
UngetToken();
if (eCSSToken_Ident != mToken.mType) {
REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotIdent);
UngetToken();
break;
}
ToLowerCase(mToken.mIdent); // case insensitive from CSS - must be lower cased
nsCOMPtr<nsIAtom> medium = do_GetAtom(mToken.mIdent);
aMedia->AppendAtom(medium);
if (!GetToken(aErrorCode, PR_TRUE)) {
if (aStopSymbol == PRUnichar(0))
return PR_TRUE;
} else if (',' != symbol) {
REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotComma);
UngetToken();
break;
} else if (expectIdent) {
REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotIdent);
UngetToken();
break;
}
else {
expectIdent = PR_TRUE;
}
REPORT_UNEXPECTED_EOF(PEGatherMediaEOF);
break;
}
else if (eCSSToken_Ident == mToken.mType) {
if (expectIdent) {
ToLowerCase(mToken.mIdent); // case insensitive from CSS - must be lower cased
nsCOMPtr<nsIAtom> medium = do_GetAtom(mToken.mIdent);
aMediaAtoms->AppendElement(medium);
expectIdent = PR_FALSE;
}
else {
REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotComma);
UngetToken();
break;
}
}
else {
if (expectIdent)
REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotIdent);
else
REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotComma);
if (eCSSToken_Symbol == mToken.mType &&
mToken.mSymbol == aStopSymbol) {
UngetToken();
return PR_TRUE;
} else if (eCSSToken_Symbol != mToken.mType ||
mToken.mSymbol != ',') {
REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotComma);
UngetToken();
break;
}
}
aMediaAtoms->Clear();
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)
{
nsAutoString url;
nsCOMPtr<nsISupportsArray> media;
aErrorCode = NS_NewISupportsArray(getter_AddRefs(media));
nsCOMPtr<nsMediaList> media = new nsMediaList();
if (!media) {
// Out of memory
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
return PR_FALSE;
}
nsAutoString url;
if (!GatherURL(aErrorCode, url)) {
REPORT_UNEXPECTED_TOKEN(PEImportNotURI);
return PR_FALSE;
}
if (!GatherMedia(aErrorCode, media) ||
!ExpectSymbol(aErrorCode, ';', PR_TRUE)) {
REPORT_UNEXPECTED_TOKEN(PEImportUnexpected);
// don't advance section, simply ignore invalid @import
return PR_FALSE;
if (!ExpectSymbol(aErrorCode, ';', PR_TRUE)) {
if (!GatherMedia(aErrorCode, media, ';') ||
!ExpectSymbol(aErrorCode, ';', PR_TRUE)) {
REPORT_UNEXPECTED_TOKEN(PEImportUnexpected);
// don't advance section, simply ignore invalid @import
return PR_FALSE;
}
NS_ASSERTION(media->Count() != 0, "media list must be nonempty");
}
ProcessImport(aErrorCode, url, media, aAppendFunc, aData);
@ -1192,7 +1255,7 @@ PRBool CSSParserImpl::ParseImportRule(nsresult& aErrorCode, RuleAppendFunc aAppe
PRBool CSSParserImpl::ProcessImport(nsresult& aErrorCode,
const nsString& aURLSpec,
nsISupportsArray* aMedia,
nsMediaList* aMedia,
RuleAppendFunc aAppendFunc,
void* aData)
{
@ -1271,22 +1334,21 @@ PRBool CSSParserImpl::ParseMediaRule(nsresult& aErrorCode,
RuleAppendFunc aAppendFunc,
void* aData)
{
nsCOMPtr<nsISupportsArray> media;
aErrorCode = NS_NewISupportsArray(getter_AddRefs(media));
if (media) {
if (GatherMedia(aErrorCode, media)) {
// XXXbz this could use better error reporting throughout the method
PRUint32 count;
media->Count(&count);
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;
}
}
nsCOMPtr<nsMediaList> media = new nsMediaList();
if (!media) {
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
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
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;
}
}

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

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

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

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

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

@ -807,102 +807,38 @@ CSSRuleListImpl::Item(PRUint32 aIndex, nsIDOMCSSRule** aReturn)
return result;
}
class DOMMediaListImpl : public nsIDOMMediaList,
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_BEGIN(nsMediaList)
NS_INTERFACE_MAP_ENTRY(nsIDOMMediaList)
NS_INTERFACE_MAP_ENTRY(nsIMediaList)
NS_INTERFACE_MAP_ENTRY(nsISupportsArray)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMediaList)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(MediaList)
NS_INTERFACE_MAP_ENTRY(nsISerializable)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(DOMMediaListImpl)
NS_IMPL_RELEASE(DOMMediaListImpl)
NS_IMPL_ADDREF(nsMediaList)
NS_IMPL_RELEASE(nsMediaList)
DOMMediaListImpl::DOMMediaListImpl(nsISupportsArray *aArray,
nsCSSStyleSheet *aStyleSheet)
: mArray(aArray), mStyleSheet(aStyleSheet)
nsMediaList::nsMediaList()
: mStyleSheet(nsnull)
{
NS_ABORT_IF_FALSE(mArray, "This can't be used without an array!!");
}
DOMMediaListImpl::~DOMMediaListImpl()
nsMediaList::~nsMediaList()
{
}
nsresult
NS_NewMediaList(nsISupportsArray* aArray,
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)
nsMediaList::GetText(nsAString& aMediaText)
{
aMediaText.Truncate();
PRUint32 cnt;
nsresult rv = Count(&cnt);
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));
for (PRInt32 i = 0, i_end = mArray.Count(); i < i_end; ++i) {
nsIAtom* medium = mArray[i];
NS_ENSURE_TRUE(medium, NS_ERROR_FAILURE);
nsAutoString buffer;
medium->ToString(buffer);
aMediaText.Append(buffer);
if (index < count) {
if (i + 1 < i_end) {
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
// it should be doing....
NS_IMETHODIMP
DOMMediaListImpl::SetText(const nsAString& aMediaText)
nsresult
nsMediaList::SetText(const nsAString& aMediaText)
{
nsresult rv = Clear();
nsCOMPtr<nsICSSParser> parser;
nsresult rv = NS_NewCSSParser(getter_AddRefs(parser));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString buf(aMediaText);
PRInt32 n = buf.FindChar(',');
PRBool htmlMode = PR_FALSE;
nsCOMPtr<nsIDOMStyleSheet> domSheet =
do_QueryInterface(NS_STATIC_CAST(nsICSSStyleSheet*, mStyleSheet));
if (domSheet) {
nsCOMPtr<nsIDOMNode> node;
domSheet->GetOwnerNode(getter_AddRefs(node));
htmlMode = !!node;
}
do {
if (n < 0)
n = buf.Length();
nsAutoString tmp;
buf.Left(tmp, n);
tmp.CompressWhitespace();
if (!tmp.IsEmpty()) {
rv = Append(tmp);
NS_ENSURE_SUCCESS(rv, rv);
}
buf.Cut(0, n + 1);
n = buf.FindChar(',');
} while (!buf.IsEmpty());
return rv;
return parser->ParseMediaList(nsString(aMediaText), nsnull, 0,
this, htmlMode);
}
/*
@ -949,32 +873,38 @@ DOMMediaListImpl::SetText(const nsAString& aMediaText)
* "all" medium or contain no media at all, which is the same as
* containing "all"
*/
NS_IMETHODIMP
DOMMediaListImpl::MatchesMedium(nsIAtom* aMedium, PRBool* aMatch)
PRBool
nsMediaList::Matches(nsPresContext* aPresContext)
{
NS_ENSURE_ARG_POINTER(aMatch);
*aMatch = PR_FALSE;
*aMatch = (-1 != IndexOf(aMedium)) ||
(-1 != IndexOf(nsLayoutAtoms::all));
if (*aMatch)
return NS_OK;
PRUint32 count;
nsresult rv = Count(&count);
if(NS_FAILED(rv))
return rv;
*aMatch = (count == 0);
if (-1 != mArray.IndexOf(aPresContext->Medium()) ||
-1 != mArray.IndexOf(nsLayoutAtoms::all))
return PR_TRUE;
return mArray.Count() == 0;
}
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;
}
nsresult
nsMediaList::Clone(nsMediaList** aResult)
{
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;
}
NS_IMETHODIMP
DOMMediaListImpl::DropReference()
{
mStyleSheet = nsnull;
return NS_OK;
}
NS_IMETHODIMP
DOMMediaListImpl::GetMediaText(nsAString& aMediaText)
nsMediaList::GetMediaText(nsAString& aMediaText)
{
return GetText(aMediaText);
}
@ -1003,7 +933,7 @@ DOMMediaListImpl::GetMediaText(nsAString& aMediaText)
NS_IMETHODIMP
DOMMediaListImpl::SetMediaText(const nsAString& aMediaText)
nsMediaList::SetMediaText(const nsAString& aMediaText)
{
nsresult rv = NS_OK;
nsCOMPtr<nsIDocument> doc;
@ -1020,41 +950,29 @@ DOMMediaListImpl::SetMediaText(const nsAString& aMediaText)
}
NS_IMETHODIMP
DOMMediaListImpl::GetLength(PRUint32* aLength)
nsMediaList::GetLength(PRUint32* aLength)
{
NS_ENSURE_ARG_POINTER(aLength);
PRUint32 cnt;
nsresult rv = Count(&cnt);
if (NS_FAILED(rv)) return rv;
*aLength = cnt;
*aLength = mArray.Count();
return NS_OK;
}
NS_IMETHODIMP
DOMMediaListImpl::Item(PRUint32 aIndex, nsAString& aReturn)
nsMediaList::Item(PRUint32 aIndex, nsAString& aReturn)
{
nsCOMPtr<nsISupports> tmp(dont_AddRef(ElementAt(aIndex)));
if (tmp) {
nsCOMPtr<nsIAtom> medium(do_QueryInterface(tmp));
NS_ENSURE_TRUE(medium, NS_ERROR_FAILURE);
nsAutoString buffer;
medium->ToString(buffer);
aReturn.Assign(buffer);
PRInt32 index = aIndex;
if (0 <= index && index < Count()) {
MediumAt(aIndex)->ToString(aReturn);
} else {
aReturn.Truncate();
SetDOMStringToNull(aReturn);
}
return NS_OK;
}
NS_IMETHODIMP
DOMMediaListImpl::DeleteMedium(const nsAString& aOldMedium)
nsMediaList::DeleteMedium(const nsAString& aOldMedium)
{
nsresult rv = NS_OK;
nsCOMPtr<nsIDocument> doc;
@ -1071,7 +989,7 @@ DOMMediaListImpl::DeleteMedium(const nsAString& aOldMedium)
}
NS_IMETHODIMP
DOMMediaListImpl::AppendMedium(const nsAString& aNewMedium)
nsMediaList::AppendMedium(const nsAString& aNewMedium)
{
nsresult rv = NS_OK;
nsCOMPtr<nsIDocument> doc;
@ -1088,7 +1006,7 @@ DOMMediaListImpl::AppendMedium(const nsAString& aNewMedium)
}
nsresult
DOMMediaListImpl::Delete(const nsAString& aOldMedium)
nsMediaList::Delete(const nsAString& aOldMedium)
{
if (aOldMedium.IsEmpty())
return NS_ERROR_DOM_NOT_FOUND_ERR;
@ -1096,19 +1014,19 @@ DOMMediaListImpl::Delete(const nsAString& aOldMedium)
nsCOMPtr<nsIAtom> old = do_GetAtom(aOldMedium);
NS_ENSURE_TRUE(old, NS_ERROR_OUT_OF_MEMORY);
PRInt32 indx = IndexOf(old);
PRInt32 indx = mArray.IndexOf(old);
if (indx < 0) {
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
RemoveElementAt(indx);
mArray.RemoveObjectAt(indx);
return NS_OK;
}
nsresult
DOMMediaListImpl::Append(const nsAString& aNewMedium)
nsMediaList::Append(const nsAString& aNewMedium)
{
if (aNewMedium.IsEmpty())
return NS_ERROR_DOM_NOT_FOUND_ERR;
@ -1116,13 +1034,13 @@ DOMMediaListImpl::Append(const nsAString& aNewMedium)
nsCOMPtr<nsIAtom> media = do_GetAtom(aNewMedium);
NS_ENSURE_TRUE(media, NS_ERROR_OUT_OF_MEMORY);
PRInt32 indx = IndexOf(media);
PRInt32 indx = mArray.IndexOf(media);
if (indx >= 0) {
RemoveElementAt(indx);
mArray.RemoveObjectAt(indx);
}
AppendElement(media);
mArray.AppendObject(media);
return NS_OK;
}
@ -1410,10 +1328,7 @@ nsCSSStyleSheet::nsCSSStyleSheet(const nsCSSStyleSheet& aCopy,
}
if (aCopy.mMedia) {
nsCOMPtr<nsISupportsArray> tmp;
(NS_STATIC_CAST(nsISupportsArray *, aCopy.mMedia))->Clone(getter_AddRefs(tmp));
mMedia = new DOMMediaListImpl(tmp, this);
NS_IF_ADDREF(mMedia);
aCopy.mMedia->Clone(getter_AddRefs(mMedia));
}
if (aCopy.mFirstChild) {
@ -1459,8 +1374,8 @@ nsCSSStyleSheet::~nsCSSStyleSheet()
NS_RELEASE(mImportsCollection);
}
if (mMedia) {
mMedia->DropReference();
NS_RELEASE(mMedia);
mMedia->SetStyleSheet(nsnull);
mMedia = nsnull;
}
mInner->RemoveSheet(this);
// XXX The document reference is not reference counted and should
@ -1559,75 +1474,20 @@ nsCSSStyleSheet::GetType(nsString& aType) const
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)
nsCSSStyleSheet::UseForMedium(nsIAtom* aMedium) const
nsCSSStyleSheet::UseForMedium(nsPresContext* aPresContext) const
{
if (mMedia) {
PRBool matches = PR_FALSE;
mMedia->MatchesMedium(aMedium, &matches);
return matches;
return mMedia->Matches(aPresContext);
}
return PR_TRUE;
}
NS_IMETHODIMP
nsCSSStyleSheet::AppendMedium(nsIAtom* aMedium)
nsCSSStyleSheet::SetMedia(nsMediaList* aMedia)
{
nsresult result = NS_OK;
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();
}
mMedia = aMedia;
return NS_OK;
}
@ -2099,18 +1959,9 @@ void nsCSSStyleSheet::List(FILE* out, PRInt32 aIndent) const
if (mMedia) {
fputs(" media: ", out);
index = 0;
PRUint32 count;
mMedia->Count(&count);
nsAutoString buffer;
while (index < PRInt32(count)) {
nsCOMPtr<nsIAtom> medium = dont_AddRef((nsIAtom*)mMedia->ElementAt(index++));
medium->ToString(buffer);
fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out);
if (index < PRInt32(count)) {
fputs(", ", out);
}
}
mMedia->GetText(buffer);
fputs(NS_ConvertUTF16toUTF8(buffer).get(), out);
}
fputs("\n", out);
@ -2271,16 +2122,13 @@ nsCSSStyleSheet::GetMedia(nsIDOMMediaList** aMedia)
*aMedia = nsnull;
if (!mMedia) {
nsCOMPtr<nsISupportsArray> tmp;
NS_NewISupportsArray(getter_AddRefs(tmp));
NS_ENSURE_TRUE(tmp, NS_ERROR_NULL_POINTER);
mMedia = new DOMMediaListImpl(tmp, this);
NS_IF_ADDREF(mMedia);
mMedia = new nsMediaList();
NS_ENSURE_TRUE(mMedia, NS_ERROR_OUT_OF_MEMORY);
mMedia->SetStyleSheet(this);
}
*aMedia = mMedia;
NS_IF_ADDREF(*aMedia);
NS_ADDREF(*aMedia);
return NS_OK;
}
@ -3926,7 +3774,7 @@ CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData)
PRBool bSheetApplicable = PR_TRUE;
sheet->GetApplicable(bSheetApplicable);
if (bSheetApplicable && sheet->UseForMedium(data->mPresContext->Medium())) {
if (bSheetApplicable && sheet->UseForMedium(data->mPresContext)) {
nsCSSStyleSheet* child = sheet->mFirstChild;
while (child) {
CascadeSheetRulesInto(child, data);

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

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

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

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

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

@ -581,22 +581,8 @@ nsHTMLStyleSheet::GetType(nsString& aType) const
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)
nsHTMLStyleSheet::UseForMedium(nsIAtom* aMedium) const
nsHTMLStyleSheet::UseForMedium(nsPresContext* aPresContext) const
{
return PR_TRUE; // works for all media
}

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

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

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

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

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

@ -38,7 +38,7 @@
#define nsICSSLoader_h___
#include "nsISupports.h"
#include "nsAString.h"
#include "nsSubstring.h"
#include "nsCompatibility.h"
#include "nsICSSImportRule.h"
@ -52,11 +52,12 @@ class nsIParser;
class nsIDocument;
class nsIUnicharInputStream;
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 \
{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);
@ -87,8 +88,8 @@ public:
NS_IMETHOD LoadInlineStyle(nsIContent* aElement,
nsIUnicharInputStream* aStream,
PRUint32 aLineNumber,
const nsAString& aTitle,
const nsAString& aMedia,
const nsSubstring& aTitle,
const nsSubstring& aMedia,
nsIParser* aParserToUnblock,
PRBool& aCompleted,
nsICSSLoaderObserver* aObserver) = 0;
@ -100,8 +101,8 @@ public:
// will be marked complete when complete
NS_IMETHOD LoadStyleLink(nsIContent* aElement,
nsIURI* aURL,
const nsAString& aTitle,
const nsAString& aMedia,
const nsSubstring& aTitle,
const nsSubstring& aMedia,
nsIParser* aParserToUnblock,
PRBool& aCompleted,
nsICSSLoaderObserver* aObserver) = 0;
@ -109,7 +110,7 @@ public:
// Load a child style sheet (@import)
NS_IMETHOD LoadChildSheet(nsICSSStyleSheet* aParentSheet,
nsIURI* aURL,
nsISupportsArray* aMedia,
nsMediaList* aMedia,
nsICSSImportRule* aRule) = 0;
// Load a user agent or user sheet. The sheet is loaded

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

@ -49,10 +49,11 @@ class nsCSSDeclaration;
class nsICSSLoader;
class nsICSSRule;
class nsISupportsArray;
class nsMediaList;
#define NS_ICSS_PARSER_IID \
{ 0xcc9c0610, 0x968c, 0x11d1, \
{0x93, 0x23, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
{ 0x94d1d921, 0xd6f6, 0x435f, \
{0xa5, 0xe8, 0x85, 0x3f, 0x6e, 0x34, 0x57, 0xf6} }
// Rule processing function
typedef void (*PR_CALLBACK RuleAppendFunc) (nsICSSRule* aRule, void* aData);
@ -113,6 +114,19 @@ public:
nsIURI* aBaseURL,
nsCSSDeclaration* aDeclaration,
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

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

@ -44,14 +44,14 @@ class nsICSSRule;
class nsIDOMNode;
class nsXMLNameSpaceMap;
class nsCSSRuleProcessor;
class nsIMediaList;
class nsMediaList;
class nsICSSGroupRule;
class nsICSSImportRule;
// IID for the nsICSSStyleSheet interface
// 37f9b0f0-5d00-4abc-9246-35473031ffd7
// 446df065-af5e-46b8-b32f-289bf5906876
#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 {
public:
@ -84,8 +84,7 @@ public:
*/
NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) = 0;
NS_IMETHOD SetTitle(const nsAString& aTitle) = 0;
NS_IMETHOD AppendMedium(nsIAtom* aMedium) = 0;
NS_IMETHOD ClearMedia(void) = 0;
NS_IMETHOD SetMedia(nsMediaList* aMedia) = 0;
NS_IMETHOD SetOwningNode(nsIDOMNode* aOwningNode) = 0;
NS_IMETHOD SetOwnerRule(nsICSSImportRule* aOwnerRule) = 0;

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

@ -35,33 +35,49 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsIMediaList_h___
#define nsIMediaList_h___
#ifndef 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}
#define NS_IMEDIA_LIST_IID \
{0xc8c2bbce, 0x1dd1, 0x11b2, {0xa1, 0x08, 0xf7, 0x29, 0x0a, 0x0e, 0x6d, 0xa2}}
class nsIMediaList : public nsISupportsArray {
class nsMediaList : public nsIDOMMediaList {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMEDIA_LIST_IID)
nsMediaList();
NS_IMETHOD GetText(nsAString& aMediaText) = 0;
NS_IMETHOD SetText(const nsAString& aMediaText) = 0;
NS_IMETHOD MatchesMedium(nsIAtom* aMedium, PRBool* aMatch) = 0;
NS_IMETHOD DropReference(void) = 0;
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMMEDIALIST
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;
};
/* 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___ */
#endif /* !defined(nsIMediaList_h_) */

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

@ -51,9 +51,9 @@ class nsIDocument;
class nsIStyleRuleProcessor;
// IID for the nsIStyleSheet interface
// 6fbfb2cb-a1c0-4576-9354-a4af4e0029ad
// 93eea32f-681b-4405-b908-3933cf1d5091
#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
@ -72,9 +72,7 @@ public:
NS_IMETHOD GetBaseURI(nsIURI** aBaseURI) const = 0;
NS_IMETHOD GetTitle(nsString& aTitle) const = 0;
NS_IMETHOD GetType(nsString& aType) const = 0;
NS_IMETHOD GetMediumCount(PRInt32& aCount) const = 0;
NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsIAtom*& aMedium) const = 0;
NS_IMETHOD_(PRBool) UseForMedium(nsIAtom* aMedium) const = 0;
NS_IMETHOD_(PRBool) UseForMedium(nsPresContext* aPresContext) const = 0;
NS_IMETHOD_(PRBool) HasRules() const = 0;
/**

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

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

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

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