| <!DOCTYPE html> | |
| <title>Removing render-blocking element should unblock rendering</title> | |
| <link rel="help" href="https://html.spec.whatwg.org/C/#blocking-attribute"> | |
| <link rel="help" href="https://html.spec.whatwg.org/C/#rendering-opportunity"> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script src="support/test-render-blocking.js"></script> | |
| <!-- | |
| The test is marked "optional" because even when the document is no longer | |
| render-blocked, the user agent is still free to take other factors, which are | |
| not limited by the spec, into consideration and therefore decide not to | |
| render. However, it is still more desirable if rendering starts | |
| immediately/soon. | |
| --> | |
| <script class="test" data="parser-inserted async script" async blocking="render" | |
| src="support/dummy-1.js?pipe=trickle(d1)&async"></script> | |
| <script class="test" data="parser-inserted defer script" defer blocking="render" | |
| src="support/dummy-1.js?pipe=trickle(d1)&defer"></script> | |
| <script class="test" data="parser-inserted module script" type="module" | |
| blocking="render" src="support/dummy-1.mjs?pipe=trickle(d1)"></script> | |
| <script class="test" data="parser-inserted async module script" type="module" | |
| async blocking="render" src="support/dummy-1.mjs?pipe=trickle(d1)&async"></script> | |
| <!-- | |
| No test for parser-inserted stylesheets and synchronous scripts because | |
| they are script-blocking or even parser-blocking, and they do not have new | |
| behaviors to test about. | |
| --> | |
| <script> | |
| function addRenderBlockingElement(tag, title, attributes, optional_text) { | |
| let element = document.createElement(tag); | |
| element.className = 'test'; | |
| element.setAttribute('data', title); | |
| element.blocking = 'render'; | |
| Object.assign(element, attributes); | |
| if (optional_text) | |
| element.textContent = optional_text; | |
| document.head.appendChild(element); | |
| } | |
| addRenderBlockingElement( | |
| 'link', 'script-inserted stylesheet link', | |
| {rel: 'stylesheet', blocking: 'render', href: 'support/target-red.css?pipe=trickle(d1)&dynamic'}); | |
| addRenderBlockingElement( | |
| 'script', 'script-inserted script', | |
| {src: 'support/dummy-1.js?pipe=trickle(d1)&dynamic'}); | |
| addRenderBlockingElement( | |
| 'script', 'script-inserted module script', | |
| {type: 'module', src: 'support/dummy-1.mjs?pipe=trickle(d1)&dynamic'}); | |
| addRenderBlockingElement( | |
| 'style', 'script-inserted inline style', {}, | |
| '@import url("support/target-red.css?pipe=trickle(d1)&imported&dynamic")'); | |
| </script> | |
| <div id="dummy">Some text</div> | |
| <script> | |
| const testElements = [...document.querySelectorAll('.test')]; | |
| const loadObservers = testElements.map(element => new LoadObserver(element)); | |
| promise_setup(async () => { | |
| for (let element of testElements) | |
| element.remove(); | |
| // Test cases are run after rendering is unblocked. | |
| await new Promise(resolve => requestAnimationFrame(resolve)); | |
| }); | |
| for (let index = 0; index < testElements.length; ++index) { | |
| promise_test( | |
| async () => assert_false(loadObservers[index].finished), | |
| 'Render-blocking on ' + testElements[index].getAttribute('data') + ' is cancellable'); | |
| // The loading can either continue or cancel. This test does not assert it. | |
| loadObservers[index].load.catch(() => {}); | |
| } | |
| </script> | |