Skip to content

Provide some way of changing an elements location in the DOM tree without triggering connect/disconnect CEReactions #10475

Open
@keithamus

Description

What problem are you trying to solve?

Often times it's useful to move existing elements within the DOM, for example when re-ordering lists. whatwg/dom#1255 goes into some detail about extending DOM operations to implement atomic-like moves of DOM nodes. Largely it looks as though this will involve new DOM APIs to opt-into atomic move operations.

CustomElements can often rely on relationships to their parent or window, and will use the connected/disconnected CEReactions to hook/unhook operations against their position in the tree. In whatwg/dom#1296 we explore adding an API to get an AbortSignal for the disconnected CEReaction, but it is also evident that some users try to debounce/coalesce disconnections in order to emulate atomicity of a move operation. However there are subtleties here; moving a node to a new parent may require tearing down event listeners or issuing new events to discover new contexts (an example within the Web Components community is the Context proposal https://github.com/webcomponents-cg/community-protocols/blob/main/proposals/context.md; custom element authors would ideally trigger a new context-request events if there element moved, even atomically, I think).

The discussion in whatwg/dom#1255 is very expansive and covers a lot around built-in nodes, and so I wanted to capture this small element of it in relation to Custom Elements alone.

In summary, it can be useful for custom elements to know if they're reparented especially as part of an atomic move operation. Generally speaking, I think some kind of new CEReaction to hook into this behaviour is necessary.

What solutions exist today?

Right now the only option is to "debounce" or otherwise coalesce connected/disconnected lifecycle hooks, for example to wrap the functionality of a disconnectedCallback in a microtask which is cancelled on the connectedCallback.

It's worth pointing out that atomic moves have the potential to break this existing pattern, depending on if the new atomic move APIs trigger the disconnect/connect CEReactions. If they don't, then they can break existing Custom Elements, but if they do then it becomes more difficult for custom element authors to make their elements preserve or re-request tree-related state during atomic move operations.

How would you solve it?

I think I'd add a new move CEReaction, perhaps with a movedCallback() API on the CustomElement definition. In order to retain backcompat with existing components, I think it would perhaps be useful to use the existence of the method as an opt-in, so if the method doesn't exist on the definition, then trigger disconnect/connect CEReactions, but if it does then only trigger a move CEReaction.

Anything else?

No response

Metadata

Assignees

No one assigned

    Labels

    addition/proposalNew features or enhancementsneeds implementer interestMoving the issue forward requires implementers to express interesttopic: custom elementsRelates to custom elements (as defined in DOM and HTML)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions