image-base-url.html (2724B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Image load parses URL after microtask runs</title> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 </head> 8 9 <body> 10 <script> 11 // See https://github.com/whatwg/html/issues/7383 and 12 // https://chromium-review.googlesource.com/c/chromium/src/+/3311225. 13 // This test asserts two things: 14 // 1.) That Document base URL modifications that take place in between an 15 // image loading microtask being scheduled and executed are reflected in 16 // the final image request 17 // 2.) That subsequent changes to a Document's base URL before an image is 18 // inserted into the DOM do not lead to the image being refetched when it 19 // is inserted asynchronously later. This is because image insertion is 20 // not a relevant mutation 21 // (https://html.spec.whatwg.org/#relevant-mutations). 22 promise_test(async t => { 23 const image = new Image(); 24 image.src = 'green.png'; 25 26 // Dynamically insert a <base> tag that should influence the above image 27 // request because the above code triggers a microtask to continue fetching 28 // the image, which will run while we await `loadPromise` below. 29 const base = document.createElement('base'); 30 base.setAttribute('href', 'resources/'); 31 document.head.append(base); 32 33 const loadPromise = new Promise((resolve, reject) => { 34 image.addEventListener('load', e => { 35 resolve(); 36 }, {once: true}); 37 38 image.addEventListener('error', e => { 39 reject('The image must load'); 40 }, {once: true}); 41 }); 42 43 // The image should load successfully, since its request was influenced by the 44 // <base> element which points the request to the right directory. 45 await loadPromise; 46 47 // Now manipulate the <base> element to point to a bogus directory. 48 base.setAttribute('href', 'bogus/'); 49 document.body.append(image); 50 51 const timeoutPromise = new Promise(resolve => t.step_timeout(resolve, 1500)); 52 const imageErrorPromise = new Promise((resolve, reject) => { 53 image.addEventListener('load', e => { 54 reject('The image should not be refetched upon insertion and load, ' + 55 'because (1) insertion is not a relevant mutation, and (2) the ' + 56 'new relative URL should not resolve to a real resource'); 57 }, {once: true}); 58 59 image.addEventListener('error', e => { 60 reject('The image should not be refetched upon insertion, because ' + 61 'insertion is not a relevant mutation'); 62 }, {once: true}); 63 }); 64 65 await Promise.race([timeoutPromise, imageErrorPromise]); 66 }, "An image should not be refetched upon insertion asynchronously after its " + 67 "Document's base URL changes"); 68 </script> 69 </body> 70 </html>