This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 27775 - [Shadow]: Define the behavior of *closed* shadow trees.
Summary: [Shadow]: Define the behavior of *closed* shadow trees.
Status: RESOLVED MOVED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: HISTORICAL - Component Model (show other bugs)
Version: unspecified
Hardware: PC All
: P2 normal
Target Milestone: ---
Assignee: Hayato Ito
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 28552
  Show dependency treegraph
 
Reported: 2015-01-07 01:12 UTC by Hayato Ito
Modified: 2015-05-27 03:07 UTC (History)
12 users (show)

See Also:


Attachments

Description Hayato Ito 2015-01-07 01:12:32 UTC
The current spec uses a term of 'UA-provided shadow trees'. The spec assumes that built-in elements, such as <video> elements, might be implemented with shadow trees.
However, the behavior of UA-provided shadow trees isn't well defined in the spec yet.

For example, in Blink, event.path API returns an array, however, it excludes nodes in UA-provided shadow trees. Unfortunately, the spec doesn't mention this behavior at all. That doesn't look good to me from the view of compatibility if browser vendors would like to use shadow trees to implement their built-in elements.

I am wondering whether it is worth or not to expose this *hidden* concept, UA shadow trees, clearly in the spec, as a *closed shadow tree*, a tentative name borrowed from the another thread, so that we can explain the behavior of builtin elements in terms of Shadow DOM. I think this would fill one of missing pieces for 'HTML as Custom Elements' concept.

In Blink, as some of you might know, ShadowRoot object has an enum internally, UserAgentShadowRoot or AuthorShadowRoot. Some builtin elements, such as <video> or <input>, use UserAgentShadowRoot in their implementation as you imagine.
Currently, the behavior of this kind of shadow trees is only explained by Blink's C++ code.
It'd be nice that I could write down a well-defined behavior of a closed shadow tree somewhere. That should be in the spec. I don't want other browser vendors to do a kind of *reverse-engineering*.


The spec should mention the followings, but not limited to:

- Element.shadowRoot - If the youngest shadow tree is closed, return null. That matches the current Blink's implementation.
- Element.getDestinationInsertionPoints - must filter out insertion points if they are in a closed shadow tree. That matches the current Blink's implementation. e.g. <detail><summary>
- Event.path - must filter out event targets if it is in a closed shadow tree. (The exact condition is more complex than you imagine).
- Needs to discuss:
  Whether or not to allow calling Element.createShadowRoot() for the shadow host which has the closed youngest shadow tree.
  If we allow it, we might have to consider the followings also:
  - InsertinonPoint.getDistributedNodes - Filter out nodes in a closed older shadow tree. In Blink, we don't need this because there is not such UA and author shadow trees, I think.
  - ShadowRoot.olderShadowRoot - If the older shadow tree is closed, return null.
- The behavior of CSS selector which *crosses* shadow trees.
  '::shadow', '/deep/' - See https://code.google.com/p/chromium/issues/detail?id=433977 also. This should be mentioned in css-scoping spec.

What makes things complex is the case when a closed shadow tree and an open shadow tree are mixed together within one shadow host:

e.g.
A).  ShadowHost => the oldest shadow tree (open) => older shadow tree (open) => youngest shadow tree (closed)
B).  ShadowHost => the oldest shadow tree (closed) => older shadow tree (closed) => youngest shadow tree (open)

In Blink, there isn't a pattern A so far. We might need to consider this case in the future.


Here, I'm not aiming to expose an API for creating a closed shadow tree to Web developers.
Although this issue might resolve one of pre-requirements for that, as a result, I don't have any idea about how we should prioritize exposing such a API.

If we were to expose the API, the API might be:

- Element.createShadowRoot take an optional dictionary, such as ({'mode': 'closed'}).

I don't care which the *default* should be, `closed` or `open`. That sounds non-essential to me. That's a domain of API. For compatibility, the default should be 'open', I think.
Please use bug 20144 for this kind of topic.
Comment 1 Olli Pettay 2015-01-07 11:22:20 UTC
(In reply to Hayato Ito from comment #0)
> I am wondering whether it is worth or not to expose this *hidden* concept,
> UA shadow trees, clearly in the spec, as a *closed shadow tree*, a tentative
> name borrowed from the another thread, so that we can explain the behavior
> of builtin elements in terms of Shadow DOM.
Do we really want that? Wouldn't it bound implementations to use similar structures for 
form elements.

> In Blink, as some of you might know, ShadowRoot object has an enum
> internally, UserAgentShadowRoot or AuthorShadowRoot. Some builtin elements,
> such as <video> or <input>, use UserAgentShadowRoot in their implementation
> as you imagine.
> Currently, the behavior of this kind of shadow trees is only explained by
> Blink's C++ code.
> It'd be nice that I could write down a well-defined behavior of a closed
> shadow tree somewhere. That should be in the spec. I don't want other
> browser vendors to do a kind of *reverse-engineering*.

But why do we need to spec browser specific behavior? Maybe I'm missing what you're proposing here.


One good thing though is that if 'closed shadow tree' is spec'ed, it might force us to spec
how proper encapsulation and information hiding works.
So maybe we do want it after all, but just not spec what kind of closed shadow tree various elements may have.
That would be up to the UA.
Or... maybe we shouldn't define 'closed shadow tree', but something like
'domain specific shadow tree', and UA would just happen to form a 'system' domain itself.
Assuming 'dsst' would hide information by default, and could opt-in to not-hide, UA shadow DOM would just work
by default. So, I think we want this, and no special 'closed shadow tree'


> - Needs to discuss:
>   Whether or not to allow calling Element.createShadowRoot() for the shadow
> host which has the closed youngest shadow tree.
>   If we allow it, we might have to consider the followings also:
I think the end goal should be to allow it. There shouldn't be special cases or inconsistencies.
Comment 2 Hayato Ito 2015-01-08 07:48:46 UTC
(In reply to Olli Pettay from comment #1)
> (In reply to Hayato Ito from comment #0)
> > I am wondering whether it is worth or not to expose this *hidden* concept,
> > UA shadow trees, clearly in the spec, as a *closed shadow tree*, a tentative
> > name borrowed from the another thread, so that we can explain the behavior
> > of builtin elements in terms of Shadow DOM.
> Do we really want that? Wouldn't it bound implementations to use similar
> structures for 
> form elements.

Yeah, I thought that "we don't want this" because such a shadow tree has been used as an implementation detail of some of builtin elements. No one should take care of such an implementation detail, basically.
However, the recent movement, 'HTML as Custom Element', made me reconsider this topic again. I feel uncomfortable in the current Shadow DOM spec because the spec can't explain an existence of such an internally-used shadow tree in a well-defined manner, even though the spec mentions it as a UA-provided shadow tree, especially in the Section 8, "HTML Elements and Their Shadow Trees".


> 
> > In Blink, as some of you might know, ShadowRoot object has an enum
> > internally, UserAgentShadowRoot or AuthorShadowRoot. Some builtin elements,
> > such as <video> or <input>, use UserAgentShadowRoot in their implementation
> > as you imagine.
> > Currently, the behavior of this kind of shadow trees is only explained by
> > Blink's C++ code.
> > It'd be nice that I could write down a well-defined behavior of a closed
> > shadow tree somewhere. That should be in the spec. I don't want other
> > browser vendors to do a kind of *reverse-engineering*.
> 
> But why do we need to spec browser specific behavior? Maybe I'm missing what
> you're proposing here.

My bad. It's not a goal to define how a builtin element should be implemented in the spec. That's up to UA.
My intention of filing this issue is just to define the behavior of closed shadow trees clearly. It's up to UA how UA makes use of it. UA doesn't have to use shadow trees if a shadow tree doesn't fit.

But, wait,,, it's against "the Section 8, HTML Elements and Their Shadow Trees".
I think the original goal of Section 8 is to define how some of builtin elements should behave if Web Developers call element.createShadowRoot() for that. That's one of tough issues. 


> 
> 
> One good thing though is that if 'closed shadow tree' is spec'ed, it might
> force us to spec
> how proper encapsulation and information hiding works.

Good point. So far, we've succeeded to hide the implementation detail of <video> elements, using UA-provided shadow trees. I hope this issue is the good first step to consider this kind of topic.

> So maybe we do want it after all, but just not spec what kind of closed
> shadow tree various elements may have.
> That would be up to the UA.
> Or... maybe we shouldn't define 'closed shadow tree', but something like
> 'domain specific shadow tree', and UA would just happen to form a 'system'
> domain itself.
> Assuming 'dsst' would hide information by default, and could opt-in to
> not-hide, UA shadow DOM would just work
> by default. So, I think we want this, and no special 'closed shadow tree'

An Interesting idea. From the view of such a domain specific shadow tree, I am feeling that the current shadow tree might be considered as one of domain specific shadow tree, where the domain is 'Author'.

We might want to define the default behavior of two instances of domain specific shadow trees, 'System and Author', at least. Any other better interpretation of your idea?

Anyway, I don't have a plan to work on this task soon because I'm not confident about how we should prioritize this task. I've not heard any urgent requests for spec-cing *closed* shadow trees so far.

> 
> 
> > - Needs to discuss:
> >   Whether or not to allow calling Element.createShadowRoot() for the shadow
> > host which has the closed youngest shadow tree.
> >   If we allow it, we might have to consider the followings also:
> I think the end goal should be to allow it. There shouldn't be special cases
> or inconsistencies.

Agreed. That's exactly the original goal of "Section 8".
Comment 3 Philip Jägenstedt 2015-01-30 06:09:18 UTC
It would be nice to have closed shadow trees, which the the shadow-piercing combinator '>>>' cannot reach into and whose internal structure is otherwise entirely opaque to the containing document. Things like <video controls> would then be closed.

We could perhaps also allow script-created shadow trees to be closed, although defaulting to open.
Comment 4 Olli Pettay 2015-01-30 23:28:20 UTC
Why default open in that case?
Comment 5 Ryosuke Niwa 2015-01-30 23:47:07 UTC
All the arguments I've heard for default open have been bogus at best.  If authors can pierce through shadow boundaries, any hope for encapsulating your components' implementation details is lost.
Comment 6 Hayato Ito 2015-02-06 01:40:36 UTC
As I mentioned in comment #0, what 'default' should be orthogonal to the problem which this bug is trying to resolve.

Whatever the default would be, 'open' or 'closed, I don't see any effect of that on the behavior of closed shadow trees. Do you think the current behavior of UA shadow trees will be affected by the default? I don't think so.

I appreciate if you guys give us comments about the concrete behavior of closed shadow trees in this bug, if you have, as Philip did about '>>>'.

As for '>>>', yeah, I agree that '>>>' shouldn't piece closed shadow trees.
Comment 7 Philip Jägenstedt 2015-02-10 04:41:55 UTC
(In reply to Olli Pettay from comment #4)
> Why default open in that case?

Hmm, I actually don't know, closed is probably a more sane default.
Comment 8 Hayato Ito 2015-02-10 05:29:15 UTC
Started to introduce an isolation mode, which is either 'open' or 'closed', at:

https://github.com/w3c/webcomponents/commit/babf9a369159c3ecc42d090bdd4f1f492264d300
Comment 9 Anne 2015-02-10 14:28:51 UTC
Can we call this encapsulation mode and reserve the word isolation for a mode where not even globals are shared?
Comment 10 Hayato Ito 2015-02-12 04:16:43 UTC
(In reply to Anne from comment #9)
> Can we call this encapsulation mode and reserve the word isolation for a
> mode where not even globals are shared?

I think we can. Done at https://github.com/w3c/webcomponents/commit/d0de816cded2c4fe069c0af32c87ee6916e5bdb4.
Comment 11 Dylan Barrell 2015-03-10 21:44:16 UTC
(In reply to Philip Jägenstedt from comment #3)
> It would be nice to have closed shadow trees, which the the shadow-piercing
> combinator '>>>' cannot reach into and whose internal structure is otherwise
> entirely opaque to the containing document. Things like <video controls>
> would then be closed.
> 
> We could perhaps also allow script-created shadow trees to be closed,
> although defaulting to open.

I would strongly caution to not allow scripts to create closed trees from two perspectives:

1) How do you do testing into a closed tree in an end-to-end testing environment like Webdriver? I have already encountered occasions where Angular 2 end-to-end testing is complicated by the shadow DOM. Making the shadow DOM totally opaque would further complicate this unless you provide a testing API - in which case what is to stop someone from mis-using the testing API to reach inside the shadow DOM.

2) How do you do custom validations of entire documents for things like accessibility when the dependencies of ARIA roles and attributes can cross shadow root boundaries. One way to do this would be to expose the composed tree through an API but failure to expose the composed tree with the ability to create non-standard components that are 100% opaque make this sort of validation impossible.
Comment 12 Dimitri Glazkov 2015-03-10 22:17:04 UTC
(In reply to Dylan Barrell from comment #11)
> (In reply to Philip Jägenstedt from comment #3)
> > It would be nice to have closed shadow trees, which the the shadow-piercing
> > combinator '>>>' cannot reach into and whose internal structure is otherwise
> > entirely opaque to the containing document. Things like <video controls>
> > would then be closed.
> > 
> > We could perhaps also allow script-created shadow trees to be closed,
> > although defaulting to open.
> 
> I would strongly caution to not allow scripts to create closed trees from
> two perspectives:
> 
> 1) How do you do testing into a closed tree in an end-to-end testing
> environment like Webdriver? I have already encountered occasions where
> Angular 2 end-to-end testing is complicated by the shadow DOM. Making the
> shadow DOM totally opaque would further complicate this unless you provide a
> testing API - in which case what is to stop someone from mis-using the
> testing API to reach inside the shadow DOM.
> 
> 2) How do you do custom validations of entire documents for things like
> accessibility when the dependencies of ARIA roles and attributes can cross
> shadow root boundaries. One way to do this would be to expose the composed
> tree through an API but failure to expose the composed tree with the ability
> to create non-standard components that are 100% opaque make this sort of
> validation impossible.

This is one of the Closed-by-default Cons in the "contentious bits" document: https://github.com/w3c/webcomponents/wiki/Shadow-DOM:-Contentious-Bits#b-the-default-value-of-closed-shadow-tree-flag. If you have specific examples, please contribute them there.
Comment 13 Hayato Ito 2015-04-23 16:06:46 UTC
Status update about spec-ing the closed mode.

Mostly done about low-hanging fruits. However, there are still remaining tasks:

1. event.path(): We should filter out a node in closed shadow tree.
  In addition to that, should we filter out a node in a open shadow tree if it is descendant tree of a closed tree?
  In general, we can't determine the open/closed-ness in the local context. We should consider the relationship between the current tree and the target tree, e.g There is a closed shadow tree in the middle.

2. event retargeting
  Now we have a closed shadow tree. Should we continue an event retargeting even in for open shadow trees? 
  How about *opt-in*?

3. Other issues for mixing open/closed shadow trees.
  I guess no one has investigated how this mixture of open/closed should work seriously. We have to investigate further.



Anything else? If you notice something, please update this thread.
Comment 14 Hayato Ito 2015-04-23 16:25:29 UTC
Let me paste quote mail here, since it's related.

https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0225.html
>	D. Event Retargeting
>		1. We agree with making it optional (opt-in or opt-out). We don’t feel that strongly, but many web developers have asked for this. The default should likely match the default for open vs. closed (no retargeting by default if open by default).  <https://www.w3.org/Bugs/Public/show_bug.cgi?id=28444 <https://www.w3.org/Bugs/Public/show_bug.cgi?id=28444>>
Comment 15 Dylan Barrell 2015-04-23 17:40:45 UTC
(In reply to Dimitri Glazkov from comment #12)
> 
> This is one of the Closed-by-default Cons in the "contentious bits"
> document:
> https://github.com/w3c/webcomponents/wiki/Shadow-DOM:-Contentious-Bits#b-the-
> default-value-of-closed-shadow-tree-flag. If you have specific examples,
> please contribute them there.

How do I comment in the wiki when I cannot edit it?
Comment 16 Dimitri Glazkov 2015-04-23 19:03:52 UTC
(In reply to Dylan Barrell from comment #15)
> (In reply to Dimitri Glazkov from comment #12)
> > 
> > This is one of the Closed-by-default Cons in the "contentious bits"
> > document:
> > https://github.com/w3c/webcomponents/wiki/Shadow-DOM:-Contentious-Bits#b-the-
> > default-value-of-closed-shadow-tree-flag. If you have specific examples,
> > please contribute them there.
> 
> How do I comment in the wiki when I cannot edit it?

Doh. Good point. My apologies for directing you there. I will incorporate your feedback.
Comment 17 Hayato Ito 2015-05-27 03:07:25 UTC
Moved to https://github.com/w3c/webcomponents/issues/85