Bug 1462272: Introduce nsImageFrame::GetCurrentRequest. r?dholbert
MozReview-Commit-ID: IXXtYClyY2z
--- a/dom/base/nsIImageLoadingContent.idl
+++ b/dom/base/nsIImageLoadingContent.idl
@@ -109,21 +109,16 @@ interface nsIImageLoadingContent : imgIN
* security policies enforced.
*
* @param aContentDecision the decision returned from nsIContentPolicy
* (any of the types REJECT_*)
*/
[notxpcom, nostdcall] void setBlockedRequest(in int16_t aContentDecision);
/**
- * @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.
*/
[notxpcom] void frameCreated(in nsIFrame aFrame);
/**
* Used to notify the image loading content node that a frame has been
* destroyed.
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -624,22 +624,16 @@ nsImageLoadingContent::GetRequest(int32_
NS_ENSURE_ARG_POINTER(aRequest);
ErrorResult result;
*aRequest = GetRequest(aRequestType, result).take();
return result.StealNSResult();
}
-NS_IMETHODIMP_(bool)
-nsImageLoadingContent::CurrentRequestHasSize()
-{
- return HaveSize(mCurrentRequest);
-}
-
NS_IMETHODIMP_(void)
nsImageLoadingContent::FrameCreated(nsIFrame* aFrame)
{
NS_ASSERTION(aFrame, "aFrame is null");
TrackImage(mCurrentRequest, aFrame);
TrackImage(mPendingRequest, aFrame);
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -268,26 +268,22 @@ nsImageFrame::Init(nsIContent* aCo
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(aContent);
if (!imageLoader) {
MOZ_CRASH("Why do we have an nsImageFrame here at all?");
}
imageLoader->AddNativeObserver(mListener);
- // We have a PresContext now, so we need to notify the image content node
- // that it can register images.
+ // We have a PresContext now, so we need to notify the image content node that
+ // it can register images.
imageLoader->FrameCreated(this);
- // Give image loads associated with an image frame a small priority boost!
- nsCOMPtr<imgIRequest> currentRequest;
- imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
- getter_AddRefs(currentRequest));
-
- if (currentRequest) {
+ // Give image loads associated with an image frame a small priority boost.
+ if (nsCOMPtr<imgIRequest> currentRequest = GetCurrentRequest()) {
uint32_t categoryToBoostPriority = imgIRequest::CATEGORY_FRAME_INIT;
// Increase load priority further if intrinsic size might be important for layout.
if (!HaveSpecifiedSize(StylePosition())) {
categoryToBoostPriority |= imgIRequest::CATEGORY_SIZE_QUERY;
}
currentRequest->BoostPriority(categoryToBoostPriority);
@@ -832,36 +828,32 @@ nsImageFrame::EnsureIntrinsicSizeAndRati
if (mImage) {
UpdateIntrinsicSize(mImage);
UpdateIntrinsicRatio(mImage);
} else {
// image request is null or image size not known, probably an
// invalid image specified
if (!(GetStateBits() & NS_FRAME_GENERATED_CONTENT)) {
bool imageInvalid = false;
+
// check for broken images. valid null images (eg. img src="") are
// not considered broken because they have no image requests
- nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
- if (imageLoader) {
- nsCOMPtr<imgIRequest> currentRequest;
- imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
- getter_AddRefs(currentRequest));
- if (currentRequest) {
- uint32_t imageStatus;
- imageInvalid =
- NS_SUCCEEDED(currentRequest->GetImageStatus(&imageStatus)) &&
- (imageStatus & imgIRequest::STATUS_ERROR);
- } else {
- // check if images are user-disabled (or blocked for other
- // reasons)
- int16_t imageBlockingStatus;
- imageLoader->GetImageBlockingStatus(&imageBlockingStatus);
- imageInvalid = imageBlockingStatus != nsIContentPolicy::ACCEPT;
- }
+ if (nsCOMPtr<imgIRequest> currentRequest = GetCurrentRequest()) {
+ uint32_t imageStatus;
+ imageInvalid =
+ NS_SUCCEEDED(currentRequest->GetImageStatus(&imageStatus)) &&
+ (imageStatus & imgIRequest::STATUS_ERROR);
+ } else if (nsCOMPtr<nsIImageLoadingContent> loader = do_QueryInterface(mContent)) {
+ // check if images are user-disabled (or blocked for other
+ // reasons)
+ int16_t imageBlockingStatus;
+ loader->GetImageBlockingStatus(&imageBlockingStatus);
+ imageInvalid = imageBlockingStatus != nsIContentPolicy::ACCEPT;
}
+
// invalid image specified. make the image big enough for the "broken" icon
if (imageInvalid) {
nscoord edgeLengthToUse =
nsPresContext::CSSPixelsToAppUnits(
ICON_SIZE + (2 * (ICON_PADDING + ALT_BORDER_WIDTH)));
mIntrinsicSize.width.SetCoordValue(edgeLengthToUse);
mIntrinsicSize.height.SetCoordValue(edgeLengthToUse);
mIntrinsicRatio.SizeTo(1, 1);
@@ -1003,26 +995,20 @@ nsImageFrame::Reflow(nsPresContext*
aMetrics.Height() -= y + aReflowInput.ComputedPhysicalBorderPadding().top;
aMetrics.Height() = std::max(0, aMetrics.Height());
}
// we have to split images if we are:
// in Paginated mode, we need to have a constrained height, and have a height larger than our available height
uint32_t loadStatus = imgIRequest::STATUS_NONE;
- nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
- NS_ASSERTION(imageLoader, "No content node??");
- if (imageLoader) {
- nsCOMPtr<imgIRequest> currentRequest;
- imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
- getter_AddRefs(currentRequest));
- if (currentRequest) {
- currentRequest->GetImageStatus(&loadStatus);
- }
+ if (nsCOMPtr<imgIRequest> currentRequest = GetCurrentRequest()) {
+ currentRequest->GetImageStatus(&loadStatus);
}
+
if (aPresContext->IsPaginated() &&
((loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) || (mState & IMAGE_SIZECONSTRAINED)) &&
NS_UNCONSTRAINEDSIZE != aReflowInput.AvailableHeight() &&
aMetrics.Height() > aReflowInput.AvailableHeight()) {
// our desired height was greater than 0, so to avoid infinite
// splitting, use 1 pixel as the min
aMetrics.Height() = std::max(nsPresContext::CSSPixelsToAppUnits(1), aReflowInput.AvailableHeight());
aStatus.SetIncomplete();
@@ -1791,16 +1777,30 @@ nsImageFrame::PaintImage(gfxContext& aRe
mPrevImage = aImage;
} else if (result == ImgDrawResult::BAD_IMAGE) {
mPrevImage = nullptr;
}
return result;
}
+already_AddRefed<imgIRequest>
+nsImageFrame::GetCurrentRequest() const
+{
+ nsCOMPtr<imgIRequest> request;
+
+ nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
+ MOZ_ASSERT(imageLoader);
+
+ imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
+ getter_AddRefs(request));
+
+ return request.forget();
+}
+
void
nsImageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists)
{
if (!IsVisibleForPainting(aBuilder))
return;
DisplayBorderBackgroundOutline(aBuilder, aLists);
@@ -1808,28 +1808,21 @@ nsImageFrame::BuildDisplayList(nsDisplay
uint32_t clipFlags =
nsStyleUtil::ObjectPropsMightCauseOverflow(StylePosition()) ?
0 : DisplayListClipState::ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT;
DisplayListClipState::AutoClipContainingBlockDescendantsToContentBox
clip(aBuilder, this, clipFlags);
if (mComputedSize.width != 0 && mComputedSize.height != 0) {
- nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
- NS_ASSERTION(imageLoader, "Not an image loading content?");
-
- nsCOMPtr<imgIRequest> currentRequest;
- if (imageLoader) {
- imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
- getter_AddRefs(currentRequest));
- }
-
EventStates contentState = mContent->AsElement()->State();
bool imageOK = IMAGE_OK(contentState, true);
+ nsCOMPtr<imgIRequest> currentRequest = GetCurrentRequest();
+
// XXX(seth): The SizeIsAvailable check here should not be necessary - the
// intention is that a non-null mImage means we have a size, but there is
// currently some code that violates this invariant.
if (!imageOK || !mImage || !SizeIsAvailable(currentRequest)) {
// No image yet, or image load failed. Draw the alt-text and an icon
// indicating the status
aLists.Content()->AppendToTop(
MakeDisplayItem<nsDisplayAltFeedback>(aBuilder, this));
@@ -2156,28 +2149,22 @@ nsImageFrame::GetFrameName(nsAString& aR
void
nsImageFrame::List(FILE* out, const char* aPrefix, uint32_t aFlags) const
{
nsCString str;
ListGeneric(str, aPrefix, aFlags);
// output the img src url
- nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
- if (imageLoader) {
- nsCOMPtr<imgIRequest> currentRequest;
- imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
- getter_AddRefs(currentRequest));
- if (currentRequest) {
- nsCOMPtr<nsIURI> uri;
- currentRequest->GetURI(getter_AddRefs(uri));
- nsAutoCString uristr;
- uri->GetAsciiSpec(uristr);
- str += nsPrintfCString(" [src=%s]", uristr.get());
- }
+ if (nsCOMPtr<imgIRequest> currentRequest = GetCurrentRequest()) {
+ nsCOMPtr<nsIURI> uri;
+ currentRequest->GetURI(getter_AddRefs(uri));
+ nsAutoCString uristr;
+ uri->GetAsciiSpec(uristr);
+ str += nsPrintfCString(" [src=%s]", uristr.get());
}
fprintf_stderr(out, "%s\n", str.get());
}
#endif
nsIFrame::LogicalSides
nsImageFrame::GetLogicalSkipSides(const ReflowInput* aReflowInput) const
{
--- a/layout/generic/nsImageFrame.h
+++ b/layout/generic/nsImageFrame.h
@@ -133,16 +133,17 @@ public:
static void ReleaseGlobals() {
if (gIconLoad) {
gIconLoad->Shutdown();
gIconLoad = nullptr;
}
NS_IF_RELEASE(sIOService);
}
+ already_AddRefed<imgIRequest> GetCurrentRequest() const;
nsresult Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData);
/**
* Function to test whether aContent, which has aComputedStyle as its style,
* should get an image frame. Note that this method is only used by the
* frame constructor; it's only here because it uses gIconLoad for now.
*/
static bool ShouldCreateImageFrameFor(mozilla::dom::Element* aElement,