Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

attachShadow options #26

Open
titoBouzout opened this issue Sep 14, 2024 · 1 comment
Open

attachShadow options #26

titoBouzout opened this issue Sep 14, 2024 · 1 comment

Comments

@titoBouzout
Copy link

Hey, is there any way to set attachShadow options? I'm looking at getting the content of the shadowRoot, so it gets included in the html when I save the full page to disk. Maybe static attachShadowOptions = {mode:'closed'... } ?

@trusktr
Copy link
Member

trusktr commented Sep 14, 2024

Yeah that looks like a convenient way to expose it. Might call it shadowRootOptions.

A workaround for now is you could override hasShadow to false,

readonly hasShadow: boolean = true

then override the get root() getter,

element/src/LumeElement.ts

Lines 223 to 235 in 9b374f1

protected get root(): Node {
if (!this.hasShadow) return this
if (this.__root) return this.__root
if (this.shadowRoot) return (this.__root = this.shadowRoot)
// TODO use `this.attachInternals()` (ElementInternals API) to get the root instead.
return (this.__root = this.attachShadow({mode: 'open'}))
}
protected set root(v: Node) {
if (!this.hasShadow) throw new Error('Can not set root, element.hasShadow is false.')
// @prod-prune
if (this.__root || this.shadowRoot) throw new Error('Element root can only be set once if there is no ShadowRoot.')
this.__root = v
}

to return the root with attachShadow(...) if it has not yet been made (f.e. on first read of the getter).

Besides the mode option, more options are coming out, so we still want to make it easy to configure, so this is a good idea.

But in general in the Custom Elements world, avoiding mode:closed is considered best practice for a number of reasons. Typically allowing users to access the ShadowRoot is good for customization, so they aren't blocked, and besides mode:closed is only really like a signal to say "hey, don't touch this unless you know what you're doing, it is very likely to change" or similar, but the thing is, it is very easy to get access to closed roots by overriding attachShadow which users will do anyway if they really need to change something. So it's kinda moot. Just keep it open unless there's a very strong signal to give. Even 3rd party code that may run after your roots are all created, if they provide elements that will be nested in your tree, then they can still use getRootNode() to traverse upward so it's not really a security feature. I never use it.

Example:

<script type="module">
  const root = document.body.attachShadow({mode: 'closed'})
  root.innerHTML = `<div></div>`
  const div = root.children[0] // 3rd party element f.e.
  console.log(document.body.shadowRoot) // null
  console.log(div.getRootNode().host) // body
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants