tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

picture-aspect-ratio.html (9255B)


      1 <!doctype html>
      2 <title>Image width and height attributes are used to infer aspect-ratio</title>
      3 <script src="/resources/testharness.js"></script>
      4 <script src="/resources/testharnessreport.js"></script>
      5 <style>
      6  img:not([nowidth]) {
      7    width: 100%;
      8    max-width: 100px;
      9    height: auto;
     10  }
     11 </style>
     12 <picture>
     13  <source srcset="/images/green-100x50.png"></source>
     14  <img>
     15 </picture>
     16 
     17 <picture>
     18  <source srcset="/images/green-100x50.png" width="100" height="100"></source>
     19  <img>
     20 </picture>
     21 
     22 <picture>
     23  <source srcset="/images/green-100x50.png" width="100" height="100"></source>
     24  <img width="50" height="100">
     25 </picture>
     26 
     27 <picture>
     28  <source srcset="/images/green-100x50.png" width="100" height="100" id="twosource-s1"></source>
     29  <source srcset="/images/green-100x50.png" width="300" height="150"></source>
     30  <img id="twosource-img">
     31 </picture>
     32 
     33 <div style="width: 100px;">
     34  <picture>
     35    <source srcset="/images/green-100x50.png" width="100%" height="50%" id="percent-src"></source>
     36    <img style="contain:size;" id="percent-img" nowidth="true">
     37  </picture>
     38 </div>
     39 
     40 <picture>
     41  <source srcset="/images/green-100x50.png" width="100abc" height="50abc" id="trailing-src"></source>
     42  <img style="contain:size;" id="trailing-img" nowidth="true">
     43 </picture>
     44 
     45 <script>
     46 let guard = async_test("source width and height attributes are used to infer aspect-ratio in <picture>");
     47 function assert_ratio(img, expected, description) {
     48  let epsilon = 0.001;
     49  assert_approx_equals(parseFloat(getComputedStyle(img).width, 10) / parseFloat(getComputedStyle(img).height, 10),
     50                       expected, epsilon, description);
     51 }
     52 
     53 function createPicture(width, height) {
     54  var picture = document.createElement("picture");
     55  var source = document.createElement("source");
     56  if (width !== undefined)
     57    source.setAttribute("width", width);
     58  if (height !== undefined)
     59    source.setAttribute("height", height);
     60  source.setAttribute("srcset", "/images/green.png");
     61  picture.appendChild(source);
     62  var img = document.createElement("img");
     63  picture.appendChild(img);
     64  document.body.appendChild(picture);
     65  return img;
     66 }
     67 
     68 function assert_cs(img, val) {
     69  assert_equals(getComputedStyle(img).aspectRatio, val);
     70 }
     71 
     72 // Create and append a new image and immediately check the ratio.
     73 // This is not racy because the spec requires the user agent to queue a task:
     74 // https://html.spec.whatwg.org/multipage/images.html#updating-the-image-data
     75 test(function() {
     76  var img = createPicture(100, 100);
     77  assert_ratio(img, 1.0);
     78  assert_cs(img, "auto 100 / 100");
     79  img.style.display = "none";
     80  img.setAttribute("nowidth", "true");
     81  assert_equals(getComputedStyle(img).width, "100px");
     82  assert_equals(getComputedStyle(img).height, "100px");
     83  var source = img.previousSibling;
     84  assert_equals(getComputedStyle(source).width, "auto");
     85  assert_equals(getComputedStyle(source).height, "auto");
     86 }, "Computed style for width/height/aspect-ratio");
     87 
     88 test(function() {
     89  img = createPicture(200, 100);
     90  img.setAttribute("width", 250);
     91  img.setAttribute("height", 50);
     92  assert_ratio(img, 2.0);
     93  assert_cs(img, "auto 200 / 100");
     94  img.style.display = "none";
     95  img.setAttribute("nowidth", "true");
     96  assert_equals(getComputedStyle(img).width, "200px");
     97  assert_equals(getComputedStyle(img).height, "100px");
     98  source = img.previousSibling;
     99  assert_equals(getComputedStyle(source).width, "auto");
    100  assert_equals(getComputedStyle(source).height, "auto");
    101 }, "Source width/height should take precedence over img attributes.");
    102 
    103 test(function() {
    104  img.parentNode.removeChild(img.previousSibling);
    105  assert_cs(img, "auto 250 / 50");
    106  img.src = "/images/green.png";
    107  assert_ratio(img, 5.0);
    108  img.style.display = "none";
    109  img.setAttribute("nowidth", "true");
    110  assert_equals(getComputedStyle(img).width, "250px");
    111  assert_equals(getComputedStyle(img).height, "50px");
    112 }, "Make sure style gets invalidated correctly when the source gets removed.");
    113 
    114 test(function() {
    115  img = createPicture(100, undefined);
    116  img.setAttribute("width", 200);
    117  img.setAttribute("height", 100);
    118  assert_cs(img, "auto");
    119  img.style.display = "none";
    120  img.setAttribute("nowidth", "true");
    121  assert_equals(getComputedStyle(img).width, "100px");
    122  assert_equals(getComputedStyle(img).height, "auto");
    123 }, "If the <source> has only one of width/height, we don't get an aspect ratio, even if the <img> has both.");
    124 
    125 test(function() {
    126  img = createPicture(undefined, undefined);
    127  img.setAttribute("width", 200);
    128  img.setAttribute("height", 100);
    129  assert_cs(img, "auto 200 / 100");
    130 }, "If we don't have width/height on the source, we fall back to width/height on the <img>.");
    131 
    132 test(function() {
    133  img = createPicture(100, undefined);
    134  img.parentNode.style.display = "none";
    135  img.setAttribute("width", "200");
    136  img.setAttribute("height", "300");
    137  img.setAttribute("nowidth", "true");
    138  assert_cs(img, "auto");
    139  assert_equals(getComputedStyle(img).width, "100px");
    140  assert_equals(getComputedStyle(img).height, "auto");
    141 }, "If we only have one width attribute, we should get width mapped but no aspect ratio, even if <img> has attributes.");
    142 
    143 test(function() {
    144  img = createPicture(undefined, 100);
    145  img.parentNode.style.display = "none";
    146  img.setAttribute("width", "200");
    147  img.setAttribute("height", "300");
    148  img.setAttribute("nowidth", "true");
    149  assert_cs(img, "auto");
    150  assert_equals(getComputedStyle(img).width, "auto");
    151  assert_equals(getComputedStyle(img).height, "100px");
    152 }, "If we only have height attribute, we should get height mapped but no aspect ratio, even if <img> has attributes.");
    153 
    154 test(function() {
    155  img = createPicture(100, 100);
    156  assert_cs(img, "auto 100 / 100");
    157  img.previousSibling.setAttribute("height", "300");
    158  assert_cs(img, "auto 100 / 300");
    159  img.previousSibling.setAttribute("width", "10");
    160  assert_cs(img, "auto 10 / 300");
    161  img.style.display = "none";
    162  img.setAttribute("nowidth", "true");
    163  assert_equals(getComputedStyle(img).width, "10px");
    164  assert_equals(getComputedStyle(img).height, "300px");
    165 }, "Dynamically changing width/height should change computed style");
    166 
    167 test(function() {
    168  img = document.getElementById("twosource-img");
    169  assert_cs(img, "auto 100 / 100");
    170  source = document.getElementById("twosource-s1");
    171  source.setAttribute("type", "x-foo/x-bar");
    172  // We should now match the second source
    173  assert_cs(img, "auto 300 / 150");
    174  img.style.display = "none";
    175  img.setAttribute("nowidth", "true");
    176  assert_equals(getComputedStyle(img).width, "300px");
    177  assert_equals(getComputedStyle(img).height, "150px");
    178 }, "Changing which <source> matches should change computed style");
    179 
    180 test(function() {
    181  img = document.getElementById("percent-img");
    182  assert_equals(img.offsetWidth, 100);
    183  assert_equals(img.offsetHeight, 0);
    184  assert_cs(img, "auto");
    185  source = document.getElementById("percent-src");
    186  assert_equals(source.width, 100);
    187  assert_equals(source.height, 50);
    188  img.style.display = "none";
    189  img.setAttribute("nowidth", "true");
    190  assert_equals(getComputedStyle(img).width, "100%");
    191  assert_equals(getComputedStyle(img).height, "50%");
    192 }, "Percentages on source should be ignored for aspect-ratio but used for width/height.");
    193 
    194 test(function() {
    195  img = document.getElementById("trailing-img");
    196  assert_equals(img.offsetWidth, 100);
    197  assert_equals(img.offsetHeight, 50);
    198  assert_cs(img, "auto 100 / 50");
    199  source = document.getElementById("trailing-src");
    200  assert_equals(source.width, 100);
    201  assert_equals(source.height, 50);
    202  img.style.display = "none";
    203  img.setAttribute("nowidth", "true");
    204  assert_equals(getComputedStyle(img).width, "100px");
    205  assert_equals(getComputedStyle(img).height, "50px");
    206 }, "Trailing garbage should be ignored but not make the attribute invalid");
    207 
    208 onload = function() {
    209  let images = document.querySelectorAll("img");
    210  test(function() {
    211    var img = images[0];
    212    assert_ratio(img, 2.0, "2.0 is the original aspect ratio of green-100x50.png");
    213    assert_cs(img, "auto");
    214    img.style.display = "none";
    215    img.setAttribute("nowidth", "true");
    216    assert_equals(getComputedStyle(img).width, "auto");
    217    assert_equals(getComputedStyle(img).height, "auto");
    218  }, "Loaded picture test: Both <source> and <img> are without width and height attributes");
    219 
    220  test(function () {
    221    img = images[1];
    222    assert_ratio(img, 2.0, "Loaded image's aspect ratio, at least by default, overrides width / height ratio.");
    223    assert_cs(img, "auto 100 / 100");
    224    img.style.display = "none";
    225    img.setAttribute("nowidth", "true");
    226    assert_equals(getComputedStyle(img).width, "100px");
    227    assert_equals(getComputedStyle(img).height, "100px");
    228  }, "Loaded picture test: <source> with width and height attributes, <img> without width and height attributes");
    229 
    230  test(function () {
    231    img = images[2];
    232    assert_ratio(img, 2.0, "Loaded image's aspect ratio, at least by default, overrides width / height ratio (2).");
    233    assert_cs(img, "auto 100 / 100");
    234    img.style.display = "none";
    235    img.setAttribute("nowidth", "true");
    236    assert_equals(getComputedStyle(img).width, "100px");
    237    assert_equals(getComputedStyle(img).height, "100px");
    238  }, "Loaded picture test: Both <source> and <img> are with width and height attributes");
    239 
    240  guard.done();
    241 };
    242 </script>