Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User definable custom selectors #92

Closed
facelessuser opened this issue Jan 19, 2019 · 5 comments
Closed

User definable custom selectors #92

facelessuser opened this issue Jan 19, 2019 · 5 comments
Labels
C: API Related to the API. C: css-custom CSS custom selectors. P: maybe Pending approval of low priority request. T: feature Feature.

Comments

@facelessuser
Copy link
Owner

The idea of allowing user definable custom selectors is a cool idea that is currently in draft: https://drafts.csswg.org/css-extensions/#typedef-custom-selector.

The idea is essentially to allow create an custom pseudo-class as an alias for a more complex expression.

@custom-selector :--heading h1, h2, h3, h4, h5, h6;

:--heading { /* styles for all headings */ }
:--heading + p { /* more styles */ }

There seems to be some open issues for a lot more complexity than what is shown here, but I think it may be reasonable to to allow stuff like this, and then a user could construct aliases for whatever they would like. That way we don't ever actually need to support such things directly ourselves.

@facelessuser facelessuser added T: feature Feature. C: API Related to the API. selectors C: css-custom CSS custom selectors. P: maybe Pending approval of low priority request. labels Jan 19, 2019
@facelessuser
Copy link
Owner Author

This is actually really easy for us to implement, as this is how we add support for some of our internal selectors. The thing that gives me pause is the fact that there is no indication that this is the official direction that CSS will official take. Will they require -- or will they not? If hate to implement something just to find out it's wrong. There are other proposals in the wild that all sounds to solve the same thing. I just need them to pick one. Something to think about...

@facelessuser
Copy link
Owner Author

Looking at the W3C draft spec vs the csswg draft, there is one difference. <ident-token> in the W3C spec, which is much older, it references that an <ident-token> cannot start with --, but in the csswg (Nov 2017) <ident-token> are allowed. We currently restrict -- which is aligned with the W3c (2014) spec. We probably need to update our pattern.

We could implement this and allow custom to start with -- or without. We don't have to follow the custom spec so rigidly, especially since it isn't official, and my not ever be official, we could just do whatever we want for this.

One thing that seems odd in the proposal is that it allows arguments, but each argument is an <ident-token>. They show that these parameters could be fed into other pseudo classes like :nth-child except you can never feed in something like -n+3 as + would invalidate the <ident-token>. So it is currently flawed for anything that could allow arguments. This may be one of the reasons why it still isn't official. But we don't have to implement arguments starting out.

@facelessuser
Copy link
Owner Author

So thinking about this more, I guess not being able to send in -n+3 is fine. I guess this is equivalent to the fact you can't send in div+p either, you could send in :--custom(div, p) and then internally set $sel1 + $sel2).

What I don't like is the $rest.

@custom-selector $rest:--n-siblings($n, $sel) {...}

Let's say we had 2 custom selectors, each that used $rest:

p:--custom1:custom2

This kind of becomes a recursion problem. :--custom1 must use $rest which is equivalent to p:--custom2 and :--custom2 must use $rest which would be equivalent to p:--custom2...turtles all the way down.

I could reasonably see implementing something like:

@custom-selector :--n-siblings($n, $sel)

But feel that allowing $rest in the following could cause difficulties:

@custom-selector $rest:--n-siblings($n, $sel)

I can see why this is still just a talking point, and not something official or fully implemented. I've only seen something like postcss implement this and it doesn't seem to implement the arguments at all.

I'm thinking we probably wouldn't implement arguments right away either. We may not even reference the spec at all and simply say call it something like "CSS aliases" and simply define our own rules. Then we could say you don't have require :-- in front. We would just compare whatever alias provided against our built-in selectors and the already registered aliases provided before.

@facelessuser
Copy link
Owner Author

Another question is do we require passing in aliases? Or do we allow the create of a custom parser:

import soupsieve as sv

parser = sv.custom_parser()
parser.set_namespaces({"ns": "http:/ns.com"})
parser.set_aliases({':header': 'h1, h2, h3, h4, h5, h6'})
parser.select(':header.class', soup)

There's nothing stopping us from allowing both though.

import soupsieve as sv

ns = {"ns": "http:/ns.com"}
aliases = {':header': 'h1, h2, h3, h4, h5, h6'}

sv.select(':header.class1', soup, namespaces=ns, aliases=aliases)

@facelessuser
Copy link
Owner Author

Experimental branch here: https://github.com/facelessuser/soupsieve/tree/custom-selectors.

Implements custom aliases by creating an Aliases object and then using it to register aliases. The Alias object is then fed into select, match, filter, closest, and compile functions.

There is no restriction requiring :--. It will check to make sure the pseudo-class name doesn't conflict with built-in. We may still require :-- though. If we add new built-in methods, we could break scripts, and we really don't want to break scripts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: API Related to the API. C: css-custom CSS custom selectors. P: maybe Pending approval of low priority request. T: feature Feature.
Projects
None yet
Development

No branches or pull requests

1 participant