[renderblocking] Dynamically inserted render-blocking stylesheets should not block scripts

This patch fixes a bug that adding `blocking=render` to script-inserted
stylesheets makes them script-blocking, which violates the spec as only
parser-inserted stylesheets can be script-blocking [1].

The fix idea is to add a new enum to PendingSheetType to represent
dynamic render-blocking sheets, so that we only block rendering but not
scripts or parser for this type.

This patch is also a preparation patch to allow unblocking rendering on
dynamic stylesheets by removing `blocking=render` [2]

[1] https://html.spec.whatwg.org/#contributes-a-script-blocking-style-sheet
[2] crrev.com/c/3601726

Bug: 1271296
Change-Id: I6eee34357ab034c802b3b022719427a1b3964c19
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3601502
Reviewed-by: Yoav Weiss <yoavweiss@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/main@{#995849}
diff --git a/html/semantics/document-metadata/interactions-of-styling-and-scripting/dynamic-render-blocking-link-stylesheet-does-not-block-script.html b/html/semantics/document-metadata/interactions-of-styling-and-scripting/dynamic-render-blocking-link-stylesheet-does-not-block-script.html
new file mode 100644
index 0000000..bcc9805
--- /dev/null
+++ b/html/semantics/document-metadata/interactions-of-styling-and-scripting/dynamic-render-blocking-link-stylesheet-does-not-block-script.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<title>Script-created render-blocking link stylesheet is not script-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<script>
+const link = document.createElement('link');
+link.rel = 'stylesheet';
+link.href = 'stylesheet.py?delay=1';
+link.blocking = 'render';
+document.head.appendChild(link);
+</script>
+<h1>Some text</h1>
+<script>
+test(() => {
+  assert_false(styleExists("h1 { color: purple; }"),
+               'stylesheet should still be pending');
+  const h1 = document.querySelector('h1');
+  assert_equals(getComputedStyle(h1).color, 'rgb(0, 0, 0)');
+});
+</script>
diff --git a/html/semantics/document-metadata/interactions-of-styling-and-scripting/dynamic-render-blocking-style-element-does-not-block-script.html b/html/semantics/document-metadata/interactions-of-styling-and-scripting/dynamic-render-blocking-style-element-does-not-block-script.html
new file mode 100644
index 0000000..9a8c4b4
--- /dev/null
+++ b/html/semantics/document-metadata/interactions-of-styling-and-scripting/dynamic-render-blocking-style-element-does-not-block-script.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<title>Script-created render-blocking style element is not script-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<script>
+const style = document.createElement('style');
+const sheet = document.createTextNode('@import url(stylesheet.py?delay=1);');
+style.appendChild(sheet);
+style.blocking = 'render';
+document.head.appendChild(style);
+</script>
+<h1>Some text</h1>
+<script>
+test(() => {
+  assert_false(styleExists("h1 { color: purple; }"),
+               'stylesheet should still be pending');
+  const h1 = document.querySelector('h1');
+  assert_equals(getComputedStyle(h1).color, 'rgb(0, 0, 0)');
+});
+</script>