Dimitri - yes, timeanddate.com agrees: 09:30 Shenzhen = 10:30 Tokyo = 17:30 San 
Francisco. The pin will be 9274# and we will use the #webapps channel.

-TTYS, ArtB

Sent from my Windows Phone
________________________________
From: ext Dimitri Glazkov<mailto:[email protected]>
Sent: ‎11/‎12/‎2013 8:13 AM
To: Barstow Art (Nokia-CIC/Boston)<mailto:[email protected]>
Cc: ext Ryosuke Niwa<mailto:[email protected]>; Dominic 
Cooney<mailto:[email protected]>; [email protected] 
WG<mailto:[email protected]>; Elliott Sprehn<mailto:[email protected]>
Subject: Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative 
Syntax


On Sun, Nov 10, 2013 at 6:49 PM, Arthur Barstow 
<[email protected]<mailto:[email protected]>> wrote:
Hi Dimitri, Dominic,

Ryosuke is here in Shezhen at WebApps' f2f meeting. We would like to have one 
or both of you join us (via voice conference) on Tuesday morning to talk about 
Web Components and his comments below.

Please look at the agenda page and let us know your availability for the one of 
the open slots before lunch (all times are local to Shenzhen):

<http://www.w3.org/wiki/Webapps/November2013Meeting#Agenda_Tuesday_November_12>

I dropped something at 9:30am. I think that's 5:30pm Mountain View and 10:30am 
Tokyo, right?


-Thanks, ArtB


On 11/9/13 3:24 AM, ext Ryosuke Niwa wrote:
Hi all,

We have been discussing cross-orign use case and declarative syntax of web 
components internally at Apple, and here are our straw man proposal to amend 
the existing Web Components specifications to support it.

*1. Modify HTML Imports to run scripts in the imported document itself*

This allows the importee and the importer to not share the same script context, 
etc…


This could be an option and shouldn’t be the default. By running scripts in a 
different context, we are ejecting the primary use case of enabling 
frameworks/libraries to better manage their assets and dependencies (aka the 
Bootstrap use case).

Rob Dodson’s article has a nice progression explaining the use case: 
http://robdodson.me/blog/2013/08/20/exploring-html-imports/

Also, check out newly minted Eric Bidelman's article on imports (especially the 
use cases section at the bottom): 
http://www.html5rocks.com/en/tutorials/webcomponents/imports/

Re: Custom Elements LC, this is an issue to handle in HTML Imports 
specification, not related to Custom Elements.


*2. Add “importcomponents" content attribute on link element*

It defines the list of custom element tag names to be imported from the 
imported HTML document.
e.g. <link rel="import" href="~" importcomponents="tag-1 tag-2"> will export 
custom elements of tag names "tag-1" and "tag-2" from ~. Any name that didn't 
have a definition in the import document is ignored (i.e. if "tag-2" was not 
defined in ~, it would be skipped but "tag-1" will be still imported).

This mechanism prevents the imported document from defining arbitrary 
components in the host document.

Re: Custom Elements LC, this should be handled in HTML Imports specification. 
HTML Imports can rely on Custom Elements specification. Any additional hooks 
that could be needed to facilitate this feature could be added in Custom 
Elements Level 2 specification.


*3. Support "static" (write-once) binding of a HTML template*

e.g.
<template id=cardTemplate>Name: {{name}}<br>Email:{{email}}</template>
<script>
document.body.appendChild(cardTemplate.instantiate({name: "Ryosuke Niwa", 
email:"[email protected]<mailto:[email protected]> 
<mailto:[email protected]<mailto:[email protected]>>"}));
</script>

This seems very similar to the Rafael Weinstein's MDV work. You guys should 
collaborate :)

Re: Custom Elements LC, this is unrelated to specification.

*4. Add “interface" content attribute to template element*

This content attribute specifies the name of the JavaScript constructor 
function to be created in the global scope. The UA creates one and will be used 
to instantiate a given custom element. The author can then setup the prototype 
chain as needed:

<template defines="name-card" interface="NameCardElement">
Name: {{name}}<br>Email:{{email}}
</template>
<script>
NameCardElement.prototype.name<http://NameCardElement.prototype.name> = 
function () {...}
NameCardElement.prototype.email = function () {...}
</script>

This is similar to doing:
var NameCardElement = document.register(’name-card');

This is another take on the declarative custom elements (a variant of [1]). 
This particular approach has four problems that the WG was able to resolve (at 
least the first three) in previous iterations:

1) It is not friendly to ES6 classes. In fact, you can't use class syntax and 
this syntax together.

2) It couples templates, shadow DOM, and custom elements in a way that's highly 
opinionated and inflexible. Throughout this year, we've tried many various ways 
to get this right, and failed [2]. I highly recommend that we avoid putting 
this into a specification now. Instead, we should let the best practices evolve 
and build on the cowpaths.

3) The approach pollutes global name space with constructors. This had been 
voiced many times as unacceptable by developers.

4) How does build a custom element that uses <name-card> as its base element? 
What about <div> or any other HTML element?

The last one remains to be the hardest. The tortured inheritance support is 
what killed <element> in the first place. We can't ignore the inheritance, 
since it is clearly present, in both DOM and JS. If we attempt to punt on 
supporting it, our decisions cut off the opportunities to evolve this right in 
the future, and will likely leave us with boogers like multiple syntaxes for 
inheritance vs. non-inheritance use cases.

I recommend studying the work the WG had already done here to avoid stepping on 
the same rakes.

Re: Custom Elements LC, this functionality should be entirely defined as part 
of <template>, relying on the Custom Elements specification. No changes to 
Custom Elements specification are needed.

[1]: 
http://lists.w3.org/Archives/Public/public-webapps/2013AprJun/thread.html#msg75
[2]: 
http://lists.w3.org/Archives/Public/public-webapps/2013JulSep/thread.html#msg287

*5. Add "defines" content attribute on HTML template element to define a custom 
element*

This new attribute defines a custom element of the given name for the template 
content.
e.g. <template defines="nestedDiv"><div><div></div></div></template> will let 
you use <nestedDiv></nestedDiv>

We didn’t think having a separate custom element was useful because we couldn’t 
think of a use case where you wanted to define a custom element declaratively 
and not use template by default, and having to associate the first template 
element with the custom element seemed unnecessary complexity.

Re: Custom Elements LC, this functionality should be entirely defined as part 
of <template>, relying on the Custom Elements specification. No changes to 
Custom Elements specification are needed.

As an aside, there were several Polymer users who had live code that used 
multiple templates and runtime logic to manage them, and various other 
scenarios [1], [2], [3].

[1]: https://github.com/Polymer/polymer/issues/222
[2]: https://github.com/Polymer/polymer/issues/156
[3]: https://github.com/Polymer/polymer/issues/157

*5.1. When a custom element is instantiated, automatically instantiate template 
inside a shadow root after statically binding the template with dataset*

This allows statically declaring arguments to a component.
e.g.
<template defines="name-card">Name: {{name}}<br>Email:{{email}}</template>
<name-card data-name="Ryosuke Niwa" 
data-email="[email protected]<mailto:[email protected]> 
<mailto:[email protected]<mailto:[email protected]>>”>

This is a cool idea, though coupling moustaches, templates, custom elements, 
and data sets brings sadness. There are several library/framework authors who 
will cry foul, since they rely on {{}} as their placeholders. Rafael Weinstein 
have been working on this problem for several years now, it might be good to 
work with him on something more flexible.

Re: Custom Elements LC, this functionality should be entirely defined as part 
of <template>, relying on the Custom Elements specification. No changes to 
Custom Elements specification are needed.

*5.2. When a new custom element object is constructed, "created" callback is 
called with a shadow root*

Unfortunately, we can't let the author define a constructor because the element 
hadn't been properly initialized with the right JS wrapper at the time of its 
construction. So just like we can't do "new HTMLTitleElement", we're not going 
to let the author do an interesting things inside a custom element's 
constructor. Instead, we're going to call "created" function on its prototype 
chain:

<template defines="name-card" interface="NameCardElement">
Name: {{name}}<br>Email:{{email}}
</template>
<script>
NameCardElement.prototype.name<http://NameCardElement.prototype.name> = 
function () {...}
NameCardElement.prototype.email = function () {...}
NameCardElement.prototype.created = function (shadowRoot) {
... // Initialize the shadowRoot here.
}
</script>

This is similar to the way document.register works in that document.register 
creates a constructor automatically.

We can't assume that Shadow DOM and Custom Elements are only used together. 
There is already one framework already in existence that uses Custom Elements, 
but not Shadow DOM [1], and we've already travelled this path [2], [3].

Re: Custom Elements LC, we should not add this argument to "created" callback, 
because this will lead to coupling Custom Elements with Shadow DOM 
specification. Your template proposal could easily add a new 
"shadowTreeCreated" callback that is invoked with this argument. The timing of 
this invocation would be specified in the respective specification (which I 
think is the HTML spec, since <template> had just moved there).

[1]: http://mozilla.github.io/brick/
[2]: http://lists.w3.org/Archives/Public/public-webapps/2013JanMar/0521.html
[3]: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18748

*6. The cross-origin component does not have access to the shadow host element, 
and the host document doesn’t have access to the element object.*

When member functions of the element is called, “this” object will be 
undefined. This is necessary because exposing the object to a cross-origin 
content will result in tricky security issues, forcing us to have proxy 
objects, etc…

Inside the document that imported a component, the element doesn’t use the 
prototype defined by the component as that exposes JS objects cross-origin. 
e.g. even if LikeButtonElement was defined in 
facebook.com/~/like-button.html<http://facebook.com/~/like-button.html> 
<http://facebook.com/%7E/like-button.html>, the document that uses this 
component wouldn’t see the prototype or the constructor. It’ll be 
HTMLUnknownElement. (We could create a new custom element type such as 
HTMLCrossOriginCustomElement if think that’s necessary).

I suspect that the boundary you're drawing at the custom element layer is going 
to give you more trouble than it's worth. There are already notions of proxy 
elements/HTMLKnownElements, which is just pure magic.

Fortunately, there is already a boundary that we built that might be just the 
right fit for this problem: the shadow DOM boundary. A while back, we had lunch 
with Mozilla security researchers who were interested in harnessing the power 
of Shadow DOM, and Elliott (cc'd) came up with a pretty nifty proposal called 
the DOMWorker. I nagged him and he is hopefully going to post it on 
public-webapps. I am pretty sure that his proposal can address your use case 
and not cripple the rest of the spec in the process.

Re: Custom Elements LC, if still necessary, this proposal is something that 
should be investigated in Level 2 of the specification, as an additional 
ability of custom elements.

*7. Expose shadow host’s dataset on shadow root*

This allows the component to communicate with the host document in a limited 
fashion without exposing the element directly.

This design allows us to have an iframe-like boundary between the shadow host 
(custom element itself) and the shadow root (implementation details), and 
address our cross-origin use case elegantly as follows:

rniwa.com/webkit.html<http://rniwa.com/webkit.html> 
<http://rniwa.com/webkit.html>

---------------------------------
<!DOCTYPE html>
<html>
<head>
<link rel=import href="https://webkit.org/components.html"; 
defines="share-button like-button">
</head>
<body>
<like-button data-url="https://build.webkit.org/";>Like 
build.webkit.org<http://build.webkit.org> 
<http://build.webkit.org></like-button>
</body>
</html>

webkit.org/components.html<http://webkit.org/components.html> 
<http://webkit.org/components.html>

---------------------------------
<template defines="like-button" interface="LikeButtonElement">
<!-- implicitly does 
shadowRoot.appendChild(myTemplate.instantiate(shadowHost.dataset)); -->
<form ...>
<input type=hidden value="{{url}}">
<button type=submit>Like!</button>
</form>
<script>
LikeButtonElement.prototype.created = function (shadowRoot) {
shadowRoot.query('form').onsubmit = function () {
// ...
}
}
</script>
</template>

Re: Custom Elements LC, this seems like something that would be part of the 
Shadow DOM specification.

All in all, I sympathize with the use case and applaud the effort and 
attention, but we should be careful not to discard our abilities to address the 
use cases we are already solving. We live in an over-constrained world :)

:DG<

Reply via email to