diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -1987,17 +1987,17 @@ PresShell::FireResizeEvent() } void PresShell::SetIgnoreFrameDestruction(bool aIgnore) { if (mDocument) { // We need to tell the ImageLoader to drop all its references to frames // because they're about to go away and it won't get notifications of that. - mDocument->StyleImageLoader()->ClearAll(); + mDocument->StyleImageLoader()->ClearFrames(); } mIgnoreFrameDestruction = aIgnore; } void PresShell::NotifyDestroyingFrame(nsIFrame* aFrame) { if (!mIgnoreFrameDestruction) { diff --git a/layout/reftests/backgrounds/reftest.list b/layout/reftests/backgrounds/reftest.list --- a/layout/reftests/backgrounds/reftest.list +++ b/layout/reftests/backgrounds/reftest.list @@ -128,15 +128,16 @@ fails == background-size-zoom-repeat.htm random-if(bug685516||B2G) == fixed-bg-with-transform-outside-viewport-1.html fixed-bg-with-transform-outside-viewport-ref.html random-if(bug685516) HTTP == root-background-1.html root-background-ref.html random-if(bug685516) HTTP != root-background-1.html about:blank random-if(bug685516||B2G) == really-big-background.html really-big-background-ref.html random-if(bug685516) == body-background.html body-background-ref.html random-if(bug685516) == table-background.html table-background-ref.html +random-if(bug685516) == table-background-print.html table-background-print-ref.html random-if(bug685516) != div-background.html div-background-ref.html random-if(bug685516) == background-repeat-1-ref.html background-repeat-1.html random-if(bug685516) == multi-background-clip-content-border.html multi-background-clip-content-border-ref.html HTTP == background-referrer.html background-referrer-ref.html diff --git a/layout/reftests/backgrounds/table-background-ref.html b/layout/reftests/backgrounds/table-background-print-ref.html copy from layout/reftests/backgrounds/table-background-ref.html copy to layout/reftests/backgrounds/table-background-print-ref.html --- a/layout/reftests/backgrounds/table-background-ref.html +++ b/layout/reftests/backgrounds/table-background-print-ref.html @@ -1,8 +1,9 @@ +
Foo @@ -32,8 +33,9 @@
Baz
+ diff --git a/layout/reftests/backgrounds/table-background.html b/layout/reftests/backgrounds/table-background-print.html copy from layout/reftests/backgrounds/table-background.html copy to layout/reftests/backgrounds/table-background-print.html --- a/layout/reftests/backgrounds/table-background.html +++ b/layout/reftests/backgrounds/table-background-print.html @@ -1,8 +1,9 @@ +
Foo @@ -32,8 +33,9 @@
Baz
+ diff --git a/layout/reftests/backgrounds/table-background-ref.html b/layout/reftests/backgrounds/table-background-ref.html --- a/layout/reftests/backgrounds/table-background-ref.html +++ b/layout/reftests/backgrounds/table-background-ref.html @@ -1,8 +1,9 @@ +
Foo @@ -32,8 +33,9 @@
Baz
+ diff --git a/layout/reftests/backgrounds/table-background.html b/layout/reftests/backgrounds/table-background.html --- a/layout/reftests/backgrounds/table-background.html +++ b/layout/reftests/backgrounds/table-background.html @@ -1,8 +1,9 @@ +
Foo @@ -32,8 +33,9 @@
Baz
+ diff --git a/layout/reftests/bugs/816948-1-ref.html b/layout/reftests/bugs/816948-1-ref.html new file mode 100644 --- /dev/null +++ b/layout/reftests/bugs/816948-1-ref.html @@ -0,0 +1,6 @@ + + + + + diff --git a/layout/reftests/bugs/816948-1.html b/layout/reftests/bugs/816948-1.html new file mode 100644 --- /dev/null +++ b/layout/reftests/bugs/816948-1.html @@ -0,0 +1,16 @@ + + + + + + diff --git a/layout/reftests/bugs/816948-iframe.html b/layout/reftests/bugs/816948-iframe.html new file mode 100644 --- /dev/null +++ b/layout/reftests/bugs/816948-iframe.html @@ -0,0 +1,3 @@ + +foopy + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1734,15 +1734,16 @@ fuzzy(40,800) == 797797-2.html 797797-2- == 804323-1.html 804323-1-ref.html == 811301-1.html 811301-1-ref.html == 812824-1.html 812824-1-ref.html == 814677.html 814677-ref.html skip-if(B2G) == 815593-1.html 815593-1-ref.html skip-if(B2G) == 814952-1.html 814952-1-ref.html == 816458-1.html 816458-1-ref.html == 816359-1.html 816359-1-ref.html +== 816948-1.html 816948-1-ref.html == 817019-1.html about:blank skip-if(B2G) == 818276-1.html 818276-1-ref.html == 825999.html 825999-ref.html == 827577-1a.html 827577-1-ref.html == 827577-1b.html 827577-1-ref.html == 827799-1.html about:blank == 836844-1.html 836844-1-ref.html diff --git a/layout/style/ImageLoader.cpp b/layout/style/ImageLoader.cpp --- a/layout/style/ImageLoader.cpp +++ b/layout/style/ImageLoader.cpp @@ -38,20 +38,37 @@ ImageLoader::SetAnimationModeEnumerator( } // This can fail if the image is in error, and we don't care. container->SetAnimationMode(*mode); return PL_DHASH_NEXT; } +static PLDHashOperator +ClearImageHashSet(nsPtrHashKey* aKey, void* aClosure) +{ + nsIDocument* doc = static_cast(aClosure); + ImageLoader::Image* image = aKey->GetKey(); + + imgIRequest* request = image->mRequests.GetWeak(doc); + if (request) { + request->CancelAndForgetObserver(NS_BINDING_ABORTED); + } + + image->mRequests.Remove(doc); + + return PL_DHASH_REMOVE; +} + void ImageLoader::DropDocumentReference() { - ClearAll(); + ClearFrames(); + mImages.EnumerateEntries(&ClearImageHashSet, mDocument); mDocument = nullptr; } void ImageLoader::AssociateRequestToFrame(imgIRequest* aRequest, nsIFrame* aFrame) { MOZ_ASSERT(mRequestToFrameMap.IsInitialized() && @@ -216,38 +233,21 @@ ImageLoader::SetAnimationMode(uint16_t a NS_ASSERTION(aMode == imgIContainer::kNormalAnimMode || aMode == imgIContainer::kDontAnimMode || aMode == imgIContainer::kLoopOnceAnimMode, "Wrong Animation Mode is being set!"); mRequestToFrameMap.EnumerateRead(SetAnimationModeEnumerator, &aMode); } -static PLDHashOperator -ClearImageHashSet(nsPtrHashKey* aKey, void* aClosure) -{ - nsIDocument* doc = static_cast(aClosure); - ImageLoader::Image* image = aKey->GetKey(); - - imgIRequest* request = image->mRequests.GetWeak(doc); - if (request) { - request->CancelAndForgetObserver(NS_BINDING_ABORTED); - } - - image->mRequests.Remove(doc); - - return PL_DHASH_REMOVE; -} - void -ImageLoader::ClearAll() +ImageLoader::ClearFrames() { mRequestToFrameMap.Clear(); mFrameToRequestMap.Clear(); - mImages.EnumerateEntries(&ClearImageHashSet, mDocument); } void ImageLoader::LoadImage(nsIURI* aURI, nsIPrincipal* aOriginPrincipal, nsIURI* aReferrer, ImageLoader::Image* aImage) { NS_ASSERTION(aImage->mRequests.Count() == 0, "Huh?"); diff --git a/layout/style/ImageLoader.h b/layout/style/ImageLoader.h --- a/layout/style/ImageLoader.h +++ b/layout/style/ImageLoader.h @@ -54,17 +54,17 @@ public: void DisassociateRequestFromFrame(imgIRequest* aRequest, nsIFrame* aFrame); void DropRequestsForFrame(nsIFrame* aFrame); void SetAnimationMode(uint16_t aMode); - void ClearAll(); + void ClearFrames(); void LoadImage(nsIURI* aURI, nsIPrincipal* aPrincipal, nsIURI* aReferrer, Image* aCSSValue); void DestroyRequest(imgIRequest* aRequest); private: // We need to be able to look up the frames associated with a request (for diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -1716,24 +1716,32 @@ css::URLValue::SizeOfIncludingThis(nsMal } css::ImageValue::ImageValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal, nsIDocument* aDocument) : URLValue(aURI, aString, aReferrer, aOriginPrincipal) { - if (aDocument->GetOriginalDocument()) { - aDocument = aDocument->GetOriginalDocument(); + // 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. + nsIDocument* loadingDoc = aDocument->GetOriginalDocument(); + if (!loadingDoc) { + loadingDoc = aDocument; } mRequests.Init(); - aDocument->StyleImageLoader()->LoadImage(aURI, aOriginPrincipal, aReferrer, - this); + loadingDoc->StyleImageLoader()->LoadImage(aURI, aOriginPrincipal, aReferrer, + this); + + if (loadingDoc != aDocument) { + aDocument->StyleImageLoader()->MaybeRegisterCSSImage(this); + } } static PLDHashOperator ClearRequestHashtable(nsISupports* aKey, nsRefPtr& aValue, void* aClosure) { mozilla::css::ImageValue* image = static_cast(aClosure); diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h --- a/layout/style/nsCSSValue.h +++ b/layout/style/nsCSSValue.h @@ -120,17 +120,17 @@ struct ImageValue : public URLValue { // this header is included all over. // aString must not be null. ImageValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal, nsIDocument* aDocument); ~ImageValue(); // Inherit operator== from URLValue - nsRefPtrHashtable mRequests; + nsRefPtrHashtable, imgRequestProxy> mRequests; // Override AddRef and Release to not only log ourselves correctly, but // also so that we delete correctly without a virtual destructor NS_INLINE_DECL_REFCOUNTING(ImageValue) }; } }