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

The following issues need APIs which should be used by custom element authors and should not be used by custom element users.
- [Need callback for form submit data (#187)](https://github.com/w3c/webcomponents/issues/187)
- [Custom pseudo-classes for host elements via shadow roots (:state) (#738)](https://github.com/w3c/webcomponents/issues/738)

At the March F2F we came up with one  [idea](https://github.com/w3c/webcomponents/issues/738#issuecomment-370324878). However using ```ShadowRoot``` for such APIs looks very weird to me and I'd like to discuss it again.

Candidates:

- ```ShadowRoot```
  Pros: Usually only custom element implementation knows the instance of ```ShadowRoot``` which is used to implement the custom element. It's difficult for custom element users to get a ```ShadowRoot``` instance created by a custom element implementation [1]
  Cons: ```ShadowRoot``` is an interface for tree-encapsulation.  Adding features unrelated to tree-encapsulation looks like a design defect.  We should not make ```ShadowRoot``` a kitchen sink.
  Cons: Not all custom element implementations need ```ShadowRoot```.  For example, a checkbox custom element won't need ```ShadowRoot```.  Creating unnecessary ```ShadowRoot``` for such APIs is not reasonable.
  Cons: If a custom element implementation uses no ```ShadowRoot```, a custom element user can call ```element.attachShadow()``` to get a ```ShadowRoot``` instance, and thus get access to these private APIs.

- ```new Something(customElement)```
  It throws if users try to create it for the same element twice.  It throws if the constructor is called with non-custom elements. The interface ```Something``` is called as [ElementStates](https://github.com/w3c/webcomponents/issues/738#issuecomment-367565438) in #738, and called as [HTMLElementPrimitives](https://github.com/w3c/webcomponents/issues/187#issuecomment-388740230) in #187.
  Pros: ```ShadowRoot``` won't have unrelated APIs.
  Pros: Usually only custom element implementation knows the instance of ```Something```. It's difficult for custom element users to get a ```Something``` instance created by a custom element implementation [1]
  Cons: If a custom element implementation uses no ```Something```, a custom element user can call ```new Something(element)``` successfully to get a ```Something``` instance.

- Deliver a ```Something``` instance by a custom element callback
  See https://github.com/w3c/webcomponents/issues/187#issuecomment-388740230 for more details. 
  Pros: ```ShadowRoot``` won't have unrelated APIs.
  Pros: Custom element users can not create a ```Something``` instance unlike other two candidates.
  Pros: It's difficult for custom element users to get a ```Something``` instance delivered to a custom element [1]
  Cons: UA implementation would need larger code for a new callback, compared to the other two candidates.

IMO, the second one or the third one is much better than the first one.

@annevk @domenic @rniwa @trusktr What do you think?

[1] If a custom element implementation stores a ```ShadowRoot``` / ```Something``` instance to ```this.foo_```, a custom element user can get the instance by accessing ```yourElement.foo_```.  There are some techniques to avoid such casual access.


-- 
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

Received on Monday, 30 July 2018 06:40:51 UTC