Closed basham closed 5 years ago
Dom nodes cannot change tag name, neither is
attribute, once upgraded, so I'm not sure it's a valid example.
Both connected and disconnected work exactly like custom elements, so it looks like you want an attribute changed in the middle, but you're after a "destructor", which is weird cause that also means "init" might be invoked twice for the same element, and the same definition.
Accordingly, disconnected is not the right place to destructor, but also destructor is usually considered a footgun.
I'll think about this, but maybe it's ok if when-element has a different meaning/outcome, and wicked elements sticks with the platform verbs and concepts
OK, after going through the code, I've decided to keep the project as is, symmetric with CustomElementsRegistry where, once you define a selector behavior, the node will follow all the primitives, no matter what.
I think when-element
has different semantics and goals, so I'm OK in it having its own way of doing things, here I'll just try to keep consistency and symmetry with documented standard.
I hope that's OK, so that users will have choices 👋
Dom nodes cannot change tag name, neither
is
attribute, once upgraded, so I'm not sure it's a valid example.
Perhaps the example I gave wasn't the best, as it relied on the is
attribute. This new example is quite contrived, but imagine something like this. It upgrades the same element in two different ways. One, it makes the button behave like a disclosure. Two, it adds a custom tooltip to the button.
wickedElements.define('[aria-expanded]',
// Clicking the element will
// toggle the aria-expanded attribute and
// toggle the visibility of the element referenced by data-expands.
)
wickedElements.define('[data-tooltip]',
// Reveal a custom tooltip upon hover or focus.
// Remove the tooltip if the element no longer has the attribute.
)
html`
<button
aria-expanded="false"
data-expands="answer-1"
data-tooltip="Ask me the questions, Bridgekeeper. I am not afraid.">
What is your favorite color?
</button>
<div id="answer-1">
Sir Galahad: Blue. No yellOOOOOOW!
</div>
`
Both connected and disconnected work exactly like custom elements, so it looks like you want an attribute changed in the middle, but you're after a "destructor", which is weird cause that also means "init" might be invoked twice for the same element, and the same definition.
Yes, I could see it being odd for the case of wickedElements
, if the presence of [data-tooltip]
triggered init()
, then the attribute was removed and added again, causing init()
to be triggered again. Some different semantics would be needed for that to feel okay.
Nevertheless, if the primary purpose of onconnected()
, init()
, or whenAdded()
is to upgrade an element, I'm struggling with finding compelling reasons to support a method for downgrading the element (by knowing when the element no longer matches the original selector and somehow undoing its setup). It's far easier to just destroy the element, do some clean up, and replace it with something new. And as you suggest, downgrading may just lead to the developer shooting themselves in the foot. I will likely remove this feature from when-elements
, and that will happily simplify the whenRemoved()
API. However, I could also see allowing the developer to register a custom when*-like callback, so they could integrate their own hooks into the system as needed. This expansion-ability is hinted at in the backlog.
Yes, I understand wanting to keep in symmetry with CustomElementsRegistry, and when-elements
is purposely different from that that API. I'm glad we could clarify the goals of our respective projects.
ondisconnected()
is called when the element is removed from the DOM, but not when the element no longer matches the selector provided indefine()
. For example, an element attribute could mutate, "invalidating" the element compared to its respective selector. But as is, it means that the same element gets booted up twice via two definitions, but the first initialization is never shut down (viaondisconnected()
) until the element is removed from the DOM.Maybe
regularElements
orwickedElements
needs some other lifecycle method, ifondisconnected()
is an inappropriate place for this behavior. But it feels as if there needs to be some way to undo initializing an element with the same rules for why it was initialized in the first place.I haven't tested it, but it would be good as a comparison to know how Custom Elements handles this, for both the cases of a new tag or tag extension.
For reference, this is how
when-elements
behaves.