diff --git a/layout/xul/base/src/nsImageBoxFrame.cpp b/layout/xul/base/src/nsImageBoxFrame.cpp index e786fee90a9..5dfad2c88ae 100644 --- a/layout/xul/base/src/nsImageBoxFrame.cpp +++ b/layout/xul/base/src/nsImageBoxFrame.cpp @@ -72,6 +72,7 @@ #include "nsIDOMDocument.h" #include "nsTransform2D.h" #include "nsITheme.h" +#include "nsIImageLoadingContent.h" #include "nsIServiceManager.h" #include "nsIURI.h" @@ -173,6 +174,7 @@ nsImageBoxFrame::AttributeChanged(PRInt32 aNameSpaceID, nsImageBoxFrame::nsImageBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext): nsLeafBoxFrame(aShell, aContext), mIntrinsicSize(0,0), + mRequestRegistered(false), mLoadFlags(nsIRequest::LOAD_NORMAL), mUseSrcAttr(false), mSuppressStyleCheck(false) @@ -195,9 +197,16 @@ nsImageBoxFrame::MarkIntrinsicWidthsDirty() void nsImageBoxFrame::DestroyFrom(nsIFrame* aDestructRoot) { - // Release image loader first so that it's refcnt can go to zero - if (mImageRequest) + if (mImageRequest) { + nsPresContext* presContext = PresContext(); + NS_ASSERTION(presContext, "No PresContext"); + nsLayoutUtils::DeregisterImageRequest(presContext, + mImageRequest, + &mRequestRegistered); + + // Release image loader first so that it's refcnt can go to zero mImageRequest->CancelAndForgetObserver(NS_ERROR_FAILURE); + } if (mListener) reinterpret_cast(mListener.get())->SetFrame(nsnull); // set the frame to null so we don't send messages to a dead object. @@ -232,7 +241,12 @@ nsImageBoxFrame::Init(nsIContent* aContent, void nsImageBoxFrame::UpdateImage() { + nsPresContext* presContext = PresContext(); + NS_ASSERTION(presContext, "No PresContext"); + if (mImageRequest) { + nsLayoutUtils::DeregisterImageRequest(presContext, mImageRequest, + &mRequestRegistered); mImageRequest->CancelAndForgetObserver(NS_ERROR_FAILURE); mImageRequest = nsnull; } @@ -259,6 +273,12 @@ nsImageBoxFrame::UpdateImage() nsContentUtils::LoadImage(uri, doc, mContent->NodePrincipal(), doc->GetDocumentURI(), mListener, mLoadFlags, getter_AddRefs(mImageRequest)); + + // Register our imgIRequest with the refresh driver + nsLayoutUtils::RegisterImageRequest(presContext, + mImageRequest, + &mRequestRegistered); + } } else { // Only get the list-style-image if we aren't being drawn @@ -583,10 +603,31 @@ NS_IMETHODIMP nsImageBoxFrame::OnStopContainer(imgIRequest *request, return NS_OK; } +NS_IMETHODIMP nsImageBoxFrame::OnStartDecode(imgIRequest* aRequest) +{ + nsPresContext* presContext = PresContext(); + NS_ASSERTION(presContext, "No PresContext"); + + nsLayoutUtils::RegisterImageRequest(presContext, + mImageRequest, + &mRequestRegistered); + + return NS_OK; +} + NS_IMETHODIMP nsImageBoxFrame::OnStopDecode(imgIRequest *request, nsresult aStatus, const PRUnichar *statusArg) { + // If the imgIRequest does not represent an animated image, then we should + // deregister it from our refresh driver. + nsPresContext* presContext = PresContext(); + NS_ASSERTION(presContext, "No PresContext"); + + nsLayoutUtils::DeregisterImageRequestIfNotAnimated(presContext, + mImageRequest, + &mRequestRegistered); + if (NS_SUCCEEDED(aStatus)) // Fire an onload DOM event. FireImageDOMEvent(mContent, NS_LOAD); @@ -624,7 +665,7 @@ NS_IMETHODIMP nsImageBoxListener::OnStartContainer(imgIRequest *request, imgIContainer *image) { if (!mFrame) - return NS_ERROR_FAILURE; + return NS_OK; return mFrame->OnStartContainer(request, image); } @@ -633,17 +674,26 @@ NS_IMETHODIMP nsImageBoxListener::OnStopContainer(imgIRequest *request, imgIContainer *image) { if (!mFrame) - return NS_ERROR_FAILURE; + return NS_OK; return mFrame->OnStopContainer(request, image); } +NS_IMETHODIMP nsImageBoxListener::OnStartDecode(imgIRequest *aRequest) +{ + if (!mFrame) { + return NS_OK; + } + + return mFrame->OnStartDecode(aRequest); +} + NS_IMETHODIMP nsImageBoxListener::OnStopDecode(imgIRequest *request, nsresult status, const PRUnichar *statusArg) { if (!mFrame) - return NS_ERROR_FAILURE; + return NS_OK; return mFrame->OnStopDecode(request, status, statusArg); } diff --git a/layout/xul/base/src/nsImageBoxFrame.h b/layout/xul/base/src/nsImageBoxFrame.h index f6f2fdce747..5eebdaa6b3e 100644 --- a/layout/xul/base/src/nsImageBoxFrame.h +++ b/layout/xul/base/src/nsImageBoxFrame.h @@ -56,6 +56,7 @@ public: // imgIDecoderObserver (override nsStubImageDecoderObserver) NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image); NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image); + NS_IMETHOD OnStartDecode(imgIRequest *aRequest); NS_IMETHOD OnStopDecode(imgIRequest *request, nsresult status, const PRUnichar *statusArg); // imgIContainerObserver (override nsStubImageDecoderObserver) @@ -119,6 +120,7 @@ public: NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image); NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image); + NS_IMETHOD OnStartDecode(imgIRequest *aRequest); NS_IMETHOD OnStopDecode(imgIRequest *request, nsresult status, const PRUnichar *statusArg); @@ -142,6 +144,10 @@ private: nsSize mIntrinsicSize; nsSize mImageSize; + // Boolean variable to determine if the current image request has been + // registered with the refresh driver. + bool mRequestRegistered; + nsCOMPtr mImageRequest; nsCOMPtr mListener;