Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-08 Thread Ryosuke Niwa

 On May 7, 2015, at 7:20 PM, Hayato Ito hay...@chromium.org wrote:
 
 Ryosuke, could you file a bug for the spec if you find an uncomfortable part 
 in the spec?
 I want to understand exactly what you are trying to improve.

I don't think there is any issue with the spec per se.  What Anne and I both 
are pointing out is that event path isn't a style concept so node distribution 
can't be thought of as a style concept.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-07 Thread Hayato Ito
Ryosuke, could you file a bug for the spec if you find an uncomfortable
part in the spec?
I want to understand exactly what you are trying to improve.

On Fri, May 8, 2015 at 2:21 AM Ryosuke Niwa rn...@apple.com wrote:


  On May 6, 2015, at 11:10 PM, Elliott Sprehn espr...@chromium.org
 wrote:
 
  On Wed, May 6, 2015 at 11:08 PM, Anne van Kesteren ann...@annevk.nl
 wrote:
  On Thu, May 7, 2015 at 6:02 AM, Hayato Ito hay...@chromium.org wrote:
   I'm saying:
   - Composed tree is related with CSS.
   - Node distribution should be considered as a part of style concept.
 
  Right, I think Ryosuke and I simply disagree with that assessment. CSS
  operates on the composed tree (and forms a render tree from it).
  Events operate on the composed tree. Selection operates on the
  composed tree (likely, we haven't discussed this much).
 
  Selection operates on the render tree. The current selection API is
 (completely) busted for modern apps, and a new one is needed that's based
 around layout. Flexbox w/ order, positioned objects, distributions, grid,
 none of them work with the DOM based API.

 Please state your presumptions like that before making a statement such as
 composed street is a style concept.

 Now, even if selection were to operate on the CSS box tree, of which I
 will not express my opinion of, event path is still not a style concept.
 If you're proposing to make it a style concept, then I just need to object
 to that.

 - R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-07 Thread Anne van Kesteren
On Thu, May 7, 2015 at 6:02 AM, Hayato Ito hay...@chromium.org wrote:
 I'm saying:
 - Composed tree is related with CSS.
 - Node distribution should be considered as a part of style concept.

Right, I think Ryosuke and I simply disagree with that assessment. CSS
operates on the composed tree (and forms a render tree from it).
Events operate on the composed tree. Selection operates on the
composed tree (likely, we haven't discussed this much). Content can be
found within the composed tree (not just the light tree, see
composition). It's a lot more than just style.


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-07 Thread Elliott Sprehn
On Wed, May 6, 2015 at 11:08 PM, Anne van Kesteren ann...@annevk.nl wrote:

 On Thu, May 7, 2015 at 6:02 AM, Hayato Ito hay...@chromium.org wrote:
  I'm saying:
  - Composed tree is related with CSS.
  - Node distribution should be considered as a part of style concept.

 Right, I think Ryosuke and I simply disagree with that assessment. CSS
 operates on the composed tree (and forms a render tree from it).
 Events operate on the composed tree. Selection operates on the
 composed tree (likely, we haven't discussed this much).


Selection operates on the render tree. The current selection API is
(completely) busted for modern apps, and a new one is needed that's based
around layout. Flexbox w/ order, positioned objects, distributions, grid,
none of them work with the DOM based API.

- E


Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-07 Thread Hayato Ito
Yeah, we, in Google, had several discussion about how the next *Selection
APIs* should be. However we don't have any concrete proposals yet.
We are aware that we need the new APIs because the existing APIs is not
suitable.

On Thu, May 7, 2015 at 3:10 PM Elliott Sprehn espr...@chromium.org wrote:

 On Wed, May 6, 2015 at 11:08 PM, Anne van Kesteren ann...@annevk.nl
 wrote:

 On Thu, May 7, 2015 at 6:02 AM, Hayato Ito hay...@chromium.org wrote:
  I'm saying:
  - Composed tree is related with CSS.
  - Node distribution should be considered as a part of style concept.

 Right, I think Ryosuke and I simply disagree with that assessment. CSS
 operates on the composed tree (and forms a render tree from it).
 Events operate on the composed tree. Selection operates on the
 composed tree (likely, we haven't discussed this much).


 Selection operates on the render tree. The current selection API is
 (completely) busted for modern apps, and a new one is needed that's based
 around layout. Flexbox w/ order, positioned objects, distributions, grid,
 none of them work with the DOM based API.

 - E



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-07 Thread Ryosuke Niwa

 On May 6, 2015, at 11:10 PM, Elliott Sprehn espr...@chromium.org wrote:
 
 On Wed, May 6, 2015 at 11:08 PM, Anne van Kesteren ann...@annevk.nl wrote:
 On Thu, May 7, 2015 at 6:02 AM, Hayato Ito hay...@chromium.org wrote:
  I'm saying:
  - Composed tree is related with CSS.
  - Node distribution should be considered as a part of style concept.
 
 Right, I think Ryosuke and I simply disagree with that assessment. CSS
 operates on the composed tree (and forms a render tree from it).
 Events operate on the composed tree. Selection operates on the
 composed tree (likely, we haven't discussed this much).
 
 Selection operates on the render tree. The current selection API is 
 (completely) busted for modern apps, and a new one is needed that's based 
 around layout. Flexbox w/ order, positioned objects, distributions, grid, 
 none of them work with the DOM based API.

Please state your presumptions like that before making a statement such as 
composed street is a style concept.

Now, even if selection were to operate on the CSS box tree, of which I will not 
express my opinion of, event path is still not a style concept.  If you're 
proposing to make it a style concept, then I just need to object to that.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-06 Thread Ryosuke Niwa

 On May 5, 2015, at 10:53 PM, Anne van Kesteren ann...@annevk.nl wrote:
 
 On Wed, May 6, 2015 at 3:22 AM, Ryosuke Niwa rn...@apple.com wrote:
 Where?  I have not yet to see a use case for which selective redistribution 
 of nodes (i.e. redistributing only a non-empty strict subset of nodes from 
 an insertion point) are required.
 
 Isn't that what e.g. select does? That is, select only cares about
 option and optgroup elements that are passed to it.

Or it could just distribute all the elements and have do:
```css
::content * { display:none; }
::content option, optgroup { display:block; }
```

Dimitri just added a document describing how we can turn partial distribution 
into whole distribution here (thanks Dimitri!):
https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Partial-Redistributions-Analysis.md

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-06 Thread Ryosuke Niwa

 On May 6, 2015, at 6:18 PM, Hayato Ito hay...@chromium.org wrote:
 
 On Wed, May 6, 2015 at 10:22 AM Ryosuke Niwa rn...@apple.com wrote:
 
  On May 5, 2015, at 11:55 AM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 
  On Tue, May 5, 2015 at 11:20 AM, Ryosuke Niwa rn...@apple.com wrote:
  On May 4, 2015, at 10:20 PM, Anne van Kesteren ann...@annevk.nl wrote:
 
  On Tue, May 5, 2015 at 6:58 AM, Elliott Sprehn espr...@chromium.org 
  wrote:
  We can solve this
  problem by running the distribution code in a separate scripting context
  with a restricted (distribution specific) API as is being discussed for
  other extension points in the platform.
 
  That seems like a lot of added complexity, but yeah, that would be an
  option I suppose. Dimitri added something like this to the imperative
  API proposal page a couple of days ago.
 
 
  One thing to consider here is that we very much consider distribution a
  style concept. It's about computing who you inherit style from and 
  where you
  should be in the box tree. It just so happens it's also leveraged in 
  event
  dispatch too (like pointer-events). It happens asynchronously from DOM
  mutation as needed just like style and reflow though.
 
  I don't really see it that way. The render tree is still computed from
  the composed tree. The composed tree is still a DOM tree, just
  composed from various other trees. In the open case you can access
  it synchronously through various APIs (e.g.  if we keep that for
  querySelector() selectors and also deepPath).
 
  I agree. I don't see any reason node distribution should be considered as 
  a style concept. It's a DOM concept. There is no CSS involved here.
 
  Yes there is.  As Elliot stated in the elided parts of his quoted
  response above, most of the places where we update distribution are
  for CSS or related concerns:
 
  # 3 event related
  # 3 shadow dom JS api
 
 These two are nothing to do with styles or CSS.
 
 I'd like to inform all guys in this thread that Composed Tree is for 
 resolving CSS inheritance by the definition.
 See the Section 2.4 Composed Trees in the spec:
 http://w3c.github.io/webcomponents/spec/shadow/#composed-trees
 
 Let me quote:
  If an element doesn't participate in a composed tree whose root node is a 
  document, the element must not appear in the formating structure [CSS21] 
  nor create any CSS box. This behavior must not be overridden by setting the 
  'display' property.
 
  In resolving CSS inheritance, an element must inherit from the parent node 
  in the composed tree, if applicable.
 
 The motivation of a composed tree is to determine the parent node in 
 resolving CSS inheritance. There is no other significant usages, except for 
 event path.

Event path / retargeting is definitely event related, and it (e.g. deepPath) 
is definitely a part of shadow DOM JS API.  Again, they're nothing to do with 
styles or CSS.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-06 Thread Hayato Ito
I'm not saying the event path is not related to a composed tree.

I'm saying:
- Composed tree is related with CSS.
- Node distribution should be considered as a part of style concept.


On Thu, May 7, 2015 at 12:54 PM Ryosuke Niwa rn...@apple.com wrote:


  On May 6, 2015, at 6:18 PM, Hayato Ito hay...@chromium.org wrote:
 
  On Wed, May 6, 2015 at 10:22 AM Ryosuke Niwa rn...@apple.com wrote:
 
   On May 5, 2015, at 11:55 AM, Tab Atkins Jr. jackalm...@gmail.com
 wrote:
  
   On Tue, May 5, 2015 at 11:20 AM, Ryosuke Niwa rn...@apple.com
 wrote:
   On May 4, 2015, at 10:20 PM, Anne van Kesteren ann...@annevk.nl
 wrote:
  
   On Tue, May 5, 2015 at 6:58 AM, Elliott Sprehn 
 espr...@chromium.org wrote:
   We can solve this
   problem by running the distribution code in a separate scripting
 context
   with a restricted (distribution specific) API as is being
 discussed for
   other extension points in the platform.
  
   That seems like a lot of added complexity, but yeah, that would be
 an
   option I suppose. Dimitri added something like this to the
 imperative
   API proposal page a couple of days ago.
  
  
   One thing to consider here is that we very much consider
 distribution a
   style concept. It's about computing who you inherit style from and
 where you
   should be in the box tree. It just so happens it's also leveraged
 in event
   dispatch too (like pointer-events). It happens asynchronously from
 DOM
   mutation as needed just like style and reflow though.
  
   I don't really see it that way. The render tree is still computed
 from
   the composed tree. The composed tree is still a DOM tree, just
   composed from various other trees. In the open case you can access
   it synchronously through various APIs (e.g.  if we keep that for
   querySelector() selectors and also deepPath).
  
   I agree. I don't see any reason node distribution should be
 considered as a style concept. It's a DOM concept. There is no CSS involved
 here.
  
   Yes there is.  As Elliot stated in the elided parts of his quoted
   response above, most of the places where we update distribution are
   for CSS or related concerns:
  
   # 3 event related
   # 3 shadow dom JS api
 
  These two are nothing to do with styles or CSS.
 
  I'd like to inform all guys in this thread that Composed Tree is for
 resolving CSS inheritance by the definition.
  See the Section 2.4 Composed Trees in the spec:
  http://w3c.github.io/webcomponents/spec/shadow/#composed-trees
 
  Let me quote:
   If an element doesn't participate in a composed tree whose root node
 is a document, the element must not appear in the formating structure
 [CSS21] nor create any CSS box. This behavior must not be overridden by
 setting the 'display' property.
 
   In resolving CSS inheritance, an element must inherit from the parent
 node in the composed tree, if applicable.
 
  The motivation of a composed tree is to determine the parent node in
 resolving CSS inheritance. There is no other significant usages, except for
 event path.

 Event path / retargeting is definitely event related, and it (e.g.
 deepPath) is definitely a part of shadow DOM JS API.  Again, they're
 nothing to do with styles or CSS.

 - R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-06 Thread Hayato Ito
On Wed, May 6, 2015 at 10:22 AM Ryosuke Niwa rn...@apple.com wrote:


  On May 5, 2015, at 11:55 AM, Tab Atkins Jr. jackalm...@gmail.com
 wrote:
 
  On Tue, May 5, 2015 at 11:20 AM, Ryosuke Niwa rn...@apple.com wrote:
  On May 4, 2015, at 10:20 PM, Anne van Kesteren ann...@annevk.nl
 wrote:
 
  On Tue, May 5, 2015 at 6:58 AM, Elliott Sprehn espr...@chromium.org
 wrote:
  We can solve this
  problem by running the distribution code in a separate scripting
 context
  with a restricted (distribution specific) API as is being discussed
 for
  other extension points in the platform.
 
  That seems like a lot of added complexity, but yeah, that would be an
  option I suppose. Dimitri added something like this to the imperative
  API proposal page a couple of days ago.
 
 
  One thing to consider here is that we very much consider distribution
 a
  style concept. It's about computing who you inherit style from and
 where you
  should be in the box tree. It just so happens it's also leveraged in
 event
  dispatch too (like pointer-events). It happens asynchronously from DOM
  mutation as needed just like style and reflow though.
 
  I don't really see it that way. The render tree is still computed from
  the composed tree. The composed tree is still a DOM tree, just
  composed from various other trees. In the open case you can access
  it synchronously through various APIs (e.g.  if we keep that for
  querySelector() selectors and also deepPath).
 
  I agree. I don't see any reason node distribution should be considered
 as a style concept. It's a DOM concept. There is no CSS involved here.
 
  Yes there is.  As Elliot stated in the elided parts of his quoted
  response above, most of the places where we update distribution are
  for CSS or related concerns:
 
  # 3 event related
  # 3 shadow dom JS api

 These two are nothing to do with styles or CSS.


I'd like to inform all guys in this thread that Composed Tree is for
resolving CSS inheritance by the definition.
See the Section 2.4 Composed Trees in the spec:
http://w3c.github.io/webcomponents/spec/shadow/#composed-trees

Let me quote:
 If an element doesn't participate in a composed tree whose root node is a
document, the element must not appear in the formating structure [CSS21]
nor create any CSS box. This behavior must not be overridden by setting the
'display' property.

 In resolving CSS inheritance, an element must inherit from the parent
node in the composed tree, if applicable.

The motivation of a composed tree is to determine the parent node in
resolving CSS inheritance. There is no other significant usages, except for
event path.



  I have issues with the argument that we should do it lazily.  On one
 hand, if node distribution is so expensive that we need to do it lazily,
 then it's unacceptable to make event dispatching so much slower.  On the
 other hand, if node distribution is fast, as it should be, then there is no
 reason we need to do it lazily.
 
  The problem is really the redistributions. If we instead had explicit
 insertion points under each shadow host, then we wouldn't really need
 redistributions at all, and node distribution can happen in O(1) per child
 change.
 
  As repeatedly stated, redistribution appears to be a necessity for
  composition to work in all but the most trivial cases.

 Where?  I have not yet to see a use case for which selective
 redistribution of nodes (i.e. redistributing only a non-empty strict subset
 of nodes from an insertion point) are required.

 - R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-06 Thread Hayato Ito
I'm feeling that there is a misunderstanding about the relation between DOM
tree and Composed Tree in this discussion.
If you understand the difference, the discussion might be more productive.

In short,
- Composed Tree DOES NOT replace DOM tree. Most of existing APIs work for
DOM tree. Composed Tree doesn't have any affect on (most of) existing APIs.
- Composed Tree is used in resolving CSS inheritance. That's all, except
for a few exception.


On Thu, May 7, 2015 at 10:18 AM Hayato Ito hay...@chromium.org wrote:

 On Wed, May 6, 2015 at 10:22 AM Ryosuke Niwa rn...@apple.com wrote:


  On May 5, 2015, at 11:55 AM, Tab Atkins Jr. jackalm...@gmail.com
 wrote:
 
  On Tue, May 5, 2015 at 11:20 AM, Ryosuke Niwa rn...@apple.com wrote:
  On May 4, 2015, at 10:20 PM, Anne van Kesteren ann...@annevk.nl
 wrote:
 
  On Tue, May 5, 2015 at 6:58 AM, Elliott Sprehn espr...@chromium.org
 wrote:
  We can solve this
  problem by running the distribution code in a separate scripting
 context
  with a restricted (distribution specific) API as is being discussed
 for
  other extension points in the platform.
 
  That seems like a lot of added complexity, but yeah, that would be an
  option I suppose. Dimitri added something like this to the imperative
  API proposal page a couple of days ago.
 
 
  One thing to consider here is that we very much consider
 distribution a
  style concept. It's about computing who you inherit style from and
 where you
  should be in the box tree. It just so happens it's also leveraged in
 event
  dispatch too (like pointer-events). It happens asynchronously from
 DOM
  mutation as needed just like style and reflow though.
 
  I don't really see it that way. The render tree is still computed from
  the composed tree. The composed tree is still a DOM tree, just
  composed from various other trees. In the open case you can access
  it synchronously through various APIs (e.g.  if we keep that for
  querySelector() selectors and also deepPath).
 
  I agree. I don't see any reason node distribution should be considered
 as a style concept. It's a DOM concept. There is no CSS involved here.
 
  Yes there is.  As Elliot stated in the elided parts of his quoted
  response above, most of the places where we update distribution are
  for CSS or related concerns:
 
  # 3 event related
  # 3 shadow dom JS api

 These two are nothing to do with styles or CSS.


 I'd like to inform all guys in this thread that Composed Tree is for
 resolving CSS inheritance by the definition.
 See the Section 2.4 Composed Trees in the spec:
 http://w3c.github.io/webcomponents/spec/shadow/#composed-trees

 Let me quote:
  If an element doesn't participate in a composed tree whose root node is
 a document, the element must not appear in the formating structure [CSS21]
 nor create any CSS box. This behavior must not be overridden by setting the
 'display' property.

  In resolving CSS inheritance, an element must inherit from the parent
 node in the composed tree, if applicable.

 The motivation of a composed tree is to determine the parent node in
 resolving CSS inheritance. There is no other significant usages, except for
 event path.



  I have issues with the argument that we should do it lazily.  On one
 hand, if node distribution is so expensive that we need to do it lazily,
 then it's unacceptable to make event dispatching so much slower.  On the
 other hand, if node distribution is fast, as it should be, then there is no
 reason we need to do it lazily.
 
  The problem is really the redistributions. If we instead had explicit
 insertion points under each shadow host, then we wouldn't really need
 redistributions at all, and node distribution can happen in O(1) per child
 change.
 
  As repeatedly stated, redistribution appears to be a necessity for
  composition to work in all but the most trivial cases.

 Where?  I have not yet to see a use case for which selective
 redistribution of nodes (i.e. redistributing only a non-empty strict subset
 of nodes from an insertion point) are required.

 - R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-05 Thread Ryosuke Niwa

 On May 5, 2015, at 11:55 AM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 
 On Tue, May 5, 2015 at 11:20 AM, Ryosuke Niwa rn...@apple.com wrote:
 On May 4, 2015, at 10:20 PM, Anne van Kesteren ann...@annevk.nl wrote:
 
 On Tue, May 5, 2015 at 6:58 AM, Elliott Sprehn espr...@chromium.org 
 wrote:
 We can solve this
 problem by running the distribution code in a separate scripting context
 with a restricted (distribution specific) API as is being discussed for
 other extension points in the platform.
 
 That seems like a lot of added complexity, but yeah, that would be an
 option I suppose. Dimitri added something like this to the imperative
 API proposal page a couple of days ago.
 
 
 One thing to consider here is that we very much consider distribution a
 style concept. It's about computing who you inherit style from and where 
 you
 should be in the box tree. It just so happens it's also leveraged in event
 dispatch too (like pointer-events). It happens asynchronously from DOM
 mutation as needed just like style and reflow though.
 
 I don't really see it that way. The render tree is still computed from
 the composed tree. The composed tree is still a DOM tree, just
 composed from various other trees. In the open case you can access
 it synchronously through various APIs (e.g.  if we keep that for
 querySelector() selectors and also deepPath).
 
 I agree. I don't see any reason node distribution should be considered as a 
 style concept. It's a DOM concept. There is no CSS involved here.
 
 Yes there is.  As Elliot stated in the elided parts of his quoted
 response above, most of the places where we update distribution are
 for CSS or related concerns:
 
 # 3 event related
 # 3 shadow dom JS api

These two are nothing to do with styles or CSS.

 I have issues with the argument that we should do it lazily.  On one hand, 
 if node distribution is so expensive that we need to do it lazily, then it's 
 unacceptable to make event dispatching so much slower.  On the other hand, 
 if node distribution is fast, as it should be, then there is no reason we 
 need to do it lazily.
 
 The problem is really the redistributions. If we instead had explicit 
 insertion points under each shadow host, then we wouldn't really need 
 redistributions at all, and node distribution can happen in O(1) per child 
 change.
 
 As repeatedly stated, redistribution appears to be a necessity for
 composition to work in all but the most trivial cases.

Where?  I have not yet to see a use case for which selective redistribution of 
nodes (i.e. redistributing only a non-empty strict subset of nodes from an 
insertion point) are required.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-05 Thread Anne van Kesteren
On Wed, May 6, 2015 at 3:22 AM, Ryosuke Niwa rn...@apple.com wrote:
 Where?  I have not yet to see a use case for which selective redistribution 
 of nodes (i.e. redistributing only a non-empty strict subset of nodes from an 
 insertion point) are required.

Isn't that what e.g. select does? That is, select only cares about
option and optgroup elements that are passed to it.


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-05 Thread Tab Atkins Jr.
On Tue, May 5, 2015 at 11:20 AM, Ryosuke Niwa rn...@apple.com wrote:
 On May 4, 2015, at 10:20 PM, Anne van Kesteren ann...@annevk.nl wrote:

 On Tue, May 5, 2015 at 6:58 AM, Elliott Sprehn espr...@chromium.org wrote:
 We can solve this
 problem by running the distribution code in a separate scripting context
 with a restricted (distribution specific) API as is being discussed for
 other extension points in the platform.

 That seems like a lot of added complexity, but yeah, that would be an
 option I suppose. Dimitri added something like this to the imperative
 API proposal page a couple of days ago.


 One thing to consider here is that we very much consider distribution a
 style concept. It's about computing who you inherit style from and where you
 should be in the box tree. It just so happens it's also leveraged in event
 dispatch too (like pointer-events). It happens asynchronously from DOM
 mutation as needed just like style and reflow though.

 I don't really see it that way. The render tree is still computed from
 the composed tree. The composed tree is still a DOM tree, just
 composed from various other trees. In the open case you can access
 it synchronously through various APIs (e.g.  if we keep that for
 querySelector() selectors and also deepPath).

 I agree. I don't see any reason node distribution should be considered as a 
 style concept. It's a DOM concept. There is no CSS involved here.

Yes there is.  As Elliot stated in the elided parts of his quoted
response above, most of the places where we update distribution are
for CSS or related concerns:

# 3 event related
# 3 shadow dom JS api
# 9 style (one of these is flushing style)
# 1 query selector (for ::content and :host-context)

 I have issues with the argument that we should do it lazily.  On one hand, if 
 node distribution is so expensive that we need to do it lazily, then it's 
 unacceptable to make event dispatching so much slower.  On the other hand, if 
 node distribution is fast, as it should be, then there is no reason we need 
 to do it lazily.

 The problem is really the redistributions. If we instead had explicit 
 insertion points under each shadow host, then we wouldn't really need 
 redistributions at all, and node distribution can happen in O(1) per child 
 change.

As repeatedly stated, redistribution appears to be a necessity for
composition to work in all but the most trivial cases.

~TJ



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-05 Thread Ryosuke Niwa

 On May 4, 2015, at 10:20 PM, Anne van Kesteren ann...@annevk.nl wrote:
 
 On Tue, May 5, 2015 at 6:58 AM, Elliott Sprehn espr...@chromium.org wrote:
 We can solve this
 problem by running the distribution code in a separate scripting context
 with a restricted (distribution specific) API as is being discussed for
 other extension points in the platform.
 
 That seems like a lot of added complexity, but yeah, that would be an
 option I suppose. Dimitri added something like this to the imperative
 API proposal page a couple of days ago.
 
 
 One thing to consider here is that we very much consider distribution a
 style concept. It's about computing who you inherit style from and where you
 should be in the box tree. It just so happens it's also leveraged in event
 dispatch too (like pointer-events). It happens asynchronously from DOM
 mutation as needed just like style and reflow though.
 
 I don't really see it that way. The render tree is still computed from
 the composed tree. The composed tree is still a DOM tree, just
 composed from various other trees. In the open case you can access
 it synchronously through various APIs (e.g.  if we keep that for
 querySelector() selectors and also deepPath).

I agree. I don't see any reason node distribution should be considered as a 
style concept. It's a DOM concept. There is no CSS involved here.

I have issues with the argument that we should do it lazily.  On one hand, if 
node distribution is so expensive that we need to do it lazily, then it's 
unacceptable to make event dispatching so much slower.  On the other hand, if 
node distribution is fast, as it should be, then there is no reason we need to 
do it lazily.

The problem is really the redistributions. If we instead had explicit insertion 
points under each shadow host, then we wouldn't really need redistributions at 
all, and node distribution can happen in O(1) per child change.

- R. Niwa



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-04 Thread Elliott Sprehn
On Thu, Apr 30, 2015 at 6:22 AM, Anne van Kesteren ann...@annevk.nl wrote:

 On Thu, Apr 30, 2015 at 3:05 PM, Hayato Ito hay...@chromium.org wrote:
  That's the exactly intended behavior in the current spec.
  The timing of distribution is not observable.

 Right, but you can synchronously observe whether something is
 distributed. The combination of those two things coupled with us not
 wanting to introduce new synchronous mutation observers is what
 creates problems for an imperative API.


 So if we want an imperative API we need to make a tradeoff. Do we care
 about offsetTop et al or do we care about microtask-based mutation
 observers? I'm inclined to think we care more about the latter, but
 the gist I put forward takes a position on neither and leaves it up to
 web developers when they want to distribute (if at all).


We don't need to pick from either of those choices. We can solve this
problem by running the distribution code in a separate scripting context
with a restricted (distribution specific) API as is being discussed for
other extension points in the platform.

One thing to consider here is that we very much consider distribution a
style concept. It's about computing who you inherit style from and where
you should be in the box tree. It just so happens it's also leveraged in
event dispatch too (like pointer-events). It happens asynchronously from
DOM mutation as needed just like style and reflow though.

We don't want synchronous reflow inside appendChild because it means
authors would have to be very careful when mutating the DOM to avoid extra
churn. Distribution is the same way, we want it async so the browser can
batch the work and only distribute when the result is actually needed.

In our code if you look at the very few places we update distribution
explicitly:

3 event related
3 shadow dom JS api
9 style (one of these is flushing style)
1 query selector (for ::content and :host-context)

And all other places where distribution wants to be updated are because we
flush style (or layout) because what that caller really wanted to know was
something about the rendering.

- E


Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-05-04 Thread Anne van Kesteren
On Tue, May 5, 2015 at 6:58 AM, Elliott Sprehn espr...@chromium.org wrote:
 We can solve this
 problem by running the distribution code in a separate scripting context
 with a restricted (distribution specific) API as is being discussed for
 other extension points in the platform.

That seems like a lot of added complexity, but yeah, that would be an
option I suppose. Dimitri added something like this to the imperative
API proposal page a couple of days ago.


 One thing to consider here is that we very much consider distribution a
 style concept. It's about computing who you inherit style from and where you
 should be in the box tree. It just so happens it's also leveraged in event
 dispatch too (like pointer-events). It happens asynchronously from DOM
 mutation as needed just like style and reflow though.

I don't really see it that way. The render tree is still computed from
the composed tree. The composed tree is still a DOM tree, just
composed from various other trees. In the open case you can access
it synchronously through various APIs (e.g.  if we keep that for
querySelector() selectors and also deepPath).


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Anne van Kesteren
On Mon, Apr 27, 2015 at 11:05 PM, Ryosuke Niwa rn...@apple.com wrote:
 I’m writing any kind of component that creates a shadow DOM, I’d just keep 
 references to all my insertion points instead of querying them each time I 
 need to distribute nodes.

I guess that is true if you know you're not going to modify your
insertion points or shadow tree. I would be happy to update the gist
to exclude this parameter and instead use something like

  shadow.querySelector(content)

somewhere. It doesn't seem important.


 Another important use case to consider is adding insertion points given the 
 list of nodes to distribute.  For example, you may want to “wrap” each node 
 you distribute by an element.  That requires the component author to know the 
 number of nodes to distribute upfront and then dynamically create as many 
 insertion points as needed.

That seems doable.


 So you mean that we'd turn distributionList into a subtree?

 Consider table-chart component which coverts a table element into a chart 
 with each column represented as a line graph in the chart. The user of this 
 component will wrap a regular table element with table-chart element to 
 construct a shadow DOM:

 ```html
 table-chart
   table
 ...
   td data-value=“253” data-delta=5253 ± 5/td
 ...
   /table
 /table-chart
 ```

 Now, suppose I wanted to show a tooltip with the value in the chart. One 
 obvious way to accomplish this would be distributing the td corresponding to 
 the currently selected point into the tooltip. But this requires us allowing 
 non-direct child nodes to be distributed.

So if we did that, distributionList would become distributionRoot. And
whenever add() is invoked any node that is not a descendant of
distributionRoot or is a descendant of a node already add()'d would
throw? It seems that would get us a bit more complexity than the
current algorithm...


 The other thing I would like to explore is what an API would look like
 that does the subclassing as well.

 For the slot approach, we can model the act of filling a slot as if attaching 
 a shadow root to the slot and the slot content going into the shadow DOM for 
 both content distribution and filling of slots by subclasses.

 Now we can do this in either of the following two strategies:
 1. Superclass wants to see a list of slot contents from subclasses.
 2. Each subclass overrides previous distribution done by superclass by 
 inspecting insertion points in the shadow DOM and modifying them as needed.

With the existence of closed shadow trees, it seems like you'd want to
allow for the superclass to not have to share its details with the
subclass.


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Anne van Kesteren
On Thu, Apr 30, 2015 at 2:30 PM, Domenic Denicola d...@domenic.me wrote:
 Can someone point me to the part of the spec that is problematic? That is,
 where is the line that says UAs may run this algorithm at any time? I am
 not sure what to Ctrl+F for.

At the end of section 3.4 it states If any condition which affects
the distribution result changes, the distribution result must be
updated before any use of the distribution result. which basically
means you can't make use of a dirty tree.


 Secondly, could someone produce a code snippet that would cause such interop
 problems, given the current spec?

  var x = new Event(eventType)
  someNodeThatIsDistributed.addEventListener(eventType, e =
console.log(e.path))
  someNodeThatIsDistributed.dispatchEvent(ev);


 Finally, assuming we have such an example, would there be a way to tighten
 the spec language such that we don't need to specify e.g. when style
 recalculation happens, but instead specify constraints? Like offsetTop must
 always reflect the redistributions or something.

That is what the specification currently does and what prevents us
from defining an imperative API. For an imperative API it is
imperative (mahaha) that we get the timing with respect to tasks
right. (Or as per my proposal, leave timing up to developers.)


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Anne van Kesteren
On Thu, Apr 30, 2015 at 3:05 PM, Hayato Ito hay...@chromium.org wrote:
 That's the exactly intended behavior in the current spec.
 The timing of distribution is not observable.

Right, but you can synchronously observe whether something is
distributed. The combination of those two things coupled with us not
wanting to introduce new synchronous mutation observers is what
creates problems for an imperative API.

So if we want an imperative API we need to make a tradeoff. Do we care
about offsetTop et al or do we care about microtask-based mutation
observers? I'm inclined to think we care more about the latter, but
the gist I put forward takes a position on neither and leaves it up to
web developers when they want to distribute (if at all).


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Anne van Kesteren
On Tue, Apr 28, 2015 at 12:31 AM, Hayato Ito hay...@chromium.org wrote:
 I think there are a lot of user operations where distribution must be
 updated before returning the meaningful result synchronously.
 Unless distribution result is correctly updated, users would take the dirty
 result.

 For example:
 - element.offsetWidth:  Style resolution requires distribution. We must
 update distribution, if it's dirty, before calculation offsetWidth
 synchronously.
 - event dispatching: event path requires distribution because it needs a
 composed tree.

 Can the current HTML/DOM specs are rich enough to explain the timing when
 the imperative APIs should be run in these cases?

The imperative API I proposed leaves the timing up to whenever
distribute() is invoked by the developer. Currently at best that can
be done from mutation observers. And I think that's fine for v1.
element.offsetWidth et al are bad APIs that we should not accommodate
for. The results they return will be deterministic, but they should
not cause further side effects such as distribution and therefore the
results might appear incorrect I suppose depending on what point of
view you have.

We discussed this point at the meeting.


 For me, the imperative APIs for distribution sounds very similar to the
 imperative APIs for style resolution. The difficulties of both problems
 might be similar.

Only if you insist on coupling them are they similar. And only if you
insist on semantics that are identical to content select. This is
the very reason why content select is not acceptable as it would
require solving that problem. Whereas an imperative API free of the
warts of element.offsetWidth would not have to.


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Anne van Kesteren
On Tue, Apr 28, 2015 at 5:48 AM, Ryosuke Niwa rn...@apple.com wrote:
 One thing that worries me about the `distribute` callback approach (a.k.a. 
 Anne's approach) is that it bakes distribution algorithm into the platform 
 without us having thoroughly studied how subclassing will be done upfront.

Agreed. Dimitri saying these are largely orthogonal makes me hopeful,
but I would prefer to see a strawman API for it before fully
committing to the distribute() design on my gist.


 Mozilla tried to solve this problem with XBL, and they seem to think what 
 they have isn't really great.

Actually, I think that we found we needed something. What was
originally in the Shadow DOM specification was sufficient for our
needs I believe, but got removed...


 In that regard, the first approach w/o distribution has an advantage of 
 letting Web developer experiment with the bare minimum and try out which 
 distribution algorithms and mechanisms work best.

Except that you don't have a clear story for how to move to a
declarative syntax later on. And redistribution seems somewhat
essential as it mostly depends on where you put your host element
whether you're subject to it. Making it immaterial where you put your
host element seems important.


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Anne van Kesteren
On Thu, Apr 30, 2015 at 2:44 PM, Domenic Denicola d...@domenic.me wrote:
 From: Anne van Kesteren ann...@annevk.nl
  var x = new Event(eventType)
  someNodeThatIsDistributed.addEventListener(eventType, e = 
 console.log(e.path))
  someNodeThatIsDistributed.dispatchEvent(ev);

 Can you explain in a bit more detail why this causes interop problems? What 
 browsers would give different results for this code? What would those results 
 be?

This essentially forces distribution to happen since you can observe
the result of distribution this way. Same with element.offsetWidth
etc. And that's not necessarily problematic, but it is problematic if
you want to do an imperative API as I tried to explain in the bit you
did not quote back.


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Hayato Ito
On Thu, Apr 30, 2015 at 9:54 PM Anne van Kesteren ann...@annevk.nl wrote:

 On Thu, Apr 30, 2015 at 2:44 PM, Domenic Denicola d...@domenic.me wrote:
  From: Anne van Kesteren ann...@annevk.nl
   var x = new Event(eventType)
   someNodeThatIsDistributed.addEventListener(eventType, e =
 console.log(e.path))
   someNodeThatIsDistributed.dispatchEvent(ev);
 
  Can you explain in a bit more detail why this causes interop problems?
 What browsers would give different results for this code? What would those
 results be?

 This essentially forces distribution to happen since you can observe
 the result of distribution this way. Same with element.offsetWidth
 etc.


That's the exactly intended behavior in the current spec.
The timing of distribution is not observable. That enables UA to optimize
the distribution calc. We can delay the calculation of the distribution as
possible as we can. We don't need to calc distribution every time when a
mutation occurs.

If you find any interop issue in the current spec about distribution,
please file a bug with a concrete example.






 --
 https://annevankesteren.nl/




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Ryosuke Niwa

 On Apr 30, 2015, at 5:12 AM, Anne van Kesteren ann...@annevk.nl wrote:
 
 On Mon, Apr 27, 2015 at 11:05 PM, Ryosuke Niwa rn...@apple.com wrote:
 The other thing I would like to explore is what an API would look like
 that does the subclassing as well.
 
 For the slot approach, we can model the act of filling a slot as if 
 attaching a shadow root to the slot and the slot content going into the 
 shadow DOM for both content distribution and filling of slots by subclasses.
 
 Now we can do this in either of the following two strategies:
 1. Superclass wants to see a list of slot contents from subclasses.
 2. Each subclass overrides previous distribution done by superclass by 
 inspecting insertion points in the shadow DOM and modifying them as needed.
 
 With the existence of closed shadow trees, it seems like you'd want to
 allow for the superclass to not have to share its details with the
 subclass.

Neither approach needs to expose internals of superclass' shadow DOM.  In 1, 
what superclass seems is a list of proxies of slot contents subclasses 
provided.  In 2, what subclass sees is a list of wrappers of overridable 
insertion points superclass defined.

I can't think of an inheritance model in any programming language in which 
overridable pieces are unknown to subclasses.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Ryosuke Niwa

 On Apr 30, 2015, at 5:12 AM, Anne van Kesteren ann...@annevk.nl wrote:
 
 On Mon, Apr 27, 2015 at 11:05 PM, Ryosuke Niwa rn...@apple.com wrote:
 I’m writing any kind of component that creates a shadow DOM, I’d just keep 
 references to all my insertion points instead of querying them each time I 
 need to distribute nodes.
 
 I guess that is true if you know you're not going to modify your
 insertion points or shadow tree. I would be happy to update the gist
 to exclude this parameter and instead use something like
 
  shadow.querySelector(content)
 
 somewhere. It doesn't seem important.

FYI, I've summarized everything we've discussed so far in 
https://gist.github.com/rniwa/2f14588926e1a11c65d3.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Ryosuke Niwa

 On Apr 30, 2015, at 6:00 AM, Domenic Denicola d...@domenic.me wrote:
 
 This essentially forces distribution to happen since you can observe the 
 result of distribution this way. Same with element.offsetWidth etc. And 
 that's not necessarily problematic,
 
 OK. So the claim that the current spec cannot be interoperably implemented is 
 false? (Not that I am a huge fan of content select, but I want to make sure 
 we have our arguments against it lined up and on solid footing.)
 
 but it is problematic if you want to do an imperative API as I tried to 
 explain in the bit you did not quote back.
 
 Sure, let's dig in to that claim now. Again, this is mostly clarifying 
 probing.
 
 Let's say we had an imperative API. As far as I understand from the gist, one 
 of the problems is when do we invoke the distributedCallback. If we use 
 MutationObserve time, then inconsistent states can be observed, etc.
 
 Why can't we say that this distributedCallback must be invoked at the same 
 time that the current spec updates the distribution result? Since it sounds 
 like there is no interop problem with this timing, I don't understand why 
 this wouldn't be an option.

There will be an interop problem. Consider a following example:

```js
someNode = ~
myButton.appendChild(someNode); // (1)
absolutelyPositionElement.offsetTop; // (2)
```

Now suppose absolutelyPositionElement.offsetTop is a some element that's in a 
disjoint subtree of the document. Heck, it could even in a separate iframe. In 
some UAs, (2) will trigger style resolution and update of the layout. Because 
UAs can't tell redistribution of myButton can affect (2), such UAs will update 
the distribution per spec text that says the distribution result must be 
updated before any _use_ of the distribution result.

Yet in other UAs, `offsetTop` may have been cached and UA might be smart enough 
to detect that (1) doesn't affect the result of 
`absolutelyPositionElement.offsetTop` because they're in a different parts of 
the tree and they're independent for the purpose of style resolution and 
layout. In such UAs, (2) does not trigger redistribution because it does not 
use the distribution result in order to compute this value.

In general, there are thousands of other DOM and CSS OM APIs that may or may 
not _use_ the distribution result depending on implementations.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Elliott Sprehn
On Thu, Apr 30, 2015 at 8:57 PM, Ryosuke Niwa rn...@apple.com wrote:

 ...
 
  The return value of (2) is the same in either case. There is no
 observable difference. No interop issue.
 
  Please file a bug for the spec with a concrete example if you can find a
 observable difference due to the lazy-evaluation of the distribution.

 The problem isn't so much that the current shadow DOM specification has an
 interop issue because what we're talking here, as the thread title clearly
 communicates, is the imperative API for node distribution, which doesn't
 exist in the current specification.

 In particular, invoking user code at the timing specified in section 3.4
 which states if any condition which affects the distribution result
 changes, the distribution result must be updated before any use of the
 distribution result introduces a new interoperability issue because
 before any use of the distribution result is implementation dependent.
 e.g. element.offsetTop may or not may use the distribution result depending
 on UA.  Furthermore, it's undesirable to precisely spec this since doing so
 will impose a serious limitation on what UAs could optimize in the future.


element.offsetTop must use the distribution result, there's no way to know
what your style is without computing your distribution. This isn't any
different than getComputedStyle(...).color needing to flush style, or
getBoundingClientRect() needing to flush layout.

Distribution is about computing who your parent and siblings are in the box
tree, and where your should inherit your style from. Doing it lazy is not
going to be any worse in terms of interop than defining new properties that
depend on style.

- E


Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Ryosuke Niwa

 On Apr 30, 2015, at 9:25 PM, Elliott Sprehn espr...@chromium.org wrote:
 
 On Thu, Apr 30, 2015 at 8:57 PM, Ryosuke Niwa rn...@apple.com wrote:
 ...
 
  The return value of (2) is the same in either case. There is no observable 
  difference. No interop issue.
 
  Please file a bug for the spec with a concrete example if you can find a 
  observable difference due to the lazy-evaluation of the distribution.
 
 The problem isn't so much that the current shadow DOM specification has an 
 interop issue because what we're talking here, as the thread title clearly 
 communicates, is the imperative API for node distribution, which doesn't 
 exist in the current specification.
 
 In particular, invoking user code at the timing specified in section 3.4 
 which states if any condition which affects the distribution result 
 changes, the distribution result must be updated before any use of the 
 distribution result introduces a new interoperability issue because before 
 any use of the distribution result is implementation dependent.  e.g. 
 element.offsetTop may or not may use the distribution result depending on 
 UA.  Furthermore, it's undesirable to precisely spec this since doing so 
 will impose a serious limitation on what UAs could optimize in the future.
 
 
 element.offsetTop must use the distribution result, there's no way to know 
 what your style is without computing your distribution. This isn't any 
 different than getComputedStyle(...).color needing to flush style, or 
 getBoundingClientRect() needing to flush layout.

That is true only if the distribution of a given node can affect the style of 
element. There are cases in which UAs can deduce that such is not the case and 
optimize the style recalculation away. e.g. two elements belonging two 
different documents.

Another example will be element.isContentEditable. Under certain circumstances 
WebKit needs to resolve styles in order to determine the value of this function 
which, then, uses the distribution result.

 Distribution is about computing who your parent and siblings are in the box 
 tree, and where your should inherit your style from. Doing it lazy is not 
 going to be any worse in terms of interop than defining new properties that 
 depend on style.

The problem is that different engines have different mechanism to deduce style 
dependencies between elements.

- R. Niwa



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Ryosuke Niwa

 On Apr 30, 2015, at 9:01 PM, Hayato Ito hay...@chromium.org wrote:
 
 Thanks, however, we're talking about 
 https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0442.html.

Ah, I think there was some miscommunication there. I don't think anyone is 
claiming that the current spec results in interop issues. The currently spec'ed 
timing is only problematic when we try to invoke an author-defined callback at 
that moment. If we never added an imperative API or an imperative API we add 
don't invoke user code at the currently spec'ed timing, we don't have any 
interop problem.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Hayato Ito
On Fri, May 1, 2015 at 2:59 AM Ryosuke Niwa rn...@apple.com wrote:


  On Apr 30, 2015, at 6:00 AM, Domenic Denicola d...@domenic.me wrote:
 
  This essentially forces distribution to happen since you can observe
 the result of distribution this way. Same with element.offsetWidth etc. And
 that's not necessarily problematic,
 
  OK. So the claim that the current spec cannot be interoperably
 implemented is false? (Not that I am a huge fan of content select, but I
 want to make sure we have our arguments against it lined up and on solid
 footing.)
 
  but it is problematic if you want to do an imperative API as I tried to
 explain in the bit you did not quote back.
 
  Sure, let's dig in to that claim now. Again, this is mostly clarifying
 probing.
 
  Let's say we had an imperative API. As far as I understand from the
 gist, one of the problems is when do we invoke the distributedCallback. If
 we use MutationObserve time, then inconsistent states can be observed, etc.
 
  Why can't we say that this distributedCallback must be invoked at the
 same time that the current spec updates the distribution result? Since it
 sounds like there is no interop problem with this timing, I don't
 understand why this wouldn't be an option.

 There will be an interop problem. Consider a following example:


The return value of (2) is the same in either case. There is no observable
difference. No interop issue.

Please file a bug for the spec with a concrete example if you can find a
observable difference due to the lazy-evaluation of the distribution.



 ```js
 someNode = ~
 myButton.appendChild(someNode); // (1)
 absolutelyPositionElement.offsetTop; // (2)
 ```

 Now suppose absolutelyPositionElement.offsetTop is a some element that's
 in a disjoint subtree of the document. Heck, it could even in a separate
 iframe. In some UAs, (2) will trigger style resolution and update of the
 layout. Because UAs can't tell redistribution of myButton can affect (2),
 such UAs will update the distribution per spec text that says the
 distribution result must be updated before any _use_ of the distribution
 result.

 Yet in other UAs, `offsetTop` may have been cached and UA might be smart
 enough to detect that (1) doesn't affect the result of
 `absolutelyPositionElement.offsetTop` because they're in a different parts
 of the tree and they're independent for the purpose of style resolution and
 layout. In such UAs, (2) does not trigger redistribution because it does
 not use the distribution result in order to compute this value.

 In general, there are thousands of other DOM and CSS OM APIs that may or
 may not _use_ the distribution result depending on implementations.

 - R. Niwa





Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Ryosuke Niwa
On Apr 30, 2015, at 8:17 PM, Hayato Ito hay...@chromium.org wrote:
 On Fri, May 1, 2015 at 2:59 AM Ryosuke Niwa rn...@apple.com wrote:
 
  On Apr 30, 2015, at 6:00 AM, Domenic Denicola d...@domenic.me wrote:
 
  This essentially forces distribution to happen since you can observe the 
  result of distribution this way. Same with element.offsetWidth etc. And 
  that's not necessarily problematic,
 
  OK. So the claim that the current spec cannot be interoperably implemented 
  is false? (Not that I am a huge fan of content select, but I want to 
  make sure we have our arguments against it lined up and on solid footing.)
 
  but it is problematic if you want to do an imperative API as I tried to 
  explain in the bit you did not quote back.
 
  Sure, let's dig in to that claim now. Again, this is mostly clarifying 
  probing.
 
  Let's say we had an imperative API. As far as I understand from the gist, 
  one of the problems is when do we invoke the distributedCallback. If we 
  use MutationObserve time, then inconsistent states can be observed, etc.
 
  Why can't we say that this distributedCallback must be invoked at the same 
  time that the current spec updates the distribution result? Since it 
  sounds like there is no interop problem with this timing, I don't 
  understand why this wouldn't be an option.
 
 There will be an interop problem. Consider a following example:
 
 
 The return value of (2) is the same in either case. There is no observable 
 difference. No interop issue.
 
 Please file a bug for the spec with a concrete example if you can find a 
 observable difference due to the lazy-evaluation of the distribution.

The problem isn't so much that the current shadow DOM specification has an 
interop issue because what we're talking here, as the thread title clearly 
communicates, is the imperative API for node distribution, which doesn't exist 
in the current specification.

In particular, invoking user code at the timing specified in section 3.4 which 
states if any condition which affects the distribution result changes, the 
distribution result must be updated before any use of the distribution result 
introduces a new interoperability issue because before any use of the 
distribution result is implementation dependent.  e.g. element.offsetTop may 
or not may use the distribution result depending on UA.  Furthermore, it's 
undesirable to precisely spec this since doing so will impose a serious 
limitation on what UAs could optimize in the future.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-30 Thread Hayato Ito
Thanks, however, we're talking about
https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0442.html.

On Fri, May 1, 2015 at 12:57 PM Ryosuke Niwa rn...@apple.com wrote:

 On Apr 30, 2015, at 8:17 PM, Hayato Ito hay...@chromium.org wrote:
  On Fri, May 1, 2015 at 2:59 AM Ryosuke Niwa rn...@apple.com wrote:
 
   On Apr 30, 2015, at 6:00 AM, Domenic Denicola d...@domenic.me wrote:
  
   This essentially forces distribution to happen since you can observe
 the result of distribution this way. Same with element.offsetWidth etc. And
 that's not necessarily problematic,
  
   OK. So the claim that the current spec cannot be interoperably
 implemented is false? (Not that I am a huge fan of content select, but I
 want to make sure we have our arguments against it lined up and on solid
 footing.)
  
   but it is problematic if you want to do an imperative API as I tried
 to explain in the bit you did not quote back.
  
   Sure, let's dig in to that claim now. Again, this is mostly
 clarifying probing.
  
   Let's say we had an imperative API. As far as I understand from the
 gist, one of the problems is when do we invoke the distributedCallback. If
 we use MutationObserve time, then inconsistent states can be observed, etc.
  
   Why can't we say that this distributedCallback must be invoked at the
 same time that the current spec updates the distribution result? Since it
 sounds like there is no interop problem with this timing, I don't
 understand why this wouldn't be an option.
 
  There will be an interop problem. Consider a following example:
 
 
  The return value of (2) is the same in either case. There is no
 observable difference. No interop issue.
 
  Please file a bug for the spec with a concrete example if you can find a
 observable difference due to the lazy-evaluation of the distribution.

 The problem isn't so much that the current shadow DOM specification has an
 interop issue because what we're talking here, as the thread title clearly
 communicates, is the imperative API for node distribution, which doesn't
 exist in the current specification.

 In particular, invoking user code at the timing specified in section 3.4
 which states if any condition which affects the distribution result
 changes, the distribution result must be updated before any use of the
 distribution result introduces a new interoperability issue because
 before any use of the distribution result is implementation dependent.
 e.g. element.offsetTop may or not may use the distribution result depending
 on UA.  Furthermore, it's undesirable to precisely spec this since doing so
 will impose a serious limitation on what UAs could optimize in the future.

 - R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-29 Thread Tab Atkins Jr.
On Wed, Apr 29, 2015 at 4:15 PM, Dimitri Glazkov dglaz...@google.com wrote:
 On Mon, Apr 27, 2015 at 8:48 PM, Ryosuke Niwa rn...@apple.com wrote:
 One thing that worries me about the `distribute` callback approach (a.k.a.
 Anne's approach) is that it bakes distribution algorithm into the platform
 without us having thoroughly studied how subclassing will be done upfront.

 Mozilla tried to solve this problem with XBS, and they seem to think what
 they have isn't really great. Google has spent multiple years working on
 this problem but they come around to say their solution, multiple
 generations of shadow DOM, may not be as great as they thought it would be.
 Given that, I'm quite terrified of making the same mistake in spec'ing how
 distribution works and later regretting it.

 At least the way I understand it, multiple shadow roots per element and
 distributions are largely orthogonal bits of machinery that solve largely
 orthogonal problems.

Yes.  Distribution is mainly about making composition of components
work seamlessly, so you can easily pass elements from your light dom
into some components you're using inside your shadow dom.  Without
distribution, you're stuck with either:

* avoiding content entirely and literally moving the elements from
the light dom to your shadow tree (like, appendChild() the nodes
themselves), which means the outer page no longer has access to the
elements for their own styling or scripting purposes (this is
terribad, obviously), or
* components have to be explicitly written with the expectation of
being composed into other components, writing their own content
select *to target the content elements of the outer shadow*, which
is also extremely terribad.

Distribution makes composition *work*, in a fundamental way.  Without
it, you simply don't have the ability to use components inside of
components except in special cases.

~TJ



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-29 Thread Tab Atkins Jr.
On Wed, Apr 29, 2015 at 4:47 PM, Ryosuke Niwa rn...@apple.com wrote:
 On Apr 29, 2015, at 4:37 PM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 On Wed, Apr 29, 2015 at 4:15 PM, Dimitri Glazkov dglaz...@google.com wrote:
 On Mon, Apr 27, 2015 at 8:48 PM, Ryosuke Niwa rn...@apple.com wrote:
 One thing that worries me about the `distribute` callback approach (a.k.a.
 Anne's approach) is that it bakes distribution algorithm into the platform
 without us having thoroughly studied how subclassing will be done upfront.

 Mozilla tried to solve this problem with XBS, and they seem to think what
 they have isn't really great. Google has spent multiple years working on
 this problem but they come around to say their solution, multiple
 generations of shadow DOM, may not be as great as they thought it would be.
 Given that, I'm quite terrified of making the same mistake in spec'ing how
 distribution works and later regretting it.

 At least the way I understand it, multiple shadow roots per element and
 distributions are largely orthogonal bits of machinery that solve largely
 orthogonal problems.

 Yes.  Distribution is mainly about making composition of components
 work seamlessly, so you can easily pass elements from your light dom
 into some components you're using inside your shadow dom.  Without
 distribution, you're stuck with either:

 As I clarified my point in another email, neither I nor anyone else is 
 questioning the value of the first-degree of node distribution from the 
 light DOM into insertion points of a shadow DOM.  What I'm questioning is 
 the value of the capability to selectively re-distribute those nodes in a 
 tree with nested shadow DOMs.

 * components have to be explicitly written with the expectation of
 being composed into other components, writing their own content
 select *to target the content elements of the outer shadow*, which
 is also extremely terribad.

 Could you give me a concrete use case in which such inspection of content 
 elements in the light DOM is required without multiple generations of shadow 
 DOM?  In all the use cases I've studied without multiple generations of 
 shadow DOM, none required the ability to filter nodes inside a content 
 element.

 Distribution makes composition *work*, in a fundamental way.  Without it, 
 you simply don't have the ability to use components inside of components 
 except in special cases.

 Could you give us a concrete example in which selective re-distribution of 
 nodes are required? That'll settle this discussion/question altogether.

I'll let a Polymer person provide a concrete example, as they're the
ones that originally brought up redistribution and convinced us it was
needed, but imagine literally any component that uses more than one
content (so you can't get away with just distributing the content
element itself), being used inside of some other component that wants
to pass some of its light-dom children to the nested component.

Without redistribution, you can only nest components (using one
component inside the shadow dom of another) if you either provide
contents directly to the nested component (no content) or the nested
component only has a single distribution point in its own shadow.

~TJ



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-29 Thread Justin Fagnani
Here's one case of redistribution:
https://github.com/Polymer/core-scaffold/blob/master/core-scaffold.html#L122

Any time you see content inside a custom element it's potentially
redistribution. Here there's on that is (line 122), and one that could be
(line 116), and one that definitely isn't (line 106).

I personally think that Hayato's analogy to function parameters is very
motivating. Arguing from use-cases at this point is going to miss many
things because so far we've focused on the most simple of components, are
having to rewrite them for Polymer 0.8, and haven't seen the variety and
complexity of cases that will evolve naturally from the community. General
expressiveness is extremely important when you don't have an option to work
around it - redistribution is one of these cases.

Cheers,
  Justin


On Wed, Apr 29, 2015 at 4:57 PM, Tab Atkins Jr. jackalm...@gmail.com
wrote:

 On Wed, Apr 29, 2015 at 4:47 PM, Ryosuke Niwa rn...@apple.com wrote:
  On Apr 29, 2015, at 4:37 PM, Tab Atkins Jr. jackalm...@gmail.com
 wrote:
  On Wed, Apr 29, 2015 at 4:15 PM, Dimitri Glazkov dglaz...@google.com
 wrote:
  On Mon, Apr 27, 2015 at 8:48 PM, Ryosuke Niwa rn...@apple.com wrote:
  One thing that worries me about the `distribute` callback approach
 (a.k.a.
  Anne's approach) is that it bakes distribution algorithm into the
 platform
  without us having thoroughly studied how subclassing will be done
 upfront.
 
  Mozilla tried to solve this problem with XBS, and they seem to think
 what
  they have isn't really great. Google has spent multiple years working
 on
  this problem but they come around to say their solution, multiple
  generations of shadow DOM, may not be as great as they thought it
 would be.
  Given that, I'm quite terrified of making the same mistake in
 spec'ing how
  distribution works and later regretting it.
 
  At least the way I understand it, multiple shadow roots per element and
  distributions are largely orthogonal bits of machinery that solve
 largely
  orthogonal problems.
 
  Yes.  Distribution is mainly about making composition of components
  work seamlessly, so you can easily pass elements from your light dom
  into some components you're using inside your shadow dom.  Without
  distribution, you're stuck with either:
 
  As I clarified my point in another email, neither I nor anyone else is
 questioning the value of the first-degree of node distribution from the
 light DOM into insertion points of a shadow DOM.  What I'm questioning is
 the value of the capability to selectively re-distribute those nodes in a
 tree with nested shadow DOMs.
 
  * components have to be explicitly written with the expectation of
  being composed into other components, writing their own content
  select *to target the content elements of the outer shadow*, which
  is also extremely terribad.
 
  Could you give me a concrete use case in which such inspection of
 content elements in the light DOM is required without multiple generations
 of shadow DOM?  In all the use cases I've studied without multiple
 generations of shadow DOM, none required the ability to filter nodes inside
 a content element.
 
  Distribution makes composition *work*, in a fundamental way.  Without
 it, you simply don't have the ability to use components inside of
 components except in special cases.
 
  Could you give us a concrete example in which selective re-distribution
 of nodes are required? That'll settle this discussion/question altogether.

 I'll let a Polymer person provide a concrete example, as they're the
 ones that originally brought up redistribution and convinced us it was
 needed, but imagine literally any component that uses more than one
 content (so you can't get away with just distributing the content
 element itself), being used inside of some other component that wants
 to pass some of its light-dom children to the nested component.

 Without redistribution, you can only nest components (using one
 component inside the shadow dom of another) if you either provide
 contents directly to the nested component (no content) or the nested
 component only has a single distribution point in its own shadow.

 ~TJ



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-29 Thread Dimitri Glazkov
On Mon, Apr 27, 2015 at 8:48 PM, Ryosuke Niwa rn...@apple.com wrote:

 One thing that worries me about the `distribute` callback approach (a.k.a.
 Anne's approach) is that it bakes distribution algorithm into the platform
 without us having thoroughly studied how subclassing will be done upfront.

 Mozilla tried to solve this problem with XBS, and they seem to think what
 they have isn't really great. Google has spent multiple years working on
 this problem but they come around to say their solution, multiple
 generations of shadow DOM, may not be as great as they thought it would be.
 Given that, I'm quite terrified of making the same mistake in spec'ing how
 distribution works and later regretting it.


At least the way I understand it, multiple shadow roots per element and
distributions are largely orthogonal bits of machinery that solve largely
orthogonal problems.

:DG


Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-29 Thread Dimitri Glazkov
On Tue, Apr 28, 2015 at 1:52 PM, Ryosuke Niwa rn...@apple.com wrote:

 I've updated the gist to reflect the discussion so far:
 https://gist.github.com/rniwa/2f14588926e1a11c65d3

 Please leave a comment if I missed anything.


Thank you for doing this. There are a couple of unescaped tags in
https://gist.github.com/rniwa/2f14588926e1a11c65d3#extention-to-custom-elements-for-consistency,
I think?

Any chance you could move it to the Web Components wiki? That way, we could
all collaborate.

:DG


Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-29 Thread Ryosuke Niwa

 On Apr 29, 2015, at 4:37 PM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 
 On Wed, Apr 29, 2015 at 4:15 PM, Dimitri Glazkov dglaz...@google.com wrote:
 On Mon, Apr 27, 2015 at 8:48 PM, Ryosuke Niwa rn...@apple.com wrote:
 One thing that worries me about the `distribute` callback approach (a.k.a.
 Anne's approach) is that it bakes distribution algorithm into the platform
 without us having thoroughly studied how subclassing will be done upfront.
 
 Mozilla tried to solve this problem with XBS, and they seem to think what
 they have isn't really great. Google has spent multiple years working on
 this problem but they come around to say their solution, multiple
 generations of shadow DOM, may not be as great as they thought it would be.
 Given that, I'm quite terrified of making the same mistake in spec'ing how
 distribution works and later regretting it.
 
 At least the way I understand it, multiple shadow roots per element and
 distributions are largely orthogonal bits of machinery that solve largely
 orthogonal problems.
 
 Yes.  Distribution is mainly about making composition of components
 work seamlessly, so you can easily pass elements from your light dom
 into some components you're using inside your shadow dom.  Without
 distribution, you're stuck with either:

As I clarified my point in another email, neither I nor anyone else is 
questioning the value of the first-degree of node distribution from the light 
DOM into insertion points of a shadow DOM.  What I'm questioning is the value 
of the capability to selectively re-distribute those nodes in a tree with 
nested shadow DOMs.

 * components have to be explicitly written with the expectation of
 being composed into other components, writing their own content
 select *to target the content elements of the outer shadow*, which
 is also extremely terribad.

Could you give me a concrete use case in which such inspection of content 
elements in the light DOM is required without multiple generations of shadow 
DOM?  In all the use cases I've studied without multiple generations of shadow 
DOM, none required the ability to filter nodes inside a content element.

 Distribution makes composition *work*, in a fundamental way.  Without it, you 
 simply don't have the ability to use components inside of components except 
 in special cases.

Could you give us a concrete example in which selective re-distribution of 
nodes are required? That'll settle this discussion/question altogether.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-29 Thread Ryosuke Niwa

 On Apr 29, 2015, at 4:16 PM, Dimitri Glazkov dglaz...@google.com wrote:
 
 On Tue, Apr 28, 2015 at 1:52 PM, Ryosuke Niwa rn...@apple.com wrote:
 I've updated the gist to reflect the discussion so far:
 https://gist.github.com/rniwa/2f14588926e1a11c65d3
 
 Please leave a comment if I missed anything.
 
 Thank you for doing this. There are a couple of unescaped tags in 
 https://gist.github.com/rniwa/2f14588926e1a11c65d3#extention-to-custom-elements-for-consistency,
  I think?
 
 Any chance you could move it to the Web Components wiki? That way, we could 
 all collaborate.

Sure, what's the preferred work flow? Fork and push a PR?

- R. Niwa.




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-29 Thread Dimitri Glazkov
On Wed, Apr 29, 2015 at 5:59 PM, Ryosuke Niwa rn...@apple.com wrote:


  On Apr 29, 2015, at 4:16 PM, Dimitri Glazkov dglaz...@google.com
 wrote:
 
  On Tue, Apr 28, 2015 at 1:52 PM, Ryosuke Niwa rn...@apple.com wrote:
  I've updated the gist to reflect the discussion so far:
  https://gist.github.com/rniwa/2f14588926e1a11c65d3
 
  Please leave a comment if I missed anything.
 
  Thank you for doing this. There are a couple of unescaped tags in
 https://gist.github.com/rniwa/2f14588926e1a11c65d3#extention-to-custom-elements-for-consistency,
 I think?
 
  Any chance you could move it to the Web Components wiki? That way, we
 could all collaborate.

 Sure, what's the preferred work flow? Fork and push a PR?


Actually, we might need to figure this out first. Github Wiki is not
super-friendly to fork/push-PR model. But I do like your idea. Maybe just
an .md page in a repo?



 - R. Niwa.




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-29 Thread Ryosuke Niwa

 On Apr 29, 2015, at 5:12 PM, Justin Fagnani justinfagn...@google.com wrote:
 
 Here's one case of redistribution: 
 https://github.com/Polymer/core-scaffold/blob/master/core-scaffold.html#L122
 
 Any time you see content inside a custom element it's potentially 
 redistribution. Here there's on that is (line 122), and one that could be 
 (line 116), and one that definitely isn't (line 106).

Thank you very much for an example. I'm assuming core-header-panel is [1]? It 
grabs core-toolbar. It looks to me that we could also replace line 122 with:

```html
content class=.core-header select=core-toolbar, .core-header/content
content select=*/content
```

and you wouldn't need redistribution. I wouldn't argue that it provides a 
better developer ergonomics but there's a serious trade off here.

If we natively supported redistribution and always triggered via `distribute` 
callback, then it may not be acceptable to invoke `distribute` on every DOM 
change in terms of performance since that could easily result in O(n^2) 
behavior. This is why the proposal we (Anne, I, and others) discussed involved 
using mutation observers instead of childrenChanged lifecycle callbacks.

Now, frameworks such as Polymer could provide a sugar on top of it by 
automatically re-distributing nodes as needed when implementing your select 
attribute.

 I personally think that Hayato's analogy to function parameters is very 
 motivating. Arguing from use-cases at this point is going to miss many things 
 because so far we've focused on the most simple of components, are having to 
 rewrite them for Polymer 0.8, and haven't seen the variety and complexity of 
 cases that will evolve naturally from the community. General expressiveness 
 is extremely important when you don't have an option to work around it - 
 redistribution is one of these cases.

Evaluating each design proposal based on a concrete use case is extremely 
important precisely because we might miss out on expressiveness in some cases 
as we're stripping down features, and we can't reject a proposal or add a 
feature for a hypothetical/theoretical need.

[1] 
https://github.com/Polymer/core-header-panel/blob/master/core-header-panel.html

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-28 Thread Elliott Sprehn
A distribute callback means running script any time we update distribution,
which is inside the style update phase (or event path computation phase,
...) which is not a location we can run script. We could run script in
another scripting context like is being considered for custom layout and
paint though, but that has a different API shape since you'd register a
separate .js file as the custom distributor. like

(document || shadowRoot).registerCustomDistributor({src: distributor.js});

I also don't believe we should support distributing any arbitrary
descendant, that has a large complexity cost and doesn't feel like
simplification. It makes computing style and generating boxes much more
complicated.

A synchronous childrenChanged callback has similar issues with when it's
safe to run script, we'd have to defer it's execution in a number of
situations, and it feels like a duplication of MutationObservers which
specifically were designed to operate in batch for better performance and
fewer footguns (ex. a naive childrenChanged based distributor will be n^2).


On Mon, Apr 27, 2015 at 8:48 PM, Ryosuke Niwa rn...@apple.com wrote:


  On Apr 27, 2015, at 12:25 AM, Justin Fagnani justinfagn...@google.com
 wrote:
 
  On Sun, Apr 26, 2015 at 11:05 PM, Anne van Kesteren ann...@annevk.nl
 wrote:
  On Sat, Apr 25, 2015 at 10:49 PM, Ryosuke Niwa rn...@apple.com wrote:
   If we wanted to allow non-direct child descendent (e.g. grand child
 node) of
   the host to be distributed, then we'd also need O(m) algorithm where
 m is
   the number of under the host element.  It might be okay to carry on
 the
   current restraint that only direct child of shadow host can be
 distributed
   into insertion points but I can't think of a good reason as to why
 such a
   restriction is desirable.
 
  The main reason is that you know that only a direct parent of a node can
 distribute it. Otherwise any ancestor could distribute a node, and in
 addition to probably being confusing and fragile, you have to define who
 wins when multiple ancestors try to.
 
  There are cases where you really want to group element logically by one
 tree structure and visually by another, like tabs. I think an alternative
 approach to distributing arbitrary descendants would be to see if nodes can
 cooperate on distribution so that a node could pass its direct children to
 another node's insertion point. The direct child restriction would still be
 there, so you always know who's responsible, but you can get the same
 effect as distributing descendants for a cooperating sets of elements.

 That's an interesting approach. Ted and I discussed this design, and it
 seems workable with Anne's `distribute` callback approach (= the second
 approach in my proposal).

 Conceptually, we ask each child of a shadow host the list of distributable
 node for under that child (including itself). For normal node without a
 shadow root, it'll simply itself along with all the distribution candidates
 returned by its children. For a node with a shadow root, we ask its
 implementation. The recursive algorithm can be written as follows in pseudo
 code:

 ```
 NodeList distributionList(Node n):
   if n has shadowRoot:
 return ask n the list of distributable noes under n (1)
   else:
 list = [n]
 for each child in n:
   list += distributionList(n)
 return list
 ```

 Now, if we adopted `distribute` callback approach, one obvious mechanism
 to do (1) is to call `distribute` on n and return whatever it didn't
 distribute as a list. Another obvious approach is to simply return [n] to
 avoid the mess of n later deciding to distribute a new node.

  So you mean that we'd turn distributionList into a subtree? I.e. you
  can pass all descendants of a host element to add()? I remember Yehuda
  making the point that this was desirable to him.
 
  The other thing I would like to explore is what an API would look like
  that does the subclassing as well. Even though we deferred that to v2
  I got the impression talking to some folks after the meeting that
  there might be more common ground than I thought.
 
  I really don't think the platform needs to do anything to support
 subclassing since it can be done so easily at the library level now that
 multiple generations of shadow roots are gone. As long as a subclass and
 base class can cooperate to produce a single shadow root with insertion
 points, the platform doesn't need to know how they did it.

 I think we should eventually add native declarative inheritance support
 for all of this.

 One thing that worries me about the `distribute` callback approach (a.k.a.
 Anne's approach) is that it bakes distribution algorithm into the platform
 without us having thoroughly studied how subclassing will be done upfront.

 Mozilla tried to solve this problem with XBS, and they seem to think what
 they have isn't really great. Google has spent multiple years working on
 this problem but they come around to say their solution, 

Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-28 Thread Justin Fagnani
On Tue, Apr 28, 2015 at 4:32 PM, Ryosuke Niwa rn...@apple.com wrote:

 On Apr 27, 2015, at 4:23 PM, Tab Atkins Jr. jackalm...@gmail.com wrote:

 On Mon, Apr 27, 2015 at 4:06 PM, Tab Atkins Jr. jackalm...@gmail.com
 wrote:

 On Mon, Apr 27, 2015 at 3:42 PM, Ryosuke Niwa rn...@apple.com wrote:

 On Apr 27, 2015, at 3:15 PM, Steve Orvell sorv...@google.com wrote:
 IMO, the appeal of this proposal is that it's a small change to the
 current spec and avoids changing user expectations about the state of the
 dom and can explain the two declarative proposals for distribution.

 It seems like with this API, we’d have to make O(n^k) calls where n is the
 number of distribution candidates and k is the number of insertion points,
 and that’s bad.  Or am I misunderstanding your design?


 I think you've understood the proposed design. As you noted, the cost is
 actually O(n*k). In our use cases, k is generally very small.


 I don't think we want to introduce O(nk) algorithm. Pretty much every
 browser optimization we implement these days are removing O(n^2) algorithms
 in the favor of O(n) algorithms. Hard-baking O(nk) behavior is bad because
 we can't even theoretically optimize it away.


 You're aware, obviously, that O(n^2) is a far different beast than
 O(nk).  If k is generally small, which it is, O(nk) is basically just
 O(n) with a constant factor applied.


 To make it clear: I'm not trying to troll Ryosuke here.

 He argued that we don't want to add new O(n^2) algorithms if we can
 help it, and that we prefer O(n).  (Uncontroversial.)

 He then further said that an O(nk) algorithm is sufficiently close to
 O(n^2) that he'd similarly like to avoid it.  I'm trying to
 reiterate/expand on Steve's message here, that the k value in question
 is usually very small, relative to the value of n, so in practice this
 O(nk) is more similar to O(n) than O(n^2), and Ryosuke's aversion to
 new O(n^2) algorithms may be mistargeted here.


 Thanks for clarification. Just as Justin pointed out [1], one of the most
 important use case of imperative API is to dynamically insert as many
 insertion points as needed to wrap each distributed node.  In such a use
 case, this algorithm DOES result in O(n^2).


I think I said it was a possibility opened by an imperative API, but I
thought it would be very rare (as will be any modification of the shadow
root in the distribution callback). I think that accomplishing decoration
by inserting an insertion point per distributed node is probably a
degenerate case and it would be better if we supported decoration, but that
seems like a v2+ type feature.

-Justin



 In fact, it could even result in O(n^3) behavior depending on how we spec
 it.  If the user code had dynamically inserted insertion points one by one
 and UA invoked this callback function for each insertion point and each
 node.  If we didn't, then author needs a mechanism to let UA know that the
 condition by which insertion points select a node has changed and it needs
 to re-distribute all the nodes again.

 - R. Niwa

 [1]
 https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0325.html




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-28 Thread Ryosuke Niwa
On Apr 27, 2015, at 4:23 PM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 On Mon, Apr 27, 2015 at 4:06 PM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 On Mon, Apr 27, 2015 at 3:42 PM, Ryosuke Niwa rn...@apple.com wrote:
 On Apr 27, 2015, at 3:15 PM, Steve Orvell sorv...@google.com wrote:
 IMO, the appeal of this proposal is that it's a small change to the 
 current spec and avoids changing user expectations about the state of the 
 dom and can explain the two declarative proposals for distribution.
 
 It seems like with this API, we’d have to make O(n^k) calls where n is 
 the number of distribution candidates and k is the number of insertion 
 points, and that’s bad.  Or am I misunderstanding your design?
 
 I think you've understood the proposed design. As you noted, the cost is 
 actually O(n*k). In our use cases, k is generally very small.
 
 I don't think we want to introduce O(nk) algorithm. Pretty much every 
 browser optimization we implement these days are removing O(n^2) algorithms 
 in the favor of O(n) algorithms. Hard-baking O(nk) behavior is bad because 
 we can't even theoretically optimize it away.
 
 You're aware, obviously, that O(n^2) is a far different beast than
 O(nk).  If k is generally small, which it is, O(nk) is basically just
 O(n) with a constant factor applied.
 
 To make it clear: I'm not trying to troll Ryosuke here.
 
 He argued that we don't want to add new O(n^2) algorithms if we can
 help it, and that we prefer O(n).  (Uncontroversial.)
 
 He then further said that an O(nk) algorithm is sufficiently close to
 O(n^2) that he'd similarly like to avoid it.  I'm trying to
 reiterate/expand on Steve's message here, that the k value in question
 is usually very small, relative to the value of n, so in practice this
 O(nk) is more similar to O(n) than O(n^2), and Ryosuke's aversion to
 new O(n^2) algorithms may be mistargeted here.

Thanks for clarification. Just as Justin pointed out [1], one of the most 
important use case of imperative API is to dynamically insert as many insertion 
points as needed to wrap each distributed node.  In such a use case, this 
algorithm DOES result in O(n^2).

In fact, it could even result in O(n^3) behavior depending on how we spec it.  
If the user code had dynamically inserted insertion points one by one and UA 
invoked this callback function for each insertion point and each node.  If we 
didn't, then author needs a mechanism to let UA know that the condition by 
which insertion points select a node has changed and it needs to re-distribute 
all the nodes again.

- R. Niwa

[1] https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0325.html 
https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0325.html



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-28 Thread Ryosuke Niwa
I've updated the gist to reflect the discussion so far:
https://gist.github.com/rniwa/2f14588926e1a11c65d3 
https://gist.github.com/rniwa/2f14588926e1a11c65d3

Please leave a comment if I missed anything.

- R. Niwa



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-28 Thread Ryosuke Niwa

 On Apr 28, 2015, at 1:04 PM, Elliott Sprehn espr...@chromium.org wrote:
 
 A distribute callback means running script any time we update distribution, 
 which is inside the style update phase (or event path computation phase, ...) 
 which is not a location we can run script.

That's not what Anne and the rest of us are proposing. That idea only came up 
in Steve's proposal [1] that kept the current timing of distribution.

 I also don't believe we should support distributing any arbitrary descendant, 
 that has a large complexity cost and doesn't feel like simplification. It 
 makes computing style and generating boxes much more complicated.

That certainly is a trade off. See a use case I outlined in [2].

 A synchronous childrenChanged callback has similar issues with when it's safe 
 to run script, we'd have to defer it's execution in a number of situations, 
 and it feels like a duplication of MutationObservers which specifically were 
 designed to operate in batch for better performance and fewer footguns (ex. a 
 naive childrenChanged based distributor will be n^2).

Since the current proposal is to add it as a custom element's lifecycle 
callback (i.e. we invoke it when we cross UA code / user code boundary), this 
shouldn't be an issue. If it is indeed an issue, then we have a problem with a 
lifecycle callback that gets triggered when an attribute value is modified.

In general, I don't think we can address Steve's need to make the consistency 
guarantee [3] without running some script either synchronously or as a 
lifecycle callback in the world of an imperative API.

- R. Niwa

[1] https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0342.html
[2] https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0344.html
[3] https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0357.html




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Ryosuke Niwa

 On Apr 26, 2015, at 6:11 PM, Hayato Ito hay...@chromium.org wrote:
 
 I think Polymer folks will answer the use case of re-distribution.
 
 So let me just show a good analogy so that every one can understand 
 intuitively what re-distribution *means*.
 Let me use a pseudo language and define XComponent's constructor as follows:
 
 XComponents::XComponents(Title text, Icon icon) {
   this.text = text;
   this.button = new XButton(icon);
   ...
 }
 
 Here, |icon| is *re-distributed*.
 
 In HTML world, this corresponds the followings:
 
 The usage of x-component element:
   x-components
 x-textHello World/x-text
 x-iconMy Icon/x-icon
   /x-component
 
 XComponent's shadow tree is:
 
   shadow-root
 h1content select=x-text/content/h1!-- (1) --
 x-buttoncontent select=x-icon/content/x-button!-- (2) --
   /shadow-root

I have a question as to whether x-button then has to select which nodes to use 
or not.  In this particular example at least, x-button will put every node 
distributed into (2) into a single insertion point in its shadow DOM.

If we don't have to support filtering of nodes at re-distribution time, then 
the whole discussion of re-distribution is almost a moot because we can just 
treat a content element like any other element that gets distributed along with 
its distributed nodes.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Ryosuke Niwa

 On Apr 27, 2015, at 1:45 PM, Ryosuke Niwa rn...@apple.com wrote:
 
 
 On Apr 27, 2015, at 11:47 AM, Steve Orvell sorv...@google.com 
 mailto:sorv...@google.com wrote:
 
 Here's a minimal and hopefully simple proposal that we can flesh out if this 
 seems like an interesting api direction:
 
 https://gist.github.com/sorvell/e201c25ec39480be66aa 
 https://gist.github.com/sorvell/e201c25ec39480be66aa
 
 It seems like with this API, we’d have to make O(n^k)

I meant to say O(nk).  Sorry, I'm still waking up :(

 calls where n is the number of distribution candidates and k is the number of 
 insertion points, and that’s bad.  Or am I misunderstanding your design?
 
 
 We keep the currently spec'd distribution algorithm/timing but remove 
 `select` in favor of an explicit selection callback.
 
 What do you mean by keeping the currently spec’ed timing?  We certainly can’t 
 do it at “style resolution time” because style resolution is an 
 implementation detail that we shouldn’t expose to the Web just like GC and 
 its timing is an implementation detail in JS.  Besides that, avoiding style 
 resolution is a very important optimizations and spec’ing when it happens 
 will prevent us from optimizing it away in the future/
 
 Do you mean instead that we synchronously invoke this algorithm when a child 
 node is inserted or removed from the host?  If so, that’ll impose 
 unacceptable runtime cost for DOM mutations.
 
 I think the only timing UA can support by default will be at the end of micro 
 task or at UA-code / user-code boundary as done for custom element lifestyle 
 callbacks at the moment.
 
 The user simply returns true if the node should be distributed to the given 
 insertion point.
 
 Advantages:
  * the callback can be synchronous-ish because it acts only on a specific 
 node when possible. Distribution then won't break existing expectations 
 since `offsetHeight` is always correct.
 
 “always correct” is somewhat stronger statement than I would state here since 
 during UA calls these shouldDistributeToInsertionPoint callbacks, we'll 
 certainly see transient offsetHeight values.
 
 - R. Niwa
 



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Ryosuke Niwa

 On Apr 26, 2015, at 11:05 PM, Anne van Kesteren ann...@annevk.nl wrote:
 
 On Sat, Apr 25, 2015 at 10:49 PM, Ryosuke Niwa rn...@apple.com wrote:
 One major drawback of this API is computing insertionList is expensive
 because we'd have to either (where n is the number of nodes in the shadow
 DOM):
 
 Maintain an ordered list of insertion points, which results in O(n)
 algorithm to run whenever a content element is inserted or removed.
 Lazily compute the ordered list of insertion points when `distribute`
 callback is about to get called in O(n).
 
 The alternative is not exposing it and letting developers get hold of
 the slots. The rationale for letting the browser do it is because you
 need the slots either way and the browser should be able to optimize
 better.

I don’t think that’s true.  If you’re creating a custom element, you’re pretty 
much in the control of what goes into your shadow DOM.  I’m writing any kind of 
component that creates a shadow DOM, I’d just keep references to all my 
insertion points instead of querying them each time I need to distribute nodes.

Another important use case to consider is adding insertion points given the 
list of nodes to distribute.  For example, you may want to “wrap” each node you 
distribute by an element.  That requires the component author to know the 
number of nodes to distribute upfront and then dynamically create as many 
insertion points as needed.

 If we wanted to allow non-direct child descendent (e.g. grand child node) of
 the host to be distributed, then we'd also need O(m) algorithm where m is
 the number of under the host element.  It might be okay to carry on the
 current restraint that only direct child of shadow host can be distributed
 into insertion points but I can't think of a good reason as to why such a
 restriction is desirable.
 
 So you mean that we'd turn distributionList into a subtree? I.e. you
 can pass all descendants of a host element to add()? I remember Yehuda
 making the point that this was desirable to him.

Consider table-chart component which coverts a table element into a chart with 
each column represented as a line graph in the chart. The user of this 
component will wrap a regular table element with table-chart element to 
construct a shadow DOM:

```html
table-chart
  table
...
  td data-value=“253” data-delta=5253 ± 5/td
...
  /table
/table-chart
```

For people who like is attribute on custom elements, pretend it's
```html
  table is=table-chart
...
  td data-value=“253” data-delta=5253 ± 5/td
...
  /table
```

Now, suppose I wanted to show a tooltip with the value in the chart. One 
obvious way to accomplish this would be distributing the td corresponding to 
the currently selected point into the tooltip. But this requires us allowing 
non-direct child nodes to be distributed.


 The other thing I would like to explore is what an API would look like
 that does the subclassing as well. Even though we deferred that to v2
 I got the impression talking to some folks after the meeting that
 there might be more common ground than I thought.

For the slot approach, we can model the act of filling a slot as if attaching a 
shadow root to the slot and the slot content going into the shadow DOM for both 
content distribution and filling of slots by subclasses.

Now we can do this in either of the following two strategies:
1. Superclass wants to see a list of slot contents from subclasses.
2. Each subclass overrides previous distribution done by superclass by 
inspecting insertion points in the shadow DOM and modifying them as needed.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Ryosuke Niwa

 On Apr 27, 2015, at 11:47 AM, Steve Orvell sorv...@google.com wrote:
 
 Here's a minimal and hopefully simple proposal that we can flesh out if this 
 seems like an interesting api direction:
 
 https://gist.github.com/sorvell/e201c25ec39480be66aa 
 https://gist.github.com/sorvell/e201c25ec39480be66aa

It seems like with this API, we’d have to make O(n^k) calls where n is the 
number of distribution candidates and k is the number of insertion points, and 
that’s bad.  Or am I misunderstanding your design?

 
 We keep the currently spec'd distribution algorithm/timing but remove 
 `select` in favor of an explicit selection callback.

What do you mean by keeping the currently spec’ed timing?  We certainly can’t 
do it at “style resolution time” because style resolution is an implementation 
detail that we shouldn’t expose to the Web just like GC and its timing is an 
implementation detail in JS.  Besides that, avoiding style resolution is a very 
important optimizations and spec’ing when it happens will prevent us from 
optimizing it away in the future/

Do you mean instead that we synchronously invoke this algorithm when a child 
node is inserted or removed from the host?  If so, that’ll impose unacceptable 
runtime cost for DOM mutations.

I think the only timing UA can support by default will be at the end of micro 
task or at UA-code / user-code boundary as done for custom element lifestyle 
callbacks at the moment.

 The user simply returns true if the node should be distributed to the given 
 insertion point.
 
 Advantages:
  * the callback can be synchronous-ish because it acts only on a specific 
 node when possible. Distribution then won't break existing expectations since 
 `offsetHeight` is always correct.

“always correct” is somewhat stronger statement than I would state here since 
during UA calls these shouldDistributeToInsertionPoint callbacks, we'll 
certainly see transient offsetHeight values.

- R. Niwa



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Hayato Ito
On Tue, Apr 28, 2015 at 6:18 AM Ryosuke Niwa rn...@apple.com wrote:


  On Apr 26, 2015, at 6:11 PM, Hayato Ito hay...@chromium.org wrote:
 
  I think Polymer folks will answer the use case of re-distribution.
 
  So let me just show a good analogy so that every one can understand
 intuitively what re-distribution *means*.
  Let me use a pseudo language and define XComponent's constructor as
 follows:
 
  XComponents::XComponents(Title text, Icon icon) {
this.text = text;
this.button = new XButton(icon);
...
  }
 
  Here, |icon| is *re-distributed*.
 
  In HTML world, this corresponds the followings:
 
  The usage of x-component element:
x-components
  x-textHello World/x-text
  x-iconMy Icon/x-icon
/x-component
 
  XComponent's shadow tree is:
 
shadow-root
  h1content select=x-text/content/h1!-- (1) --
  x-buttoncontent select=x-icon/content/x-button!-- (2) --
/shadow-root

 I have a question as to whether x-button then has to select which nodes to
 use or not.  In this particular example at least, x-button will put every
 node distributed into (2) into a single insertion point in its shadow DOM.

 If we don't have to support filtering of nodes at re-distribution time,
 then the whole discussion of re-distribution is almost a moot because we
 can just treat a content element like any other element that gets
 distributed along with its distributed nodes.


x-button can select.
You might want to take a look at the distribution algorithm [1], where the
behavior is well defined.

[1]: http://w3c.github.io/webcomponents/spec/shadow/#distribution-algorithms

In short, the distributed nodes of content select=x-icons will be the
next candidates of nodes from where insertion points in the shadow tree
x-button hosts can select.




 - R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Anne van Kesteren
On Mon, Apr 27, 2015 at 9:25 AM, Justin Fagnani
justinfagn...@google.com wrote:
 I really don't think the platform needs to do anything to support
 subclassing since it can be done so easily at the library level now that
 multiple generations of shadow roots are gone. As long as a subclass and
 base class can cooperate to produce a single shadow root with insertion
 points, the platform doesn't need to know how they did it.

So a) this is only if they cooperate and the superclass does not want
to keep its tree and distribution logic hidden and b) if we want to
eventually add declarative functionality we'll need to explain it
somehow. Seems better that we know upfront how that will work.


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Justin Fagnani
On Mon, Apr 27, 2015 at 1:01 AM, Anne van Kesteren ann...@annevk.nl wrote:

 On Mon, Apr 27, 2015 at 9:25 AM, Justin Fagnani
 justinfagn...@google.com wrote:
  I really don't think the platform needs to do anything to support
  subclassing since it can be done so easily at the library level now that
  multiple generations of shadow roots are gone. As long as a subclass and
  base class can cooperate to produce a single shadow root with insertion
  points, the platform doesn't need to know how they did it.

 So a) this is only if they cooperate


In reality, base and sub class are going to have to cooperate. There's no
style or dom isolation between the two anymore, and lifecycle callbacks,
templating, and data binding already make them pretty entangled.


 and the superclass does not want
 to keep its tree and distribution logic hidden


A separate hidden tree per class sounds very much like multiple generations
of shadow trees, and we just killed that... This is one of my concerns
about the inheritance part of the slots proposal: it appeared to give new
significance to template tags which essentially turn them into multiple
shadow roots, just without the style isolation.


 and b) if we want to
 eventually add declarative functionality we'll need to explain it
 somehow. Seems better that we know upfront how that will work.


I think this is a case where the frameworks would lead and the platform, if
it ever decided to, could integrate the best approach - much like data
binding.

I imagine that frameworks will create declarative forms of distribution and
template inheritance that work something like the current system, or the
slots proposal (or other template systems with inheritance like Jinja). I
don't even think a platform-based solution won't be any faster in the
common case because the frameworks can pre-compute the concrete template
(including distribution points and bindings) from the entire inheritance
hierarchy up front, and stamp out the same thing per instance.

Cheers,
  Justin




 --
 https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Anne van Kesteren
On Sat, Apr 25, 2015 at 10:49 PM, Ryosuke Niwa rn...@apple.com wrote:
 One major drawback of this API is computing insertionList is expensive
 because we'd have to either (where n is the number of nodes in the shadow
 DOM):

 Maintain an ordered list of insertion points, which results in O(n)
 algorithm to run whenever a content element is inserted or removed.
 Lazily compute the ordered list of insertion points when `distribute`
 callback is about to get called in O(n).

The alternative is not exposing it and letting developers get hold of
the slots. The rationale for letting the browser do it is because you
need the slots either way and the browser should be able to optimize
better.


 If we wanted to allow non-direct child descendent (e.g. grand child node) of
 the host to be distributed, then we'd also need O(m) algorithm where m is
 the number of under the host element.  It might be okay to carry on the
 current restraint that only direct child of shadow host can be distributed
 into insertion points but I can't think of a good reason as to why such a
 restriction is desirable.

So you mean that we'd turn distributionList into a subtree? I.e. you
can pass all descendants of a host element to add()? I remember Yehuda
making the point that this was desirable to him.

The other thing I would like to explore is what an API would look like
that does the subclassing as well. Even though we deferred that to v2
I got the impression talking to some folks after the meeting that
there might be more common ground than I thought.


As for the points before about mutation observers. I kind of like just
having distribute() for v1 since it allows maximum flexibility. I
would be okay with having an option that is either optin or optout
that does the observing automatically, though I guess if we move from
children to descendants that gets more expensive.


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Justin Fagnani
On Sun, Apr 26, 2015 at 11:05 PM, Anne van Kesteren ann...@annevk.nl
wrote:

 On Sat, Apr 25, 2015 at 10:49 PM, Ryosuke Niwa rn...@apple.com wrote:
  One major drawback of this API is computing insertionList is expensive
  because we'd have to either (where n is the number of nodes in the shadow
  DOM):
 
  Maintain an ordered list of insertion points, which results in O(n)
  algorithm to run whenever a content element is inserted or removed.


I don't expect shadow roots to be modified that much. We certainly don't
see it now, though the imperative API opens up some new possibilities like
calculating a grouping of child nodes and generating a content tag per
group, or even generating a content tag per child to perform decoration.
I still think those would be very rare cases.


  Lazily compute the ordered list of insertion points when `distribute`
  callback is about to get called in O(n).

 The alternative is not exposing it and letting developers get hold of
 the slots. The rationale for letting the browser do it is because you
 need the slots either way and the browser should be able to optimize
 better.


  If we wanted to allow non-direct child descendent (e.g. grand child
 node) of
  the host to be distributed, then we'd also need O(m) algorithm where m is
  the number of under the host element.  It might be okay to carry on the
  current restraint that only direct child of shadow host can be
 distributed
  into insertion points but I can't think of a good reason as to why such a
  restriction is desirable.


The main reason is that you know that only a direct parent of a node can
distribute it. Otherwise any ancestor could distribute a node, and in
addition to probably being confusing and fragile, you have to define who
wins when multiple ancestors try to.

There are cases where you really want to group element logically by one
tree structure and visually by another, like tabs. I think an alternative
approach to distributing arbitrary descendants would be to see if nodes can
cooperate on distribution so that a node could pass its direct children to
another node's insertion point. The direct child restriction would still be
there, so you always know who's responsible, but you can get the same
effect as distributing descendants for a cooperating sets of elements.


 So you mean that we'd turn distributionList into a subtree? I.e. you
 can pass all descendants of a host element to add()? I remember Yehuda
 making the point that this was desirable to him.

 The other thing I would like to explore is what an API would look like
 that does the subclassing as well. Even though we deferred that to v2
 I got the impression talking to some folks after the meeting that
 there might be more common ground than I thought.


I really don't think the platform needs to do anything to support
subclassing since it can be done so easily at the library level now that
multiple generations of shadow roots are gone. As long as a subclass and
base class can cooperate to produce a single shadow root with insertion
points, the platform doesn't need to know how they did it.

Cheers,
  Justin



 As for the points before about mutation observers. I kind of like just
 having distribute() for v1 since it allows maximum flexibility. I
 would be okay with having an option that is either optin or optout
 that does the observing automatically, though I guess if we move from
 children to descendants that gets more expensive.


 --
 https://annevankesteren.nl/




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Anne van Kesteren
On Mon, Apr 27, 2015 at 10:23 AM, Justin Fagnani
justinfagn...@google.com wrote:
 A separate hidden tree per class sounds very much like multiple generations
 of shadow trees, and we just killed that...

We killed it for v1, not indefinitely. As I already said, based on
my post-meeting conversations it might not have been as contentious as
I thought. It's mostly the specifics. I haven't quite wrapped my head
around those specifics, but the way Gecko implemented shadow (which
does not match the specification or Chrome) seemed to be very similar
to what Apple wanted.


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Anne van Kesteren
On Mon, Apr 27, 2015 at 3:41 PM, Matthew Robb matthewwr...@gmail.com wrote:
 I know this isn't the biggest deal but I think naming the function
 distribute is highly suggestive, why not just expose this as
 `childListChangedCallback` ?

Because that doesn't match the actual semantics. The callback is
invoked once distribute() is invoked by the web developer or
distribute() has been invoked on a composed ancestor ShadowRoot and
all composed ancestor ShadowRoot's have already had their callback
run. (Note that the distribute callback and the distribute method are
different things.)

Since the distribute callback is in charge of distribution it does in
fact make sense to call it such I think.


-- 
https://annevankesteren.nl/



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Matthew Robb
I know this isn't the biggest deal but I think naming the function
distribute is highly suggestive, why not just expose this as
`childListChangedCallback` ?


- Matthew Robb

On Mon, Apr 27, 2015 at 4:34 AM, Anne van Kesteren ann...@annevk.nl wrote:

 On Mon, Apr 27, 2015 at 10:23 AM, Justin Fagnani
 justinfagn...@google.com wrote:
  A separate hidden tree per class sounds very much like multiple
 generations
  of shadow trees, and we just killed that...

 We killed it for v1, not indefinitely. As I already said, based on
 my post-meeting conversations it might not have been as contentious as
 I thought. It's mostly the specifics. I haven't quite wrapped my head
 around those specifics, but the way Gecko implemented shadow (which
 does not match the specification or Chrome) seemed to be very similar
 to what Apple wanted.


 --
 https://annevankesteren.nl/




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Hayato Ito
I think there are a lot of user operations where distribution must be
updated before returning the meaningful result synchronously.
Unless distribution result is correctly updated, users would take the dirty
result.

For example:
- element.offsetWidth:  Style resolution requires distribution. We must
update distribution, if it's dirty, before calculation offsetWidth
synchronously.
- event dispatching: event path requires distribution because it needs a
composed tree.

Can the current HTML/DOM specs are rich enough to explain the timing when
the imperative APIs should be run in these cases?

For me, the imperative APIs for distribution sounds very similar to the
imperative APIs for style resolution. The difficulties of both problems
might be similar.





On Tue, Apr 28, 2015 at 7:18 AM Steve Orvell sorv...@google.com wrote:

 IMO, the appeal of this proposal is that it's a small change to the
 current spec and avoids changing user expectations about the state of the
 dom and can explain the two declarative proposals for distribution.


 It seems like with this API, we’d have to make O(n^k) calls where n is
 the number of distribution candidates and k is the number of insertion
 points, and that’s bad.  Or am I misunderstanding your design?


 I think you've understood the proposed design. As you noted, the cost is
 actually O(n*k). In our use cases, k is generally very small.

 Do you mean instead that we synchronously invoke this algorithm when a
 child node is inserted or removed from the host?  If so, that’ll impose
 unacceptable runtime cost for DOM mutations.
 I think the only timing UA can support by default will be at the end of
 micro task or at UA-code / user-code boundary as done for custom element
 lifestyle callbacks at the moment.


 Running this callback at the UA-code/user-code boundary seems like it
 would be fine. Running the more complicated distribute all the nodes
 proposals at this time would obviously not be feasible. The notion here is
 that since we're processing only a single node at a time, this can be done
 after an atomic dom action.

 “always correct” is somewhat stronger statement than I would state here
 since during UA calls these shouldDistributeToInsertionPoint callbacks,
 we'll certainly see transient offsetHeight values.


 Yes, you're right about that. Specifically it would be bad to try to read
 `offsetHeight` in this callback and this would be an anti-pattern. If
 that's not good enough, perhaps we can explore actually not working
 directly with the node but instead the subset of information necessary to
 be able to decide on distribution.

 Can you explain, under the initial proposal, how a user can ask an
 element's dimensions and get the post-distribution answer? With current
 dom api's I can be sure that if I do parent.appendChild(child) and then
 parent.offsetWidth, the answer takes child into account. I'm looking to
 understand how we don't violate this expectation when parent distributes.
 Or if we violate this expectation, what is the proposed right way to ask
 this question?

 In addition to rendering information about a node, distribution also
 effects the flow of events. So a similar question: when is it safe to call
 child.dispatchEvent such that if parent distributes elements to its
 shadowRoot, elements in the shadowRoot will see the event?

 On Mon, Apr 27, 2015 at 1:45 PM, Ryosuke Niwa rn...@apple.com wrote:


 On Apr 27, 2015, at 11:47 AM, Steve Orvell sorv...@google.com wrote:

 Here's a minimal and hopefully simple proposal that we can flesh out if
 this seems like an interesting api direction:


 https://gist.github.com/sorvell/e201c25ec39480be66aa


 It seems like with this API, we’d have to make O(n^k) calls where n is
 the number of distribution candidates and k is the number of insertion
 points, and that’s bad.  Or am I misunderstanding your design?


 We keep the currently spec'd distribution algorithm/timing but remove
 `select` in favor of an explicit selection callback.


 What do you mean by keeping the currently spec’ed timing?  We certainly
 can’t do it at “style resolution time” because style resolution is an
 implementation detail that we shouldn’t expose to the Web just like GC and
 its timing is an implementation detail in JS.  Besides that, avoiding style
 resolution is a very important optimizations and spec’ing when it happens
 will prevent us from optimizing it away in the future/

 Do you mean instead that we synchronously invoke this algorithm when a
 child node is inserted or removed from the host?  If so, that’ll impose
 unacceptable runtime cost for DOM mutations.

 I think the only timing UA can support by default will be at the end of
 micro task or at UA-code / user-code boundary as done for custom element
 lifestyle callbacks at the moment.

 The user simply returns true if the node should be distributed to the
 given insertion point.

 Advantages:
  * the callback can be synchronous-ish because it acts only on a 

Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Tab Atkins Jr.
On Mon, Apr 27, 2015 at 4:06 PM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 On Mon, Apr 27, 2015 at 3:42 PM, Ryosuke Niwa rn...@apple.com wrote:
 On Apr 27, 2015, at 3:15 PM, Steve Orvell sorv...@google.com wrote:
 IMO, the appeal of this proposal is that it's a small change to the current 
 spec and avoids changing user expectations about the state of the dom and 
 can explain the two declarative proposals for distribution.

 It seems like with this API, we’d have to make O(n^k) calls where n is the 
 number of distribution candidates and k is the number of insertion points, 
 and that’s bad.  Or am I misunderstanding your design?

 I think you've understood the proposed design. As you noted, the cost is 
 actually O(n*k). In our use cases, k is generally very small.

 I don't think we want to introduce O(nk) algorithm. Pretty much every 
 browser optimization we implement these days are removing O(n^2) algorithms 
 in the favor of O(n) algorithms. Hard-baking O(nk) behavior is bad because 
 we can't even theoretically optimize it away.

 You're aware, obviously, that O(n^2) is a far different beast than
 O(nk).  If k is generally small, which it is, O(nk) is basically just
 O(n) with a constant factor applied.

To make it clear: I'm not trying to troll Ryosuke here.

He argued that we don't want to add new O(n^2) algorithms if we can
help it, and that we prefer O(n).  (Uncontroversial.)

He then further said that an O(nk) algorithm is sufficiently close to
O(n^2) that he'd similarly like to avoid it.  I'm trying to
reiterate/expand on Steve's message here, that the k value in question
is usually very small, relative to the value of n, so in practice this
O(nk) is more similar to O(n) than O(n^2), and Ryosuke's aversion to
new O(n^2) algorithms may be mistargeted here.

~TJ



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Steve Orvell
IMO, the appeal of this proposal is that it's a small change to the current
spec and avoids changing user expectations about the state of the dom and
can explain the two declarative proposals for distribution.


 It seems like with this API, we’d have to make O(n^k) calls where n is the
 number of distribution candidates and k is the number of insertion points,
 and that’s bad.  Or am I misunderstanding your design?


I think you've understood the proposed design. As you noted, the cost is
actually O(n*k). In our use cases, k is generally very small.

Do you mean instead that we synchronously invoke this algorithm when a
 child node is inserted or removed from the host?  If so, that’ll impose
 unacceptable runtime cost for DOM mutations.
 I think the only timing UA can support by default will be at the end of
 micro task or at UA-code / user-code boundary as done for custom element
 lifestyle callbacks at the moment.


Running this callback at the UA-code/user-code boundary seems like it would
be fine. Running the more complicated distribute all the nodes proposals
at this time would obviously not be feasible. The notion here is that since
we're processing only a single node at a time, this can be done after an
atomic dom action.

“always correct” is somewhat stronger statement than I would state here
 since during UA calls these shouldDistributeToInsertionPoint callbacks,
 we'll certainly see transient offsetHeight values.


Yes, you're right about that. Specifically it would be bad to try to read
`offsetHeight` in this callback and this would be an anti-pattern. If
that's not good enough, perhaps we can explore actually not working
directly with the node but instead the subset of information necessary to
be able to decide on distribution.

Can you explain, under the initial proposal, how a user can ask an
element's dimensions and get the post-distribution answer? With current dom
api's I can be sure that if I do parent.appendChild(child) and then
parent.offsetWidth, the answer takes child into account. I'm looking to
understand how we don't violate this expectation when parent distributes.
Or if we violate this expectation, what is the proposed right way to ask
this question?

In addition to rendering information about a node, distribution also
effects the flow of events. So a similar question: when is it safe to call
child.dispatchEvent such that if parent distributes elements to its
shadowRoot, elements in the shadowRoot will see the event?

On Mon, Apr 27, 2015 at 1:45 PM, Ryosuke Niwa rn...@apple.com wrote:


 On Apr 27, 2015, at 11:47 AM, Steve Orvell sorv...@google.com wrote:

 Here's a minimal and hopefully simple proposal that we can flesh out if
 this seems like an interesting api direction:


 https://gist.github.com/sorvell/e201c25ec39480be66aa


 It seems like with this API, we’d have to make O(n^k) calls where n is the
 number of distribution candidates and k is the number of insertion points,
 and that’s bad.  Or am I misunderstanding your design?


 We keep the currently spec'd distribution algorithm/timing but remove
 `select` in favor of an explicit selection callback.


 What do you mean by keeping the currently spec’ed timing?  We certainly
 can’t do it at “style resolution time” because style resolution is an
 implementation detail that we shouldn’t expose to the Web just like GC and
 its timing is an implementation detail in JS.  Besides that, avoiding style
 resolution is a very important optimizations and spec’ing when it happens
 will prevent us from optimizing it away in the future/

 Do you mean instead that we synchronously invoke this algorithm when a
 child node is inserted or removed from the host?  If so, that’ll impose
 unacceptable runtime cost for DOM mutations.

 I think the only timing UA can support by default will be at the end of
 micro task or at UA-code / user-code boundary as done for custom element
 lifestyle callbacks at the moment.

 The user simply returns true if the node should be distributed to the
 given insertion point.

 Advantages:
  * the callback can be synchronous-ish because it acts only on a specific
 node when possible. Distribution then won't break existing expectations
 since `offsetHeight` is always correct.


 “always correct” is somewhat stronger statement than I would state here
 since during UA calls these shouldDistributeToInsertionPoint callbacks,
 we'll certainly see transient offsetHeight values.

 - R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Hayato Ito
Could you clarify what you are trying to achieve? If we don't support,
everything would be weird.

I guess you are proposing the alternative of the current pool population
algorithm and pool distribution algorithm.
I appreciate you could explain what are expected result using algorithms.



On Tue, Apr 28, 2015 at 6:58 AM Ryosuke Niwa rn...@apple.com wrote:

 On Apr 27, 2015, at 2:38 PM, Hayato Ito hay...@chromium.org wrote:

 On Tue, Apr 28, 2015 at 6:18 AM Ryosuke Niwa rn...@apple.com wrote:


  On Apr 26, 2015, at 6:11 PM, Hayato Ito hay...@chromium.org wrote:
 
  I think Polymer folks will answer the use case of re-distribution.
 
  So let me just show a good analogy so that every one can understand
 intuitively what re-distribution *means*.
  Let me use a pseudo language and define XComponent's constructor as
 follows:
 
  XComponents::XComponents(Title text, Icon icon) {
this.text = text;
this.button = new XButton(icon);
...
  }
 
  Here, |icon| is *re-distributed*.
 
  In HTML world, this corresponds the followings:
 
  The usage of x-component element:
x-components
  x-textHello World/x-text
  x-iconMy Icon/x-icon
/x-component
 
  XComponent's shadow tree is:
 
shadow-root
  h1content select=x-text/content/h1!-- (1) --
  x-buttoncontent select=x-icon/content/x-button!-- (2) --
/shadow-root

 I have a question as to whether x-button then has to select which nodes
 to use or not.  In this particular example at least, x-button will put
 every node distributed into (2) into a single insertion point in its shadow
 DOM.

 If we don't have to support filtering of nodes at re-distribution time,
 then the whole discussion of re-distribution is almost a moot because we
 can just treat a content element like any other element that gets
 distributed along with its distributed nodes.


 x-button can select.
 You might want to take a look at the distribution algorithm [1], where
 the behavior is well defined.


 I know we can in the current spec but should we support it?  What are
 concrete use cases in which x-button or other components need to select
 nodes in nested shadow DOM case?

 - R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Steve Orvell

 Again, the timing was deferred in [1] and [2] so it really depends on when
 each component decides to distribute.


I want to be able to create an element x-foo that acts like other dom
elements. This element uses Shadow DOM and distribution to encapsulate its
details.

Let's imagine a 3rd party user named Bob that uses div and x-foo. Bob
knows he can call div.appendChild(element) and then immediately ask
div.offsetHeight and know that this height includes whatever the added
element should contribute to the div's height. Bob expects to be able to do
this with the x-foo element also since it is just another element from
his perspective.

How can I, the author of x-foo, craft my element such that I don't
violate Bob's expectations? Does your proposal support this?

On Mon, Apr 27, 2015 at 3:42 PM, Ryosuke Niwa rn...@apple.com wrote:


  On Apr 27, 2015, at 3:15 PM, Steve Orvell sorv...@google.com wrote:
 
  IMO, the appeal of this proposal is that it's a small change to the
 current spec and avoids changing user expectations about the state of the
 dom and can explain the two declarative proposals for distribution.
 
  It seems like with this API, we’d have to make O(n^k) calls where n is
 the number of distribution candidates and k is the number of insertion
 points, and that’s bad.  Or am I misunderstanding your design?
 
  I think you've understood the proposed design. As you noted, the cost is
 actually O(n*k). In our use cases, k is generally very small.

 I don't think we want to introduce O(nk) algorithm. Pretty much every
 browser optimization we implement these days are removing O(n^2) algorithms
 in the favor of O(n) algorithms. Hard-baking O(nk) behavior is bad because
 we can't even theoretically optimize it away.

  Do you mean instead that we synchronously invoke this algorithm when a
 child node is inserted or removed from the host?  If so, that’ll impose
 unacceptable runtime cost for DOM mutations.
  I think the only timing UA can support by default will be at the end of
 micro task or at UA-code / user-code boundary as done for custom element
 lifestyle callbacks at the moment.
  Running this callback at the UA-code/user-code boundary seems like it
 would be fine. Running the more complicated distribute all the nodes
 proposals at this time would obviously not be feasible. The notion here is
 that since we're processing only a single node at a time, this can be done
 after an atomic dom action.

 Indeed, running such an algorithm each time node is inserted or removed
 will be quite expensive.

  “always correct” is somewhat stronger statement than I would state here
 since during UA calls these shouldDistributeToInsertionPoint callbacks,
 we'll certainly see transient offsetHeight values.
 
  Yes, you're right about that. Specifically it would be bad to try to
 read `offsetHeight` in this callback and this would be an anti-pattern. If
 that's not good enough, perhaps we can explore actually not working
 directly with the node but instead the subset of information necessary to
 be able to decide on distribution.

 I'm not necessarily saying that it's not good enough.  I'm just saying
 that it is possible to observe such a state even with this API.

  Can you explain, under the initial proposal, how a user can ask an
 element's dimensions and get the post-distribution answer? With current dom
 api's I can be sure that if I do parent.appendChild(child) and then
 parent.offsetWidth, the answer takes child into account. I'm looking to
 understand how we don't violate this expectation when parent distributes.
 Or if we violate this expectation, what is the proposed right way to ask
 this question?

 You don't get that guarantee in the design we discussed on Friday [1] [2].
 In fact, we basically deferred the timing issue to other APIs that observe
 DOM changes, namely mutation observers and custom elements lifecycle
 callbacks. Each component uses those APIs to call distribute().

  In addition to rendering information about a node, distribution also
 effects the flow of events. So a similar question: when is it safe to call
 child.dispatchEvent such that if parent distributes elements to its
 shadowRoot, elements in the shadowRoot will see the event?

 Again, the timing was deferred in [1] and [2] so it really depends on when
 each component decides to distribute.

 - R. Niwa

 [1] https://gist.github.com/rniwa/2f14588926e1a11c65d3
 [2] https://gist.github.com/annevk/e9e61801fcfb251389ef




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Ryosuke Niwa

 On Apr 27, 2015, at 2:38 PM, Hayato Ito hay...@chromium.org wrote:
 
 On Tue, Apr 28, 2015 at 6:18 AM Ryosuke Niwa rn...@apple.com 
 mailto:rn...@apple.com wrote:
 
  On Apr 26, 2015, at 6:11 PM, Hayato Ito hay...@chromium.org 
  mailto:hay...@chromium.org wrote:
 
  I think Polymer folks will answer the use case of re-distribution.
 
  So let me just show a good analogy so that every one can understand 
  intuitively what re-distribution *means*.
  Let me use a pseudo language and define XComponent's constructor as follows:
 
  XComponents::XComponents(Title text, Icon icon) {
this.text = text;
this.button = new XButton(icon);
...
  }
 
  Here, |icon| is *re-distributed*.
 
  In HTML world, this corresponds the followings:
 
  The usage of x-component element:
x-components
  x-textHello World/x-text
  x-iconMy Icon/x-icon
/x-component
 
  XComponent's shadow tree is:
 
shadow-root
  h1content select=x-text/content/h1!-- (1) --
  x-buttoncontent select=x-icon/content/x-button!-- (2) --
/shadow-root
 
 I have a question as to whether x-button then has to select which nodes to 
 use or not.  In this particular example at least, x-button will put every 
 node distributed into (2) into a single insertion point in its shadow DOM.
 
 If we don't have to support filtering of nodes at re-distribution time, then 
 the whole discussion of re-distribution is almost a moot because we can just 
 treat a content element like any other element that gets distributed along 
 with its distributed nodes.
 
 
 x-button can select.
 You might want to take a look at the distribution algorithm [1], where the 
 behavior is well defined.

I know we can in the current spec but should we support it?  What are concrete 
use cases in which x-button or other components need to select nodes in nested 
shadow DOM case?

- R. Niwa



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Ryosuke Niwa

 On Apr 27, 2015, at 3:15 PM, Steve Orvell sorv...@google.com wrote:
 
 IMO, the appeal of this proposal is that it's a small change to the current 
 spec and avoids changing user expectations about the state of the dom and can 
 explain the two declarative proposals for distribution.
 
 It seems like with this API, we’d have to make O(n^k) calls where n is the 
 number of distribution candidates and k is the number of insertion points, 
 and that’s bad.  Or am I misunderstanding your design?
 
 I think you've understood the proposed design. As you noted, the cost is 
 actually O(n*k). In our use cases, k is generally very small.

I don't think we want to introduce O(nk) algorithm. Pretty much every browser 
optimization we implement these days are removing O(n^2) algorithms in the 
favor of O(n) algorithms. Hard-baking O(nk) behavior is bad because we can't 
even theoretically optimize it away.

 Do you mean instead that we synchronously invoke this algorithm when a child 
 node is inserted or removed from the host?  If so, that’ll impose 
 unacceptable runtime cost for DOM mutations.
 I think the only timing UA can support by default will be at the end of 
 micro task or at UA-code / user-code boundary as done for custom element 
 lifestyle callbacks at the moment.
 Running this callback at the UA-code/user-code boundary seems like it would 
 be fine. Running the more complicated distribute all the nodes proposals at 
 this time would obviously not be feasible. The notion here is that since 
 we're processing only a single node at a time, this can be done after an 
 atomic dom action.

Indeed, running such an algorithm each time node is inserted or removed will be 
quite expensive.

 “always correct” is somewhat stronger statement than I would state here 
 since during UA calls these shouldDistributeToInsertionPoint callbacks, 
 we'll certainly see transient offsetHeight values.
 
 Yes, you're right about that. Specifically it would be bad to try to read 
 `offsetHeight` in this callback and this would be an anti-pattern. If that's 
 not good enough, perhaps we can explore actually not working directly with 
 the node but instead the subset of information necessary to be able to decide 
 on distribution.

I'm not necessarily saying that it's not good enough.  I'm just saying that it 
is possible to observe such a state even with this API.

 Can you explain, under the initial proposal, how a user can ask an element's 
 dimensions and get the post-distribution answer? With current dom api's I can 
 be sure that if I do parent.appendChild(child) and then parent.offsetWidth, 
 the answer takes child into account. I'm looking to understand how we don't 
 violate this expectation when parent distributes. Or if we violate this 
 expectation, what is the proposed right way to ask this question?

You don't get that guarantee in the design we discussed on Friday [1] [2]. In 
fact, we basically deferred the timing issue to other APIs that observe DOM 
changes, namely mutation observers and custom elements lifecycle callbacks. 
Each component uses those APIs to call distribute().

 In addition to rendering information about a node, distribution also effects 
 the flow of events. So a similar question: when is it safe to call 
 child.dispatchEvent such that if parent distributes elements to its 
 shadowRoot, elements in the shadowRoot will see the event?

Again, the timing was deferred in [1] and [2] so it really depends on when each 
component decides to distribute.

- R. Niwa

[1] https://gist.github.com/rniwa/2f14588926e1a11c65d3
[2] https://gist.github.com/annevk/e9e61801fcfb251389ef




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Ryosuke Niwa

 On Apr 27, 2015, at 4:41 PM, Steve Orvell sorv...@google.com wrote:
 
 Again, the timing was deferred in [1] and [2] so it really depends on when 
 each component decides to distribute.
 
 I want to be able to create an element x-foo that acts like other dom 
 elements. This element uses Shadow DOM and distribution to encapsulate its 
 details.
 
 Let's imagine a 3rd party user named Bob that uses div and x-foo. Bob 
 knows he can call div.appendChild(element) and then immediately ask 
 div.offsetHeight and know that this height includes whatever the added 
 element should contribute to the div's height. Bob expects to be able to do 
 this with the x-foo element also since it is just another element from his 
 perspective.
 
 How can I, the author of x-foo, craft my element such that I don't violate 
 Bob's expectations? Does your proposal support this?

In order to support this use case, the author of x-foo must use some mechanism 
to observe changes to x-foo's child nodes and involve `distribute` 
synchronously.  This will become possible, for example, if we added 
childrenChanged lifecycle callback to custom elements.

That might be an acceptable mode of operations. If you wanted to synchronously 
update your insertion points, rely on custom element's lifecycle callbacks and 
you can only support direct children for distribution. Alternatively, if you 
wanted to support to distribute a non-direct-child descendent, just use 
mutation observers to do it at the end of a micro task.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Ryosuke Niwa

 On Apr 27, 2015, at 3:31 PM, Hayato Ito hay...@chromium.org wrote:
 
 I think there are a lot of user operations where distribution must be updated 
 before returning the meaningful result synchronously.
 Unless distribution result is correctly updated, users would take the dirty 
 result.

Indeed.

 For example:
 - element.offsetWidth:  Style resolution requires distribution. We must 
 update distribution, if it's dirty, before calculation offsetWidth 
 synchronously.
 - event dispatching: event path requires distribution because it needs a 
 composed tree.
 
 Can the current HTML/DOM specs are rich enough to explain the timing when the 
 imperative APIs should be run in these cases?

It certainly doesn't tell us when style resolution happens. In the case of 
event dispatching, it's impossible even in theory unless we somehow disallow 
event dispatching within our `distribute` callbacks since we can dispatch new 
events within the callbacks to decide to where a given node gets distributed. 
Given that, I don't think we should even try to make such a guarantee.

We could, however, make a slightly weaker guarantee that some level of 
conditions for the user code outside of `distribute` callbacks. For example, I 
can think of three levels (weakest to strongest) of self-consistent invariants:
1. every node is distributed to at most one insertion point.
2. all first-order distributions is up-to-date (redistribution may happen 
later).
3. all distributions is up-to-date.

 For me, the imperative APIs for distribution sounds very similar to the 
 imperative APIs for style resolution. The difficulties of both problems might 
 be similar.

We certainly don't want to (in fact, we'll object to) spec the timing for style 
resolution or what even style resolution means.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Tab Atkins Jr.
On Mon, Apr 27, 2015 at 3:42 PM, Ryosuke Niwa rn...@apple.com wrote:
 On Apr 27, 2015, at 3:15 PM, Steve Orvell sorv...@google.com wrote:
 IMO, the appeal of this proposal is that it's a small change to the current 
 spec and avoids changing user expectations about the state of the dom and 
 can explain the two declarative proposals for distribution.

 It seems like with this API, we’d have to make O(n^k) calls where n is the 
 number of distribution candidates and k is the number of insertion points, 
 and that’s bad.  Or am I misunderstanding your design?

 I think you've understood the proposed design. As you noted, the cost is 
 actually O(n*k). In our use cases, k is generally very small.

 I don't think we want to introduce O(nk) algorithm. Pretty much every browser 
 optimization we implement these days are removing O(n^2) algorithms in the 
 favor of O(n) algorithms. Hard-baking O(nk) behavior is bad because we can't 
 even theoretically optimize it away.

You're aware, obviously, that O(n^2) is a far different beast than
O(nk).  If k is generally small, which it is, O(nk) is basically just
O(n) with a constant factor applied.

~TJ



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Ryosuke Niwa

 On Apr 27, 2015, at 5:43 PM, Steve Orvell sorv...@google.com wrote:
 
 That might be an acceptable mode of operations. If you wanted to 
 synchronously update your insertion points, rely on custom element's 
 lifecycle callbacks and you can only support direct children for 
 distribution. 
 
 That's interesting, thanks for working through it. Given a `childrenChanged` 
 callback, I think your first proposal `content.insertAt` and 
 `content.remove` best supports a synchronous mental model. As you note, 
 re-distribution is then the element author's responsibility. This would be 
 done by listening to the synchronous `distributionChanged` event. That seems 
 straightforward.
 
 Mutations that are not captured in childrenChanged that can affect 
 distribution would still be a problem, however. Given:
 
 div id=host
   div id=child/div
 /div
 
 child.setAttribute('slot', 'a');
 host.offsetHeight;
 
 Again, we are guaranteed that parent's offsetHeight includes any contribution 
 that adding the slot attribute caused (e.g. via a #child[slot=a] rule)
 
 If the `host` is a custom element that uses distribution, would it be 
 possible to have this same guarantee?
 
 x-foo id=host
   div id=child/div
 /x-foo
 
 child.setAttribute('slot', 'a');
 host.offsetHeight;

That's a good point. Perhaps we need to make childrenChanged optionally get 
called when attributes of child nodes are changed just like the way you can 
configure mutation observers to optionally monitor attribute changes.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Steve Orvell

 Perhaps we need to make childrenChanged optionally get called when
 attributes of child nodes are changed just like the way you can configure
 mutation observers to optionally monitor attribute changes.


Wow, let me summarize if I can. Let's say we have (a) a custom elements
synchronous callback `childrenChanged` that can see child adds/removes and
child attribute mutations, (b) the first option in the proposed api here
https://gist.github.com/rniwa/2f14588926e1a11c65d3, (c) user element code
that wires everything together correctly. Then, unless I am mistaken, we
have enough power to implement something like the currently spec'd
declarative `select` mechanism or the proposed `slot` mechanism without any
change to user's expectations about when information in the dom can be
queried.

Do the implementors think all of that is feasible?

Possible corner case: If a content is added to a shadowRoot, this should
probably invalidate the distribution and redo everything. To maintain a
synchronous mental model, the content mutation in the shadowRoot subtree
needs to be seen synchronously. This is not possible with the tools
mentioned above, but it seems like a reasonable requirement that the
shadowRoot author can be aware of this change since the author is causing
it to happen.


On Mon, Apr 27, 2015 at 7:01 PM, Ryosuke Niwa rn...@apple.com wrote:


  On Apr 27, 2015, at 5:43 PM, Steve Orvell sorv...@google.com wrote:
 
  That might be an acceptable mode of operations. If you wanted to
 synchronously update your insertion points, rely on custom element's
 lifecycle callbacks and you can only support direct children for
 distribution.
 
  That's interesting, thanks for working through it. Given a
 `childrenChanged` callback, I think your first proposal
 `content.insertAt` and `content.remove` best supports a synchronous
 mental model. As you note, re-distribution is then the element author's
 responsibility. This would be done by listening to the synchronous
 `distributionChanged` event. That seems straightforward.
 
  Mutations that are not captured in childrenChanged that can affect
 distribution would still be a problem, however. Given:
 
  div id=host
div id=child/div
  /div
 
  child.setAttribute('slot', 'a');
  host.offsetHeight;
 
  Again, we are guaranteed that parent's offsetHeight includes any
 contribution that adding the slot attribute caused (e.g. via a
 #child[slot=a] rule)
 
  If the `host` is a custom element that uses distribution, would it be
 possible to have this same guarantee?
 
  x-foo id=host
div id=child/div
  /x-foo
 
  child.setAttribute('slot', 'a');
  host.offsetHeight;

 That's a good point. Perhaps we need to make childrenChanged optionally
 get called when attributes of child nodes are changed just like the way you
 can configure mutation observers to optionally monitor attribute changes.

 - R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Ryosuke Niwa

 On Apr 27, 2015, at 7:32 PM, Steve Orvell sorv...@google.com wrote:
 
 Perhaps we need to make childrenChanged optionally get called when 
 attributes of child nodes are changed just like the way you can configure 
 mutation observers to optionally monitor attribute changes.
 
 Wow, let me summarize if I can. Let's say we have (a) a custom elements 
 synchronous callback `childrenChanged` that can see child adds/removes and 
 child attribute mutations, (b) the first option in the proposed api here 
 https://gist.github.com/rniwa/2f14588926e1a11c65d3, (c) user element code 
 that wires everything together correctly. Then, unless I am mistaken, we have 
 enough power to implement something like the currently spec'd declarative 
 `select` mechanism or the proposed `slot` mechanism without any change to 
 user's expectations about when information in the dom can be queried.

Right. The sticking point is that it's like re-introducing mutation events all 
over again if we don't do it carefully.

 Do the implementors think all of that is feasible?

I think something alone this line should be feasible to implement but the 
performance impact of firing so many events may warrant going back to 
micro-task timing and think of an alternative solution for the consistency.

 Possible corner case: If a content is added to a shadowRoot, this should 
 probably invalidate the distribution and redo everything. To maintain a 
 synchronous mental model, the content mutation in the shadowRoot subtree 
 needs to be seen synchronously. This is not possible with the tools mentioned 
 above, but it seems like a reasonable requirement that the shadowRoot author 
 can be aware of this change since the author is causing it to happen.

Alternatively, an insertion point could start empty, and the author could move 
stuff into it after running. We can also add `removeAll` on HTMLContentElement 
or 'resetDistribution' on ShadowRoot to remove all distributed nodes from a 
given insertion point or all insertion points associated with a shadow root.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Ryosuke Niwa

 On Apr 27, 2015, at 12:25 AM, Justin Fagnani justinfagn...@google.com wrote:
 
 On Sun, Apr 26, 2015 at 11:05 PM, Anne van Kesteren ann...@annevk.nl wrote:
 On Sat, Apr 25, 2015 at 10:49 PM, Ryosuke Niwa rn...@apple.com wrote:
  If we wanted to allow non-direct child descendent (e.g. grand child node) 
  of
  the host to be distributed, then we'd also need O(m) algorithm where m is
  the number of under the host element.  It might be okay to carry on the
  current restraint that only direct child of shadow host can be distributed
  into insertion points but I can't think of a good reason as to why such a
  restriction is desirable.
 
 The main reason is that you know that only a direct parent of a node can 
 distribute it. Otherwise any ancestor could distribute a node, and in 
 addition to probably being confusing and fragile, you have to define who wins 
 when multiple ancestors try to.
 
 There are cases where you really want to group element logically by one tree 
 structure and visually by another, like tabs. I think an alternative approach 
 to distributing arbitrary descendants would be to see if nodes can cooperate 
 on distribution so that a node could pass its direct children to another 
 node's insertion point. The direct child restriction would still be there, so 
 you always know who's responsible, but you can get the same effect as 
 distributing descendants for a cooperating sets of elements.

That's an interesting approach. Ted and I discussed this design, and it seems 
workable with Anne's `distribute` callback approach (= the second approach in 
my proposal).

Conceptually, we ask each child of a shadow host the list of distributable node 
for under that child (including itself). For normal node without a shadow root, 
it'll simply itself along with all the distribution candidates returned by its 
children. For a node with a shadow root, we ask its implementation. The 
recursive algorithm can be written as follows in pseudo code:

```
NodeList distributionList(Node n):
  if n has shadowRoot:
return ask n the list of distributable noes under n (1)
  else:
list = [n]
for each child in n:
  list += distributionList(n)
return list
```

Now, if we adopted `distribute` callback approach, one obvious mechanism to do 
(1) is to call `distribute` on n and return whatever it didn't distribute as a 
list. Another obvious approach is to simply return [n] to avoid the mess of n 
later deciding to distribute a new node.

 So you mean that we'd turn distributionList into a subtree? I.e. you
 can pass all descendants of a host element to add()? I remember Yehuda
 making the point that this was desirable to him.
 
 The other thing I would like to explore is what an API would look like
 that does the subclassing as well. Even though we deferred that to v2
 I got the impression talking to some folks after the meeting that
 there might be more common ground than I thought.
 
 I really don't think the platform needs to do anything to support subclassing 
 since it can be done so easily at the library level now that multiple 
 generations of shadow roots are gone. As long as a subclass and base class 
 can cooperate to produce a single shadow root with insertion points, the 
 platform doesn't need to know how they did it.

I think we should eventually add native declarative inheritance support for all 
of this.

One thing that worries me about the `distribute` callback approach (a.k.a. 
Anne's approach) is that it bakes distribution algorithm into the platform 
without us having thoroughly studied how subclassing will be done upfront.

Mozilla tried to solve this problem with XBS, and they seem to think what they 
have isn't really great. Google has spent multiple years working on this 
problem but they come around to say their solution, multiple generations of 
shadow DOM, may not be as great as they thought it would be. Given that, I'm 
quite terrified of making the same mistake in spec'ing how distribution works 
and later regretting it.

In that regard, the first approach w/o distribution has an advantage of letting 
Web developer experiment with the bare minimum and try out which distribution 
algorithms and mechanisms work best.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Hayato Ito
For the record, I, as a spec editor, still think Shadow Root hosts yet
another Shadow Root is the best idea among all ideas I've ever seen, with
a shadow as function, because it can explain everything in a unified
way using a single tree of trees, without bringing yet another complexity
such as multiple templates.

Please see
https://github.com/w3c/webcomponents/wiki/Multiple-Shadow-Roots-as-%22a-Shadow-Root-hosts-another-Shadow-Root%22




On Tue, Apr 28, 2015 at 12:51 PM Ryosuke Niwa rn...@apple.com wrote:


  On Apr 27, 2015, at 12:25 AM, Justin Fagnani justinfagn...@google.com
 wrote:
 
  On Sun, Apr 26, 2015 at 11:05 PM, Anne van Kesteren ann...@annevk.nl
 wrote:
  On Sat, Apr 25, 2015 at 10:49 PM, Ryosuke Niwa rn...@apple.com wrote:
   If we wanted to allow non-direct child descendent (e.g. grand child
 node) of
   the host to be distributed, then we'd also need O(m) algorithm where
 m is
   the number of under the host element.  It might be okay to carry on
 the
   current restraint that only direct child of shadow host can be
 distributed
   into insertion points but I can't think of a good reason as to why
 such a
   restriction is desirable.
 
  The main reason is that you know that only a direct parent of a node can
 distribute it. Otherwise any ancestor could distribute a node, and in
 addition to probably being confusing and fragile, you have to define who
 wins when multiple ancestors try to.
 
  There are cases where you really want to group element logically by one
 tree structure and visually by another, like tabs. I think an alternative
 approach to distributing arbitrary descendants would be to see if nodes can
 cooperate on distribution so that a node could pass its direct children to
 another node's insertion point. The direct child restriction would still be
 there, so you always know who's responsible, but you can get the same
 effect as distributing descendants for a cooperating sets of elements.

 That's an interesting approach. Ted and I discussed this design, and it
 seems workable with Anne's `distribute` callback approach (= the second
 approach in my proposal).

 Conceptually, we ask each child of a shadow host the list of distributable
 node for under that child (including itself). For normal node without a
 shadow root, it'll simply itself along with all the distribution candidates
 returned by its children. For a node with a shadow root, we ask its
 implementation. The recursive algorithm can be written as follows in pseudo
 code:

 ```
 NodeList distributionList(Node n):
   if n has shadowRoot:
 return ask n the list of distributable noes under n (1)
   else:
 list = [n]
 for each child in n:
   list += distributionList(n)
 return list
 ```

 Now, if we adopted `distribute` callback approach, one obvious mechanism
 to do (1) is to call `distribute` on n and return whatever it didn't
 distribute as a list. Another obvious approach is to simply return [n] to
 avoid the mess of n later deciding to distribute a new node.

  So you mean that we'd turn distributionList into a subtree? I.e. you
  can pass all descendants of a host element to add()? I remember Yehuda
  making the point that this was desirable to him.
 
  The other thing I would like to explore is what an API would look like
  that does the subclassing as well. Even though we deferred that to v2
  I got the impression talking to some folks after the meeting that
  there might be more common ground than I thought.
 
  I really don't think the platform needs to do anything to support
 subclassing since it can be done so easily at the library level now that
 multiple generations of shadow roots are gone. As long as a subclass and
 base class can cooperate to produce a single shadow root with insertion
 points, the platform doesn't need to know how they did it.

 I think we should eventually add native declarative inheritance support
 for all of this.

 One thing that worries me about the `distribute` callback approach (a.k.a.
 Anne's approach) is that it bakes distribution algorithm into the platform
 without us having thoroughly studied how subclassing will be done upfront.

 Mozilla tried to solve this problem with XBS, and they seem to think what
 they have isn't really great. Google has spent multiple years working on
 this problem but they come around to say their solution, multiple
 generations of shadow DOM, may not be as great as they thought it would be.
 Given that, I'm quite terrified of making the same mistake in spec'ing how
 distribution works and later regretting it.

 In that regard, the first approach w/o distribution has an advantage of
 letting Web developer experiment with the bare minimum and try out which
 distribution algorithms and mechanisms work best.

 - R. Niwa





Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Olli Pettay

On 04/27/2015 02:11 AM, Hayato Ito wrote:

I think Polymer folks will answer the use case of re-distribution.



I wasn't questioning the need for re-distribution. I was questioning the need 
to distribute grandchildren etc -
and even more, I was wondering what kind of algorithm would be sane in that 
case.

And passing random not-in-document, nor in-shadow-DOM elements to be 
distributed would be hard too.




So let me just show a good analogy so that every one can understand intuitively 
what re-distribution *means*.
Let me use a pseudo language and define XComponent's constructor as follows:

XComponents::XComponents(Title text, Icon icon) {
   this.text = text;
   this.button = new XButton(icon);
   ...
}

Here, |icon| is *re-distributed*.

In HTML world, this corresponds the followings:

The usage of x-component element:
   x-components
 x-textHello World/x-text
 x-iconMy Icon/x-icon
   /x-component

XComponent's shadow tree is:

   shadow-root
 h1content select=x-text/content/h1
 x-buttoncontent select=x-icon/content/x-button
   /shadow-root

Re-distribution enables the constructor of X-Component to pass the given 
parameter to other component's constructor, XButton's constructor.
If we don't have a re-distribution, XComponents can't create X-Button using the 
dynamic information.

XComponents::XCompoennts(Title text, Icon icon) {
   this.text = text;
   // this.button = new xbutton(icon);  // We can't!  We don't have 
redistribution!
   this.button = new xbutton(icon.png);  // XComponet have to do 
hard-coding. Please allow me to pass |icon| to x-button!
   ...
}


On Sun, Apr 26, 2015 at 12:23 PM Olli Pettay o...@pettay.fi 
mailto:o...@pettay.fi wrote:

On 04/25/2015 01:58 PM, Ryosuke Niwa wrote:
 
  On Apr 25, 2015, at 1:17 PM, Olli Pettay o...@pettay.fi 
mailto:o...@pettay.fi wrote:
 
  On 04/25/2015 09:28 AM, Anne van Kesteren wrote:
  On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com 
mailto:rn...@apple.com wrote:
  In today's F2F, I've got an action item to come up with a concrete 
workable proposal for imperative API.  I had a great chat about this
  afterwards with various people who attended F2F and here's a summary.  
I'll continue to work with Dimitri  Erik to work out details in the
  coming months (our deadline is July 13th).
 
  https://gist.github.com/rniwa/2f14588926e1a11c65d3
 
  I thought we came up with something somewhat simpler that didn't 
require adding an event or adding remove() for that matter:
 
  https://gist.github.com/annevk/e9e61801fcfb251389ef
 
 
  That is pretty much exactly how I was thinking the imperative API to 
work. (well, assuming errors in the example fixed)
 
  An example explaining how this all works in case of nested shadow trees 
would be good. I assume the more nested shadow tree just may get some
  nodes, which were already distributed, in the distributionList.
 
  Right, that was the design we discussed.
 
  How does the distribute() behave? Does it end up invoking distribution 
in all the nested shadow roots or only in the callee?
 
  Yes, that's the only reason we need distribute() in the first place.  If 
we didn't have to care about redistribution, simply exposing methods to
  insert/remove distributed nodes on content element is sufficient.
 
  Should distribute callback be called automatically at the end of the 
microtask if there has been relevant[1] DOM mutations since the last manual
  call to distribute()? That would make the API a bit simpler to use, if 
one wouldn't have to use MutationObservers.
 
  That's a possibility.  It could be an option to specify as well.  But 
there might be components that are not interested in updating distributed
  nodes for the sake of performance for example.  I'm not certain forcing 
everyone to always update distributed nodes is necessarily desirable given
  the lack of experience with an imperative API for distributing nodes.
 
  [1] Assuming we want to distribute only direct children, then any child 
list change or any attribute change in the children might cause
  distribution() automatically.
 
  I think that's a big if now that we've gotten rid of select attribute 
and multiple generations of shadow DOM.

It is not clear to me at all how you would handle the case when a node has 
several ancestors with shadow trees, and each of those want to distribute
the node to some insertion point.
Also, what is the use case to distribute non-direct descendants?




   As far as I could recall, one of
  the reasons we only supported distributing direct children was so that we could 
implement select attribute and multiple generations of shadow
  DOM.   If we wanted, we could always impose such a restriction in a 
declarative syntax and inheritance mechanism we add in v2 since those v2 APIs
  are 

Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-27 Thread Steve Orvell
Here's a minimal and hopefully simple proposal that we can flesh out if
this seems like an interesting api direction:

https://gist.github.com/sorvell/e201c25ec39480be66aa

We keep the currently spec'd distribution algorithm/timing but remove
`select` in favor of an explicit selection callback. The user simply
returns true if the node should be distributed to the given insertion point.

Advantages:
 * the callback can be synchronous-ish because it acts only on a specific
node when possible. Distribution then won't break existing expectations
since `offsetHeight` is always correct.
 * can implement either the currently spec'd `select` mechanism or the
proposed `slot` mechanism
 * can easily evolve to support distribution to isolated roots by using a
pure function that gets read only node 'proxies' as arguments.

Disadvantages:
 * cannot re-order the distribution
 * cannot distribute sub-elements

On Sat, Apr 25, 2015 at 1:58 PM, Ryosuke Niwa rn...@apple.com wrote:


  On Apr 25, 2015, at 1:17 PM, Olli Pettay o...@pettay.fi wrote:
 
  On 04/25/2015 09:28 AM, Anne van Kesteren wrote:
  On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com wrote:
  In today's F2F, I've got an action item to come up with a concrete
 workable
  proposal for imperative API.  I had a great chat about this afterwards
 with
  various people who attended F2F and here's a summary.  I'll continue
 to work
  with Dimitri  Erik to work out details in the coming months (our
 deadline
  is July 13th).
 
  https://gist.github.com/rniwa/2f14588926e1a11c65d3
 
  I thought we came up with something somewhat simpler that didn't
  require adding an event or adding remove() for that matter:
 
https://gist.github.com/annevk/e9e61801fcfb251389ef
 
 
  That is pretty much exactly how I was thinking the imperative API to
 work.
  (well, assuming errors in the example fixed)
 
  An example explaining how this all works in case of nested shadow trees
 would be good.
  I assume the more nested shadow tree just may get some nodes, which were
 already distributed, in the distributionList.

 Right, that was the design we discussed.

  How does the distribute() behave? Does it end up invoking distribution
 in all the nested shadow roots or only in the callee?

 Yes, that's the only reason we need distribute() in the first place.  If
 we didn't have to care about redistribution, simply exposing methods to
 insert/remove distributed nodes on content element is sufficient.

  Should distribute callback be called automatically at the end of the
 microtask if there has been relevant[1] DOM mutations since the last
  manual call to distribute()? That would make the API a bit simpler to
 use, if one wouldn't have to use MutationObservers.

 That's a possibility.  It could be an option to specify as well.  But
 there might be components that are not interested in updating distributed
 nodes for the sake of performance for example.  I'm not certain forcing
 everyone to always update distributed nodes is necessarily desirable given
 the lack of experience with an imperative API for distributing nodes.

  [1] Assuming we want to distribute only direct children, then any child
 list change or any attribute change in the children
  might cause distribution() automatically.

 I think that's a big if now that we've gotten rid of select attribute
 and multiple generations of shadow DOM.  As far as I could recall, one of
 the reasons we only supported distributing direct children was so that we
 could implement select attribute and multiple generations of shadow DOM.
  If we wanted, we could always impose such a restriction in a declarative
 syntax and inheritance mechanism we add in v2 since those v2 APIs are
 supposed to build on top of this imperative API.

 Another big if is whether we even need to let each shadow DOM select nodes
 to redistribute.  If we don't need to support filtering distributed nodes
 in insertion points for re-distribution (i.e. we either distribute
 everything under a given content element or nothing), then we don't need
 all of this redistribution mechanism baked into the browser and the model
 where we just have insert/remove on content element will work.

 - R. Niwa





Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-26 Thread Hayato Ito
I think Polymer folks will answer the use case of re-distribution.

So let me just show a good analogy so that every one can understand
intuitively what re-distribution *means*.
Let me use a pseudo language and define XComponent's constructor as follows:

XComponents::XComponents(Title text, Icon icon) {
  this.text = text;
  this.button = new XButton(icon);
  ...
}

Here, |icon| is *re-distributed*.

In HTML world, this corresponds the followings:

The usage of x-component element:
  x-components
x-textHello World/x-text
x-iconMy Icon/x-icon
  /x-component

XComponent's shadow tree is:

  shadow-root
h1content select=x-text/content/h1
x-buttoncontent select=x-icon/content/x-button
  /shadow-root

Re-distribution enables the constructor of X-Component to pass the given
parameter to other component's constructor, XButton's constructor.
If we don't have a re-distribution, XComponents can't create X-Button using
the dynamic information.

XComponents::XCompoennts(Title text, Icon icon) {
  this.text = text;
  // this.button = new xbutton(icon);  // We can't!  We don't have
redistribution!
  this.button = new xbutton(icon.png);  // XComponet have to do
hard-coding. Please allow me to pass |icon| to x-button!
  ...
}


On Sun, Apr 26, 2015 at 12:23 PM Olli Pettay o...@pettay.fi wrote:

 On 04/25/2015 01:58 PM, Ryosuke Niwa wrote:
 
  On Apr 25, 2015, at 1:17 PM, Olli Pettay o...@pettay.fi wrote:
 
  On 04/25/2015 09:28 AM, Anne van Kesteren wrote:
  On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com
 wrote:
  In today's F2F, I've got an action item to come up with a concrete
 workable proposal for imperative API.  I had a great chat about this
  afterwards with various people who attended F2F and here's a
 summary.  I'll continue to work with Dimitri  Erik to work out details in
 the
  coming months (our deadline is July 13th).
 
  https://gist.github.com/rniwa/2f14588926e1a11c65d3
 
  I thought we came up with something somewhat simpler that didn't
 require adding an event or adding remove() for that matter:
 
  https://gist.github.com/annevk/e9e61801fcfb251389ef
 
 
  That is pretty much exactly how I was thinking the imperative API to
 work. (well, assuming errors in the example fixed)
 
  An example explaining how this all works in case of nested shadow trees
 would be good. I assume the more nested shadow tree just may get some
  nodes, which were already distributed, in the distributionList.
 
  Right, that was the design we discussed.
 
  How does the distribute() behave? Does it end up invoking distribution
 in all the nested shadow roots or only in the callee?
 
  Yes, that's the only reason we need distribute() in the first place.  If
 we didn't have to care about redistribution, simply exposing methods to
  insert/remove distributed nodes on content element is sufficient.
 
  Should distribute callback be called automatically at the end of the
 microtask if there has been relevant[1] DOM mutations since the last manual
  call to distribute()? That would make the API a bit simpler to use, if
 one wouldn't have to use MutationObservers.
 
  That's a possibility.  It could be an option to specify as well.  But
 there might be components that are not interested in updating distributed
  nodes for the sake of performance for example.  I'm not certain forcing
 everyone to always update distributed nodes is necessarily desirable given
  the lack of experience with an imperative API for distributing nodes.
 
  [1] Assuming we want to distribute only direct children, then any child
 list change or any attribute change in the children might cause
  distribution() automatically.
 
  I think that's a big if now that we've gotten rid of select attribute
 and multiple generations of shadow DOM.

 It is not clear to me at all how you would handle the case when a node has
 several ancestors with shadow trees, and each of those want to distribute
 the node to some insertion point.
 Also, what is the use case to distribute non-direct descendants?




   As far as I could recall, one of
  the reasons we only supported distributing direct children was so that
 we could implement select attribute and multiple generations of shadow
  DOM.   If we wanted, we could always impose such a restriction in a
 declarative syntax and inheritance mechanism we add in v2 since those v2
 APIs
  are supposed to build on top of this imperative API.
 
  Another big if is whether we even need to let each shadow DOM select
 nodes to redistribute.  If we don't need to support filtering distributed
  nodes in insertion points for re-distribution (i.e. we either distribute
 everything under a given content element or nothing), then we don't need
  all of this redistribution mechanism baked into the browser and the
 model where we just have insert/remove on content element will work.
 
  - R. Niwa
 





Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-25 Thread Ryosuke Niwa
Sure, I'll put the summary of discussion there later.

- R. Niwa

 On Apr 25, 2015, at 10:00 AM, Hayato Ito hay...@chromium.org wrote:
 
 Thank you, guys.
 I really appreciate if you guys could use the W3C bug, 18429, to discuss this 
 kind of specific topic about Shadow DOM so that we can track the progress 
 easily in one place. I'm not fan of the discussion being scattered. :)
 
 https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429
 
 
 On Sat, Apr 25, 2015 at 9:32 AM Anne van Kesteren ann...@annevk.nl wrote:
 On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com wrote:
  In today's F2F, I've got an action item to come up with a concrete workable
  proposal for imperative API.  I had a great chat about this afterwards with
  various people who attended F2F and here's a summary.  I'll continue to 
  work
  with Dimitri  Erik to work out details in the coming months (our deadline
  is July 13th).
 
  https://gist.github.com/rniwa/2f14588926e1a11c65d3
 
 I thought we came up with something somewhat simpler that didn't
 require adding an event or adding remove() for that matter:
 
   https://gist.github.com/annevk/e9e61801fcfb251389ef
 
 I added an example there that shows how you could implement content
 select, it's rather trivial with the matches() API. I think you can
 derive any other use case easily from that example, though I'm willing
 to help guide people through others if it is unclear. I guess we might
 still want positional insertion as a convenience though the above
 seems to be all you need primitive-wise.
 
 
 --
 https://annevankesteren.nl/


Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-25 Thread Hayato Ito
Thank you, guys.
I really appreciate if you guys could use the W3C bug, 18429, to discuss
this kind of specific topic about Shadow DOM so that we can track the
progress easily in one place. I'm not fan of the discussion being scattered.
:)

https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429


On Sat, Apr 25, 2015 at 9:32 AM Anne van Kesteren ann...@annevk.nl wrote:

 On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com wrote:
  In today's F2F, I've got an action item to come up with a concrete
 workable
  proposal for imperative API.  I had a great chat about this afterwards
 with
  various people who attended F2F and here's a summary.  I'll continue to
 work
  with Dimitri  Erik to work out details in the coming months (our
 deadline
  is July 13th).
 
  https://gist.github.com/rniwa/2f14588926e1a11c65d3

 I thought we came up with something somewhat simpler that didn't
 require adding an event or adding remove() for that matter:

   https://gist.github.com/annevk/e9e61801fcfb251389ef

 I added an example there that shows how you could implement content
 select, it's rather trivial with the matches() API. I think you can
 derive any other use case easily from that example, though I'm willing
 to help guide people through others if it is unclear. I guess we might
 still want positional insertion as a convenience though the above
 seems to be all you need primitive-wise.


 --
 https://annevankesteren.nl/




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-25 Thread Ryosuke Niwa

 On Apr 25, 2015, at 9:28 AM, Anne van Kesteren ann...@annevk.nl wrote:
 
 On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com wrote:
 In today's F2F, I've got an action item to come up with a concrete workable
 proposal for imperative API.  I had a great chat about this afterwards with
 various people who attended F2F and here's a summary.  I'll continue to work
 with Dimitri  Erik to work out details in the coming months (our deadline
 is July 13th).
 
 https://gist.github.com/rniwa/2f14588926e1a11c65d3
 
 I thought we came up with something somewhat simpler that didn't
 require adding an event or adding remove() for that matter:

That's the second approach I mentioned.  Like I mentioned in the gist, this 
model assumes that redistribution is done by UA and only direct children can be 
distributed.  I realized that those constraints are no longer necessary given 
we don't have content select or multiple generations of shadow DOM.

  https://gist.github.com/annevk/e9e61801fcfb251389ef
 
 I added an example there that shows how you could implement content
 select, it's rather trivial with the matches() API. I think you can
 derive any other use case easily from that example, though I'm willing
 to help guide people through others if it is unclear. I guess we might
 still want positional insertion as a convenience though the above
 seems to be all you need primitive-wise.
 
 
 -- 
 https://annevankesteren.nl/
 



RE: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-25 Thread Travis Leithead
Nice work folks, and thanks for writing this up so quickly! Anne's Gist 
captured exactly what I was thinking this would look like.

One nit: it would be nice if the callback could be registered from _inside_ the 
shadowRoot, but I couldn't come up with a satisfactory way to do that without 
adding more complexity. :)

-Original Message-
From: Ryosuke Niwa [mailto:rn...@apple.com] 
Sent: Saturday, April 25, 2015 10:13 AM
To: Anne van Kesteren
Cc: WebApps WG; Erik Bryn; Dimitri Glazkov
Subject: Re: Imperative API for Node Distribution in Shadow DOM (Revisited)


 On Apr 25, 2015, at 9:28 AM, Anne van Kesteren ann...@annevk.nl wrote:
 
 On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com wrote:
 In today's F2F, I've got an action item to come up with a concrete workable
 proposal for imperative API.  I had a great chat about this afterwards with
 various people who attended F2F and here's a summary.  I'll continue to work
 with Dimitri  Erik to work out details in the coming months (our deadline
 is July 13th).
 
 https://gist.github.com/rniwa/2f14588926e1a11c65d3
 
 I thought we came up with something somewhat simpler that didn't
 require adding an event or adding remove() for that matter:

That's the second approach I mentioned.  Like I mentioned in the gist, this 
model assumes that redistribution is done by UA and only direct children can be 
distributed.  I realized that those constraints are no longer necessary given 
we don't have content select or multiple generations of shadow DOM.

  https://gist.github.com/annevk/e9e61801fcfb251389ef
 
 I added an example there that shows how you could implement content
 select, it's rather trivial with the matches() API. I think you can
 derive any other use case easily from that example, though I'm willing
 to help guide people through others if it is unclear. I guess we might
 still want positional insertion as a convenience though the above
 seems to be all you need primitive-wise.
 
 
 -- 
 https://annevankesteren.nl/
 




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-25 Thread Ryosuke Niwa

 On Apr 25, 2015, at 9:28 AM, Anne van Kesteren ann...@annevk.nl wrote:
 
 On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com wrote:
 In today's F2F, I've got an action item to come up with a concrete workable
 proposal for imperative API.  I had a great chat about this afterwards with
 various people who attended F2F and here's a summary.  I'll continue to work
 with Dimitri  Erik to work out details in the coming months (our deadline
 is July 13th).
 
 https://gist.github.com/rniwa/2f14588926e1a11c65d3
 
 I thought we came up with something somewhat simpler that didn't
 require adding an event or adding remove() for that matter:
 
  https://gist.github.com/annevk/e9e61801fcfb251389ef 
 https://gist.github.com/annevk/e9e61801fcfb251389ef

```js
var shadow = host.createShadowRoot({
  mode: closed,
  distribute: (distributionList, insertionList) = {
for(var i = 0; i  distributionList.length; i++) {
  for(var ii = 0; ii  insertionList.length; ii++) {
var select = insertionList[ii].getAttribute(select)
if(select != null  distributionList[i].matches(select)) {
  insertionList[ii].add(distrubtionList[i])
} else if(select != null) {
  insertionList[ii].add(distrubtionList[i])
}
  }
}
  }
})
host.shadowRoot.distribute()
```

One major drawback of this API is computing insertionList is expensive because 
we'd have to either (where n is the number of nodes in the shadow DOM):
Maintain an ordered list of insertion points, which results in O(n) algorithm 
to run whenever a content element is inserted or removed.
Lazily compute the ordered list of insertion points when `distribute` callback 
is about to get called in O(n).

If we wanted to allow non-direct child descendent (e.g. grand child node) of 
the host to be distributed, then we'd also need O(m) algorithm where m is the 
number of under the host element.  It might be okay to carry on the current 
restraint that only direct child of shadow host can be distributed into 
insertion points but I can't think of a good reason as to why such a 
restriction is desirable.

- R. Niwa



Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-25 Thread Ryosuke Niwa

 On Apr 25, 2015, at 1:17 PM, Olli Pettay o...@pettay.fi wrote:
 
 On 04/25/2015 09:28 AM, Anne van Kesteren wrote:
 On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com wrote:
 In today's F2F, I've got an action item to come up with a concrete workable
 proposal for imperative API.  I had a great chat about this afterwards with
 various people who attended F2F and here's a summary.  I'll continue to work
 with Dimitri  Erik to work out details in the coming months (our deadline
 is July 13th).
 
 https://gist.github.com/rniwa/2f14588926e1a11c65d3
 
 I thought we came up with something somewhat simpler that didn't
 require adding an event or adding remove() for that matter:
 
   https://gist.github.com/annevk/e9e61801fcfb251389ef
 
 
 That is pretty much exactly how I was thinking the imperative API to work.
 (well, assuming errors in the example fixed)
 
 An example explaining how this all works in case of nested shadow trees would 
 be good.
 I assume the more nested shadow tree just may get some nodes, which were 
 already distributed, in the distributionList.

Right, that was the design we discussed.

 How does the distribute() behave? Does it end up invoking distribution in all 
 the nested shadow roots or only in the callee?

Yes, that's the only reason we need distribute() in the first place.  If we 
didn't have to care about redistribution, simply exposing methods to 
insert/remove distributed nodes on content element is sufficient.

 Should distribute callback be called automatically at the end of the 
 microtask if there has been relevant[1] DOM mutations since the last
 manual call to distribute()? That would make the API a bit simpler to use, if 
 one wouldn't have to use MutationObservers.

That's a possibility.  It could be an option to specify as well.  But there 
might be components that are not interested in updating distributed nodes for 
the sake of performance for example.  I'm not certain forcing everyone to 
always update distributed nodes is necessarily desirable given the lack of 
experience with an imperative API for distributing nodes.

 [1] Assuming we want to distribute only direct children, then any child list 
 change or any attribute change in the children
 might cause distribution() automatically.

I think that's a big if now that we've gotten rid of select attribute and 
multiple generations of shadow DOM.  As far as I could recall, one of the 
reasons we only supported distributing direct children was so that we could 
implement select attribute and multiple generations of shadow DOM.   If we 
wanted, we could always impose such a restriction in a declarative syntax and 
inheritance mechanism we add in v2 since those v2 APIs are supposed to build on 
top of this imperative API.

Another big if is whether we even need to let each shadow DOM select nodes to 
redistribute.  If we don't need to support filtering distributed nodes in 
insertion points for re-distribution (i.e. we either distribute everything 
under a given content element or nothing), then we don't need all of this 
redistribution mechanism baked into the browser and the model where we just 
have insert/remove on content element will work.

- R. Niwa




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-25 Thread Hayato Ito
Thanks. I am really glad to see more and more guys are thinking about
Shadow DOM.
I know distribution/re-distributions is a tough issue. A lot of exciting
things are waiting for you. :)

On Sat, Apr 25, 2015 at 10:19 AM Ryosuke Niwa rn...@apple.com wrote:

 Sure, I'll put the summary of discussion there later.

 - R. Niwa

 On Apr 25, 2015, at 10:00 AM, Hayato Ito hay...@chromium.org wrote:

 Thank you, guys.
 I really appreciate if you guys could use the W3C bug, 18429, to discuss
 this kind of specific topic about Shadow DOM so that we can track the
 progress easily in one place. I'm not fan of the discussion being
 scattered. :)

 https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429


 On Sat, Apr 25, 2015 at 9:32 AM Anne van Kesteren ann...@annevk.nl
 wrote:

 On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com wrote:
  In today's F2F, I've got an action item to come up with a concrete
 workable
  proposal for imperative API.  I had a great chat about this afterwards
 with
  various people who attended F2F and here's a summary.  I'll continue to
 work
  with Dimitri  Erik to work out details in the coming months (our
 deadline
  is July 13th).
 
  https://gist.github.com/rniwa/2f14588926e1a11c65d3

 I thought we came up with something somewhat simpler that didn't
 require adding an event or adding remove() for that matter:

   https://gist.github.com/annevk/e9e61801fcfb251389ef

 I added an example there that shows how you could implement content
 select, it's rather trivial with the matches() API. I think you can
 derive any other use case easily from that example, though I'm willing
 to help guide people through others if it is unclear. I guess we might
 still want positional insertion as a convenience though the above
 seems to be all you need primitive-wise.


 --
 https://annevankesteren.nl/




Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-25 Thread Olli Pettay

On 04/25/2015 09:28 AM, Anne van Kesteren wrote:

On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com wrote:

In today's F2F, I've got an action item to come up with a concrete workable
proposal for imperative API.  I had a great chat about this afterwards with
various people who attended F2F and here's a summary.  I'll continue to work
with Dimitri  Erik to work out details in the coming months (our deadline
is July 13th).

https://gist.github.com/rniwa/2f14588926e1a11c65d3


I thought we came up with something somewhat simpler that didn't
require adding an event or adding remove() for that matter:

   https://gist.github.com/annevk/e9e61801fcfb251389ef



That is pretty much exactly how I was thinking the imperative API to work.
(well, assuming errors in the example fixed)

An example explaining how this all works in case of nested shadow trees would 
be good.
I assume the more nested shadow tree just may get some nodes, which were 
already distributed, in the distributionList.

How does the distribute() behave? Does it end up invoking distribution in all 
the nested shadow roots or only in the callee?

Should distribute callback be called automatically at the end of the microtask 
if there has been relevant[1] DOM mutations since the last
manual call to distribute()? That would make the API a bit simpler to use, if 
one wouldn't have to use MutationObservers.
(even then one could skip distribution say for example during page load time and do a page level distribute all the stuff once all the data is ready 
etc, if wanted.).





-Olli

[1] Assuming we want to distribute only direct children, then any child list 
change or any attribute change in the children
might cause distribution() automatically.





I added an example there that shows how you could implement content
select, it's rather trivial with the matches() API. I think you can
derive any other use case easily from that example, though I'm willing
to help guide people through others if it is unclear. I guess we might
still want positional insertion as a convenience though the above
seems to be all you need primitive-wise.







Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-25 Thread Olli Pettay

On 04/25/2015 01:58 PM, Ryosuke Niwa wrote:



On Apr 25, 2015, at 1:17 PM, Olli Pettay o...@pettay.fi wrote:

On 04/25/2015 09:28 AM, Anne van Kesteren wrote:

On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com wrote:

In today's F2F, I've got an action item to come up with a concrete workable 
proposal for imperative API.  I had a great chat about this
afterwards with various people who attended F2F and here's a summary.  I'll 
continue to work with Dimitri  Erik to work out details in the
coming months (our deadline is July 13th).

https://gist.github.com/rniwa/2f14588926e1a11c65d3


I thought we came up with something somewhat simpler that didn't require adding 
an event or adding remove() for that matter:

https://gist.github.com/annevk/e9e61801fcfb251389ef



That is pretty much exactly how I was thinking the imperative API to work. 
(well, assuming errors in the example fixed)

An example explaining how this all works in case of nested shadow trees would 
be good. I assume the more nested shadow tree just may get some
nodes, which were already distributed, in the distributionList.


Right, that was the design we discussed.


How does the distribute() behave? Does it end up invoking distribution in all 
the nested shadow roots or only in the callee?


Yes, that's the only reason we need distribute() in the first place.  If we 
didn't have to care about redistribution, simply exposing methods to
insert/remove distributed nodes on content element is sufficient.


Should distribute callback be called automatically at the end of the microtask 
if there has been relevant[1] DOM mutations since the last manual
call to distribute()? That would make the API a bit simpler to use, if one 
wouldn't have to use MutationObservers.


That's a possibility.  It could be an option to specify as well.  But there 
might be components that are not interested in updating distributed
nodes for the sake of performance for example.  I'm not certain forcing 
everyone to always update distributed nodes is necessarily desirable given
the lack of experience with an imperative API for distributing nodes.


[1] Assuming we want to distribute only direct children, then any child list 
change or any attribute change in the children might cause
distribution() automatically.


I think that's a big if now that we've gotten rid of select attribute and 
multiple generations of shadow DOM.


It is not clear to me at all how you would handle the case when a node has 
several ancestors with shadow trees, and each of those want to distribute
the node to some insertion point.
Also, what is the use case to distribute non-direct descendants?





 As far as I could recall, one of
the reasons we only supported distributing direct children was so that we could implement 
select attribute and multiple generations of shadow
DOM.   If we wanted, we could always impose such a restriction in a declarative 
syntax and inheritance mechanism we add in v2 since those v2 APIs
are supposed to build on top of this imperative API.

Another big if is whether we even need to let each shadow DOM select nodes to 
redistribute.  If we don't need to support filtering distributed
nodes in insertion points for re-distribution (i.e. we either distribute 
everything under a given content element or nothing), then we don't need
all of this redistribution mechanism baked into the browser and the model where 
we just have insert/remove on content element will work.

- R. Niwa






Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-25 Thread Ryosuke Niwa
Just to clarity, I obviously haven't had a time to discuss this with my 
colleagues so I don't know which one (or something else entirely) we (Apple) 
end up endorsing/opposing at the end.

 On Apr 25, 2015, at 12:14 AM, Ryosuke Niwa rn...@apple.com wrote:
 
 Hi all,
 
 In today's F2F, I've got an action item to come up with a concrete workable 
 proposal for imperative API.  I had a great chat about this afterwards with 
 various people who attended F2F and here's a summary.  I'll continue to work 
 with Dimitri  Erik to work out details in the coming months (our deadline is 
 July 13th).
 
 https://gist.github.com/rniwa/2f14588926e1a11c65d3 
 https://gist.github.com/rniwa/2f14588926e1a11c65d3
 
 Imperative API for Node Distribution in Shadow DOM
 
 There are two approaches to the problem depending on whether we want to 
 natively support redistribution or not.
 
 To recap, a redistribution of a node (N_1) happens when it's distributed to 
 an insertion point (I_1) inside a shadow root (S_1), and I_1's parent also 
 has a shadow root which contains an insertion point which ends picking up 
 N_1. e.g. the original tree may look like:
 
 (host of S_1) - S_1
   + N_1 + (host of S_2) - S_2
+ I_1   + I_2
 Here, (host of S_1) has N_1 as a child, and (host of S_2) is a child of S_1 
 and has I_1 as a child. S_2 has I_2 as a child. The composed tree, then, may 
 look like:
 
 (host of S_1)
  + (host of S_2)
+ I_2
  + N_1
  
 https://gist.github.com/rniwa/2f14588926e1a11c65d3#redistribution-is-implemented-by-authorsRedistribution
  is implemented by authors
 
 In this model, we can add insertAt and remove on content element and expose 
 distributedNodes defined as follows:
 
 insertAt(Node nodeToDistribute, long index) - Inserts nodeToDistribute to the 
 list of the distributed nodes at index. It throws if nodeToDistribute is not 
 a descendent (or a direct child if wanted to keep this constraint) of the 
 shadow host of the ancestor shadow root of containt or if index is larger 
 than the length of distributedNodes.
 remove(Node distributedNode) - Remove distributedNode from the list 
 distributed nodes. Throws if distributedNodes doesn't contain this node.
 distributedNodes - Returns an array of nodes that are distributed into this 
 insertion point in the order they appear.
 In addition, content fires a synchrnous distributionchanged event when 
 distributedNodeschanges (in response to calls to insertAt or remove). 
 
  https://gist.github.com/rniwa/2f14588926e1a11c65d3#prosPros
 
 Very simple / very primitive looking.
 Defers the exact mechanism/algorithm of re-distributions to component authors.
 We can support distributing any descendent, not just direct children, to any 
 insertion points. This was not possible with select attribute especially with 
 the presence of multiple generations of shadow DOM due to perfomance problems.
 Allows distributed nodes to be re-ordered (select doesn't allow this).
  https://gist.github.com/rniwa/2f14588926e1a11c65d3#consCons
 
 Each component needs to manually implement re-distributions by recursively 
 traversing through distributedNodes of content elements inside 
 distributedNodes of the content element if it didn't want to re-distribute 
 everything. This is particularly challenging because you need to listen to 
 distributionchanged event on every such content element. We might need 
 something aking to MutationObserver's subtree option to monitor this if we're 
 going this route.
 It seems hard to support re-distribution natively in v2.
  
 https://gist.github.com/rniwa/2f14588926e1a11c65d3#redistribution-is-implemented-by-uasRedistribution
  is implemented by UAs
 
 In this model, the browser is responsible for taking care of redistributions. 
 Namely, we would like to expose distributionPool on the shadow root which 
 contains the ordered list of nodes that could be distributed (because they're 
 direct children of the host) or re-distributed. Conceptually, you could think 
 of it as a depth first traversal of distributedNodes of every content 
 element. Because this list contains every candidate for (re)distribution, 
 it's impractical to include every descendent node especially if we wanted to 
 do synchronous updates so we're back to supporting only direct children for 
 distribution.
 
 In this proposal, we add a new callback distributeCallback(NodeList 
 distributionPool) as an arguemnt (probably inside a dictionary) to 
 createShadowRoot. e.g.
 
 var shadowRoot = element.createShadowRoot({
   distributedCallback: function (distributionPool) {
 ... // code to distribute nodes
   }
 });
 Unfortunately, we can't really use insertAt and remove in model because 
 distributionPoolmaybe changed under the foot by (outer) insertion points in 
 the light DOM if this shadow root to attached to a host inside another shadow 
 DOM unless we manually listen to distributionchangedevent on every content 
 (which may recursively 

Re: Imperative API for Node Distribution in Shadow DOM (Revisited)

2015-04-25 Thread Anne van Kesteren
On Sat, Apr 25, 2015 at 12:17 AM, Ryosuke Niwa rn...@apple.com wrote:
 In today's F2F, I've got an action item to come up with a concrete workable
 proposal for imperative API.  I had a great chat about this afterwards with
 various people who attended F2F and here's a summary.  I'll continue to work
 with Dimitri  Erik to work out details in the coming months (our deadline
 is July 13th).

 https://gist.github.com/rniwa/2f14588926e1a11c65d3

I thought we came up with something somewhat simpler that didn't
require adding an event or adding remove() for that matter:

  https://gist.github.com/annevk/e9e61801fcfb251389ef

I added an example there that shows how you could implement content
select, it's rather trivial with the matches() API. I think you can
derive any other use case easily from that example, though I'm willing
to help guide people through others if it is unclear. I guess we might
still want positional insertion as a convenience though the above
seems to be all you need primitive-wise.


-- 
https://annevankesteren.nl/