summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/image-base-url.html
blob: 932cd92b4151fe61d407e693a52e17dcd0363307 (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
<!DOCTYPE html>
<html>
<head>
  <title>Image load parses URL after microtask runs</title>
  <script src="/resources/testharness.js"></script>
  <script src="/resources/testharnessreport.js"></script>
</head>

<body>
<script>
// See https://github.com/whatwg/html/issues/7383 and
// https://chromium-review.googlesource.com/c/chromium/src/+/3311225.
// This test asserts two things:
//   1.) That Document base URL modifications that take place in between an
//       image loading microtask being scheduled and executed are reflected in
//       the final image request
//   2.) That subsequent changes to a Document's base URL before an image is
//       inserted into the DOM do not lead to the image being refetched when it
//       is inserted asynchronously later. This is because image insertion is
//       not a relevant mutation
//       (https://html.spec.whatwg.org/#relevant-mutations).
promise_test(async t => {
  const image = new Image();
  image.src = 'green.png';

  // Dynamically insert a <base> tag that should influence the above image
  // request because the above code triggers a microtask to continue fetching
  // the image, which will run while we await `loadPromise` below.
  const base = document.createElement('base');
  base.setAttribute('href', 'resources/');
  document.head.append(base);

  const loadPromise = new Promise((resolve, reject) => {
    image.addEventListener('load', e => {
      resolve();
    }, {once: true});

    image.addEventListener('error', e => {
      reject('The image must load');
    }, {once: true});
  });

  // The image should load successfully, since its request was influenced by the
  // <base> element which points the request to the right directory.
  await loadPromise;

  // Now manipulate the <base> element to point to a bogus directory.
  base.setAttribute('href', 'bogus/');
  document.body.append(image);

  const timeoutPromise = new Promise(resolve => t.step_timeout(resolve, 1500));
  const imageErrorPromise = new Promise((resolve, reject) => {
    image.addEventListener('load', e => {
      reject('The image should not be refetched upon insertion and load, ' +
             'because (1) insertion is not a relevant mutation, and (2) the ' +
             'new relative URL should not resolve to a real resource');
    }, {once: true});

    image.addEventListener('error', e => {
      reject('The image should not be refetched upon insertion, because ' +
             'insertion is not a relevant mutation');
    }, {once: true});
  });

  await Promise.race([timeoutPromise, imageErrorPromise]);
}, "An image should not be refetched upon insertion asynchronously after its " +
   "Document's base URL changes");
</script>
</body>
</html>