Re: [w3c/webcomponents] How to define APIs only for custom element authors (#758)

> Anther side effect of the new callback: the possibility to bypass internals defined during the inheritance. 

This is true with any of the options on the table. E.g. you say that the `Something` constructor is guaranteed to be untouched, but that's not true; the subclass does not need to call it (they can use `Reflect.construct` to directly call `HTMLElement`, and bypass the superclass constructor). In the end the author of the custom element class has ultimate control.

> Hm... I guess another option is make HTMLElement's constructor take an argument. 

Interesting. This seems workable to me, although a bit weird for developers. Especially because standing advice for JS class usage is "don't do anything before calling `super()`".

Basically `ElementInternal` is useless until it's passed to a [HTMLConstructor] via `super()`, then it becomes useful. That's not too complicated.

I think this works, although there may be `Reflect.construct` shenanigans that could mess it up.

> I guess element.attachElementInternal() which would throw on a second invocation would be fine... that would be analogous to how shadow DOM API would work. Custom elements that don't use it can either attach it and never use it, or we could make this an opt-in feature where you'd have to declare it in a static field like we did for observedAttributes.

The problem there is you can attach it to arbitrary elements you don't own. Even if we only allow it on custom elements, that seems unfortunate.

> Also, I noticed it's difficult to define createdCallback behavior in new MyElement() case.

I think you just define it to happen at the bottom of the `[HTMLConstructor]` steps. (So it happens when you call `super()`, before the rest of the author-defined constructor code.)

> Opt-in sounds a good idea. Adding a flag to ElementDefinitionOptions would be an easy way.

So I guess the idea here is that this reduces the bad case to when custom element authors opt-in with `needsElementInternals: true`, but fail to do `this.attachInternals()` (or whatever) before calling any author code. That helps a bit.

---

Overall I think we have three proposals that each have OK tradeoffs:

- Pass `ElementInternals` to `super()`. Pro: encapsulation seems perfect. Con: a weird pattern for developers to learn.
- `createdCallback()`, invoked by `super()`. Pro: encapsulation seems perfect. Con: potentially two JS callbacks if developers use both `constructor` and `createdCallback()`.
- `needsElementInternals` + `this.attachInternals()` or something. Pro: doesn't have other options' cons. Con: encapsulation is imperfect if custom element author is not careful.

I personally think the `createdCallback()` version is simplest, especially because I'd anticipate authors only using either createdCallback() or the constructor, not both. But all of these seem livable.

I think it would be good to spend pre-TPAC time keeping our minds open and fleshing out the list of alternatives, either by adding more or expanding on the pro-cons. We've had a lot of good brainstorming over the last week that feels productive. We can then narrow the field at TPAC.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/758#issuecomment-429067962

Received on Thursday, 11 October 2018 18:27:29 UTC