Bug 1055750 - Part 3 - Track image vs imageset request load type through ImageLoadingContent::LoadImage r=bz,tanvi

This commit is contained in:
John Schoenick 2014-08-19 14:49:38 -07:00
Родитель d8905bc74a
Коммит 4514600c1a
18 изменённых файлов: 204 добавлений и 75 удалений

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

@ -24,9 +24,14 @@ typedef unsigned long nsContentPolicyType;
* by launching a dialog to prompt the user for something).
*/
[scriptable,uuid(d8210e91-1970-4230-88ef-74b6fdc418cf)]
[scriptable,uuid(94513f07-d559-480e-8879-6249852365ea)]
interface nsIContentPolicy : nsISupports
{
/**
* Indicates a unset or bogus policy type.
*/
const nsContentPolicyType TYPE_INVALID = 0;
/**
* Gecko/Firefox developers: Do not use TYPE_OTHER under any circumstances.
*

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

@ -37,7 +37,7 @@ interface nsIFrame;
* interface to mirror this interface when changing it.
*/
[scriptable, builtinclass, uuid(256a5283-ebb5-4430-8e15-5ada92156ef7)]
[scriptable, builtinclass, uuid(ce098f6c-baca-4178-a9aa-266e8bfe509b)]
interface nsIImageLoadingContent : imgINotificationObserver
{
/**
@ -149,9 +149,10 @@ interface nsIImageLoadingContent : imgINotificationObserver
/**
* forceReload forces reloading of the image pointed to by currentURI
*
* @param aNotify [optional] request should notify, defaults to true
* @throws NS_ERROR_NOT_AVAILABLE if there is no current URI to reload
*/
void forceReload();
[optional_argc] void forceReload([optional] in boolean aNotify /* = true */);
/**
* Enables/disables image state forcing. When |aForce| is PR_TRUE, we force

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

@ -3020,7 +3020,8 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
aObserver, /* imgINotificationObserver */
aLoadingDocument, /* uniquification key */
aLoadFlags, /* load flags */
nullptr, /* cache key */
nullptr, /* cache key */
aContentPolicyType, /* content policy type */
initiatorType, /* the load initiator */
aRequest);
}

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

@ -35,7 +35,7 @@ public:
nsresult Init(imgRequestProxy* aImageRequest)
{
// No need to notify, since we have no frame.
return UseAsPrimaryRequest(aImageRequest, false);
return UseAsPrimaryRequest(aImageRequest, false, eImageLoadType_Normal);
}
// nsIContent overrides

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

@ -522,6 +522,19 @@ nsImageLoadingContent::FrameDestroyed(nsIFrame* aFrame)
}
}
/* static */
nsContentPolicyType
nsImageLoadingContent::PolicyTypeForLoad(ImageLoadType aImageLoadType)
{
if (aImageLoadType == eImageLoadType_Imageset) {
return nsIContentPolicy::TYPE_IMAGESET;
}
MOZ_ASSERT(aImageLoadType == eImageLoadType_Normal,
"Unknown ImageLoadType type in PolicyTypeForLoad");
return nsIContentPolicy::TYPE_IMAGE;
}
int32_t
nsImageLoadingContent::GetRequestType(imgIRequest* aRequest,
ErrorResult& aError)
@ -600,7 +613,7 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
// Do the load.
nsCOMPtr<nsIStreamListener> listener;
nsRefPtr<imgRequestProxy>& req = PrepareNextRequest();
nsRefPtr<imgRequestProxy>& req = PrepareNextRequest(eImageLoadType_Normal);
nsresult rv = nsContentUtils::GetImgLoaderForChannel(aChannel)->
LoadImageWithChannel(aChannel, this, doc,
getter_AddRefs(listener),
@ -632,7 +645,8 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
}
void
nsImageLoadingContent::ForceReload(ErrorResult& aError)
nsImageLoadingContent::ForceReload(const mozilla::dom::Optional<bool>& aNotify,
mozilla::ErrorResult& aError)
{
nsCOMPtr<nsIURI> currentURI;
GetCurrentURI(getter_AddRefs(currentURI));
@ -641,16 +655,32 @@ nsImageLoadingContent::ForceReload(ErrorResult& aError)
return;
}
nsresult rv = LoadImage(currentURI, true, true, nullptr, nsIRequest::VALIDATE_ALWAYS);
// defaults to true
bool notify = !aNotify.WasPassed() || aNotify.Value();
// We keep this flag around along with the old URI even for failed requests
// without a live request object
ImageLoadType loadType = \
(mCurrentRequestFlags & REQUEST_IS_IMAGESET) ? eImageLoadType_Imageset
: eImageLoadType_Normal;
nsresult rv = LoadImage(currentURI, true, notify, loadType, nullptr,
nsIRequest::VALIDATE_ALWAYS);
if (NS_FAILED(rv)) {
aError.Throw(rv);
}
}
NS_IMETHODIMP nsImageLoadingContent::ForceReload()
NS_IMETHODIMP
nsImageLoadingContent::ForceReload(bool aNotify /* = true */,
uint8_t aArgc)
{
mozilla::dom::Optional<bool> notify;
if (aArgc >= 1) {
notify.Construct() = aNotify;
}
ErrorResult result;
ForceReload(result);
ForceReload(notify, result);
return result.ErrorCode();
}
@ -735,7 +765,8 @@ nsImageLoadingContent::GetVisibleCount()
nsresult
nsImageLoadingContent::LoadImage(const nsAString& aNewURI,
bool aForce,
bool aNotify)
bool aNotify,
ImageLoadType aImageLoadType)
{
// First, get a document (needed for security checks and the like)
nsIDocument* doc = GetOurOwnerDoc();
@ -758,9 +789,9 @@ nsImageLoadingContent::LoadImage(const nsAString& aNewURI,
// Loading an embedded img from the same URI as the document URI will not work
// as a resource cannot recursively embed itself. Attempting to do so generally
// results in having to pre-emptively close down an in-flight HTTP transaction
// results in having to pre-emptively close down an in-flight HTTP transaction
// and then incurring the significant cost of establishing a new TCP channel.
// This is generally triggered from <img src="">
// This is generally triggered from <img src="">
// In light of that, just skip loading it..
// Do make sure to drop our existing image, if any
CancelImageRequests(aNotify);
@ -769,13 +800,14 @@ nsImageLoadingContent::LoadImage(const nsAString& aNewURI,
NS_TryToSetImmutable(imageURI);
return LoadImage(imageURI, aForce, aNotify, doc);
return LoadImage(imageURI, aForce, aNotify, aImageLoadType, doc);
}
nsresult
nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
bool aForce,
bool aNotify,
ImageLoadType aImageLoadType,
nsIDocument* aDocument,
nsLoadFlags aLoadFlags)
{
@ -829,11 +861,14 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
// Are we blocked?
int16_t cpDecision = nsIContentPolicy::REJECT_REQUEST;
nsContentPolicyType policyType = PolicyTypeForLoad(aImageLoadType);
nsContentUtils::CanLoadImage(aNewURI,
static_cast<nsIImageLoadingContent*>(this),
aDocument,
aDocument->NodePrincipal(),
&cpDecision);
&cpDecision,
policyType);
if (!NS_CP_ACCEPTED(cpDecision)) {
FireEvent(NS_LITERAL_STRING("error"));
SetBlockedRequest(aNewURI, cpDecision);
@ -849,7 +884,7 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
}
// Not blocked. Do the load.
nsRefPtr<imgRequestProxy>& req = PrepareNextRequest();
nsRefPtr<imgRequestProxy>& req = PrepareNextRequest(aImageLoadType);
nsCOMPtr<nsIContent> content =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
nsresult rv;
@ -858,7 +893,8 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
aDocument->GetDocumentURI(),
this, loadFlags,
content->LocalName(),
getter_AddRefs(req));
getter_AddRefs(req),
policyType);
if (NS_SUCCEEDED(rv)) {
TrackImage(req);
@ -982,14 +1018,14 @@ nsImageLoadingContent::UpdateImageState(bool aNotify)
// XXX - This machinery should be removed after bug 521604.
return;
}
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
if (!thisContent) {
return;
}
mLoading = mBroken = mUserDisabled = mSuppressed = false;
// If we were blocked by server-based content policy, we claim to be
// suppressed. If we were blocked by type-based content policy, we claim to
// be user-disabled. Otherwise, claim to be broken.
@ -1024,7 +1060,8 @@ nsImageLoadingContent::CancelImageRequests(bool aNotify)
nsresult
nsImageLoadingContent::UseAsPrimaryRequest(imgRequestProxy* aRequest,
bool aNotify)
bool aNotify,
ImageLoadType aImageLoadType)
{
// Our state will change. Watch it.
AutoStateChanger changer(this, aNotify);
@ -1034,7 +1071,7 @@ nsImageLoadingContent::UseAsPrimaryRequest(imgRequestProxy* aRequest,
ClearCurrentRequest(NS_BINDING_ABORTED, REQUEST_DISCARD);
// Clone the request we were given.
nsRefPtr<imgRequestProxy>& req = PrepareNextRequest();
nsRefPtr<imgRequestProxy>& req = PrepareNextRequest(aImageLoadType);
nsresult rv = aRequest->Clone(this, getter_AddRefs(req));
if (NS_SUCCEEDED(rv)) {
TrackImage(req);
@ -1125,15 +1162,15 @@ nsImageLoadingContent::FireEvent(const nsAString& aEventType)
}
nsRefPtr<imgRequestProxy>&
nsImageLoadingContent::PrepareNextRequest()
nsImageLoadingContent::PrepareNextRequest(ImageLoadType aImageLoadType)
{
// If we don't have a usable current request, get rid of any half-baked
// request that might be sitting there and make this one current.
if (!HaveSize(mCurrentRequest))
return PrepareCurrentRequest();
return PrepareCurrentRequest(aImageLoadType);
// Otherwise, make it pending.
return PreparePendingRequest();
return PreparePendingRequest(aImageLoadType);
}
void
@ -1155,16 +1192,19 @@ nsImageLoadingContent::SetBlockedRequest(nsIURI* aURI, int16_t aContentDecision)
if (!HaveSize(mCurrentRequest)) {
mImageBlockingStatus = aContentDecision;
uint32_t keepFlags = mCurrentRequestFlags & REQUEST_IS_IMAGESET;
ClearCurrentRequest(NS_ERROR_IMAGE_BLOCKED, REQUEST_DISCARD);
// We still want to remember what URI we were despite not having an actual
// request.
// We still want to remember what URI we were and if it was an imageset,
// despite not having an actual request. These are both cleared as part of
// ClearCurrentRequest() before a new request is started.
mCurrentURI = aURI;
mCurrentRequestFlags = keepFlags;
}
}
nsRefPtr<imgRequestProxy>&
nsImageLoadingContent::PrepareCurrentRequest()
nsImageLoadingContent::PrepareCurrentRequest(ImageLoadType aImageLoadType)
{
// Blocked images go through SetBlockedRequest, which is a separate path. For
// everything else, we're unblocked.
@ -1177,12 +1217,16 @@ nsImageLoadingContent::PrepareCurrentRequest()
mCurrentRequestFlags |= REQUEST_NEEDS_ANIMATION_RESET;
}
if (aImageLoadType == eImageLoadType_Imageset) {
mCurrentRequestFlags |= REQUEST_IS_IMAGESET;
}
// Return a reference.
return mCurrentRequest;
}
nsRefPtr<imgRequestProxy>&
nsImageLoadingContent::PreparePendingRequest()
nsImageLoadingContent::PreparePendingRequest(ImageLoadType aImageLoadType)
{
// Get rid of anything that was there previously.
ClearPendingRequest(NS_ERROR_IMAGE_SRC_CHANGED, REQUEST_DISCARD);
@ -1191,6 +1235,10 @@ nsImageLoadingContent::PreparePendingRequest()
mPendingRequestFlags |= REQUEST_NEEDS_ANIMATION_RESET;
}
if (aImageLoadType == eImageLoadType_Imageset) {
mPendingRequestFlags |= REQUEST_IS_IMAGESET;
}
// Return a reference.
return mPendingRequest;
}
@ -1233,7 +1281,11 @@ nsImageLoadingContent::MakePendingRequestCurrent()
// to go to 0 and the image to be discarded!
ImageRequestAutoLock autoLock(mCurrentRequest);
PrepareCurrentRequest() = mPendingRequest;
ImageLoadType loadType = \
(mPendingRequestFlags & REQUEST_IS_IMAGESET) ? eImageLoadType_Imageset
: eImageLoadType_Normal;
PrepareCurrentRequest(loadType) = mPendingRequest;
mPendingRequest = nullptr;
mCurrentRequestFlags = mPendingRequestFlags;
mPendingRequestFlags = 0;
@ -1246,8 +1298,9 @@ nsImageLoadingContent::ClearCurrentRequest(nsresult aReason,
{
if (!mCurrentRequest) {
// Even if we didn't have a current request, we might have been keeping
// a URI as a placeholder for a failed load. Clear that now.
// a URI and flags as a placeholder for a failed load. Clear that now.
mCurrentURI = nullptr;
mCurrentRequestFlags = 0;
return;
}
NS_ABORT_IF_FALSE(!mCurrentURI,

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

@ -22,6 +22,8 @@
#include "nsIRequest.h"
#include "mozilla/ErrorResult.h"
#include "nsAutoPtr.h"
#include "nsIContentPolicy.h"
#include "mozilla/dom/BindingDeclarations.h"
class nsIURI;
class nsIDocument;
@ -63,28 +65,46 @@ public:
int32_t
GetRequestType(imgIRequest* aRequest, mozilla::ErrorResult& aError);
already_AddRefed<nsIURI> GetCurrentURI(mozilla::ErrorResult& aError);
void ForceReload(const mozilla::dom::Optional<bool>& aNotify,
mozilla::ErrorResult& aError);
// XPCOM [optional] syntax helper
nsresult ForceReload(bool aNotify = true) {
return ForceReload(aNotify, 1);
}
/**
* Used to initialize content with a previously opened channel. Assumes
* eImageLoadType_Normal
*/
already_AddRefed<nsIStreamListener>
LoadImageWithChannel(nsIChannel* aChannel, mozilla::ErrorResult& aError);
void ForceReload(mozilla::ErrorResult& aError);
protected:
enum ImageLoadType {
// Most normal image loads
eImageLoadType_Normal,
// From a <img srcset> or <picture> context. Affects type given to content
// policy.
eImageLoadType_Imageset
};
/**
* LoadImage is called by subclasses when the appropriate
* attributes (eg 'src' for <img> tags) change. The string passed
* in is the new uri string; this consolidates the code for getting
* the charset, constructing URI objects, and any other incidentals
* into this superclass.
* into this superclass.
*
* @param aNewURI the URI spec to be loaded (may be a relative URI)
* @param aForce If true, make sure to load the URI. If false, only
* load if the URI is different from the currently loaded URI.
* @param aNotify If true, nsIDocumentObserver state change notifications
* will be sent as needed.
* @param aImageLoadType The ImageLoadType for this request
*/
nsresult LoadImage(const nsAString& aNewURI, bool aForce,
bool aNotify);
bool aNotify, ImageLoadType aImageLoadType);
/**
* ImageState is called by subclasses that are computing their content state.
@ -108,13 +128,14 @@ protected:
* load if the URI is different from the currently loaded URI.
* @param aNotify If true, nsIDocumentObserver state change notifications
* will be sent as needed.
* @param aImageLoadType The ImageLoadType for this request
* @param aDocument Optional parameter giving the document this node is in.
* This is purely a performance optimization.
* @param aLoadFlags Optional parameter specifying load flags to use for
* the image load
*/
nsresult LoadImage(nsIURI* aNewURI, bool aForce, bool aNotify,
nsIDocument* aDocument = nullptr,
ImageLoadType aImageLoadType, nsIDocument* aDocument = nullptr,
nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL);
/**
@ -158,7 +179,8 @@ protected:
* effectively be called instead of LoadImage or LoadImageWithChannel.
* If aNotify is true, this method will notify on state changes.
*/
nsresult UseAsPrimaryRequest(imgRequestProxy* aRequest, bool aNotify);
nsresult UseAsPrimaryRequest(imgRequestProxy* aRequest, bool aNotify,
ImageLoadType aImageLoadType);
/**
* Derived classes of nsImageLoadingContent MUST call
@ -191,6 +213,9 @@ protected:
void OnUnlockedDraw();
nsresult OnImageIsAnimated(imgIRequest *aRequest);
// The nsContentPolicyType we would use for this ImageLoadType
static nsContentPolicyType PolicyTypeForLoad(ImageLoadType aImageLoadType);
private:
/**
* Struct used to manage the image observers.
@ -260,8 +285,10 @@ protected:
* a _usable_ current request (one with SIZE_AVAILABLE), this request is
* "pending" until it becomes usable. Otherwise, this becomes the current
* request.
*
* @param aImageLoadType The ImageLoadType for this request
*/
nsRefPtr<imgRequestProxy>& PrepareNextRequest();
nsRefPtr<imgRequestProxy>& PrepareNextRequest(ImageLoadType aImageLoadType);
/**
* Called when we would normally call PrepareNextRequest(), but the request was
@ -275,9 +302,11 @@ protected:
* to get rid of one of the requests, you should call
* Clear*Request(NS_BINDING_ABORTED) instead, since it passes a more appropriate
* aReason than Prepare*Request() does (NS_ERROR_IMAGE_SRC_CHANGED).
*
* @param aImageLoadType The ImageLoadType for this request
*/
nsRefPtr<imgRequestProxy>& PrepareCurrentRequest();
nsRefPtr<imgRequestProxy>& PreparePendingRequest();
nsRefPtr<imgRequestProxy>& PrepareCurrentRequest(ImageLoadType aImageLoadType);
nsRefPtr<imgRequestProxy>& PreparePendingRequest(ImageLoadType aImageLoadType);
/**
* Switch our pending request to be our current request.
@ -339,7 +368,10 @@ protected:
// Set if the request is blocking onload.
REQUEST_BLOCKS_ONLOAD = 0x00000002U,
// Set if the request is currently tracked with the document.
REQUEST_IS_TRACKED = 0x00000004U
REQUEST_IS_TRACKED = 0x00000004U,
// Set if this is an imageset request, such as from <img srcset> or
// <picture>
REQUEST_IS_IMAGESET = 0x00000008U
};
// If the image was blocked or if there was an error loading, it's nice to

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

@ -434,13 +434,9 @@ HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
QueueImageLoadTask();
} else {
// Bug 1076583 - We still use the older synchronous algorithm in
// non-responsive mode. We want aForce == true in this LoadImage
// call, because we want to force a new load of the image with
// the new cross origin policy.
nsCOMPtr<nsIURI> currentURI;
if (NS_SUCCEEDED(GetCurrentURI(getter_AddRefs(currentURI))) && currentURI) {
LoadImage(currentURI, true, aNotify);
}
// non-responsive mode. Force a new load of the image with the
// new cross origin policy.
ForceReload(aNotify);
}
}
@ -551,7 +547,7 @@ HTMLImageElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
// the state gets in Element's attr-setting happen around this
// LoadImage call, we could start passing false instead of aNotify
// here.
LoadImage(aValue, true, aNotify);
LoadImage(aValue, true, aNotify, eImageLoadType_Normal);
mNewRequestsWillNeedAnimationReset = false;
}
@ -909,14 +905,19 @@ HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify)
if (mResponsiveSelector) {
nsCOMPtr<nsIURI> url = mResponsiveSelector->GetSelectedImageURL();
rv = LoadImage(url, aForce, aNotify);
rv = LoadImage(url, aForce, aNotify, eImageLoadType_Imageset);
} else {
nsAutoString src;
if (!GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
CancelImageRequests(aNotify);
rv = NS_OK;
} else {
rv = LoadImage(src, aForce, aNotify);
// If we have a srcset attribute or are in a <picture> element,
// we always use the Imageset load type, even if we parsed no
// valid responsive sources from either, per spec.
rv = LoadImage(src, aForce, aNotify,
HaveSrcsetOrInPicture() ? eImageLoadType_Imageset
: eImageLoadType_Normal);
}
}

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

@ -1314,7 +1314,7 @@ HTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
} else if (aNotify && aName == nsGkAtoms::src &&
mType == NS_FORM_INPUT_IMAGE) {
if (aValue) {
LoadImage(aValue->String(), true, aNotify);
LoadImage(aValue->String(), true, aNotify, eImageLoadType_Normal);
} else {
// Null value means the attr got unset; drop the image
CancelImageRequests(aNotify);
@ -1393,7 +1393,7 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
// whether we have an image to load;
nsAutoString src;
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
LoadImage(src, false, aNotify);
LoadImage(src, false, aNotify, eImageLoadType_Normal);
}
}
}
@ -4393,7 +4393,7 @@ HTMLInputElement::MaybeLoadImage()
nsAutoString uri;
if (mType == NS_FORM_INPUT_IMAGE &&
GetAttr(kNameSpaceID_None, nsGkAtoms::src, uri) &&
(NS_FAILED(LoadImage(uri, false, true)) ||
(NS_FAILED(LoadImage(uri, false, true, eImageLoadType_Normal)) ||
!LoadingEnabled())) {
CancelImageRequests(true);
}

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

@ -85,7 +85,7 @@ SVGFEImageElement::LoadSVGImage(bool aForce, bool aNotify)
}
}
return LoadImage(href, aForce, aNotify);
return LoadImage(href, aForce, aNotify, eImageLoadType_Normal);
}
//----------------------------------------------------------------------

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

@ -127,7 +127,7 @@ SVGImageElement::LoadSVGImage(bool aForce, bool aNotify)
if (baseURI && !href.IsEmpty())
NS_MakeAbsoluteURI(href, href, baseURI);
return LoadImage(href, aForce, aNotify);
return LoadImage(href, aForce, aNotify, eImageLoadType_Normal);
}
//----------------------------------------------------------------------

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

@ -103,7 +103,7 @@ interface MozImageLoadingContent {
[ChromeOnly,Throws]
nsIStreamListener? loadImageWithChannel(MozChannel aChannel);
[ChromeOnly,Throws]
void forceReload();
void forceReload(optional boolean aNotify);
[ChromeOnly]
void forceImageState(boolean aForce, unsigned long long aState);
};

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

@ -275,7 +275,7 @@ nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode *aDOMNode, imgRe
// bail for the parent node of the root element or null argument
if (!domElement)
break;
nsCOMPtr<nsIDOMCSSStyleDeclaration> computedStyle;
window->GetComputedStyle(domElement, EmptyString(),
getter_AddRefs(computedStyle));
@ -296,7 +296,8 @@ nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode *aDOMNode, imgRe
return il->LoadImage(bgUri, nullptr, nullptr, principal, nullptr,
nullptr, nullptr, nsIRequest::LOAD_NORMAL,
nullptr, EmptyString(), aRequest);
nullptr, nsIContentPolicy::TYPE_IMAGE,
EmptyString(), aRequest);
}
}

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

@ -18,6 +18,7 @@ interface nsIURI;
interface nsISimpleEnumerator;
#include "nsIRequest.idl" // for nsLoadFlags
#include "nsIContentPolicy.idl" // for nsContentPolicyType
/**
* imgILoader interface
@ -26,7 +27,7 @@ interface nsISimpleEnumerator;
* @version 0.3
* @see imagelib2
*/
[scriptable, builtinclass, uuid(046d5fa6-ac59-489d-b51e-0ffe57e8df59)]
[scriptable, builtinclass, uuid(42ef3b0a-cd82-454b-b4c4-f3470014a68b)]
interface imgILoader : nsISupports
{
// Extra flags to pass to loadImage if you want a load to use CORS
@ -46,6 +47,9 @@ interface imgILoader : nsISupports
* @param aLoadFlags Load flags for the request
* @param aCacheKey cache key to use for a load if the original
* image came from a request that had post data
* @param aContentPolicyType [optional] the nsContentPolicyType to
* use for this load. Defaults to
* nsIContentPolicy::TYPE_IMAGE
* libpr0n does NOT keep a strong ref to the observer; this prevents
@ -61,13 +65,15 @@ interface imgILoader : nsISupports
in imgINotificationObserver aObserver,
in nsISupports aCX,
in nsLoadFlags aLoadFlags,
in nsISupports cacheKey);
in nsISupports cacheKey,
[optional]
in nsContentPolicyType aContentPolicyType);
/**
* Start the load and decode of an image.
* @param aChannel the channel to load the image from. This must
* already be opened before ths method is called, and there
* must have been no OnDataAvailable calls for it yet.
* must have been no OnDataAvailable calls for it yet.
* @param aObserver the observer (may be null)
* @param cx some random data
* @param aListener [out]

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

@ -635,6 +635,7 @@ static nsresult NewImageChannel(nsIChannel **aResult,
nsILoadGroup *aLoadGroup,
const nsCString& aAcceptHeader,
nsLoadFlags aLoadFlags,
nsContentPolicyType aPolicyType,
nsIPrincipal *aLoadingPrincipal,
nsISupports *aRequestingContext)
{
@ -680,6 +681,7 @@ static nsresult NewImageChannel(nsIChannel **aResult,
if (inherit) {
securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
}
// Note we are calling NS_NewChannelInternal() here with a node and a principal.
// This is for things like background images that are specified by user
// stylesheets, where the document is being styled, but the principal is that
@ -689,7 +691,7 @@ static nsresult NewImageChannel(nsIChannel **aResult,
requestingNode,
requestingPrincipal,
securityFlags,
nsIContentPolicy::TYPE_IMAGE,
aPolicyType,
nullptr, // loadGroup
callbacks,
aLoadFlags);
@ -1442,6 +1444,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
imgINotificationObserver *aObserver,
nsISupports *aCX,
nsLoadFlags aLoadFlags,
nsContentPolicyType aLoadPolicyType,
imgRequestProxy **aProxyRequest,
nsIPrincipal* aLoadingPrincipal,
int32_t aCORSMode)
@ -1490,6 +1493,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
aLoadGroup,
mAcceptHeader,
aLoadFlags,
aLoadPolicyType,
aLoadingPrincipal,
aCX);
if (NS_FAILED(rv)) {
@ -1567,6 +1571,7 @@ bool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
imgINotificationObserver *aObserver,
nsISupports *aCX,
nsLoadFlags aLoadFlags,
nsContentPolicyType aLoadPolicyType,
bool aCanMakeNewChannel,
imgRequestProxy **aProxyRequest,
nsIPrincipal* aLoadingPrincipal,
@ -1678,8 +1683,9 @@ bool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
return ValidateRequestWithNewChannel(request, aURI, aInitialDocumentURI,
aReferrerURI, aLoadGroup, aObserver,
aCX, aLoadFlags, aProxyRequest,
aLoadingPrincipal, aCORSMode);
aCX, aLoadFlags, aLoadPolicyType,
aProxyRequest, aLoadingPrincipal,
aCORSMode);
}
return !validateRequest;
@ -1853,8 +1859,13 @@ NS_IMETHODIMP imgLoader::LoadImageXPCOM(nsIURI *aURI,
nsISupports *aCX,
nsLoadFlags aLoadFlags,
nsISupports *aCacheKey,
nsContentPolicyType aContentPolicyType,
imgIRequest **_retval)
{
// Optional parameter, so defaults to 0 (== TYPE_INVALID)
if (!aContentPolicyType) {
aContentPolicyType = nsIContentPolicy::TYPE_IMAGE;
}
imgRequestProxy *proxy;
nsresult result = LoadImage(aURI,
aInitialDocumentURI,
@ -1865,6 +1876,7 @@ NS_IMETHODIMP imgLoader::LoadImageXPCOM(nsIURI *aURI,
aCX,
aLoadFlags,
aCacheKey,
aContentPolicyType,
EmptyString(),
&proxy);
*_retval = proxy;
@ -1889,10 +1901,11 @@ nsresult imgLoader::LoadImage(nsIURI *aURI,
nsISupports *aCX,
nsLoadFlags aLoadFlags,
nsISupports *aCacheKey,
nsContentPolicyType aContentPolicyType,
const nsAString& initiatorType,
imgRequestProxy **_retval)
{
VerifyCacheSizes();
VerifyCacheSizes();
NS_ASSERTION(aURI, "imgLoader::LoadImage -- NULL URI pointer");
@ -1967,8 +1980,9 @@ nsresult imgLoader::LoadImage(nsIURI *aURI,
if (cache.Get(spec, getter_AddRefs(entry)) && entry) {
if (ValidateEntry(entry, aURI, aInitialDocumentURI, aReferrerURI,
aLoadGroup, aObserver, aCX, requestFlags, true,
_retval, aLoadingPrincipal, corsmode)) {
aLoadGroup, aObserver, aCX, requestFlags,
aContentPolicyType, true, _retval,
aLoadingPrincipal, corsmode)) {
request = entry->GetRequest();
// If this entry has no proxies, its request has no reference to the entry.
@ -2010,6 +2024,7 @@ nsresult imgLoader::LoadImage(nsIURI *aURI,
aLoadGroup,
mAcceptHeader,
requestFlags,
aContentPolicyType,
aLoadingPrincipal,
aCX);
if (NS_FAILED(rv))
@ -2192,9 +2207,13 @@ nsresult imgLoader::LoadImageWithChannel(nsIChannel *channel, imgINotificationOb
//
// XXX -- should this be changed? it's pretty much verbatim from the old
// code, but seems nonsensical.
if (ValidateEntry(entry, uri, nullptr, nullptr, nullptr, aObserver, aCX,
requestFlags, false, nullptr, nullptr,
imgIRequest::CORS_NONE)) {
//
// Since aCanMakeNewChannel == false, we don't need to pass content policy
// type/principal/etc
if (ValidateEntry(entry, uri, nullptr, nullptr, nullptr,
aObserver, aCX, requestFlags,
nsIContentPolicy::TYPE_INVALID, false, nullptr,
nullptr, imgIRequest::CORS_NONE)) {
request = entry->GetRequest();
} else {
nsCOMPtr<nsICachingChannel> cacheChan(do_QueryInterface(channel));

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

@ -257,8 +257,10 @@ public:
nsISupports *aCX,
nsLoadFlags aLoadFlags,
nsISupports *aCacheKey,
nsContentPolicyType aContentPolicyType,
const nsAString& initiatorType,
imgRequestProxy **_retval);
nsresult LoadImageWithChannel(nsIChannel *channel,
imgINotificationObserver *aObserver,
nsISupports *aCX,
@ -336,7 +338,9 @@ private: // methods
nsIURI *aInitialDocumentURI, nsIURI *aReferrerURI,
nsILoadGroup *aLoadGroup,
imgINotificationObserver *aObserver, nsISupports *aCX,
nsLoadFlags aLoadFlags, bool aCanMakeNewChannel,
nsLoadFlags aLoadFlags,
nsContentPolicyType aContentPolicyType,
bool aCanMakeNewChannel,
imgRequestProxy **aProxyRequest,
nsIPrincipal* aLoadingPrincipal,
int32_t aCORSMode);
@ -347,6 +351,7 @@ private: // methods
nsILoadGroup *aLoadGroup,
imgINotificationObserver *aObserver,
nsISupports *aCX, nsLoadFlags aLoadFlags,
nsContentPolicyType aContentPolicyType,
imgRequestProxy **aProxyRequest,
nsIPrincipal* aLoadingPrincipal,
int32_t aCORSMode);

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

@ -1938,7 +1938,7 @@ nsImageFrame::LoadIcon(const nsAString& aSpec,
nsCOMPtr<nsIURI> realURI;
SpecToURI(aSpec, sIOService, getter_AddRefs(realURI));
nsRefPtr<imgLoader> il =
nsContentUtils::GetImgLoaderForDocument(aPresContext->Document());
@ -1947,6 +1947,7 @@ nsImageFrame::LoadIcon(const nsAString& aSpec,
// For icon loads, we don't need to merge with the loadgroup flags
nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
nsContentPolicyType contentPolicyType = nsIContentPolicy::TYPE_IMAGE;
return il->LoadImage(realURI, /* icon URI */
nullptr, /* initial document URI; this is only
@ -1959,6 +1960,7 @@ nsImageFrame::LoadIcon(const nsAString& aSpec,
nullptr, /* Not associated with any particular document */
loadFlags,
nullptr,
contentPolicyType,
EmptyString(),
aRequest);
}

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

@ -14,6 +14,7 @@
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIObserver.h"
#include "nsIContentPolicy.h"
#include "imgRequestProxy.h"
using namespace mozilla;
@ -244,7 +245,7 @@ OSXNotificationCenter::ShowAlertNotification(const nsAString & aImageUrl, const
if (imageUri) {
nsresult rv = il->LoadImage(imageUri, nullptr, nullptr, aPrincipal, nullptr,
this, nullptr, nsIRequest::LOAD_NORMAL, nullptr,
EmptyString(),
nsIContentPolicy::TYPE_IMAGE, EmptyString(),
getter_AddRefs(osxni->mIconRequest));
if (NS_SUCCEEDED(rv)) {
// Set a timer for six seconds. If we don't have an icon by the time this

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

@ -40,6 +40,7 @@
#include "imgIContainer.h"
#include "nsCocoaUtils.h"
#include "nsContentUtils.h"
#include "nsIContentPolicy.h"
using mozilla::gfx::SourceSurface;
using mozilla::RefPtr;
@ -307,7 +308,8 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconURI)
nsresult rv = loader->LoadImage(aIconURI, nullptr, nullptr, nullptr, loadGroup, this,
nullptr, nsIRequest::LOAD_NORMAL, nullptr,
EmptyString(), getter_AddRefs(mIconRequest));
nsIContentPolicy::TYPE_IMAGE, EmptyString(),
getter_AddRefs(mIconRequest));
if (NS_FAILED(rv)) return rv;
// We need to request the icon be decoded (bug 573583, bug 705516).