Skip to content
This repository has been archived by the owner on Feb 23, 2022. It is now read-only.

Allow ::slotted(selectors) #113

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

JamesXNelson
Copy link

::slotted selectors are necessary for ShadowDOM V1

It may make sense to allow ::anyname(selectors) instead of cherry-picking individual named selectors, but I do not know the code well enough to make such a judgement.

"If" tests are desired, let me know where to add them, and I can add that to PR.

@iflan
Copy link
Member

iflan commented Mar 1, 2017

Hi James,

Looking at ::slotted, it seems to have pretty specific semantics. Generally, from what I see, it's pretty hard to predict what should go in a pseudo element, so I don't think your generic proposal is a good fit yet.

It looks like Shadow DOM is also introducing a new selector, >>>, the shadow-piercing descendant combinator.

As far as the PR goes, I will need tests for it. I don't have time to do that in depth tonight, but I'll try to get to it soon.

Ian

@iflan
Copy link
Member

iflan commented Mar 1, 2017

(And by "do that", I meant "review the code".)

@JamesXNelson
Copy link
Author

Heya.

As I continued to work with shadow DOM, I also needed :host(selectors > here), and :host-context(selectors > here) as well.

If you have any existing css infrastructure testing, I would be happy to put together an automated test. I see GssParserTest is probably good enough for this?

I think there is also support for ::slotted(div)::before as well, so it might start getting a touch more complicated if we want to hit the moving target that is shadow dom css. Let me know how I can be of assistance to get some (useful) code merged!

@JamesXNelson
Copy link
Author

JamesXNelson commented Mar 5, 2017

Note, the current working draft says that >>> combinators will only apply to querySelector(), and not css styling.

So, unless/until that changes, the most you'd want to do is issue a warning to developers that attempting to use this in a stylesheet will not work.

Also note, the draft shows ::slotted as containing complex selectors, but the discussion it is based on in the web component spec authors' github repo, the consensus was to support simple selectors only, as ::slotted(div.foo) with ::slotted(.foo)::before also supported; the idea being that you can only match the top-level children of a slot, so no combinator would ever make sense.

I made the PR match the recommendations I was able to grok from the still evolving spec:

"Note: ::slotted() can only represent the elements assigned to the slot. Slots can also be assigned text nodes, which can’t be selected by ::slotted(). The only way to style assigned text nodes is by styling the slot and relying on inheritance."

If we want to be pedantic, the only usable prefixes of ::slotted is empty ::slotted, slot::slotted or *::slotted; any other combination won't work, because only <slot /> elements can have a slotted pseudo.

Copy link
Member

@iflan iflan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this! I think it looks good, generally, but I have a few comments.

If only simple selectors are allowed, then reusing the code we have for :not(selector), as you have done, seems right to me. :host(selectors > here) and :host-context(...) obviously need a special case, too. It would be great, though, if we could make the tokens "generic" and have just one for functions that take simple selectors and another for functions that take compound selectors.

I don't know if I want to try to enforce things like enforcing the usable prefixes of ::slotted in the grammar. Instead, I think that should be in a compiler pass were we to want it. If we do that, we can also warn about /deep/, which is currently supported.

You don't have to make that change in this PR unless you'd like to.

Also, if >>> isn't supported in rules, then I think I wouldn't even bother mentioning it.

Also, you can add tests here:

https://github.com/google/closure-stylesheets/blob/master/tests/com/google/common/css/compiler/ast/GssParserTest.java

Thanks!

Ian

@@ -707,6 +707,8 @@ PARSER_END(GssParserCC)
// Special handling needed because ':not' takes simple selectors as
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just generalize this to two tokens: SIMPLE_SELECTOR_FUNCTION and SELECTOR_FUNCTION? It seems like a bunch of duplicate code in the pseudo expansion would go away.

Copy link
Author

@JamesXNelson JamesXNelson Mar 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aye. I agree that the duplication here is less than stellar.

However, I think the semantics of :not is slightly different.

:not() takes only a simple selector; one tag name, class name or id. I tested this in browser console, and it did not like any compound selectors ( :not(elementName.className) did not work)

The other three, ::slotted, :host and :host-context all support a compound selector (what simpleSelector() actually matches). ::slotted(div.clazz) is valid here.

I think simpleSelector should be renamed to compoundSelector, and then a new simpleSelector:

 elementName()
 | id()
 | className()
 | pseudo()

I will test tonight that :host-context does not also support combinators.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not supports compounding only through duplication:

div:not(.class1):not(.class2)

}
{
t = <COLON> { beginLocation = this.getLocation(); tokens.add(t); }
( ( t = <IDENTIFIER> { pseudo = t.image; tokens.add(t); } )
|
( // ::slotted( simple_selector )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update the docs above under pseudo.

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that I really want this to be checked in. What's the advantage?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No advantage. It's an intellij project file.
Will remove this file, and perhaps add a .gitignore for it.

@JamesXNelson JamesXNelson force-pushed the allow-slotted-selector branch 2 times, most recently from 943a638 to 4ef475c Compare November 20, 2017 02:02
Unlike ::slotted(), which only allows simple selectors
inside the parens, :host and :host-context allow
complex selectors to be placed inside the parens.
@JamesXNelson
Copy link
Author

Hi @iflan

Sorry I kind of forgot about this pull request.

I updated the comment per your request in the BNF.

I don't think we decided on any naming for splitting up the pseudo definition. I'd be happy to break it up if you decide what you want and let me know. Thanks!

@JamesXNelson
Copy link
Author

I'll add some tests shortly.

@Jauhen
Copy link

Jauhen commented Apr 16, 2018

It would be great if you also add support for ::cue() pseudo selector:
https://w3c.github.io/webvtt/#css-extensions-introduction

@ghost
Copy link

ghost commented May 22, 2020

Custom Elements we're the perfect solution for me, until i couldn't style the children.. I do not get how custom elements are of any use without that.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants