summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/sizes/sizes-auto.html
blob: 6c1a741f2bfd512534975f71047d80f4d8b6b146 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<!doctype html>
<title>img parse a sizes attribute: sizes=auto</title>
<link rel="help" href="https://html.spec.whatwg.org/multipage/images.html#parse-a-sizes-attribute">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
img { height: 10px; } /* Keep all images in the viewport, so lazy images load */
#narrow-div { width: 10px; }
#wide-div { width: 500px; }
</style>
<div id=log></div>
<script src="support/parse-a-sizes-attribute.js"></script>
<img srcset='/images/green-1x1.png?ref1 50w, /images/green-16x16.png?ref1 51w' sizes='1px' id=ref1>
<img srcset='/images/green-1x1.png?ref2 50w, /images/green-16x16.png?ref2 51w' sizes='100vw' id=ref2>
<div id='narrow-div'></div>
<div id='wide-div'></div>
<script>
"use strict";

// https://github.com/web-platform-tests/rfcs/pull/75
let async_promise_test = (promise, description) => {
  async_test(test => {
    promise(test)
      .then(() => {test.done();})
      .catch(test.step_func(error => { throw error; }));
  }, description);
};

function check(imgOrPicture) {
  let img = imgOrPicture;
  let source;
  if (imgOrPicture.localName === 'picture') {
    source = imgOrPicture.firstChild;
    img = imgOrPicture.lastChild;
  }
  const ref = document.getElementById(img.dataset.ref);
  async_promise_test(async (t) => {
    let expect = ref.currentSrc;
    if (expect) {
      expect = expect.split('?')[0];
    }
    if (expect === '' || expect === null || expect === undefined) {
      assert_unreached('ref currentSrc was ' + format_value(expect));
    }
    await new Promise((resolve, reject) => {
      img.onload = resolve;
      img.onerror = reject;
    });
    t.step(() => {
      let got = img.currentSrc;
      assert_greater_than(got.indexOf('?'), -1, 'expected a "?" in currentSrc');
      got = got.split('?')[0];
      assert_equals(got, expect);
    })
  }, imgOrPicture.outerHTML);
}

const tests = [
  // Smoke tests
  {sizes: '1px', 'data-ref': 'ref1'},
  {sizes: '', 'data-ref': 'ref2'},
  // Actual tests
  {loading: 'lazy', sizes: 'auto', width: '10', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'AUTO', width: '10', 'data-ref': 'ref1'},
  {loading: 'lazy', width: '10', 'data-ref': 'ref2'}, // no `sizes: 'auto'` -> 100vw
  {loading: 'lazy', style: 'width: 10px', 'data-ref': 'ref2'}, // no `sizes: 'auto'` -> 100vw
  {loading: 'lazy', style: 'max-width: 10px', 'data-ref': 'ref2'}, // no `sizes: 'auto'` -> 100vw
  {loading: 'lazy', style: 'width: 100%; max-width: 10px', 'data-ref': 'ref2'}, // no `sizes: 'auto'` -> 100vw
  {loading: 'lazy', sizes: 'auto', width: '500', 'data-ref': 'ref2'},
  {loading: 'lazy', sizes: 'auto', width: '10', style: 'visibility: hidden', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', width: '10', style: 'display: inline', hidden: '', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', width: '0', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', style: 'width: 0px', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', 'data-ref': 'ref2'}, // no width -> UA default of 300px
  {loading: 'lazy', sizes: 'auto, 100vw', width: '10', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: '100vw, auto', width: '10', 'data-ref': 'ref2'},
  {loading: 'eager', sizes: 'auto', width: '10', 'data-ref': 'ref2'},
  {loading: 'lazy', sizes: 'auto', width: '100%', parent: 'narrow-div', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', width: '100%', parent: 'wide-div', 'data-ref': 'ref2'},
  {loading: 'lazy', sizes: 'auto', style: 'height: 10px; aspect-ratio: 10 / 10', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', style: 'height: 10px; aspect-ratio: 500 / 10', 'data-ref': 'ref2'},
  {loading: 'lazy', sizes: 'auto', style: 'min-height: 10px; aspect-ratio: 10 / 10', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', style: 'min-height: 10px; aspect-ratio: 500 / 10', 'data-ref': 'ref2'},
  {loading: 'lazy', sizes: 'auto', style: 'inline-size: 10px', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', style: 'min-inline-size: 10px', 'data-ref': 'ref2'}, // no width -> UA default of 300px
  {loading: 'lazy', sizes: 'auto', style: 'block-size: 10px; aspect-ratio: 10 / 10', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', style: 'min-block-size: 10px; aspect-ratio: 10 / 10', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', style: 'block-size: 10px; writing-mode: vertical-rl', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', style: 'min-block-size: 10px; writing-mode: vertical-rl', 'data-ref': 'ref2'}, // no width -> UA default of 300px
  {loading: 'lazy', sizes: 'auto', style: 'inline-size: 10px; aspect-ratio: 10/10; writing-mode: vertical-rl', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', style: 'min-inline-size: 10px; aspect-ratio: 10/10; writing-mode: vertical-rl', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', style: '--my-width: 10px; width: var(--my-width)', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', style: 'width: calc(5px + 5px)', 'data-ref': 'ref1'},
  {loading: 'lazy', sizes: 'auto', style: 'position: absolute; left: 50%; right: 49%', 'data-ref': 'ref2'}, // replaced elements don't get the width resolved from 'left'/'right' per https://drafts.csswg.org/css2/#abs-replaced-width
];

function test_img(obj, i) {
  const img = document.createElement('img');
  let parent = document.body;
  for (const attr in obj) {
    if (attr === 'parent') {
      parent = document.getElementById(obj.parent);
    } else {
      img.setAttribute(attr, obj[attr]);
    }
  }
  img.srcset = `/images/green-1x1.png?img${i} 50w, /images/green-16x16.png?img${i} 51w`
  parent.appendChild(img);
  check(img);
}

function test_picture(obj, i) {
  const picture = document.createElement('picture');
  const source = document.createElement('source');
  const img = document.createElement('img');
  let parent = document.body;
  for (const attr in obj) {
    switch (attr) {
      case 'parent':
        parent = document.getElementById(obj.parent);
        break;
      case 'sizes':
        // Authors have to specify sizes="auto" on the img to use auto-sizes.
        if(obj[attr].toLowerCase().startsWith("auto")) {
          img.setAttribute(attr, obj[attr]);
          break;
        }
      case 'type':
      case 'media':
        source.setAttribute(attr, obj[attr]);
        break;
      default:
        img.setAttribute(attr, obj[attr]);
        break;
    }
  }
  source.srcset = `/images/green-1x1.png?picture${i} 50w, /images/green-16x16.png?picture${i} 51w`;
  picture.appendChild(source);
  picture.appendChild(img);
  parent.appendChild(picture);
  check(picture);
}

onload = () => {
  let i = 0;
  for (const obj of tests) {
    i++;
    test_img(obj, i);
    test_picture(obj, i);
  }
  done();
}
</script>