| <!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="shadowHost"></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 shadowHost = document.querySelector('#shadowHost'); | 
 | const shadowRoot = shadowHost.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({disabled: true, media: "screen, print"}); | 
 |   assert_equals(sheet.title, null, "The title attribute must return the title or null if title is the empty string"); | 
 |   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, null, "The title attribute must return the title or null if title is the empty string"); | 
 |   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, null, "The title attribute must return the title or null if title is the empty string"); | 
 |   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'); | 
 |  | 
 | test(() => { | 
 |   const sheet = new CSSStyleSheet({title: "something"}); | 
 |   assert_equals(sheet.title, null, "title and alternate are not supported by the constructor. https://github.com/WICG/construct-stylesheets/issues/105"); | 
 | }, "title can be set in the CSSStyleSheet constructor"); | 
 |  | 
 | promise_test(() => { | 
 |   const sheet = new CSSStyleSheet({disabled: true, media: "screen, print"}); | 
 |   const promise_sheet = sheet.replace(redStyleTexts[0]); | 
 |   return promise_sheet.then(function(sheet) { | 
 |     assert_equals(sheet.title, null, "The title attribute must return the title or null if title is the empty string"); | 
 |     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({disabled: true}); | 
 |   const whiteSheet = new CSSStyleSheet({disabled: 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. | 
 |  | 
 |     // disabled stylesheets aren't applied | 
 |     document.adoptedStyleSheets = [whiteStyleSheet]; | 
 |     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)"); | 
 |  | 
 |     // disable dsheets don't block other styles from applying | 
 |     document.adoptedStyleSheets = [greenStyleSheet, blueStyleSheet]; | 
 |     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)"); | 
 |     document.adoptedStyleSheets = []; | 
 |   }); | 
 | }, '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(() => { | 
 |   return Promise.all(createAllSheetsPromise()).then(values => { | 
 |     const greenStyleSheet = values[0]; | 
 |     const redStyleSheet = values[1]; | 
 |     shadowRoot.adoptedStyleSheets = [greenStyleSheet]; | 
 |     assert_equals(getComputedStyle(greenShadowSpan).color, "rgb(0, 128, 0)", "Style applies connected"); | 
 |     assert_equals(getComputedStyle(redShadowSpan).color, "rgb(0, 0, 0)", "Style applies when connected"); | 
 |     let hostParent = shadowHost.parentNode; | 
 |     hostParent.removeChild(shadowHost); | 
 |     assert_equals(getComputedStyle(greenShadowSpan).color, "", "Style doesn't apply when detached"); | 
 |     assert_equals(getComputedStyle(redShadowSpan).color, "", "Style doesn't apply when detached"); | 
 |     shadowRoot.adoptedStyleSheets = [redStyleSheet, greenStyleSheet]; | 
 |     hostParent.appendChild(shadowHost); | 
 |     assert_equals(getComputedStyle(greenShadowSpan).color, "rgb(0, 128, 0)", "Style applies after reattach"); | 
 |     assert_equals(getComputedStyle(redShadowSpan).color, "rgb(255, 0, 0)", "Style applies after reattach"); | 
 |   }); | 
 | }, 'Re-attaching shadow host with adopted stylesheets work'); | 
 |  | 
 | test(() => { | 
 |   const sheet = new CSSStyleSheet(); | 
 |   sheet.replaceSync(":host { color: red; }"); | 
 |   const host = document.createElement("div"); | 
 |   let sr = host.attachShadow({mode: "open"}); | 
 |   sr.adoptedStyleSheets = [sheet]; | 
 |   document.body.appendChild(host); | 
 |   assert_equals(getComputedStyle(host).color, "rgb(255, 0, 0)", "Style applies when connected"); | 
 |   sheet.replaceSync(":host { color: blue; }"); | 
 |   assert_equals(getComputedStyle(host).color, "rgb(0, 0, 255)", "Style update applies when connected"); | 
 | }, 'Attaching a shadow root that already has adopted stylesheets work'); | 
 |  | 
 | test(() => { | 
 |   const sheet = new CSSStyleSheet(); | 
 |   sheet.replaceSync(":host([red]) { color: red; } :host(.blue) { color: blue; }"); | 
 |   const host = document.createElement("div"); | 
 |   host.toggleAttribute("red"); | 
 |   document.body.appendChild(host); | 
 |   assert_equals(getComputedStyle(host).color, "rgb(0, 0, 0)", "No style applies yet"); | 
 |  | 
 |   let sr = host.attachShadow({mode: "open"}); | 
 |   sr.adoptedStyleSheets = [sheet]; | 
 |  | 
 |   assert_equals(getComputedStyle(host).color, "rgb(255, 0, 0)", "Style applies after adding style"); | 
 |   document.body.removeChild(host); | 
 |   document.body.appendChild(host); | 
 |   assert_equals(getComputedStyle(host).color, "rgb(255, 0, 0)", "Style applies after reattachment"); | 
 |   host.toggleAttribute("red"); | 
 |   assert_equals(getComputedStyle(host).color, "rgb(0, 0, 0)", "Attribute updates to the element after reattachment apply"); | 
 |   host.classList.toggle("blue"); | 
 |   assert_equals(getComputedStyle(host).color, "rgb(0, 0, 255)", "Class updates to the element after reattachment apply"); | 
 |  | 
 | }, "Re-attaching shadow host and updating attributes work"); | 
 |  | 
 | 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)"); | 
 |     document.adoptedStyleSheets = []; | 
 |   }); | 
 | }, '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_dom( | 
 |       'NotAllowedError', | 
 |       iframe.contentWindow.DOMException, | 
 |       () => { 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(async () => { | 
 |   const iframe = document.createElement("iframe"); | 
 |   const iframeLoaded = new Promise(resolve => iframe.addEventListener("load", resolve)); | 
 |   document.body.appendChild(iframe); | 
 |   await iframeLoaded; | 
 |   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_dom('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_dom('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_dom('NotAllowedError', iframe.contentWindow.DOMException, () => { | 
 |     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_dom('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(() => { | 
 |   const sheet = new CSSStyleSheet(); | 
 |   assert_equals(sheet.cssRules.length, 0); | 
 |  | 
 |   sheet.replaceSync(redStyleTexts[0]) | 
 |   assert_equals(sheet.cssRules.length, 1); | 
 |   assert_equals(redStyleTexts[0], sheet.cssRules[0].cssText); | 
 |  | 
 |   sheet.replaceSync(redStyleTexts[1]); | 
 |   assert_equals(sheet.cssRules.length, 1); | 
 |   assert_equals(redStyleTexts[1], sheet.cssRules[0].cssText); | 
 | }, 'CSSStyleSheet.replaceSync replaces stylesheet text synchronously'); | 
 |  | 
 | 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 correctly updates the style of its adopters synchronously'); | 
 |  | 
 | 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("target"); | 
 |  | 
 |   // 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(".target { color: red; }"); | 
 |   assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)"); | 
 |  | 
 |   // Create a style element that will set colors to white. | 
 |   const style = document.createElement("style"); | 
 |   style.textContent = ".target { color: white; }"; | 
 |   span.shadowRoot.appendChild(style) | 
 |   assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)", "non-adopted styles should be ordered before adopted styles"); | 
 |  | 
 |   span.shadowRoot.adoptedStyleSheets = []; | 
 |   assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 255, 255)", "with no adopted styles in conflict, the non-adopted style should take effect"); | 
 |  | 
 |   span.shadowRoot.adoptedStyleSheets = [sheet]; | 
 |   assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)", "the adopted style should be ordered after the non-adopted style"); | 
 |  | 
 |   sheet.disabled = true; | 
 |   assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 255, 255)", "with the adopted sheet disabled, the non-adopted style should take effect"); | 
 |  | 
 |   sheet.disabled = false; | 
 |   assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)", "the adopted sheet re-enabled, it should take effect again"); | 
 | }, 'Adopted sheets are ordered after non-adopted sheets in the shadow root') | 
 |  | 
 | test(() => { | 
 |   // Attach a div inside a shadow root with the class ".red". | 
 |   const span = document.createElement("span"); | 
 |   thirdSection.appendChild(span); | 
 |   span.classList.add("target"); | 
 |  | 
 |   // Create empty stylesheet. | 
 |   const sheet = new CSSStyleSheet(); | 
 |   document.adoptedStyleSheets = [sheet]; | 
 |   assert_equals(getComputedStyle(span).color, "rgb(0, 0, 0)"); | 
 |  | 
 |   // Replace the stylesheet text that will color it red. | 
 |   sheet.replaceSync(".target { color: red; }"); | 
 |   assert_equals(getComputedStyle(span).color, "rgb(255, 0, 0)"); | 
 |  | 
 |   // Create a style element that will set colors to white. | 
 |   const style = document.createElement("style"); | 
 |   style.textContent = ".target { color: white; }"; | 
 |   span.appendChild(style) | 
 |   assert_equals(getComputedStyle(span).color, "rgb(255, 0, 0)", "non-adopted styles should be ordered before adopted styles"); | 
 |  | 
 |   document.adoptedStyleSheets = []; | 
 |   assert_equals(getComputedStyle(span).color, "rgb(255, 255, 255)", "with no adopted styles in conflict, the non-adopted style should take effect"); | 
 |  | 
 |   document.adoptedStyleSheets = [sheet]; | 
 |   assert_equals(getComputedStyle(span).color, "rgb(255, 0, 0)", "the adopted style should be ordered after the non-adopted style"); | 
 |  | 
 |   sheet.disabled = true; | 
 |   assert_equals(getComputedStyle(span).color, "rgb(255, 255, 255)", "with the adopted sheet disabled, the non-adopted style should take effect"); | 
 |  | 
 |   sheet.disabled = false; | 
 |   assert_equals(getComputedStyle(span).color, "rgb(255, 0, 0)", "the adopted sheet re-enabled, it should take effect again") | 
 | }, 'Adopted sheets are ordered after non-adopted sheets in the document') | 
 |  | 
 | const import_text = '@import url("support/constructable-import.css");'; | 
 |  | 
 | 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(t => { | 
 |     const importUrl = "support/constructable-import.css"; | 
 |     const sheet = new CSSStyleSheet(); | 
 |  | 
 |     sheet.replaceSync(`@import url("${importUrl}");`); | 
 |  | 
 |     const timeAfterReplaceSync = performance.now(); | 
 |     let link = document.createElement("link"); | 
 |     link.rel = "stylesheet"; | 
 |     link.href = importUrl; | 
 |  | 
 |     return new Promise(resolve => { | 
 |       link.addEventListener("error", t.unreached_func("Load shouldn't fail")); | 
 |       link.addEventListener("load", t.step_func(() => { | 
 |         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, timeAfterReplaceSync, "The entry's start time should be after replaceSync threw"); | 
 |         link.remove(); | 
 |         resolve(); | 
 |       })); | 
 |       document.body.appendChild(link); | 
 |     }); | 
 | }, "CSSStyleSheet.replaceSync should not trigger any loads from @import rules") | 
 |  | 
 | 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 NOT applied. | 
 |   const sheet_promise = sheet.replace(import_text); | 
 |   return sheet_promise.then((sheet) => { | 
 |     // replace() ignores @import rules: | 
 |     assert_equals(sheet.cssRules.length, 0); | 
 |     assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)"); | 
 |   }).catch((reason) => { | 
 |     assert_unreached(`Promise was rejected (${reason}) when it should have been resolved`); | 
 |   }); | 
 | }, 'CSSStyleSheet.replace allows, but ignores, import rule inside'); | 
 |  | 
 | promise_test(() => { | 
 |   const span = document.createElement("span"); | 
 |   thirdSection.appendChild(span); | 
 |   const shadowDiv = attachShadowDiv(span); | 
 |   const targetSpan = document.createElement("span"); | 
 |   targetSpan.classList.add("target"); | 
 |   shadowDiv.appendChild(targetSpan); | 
 |   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 NOT applied, but regular rule does apply. | 
 |   const sheet_promise = sheet.replace(import_text + ".target { color: blue; }"); | 
 |   return sheet_promise.then((sheet) => { | 
 |     assert_equals(sheet.cssRules.length, 1); | 
 |     // @import not applied: | 
 |     assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)"); | 
 |     // regular rule applied: | 
 |     assert_equals(getComputedStyle(targetSpan).color, "rgb(0, 0, 255)"); | 
 |   }).catch((reason) => { | 
 |     assert_unreached(`Promise was rejected (${reason}) when it should have been resolved`); | 
 |   }); | 
 | }, 'CSSStyleSheet.replace ignores @import rule but still loads other rules'); | 
 |  | 
 | 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 NOT applied. | 
 |   try { | 
 |     sheet.replaceSync(import_text); | 
 |     // replaceSync() ignores @import rules: | 
 |     assert_equals(sheet.cssRules.length, 0); | 
 |     assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)"); | 
 |   } catch(reason) { | 
 |     assert_unreached(`replaceSync threw an exception (${reason}) when it shouldn't have`); | 
 |   } | 
 | }, 'CSSStyleSheet.replaceSync allows, but ignores, import rule inside'); | 
 |  | 
 | promise_test(() => { | 
 |   const sheet = new CSSStyleSheet(); | 
 |   const sheet_promise = sheet.replace("@import url('not-there.css');"); | 
 |  | 
 |   return sheet_promise.then((sheet) => { | 
 |     // No exception here | 
 |   }).catch((reason) => { | 
 |     assert_unreached("Promise was rejected"); | 
 |   }); | 
 | }, 'CSSStyleSheet.replace does not reject 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'); | 
 |  | 
 | test(() => { | 
 |   const span = document.createElement("span"); | 
 |   const div = document.createElement("div"); | 
 |   thirdSection.appendChild(span); | 
 |   span.appendChild(div); | 
 |   const shadowDiv = attachShadowDiv(div); | 
 |   const sheet = new CSSStyleSheet(); | 
 |   sheet.replaceSync("* { color: red; }"); | 
 |   div.shadowRoot.adoptedStyleSheets = [sheet]; | 
 |   assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)"); | 
 |  | 
 |   document.adoptNode(span); | 
 |   assert_equals(div.shadowRoot.adoptedStyleSheets.length, 1); | 
 |   assert_equals(div.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(div.shadowRoot, null); | 
 |   assert_equals(div.shadowRoot.adoptedStyleSheets.length, 0); | 
 |   assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)"); | 
 | }, `Adopting a shadow host's ancestor will empty adoptedStyleSheets if adopting to a different document`); | 
 |  | 
 | test(() => { | 
 |   const host = document.createElement("div"); | 
 |   const root = host.attachShadow({mode: "open"}); | 
 |   root.adoptedStyleSheets = [new CSSStyleSheet()]; | 
 |   document.body.offsetTop; | 
 | }, 'Forcing a style update after adding an adopted stylesheet on a disconnected shadow root should not crash.'); | 
 |  | 
 | test(() => { | 
 |   const host = document.createElement("div"); | 
 |   thirdSection.appendChild(host); | 
 |   const root = host.attachShadow({mode: "open"}); | 
 |   const sheet = new CSSStyleSheet(); | 
 |   root.adoptedStyleSheets = [sheet]; | 
 |   host.remove(); | 
 |   sheet.replaceSync(''); | 
 | }, 'Modifying an adopted stylesheet on a disconnected shadow root should not crash.'); | 
 |  | 
 | function currentLocation() { | 
 |   const sections = location.href.split("/") | 
 |   sections.pop(); | 
 |   return sections.join("/"); | 
 | } | 
 |  | 
 | test(() => { | 
 |   const span = document.createElement("span"); | 
 |   thirdSection.appendChild(span); | 
 |   const shadowDiv = attachShadowDiv(span); | 
 |  | 
 |   const fileName = "example.png" | 
 |   const fullPath = `${currentLocation()}/${fileName}` | 
 |  | 
 |   const sheet = new CSSStyleSheet(); | 
 |   span.shadowRoot.adoptedStyleSheets = [sheet]; | 
 |  | 
 |   sheet.replaceSync(`* { background-image: url("${fileName}"); }`); | 
 |   const styleFromRelative = getComputedStyle(shadowDiv).backgroundImage; | 
 |  | 
 |   sheet.replaceSync(`* { background-image: url("${fullPath}"); }`); | 
 |   const styleFromFull = getComputedStyle(shadowDiv).backgroundImage; | 
 |  | 
 |   assert_equals(styleFromRelative, styleFromFull); | 
 | }, "Constructing a sheet with the default base URL uses the constructor document's base URL for CSS rules"); | 
 |  | 
 | </script> |