From 7c7c25bd2923a8b2bdf6269bdde6c84ca388300b Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Wed, 18 Mar 2015 18:29:32 -0700 Subject: [PATCH] Bug 1019840 - Use cached intrinsic size in nsImageFrame::ComputeSize unless the image loader has a size. r=tn --- dom/base/nsIImageLoadingContent.idl | 12 ++++++------ dom/base/nsImageLoadingContent.cpp | 6 ++++++ layout/generic/nsImageFrame.cpp | 10 +++++++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/dom/base/nsIImageLoadingContent.idl b/dom/base/nsIImageLoadingContent.idl index f477b67ebf3..0a469c165e1 100644 --- a/dom/base/nsIImageLoadingContent.idl +++ b/dom/base/nsIImageLoadingContent.idl @@ -28,16 +28,11 @@ interface nsIFrame; * become current only when the image is loaded. It is the responsibility of * observers to check which request they are getting notifications for. * - * Observers added in mid-load will not get any notifications they - * missed. We should NOT freeze this interface without considering - * this issue. (It could be that the image status on imgIRequest is - * sufficient, when combined with the imageBlockingStatus information.) - * * Please make sure to update the MozImageLoadingContent WebIDL * interface to mirror this interface when changing it. */ -[scriptable, builtinclass, uuid(5794d12b-3195-4526-a814-a2181f6c71fe)] +[scriptable, builtinclass, uuid(770f7d84-c917-42d7-bf8d-d1b70649e733)] interface nsIImageLoadingContent : imgINotificationObserver { /** @@ -100,6 +95,11 @@ interface nsIImageLoadingContent : imgINotificationObserver */ imgIRequest getRequest(in long aRequestType); + /** + * @return true if the current request's size is available. + */ + [noscript, notxpcom] boolean currentRequestHasSize(); + /** * Used to notify the image loading content node that a frame has been * created. diff --git a/dom/base/nsImageLoadingContent.cpp b/dom/base/nsImageLoadingContent.cpp index 88d93a8dede..55c2bd77d13 100644 --- a/dom/base/nsImageLoadingContent.cpp +++ b/dom/base/nsImageLoadingContent.cpp @@ -493,6 +493,12 @@ nsImageLoadingContent::GetRequest(int32_t aRequestType, return result.ErrorCode(); } +NS_IMETHODIMP_(bool) +nsImageLoadingContent::CurrentRequestHasSize() +{ + return HaveSize(mCurrentRequest); +} + NS_IMETHODIMP_(void) nsImageLoadingContent::FrameCreated(nsIFrame* aFrame) { diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index f9017246de7..3dba8986031 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -743,10 +743,18 @@ nsImageFrame::ComputeSize(nsRenderingContext *aRenderingContext, NS_ASSERTION(imageLoader, "No content node??"); mozilla::IntrinsicSize intrinsicSize(mIntrinsicSize); + // XXX(seth): We may sometimes find ourselves in the situation where we have + // mImage, but imageLoader's current request does not have a size yet. + // This can happen when we load an image speculatively from cache, it fails + // to validate, and the new image load hasn't fired SIZE_AVAILABLE yet. In + // this situation we should always use mIntrinsicSize, because + // GetNaturalWidth/Height will return 0, so we check CurrentRequestHasSize() + // below. See bug 1019840. We will fix this in bug 1141395. + // Content may override our default dimensions. This is termed as overriding // the intrinsic size by the spec, but all other consumers of mIntrinsic* // values are being used to refer to the real/true size of the image data. - if (imageLoader && mImage && + if (imageLoader && imageLoader->CurrentRequestHasSize() && mImage && intrinsicSize.width.GetUnit() == eStyleUnit_Coord && intrinsicSize.height.GetUnit() == eStyleUnit_Coord) { uint32_t width;