Bug 851755 - Make nsImageBoxFrame block its document's onload when its image blocks onload. r=tn

--HG--
extra : rebase_source : e68858154d321796c9490c5c83b96848de733e46
This commit is contained in:
Joe Drew 2013-03-15 22:53:25 -04:00
parent 9e2352d65c
commit 42bcd21d5d
2 changed files with 66 additions and 12 deletions

View File

@ -144,7 +144,8 @@ nsImageBoxFrame::nsImageBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext)
mRequestRegistered(false), mRequestRegistered(false),
mLoadFlags(nsIRequest::LOAD_NORMAL), mLoadFlags(nsIRequest::LOAD_NORMAL),
mUseSrcAttr(false), mUseSrcAttr(false),
mSuppressStyleCheck(false) mSuppressStyleCheck(false),
mFireEventOnDecode(false)
{ {
MarkIntrinsicWidthsDirty(); MarkIntrinsicWidthsDirty();
} }
@ -630,6 +631,22 @@ nsresult nsImageBoxFrame::OnStartContainer(imgIRequest *request,
nsresult nsImageBoxFrame::OnStopDecode(imgIRequest *request) nsresult nsImageBoxFrame::OnStopDecode(imgIRequest *request)
{ {
if (mFireEventOnDecode) {
mFireEventOnDecode = false;
uint32_t reqStatus;
request->GetImageStatus(&reqStatus);
if (!(reqStatus & imgIRequest::STATUS_ERROR)) {
FireImageDOMEvent(mContent, NS_LOAD);
} else {
// Fire an onerror DOM event.
mIntrinsicSize.SizeTo(0, 0);
PresContext()->PresShell()->
FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
FireImageDOMEvent(mContent, NS_LOAD_ERROR);
}
}
nsBoxLayoutState state(PresContext()); nsBoxLayoutState state(PresContext());
this->Redraw(state); this->Redraw(state);
@ -639,15 +656,26 @@ nsresult nsImageBoxFrame::OnStopDecode(imgIRequest *request)
nsresult nsImageBoxFrame::OnStopRequest(imgIRequest *request, nsresult nsImageBoxFrame::OnStopRequest(imgIRequest *request,
nsresult aStatus) nsresult aStatus)
{ {
if (NS_SUCCEEDED(aStatus)) uint32_t reqStatus;
// Fire an onload DOM event. request->GetImageStatus(&reqStatus);
FireImageDOMEvent(mContent, NS_LOAD);
else { // We want to give the decoder a chance to find errors. If we haven't found
// Fire an onerror DOM event. // an error yet and we've already started decoding, we must only fire these
mIntrinsicSize.SizeTo(0, 0); // events after we finish decoding.
PresContext()->PresShell()-> if (NS_SUCCEEDED(aStatus) && !(reqStatus & imgIRequest::STATUS_ERROR) &&
FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY); reqStatus & imgIRequest::STATUS_DECODE_STARTED) {
FireImageDOMEvent(mContent, NS_LOAD_ERROR); mFireEventOnDecode = true;
} else {
if (NS_SUCCEEDED(aStatus)) {
// Fire an onload DOM event.
FireImageDOMEvent(mContent, NS_LOAD);
} else {
// Fire an onerror DOM event.
mIntrinsicSize.SizeTo(0, 0);
PresContext()->PresShell()->
FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
FireImageDOMEvent(mContent, NS_LOAD_ERROR);
}
} }
return NS_OK; return NS_OK;
@ -673,7 +701,7 @@ nsresult nsImageBoxFrame::FrameChanged(imgIRequest *aRequest)
return NS_OK; return NS_OK;
} }
NS_IMPL_ISUPPORTS1(nsImageBoxListener, imgINotificationObserver) NS_IMPL_ISUPPORTS2(nsImageBoxListener, imgINotificationObserver, imgIOnloadBlocker)
nsImageBoxListener::nsImageBoxListener() nsImageBoxListener::nsImageBoxListener()
{ {
@ -691,3 +719,25 @@ nsImageBoxListener::Notify(imgIRequest *request, int32_t aType, const nsIntRect*
return mFrame->Notify(request, aType, aData); return mFrame->Notify(request, aType, aData);
} }
/* void blockOnload (in imgIRequest aRequest); */
NS_IMETHODIMP
nsImageBoxListener::BlockOnload(imgIRequest *aRequest)
{
if (mFrame && mFrame->GetContent() && mFrame->GetContent()->GetCurrentDoc()) {
mFrame->GetContent()->GetCurrentDoc()->BlockOnload();
}
return NS_OK;
}
/* void unblockOnload (in imgIRequest aRequest); */
NS_IMETHODIMP
nsImageBoxListener::UnblockOnload(imgIRequest *aRequest)
{
if (mFrame && mFrame->GetContent() && mFrame->GetContent()->GetCurrentDoc()) {
mFrame->GetContent()->GetCurrentDoc()->UnblockOnload(false);
}
return NS_OK;
}

View File

@ -12,13 +12,15 @@
#include "imgIRequest.h" #include "imgIRequest.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "imgINotificationObserver.h" #include "imgINotificationObserver.h"
#include "imgIOnloadBlocker.h"
class imgRequestProxy; class imgRequestProxy;
class nsImageBoxFrame; class nsImageBoxFrame;
class nsDisplayXULImage; class nsDisplayXULImage;
class nsImageBoxListener : public imgINotificationObserver class nsImageBoxListener : public imgINotificationObserver,
public imgIOnloadBlocker
{ {
public: public:
nsImageBoxListener(); nsImageBoxListener();
@ -26,6 +28,7 @@ public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_IMGINOTIFICATIONOBSERVER NS_DECL_IMGINOTIFICATIONOBSERVER
NS_DECL_IMGIONLOADBLOCKER
void SetFrame(nsImageBoxFrame *frame) { mFrame = frame; } void SetFrame(nsImageBoxFrame *frame) { mFrame = frame; }
@ -118,6 +121,7 @@ private:
bool mUseSrcAttr; ///< Whether or not the image src comes from an attribute. bool mUseSrcAttr; ///< Whether or not the image src comes from an attribute.
bool mSuppressStyleCheck; bool mSuppressStyleCheck;
bool mFireEventOnDecode;
}; // class nsImageBoxFrame }; // class nsImageBoxFrame
class nsDisplayXULImage : public nsDisplayImageContainer { class nsDisplayXULImage : public nsDisplayImageContainer {