Re: Shadow DOM Encapsulation

On Feb 6, 2014, at 7:02 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:

> On Thu, Feb 6, 2014 at 6:54 PM, Peter Linss <peter.linss@hp.com> wrote:
>> On Feb 6, 2014, at 5:23 PM, Tab Atkins Jr. <jackalmage@gmail.com>
>> wrote:
>>> Note also that this isn't quite as easy as it sounds.  When you expose
>>> things, where are they relative to everything else?
>> 
>> They are in the same place as they are defined, the structure is preserved for everything exported.
>> 
>> For example, given the shadow DOM:
>> <component>
>>  <part-one export>
>>    <sub-part-one />
>>  </part-one>
>>  <part-two>
>>    <sub-part-two export>
>>      <sub-sub-part-two />
>>    </sub-part-two>
>>  </part-two>
>> </component>
>> 
>> You'd see it as though it were defined as:
>> <part-one>
>>  <sub-part-one />
>> </part-one>
>> <sub-part-two>
>>  <sub-sub-part-two />
>> </sub-part-two>
> 
> Oof, so then "part-one + sub-part-two" would actually match?  That's
> seems super weird to me.

In that obviously contrived example, yes, (although, for consistency, it would actually be "::part-one + ::sub-part-two") because that's the structure that's being exported, the <part-two> element doesn't exist when seen from the outside.

This is actually a feature. For example, what if the component was initially shipped without the <part-two> element? It can be added, but not exported, and not break existing stylesheets because it doesn't affect the structure exposed to the selectors.

> 
>>>> The other part of my proposal was to simply use pseudo-elements to directly select the exported component pieces by name, and to relax the restrictions on pseudo-element selectors to allow pseudo-classes, attribute selectors, and descendants (with combinators).
>>>> 
>>>> With those restrictions relaxed, it's not necessary to flatten the pseudo-element space, so the internal structure of exported pieces could be maintained.
>>>> 
>>>> So a piece could be selected as:
>>>> component ::piece { ... }
>>>> it's child could be selected as:
>>>> component ::piece ::child-peice { ... }
>>>> etc, with the full expressiveness of selectors. This addresses your points #2 & #3.
>>> 
>>> Well, no, not quite.  You're using spaces where they're not allowing.
>>> It'd have to be at least:
>>> 
>>> component::piece::child-piece
>>> 
>>> Or something else for the child-piece part that allowed combinators.
>> 
>> No, I really meant spaces, i.e. descendant combinators (see "loosening restrictions on use of pseudo-element selectors" in a previous message). You could use other combinators as needed to address specific nodes. There's no magic pseudo-element or combinator needed to pierce the shadow layer, the shadow component simply exports its parts as a structure of pseudo-elements.
> 
> That completely changes the meaning of pseudo-elements, though.
> That's what I'm trying to allude to.

No, it doesn't. ::before and ::after are kind of weird in that they generate boxes that are actually siblings. "component::piece" would still mean the "::piece" pseudo-element of the "component", which wouldn't match anything (unless we define a ::piece pseudo-element in CSS), "component ::piece" means the "::piece" inside the "component".

(although, as I alluded to below, it could also make sense, except for ::before and ::after to treat "component::piece" as equivalent to "component > ::piece")

> 
> "component ::before" explicitly means the same thing as "component
> *::before".  Similarly, "component ::piece" would mean the same thing
> as "component *::piece", which is definitely not what you're
> intending.  

It _is_ what I'm intending.

> This is part of the definition of pseudo-element syntax; I
> don't think it's reasonable to change it.

Not proposing to change it. I'm only proposing to relax the restrictions on it's use. So:
component ::part-one:hover ::sub-part-one[foo=bar]:nth-child(even) { ... }
would be valid.

(as would "p::first-line span { color: blue }", but that's a horse of another color...)

> 
>> The only interesting thing here is that there's an implied > between all pseudo-elements and the rest of the selector, so:
>> p::first-line
>> is morally equivalent to:
>> p > ::first-line
>> That's the way Gecko at-least used to do it internally...
>> 
>> We did this back in '98 or so in Gecko when building form controls out of "anonymous" boxes and hidden dom nodes (for content and event handling), essentially the 16 year-old precursor to today's shadow-dom. The interesting "anonymous" boxes each had a pseudo-element name and you could simply style them with normal CSS selectors.
> 
> Are you implying then that the ::piece thing is *actually* a child (or
> descendant) of the element in the normal way we use the term, but is
> only matchable via its special name?

Yes.

>  That's pretty weird, I think.

Why? The "::piece" thing is just that, a "thing", it's not a normal DOM element so shouldn't be addressable via element selectors, but being a shadow-dom node it's "*kind of* an element", e.g. a "pseudo-element"... Seems pretty straight-forward to me.

> 
>> I accept the symmetry argument between the structure exposed to selectors and the JS APIs, but this isn't the right place to debate the JS APIs.
> 
> Right, but given the JS APIs, it's the right place to make arguments
> about matching them. ^_^

Yes, and I'm all for the consistency, I'm just not convinced the JS APIs are correct and I didn't want to open that debate on www-style.

My position is that we should decide the correct model first, then have both the selectors and the JS API match the model. But that's a different thread (and probably a different forum), I was trying to keep this thread focused on the selector issue.

Peter

Received on Friday, 7 February 2014 04:26:57 UTC