<!doctype html> <meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="/common/utils.js"></script> <script src="/preload/resources/preload_helper.js"></script> <body> <script> ['attached', 'detacted'].forEach(state => promise_test(async t => { const href = '/common/square.png'; const sequence = []; const name = `with-preload-${state}`; const loaded = new Promise(resolveLoad => { customElements.define(name, class extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: "closed" }); const link = document.createElement('link'); link.rel = 'preload'; link.as = 'image'; link.href = href; if (state === 'attached') shadow.appendChild(link); sequence.push('constructed'); link.addEventListener('load', () => { sequence.push('loaded'); resolveLoad(); }); } connectedCallback() { sequence.push('connected'); } }); }); const wrapper = document.createElement(name); const timeout = 500; await new Promise(resolve => t.step_timeout(resolve, timeout)); document.body.appendChild(wrapper); await Promise.any([loaded, new Promise(resolve => t.step_timeout(() => { sequence.push('timeout'); resolve(); }, timeout))]); assert_array_equals(sequence, ['constructed', 'connected', state === 'attached' ? 'loaded' : 'timeout']); }, `preload link should ${state === 'attached' ? 'be fetched when attached' : 'note fetched when detached from'} a shadow DOM`)); promise_test(async t => { const href = '/common/square.png'; const doc = document.implementation.createHTMLDocument(); const link = doc.createElement('link'); link.rel = 'preload'; link.as = 'image'; link.href = href; const loaded = new Promise(resolve => link.addEventListener('load', () => resolve('loaded'))); const timeoutMillis = 1000; const timeout = new Promise(resolve => t.step_timeout(() => resolve('timeout'), timeoutMillis)); doc.head.appendChild(link); const result = await Promise.any([loaded, timeout]); assert_equals(result, 'timeout'); }, 'preload links only work for documents within browsing contexts'); promise_test(async t => { const href = '/common/square.png'; const fragment = document.createDocumentFragment(); const link = document.createElement('link'); link.rel = 'preload'; link.as = 'image'; link.href = href; fragment.appendChild(link); const timeoutMillis = 1000; let didLoad = false; const loaded = new Promise(resolve => link.addEventListener('load', () => { resolve('loaded'); didLoad = true; })); const timeout = () => new Promise(resolve => t.step_timeout(() => resolve('timeout'), timeoutMillis)); await timeout(); assert_false(didLoad, 'Loaded prematurely, fragment not connected to document yet'); document.head.appendChild(link); await Promise.any([loaded, timeout()]); assert_true(didLoad); }, 'preload links from DocumentFragment only work when attached'); promise_test(async t => { const href = '/common/square.png'; const link = document.createElement('link'); link.rel = 'preload'; link.as = 'image'; link.href = href; const loaded = new Promise(resolve => link.addEventListener('load', () => resolve('loaded'))); const timeoutMillis = 1000; const timeout = new Promise(resolve => t.step_timeout(() => resolve('timeout'), timeoutMillis)); const result = await Promise.any([loaded, timeout]); assert_equals(result, 'timeout'); }, 'preload links only work when attached to the document'); </script> </body>