Re: [WICG/webcomponents] The is="" attribute is confusing? Maybe we should encourage only ES6 class-based extension. (#509)

@trusktr after thinking about this for a little while, I think the API would be much simpler if it had only `attachedCallback` and `detachedCallback` plus the `target` getter, as long as we propose a new API that would actually cut the mustard and offer what most developers want from CustomElements: their lifecycle on the DOM.

## ElementObserver

This API proposal consist in being able to use `connectedCallback` and `disconnectedCallback` to **any** DOM element, exactly in the same way it works with Custom Elements, through a *MutationObserver* friendly API.

```js
const eo = new ElementObserver((records, eo) => {
  for (const {target, type} of records) {
    if (type === 'connected') {
      // target has been connected
      doConnectedThings(target);
    }
    else {
      // target has been disconnected
      doDisconnectedThings(target);
    }
  }
});

const target = document.querySelector('any-dom-element');

eo.observe(target);

if (target.isConnected)
  doConnectedThings(target);
```

If the asynchronous nature (easier to polyfill and aligned with MO) is not cool or ideal, the API could instead be like:

```js
const eo = new ElementObserver({
  connectedCallback(element) {
    // do things with element
  },
  disconnectedCallback(element) {
    // do things with element
  }
});

eo.observe(anyDOMElement);

// maybe the sync version could trigger
// connectedCallback if the element is already live?
```

With this new mechanism a lot of the arguments around builtin-extends might vanish, because at that point we'll have *MutationObserver* to mimic `attributeChangedCallback` on any element, and these two new mechanisms to understand when the element gets in or out the DOM.

This API makes it possible, out of the box, to define behaviors however developers like, but it'll also make it possible to have a simplified API for behaviors, in case we'd like to abuse the `has` attribute.

```js
// base class
class Behavior {
  get target() { /* return the element/target */ }
  // a constructor like place to setup once
  attachedCallback() {
    this.eo = new ElementObserver(callback || literalObserver);
    this.eo.observe(this.target);
  }
  // a destructor like place to teardown once
  detachedCallback() {
    this.eo.disconnect();
    // this.target is null after this call
  }
}
```

Doing this way the Behavior doesn't mislead with elements associated callbacks through its prototype, the separation of concerns/responsibilities is clear, there's no confusion, and observing elements lifecycle becomes optional, so that behaviors can be much simpler in intent, scope, and also code.

What do you, or anyone else, think about these two possible APIs? Is it worth opening a new issue and discuss any of these in there?

Thank you.



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

Received on Thursday, 25 March 2021 07:54:55 UTC