Bug 696301 part 2. Communicate the crossorigin preload state from the parser to the scriptloader. r=sicking,hsivonen

This commit is contained in:
Boris Zbarsky 2012-03-10 10:13:52 -06:00
parent 0d8f6a7de7
commit 6857670c0e
11 changed files with 85 additions and 41 deletions

View File

@ -1424,7 +1424,8 @@ public:
/**
* Called by nsParser to preload images. Can be removed and code moved
* to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
* parser-module is linked with gklayout-module.
* parser-module is linked with gklayout-module. aCrossOriginAttr should
* be a void string if the attr is not present.
*/
virtual void MaybePreLoadImage(nsIURI* uri,
const nsAString& aCrossOriginAttr) = 0;

View File

@ -7737,14 +7737,20 @@ nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr)
}
nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
if (aCrossOriginAttr.LowerCaseEqualsLiteral("anonymous")) {
switch (nsGenericElement::StringToCORSMode(aCrossOriginAttr)) {
case CORS_NONE:
// Nothing to do
break;
case CORS_ANONYMOUS:
loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS;
} else if (aCrossOriginAttr.LowerCaseEqualsLiteral("use-credentials")) {
break;
case CORS_USE_CREDENTIALS:
loadFlags |= imgILoader::LOAD_CORS_USE_CREDENTIALS;
break;
default:
/* should never happen */
MOZ_NOT_REACHED("Unknown CORS mode!");
}
// else should we err on the side of not doing the preload if
// aCrossOriginAttr is nonempty? Let's err on the side of doing the
// preload as CORS_NONE.
// Image not in cache - trigger preload
nsCOMPtr<imgIRequest> request;

View File

@ -6257,6 +6257,18 @@ nsGenericElement::ParseCORSValue(const nsAString& aValue,
MOZ_ASSERT(success);
}
/* static */ CORSMode
nsGenericElement::StringToCORSMode(const nsAString& aValue)
{
if (aValue.IsVoid()) {
return CORS_NONE;
}
nsAttrValue val;
nsGenericElement::ParseCORSValue(aValue, val);
return CORSMode(val.GetEnumValue());
}
#define EVENT(name_, id_, type_, struct_) \
NS_IMETHODIMP nsINode::GetOn##name_(JSContext *cx, jsval *vp) { \
nsEventListenerManager *elm = GetListenerManager(false); \

View File

@ -65,6 +65,7 @@
#include "nsDOMClassInfoID.h" // DOMCI_DATA
#include "nsIDOMTouchEvent.h"
#include "nsIInlineEventHandlers.h"
#include "mozilla/CORSMode.h"
#include "nsISMILAttr.h"
@ -647,6 +648,11 @@ public:
* GetEnumValue() returns one of the above constants.
*/
static void ParseCORSValue(const nsAString& aValue, nsAttrValue& aResult);
/**
* Return the CORS mode for a given string
*/
static mozilla::CORSMode StringToCORSMode(const nsAString& aValue);
protected:
/*

View File

@ -1325,7 +1325,8 @@ nsScriptLoader::ParsingComplete(bool aTerminated)
void
nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
const nsAString &aType)
const nsAString &aType,
const nsAString &aCrossOrigin)
{
// Check to see if scripts has been turned off.
if (!mEnabled || !mDocument->IsScriptEnabled()) {

View File

@ -238,9 +238,12 @@ public:
* @param aURI The URI of the external script.
* @param aCharset The charset parameter for the script.
* @param aType The type parameter for the script.
* @param aCrossOrigin The crossorigin attribute for the script.
* Void if not present.
*/
virtual void PreloadURI(nsIURI *aURI, const nsAString &aCharset,
const nsAString &aType);
const nsAString &aType,
const nsAString &aCrossOrigin);
private:
/**

View File

@ -61,20 +61,21 @@ nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor)
aExecutor->SetSpeculationBase(mUrl);
break;
case eSpeculativeLoadImage:
aExecutor->PreloadImage(mUrl, mCharsetOrCrossOrigin);
aExecutor->PreloadImage(mUrl, mCrossOrigin);
break;
case eSpeculativeLoadScript:
aExecutor->PreloadScript(mUrl, mCharsetOrCrossOrigin, mTypeOrCharsetSource);
aExecutor->PreloadScript(mUrl, mCharset, mTypeOrCharsetSource,
mCrossOrigin);
break;
case eSpeculativeLoadStyle:
aExecutor->PreloadStyle(mUrl, mCharsetOrCrossOrigin);
aExecutor->PreloadStyle(mUrl, mCharset);
break;
case eSpeculativeLoadManifest:
aExecutor->ProcessOfflineManifest(mUrl);
break;
case eSpeculativeLoadSetDocumentCharset: {
nsCAutoString narrowName;
CopyUTF16toUTF8(mCharsetOrCrossOrigin, narrowName);
CopyUTF16toUTF8(mCharset, narrowName);
NS_ASSERTION(mTypeOrCharsetSource.Length() == 1,
"Unexpected charset source string");
PRInt32 intSource = (PRInt32)mTypeOrCharsetSource.First();

View File

@ -72,18 +72,20 @@ class nsHtml5SpeculativeLoad {
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadImage;
mUrl.Assign(aUrl);
mCharsetOrCrossOrigin.Assign(aCrossOrigin);
mCrossOrigin.Assign(aCrossOrigin);
}
inline void InitScript(const nsAString& aUrl,
const nsAString& aCharset,
const nsAString& aType) {
const nsAString& aCharset,
const nsAString& aType,
const nsAString& aCrossOrigin) {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadScript;
mUrl.Assign(aUrl);
mCharsetOrCrossOrigin.Assign(aCharset);
mCharset.Assign(aCharset);
mTypeOrCharsetSource.Assign(aType);
mCrossOrigin.Assign(aCrossOrigin);
}
inline void InitStyle(const nsAString& aUrl, const nsAString& aCharset) {
@ -91,7 +93,7 @@ class nsHtml5SpeculativeLoad {
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadStyle;
mUrl.Assign(aUrl);
mCharsetOrCrossOrigin.Assign(aCharset);
mCharset.Assign(aCharset);
}
/**
@ -127,7 +129,7 @@ class nsHtml5SpeculativeLoad {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadSetDocumentCharset;
CopyUTF8toUTF16(aCharset, mCharsetOrCrossOrigin);
CopyUTF8toUTF16(aCharset, mCharset);
mTypeOrCharsetSource.Assign((PRUnichar)aCharsetSource);
}
@ -137,14 +139,12 @@ class nsHtml5SpeculativeLoad {
eHtml5SpeculativeLoad mOpCode;
nsString mUrl;
/**
* If mOpCode is eSpeculativeLoadImage, this is the value of the
* "crossorigin" attribute. If mOpCode is eSpeculativeLoadStyle
* or eSpeculativeLoadScript then this is the value of the
* "charset" attribute. For eSpeculativeLoadSetDocumentCharset it is
* the charset that the document's charset is being set to. Otherwise
* it's empty.
* If mOpCode is eSpeculativeLoadStyle or eSpeculativeLoadScript
* then this is the value of the "charset" attribute. For
* eSpeculativeLoadSetDocumentCharset it is the charset that the
* document's charset is being set to. Otherwise it's empty.
*/
nsString mCharsetOrCrossOrigin;
nsString mCharset;
/**
* If mOpCode is eSpeculativeLoadSetDocumentCharset, this is a
* one-character string whose single character's code point is to be
@ -152,6 +152,12 @@ class nsHtml5SpeculativeLoad {
* the value of the type attribute.
*/
nsString mTypeOrCharsetSource;
/**
* If mOpCode is eSpeculativeLoadImage or eSpeculativeLoadScript,
* this is the value of the "crossorigin" attribute. If the
* attribute is not set, this will be a void string.
*/
nsString mCrossOrigin;
};
#endif // nsHtml5SpeculativeLoad_h_

View File

@ -108,11 +108,9 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm
if (url) {
nsString* crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
if (crossOrigin) {
mSpeculativeLoadQueue.AppendElement()->InitImage(*url, *crossOrigin);
} else {
mSpeculativeLoadQueue.AppendElement()->InitImage(*url, EmptyString());
}
mSpeculativeLoadQueue.AppendElement()->
InitImage(*url,
crossOrigin ? *crossOrigin : NullString());
}
} else if (nsHtml5Atoms::script == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
@ -123,9 +121,13 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm
if (url) {
nsString* charset = aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
nsString* type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
mSpeculativeLoadQueue.AppendElement()->InitScript(*url,
(charset) ? *charset : EmptyString(),
(type) ? *type : EmptyString());
nsString* crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
mSpeculativeLoadQueue.AppendElement()->
InitScript(*url,
(charset) ? *charset : EmptyString(),
(type) ? *type : EmptyString(),
(crossOrigin) ? *crossOrigin : NullString());
mCurrentHtmlScriptIsAsyncOrDefer =
aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER);
@ -145,7 +147,7 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm
} else if (nsHtml5Atoms::video == aName) {
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_POSTER);
if (url) {
mSpeculativeLoadQueue.AppendElement()->InitImage(*url, EmptyString());
mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString());
}
} else if (nsHtml5Atoms::style == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
@ -170,7 +172,7 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm
if (nsHtml5Atoms::image == aName) {
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
if (url) {
mSpeculativeLoadQueue.AppendElement()->InitImage(*url, EmptyString());
mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString());
}
} else if (nsHtml5Atoms::script == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
@ -180,9 +182,13 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
if (url) {
nsString* type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
mSpeculativeLoadQueue.AppendElement()->InitScript(*url,
EmptyString(),
(type) ? *type : EmptyString());
nsString* crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
mSpeculativeLoadQueue.AppendElement()->
InitScript(*url,
EmptyString(),
(type) ? *type : EmptyString(),
(crossOrigin) ? *crossOrigin : NullString());
}
} else if (nsHtml5Atoms::style == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();

View File

@ -930,13 +930,14 @@ nsHtml5TreeOpExecutor::ConvertIfNotPreloadedYet(const nsAString& aURL)
void
nsHtml5TreeOpExecutor::PreloadScript(const nsAString& aURL,
const nsAString& aCharset,
const nsAString& aType)
const nsAString& aType,
const nsAString& aCrossOrigin)
{
nsCOMPtr<nsIURI> uri = ConvertIfNotPreloadedYet(aURL);
if (!uri) {
return;
}
mDocument->ScriptLoader()->PreloadURI(uri, aCharset, aType);
mDocument->ScriptLoader()->PreloadURI(uri, aCharset, aType, aCrossOrigin);
}
void

View File

@ -425,7 +425,8 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
void PreloadScript(const nsAString& aURL,
const nsAString& aCharset,
const nsAString& aType);
const nsAString& aType,
const nsAString& aCrossOrigin);
void PreloadStyle(const nsAString& aURL, const nsAString& aCharset);