<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title>This test validates the render blocking status of resources.</title>
<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#sec-performanceresourcetiming"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<!-- Start of test cases -->
<script>
    // Dynamic style using document.write in head
    document.write(`
        <link rel=stylesheet
              href='resources/empty_style.css?stylesheet-head-dynamic-docWrite'>
    `);
    document.write(`
        <link rel=stylesheet
              href='resources/empty_style.css?stylesheet-head-dynamic-docWrite-print'
              media=print>
    `);
</script>

<link rel=stylesheet href="resources/empty_style.css?stylesheet-head">
<link rel=stylesheet href="resources/empty_style.css?stylesheet-head-media-print"
      media=print>
<link rel="alternate stylesheet"
      href="resources/empty_style.css?stylesheet-head-alternate">
<link rel=preload as=style href="resources/empty_style.css?link-style-head-preload">
<link rel=preload as=style href="resources/empty_style.css?link-style-preload-used">
<link rel=stylesheet href="resources/importer.css?stylesheet-importer-head">
<link rel=stylesheet id="link-head-remove-attr" blocking="render"
    href="resources/empty_style.css?stylesheet-head-blocking-render-remove-attr">
<link rel=modulepreload href="resources/empty_script.js?link-head-modulepreload">

<style>@import url(resources/empty_style.css?stylesheet-inline-imported);</style>
<style media=print>
    @import url(resources/empty_style.css?stylesheet-inline-imported-print);
</style>
</head>

<body>

<link rel=stylesheet href="resources/empty_style.css?stylesheet-body">
<link rel=stylesheet href="resources/importer.css?stylesheet-importer-body">
<link rel=stylesheet href="resources/empty_style.css?stylesheet-body-media-print"
      media=print>
<link rel=stylesheet blocking="render"
    href="resources/empty_style.css?stylesheet-body-blocking-render">

<!-- https://html.spec.whatwg.org/multipage/urls-and-fetching.html#blocking-attributes
     mentions that an element is potentially render-blocking if its blocking
     tokens set contains "render", or if it is implicitly potentially
     render-blocking. By default, an element is not implicitly potentially
     render-blocking.
     https://html.spec.whatwg.org/multipage/links.html#link-type-stylesheet
     specifies that a link element of type stylesheet is implicitly potentially
     render-blocking only if the element was created by its node document's parser. -->
<script>
    // Dynamic style using document.write in body
    document.write(`
        <link rel=stylesheet
              href='resources/empty_style.css?stylesheet-body-dynamic-docWrite'>
    `);
    document.write(`
        <link rel=stylesheet
              href='resources/empty_style.css?stylesheet-body-dynamic-docWrite-print'
              media=print>
    `);

    // Dynamic style using innerHTML
    document.head.innerHTML += `
        <link rel=stylesheet
              href='resources/empty_style.css?stylesheet-head-dynamic-innerHTML'>
    `;
    document.head.innerHTML += `
        <link rel=stylesheet
              href='resources/empty_style.css?stylesheet-head-dynamic-innerHTML-print'
              media=print>
    `;
    document.head.innerHTML += `
        <link rel=stylesheet blocking=render
              href='resources/empty_style.css?stylesheet-head-blocking-render-dynamic-innerHTML'>
    `;

    // Dynamic style using DOM API
    var link = document.createElement("link");
    link.href = "resources/empty_style.css?stylesheet-head-dynamic-dom";
    link.rel = "stylesheet";
    document.head.appendChild(link);

    // Add a dynamic render-blocking style with DOM API
    link = document.createElement("link");
    link.href = "resources/empty_style.css?stylesheet-head-blocking-render-dynamic-dom";
    link.rel = "stylesheet";
    link.blocking = "render";
    document.head.appendChild(link);

    // Dynamic style preload using DOM API
    link = document.createElement("link");
    link.href = "resources/empty_style.css?link-style-head-preload-dynamic-dom";
    link.rel = "preload";
    link.as = "style";
    document.head.appendChild(link);

    // Dynamic module via modulepreload using DOM API
    link = document.createElement("link");
    link.href = "resources/empty_script.js?link-head-modulepreload-dynamic-dom";
    link.rel = "modulepreload";
    document.head.appendChild(link);

    // Add a style preload with DOM API to be used later
    link = document.createElement("link");
    link.href = "resources/empty_style.css?link-style-preload-used-dynamic";
    link.rel = "preload";
    link.as = "style";
    document.head.appendChild(link);
    // Use the preload
    link = document.createElement("link");
    link.href = "resources/empty_style.css?link-style-preload-used-dynamic";
    link.rel = "stylesheet";
    document.head.appendChild(link);

    // Dynamic inline CSS
    // Add an inline CSS importer
    document.write(`
        <style>
            @import url('resources/empty_style.css?stylesheet-inline-imported-dynamic-docwrite')
        </style>
    `);
    document.write(`
        <style media=print>
            @import url('resources/empty_style.css?stylesheet-inline-imported-dynamic-docwrite-print')
        </style>
    `);

    // Add a dynamic inline CSS importer using DOM API
    let style = document.createElement("style");
    style.textContent = "@import url('resources/empty_style.css?stylesheet-inline-imported-dynamic-dom')";
    document.head.appendChild(style);

    // Add a dynamic render-blocking inline CSS importer
    style = document.createElement("style");
    style.textContent = "@import url('resources/empty_style.css?stylesheet-inline-imported-blocking-render-dynamic-dom')";
    style.blocking = "render";
    document.head.appendChild(style);

    // Dynamic CSS importer
    document.write(`
        <link rel=stylesheet href='resources/importer_dynamic.css'>
    `);
    document.write(`
        <link rel=stylesheet href='resources/importer_print.css' media=print>
    `);

    // Removing blocking render attribute after request is made
    const sheet = document.getElementById("link-head-remove-attr");
    sheet.blocking = "";
</script>

<link rel=stylesheet href="resources/empty_style.css?link-style-preload-used">

<script>

const wait_for_onload = () => {
  return new Promise(resolve => {
    window.addEventListener("load", resolve);
})};

promise_test(
  async () => {
    const expectedRenderBlockingStatus = {
        'stylesheet-head-dynamic-docWrite': 'blocking',
        'stylesheet-head-dynamic-docWrite-print': 'non-blocking',
        'stylesheet-head': 'blocking',
        'stylesheet-head-media-print' : 'non-blocking',
        'stylesheet-head-alternate' : 'non-blocking',
        'link-style-head-preload' : 'non-blocking',
        'stylesheet-importer-head' : 'blocking',
        'stylesheet-head-blocking-render-remove-attr' : 'blocking',
        'link-head-modulepreload' : 'non-blocking',
        'stylesheet-inline-imported' : 'blocking',
        'stylesheet-inline-imported-print' : 'non-blocking',
        'stylesheet-body': 'non-blocking',
        'stylesheet-importer-body' : 'non-blocking',
        'stylesheet-body-media-print' : 'non-blocking',
        'stylesheet-body-blocking-render' : 'non-blocking',
        'stylesheet-body-dynamic-docWrite' : 'non-blocking',
        'stylesheet-body-dynamic-docWrite-print': 'non-blocking',
        'stylesheet-head-dynamic-innerHTML' : 'non-blocking',
        'stylesheet-head-dynamic-innerHTML-print' : 'non-blocking',
        'stylesheet-head-blocking-render-dynamic-innerHTML' : 'blocking',
        'stylesheet-head-dynamic-dom' : 'non-blocking',
        'stylesheet-head-blocking-render-dynamic-dom' : 'blocking',
        'link-style-head-preload-dynamic-dom' : 'non-blocking',
        'link-head-modulepreload-dynamic-dom' : 'non-blocking',
        'link-style-preload-used' : 'non-blocking',
        'link-style-preload-used-dynamic' : 'non-blocking',
        'stylesheet-inline-imported-dynamic-docwrite': 'blocking',
        'stylesheet-inline-imported-dynamic-docwrite-print' : 'non-blocking',
        'stylesheet-inline-imported-dynamic-dom' : 'non-blocking',
        'stylesheet-inline-imported-blocking-render-dynamic-dom' : 'blocking',
        'stylesheet-imported' : 'blocking',
        'stylesheet-imported-print' : 'non-blocking',
        'stylesheet-imported-dynamic' : 'non-blocking'
    };

    await wait_for_onload();

    const entry_list = performance.getEntriesByType("resource");
    for (entry of entry_list) {
        if (entry.name.includes("empty_style.css") ||
                entry.name.includes("importer.css") ||
                entry.name.includes("empty_script.js")) {
            key = entry.name.split("?").pop();
            expectedStatus = expectedRenderBlockingStatus[key];
            assert_equals(entry.renderBlockingStatus, expectedStatus,
                `render blocking status for ${entry.name} should be ${expectedStatus}`);
        }
    }
}, "Validate render blocking status of link resources in PerformanceResourceTiming");

</script>