Bug 1615261 - Fix ImageLoader setup for animated images in print preview. r=tnikkel

It's not clear to me this ever worked before either, I don't think the logic
before my patch was sound before.

But oh well. This should work, gotta add a test for it.

Differential Revision: https://phabricator.services.mozilla.com/D62777
This commit is contained in:
Emilio Cobos Álvarez
2020-02-14 12:36:25 +00:00
parent 041d1af93a
commit 58be124d69
3 changed files with 48 additions and 19 deletions

View File

@@ -399,7 +399,7 @@ static CORSMode EffectiveCorsMode(nsIURI* aURI,
/* static */
already_AddRefed<imgRequestProxy> ImageLoader::LoadImage(
const StyleComputedImageUrl& aImage, Document& aLoadingDoc) {
const StyleComputedImageUrl& aImage, Document& aDocument) {
MOZ_ASSERT(NS_IsMainThread());
nsIURI* uri = aImage.GetURI();
if (!uri) {
@@ -412,9 +412,18 @@ already_AddRefed<imgRequestProxy> ImageLoader::LoadImage(
const URLExtraData& data = aImage.ExtraData();
// NB: If aDocument is not the original document, we may not be able to load
// images from aDocument. Instead we do the image load from the original
// doc and clone it to aDocument.
Document* loadingDoc = aDocument.GetOriginalDocument();
const bool isPrint = !!loadingDoc;
if (!loadingDoc) {
loadingDoc = &aDocument;
}
RefPtr<imgRequestProxy> request;
nsresult rv = nsContentUtils::LoadImage(
uri, &aLoadingDoc, &aLoadingDoc, data.Principal(), 0, data.ReferrerInfo(),
uri, loadingDoc, loadingDoc, data.Principal(), 0, data.ReferrerInfo(),
sImageObserver, loadFlags, NS_LITERAL_STRING("css"),
getter_AddRefs(request));
@@ -422,6 +431,28 @@ already_AddRefed<imgRequestProxy> ImageLoader::LoadImage(
return nullptr;
}
if (isPrint) {
RefPtr<imgRequestProxy> ret;
request->GetStaticRequest(&aDocument, getter_AddRefs(ret));
// Now we have a static image. If it is different from the one from the
// loading doc (that is, `request` is an animated image, and `ret` is a
// frozen version of it), we can forget about notifications from the
// animated image (assuming nothing else cares about it already).
//
// This is not technically needed for correctness, but helps keep the
// invariant that we only receive notifications for images that are in
// `sImages`.
if (ret != request) {
if (!sImages->Contains(request)) {
request->CancelAndForgetObserver(NS_BINDING_ABORTED);
}
if (!ret) {
return nullptr;
}
request = std::move(ret);
}
}
sImages->LookupForAdd(request).OrInsert([] { return new ImageTableEntry(); });
return request.forget();
}