Issue #1543 - Align <img> with no src to the updated spec.

This commit is contained in:
Moonchild 2020-05-11 23:17:47 +00:00 • committed by Roy Tam
commit db14a637c4
25 changed files with 124 additions and 85 deletions

View file

@ -83,7 +83,7 @@
'listitem-2-3']);
queueTraversalSequence(gQueue, docAcc, TraversalRules.Graphic, null,
['image-2', 'image-3']);
['image-1', 'image-2', 'image-3']);
queueTraversalSequence(gQueue, docAcc, TraversalRules.Link, null,
['link-0', 'link-1', 'link-2', 'link-3']);
@ -117,7 +117,7 @@
'1. Scheme', '2. Racket', '3. Clojure',
'4. Standard Lisp', 'link-0', ' Lisp',
'checkbox-1-5', ' LeLisp', '• JavaScript',
'heading-5', 'image-2', 'image-3',
'heading-5', 'image-1', 'image-2', 'image-3',
'Not actually an image', 'link-1', 'anchor-1',
'link-2', 'anchor-2', 'link-3', '3', '1', '4',
'1', 'Sunday', 'M', 'Week 1', '3', '4', '7', '2',

View file

@ -20,8 +20,8 @@
document.getElementsByTagName("img")[0].firstChild.data = "2";
var accTree = {
role: ROLE_TEXT,
children: [ { role: ROLE_TEXT_LEAF } ]
role: ROLE_GRAPHIC,
children: []
};
testAccessibleTree("the_img", accTree);
SimpleTest.finish();

View file

@ -68,7 +68,7 @@ interface nsIImageLoadingContent : imgINotificationObserver
* the image was blocked. This status always refers to the
* CURRENT_REQUEST load.
*/
readonly attribute short imageBlockingStatus;
[infallible] readonly attribute short imageBlockingStatus;
/**
* Used to register an image decoder observer. Typically, this will

View file

@ -2,6 +2,7 @@
<html>
<body>
<img id="image1" src="">
<img id="image2">
<input id="image3" type="image">
</body>
</html>

View file

@ -4,7 +4,8 @@
<title>Delayed image reftest wrapper</title>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// This loads a externally specified image, forces a draw (in case of
// decode-on-draw), waits 350ms, and then triggers the reftest snapshot.

View file

@ -9,7 +9,8 @@ img {
</style>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// Loads an externally specified image and displays it
// with a green background. Intended for use with tests

View file

@ -4,7 +4,8 @@
<title>Delayed image reftest wrapper</title>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// This loads a externally specified image, forces a draw (in case of
// decode-on-draw), waits 100ms, and then triggers the reftest snapshot.

View file

@ -14,13 +14,13 @@
</script>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// Use as "wrapper.html?image.png"
var imgURL = document.location.search.substr(1);
document.images[0].onload = onImageLoad;
document.images[0].onerror = onImageLoad;
document.images[0].alt = "";
document.images[0].src = imgURL;
</script>
</body>

View file

@ -14,13 +14,13 @@
</script>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// Use as "wrapper.html?image.png"
var imgURL = document.location.search.substr(1);
document.images[0].onload = onImageLoad;
document.images[0].onerror = onImageLoad;
document.images[0].alt = "";
document.images[0].src = imgURL;
</script>
</body>

View file

@ -14,13 +14,13 @@
</script>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// Use as "wrapper.html?image.png"
var imgURL = document.location.search.substr(1);
document.images[0].onload = onImageLoad;
document.images[0].onerror = onImageLoad;
document.images[0].alt = "";
document.images[0].src = imgURL;
</script>
</body>

View file

@ -14,13 +14,13 @@
</script>
</head>
<body>
<img width="16px" height="16px" id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img width="16px" height="16px" id="image1" alt=" ">
<script>
// Use as "wrapper.html?image.png"
var imgURL = document.location.search.substr(1);
document.images[0].onload = onImageLoad;
document.images[0].onerror = onImageLoad;
document.images[0].alt = "";
document.images[0].src = imgURL;
</script>
</body>

View file

@ -14,7 +14,8 @@
</script>
</head>
<body>
<img width="8px" id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img width="8px" id="image1" alt=" ">
<script>
// Use as "wrapper.html?image.png"
var imgURL = document.location.search.substr(1);

View file

@ -4,7 +4,8 @@
<title>Delayed image reftest wrapper</title>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// This loads a externally specified image, forces a draw (in case of
// decode-on-draw), waits 100ms, and then triggers the reftest snapshot.

View file

@ -14,7 +14,8 @@
</script>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// Use as "wrapper.html?image.png
var imgURL = document.location.search.substr(1);

View file

@ -51,7 +51,6 @@
// code.
var finalImg = document.getElementById('image1');
finalImg.alt = "";
finalImg.onload = finalImg.onerror = step3;
finalImg.src = gImg.src;
}
@ -68,7 +67,8 @@
</script>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// Use as "wrapper.html?image.png
gImg = document.createElement('img');

View file

@ -14,13 +14,13 @@
</script>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// Use as "wrapper.html?image.png
var imgURL = document.location.search.substr(1);
document.images[0].onload = onImageLoad;
document.images[0].onerror = onImageLoad;
document.images[0].alt = "";
document.images[0].src = imgURL;
</script>
</body>

View file

@ -14,7 +14,8 @@
</script>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// Use as "wrapper.html?image.png
var imgURL = document.location.search.substr(1);

View file

@ -14,13 +14,13 @@
</script>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// Use as "wrapper.html?image.png
var imgURL = document.location.search.substr(1);
document.images[0].onload = onImageLoad;
document.images[0].onerror = onImageLoad;
document.images[0].alt = "";
document.images[0].src = imgURL;
</script>
</body>

View file

@ -14,7 +14,8 @@
</script>
</head>
<body>
<img id="image1">
<!-- non-empty alt to avoid the broken image icon -->
<img id="image1" alt=" ">
<script>
// Use as "wrapper.html?image.png
var imgURL = document.location.search.substr(1);

View file

@ -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
@ -440,8 +440,22 @@ nsImageFrame::SourceRectToDest(const nsIntRect& aRect)
(!(_state).HasAtLeastOneOfStates(NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_USERDISABLED) && \
(_state).HasState(NS_EVENT_STATE_LOADING) && (_loadingOK)))
/* 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)
{
@ -452,44 +466,26 @@ nsImageFrame::ShouldCreateImageFrameFor(Element* aElement,
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;
}
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;
}
else if (aStyleContext->PresContext()->CompatibilityMode() !=
eCompatibility_NavQuirks) {
useSizedBox = false;
}
else {
// check whether we have specified size
useSizedBox = HaveSpecifiedSize(aStyleContext->StylePosition());
return true;
}
return useSizedBox;
// If our "do not show placeholders" pref is set, skip the icon
if (gIconLoad && gIconLoad->mPrefForceInlineAltText) {
return false;
}
// If there is no Alt text, always create an image frame (regardless of src)
if (!HasAltText(aElement)) {
return true;
}
if (aStyleContext->PresContext()->CompatibilityMode() == eCompatibility_NavQuirks) {
return HaveSpecifiedSize(aStyleContext->StylePosition());
}
return false;
}
nsresult
@ -775,6 +771,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 +804,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)));
@ -1389,7 +1390,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 {

View file

@ -106,6 +106,8 @@ public:
void OnVisibilityChange(Visibility aNewVisibility,
Maybe<OnNonvisible> aNonvisibleAction = Nothing()) override;
bool ShouldShowBrokenImageIcon() const;
#ifdef ACCESSIBILITY
virtual mozilla::a11y::AccType AccessibleType() override;
#endif

View file

@ -1,2 +1,2 @@
<!DOCTYPE html>
<img style="background-image: url(really-big-background.png); width: 1600px; height: 1200px; position: absolute;"></img>
<img alt=" " style="background-image: url(really-big-background.png); width: 1600px; height: 1200px; position: absolute;"></img>

File diff suppressed because one or more lines are too long

View file

@ -109,7 +109,7 @@ asserts(8) load 420654-1.xhtml # bug 458238, bug 436123, bug 457397
load 423514-1.xhtml
load 430374.html
load 444431-1.html
load 444702-1.html
asserts(1) load 444702-1.html # nscoord overflow.
load 448988-1.xhtml
load 450311-1.html
load 451170.html

View file

@ -0,0 +1,25 @@
<!doctype html>
<title>Images without alt attribute or with an empty alt attribute render as replaced elements regardless of src</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link rel="author" href="https://mozilla.org" title="Mozilla">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1196668">
<style>
img {
width: 100px;
height: 150px;
}
</style>
<img>
<img src="broken">
<img alt="">
<script>
const t = async_test("Images without alt attribute or with an empty alt attribute render as replaced elements regardless of src");
onload = t.step_func_done(function() {
for (const img of document.querySelectorAll("img")) {
assert_equals(img.offsetWidth, 100, `width: ${img.outerHTML}`);
assert_equals(img.offsetHeight, 150, `height: ${img.outerHTML}`);
}
});
</script>