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

fix(core): scope nested global selector issues #2925

Merged
merged 2 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions packages/core/src/helpers/selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,17 +197,20 @@ export function scopeNestedSelector(
},
{ ignoreList: [`selector`] }
);
const parentRef = first.type === `nesting`;
const globalSelector = first.type === `pseudo_class` && first.value === `global`;
const startWithScoping = rootScopeLevel
? scopeAst.nodes.every((node, i) => {
return matchTypeAndValue(node, outputAst.nodes[i]);
})
: false;
let nestedMixRoot = false;
// merge scope flags
const nestStartWithNesting = first.type === `nesting`;
const nestedStartWithGlobal =
rootScopeLevel && first.type === `pseudo_class` && first.value === `global`;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the change is here - the addition of rootScopeLevel && to limit the behavior of not prepending the parent scope for root mixins

const nestStartWithScope =
rootScopeLevel &&
scopeAst.nodes.every((node, i) => {
return matchTypeAndValue(node, outputAst.nodes[i]);
});
let scopeAlreadyMerged = false;
// merge scope into selector
walkSelector(outputAst, (node, i, nodes) => {
if (isAnchor(node)) {
nestedMixRoot = true;
scopeAlreadyMerged = true;
nodes.splice(i, 1, {
type: `selector`,
nodes: cloneDeep(scopeAst.nodes as SelectorNode[]),
Expand All @@ -218,7 +221,14 @@ export function scopeNestedSelector(
});
}
});
if (first && !parentRef && !startWithScoping && !globalSelector && !nestedMixRoot) {
// merge scope at the beginning of selector
if (
first &&
!nestStartWithNesting &&
!nestStartWithScope &&
!nestedStartWithGlobal &&
!scopeAlreadyMerged
) {
outputAst.nodes.unshift(...cloneDeep(scopeAst.nodes as SelectorNode[]), {
type: `combinator`,
combinator: `space`,
Expand Down
21 changes: 21 additions & 0 deletions packages/core/test/features/css-class.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
testStylableCore,
shouldReportNoDiagnostics,
diagnosticBankReportToStrings,
deindent,
} from '@stylable/core-test-kit';
import { expect } from 'chai';
import type * as postcss from 'postcss';
Expand Down Expand Up @@ -1019,6 +1020,26 @@ describe(`features/css-class`, () => {

shouldReportNoDiagnostics(meta);
});
it('should nest -st-global classes', () => {
const { sheets } = testStylableCore(`
.global {
-st-global: "body";
}
@st-scope html {
.global {}
}
`);
const { meta } = sheets['/entry.st.css'];

shouldReportNoDiagnostics(meta);
expect(deindent(meta.targetAst!.toString())).to.eql(
deindent(`
body {
}
html body {}
`)
);
});
});
describe(`css-pseudo-element`, () => {
// ToDo: move to css-pseudo-element spec once feature is created
Expand Down
3 changes: 1 addition & 2 deletions packages/core/test/features/st-mixin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1271,7 +1271,6 @@ describe(`features/st-mixin`, () => {
shouldReportNoDiagnostics(meta);
});
it(`should append mixin rules`, () => {
// ToDo: fix ":global(.part)" to transform with mixin root
const { sheets } = testStylableCore({
'/mixin.js': `
module.exports = function() {
Expand Down Expand Up @@ -1302,7 +1301,7 @@ describe(`features/st-mixin`, () => {
@rule[1] .entry__root Element { d: Capital element }
@rule[2] .entry__root element { d: lowercase element }
@rule[3] .entry__root .entry__part { d: class namespaced in context }
@rule[4] .part { d: global class }
@rule[4] .entry__root .part { d: global class }
@rule[5] .entry__root .entry__x, .entry__root .entry__y { d: multiple selectors }
*/
.root {
Expand Down