@stylable/core
Advanced tools
Comparing version 5.9.0 to 5.10.0
@@ -33,2 +33,3 @@ "use strict"; | ||
const STSymbol = __importStar(require("./st-symbol")); | ||
const STPart = __importStar(require("./st-part")); | ||
const STCustomState = __importStar(require("./st-custom-state")); | ||
@@ -188,3 +189,4 @@ const resolve_1 = require("../helpers/resolve"); | ||
function addClass(context, name, rule) { | ||
if (!STSymbol.get(context.meta, name, `class`)) { | ||
let symbol = STSymbol.get(context.meta, name, `class`); | ||
if (!symbol) { | ||
let alias = STSymbol.get(context.meta, name); | ||
@@ -194,3 +196,3 @@ if (alias && alias._kind !== 'import') { | ||
} | ||
STSymbol.addSymbol({ | ||
symbol = STSymbol.addSymbol({ | ||
context, | ||
@@ -205,4 +207,4 @@ symbol: { | ||
}); | ||
STPart.registerLegacyPart(context.meta, name, { mapTo: symbol }); | ||
} | ||
const symbol = STSymbol.get(context.meta, name, `class`); | ||
// mark native css as global | ||
@@ -209,0 +211,0 @@ if (context.meta.type === 'css' && !symbol['-st-global']) { |
@@ -11,2 +11,3 @@ export type { FeatureContext, FeatureTransformContext } from './feature'; | ||
export type { VarSymbol, ComputedStVar, FlatComputedStVar } from './st-var'; | ||
export * as STPart from './st-part'; | ||
export * as STCustomSelector from './st-custom-selector'; | ||
@@ -13,0 +14,0 @@ export * as STCustomState from './st-custom-state'; |
@@ -26,3 +26,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CSSMedia = exports.CSSContains = exports.CSSLayer = exports.CSSKeyframes = exports.CSSCustomProperty = exports.CSSPseudoClass = exports.CSSType = exports.CSSClass = exports.STMixin = exports.STCustomState = exports.STCustomSelector = exports.STVar = exports.STScope = exports.STGlobal = exports.STNamespace = exports.STImport = exports.STSymbol = void 0; | ||
exports.CSSMedia = exports.CSSContains = exports.CSSLayer = exports.CSSKeyframes = exports.CSSCustomProperty = exports.CSSPseudoClass = exports.CSSType = exports.CSSClass = exports.STMixin = exports.STCustomState = exports.STCustomSelector = exports.STPart = exports.STVar = exports.STScope = exports.STGlobal = exports.STNamespace = exports.STImport = exports.STSymbol = void 0; | ||
exports.STSymbol = __importStar(require("./st-symbol")); | ||
@@ -34,2 +34,3 @@ exports.STImport = __importStar(require("./st-import")); | ||
exports.STVar = __importStar(require("./st-var")); | ||
exports.STPart = __importStar(require("./st-part")); | ||
exports.STCustomSelector = __importStar(require("./st-custom-selector")); | ||
@@ -36,0 +37,0 @@ exports.STCustomState = __importStar(require("./st-custom-state")); |
@@ -31,2 +31,3 @@ "use strict"; | ||
const selector_1 = require("../helpers/selector"); | ||
const STPart = __importStar(require("./st-part")); | ||
const postcss = __importStar(require("postcss")); | ||
@@ -58,2 +59,3 @@ const css_selector_parser_1 = require("@tokey/css-selector-parser"); | ||
analyzed[name] = { selector, ast, isScoped, def: atRule }; | ||
STPart.registerLegacyPart(context.meta, name, { mapTo: ast }); | ||
} | ||
@@ -70,3 +72,3 @@ else { | ||
} | ||
const inlined = (0, custom_selector_1.transformCustomSelectorMap)(customSelectors, (report) => { | ||
const inlined = (0, custom_selector_1.transformInlineCustomSelectorMap)(customSelectors, (report) => { | ||
if (report.type === 'unknown' && analyzed[report.origin]) { | ||
@@ -149,3 +151,3 @@ const unknownSelector = `:--${report.unknown}`; | ||
const analyzed = plugable_record_1.plugableRecord.getUnsafe(meta.data, dataKey); | ||
const inlined = (0, custom_selector_1.transformCustomSelectors)(ast, (name) => analyzed[name]?.ast, (report) => { | ||
const inlined = (0, custom_selector_1.transformInlineCustomSelectors)(ast, (name) => analyzed[name]?.ast, (report) => { | ||
if (options.diagnostics && options.node) { | ||
@@ -152,0 +154,0 @@ const unknownSelector = `:--${report.unknown}`; |
@@ -65,2 +65,9 @@ "use strict"; | ||
exports.hooks = (0, feature_1.createFeature)({ | ||
transformSelectorNode({ selectorContext, node }) { | ||
const isMarker = (0, rule_1.isStMixinMarker)(node); | ||
if (isMarker) { | ||
selectorContext.setNextSelectorScope(selectorContext.inferredSelectorMixin, node, node.value); | ||
} | ||
return isMarker; | ||
}, | ||
transformLastPass({ context, ast, transformer, cssVarsMapping, path }) { | ||
@@ -303,3 +310,3 @@ ast.walkRules((rule) => appendMixins(context, transformer, rule, cssVarsMapping, path)); | ||
(0, stylable_assets_1.fixRelativeUrls)(mixinRoot, context.resolver.resolvePath((0, path_1.dirname)(meta.source), mixinPath), meta.source); | ||
(0, stylable_utils_1.mergeRules)(mixinRoot, config.rule, mixDef.data.originDecl, context.diagnostics); | ||
(0, stylable_utils_1.mergeRules)(mixinRoot, config.rule, mixDef.data.originDecl, context.diagnostics, true); | ||
} | ||
@@ -343,3 +350,3 @@ function handleCSSMixin(context, config, resolveChain) { | ||
if (roots.length === 1) { | ||
(0, stylable_utils_1.mergeRules)(roots[0], config.rule, mixDef.data.originDecl, config.transformer.diagnostics); | ||
(0, stylable_utils_1.mergeRules)(roots[0], config.rule, mixDef.data.originDecl, config.transformer.diagnostics, false); | ||
} | ||
@@ -349,3 +356,3 @@ else if (roots.length > 1) { | ||
roots.forEach((root) => mixinRoot.prepend(...root.nodes)); | ||
(0, stylable_utils_1.mergeRules)(mixinRoot, config.rule, mixDef.data.originDecl, config.transformer.diagnostics); | ||
(0, stylable_utils_1.mergeRules)(mixinRoot, config.rule, mixDef.data.originDecl, config.transformer.diagnostics, false); | ||
} | ||
@@ -352,0 +359,0 @@ } |
@@ -19,2 +19,3 @@ import type { Stylable } from '../stylable'; | ||
} | ||
export declare function isStScopeStatement(node: any): node is postcss.AtRule; | ||
//# sourceMappingURL=st-scope.d.ts.map |
@@ -26,3 +26,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.StylablePublicApi = exports.hooks = exports.diagnostics = void 0; | ||
exports.isStScopeStatement = exports.StylablePublicApi = exports.hooks = exports.diagnostics = void 0; | ||
const feature_1 = require("./feature"); | ||
@@ -96,2 +96,3 @@ const selector_1 = require("../helpers/selector"); | ||
} | ||
exports.isStScopeStatement = isStScopeStatement; | ||
function flattenScope(atRule) { | ||
@@ -98,0 +99,0 @@ const scopeSelector = atRule.params; |
@@ -84,5 +84,5 @@ import { FeatureContext } from './feature'; | ||
localName?: string; | ||
}): void; | ||
}): StylableSymbol | undefined; | ||
export declare function reportRedeclare(context: FeatureContext): void; | ||
export {}; | ||
//# sourceMappingURL=st-symbol.d.ts.map |
@@ -97,2 +97,3 @@ "use strict"; | ||
typeTable[name] = symbol; | ||
return symbol; | ||
} | ||
@@ -99,0 +100,0 @@ exports.addSymbol = addSymbol; |
@@ -13,5 +13,12 @@ import { SelectorList } from '@tokey/css-selector-parser'; | ||
export type TransformCustomSelectorReport = UnknownReport | CircularReport; | ||
export declare function transformCustomSelectorMap(customSelectors: CustomSelectorMap, report: (data: TransformCustomSelectorReport) => void): CustomSelectorMap; | ||
export declare function transformCustomSelectors(inputSelectors: SelectorList, getCustomSelector: (name: string) => SelectorList | undefined, report: (data: UnknownReport) => void): SelectorList; | ||
export declare function transformInlineCustomSelectorMap(customSelectors: CustomSelectorMap, report: (data: TransformCustomSelectorReport) => void): CustomSelectorMap; | ||
/** | ||
* Takes a list of selectors and a function that returns a selector | ||
* against a custom selector name. | ||
* | ||
* Then search for inline custom selectors (e.g. ":--custom") and | ||
* replaces them with the retrieved selectors it receives | ||
*/ | ||
export declare function transformInlineCustomSelectors(inputSelectors: SelectorList, getCustomSelector: (name: string) => SelectorList | undefined, report: (data: UnknownReport) => void): SelectorList; | ||
export {}; | ||
//# sourceMappingURL=custom-selector.d.ts.map |
@@ -6,6 +6,6 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.transformCustomSelectors = exports.transformCustomSelectorMap = void 0; | ||
exports.transformInlineCustomSelectors = exports.transformInlineCustomSelectorMap = void 0; | ||
const css_selector_parser_1 = require("@tokey/css-selector-parser"); | ||
const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep")); | ||
function transformCustomSelectorMap(customSelectors, report) { | ||
function transformInlineCustomSelectorMap(customSelectors, report) { | ||
const result = {}; | ||
@@ -17,3 +17,3 @@ const link = (name, path) => { | ||
} | ||
result[name] = transformCustomSelectors(ast, (nestedName) => { | ||
result[name] = transformInlineCustomSelectors(ast, (nestedName) => { | ||
const selector = `:--${nestedName}`; | ||
@@ -36,15 +36,22 @@ if (path.includes(selector)) { | ||
} | ||
exports.transformCustomSelectorMap = transformCustomSelectorMap; | ||
exports.transformInlineCustomSelectorMap = transformInlineCustomSelectorMap; | ||
function isCustomSelectorNode(node) { | ||
return node.type === 'pseudo_class' && node.value.startsWith('--'); | ||
} | ||
function transformCustomSelectors(inputSelectors, getCustomSelector, report) { | ||
/** | ||
* Takes a list of selectors and a function that returns a selector | ||
* against a custom selector name. | ||
* | ||
* Then search for inline custom selectors (e.g. ":--custom") and | ||
* replaces them with the retrieved selectors it receives | ||
*/ | ||
function transformInlineCustomSelectors(inputSelectors, getCustomSelector, report) { | ||
const result = []; | ||
for (const selector of inputSelectors) { | ||
result.push(...transformCustomSelector(selector, getCustomSelector, report)); | ||
result.push(...transformInlineCustomSelector(selector, getCustomSelector, report)); | ||
} | ||
return result; | ||
} | ||
exports.transformCustomSelectors = transformCustomSelectors; | ||
function transformCustomSelector(inputSelector, getCustomSelector, report) { | ||
exports.transformInlineCustomSelectors = transformInlineCustomSelectors; | ||
function transformInlineCustomSelector(inputSelector, getCustomSelector, report) { | ||
const insertions = []; | ||
@@ -51,0 +58,0 @@ // get insertion points |
@@ -1,8 +0,10 @@ | ||
import { SelectorList } from '@tokey/css-selector-parser'; | ||
import { SelectorList, SelectorNode } from '@tokey/css-selector-parser'; | ||
import * as postcss from 'postcss'; | ||
export declare function isChildOfAtRule(rule: postcss.Container, atRuleName: string): boolean; | ||
export declare function isInConditionalGroup(node: postcss.Rule | postcss.AtRule, includeRoot?: boolean): any; | ||
export declare function createSubsetAst<T extends postcss.Root | postcss.AtRule>(root: postcss.Root | postcss.AtRule, selectorPrefix: string, mixinTarget?: T, isRoot?: boolean, getCustomSelector?: (name: string) => SelectorList | undefined, scopeSelector?: string): T; | ||
export declare function createSubsetAst<T extends postcss.Root | postcss.AtRule | postcss.Rule>(root: postcss.Root | postcss.AtRule | postcss.Rule, selectorPrefix: string, mixinTarget?: T, isRoot?: boolean, getCustomSelector?: (name: string) => SelectorList | undefined, isNestedInMixin?: boolean): T; | ||
export declare const stMixinMarker = "st-mixin-marker"; | ||
export declare const isStMixinMarker: (node: SelectorNode) => boolean; | ||
/** @deprecated internal for transformer */ | ||
export declare function findRule(root: postcss.Root, selector: string, test?: any): null | postcss.Declaration; | ||
//# sourceMappingURL=rule.d.ts.map |
@@ -26,3 +26,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.findRule = exports.createSubsetAst = exports.isInConditionalGroup = exports.isChildOfAtRule = void 0; | ||
exports.findRule = exports.isStMixinMarker = exports.stMixinMarker = exports.createSubsetAst = exports.isInConditionalGroup = exports.isChildOfAtRule = void 0; | ||
const selector_1 = require("./selector"); | ||
@@ -46,3 +46,3 @@ const css_selector_parser_1 = require("@tokey/css-selector-parser"); | ||
exports.isInConditionalGroup = isInConditionalGroup; | ||
function createSubsetAst(root, selectorPrefix, mixinTarget, isRoot = false, getCustomSelector, scopeSelector = '') { | ||
function createSubsetAst(root, selectorPrefix, mixinTarget, isRoot = false, getCustomSelector, isNestedInMixin = false) { | ||
// keyframes on class mixin? | ||
@@ -53,5 +53,8 @@ const prefixSelectorList = (0, selector_1.parseSelectorWithCache)(selectorPrefix); | ||
const mixinRoot = mixinTarget ? mixinTarget : postcss.root(); | ||
const scopeSelectorAST = (0, selector_1.parseSelectorWithCache)(scopeSelector); | ||
root.nodes.forEach((node) => { | ||
if (node.type === `rule` && (node.selector === ':vars' || node.selector === ':import')) { | ||
if (node.type === 'decl') { | ||
mixinTarget?.append(node.clone()); | ||
} | ||
else if (node.type === `rule` && | ||
(node.selector === ':vars' || node.selector === ':import')) { | ||
// nodes that don't mix | ||
@@ -61,6 +64,3 @@ return; | ||
else if (node.type === `rule`) { | ||
let selectorAst = (0, selector_1.parseSelectorWithCache)(node.selector, { clone: true }); | ||
if (scopeSelector) { | ||
selectorAst = (0, selector_1.scopeNestedSelector)(scopeSelectorAST, selectorAst, isRoot).ast; | ||
} | ||
const selectorAst = (0, selector_1.parseSelectorWithCache)(node.selector, { clone: true }); | ||
let ast = isRoot | ||
@@ -70,7 +70,7 @@ ? (0, selector_1.scopeNestedSelector)(prefixSelectorList, selectorAst, true).ast | ||
if (getCustomSelector) { | ||
ast = (0, custom_selector_1.transformCustomSelectors)(ast, getCustomSelector, () => { | ||
ast = (0, custom_selector_1.transformInlineCustomSelectors)(ast, getCustomSelector, () => { | ||
/*don't report*/ | ||
}); | ||
} | ||
const matchesSelectors = isRoot ? ast : ast.filter((node) => containsPrefix(node)); | ||
const matchesSelectors = isRoot || isNestedInMixin ? ast : ast.filter((node) => containsPrefix(node)); | ||
if (matchesSelectors.length) { | ||
@@ -81,6 +81,7 @@ const selector = (0, selector_1.stringifySelector)(matchesSelectors.map((selectorNode) => { | ||
} | ||
replaceTargetWithNesting(selectorNode, prefixType); | ||
replaceTargetWithMixinAnchor(selectorNode, prefixType); | ||
return selectorNode; | ||
})); | ||
mixinRoot.append(node.clone({ selector })); | ||
const clonedRule = createSubsetAst(node, selectorPrefix, node.clone({ selector, nodes: [] }), isRoot, getCustomSelector, true /*isNestedInMixin*/); | ||
mixinRoot.append(clonedRule); | ||
} | ||
@@ -94,7 +95,24 @@ } | ||
node.name === 'container') { | ||
const scopeSelector = node.name === 'st-scope' ? node.params : ''; | ||
let scopeSelector = node.name === 'st-scope' ? node.params : ''; | ||
let isNestedInMixin = false; | ||
if (scopeSelector) { | ||
const ast = (0, selector_1.parseSelectorWithCache)(scopeSelector, { clone: true }); | ||
const matchesSelectors = isRoot | ||
? ast | ||
: ast.filter((node) => containsPrefix(node)); | ||
if (matchesSelectors.length) { | ||
isNestedInMixin = true; | ||
scopeSelector = (0, selector_1.stringifySelector)(matchesSelectors.map((selectorNode) => { | ||
if (!isRoot) { | ||
selectorNode = fixChunkOrdering(selectorNode, prefixType); | ||
} | ||
replaceTargetWithMixinAnchor(selectorNode, prefixType); | ||
return selectorNode; | ||
})); | ||
} | ||
} | ||
const atRuleSubset = createSubsetAst(node, selectorPrefix, postcss.atRule({ | ||
params: node.params, | ||
params: scopeSelector || node.params, | ||
name: node.name, | ||
}), isRoot, getCustomSelector, scopeSelector); | ||
}), isRoot, getCustomSelector, isNestedInMixin); | ||
if (atRuleSubset.nodes) { | ||
@@ -115,3 +133,6 @@ mixinRoot.append(atRuleSubset); | ||
exports.createSubsetAst = createSubsetAst; | ||
function replaceTargetWithNesting(selectorNode, prefixType) { | ||
exports.stMixinMarker = 'st-mixin-marker'; | ||
const isStMixinMarker = (node) => node.type === 'attribute' && node.value === exports.stMixinMarker; | ||
exports.isStMixinMarker = isStMixinMarker; | ||
function replaceTargetWithMixinAnchor(selectorNode, prefixType) { | ||
(0, selector_1.walkSelector)(selectorNode, (node) => { | ||
@@ -121,4 +142,4 @@ if ((0, selector_1.matchTypeAndValue)(node, prefixType)) { | ||
{ | ||
type: `nesting`, | ||
value: `&`, | ||
type: `attribute`, | ||
value: exports.stMixinMarker, | ||
start: node.start, | ||
@@ -125,0 +146,0 @@ end: node.end, |
@@ -11,2 +11,3 @@ import { parseCssSelector, stringifySelectorAst, walk, SelectorNode, PseudoClass, Selector, SelectorList, FunctionalSelector, Class, Attribute, Invalid, ImmutableSelectorList, ImmutableSelectorNode, Combinator } from '@tokey/css-selector-parser'; | ||
}): ImmutableSelectorList; | ||
export declare function cloneSelector<T extends Selector | SelectorList>(s: T): T; | ||
/** | ||
@@ -42,3 +43,3 @@ * returns for each selector if it contains only | ||
*/ | ||
export declare function scopeNestedSelector(scopeSelectorAst: ImmutableSelectorList, nestedSelectorAst: ImmutableSelectorList, rootScopeLevel?: boolean): { | ||
export declare function scopeNestedSelector(scopeSelectorAst: ImmutableSelectorList, nestedSelectorAst: ImmutableSelectorList, rootScopeLevel?: boolean, isAnchor?: (node: SelectorNode) => boolean): { | ||
selector: string; | ||
@@ -45,0 +46,0 @@ ast: SelectorList; |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.scopeNestedSelector = exports.isCompRoot = exports.matchTypeAndValue = exports.isInPseudoClassContext = exports.createCombinatorSelector = exports.convertToPseudoClass = exports.convertToSelector = exports.convertToInvalid = exports.convertToAttribute = exports.convertToClass = exports.flattenFunctionalSelector = exports.isSimpleSelector = exports.parseSelectorWithCache = exports.walkSelector = exports.stringifySelector = exports.parseSelector = void 0; | ||
exports.scopeNestedSelector = exports.isCompRoot = exports.matchTypeAndValue = exports.isInPseudoClassContext = exports.createCombinatorSelector = exports.convertToPseudoClass = exports.convertToSelector = exports.convertToInvalid = exports.convertToAttribute = exports.convertToClass = exports.flattenFunctionalSelector = exports.isSimpleSelector = exports.cloneSelector = exports.parseSelectorWithCache = exports.walkSelector = exports.stringifySelector = exports.parseSelector = void 0; | ||
const css_selector_parser_1 = require("@tokey/css-selector-parser"); | ||
@@ -30,2 +30,6 @@ const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep")); | ||
exports.parseSelectorWithCache = parseSelectorWithCache; | ||
function cloneSelector(s) { | ||
return (0, lodash_clonedeep_1.default)(s); | ||
} | ||
exports.cloneSelector = cloneSelector; | ||
/** | ||
@@ -141,2 +145,3 @@ * returns for each selector if it contains only | ||
exports.isCompRoot = isCompRoot; | ||
const isNestedNode = (node) => node.type === 'nesting'; | ||
/** | ||
@@ -147,3 +152,3 @@ * combine 2 selector lists. | ||
*/ | ||
function scopeNestedSelector(scopeSelectorAst, nestedSelectorAst, rootScopeLevel = false) { | ||
function scopeNestedSelector(scopeSelectorAst, nestedSelectorAst, rootScopeLevel = false, isAnchor = isNestedNode) { | ||
const resultSelectors = []; | ||
@@ -169,3 +174,3 @@ nestedSelectorAst.forEach((targetAst) => { | ||
(0, exports.walkSelector)(outputAst, (node, i, nodes) => { | ||
if (node.type === 'nesting') { | ||
if (isAnchor(node)) { | ||
nestedMixRoot = true; | ||
@@ -172,0 +177,0 @@ nodes.splice(i, 1, { |
export { safeParse } from './parser'; | ||
export { processorDiagnostics, StylableProcessor } from './stylable-processor'; | ||
export { StylableProcessor } from './stylable-processor'; | ||
export { StylableTransformer, postProcessor, replaceValueHook, StylableExports, transformerDiagnostics, ResolvedElement, InferredSelector, } from './stylable-transformer'; | ||
export { validateDefaultConfig } from './stylable'; | ||
export { STSymbol, STImport, STGlobal, STNamespace, STCustomSelector, STCustomState, CSSClass, CSSType, CSSKeyframes, CSSLayer, CSSContains, CSSCustomProperty, } from './features'; | ||
export { STSymbol, STImport, STGlobal, STNamespace, STPart, STCustomSelector, STCustomState, CSSClass, CSSType, CSSKeyframes, CSSLayer, CSSContains, CSSCustomProperty, } from './features'; | ||
export type { MappedStates, StateParsedValue, TemplateStateParsedValue, } from './helpers/custom-state'; | ||
@@ -7,0 +7,0 @@ export { murmurhash3_32_gc } from './murmurhash'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.plugableRecord = exports.processDeclarationFunctions = exports.createAtImportProps = exports.parsePseudoImport = exports.tryCollectImportsDeep = exports.createCustomValue = exports.packageNamespaceFactory = exports.createStylableFileProcessor = exports.cachedProcessFile = exports.StylableResolver = exports.reportDiagnostic = exports.emitDiagnostics = exports.parseSelectorWithCache = exports.namespaceDelimiter = exports.namespace = exports.fixRelativeUrls = exports.isRelativeNativeCss = exports.makeAbsolute = exports.isAsset = exports.knownPseudoClassesWithNestedSelectors = exports.nativePseudoElements = exports.nativePseudoClasses = exports.cssParse = exports.murmurhash3_32_gc = exports.CSSCustomProperty = exports.CSSContains = exports.CSSLayer = exports.CSSKeyframes = exports.CSSType = exports.CSSClass = exports.STCustomState = exports.STCustomSelector = exports.STNamespace = exports.STGlobal = exports.STImport = exports.STSymbol = exports.validateDefaultConfig = exports.InferredSelector = exports.transformerDiagnostics = exports.StylableTransformer = exports.StylableProcessor = exports.processorDiagnostics = exports.safeParse = void 0; | ||
exports.plugableRecord = exports.processDeclarationFunctions = exports.createAtImportProps = exports.parsePseudoImport = exports.tryCollectImportsDeep = exports.createCustomValue = exports.packageNamespaceFactory = exports.createStylableFileProcessor = exports.cachedProcessFile = exports.StylableResolver = exports.reportDiagnostic = exports.emitDiagnostics = exports.parseSelectorWithCache = exports.namespaceDelimiter = exports.namespace = exports.fixRelativeUrls = exports.isRelativeNativeCss = exports.makeAbsolute = exports.isAsset = exports.knownPseudoClassesWithNestedSelectors = exports.nativePseudoElements = exports.nativePseudoClasses = exports.cssParse = exports.murmurhash3_32_gc = exports.CSSCustomProperty = exports.CSSContains = exports.CSSLayer = exports.CSSKeyframes = exports.CSSType = exports.CSSClass = exports.STCustomState = exports.STCustomSelector = exports.STPart = exports.STNamespace = exports.STGlobal = exports.STImport = exports.STSymbol = exports.validateDefaultConfig = exports.InferredSelector = exports.transformerDiagnostics = exports.StylableTransformer = exports.StylableProcessor = exports.safeParse = void 0; | ||
var parser_1 = require("./parser"); | ||
Object.defineProperty(exports, "safeParse", { enumerable: true, get: function () { return parser_1.safeParse; } }); | ||
var stylable_processor_1 = require("./stylable-processor"); | ||
Object.defineProperty(exports, "processorDiagnostics", { enumerable: true, get: function () { return stylable_processor_1.processorDiagnostics; } }); | ||
Object.defineProperty(exports, "StylableProcessor", { enumerable: true, get: function () { return stylable_processor_1.StylableProcessor; } }); | ||
@@ -20,2 +19,3 @@ var stylable_transformer_1 = require("./stylable-transformer"); | ||
Object.defineProperty(exports, "STNamespace", { enumerable: true, get: function () { return features_1.STNamespace; } }); | ||
Object.defineProperty(exports, "STPart", { enumerable: true, get: function () { return features_1.STPart; } }); | ||
Object.defineProperty(exports, "STCustomSelector", { enumerable: true, get: function () { return features_1.STCustomSelector; } }); | ||
@@ -22,0 +22,0 @@ Object.defineProperty(exports, "STCustomState", { enumerable: true, get: function () { return features_1.STCustomState; } }); |
@@ -1,4 +0,4 @@ | ||
import { ProcessOptions, Root, parse as cssParse } from 'postcss'; | ||
import postcss, { ProcessOptions, Root, parse as cssParse } from 'postcss'; | ||
export type CSSObject = any & object; | ||
export declare function cssObjectToAst(cssObject: CSSObject, sourceFile?: string): import("postcss").LazyResult | import("postcss/lib/no-work-result").default; | ||
export declare function cssObjectToAst(cssObject: CSSObject, sourceFile?: string): postcss.LazyResult | import("postcss/lib/no-work-result").default; | ||
export type CssParser = typeof safeParse; | ||
@@ -5,0 +5,0 @@ export declare function safeParse(css: string, options?: ProcessOptions): Root; |
@@ -13,2 +13,3 @@ "use strict"; | ||
features_1.STVar, | ||
features_1.STPart, | ||
features_1.STCustomSelector, | ||
@@ -15,0 +16,0 @@ features_1.STCustomState, |
@@ -5,9 +5,2 @@ import type * as postcss from 'postcss'; | ||
import { FeatureContext, STNamespace } from './features'; | ||
export declare const processorDiagnostics: { | ||
INVALID_NESTING: { | ||
(child: string, parent: string): import("./diagnostics").DiagnosticBase; | ||
code: string; | ||
severity: import("./diagnostics").DiagnosticSeverity; | ||
}; | ||
}; | ||
export declare class StylableProcessor implements FeatureContext { | ||
@@ -14,0 +7,0 @@ diagnostics: Diagnostics; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.processNamespace = exports.StylableProcessor = exports.processorDiagnostics = void 0; | ||
exports.processNamespace = exports.StylableProcessor = void 0; | ||
const diagnostics_1 = require("./diagnostics"); | ||
@@ -13,5 +13,2 @@ const native_reserved_lists_1 = require("./native-reserved-lists"); | ||
const rule_1 = require("./helpers/rule"); | ||
exports.processorDiagnostics = { | ||
INVALID_NESTING: (0, diagnostics_1.createDiagnosticReporter)('11011', 'error', (child, parent) => `nesting of rules within rules is not supported, found: "${child}" inside "${parent}"`), | ||
}; | ||
class StylableProcessor { | ||
@@ -34,6 +31,2 @@ constructor(diagnostics = new diagnostics_1.Diagnostics(), resolveNamespace = features_2.STNamespace.defaultProcessNamespace) { | ||
} | ||
const parent = rule.parent; | ||
if (parent?.type === 'rule') { | ||
this.diagnostics.report(exports.processorDiagnostics.INVALID_NESTING(rule.selector, parent.selector), { node: rule }); | ||
} | ||
}); | ||
@@ -40,0 +33,0 @@ const isStylable = this.meta.type === 'stylable'; |
@@ -77,5 +77,5 @@ import * as postcss from 'postcss'; | ||
transform(meta: StylableMeta): StylableResults; | ||
transformAst(ast: postcss.Root, meta: StylableMeta, metaExports?: StylableExports, stVarOverride?: Record<string, string>, path?: string[], mixinTransform?: boolean, inferredNestSelector?: InferredSelector): void; | ||
transformAst(ast: postcss.Root, meta: StylableMeta, metaExports?: StylableExports, stVarOverride?: Record<string, string>, path?: string[], mixinTransform?: boolean, inferredSelectorMixin?: InferredSelector): void; | ||
resolveSelectorElements(meta: StylableMeta, selector: string): ResolvedElement[][]; | ||
scopeSelector(originMeta: StylableMeta, selector: string, selectorNode?: postcss.Rule | postcss.AtRule, inferredNestSelector?: InferredSelector, unwrapGlobals?: boolean): { | ||
scopeSelector(originMeta: StylableMeta, selector: string, selectorNode?: postcss.Rule | postcss.AtRule, inferredNestSelector?: InferredSelector, inferredMixinSelector?: InferredSelector, unwrapGlobals?: boolean): { | ||
selector: string; | ||
@@ -86,3 +86,3 @@ elements: ResolvedElement[][]; | ||
}; | ||
createSelectorContext(meta: StylableMeta, selectorAst: SelectorList, selectorNode: postcss.Rule | postcss.AtRule, selectorStr?: string, selectorNest?: InferredSelector): ScopeContext; | ||
createSelectorContext(meta: StylableMeta, selectorAst: SelectorList, selectorNode: postcss.Rule | postcss.AtRule, selectorStr?: string, selectorNest?: InferredSelector, selectorMixin?: InferredSelector): ScopeContext; | ||
createInferredSelector(meta: StylableMeta, { name, type }: { | ||
@@ -141,3 +141,3 @@ name: string; | ||
private transformer; | ||
inferredSelectorNest: InferredSelector; | ||
inferredSelectorMixin?: InferredSelector | undefined; | ||
transform: boolean; | ||
@@ -151,2 +151,3 @@ selectorStr: string; | ||
node?: CompoundSelector['nodes'][number]; | ||
isNested: boolean; | ||
splitSelectors: SelectorMultiplier; | ||
@@ -156,5 +157,6 @@ lastInferredSelectorNode: SelectorNode | undefined; | ||
inferredSelectorContext: InferredSelector; | ||
inferredSelectorNest: InferredSelector; | ||
inferredSelector: InferredSelector; | ||
inferredMultipleSelectors: InferredSelector; | ||
constructor(originMeta: StylableMeta, resolver: StylableResolver, selectorAst: SelectorList, ruleOrAtRule: postcss.Rule | postcss.AtRule, scopeSelectorAst: StylableTransformer['scopeSelectorAst'], transformer: StylableTransformer, inferredSelectorNest: InferredSelector, selectorContext: InferredSelector, selectorStr?: string); | ||
constructor(originMeta: StylableMeta, resolver: StylableResolver, selectorAst: SelectorList, ruleOrAtRule: postcss.Rule | postcss.AtRule, scopeSelectorAst: StylableTransformer['scopeSelectorAst'], transformer: StylableTransformer, inferredSelectorNest?: InferredSelector, inferredSelectorMixin?: InferredSelector | undefined, inferredSelectorContext?: InferredSelector, selectorStr?: string); | ||
get experimentalSelectorInference(): boolean; | ||
@@ -161,0 +163,0 @@ static legacyElementsTypesMapping: Record<string, string>; |
@@ -95,3 +95,3 @@ "use strict"; | ||
} | ||
transformAst(ast, meta, metaExports, stVarOverride = this.defaultStVarOverride, path = [], mixinTransform = false, inferredNestSelector) { | ||
transformAst(ast, meta, metaExports, stVarOverride = this.defaultStVarOverride, path = [], mixinTransform = false, inferredSelectorMixin) { | ||
if (meta.type !== 'stylable') { | ||
@@ -240,4 +240,3 @@ return; | ||
// transform selector | ||
const { selector, inferredSelector } = this.scopeSelector(meta, node.selector, node, (currentParent && this.containerInferredSelectorMap.get(currentParent)) || | ||
inferredNestSelector); | ||
const { selector, inferredSelector } = this.scopeSelector(meta, node.selector, node, currentParent && this.containerInferredSelectorMap.get(currentParent), inferredSelectorMixin); | ||
// save results | ||
@@ -306,4 +305,4 @@ this.containerInferredSelectorMap.set(node, inferredSelector); | ||
} | ||
scopeSelector(originMeta, selector, selectorNode, inferredNestSelector, unwrapGlobals = false) { | ||
const context = this.createSelectorContext(originMeta, (0, selector_1.parseSelectorWithCache)(selector, { clone: true }), selectorNode || postcss.rule({ selector }), selector, inferredNestSelector); | ||
scopeSelector(originMeta, selector, selectorNode, inferredNestSelector, inferredMixinSelector, unwrapGlobals = false) { | ||
const context = this.createSelectorContext(originMeta, (0, selector_1.parseSelectorWithCache)(selector, { clone: true }), selectorNode || postcss.rule({ selector }), selector, inferredNestSelector, inferredMixinSelector); | ||
const targetSelectorAst = this.scopeSelectorAst(context); | ||
@@ -320,8 +319,4 @@ if (unwrapGlobals) { | ||
} | ||
createSelectorContext(meta, selectorAst, selectorNode, selectorStr, selectorNest) { | ||
const inferredContext = this.createInferredSelector(meta, { | ||
name: meta.root, | ||
type: 'class', | ||
}); | ||
return new ScopeContext(meta, this.resolver, selectorAst, selectorNode, this.scopeSelectorAst.bind(this), this, selectorNest || inferredContext.clone(), inferredContext, selectorStr); | ||
createSelectorContext(meta, selectorAst, selectorNode, selectorStr, selectorNest, selectorMixin) { | ||
return new ScopeContext(meta, this.resolver, selectorAst, selectorNode, this.scopeSelectorAst.bind(this), this, selectorNest, selectorMixin, undefined, selectorStr); | ||
} | ||
@@ -345,3 +340,3 @@ createInferredSelector(meta, { name, type }) { | ||
if (node.type === 'combinator') { | ||
if (this.experimentalSelectorInference) { | ||
if (this.experimentalSelectorInference || context.isNested) { | ||
context.setNextSelectorScope(context.inferredSelectorContext, node); | ||
@@ -458,2 +453,9 @@ } | ||
} | ||
else if (node.type === 'attribute') { | ||
features_2.STMixin.hooks.transformSelectorNode({ | ||
context: transformerContext, | ||
selectorContext: context, | ||
node, | ||
}); | ||
} | ||
} | ||
@@ -633,8 +635,11 @@ } | ||
checked[name].add(uniqueId); | ||
// prefer custom selector | ||
const customSelector = features_2.STCustomSelector.getCustomSelectorExpended(meta, name); | ||
if (customSelector) { | ||
const selectorList = (0, selector_1.parseSelectorWithCache)(customSelector, { | ||
clone: true, | ||
}); | ||
// | ||
const partDef = features_1.STPart.getPart(meta, name); | ||
if (!partDef) { | ||
continue; | ||
} | ||
if (Array.isArray(partDef.mapTo)) { | ||
// prefer custom selector | ||
const selectorList = (0, selector_1.cloneSelector)(partDef.mapTo); | ||
const selectorStr = (0, selector_1.stringifySelector)(partDef.mapTo); | ||
selectorList.forEach((selector) => { | ||
@@ -648,3 +653,3 @@ const r = removeFirstRootInFirstCompound(selector, meta); | ||
}); | ||
const internalContext = this.api.createSelectorContext(meta, selectorList, postcss.rule({ selector: customSelector }), customSelector); | ||
const internalContext = this.api.createSelectorContext(meta, selectorList, postcss.rule({ selector: selectorStr }), selectorStr); | ||
internalContext.isStandaloneSelector = isFirstInSelector; | ||
@@ -664,5 +669,4 @@ const customAstSelectors = this.api.scopeSelectorAst(internalContext); | ||
} | ||
// matching class part | ||
const classSymbol = features_2.CSSClass.get(meta, name); | ||
if (classSymbol) { | ||
else { | ||
// matching class part | ||
const resolvedPart = this.api.getResolvedSymbols(meta).class[name]; | ||
@@ -762,3 +766,3 @@ const resolvedBaseSymbol = (0, resolve_1.getOriginDefinition)(resolvedPart); | ||
class ScopeContext { | ||
constructor(originMeta, resolver, selectorAst, ruleOrAtRule, scopeSelectorAst, transformer, inferredSelectorNest, selectorContext, selectorStr) { | ||
constructor(originMeta, resolver, selectorAst, ruleOrAtRule, scopeSelectorAst, transformer, inferredSelectorNest, inferredSelectorMixin, inferredSelectorContext, selectorStr) { | ||
this.originMeta = originMeta; | ||
@@ -770,3 +774,3 @@ this.resolver = resolver; | ||
this.transformer = transformer; | ||
this.inferredSelectorNest = inferredSelectorNest; | ||
this.inferredSelectorMixin = inferredSelectorMixin; | ||
this.transform = true; | ||
@@ -784,4 +788,32 @@ // source multi-selector input | ||
this.inferredMultipleSelectors = new InferredSelector(this.transformer); | ||
this.isNested = !!(ruleOrAtRule.parent && | ||
// top level | ||
ruleOrAtRule.parent.type !== 'root' && | ||
// directly in @st-scope | ||
!features_2.STScope.isStScopeStatement(ruleOrAtRule.parent)); | ||
/* | ||
resolve default selector context for initial selector and selector | ||
following a combinator. | ||
Currently set to stylesheet root for top level selectors and selectors | ||
directly nested under @st-scope. But will change in the future to a universal selector | ||
once experimentalSelectorInference will be the default behavior | ||
*/ | ||
const inferredContext = inferredSelectorContext || | ||
(this.isNested || transformer.experimentalSelectorInference | ||
? new InferredSelector(transformer, [ | ||
{ | ||
_kind: 'css', | ||
meta: originMeta, | ||
symbol: { _kind: 'element', name: '*' }, | ||
}, | ||
]) | ||
: transformer.createInferredSelector(originMeta, { | ||
name: originMeta.root, | ||
type: 'class', | ||
})); | ||
// set selector data | ||
this.selectorStr = selectorStr || (0, selector_1.stringifySelector)(selectorAst); | ||
this.inferredSelectorContext = new InferredSelector(this.transformer, selectorContext); | ||
this.inferredSelectorContext = new InferredSelector(this.transformer, inferredContext); | ||
this.inferredSelectorNest = inferredSelectorNest || this.inferredSelectorContext.clone(); | ||
this.inferredSelector = new InferredSelector(this.transformer, this.inferredSelectorContext); | ||
@@ -813,3 +845,3 @@ } | ||
createNestedContext(selectorAst, selectorContext) { | ||
const ctx = new ScopeContext(this.originMeta, this.resolver, selectorAst, this.ruleOrAtRule, this.scopeSelectorAst, this.transformer, this.inferredSelectorNest, selectorContext || this.inferredSelectorContext); | ||
const ctx = new ScopeContext(this.originMeta, this.resolver, selectorAst, this.ruleOrAtRule, this.scopeSelectorAst, this.transformer, this.inferredSelectorNest, this.inferredSelectorMixin, selectorContext || this.inferredSelectorContext); | ||
ctx.transform = this.transform; | ||
@@ -816,0 +848,0 @@ ctx.selectorAstResolveMap = this.selectorAstResolveMap; |
@@ -12,3 +12,3 @@ import type * as postcss from 'postcss'; | ||
}; | ||
export declare function mergeRules(mixinAst: postcss.Root, rule: postcss.Rule, mixinDecl: postcss.Declaration, report?: Diagnostics): postcss.Rule; | ||
export declare function mergeRules(mixinAst: postcss.Root, rule: postcss.Rule, mixinDecl: postcss.Declaration, report: Diagnostics, useNestingAsAnchor: boolean): postcss.Rule; | ||
export declare const sourcePathDiagnostics: { | ||
@@ -15,0 +15,0 @@ MISSING_SOURCE_FILENAME: { |
@@ -16,5 +16,7 @@ "use strict"; | ||
// ToDo: move to helpers/mixin | ||
function mergeRules(mixinAst, rule, mixinDecl, report) { | ||
function mergeRules(mixinAst, rule, mixinDecl, report, useNestingAsAnchor) { | ||
let mixinRoot = null; | ||
const nestedInKeyframes = (0, rule_1.isChildOfAtRule)(rule, `keyframes`); | ||
const anchorSelector = useNestingAsAnchor ? '&' : '[' + rule_1.stMixinMarker + ']'; | ||
const anchorNodeCheck = useNestingAsAnchor ? undefined : rule_1.isStMixinMarker; | ||
mixinAst.walkRules((mixinRule) => { | ||
@@ -24,3 +26,3 @@ if ((0, rule_1.isChildOfAtRule)(mixinRule, 'keyframes')) { | ||
} | ||
if (mixinRule.selector === '&' && !mixinRoot) { | ||
if (mixinRule.selector === anchorSelector && !mixinRoot) { | ||
if (mixinRule.parent === mixinAst) { | ||
@@ -30,3 +32,3 @@ mixinRoot = mixinRule; | ||
else { | ||
const { selector } = (0, selector_1.scopeNestedSelector)((0, selector_1.parseSelectorWithCache)(rule.selector), (0, selector_1.parseSelectorWithCache)(mixinRule.selector)); | ||
const { selector } = (0, selector_1.scopeNestedSelector)((0, selector_1.parseSelectorWithCache)(rule.selector), (0, selector_1.parseSelectorWithCache)(mixinRule.selector), false, anchorNodeCheck); | ||
mixinRoot = 'NoRoot'; | ||
@@ -37,3 +39,3 @@ mixinRule.selector = selector; | ||
else { | ||
const { selector } = (0, selector_1.scopeNestedSelector)((0, selector_1.parseSelectorWithCache)(rule.selector), (0, selector_1.parseSelectorWithCache)(mixinRule.selector)); | ||
const { selector } = (0, selector_1.scopeNestedSelector)((0, selector_1.parseSelectorWithCache)(rule.selector), (0, selector_1.parseSelectorWithCache)(mixinRule.selector), false, anchorNodeCheck); | ||
mixinRule.selector = selector; | ||
@@ -47,5 +49,5 @@ } | ||
if (node === mixinRoot) { | ||
node.walkDecls((node) => { | ||
rule.insertBefore(mixinDecl, node); | ||
}); | ||
for (const nested of [...node.nodes]) { | ||
rule.insertBefore(mixinDecl, nested); | ||
} | ||
} | ||
@@ -52,0 +54,0 @@ else if (node.type === 'decl') { |
@@ -138,3 +138,3 @@ "use strict"; | ||
const transformer = this.createTransformer(options); | ||
const r = transformer.scopeSelector(meta, selector, undefined, undefined, true); | ||
const r = transformer.scopeSelector(meta, selector, undefined, undefined, undefined, true); | ||
return { | ||
@@ -141,0 +141,0 @@ selector: r.selector, |
{ | ||
"name": "@stylable/core", | ||
"version": "5.9.0", | ||
"version": "5.10.0", | ||
"description": "CSS for Components", | ||
@@ -22,3 +22,3 @@ "main": "dist/index.js", | ||
"lodash.clonedeepwith": "^4.5.0", | ||
"postcss": "^8.4.21", | ||
"postcss": "^8.4.22", | ||
"postcss-js": "^4.0.1", | ||
@@ -25,0 +25,0 @@ "postcss-nested": "^6.0.1", |
@@ -7,2 +7,3 @@ import { createFeature, FeatureContext, FeatureTransformContext } from './feature'; | ||
import type { ElementSymbol } from './css-type'; | ||
import * as STPart from './st-part'; | ||
import * as STCustomState from './st-custom-state'; | ||
@@ -263,3 +264,4 @@ import { getOriginDefinition } from '../helpers/resolve'; | ||
export function addClass(context: FeatureContext, name: string, rule?: postcss.Rule): ClassSymbol { | ||
if (!STSymbol.get(context.meta, name, `class`)) { | ||
let symbol = STSymbol.get(context.meta, name, `class`); | ||
if (!symbol) { | ||
let alias = STSymbol.get(context.meta, name); | ||
@@ -269,3 +271,3 @@ if (alias && alias._kind !== 'import') { | ||
} | ||
STSymbol.addSymbol({ | ||
symbol = STSymbol.addSymbol({ | ||
context, | ||
@@ -279,5 +281,5 @@ symbol: { | ||
safeRedeclare: !!alias, | ||
}); | ||
}) as ClassSymbol; | ||
STPart.registerLegacyPart(context.meta, name, { mapTo: symbol }); | ||
} | ||
const symbol = STSymbol.get(context.meta, name, `class`)!; | ||
// mark native css as global | ||
@@ -284,0 +286,0 @@ if (context.meta.type === 'css' && !symbol['-st-global']) { |
@@ -18,2 +18,4 @@ export type { FeatureContext, FeatureTransformContext } from './feature'; | ||
export * as STPart from './st-part'; | ||
export * as STCustomSelector from './st-custom-selector'; | ||
@@ -20,0 +22,0 @@ |
import { plugableRecord } from '../helpers/plugable-record'; | ||
import { createFeature } from './feature'; | ||
import { | ||
transformCustomSelectorMap, | ||
transformCustomSelectors, | ||
transformInlineCustomSelectorMap, | ||
transformInlineCustomSelectors, | ||
CustomSelectorMap, | ||
} from '../helpers/custom-selector'; | ||
import { parseSelectorWithCache } from '../helpers/selector'; | ||
import * as STPart from './st-part'; | ||
import * as postcss from 'postcss'; | ||
@@ -51,2 +52,3 @@ import { SelectorList, stringifySelectorAst } from '@tokey/css-selector-parser'; | ||
analyzed[name] = { selector, ast, isScoped, def: atRule }; | ||
STPart.registerLegacyPart(context.meta, name, { mapTo: ast }); | ||
} else { | ||
@@ -62,3 +64,3 @@ // TODO: add warn there are two types one is not valid name and the other is empty name. | ||
} | ||
const inlined = transformCustomSelectorMap(customSelectors, (report) => { | ||
const inlined = transformInlineCustomSelectorMap(customSelectors, (report) => { | ||
if (report.type === 'unknown' && analyzed[report.origin]) { | ||
@@ -146,3 +148,3 @@ const unknownSelector = `:--${report.unknown}`; | ||
const analyzed = plugableRecord.getUnsafe(meta.data, dataKey); | ||
const inlined = transformCustomSelectors( | ||
const inlined = transformInlineCustomSelectors( | ||
ast, | ||
@@ -149,0 +151,0 @@ (name) => analyzed[name]?.ast, |
@@ -8,3 +8,3 @@ import { createFeature, FeatureTransformContext } from './feature'; | ||
import type { ClassSymbol } from './css-class'; | ||
import { createSubsetAst } from '../helpers/rule'; | ||
import { createSubsetAst, isStMixinMarker } from '../helpers/rule'; | ||
import { scopeNestedSelector } from '../helpers/selector'; | ||
@@ -114,2 +114,13 @@ import { mixinHelperDiagnostics, parseStMixin, parseStPartialMixin } from '../helpers/mixin'; | ||
export const hooks = createFeature({ | ||
transformSelectorNode({ selectorContext, node }) { | ||
const isMarker = isStMixinMarker(node); | ||
if (isMarker) { | ||
selectorContext.setNextSelectorScope( | ||
selectorContext.inferredSelectorMixin, | ||
node, | ||
node.value | ||
); | ||
} | ||
return isMarker; | ||
}, | ||
transformLastPass({ context, ast, transformer, cssVarsMapping, path }) { | ||
@@ -427,3 +438,3 @@ ast.walkRules((rule) => appendMixins(context, transformer, rule, cssVarsMapping, path)); | ||
mergeRules(mixinRoot, config.rule, mixDef.data.originDecl, context.diagnostics); | ||
mergeRules(mixinRoot, config.rule, mixDef.data.originDecl, context.diagnostics, true); | ||
} | ||
@@ -504,7 +515,19 @@ | ||
if (roots.length === 1) { | ||
mergeRules(roots[0], config.rule, mixDef.data.originDecl, config.transformer.diagnostics); | ||
mergeRules( | ||
roots[0], | ||
config.rule, | ||
mixDef.data.originDecl, | ||
config.transformer.diagnostics, | ||
false | ||
); | ||
} else if (roots.length > 1) { | ||
const mixinRoot = postcss.root(); | ||
roots.forEach((root) => mixinRoot.prepend(...root.nodes)); | ||
mergeRules(mixinRoot, config.rule, mixDef.data.originDecl, config.transformer.diagnostics); | ||
mergeRules( | ||
mixinRoot, | ||
config.rule, | ||
mixDef.data.originDecl, | ||
config.transformer.diagnostics, | ||
false | ||
); | ||
} | ||
@@ -511,0 +534,0 @@ } |
@@ -83,3 +83,3 @@ import { createFeature } from './feature'; | ||
function isStScopeStatement(node: any): node is postcss.AtRule { | ||
export function isStScopeStatement(node: any): node is postcss.AtRule { | ||
return node.type === 'atrule' && node.name === 'st-scope'; | ||
@@ -86,0 +86,0 @@ } |
@@ -190,2 +190,3 @@ import { FeatureContext, createFeature } from './feature'; | ||
typeTable[name] = symbol; | ||
return symbol; | ||
} | ||
@@ -192,0 +193,0 @@ |
@@ -17,3 +17,3 @@ import { | ||
export function transformCustomSelectorMap( | ||
export function transformInlineCustomSelectorMap( | ||
customSelectors: CustomSelectorMap, | ||
@@ -28,3 +28,3 @@ report: (data: TransformCustomSelectorReport) => void | ||
} | ||
result[name] = transformCustomSelectors( | ||
result[name] = transformInlineCustomSelectors( | ||
ast, | ||
@@ -56,3 +56,10 @@ (nestedName) => { | ||
export function transformCustomSelectors( | ||
/** | ||
* Takes a list of selectors and a function that returns a selector | ||
* against a custom selector name. | ||
* | ||
* Then search for inline custom selectors (e.g. ":--custom") and | ||
* replaces them with the retrieved selectors it receives | ||
*/ | ||
export function transformInlineCustomSelectors( | ||
inputSelectors: SelectorList, | ||
@@ -64,3 +71,3 @@ getCustomSelector: (name: string) => SelectorList | undefined, | ||
for (const selector of inputSelectors) { | ||
result.push(...transformCustomSelector(selector, getCustomSelector, report)); | ||
result.push(...transformInlineCustomSelector(selector, getCustomSelector, report)); | ||
} | ||
@@ -70,3 +77,3 @@ return result; | ||
function transformCustomSelector( | ||
function transformInlineCustomSelector( | ||
inputSelector: Selector, | ||
@@ -73,0 +80,0 @@ getCustomSelector: (name: string) => SelectorList | undefined, |
@@ -15,5 +15,6 @@ import { | ||
SelectorList, | ||
SelectorNode, | ||
} from '@tokey/css-selector-parser'; | ||
import * as postcss from 'postcss'; | ||
import { transformCustomSelectors } from './custom-selector'; | ||
import { transformInlineCustomSelectors } from './custom-selector'; | ||
@@ -38,4 +39,4 @@ export function isChildOfAtRule(rule: postcss.Container, atRuleName: string) { | ||
export function createSubsetAst<T extends postcss.Root | postcss.AtRule>( | ||
root: postcss.Root | postcss.AtRule, | ||
export function createSubsetAst<T extends postcss.Root | postcss.AtRule | postcss.Rule>( | ||
root: postcss.Root | postcss.AtRule | postcss.Rule, | ||
selectorPrefix: string, | ||
@@ -45,3 +46,3 @@ mixinTarget?: T, | ||
getCustomSelector?: (name: string) => SelectorList | undefined, | ||
scopeSelector = '' | ||
isNestedInMixin = false | ||
): T { | ||
@@ -53,12 +54,13 @@ // keyframes on class mixin? | ||
const mixinRoot = mixinTarget ? mixinTarget : postcss.root(); | ||
const scopeSelectorAST = parseSelectorWithCache(scopeSelector); | ||
root.nodes.forEach((node) => { | ||
if (node.type === `rule` && (node.selector === ':vars' || node.selector === ':import')) { | ||
if (node.type === 'decl') { | ||
mixinTarget?.append(node.clone()); | ||
} else if ( | ||
node.type === `rule` && | ||
(node.selector === ':vars' || node.selector === ':import') | ||
) { | ||
// nodes that don't mix | ||
return; | ||
} else if (node.type === `rule`) { | ||
let selectorAst = parseSelectorWithCache(node.selector, { clone: true }); | ||
if (scopeSelector) { | ||
selectorAst = scopeNestedSelector(scopeSelectorAST, selectorAst, isRoot).ast; | ||
} | ||
const selectorAst = parseSelectorWithCache(node.selector, { clone: true }); | ||
let ast = isRoot | ||
@@ -68,7 +70,8 @@ ? scopeNestedSelector(prefixSelectorList, selectorAst, true).ast | ||
if (getCustomSelector) { | ||
ast = transformCustomSelectors(ast, getCustomSelector, () => { | ||
ast = transformInlineCustomSelectors(ast, getCustomSelector, () => { | ||
/*don't report*/ | ||
}); | ||
} | ||
const matchesSelectors = isRoot ? ast : ast.filter((node) => containsPrefix(node)); | ||
const matchesSelectors = | ||
isRoot || isNestedInMixin ? ast : ast.filter((node) => containsPrefix(node)); | ||
@@ -81,3 +84,3 @@ if (matchesSelectors.length) { | ||
} | ||
replaceTargetWithNesting(selectorNode, prefixType); | ||
replaceTargetWithMixinAnchor(selectorNode, prefixType); | ||
return selectorNode; | ||
@@ -87,3 +90,11 @@ }) | ||
mixinRoot.append(node.clone({ selector })); | ||
const clonedRule = createSubsetAst( | ||
node, | ||
selectorPrefix, | ||
node.clone({ selector, nodes: [] }), | ||
isRoot, | ||
getCustomSelector, | ||
true /*isNestedInMixin*/ | ||
); | ||
mixinRoot.append(clonedRule); | ||
} | ||
@@ -98,3 +109,22 @@ } else if (node.type === `atrule`) { | ||
) { | ||
const scopeSelector = node.name === 'st-scope' ? node.params : ''; | ||
let scopeSelector = node.name === 'st-scope' ? node.params : ''; | ||
let isNestedInMixin = false; | ||
if (scopeSelector) { | ||
const ast = parseSelectorWithCache(scopeSelector, { clone: true }); | ||
const matchesSelectors = isRoot | ||
? ast | ||
: ast.filter((node) => containsPrefix(node)); | ||
if (matchesSelectors.length) { | ||
isNestedInMixin = true; | ||
scopeSelector = stringifySelector( | ||
matchesSelectors.map((selectorNode) => { | ||
if (!isRoot) { | ||
selectorNode = fixChunkOrdering(selectorNode, prefixType); | ||
} | ||
replaceTargetWithMixinAnchor(selectorNode, prefixType); | ||
return selectorNode; | ||
}) | ||
); | ||
} | ||
} | ||
const atRuleSubset = createSubsetAst( | ||
@@ -104,3 +134,3 @@ node, | ||
postcss.atRule({ | ||
params: node.params, | ||
params: scopeSelector || node.params, | ||
name: node.name, | ||
@@ -110,3 +140,3 @@ }), | ||
getCustomSelector, | ||
scopeSelector | ||
isNestedInMixin | ||
); | ||
@@ -127,3 +157,6 @@ if (atRuleSubset.nodes) { | ||
function replaceTargetWithNesting(selectorNode: Selector, prefixType: ImmutableSelectorNode) { | ||
export const stMixinMarker = 'st-mixin-marker'; | ||
export const isStMixinMarker = (node: SelectorNode) => | ||
node.type === 'attribute' && node.value === stMixinMarker; | ||
function replaceTargetWithMixinAnchor(selectorNode: Selector, prefixType: ImmutableSelectorNode) { | ||
walkSelector(selectorNode, (node) => { | ||
@@ -133,4 +166,4 @@ if (matchTypeAndValue(node, prefixType)) { | ||
{ | ||
type: `nesting`, | ||
value: `&`, | ||
type: `attribute`, | ||
value: stMixinMarker, | ||
start: node.start, | ||
@@ -137,0 +170,0 @@ end: node.end, |
@@ -48,2 +48,6 @@ import { | ||
export function cloneSelector<T extends Selector | SelectorList>(s: T): T { | ||
return cloneDeep(s); | ||
} | ||
/** | ||
@@ -167,2 +171,3 @@ * returns for each selector if it contains only | ||
const isNestedNode = (node: SelectorNode) => node.type === 'nesting'; | ||
/** | ||
@@ -176,3 +181,4 @@ * combine 2 selector lists. | ||
nestedSelectorAst: ImmutableSelectorList, | ||
rootScopeLevel = false | ||
rootScopeLevel = false, | ||
isAnchor: (node: SelectorNode) => boolean = isNestedNode | ||
): { selector: string; ast: SelectorList } { | ||
@@ -205,3 +211,3 @@ const resultSelectors: SelectorList = []; | ||
walkSelector(outputAst, (node, i, nodes) => { | ||
if (node.type === 'nesting') { | ||
if (isAnchor(node)) { | ||
nestedMixRoot = true; | ||
@@ -208,0 +214,0 @@ nodes.splice(i, 1, { |
export { safeParse } from './parser'; | ||
export { processorDiagnostics, StylableProcessor } from './stylable-processor'; | ||
export { StylableProcessor } from './stylable-processor'; | ||
export { | ||
@@ -18,2 +18,3 @@ StylableTransformer, | ||
STNamespace, | ||
STPart, | ||
STCustomSelector, | ||
@@ -20,0 +21,0 @@ STCustomState, |
@@ -14,2 +14,3 @@ import type * as postcss from 'postcss'; | ||
STVar, | ||
STPart, | ||
STCustomSelector, | ||
@@ -34,2 +35,3 @@ STCustomState, | ||
STVar, | ||
STPart, | ||
STCustomSelector, | ||
@@ -36,0 +38,0 @@ STCustomState, |
import type * as postcss from 'postcss'; | ||
import { createDiagnosticReporter, Diagnostics } from './diagnostics'; | ||
import { Diagnostics } from './diagnostics'; | ||
import { knownPseudoClassesWithNestedSelectors } from './native-reserved-lists'; | ||
@@ -29,11 +29,2 @@ import { StylableMeta } from './stylable-meta'; | ||
export const processorDiagnostics = { | ||
INVALID_NESTING: createDiagnosticReporter( | ||
'11011', | ||
'error', | ||
(child: string, parent: string) => | ||
`nesting of rules within rules is not supported, found: "${child}" inside "${parent}"` | ||
), | ||
}; | ||
export class StylableProcessor implements FeatureContext { | ||
@@ -60,12 +51,2 @@ public meta!: StylableMeta; | ||
} | ||
const parent = rule.parent; | ||
if (parent?.type === 'rule') { | ||
this.diagnostics.report( | ||
processorDiagnostics.INVALID_NESTING( | ||
rule.selector, | ||
(parent as postcss.Rule).selector | ||
), | ||
{ node: rule } | ||
); | ||
} | ||
}); | ||
@@ -72,0 +53,0 @@ |
@@ -8,2 +8,3 @@ import isVendorPrefixed from 'is-vendor-prefixed'; | ||
import { | ||
cloneSelector, | ||
createCombinatorSelector, | ||
@@ -26,2 +27,3 @@ parseSelectorWithCache, | ||
import { | ||
STPart, | ||
ClassSymbol, | ||
@@ -196,3 +198,3 @@ CSSContains, | ||
mixinTransform = false, | ||
inferredNestSelector?: InferredSelector | ||
inferredSelectorMixin?: InferredSelector | ||
) { | ||
@@ -344,4 +346,4 @@ if (meta.type !== 'stylable') { | ||
node, | ||
(currentParent && this.containerInferredSelectorMap.get(currentParent)) || | ||
inferredNestSelector | ||
currentParent && this.containerInferredSelectorMap.get(currentParent), | ||
inferredSelectorMixin | ||
); | ||
@@ -418,2 +420,3 @@ // save results | ||
inferredNestSelector?: InferredSelector, | ||
inferredMixinSelector?: InferredSelector, | ||
unwrapGlobals = false | ||
@@ -431,3 +434,4 @@ ): { | ||
selector, | ||
inferredNestSelector | ||
inferredNestSelector, | ||
inferredMixinSelector | ||
); | ||
@@ -450,8 +454,5 @@ const targetSelectorAst = this.scopeSelectorAst(context); | ||
selectorStr?: string, | ||
selectorNest?: InferredSelector | ||
selectorNest?: InferredSelector, | ||
selectorMixin?: InferredSelector | ||
) { | ||
const inferredContext = this.createInferredSelector(meta, { | ||
name: meta.root, | ||
type: 'class', | ||
}); | ||
return new ScopeContext( | ||
@@ -464,4 +465,5 @@ meta, | ||
this, | ||
selectorNest || inferredContext.clone(), | ||
inferredContext, | ||
selectorNest, | ||
selectorMixin, | ||
undefined, | ||
selectorStr | ||
@@ -490,3 +492,3 @@ ); | ||
if (node.type === 'combinator') { | ||
if (this.experimentalSelectorInference) { | ||
if (this.experimentalSelectorInference || context.isNested) { | ||
context.setNextSelectorScope(context.inferredSelectorContext, node); | ||
@@ -609,2 +611,8 @@ } | ||
context.setNextSelectorScope(context.inferredSelectorNest, node, node.value); | ||
} else if (node.type === 'attribute') { | ||
STMixin.hooks.transformSelectorNode({ | ||
context: transformerContext, | ||
selectorContext: context, | ||
node, | ||
}); | ||
} | ||
@@ -832,8 +840,11 @@ } | ||
checked[name].add(uniqueId); | ||
// prefer custom selector | ||
const customSelector = STCustomSelector.getCustomSelectorExpended(meta, name); | ||
if (customSelector) { | ||
const selectorList = parseSelectorWithCache(customSelector, { | ||
clone: true, | ||
}); | ||
// | ||
const partDef = STPart.getPart(meta, name); | ||
if (!partDef) { | ||
continue; | ||
} | ||
if (Array.isArray(partDef.mapTo)) { | ||
// prefer custom selector | ||
const selectorList = cloneSelector(partDef.mapTo); | ||
const selectorStr = stringifySelector(partDef.mapTo); | ||
selectorList.forEach((selector) => { | ||
@@ -852,4 +863,4 @@ const r = removeFirstRootInFirstCompound(selector, meta); | ||
selectorList, | ||
postcss.rule({ selector: customSelector }), | ||
customSelector | ||
postcss.rule({ selector: selectorStr }), | ||
selectorStr | ||
); | ||
@@ -871,6 +882,4 @@ internalContext.isStandaloneSelector = isFirstInSelector; | ||
break resolved; | ||
} | ||
// matching class part | ||
const classSymbol = CSSClass.get(meta, name); | ||
if (classSymbol) { | ||
} else { | ||
// matching class part | ||
const resolvedPart = this.api.getResolvedSymbols(meta).class[name]; | ||
@@ -984,2 +993,4 @@ const resolvedBaseSymbol = getOriginDefinition(resolvedPart); | ||
public node?: CompoundSelector['nodes'][number]; | ||
// true for nested selector | ||
public isNested: boolean; | ||
// store selector duplication points | ||
@@ -990,4 +1001,6 @@ public splitSelectors = new SelectorMultiplier(); | ||
public isStandaloneSelector = true; | ||
// used for nesting or after combinators | ||
// used as initial selector or after combinators | ||
public inferredSelectorContext: InferredSelector; | ||
// used for nesting selector | ||
public inferredSelectorNest: InferredSelector; | ||
// current type while traversing a selector | ||
@@ -1004,8 +1017,40 @@ public inferredSelector: InferredSelector; | ||
private transformer: StylableTransformer, | ||
public inferredSelectorNest: InferredSelector, | ||
selectorContext: InferredSelector, | ||
inferredSelectorNest?: InferredSelector, | ||
public inferredSelectorMixin?: InferredSelector, | ||
inferredSelectorContext?: InferredSelector, | ||
selectorStr?: string | ||
) { | ||
this.isNested = !!( | ||
ruleOrAtRule.parent && | ||
// top level | ||
ruleOrAtRule.parent.type !== 'root' && | ||
// directly in @st-scope | ||
!STScope.isStScopeStatement(ruleOrAtRule.parent) | ||
); | ||
/* | ||
resolve default selector context for initial selector and selector | ||
following a combinator. | ||
Currently set to stylesheet root for top level selectors and selectors | ||
directly nested under @st-scope. But will change in the future to a universal selector | ||
once experimentalSelectorInference will be the default behavior | ||
*/ | ||
const inferredContext = | ||
inferredSelectorContext || | ||
(this.isNested || transformer.experimentalSelectorInference | ||
? new InferredSelector(transformer, [ | ||
{ | ||
_kind: 'css', | ||
meta: originMeta, | ||
symbol: { _kind: 'element', name: '*' }, | ||
}, | ||
]) | ||
: transformer.createInferredSelector(originMeta, { | ||
name: originMeta.root, | ||
type: 'class', | ||
})); | ||
// set selector data | ||
this.selectorStr = selectorStr || stringifySelector(selectorAst); | ||
this.inferredSelectorContext = new InferredSelector(this.transformer, selectorContext); | ||
this.inferredSelectorContext = new InferredSelector(this.transformer, inferredContext); | ||
this.inferredSelectorNest = inferredSelectorNest || this.inferredSelectorContext.clone(); | ||
this.inferredSelector = new InferredSelector( | ||
@@ -1057,2 +1102,3 @@ this.transformer, | ||
this.inferredSelectorNest, | ||
this.inferredSelectorMixin, | ||
selectorContext || this.inferredSelectorContext | ||
@@ -1059,0 +1105,0 @@ ); |
@@ -5,3 +5,3 @@ import { isAbsolute } from 'path'; | ||
import type { ImportSymbol, StylableSymbol } from './features'; | ||
import { isChildOfAtRule } from './helpers/rule'; | ||
import { isChildOfAtRule, stMixinMarker, isStMixinMarker } from './helpers/rule'; | ||
import { scopeNestedSelector, parseSelectorWithCache } from './helpers/selector'; | ||
@@ -26,6 +26,9 @@ | ||
mixinDecl: postcss.Declaration, | ||
report?: Diagnostics | ||
report: Diagnostics, | ||
useNestingAsAnchor: boolean | ||
) { | ||
let mixinRoot: postcss.Rule | null | 'NoRoot' = null; | ||
const nestedInKeyframes = isChildOfAtRule(rule, `keyframes`); | ||
const anchorSelector = useNestingAsAnchor ? '&' : '[' + stMixinMarker + ']'; | ||
const anchorNodeCheck = useNestingAsAnchor ? undefined : isStMixinMarker; | ||
mixinAst.walkRules((mixinRule: postcss.Rule) => { | ||
@@ -35,3 +38,3 @@ if (isChildOfAtRule(mixinRule, 'keyframes')) { | ||
} | ||
if (mixinRule.selector === '&' && !mixinRoot) { | ||
if (mixinRule.selector === anchorSelector && !mixinRoot) { | ||
if (mixinRule.parent === mixinAst) { | ||
@@ -42,3 +45,5 @@ mixinRoot = mixinRule; | ||
parseSelectorWithCache(rule.selector), | ||
parseSelectorWithCache(mixinRule.selector) | ||
parseSelectorWithCache(mixinRule.selector), | ||
false, | ||
anchorNodeCheck | ||
); | ||
@@ -51,3 +56,5 @@ mixinRoot = 'NoRoot'; | ||
parseSelectorWithCache(rule.selector), | ||
parseSelectorWithCache(mixinRule.selector) | ||
parseSelectorWithCache(mixinRule.selector), | ||
false, | ||
anchorNodeCheck | ||
); | ||
@@ -63,5 +70,5 @@ mixinRule.selector = selector; | ||
if (node === mixinRoot) { | ||
node.walkDecls((node) => { | ||
rule.insertBefore(mixinDecl, node); | ||
}); | ||
for (const nested of [...node.nodes]) { | ||
rule.insertBefore(mixinDecl, nested); | ||
} | ||
} else if (node.type === 'decl') { | ||
@@ -68,0 +75,0 @@ rule.insertBefore(mixinDecl, node); |
@@ -188,3 +188,3 @@ import type { CacheItem, FileProcessor, MinimalFS } from './cached-process-file'; | ||
const transformer = this.createTransformer(options); | ||
const r = transformer.scopeSelector(meta, selector, undefined, undefined, true); | ||
const r = transformer.scopeSelector(meta, selector, undefined, undefined, undefined, true); | ||
return { | ||
@@ -191,0 +191,0 @@ selector: r.selector, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1290298
313
23229
Updatedpostcss@^8.4.22