| <!DOCTYPE html> | |
| <title>CSSStyleSheet Disallow Import Rules</title> | |
| <link rel="author" title="Erik Nordin" href="mailto:enordin@mozilla.com"> | |
| <link rel="help" href="https://github.com/WICG/construct-stylesheets/issues/119#issuecomment-597733392"> | |
| <div id="target"></div> | |
| <script src='/resources/testharness.js'></script> | |
| <script src='/resources/testharnessreport.js'></script> | |
| <script> | |
| const greenStyleText = ".green { color: green; }"; | |
| const import_text = '@import url("support/constructable-import.css");'; | |
| function attachShadowDiv(host) { | |
| const shadowRoot = host.attachShadow({mode: 'open'}); | |
| const shadowDiv = document.createElement("div"); | |
| shadowRoot.appendChild(shadowDiv); | |
| return shadowDiv; | |
| } | |
| test(() => { | |
| assert_throws_dom("SyntaxError", () => { (new CSSStyleSheet).insertRule(import_text) }); | |
| }, 'Inserting an @import rule through insertRule on a constructed stylesheet throws an exception'); | |
| promise_test(async t => { | |
| const importUrl = "support/constructable-import.css"; | |
| const sheet = new CSSStyleSheet(); | |
| sheet.replaceSync(import_text); | |
| await sheet.replace(import_text); | |
| assert_throws_dom("SyntaxError", () => { sheet.insertRule(import_text) }); | |
| const timeAfterImportsInvoked = performance.now(); | |
| let link = document.createElement("link"); | |
| t.add_cleanup(() => { link.remove(); }); | |
| link.rel = "stylesheet"; | |
| link.href = importUrl; | |
| await new Promise((resolve, reject) => { | |
| link.addEventListener("load", resolve); | |
| link.addEventListener("error", reject); | |
| document.body.appendChild(link); | |
| }); | |
| let entries = window.performance.getEntriesByType('resource').filter(entry => entry.name.includes(importUrl)); | |
| assert_equals(entries.length, 1, "There should be only one entry for the import URL"); | |
| assert_greater_than_equal(entries[0].startTime, timeAfterImportsInvoked, "The entry's start time should be after all throws"); | |
| }, "@import rules should not trigger any loads.") | |
| promise_test(() => { | |
| const span = document.createElement("span"); | |
| target.appendChild(span); | |
| const shadowDiv = attachShadowDiv(span); | |
| shadowDiv.classList.add("green"); | |
| const sheet = new CSSStyleSheet(); | |
| span.shadowRoot.adoptedStyleSheets = [sheet]; | |
| assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)"); | |
| const sheet_promise = sheet.replace(`${import_text} ${greenStyleText}`); | |
| return sheet_promise.then((sheet) => { | |
| assert_equals(sheet.cssRules.length, 1); | |
| assert_equals(sheet.cssRules[0].cssText, greenStyleText); | |
| assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 128, 0)"); | |
| }).catch((reason) => { | |
| assert_unreached(`Promise was rejected (${reason}) when it should have been resolved`); | |
| }); | |
| }, '@import rules are not parsed in CSSStyleSheet.replace'); | |
| test(() => { | |
| const span = document.createElement("span"); | |
| target.appendChild(span); | |
| const shadowDiv = attachShadowDiv(span); | |
| shadowDiv.classList.add("green"); | |
| const sheet = new CSSStyleSheet(); | |
| span.shadowRoot.adoptedStyleSheets = [sheet]; | |
| assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)"); | |
| // Replace and assert that the imported rule is applied. | |
| const sheet_promise = sheet.replaceSync(`${import_text} ${greenStyleText}`); | |
| assert_equals(sheet.cssRules.length, 1); | |
| assert_equals(sheet.cssRules[0].cssText, greenStyleText); | |
| assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 128, 0)"); | |
| }, '@import rules are not parsed in CSSStyleSheet.replaceSync'); | |
| </script> |