This is a great question. My $0.02 inline.

On Thu, Feb 6, 2014 at 2:08 PM, Justin Fagnani <[email protected]>wrote:

> I'm still trying to wrap my head around the Zen of custom elements. Right
> now I'm pondering how to keep content out of the Shadow DOM, in
> document-oriented apps, like CMS's, blogs, forums, doc viewers, etc.
> Currently every app I've seen has a single tag in the top document and from
> there it's shadow all the way down.
>
> The html5rocks.com article on Shadow DOM includes this great paragraph:
>
> One rule of thumb, which is possibly being violated here, is that you
>> shouldn’t put content in Shadow DOM. Content must be in the document to be
>> accessible to screen readers, search engines, extensions and so on. Shadow
>> DOM is for all of the semantically meaningless markup you need to create an
>> attractive, usable widget. But the content should stay in the page.
>
>
I wrote that, and let me tell you, I was in a different place then. It was
a different time. User agents grok this stuff better than I imagined at
this time (though it is not perfect.) I don't think "flattened tree" was
even a concept back then. Let alone doing a lot of heavy-lifting with
non-visual elements.

This makes a lot of sense when you start internalizing the web components
> way. For a static document that uses custom tags, it's even easy to demo,
> with something like:
>
> <html><body>
>   <blog-post>
>     <blog-title>Keep Content Out of Shadow DOM</blog-title>
>     <blog-body>It's easy!</blog-body>
>     <blog-footer><p>We can put <b>markup</b> here too</p></blog-footer>
>   </blog-post>
> </html></body>
>
> Sweet. This would presumably be crawlable too, if the custom tag names
> don't trip up the crawler.
>
> But I'm a little lost on how best to achieve this ideal in a dynamic app,
>

I doubt this was a solved problem for the pre-Polymer dynamic app, either.


> since the markup that uses the custom elements itself needs to be
> generated, and the primary way we have of doing that is via a component and
> its template. Doing that would mean that the markup ends up in shadow DOM,
>

Shadow DOM isn't a lock-box, there's also projection with <content>. It
might be an interesting exercise to say "what should my markup look like?"
and then try to work from there.


> which we don't want
>

Lots of chunks of markup belong in Shadow DOM. I think that's OK.

(assuming light dom option is going away).
>

Light DOM isn't going away. Can you elaborate on what you mean?


> The other options are imperatively building up the DOM, or using template
> binding outside of custom elements, which I've heard isn't being encouraged
> (please correct me if I'm wrong there).
>

Once you're running script, if your UA supports Shadow DOM you should use
Shadow DOM and expect your UA to understand it.

There might be a case for content in the ordinary DOM for compatibility
with UAs which don't understand Shadow DOM. But you might not want to rely
on them running script, either? I'm not sure.


> But let's assume that using a template is the way to go. It'd look like
> this:
>
> <html><body>
>   <template id="post" bind>
>      <blog-post>
>       <blog-title>{{ title }}</blog-title>
>       <blog-body>{{ body }}</blog-body>
>       <blog-footer><p>We can put <b>markup</b> here too</p></blog-footer>
>     </blog-post>
>   </template>
> </html></body>
>
> Then do a: querySelector('#post').model = post; and voilá!
>
> This has a few interesting implications.
>
> First, it seems like there's two sets of "bindings" for everything: one
> set of template binding mustaches to generate the document's DOM that uses
> custom tags, and the other would be mostly a set of content tags with
> selectors in the custom tags which project the content into the right
> places in the shadow trees.
>

I guess for me this boils down to the way I want the author to interact
with my component.

If the thing is content--like it might have a button or a bold run in
it--then I'd try to make it markup and use <content> to project it.

If the thing isn't content--like a blob of JSON or an array of
presidents--then I'd try to use properties for it.

Then there's a way to blat data out as content--template. Because
ultimately we want to present stuff.

Going from content to data is weird. I only did that when I was writing an
interactive, reflective DOM viewer in Polymer. It's niche.

Polymer elements mean things that were once objects, like XMLHttpRequest,
can now  be elements, like <polymer-ajax>. You don't need to use <content>
for those because you're not presenting them. But somehow I expect these
things to be relatively "static" in arrangement with just their properties
changing. The DOM tree is used like XAML to create them so you can wire up
their properties.

It would also seem to imply, though I haven't tried to go down this road so
> salt grains apply, that custom tags shouldn't really be interfacing with
> directly an app's data-model, but mainly with their own attributes and
> content.
>

Yes, this is right. Their own properties/attributes/events, and content for
when they are presenting content. If you get hooks too deeply and directly
into the app's data model, you'll get a tangle. Divide and conquer, I think.

I imagine Polymer applications are a box. Within the box there's an
arrangement of elements (at a coarse-grained level with a tree structure)
and databindings (at a finer-grained level with a network structure.) It's
sitting there like a machine that when you pour data into it responds in a
range of ways, but all of that is carried out by the mechanism. There's
very little code in there.

There's a bit of code on the border which might take your data and massage
it into something amenable to databinding. And there's legacy code wrapped
up in some Polymer elements at the leaf of the tree.

I think it makes sense to use the DOM tree to compose the pieces, a bit
like XAML. Shadow DOM can act as a container for that. But I think
<content> is really for presentation.


> Bindings would still be common for controlling rendering based on
> component state. I could maybe see that being a principle, but I haven't
> heard it before. I'm unsure with this approach how rendering would best be
> controlled based on the structure of content. Mutation observers that
> update internal state variables?
>

<content>, CSS and databinding all have a role here. I think it makes sense
to control rendering based on component state. But I don't see the
connection to structure of content outside of unusual ones like the DOM
viewer. Can you give me an example?


> Am I totally off in the weeds? I have not seen a Polymer app built this
> way, but I have not yet seen a Polymer app that adheres to the html5rocks
> advice either.
>
> Thanks,
>   Justin
>
>  Follow Polymer on Google+: plus.google.com/107187849809354688692
> ---
> You received this message because you are subscribed to the Google Groups
> "Polymer" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/polymer-dev/CAEKsHmAiTh3ZNPTEyeOwsTHLG6JpNn8JrZugGri%2BUJkeTSTDhg%40mail.gmail.com
> .
> For more options, visit https://groups.google.com/groups/opt_out.
>



-- 
Email SLA <http://goto.google.com/dc-email-sla> •
Google+<https://plus.sandbox.google.com/111762620242974506845/posts>

Follow Polymer on Google+: plus.google.com/107187849809354688692
--- 
You received this message because you are subscribed to the Google Groups 
"Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/polymer-dev/CAHnmYQ96004bWuhVQi5n1ku0o%2BZ%2BduqtXL15wUF1DZbro_9-4A%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to