Bug 19684 - [Shadow]: shadow reference combinator should be css function.
[Shadow]: shadow reference combinator should be css function.
Status: RESOLVED FIXED
Product: WebAppsWG
Classification: Unclassified
Component: Component Model
unspecified
PC All
: P2 normal
: ---
Assigned To: Dimitri Glazkov
public-webapps-bugzilla
:
Depends on:
Blocks: 15480
  Show dependency treegraph
 
Reported: 2012-10-24 03:35 UTC by Takashi Sakamoto
Modified: 2013-05-14 17:12 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Takashi Sakamoto 2012-10-24 03:35:02 UTC
I think, /select/ is a little confusing for web developers. It would be better to use css function instead, e.g.
- distributed-into(), or
- selected-by()

I will write the reason why I suggest css function.
Current shadow dom spec says, 

- The combinator value must be select
- The first compound selector of the combinator must match an insertion point
- The second compound selector must match an element, distributed to this insertion point

Its example is .some-insertion-point /select/ div.special.

However, any element can have "select". For example, users can write '<div  class="some-insertion-point" select="...">'.

So it is difficult to know whether /select/ is just reference combinator or shadow reference combinator.

For example,
<div class="shadow-host">
   <#shadow-root>
      <style>
      .some-insertion-point /select/ div.special { color: red; }
      </style>
      <div class=".some-insertion-point" select="#B">
      <content class=".some-insertion-point">
      <div id="B">This text is red?</div>
   </#shadow-root>
   <div class="special">This text should be red!</div>
</div>

The ".some-insertion-point /select/ div.special { color: red; }" should be applied to distributed node or just div in shadow dom subtree? Both?

The most difficult thing is that we cannot decide whether ".some-insertion-point" points really insertion points or not when parsing the rule.

So by using css function, we can write:
- div.special:distributed-into('.some-insertion-point') { color: red; }, or
- div.special:selected-by('.some-insertion-point') { color: red; }

This is very easy to know that the style should be applied to distributed nodes.

What do you think about this?
Comment 1 Dimitri Glazkov 2012-10-24 03:57:37 UTC
(In reply to comment #0)
> I think, /select/ is a little confusing for web developers. It would be
> better to use css function instead, e.g.
> - distributed-into(), or
> - selected-by()
> 
> I will write the reason why I suggest css function.
> Current shadow dom spec says, 
> 
> - The combinator value must be select
> - The first compound selector of the combinator must match an insertion point
> - The second compound selector must match an element, distributed to this
> insertion point
> 
> Its example is .some-insertion-point /select/ div.special.
> 
> However, any element can have "select". For example, users can write '<div 
> class="some-insertion-point" select="...">'.
> 
> So it is difficult to know whether /select/ is just reference combinator or
> shadow reference combinator.

"select" is not a valid attribute for a "div".  I don't see what is difficult.

> 
> For example,
> <div class="shadow-host">
>    <#shadow-root>
>       <style>
>       .some-insertion-point /select/ div.special { color: red; }
>       </style>
>       <div class=".some-insertion-point" select="#B">
>       <content class=".some-insertion-point">
>       <div id="B">This text is red?</div>
>    </#shadow-root>
>    <div class="special">This text should be red!</div>
> </div>
> 
> The ".some-insertion-point /select/ div.special { color: red; }" should be
> applied to distributed node or just div in shadow dom subtree? Both?
> 
> The most difficult thing is that we cannot decide whether
> ".some-insertion-point" points really insertion points or not when parsing
> the rule.
> 
> So by using css function, we can write:
> - div.special:distributed-into('.some-insertion-point') { color: red; }, or
> - div.special:selected-by('.some-insertion-point') { color: red; }
> 
> This is very easy to know that the style should be applied to distributed
> nodes.
> 
> What do you think about this?

I think the example you brought up is rather weak. I honestly don't see a problem with this. Thus, in my opinion, this is bike-shedding.

Also, you need to argue with Tab and the CSS WG about this. He is the one who recommended to use reference combinator.

Also, here's more information on the reference combinator: http://www.w3.org/TR/selectors4/#idref-combinators
Comment 2 Takashi Sakamoto 2012-10-24 04:31:10 UTC
(In reply to comment #1)
> (In reply to comment #0)
> > I think, /select/ is a little confusing for web developers. It would be
> > better to use css function instead, e.g.
> > - distributed-into(), or
> > - selected-by()
> > 
> > I will write the reason why I suggest css function.
> > Current shadow dom spec says, 
> > 
> > - The combinator value must be select
> > - The first compound selector of the combinator must match an insertion point
> > - The second compound selector must match an element, distributed to this
> > insertion point
> > 
> > Its example is .some-insertion-point /select/ div.special.
> > 
> > However, any element can have "select". For example, users can write '<div 
> > class="some-insertion-point" select="...">'.
> > 
> > So it is difficult to know whether /select/ is just reference combinator or
> > shadow reference combinator.
> 
> "select" is not a valid attribute for a "div".  I don't see what is
> difficult.

Would you mean whether reference combinator works or not depends on whether the attribute is valid or not?

I looked at the reference combinator's spec and couldn't found that attribute selector only works for valid attribute or something. I could find the following:

"attribute selectors must be considered to match an element if that element has an attribute that matches the attribute represented by the attribute selector."

> > For example,
> > <div class="shadow-host">
> >    <#shadow-root>
> >       <style>
> >       .some-insertion-point /select/ div.special { color: red; }
> >       </style>
> >       <div class=".some-insertion-point" select="#B">
> >       <content class=".some-insertion-point">
> >       <div id="B">This text is red?</div>
> >    </#shadow-root>
> >    <div class="special">This text should be red!</div>
> > </div>
> > 
> > The ".some-insertion-point /select/ div.special { color: red; }" should be
> > applied to distributed node or just div in shadow dom subtree? Both?
> > 
> > The most difficult thing is that we cannot decide whether
> > ".some-insertion-point" points really insertion points or not when parsing
> > the rule.
> > 
> > So by using css function, we can write:
> > - div.special:distributed-into('.some-insertion-point') { color: red; }, or
> > - div.special:selected-by('.some-insertion-point') { color: red; }
> > 
> > This is very easy to know that the style should be applied to distributed
> > nodes.
> > 
> > What do you think about this?
> 
> I think the example you brought up is rather weak. I honestly don't see a
> problem with this. Thus, in my opinion, this is bike-shedding.

If shadow reference combinator doesn't cross any treescope boundaries, I agree with you that this is not a problem.
However, the current spec says that sometimes reference combinator can cross treescope boundary. I feel that it might be inconsistent.

> Also, you need to argue with Tab and the CSS WG about this. He is the one
> who recommended to use reference combinator.
> 
> Also, here's more information on the reference combinator:
> http://www.w3.org/TR/selectors4/#idref-combinators
Comment 3 Shinya Kawanaka 2012-10-24 05:10:19 UTC
I agree with Sakamoto-san. I'm afraid that ShadowDOM's spec conflicts the Selectors spec.

Let me add another example. In the following example, 'content /select/ div' will match div#div according to Selector Level 4 spec. It seems this conflicts the current Shadow DOM spec.

Correct me if I'm wrong. I'm not 100% sure...

<style>
content /select/ div {
    color red;
}
</style>
<content select="div"></content>
<div id="div">This is red according to Selector Level 4</div>
Comment 4 Takashi Sakamoto 2012-10-24 06:15:17 UTC
I read reference combinator again.
So I think, I probably misunderstood "host language" and "reference".

(1) reference combinator especially depends on the first value.
(2) the attribute is solved in the context of the first value.

So if "content /select/ div.special" is given, since currently "select" attribute is used by only <content>, we can know only <content> has valid host language / valid reference about /select/.

From the viewpoint of implementation, we should know whether some given attribute is valid for some element. RuleSets are registered with TREESCOPE according to the context.

I think, this might be bike-shedding. But I found one implementation problem, fallback case - idref. 

If ".some /select/ div.special" is given in some shadow root stylesheet and "<div class=some select=#a>" and "<div class=special id=a>" exists in the shadow root's subtree,

<#shadow-root>
   <style>
   .some /select/ div.special { color: red; }
   </style>
   <div class=some select=#a></div>
   <div class=special></div>
</#shadow-root>

Since the "<div class=some>" has no host languages and no valid context for "select", we have to see idref as fallback. The spec says:

"Unless the host language defines a different syntax for expressing this relationship, this relationship is considered to exist if the value of the specified attribute on the first element is an IDREF or an ID selector referencing the second element. "

But web developers will not probably add "select" to other elements except "<content>". So we would not see such fallback case...

Best regards,
Takashi Sakamoto

(In reply to comment #2)
> (In reply to comment #1)
> > (In reply to comment #0)
> > > I think, /select/ is a little confusing for web developers. It would be
> > > better to use css function instead, e.g.
> > > - distributed-into(), or
> > > - selected-by()
> > > 
> > > I will write the reason why I suggest css function.
> > > Current shadow dom spec says, 
> > > 
> > > - The combinator value must be select
> > > - The first compound selector of the combinator must match an insertion point
> > > - The second compound selector must match an element, distributed to this
> > > insertion point
> > > 
> > > Its example is .some-insertion-point /select/ div.special.
> > > 
> > > However, any element can have "select". For example, users can write '<div 
> > > class="some-insertion-point" select="...">'.
> > > 
> > > So it is difficult to know whether /select/ is just reference combinator or
> > > shadow reference combinator.
> > 
> > "select" is not a valid attribute for a "div".  I don't see what is
> > difficult.
> 
> Would you mean whether reference combinator works or not depends on whether
> the attribute is valid or not?
> 
> I looked at the reference combinator's spec and couldn't found that
> attribute selector only works for valid attribute or something. I could find
> the following:
> 
> "attribute selectors must be considered to match an element if that element
> has an attribute that matches the attribute represented by the attribute
> selector."
> 
> > > For example,
> > > <div class="shadow-host">
> > >    <#shadow-root>
> > >       <style>
> > >       .some-insertion-point /select/ div.special { color: red; }
> > >       </style>
> > >       <div class=".some-insertion-point" select="#B">
> > >       <content class=".some-insertion-point">
> > >       <div id="B">This text is red?</div>
> > >    </#shadow-root>
> > >    <div class="special">This text should be red!</div>
> > > </div>
> > > 
> > > The ".some-insertion-point /select/ div.special { color: red; }" should be
> > > applied to distributed node or just div in shadow dom subtree? Both?
> > > 
> > > The most difficult thing is that we cannot decide whether
> > > ".some-insertion-point" points really insertion points or not when parsing
> > > the rule.
> > > 
> > > So by using css function, we can write:
> > > - div.special:distributed-into('.some-insertion-point') { color: red; }, or
> > > - div.special:selected-by('.some-insertion-point') { color: red; }
> > > 
> > > This is very easy to know that the style should be applied to distributed
> > > nodes.
> > > 
> > > What do you think about this?
> > 
> > I think the example you brought up is rather weak. I honestly don't see a
> > problem with this. Thus, in my opinion, this is bike-shedding.
> 
> If shadow reference combinator doesn't cross any treescope boundaries, I
> agree with you that this is not a problem.
> However, the current spec says that sometimes reference combinator can cross
> treescope boundary. I feel that it might be inconsistent.
> 
> > Also, you need to argue with Tab and the CSS WG about this. He is the one
> > who recommended to use reference combinator.
> > 
> > Also, here's more information on the reference combinator:
> > http://www.w3.org/TR/selectors4/#idref-combinators
Comment 5 Dimitri Glazkov 2012-10-24 15:29:02 UTC
(In reply to comment #4)
> I read reference combinator again.
> So I think, I probably misunderstood "host language" and "reference".
> 
> (1) reference combinator especially depends on the first value.
> (2) the attribute is solved in the context of the first value.
> 
> So if "content /select/ div.special" is given, since currently "select"
> attribute is used by only <content>, we can know only <content> has valid
> host language / valid reference about /select/.
> 
> From the viewpoint of implementation, we should know whether some given
> attribute is valid for some element. RuleSets are registered with TREESCOPE
> according to the context.
> 
> I think, this might be bike-shedding. But I found one implementation
> problem, fallback case - idref. 
> 
> If ".some /select/ div.special" is given in some shadow root stylesheet and
> "<div class=some select=#a>" and "<div class=special id=a>" exists in the
> shadow root's subtree,
> 
> <#shadow-root>
>    <style>
>    .some /select/ div.special { color: red; }
>    </style>
>    <div class=some select=#a></div>
>    <div class=special></div>
> </#shadow-root>
> 
> Since the "<div class=some>" has no host languages and no valid context for
> "select", we have to see idref as fallback. The spec says:
> 
> "Unless the host language defines a different syntax for expressing this
> relationship, this relationship is considered to exist if the value of the
> specified attribute on the first element is an IDREF or an ID selector
> referencing the second element. "

This is not how interpret the spec. We (the host language) define /select/ as something that _only_ applies to <content> element and matches results of the distribution.

However, I think the selectors4 spec could use some finer language here. I'll file a bug.
 
> But web developers will not probably add "select" to other elements except
> "<content>". So we would not see such fallback case...
Comment 6 Dimitri Glazkov 2012-10-24 15:30:06 UTC
^^^ Fantasai, Tab -- what do you think?
Comment 7 Dimitri Glazkov 2012-10-31 20:34:48 UTC
We're going to keep going ahead with the reference combinator unless CSS WG changes their mind.
Comment 8 fantasai 2012-11-26 19:46:32 UTC
I don't think the CSSWG has even considered the use of reference combinators for shadow dom. It's never come up in my recollection, and I'm the editor of the Selectors 4 spec. So I think this issue is still open for consideration.
Comment 9 Dimitri Glazkov 2012-11-26 21:46:15 UTC
(In reply to comment #8)
> I don't think the CSSWG has even considered the use of reference combinators
> for shadow dom. It's never come up in my recollection, and I'm the editor of
> the Selectors 4 spec. So I think this issue is still open for consideration.

Okay. Can you guys consider it? I was mostly operating under Tab's guidance.
Comment 10 Dimitri Glazkov 2012-11-28 23:30:47 UTC
Relevant discussion here: http://lists.w3.org/Archives/Public/www-style/2012Nov/0428.html
Comment 11 Dimitri Glazkov 2012-12-06 21:14:54 UTC
(In reply to comment #10)
> Relevant discussion here:
> http://lists.w3.org/Archives/Public/www-style/2012Nov/0428.html

Tab, fantasai, can you guys summarize results of your discussion on this thread? Would be nice to have something to hang a hat on :)
Comment 12 Tab Atkins Jr. 2012-12-07 16:54:21 UTC
(In reply to comment #11)
> (In reply to comment #10)
> > Relevant discussion here:
> > http://lists.w3.org/Archives/Public/www-style/2012Nov/0428.html
> 
> Tab, fantasai, can you guys summarize results of your discussion on this
> thread? Would be nice to have something to hang a hat on :)

Copy/paste from the internal email discussing this:

Okay, first, rationalization.  fantasai pointed out a legitimate
criticism with the use of the /select/ combinator.  Currently,
evaluating a selector left-to-right or right-to-left are both stable -
they change in continuous (for a reasonable definition of "continuous"
as applied to discrete mutations of the element set) ways.  In
particular, if you start with a selector like "A", then add more to
the left of it, like "B A", the latter's result is guaranteed to
contain only elements matched in the former's result - that is, adding
to the left purely *filters* the result, never changes it.

Our use of /select/ changes this.  Going from "A" to "B /select/ A"
fundamentally changes the set of matched elements; in fact, due to our
definition, you're guaranteed that *none* of the elements match
between the two sets.  This is weird.

Currently, the only thing we have remotely like this is
pseudo-elements: a selector like "*" matches all elements *except for*
the pseudo-elements in the tree, which you have to specifically
address with "*::before" or the like.  So, we can build on this.

Given the existing plans for a ::shadow() pseudoelement to let a
light-dom stylesheet target explicitly-surfaced shadow-dom elements,
we can create a parallel ::light() pseudoelement that does the
reverse.  ::light() pseudoelements only exist on <content> elements
(and <shadow>? I forget), and take a selector, which is applied
against the set of elements redistributed by the content element.
Note that this selector is applied like normal for selectors, not just
against children, so that something like "content::light(:link)" will
grab *all* the links in the redistributed nodes, even if they're not
children.  To target just children, use a scoped selector or a
relative selector, like "content::light(> :link)".

This preserves some of the implicit invariants of CSS selectors,
without removing any power - it's just a bikeshed of the /select/
syntax.
Comment 13 Tab Atkins Jr. 2012-12-07 16:55:40 UTC
(In reply to comment #12)
> Given the existing plans for a ::shadow() pseudoelement to let a
> light-dom stylesheet target explicitly-surfaced shadow-dom elements,

It has since been pointed out that we switched syntax away from ::shadow() and toward just allowing x-prefixed pseudo-elements.  This doesn't impact our suggestion - the naming similarity was a plus, but not the primary reason to make the syntax change.
Comment 14 Dimitri Glazkov 2012-12-07 18:15:20 UTC
(In reply to comment #13)
> (In reply to comment #12)
> > Given the existing plans for a ::shadow() pseudoelement to let a
> > light-dom stylesheet target explicitly-surfaced shadow-dom elements,
> 
> It has since been pointed out that we switched syntax away from ::shadow()
> and toward just allowing x-prefixed pseudo-elements.  This doesn't impact
> our suggestion - the naming similarity was a plus, but not the primary
> reason to make the syntax change.

Thanks, Tab! I am going to change the spec accordingly.
Comment 15 Dimitri Glazkov 2013-05-14 17:12:30 UTC
This has been fixed a while back.