- From: /#!/JoePea <trusktr@gmail.com>
- Date: Mon, 11 Apr 2016 14:29:01 -0700
- To: Domenic Denicola <d@domenic.me>, Ryosuke Niwa <rniwa@apple.com>
- Cc: "public-webapps@w3.org" <public-webapps@w3.org>
I get what you mean about the behaviors defined from classes that exist in the scope, in React. The really great thing about React is the ability to compose a class by using multiple classes to return the render spec. One of React's strong-points at a high level is it offers encapsulation where the components used in the HTML (which don't map directly to the actual DOM result that the browser is finally given) are specific to the component, encapsulated there. The current methods of encapsulation that I see with normal HTML are documents and shadow roots, where shadow roots seem to be closer to React than documents because the top-level HTML that we inspect in the DOM may not be what is actually rendered (like with React), although the implementation is completely different, but at a high level shadow dom has that small similarity with React. So, to make code-reuse as possible as it is with React (due to React's aforementioned encapsulation and use of the JavaScript scopefor it's "HTML elements"), maybe the Custom Element API can take advantage of ShadowDOM instead of documents? What if custom elements can be registered on a shadow-root basis, so that the author of a Custom Element (one that isn't registered by default) can register a bunch of elements that it's shadow root will use, passing constructors that the author code may have imported from anywhere. Then that same author simply exports the custom element (does not register it) for a following author to use. The following author would import that custom element, then register it with the shadow roots of his/her new custom elements, and thus the cycle continues, with registered elements defined on shadow roots on a per-custom-element basis, without those elements ever being registered to some global registry. ``` // library code import SomeClass from './somewhere' export default class AuthorElement extends HTMLElement { constructor() { this.shadowRoot.defineElement( 'authors-should-call-this-anything-they-want', SomeClass ) // ... } } ``` Then, finally, the top-level app author can register the top-most custom elements using an API similar to current, in the top-level namespace (global scope) for the window or document. ``` // app code import AuthorElement from './AuthorElement' document.defineElement( 'any-name-the-app-author-wants', SomeClass ) ``` So, basically, inaddition to global/window-or-document-based elements there'd also be shadow root definitions for encapsulation, since shadow roots are to custom elements as what (slightly stretched) JSX specs are to React components. An important part of the Custom Element API would be that Custom Element authors should never register their Custom Elements globally, only export them for the user of their custom element to register them. The final top-level app author would register only the elements that will be used in the top-level HTML of the app, all other elements already registered in their shadow roots by the authors of each element. Something like this would create a development environment much more similar to React, having encapsulation and making code more re-usable. The only downside of this approach would be the need to manually register elements per-shadow-root, not just importing them (in react, importing is enough, as the JSX uses the JavaScript scope as the element registry). On a side note, interestingly, template string tag functions would let us take advantage of JavaScript scope directly without build tools: ``` import SomeClass from './SomeClass' import OtherClass from './OtherClass' html` <div> <${SomeClass}> <${OtherClass}> </${OtherClass}> </${SomeClass}> </div> ` ``` /#!/JoePea On Mon, Apr 11, 2016 at 11:25 AM, Domenic Denicola <d@domenic.me> wrote: > I think you are being misled by a superficial similarity with React's JSX. > > JSX's `<Foo>` desugars to `React.createElement(Foo)`, which creates a `<div>` element with some of its behavior derived from the `Foo` class, found in JavaScript lexical scope. The `Foo` token has no impact on the DOM tree. > > Custom elements' `<x-foo>` is completely unlike that. In that case, `x-foo` is a tag name, and a full participant in the DOM tree structure. It affects CSS selector matching, APIs like querySelector and getElementsByTagName, and more. It's not just a div. > > As Ryosuke notes, it's very hard to imagine how "scoped tag names" would work. Both for implementation reasons, like the HTMLElement constructor, but also for cases like CSS or the DOM APIs, which operate fundamentally on a global mapping. >
Received on Monday, 11 April 2016 21:30:09 UTC