diff --git a/content/html/style/public/nsICSSStyleSheet.h b/content/html/style/public/nsICSSStyleSheet.h index e78eae41fdbf..70c89e876e7d 100644 --- a/content/html/style/public/nsICSSStyleSheet.h +++ b/content/html/style/public/nsICSSStyleSheet.h @@ -76,7 +76,12 @@ public: NS_IMETHOD StyleSheetCount(PRInt32& aCount) const = 0; NS_IMETHOD GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const = 0; - NS_IMETHOD Init(nsIURI* aURL) = 0; + /** + * SetURL must be called on all sheets before parsing into them. + * SetURL may only be called while the sheet is 1) incomplete and 2) + * has no rules in it + */ + NS_IMETHOD SetURL(nsIURI* aURL) = 0; NS_IMETHOD SetTitle(const nsAString& aTitle) = 0; NS_IMETHOD AppendMedium(nsIAtom* aMedium) = 0; NS_IMETHOD ClearMedia(void) = 0; diff --git a/content/html/style/src/nsCSSLoader.cpp b/content/html/style/src/nsCSSLoader.cpp index 0e0548041670..351640e5733b 100644 --- a/content/html/style/src/nsCSSLoader.cpp +++ b/content/html/style/src/nsCSSLoader.cpp @@ -782,10 +782,14 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader, return NS_OK; } + if (channelURI) { + // Enough to set the URI on mSheet, since any sibling datas we have share + // the same mInner as mSheet and will thus get the same URI. + mSheet->SetURL(channelURI); + } + PRBool completed; - return mLoader->ParseSheet(aDataStream, this, - channelURI ? channelURI : mURI, - completed); + return mLoader->ParseSheet(aDataStream, this, completed); } #ifdef MOZ_XUL @@ -1035,8 +1039,15 @@ CSSLoaderImpl::CreateSheet(nsIURI* aURI, if (!*aSheet) { aSheetState = eSheetNeedsParser; - rv = NS_NewCSSStyleSheet(aSheet); // Don't init the sheet here, but in - // ParseSheet once we know the final URI + nsCOMPtr sheetURI = aURI; + if (!sheetURI) { + // Inline style. Use the document's base URL so that @import in + // the inline sheet picks up the right base. + NS_ASSERTION(aLinkingContent, "Inline stylesheet without linking content?"); + aLinkingContent->GetBaseURL(getter_AddRefs(sheetURI)); + } + + rv = NS_NewCSSStyleSheet(aSheet, sheetURI); NS_ENSURE_SUCCESS(rv, rv); } @@ -1271,7 +1282,7 @@ CSSLoaderImpl::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState) } PRBool completed; - rv = ParseSheet(converterStream, aLoadData, aLoadData->mURI, completed); + rv = ParseSheet(converterStream, aLoadData, completed); NS_ASSERTION(completed, "sync load did not complete"); return rv; } @@ -1392,25 +1403,17 @@ CSSLoaderImpl::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState) nsresult CSSLoaderImpl::ParseSheet(nsIUnicharInputStream* aStream, SheetLoadData* aLoadData, - nsIURI* aSheetURI, PRBool& aCompleted) { LOG(("CSSLoaderImpl::ParseSheet")); NS_PRECONDITION(aStream, "Must have data to parse"); NS_PRECONDITION(aLoadData, "Must have load data"); - NS_PRECONDITION(aSheetURI, "Must have sheet URI"); NS_PRECONDITION(aLoadData->mSheet, "Must have sheet to parse into"); aCompleted = PR_FALSE; - // Init the sheet with the correct URI so that the relative URIs in - // it will be resolved properly. - nsresult rv = aLoadData->mSheet->Init(aSheetURI); - NS_ASSERTION(NS_SUCCEEDED(rv), - "If this is failing, something has gone terribly wrong"); - nsCOMPtr parser; - rv = GetParserFor(aLoadData->mSheet, getter_AddRefs(parser)); + nsresult rv = GetParserFor(aLoadData->mSheet, getter_AddRefs(parser)); if (NS_FAILED(rv)) { LOG_ERROR((" Failed to get CSS parser")); SheetComplete(aLoadData, PR_FALSE); @@ -1422,7 +1425,9 @@ CSSLoaderImpl::ParseSheet(nsIUnicharInputStream* aStream, nsCOMPtr dummySheet; // Push our load data on the stack so any kids can pick it up mParsingDatas.AppendElement(aLoadData); - rv = parser->Parse(aStream, aSheetURI, *getter_AddRefs(dummySheet)); + nsCOMPtr uri; + aLoadData->mSheet->GetURL(*getter_AddRefs(uri)); + rv = parser->Parse(aStream, uri, *getter_AddRefs(dummySheet)); mParsingDatas.RemoveElementAt(mParsingDatas.Count() - 1); RecycleParser(parser); @@ -1610,12 +1615,9 @@ CSSLoaderImpl::LoadInlineStyle(nsIContent* aElement, return NS_ERROR_OUT_OF_MEMORY; } - nsCOMPtr baseURI; - aElement->GetBaseURL(getter_AddRefs(baseURI)); - NS_ADDREF(data); // Parse completion releases the load data - return ParseSheet(aStream, data, baseURI, aCompleted); + return ParseSheet(aStream, data, aCompleted); } NS_IMETHODIMP diff --git a/content/html/style/src/nsCSSLoader.h b/content/html/style/src/nsCSSLoader.h index 5c4cec551b21..ba87ea84c8db 100644 --- a/content/html/style/src/nsCSSLoader.h +++ b/content/html/style/src/nsCSSLoader.h @@ -286,7 +286,6 @@ protected: // access to nsresult ParseSheet(nsIUnicharInputStream* aStream, SheetLoadData* aLoadData, - nsIURI* aSheetURI, PRBool& aCompleted); public: diff --git a/content/html/style/src/nsCSSStyleSheet.cpp b/content/html/style/src/nsCSSStyleSheet.cpp index 23ef8b8dadfd..76b5a6696fbf 100644 --- a/content/html/style/src/nsCSSStyleSheet.cpp +++ b/content/html/style/src/nsCSSStyleSheet.cpp @@ -805,7 +805,7 @@ public: NS_DECL_ISUPPORTS // basic style sheet data - NS_IMETHOD Init(nsIURI* aURL); + NS_IMETHOD SetURL(nsIURI* aURL); NS_IMETHOD GetURL(nsIURI*& aURL) const; NS_IMETHOD GetTitle(nsString& aTitle) const; NS_IMETHOD SetTitle(const nsAString& aTitle); @@ -1780,7 +1780,7 @@ CSSStyleSheetImpl::DropRuleProcessorReference(nsICSSStyleRuleProcessor* aProcess NS_IMETHODIMP -CSSStyleSheetImpl::Init(nsIURI* aURL) +CSSStyleSheetImpl::SetURL(nsIURI* aURL) { NS_PRECONDITION(aURL, "null ptr"); if (! aURL) @@ -1790,9 +1790,8 @@ CSSStyleSheetImpl::Init(nsIURI* aURL) return NS_ERROR_OUT_OF_MEMORY; } - NS_ASSERTION(! mInner->mURL, "already initialized"); - if (mInner->mURL) - return NS_ERROR_ALREADY_INITIALIZED; + NS_ASSERTION(!mInner->mOrderedRules && !mInner->mComplete, + "Can't call SetURL on sheets that are complete or have rules"); mInner->mURL = aURL; return NS_OK; @@ -3059,7 +3058,7 @@ NS_NewCSSStyleSheet(nsICSSStyleSheet** aInstancePtrResult, nsIURI* aURL) if (NS_FAILED(rv = NS_NewCSSStyleSheet(&sheet))) return rv; - if (NS_FAILED(rv = sheet->Init(aURL))) { + if (NS_FAILED(rv = sheet->SetURL(aURL))) { NS_RELEASE(sheet); return rv; } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index dd01fcb253b0..9601fcb2c2de 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -2229,7 +2229,7 @@ nsresult PresShell::CreatePreferenceStyleSheet(void) result = NS_NewURI(getter_AddRefs(uri), "about:PreferenceStyleSheet", nsnull); if (NS_SUCCEEDED(result)) { NS_ASSERTION(uri, "null but no error"); - result = mPrefStyleSheet->Init(uri); + result = mPrefStyleSheet->SetURL(uri); if (NS_SUCCEEDED(result)) { mPrefStyleSheet->SetComplete(); nsCOMPtr sheet(do_QueryInterface(mPrefStyleSheet)); diff --git a/layout/html/base/src/nsPresShell.cpp b/layout/html/base/src/nsPresShell.cpp index dd01fcb253b0..9601fcb2c2de 100644 --- a/layout/html/base/src/nsPresShell.cpp +++ b/layout/html/base/src/nsPresShell.cpp @@ -2229,7 +2229,7 @@ nsresult PresShell::CreatePreferenceStyleSheet(void) result = NS_NewURI(getter_AddRefs(uri), "about:PreferenceStyleSheet", nsnull); if (NS_SUCCEEDED(result)) { NS_ASSERTION(uri, "null but no error"); - result = mPrefStyleSheet->Init(uri); + result = mPrefStyleSheet->SetURL(uri); if (NS_SUCCEEDED(result)) { mPrefStyleSheet->SetComplete(); nsCOMPtr sheet(do_QueryInterface(mPrefStyleSheet)); diff --git a/layout/mathml/base/src/nsMathMLFrame.cpp b/layout/mathml/base/src/nsMathMLFrame.cpp index a6316c0d9d01..33ac8a807c47 100644 --- a/layout/mathml/base/src/nsMathMLFrame.cpp +++ b/layout/mathml/base/src/nsMathMLFrame.cpp @@ -534,7 +534,7 @@ GetMathMLAttributeStyleSheet(nsIPresContext* aPresContext, nsCOMPtr cssSheet(do_CreateInstance(kCSSStyleSheetCID)); if (!cssSheet) return; - cssSheet->Init(uri); + cssSheet->SetURL(uri); nsCOMPtr domSheet(do_QueryInterface(cssSheet)); if (domSheet) { PRUint32 index; diff --git a/layout/style/nsCSSLoader.cpp b/layout/style/nsCSSLoader.cpp index 0e0548041670..351640e5733b 100644 --- a/layout/style/nsCSSLoader.cpp +++ b/layout/style/nsCSSLoader.cpp @@ -782,10 +782,14 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader, return NS_OK; } + if (channelURI) { + // Enough to set the URI on mSheet, since any sibling datas we have share + // the same mInner as mSheet and will thus get the same URI. + mSheet->SetURL(channelURI); + } + PRBool completed; - return mLoader->ParseSheet(aDataStream, this, - channelURI ? channelURI : mURI, - completed); + return mLoader->ParseSheet(aDataStream, this, completed); } #ifdef MOZ_XUL @@ -1035,8 +1039,15 @@ CSSLoaderImpl::CreateSheet(nsIURI* aURI, if (!*aSheet) { aSheetState = eSheetNeedsParser; - rv = NS_NewCSSStyleSheet(aSheet); // Don't init the sheet here, but in - // ParseSheet once we know the final URI + nsCOMPtr sheetURI = aURI; + if (!sheetURI) { + // Inline style. Use the document's base URL so that @import in + // the inline sheet picks up the right base. + NS_ASSERTION(aLinkingContent, "Inline stylesheet without linking content?"); + aLinkingContent->GetBaseURL(getter_AddRefs(sheetURI)); + } + + rv = NS_NewCSSStyleSheet(aSheet, sheetURI); NS_ENSURE_SUCCESS(rv, rv); } @@ -1271,7 +1282,7 @@ CSSLoaderImpl::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState) } PRBool completed; - rv = ParseSheet(converterStream, aLoadData, aLoadData->mURI, completed); + rv = ParseSheet(converterStream, aLoadData, completed); NS_ASSERTION(completed, "sync load did not complete"); return rv; } @@ -1392,25 +1403,17 @@ CSSLoaderImpl::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState) nsresult CSSLoaderImpl::ParseSheet(nsIUnicharInputStream* aStream, SheetLoadData* aLoadData, - nsIURI* aSheetURI, PRBool& aCompleted) { LOG(("CSSLoaderImpl::ParseSheet")); NS_PRECONDITION(aStream, "Must have data to parse"); NS_PRECONDITION(aLoadData, "Must have load data"); - NS_PRECONDITION(aSheetURI, "Must have sheet URI"); NS_PRECONDITION(aLoadData->mSheet, "Must have sheet to parse into"); aCompleted = PR_FALSE; - // Init the sheet with the correct URI so that the relative URIs in - // it will be resolved properly. - nsresult rv = aLoadData->mSheet->Init(aSheetURI); - NS_ASSERTION(NS_SUCCEEDED(rv), - "If this is failing, something has gone terribly wrong"); - nsCOMPtr parser; - rv = GetParserFor(aLoadData->mSheet, getter_AddRefs(parser)); + nsresult rv = GetParserFor(aLoadData->mSheet, getter_AddRefs(parser)); if (NS_FAILED(rv)) { LOG_ERROR((" Failed to get CSS parser")); SheetComplete(aLoadData, PR_FALSE); @@ -1422,7 +1425,9 @@ CSSLoaderImpl::ParseSheet(nsIUnicharInputStream* aStream, nsCOMPtr dummySheet; // Push our load data on the stack so any kids can pick it up mParsingDatas.AppendElement(aLoadData); - rv = parser->Parse(aStream, aSheetURI, *getter_AddRefs(dummySheet)); + nsCOMPtr uri; + aLoadData->mSheet->GetURL(*getter_AddRefs(uri)); + rv = parser->Parse(aStream, uri, *getter_AddRefs(dummySheet)); mParsingDatas.RemoveElementAt(mParsingDatas.Count() - 1); RecycleParser(parser); @@ -1610,12 +1615,9 @@ CSSLoaderImpl::LoadInlineStyle(nsIContent* aElement, return NS_ERROR_OUT_OF_MEMORY; } - nsCOMPtr baseURI; - aElement->GetBaseURL(getter_AddRefs(baseURI)); - NS_ADDREF(data); // Parse completion releases the load data - return ParseSheet(aStream, data, baseURI, aCompleted); + return ParseSheet(aStream, data, aCompleted); } NS_IMETHODIMP diff --git a/layout/style/nsCSSLoader.h b/layout/style/nsCSSLoader.h index 5c4cec551b21..ba87ea84c8db 100644 --- a/layout/style/nsCSSLoader.h +++ b/layout/style/nsCSSLoader.h @@ -286,7 +286,6 @@ protected: // access to nsresult ParseSheet(nsIUnicharInputStream* aStream, SheetLoadData* aLoadData, - nsIURI* aSheetURI, PRBool& aCompleted); public: diff --git a/layout/style/nsCSSStyleSheet.cpp b/layout/style/nsCSSStyleSheet.cpp index 23ef8b8dadfd..76b5a6696fbf 100644 --- a/layout/style/nsCSSStyleSheet.cpp +++ b/layout/style/nsCSSStyleSheet.cpp @@ -805,7 +805,7 @@ public: NS_DECL_ISUPPORTS // basic style sheet data - NS_IMETHOD Init(nsIURI* aURL); + NS_IMETHOD SetURL(nsIURI* aURL); NS_IMETHOD GetURL(nsIURI*& aURL) const; NS_IMETHOD GetTitle(nsString& aTitle) const; NS_IMETHOD SetTitle(const nsAString& aTitle); @@ -1780,7 +1780,7 @@ CSSStyleSheetImpl::DropRuleProcessorReference(nsICSSStyleRuleProcessor* aProcess NS_IMETHODIMP -CSSStyleSheetImpl::Init(nsIURI* aURL) +CSSStyleSheetImpl::SetURL(nsIURI* aURL) { NS_PRECONDITION(aURL, "null ptr"); if (! aURL) @@ -1790,9 +1790,8 @@ CSSStyleSheetImpl::Init(nsIURI* aURL) return NS_ERROR_OUT_OF_MEMORY; } - NS_ASSERTION(! mInner->mURL, "already initialized"); - if (mInner->mURL) - return NS_ERROR_ALREADY_INITIALIZED; + NS_ASSERTION(!mInner->mOrderedRules && !mInner->mComplete, + "Can't call SetURL on sheets that are complete or have rules"); mInner->mURL = aURL; return NS_OK; @@ -3059,7 +3058,7 @@ NS_NewCSSStyleSheet(nsICSSStyleSheet** aInstancePtrResult, nsIURI* aURL) if (NS_FAILED(rv = NS_NewCSSStyleSheet(&sheet))) return rv; - if (NS_FAILED(rv = sheet->Init(aURL))) { + if (NS_FAILED(rv = sheet->SetURL(aURL))) { NS_RELEASE(sheet); return rv; } diff --git a/layout/style/nsICSSStyleSheet.h b/layout/style/nsICSSStyleSheet.h index e78eae41fdbf..70c89e876e7d 100644 --- a/layout/style/nsICSSStyleSheet.h +++ b/layout/style/nsICSSStyleSheet.h @@ -76,7 +76,12 @@ public: NS_IMETHOD StyleSheetCount(PRInt32& aCount) const = 0; NS_IMETHOD GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const = 0; - NS_IMETHOD Init(nsIURI* aURL) = 0; + /** + * SetURL must be called on all sheets before parsing into them. + * SetURL may only be called while the sheet is 1) incomplete and 2) + * has no rules in it + */ + NS_IMETHOD SetURL(nsIURI* aURL) = 0; NS_IMETHOD SetTitle(const nsAString& aTitle) = 0; NS_IMETHOD AppendMedium(nsIAtom* aMedium) = 0; NS_IMETHOD ClearMedia(void) = 0;