Re: [webcomponents] Imperative API for Insertion Points

2014-02-18 Thread Erik Bryn
On Mon, Feb 17, 2014 at 11:03 AM, Edward O'Connor wrote:

> I think Ryosuke's .add/remove are a better base layer than
> . In fact,  is straightforwardly
> implementable / explainable on top of MO + .add/remove, but
> there are several use cases that .add/remove address that are
> difficult or impossible with  (as described in Maciej's
> recent email on this thread).
>

I agree. As a contributor to a major JS framework, I was shocked by the
lack of an imperative API and that  was even a thing.

- Erik


Re: [webcomponents] Imperative API for Insertion Points

2014-02-17 Thread Edward O'Connor
Hi Alex,

You wrote:

> This doesn't seem like progress. I'd hope an imperative API would,
> instead, be used to explain how the existing system works and then
> propose layering that both accommodates the existing system and opens
> new areas for programmatic use.

I think Ryosuke's .add/remove are a better base layer than
. In fact,  is straightforwardly
implementable / explainable on top of MO + .add/remove, but
there are several use cases that .add/remove address that are
difficult or impossible with  (as described in Maciej's
recent email on this thread).


Ted



Re: [webcomponents] Imperative API for Insertion Points

2014-02-16 Thread Ryosuke Niwa

> On Feb 16, 2014, at 1:21 AM, Alex Russell  wrote:
> 
>> On Sun, Feb 16, 2014 at 12:52 AM, Ryosuke Niwa  wrote:
>>> On Feb 16, 2014, at 12:42 AM, Ryosuke Niwa  wrote:
>>> 
 On Feb 15, 2014, at 11:30 PM, Alex Russell  wrote:
 
> On Sat, Feb 15, 2014 at 4:57 PM, Ryosuke Niwa  wrote:
> Hi all,
> 
> I’d like to propose one solution for
> 
> [Shadow]: Specify imperative API for node distribution
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429
> 
> because select content attribute doesn’t satisfy the needs of 
> framework/library authors to support conditionals in their templates,
> and doesn’t satisfy my random image element use case below.
> 
> 
> == Use Case ==
> Random image element is a custom element that shows one of child img 
> elements chosen uniformally random.
> 
> e.g. the markup of a document that uses random-image-element may look 
> like this:
> 
>   
>   
>   
> 
> 
> random-image-element displays one out of the three img child elements 
> when a user clicks on it.
> 
> As an author of this element, I could modify the DOM and add style 
> content attribute directly on those elements
> but I would rather use shadow DOM to encapsulate the implementation.
> 
> 
> == API Proposal ==
> 
> Add two methods void add(Element) and void remove(Element) to content 
> element.
> (We can give them more descriptive names. I matched select element for 
> now).
> 
> Each content element has an ordered list of *explicitly inserted nodes*.
> 
> add(Element element) must act according to the following algorithm:
> If the content element's shadow host's node tree doesn't contain 
> _element_, throw HierarchyRequestError.
> If element is already in some other content element's _explicitly 
> inserted nodes_
> then call remove with _element_ on that content element.
> Append _element_ to the end of _explicitly inserted nodes_.
> 
> remove(Element element) must act according to the following algorithm:
> If the content element's _explicitly inserted nodes_ does not contain 
> _element_, throw NotFoundError.
 
 Throwing exceptions is hostile to usability.
>>> 
>>> If people are so inclined, we don’t have to throw an exception and silently 
>>> fail.
> Remove _element_ from _explicitly inserted nodes_.
> 
> The idea here is that _explicitly inserted nodes_ of an insertion point A 
> would be the list of distributed nodes of A but
> I haven't figured out exactly how _explicitly inserted nodes_ should 
> interact with select content attribute.
> 
> I think the simplest model would be _explicitly inserted nodes_ simply 
> overriding whatever select content attribute was
> trying to do but I don't have a strong opinion about how they should 
> interact yet.
> 
> I don't think it makes sense to support redistributions, etc... at least 
> in the initial API.
> 
> 
> This proposal has an advantage over the existing proposal on 
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429:
> It doesn't require UA calling back to JS constantly to match elements
> Point 1 implies we don't expose when distribution happens for select 
> content attribute.
 This doesn't seem like progress. I'd hope an imperative API would, 
 instead, be used to explain how the existing system works and then propose 
 layering that both accommodates the existing system and opens new areas 
 for programmatic use.
 
 We can imagine such a system for programmatic Shadow DOM with some sort of 
 distribute(Element) callback that can be over-ridden and use add/remove 
 methods to do final distribution.
>>> 
>>> The problem here is that such a callback must be called on every node upon 
>>> any state change because UAs have no way of knowing what causes 
>>> redistribution for a given component.  As as a matter of fact, some use 
>>> cases may involve changing the node distributions based on some JS objects 
>>> state.  And having authors codify such conditions for UAs is much more 
>>> cumbersome than letting them re-distribute nodes at their will.
>> 
>> To give you more concrete example, in the case of my random image element, 
>> how can UA notice that user clicking on the element should trigger 
>> reconstruction of the composed tree?
> 
> Isn't the stated design of the custom element that it re-constructs the 
> composed tree with a random image every time it's clicked? It's not actually 
> clear what you wanted here because there isn't any example code to go on.
>  
>>  Should the script call some method like redistribute() on the host upon 
>> click?  But then, since the element needs to pick a child uniformly random, 
>> it probably needs to keep track of the number of children to be distributed 
>> and retur

Re: [webcomponents] Imperative API for Insertion Points

2014-02-16 Thread Maciej Stachowiak
On Feb 15, 2014, at 4:57 PM, Ryosuke Niwa  wrote:Hi all,I’d like to propose one solution for[Shadow]: Specify imperative API for node distributionhttps://www.w3.org/Bugs/Public/show_bug.cgi?id=18429because select content attribute doesn’t satisfy the needs of framework/library authors to support conditionals in their templates,and doesn’t satisfy my random image element use case below.== Use Case ==Random image element is a custom element that shows one of child img elements chosen uniformally random.e.g. the markup of a document that uses random-image-element may look like this:      random-image-element displays one out of the three img child elements when a user clicks on it.As an author of this element, I could modify the DOM and add style content attribute directly on those elementsbut I would rather use shadow DOM to encapsulate the implementation.I wanted to mention that this handles other use cases besides selecting a random child which are impossible (or at least very awkward) with  as presently defined:(1) A container component that can hold an arbitrary number of children, and wraps each of its light DOM children in a piece of markup inside the Shadow DOM. Consider a  component that placed each child into a , and styled them all specially:    I    UImagine it would render like this (explaining why separate individual  elements won't cut it).(2) A component that expects alternate labels and corresponding items, wants to parent them into different boxes, but wants to make sure they remain corresponding.    Puppies     lots of pictures of puppies     Kittens     lots of pictures of kittens     Sadness        Bunnies     lots of pictures of bunnies ...The component author would like this to render as a tabview with 4 tab labels at the top ("Puppies", "Kittens", "Sadness", "Bunnies") and 3 actual tab panes with one placeholder inserted: (the puppy pane, the kitten pane, a blank placeholder, the bunny pane).But if my shadow DOM looks like this:Then the pictures of bunnies would line up with the "Sadness" label, and I don't have an easy way to add the placeholder anywhere but at the beginning or the end of the tab panes.(3) An element that selects some of its children conditionally. Let's say you have an element that will select different children depending on what features the browser supports:    Spiffy WebGL view goes here!    Passable 2-D canvas view goes here    Oh noes! You need more browser features to use this site!The idea is to select in only exactly one of the cases - the first that matches. The others don't go into the shadow DOM. There isn't a great way to select only one of the "case" elements here (after having run the JS to evaluate which applies).The SVG "switch" element does something similar, as does Modernizr's normal class-based mode of operation.I hope these examples give more motivation for why programmatically binding an insertion point may be useful. Regards,Maciej

Re: [webcomponents] Imperative API for Insertion Points

2014-02-16 Thread Ryosuke Niwa

> On Feb 15, 2014, at 4:57 PM, Ryosuke Niwa  wrote:
> 
> Hi all,
> 
> I’d like to propose one solution for
> 
> [Shadow]: Specify imperative API for node distribution
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429
> 
> because select content attribute doesn’t satisfy the needs of 
> framework/library authors to support conditionals in their templates,
> and doesn’t satisfy my random image element use case below.
> 
> 
> == Use Case ==
> Random image element is a custom element that shows one of child img elements 
> chosen uniformally random.
> 
> e.g. the markup of a document that uses random-image-element may look like 
> this:
> 
>   
>   
>   
> 
> 
> random-image-element displays one out of the three img child elements when a 
> user clicks on it.
> 
> As an author of this element, I could modify the DOM and add style content 
> attribute directly on those elements
> but I would rather use shadow DOM to encapsulate the implementation.
> 
> 
> == API Proposal ==
> 
> Add two methods void add(Element) and void remove(Element) to content element.
> (We can give them more descriptive names. I matched select element for now).
> 
> Each content element has an ordered list of *explicitly inserted nodes*.
> 
> add(Element element) must act according to the following algorithm:
> If the content element's shadow host's node tree doesn't contain _element_, 
> throw HierarchyRequestError.
> If element is already in some other content element's _explicitly inserted 
> nodes_
> then call remove with _element_ on that content element.
> Append _element_ to the end of _explicitly inserted nodes_.
> 
> remove(Element element) must act according to the following algorithm:
> If the content element's _explicitly inserted nodes_ does not contain 
> _element_, throw NotFoundError.
> Remove _element_ from _explicitly inserted nodes_.
> 
> The idea here is that _explicitly inserted nodes_ of an insertion point A 
> would be the list of distributed nodes of A but
> I haven't figured out exactly how _explicitly inserted nodes_ should interact 
> with select content attribute.
> 
> I think the simplest model would be _explicitly inserted nodes_ simply 
> overriding whatever select content attribute was
> trying to do but I don't have a strong opinion about how they should interact 
> yet.
> 
> I don't think it makes sense to support redistributions, etc... at least in 
> the initial API.
> 
> This proposal has an advantage over the existing proposal on 
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429:
> It doesn't require UA calling back to JS constantly to match elements
> Point 1 implies we don't expose when distribution happens for select content 
> attribute.
I'm sorry I don't know what was reading. The strawman proposal on the bug is 
basically what I'm "proposing".  add/remove are simply on distributedChildren 
instead.

In fact, the stated design is probably better than what I have here now that we 
have getDistributedNodes() on content element.

I think we just need to turn that into a Static/Live NodeList with add/remove.  
I would prefer the name distributedNodes.

One important implication of adding this API surface is that the node 
distribution from declarative syntax also needs to happen at the end of each 
micro task as opposed to happen implicitly after each DOM mutation if we wanted 
to formulate the mutation observer as a way of implementing "select" content 
attribute.

Since this is visible to the scripts, it's important to take it into the 
account in the level 1 specification.

- R. Niwa

Re: [webcomponents] Imperative API for Insertion Points

2014-02-16 Thread Alex Russell
On Sun, Feb 16, 2014 at 12:52 AM, Ryosuke Niwa  wrote:

> On Feb 16, 2014, at 12:42 AM, Ryosuke Niwa  wrote:
>
> On Feb 15, 2014, at 11:30 PM, Alex Russell  wrote:
>
> On Sat, Feb 15, 2014 at 4:57 PM, Ryosuke Niwa  wrote:
>
>> Hi all,
>>
>> I’d like to propose one solution for
>>
>> [Shadow]: Specify imperative API for node distribution
>> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429
>>
>> because select content attribute doesn’t satisfy the needs of
>> framework/library authors to support conditionals in their templates,
>> and doesn’t satisfy my random image element use case below.
>>
>>
>> *== Use Case ==*
>> Random image element is a custom element that shows one of child img
>> elements chosen uniformally random.
>>
>> e.g. the markup of a document that uses random-image-element may look
>> like this:
>> 
>>   
>>   
>>   
>> 
>>
>> random-image-element displays one out of the three img child elements
>> when a user clicks on it.
>>
>> As an author of this element, I could modify the DOM and add style
>> content attribute directly on those elements
>> but I would rather use shadow DOM to encapsulate the implementation.
>>
>>
>> *== API Proposal ==*
>>
>> Add two methods void add(Element) and void remove(Element) to content
>> element.
>> (We can give them more descriptive names. I matched select element for
>> now).
>>
>> Each content element has an ordered list of **explicitly inserted nodes*
>> *.
>>
>> add(Element element) must act according to the following algorithm:
>>
>>1. If the content element's shadow host's node tree doesn't contain _
>>*element*_, throw HierarchyRequestError.
>>2. If element is already in some other content element's _*explicitly
>>inserted nodes*_
>>then call remove with _*element*_ on that content element.
>>3. Append _*element*_ to the end of _*explicitly inserted nodes*_.
>>
>>
>> remove(Element element) must act according to the following algorithm:
>>
>>1. If the content element's _*explicitly inserted nodes*_ does not
>>contain _*element*_, throw NotFoundError.
>>
>>
> Throwing exceptions is hostile to usability.
>
>
> If people are so inclined, we don’t have to throw an exception and
> silently fail.
>
>
>>1. Remove _*element*_ from _*explicitly inserted nodes*_.
>>
>>
>> The idea here is that _*explicitly inserted nodes*_ of an insertion
>> point A would be the list of distributed nodes of A but
>> I haven't figured out exactly how _*explicitly inserted nodes*_ should
>> interact with select content attribute.
>>
>> I think the simplest model would be _*explicitly inserted nodes*_ simply
>> overriding whatever select content attribute was
>> trying to do but I don't have a strong opinion about how they should
>> interact yet.
>>
>> I don't think it makes sense to support redistributions, etc... at least
>> in the initial API.
>>
>>
>> This proposal has an advantage over the existing proposal on
>> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429:
>>
>>1. It doesn't require UA calling back to JS constantly to match
>>elements
>>2. Point 1 implies we don't expose when distribution happens for
>>select content attribute.
>>
>> This doesn't seem like progress. I'd hope an imperative API would,
> instead, be used to explain how the existing system works and then propose
> layering that both accommodates the existing system and opens new areas for
> programmatic use.
>
> We can imagine such a system for programmatic Shadow DOM with some sort of
> distribute(Element) callback that can be over-ridden and use add/remove
> methods to do final distribution.
>
>
> The problem here is that such a callback must be called on every node upon
> any state change because UAs have no way of knowing what causes
> redistribution for a given component.  As as a matter of fact, some use
> cases may involve changing the node distributions based on some JS objects
> state.  And having authors codify such conditions for UAs is much more
> cumbersome than letting them re-distribute nodes at their will.
>
>
> To give you more concrete example, in the case of my random image element,
> how can UA notice that user clicking on the element should trigger
> reconstruction of the composed tree?
>

Isn't the stated design of the custom element that it re-constructs the
composed tree with a random image every time it's clicked? It's not
actually clear what you wanted here because there isn't any example code to
go on.


>  Should the script call some method like redistribute() on the host upon
> click?  But then, since the element needs to pick a child uniformly random,
> it probably needs to keep track of the number of children to be distributed
> and return true exactly when that node was passed into the callback.
>  That’s an extremely cumbersome API at least for my use case.
>

I have the sense that if you produced example code you'd be able to make a
better guess about what's onerous and what isn't. As it is, we're debating
hypothet

Re: [webcomponents] Imperative API for Insertion Points

2014-02-16 Thread Ryosuke Niwa
On Feb 16, 2014, at 12:42 AM, Ryosuke Niwa  wrote:

> On Feb 15, 2014, at 11:30 PM, Alex Russell  wrote:
> 
>> On Sat, Feb 15, 2014 at 4:57 PM, Ryosuke Niwa  wrote:
>> Hi all,
>> 
>> I’d like to propose one solution for
>> 
>> [Shadow]: Specify imperative API for node distribution
>> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429
>> 
>> because select content attribute doesn’t satisfy the needs of 
>> framework/library authors to support conditionals in their templates,
>> and doesn’t satisfy my random image element use case below.
>> 
>> 
>> == Use Case ==
>> Random image element is a custom element that shows one of child img 
>> elements chosen uniformally random.
>> 
>> e.g. the markup of a document that uses random-image-element may look like 
>> this:
>> 
>>   
>>   
>>   
>> 
>> 
>> random-image-element displays one out of the three img child elements when a 
>> user clicks on it.
>> 
>> As an author of this element, I could modify the DOM and add style content 
>> attribute directly on those elements
>> but I would rather use shadow DOM to encapsulate the implementation.
>> 
>> 
>> == API Proposal ==
>> 
>> Add two methods void add(Element) and void remove(Element) to content 
>> element.
>> (We can give them more descriptive names. I matched select element for now).
>> 
>> Each content element has an ordered list of *explicitly inserted nodes*.
>> 
>> add(Element element) must act according to the following algorithm:
>> If the content element's shadow host's node tree doesn't contain _element_, 
>> throw HierarchyRequestError.
>> If element is already in some other content element's _explicitly inserted 
>> nodes_
>> then call remove with _element_ on that content element.
>> Append _element_ to the end of _explicitly inserted nodes_.
>> 
>> remove(Element element) must act according to the following algorithm:
>> If the content element's _explicitly inserted nodes_ does not contain 
>> _element_, throw NotFoundError.
>> 
>> Throwing exceptions is hostile to usability.
> 
> If people are so inclined, we don’t have to throw an exception and silently 
> fail.
>> Remove _element_ from _explicitly inserted nodes_.
>> 
>> The idea here is that _explicitly inserted nodes_ of an insertion point A 
>> would be the list of distributed nodes of A but
>> I haven't figured out exactly how _explicitly inserted nodes_ should 
>> interact with select content attribute.
>> 
>> I think the simplest model would be _explicitly inserted nodes_ simply 
>> overriding whatever select content attribute was
>> trying to do but I don't have a strong opinion about how they should 
>> interact yet.
>> 
>> I don't think it makes sense to support redistributions, etc... at least in 
>> the initial API.
>> 
>> 
>> This proposal has an advantage over the existing proposal on 
>> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429:
>> It doesn't require UA calling back to JS constantly to match elements
>> Point 1 implies we don't expose when distribution happens for select content 
>> attribute.
>> This doesn't seem like progress. I'd hope an imperative API would, instead, 
>> be used to explain how the existing system works and then propose layering 
>> that both accommodates the existing system and opens new areas for 
>> programmatic use.
>> 
>> We can imagine such a system for programmatic Shadow DOM with some sort of 
>> distribute(Element) callback that can be over-ridden and use add/remove 
>> methods to do final distribution.
> 
> The problem here is that such a callback must be called on every node upon 
> any state change because UAs have no way of knowing what causes 
> redistribution for a given component.  As as a matter of fact, some use cases 
> may involve changing the node distributions based on some JS objects state.  
> And having authors codify such conditions for UAs is much more cumbersome 
> than letting them re-distribute nodes at their will.

To give you more concrete example, in the case of my random image element, how 
can UA notice that user clicking on the element should trigger reconstruction 
of the composed tree?  Should the script call some method like redistribute() 
on the host upon click?  But then, since the element needs to pick a child 
uniformly random, it probably needs to keep track of the number of children to 
be distributed and return true exactly when that node was passed into the 
callback.  That’s an extremely cumbersome API at least for my use case.

- R. Niwa



Re: [webcomponents] Imperative API for Insertion Points

2014-02-16 Thread Ryosuke Niwa
On Feb 15, 2014, at 11:30 PM, Alex Russell  wrote:

> On Sat, Feb 15, 2014 at 4:57 PM, Ryosuke Niwa  wrote:
> Hi all,
> 
> I’d like to propose one solution for
> 
> [Shadow]: Specify imperative API for node distribution
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429
> 
> because select content attribute doesn’t satisfy the needs of 
> framework/library authors to support conditionals in their templates,
> and doesn’t satisfy my random image element use case below.
> 
> 
> == Use Case ==
> Random image element is a custom element that shows one of child img elements 
> chosen uniformally random.
> 
> e.g. the markup of a document that uses random-image-element may look like 
> this:
> 
>   
>   
>   
> 
> 
> random-image-element displays one out of the three img child elements when a 
> user clicks on it.
> 
> As an author of this element, I could modify the DOM and add style content 
> attribute directly on those elements
> but I would rather use shadow DOM to encapsulate the implementation.
> 
> 
> == API Proposal ==
> 
> Add two methods void add(Element) and void remove(Element) to content element.
> (We can give them more descriptive names. I matched select element for now).
> 
> Each content element has an ordered list of *explicitly inserted nodes*.
> 
> add(Element element) must act according to the following algorithm:
> If the content element's shadow host's node tree doesn't contain _element_, 
> throw HierarchyRequestError.
> If element is already in some other content element's _explicitly inserted 
> nodes_
> then call remove with _element_ on that content element.
> Append _element_ to the end of _explicitly inserted nodes_.
> 
> remove(Element element) must act according to the following algorithm:
> If the content element's _explicitly inserted nodes_ does not contain 
> _element_, throw NotFoundError.
> 
> Throwing exceptions is hostile to usability.

If people are so inclined, we don’t have to throw an exception and silently 
fail.
> Remove _element_ from _explicitly inserted nodes_.
> 
> The idea here is that _explicitly inserted nodes_ of an insertion point A 
> would be the list of distributed nodes of A but
> I haven't figured out exactly how _explicitly inserted nodes_ should interact 
> with select content attribute.
> 
> I think the simplest model would be _explicitly inserted nodes_ simply 
> overriding whatever select content attribute was
> trying to do but I don't have a strong opinion about how they should interact 
> yet.
> 
> I don't think it makes sense to support redistributions, etc... at least in 
> the initial API.
> 
> 
> This proposal has an advantage over the existing proposal on 
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429:
> It doesn't require UA calling back to JS constantly to match elements
> Point 1 implies we don't expose when distribution happens for select content 
> attribute.
> This doesn't seem like progress. I'd hope an imperative API would, instead, 
> be used to explain how the existing system works and then propose layering 
> that both accommodates the existing system and opens new areas for 
> programmatic use.
> 
> We can imagine such a system for programmatic Shadow DOM with some sort of 
> distribute(Element) callback that can be over-ridden and use add/remove 
> methods to do final distribution.

The problem here is that such a callback must be called on every node upon any 
state change because UAs have no way of knowing what causes redistribution for 
a given component.  As as a matter of fact, some use cases may involve changing 
the node distributions based on some JS objects state.  And having authors 
codify such conditions for UAs is much more cumbersome than letting them 
re-distribute nodes at their will.

In terms of add/remove explaining “select” content attribute, we could describe 
node distribution as something that happens at the end of micro task via 
mutation observers.  In fact, we should probably spec as such.

> I'm deeply skeptical of appeals to defeat/elide layering on the basis of 
> performance arguments. Real-world systems often have fast-paths for common 
> operations and we should note that a self-hosted DOM would feel no particular 
> pain about "calling back to JS". If your mental model is that the world is 
> C++ and JS is bolt-on, you're bound to get this continuously wrong.

Points 1 and 2 are mostly API advantages, not of performance.

- R. Niwa



Re: [webcomponents] Imperative API for Insertion Points

2014-02-15 Thread Alex Russell
On Sat, Feb 15, 2014 at 4:57 PM, Ryosuke Niwa  wrote:

> Hi all,
>
> I’d like to propose one solution for
>
> [Shadow]: Specify imperative API for node distribution
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429
>
> because select content attribute doesn’t satisfy the needs of
> framework/library authors to support conditionals in their templates,
> and doesn’t satisfy my random image element use case below.
>
>
> *== Use Case ==*
> Random image element is a custom element that shows one of child img
> elements chosen uniformally random.
>
> e.g. the markup of a document that uses random-image-element may look like
> this:
> 
>   
>   
>   
> 
>
> random-image-element displays one out of the three img child elements when
> a user clicks on it.
>
> As an author of this element, I could modify the DOM and add style content
> attribute directly on those elements
> but I would rather use shadow DOM to encapsulate the implementation.
>
>
> *== API Proposal ==*
>
> Add two methods void add(Element) and void remove(Element) to content
> element.
> (We can give them more descriptive names. I matched select element for
> now).
>
> Each content element has an ordered list of **explicitly inserted nodes**.
>
> add(Element element) must act according to the following algorithm:
>
>1. If the content element's shadow host's node tree doesn't contain _
>*element*_, throw HierarchyRequestError.
>2. If element is already in some other content element's _*explicitly
>inserted nodes*_
>then call remove with _*element*_ on that content element.
>3. Append _*element*_ to the end of _*explicitly inserted nodes*_.
>
>
> remove(Element element) must act according to the following algorithm:
>
>1. If the content element's _*explicitly inserted nodes*_ does not
>contain _*element*_, throw NotFoundError.
>
>
Throwing exceptions is hostile to usability.


>
>1. Remove _*element*_ from _*explicitly inserted nodes*_.
>
>
> The idea here is that _*explicitly inserted nodes*_ of an insertion point
> A would be the list of distributed nodes of A but
> I haven't figured out exactly how _*explicitly inserted nodes*_ should
> interact with select content attribute.
>
> I think the simplest model would be _*explicitly inserted nodes*_ simply
> overriding whatever select content attribute was
> trying to do but I don't have a strong opinion about how they should
> interact yet.
>
> I don't think it makes sense to support redistributions, etc... at least
> in the initial API.
>
>
> This proposal has an advantage over the existing proposal on
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429:
>
>1. It doesn't require UA calling back to JS constantly to match
>elements
>2. Point 1 implies we don't expose when distribution happens for
>select content attribute.
>
> This doesn't seem like progress. I'd hope an imperative API would,
instead, be used to explain how the existing system works and then propose
layering that both accommodates the existing system and opens new areas for
programmatic use.

We can imagine such a system for programmatic Shadow DOM with some sort of
distribute(Element) callback that can be over-ridden and use add/remove
methods to do final distribution.

I'm deeply skeptical of appeals to defeat/elide layering on the basis of
performance arguments. Real-world systems often have fast-paths for common
operations and we should note that a self-hosted DOM would feel no
particular pain about "calling back to JS". If your mental model is that
the world is C++ and JS is bolt-on, you're bound to get this continuously
wrong.

Regards


[webcomponents] Imperative API for Insertion Points

2014-02-15 Thread Ryosuke Niwa
Hi all,

I’d like to propose one solution for

[Shadow]: Specify imperative API for node distribution
https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429

because select content attribute doesn’t satisfy the needs of framework/library 
authors to support conditionals in their templates,
and doesn’t satisfy my random image element use case below.


== Use Case ==
Random image element is a custom element that shows one of child img elements 
chosen uniformally random.

e.g. the markup of a document that uses random-image-element may look like this:

  
  
  


random-image-element displays one out of the three img child elements when a 
user clicks on it.

As an author of this element, I could modify the DOM and add style content 
attribute directly on those elements
but I would rather use shadow DOM to encapsulate the implementation.


== API Proposal ==

Add two methods void add(Element) and void remove(Element) to content element.
(We can give them more descriptive names. I matched select element for now).

Each content element has an ordered list of *explicitly inserted nodes*.

add(Element element) must act according to the following algorithm:
If the content element's shadow host's node tree doesn't contain _element_, 
throw HierarchyRequestError.
If element is already in some other content element's _explicitly inserted 
nodes_
then call remove with _element_ on that content element.
Append _element_ to the end of _explicitly inserted nodes_.

remove(Element element) must act according to the following algorithm:
If the content element's _explicitly inserted nodes_ does not contain 
_element_, throw NotFoundError.
Remove _element_ from _explicitly inserted nodes_.

The idea here is that _explicitly inserted nodes_ of an insertion point A would 
be the list of distributed nodes of A but
I haven't figured out exactly how _explicitly inserted nodes_ should interact 
with select content attribute.

I think the simplest model would be _explicitly inserted nodes_ simply 
overriding whatever select content attribute was
trying to do but I don't have a strong opinion about how they should interact 
yet.

I don't think it makes sense to support redistributions, etc... at least in the 
initial API.


This proposal has an advantage over the existing proposal on 
https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429:
It doesn't require UA calling back to JS constantly to match elements
Point 1 implies we don't expose when distribution happens for select content 
attribute.

- R. Niwa