| <!DOCTYPE html> |
| <title>CSSStyleSheet constructor and adoptedStyleSheets</title> |
| <link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> |
| <link rel="help" href="https://wicg.github.io/construct-stylesheets/"> |
| <script src = '/resources/testharness.js'></script> |
| <script src = '/resources/testharnessreport.js'></script> |
| |
| <section id="firstSection"> |
| <div> |
| <span class="green"></span> |
| <span class="red"></span> |
| <span class="blue"></span> |
| <span class="white"></span> |
| <span class="yellow"></span> |
| </div> |
| </section> |
| <section id="secondSection"></section> |
| <section id="thirdSection"></section> |
| |
| <script> |
| 'use strict'; |
| const greenStyleText = ".green { color: green; }"; |
| const redStyleTexts = [".red { color: red; }", ".red + span + span { color: red; }"]; |
| const blueStyleTexts = [".blue { color: blue; }", ".blue + span + span { color: blue; }"]; |
| const whiteStyleText = "* { color: white; }"; |
| const yellowStyleText = ".yellow { color: yellow; }"; |
| |
| const firstDiv = document.querySelector('#firstSection > div'); |
| const secondDiv = firstDiv.cloneNode(true); |
| const shadowRoot = document.querySelector('#secondSection').attachShadow({mode: 'open'}); |
| shadowRoot.appendChild(secondDiv); |
| |
| const greenSpan = firstDiv.children[0]; |
| const redSpan = firstDiv.children[1]; |
| const blueSpan = firstDiv.children[2]; |
| const whiteSpan = firstDiv.children[3]; |
| const yellowSpan = firstDiv.children[4]; |
| const greenShadowSpan = secondDiv.children[0]; |
| const redShadowSpan = secondDiv.children[1]; |
| const blueShadowSpan = secondDiv.children[2]; |
| const whiteShadowSpan = secondDiv.children[3]; |
| const yellowShadowSpan = secondDiv.children[4]; |
| |
| test(() => { |
| assert_equals(document.adoptedStyleSheets.length, 0); |
| }, "document.adoptedStyleSheets should initially have length 0."); |
| |
| test(() => { |
| const sheet = new CSSStyleSheet({title: "Red", disabled: true, media: "screen, print"}); |
| assert_equals(sheet.title, "Red"); |
| assert_equals(sheet.ownerNode, null); |
| assert_equals(sheet.ownerRule, null); |
| assert_equals(sheet.media.length, 2); |
| assert_equals(sheet.media.item(0), "screen"); |
| assert_equals(sheet.media.item(1), "print"); |
| assert_true(sheet.disabled); |
| assert_equals(sheet.cssRules.length, 0); |
| |
| sheet.insertRule(redStyleTexts[0]); |
| assert_equals(sheet.cssRules.length, 1); |
| assert_equals(sheet.cssRules[0].cssText, redStyleTexts[0]); |
| |
| sheet.insertRule(redStyleTexts[1]); |
| assert_equals(sheet.cssRules.length, 2); |
| assert_equals(sheet.cssRules[0].cssText, redStyleTexts[1]); |
| |
| const sheet2 = new CSSStyleSheet({}); |
| assert_equals(sheet2.title, "") |
| assert_equals(sheet2.ownerNode, null); |
| assert_equals(sheet2.ownerRule, null); |
| assert_equals(sheet2.media.length, 0); |
| assert_false(sheet2.disabled); |
| assert_equals(sheet2.cssRules.length, 0); |
| |
| sheet2.insertRule(redStyleTexts[1]); |
| assert_equals(sheet2.cssRules.length, 1); |
| assert_equals(sheet2.cssRules[0].cssText, redStyleTexts[1]); |
| |
| sheet2.deleteRule(0); |
| assert_equals(sheet2.cssRules.length, 0); |
| |
| const sheet3 = new CSSStyleSheet(); |
| assert_equals(sheet3.title, "") |
| assert_equals(sheet3.ownerNode, null); |
| assert_equals(sheet3.ownerRule, null); |
| assert_equals(sheet3.media.length, 0); |
| assert_false(sheet3.disabled); |
| assert_equals(sheet3.cssRules.length, 0); |
| |
| sheet3.insertRule(redStyleTexts[1]); |
| assert_equals(sheet3.cssRules.length, 1); |
| assert_equals(sheet3.cssRules[0].cssText, redStyleTexts[1]); |
| |
| sheet3.deleteRule(0); |
| assert_equals(sheet3.cssRules.length, 0); |
| }, 'new CSSStyleSheet produces empty CSSStyleSheet'); |
| |
| promise_test(() => { |
| const sheet = new CSSStyleSheet({title: "Red", disabled: true, media: "screen, print"}); |
| const promise_sheet = sheet.replace(redStyleTexts[0]); |
| return promise_sheet.then(function(sheet) { |
| assert_equals(sheet.title, "Red"); |
| assert_equals(sheet.ownerNode, null); |
| assert_equals(sheet.ownerRule, null); |
| assert_equals(sheet.media.length, 2); |
| assert_equals(sheet.media.item(0), "screen"); |
| assert_equals(sheet.media.item(1), "print"); |
| assert_true(sheet.disabled); |
| assert_equals(sheet.cssRules.length, 1); |
| assert_equals(sheet.cssRules[0].cssText, redStyleTexts[0]); |
| |
| sheet.insertRule(redStyleTexts[1]); |
| assert_equals(sheet.cssRules.length, 2); |
| assert_equals(sheet.cssRules[0].cssText, redStyleTexts[1]); |
| }); |
| }, 'CSSStyleSheet.replace produces Promise<CSSStyleSheet>'); |
| |
| function createAllSheetsPromise() { |
| const greenSheet = new CSSStyleSheet(); |
| const redSheet = new CSSStyleSheet({media: "screen, print"}); |
| const blueSheet = new CSSStyleSheet({title: "Blue", disabled: true}); |
| const whiteSheet = new CSSStyleSheet({title: "White", alternate: true}); |
| const yellowSheet = new CSSStyleSheet({disabled: false}); |
| |
| const greenPromise = greenSheet.replace(greenStyleText); |
| const redPromise = redSheet.replace(redStyleTexts[0] + redStyleTexts[1]); |
| const bluePromise = blueSheet.replace(blueStyleTexts[0] + blueStyleTexts[1]); |
| const whitePromise = whiteSheet.replace(whiteStyleText); |
| const yellowPromise = yellowSheet.replace(yellowStyleText); |
| return [greenPromise, redPromise, bluePromise, whitePromise, yellowPromise]; |
| } |
| |
| promise_test(() => { |
| return Promise.all(createAllSheetsPromise()).then(values => { |
| const greenStyleSheet = values[0]; |
| const redStyleSheet = values[1]; |
| const blueStyleSheet = values[2]; |
| const whiteStyleSheet = values[3]; |
| const yellowStyleSheet = values[4]; |
| |
| // Lists of style sheets can be created, assigned and read. |
| document.adoptedStyleSheets = [whiteStyleSheet]; |
| // alternate stylesheets aren't applied when title != current preferable name |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(0, 0, 0)"); |
| |
| document.adoptedStyleSheets = [greenStyleSheet, blueStyleSheet]; |
| // disabled stylesheets aren't applied |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 128, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(0, 0, 0)"); |
| |
| document.adoptedStyleSheets = [redStyleSheet, yellowStyleSheet]; |
| |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(255, 255, 0)"); |
| |
| document.adoptedStyleSheets = [redStyleSheet, yellowStyleSheet, greenStyleSheet, blueStyleSheet]; |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 128, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(255, 255, 0)"); |
| }); |
| }, 'Constructed style sheets can be applied on document'); |
| |
| promise_test(() => { |
| return Promise.all(createAllSheetsPromise()).then(values => { |
| const greenStyleSheet = values[0]; |
| const redStyleSheet = values[1]; |
| const blueStyleSheet = values[2]; |
| const whiteStyleSheet = values[3]; |
| const yellowStyleSheet = values[4]; |
| shadowRoot.adoptedStyleSheets = [whiteStyleSheet]; |
| assert_equals(getComputedStyle(greenShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(blueShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowShadowSpan).color, "rgb(0, 0, 0)"); |
| |
| shadowRoot.adoptedStyleSheets = [greenStyleSheet, blueStyleSheet]; |
| assert_equals(getComputedStyle(greenShadowSpan).color, "rgb(0, 128, 0)"); |
| assert_equals(getComputedStyle(redShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(blueShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowShadowSpan).color, "rgb(0, 0, 0)"); |
| |
| shadowRoot.adoptedStyleSheets = [redStyleSheet, yellowStyleSheet]; |
| assert_equals(getComputedStyle(greenShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redShadowSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteShadowSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(yellowShadowSpan).color, "rgb(255, 255, 0)"); |
| |
| shadowRoot.adoptedStyleSheets = [redStyleSheet, yellowStyleSheet, greenStyleSheet, blueStyleSheet]; |
| assert_equals(getComputedStyle(greenShadowSpan).color, "rgb(0, 128, 0)"); |
| assert_equals(getComputedStyle(redShadowSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteShadowSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(yellowShadowSpan).color, "rgb(255, 255, 0)"); |
| }); |
| }, 'Constructed style sheets can be applied on shadow root'); |
| |
| promise_test(() => { |
| const plainSheet = new CSSStyleSheet(); |
| const redStyleSheetPromise = plainSheet.replace(redStyleTexts[0]); |
| return redStyleSheetPromise.then(function(redStyleSheet) { |
| document.adoptedStyleSheets = [redStyleSheet]; |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(0, 0, 0)"); |
| |
| redStyleSheet.insertRule(redStyleTexts[1]); |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(0, 0, 0)"); |
| |
| redStyleSheet.deleteRule(1); |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(0, 0, 0)"); |
| |
| redStyleSheet.cssRules[0].style.color = "white"; |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(255, 255, 255)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(0, 0, 0)"); |
| }); |
| }, 'Changes to constructed stylesheets through CSSOM is reflected'); |
| |
| promise_test(() => { |
| const plainSheet = new CSSStyleSheet(); |
| const redStyleSheetPromise = plainSheet.replace(redStyleTexts[0]); |
| return redStyleSheetPromise.then(function(redStyleSheet) { |
| document.adoptedStyleSheets = [redStyleSheet]; |
| shadowRoot.adoptedStyleSheets = [redStyleSheet]; |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(0, 0, 0)"); |
| |
| assert_equals(getComputedStyle(greenShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redShadowSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowShadowSpan).color, "rgb(0, 0, 0)"); |
| |
| shadowRoot.adoptedStyleSheets[0].insertRule(redStyleTexts[1]); |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(0, 0, 0)"); |
| |
| assert_equals(getComputedStyle(greenShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redShadowSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueShadowSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteShadowSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(yellowShadowSpan).color, "rgb(0, 0, 0)"); |
| }); |
| }, 'Constructed stylesheet can be used and modified in multiple TreeScopes'); |
| |
| promise_test(() => { |
| const iframe = document.createElement("iframe"); |
| document.body.appendChild(iframe); |
| const thirdDiv = firstDiv.cloneNode(true); |
| iframe.contentDocument.body.appendChild(thirdDiv); |
| const greenIframeSpan = thirdDiv.children[0]; |
| const redIframeSpan = thirdDiv.children[1]; |
| const blueIframeSpan = thirdDiv.children[2]; |
| const whiteIframeSpan = thirdDiv.children[3]; |
| const yellowIframeSpan = thirdDiv.children[4]; |
| |
| const plainSheet = new CSSStyleSheet(); |
| const redStyleSheetPromise = plainSheet.replace(redStyleTexts[0]); |
| return redStyleSheetPromise.then(function(redStyleSheet) { |
| assert_throws('NotAllowedError', () => { iframe.contentDocument.adoptedStyleSheets = [redStyleSheet]; }); |
| assert_equals(getComputedStyle(greenIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(blueIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowIframeSpan).color, "rgb(0, 0, 0)"); |
| |
| document.adoptedStyleSheets = [redStyleSheet]; |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(0, 0, 0)"); |
| |
| document.adoptedStyleSheets[0].insertRule(redStyleTexts[1]); |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(0, 0, 0)"); |
| }); |
| }, 'Stylesheets constructed on the main Document cannot be used in iframes'); |
| |
| promise_test(() => { |
| const iframe = document.createElement("iframe"); |
| document.body.appendChild(iframe); |
| const thirdDiv = firstDiv.cloneNode(true); |
| iframe.contentDocument.body.appendChild(thirdDiv); |
| const greenIframeSpan = thirdDiv.children[0]; |
| const redIframeSpan = thirdDiv.children[1]; |
| const blueIframeSpan = thirdDiv.children[2]; |
| const whiteIframeSpan = thirdDiv.children[3]; |
| const yellowIframeSpan = thirdDiv.children[4]; |
| |
| // Make sure both the main Document and the iframe are not styled |
| const emptyStyleSheet = new CSSStyleSheet(); |
| document.adoptedStyleSheets = [emptyStyleSheet]; |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(0, 0, 0)"); |
| |
| assert_equals(getComputedStyle(greenIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(blueIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowIframeSpan).color, "rgb(0, 0, 0)"); |
| |
| const iframePlainSheet = new iframe.contentWindow.CSSStyleSheet(); |
| const iframeRedStyleSheetPromise = iframePlainSheet.replace(redStyleTexts[0]); |
| return iframeRedStyleSheetPromise.then(function(iframeRedStyleSheet) { |
| assert_throws('NotAllowedError', () => { document.adoptedStyleSheets = [iframeRedStyleSheet]; }); |
| assert_equals(getComputedStyle(greenSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(blueSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowSpan).color, "rgb(0, 0, 0)"); |
| |
| iframe.contentDocument.adoptedStyleSheets = [iframeRedStyleSheet]; |
| assert_equals(getComputedStyle(greenIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redIframeSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(yellowIframeSpan).color, "rgb(0, 0, 0)"); |
| |
| iframe.contentDocument.adoptedStyleSheets[0].insertRule(redStyleTexts[1]); |
| assert_equals(getComputedStyle(greenIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(redIframeSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(blueIframeSpan).color, "rgb(0, 0, 0)"); |
| assert_equals(getComputedStyle(whiteIframeSpan).color, "rgb(255, 0, 0)"); |
| assert_equals(getComputedStyle(yellowIframeSpan).color, "rgb(0, 0, 0)"); |
| }); |
| }, 'Stylesheet constructed on iframe cannot be used in the main Document'); |
| </script> |
| |
| <div id="divNonConstructed" class="nonConstructed"> |
| </div> |
| |
| <script> |
| `use strict`; |
| const shadowRootNonConstructed = divNonConstructed.attachShadow({mode:'open'}) |
| nonConstructedStyle = document.createElement("style"); |
| shadowRootNonConstructed.appendChild(nonConstructedStyle); |
| nonConstructedStyle.sheet.insertRule(".nonConstructed { color: red; }", 0); |
| const nonConstructedStyleSheet = nonConstructedStyle.sheet; |
| |
| test(() => { |
| assert_equals(getComputedStyle(divNonConstructed).color, "rgb(0, 0, 0)"); |
| assert_throws('NotAllowedError', () => { document.adoptedStyleSheets = [nonConstructedStyleSheet]; }); |
| }, 'Adding non-constructed stylesheet to AdoptedStyleSheets is not allowed when the owner document of the stylesheet is in the same document tree as the AdoptedStyleSheets'); |
| |
| test(() => { |
| const iframe = document.createElement("iframe"); |
| document.body.appendChild(iframe); |
| iframeDiv = iframe.contentDocument.createElement("div"); |
| iframeDiv.classList.add("nonConstructed"); |
| iframe.contentDocument.body.appendChild(iframeDiv); |
| |
| assert_equals(getComputedStyle(iframeDiv).color, "rgb(0, 0, 0)"); |
| assert_throws('NotAllowedError', () => { iframe.contentDocument.adoptedStyleSheets = [nonConstructedStyleSheet]; }); |
| assert_equals(getComputedStyle(iframeDiv).color, "rgb(0, 0, 0)"); |
| |
| iframeStyle = iframe.contentDocument.createElement("style"); |
| iframe.contentDocument.body.appendChild(iframeStyle); |
| iframeStyle.sheet.insertRule(".nonConstructedSpan { color: red; }"); |
| const iframeStyleSheet = iframeStyle.sheet; |
| nonConstructedSpan = document.createElement("span"); |
| nonConstructedSpan.classList.add(".nonConstructedSpan"); |
| divNonConstructed.appendChild(nonConstructedSpan); |
| |
| assert_equals(getComputedStyle(iframeDiv).color, "rgb(0, 0, 0)"); |
| assert_throws('NotAllowedError', () => { document.adoptedStyleSheets = [iframeStyleSheet]; }); |
| assert_equals(getComputedStyle(iframeDiv).color, "rgb(0, 0, 0)"); |
| }, 'Adding non-constructed stylesheet to AdoptedStyleSheets is not allowed when the owner document of the stylesheet and the AdoptedStyleSheets are in different document trees'); |
| |
| function attachShadowDiv(host) { |
| const shadowRoot = host.attachShadow({mode: 'open'}); |
| const shadowDiv = document.createElement("div"); |
| shadowRoot.appendChild(shadowDiv); |
| return shadowDiv; |
| } |
| |
| test(() => { |
| // Attach a div inside a shadow root with the class ".red". |
| const span = document.createElement("span"); |
| thirdSection.appendChild(span); |
| const shadowDiv = attachShadowDiv(span); |
| shadowDiv.classList.add("red"); |
| // Create empty stylesheet. |
| const sheet = new CSSStyleSheet(); |
| span.shadowRoot.adoptedStyleSheets = [sheet]; |
| assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)"); |
| // Replace the stylesheet text that will color it red. |
| sheet.replaceSync(redStyleTexts[0]); |
| assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)"); |
| assert_equals(sheet.cssRules.length, 1); |
| assert_equals(sheet.cssRules[0].cssText, redStyleTexts[0]); |
| sheet.insertRule(redStyleTexts[1]); |
| assert_equals(sheet.cssRules.length, 2); |
| assert_equals(sheet.cssRules[0].cssText, redStyleTexts[1]); |
| }, 'CSSStyleSheet.replaceSync replaces stylesheet text synchronously'); |
| |
| const import_text = '@import url("support/constructable-import.css");'; |
| |
| test(() => { |
| assert_throws("NotAllowedError", () => { (new CSSStyleSheet).replaceSync(import_text) }); |
| }, 'CSSStyleSheet.replaceSync throws exception when there is import rule inside'); |
| |
| test(() => { |
| assert_throws("NotAllowedError", () => { (new CSSStyleSheet).insertRule(import_text) }); |
| }, 'Inserting an @import rule through insertRule on a constructed stylesheet throws an exception'); |
| |
| promise_test(() => { |
| const span = document.createElement("span"); |
| thirdSection.appendChild(span); |
| const shadowDiv = attachShadowDiv(span); |
| 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.replace(import_text); |
| return sheet_promise.then((sheet) => { |
| assert_equals(sheet.cssRules.length, 1); |
| assert_equals(sheet.cssRules[0].cssText, import_text); |
| assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)"); |
| }); |
| }, 'CSSStyleSheet.replace allows import rule inside'); |
| |
| promise_test(() => { |
| const sheet = new CSSStyleSheet(); |
| const sheet_promise = sheet.replace("import url('not-there.css');"); |
| return sheet_promise.catch((reason) => { |
| assert_equals(reason.name, "NotAllowedError"); |
| }); |
| }, 'CSSStyleSheet.replace returns rejected promise on failed imports'); |
| |
| test(() => { |
| const span = document.createElement("span"); |
| thirdSection.appendChild(span); |
| const shadowDiv = attachShadowDiv(span); |
| const sheet = new CSSStyleSheet(); |
| span.shadowRoot.adoptedStyleSheets = [sheet]; |
| |
| const newSpan = span.cloneNode(true); |
| assert_equals(newSpan.shadowRoot, null); |
| }, 'Cloning a shadow host will not clone shadow root, and also adoptedStyleSheets'); |
| |
| test(() => { |
| const span = document.createElement("span"); |
| thirdSection.appendChild(span); |
| const shadowDiv = attachShadowDiv(span); |
| const sheet = new CSSStyleSheet(); |
| span.shadowRoot.adoptedStyleSheets = [sheet]; |
| |
| const iframe = document.createElement("iframe"); |
| document.body.appendChild(iframe); |
| const newSpan = iframe.contentDocument.importNode(span, true); |
| iframe.contentDocument.body.appendChild(newSpan); |
| assert_equals(newSpan.shadowRoot, null); |
| }, 'Importing a shadow host will not copy shadow root, and also adoptedStyleSheets'); |
| |
| test(() => { |
| const span = document.createElement("span"); |
| thirdSection.appendChild(span); |
| const shadowDiv = attachShadowDiv(span); |
| const sheet = new CSSStyleSheet(); |
| sheet.replaceSync("* { color: red; }"); |
| span.shadowRoot.adoptedStyleSheets = [sheet]; |
| assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)"); |
| |
| document.adoptNode(span); |
| assert_equals(span.shadowRoot.adoptedStyleSheets.length, 1); |
| assert_equals(span.shadowRoot.adoptedStyleSheets[0], sheet); |
| |
| const iframe = document.createElement("iframe"); |
| document.body.appendChild(iframe); |
| iframe.contentDocument.adoptNode(span); |
| iframe.contentDocument.body.appendChild(span); |
| assert_not_equals(span.shadowRoot, null); |
| assert_equals(span.shadowRoot.adoptedStyleSheets.length, 0); |
| assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)"); |
| }, 'Adopting a shadow host will empty adoptedStyleSheets if adopting to a different document'); |
| |
| </script> |
| |