# HG changeset patch # Parent 2fec836baa289d630182dd37c171069888ef796e diff --git a/content/base/public/nsIImageLoadingContent.idl b/content/base/public/nsIImageLoadingContent.idl --- a/content/base/public/nsIImageLoadingContent.idl +++ b/content/base/public/nsIImageLoadingContent.idl @@ -171,13 +171,24 @@ interface nsIImageLoadingContent : imgID /** * Enables/disables image state forcing. When |aForce| is PR_TRUE, we force * nsImageLoadingContent::ImageState() to return |aState|. Call again with |aForce| * as PR_FALSE to revert ImageState() to its original behaviour. */ void forceImageState(in boolean aForce, in unsigned long long aState); + const long CORS_NONE = 0; + const long CORS_ANONYMOUS = 1; + const long CORS_USE_CREDENTIALS = 2; + + /** + * Used to get the CORS mode for the load. + * + * @return The CORS mode. + */ + long getCORSMode(); + /** * We need to be notified when our document changes. */ [noscript, notxpcom] void NotifyOwnerDocumentChanged(in nsIDocument aOldDoc); }; diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -251,16 +251,17 @@ GK_ATOM(control, "control") #ifdef MOZ_MEDIA GK_ATOM(controls, "controls") #endif GK_ATOM(coords, "coords") 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") GK_ATOM(cycler, "cycler") GK_ATOM(data, "data") GK_ATOM(datalist, "datalist") GK_ATOM(dataType, "data-type") GK_ATOM(dateTime, "date-time") diff --git a/content/base/src/nsImageLoadingContent.cpp b/content/base/src/nsImageLoadingContent.cpp --- a/content/base/src/nsImageLoadingContent.cpp +++ b/content/base/src/nsImageLoadingContent.cpp @@ -714,23 +714,32 @@ nsImageLoadingContent::LoadImage(nsIURI* nsContentUtils::CanLoadImage(aNewURI, this, aDocument, aDocument->NodePrincipal(), &cpDecision); if (!NS_CP_ACCEPTED(cpDecision)) { FireEvent(NS_LITERAL_STRING("error")); SetBlockedRequest(aNewURI, cpDecision); return NS_OK; } + nsLoadFlags loadFlags = aLoadFlags; + PRInt32 corsmode = nsIImageLoadingContent::CORS_NONE; + GetCORSMode(&corsmode); + if (corsmode == nsIImageLoadingContent::CORS_ANONYMOUS) { + loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS; + } else if (corsmode == nsIImageLoadingContent::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); } else { // If we don't have a current URI, we might as well store this URI so people // know what we tried (and failed) to load. if (!mCurrentRequest) mCurrentURI = aNewURI; @@ -1081,8 +1090,14 @@ nsImageLoadingContent::CreateStaticImage aDest->mStateChangerDepth = mStateChangerDepth; aDest->mIsImageStateForced = mIsImageStateForced; aDest->mLoading = mLoading; aDest->mBroken = mBroken; aDest->mUserDisabled = mUserDisabled; aDest->mSuppressed = mSuppressed; } +NS_IMETHODIMP +nsImageLoadingContent::GetCORSMode(PRInt32* aCORSMode) +{ + *aCORSMode = CORS_NONE; + return NS_OK; +} diff --git a/content/html/content/src/nsHTMLImageElement.cpp b/content/html/content/src/nsHTMLImageElement.cpp --- a/content/html/content/src/nsHTMLImageElement.cpp +++ b/content/html/content/src/nsHTMLImageElement.cpp @@ -103,16 +103,19 @@ public: NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::) // nsIDOMHTMLImageElement NS_DECL_NSIDOMHTMLIMAGEELEMENT // override from nsGenericHTMLElement NS_IMETHOD GetDraggable(PRBool* aDraggable); + // override from nsImageLoadingContent + NS_IMETHOD GetCORSMode(PRInt32* aCorsMode); + // nsIJSNativeInitializer NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext, JSObject* aObj, PRUint32 argc, jsval* argv); // nsIContent virtual PRBool ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute, const nsAString& aValue, @@ -220,16 +223,27 @@ NS_IMPL_STRING_ATTR(nsHTMLImageElement, NS_IMPL_INT_ATTR(nsHTMLImageElement, Hspace, hspace) NS_IMPL_BOOL_ATTR(nsHTMLImageElement, IsMap, ismap) NS_IMPL_URI_ATTR(nsHTMLImageElement, LongDesc, longdesc) NS_IMPL_STRING_ATTR(nsHTMLImageElement, Lowsrc, lowsrc) 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[] = { + { "", nsIImageLoadingContent::CORS_NONE }, + { "anonymous", nsIImageLoadingContent::CORS_ANONYMOUS }, + { "use-credentials", nsIImageLoadingContent::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) { // images may be dragged unless the draggable attribute is false *aDraggable = !AttrValueIs(kNameSpaceID_None, nsGkAtoms::draggable, nsGkAtoms::_false, eIgnoreCase); return NS_OK; } @@ -331,16 +345,19 @@ nsHTMLImageElement::ParseAttribute(PRInt nsIAtom* aAttribute, const nsAString& aValue, nsAttrValue& aResult) { if (aNamespaceID == kNameSpaceID_None) { 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; } } return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, aResult); } @@ -620,8 +637,21 @@ nsHTMLImageElement::GetNaturalWidth(PRIn nsresult nsHTMLImageElement::CopyInnerTo(nsGenericElement* aDest) const { if (aDest->GetOwnerDoc()->IsStaticDocument()) { CreateStaticImageClone(static_cast(aDest)); } return nsGenericHTMLElement::CopyInnerTo(aDest); } + +NS_IMETHODIMP +nsHTMLImageElement::GetCORSMode(PRInt32* aCORSMode) +{ + const nsAttrValue* value = GetParsedAttr(nsGkAtoms::crossOrigin); + if (value && value->Type() == nsAttrValue::eEnum) { + *aCORSMode = value->GetEnumValue(); + } else { + *aCORSMode = CORS_NONE; + } + + return NS_OK; +} diff --git a/dom/interfaces/html/nsIDOMHTMLImageElement.idl b/dom/interfaces/html/nsIDOMHTMLImageElement.idl --- a/dom/interfaces/html/nsIDOMHTMLImageElement.idl +++ b/dom/interfaces/html/nsIDOMHTMLImageElement.idl @@ -50,16 +50,17 @@ * http://www.whatwg.org/specs/web-apps/current-work/ */ [scriptable, uuid(cf8a8744-ec3b-474e-8f2b-8def3da2344a)] interface nsIDOMHTMLImageElement : nsIDOMHTMLElement { attribute DOMString alt; attribute DOMString src; + attribute DOMString crossOrigin; attribute DOMString useMap; attribute boolean isMap; attribute long width; attribute long height; readonly attribute long naturalWidth; readonly attribute long naturalHeight; readonly attribute boolean complete; diff --git a/toolkit/system/gnome/nsAlertsIconListener.cpp b/toolkit/system/gnome/nsAlertsIconListener.cpp --- a/toolkit/system/gnome/nsAlertsIconListener.cpp +++ b/toolkit/system/gnome/nsAlertsIconListener.cpp @@ -257,17 +257,17 @@ nsAlertsIconListener::StartRequest(const NS_NewURI(getter_AddRefs(imageUri), aImageUrl); if (!imageUri) return ShowAlert(NULL); nsCOMPtr il(do_GetService("@mozilla.org/image/loader;1")); if (!il) return ShowAlert(NULL); - return il->LoadImage(imageUri, nsnull, nsnull, nsnull, this, + return il->LoadImage(imageUri, nsnull, nsnull, nsnull, nsnull, this, nsnull, nsIRequest::LOAD_NORMAL, nsnull, nsnull, nsnull, getter_AddRefs(mIconRequest)); } void nsAlertsIconListener::SendCallback() { if (mAlertListener)