Skip to content

Commit

Permalink
Add test for <source> width/height
Browse files Browse the repository at this point in the history
This is for whatwg/html#5894
  • Loading branch information
cbiesinger committed Feb 23, 2021
1 parent c30545d commit 33ebbc4
Showing 1 changed file with 168 additions and 0 deletions.
@@ -0,0 +1,168 @@
<!doctype html>
<title>Image width and height attributes are used to infer aspect-ratio</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
img:not([nowidth]) {
width: 100%;
max-width: 100px;
height: auto;
}
</style>
<picture>
<source srcset="/images/green-100x50.png"></source>
<img>
</picture>

<picture>
<source srcset="/images/green-100x50.png" width="100" height="100"></source>
<img>
</picture>

<picture>
<source srcset="/images/green-100x50.png" width="100" height="100"></source>
<img width="50" height="100">
</picture>

<picture>
<source srcset="/images/green-100x50.png" width="100" height="100" id="twosource-s1"></source>
<source srcset="/images/green-100x50.png" width="300" height="150"></source>
<img id="twosource-img">
</picture>

<div style="width: 100px;">
<picture>
<source srcset="/images/green-100x50.png" width="100%" height="50%" id="percent-src"></source>
<img style="contain:size;" id="percent-img" nowidth="true">
</picture>
</div>

<picture>
<source srcset="/images/green-100x50.png" width="100abc" height="50abc" id="trailing-src"></source>
<img style="contain:size;" id="trailing-img" nowidth="true">
</picture>

<script>
let t = async_test("source width and height attributes are used to infer aspect-ratio in <picture>");
function assert_ratio(img, expected, description) {
let epsilon = 0.001;
assert_approx_equals(parseFloat(getComputedStyle(img).width, 10) / parseFloat(getComputedStyle(img).height, 10),
expected, epsilon, description);
}

function createPicture(width, height) {
var picture = document.createElement("picture");
var source = document.createElement("source");
if (width !== undefined)
source.setAttribute("width", width);
if (height !== undefined)
source.setAttribute("height", height);
source.setAttribute("srcset", "/images/green.png");
picture.appendChild(source);
var img = document.createElement("img");
picture.appendChild(img);
document.body.appendChild(picture);
return img;
}

function assert_cs(img, val) {
assert_equals(getComputedStyle(img).aspectRatio, val);
}

// Create and append a new image and immediately check the ratio.
// This is not racy because the spec requires the user agent to queue a task:
// https://html.spec.whatwg.org/multipage/images.html#updating-the-image-data
test(function() {
var img = createPicture(100, 100);
assert_ratio(img, 1.0);
assert_cs(img, "auto 100 / 100");

// Source width/height should take precedence over img attributes.
img = createPicture(200, 100);
img.setAttribute("width", 250);
img.setAttribute("height", 50);
assert_ratio(img, 2.0);
assert_cs(img, "auto 200 / 100");

// Make sure style gets invalidated correctly when the source gets removed.
img.parentNode.removeChild(img.previousSibling);
assert_cs(img, "auto 250 / 50");
img.src = "/images/green.png";
assert_ratio(img, 5.0);

// If the <source> has only one of width/height, we don't get an aspect
// ratio, even if the <img> has both.
img = createPicture(100, undefined);
img.setAttribute("width", 200);
img.setAttribute("height", 100);
assert_cs(img, "auto");

// If we don't have width/height on the source, we fall back to width/height
// on the <img>.
img = createPicture(undefined, undefined);
img.setAttribute("width", 200);
img.setAttribute("height", 100);
assert_cs(img, "auto 200 / 100");

// If we only have one width/height attribute, we should get that attribute
// mapped but no aspect ratio, even if <img> has attributes.
img = createPicture(100, undefined);
img.parentNode.style.display = "none";
img.setAttribute("width", "200");
img.setAttribute("height", "300");
img.setAttribute("nowidth", "true");
assert_cs(img, "auto");
assert_equals(getComputedStyle(img).width, "100px");
assert_equals(getComputedStyle(img).height, "auto");

img = createPicture(undefined, 100);
img.parentNode.style.display = "none";
img.setAttribute("width", "200");
img.setAttribute("height", "300");
img.setAttribute("nowidth", "true");
assert_cs(img, "auto");
assert_equals(getComputedStyle(img).width, "auto");
assert_equals(getComputedStyle(img).height, "100px");

// Testing dynamic changes
img = createPicture(100, 100);
assert_cs(img, "auto 100 / 100");
img.previousSibling.setAttribute("height", "300");
assert_cs(img, "auto 100 / 300");
img.previousSibling.setAttribute("width", "10");
assert_cs(img, "auto 10 / 300");

img = document.getElementById("twosource-img");
assert_cs(img, "auto 100 / 100");
var source = document.getElementById("twosource-s1");
source.setAttribute("type", "x-foo/x-bar");
// We should now match the second source
assert_cs(img, "auto 300 / 150");

// Percentages on source should be ignored for aspect-ratio but used for
// width/height.
img = document.getElementById("percent-img");
assert_equals(img.offsetWidth, 100);
assert_equals(img.offsetHeight, 0);
assert_cs(img, "auto");
source = document.getElementById("percent-src");
assert_equals(source.width, 100);
assert_equals(source.height, 50);

// Trailing garbage should be ignored but not invalidate anything.
img = document.getElementById("trailing-img");
assert_equals(img.offsetWidth, 100);
assert_equals(img.offsetHeight, 50);
assert_cs(img, "auto 100 / 50");
source = document.getElementById("trailing-src");
assert_equals(source.width, 100);
assert_equals(source.height, 50);
}, "Computed style");

onload = t.step_func_done(function() {
let images = document.querySelectorAll("img");
assert_ratio(images[0], 2.0, "2.0 is the original aspect ratio of green-100x50.png");
assert_ratio(images[1], 2.0, "Loaded image's aspect ratio, at least by default, overrides width / height ratio.");
assert_ratio(images[2], 2.0, "Loaded image's aspect ratio, at least by default, overrides width / height ratio (2).");
});
</script>

0 comments on commit 33ebbc4

Please sign in to comment.