diff options
Diffstat (limited to 'layout/generic/nsImageFrame.cpp')
-rw-r--r-- | layout/generic/nsImageFrame.cpp | 139 |
1 files changed, 66 insertions, 73 deletions
diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index c64520f2e..03fcbd8e3 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -116,7 +116,7 @@ static bool HaveSpecifiedSize(const nsStylePosition* aStylePosition) // Decide whether we can optimize away reflows that result from the // image's intrinsic size changing. -inline bool HaveFixedSize(const ReflowInput& aReflowInput) +static bool HaveFixedSize(const ReflowInput& aReflowInput) { NS_ASSERTION(aReflowInput.mStylePosition, "crappy reflowInput - null stylePosition"); // Don't try to make this optimization when an image has percentages @@ -430,66 +430,56 @@ nsImageFrame::SourceRectToDest(const nsIntRect& aRect) // that we'll construct image frames for them as needed if their display is // toggled from "none" (though we won't paint them, unless their visibility // is changed too). -#define BAD_STATES (NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_USERDISABLED | \ - NS_EVENT_STATE_LOADING) +#define BAD_STATES (NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_USERDISABLED) -// This is a macro so that we don't evaluate the boolean last arg -// unless we have to; it can be expensive -#define IMAGE_OK(_state, _loadingOK) \ - (!(_state).HasAtLeastOneOfStates(BAD_STATES) || \ - (!(_state).HasAtLeastOneOfStates(NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_USERDISABLED) && \ - (_state).HasState(NS_EVENT_STATE_LOADING) && (_loadingOK))) +static bool ImageOk(EventStates aState) { + return !aState.HasAtLeastOneOfStates(BAD_STATES); +} -/* static */ -bool +static bool HasAltText(Element* aElement) +{ + // We always return some alternate text for <input>, see + // nsCSSFrameConstructor::GetAlternateTextFor. + if (aElement->IsHTMLElement(nsGkAtoms::input)) { + return true; + } + + MOZ_ASSERT(aElement->IsHTMLElement(nsGkAtoms::img)); + nsAutoString altText; + return aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, altText) && !altText.IsEmpty(); +} + +// Check if we want to use an image frame or just let the frame constructor make +// us into an inline. +/* static */ bool nsImageFrame::ShouldCreateImageFrameFor(Element* aElement, nsStyleContext* aStyleContext) { - EventStates state = aElement->State(); - if (IMAGE_OK(state, - HaveSpecifiedSize(aStyleContext->StylePosition()))) { - // Image is fine; do the image frame thing + if (ImageOk(aElement->State())) { + // Image is fine or loading; do the image frame thing return true; } - // Check if we want to use a placeholder box with an icon or just - // let the presShell make us into inline text. Decide as follows: - // - // - if our special "force icons" style is set, show an icon - // - else if our "do not show placeholders" pref is set, skip the icon - // - else: - // - if there is a src attribute, there is no alt attribute, - // and this is not an <object> (which could not possibly have - // such an attribute), show an icon. - // - if QuirksMode, and the IMG has a size show an icon. - // - otherwise, skip the icon - bool useSizedBox; - + // If our special "force icons" style is set, show an icon if (aStyleContext->StyleUIReset()->mForceBrokenImageIcon) { - useSizedBox = true; - } - else if (gIconLoad && gIconLoad->mPrefForceInlineAltText) { - useSizedBox = false; + return true; } - else if (aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::src) && - !aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::alt) && - !aElement->IsHTMLElement(nsGkAtoms::object) && - !aElement->IsHTMLElement(nsGkAtoms::input)) { - // Use a sized box if we have no alt text. This means no alt attribute - // and the node is not an object or an input (since those always have alt - // text). - useSizedBox = true; + + // If our "do not show placeholders" pref is set, skip the icon + if (gIconLoad && gIconLoad->mPrefForceInlineAltText) { + return false; } - else if (aStyleContext->PresContext()->CompatibilityMode() != - eCompatibility_NavQuirks) { - useSizedBox = false; + + // If there is no Alt text, always create an image frame (regardless of src) + if (!HasAltText(aElement)) { + return true; } - else { - // check whether we have specified size - useSizedBox = HaveSpecifiedSize(aStyleContext->StylePosition()); + + if (aStyleContext->PresContext()->CompatibilityMode() == eCompatibility_NavQuirks) { + return HaveSpecifiedSize(aStyleContext->StylePosition()); } - - return useSizedBox; + + return false; } nsresult @@ -775,6 +765,25 @@ nsImageFrame::PredictedDestRect(const nsRect& aFrameContentBox) StylePosition()); } +bool nsImageFrame::ShouldShowBrokenImageIcon() const +{ + bool imageBroken = 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)); + uint32_t imageStatus; + imageBroken = + currentRequest && + NS_SUCCEEDED(currentRequest->GetImageStatus(&imageStatus)) && + (imageStatus & imgIRequest::STATUS_ERROR); + } + return imageBroken; +} + void nsImageFrame::EnsureIntrinsicSizeAndRatio() { @@ -789,25 +798,11 @@ nsImageFrame::EnsureIntrinsicSizeAndRatio() UpdateIntrinsicSize(mImage); UpdateIntrinsicRatio(mImage); } else { - // image request is null or image size not known, probably an - // invalid image specified + // Image request is null or image size not known. if (!(GetStateBits() & NS_FRAME_GENERATED_CONTENT)) { - bool imageBroken = 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)); - uint32_t imageStatus; - imageBroken = - currentRequest && - NS_SUCCEEDED(currentRequest->GetImageStatus(&imageStatus)) && - (imageStatus & imgIRequest::STATUS_ERROR); - } - // invalid image specified. make the image big enough for the "broken" icon - if (imageBroken) { + // Likely an invalid image. Check if we should display it as broken. + if (ShouldShowBrokenImageIcon()) { + // Invalid image specified. make the image big enough for the "broken" icon nscoord edgeLengthToUse = nsPresContext::CSSPixelsToAppUnits( ICON_SIZE + (2 * (ICON_PADDING + ALT_BORDER_WIDTH))); @@ -1015,8 +1010,7 @@ nsImageFrame::Reflow(nsPresContext* aPresContext, } aMetrics.SetOverflowAreasToDesiredBounds(); - EventStates contentState = mContent->AsElement()->State(); - bool imageOK = IMAGE_OK(contentState, true); + bool imageOK = ImageOk(mContent->AsElement()->State()); // Determine if the size is available bool haveSize = false; @@ -1335,7 +1329,7 @@ nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext, MOZ_ASSERT(gIconLoad, "How did we succeed in Init then?"); // Whether we draw the broken or loading icon. - bool isLoading = IMAGE_OK(GetContent()->AsElement()->State(), true); + bool isLoading = ImageOk(mContent->AsElement()->State()); // Calculate the inner area nsRect inner = GetInnerArea() + aPt; @@ -1389,7 +1383,8 @@ nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext, DrawResult result = DrawResult::NOT_READY; // Check if we should display image placeholders - if (!gIconLoad->mPrefShowPlaceholders || + if (!ShouldShowBrokenImageIcon() || + !gIconLoad->mPrefShowPlaceholders || (isLoading && !gIconLoad->mPrefShowLoadingPlaceholder)) { result = DrawResult::SUCCESS; } else { @@ -1730,7 +1725,6 @@ nsImageFrame::PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt, void nsImageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) @@ -1755,8 +1749,7 @@ nsImageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, getter_AddRefs(currentRequest)); } - EventStates contentState = mContent->AsElement()->State(); - bool imageOK = IMAGE_OK(contentState, true); + bool imageOK = ImageOk(mContent->AsElement()->State()); // 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 |