[Custom Elements] Should I write v1 Custom Elements in a way backwards compatible with v0 API?

2016-08-20 Thread /#!/JoePea
ved for brevity...
}
attachedCallback() { this.connectedCallback() } // back-compat

disconnectedCallback() {
// code removed for brevity...
}
detachedCallback() { this.disconnectedCallback() } //
back-compat
}

classCache.set(elementClass, WebComponent)
    return WebComponent
}

Any thoughts?


*/#!/*JoePea


Re: [Custom Elements] Not requiring hyphens in names.

2016-04-22 Thread /#!/JoePea
Thanks for the link!

​I really believe that we should be allowed to name our elements with any
name we wish, and that they should override native elements (that is future
proof), and that overriding should be on some type of encapsulated basis
(for example, override within a shadow root and it won't affect other code
outside the shadow root).​


On Thursday, April 14, 2016, Takayoshi Kochi  wrote:

> Just FYI, the idea of allowing non-hyphen elements if they contain
> non-ASCII characters
> which probably won't collide with future HTML elements was posted in the
> discussion:
> https://github.com/w3c/webcomponents/issues/239#issuecomment-190603674
>
>
> On Fri, Apr 15, 2016 at 7:01 AM, /#!/JoePea  wrote:
>
>> On Wed, Apr 13, 2016 at 1:09 PM, Tab Atkins Jr. 
>> wrote:
>> > That means we lose the lingua franca that HTML provides; two
>> > independent libraries can't ever depend on the core HTML elements,
>> > because the other library might have overridden some of them.
>>
>> Based on my idea of registering elements on a per-shadow-root basis
>> (
>> https://discourse.wicg.io/t/proposal-register-custom-elements-onto-shadowdom-roots/1440
>> ),
>> then libraries could use any native or custom elements that they want
>> within their shadow roots. Shadow roots would provide encapsulation,
>> and element registrations would be scoped to those shadow roots.
>>
>> There are two possible ways to deal with element registrations on the
>> `document`:
>>
>> 1. Either elements registered on the `document` have effect across
>> shadow roots, but shadow roots can override these registrations:
>>
>> ```js
>> document.registerElement('foo-bar', SomeClass)
>> // ...
>> shadowRoot.registerElement('foo-bar', OtherClass) // takes precedence
>> over the document registration.
>> ```
>>
>> 2. Or, document registrations simply wouldn't cross the shadow root
>> boundary.
>>
>> I personally like the second option, leaving maximum control in the
>> hands of the developer, regardless of some global script registering
>> an element on the document that may encroach the scope of a shadow
>> root. If a shadow root author really wants the same element, there's
>> slightly more effort to also register that element with the shadow
>> root, but the overall control outweighs this extra effort in my
>> opinion.
>>
>> Then, if we add the ability to override native elements, we'll have
>> something powerful, IMO.
>>
>> ```js
>> // file1.js
>> import BetterImageWithWebGLFilters from 'better-img'
>> document.registerElement('img', BetterImageWithWebGLFilters)
>>
>> // file2.js
>> let s = el.createShadowRoot()
>> s.appendChild(document.createElement('img')) // uses native
>> HTMLImageElement because document registration stops at shadow root
>> boundary.
>>
>> // file3.js
>> import BetterImageWithWebGLFilters from 'better-img'
>> let s = el.createShadowRoot()
>> s.registerElement('img', BetterImageWithWebGLFilters)
>> s.appendChild(document.createElement('img')) // this person wants
>> BetterImageWithWebGLFilters in their shadow root
>>
>> // file4.js
>> let s = el.createShadowRoot()
>> s.registerElement('div', AwesomeClass) // this does not affect other
>> shadow roots or the document, it's contained within the shadow root.
>> ```
>>
>> This would be awesome I think. It'd allow for a level of encapsulation
>> and modularization on a shadow-root basis (which can paired with
>> Custom Elements very nicely).
>>
>> /#!/JoePea
>>
>>
>
>
> --
> Takayoshi Kochi
>


Re: [Custom Elements] Not requiring hyphens in names.

2016-04-14 Thread /#!/JoePea
On Wed, Apr 13, 2016 at 1:09 PM, Tab Atkins Jr.  wrote:
> That means we lose the lingua franca that HTML provides; two
> independent libraries can't ever depend on the core HTML elements,
> because the other library might have overridden some of them.

Based on my idea of registering elements on a per-shadow-root basis
(https://discourse.wicg.io/t/proposal-register-custom-elements-onto-shadowdom-roots/1440),
then libraries could use any native or custom elements that they want
within their shadow roots. Shadow roots would provide encapsulation,
and element registrations would be scoped to those shadow roots.

There are two possible ways to deal with element registrations on the
`document`:

1. Either elements registered on the `document` have effect across
shadow roots, but shadow roots can override these registrations:

```js
document.registerElement('foo-bar', SomeClass)
// ...
shadowRoot.registerElement('foo-bar', OtherClass) // takes precedence
over the document registration.
```

2. Or, document registrations simply wouldn't cross the shadow root boundary.

I personally like the second option, leaving maximum control in the
hands of the developer, regardless of some global script registering
an element on the document that may encroach the scope of a shadow
root. If a shadow root author really wants the same element, there's
slightly more effort to also register that element with the shadow
root, but the overall control outweighs this extra effort in my
opinion.

Then, if we add the ability to override native elements, we'll have
something powerful, IMO.

```js
// file1.js
import BetterImageWithWebGLFilters from 'better-img'
document.registerElement('img', BetterImageWithWebGLFilters)

// file2.js
let s = el.createShadowRoot()
s.appendChild(document.createElement('img')) // uses native
HTMLImageElement because document registration stops at shadow root
boundary.

// file3.js
import BetterImageWithWebGLFilters from 'better-img'
let s = el.createShadowRoot()
s.registerElement('img', BetterImageWithWebGLFilters)
s.appendChild(document.createElement('img')) // this person wants
BetterImageWithWebGLFilters in their shadow root

// file4.js
let s = el.createShadowRoot()
s.registerElement('div', AwesomeClass) // this does not affect other
shadow roots or the document, it's contained within the shadow root.
```

This would be awesome I think. It'd allow for a level of encapsulation
and modularization on a shadow-root basis (which can paired with
Custom Elements very nicely).

/#!/JoePea



Re: [Custom Elements] Not requiring hyphens in names.

2016-04-13 Thread /#!/JoePea
What if custom Elements simply override existing ones then?

```js
shadowRoot.registerElement('div', MyElement)
```

If overriding native elements was documented, it'd be fine. By
default, a blank document or shadow root has no elements registered,
so  would use the native DIV. But, why not let the user define
what a  is? There could optionally be a warning outputted to
console:

```
Warning: DIV was overridden: /path/to/some/file.js:123:4
```

^ shows where is happens so an end user can easily find and remove the
culprit if that is ever a problem. In JavaScript, we can override many
of the things on the global `window` object. It's the developer's job
to add (or remove) scripts that modify their `window` properties. Why
not give the same level of flexibility with DOM elements? ,
, etc, can just be treated as global variables, overridable.  I
don't think that would do too much harm.

Being able to override on a shadow-root basic could encapsulate the
cases where such overriding is needed.

Being able to override native elements would make some interesting use
cases possible too, like providing alternate functionality to
commonly-used elements without having to touch existing markup of an
existing app. For example, AMP's  element could just be
.

TLDR: browsers would still be able to add new native elements, while
users would be able to override them. Why not? Allowing this won't
break the web (since nothing is currently overridden to begin with).
Let's make both browser makers and web app authors live's better as
much as possible at the same time. Being able to override elements
would be such a compromise: browser developers can add new default
elements, while web app authors can choose to use them or not, or to
override them.

Riot.js likes not requiring hyphens too!
/#!/JoePea


On Wed, Apr 13, 2016 at 11:53 AM, Nick Dugger  wrote:
> I personal don't mind the hyphenation requirement for custom elements. Tab
> Atkins brings up a great point about ensuring that new elements will be able
> to be added to spec without worry of name conflicts with existing custom
> elements on the page. It's much more future proof, in my opinion.
>
> On Wed, Apr 13, 2016 at 1:12 PM, /#!/JoePea  wrote:
>>
>> I personally don't like this limitation. I think Custom Elements would
>> be better if we could create elements that have   
>>  , with the possible exception that we can't override the
>> native elements.
>>
>> Based on my previous email about registering elements on shadow roots,
>> I think being able to choose any name would make things just cleaner:
>>
>> ```js
>> //  --- SomeElement.js
>> import MyElement from './MyElement'
>>
>> export default
>> class SomeElement extends HTMLElement {
>> constructor() {
>> this.root = this.createShadowRoot()
>> this.root.registerElement('MyElement', MyElement) //
>>  or 
>>
>> const frag = document.createDocumentFragment()
>> frag.innerHTML = `
>> 
>>   
>>   ...
>>   
>> 
>> `
>> this.root.appendChild(frag)
>> }
>>
>> static get observedAttributes() { return [ ... ] }
>> connectedCallback() { ... }
>> disconnectedCallback() { ... }
>> attributeChangedCallback() { ... }
>> }
>>
>> //  --- app.js
>> import SomeElement from './SomeElement'
>>
>> // elements registered on the document won't cross into shadow roots
>> document.registerElement('SomeElement', SomeElement)
>> document.body.appendChild(document.createElement('someelement'))
>> ```
>>
>> /#!/JoePea
>>
>



[Custom Elements] Not requiring hyphens in names.

2016-04-13 Thread /#!/JoePea
I personally don't like this limitation. I think Custom Elements would
be better if we could create elements that have   
 , with the possible exception that we can't override the
native elements.

Based on my previous email about registering elements on shadow roots,
I think being able to choose any name would make things just cleaner:

```js
//  --- SomeElement.js
import MyElement from './MyElement'

export default
class SomeElement extends HTMLElement {
constructor() {
this.root = this.createShadowRoot()
this.root.registerElement('MyElement', MyElement) //
 or 

const frag = document.createDocumentFragment()
frag.innerHTML = `

  
  ...
  

`
this.root.appendChild(frag)
}

static get observedAttributes() { return [ ... ] }
connectedCallback() { ... }
disconnectedCallback() { ... }
attributeChangedCallback() { ... }
}

//  --- app.js
import SomeElement from './SomeElement'

// elements registered on the document won't cross into shadow roots
document.registerElement('SomeElement', SomeElement)
document.body.appendChild(document.createElement('someelement'))
```

/#!/JoePea



Re: [Custom Elements] They are globals.

2016-04-12 Thread /#!/JoePea
On Mon, Apr 11, 2016 at 4:44 PM, Ryosuke Niwa  wrote:
> You'd have to instead write it as "new SomeClass(this.shadowRoot)" and then 
> (1) needs to be modified as: `super(..arguments)` to pass the argument along 
> to the HTMLElement constructor.

For sure, similar to the examples in the GitHub issue. :]

React doesn't encourage the instantiation of element classes directly.
What if browsers did that too and threw errors whenever someone tried
to instantiate a class using `new` that extended from any of the
native classes:

```js
import {SomeElement} from 'some-library'

// this would cause a `TypeError: Illegal constructor` or something
let el = new SomeElement()

// does not return a constructor
shadowRoot1.registerElement('any-name', SomeElement)

// only this instantiation method is allowed
let el1 = shadowRoot1.createElement('any-name')

// we can use the same class in a different component where
//  is already defined but isn't backed by SomeElement
shadowRoot2.registerElement('other-name', SomeElement)
let el2 = shadowRoot2.createElement('other-name')

// maybe this should throw an error instead of returning
// HTMLUnknownElement, otherwise it might hide the obvious
// human error instead teaching the developer
shadowRoot1.registerElement('a-name', SomeElement)
let el3 = shadowRoot2.createElement('a-name')

// this would cause an error because el1 was created from
// shadowRoot1 so el1 doesn't work in shadowRoot2
shadowRoot2.appendChild(el1)
```

ShadowDOM is still evolving and the Web Component spec hasn't
officially settled, so I think there's a good opportunity here for the
web to be more helpful by throwing errors and not being ambiguous as
for example in `document.createElement('ths-has-a-typo')`.

TLDR - ShadowDOM could be the encapsulation of HTML to Custom Elements
as JSX is the encapsulation of HTML to React Components (in a morphed
way, as obviously the mechanics are different).

Here's what a small component might look like:

```js
//  --- HandyForm.js
import AwesomeButton from './AwesomeButton'
import { FancyForm, FancyInput } from './FancyForm'

export default
class HandyForm extends HTMLElement {
constructor() {
this.root = this.createShadowRoot()
this.root.registerElement('', AwesomeButton)
this.root.registerElement('', FancyForm)
this.root.registerElement('', FancyInput)

const frag = document.createDocumentFragment()
frag.innerHTML = `


 



`
this.root.appendChild(frag)
}

static get observedAttributes() { return [ ... ] }

connectedCallback() { ... }
disconnectedCallback() { ... }
attributeChangedCallback() { ... }
}

//  --- app.js
import HandyForm from './HandyForm'

// elements registered on the document won't cross into shadow roots
document.registerElement('handy-form', HandyForm)
document.body.appendChild(document.createElement('handy-form'))
```

- Joe

/#!/JoePea



Re: [Custom Elements] They are globals.

2016-04-11 Thread /#!/JoePea
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`
  
  <${SomeClass}>
  <${OtherClass}>
  
  
  
`
```
/#!/JoePea


On Mon, Apr 11, 2016 at 11:25 AM, Domenic Denicola  wrote:
> I think you are being misled by a superficial similarity with React's JSX.
>
> JSX's `` desugars to `React.createElement(Foo)`, which creates a `` 
> 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' `` 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.
>



Re: [Custom Elements] More ES6-like API

2016-04-11 Thread /#!/JoePea
Thanks Ryosuke! That's looking a lot better.
/#!/JoePea


On Mon, Apr 11, 2016 at 10:28 AM, Ryosuke Niwa  wrote:
> That's exactly what we're doing. The latest spec uses ES6 class constructor 
> to define custom elements. See an example below this section in DOM spec: 
> https://dom.spec.whatwg.org/#concept-element-custom-element-state
>
> - R. Niwa
>
>> On Apr 10, 2016, at 7:58 PM, /#!/JoePea  wrote:
>>
>> It'd be nice if users could define actual constructors, as described here:
>>
>> https://github.com/w3c/webcomponents/issues/423#issuecomment-208131046
>>
>> Cheers!
>> - Joe
>>
>> /#!/JoePea
>>



[Custom Elements] They are globals.

2016-04-11 Thread /#!/JoePea
Hello,

Is it possible to take an approach more similar to React where Custom
Elements aren't registered in a global pool? What if two libraries we'd
like to use define elements of the same name, and we wish to import these
via `import` and not modify the source code of our dependencies?

I don't really see the solution yet (if any), since the browser needs to
know about the elements in order to make them work.

Any thoughts? Is a more encapsulated approach possible?

Regards,
- Joe


-- 
/#!/JoePea


Re: [Custom Elements] Extension of arbitrary elements at runtime.

2016-04-11 Thread /#!/JoePea
Hello Brian

The purpose of the motor-scene and motor-node elements is that they will be
easy to apply 3D transforms to (and WebGL soon), with easing for example. I
suppose a better approach for augmenting and existing DOM could be to
simply apply the transforms via selectors instead of trying to apply the
behavior via extending with is="". This wouldn't allow custom attributes
though, like extending would.

I think the best solution, for now, is as you recommended: to add the
layers if possible.

Thanks for the input!
- Joe

On Monday, April 11, 2016, Brian Kardell  wrote:

>
>
> On Sun, Apr 10, 2016 at 11:11 PM, /#!/JoePea  > wrote:
>
>> The is="" attribute lets one specify that some element is actually an
>> extended version of that element.
>>
>> But, in order for this to work, the Custom Element definition has to
>> deliberately extend that same basic element type or else it won't
>> work.
>>
>> It'd be nice if a Custom Element definition could be arbitrarily
>> applied to any type of element, with the is="" tag for example, and
>> that the element would then be upgraded to the extending type at
>> runtime. The custom element could be told what class it is extending
>> at runtime in order to perhaps act differently using conditional
>> statements.
>>
>> So, writing defining the element could be like this:
>>
>> ```js
>> let isDynamic = true
>> document.registerElement('some-element', {
>>   createdCallback: function() {
>> if (this.typeExtended == 'DIV")
>>   // ...
>> if (this.typeExtended == 'BUTTON')
>>   // ...
>>   },
>> }, isDynamic)
>> ```
>>
>> then using the element could be like this:
>>
>> ```html
>> 
>> 
>> 
>> ```
>>
>> What are your thoughts on such a way to extend any type of element at
>> runtime? Could it be a way for augmenting, for example, an existing
>> app without necessarily having to modify it's markup, just simply
>> adding is="" attributes as needed? Would this make things too
>> complicated?
>>
>> The real reason I thought of this idea is because:
>> https://github.com/infamous/infamous/issues/5
>>
>> There might be a better way, but thought I'd mention it just in case
>> it sparks any ideas.
>>
>> Cheers!
>> - Joe
>>
>> /#!/JoePea
>>
>>
>
> Is there a reason that you cannot wrap with fallback?  For example, in
> your github issue you are given and existing app with markup like:
>
> 
>   
> Hello
>   
>
>
> and the issue wanted to change it to
>
> 
>   
> Hello
>   
>
>
> Is there a reason it could it not just be
>
> 
>   
>   
> Hello
> 
> 
>
>
> There isn't really a significant difference between div and motor-scene to
> non-supporting browsers.
>
>
> --
> Brian Kardell :: @briankardell
>


-- 
/#!/JoePea


[Custom Elements] Extension of arbitrary elements at runtime.

2016-04-10 Thread /#!/JoePea
The is="" attribute lets one specify that some element is actually an
extended version of that element.

But, in order for this to work, the Custom Element definition has to
deliberately extend that same basic element type or else it won't
work.

It'd be nice if a Custom Element definition could be arbitrarily
applied to any type of element, with the is="" tag for example, and
that the element would then be upgraded to the extending type at
runtime. The custom element could be told what class it is extending
at runtime in order to perhaps act differently using conditional
statements.

So, writing defining the element could be like this:

```js
let isDynamic = true
document.registerElement('some-element', {
  createdCallback: function() {
if (this.typeExtended == 'DIV")
  // ...
if (this.typeExtended == 'BUTTON')
  // ...
  },
}, isDynamic)
```

then using the element could be like this:

```html



```

What are your thoughts on such a way to extend any type of element at
runtime? Could it be a way for augmenting, for example, an existing
app without necessarily having to modify it's markup, just simply
adding is="" attributes as needed? Would this make things too
complicated?

The real reason I thought of this idea is because:
https://github.com/infamous/infamous/issues/5

There might be a better way, but thought I'd mention it just in case
it sparks any ideas.

Cheers!
- Joe

/#!/JoePea



[Custom Elements] More ES6-like API

2016-04-10 Thread /#!/JoePea
It'd be nice if users could define actual constructors, as described here:

https://github.com/w3c/webcomponents/issues/423#issuecomment-208131046

Cheers!
- Joe

/#!/JoePea