Make the "href" property of stylesheets reflect the original URI that was reflected to load the sheet. Bug 397427, r=dbaron,biesi, sr=dbaron, a=dsicore

This commit is contained in:
bzbarsky@mit.edu 2007-10-23 14:56:41 -07:00
Родитель b832c7532f
Коммит 26d7ccd742
20 изменённых файлов: 176 добавлений и 60 удалений

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

@ -446,13 +446,8 @@ nsScriptSecurityManager::GetChannelPrincipal(nsIChannel* aChannel,
// OK, get the principal from the URI. Make sure this does the same thing
// as nsDocument::Reset and nsXULDocument::StartDocumentLoad.
nsCOMPtr<nsIURI> uri;
nsLoadFlags loadFlags = 0;
nsresult rv = aChannel->GetLoadFlags(&loadFlags);
if (NS_SUCCEEDED(rv) && (loadFlags & nsIChannel::LOAD_REPLACE)) {
aChannel->GetURI(getter_AddRefs(uri));
} else {
aChannel->GetOriginalURI(getter_AddRefs(uri));
}
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
return GetCodebasePrincipal(uri, aPrincipal);
}

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

@ -1161,13 +1161,7 @@ nsDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup)
// Note: this code is duplicated in nsXULDocument::StartDocumentLoad and
// nsScriptSecurityManager::GetChannelPrincipal.
// Note: this should match nsDocShell::OnLoadingSite
nsLoadFlags loadFlags = 0;
nsresult rv = aChannel->GetLoadFlags(&loadFlags);
if (NS_SUCCEEDED(rv) && (loadFlags & nsIChannel::LOAD_REPLACE)) {
aChannel->GetURI(getter_AddRefs(uri));
} else {
aChannel->GetOriginalURI(getter_AddRefs(uri));
}
NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
nsIScriptSecurityManager *securityManager =
nsContentUtils::GetSecurityManager();

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

@ -424,18 +424,8 @@ nsXULDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
mChannel = aChannel;
// Get the URI. Note that this should match nsDocShell::OnLoadingSite
// XXXbz this code is repeated from nsDocument::Reset and
// nsScriptSecurityManager::GetChannelPrincipal; we really need to refactor
// this part better.
nsLoadFlags loadFlags = 0;
nsresult rv = aChannel->GetLoadFlags(&loadFlags);
if (NS_SUCCEEDED(rv)) {
if (loadFlags & nsIChannel::LOAD_REPLACE) {
rv = aChannel->GetURI(getter_AddRefs(mDocumentURI));
} else {
rv = aChannel->GetOriginalURI(getter_AddRefs(mDocumentURI));
}
}
nsresult rv =
NS_GetFinalChannelURI(aChannel, getter_AddRefs(mDocumentURI));
NS_ENSURE_SUCCESS(rv, rv);
rv = ResetStylesheetsToURI(mDocumentURI);

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

@ -7760,12 +7760,7 @@ nsDocShell::OnLoadingSite(nsIChannel * aChannel, PRBool aFireOnLocationChange,
// else use the original url
//
// Note that this should match what documents do (see nsDocument::Reset).
nsLoadFlags loadFlags = 0;
aChannel->GetLoadFlags(&loadFlags);
if (loadFlags & nsIChannel::LOAD_REPLACE)
aChannel->GetURI(getter_AddRefs(uri));
else
aChannel->GetOriginalURI(getter_AddRefs(uri));
NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
NS_ENSURE_TRUE(uri, PR_FALSE);
return OnNewURI(uri, aChannel, mLoadType, aFireOnLocationChange,

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

@ -1849,7 +1849,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->SetURIs(uri, uri);
result = mPrefStyleSheet->SetURIs(uri, nsnull, uri);
if (NS_SUCCEEDED(result)) {
mPrefStyleSheet->SetComplete();
nsCOMPtr<nsIDOMCSSStyleSheet> sheet(do_QueryInterface(mPrefStyleSheet));

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

@ -594,7 +594,7 @@ GetMathMLAttributeStyleSheet(nsPresContext* aPresContext,
nsCOMPtr<nsICSSStyleSheet> cssSheet(do_CreateInstance(kCSSStyleSheetCID));
if (!cssSheet)
return;
cssSheet->SetURIs(uri, uri);
cssSheet->SetURIs(uri, nsnull, uri);
cssSheet->SetTitle(NS_ConvertASCIItoUTF16(kTitle));
// all done, no further activity from the net involved, so we better do this
cssSheet->SetComplete();

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

@ -777,19 +777,18 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader,
return NS_OK;
}
nsCOMPtr<nsIURI> channelURI;
nsCOMPtr<nsIURI> originalURI;
channel->GetOriginalURI(getter_AddRefs(originalURI));
// If the channel's original URI is "chrome:", we want that, since
// the observer code in nsXULPrototypeCache depends on chrome stylesheets
// having a chrome URI. (Whether or not chrome stylesheets come through
// this codepath seems nondeterministic.)
// Otherwise we want the potentially-HTTP-redirected URI.
channel->GetOriginalURI(getter_AddRefs(channelURI));
PRBool isChrome;
if (NS_FAILED(channelURI->SchemeIs("chrome", &isChrome)) || !isChrome) {
channel->GetURI(getter_AddRefs(channelURI));
}
nsCOMPtr<nsIURI> channelURI;
NS_GetFinalChannelURI(channel, getter_AddRefs(channelURI));
if (!channelURI) {
if (!channelURI || !originalURI) {
NS_ERROR("Someone just violated the nsIRequest contract");
LOG_WARN((" Channel without a URI. Bad!"));
mLoader->SheetComplete(this, NS_ERROR_UNEXPECTED);
@ -875,9 +874,9 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader,
return NS_OK;
}
// Enough to set the URI on mSheet, since any sibling datas we have share
// Enough to set the URIs on mSheet, since any sibling datas we have share
// the same mInner as mSheet and will thus get the same URI.
mSheet->SetURIs(channelURI, channelURI);
mSheet->SetURIs(channelURI, originalURI, channelURI);
PRBool completed;
return mLoader->ParseSheet(aDataStream, this, completed);
@ -1082,19 +1081,25 @@ CSSLoaderImpl::CreateSheet(nsIURI* aURI,
if (!*aSheet) {
aSheetState = eSheetNeedsParser;
nsIURI *sheetURI = aURI;
nsCOMPtr<nsIURI> baseURI = aURI;
nsIURI *sheetURI;
nsCOMPtr<nsIURI> baseURI;
nsIURI* originalURI;
if (!aURI) {
// 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?");
baseURI = aLinkingContent->GetBaseURI();
sheetURI = aLinkingContent->GetDocument()->GetDocumentURI();
originalURI = nsnull;
} else {
baseURI = aURI;
sheetURI = aURI;
originalURI = aURI;
}
rv = NS_NewCSSStyleSheet(aSheet);
NS_ENSURE_SUCCESS(rv, rv);
(*aSheet)->SetURIs(sheetURI, baseURI);
(*aSheet)->SetURIs(sheetURI, originalURI, baseURI);
}
NS_ASSERTION(*aSheet, "We should have a sheet by now!");

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

@ -707,7 +707,7 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput,
NS_NewCSSStyleSheet(getter_AddRefs(mSheet));
NS_ENSURE_TRUE(mSheet, NS_ERROR_OUT_OF_MEMORY);
mSheet->SetURIs(aSheetURI, aBaseURI);
mSheet->SetURIs(aSheetURI, aSheetURI, aBaseURI);
mSheet->SetPrincipal(aSheetPrincipal);
mNameSpaceMap = nsnull;
}

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

@ -771,7 +771,8 @@ nsCSSStyleSheet::DropRuleProcessor(nsCSSRuleProcessor* aProcessor)
NS_IMETHODIMP
nsCSSStyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI)
nsCSSStyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI,
nsIURI* aBaseURI)
{
NS_PRECONDITION(aSheetURI && aBaseURI, "null ptr");
@ -779,6 +780,7 @@ nsCSSStyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI)
"Can't call SetURL on sheets that are complete or have rules");
mInner->mSheetURI = aSheetURI;
mInner->mOriginalSheetURI = aOriginalSheetURI;
mInner->mBaseURI = aBaseURI;
return NS_OK;
}
@ -1416,15 +1418,14 @@ nsCSSStyleSheet::GetParentStyleSheet(nsIDOMStyleSheet** aParentStyleSheet)
NS_IMETHODIMP
nsCSSStyleSheet::GetHref(nsAString& aHref)
{
nsCAutoString str;
// XXXldb The DOM spec says that this should be null for inline style sheets.
if (mInner->mSheetURI) {
mInner->mSheetURI->GetSpec(str);
if (mInner->mOriginalSheetURI) {
nsCAutoString str;
mInner->mOriginalSheetURI->GetSpec(str);
CopyUTF8toUTF16(str, aHref);
} else {
SetDOMStringToNull(aHref);
}
CopyUTF8toUTF16(str, aHref);
return NS_OK;
}

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

@ -74,6 +74,7 @@ public:
nsAutoVoidArray mSheets;
nsCOMPtr<nsIURI> mSheetURI; // for error reports, etc.
nsCOMPtr<nsIURI> mOriginalSheetURI; // for GetHref. Can be null.
nsCOMPtr<nsIURI> mBaseURI; // for resolving relative URIs
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMArray<nsICSSRule> mOrderedRules;
@ -136,7 +137,8 @@ public:
NS_IMETHOD ReplaceRuleInGroup(nsICSSGroupRule* aGroup, nsICSSRule* aOld, nsICSSRule* aNew);
NS_IMETHOD StyleSheetCount(PRInt32& aCount) const;
NS_IMETHOD GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const;
NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI);
NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI,
nsIURI* aBaseURI);
virtual NS_HIDDEN_(void) SetPrincipal(nsIPrincipal* aPrincipal);
virtual NS_HIDDEN_(nsIPrincipal*) Principal() const;
NS_IMETHOD SetTitle(const nsAString& aTitle);

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

@ -53,10 +53,10 @@ class nsICSSImportRule;
class nsIPrincipal;
// IID for the nsICSSStyleSheet interface
// 36541c18-e735-48ef-8622-3a481275b757
// 74fa10f3-fab7-425a-a7dd-e2afd1ba7a07
#define NS_ICSS_STYLE_SHEET_IID \
{ 0x36541c18, 0xe735, 0x48ef, \
{ 0x86, 0x22, 0x3a, 0x48, 0x12, 0x75, 0xb7, 0x57 } }
{ 0x74fa10f3, 0xfab7, 0x425a, \
{ 0xa7, 0xdd, 0xe2, 0xaf, 0xd1, 0xba, 0x7a, 0x07 } }
class nsICSSStyleSheet : public nsIStyleSheet {
public:
@ -87,7 +87,8 @@ public:
* SetURIs may only be called while the sheet is 1) incomplete and 2)
* has no rules in it
*/
NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) = 0;
NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI,
nsIURI* aBaseURI) = 0;
/**
* SetPrincipal should be called on all sheets before parsing into them.

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

@ -83,6 +83,7 @@ _TEST_FILES = test_bug74880.html \
test_bug389464.html \
test_bug391034.html \
test_bug391221.html \
test_bug397427.html \
test_compute_data_with_start_struct.html \
test_dont_use_document_colors.html \
test_inherit_storage.html \
@ -101,6 +102,15 @@ _TEST_FILES = test_bug74880.html \
unstyled.css \
unstyled-frame.xml \
unstyled-frame.css \
redirect-1.css \
post-redirect-1.css \
redirect-1.css^headers^ \
redirect-2.css \
post-redirect-2.css \
redirect-2.css^headers^ \
redirect-3.css \
redirect-3.css^headers^ \
post-redirect-3.css \
$(NULL)

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

@ -0,0 +1 @@
#one { color: green; background: url("#"); }

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

@ -0,0 +1 @@
#two { color: green; background: url("#"); }

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

@ -0,0 +1 @@
#three { color: green; background: url("#"); }

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

@ -0,0 +1,2 @@
HTTP 302 Found
Location: http://example.org/tests/layout/style/test/post-redirect-1.css

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

@ -0,0 +1,2 @@
HTTP 302 Found
Location: http://example.org/tests/layout/style/test/post-redirect-2.css

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

@ -0,0 +1,2 @@
HTTP 302 Found
Location: http://example.org/tests/layout/style/test/post-redirect-3.css

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

@ -0,0 +1,92 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=397427
-->
<head>
<title>Test for Bug 397427</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<style id="a">
@import url("redirect-1.css");
@import url("redirect-2.css");
.test { color: red }
</style>
<link id="b" rel="stylesheet" href="http://example.com">
<link id="c" rel="stylesheet" href="redirect-2.css">
<link id="d" rel="stylesheet" href="redirect-3.css">
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=397427">Mozilla Bug 397427</a>
<p id="display">
<span id="one" class="test"></span>
<span id="two" class="test"></span>
<span id="three" class="test"></span>
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 397427 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
is($("a").sheet.href, null, "href should be null");
is(typeof($("a").sheet.href), "object", "should be actual null");
// Make sure the redirected sheets are loaded and have the right base URI
is(document.defaultView.getComputedStyle($("one"), "").color,
"rgb(0, 128, 0)", "Redirect 1 did not work");
is(document.defaultView.getComputedStyle($("one"), "").backgroundImage,
"url(http://example.org/tests/layout/style/test/post-redirect-1.css#)",
"Redirect 1 did not get right base URI");
is(document.defaultView.getComputedStyle($("two"), "").color,
"rgb(0, 128, 0)", "Redirect 2 did not work");
is(document.defaultView.getComputedStyle($("two"), "").backgroundImage,
"url(http://example.org/tests/layout/style/test/post-redirect-2.css#)",
"Redirect 2 did not get right base URI");
is(document.defaultView.getComputedStyle($("three"), "").color,
"rgb(0, 128, 0)", "Redirect 3 did not work");
is(document.defaultView.getComputedStyle($("three"), "").backgroundImage,
"url(http://example.org/tests/layout/style/test/post-redirect-3.css#)",
"Redirect 3 did not get right base URI");
var ruleList = $("a").sheet.cssRules;
is(ruleList[0].styleSheet.href,
window.location.href.replace(/test_bug397427.html$/, "redirect-1.css"),
"Unexpected href for imported sheet");
todo(ruleList[0].href == window.location.href.replace(/test_bug397427.html$/, "redirect-1.css"),
"Rule href should be absolute");
is(ruleList[1].styleSheet.href,
window.location.href.replace(/test_bug397427.html$/, "redirect-2.css"),
"Unexpected href for imported sheet");
todo(ruleList[1].href == window.location.href.replace(/test_bug397427.html$/, "redirect-2.css"),
"Rule href should be absolute");
is($("b").href, "http://example.com/", "Unexpected href one");
is($("b").href, $("b").sheet.href,
"Should have the same href when not redirecing");
is($("c").href,
window.location.href.replace(/test_bug397427.html$/, "redirect-2.css"),
"Unexpected href two");
is($("c").href, $("c").sheet.href,
"Should have the same href when redirecting");
is($("d").href,
window.location.href.replace(/test_bug397427.html$/, "redirect-3.css"),
"Unexpected href three");
is($("d").href, $("d").sheet.href,
"Should have the same href when redirecting again");
})
addLoadEvent(SimpleTest.finish);
</script>
</pre>
</body>
</html>

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

@ -1304,4 +1304,26 @@ NS_GetInnermostURI(nsIURI *uri)
return uri;
}
/**
* Get the "final" URI for a channel. This is either the same as GetURI or
* GetOriginalURI, depending on whether this channel has
* nsIChanel::LOAD_REPLACE set. For channels without that flag set, the final
* URI is the original URI, while for ones with the flag the final URI is the
* channel URI.
*/
inline nsresult
NS_GetFinalChannelURI(nsIChannel* channel, nsIURI** uri)
{
*uri = nsnull;
nsLoadFlags loadFlags = 0;
nsresult rv = channel->GetLoadFlags(&loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
if (loadFlags & nsIChannel::LOAD_REPLACE) {
return channel->GetURI(uri);
}
return channel->GetOriginalURI(uri);
}
#endif // !nsNetUtil_h__