diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index a3aec6eec93c..42d0dfd4a838 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -256,6 +256,7 @@ GK_ATOM(copy, "copy") GK_ATOM(copyOf, "copy-of") GK_ATOM(count, "count") GK_ATOM(crop, "crop") +GK_ATOM(crossOrigin, "crossOrigin") GK_ATOM(curpos, "curpos") GK_ATOM(current, "current") GK_ATOM(currentloop, "currentloop") diff --git a/content/base/src/nsImageLoadingContent.cpp b/content/base/src/nsImageLoadingContent.cpp index 43192cab6456..6ee59eb74e23 100644 --- a/content/base/src/nsImageLoadingContent.cpp +++ b/content/base/src/nsImageLoadingContent.cpp @@ -719,13 +719,21 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI, return NS_OK; } + nsLoadFlags loadFlags = aLoadFlags; + PRInt32 corsmode = GetCORSMode(); + if (corsmode == nsImageLoadingContent::CORS_ANONYMOUS) { + loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS; + } else if (corsmode == nsImageLoadingContent::CORS_USE_CREDENTIALS) { + loadFlags |= imgILoader::LOAD_CORS_USE_CREDENTIALS; + } + // Not blocked. Do the load. nsCOMPtr& req = PrepareNextRequest(); nsresult rv; rv = nsContentUtils::LoadImage(aNewURI, aDocument, aDocument->NodePrincipal(), aDocument->GetDocumentURI(), - this, aLoadFlags, + this, loadFlags, getter_AddRefs(req)); if (NS_SUCCEEDED(rv)) { TrackImage(req); @@ -1086,3 +1094,8 @@ nsImageLoadingContent::CreateStaticImageClone(nsImageLoadingContent* aDest) cons aDest->mSuppressed = mSuppressed; } +nsImageLoadingContent::CORSMode +nsImageLoadingContent::GetCORSMode() +{ + return CORS_NONE; +} diff --git a/content/base/src/nsImageLoadingContent.h b/content/base/src/nsImageLoadingContent.h index 691700436bbb..b38df99e0c22 100644 --- a/content/base/src/nsImageLoadingContent.h +++ b/content/base/src/nsImageLoadingContent.h @@ -69,6 +69,25 @@ public: NS_DECL_IMGIDECODEROBSERVER NS_DECL_NSIIMAGELOADINGCONTENT + enum CORSMode { + /** + * The default of not using CORS to validate cross-origin loads. + */ + CORS_NONE, + + /** + * Validate cross-site loads using CORS, but do not send any credentials + * (cookies, HTTP auth logins, etc) along with the request. + */ + CORS_ANONYMOUS, + + /** + * Validate cross-site loads using CORS, and send credentials such as cookies + * and HTTP auth logins along with the request. + */ + CORS_USE_CREDENTIALS + }; + protected: /** * LoadImage is called by subclasses when the appropriate @@ -159,6 +178,12 @@ protected: // current one. See the comment for mBlockingOnload for more information. void SetBlockingOnload(PRBool aBlocking); + /** + * Returns the CORS mode that will be used for all future image loads. The + * default implementation returns CORS_NONE unconditionally. + */ + virtual CORSMode GetCORSMode(); + private: /** * Struct used to manage the image observers. diff --git a/content/html/content/src/nsHTMLImageElement.cpp b/content/html/content/src/nsHTMLImageElement.cpp index 76d0e78ac07c..a6f2c8f477b2 100644 --- a/content/html/content/src/nsHTMLImageElement.cpp +++ b/content/html/content/src/nsHTMLImageElement.cpp @@ -108,6 +108,9 @@ public: // override from nsGenericHTMLElement NS_IMETHOD GetDraggable(PRBool* aDraggable); + // override from nsImageLoadingContent + nsImageLoadingContent::CORSMode GetCORSMode(); + // nsIJSNativeInitializer NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext, JSObject* aObj, PRUint32 argc, jsval* argv); @@ -225,6 +228,17 @@ NS_IMPL_URI_ATTR(nsHTMLImageElement, Src, src) NS_IMPL_STRING_ATTR(nsHTMLImageElement, UseMap, usemap) NS_IMPL_INT_ATTR(nsHTMLImageElement, Vspace, vspace) +static const nsAttrValue::EnumTable kCrossOriginTable[] = { + { "", nsImageLoadingContent::CORS_NONE }, + { "anonymous", nsImageLoadingContent::CORS_ANONYMOUS }, + { "use-credentials", nsImageLoadingContent::CORS_USE_CREDENTIALS }, + { 0 } +}; +// Default crossOrigin mode is CORS_NONE. +static const nsAttrValue::EnumTable* kCrossOriginDefault = &kCrossOriginTable[0]; + +NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLImageElement, CrossOrigin, crossOrigin, kCrossOriginDefault->tag) + NS_IMETHODIMP nsHTMLImageElement::GetDraggable(PRBool* aDraggable) { @@ -338,6 +352,9 @@ nsHTMLImageElement::ParseAttribute(PRInt32 aNamespaceID, if (aAttribute == nsGkAtoms::align) { return ParseAlignValue(aValue, aResult); } + if (aAttribute == nsGkAtoms::crossOrigin) { + return aResult.ParseEnumValue(aValue, kCrossOriginTable, PR_FALSE); + } if (ParseImageAttribute(aAttribute, aValue, aResult)) { return PR_TRUE; } @@ -633,3 +650,16 @@ nsHTMLImageElement::CopyInnerTo(nsGenericElement* aDest) const } return nsGenericHTMLElement::CopyInnerTo(aDest); } + +nsImageLoadingContent::CORSMode +nsHTMLImageElement::GetCORSMode() +{ + nsImageLoadingContent::CORSMode ret = nsImageLoadingContent::CORS_NONE; + + const nsAttrValue* value = GetParsedAttr(nsGkAtoms::crossOrigin); + if (value && value->Type() == nsAttrValue::eEnum) { + ret = (nsImageLoadingContent::CORSMode) value->GetEnumValue(); + } + + return ret; +} diff --git a/dom/interfaces/html/nsIDOMHTMLImageElement.idl b/dom/interfaces/html/nsIDOMHTMLImageElement.idl index 6f0cb12da612..c03d00169617 100644 --- a/dom/interfaces/html/nsIDOMHTMLImageElement.idl +++ b/dom/interfaces/html/nsIDOMHTMLImageElement.idl @@ -50,11 +50,12 @@ * http://www.whatwg.org/specs/web-apps/current-work/ */ -[scriptable, uuid(4bedb0a0-f901-4c61-a93a-a43c1b7674d4)] +[scriptable, uuid(ce760602-0528-493d-966d-65d4ee52347d)] interface nsIDOMHTMLImageElement : nsIDOMHTMLElement { attribute DOMString alt; attribute DOMString src; + attribute DOMString crossOrigin; attribute DOMString useMap; attribute boolean isMap; attribute unsigned long width;