You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a start of what it would look like to add event support to SSR. It uses Node's Event and EventTarget classes and extends EventTarget to have a parent that it can dispatch to to implement bubbling. stopPropagation(), etc., should work, but aren't tested yet.
The big open questions are:
Can we have an event path of just the custom elements without materializing the built-ins that would be on the path with a full DOM structure? This seems ok if the only event patterns we support are for cross-custom-element communication, ie context.
Where do elements install event listeners? I added a call to connectedCallback() in here, but that only doesn't throw because none of the test elements do anything with the DOM in connectedCallback(). That wouldn't be viable in general.
Do we need to implement the capture phase?
How could we implement the proper composed path? We would need some concept of slotted elements being in the custom element instance stack.
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
This PR includes no changesets
When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types
In addition to your notes above, also just want to add these for discussion:
This effectively makes the CE instance required, since it's relying on arbitrary user code doing this.dispatchEvent on the instance... I know we want to suspend constraints on an interface-only ElementRenderer while exploring, but this seems like a fundamental decision
This would not be compatible with loading an alternate DOM shim, since the instance would be disconnected and have no parent; to make it compatible, we'd need to do parent.appendChild(instance) and have the shim do the __eventTargetParent hookup, but it might be problematic to just randomly "append" into the parent if that's not actually where it goes (due to the desire to skip built-ins)
justinfagnani
changed the title
Add basic event support
[@lit-labs/ssr] Add basic event support
Nov 30, 2021
aomarks
changed the title
[@lit-labs/ssr] Add basic event support
[ssr] Add basic event support
Jan 19, 2022
Wonder if there's an alternative that would be more compatible with bring-your-own-shim and keeping the ElementRenderer just an interface where instead of requiring the instance to hook up the fake parent, we instead:
Add ElementRenderer:dispatchEvent (which in ours will just call instance.dispatchEvent()
Add a patch of dispatchEvent on whatever Element.prototype exists (either our dom shim, which would just have Element extend EventTarget, or a real DOM shim like jsdom, which would have a more correct implementation)
Our patch would super to the existing dispatchEvent, and then if it should bubble AND there's no this.parentNode (which is always the case in our DOM shim, and would be the case when using jsdom and you go up and hit a LitElementRenderer instance), then look in the (somehow-made-accessible) open custom elements stack and dispatch to the next element up.
It seems like that might avoid punting on ElementRenderer just yet.
We of course (maybe as part of this), should try running with a full DOM shim to make sure even the basic stuff works there, and specifically that event dispatch would work.
I am definitely in support of exposing dispatchEvent. The largest use-case for us will be context and dependency-injection APIs. Our DI infrastructure already is implemented using events on the client, and we have a context-like feature that could be implemented on the server using events. We also have plans to implement general-purpose context APIs, which would obviously benefit as well.
Can we have an event path of just the custom elements without materializing the built-ins that would be on the path with a > full DOM structure? This seems ok if the only event patterns we support are for cross-custom-element communication, ie context.
I think this constraint is suitable for our implementations and the majority of our components. It seems in-line with other code we have that no-ops operations that would provide references to native elements, such as ref directives, slotted element inspection, etc.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a start of what it would look like to add event support to SSR. It uses Node's
EventandEventTargetclasses and extendsEventTargetto have a parent that it can dispatch to to implement bubbling.stopPropagation(), etc., should work, but aren't tested yet.The big open questions are:
connectedCallback()in here, but that only doesn't throw because none of the test elements do anything with the DOM inconnectedCallback(). That wouldn't be viable in general.