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

[Question] Is it possible to get the full selector for a nested rule? #210

Open
jgerigmeyer opened this issue Dec 6, 2022 · 3 comments
Open

Comments

@jgerigmeyer
Copy link

With the recently-added support for CSS Nesting, is there a good way to get the full selector value for a given nested rule -- that is, including any ancestor rule preludes? For example, given the following CSS:

.one {
  color: red;

  &.two {
    color: green;
  }
}

From the context of the color: green declaration, ideally I want to get the full selector for that declaration (.one.two). rule.prelude returns &.two -- is there a convenient way to find ancestor/parent selectors, or better yet the full "un-nested" selector/list raw value?

@lahmatiy
Copy link
Member

Well, AST nodes has no context, so what you want can't be done without giving a context for a selector/rule... Anyway, truly speaking, I didn't think yet about such a functionality like unrolling a nested selectors. I have no a strong position here, should it be a part of CSSTree or not. The CSS Nesting spec is not stable yet, so I think it's too yearly to implement it. For instance, leading & is not a mandatory thing anymore and nested selectors can be started with any combinator now. So, it's not only about replacing & for a parent selector but also about a substitution before a leading combinator etc. For sure, support for CSS Nesting will be changed in next releases due to changes in the spec. And I will think more about unrolling a nested selectors as well.

@jgerigmeyer
Copy link
Author

@lahmatiy Thanks for your response! I agree that this isn't urgent, since the spec isn't stable. But eventually it would be a very helpful feature. Right now I'm using this.rule.prelude in the context of a walk() callback, and I was just noticing that this approach will no longer work once nesting is used.

@lahmatiy
Copy link
Member

I see. Well, you need a stack of rules (or all nodes, depends on your task) for your purposes. walk() has no such a feature for now, but you can implement it by yourself, for instance:

const rulesStack = [];
const produceAbsoluteSelector = (prelude, stack) => {
    // replace & for a rule selectors from stack here
}

walk(ast, {
    enter(node) {
        if (node.type === 'Rule') {
            const selector = produceAbsoluteSelector(node.prelude, rulesStack);
            // do something with a selector

            rulesStack.push(node);
        }
    },
    leave(node) {
        if (node.type === 'Rule') {
            rulesStack.pop();
        }
    }
});

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

No branches or pull requests

2 participants