Re: [webcomponents] Imperative API for Insertion Points

On Feb 15, 2014, at 4:57 PM, Ryosuke Niwa <rniwa@apple.com> wrote:

> Hi all,
> 
> I’d like to propose one solution for
> 
> [Shadow]: Specify imperative API for node distribution
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429
> 
> because select content attribute doesn’t satisfy the needs of framework/library authors to support conditionals in their templates,
> and doesn’t satisfy my random image element use case below.
> 
> 
> == Use Case ==
> Random image element is a custom element that shows one of child img elements chosen uniformally random.
> 
> e.g. the markup of a document that uses random-image-element may look like this:
> <random-image-element>
>   <img src="kitten.jpg">
>   <img src="cat.jpg">
>   <img src="webkitten.jpg">
> </random-image-element>
> 
> random-image-element displays one out of the three img child elements when a user clicks on it.
> 
> As an author of this element, I could modify the DOM and add style content attribute directly on those elements
> but I would rather use shadow DOM to encapsulate the implementation.

I wanted to mention that this handles other use cases besides selecting a random child which are impossible (or at least very awkward) with <content select=""> as presently defined:

(1) A container component that can hold an arbitrary number of children, and wraps each of its light DOM children in a piece of markup inside the Shadow DOM. Consider a <buttonbar> component that placed each child into a <button>, and styled them all specially:

<buttonbar>
    <i onclick="execCommand('italic')">I</i>
    <b onclick="execCommand('bold')>B</b>
    <u onclick="execCommand('underline')>U</u>
<button>

Imagine it would render like this (explaining why separate individual <button> elements won't cut it).




(2) A component that expects alternate labels and corresponding items, wants to parent them into different boxes, but wants to make sure they remain corresponding.

<tabview>
    <tabtitle>Puppies</tabtitle>
    <tabpane>.... lots of pictures of puppies ....</tabpane>
    <tabtitle>Kittens</tabtitle>
    <tabpane>.... lots of pictures of kittens ....</tabpane>
    <tabtitle>Sadness</tabtitle>
    <!-- no tab pane provided for this title yet -->
    <tabtitle>Bunnies</tabtitle>
    <tabpane>.... lots of pictures of bunnies ...</tabpane>
</tabview>

The component author would like this to render as a tabview with 4 tab labels at the top ("Puppies", "Kittens", "Sadness", "Bunnies") and 3 actual tab panes with one placeholder inserted: (the puppy pane, the kitten pane, a blank placeholder, the bunny pane).

But if my shadow DOM looks like this:

<div class=tab-label-bar><content select="tabtitle"></div>
<div class=tab-holder><content select="tabpane"></div>

Then the pictures of bunnies would line up with the "Sadness" label, and I don't have an easy way to add the placeholder anywhere but at the beginning or the end of the tab panes.

(3) An element that selects some of its children conditionally. Let's say you have an element that will select different children depending on what features the browser supports:

<cond>
    <case condition="Modernizr.webgl">Spiffy WebGL view goes here!</case>
    <case condition="Modernizr.canvas">Passable 2-D canvas view goes here</case>
    <case default>Oh noes! You need more browser features to use this site!</case>
</cond>

The idea is to select in only exactly one of the cases - the first that matches. The others don't go into the shadow DOM. There isn't a great way to select only one of the "case" elements here (after having run the JS to evaluate which applies).

The SVG "switch" element does something similar, as does Modernizr's normal class-based mode of operation.


I hope these examples give more motivation for why programmatically binding an insertion point may be useful. 

Regards,
Maciej

Received on Sunday, 16 February 2014 19:27:25 UTC