[csswg-drafts] [cssom] Need to agree on when LinkedStyle.sheet gets updated in shadow trees.

emilio has just created a new issue for https://github.com/w3c/csswg-drafts:

== [cssom] Need to agree on when LinkedStyle.sheet gets updated in shadow trees. ==
Since it's observable via cssRules and all that stuff.

In Gecko, when a shadow host is unbound, we also disconnect the `ShadowRoot` children. This has side effects, such as loosing (only temporarily) the `sheet` pointer, and loosing the `disabled` state.

I was going to fix this in Gecko, when to my surprise Chrome (which is the only other implementor of `ShadowRoot.styleSheets` doesn't keep the stylesheets around in disconnected subtrees.

We should agree on when should they be kept.

Test-case (sorry, pretty messy):

```html
<!doctype html>
<div id="host"></div>
<script>
  let host = document.querySelector("#host");
  host.attachShadow({ mode: "open" }).innerHTML = `<style>* { color: red }</style><span>Should not be red</span>`;

  console.log("host.shadowRoot.styleSheets", host.shadowRoot.styleSheets);
  console.log("style.sheet", host.shadowRoot.querySelector('style').sheet);

  let sheet = host.shadowRoot.styleSheets[0];
  console.log("host.shadowRoot.styleSheets[0]", sheet);
  sheet.disabled = true;

  // assert_equals(getComputedStyle(host.shadowRoot.querySelector('span')).color, "rgb(0, 0, 0)");
  document.body.offsetTop;

  host.remove();

  console.log("host.shadowRoot.styleSheets (after removal)", host.shadowRoot.styleSheets);
  console.log("style.sheet (after removal)", host.shadowRoot.querySelector('style').sheet);
  sheet = host.shadowRoot.styleSheets[0];
  console.log("host.shadowRoot.styleSheets[0] (after removal)", sheet);
  console.log("host.shadowRoot.styleSheets[0].disabled (after removal)", sheet ? sheet.disabled : "(no sheet)");

  document.body.offsetTop;
  document.body.appendChild(host);

  document.body.offsetTop;
  let host2 = document.createElement('div');
  host2.attachShadow({ mode: "open" }).innerHTML = `<style>* { color: red }</style><span>Should not be red</span>`;
  console.log("host2.shadowRoot.styleSheets", host2.shadowRoot.styleSheets);
  console.log("style.sheet", host2.shadowRoot.querySelector('style').sheet);
  sheet = host2.shadowRoot.styleSheets[0];
  console.log("host2.shadowRoot.styleSheets[0]", sheet);
</script>
```

Or online at https://crisal.io/tmp/disabled-shadow.html.

And to be clear I'm fine speccing and implementing the Blink behavior, if we decide that accessing stylesheets in disconnected shadow roots is not worth the churn.

cc @lilles @tabatkins @rniwa

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/3096 using your GitHub account

Received on Tuesday, 11 September 2018 00:25:39 UTC