[w3c/webcomponents] attachedCallback in light tree, but what about in shadow tree? (#504)

I made some [custom elements](https://github.com/infamous/infamous/tree/master/src/motor-html) for create a 3D scene, for example:

```html
<motor-scene id="motor-scene">
    <motor-node
        absoluteSize='200,200,0'
        rotation='0,30,0'
        align='0.5,0.5,0'
        mountPoint='0.5,0.5,0' >

        <h1>{props.msg}</h1>

    </motor-node>
</motor-scene>
```

I noticed attached call backfires only when attached to the light tree (in Chrome). It breaks when I try to transclude things together (using `<content>`), for example:

shadowDOM:
```html
            <div>
                <motor-scene id="motor-scene">
                    <content selector="motor-node">
                    </content>
                </motor-scene>
            </div>
```

light DOM:
```html
    <foo-bar>
        <motor-node slot="content"
            absoluteSize='200,200,0'
            align='0.5,0.5,0'
            mountPoint='0.5,0.5,0' >

            <h1>{props.msg}</h1>

        </motor-node>
    </foo-bar>
```

And you can see, the expected is that the `motor-node` is placed inside the `motor-scene` (which is a requirement for things to work properly (preserve-3d, CSS transform caching, etc).

I noticed that the `attachedCallback` will be called when the `motor-node` exists in the light DOM, but not when it is put into it's new place. I guess this makes sense in the perspective of a component user who it attaching the `motor-node` into a `some-layout` for example, but for me (the component dev), I've stumbled, because my custom elements rely on their `attachedCallback`s in order to set themselves up: motor-nodes can only be children of motor-scene or other motor-node elements, and this is all detected with `attachedCallback` (and throws an error if this isn't the case). So, it seems like this design has shot me in the foot when it comes time to try and transclude things the web-components way.

In React, the same concept that I am trying to achieve would work just fine, because things in DOM are constructed for real in a single light DOM (so all the attaching/detaching) works just fine.

Unless I'm not seeing the full picture, it seems that if I want to make this work with Web Components that I need to have a component system that sites purely on top of the light DOM and not use shadow DOM (for example, React, or just Custom Elements but without using Shadow DOM inside them).

It also seems that if I want to allow my end users to use Shadow DOM to construct their own trees using my custom elements (which is a possibility), that I might have to have my own shadow wherein my entire scene graph is contained (so it behaves like a light DOM as far as I'm concerned inside of a scene's shadow root), and that I would need to be able to traverse all of the user's shadow dom roots in order to detect and construct a scene graph in my own shadow root. 

Basically, this seems like a huge undertaking that is almost completely not worth trying (compared to using something else like React). It seems like if we modified transclusion to behave like attaching (from light DOM) and re-attaching (into shadow DOM) along with firing `attached/detachedCallback` in those cases would let me do what I want to do, because those callbacks trigger calls that construct a tree structure parallel to the DOM structure (I would have to ignore the `<content>` elements, and besides warning about "motor-nodes need to be attached to motor-scene or motor-node elements` I would then also be able to warn about "motor-nodes can only be trancluded into motor-scene or motor-node elements"`. In React, we don't have to detect the transclusion case (as far as Custom Elements are concerned), and I would also argue Shadow DOM is not needed when making components with React but some people use it anyways (which I think is unnecessary extra complexity).

To show what my elements are doing visually, basically the attachedCallbacks are used to create a parallel tree structure where the `o`s are the motor-scene and motor-node elements:

```
       light DOM            parallel tree structure

            o                     o
            |                     |
            |                     |
       o----o----o    -->    o----o----o
            |    |                |    |
            o    |                o    |
                 o                     o
```

With transclusiong, this strategy for creating the behind-the-scenes tree structure is falling apart. I'll need the structure in order to be able to use that in WebGL (not just DOM). If I ignore WebGL, then I can get rid of my behind-the-scenes tree structure, and let DOM handle's it's own 3D scene graph entirely. Instead of holding matrix transforms in the behind-the-scenes structure, I would just place them right inside the custom element instances and be done with it. Simple.

I guess I'm just trying to figure out how to use transclusion the web components way. If I stick to React, the problem is easily solved: just let React attach all elements into light DOM, and I'm done with it. But, I don't want to settle with a solution like that then not be able to use my components in an Angular app (suppose I switch to a different project with new framework requirements, then I'd have to port the components or start from scratch). I want to truly write once, use everywhere.

Sorry that this is all somewhat random order, because I'm thinking as I go. [A-Frame](http://aframe.io) will have similar problems. I'll also ask there to see if anyone has thought about this.

*END GOAL: I want to build with WebComponents, not with a 3rd party lib like React, so that my elements can be used anywhere (React, Angular, Meteor, Ember, etc)*

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

Received on Sunday, 22 May 2016 17:57:18 UTC