Comments (18)
(Forgot the ccs, hah)
cc @mfreed7 @rniwa @annevk @avandolder
from dom.
I did think about this one. The important detail (to me at least) is that attachShadow
in these cases will clear out the shadow root before returning it. So it's not like this is an end-run around revealing closed shadow root content or anything. It's just a weird way to create a closed shadow root via a call to attachShadow({mode:'open'})
.
I do agree that it's perhaps a bit odd that the options provided to attachShadow
don't get respected in this case, but the alternative seemed worse to me: changing the flags on an already-existing shadow root as a result of this call. I'm open to suggestions. (Keeping in mind that several implementations have shipped.)
from dom.
I don't know, that makes code like this potentially fail in a very action-at-a-distance way, and with no pointer to the root cause of the issue (a shadowrootmode=closed
template):
host.attachShadow({ mode: "open" });
host.shadowRoot.appendChild(...);
I guess we could add a console warning or so... Maybe it's worth a note in the spec?
from dom.
Why did we not throw again?
I'm also not sure I understand
This means that if multiple declarative shadow roots are contained within a single shadow host, only the last one will remain.
upon rereading. How could a host ever have multiple shadow roots?
from dom.
You'd have multiple <template>
elements as children.
from dom.
Okay, but those are not necessarily declarative shadow roots. Only one of them can be. Might just be a matter of using more precise wording then.
from dom.
I don't know, that makes code like this potentially fail in a very action-at-a-distance way, and with no pointer to the root cause of the issue (a
shadowrootmode=closed
template):
That's true. But typically this (DSD) is already "action at a distance" by definition, since it's rendered on the server.
I guess we could add a console warning or so... Maybe it's worth a note in the spec?
This makes a lot of sense - the console warning. I think I'll add that to Chromium. Do we add notes about console warnings to the spec?
Why did we not throw again?
Not throwing is an important backwards-compatibility behavior, which is the entire point for this whole "empty and return the root" behavior. If a component was built without SSR/DSD knowledge, and then some server code decides to SSR that component, we didn't want to break the component. The only real way to do that is to keep attachShadow()
working roughly as intended.
Importantly, if the server is taking a component that calls attachShadow({mode:'open'})
and converting that into a <template shadowrootmode=closed>
, then that server is already very broken. So I don't think the "change the parameters" issue is really an issue in practice. Plus, components that understand SSD/DSD will check for a .shadowRoot
and won't ever call attachShadow()
.
Okay, but those are not necessarily declarative shadow roots. Only one of them can be. Might just be a matter of using more precise wording then.
I agree that the wording is kind of hard to understand here. Perhaps instead of "declarative shadow roots" in that sentence, we should just use "<template shadowrootmode>
's" or something?
from dom.
I think the ideal behaviour here would be to throw only if the init parameters are mismatched. Alternatively current behaviour and console warning, and probably note on the spec. But I find the current behaviour rather unfortunate
from dom.
I think the ideal behaviour here would be to throw only if the init parameters are mismatched. Alternatively current behaviour and console warning, and probably note on the spec. But I find the current behaviour rather unfortunate
I think I could live with that (throw if parameters mismatch). I'm assuming this won't be much of a breaking change.
Are you suggesting we check all parameters, such as delegatesFocus
, slotAssignment
, etc.?
from dom.
For the wording issue: yes,
template
elements whoseshadowrootmode
attribute is appropriately set
would work I think.
@emilio having to check for all the parameters and remember to do so when we add new parameters seems like a pain, but I guess we could do it. In retrospect I'm not sure we should have supported this scenario, but it's probably too late to completely change it.
from dom.
Are you suggesting we check all parameters, such as
delegatesFocus
,slotAssignment
, etc.?
Yes, otherwise they get silently ignored...
from dom.
I was getting started thinking about this change, and another case comes up. What should happen here?
<div>
<template shadowrootmode=open>Root 1</template>
<template shadowrootmode=closed>Root 2</template>
</div>
In current behavior and spec, there will be an open
shadow root attached which contains "Root 2", because the "attach a shadow root" algorithm will clear out the first (open) root and insert "Root 2". We can't throw in the parser. Should this just be the console warning case?
from dom.
It seems like the first template should win in this case.
from dom.
@rniwa I guess what you are suggesting is that the HTML parser completely ignores subsequent shadowrootmode
template elements?
What does the parser do when a script attached a shadow root?
from dom.
It seems like the first template should win in this case.
@rniwa I guess what you are suggesting is that the HTML parser completely ignores subsequentshadowrootmode
template elements?
I suppose that could work, presuming you mean always ignore subsequent declarative shadow roots, not just when their parameters mismatch. It's a change in behavior, so it might not be web compatible, but it seems relatively safe. If it sounds like you're happy with that, I'll try to implement it and see what happens.
from dom.
I suppose that could work, presuming you mean always ignore subsequent declarative shadow roots, not just when their parameters mismatch. It's a change in behavior, so it might not be web compatible, but it seems relatively safe. If it sounds like you're happy with that, I'll try to implement it and see what happens.
Hearing no objections, I went ahead and implemented this in Chromium, and changed/added some WPTs. I also put up a corresponding set of HTML/DOM spec PRs. To summarize the changes:
- If two declarative shadow roots are included within a single host element, only the first one will remain. This is a change in behavior from before, but it hopefully won't encounter compat issues (TBD).
- If attachShadow() is used on an existing declarative shadow root, and the parameters (e.g. shadow root type, delegates focus, etc.) do not match, an exception is thrown. This, also, is a breaking change, but again hopefully not one that has compat implications.
Hopefully folks are happy with these changes. If so, I'll try shipping them in the next Chrome and verify the compat safety.
from dom.
Thanks @mfreed7, that works for us. I'll attempt to look at the PRs next week to double check all the details.
from dom.
Thanks @mfreed7, that works for us. I'll attempt to look at the PRs next week to double check all the details.
Great, thanks! I enabled the new behavior (and landed the WPTs) in Chrome 122, so I'll watch for issues.
from dom.
Related Issues (20)
- Delegate to Iterator helper methods on NodeList HOT 2
- Proposal for built-in method to synchronize elements with virtual DOM representation
- another version of `Element.prototype.contains` that considers slotted elements as children HOT 2
- Variable strength aborting HOT 1
- Proposal: DOM APIs in web workers? HOT 42
- clone with clone children flag set should append clone before cloning children HOT 2
- Provide a "deep clone" shorthand HOT 1
- Explicitly update the child's parent HOT 2
- Support for HTML/XML stream parsing/rewriting. HOT 4
- matchMedia-like API for element matches
- MutationOvserver and DOMNodeInsertedIntoDocument HOT 1
- Add guidance about using DOMTokenList
- Elements with Fallback, Proxy, Replacement, Substitute, or Surrogate Elements
- Selecting Events with Style HOT 6
- Element.attachShadow should set the declarative flag to false of an existing declarative shadow dom. HOT 4
- Corresponding attribute for clonable of ShadowRootInit? HOT 3
- How should `clonable` work in `cloneNode(false)`? HOT 11
- Support for appending a cloned template adjacent to an existing element HOT 1
- Make some ShadowRoot attributes mutable
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dom.