mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 13:25:37 +00:00
fixing bug 75185 r=brendan sr=attinasi
This commit is contained in:
parent
2fa656fb4b
commit
4f028f9c98
@ -69,6 +69,8 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|||||||
#include "nsIDOMNode.h"
|
#include "nsIDOMNode.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "nsContentPolicyUtils.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#undef NOISY_IMAGE_LOADING
|
#undef NOISY_IMAGE_LOADING
|
||||||
@ -189,13 +191,19 @@ nsImageFrame::Destroy(nsIPresContext* aPresContext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
if (mImageRequest)
|
if (mImageRequest)
|
||||||
mImageRequest->Cancel(NS_ERROR_FAILURE); // NS_BINDING_ABORT ?
|
mImageRequest->Cancel(NS_ERROR_FAILURE); // NS_BINDING_ABORT ?
|
||||||
if (mLowImageRequest)
|
if (mLowImageRequest)
|
||||||
mLowImageRequest->Cancel(NS_ERROR_FAILURE); // NS_BINDING_ABORT ?
|
mLowImageRequest->Cancel(NS_ERROR_FAILURE); // NS_BINDING_ABORT ?
|
||||||
|
|
||||||
|
// set the frame to null so we don't send messages to a dead object.
|
||||||
|
if (mListener)
|
||||||
|
NS_REINTERPRET_CAST(nsImageListener*, mListener.get())->SetFrame(nsnull);
|
||||||
|
|
||||||
|
mImageRequest = nsnull;
|
||||||
|
mLowImageRequest = nsnull;
|
||||||
|
mListener = nsnull;
|
||||||
|
|
||||||
if (mListener)
|
|
||||||
NS_REINTERPRET_CAST(nsImageListener*, mListener.get())->SetFrame(nsnull); // set the frame to null so we don't send messages to a dead object.
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef USE_IMG2
|
#ifndef USE_IMG2
|
||||||
@ -245,19 +253,21 @@ nsImageFrame::Init(nsIPresContext* aPresContext,
|
|||||||
nsresult lowSrcResult;
|
nsresult lowSrcResult;
|
||||||
lowSrcResult = mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::lowsrc, lowSrc);
|
lowSrcResult = mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::lowsrc, lowSrc);
|
||||||
|
|
||||||
// Set the image loader's source URL and base URL
|
#ifndef USE_IMG2
|
||||||
nsCOMPtr<nsIURI> baseURL;
|
nsCOMPtr<nsIURI> baseURL;
|
||||||
GetBaseURI(getter_AddRefs(baseURL));
|
GetBaseURI(getter_AddRefs(baseURL));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set the image loader's source URL and base URL
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
nsImageListener *listener;
|
if (!mListener) {
|
||||||
NS_NEWXPCOM(listener, nsImageListener);
|
nsImageListener *listener = new nsImageListener(this);
|
||||||
NS_ADDREF(listener);
|
if (!listener) return NS_ERROR_OUT_OF_MEMORY;
|
||||||
listener->SetFrame(this);
|
NS_ADDREF(listener);
|
||||||
listener->QueryInterface(NS_GET_IID(imgIDecoderObserver), getter_AddRefs(mListener));
|
listener->QueryInterface(NS_GET_IID(imgIDecoderObserver), getter_AddRefs(mListener));
|
||||||
NS_ASSERTION(mListener, "queryinterface for the listener failed");
|
NS_ASSERTION(mListener, "queryinterface for the listener failed");
|
||||||
NS_RELEASE(listener);
|
NS_RELEASE(listener);
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1", &rv));
|
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1", &rv));
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
@ -270,9 +280,11 @@ nsImageFrame::Init(nsIPresContext* aPresContext,
|
|||||||
if (NS_CONTENT_ATTR_HAS_VALUE == lowSrcResult && lowSrc.Length() > 0) {
|
if (NS_CONTENT_ATTR_HAS_VALUE == lowSrcResult && lowSrc.Length() > 0) {
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
nsCOMPtr<nsIURI> lowURI;
|
nsCOMPtr<nsIURI> lowURI;
|
||||||
NS_NewURI(getter_AddRefs(lowURI), src, baseURL);
|
GetURI(lowSrc, getter_AddRefs(lowURI));
|
||||||
|
|
||||||
il->LoadImage(lowURI, loadGroup, mListener, aPresContext, getter_AddRefs(mLowImageRequest));
|
if (CanLoadImage(lowURI)) {
|
||||||
|
il->LoadImage(lowURI, loadGroup, mListener, aPresContext, getter_AddRefs(mLowImageRequest));
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
mLowSrcImageLoader = new nsHTMLImageLoader;
|
mLowSrcImageLoader = new nsHTMLImageLoader;
|
||||||
if (mLowSrcImageLoader) {
|
if (mLowSrcImageLoader) {
|
||||||
@ -287,9 +299,11 @@ nsImageFrame::Init(nsIPresContext* aPresContext,
|
|||||||
mCanSendLoadEvent = PR_TRUE;
|
mCanSendLoadEvent = PR_TRUE;
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> srcURI;
|
nsCOMPtr<nsIURI> srcURI;
|
||||||
NS_NewURI(getter_AddRefs(srcURI), src, baseURL);
|
GetURI(src, getter_AddRefs(srcURI));
|
||||||
il->LoadImage(srcURI, loadGroup, mListener, aPresContext, getter_AddRefs(mImageRequest));
|
if (CanLoadImage(srcURI)) {
|
||||||
// if the image was found in the cache, it is possible that LoadImage will result in a call to OnStartContainer()
|
il->LoadImage(srcURI, loadGroup, mListener, aPresContext, getter_AddRefs(mImageRequest));
|
||||||
|
// if the image was found in the cache, it is possible that LoadImage will result in a call to OnStartContainer()
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
mImageLoader.Init(this, UpdateImageFrame, (void*)&mImageLoader, baseURL, src);
|
mImageLoader.Init(this, UpdateImageFrame, (void*)&mImageLoader, baseURL, src);
|
||||||
|
|
||||||
@ -324,10 +338,6 @@ NS_IMETHODIMP nsImageFrame::OnStartDecode(imgIRequest *aRequest, nsIPresContext
|
|||||||
|
|
||||||
NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresContext *aPresContext, imgIContainer *aImage)
|
NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresContext *aPresContext, imgIContainer *aImage)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIPresShell> presShell;
|
|
||||||
nsresult rv = aPresContext->GetShell(getter_AddRefs(presShell));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
mInitialLoadCompleted = PR_TRUE;
|
mInitialLoadCompleted = PR_TRUE;
|
||||||
|
|
||||||
nscoord w, h;
|
nscoord w, h;
|
||||||
@ -350,26 +360,16 @@ NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresConte
|
|||||||
if (mComputedSize.width != 0 && mComputedSize.height != 0)
|
if (mComputedSize.width != 0 && mComputedSize.height != 0)
|
||||||
mTransform.SetToScale((float(mIntrinsicSize.width) / float(mComputedSize.width)), (float(mIntrinsicSize.height) / float(mComputedSize.height)));
|
mTransform.SetToScale((float(mIntrinsicSize.width) / float(mComputedSize.width)), (float(mIntrinsicSize.height) / float(mComputedSize.height)));
|
||||||
|
|
||||||
if (mParent) {
|
if (!mSizeConstrained) {
|
||||||
if (mGotInitialReflow) { // don't reflow if we havn't gotten the inital reflow yet
|
nsCOMPtr<nsIPresShell> presShell;
|
||||||
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||||
|
NS_ASSERTION(mParent, "No parent to pass the reflow request up to.");
|
||||||
|
NS_ASSERTION(presShell, "No PresShell.");
|
||||||
|
if (mParent && presShell && mGotInitialReflow) { // don't reflow if we havn't gotten the inital reflow yet
|
||||||
mState |= NS_FRAME_IS_DIRTY;
|
mState |= NS_FRAME_IS_DIRTY;
|
||||||
mParent->ReflowDirtyChild(presShell, (nsIFrame*) this);
|
mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
NS_ASSERTION(0, "No parent to pass the reflow request up to.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCanSendLoadEvent && presShell) {
|
|
||||||
// Send load event
|
|
||||||
mCanSendLoadEvent = PR_FALSE;
|
|
||||||
|
|
||||||
nsEventStatus status = nsEventStatus_eIgnore;
|
|
||||||
nsEvent event;
|
|
||||||
event.eventStructType = NS_EVENT;
|
|
||||||
event.message = NS_IMAGE_LOAD;
|
|
||||||
presShell->HandleEventWithTarget(&event,this,mContent,NS_EVENT_FLAG_INIT | NS_EVENT_FLAG_CANT_BUBBLE,&status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -382,19 +382,18 @@ NS_IMETHODIMP nsImageFrame::OnStartFrame(imgIRequest *aRequest, nsIPresContext *
|
|||||||
|
|
||||||
NS_IMETHODIMP nsImageFrame::OnDataAvailable(imgIRequest *aRequest, nsIPresContext *aPresContext, gfxIImageFrame *aFrame, const nsRect *aRect)
|
NS_IMETHODIMP nsImageFrame::OnDataAvailable(imgIRequest *aRequest, nsIPresContext *aPresContext, gfxIImageFrame *aFrame, const nsRect *aRect)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIPresShell> presShell;
|
// XXX do we need to make sure that the reflow from the OnStartContainer has been
|
||||||
nsresult rv = aPresContext->GetShell(getter_AddRefs(presShell));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
// XXX we need to make sure that the reflow from the OnContainerStart has been
|
|
||||||
// processed before we start calling invalidate
|
// processed before we start calling invalidate
|
||||||
|
|
||||||
if (!aRect)
|
if (!aRect)
|
||||||
return NS_ERROR_NULL_POINTER;
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
|
||||||
nsRect r(aRect->x, aRect->y, aRect->width, aRect->height);
|
nsRect r(aRect->x, aRect->y, aRect->width, aRect->height);
|
||||||
|
|
||||||
|
/* XXX Why do we subtract 1 here? The rect is (for example): (0, 0, 600, 1)..
|
||||||
|
Why do we have to make y -1?
|
||||||
|
*/
|
||||||
|
|
||||||
// The y coordinate of aRect is passed as a scanline where the first scanline is given
|
// The y coordinate of aRect is passed as a scanline where the first scanline is given
|
||||||
// a value of 1. We need to convert this to the nsFrames coordinate space by subtracting
|
// a value of 1. We need to convert this to the nsFrames coordinate space by subtracting
|
||||||
// 1.
|
// 1.
|
||||||
@ -426,15 +425,76 @@ NS_IMETHODIMP nsImageFrame::OnStopContainer(imgIRequest *aRequest, nsIPresContex
|
|||||||
|
|
||||||
NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *aPresContext, nsresult aStatus, const PRUnichar *aStatusArg)
|
NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *aPresContext, nsresult aStatus, const PRUnichar *aStatusArg)
|
||||||
{
|
{
|
||||||
|
nsCOMPtr<nsIPresShell> presShell;
|
||||||
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||||
|
|
||||||
|
// check to see if an image error occurred
|
||||||
|
PRBool imageFailedToLoad = PR_FALSE;
|
||||||
|
|
||||||
|
if (NS_FAILED(aStatus)) { // We failed to load the image. Notify the pres shell
|
||||||
|
PRBool lowFailed = PR_FALSE;
|
||||||
|
PRBool imageFailed = PR_FALSE;
|
||||||
|
|
||||||
|
// One of the two images didn't load, which one?
|
||||||
|
if (mLowImageRequest == aRequest || !mLowImageRequest) {
|
||||||
|
lowFailed = PR_TRUE;
|
||||||
|
}
|
||||||
|
if (mImageRequest == aRequest || !mImageRequest) {
|
||||||
|
imageFailed = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imageFailed && lowFailed)
|
||||||
|
imageFailedToLoad = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if src failed and there is no lowsrc
|
||||||
|
// or both failed to load, then notify the PresShell
|
||||||
|
if (imageFailedToLoad) {
|
||||||
|
if (presShell) {
|
||||||
|
nsAutoString usemap;
|
||||||
|
mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::usemap, usemap);
|
||||||
|
// We failed to load the image. Notify the pres shell if we aren't an image map
|
||||||
|
if (usemap.IsEmpty()) {
|
||||||
|
presShell->CantRenderReplacedElement(aPresContext, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// After these DOM events are fired its possible that this frame may be deleted. As a result
|
||||||
|
// the code should not attempt to access any of the frames internal data after this point.
|
||||||
|
if (presShell) {
|
||||||
|
if (imageFailedToLoad) {
|
||||||
|
// Send error event
|
||||||
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
|
nsEvent event;
|
||||||
|
event.eventStructType = NS_EVENT;
|
||||||
|
event.message = NS_IMAGE_ERROR;
|
||||||
|
presShell->HandleEventWithTarget(&event,this,mContent,NS_EVENT_FLAG_INIT,&status);
|
||||||
|
} else if (mCanSendLoadEvent) {
|
||||||
|
// Send load event
|
||||||
|
mCanSendLoadEvent = PR_FALSE;
|
||||||
|
|
||||||
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
|
nsEvent event;
|
||||||
|
event.eventStructType = NS_EVENT;
|
||||||
|
event.message = NS_IMAGE_LOAD;
|
||||||
|
presShell->HandleEventWithTarget(&event,this,mContent,NS_EVENT_FLAG_INIT | NS_EVENT_FLAG_CANT_BUBBLE,&status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageFrame::FrameChanged(imgIContainer *aContainer, nsIPresContext *aPresContext, gfxIImageFrame *aNewFrame, nsRect *aDirtyRect)
|
NS_IMETHODIMP nsImageFrame::FrameChanged(imgIContainer *aContainer, nsIPresContext *aPresContext, gfxIImageFrame *aNewFrame, nsRect *aDirtyRect)
|
||||||
{
|
{
|
||||||
|
nsRect r(*aDirtyRect);
|
||||||
|
|
||||||
float p2t;
|
float p2t;
|
||||||
aPresContext->GetPixelsToTwips(&p2t);
|
aPresContext->GetPixelsToTwips(&p2t);
|
||||||
nsRect r(*aDirtyRect);
|
r.x = NSIntPixelsToTwips(r.x, p2t);
|
||||||
r *= p2t; // convert to twips
|
r.y = NSIntPixelsToTwips(r.y, p2t);
|
||||||
|
r.width = NSIntPixelsToTwips(r.width, p2t);
|
||||||
|
r.height = NSIntPixelsToTwips(r.height, p2t);
|
||||||
|
|
||||||
mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
||||||
|
|
||||||
@ -487,7 +547,7 @@ nsImageFrame::UpdateImage(nsIPresContext* aPresContext, PRUint32 aStatus, void*
|
|||||||
nsAutoString usemap;
|
nsAutoString usemap;
|
||||||
mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::usemap, usemap);
|
mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::usemap, usemap);
|
||||||
// We failed to load the image. Notify the pres shell if we aren't an image map
|
// We failed to load the image. Notify the pres shell if we aren't an image map
|
||||||
if (usemap.Length() == 0) {
|
if (usemap.IsEmpty()) {
|
||||||
presShell->CantRenderReplacedElement(aPresContext, this);
|
presShell->CantRenderReplacedElement(aPresContext, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -616,7 +676,7 @@ nsImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
|||||||
newHeight = (mIntrinsicSize.height * newWidth) / mIntrinsicSize.width;
|
newHeight = (mIntrinsicSize.height * newWidth) / mIntrinsicSize.width;
|
||||||
haveComputedSize = PR_TRUE;
|
haveComputedSize = PR_TRUE;
|
||||||
} else {
|
} else {
|
||||||
newHeight = NSIntPixelsToTwips(1, p2t); // XXX?
|
newHeight = 0;
|
||||||
needIntrinsicImageSize = PR_TRUE;
|
needIntrinsicImageSize = PR_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -628,30 +688,31 @@ nsImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
|||||||
newWidth = (mIntrinsicSize.width * newHeight) / mIntrinsicSize.height;
|
newWidth = (mIntrinsicSize.width * newHeight) / mIntrinsicSize.height;
|
||||||
haveComputedSize = PR_TRUE;
|
haveComputedSize = PR_TRUE;
|
||||||
} else {
|
} else {
|
||||||
newWidth = NSIntPixelsToTwips(1, p2t);
|
newWidth = 0;
|
||||||
needIntrinsicImageSize = PR_TRUE;
|
needIntrinsicImageSize = PR_TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// auto size the image
|
// auto size the image
|
||||||
if (mIntrinsicSize.width == 0 && mIntrinsicSize.height == 0) {
|
if (mIntrinsicSize.width == 0 && mIntrinsicSize.height == 0)
|
||||||
newWidth = NSIntPixelsToTwips(1, p2t);
|
|
||||||
newHeight = NSIntPixelsToTwips(1, p2t);
|
|
||||||
needIntrinsicImageSize = PR_TRUE;
|
needIntrinsicImageSize = PR_TRUE;
|
||||||
} else {
|
else
|
||||||
newWidth = mIntrinsicSize.width;
|
|
||||||
newHeight = mIntrinsicSize.height;
|
|
||||||
haveComputedSize = PR_TRUE;
|
haveComputedSize = PR_TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
|
newWidth = mIntrinsicSize.width;
|
||||||
|
newHeight = mIntrinsicSize.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
mComputedSize.width = newWidth;
|
mComputedSize.width = newWidth;
|
||||||
mComputedSize.height = newHeight;
|
mComputedSize.height = newHeight;
|
||||||
|
|
||||||
if (mComputedSize == mIntrinsicSize)
|
if (mComputedSize == mIntrinsicSize) {
|
||||||
mTransform.SetToIdentity();
|
mTransform.SetToIdentity();
|
||||||
else
|
} else {
|
||||||
mTransform.SetToScale((float(mIntrinsicSize.width) / float(mComputedSize.width)), (float(mIntrinsicSize.height) / float(mComputedSize.height)));
|
if (mComputedSize.width != 0 && mComputedSize.height != 0) {
|
||||||
|
mTransform.SetToScale(float(mIntrinsicSize.width) / float(mComputedSize.width),
|
||||||
|
float(mIntrinsicSize.height) / float(mComputedSize.height));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
aDesiredSize.width = mComputedSize.width;
|
aDesiredSize.width = mComputedSize.width;
|
||||||
aDesiredSize.height = mComputedSize.height;
|
aDesiredSize.height = mComputedSize.height;
|
||||||
@ -977,12 +1038,12 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
|
|||||||
PRInt32 imgSrcLinesLoaded = -1;
|
PRInt32 imgSrcLinesLoaded = -1;
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
|
|
||||||
NS_ASSERTION(mImageRequest, "no image request! this is bad");
|
|
||||||
|
|
||||||
nsCOMPtr<imgIContainer> imgCon;
|
nsCOMPtr<imgIContainer> imgCon;
|
||||||
nsCOMPtr<imgIContainer> lowImgCon;
|
nsCOMPtr<imgIContainer> lowImgCon;
|
||||||
|
|
||||||
mImageRequest->GetImage(getter_AddRefs(imgCon));
|
if (mImageRequest) {
|
||||||
|
mImageRequest->GetImage(getter_AddRefs(imgCon));
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
nsIImage * lowImage = nsnull;
|
nsIImage * lowImage = nsnull;
|
||||||
nsIImage * image = nsnull;
|
nsIImage * image = nsnull;
|
||||||
@ -1001,8 +1062,10 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
PRUint32 loadStatus;
|
PRUint32 loadStatus = imgIRequest::STATUS_NONE;
|
||||||
mImageRequest->GetImageStatus(&loadStatus);
|
if (mImageRequest) {
|
||||||
|
mImageRequest->GetImageStatus(&loadStatus);
|
||||||
|
}
|
||||||
if (!(loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) || (!imgCon && !lowImgCon)) {
|
if (!(loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) || (!imgCon && !lowImgCon)) {
|
||||||
#else
|
#else
|
||||||
image = mImageLoader.GetImage();
|
image = mImageLoader.GetImage();
|
||||||
@ -1143,7 +1206,7 @@ nsImageFrame::GetImageMap(nsIPresContext* aPresContext)
|
|||||||
if (nsnull == mImageMap) {
|
if (nsnull == mImageMap) {
|
||||||
nsAutoString usemap;
|
nsAutoString usemap;
|
||||||
mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::usemap, usemap);
|
mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::usemap, usemap);
|
||||||
if (0 == usemap.Length()) {
|
if (usemap.IsEmpty()) {
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1480,18 +1543,17 @@ nsImageFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|||||||
|
|
||||||
PRUint32 loadStatus;
|
PRUint32 loadStatus;
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
nsCOMPtr<nsIURI> baseURI;
|
|
||||||
GetBaseURI(getter_AddRefs(baseURI));
|
|
||||||
|
|
||||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||||
GetLoadGroup(aPresContext, getter_AddRefs(loadGroup));
|
GetLoadGroup(aPresContext, getter_AddRefs(loadGroup));
|
||||||
|
|
||||||
mImageRequest->GetImageStatus(&loadStatus);
|
mImageRequest->GetImageStatus(&loadStatus);
|
||||||
if (loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) {
|
if (loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) {
|
||||||
nsCOMPtr<nsIURI> uri;
|
nsCOMPtr<nsIURI> uri;
|
||||||
NS_NewURI(getter_AddRefs(uri), newSRC, baseURI);
|
GetURI(newSRC, getter_AddRefs(uri));
|
||||||
|
|
||||||
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1"));
|
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1"));
|
||||||
NS_ASSERTION(il, "no image loader!");
|
NS_ASSERTION(il, "no image loader!");
|
||||||
|
|
||||||
il->LoadImage(uri, loadGroup, mListener, aPresContext, getter_AddRefs(mImageRequest));
|
il->LoadImage(uri, loadGroup, mListener, aPresContext, getter_AddRefs(mImageRequest));
|
||||||
|
|
||||||
mImageRequest->GetImageStatus(&loadStatus);
|
mImageRequest->GetImageStatus(&loadStatus);
|
||||||
@ -1516,9 +1578,11 @@ nsImageFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|||||||
mCanSendLoadEvent = PR_TRUE;
|
mCanSendLoadEvent = PR_TRUE;
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> uri;
|
nsCOMPtr<nsIURI> uri;
|
||||||
NS_NewURI(getter_AddRefs(uri), newSRC, baseURI);
|
GetURI(newSRC, getter_AddRefs(uri));
|
||||||
|
|
||||||
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1"));
|
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1"));
|
||||||
NS_ASSERTION(il, "no image loader!");
|
NS_ASSERTION(il, "no image loader!");
|
||||||
|
|
||||||
il->LoadImage(uri, loadGroup, mListener, aPresContext, getter_AddRefs(mImageRequest));
|
il->LoadImage(uri, loadGroup, mListener, aPresContext, getter_AddRefs(mImageRequest));
|
||||||
#else
|
#else
|
||||||
mImageLoader.StopLoadImage(aPresContext);
|
mImageLoader.StopLoadImage(aPresContext);
|
||||||
@ -1619,6 +1683,35 @@ void HaveFixedSize(const nsHTMLReflowState& aReflowState, PRPackedBool& aConstra
|
|||||||
heightUnit == eStyleUnit_Percent));
|
heightUnit == eStyleUnit_Percent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define INTERNAL_GOPHER_STRING "internal-gopher-"
|
||||||
|
#define INTERNAL_GOPHER_LENGTH 17
|
||||||
|
|
||||||
|
void
|
||||||
|
nsImageFrame::GetURI(const nsAReadableString& aSpec, nsIURI **aURI)
|
||||||
|
{
|
||||||
|
nsAutoString newURI;
|
||||||
|
|
||||||
|
/* Note: navigator 4.* and earlier releases ignored the base tags
|
||||||
|
effect on the builtin images. So we do too. Use aSpec instead
|
||||||
|
of the absolute url...
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The prefix for special "internal" images that are well known.
|
||||||
|
Look and see if this is an internal-gopher- url.
|
||||||
|
*/
|
||||||
|
if (NS_LITERAL_STRING(INTERNAL_GOPHER_STRING).Equals(Substring(aSpec, 0, INTERNAL_GOPHER_LENGTH))) {
|
||||||
|
newURI.Assign(NS_LITERAL_STRING("resource:/res/html/gopher-") +
|
||||||
|
Substring(aSpec, INTERNAL_GOPHER_LENGTH, aSpec.Length() - INTERNAL_GOPHER_LENGTH) +
|
||||||
|
NS_LITERAL_STRING(".gif"));
|
||||||
|
} else {
|
||||||
|
newURI.Assign(aSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> baseURI;
|
||||||
|
GetBaseURI(getter_AddRefs(baseURI));
|
||||||
|
NS_NewURI(aURI, newURI, baseURI);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsImageFrame::GetBaseURI(nsIURI **aURI)
|
nsImageFrame::GetBaseURI(nsIURI **aURI)
|
||||||
{
|
{
|
||||||
@ -1664,6 +1757,40 @@ nsImageFrame::GetLoadGroup(nsIPresContext *aPresContext, nsILoadGroup **aLoadGro
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check with the content-policy things to make sure this load is permitted.
|
||||||
|
PRBool
|
||||||
|
nsImageFrame::CanLoadImage(nsIURI *aURI)
|
||||||
|
{
|
||||||
|
PRBool shouldLoad = PR_TRUE; // default permit
|
||||||
|
|
||||||
|
// XXX leave this if 0'd until there is a good way to test it.
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mContent));
|
||||||
|
|
||||||
|
if (!element) // this would seem bad(tm)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
nsXPIDLCString uric;
|
||||||
|
aURI->GetSpec(getter_Copies(uric));
|
||||||
|
|
||||||
|
nsString uri = NS_ConvertUTF8toUCS2(uric);
|
||||||
|
|
||||||
|
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::CONTENT_IMAGE,
|
||||||
|
uri, element, &shouldLoad);
|
||||||
|
if (NS_SUCCEEDED(rv) && !shouldLoad)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
/* ... additional checks ? */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return shouldLoad;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsImageFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
nsImageFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
||||||
@ -1692,7 +1819,8 @@ nsImageFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
|||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
NS_IMPL_ISUPPORTS2(nsImageListener, imgIDecoderObserver, imgIContainerObserver)
|
NS_IMPL_ISUPPORTS2(nsImageListener, imgIDecoderObserver, imgIContainerObserver)
|
||||||
|
|
||||||
nsImageListener::nsImageListener()
|
nsImageListener::nsImageListener(nsImageFrame *aFrame) :
|
||||||
|
mFrame(aFrame)
|
||||||
{
|
{
|
||||||
NS_INIT_ISUPPORTS();
|
NS_INIT_ISUPPORTS();
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "nsLeafFrame.h"
|
#include "nsLeafFrame.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
|
#include "nsAReadableString.h"
|
||||||
#include "nsIPresContext.h"
|
#include "nsIPresContext.h"
|
||||||
#include "nsHTMLImageLoader.h"
|
#include "nsHTMLImageLoader.h"
|
||||||
#include "nsIImageFrame.h"
|
#include "nsIImageFrame.h"
|
||||||
@ -49,7 +50,7 @@ class nsImageFrame;
|
|||||||
class nsImageListener : imgIDecoderObserver
|
class nsImageListener : imgIDecoderObserver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsImageListener();
|
nsImageListener(nsImageFrame *aFrame);
|
||||||
virtual ~nsImageListener();
|
virtual ~nsImageListener();
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
@ -182,8 +183,11 @@ protected:
|
|||||||
PRUint32 aStatus);
|
PRUint32 aStatus);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void GetBaseURI(nsIURI **uri);
|
PRBool CanLoadImage(nsIURI *aURI);
|
||||||
void GetLoadGroup(nsIPresContext *aPresContext, nsILoadGroup **aLoadGroup);
|
|
||||||
|
inline void GetURI(const nsAReadableString& aSpec, nsIURI **aURI);
|
||||||
|
inline void GetBaseURI(nsIURI **uri);
|
||||||
|
inline void GetLoadGroup(nsIPresContext *aPresContext, nsILoadGroup **aLoadGroup);
|
||||||
|
|
||||||
nsHTMLImageLoader mImageLoader;
|
nsHTMLImageLoader mImageLoader;
|
||||||
nsHTMLImageLoader * mLowSrcImageLoader;
|
nsHTMLImageLoader * mLowSrcImageLoader;
|
||||||
|
@ -69,6 +69,8 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|||||||
#include "nsIDOMNode.h"
|
#include "nsIDOMNode.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "nsContentPolicyUtils.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#undef NOISY_IMAGE_LOADING
|
#undef NOISY_IMAGE_LOADING
|
||||||
@ -189,13 +191,19 @@ nsImageFrame::Destroy(nsIPresContext* aPresContext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
if (mImageRequest)
|
if (mImageRequest)
|
||||||
mImageRequest->Cancel(NS_ERROR_FAILURE); // NS_BINDING_ABORT ?
|
mImageRequest->Cancel(NS_ERROR_FAILURE); // NS_BINDING_ABORT ?
|
||||||
if (mLowImageRequest)
|
if (mLowImageRequest)
|
||||||
mLowImageRequest->Cancel(NS_ERROR_FAILURE); // NS_BINDING_ABORT ?
|
mLowImageRequest->Cancel(NS_ERROR_FAILURE); // NS_BINDING_ABORT ?
|
||||||
|
|
||||||
|
// set the frame to null so we don't send messages to a dead object.
|
||||||
|
if (mListener)
|
||||||
|
NS_REINTERPRET_CAST(nsImageListener*, mListener.get())->SetFrame(nsnull);
|
||||||
|
|
||||||
|
mImageRequest = nsnull;
|
||||||
|
mLowImageRequest = nsnull;
|
||||||
|
mListener = nsnull;
|
||||||
|
|
||||||
if (mListener)
|
|
||||||
NS_REINTERPRET_CAST(nsImageListener*, mListener.get())->SetFrame(nsnull); // set the frame to null so we don't send messages to a dead object.
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef USE_IMG2
|
#ifndef USE_IMG2
|
||||||
@ -245,19 +253,21 @@ nsImageFrame::Init(nsIPresContext* aPresContext,
|
|||||||
nsresult lowSrcResult;
|
nsresult lowSrcResult;
|
||||||
lowSrcResult = mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::lowsrc, lowSrc);
|
lowSrcResult = mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::lowsrc, lowSrc);
|
||||||
|
|
||||||
// Set the image loader's source URL and base URL
|
#ifndef USE_IMG2
|
||||||
nsCOMPtr<nsIURI> baseURL;
|
nsCOMPtr<nsIURI> baseURL;
|
||||||
GetBaseURI(getter_AddRefs(baseURL));
|
GetBaseURI(getter_AddRefs(baseURL));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set the image loader's source URL and base URL
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
nsImageListener *listener;
|
if (!mListener) {
|
||||||
NS_NEWXPCOM(listener, nsImageListener);
|
nsImageListener *listener = new nsImageListener(this);
|
||||||
NS_ADDREF(listener);
|
if (!listener) return NS_ERROR_OUT_OF_MEMORY;
|
||||||
listener->SetFrame(this);
|
NS_ADDREF(listener);
|
||||||
listener->QueryInterface(NS_GET_IID(imgIDecoderObserver), getter_AddRefs(mListener));
|
listener->QueryInterface(NS_GET_IID(imgIDecoderObserver), getter_AddRefs(mListener));
|
||||||
NS_ASSERTION(mListener, "queryinterface for the listener failed");
|
NS_ASSERTION(mListener, "queryinterface for the listener failed");
|
||||||
NS_RELEASE(listener);
|
NS_RELEASE(listener);
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1", &rv));
|
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1", &rv));
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
@ -270,9 +280,11 @@ nsImageFrame::Init(nsIPresContext* aPresContext,
|
|||||||
if (NS_CONTENT_ATTR_HAS_VALUE == lowSrcResult && lowSrc.Length() > 0) {
|
if (NS_CONTENT_ATTR_HAS_VALUE == lowSrcResult && lowSrc.Length() > 0) {
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
nsCOMPtr<nsIURI> lowURI;
|
nsCOMPtr<nsIURI> lowURI;
|
||||||
NS_NewURI(getter_AddRefs(lowURI), src, baseURL);
|
GetURI(lowSrc, getter_AddRefs(lowURI));
|
||||||
|
|
||||||
il->LoadImage(lowURI, loadGroup, mListener, aPresContext, getter_AddRefs(mLowImageRequest));
|
if (CanLoadImage(lowURI)) {
|
||||||
|
il->LoadImage(lowURI, loadGroup, mListener, aPresContext, getter_AddRefs(mLowImageRequest));
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
mLowSrcImageLoader = new nsHTMLImageLoader;
|
mLowSrcImageLoader = new nsHTMLImageLoader;
|
||||||
if (mLowSrcImageLoader) {
|
if (mLowSrcImageLoader) {
|
||||||
@ -287,9 +299,11 @@ nsImageFrame::Init(nsIPresContext* aPresContext,
|
|||||||
mCanSendLoadEvent = PR_TRUE;
|
mCanSendLoadEvent = PR_TRUE;
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> srcURI;
|
nsCOMPtr<nsIURI> srcURI;
|
||||||
NS_NewURI(getter_AddRefs(srcURI), src, baseURL);
|
GetURI(src, getter_AddRefs(srcURI));
|
||||||
il->LoadImage(srcURI, loadGroup, mListener, aPresContext, getter_AddRefs(mImageRequest));
|
if (CanLoadImage(srcURI)) {
|
||||||
// if the image was found in the cache, it is possible that LoadImage will result in a call to OnStartContainer()
|
il->LoadImage(srcURI, loadGroup, mListener, aPresContext, getter_AddRefs(mImageRequest));
|
||||||
|
// if the image was found in the cache, it is possible that LoadImage will result in a call to OnStartContainer()
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
mImageLoader.Init(this, UpdateImageFrame, (void*)&mImageLoader, baseURL, src);
|
mImageLoader.Init(this, UpdateImageFrame, (void*)&mImageLoader, baseURL, src);
|
||||||
|
|
||||||
@ -324,10 +338,6 @@ NS_IMETHODIMP nsImageFrame::OnStartDecode(imgIRequest *aRequest, nsIPresContext
|
|||||||
|
|
||||||
NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresContext *aPresContext, imgIContainer *aImage)
|
NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresContext *aPresContext, imgIContainer *aImage)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIPresShell> presShell;
|
|
||||||
nsresult rv = aPresContext->GetShell(getter_AddRefs(presShell));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
mInitialLoadCompleted = PR_TRUE;
|
mInitialLoadCompleted = PR_TRUE;
|
||||||
|
|
||||||
nscoord w, h;
|
nscoord w, h;
|
||||||
@ -350,26 +360,16 @@ NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresConte
|
|||||||
if (mComputedSize.width != 0 && mComputedSize.height != 0)
|
if (mComputedSize.width != 0 && mComputedSize.height != 0)
|
||||||
mTransform.SetToScale((float(mIntrinsicSize.width) / float(mComputedSize.width)), (float(mIntrinsicSize.height) / float(mComputedSize.height)));
|
mTransform.SetToScale((float(mIntrinsicSize.width) / float(mComputedSize.width)), (float(mIntrinsicSize.height) / float(mComputedSize.height)));
|
||||||
|
|
||||||
if (mParent) {
|
if (!mSizeConstrained) {
|
||||||
if (mGotInitialReflow) { // don't reflow if we havn't gotten the inital reflow yet
|
nsCOMPtr<nsIPresShell> presShell;
|
||||||
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||||
|
NS_ASSERTION(mParent, "No parent to pass the reflow request up to.");
|
||||||
|
NS_ASSERTION(presShell, "No PresShell.");
|
||||||
|
if (mParent && presShell && mGotInitialReflow) { // don't reflow if we havn't gotten the inital reflow yet
|
||||||
mState |= NS_FRAME_IS_DIRTY;
|
mState |= NS_FRAME_IS_DIRTY;
|
||||||
mParent->ReflowDirtyChild(presShell, (nsIFrame*) this);
|
mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
NS_ASSERTION(0, "No parent to pass the reflow request up to.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCanSendLoadEvent && presShell) {
|
|
||||||
// Send load event
|
|
||||||
mCanSendLoadEvent = PR_FALSE;
|
|
||||||
|
|
||||||
nsEventStatus status = nsEventStatus_eIgnore;
|
|
||||||
nsEvent event;
|
|
||||||
event.eventStructType = NS_EVENT;
|
|
||||||
event.message = NS_IMAGE_LOAD;
|
|
||||||
presShell->HandleEventWithTarget(&event,this,mContent,NS_EVENT_FLAG_INIT | NS_EVENT_FLAG_CANT_BUBBLE,&status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -382,19 +382,18 @@ NS_IMETHODIMP nsImageFrame::OnStartFrame(imgIRequest *aRequest, nsIPresContext *
|
|||||||
|
|
||||||
NS_IMETHODIMP nsImageFrame::OnDataAvailable(imgIRequest *aRequest, nsIPresContext *aPresContext, gfxIImageFrame *aFrame, const nsRect *aRect)
|
NS_IMETHODIMP nsImageFrame::OnDataAvailable(imgIRequest *aRequest, nsIPresContext *aPresContext, gfxIImageFrame *aFrame, const nsRect *aRect)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIPresShell> presShell;
|
// XXX do we need to make sure that the reflow from the OnStartContainer has been
|
||||||
nsresult rv = aPresContext->GetShell(getter_AddRefs(presShell));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
// XXX we need to make sure that the reflow from the OnContainerStart has been
|
|
||||||
// processed before we start calling invalidate
|
// processed before we start calling invalidate
|
||||||
|
|
||||||
if (!aRect)
|
if (!aRect)
|
||||||
return NS_ERROR_NULL_POINTER;
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
|
||||||
nsRect r(aRect->x, aRect->y, aRect->width, aRect->height);
|
nsRect r(aRect->x, aRect->y, aRect->width, aRect->height);
|
||||||
|
|
||||||
|
/* XXX Why do we subtract 1 here? The rect is (for example): (0, 0, 600, 1)..
|
||||||
|
Why do we have to make y -1?
|
||||||
|
*/
|
||||||
|
|
||||||
// The y coordinate of aRect is passed as a scanline where the first scanline is given
|
// The y coordinate of aRect is passed as a scanline where the first scanline is given
|
||||||
// a value of 1. We need to convert this to the nsFrames coordinate space by subtracting
|
// a value of 1. We need to convert this to the nsFrames coordinate space by subtracting
|
||||||
// 1.
|
// 1.
|
||||||
@ -426,15 +425,76 @@ NS_IMETHODIMP nsImageFrame::OnStopContainer(imgIRequest *aRequest, nsIPresContex
|
|||||||
|
|
||||||
NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *aPresContext, nsresult aStatus, const PRUnichar *aStatusArg)
|
NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *aPresContext, nsresult aStatus, const PRUnichar *aStatusArg)
|
||||||
{
|
{
|
||||||
|
nsCOMPtr<nsIPresShell> presShell;
|
||||||
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||||
|
|
||||||
|
// check to see if an image error occurred
|
||||||
|
PRBool imageFailedToLoad = PR_FALSE;
|
||||||
|
|
||||||
|
if (NS_FAILED(aStatus)) { // We failed to load the image. Notify the pres shell
|
||||||
|
PRBool lowFailed = PR_FALSE;
|
||||||
|
PRBool imageFailed = PR_FALSE;
|
||||||
|
|
||||||
|
// One of the two images didn't load, which one?
|
||||||
|
if (mLowImageRequest == aRequest || !mLowImageRequest) {
|
||||||
|
lowFailed = PR_TRUE;
|
||||||
|
}
|
||||||
|
if (mImageRequest == aRequest || !mImageRequest) {
|
||||||
|
imageFailed = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imageFailed && lowFailed)
|
||||||
|
imageFailedToLoad = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if src failed and there is no lowsrc
|
||||||
|
// or both failed to load, then notify the PresShell
|
||||||
|
if (imageFailedToLoad) {
|
||||||
|
if (presShell) {
|
||||||
|
nsAutoString usemap;
|
||||||
|
mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::usemap, usemap);
|
||||||
|
// We failed to load the image. Notify the pres shell if we aren't an image map
|
||||||
|
if (usemap.IsEmpty()) {
|
||||||
|
presShell->CantRenderReplacedElement(aPresContext, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// After these DOM events are fired its possible that this frame may be deleted. As a result
|
||||||
|
// the code should not attempt to access any of the frames internal data after this point.
|
||||||
|
if (presShell) {
|
||||||
|
if (imageFailedToLoad) {
|
||||||
|
// Send error event
|
||||||
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
|
nsEvent event;
|
||||||
|
event.eventStructType = NS_EVENT;
|
||||||
|
event.message = NS_IMAGE_ERROR;
|
||||||
|
presShell->HandleEventWithTarget(&event,this,mContent,NS_EVENT_FLAG_INIT,&status);
|
||||||
|
} else if (mCanSendLoadEvent) {
|
||||||
|
// Send load event
|
||||||
|
mCanSendLoadEvent = PR_FALSE;
|
||||||
|
|
||||||
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
|
nsEvent event;
|
||||||
|
event.eventStructType = NS_EVENT;
|
||||||
|
event.message = NS_IMAGE_LOAD;
|
||||||
|
presShell->HandleEventWithTarget(&event,this,mContent,NS_EVENT_FLAG_INIT | NS_EVENT_FLAG_CANT_BUBBLE,&status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageFrame::FrameChanged(imgIContainer *aContainer, nsIPresContext *aPresContext, gfxIImageFrame *aNewFrame, nsRect *aDirtyRect)
|
NS_IMETHODIMP nsImageFrame::FrameChanged(imgIContainer *aContainer, nsIPresContext *aPresContext, gfxIImageFrame *aNewFrame, nsRect *aDirtyRect)
|
||||||
{
|
{
|
||||||
|
nsRect r(*aDirtyRect);
|
||||||
|
|
||||||
float p2t;
|
float p2t;
|
||||||
aPresContext->GetPixelsToTwips(&p2t);
|
aPresContext->GetPixelsToTwips(&p2t);
|
||||||
nsRect r(*aDirtyRect);
|
r.x = NSIntPixelsToTwips(r.x, p2t);
|
||||||
r *= p2t; // convert to twips
|
r.y = NSIntPixelsToTwips(r.y, p2t);
|
||||||
|
r.width = NSIntPixelsToTwips(r.width, p2t);
|
||||||
|
r.height = NSIntPixelsToTwips(r.height, p2t);
|
||||||
|
|
||||||
mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
||||||
|
|
||||||
@ -487,7 +547,7 @@ nsImageFrame::UpdateImage(nsIPresContext* aPresContext, PRUint32 aStatus, void*
|
|||||||
nsAutoString usemap;
|
nsAutoString usemap;
|
||||||
mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::usemap, usemap);
|
mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::usemap, usemap);
|
||||||
// We failed to load the image. Notify the pres shell if we aren't an image map
|
// We failed to load the image. Notify the pres shell if we aren't an image map
|
||||||
if (usemap.Length() == 0) {
|
if (usemap.IsEmpty()) {
|
||||||
presShell->CantRenderReplacedElement(aPresContext, this);
|
presShell->CantRenderReplacedElement(aPresContext, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -616,7 +676,7 @@ nsImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
|||||||
newHeight = (mIntrinsicSize.height * newWidth) / mIntrinsicSize.width;
|
newHeight = (mIntrinsicSize.height * newWidth) / mIntrinsicSize.width;
|
||||||
haveComputedSize = PR_TRUE;
|
haveComputedSize = PR_TRUE;
|
||||||
} else {
|
} else {
|
||||||
newHeight = NSIntPixelsToTwips(1, p2t); // XXX?
|
newHeight = 0;
|
||||||
needIntrinsicImageSize = PR_TRUE;
|
needIntrinsicImageSize = PR_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -628,30 +688,31 @@ nsImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
|||||||
newWidth = (mIntrinsicSize.width * newHeight) / mIntrinsicSize.height;
|
newWidth = (mIntrinsicSize.width * newHeight) / mIntrinsicSize.height;
|
||||||
haveComputedSize = PR_TRUE;
|
haveComputedSize = PR_TRUE;
|
||||||
} else {
|
} else {
|
||||||
newWidth = NSIntPixelsToTwips(1, p2t);
|
newWidth = 0;
|
||||||
needIntrinsicImageSize = PR_TRUE;
|
needIntrinsicImageSize = PR_TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// auto size the image
|
// auto size the image
|
||||||
if (mIntrinsicSize.width == 0 && mIntrinsicSize.height == 0) {
|
if (mIntrinsicSize.width == 0 && mIntrinsicSize.height == 0)
|
||||||
newWidth = NSIntPixelsToTwips(1, p2t);
|
|
||||||
newHeight = NSIntPixelsToTwips(1, p2t);
|
|
||||||
needIntrinsicImageSize = PR_TRUE;
|
needIntrinsicImageSize = PR_TRUE;
|
||||||
} else {
|
else
|
||||||
newWidth = mIntrinsicSize.width;
|
|
||||||
newHeight = mIntrinsicSize.height;
|
|
||||||
haveComputedSize = PR_TRUE;
|
haveComputedSize = PR_TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
|
newWidth = mIntrinsicSize.width;
|
||||||
|
newHeight = mIntrinsicSize.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
mComputedSize.width = newWidth;
|
mComputedSize.width = newWidth;
|
||||||
mComputedSize.height = newHeight;
|
mComputedSize.height = newHeight;
|
||||||
|
|
||||||
if (mComputedSize == mIntrinsicSize)
|
if (mComputedSize == mIntrinsicSize) {
|
||||||
mTransform.SetToIdentity();
|
mTransform.SetToIdentity();
|
||||||
else
|
} else {
|
||||||
mTransform.SetToScale((float(mIntrinsicSize.width) / float(mComputedSize.width)), (float(mIntrinsicSize.height) / float(mComputedSize.height)));
|
if (mComputedSize.width != 0 && mComputedSize.height != 0) {
|
||||||
|
mTransform.SetToScale(float(mIntrinsicSize.width) / float(mComputedSize.width),
|
||||||
|
float(mIntrinsicSize.height) / float(mComputedSize.height));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
aDesiredSize.width = mComputedSize.width;
|
aDesiredSize.width = mComputedSize.width;
|
||||||
aDesiredSize.height = mComputedSize.height;
|
aDesiredSize.height = mComputedSize.height;
|
||||||
@ -977,12 +1038,12 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
|
|||||||
PRInt32 imgSrcLinesLoaded = -1;
|
PRInt32 imgSrcLinesLoaded = -1;
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
|
|
||||||
NS_ASSERTION(mImageRequest, "no image request! this is bad");
|
|
||||||
|
|
||||||
nsCOMPtr<imgIContainer> imgCon;
|
nsCOMPtr<imgIContainer> imgCon;
|
||||||
nsCOMPtr<imgIContainer> lowImgCon;
|
nsCOMPtr<imgIContainer> lowImgCon;
|
||||||
|
|
||||||
mImageRequest->GetImage(getter_AddRefs(imgCon));
|
if (mImageRequest) {
|
||||||
|
mImageRequest->GetImage(getter_AddRefs(imgCon));
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
nsIImage * lowImage = nsnull;
|
nsIImage * lowImage = nsnull;
|
||||||
nsIImage * image = nsnull;
|
nsIImage * image = nsnull;
|
||||||
@ -1001,8 +1062,10 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
PRUint32 loadStatus;
|
PRUint32 loadStatus = imgIRequest::STATUS_NONE;
|
||||||
mImageRequest->GetImageStatus(&loadStatus);
|
if (mImageRequest) {
|
||||||
|
mImageRequest->GetImageStatus(&loadStatus);
|
||||||
|
}
|
||||||
if (!(loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) || (!imgCon && !lowImgCon)) {
|
if (!(loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) || (!imgCon && !lowImgCon)) {
|
||||||
#else
|
#else
|
||||||
image = mImageLoader.GetImage();
|
image = mImageLoader.GetImage();
|
||||||
@ -1143,7 +1206,7 @@ nsImageFrame::GetImageMap(nsIPresContext* aPresContext)
|
|||||||
if (nsnull == mImageMap) {
|
if (nsnull == mImageMap) {
|
||||||
nsAutoString usemap;
|
nsAutoString usemap;
|
||||||
mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::usemap, usemap);
|
mContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::usemap, usemap);
|
||||||
if (0 == usemap.Length()) {
|
if (usemap.IsEmpty()) {
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1480,18 +1543,17 @@ nsImageFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|||||||
|
|
||||||
PRUint32 loadStatus;
|
PRUint32 loadStatus;
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
nsCOMPtr<nsIURI> baseURI;
|
|
||||||
GetBaseURI(getter_AddRefs(baseURI));
|
|
||||||
|
|
||||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||||
GetLoadGroup(aPresContext, getter_AddRefs(loadGroup));
|
GetLoadGroup(aPresContext, getter_AddRefs(loadGroup));
|
||||||
|
|
||||||
mImageRequest->GetImageStatus(&loadStatus);
|
mImageRequest->GetImageStatus(&loadStatus);
|
||||||
if (loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) {
|
if (loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) {
|
||||||
nsCOMPtr<nsIURI> uri;
|
nsCOMPtr<nsIURI> uri;
|
||||||
NS_NewURI(getter_AddRefs(uri), newSRC, baseURI);
|
GetURI(newSRC, getter_AddRefs(uri));
|
||||||
|
|
||||||
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1"));
|
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1"));
|
||||||
NS_ASSERTION(il, "no image loader!");
|
NS_ASSERTION(il, "no image loader!");
|
||||||
|
|
||||||
il->LoadImage(uri, loadGroup, mListener, aPresContext, getter_AddRefs(mImageRequest));
|
il->LoadImage(uri, loadGroup, mListener, aPresContext, getter_AddRefs(mImageRequest));
|
||||||
|
|
||||||
mImageRequest->GetImageStatus(&loadStatus);
|
mImageRequest->GetImageStatus(&loadStatus);
|
||||||
@ -1516,9 +1578,11 @@ nsImageFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|||||||
mCanSendLoadEvent = PR_TRUE;
|
mCanSendLoadEvent = PR_TRUE;
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> uri;
|
nsCOMPtr<nsIURI> uri;
|
||||||
NS_NewURI(getter_AddRefs(uri), newSRC, baseURI);
|
GetURI(newSRC, getter_AddRefs(uri));
|
||||||
|
|
||||||
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1"));
|
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1"));
|
||||||
NS_ASSERTION(il, "no image loader!");
|
NS_ASSERTION(il, "no image loader!");
|
||||||
|
|
||||||
il->LoadImage(uri, loadGroup, mListener, aPresContext, getter_AddRefs(mImageRequest));
|
il->LoadImage(uri, loadGroup, mListener, aPresContext, getter_AddRefs(mImageRequest));
|
||||||
#else
|
#else
|
||||||
mImageLoader.StopLoadImage(aPresContext);
|
mImageLoader.StopLoadImage(aPresContext);
|
||||||
@ -1619,6 +1683,35 @@ void HaveFixedSize(const nsHTMLReflowState& aReflowState, PRPackedBool& aConstra
|
|||||||
heightUnit == eStyleUnit_Percent));
|
heightUnit == eStyleUnit_Percent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define INTERNAL_GOPHER_STRING "internal-gopher-"
|
||||||
|
#define INTERNAL_GOPHER_LENGTH 17
|
||||||
|
|
||||||
|
void
|
||||||
|
nsImageFrame::GetURI(const nsAReadableString& aSpec, nsIURI **aURI)
|
||||||
|
{
|
||||||
|
nsAutoString newURI;
|
||||||
|
|
||||||
|
/* Note: navigator 4.* and earlier releases ignored the base tags
|
||||||
|
effect on the builtin images. So we do too. Use aSpec instead
|
||||||
|
of the absolute url...
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The prefix for special "internal" images that are well known.
|
||||||
|
Look and see if this is an internal-gopher- url.
|
||||||
|
*/
|
||||||
|
if (NS_LITERAL_STRING(INTERNAL_GOPHER_STRING).Equals(Substring(aSpec, 0, INTERNAL_GOPHER_LENGTH))) {
|
||||||
|
newURI.Assign(NS_LITERAL_STRING("resource:/res/html/gopher-") +
|
||||||
|
Substring(aSpec, INTERNAL_GOPHER_LENGTH, aSpec.Length() - INTERNAL_GOPHER_LENGTH) +
|
||||||
|
NS_LITERAL_STRING(".gif"));
|
||||||
|
} else {
|
||||||
|
newURI.Assign(aSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> baseURI;
|
||||||
|
GetBaseURI(getter_AddRefs(baseURI));
|
||||||
|
NS_NewURI(aURI, newURI, baseURI);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsImageFrame::GetBaseURI(nsIURI **aURI)
|
nsImageFrame::GetBaseURI(nsIURI **aURI)
|
||||||
{
|
{
|
||||||
@ -1664,6 +1757,40 @@ nsImageFrame::GetLoadGroup(nsIPresContext *aPresContext, nsILoadGroup **aLoadGro
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check with the content-policy things to make sure this load is permitted.
|
||||||
|
PRBool
|
||||||
|
nsImageFrame::CanLoadImage(nsIURI *aURI)
|
||||||
|
{
|
||||||
|
PRBool shouldLoad = PR_TRUE; // default permit
|
||||||
|
|
||||||
|
// XXX leave this if 0'd until there is a good way to test it.
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mContent));
|
||||||
|
|
||||||
|
if (!element) // this would seem bad(tm)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
nsXPIDLCString uric;
|
||||||
|
aURI->GetSpec(getter_Copies(uric));
|
||||||
|
|
||||||
|
nsString uri = NS_ConvertUTF8toUCS2(uric);
|
||||||
|
|
||||||
|
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::CONTENT_IMAGE,
|
||||||
|
uri, element, &shouldLoad);
|
||||||
|
if (NS_SUCCEEDED(rv) && !shouldLoad)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
/* ... additional checks ? */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return shouldLoad;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsImageFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
nsImageFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
||||||
@ -1692,7 +1819,8 @@ nsImageFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
|||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
NS_IMPL_ISUPPORTS2(nsImageListener, imgIDecoderObserver, imgIContainerObserver)
|
NS_IMPL_ISUPPORTS2(nsImageListener, imgIDecoderObserver, imgIContainerObserver)
|
||||||
|
|
||||||
nsImageListener::nsImageListener()
|
nsImageListener::nsImageListener(nsImageFrame *aFrame) :
|
||||||
|
mFrame(aFrame)
|
||||||
{
|
{
|
||||||
NS_INIT_ISUPPORTS();
|
NS_INIT_ISUPPORTS();
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "nsLeafFrame.h"
|
#include "nsLeafFrame.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
|
#include "nsAReadableString.h"
|
||||||
#include "nsIPresContext.h"
|
#include "nsIPresContext.h"
|
||||||
#include "nsHTMLImageLoader.h"
|
#include "nsHTMLImageLoader.h"
|
||||||
#include "nsIImageFrame.h"
|
#include "nsIImageFrame.h"
|
||||||
@ -49,7 +50,7 @@ class nsImageFrame;
|
|||||||
class nsImageListener : imgIDecoderObserver
|
class nsImageListener : imgIDecoderObserver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsImageListener();
|
nsImageListener(nsImageFrame *aFrame);
|
||||||
virtual ~nsImageListener();
|
virtual ~nsImageListener();
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
@ -182,8 +183,11 @@ protected:
|
|||||||
PRUint32 aStatus);
|
PRUint32 aStatus);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void GetBaseURI(nsIURI **uri);
|
PRBool CanLoadImage(nsIURI *aURI);
|
||||||
void GetLoadGroup(nsIPresContext *aPresContext, nsILoadGroup **aLoadGroup);
|
|
||||||
|
inline void GetURI(const nsAReadableString& aSpec, nsIURI **aURI);
|
||||||
|
inline void GetBaseURI(nsIURI **uri);
|
||||||
|
inline void GetLoadGroup(nsIPresContext *aPresContext, nsILoadGroup **aLoadGroup);
|
||||||
|
|
||||||
nsHTMLImageLoader mImageLoader;
|
nsHTMLImageLoader mImageLoader;
|
||||||
nsHTMLImageLoader * mLowSrcImageLoader;
|
nsHTMLImageLoader * mLowSrcImageLoader;
|
||||||
|
Loading…
Reference in New Issue
Block a user