From 8f781254826d263e8fb8b67bc8824510c9736c15 Mon Sep 17 00:00:00 2001 From: Ido Rosenthal Date: Wed, 27 Sep 2023 13:25:24 +0300 Subject: [PATCH] fix: initial mapped selector infer with exp selector inference --- packages/core/src/stylable-transformer.ts | 21 +++++++++++++-- .../test/features/css-pseudo-element.spec.ts | 26 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/packages/core/src/stylable-transformer.ts b/packages/core/src/stylable-transformer.ts index 847651e18..f21e1b1f1 100644 --- a/packages/core/src/stylable-transformer.ts +++ b/packages/core/src/stylable-transformer.ts @@ -505,7 +505,7 @@ export class StylableTransformer { // reset current anchor for all except last selector context.inferredSelector = new InferredSelector( this, - context.inferredSelectorContext + context.inferredSelectorStart ); } } @@ -680,7 +680,10 @@ export class InferredSelector { constructor( private api: Pick< StylableTransformer, - 'getResolvedSymbols' | 'createSelectorContext' | 'scopeSelectorAst' + | 'getResolvedSymbols' + | 'createSelectorContext' + | 'scopeSelectorAst' + | 'createInferredSelector' >, resolve?: InferredResolve[] | InferredSelector ) { @@ -886,6 +889,17 @@ export class InferredSelector { selectorStr ); internalContext.isStandaloneSelector = isFirstInSelector; + if (!structureMode && experimentalSelectorInference) { + internalContext.inferredSelectorStart.set( + this.api.createInferredSelector(meta, { + name: 'root', + type: 'class', + }) + ); + internalContext.inferredSelector.set( + internalContext.inferredSelectorStart + ); + } const customAstSelectors = this.api.scopeSelectorAst(internalContext); const inferred = customAstSelectors.length === 1 || experimentalSelectorInference @@ -1020,6 +1034,8 @@ export class ScopeContext { public lastInferredSelectorNode: SelectorNode | undefined; // selector is not a continuation of another selector public isStandaloneSelector = true; + // used as initial selector + public inferredSelectorStart: InferredSelector; // used as initial selector or after combinators public inferredSelectorContext: InferredSelector; // used for nesting selector @@ -1072,6 +1088,7 @@ export class ScopeContext { // set selector data this.selectorStr = selectorStr || stringifySelector(selectorAst); this.inferredSelectorContext = new InferredSelector(this.transformer, inferredContext); + this.inferredSelectorStart = new InferredSelector(this.transformer, inferredContext); this.inferredSelectorNest = inferredSelectorNest || this.inferredSelectorContext.clone(); this.inferredSelector = new InferredSelector( this.transformer, diff --git a/packages/core/test/features/css-pseudo-element.spec.ts b/packages/core/test/features/css-pseudo-element.spec.ts index 9dedaed3b..85a499440 100644 --- a/packages/core/test/features/css-pseudo-element.spec.ts +++ b/packages/core/test/features/css-pseudo-element.spec.ts @@ -324,6 +324,32 @@ describe('features/css-pseudo-element', () => { } ); }); + it('should transform custom element with multiple selector inside nested pseudo-classes', () => { + // ToDo: with experimentalSelectorInference=true, the nested selector will be transformed inlined + testStylableCore( + ` + @custom-selector :--part .partA, .partB; + @custom-selector :--nestedPart ::part, .partC; + + /* @rule(1 level) .entry__root:not(.entry__partA,.entry__partB) */ + .root:not(::part) {} + + /* + notice: partB is pushed at the end because of how custom selectors are + processed atm. + + @rule(2 levels) .entry__root:not(.entry__partA,.entry__partC,.entry__partB) + */ + .root:not(::nestedPart) {} + + /* @rule(custom-selector syntax) + .entry__root:not(.entry__partA, .entry__partB) + */ + .root:not(:--part) {} + `, + { stylableConfig: { experimentalSelectorInference: true } } + ); + }); }); }); describe('st-import', () => {