[webcomponents] [Shadow]: Specify imperative API for node distribution (bugzilla: 18429) (#60)

Title: [Shadow]: Specify imperative API for node distribution (bugzilla: 18429)

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

----
comment: 0
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c0
*Dimitri Glazkov* wrote on 2012-07-27 22:19:33 +0000.

Declarative insertion points syntax is not able to address several use cases (spec bugs to be filed by Hayato-san and Shinya-san). Here's a strawman for an imperative API:

The general idea is that the insertion point distribution is actually something that occurs as a result of running some function/callback. The callback could be powered with Mutation Observers, or some internal implementation. When this function runs, it operates on a special API of HTMLContentElement: the distributedChildren (name TBD) array.

Adding a Node to this array makes it appear projected into its HTMLContentElement. If a node is not a descendant of shadow host, an exception is thrown. If a node is a descendant of another node that is already a member of any distributedChildren array of the shadow subtree, that other node is ejected from the distributedChildren array to which it belonged. There are more cases to handle, but you get the gist.

The declarative API is simply a byproduct of some default function/callback. You can override this callback with your custom handler, thus disabling the declarative API.

The advantage here is that you can:

1) completely explain the magic of the declarative insertion point syntax

2) provide solutions to all of the use cases (including crazy stuff like dynamic creation of insertion points for varying number of children)

The disadvantage is that:

1) the API has tremendous foot-gun potential and we need to make darn sure to steer clear of those.

2) there are potential challenges with making this work in a performant fashion.

----

comment: 1
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c1
*Dimitri Glazkov* wrote on 2014-02-11 18:48:15 +0000.

We still need the imperative API. It just needs to be addressed at the level of the underlying primitives and with proper layering.

----

comment: 2
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c2
*Dimitri Glazkov* wrote on 2014-03-07 18:39:46 +0000.

There's an API proposed on http://lists.w3.org/Archives/Public/public-webapps/2014JanMar/0376.html. It needs a small tweak to play nice with distributions.

Distributions are necessary to maintain composability properties of Shadow DOM. Since it might be hard for a newcomer to reconstruct the whole picture from emails and bug comments, I took a bit of time to document it here: https://gist.github.com/dglazkov/e8402f9ab18ad7ef2e7d

tl;dr: distributions are a requirement for Shadow DOM. They are here to stay, because without them, Shadow DOM is just a fun theoretical exercise.

The tweak is minor: the add/remove methods populate a pool of candidates. We then hook processing this pool into pool population algorithm (http://w3c.github.io/webcomponents/spec/shadow/#dfn-pool-population-algorithm), modulo additional integrity checks (tbd). Even better, make this pool of candidates an Array.

This eliminates both the problem with the original proposal, and makes the recently proposed API work with distributions.

----

comment: 3
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c3
*Dimitri Glazkov* wrote on 2014-04-10 17:30:31 +0000.

Here's a brainstorm gist for F2F session tomorrow.

https://gist.github.com/dglazkov/ce96f673b0b2ce7b8c55

----

comment: 4
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c4
*Hayato Ito* wrote on 2014-04-11 01:32:25 +0000.

Inspired from the Dimitri's gist, here is yet another idea.
This is a kind of the mixture of 'Passive candidate array' and 'Selector-based Routing'.
I'd have to say that this is a *very* rough idea.

Given the same DOM tree from the gist,

>> // Make sure that contentSummaryUI selects 'all' from the pool.
>> contentSummaryUI.setAttribute('select', '*')
>> contentSummaryUI.getDistributedNode()
[firstSummary, <p>]

>> // New API for insertion point: addDistributionCandidate(shadow_host, selector)
>> // addDistributionCandidate(..., ...) takes a shadow host and "selector" expression to select nodes from the children of the shadow host.
>> var distributionCandidate1 = contentSummaryUI.addDistributionCandidate(div, "summary:first-of-type");

>> // Supports also specifying a distributed node directly???
>> // var distributionCandidate1 = contentSummaryUI.addDistributionCandidate(firstSummary);

>> contentSummaryUI.distributionCandidates()
[distributionCandidate1]

>> // If an insertion point has a non-empty distributionCandidates, the pool is populated from the list of candidates.

>> contentSummaryUI.getDistributedNodes()
[firstSummary]

>> Does `DistributionCandidate` have an API?
>> distributionCandidate1.nodes()
[firstSummary]

>> contentSummaryUI.removeDistributionCandidate(distributionCandidate1)
>> contentSummaryUI.distributionCandidates()
[]
>> contentSummaryUI.getDistributedNodes();
[firstSummary, <p>]

----

comment: 5
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c5
*Dimitri Glazkov* wrote on 2015-02-07 00:32:37 +0000.

I just looked at this with fresh eyes and realized that I could polyfill an imperative API by using classes and matching their names to those of insertion points:

http://jsbin.com/baholi/3/edit?html,js,output

----

comment: 6
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c6
*Dimitri Glazkov* wrote on 2015-03-06 23:49:47 +0000.

(In reply to Dimitri Glazkov from comment #5)
> I just looked at this with fresh eyes and realized that I could polyfill an
> imperative API by using classes and matching their names to those of
> insertion points:
> 
> http://jsbin.com/baholi/3/edit?html,js,output

Of course, it doesn't work with distributions :`(

----

comment: 7
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c7
*Hayato Ito* wrote on 2015-04-27 03:09:48 +0000.

Let me move this bug to V2, assuming this is not a blocker for V1.

----

comment: 8
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c8
*Anne* wrote on 2015-04-27 03:20:19 +0000.

Hayato, what would we do in v1? I think we concluded that since both <content select> and <content slot> were not working for everyone involved, we needed to do imperative distribution first.

----

comment: 9
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c9
*Hayato Ito* wrote on 2015-04-27 03:32:57 +0000.

(In reply to Anne from comment #8)
> Hayato, what would we do in v1? I think we concluded that since both
> <content select> and <content slot> were not working for everyone involved,
> we needed to do imperative distribution first.

Yeah, imperative API is a stretch goal for v1, isn't it?

I'm okay to have a stretch goal under v1 umbrella. Let me move this back to v1.

We can decide to have the imperative APIs for v1 after July 13.

----

comment: 10
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c10
*Anne* wrote on 2015-04-27 05:37:01 +0000.

I think that without an imperative API we're back to <content select> vs <content slot> and likely no closer to reaching agreement to ship. So my goal is to get the imperative API done.

----

comment: 11
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c11
*Hayato Ito* wrote on 2015-04-27 07:18:48 +0000.

Thanks. I'm still uncertain, but let me contribute to the imperative API well and see how we can.

I really hope the discussion will be done in this bug. :)

----

comment: 12
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c12
*Hayato Ito* wrote on 2015-04-27 21:46:25 +0000.

The relevant discussion on public-webapps@

https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0288.html

----

comment: 13
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429#c13
*Hayato Ito* wrote on 2015-04-30 14:36:05 +0000.

For reference, could someone add a link to known use cases for an imperative API in this discussion?

I'd like to know every use cases we'd like to support in an imperative API.

---
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/60

Received on Monday, 25 May 2015 08:48:43 UTC