Skip to content

Commit

Permalink
[renderblocking] Don't cancel implicit render-blocking when blocking …
Browse files Browse the repository at this point in the history
…attribute is removed

1. This patch adds tests for whatwg/html#7857.
   When `blocking=render` is removed, if the element is implicitly
   render-blocking, we shouldn't unblock rendering for it.

2. This patch fixes how <link> element respond to `blocking` attribute
   changes. Previously, the element simply reprocesses (cancel and then
   restart) on every `blocking` attribute change, causing unnecessary
   work and also some bugs on stylesheets. This patch changes that into
   unblock rendering if needed to match the spec.

Bug: 1271296
Change-Id: I54a2f33dc1ed9971eaeceeb677a165d598d5d4d1
  • Loading branch information
xiaochengh authored and chromium-wpt-export-bot committed Apr 27, 2022
1 parent 71f67d1 commit ccb8ffa
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<title>Synchronous script element still blocks rendering after removing `blocking=render`</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/test-render-blocking.js"></script>

<script>
// Test script must be added before the synchronous script because the
// synchronous script is parser-blocking.

promise_setup(async () => {
let script = await nodeInserted(document.head, node => node.id === 'script');
script.blocking = '';

// Also inserts some contents for non-compliant UA to render
document.body = document.createElement('body');
document.body.appendChild(document.createTextNode('Some text'));
});

test_render_blocking(
() => assert_equals(window.dummy, 1),
'Render-blocking script is loaded and evaluated');
</script>

<script id="script" blocking="render" src="support/dummy-1.js?pipe=trickle(d1)"></script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<title>Parser-inserted style element still blocks rendering after removing `blocking=render`</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/test-render-blocking.js"></script>

<script>
// Test script must be added before the style element because the style
// element is script-blocking.

promise_setup(async () => {
let sheet = await nodeInserted(document.head, node => node.id === 'sheet');
sheet.blocking = '';
});

test_render_blocking(
() => {
let color = getComputedStyle(document.querySelector('.target')).color;
assert_equals(color, 'rgb(255, 0, 0)');
},
'Render-blocking stylesheet is applied');
</script>

<style id="sheet" blocking="render">
@import url("support/target-red.css?pipe=trickle(d1)");
</style>

<div class="target">Some text</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<title>Parser-inserted stylesheet link still blocks rendering after removing `blocking=render`</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/test-render-blocking.js"></script>

<script>
// Test script must be added before the stylesheet link because the stylesheet
// link is script-blocking.

promise_setup(async () => {
let sheet = await nodeInserted(document.head, node => node.id === 'sheet');
sheet.blocking = '';
});

test_render_blocking(
() => {
let color = getComputedStyle(document.querySelector('.target')).color;
assert_equals(color, 'rgb(255, 0, 0)');
},
'Render-blocking stylesheet is applied');
</script>

<link id="sheet" rel="stylesheet" blocking="render"
href="support/target-red.css?pipe=trickle(d1)">

<div class="target">Some text</div>
16 changes: 16 additions & 0 deletions html/dom/render-blocking/support/test-render-blocking.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ class LoadObserver {
}
}

// Observes the insertion of a script/parser-blocking element into DOM via
// MutationObserver, so that we can access the element before it's loaded.
function nodeInserted(parentNode, predicate) {
return new Promise(resolve => {
function callback(mutationList) {
for (let mutation of mutationList) {
for (let node of mutation.addedNodes) {
if (predicate(node))
resolve(node);
}
}
}
new MutationObserver(callback).observe(parentNode, {childList: true});
});
}

function createAutofocusTarget() {
const autofocusTarget = document.createElement('textarea');
autofocusTarget.setAttribute('autofocus', '');
Expand Down

0 comments on commit ccb8ffa

Please sign in to comment.