@stylable/core
Advanced tools
Comparing version 4.7.4 to 4.8.0
import { FileProcessor, MinimalFS } from './cached-process-file'; | ||
import { CssParser } from './parser'; | ||
import { processNamespace, StylableMeta } from './stylable-processor'; | ||
import { processNamespace } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import { TimedCacheOptions } from './timed-cache'; | ||
@@ -5,0 +6,0 @@ import type { Diagnostics } from './diagnostics'; |
import type * as postcss from 'postcss'; | ||
import type { Diagnostics } from './diagnostics'; | ||
import type { StylableMeta } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import type { CSSResolve, JSResolve, StylableResolver } from './stylable-resolver'; | ||
@@ -5,0 +5,0 @@ import type { replaceValueHook, StylableTransformer } from './stylable-transformer'; |
@@ -127,2 +127,5 @@ "use strict"; | ||
} | ||
else { | ||
// TODO: warn | ||
} | ||
} | ||
@@ -220,5 +223,2 @@ else if (value === '') { | ||
return { outputValue, topLevelType, typeError }; | ||
// TODO: handle calc (parse internals but maintain expression) | ||
// TODO: check this thing. native function that accent our function does not work | ||
// e.g: calc(getVarName()) | ||
} | ||
@@ -225,0 +225,0 @@ exports.processDeclarationValue = processDeclarationValue; |
export { CssParser, cssObjectToAst, cssParse, safeParse } from './parser'; | ||
export { CacheItem, FileProcessor, MinimalFS, cachedProcessFile, processFn, } from './cached-process-file'; | ||
export { CSSVarSymbol, ClassSymbol, DeclStylableProps, ElementSymbol, ImportSymbol, Imported, KeyframesSymbol, RESERVED_ROOT_NAME, RefedMixin, SDecl, SRule, SimpleSelector, StylableDirectives, StylableMeta, StylableProcessor, StylableSymbol, VarSymbol, createEmptyMeta, process, processNamespace, processorWarnings, validateScopingSelector, parsePseudoImport, } from './stylable-processor'; | ||
export { AdditionalSelector, KeyFrameWithNode, ResolvedElement, ScopedSelectorResults, StylableExports, StylableResults, StylableTransformer, TransformHooks, TransformerOptions, postProcessor, replaceValueHook, transformerWarnings, } from './stylable-transformer'; | ||
export { CUSTOM_SELECTOR_RE, createSubsetAst, expandCustomSelectors, findDeclaration, findRule, generateScopedCSSVar, getAlias, getDeclStylable, getSourcePath, isCSSVarProp, isValidClassName, isValidDeclaration, mergeRules, removeUnusedRules, scopeCSSVar, scopeSelector, transformMatchesOnRule, } from './stylable-utils'; | ||
export { CSSResolve, CachedModule, JSResolve, JsModule, StylableResolver, StylableResolverCache, isInPath, resolverWarnings, } from './stylable-resolver'; | ||
export type { CSSVarSymbol, ClassSymbol, ElementSymbol, ImportSymbol, Imported, KeyframesSymbol, RefedMixin, SimpleSelector, StylableDirectives, StylableSymbol, VarSymbol, } from './features'; | ||
export { StylableProcessor, createEmptyMeta, process, processNamespace, processorWarnings, validateScopingSelector, } from './stylable-processor'; | ||
export { ensureStylableImports } from './stylable-imports-tools'; | ||
export { StylableMeta, RESERVED_ROOT_NAME } from './stylable-meta'; | ||
export { KeyFrameWithNode, ResolvedElement, StylableExports, StylableResults, StylableTransformer, TransformHooks, TransformerOptions, postProcessor, replaceValueHook, transformerWarnings, } from './stylable-transformer'; | ||
export { CUSTOM_SELECTOR_RE, expandCustomSelectors, findDeclaration, generateScopedCSSVar, getAlias, getSourcePath, isCSSVarProp, isValidClassName, isValidDeclaration, mergeRules, scopeCSSVar, transformMatchesOnRule, } from './stylable-utils'; | ||
export { CSSResolve, JSResolve, JsModule, StylableResolver, StylableResolverCache, isInPath, resolverWarnings, } from './stylable-resolver'; | ||
export { Diagnostic, DiagnosticOptions, DiagnosticType, Diagnostics } from './diagnostics'; | ||
@@ -18,3 +21,2 @@ export { File, MinimalFSSetup, createMinimalFS } from './memory-minimal-fs'; | ||
export { StateParamType, StateResult, SubValidator, systemValidators } from './state-validators'; | ||
export { PseudoSelectorAstNode, SelectorAstNode, SelectorChunk, SelectorChunk2, Visitor, createChecker, createSimpleSelectorChecker, createWarningRule, filterChunkNodesByType, fixChunkOrdering, getOriginDefinition, isChildOfAtRule, isCompRoot, isGlobal, isImport, isNested, isNodeMatch, isRootValid, isSimpleSelector, matchAtKeyframes, matchAtMedia, matchSelectorTarget, mergeChunks, parseSelector, separateChunks, separateChunks2, stringifySelector, traverseNode, } from './selector-utils'; | ||
export { isCssNativeFunction, nativeFunctions, nativeFunctionsDic, nativePseudoClasses, nativePseudoElements, reservedKeyFrames, } from './native-reserved-lists'; | ||
@@ -27,3 +29,3 @@ export { noCollisionNamespace, packageNamespaceFactory } from './resolve-namespace-factories'; | ||
export { TimedCacheOptions, timedCache } from './timed-cache'; | ||
import { createBooleanStateClassName, createStateWithParamClassName, processPseudoStates, resolveStateParam, setStateToNode, validateStateArgument, validateStateDefinition } from './pseudo-states'; | ||
import { createBooleanStateClassName, createStateWithParamClassName, processPseudoStates, resolveStateParam, setStateToNode, validateStateArgument } from './pseudo-states'; | ||
export declare const pseudoStates: { | ||
@@ -44,2 +46,3 @@ booleanStateDelimiter: string; | ||
STATE_STARTS_WITH_HYPHEN: (name: string) => string; | ||
RESERVED_NATIVE_STATE: (name: string) => string; | ||
}; | ||
@@ -49,4 +52,69 @@ stateMiddleDelimiter: string; | ||
validateStateArgument: typeof validateStateArgument; | ||
validateStateDefinition: typeof validateStateDefinition; | ||
validateStateDefinition: (this: any, decl: import("postcss").Declaration, meta: import("./stylable-meta").StylableMeta, resolver: import("./stylable-resolver").StylableResolver, diagnostics: import("./diagnostics").Diagnostics) => void; | ||
}; | ||
export { getRuleScopeSelector } from './helpers/rule'; | ||
import { isCompRoot as deprecatedIsCompRoot } from './helpers/selector'; | ||
/**@deprecated*/ | ||
export declare const isCompRoot: typeof deprecatedIsCompRoot; | ||
import { isChildOfAtRule as deprecatedIsChildOfAtRule, createWarningRule as deprecatedCreateWarningRule } from './helpers/rule'; | ||
/**@deprecated*/ | ||
export declare const isChildOfAtRule: typeof deprecatedIsChildOfAtRule; | ||
/**@deprecated*/ | ||
export declare const createWarningRule: typeof deprecatedCreateWarningRule; | ||
import { getOriginDefinition as deprecatedGetOriginDefinition } from './helpers/resolve'; | ||
/**@deprecated*/ | ||
export declare const getOriginDefinition: typeof deprecatedGetOriginDefinition; | ||
export type { SRule, SDecl, DeclStylableProps } from './deprecated/postcss-ast-extension'; | ||
import { getDeclStylable as deprecatedGetDeclStylable } from './deprecated/postcss-ast-extension'; | ||
/**@deprecated*/ | ||
export declare const getDeclStylable: typeof deprecatedGetDeclStylable; | ||
import { scopeSelector as deprecatedScopeSelector, createSubsetAst as deprecatedCreateSubsetAst, removeUnusedRules as deprecatedRemoveUnusedRules, findRule as deprecatedFindRule } from './deprecated/deprecated-stylable-utils'; | ||
/**@deprecated*/ | ||
export declare const scopeSelector: typeof deprecatedScopeSelector; | ||
/**@deprecated*/ | ||
export declare const createSubsetAst: typeof deprecatedCreateSubsetAst; | ||
/**@deprecated*/ | ||
export declare const removeUnusedRules: typeof deprecatedRemoveUnusedRules; | ||
/**@deprecated*/ | ||
export declare const findRule: typeof deprecatedFindRule; | ||
export type { SelectorChunk, SelectorChunk2, Visitor, SelectorAstNode, PseudoSelectorAstNode, } from './deprecated/deprecated-selector-utils'; | ||
import { matchSelectorTarget as deprecatedMatchSelectorTarget, fixChunkOrdering as deprecatedFixChunkOrdering, filterChunkNodesByType as deprecatedFilterChunkNodesByType, separateChunks as deprecatedSeparateChunks, separateChunks2 as deprecatedSeparateChunks2, mergeChunks as deprecatedMergeChunks, matchAtMedia as deprecatedMatchAtMedia, matchAtKeyframes as deprecatedMatchAtKeyframes, isImport as deprecatedIsImport, isSimpleSelector as deprecatedIsSimpleSelector, isRootValid as deprecatedIsRootValid, isGlobal as deprecatedIsGlobal, createChecker as deprecatedCreateChecker, isNested as deprecatedIsNested, traverseNode as deprecatedTraverseNode, parseSelector as deprecatedParseSelector, stringifySelector as deprecatedStringifySelector, isNodeMatch as deprecatedIsNodeMatch } from './deprecated/deprecated-selector-utils'; | ||
/**@deprecated*/ | ||
export declare const matchSelectorTarget: typeof deprecatedMatchSelectorTarget; | ||
/**@deprecated*/ | ||
export declare const fixChunkOrdering: typeof deprecatedFixChunkOrdering; | ||
/**@deprecated*/ | ||
export declare const filterChunkNodesByType: typeof deprecatedFilterChunkNodesByType; | ||
/**@deprecated*/ | ||
export declare const separateChunks: typeof deprecatedSeparateChunks; | ||
/**@deprecated*/ | ||
export declare const separateChunks2: typeof deprecatedSeparateChunks2; | ||
/**@deprecated*/ | ||
export declare const mergeChunks: typeof deprecatedMergeChunks; | ||
/**@deprecated*/ | ||
export declare const matchAtMedia: typeof deprecatedMatchAtMedia; | ||
/**@deprecated*/ | ||
export declare const matchAtKeyframes: typeof deprecatedMatchAtKeyframes; | ||
/**@deprecated*/ | ||
export declare const isImport: typeof deprecatedIsImport; | ||
/**@deprecated*/ | ||
export declare const isSimpleSelector: typeof deprecatedIsSimpleSelector; | ||
/**@deprecated*/ | ||
export declare const isRootValid: typeof deprecatedIsRootValid; | ||
/**@deprecated*/ | ||
export declare const isGlobal: typeof deprecatedIsGlobal; | ||
/**@deprecated*/ | ||
export declare const createChecker: typeof deprecatedCreateChecker; | ||
/**@deprecated*/ | ||
export declare const isNested: typeof deprecatedIsNested; | ||
/**@deprecated*/ | ||
export declare const isNodeMatch: typeof deprecatedIsNodeMatch; | ||
/**@deprecated*/ | ||
export declare const traverseNode: typeof deprecatedTraverseNode; | ||
/**@deprecated*/ | ||
export declare const parseSelector: typeof deprecatedParseSelector; | ||
/**@deprecated*/ | ||
export declare const stringifySelector: typeof deprecatedStringifySelector; | ||
/**@deprecated*/ | ||
export declare const createSimpleSelectorChecker: () => (node: import("./deprecated/deprecated-selector-utils").SelectorAstNode) => boolean; | ||
//# sourceMappingURL=index.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.rootValueMapping = exports.paramMapping = exports.mixinDeclRegExp = exports.listOptions = exports.groupValues = exports.globalValueRegExp = exports.getStringValue = exports.getNamedArgs = exports.getFormatterArgs = exports.animationPropRegExp = exports.STYLABLE_VALUE_MATCHER = exports.STYLABLE_NAMED_MATCHER = exports.SBTypesParsers = exports.createMinimalFS = exports.Diagnostics = exports.resolverWarnings = exports.isInPath = exports.StylableResolver = exports.transformMatchesOnRule = exports.scopeSelector = exports.scopeCSSVar = exports.removeUnusedRules = exports.mergeRules = exports.isValidDeclaration = exports.isValidClassName = exports.isCSSVarProp = exports.getSourcePath = exports.getDeclStylable = exports.getAlias = exports.generateScopedCSSVar = exports.findRule = exports.findDeclaration = exports.expandCustomSelectors = exports.createSubsetAst = exports.CUSTOM_SELECTOR_RE = exports.transformerWarnings = exports.StylableTransformer = exports.parsePseudoImport = exports.validateScopingSelector = exports.processorWarnings = exports.processNamespace = exports.process = exports.createEmptyMeta = exports.StylableProcessor = exports.StylableMeta = exports.RESERVED_ROOT_NAME = exports.cachedProcessFile = exports.safeParse = exports.cssParse = exports.cssObjectToAst = void 0; | ||
exports.parseSelector = exports.mergeChunks = exports.matchSelectorTarget = exports.matchAtMedia = exports.matchAtKeyframes = exports.isSimpleSelector = exports.isRootValid = exports.isNodeMatch = exports.isNested = exports.isImport = exports.isGlobal = exports.isCompRoot = exports.isChildOfAtRule = exports.getOriginDefinition = exports.fixChunkOrdering = exports.filterChunkNodesByType = exports.createWarningRule = exports.createSimpleSelectorChecker = exports.createChecker = exports.systemValidators = exports.unbox = exports.stTypes = exports.resolveCustomValues = exports.isCustomValue = exports.getBoxValue = exports.createCustomValue = exports.box = exports.CustomValueStrategy = exports.resolveArgumentsValue = exports.processDeclarationValue = exports.functionWarnings = exports.evalDeclarationValue = exports.makeAbsolute = exports.isUrl = exports.isExternal = exports.isAsset = exports.fixRelativeUrls = exports.collectAssets = exports.assureRelativeUrlPrefix = exports.mixinWarnings = exports.appendMixins = exports.appendMixin = exports.Stylable = exports.createInfrastructure = exports.valueParserWarnings = exports.valueMapping = exports.validateAllowedNodesUntil = exports.strategies = exports.stValuesMap = exports.stValues = void 0; | ||
exports.pseudoStates = exports.timedCache = exports.murmurhash3_32_gc = exports.visitMetaCSSDependenciesBFS = exports.emitDiagnostics = exports.createDefaultResolver = exports.packageNamespaceFactory = exports.noCollisionNamespace = exports.reservedKeyFrames = exports.nativePseudoElements = exports.nativePseudoClasses = exports.nativeFunctionsDic = exports.isCssNativeFunction = exports.traverseNode = exports.stringifySelector = exports.separateChunks2 = exports.separateChunks = void 0; | ||
exports.valueMapping = exports.validateAllowedNodesUntil = exports.strategies = exports.stValuesMap = exports.stValues = exports.rootValueMapping = exports.paramMapping = exports.mixinDeclRegExp = exports.listOptions = exports.groupValues = exports.globalValueRegExp = exports.getStringValue = exports.getNamedArgs = exports.getFormatterArgs = exports.animationPropRegExp = exports.STYLABLE_VALUE_MATCHER = exports.STYLABLE_NAMED_MATCHER = exports.SBTypesParsers = exports.createMinimalFS = exports.Diagnostics = exports.resolverWarnings = exports.isInPath = exports.StylableResolver = exports.transformMatchesOnRule = exports.scopeCSSVar = exports.mergeRules = exports.isValidDeclaration = exports.isValidClassName = exports.isCSSVarProp = exports.getSourcePath = exports.getAlias = exports.generateScopedCSSVar = exports.findDeclaration = exports.expandCustomSelectors = exports.CUSTOM_SELECTOR_RE = exports.transformerWarnings = exports.StylableTransformer = exports.RESERVED_ROOT_NAME = exports.StylableMeta = exports.ensureStylableImports = exports.validateScopingSelector = exports.processorWarnings = exports.processNamespace = exports.process = exports.createEmptyMeta = exports.StylableProcessor = exports.cachedProcessFile = exports.safeParse = exports.cssParse = exports.cssObjectToAst = void 0; | ||
exports.matchSelectorTarget = exports.findRule = exports.removeUnusedRules = exports.createSubsetAst = exports.scopeSelector = exports.getDeclStylable = exports.getOriginDefinition = exports.createWarningRule = exports.isChildOfAtRule = exports.isCompRoot = exports.getRuleScopeSelector = exports.pseudoStates = exports.timedCache = exports.murmurhash3_32_gc = exports.visitMetaCSSDependenciesBFS = exports.emitDiagnostics = exports.createDefaultResolver = exports.packageNamespaceFactory = exports.noCollisionNamespace = exports.reservedKeyFrames = exports.nativePseudoElements = exports.nativePseudoClasses = exports.nativeFunctionsDic = exports.isCssNativeFunction = exports.systemValidators = exports.unbox = exports.stTypes = exports.resolveCustomValues = exports.isCustomValue = exports.getBoxValue = exports.createCustomValue = exports.box = exports.CustomValueStrategy = exports.resolveArgumentsValue = exports.processDeclarationValue = exports.functionWarnings = exports.evalDeclarationValue = exports.makeAbsolute = exports.isUrl = exports.isExternal = exports.isAsset = exports.fixRelativeUrls = exports.collectAssets = exports.assureRelativeUrlPrefix = exports.mixinWarnings = exports.appendMixins = exports.appendMixin = exports.Stylable = exports.createInfrastructure = exports.valueParserWarnings = void 0; | ||
exports.createSimpleSelectorChecker = exports.stringifySelector = exports.parseSelector = exports.traverseNode = exports.isNodeMatch = exports.isNested = exports.createChecker = exports.isGlobal = exports.isRootValid = exports.isSimpleSelector = exports.isImport = exports.matchAtKeyframes = exports.matchAtMedia = exports.mergeChunks = exports.separateChunks2 = exports.separateChunks = exports.filterChunkNodesByType = exports.fixChunkOrdering = void 0; | ||
var parser_1 = require("./parser"); | ||
@@ -13,4 +13,2 @@ Object.defineProperty(exports, "cssObjectToAst", { enumerable: true, get: function () { return parser_1.cssObjectToAst; } }); | ||
var stylable_processor_1 = require("./stylable-processor"); | ||
Object.defineProperty(exports, "RESERVED_ROOT_NAME", { enumerable: true, get: function () { return stylable_processor_1.RESERVED_ROOT_NAME; } }); | ||
Object.defineProperty(exports, "StylableMeta", { enumerable: true, get: function () { return stylable_processor_1.StylableMeta; } }); | ||
Object.defineProperty(exports, "StylableProcessor", { enumerable: true, get: function () { return stylable_processor_1.StylableProcessor; } }); | ||
@@ -22,3 +20,7 @@ Object.defineProperty(exports, "createEmptyMeta", { enumerable: true, get: function () { return stylable_processor_1.createEmptyMeta; } }); | ||
Object.defineProperty(exports, "validateScopingSelector", { enumerable: true, get: function () { return stylable_processor_1.validateScopingSelector; } }); | ||
Object.defineProperty(exports, "parsePseudoImport", { enumerable: true, get: function () { return stylable_processor_1.parsePseudoImport; } }); | ||
var stylable_imports_tools_1 = require("./stylable-imports-tools"); | ||
Object.defineProperty(exports, "ensureStylableImports", { enumerable: true, get: function () { return stylable_imports_tools_1.ensureStylableImports; } }); | ||
var stylable_meta_1 = require("./stylable-meta"); | ||
Object.defineProperty(exports, "StylableMeta", { enumerable: true, get: function () { return stylable_meta_1.StylableMeta; } }); | ||
Object.defineProperty(exports, "RESERVED_ROOT_NAME", { enumerable: true, get: function () { return stylable_meta_1.RESERVED_ROOT_NAME; } }); | ||
var stylable_transformer_1 = require("./stylable-transformer"); | ||
@@ -29,9 +31,6 @@ Object.defineProperty(exports, "StylableTransformer", { enumerable: true, get: function () { return stylable_transformer_1.StylableTransformer; } }); | ||
Object.defineProperty(exports, "CUSTOM_SELECTOR_RE", { enumerable: true, get: function () { return stylable_utils_1.CUSTOM_SELECTOR_RE; } }); | ||
Object.defineProperty(exports, "createSubsetAst", { enumerable: true, get: function () { return stylable_utils_1.createSubsetAst; } }); | ||
Object.defineProperty(exports, "expandCustomSelectors", { enumerable: true, get: function () { return stylable_utils_1.expandCustomSelectors; } }); | ||
Object.defineProperty(exports, "findDeclaration", { enumerable: true, get: function () { return stylable_utils_1.findDeclaration; } }); | ||
Object.defineProperty(exports, "findRule", { enumerable: true, get: function () { return stylable_utils_1.findRule; } }); | ||
Object.defineProperty(exports, "generateScopedCSSVar", { enumerable: true, get: function () { return stylable_utils_1.generateScopedCSSVar; } }); | ||
Object.defineProperty(exports, "getAlias", { enumerable: true, get: function () { return stylable_utils_1.getAlias; } }); | ||
Object.defineProperty(exports, "getDeclStylable", { enumerable: true, get: function () { return stylable_utils_1.getDeclStylable; } }); | ||
Object.defineProperty(exports, "getSourcePath", { enumerable: true, get: function () { return stylable_utils_1.getSourcePath; } }); | ||
@@ -42,5 +41,3 @@ Object.defineProperty(exports, "isCSSVarProp", { enumerable: true, get: function () { return stylable_utils_1.isCSSVarProp; } }); | ||
Object.defineProperty(exports, "mergeRules", { enumerable: true, get: function () { return stylable_utils_1.mergeRules; } }); | ||
Object.defineProperty(exports, "removeUnusedRules", { enumerable: true, get: function () { return stylable_utils_1.removeUnusedRules; } }); | ||
Object.defineProperty(exports, "scopeCSSVar", { enumerable: true, get: function () { return stylable_utils_1.scopeCSSVar; } }); | ||
Object.defineProperty(exports, "scopeSelector", { enumerable: true, get: function () { return stylable_utils_1.scopeSelector; } }); | ||
Object.defineProperty(exports, "transformMatchesOnRule", { enumerable: true, get: function () { return stylable_utils_1.transformMatchesOnRule; } }); | ||
@@ -107,26 +104,2 @@ var stylable_resolver_1 = require("./stylable-resolver"); | ||
Object.defineProperty(exports, "systemValidators", { enumerable: true, get: function () { return state_validators_1.systemValidators; } }); | ||
var selector_utils_1 = require("./selector-utils"); | ||
Object.defineProperty(exports, "createChecker", { enumerable: true, get: function () { return selector_utils_1.createChecker; } }); | ||
Object.defineProperty(exports, "createSimpleSelectorChecker", { enumerable: true, get: function () { return selector_utils_1.createSimpleSelectorChecker; } }); | ||
Object.defineProperty(exports, "createWarningRule", { enumerable: true, get: function () { return selector_utils_1.createWarningRule; } }); | ||
Object.defineProperty(exports, "filterChunkNodesByType", { enumerable: true, get: function () { return selector_utils_1.filterChunkNodesByType; } }); | ||
Object.defineProperty(exports, "fixChunkOrdering", { enumerable: true, get: function () { return selector_utils_1.fixChunkOrdering; } }); | ||
Object.defineProperty(exports, "getOriginDefinition", { enumerable: true, get: function () { return selector_utils_1.getOriginDefinition; } }); | ||
Object.defineProperty(exports, "isChildOfAtRule", { enumerable: true, get: function () { return selector_utils_1.isChildOfAtRule; } }); | ||
Object.defineProperty(exports, "isCompRoot", { enumerable: true, get: function () { return selector_utils_1.isCompRoot; } }); | ||
Object.defineProperty(exports, "isGlobal", { enumerable: true, get: function () { return selector_utils_1.isGlobal; } }); | ||
Object.defineProperty(exports, "isImport", { enumerable: true, get: function () { return selector_utils_1.isImport; } }); | ||
Object.defineProperty(exports, "isNested", { enumerable: true, get: function () { return selector_utils_1.isNested; } }); | ||
Object.defineProperty(exports, "isNodeMatch", { enumerable: true, get: function () { return selector_utils_1.isNodeMatch; } }); | ||
Object.defineProperty(exports, "isRootValid", { enumerable: true, get: function () { return selector_utils_1.isRootValid; } }); | ||
Object.defineProperty(exports, "isSimpleSelector", { enumerable: true, get: function () { return selector_utils_1.isSimpleSelector; } }); | ||
Object.defineProperty(exports, "matchAtKeyframes", { enumerable: true, get: function () { return selector_utils_1.matchAtKeyframes; } }); | ||
Object.defineProperty(exports, "matchAtMedia", { enumerable: true, get: function () { return selector_utils_1.matchAtMedia; } }); | ||
Object.defineProperty(exports, "matchSelectorTarget", { enumerable: true, get: function () { return selector_utils_1.matchSelectorTarget; } }); | ||
Object.defineProperty(exports, "mergeChunks", { enumerable: true, get: function () { return selector_utils_1.mergeChunks; } }); | ||
Object.defineProperty(exports, "parseSelector", { enumerable: true, get: function () { return selector_utils_1.parseSelector; } }); | ||
Object.defineProperty(exports, "separateChunks", { enumerable: true, get: function () { return selector_utils_1.separateChunks; } }); | ||
Object.defineProperty(exports, "separateChunks2", { enumerable: true, get: function () { return selector_utils_1.separateChunks2; } }); | ||
Object.defineProperty(exports, "stringifySelector", { enumerable: true, get: function () { return selector_utils_1.stringifySelector; } }); | ||
Object.defineProperty(exports, "traverseNode", { enumerable: true, get: function () { return selector_utils_1.traverseNode; } }); | ||
var native_reserved_lists_1 = require("./native-reserved-lists"); | ||
@@ -165,2 +138,123 @@ Object.defineProperty(exports, "isCssNativeFunction", { enumerable: true, get: function () { return native_reserved_lists_1.isCssNativeFunction; } }); | ||
}; | ||
var rule_1 = require("./helpers/rule"); | ||
Object.defineProperty(exports, "getRuleScopeSelector", { enumerable: true, get: function () { return rule_1.getRuleScopeSelector; } }); | ||
// *** deprecated *** | ||
const deprecation_1 = require("./helpers/deprecation"); | ||
const selector_1 = require("./helpers/selector"); | ||
/**@deprecated*/ | ||
exports.isCompRoot = (0, deprecation_1.wrapFunctionForDeprecation)(selector_1.isCompRoot, { | ||
name: `isCompRoot`, | ||
}); | ||
const rule_2 = require("./helpers/rule"); | ||
/**@deprecated*/ | ||
exports.isChildOfAtRule = (0, deprecation_1.wrapFunctionForDeprecation)(rule_2.isChildOfAtRule, { | ||
name: `isChildOfAtRule`, | ||
}); | ||
/**@deprecated*/ | ||
exports.createWarningRule = (0, deprecation_1.wrapFunctionForDeprecation)(rule_2.createWarningRule, { | ||
name: `createWarningRule`, | ||
}); | ||
const resolve_1 = require("./helpers/resolve"); | ||
/**@deprecated*/ | ||
exports.getOriginDefinition = (0, deprecation_1.wrapFunctionForDeprecation)(resolve_1.getOriginDefinition, { | ||
name: `getOriginDefinition`, | ||
}); | ||
const postcss_ast_extension_1 = require("./deprecated/postcss-ast-extension"); | ||
/**@deprecated*/ | ||
exports.getDeclStylable = (0, deprecation_1.wrapFunctionForDeprecation)(postcss_ast_extension_1.getDeclStylable, { | ||
name: `getDeclStylable`, | ||
}); | ||
const deprecated_stylable_utils_1 = require("./deprecated/deprecated-stylable-utils"); | ||
/**@deprecated*/ | ||
exports.scopeSelector = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_stylable_utils_1.scopeSelector, { | ||
name: `scopeSelector`, | ||
}); | ||
/**@deprecated*/ | ||
exports.createSubsetAst = deprecated_stylable_utils_1.createSubsetAst; | ||
/**@deprecated*/ | ||
exports.removeUnusedRules = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_stylable_utils_1.removeUnusedRules, { | ||
name: `removeUnusedRules`, | ||
}); | ||
/**@deprecated*/ | ||
exports.findRule = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_stylable_utils_1.findRule, { | ||
name: `findRule`, | ||
}); | ||
const deprecated_selector_utils_1 = require("./deprecated/deprecated-selector-utils"); | ||
/**@deprecated*/ | ||
exports.matchSelectorTarget = deprecated_selector_utils_1.matchSelectorTarget; | ||
/**@deprecated*/ | ||
exports.fixChunkOrdering = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.fixChunkOrdering, { | ||
name: `fixChunkOrdering`, | ||
}); | ||
/**@deprecated*/ | ||
exports.filterChunkNodesByType = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.filterChunkNodesByType, { | ||
name: `filterChunkNodesByType`, | ||
}); | ||
/**@deprecated*/ | ||
exports.separateChunks = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.separateChunks, { | ||
name: `separateChunks`, | ||
}); | ||
/**@deprecated*/ | ||
exports.separateChunks2 = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.separateChunks2, { | ||
name: `separateChunks2`, | ||
}); | ||
/**@deprecated*/ | ||
exports.mergeChunks = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.mergeChunks, { | ||
name: `mergeChunks`, | ||
}); | ||
/**@deprecated*/ | ||
exports.matchAtMedia = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.matchAtMedia, { | ||
name: `matchAtMedia`, | ||
}); | ||
/**@deprecated*/ | ||
exports.matchAtKeyframes = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.matchAtKeyframes, { | ||
name: `matchAtKeyframes`, | ||
}); | ||
/**@deprecated*/ | ||
exports.isImport = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.isImport, { | ||
name: `isImport`, | ||
}); | ||
/**@deprecated*/ | ||
exports.isSimpleSelector = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.isSimpleSelector, { | ||
name: `isSimpleSelector`, | ||
}); | ||
/**@deprecated*/ | ||
exports.isRootValid = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.isRootValid, { | ||
name: `isRootValid`, | ||
}); | ||
/**@deprecated*/ | ||
exports.isGlobal = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.isGlobal, { | ||
name: `isGlobal`, | ||
}); | ||
/**@deprecated*/ | ||
exports.createChecker = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.createChecker, { | ||
name: `createChecker`, | ||
}); | ||
/**@deprecated*/ | ||
exports.isNested = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.isNested, { | ||
name: `isNested`, | ||
}); | ||
/**@deprecated*/ | ||
exports.isNodeMatch = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.isNodeMatch, { | ||
name: `isNodeMatch`, | ||
}); | ||
/**@deprecated*/ | ||
exports.traverseNode = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.traverseNode, { | ||
name: `traverseNode`, | ||
pleaseUse: `"import { walk } from '@tokey/css-selector-parser'"`, | ||
}); | ||
/**@deprecated*/ | ||
exports.parseSelector = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.parseSelector, { | ||
name: `parseSelector`, | ||
pleaseUse: `"import { parseCssSelector } from '@tokey/css-selector-parser'"`, | ||
}); | ||
/**@deprecated*/ | ||
exports.stringifySelector = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.stringifySelector, { | ||
name: `stringifySelector`, | ||
pleaseUse: `"import { stringifySelector } from '@tokey/css-selector-parser'"`, | ||
}); | ||
/**@deprecated*/ | ||
exports.createSimpleSelectorChecker = (0, deprecation_1.wrapFunctionForDeprecation)(deprecated_selector_utils_1.createSimpleSelectorChecker, { | ||
name: `createSimpleSelectorChecker`, | ||
}); | ||
//# sourceMappingURL=index.js.map |
export declare const nativePseudoClasses: string[]; | ||
/** | ||
* list names of pseudo classes that cannot be override by custom states | ||
* // [breaking] ToDo: add names of general pseudo classes that are not specific to elements | ||
* // like: root, only-child, nth-of-type, nth-last-child, nth-last-of-type, only-of-type... | ||
*/ | ||
export declare const reservedPseudoClasses: string[]; | ||
export declare const nativePseudoElements: string[]; | ||
@@ -3,0 +9,0 @@ export declare const reservedKeyFrames: string[]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isCssNativeFunction = exports.nativeFunctionsDic = exports.reservedKeyFrames = exports.nativePseudoElements = exports.nativePseudoClasses = void 0; | ||
exports.isCssNativeFunction = exports.nativeFunctionsDic = exports.reservedKeyFrames = exports.nativePseudoElements = exports.reservedPseudoClasses = exports.nativePseudoClasses = void 0; | ||
// MDN reference: https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes | ||
@@ -55,2 +55,18 @@ exports.nativePseudoClasses = [ | ||
]; | ||
/** | ||
* list names of pseudo classes that cannot be override by custom states | ||
* // [breaking] ToDo: add names of general pseudo classes that are not specific to elements | ||
* // like: root, only-child, nth-of-type, nth-last-child, nth-last-of-type, only-of-type... | ||
*/ | ||
exports.reservedPseudoClasses = [ | ||
`not`, | ||
`any`, | ||
`matches`, | ||
`is`, | ||
`where`, | ||
`has`, | ||
// not native | ||
`global`, | ||
`local`, | ||
]; | ||
exports.nativePseudoElements = [ | ||
@@ -57,0 +73,0 @@ 'after', |
import type * as postcss from 'postcss'; | ||
import type { Diagnostics } from './diagnostics'; | ||
import type { SelectorAstNode } from './selector-utils'; | ||
import type { PseudoClass } from '@tokey/css-selector-parser'; | ||
import { StateResult } from './state-validators'; | ||
import type { StylableMeta } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import type { StylableResolver } from './stylable-resolver'; | ||
@@ -20,10 +20,11 @@ import { MappedStates } from './stylable-value-parsers'; | ||
STATE_STARTS_WITH_HYPHEN: (name: string) => string; | ||
RESERVED_NATIVE_STATE: (name: string) => string; | ||
}; | ||
export declare function processPseudoStates(value: string, decl: postcss.Declaration, diagnostics: Diagnostics): MappedStates; | ||
export declare function validateStateDefinition(decl: postcss.Declaration, meta: StylableMeta, resolver: StylableResolver, diagnostics: Diagnostics): void; | ||
export declare const validateStateDefinition: (this: any, decl: postcss.Declaration, meta: StylableMeta, resolver: StylableResolver, diagnostics: Diagnostics) => void; | ||
export declare function validateStateArgument(stateAst: StateParsedValue, meta: StylableMeta, value: string, resolver: StylableResolver, diagnostics: Diagnostics, rule?: postcss.Rule, validateDefinition?: boolean, validateValue?: boolean): StateResult; | ||
export declare function setStateToNode(states: MappedStates, meta: StylableMeta, name: string, node: SelectorAstNode, namespace: string, resolver: StylableResolver, diagnostics: Diagnostics, rule?: postcss.Rule): void; | ||
export declare function setStateToNode(states: MappedStates, meta: StylableMeta, name: string, node: PseudoClass, namespace: string, resolver: StylableResolver, diagnostics: Diagnostics, rule?: postcss.Rule): void; | ||
export declare function createBooleanStateClassName(stateName: string, namespace: string): string; | ||
export declare function createStateWithParamClassName(stateName: string, namespace: string, param: string): string; | ||
export declare function resolveStateParam(param: string): string; | ||
export declare function resolveStateParam(param: string, escape?: boolean): string; | ||
//# sourceMappingURL=pseudo-states.d.ts.map |
@@ -9,2 +9,4 @@ "use strict"; | ||
const functions_1 = require("./functions"); | ||
const selector_1 = require("./helpers/selector"); | ||
const deprecation_1 = require("./helpers/deprecation"); | ||
const state_validators_1 = require("./state-validators"); | ||
@@ -14,2 +16,4 @@ const stylable_value_parsers_1 = require("./stylable-value-parsers"); | ||
const utils_1 = require("./utils"); | ||
const native_reserved_lists_1 = require("./native-reserved-lists"); | ||
const cssesc_1 = __importDefault(require("cssesc")); | ||
exports.stateMiddleDelimiter = '-'; | ||
@@ -26,2 +30,3 @@ exports.booleanStateDelimiter = '--'; | ||
STATE_STARTS_WITH_HYPHEN: (name) => `state "${name}" declaration cannot begin with a "${exports.stateMiddleDelimiter}" character`, | ||
RESERVED_NATIVE_STATE: (name) => `state "${name}" is reserved for native pseudo-class`, | ||
}; | ||
@@ -40,2 +45,8 @@ // PROCESS | ||
} | ||
else if (native_reserved_lists_1.reservedPseudoClasses.includes(stateDefinition.value)) { | ||
diagnostics.warn(decl, exports.stateErrors.RESERVED_NATIVE_STATE(stateDefinition.value), { | ||
word: stateDefinition.value, | ||
}); | ||
return; | ||
} | ||
if (stateDefinition.type === 'function') { | ||
@@ -67,3 +78,3 @@ resolveStateType(stateDefinition, mappedStates, stateDefault, diagnostics, decl); | ||
const stateType = { | ||
type: stateDefinition.nodes[0].value, | ||
type: paramType.value, | ||
arguments: [], | ||
@@ -128,12 +139,14 @@ defaultValue: postcss_value_parser_1.default | ||
// TRANSFORM | ||
function validateStateDefinition(decl, meta, resolver, diagnostics) { | ||
/* @deprecated */ | ||
exports.validateStateDefinition = (0, deprecation_1.wrapFunctionForDeprecation)(function (decl, meta, resolver, diagnostics) { | ||
if (decl.parent && decl.parent.type !== 'root') { | ||
const container = decl.parent; | ||
if (container.type !== 'atrule') { | ||
const sRule = container; | ||
if (sRule.selectorAst.nodes && sRule.selectorAst.nodes.length === 1) { | ||
const singleSelectorAst = sRule.selectorAst.nodes[0]; | ||
const parentRule = container; | ||
const selectorAst = (0, selector_1.parseSelectorWithCache)(parentRule.selector); | ||
if (selectorAst.length && selectorAst.length === 1) { | ||
const singleSelectorAst = selectorAst[0]; | ||
const selectorChunk = singleSelectorAst.nodes; | ||
if (selectorChunk.length === 1 && selectorChunk[0].type === 'class') { | ||
const className = selectorChunk[0].name; | ||
const className = selectorChunk[0].value; | ||
const classMeta = meta.classes[className]; | ||
@@ -146,3 +159,3 @@ const states = classMeta[stylable_value_parsers_2.valueMapping.states]; | ||
if (state && typeof state === 'object') { | ||
const res = validateStateArgument(state, meta, state.defaultValue || '', resolver, diagnostics, sRule, true, !!state.defaultValue); | ||
const res = validateStateArgument(state, meta, state.defaultValue || '', resolver, diagnostics, parentRule, true, !!state.defaultValue); | ||
if (res.errors) { | ||
@@ -164,4 +177,3 @@ res.errors.unshift(`pseudo-state "${stateName}" default value "${state.defaultValue}" failed validation:`); | ||
} | ||
} | ||
exports.validateStateDefinition = validateStateDefinition; | ||
}, { name: `validateStateDefinition` }); | ||
function validateStateArgument(stateAst, meta, value, resolver, diagnostics, rule, validateDefinition, validateValue = true) { | ||
@@ -189,8 +201,7 @@ const resolvedValidations = { | ||
if (stateDef === null) { | ||
node.type = 'class'; | ||
node.name = createBooleanStateClassName(name, namespace); | ||
(0, selector_1.convertToClass)(node).value = createBooleanStateClassName(name, namespace); | ||
} | ||
else if (typeof stateDef === 'string') { | ||
node.type = 'invalid'; // simply concat global mapped selector - ToDo: maybe change to 'selector' | ||
node.value = stateDef; | ||
// simply concat global mapped selector - ToDo: maybe change to 'selector' | ||
(0, selector_1.convertToInvalid)(node).value = stateDef; | ||
} | ||
@@ -200,7 +211,9 @@ else if (typeof stateDef === 'object') { | ||
} | ||
delete node.nodes; | ||
} | ||
exports.setStateToNode = setStateToNode; | ||
function resolveStateValue(meta, resolver, diagnostics, rule, node, stateDef, name, namespace) { | ||
let actualParam = resolveParam(meta, resolver, diagnostics, rule, node.content || stateDef.defaultValue); | ||
if (rule && !node.content && !stateDef.defaultValue) { | ||
const inputValue = node.nodes && node.nodes.length ? (0, selector_1.stringifySelector)(node.nodes) : ``; | ||
let actualParam = resolveParam(meta, resolver, diagnostics, rule, inputValue ? inputValue : stateDef.defaultValue); | ||
if (rule && !inputValue && !stateDef.defaultValue) { | ||
diagnostics.warn(rule, exports.stateErrors.NO_STATE_ARGUMENT_GIVEN(name, stateDef.type), { | ||
@@ -228,4 +241,3 @@ word: name, | ||
const strippedParam = (0, utils_1.stripQuotation)(actualParam); | ||
node.type = 'class'; | ||
node.name = createStateWithParamClassName(name, namespace, strippedParam); | ||
(0, selector_1.convertToClass)(node).value = createStateWithParamClassName(name, namespace, strippedParam); | ||
} | ||
@@ -238,13 +250,17 @@ function resolveParam(meta, resolver, diagnostics, rule, nodeContent) { | ||
function createBooleanStateClassName(stateName, namespace) { | ||
return `${namespace}${exports.booleanStateDelimiter}${stateName}`; | ||
const escapedNamespace = (0, cssesc_1.default)(namespace, { isIdentifier: true }); | ||
return `${escapedNamespace}${exports.booleanStateDelimiter}${stateName}`; | ||
} | ||
exports.createBooleanStateClassName = createBooleanStateClassName; | ||
function createStateWithParamClassName(stateName, namespace, param) { | ||
return `${namespace}${exports.stateWithParamDelimiter}${stateName}${resolveStateParam(param)}`; | ||
const escapedNamespace = (0, cssesc_1.default)(namespace, { isIdentifier: true }); | ||
return `${escapedNamespace}${exports.stateWithParamDelimiter}${stateName}${resolveStateParam(param, true)}`; | ||
} | ||
exports.createStateWithParamClassName = createStateWithParamClassName; | ||
function resolveStateParam(param) { | ||
return `${exports.stateMiddleDelimiter}${param.length}${exports.stateMiddleDelimiter}${param.replace(/\s/gm, '_')}`; | ||
function resolveStateParam(param, escape = false) { | ||
const result = `${exports.stateMiddleDelimiter}${param.length}${exports.stateMiddleDelimiter}${param.replace(/\s/gm, '_')}`; | ||
// adding/removing initial `s` to indicate that it's not the first param of the identifier | ||
return escape ? (0, cssesc_1.default)(`s` + result, { isIdentifier: true }).slice(1) : result; | ||
} | ||
exports.resolveStateParam = resolveStateParam; | ||
//# sourceMappingURL=pseudo-states.js.map |
@@ -1,2 +0,2 @@ | ||
import type { StylableMeta } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
export interface EmitDiagnosticsContext { | ||
@@ -3,0 +3,0 @@ emitError(e: Error): void; |
import type * as postcss from 'postcss'; | ||
import type { CSSVarSymbol, ClassSymbol, ElementSymbol, Imported, KeyframesSymbol, RefedMixin, SimpleSelector, StylableSymbol, VarSymbol } from './features'; | ||
import type { Diagnostics } from './diagnostics'; | ||
import type { SelectorAstNode, SelectorChunk2 } from './selector-utils'; | ||
import { MappedStates, MixinValue } from './stylable-value-parsers'; | ||
import type { SelectorList } from '@tokey/css-selector-parser'; | ||
export declare const RESERVED_ROOT_NAME = "root"; | ||
@@ -25,3 +25,3 @@ export declare class StylableMeta { | ||
transformDiagnostics: Diagnostics | null; | ||
transformedScopes: Record<string, SelectorChunk2[][]> | null; | ||
transformedScopes: Record<string, SelectorList> | null; | ||
scopes: postcss.AtRule[]; | ||
@@ -34,64 +34,2 @@ simpleSelectors: Record<string, SimpleSelector>; | ||
} | ||
export interface Imported { | ||
from: string; | ||
defaultExport: string; | ||
named: Record<string, string>; | ||
keyframes: Record<string, string>; | ||
rule: postcss.Rule | postcss.AtRule; | ||
request: string; | ||
context: string; | ||
} | ||
export interface StylableDirectives { | ||
'-st-root'?: boolean; | ||
'-st-states'?: MappedStates; | ||
'-st-extends'?: ImportSymbol | ClassSymbol | ElementSymbol; | ||
'-st-global'?: SelectorAstNode[]; | ||
} | ||
export interface ClassSymbol extends StylableDirectives { | ||
_kind: 'class'; | ||
name: string; | ||
alias?: ImportSymbol; | ||
scoped?: string; | ||
} | ||
export interface ElementSymbol extends StylableDirectives { | ||
_kind: 'element'; | ||
name: string; | ||
alias?: ImportSymbol; | ||
} | ||
export interface ImportSymbol { | ||
_kind: 'import'; | ||
type: 'named' | 'default'; | ||
name: string; | ||
import: Imported; | ||
context: string; | ||
} | ||
export interface VarSymbol { | ||
_kind: 'var'; | ||
name: string; | ||
value: string; | ||
text: string; | ||
valueType: string | null; | ||
node: postcss.Node; | ||
} | ||
export interface KeyframesSymbol { | ||
_kind: 'keyframes'; | ||
alias: string; | ||
name: string; | ||
import?: Imported; | ||
global?: boolean; | ||
} | ||
export interface CSSVarSymbol { | ||
_kind: 'cssVar'; | ||
name: string; | ||
global: boolean; | ||
} | ||
export declare type StylableSymbol = ImportSymbol | VarSymbol | ClassSymbol | ElementSymbol | CSSVarSymbol | KeyframesSymbol; | ||
export interface RefedMixin { | ||
mixin: MixinValue; | ||
ref: ImportSymbol | ClassSymbol; | ||
} | ||
export interface SimpleSelector { | ||
symbol: ClassSymbol | ElementSymbol; | ||
node: postcss.Rule | postcss.Root; | ||
} | ||
//# sourceMappingURL=stylable-meta.d.ts.map |
@@ -5,2 +5,3 @@ "use strict"; | ||
const stylable_utils_1 = require("./stylable-utils"); | ||
const deprecation_1 = require("./helpers/deprecation"); | ||
const stylable_value_parsers_1 = require("./stylable-value-parsers"); | ||
@@ -38,2 +39,3 @@ exports.RESERVED_ROOT_NAME = 'root'; | ||
this.simpleSelectors = {}; | ||
(0, deprecation_1.setFieldForDeprecation)(this, `mixins`, { objectType: `stylableMeta` }); | ||
this.mixins = []; | ||
@@ -40,0 +42,0 @@ this.transformDiagnostics = null; |
@@ -1,2 +0,4 @@ | ||
import type { RefedMixin, SRule, StylableMeta } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import type { RefedMixin } from './features'; | ||
import type { SRule } from './deprecated/postcss-ast-extension'; | ||
import type { StylableTransformer } from './stylable-transformer'; | ||
@@ -3,0 +5,0 @@ export declare const mixinWarnings: { |
@@ -28,4 +28,6 @@ "use strict"; | ||
const stylable_assets_1 = require("./stylable-assets"); | ||
const rule_1 = require("./helpers/rule"); | ||
const stylable_utils_1 = require("./stylable-utils"); | ||
const stylable_value_parsers_1 = require("./stylable-value-parsers"); | ||
const deprecation_1 = require("./helpers/deprecation"); | ||
exports.mixinWarnings = { | ||
@@ -46,9 +48,10 @@ FAILED_TO_APPLY_MIXIN(error) { | ||
function appendMixins(transformer, rule, meta, variableOverride, cssVarsMapping, path = []) { | ||
if (!rule.mixins || rule.mixins.length === 0) { | ||
const mixins = (0, deprecation_1.ignoreDeprecationWarn)(() => rule.mixins); | ||
if (!mixins || mixins.length === 0) { | ||
return; | ||
} | ||
rule.mixins.forEach((mix) => { | ||
mixins.forEach((mix) => { | ||
appendMixin(mix, transformer, rule, meta, variableOverride, cssVarsMapping, path); | ||
}); | ||
rule.mixins.length = 0; | ||
mixins.length = 0; | ||
rule.walkDecls(stylable_value_parsers_1.mixinDeclRegExp, (node) => { | ||
@@ -127,3 +130,3 @@ node.remove(); | ||
const isRootMixin = resolvedClass.symbol.name === resolvedClass.meta.root; | ||
const mixinRoot = (0, stylable_utils_1.createSubsetAst)(resolvedClass.meta.ast, (resolvedClass.symbol._kind === 'class' ? '.' : '') + resolvedClass.symbol.name, undefined, isRootMixin); | ||
const mixinRoot = (0, rule_1.createSubsetAst)(resolvedClass.meta.ast, (resolvedClass.symbol._kind === 'class' ? '.' : '') + resolvedClass.symbol.name, undefined, isRootMixin); | ||
const namedArgs = mix.mixin.options; | ||
@@ -187,3 +190,3 @@ if (mix.mixin.partial) { | ||
const resolvedArgs = (0, functions_1.resolveArgumentsValue)(namedArgs, transformer, meta, transformer.diagnostics, mixinDecl, variableOverride, path, cssVarsMapping); | ||
const mixinRoot = (0, stylable_utils_1.createSubsetAst)(meta.ast, '.' + mix.ref.name, undefined, isRootMixin); | ||
const mixinRoot = (0, rule_1.createSubsetAst)(meta.ast, '.' + mix.ref.name, undefined, isRootMixin); | ||
if (isPartial) { | ||
@@ -190,0 +193,0 @@ filterPartialMixinDecl(meta, mixinRoot, overrideKeys); |
import * as postcss from 'postcss'; | ||
import { Diagnostics } from './diagnostics'; | ||
import { SelectorAstNode } from './selector-utils'; | ||
import { Imported, RefedMixin, StylableDirectives, StylableMeta } from './stylable-meta'; | ||
import { StylableMeta } from './stylable-meta'; | ||
import type { Imported, StylableDirectives } from './features'; | ||
import type { ImmutableSelectorNode } from '@tokey/css-selector-parser'; | ||
import type { SRule } from './deprecated/postcss-ast-extension'; | ||
export * from './stylable-meta'; | ||
export declare const processorWarnings: { | ||
UNSCOPED_CLASS(name: string): string; | ||
UNSCOPED_ELEMENT(name: string): string; | ||
UNSCOPED_TYPE_SELECTOR(name: string): string; | ||
FORBIDDEN_DEF_IN_COMPLEX_SELECTOR(name: string): string; | ||
ROOT_AFTER_SPACING(): string; | ||
DEFAULT_IMPORT_IS_LOWER_CASE(): string; | ||
ILLEGAL_PROP_IN_IMPORT(propName: string): string; | ||
STATE_DEFINITION_IN_ELEMENT(): string; | ||
@@ -24,13 +24,7 @@ STATE_DEFINITION_IN_COMPLEX(): string; | ||
PARTIAL_MIXIN_MISSING_ARGUMENTS(type: string): string; | ||
FROM_PROP_MISSING_IN_IMPORT(): string; | ||
INVALID_NAMESPACE_DEF(): string; | ||
EMPTY_NAMESPACE_DEF(): string; | ||
EMPTY_IMPORT_FROM(): string; | ||
MULTIPLE_FROM_IN_IMPORT(): string; | ||
NO_VARS_DEF_IN_ST_SCOPE(): string; | ||
NO_IMPORT_IN_ST_SCOPE(): string; | ||
NO_ST_IMPORT_IN_NESTED_SCOPE(): string; | ||
ST_IMPORT_STAR(): string; | ||
ST_IMPORT_EMPTY_FROM(): string; | ||
INVALID_ST_IMPORT_FORMAT(errors: string[]): string; | ||
NO_KEYFRAMES_IN_ST_SCOPE(): string; | ||
@@ -47,2 +41,3 @@ MISSING_SCOPING_PARAM(): string; | ||
INVALID_NESTING(child: string, parent: string): string; | ||
INVALID_FUNCTIONAL_SELECTOR(selector: string, type: string): string; | ||
DEPRECATED_ST_GLOBAL_CUSTOM_PROPERTY(): string; | ||
@@ -66,4 +61,4 @@ DEPRECATED_ST_FUNCTION_NAME: (name: string, alternativeName: string) => string; | ||
protected checkRedeclareSymbol(symbolName: string, node: postcss.Node): void; | ||
protected checkRedeclareKeyframes(symbolName: string, node: postcss.Node): import("./stylable-meta").KeyframesSymbol; | ||
protected checkForScopedNodeAfter(rule: postcss.Rule, nodes: SelectorAstNode[], index: number): boolean; | ||
protected checkRedeclareKeyframes(symbolName: string, node: postcss.Node): import("./features").KeyframesSymbol; | ||
protected checkForScopedNodeAfter(rule: postcss.Rule, nodes: ImmutableSelectorNode[], index: number): boolean; | ||
protected addElementSymbolOnce(name: string, rule: postcss.Rule): void; | ||
@@ -79,7 +74,5 @@ protected addClassSymbolOnce(name: string, rule: postcss.Rule): void; | ||
protected extendTypedRule(node: postcss.Node, selector: string, key: keyof StylableDirectives, value: any): void; | ||
protected handleStImport(atRule: postcss.AtRule): Imported; | ||
private handleScope; | ||
private checkForInvalidAsUsage; | ||
} | ||
export declare function parsePseudoImport(rule: postcss.Rule, context: string, diagnostics: Diagnostics): Imported; | ||
export declare function validateScopingSelector(atRule: postcss.AtRule, { selector: scopingSelector }: SRule, diagnostics: Diagnostics): void; | ||
@@ -89,15 +82,2 @@ export declare function createEmptyMeta(root: postcss.Root, diagnostics: Diagnostics): StylableMeta; | ||
export declare function process(root: postcss.Root, diagnostics?: Diagnostics, resolveNamespace?: typeof processNamespace): StylableMeta; | ||
export interface SRule extends postcss.Rule { | ||
selectorAst: SelectorAstNode; | ||
isSimpleSelector: boolean; | ||
selectorType: 'class' | 'element' | 'complex'; | ||
mixins?: RefedMixin[]; | ||
stScopeSelector?: string; | ||
} | ||
export interface DeclStylableProps { | ||
sourceValue: string; | ||
} | ||
export interface SDecl extends postcss.Declaration { | ||
stylable: DeclStylableProps; | ||
} | ||
//# sourceMappingURL=stylable-processor.d.ts.map |
@@ -28,20 +28,22 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.process = exports.processNamespace = exports.createEmptyMeta = exports.validateScopingSelector = exports.parsePseudoImport = exports.StylableProcessor = exports.processorWarnings = void 0; | ||
exports.process = exports.processNamespace = exports.createEmptyMeta = exports.validateScopingSelector = exports.StylableProcessor = exports.processorWarnings = void 0; | ||
const path_1 = __importDefault(require("path")); | ||
const postcss = __importStar(require("postcss")); | ||
const postcss_value_parser_1 = __importDefault(require("postcss-value-parser")); | ||
const toky_1 = require("toky"); | ||
const custom_values_1 = require("./custom-values"); | ||
const diagnostics_1 = require("./diagnostics"); | ||
const deprecated_selector_utils_1 = require("./deprecated/deprecated-selector-utils"); | ||
const murmurhash_1 = require("./murmurhash"); | ||
const native_reserved_lists_1 = require("./native-reserved-lists"); | ||
const selector_utils_1 = require("./selector-utils"); | ||
const stylable_meta_1 = require("./stylable-meta"); | ||
const stylable_utils_1 = require("./stylable-utils"); | ||
const process_declaration_functions_1 = require("./process-declaration-functions"); | ||
const selector_1 = require("./helpers/selector"); | ||
const rule_1 = require("./helpers/rule"); | ||
const stylable_value_parsers_1 = require("./stylable-value-parsers"); | ||
const utils_1 = require("./utils"); | ||
const deprecation_1 = require("./helpers/deprecation"); | ||
const validate_at_property_1 = require("./validate-at-property"); | ||
const stylable_imports_tools_1 = require("./stylable-imports-tools"); | ||
__exportStar(require("./stylable-meta"), exports); /* TEMP EXPORT */ | ||
const parseNamed = stylable_value_parsers_1.SBTypesParsers[stylable_value_parsers_1.valueMapping.named]; | ||
const parseStates = stylable_value_parsers_1.SBTypesParsers[stylable_value_parsers_1.valueMapping.states]; | ||
@@ -54,4 +56,4 @@ const parseGlobal = stylable_value_parsers_1.SBTypesParsers[stylable_value_parsers_1.valueMapping.global]; | ||
}, | ||
UNSCOPED_ELEMENT(name) { | ||
return `unscoped element "${name}" will affect all elements of the same type in the document`; | ||
UNSCOPED_TYPE_SELECTOR(name) { | ||
return `unscoped type selector "${name}" will affect all elements of the same type in the document`; | ||
}, | ||
@@ -64,10 +66,4 @@ FORBIDDEN_DEF_IN_COMPLEX_SELECTOR(name) { | ||
}, | ||
DEFAULT_IMPORT_IS_LOWER_CASE() { | ||
return 'Default import of a Stylable stylesheet must start with an upper-case letter'; | ||
}, | ||
ILLEGAL_PROP_IN_IMPORT(propName) { | ||
return `"${propName}" css attribute cannot be used inside ${stylable_value_parsers_1.rootValueMapping.import} block`; | ||
}, | ||
STATE_DEFINITION_IN_ELEMENT() { | ||
return 'cannot define pseudo states inside element selectors'; | ||
return 'cannot define pseudo states inside a type selector'; | ||
}, | ||
@@ -104,5 +100,2 @@ STATE_DEFINITION_IN_COMPLEX() { | ||
}, | ||
FROM_PROP_MISSING_IN_IMPORT() { | ||
return `"${stylable_value_parsers_1.valueMapping.from}" is missing in ${stylable_value_parsers_1.rootValueMapping.import} block`; | ||
}, | ||
INVALID_NAMESPACE_DEF() { | ||
@@ -114,8 +107,2 @@ return 'invalid @namespace'; | ||
}, | ||
EMPTY_IMPORT_FROM() { | ||
return '"-st-from" cannot be empty'; | ||
}, | ||
MULTIPLE_FROM_IN_IMPORT() { | ||
return `cannot define multiple "${stylable_value_parsers_1.valueMapping.from}" declarations in a single import`; | ||
}, | ||
NO_VARS_DEF_IN_ST_SCOPE() { | ||
@@ -130,11 +117,2 @@ return `cannot define "${stylable_value_parsers_1.rootValueMapping.vars}" inside of "@st-scope"`; | ||
}, | ||
ST_IMPORT_STAR() { | ||
return '@st-import * is not supported'; | ||
}, | ||
ST_IMPORT_EMPTY_FROM() { | ||
return '@st-import must specify a valid "from" string value'; | ||
}, | ||
INVALID_ST_IMPORT_FORMAT(errors) { | ||
return `Invalid @st-import format:\n - ${errors.join('\n - ')}`; | ||
}, | ||
NO_KEYFRAMES_IN_ST_SCOPE() { | ||
@@ -173,2 +151,5 @@ return `cannot use "@keyframes" inside of "@st-scope"`; | ||
}, | ||
INVALID_FUNCTIONAL_SELECTOR(selector, type) { | ||
return `"${selector}" ${type} is not functional`; | ||
}, | ||
DEPRECATED_ST_GLOBAL_CUSTOM_PROPERTY() { | ||
@@ -193,3 +174,3 @@ return `"st-global-custom-property" is deprecated and will be removed in the next version. Use "@property" with ${stylable_value_parsers_1.paramMapping.global}`; | ||
if (node.type === 'rule' && node.selector === stylable_value_parsers_1.rootValueMapping.import) { | ||
const imported = parsePseudoImport(node, this.dirContext, this.diagnostics); | ||
const imported = (0, stylable_imports_tools_1.parsePseudoImport)(node, this.dirContext, this.diagnostics); | ||
this.meta.imports.push(imported); | ||
@@ -200,5 +181,5 @@ this.addImportSymbols(imported); | ||
root.walkRules((rule) => { | ||
if (!(0, selector_utils_1.isChildOfAtRule)(rule, 'keyframes')) { | ||
if (!(0, rule_1.isChildOfAtRule)(rule, 'keyframes')) { | ||
this.handleCustomSelectors(rule); | ||
this.handleRule(rule, (0, selector_utils_1.isChildOfAtRule)(rule, stylable_value_parsers_1.rootValueMapping.stScope)); | ||
this.handleRule(rule, (0, rule_1.isChildOfAtRule)(rule, stylable_value_parsers_1.rootValueMapping.stScope)); | ||
} | ||
@@ -262,3 +243,3 @@ const parent = rule.parent; | ||
case 'keyframes': | ||
if (!(0, selector_utils_1.isChildOfAtRule)(atRule, stylable_value_parsers_1.rootValueMapping.stScope)) { | ||
if (!(0, rule_1.isChildOfAtRule)(atRule, stylable_value_parsers_1.rootValueMapping.stScope)) { | ||
this.meta.keyframes.push(atRule); | ||
@@ -294,3 +275,3 @@ let { params: name } = atRule; | ||
else { | ||
this.diagnostics.warn(atRule, exports.processorWarnings.NO_KEYFRAMES_IN_ST_SCOPE()); | ||
this.diagnostics.error(atRule, exports.processorWarnings.NO_KEYFRAMES_IN_ST_SCOPE()); | ||
} | ||
@@ -321,3 +302,4 @@ break; | ||
else { | ||
const stImport = this.handleStImport(atRule); | ||
const stImport = (0, stylable_imports_tools_1.parseStImport)(atRule, this.dirContext, this.diagnostics); | ||
atRule.remove(); | ||
this.meta.imports.push(stImport); | ||
@@ -406,23 +388,24 @@ this.addImportSymbols(stImport); | ||
handleRule(rule, inStScope = false) { | ||
rule.selectorAst = (0, selector_utils_1.parseSelector)(rule.selector); | ||
const checker = (0, selector_utils_1.createSimpleSelectorChecker)(); | ||
rule.selectorAst = (0, deprecated_selector_utils_1.parseSelector)(rule.selector); | ||
const selectorAst = (0, selector_1.parseSelectorWithCache)(rule.selector); | ||
let locallyScoped = false; | ||
(0, selector_utils_1.traverseNode)(rule.selectorAst, (node, index, nodes, parents) => { | ||
if (node.type === 'selector' && !(0, selector_utils_1.isNested)(parents)) { | ||
let simpleSelector; | ||
(0, selector_1.walkSelector)(selectorAst, (node, index, nodes, parents) => { | ||
const type = node.type; | ||
if (type === 'selector' && !(0, selector_1.isInPseudoClassContext)(parents)) { | ||
locallyScoped = false; | ||
} | ||
if (!checker(node)) { | ||
rule.isSimpleSelector = false; | ||
if (type !== `selector` && type !== `class` && type !== `type`) { | ||
simpleSelector = false; | ||
} | ||
const { name, type } = node; | ||
if (type === 'pseudo-class') { | ||
if (name === 'import') { | ||
if (node.type === 'pseudo_class') { | ||
if (node.value === 'import') { | ||
if (rule.selector === stylable_value_parsers_1.rootValueMapping.import) { | ||
if ((0, selector_utils_1.isChildOfAtRule)(rule, stylable_value_parsers_1.rootValueMapping.stScope)) { | ||
if ((0, rule_1.isChildOfAtRule)(rule, stylable_value_parsers_1.rootValueMapping.stScope)) { | ||
this.diagnostics.warn(rule, exports.processorWarnings.NO_IMPORT_IN_ST_SCOPE()); | ||
rule.remove(); | ||
return false; | ||
return selector_1.walkSelector.stopAll; | ||
} | ||
rule.remove(); | ||
return false; | ||
return selector_1.walkSelector.stopAll; | ||
} | ||
@@ -433,11 +416,11 @@ else { | ||
} | ||
else if (name === 'vars') { | ||
else if (node.value === 'vars') { | ||
if (rule.selector === stylable_value_parsers_1.rootValueMapping.vars) { | ||
if ((0, selector_utils_1.isChildOfAtRule)(rule, stylable_value_parsers_1.rootValueMapping.stScope)) { | ||
if ((0, rule_1.isChildOfAtRule)(rule, stylable_value_parsers_1.rootValueMapping.stScope)) { | ||
this.diagnostics.warn(rule, exports.processorWarnings.NO_VARS_DEF_IN_ST_SCOPE()); | ||
rule.remove(); | ||
return false; | ||
return selector_1.walkSelector.stopAll; | ||
} | ||
this.addVarSymbols(rule); | ||
return false; | ||
return selector_1.walkSelector.stopAll; | ||
} | ||
@@ -448,7 +431,15 @@ else { | ||
} | ||
else if (node.value === `global`) { | ||
return selector_1.walkSelector.skipNested; | ||
} | ||
} | ||
else if (type === 'class') { | ||
this.addClassSymbolOnce(name, rule); | ||
if (this.meta.classes[name]) { | ||
if (!this.meta.classes[name].alias) { | ||
else if (node.type === 'class') { | ||
this.addClassSymbolOnce(node.value, rule); | ||
if (node.nodes) { | ||
this.diagnostics.error(rule, exports.processorWarnings.INVALID_FUNCTIONAL_SELECTOR(`.` + node.value, `class`), { | ||
word: (0, selector_1.stringifySelector)(node), | ||
}); | ||
} | ||
if (this.meta.classes[node.value]) { | ||
if (!this.meta.classes[node.value].alias) { | ||
locallyScoped = true; | ||
@@ -458,4 +449,4 @@ } | ||
if (this.checkForScopedNodeAfter(rule, nodes, index) === false) { | ||
this.diagnostics.warn(rule, exports.processorWarnings.UNSCOPED_CLASS(name), { | ||
word: name, | ||
this.diagnostics.warn(rule, exports.processorWarnings.UNSCOPED_CLASS(node.value), { | ||
word: node.value, | ||
}); | ||
@@ -469,8 +460,21 @@ } | ||
} | ||
else if (type === 'element') { | ||
this.addElementSymbolOnce(name, rule); | ||
else if (node.type === 'type') { | ||
this.addElementSymbolOnce(node.value, rule); | ||
/** | ||
* intent to deprecate: currently `value(param)` can be used | ||
* as a custom state value. Unless there is a reasonable | ||
* use case, this should be removed. | ||
*/ | ||
if (node.nodes && | ||
(parents.length < 2 || | ||
parents[parents.length - 2].type !== `pseudo_class` || | ||
node.value !== `value`)) { | ||
this.diagnostics.error(rule, exports.processorWarnings.INVALID_FUNCTIONAL_SELECTOR(node.value, `type`), { | ||
word: (0, selector_1.stringifySelector)(node), | ||
}); | ||
} | ||
if (locallyScoped === false && !inStScope) { | ||
if (this.checkForScopedNodeAfter(rule, nodes, index) === false) { | ||
this.diagnostics.warn(rule, exports.processorWarnings.UNSCOPED_ELEMENT(name), { | ||
word: name, | ||
this.diagnostics.warn(rule, exports.processorWarnings.UNSCOPED_TYPE_SELECTOR(node.value), { | ||
word: node.value, | ||
}); | ||
@@ -483,8 +487,26 @@ } | ||
} | ||
else if (type === 'nested-pseudo-class' && name === 'global') { | ||
return true; | ||
else if (node.type === `id`) { | ||
if (node.nodes) { | ||
this.diagnostics.error(rule, exports.processorWarnings.INVALID_FUNCTIONAL_SELECTOR(`#` + node.value, `id`), { | ||
word: (0, selector_1.stringifySelector)(node), | ||
}); | ||
} | ||
} | ||
return void 0; | ||
else if (node.type === `attribute`) { | ||
if (node.nodes) { | ||
this.diagnostics.error(rule, exports.processorWarnings.INVALID_FUNCTIONAL_SELECTOR(`[${node.value}]`, `attribute`), { | ||
word: (0, selector_1.stringifySelector)(node), | ||
}); | ||
} | ||
} | ||
else if (node.type === `nesting`) { | ||
if (node.nodes) { | ||
this.diagnostics.error(rule, exports.processorWarnings.INVALID_FUNCTIONAL_SELECTOR(node.value, `nesting`), { | ||
word: (0, selector_1.stringifySelector)(node), | ||
}); | ||
} | ||
} | ||
return; | ||
}); | ||
if (rule.isSimpleSelector !== false) { | ||
if (simpleSelector !== false) { | ||
rule.isSimpleSelector = true; | ||
@@ -496,3 +518,4 @@ rule.selectorType = rule.selector.match(/^\./) ? 'class' : 'element'; | ||
} | ||
if (!(0, selector_utils_1.isRootValid)(rule.selectorAst, 'root')) { | ||
// ToDo: check cases of root in nested selectors? | ||
if (!(0, selector_1.isRootValid)(selectorAst)) { | ||
this.diagnostics.warn(rule, exports.processorWarnings.ROOT_AFTER_SPACING()); | ||
@@ -522,11 +545,12 @@ } | ||
if (!element) { | ||
// ToDo: can this get here??? | ||
break; | ||
} | ||
if (element.type === 'spacing' || element.type === 'operator') { | ||
if (element.type === 'combinator') { | ||
break; | ||
} | ||
if (element.type === 'class') { | ||
this.addClassSymbolOnce(element.name, rule); | ||
if (this.meta.classes[element.name]) { | ||
if (!this.meta.classes[element.name].alias) { | ||
this.addClassSymbolOnce(element.value, rule); | ||
if (this.meta.classes[element.value]) { | ||
if (!this.meta.classes[element.value].alias) { | ||
return true; | ||
@@ -540,3 +564,3 @@ } | ||
addElementSymbolOnce(name, rule) { | ||
if ((0, selector_utils_1.isCompRoot)(name) && !this.meta.elements[name]) { | ||
if ((0, selector_1.isCompRoot)(name) && !this.meta.elements[name]) { | ||
let alias = this.meta.mappedSymbols[name]; | ||
@@ -691,8 +715,13 @@ if (alias && alias._kind !== 'import') { | ||
handleDirectives(rule, decl) { | ||
const isSimplePerSelector = (0, selector_1.isSimpleSelector)(rule.selector); | ||
const type = isSimplePerSelector.reduce((accType, { type }) => { | ||
return !accType ? type : accType !== type ? `complex` : type; | ||
}, ``); | ||
const isSimple = type !== `complex`; | ||
if (decl.prop === stylable_value_parsers_1.valueMapping.states) { | ||
if (rule.isSimpleSelector && rule.selectorType !== 'element') { | ||
if (isSimple && type !== 'type') { | ||
this.extendTypedRule(decl, rule.selector, stylable_value_parsers_1.valueMapping.states, parseStates(decl.value, decl, this.diagnostics)); | ||
} | ||
else { | ||
if (rule.selectorType === 'element') { | ||
if (type === 'type') { | ||
this.diagnostics.warn(decl, exports.processorWarnings.STATE_DEFINITION_IN_ELEMENT()); | ||
@@ -706,3 +735,3 @@ } | ||
else if (decl.prop === stylable_value_parsers_1.valueMapping.extends) { | ||
if (rule.isSimpleSelector) { | ||
if (isSimple) { | ||
const parsed = parseExtends(decl.value); | ||
@@ -751,3 +780,3 @@ const symbolName = parsed.types[0] && parsed.types[0].symbolName; | ||
mixins.push(refedMixin); | ||
this.meta.mixins.push(refedMixin); | ||
(0, deprecation_1.ignoreDeprecationWarn)(() => this.meta.mixins).push(refedMixin); | ||
} | ||
@@ -760,5 +789,6 @@ else { | ||
}); | ||
if (rule.mixins) { | ||
const partials = rule.mixins.filter((r) => r.mixin.partial); | ||
const nonPartials = rule.mixins.filter((r) => !r.mixin.partial); | ||
const previousMixins = (0, deprecation_1.ignoreDeprecationWarn)(() => rule.mixins); | ||
if (previousMixins) { | ||
const partials = previousMixins.filter((r) => r.mixin.partial); | ||
const nonPartials = previousMixins.filter((r) => !r.mixin.partial); | ||
const isInPartial = decl.prop === stylable_value_parsers_1.valueMapping.partialMixin; | ||
@@ -786,3 +816,3 @@ if ((partials.length && decl.prop === stylable_value_parsers_1.valueMapping.partialMixin) || | ||
else if (decl.prop === stylable_value_parsers_1.valueMapping.global) { | ||
if (rule.isSimpleSelector && rule.selectorType !== 'element') { | ||
if (isSimple && type !== 'type') { | ||
this.setClassGlobalMapping(decl, rule); | ||
@@ -814,41 +844,2 @@ } | ||
} | ||
handleStImport(atRule) { | ||
var _a, _b; | ||
const importObj = { | ||
defaultExport: '', | ||
from: '', | ||
request: '', | ||
named: {}, | ||
rule: atRule, | ||
context: this.dirContext, | ||
keyframes: {}, | ||
}; | ||
const imports = (0, toky_1.tokenizeImports)(`import ${atRule.params}`, '[', ']', true)[0]; | ||
if (imports && imports.star) { | ||
this.diagnostics.error(atRule, exports.processorWarnings.ST_IMPORT_STAR()); | ||
} | ||
else { | ||
importObj.defaultExport = imports.defaultName || ''; | ||
setImportObjectFrom(imports.from || '', this.dirContext, importObj); | ||
if ((_a = imports.tagged) === null || _a === void 0 ? void 0 : _a.keyframes) { | ||
// importObj.keyframes = imports.tagged?.keyframes; | ||
for (const [impName, impAsName] of Object.entries(imports.tagged.keyframes)) { | ||
importObj.keyframes[impAsName] = impName; | ||
} | ||
} | ||
if (imports.named) { | ||
for (const [impName, impAsName] of Object.entries(imports.named)) { | ||
importObj.named[impAsName] = impName; | ||
} | ||
} | ||
if (imports.errors.length) { | ||
this.diagnostics.error(atRule, exports.processorWarnings.INVALID_ST_IMPORT_FORMAT(imports.errors)); | ||
} | ||
else if (!((_b = imports.from) === null || _b === void 0 ? void 0 : _b.trim())) { | ||
this.diagnostics.error(atRule, exports.processorWarnings.ST_IMPORT_EMPTY_FROM()); | ||
} | ||
} | ||
atRule.remove(); | ||
return importObj; | ||
} | ||
handleScope(atRule) { | ||
@@ -861,3 +852,3 @@ const scopingRule = postcss.rule({ selector: atRule.params }); | ||
const scopedRule = rule.clone({ | ||
selector: (0, stylable_utils_1.scopeSelector)(scopingRule.selector, rule.selector, false).selector, | ||
selector: (0, selector_1.scopeNestedSelector)((0, selector_1.parseSelectorWithCache)(scopingRule.selector), (0, selector_1.parseSelectorWithCache)(rule.selector)).selector, | ||
}); | ||
@@ -879,68 +870,2 @@ scopedRule.stScopeSelector = atRule.params; | ||
exports.StylableProcessor = StylableProcessor; | ||
function setImportObjectFrom(importPath, dirPath, importObj) { | ||
if (!path_1.default.isAbsolute(importPath) && !importPath.startsWith('.')) { | ||
importObj.request = importPath; | ||
importObj.from = importPath; | ||
} | ||
else { | ||
importObj.request = importPath; | ||
importObj.from = | ||
path_1.default.posix && path_1.default.posix.isAbsolute(dirPath) // browser has no posix methods | ||
? path_1.default.posix.resolve(dirPath, importPath) | ||
: path_1.default.resolve(dirPath, importPath); | ||
} | ||
} | ||
function parsePseudoImport(rule, context, diagnostics) { | ||
let fromExists = false; | ||
const importObj = { | ||
defaultExport: '', | ||
from: '', | ||
request: '', | ||
named: {}, | ||
keyframes: {}, | ||
rule, | ||
context, | ||
}; | ||
rule.walkDecls((decl) => { | ||
switch (decl.prop) { | ||
case stylable_value_parsers_1.valueMapping.from: { | ||
const importPath = (0, utils_1.stripQuotation)(decl.value); | ||
if (!importPath.trim()) { | ||
diagnostics.error(decl, exports.processorWarnings.EMPTY_IMPORT_FROM()); | ||
} | ||
if (fromExists) { | ||
diagnostics.warn(rule, exports.processorWarnings.MULTIPLE_FROM_IN_IMPORT()); | ||
} | ||
setImportObjectFrom(importPath, context, importObj); | ||
fromExists = true; | ||
break; | ||
} | ||
case stylable_value_parsers_1.valueMapping.default: | ||
importObj.defaultExport = decl.value; | ||
if (!(0, selector_utils_1.isCompRoot)(importObj.defaultExport) && importObj.from.match(/\.css$/)) { | ||
diagnostics.warn(decl, exports.processorWarnings.DEFAULT_IMPORT_IS_LOWER_CASE(), { | ||
word: importObj.defaultExport, | ||
}); | ||
} | ||
break; | ||
case stylable_value_parsers_1.valueMapping.named: | ||
{ | ||
const { keyframesMap, namedMap } = parseNamed(decl.value, decl, diagnostics); | ||
importObj.named = namedMap; | ||
importObj.keyframes = keyframesMap; | ||
} | ||
break; | ||
default: | ||
diagnostics.warn(decl, exports.processorWarnings.ILLEGAL_PROP_IN_IMPORT(decl.prop), { | ||
word: decl.prop, | ||
}); | ||
break; | ||
} | ||
}); | ||
if (!importObj.from) { | ||
diagnostics.error(rule, exports.processorWarnings.FROM_PROP_MISSING_IN_IMPORT()); | ||
} | ||
return importObj; | ||
} | ||
exports.parsePseudoImport = parsePseudoImport; | ||
function validateScopingSelector(atRule, { selector: scopingSelector }, diagnostics) { | ||
@@ -947,0 +872,0 @@ if (!scopingSelector) { |
import type { FileProcessor } from './cached-process-file'; | ||
import type { Diagnostics } from './diagnostics'; | ||
import type { ClassSymbol, ElementSymbol, Imported } from './stylable-meta'; | ||
import type { ImportSymbol, StylableMeta, StylableSymbol } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import type { ImportSymbol, ClassSymbol, ElementSymbol, Imported, StylableSymbol } from './features'; | ||
import type { StylableTransformer } from './stylable-transformer'; | ||
@@ -14,4 +14,21 @@ export declare const resolverWarnings: { | ||
}; | ||
export declare type CachedModule = StylableMeta | JsModule | null; | ||
export declare type StylableResolverCache = Map<string, StylableMeta | JsModule | null>; | ||
export interface InvalidCachedModule { | ||
kind: 'js' | 'css'; | ||
value: null; | ||
error: unknown; | ||
request: string; | ||
context: string; | ||
} | ||
export interface CachedStylableMeta { | ||
resolvedPath: string; | ||
kind: 'css'; | ||
value: StylableMeta; | ||
} | ||
export interface CachedJsModule { | ||
resolvedPath: string; | ||
kind: 'js'; | ||
value: JsModule; | ||
} | ||
export declare type CachedModuleEntity = InvalidCachedModule | CachedStylableMeta | CachedJsModule; | ||
export declare type StylableResolverCache = Map<string, CachedModuleEntity>; | ||
export interface CSSResolve<T extends StylableSymbol = StylableSymbol> { | ||
@@ -39,3 +56,3 @@ _kind: 'css'; | ||
meta: StylableMeta; | ||
symbol: import("./stylable-meta").KeyframesSymbol; | ||
symbol: import("./features").KeyframesSymbol; | ||
} | undefined; | ||
@@ -42,0 +59,0 @@ deepResolve(maybeImport: StylableSymbol | undefined, path?: StylableSymbol[]): CSSResolve | JSResolve | null; |
@@ -33,29 +33,35 @@ "use strict"; | ||
} | ||
let res; | ||
if (from.match(/\.css$/)) { | ||
let entity; | ||
if (from.endsWith('.css')) { | ||
const kind = 'css'; | ||
try { | ||
res = this.fileProcessor.process(from, false, context); | ||
const resolvedPath = this.fileProcessor.resolvePath(from, context); | ||
const value = this.fileProcessor.process(resolvedPath, false, context); | ||
entity = { kind, value, resolvedPath }; | ||
} | ||
catch (e) { | ||
res = null; | ||
catch (error) { | ||
entity = { kind, value: null, error, request: from, context }; | ||
} | ||
} | ||
else { | ||
const kind = 'js'; | ||
try { | ||
res = this.requireModule(this.fileProcessor.resolvePath(from, context)); | ||
const resolvedPath = this.fileProcessor.resolvePath(from, context); | ||
const value = this.requireModule(resolvedPath); | ||
entity = { kind, value, resolvedPath }; | ||
} | ||
catch { | ||
res = null; | ||
catch (error) { | ||
entity = { kind, value: null, error, request: from, context }; | ||
} | ||
} | ||
(_b = this.cache) === null || _b === void 0 ? void 0 : _b.set(key, res); | ||
return res; | ||
(_b = this.cache) === null || _b === void 0 ? void 0 : _b.set(key, entity); | ||
return entity; | ||
} | ||
resolveImported(imported, name, subtype = 'mappedSymbols') { | ||
const res = this.getModule(imported); | ||
if (res === null) { | ||
if (res.value === null) { | ||
return null; | ||
} | ||
if (imported.from.match(/\.css$/)) { | ||
const meta = res; | ||
if (res.kind === 'css') { | ||
const { value: meta } = res; | ||
return { | ||
@@ -68,3 +74,3 @@ _kind: 'css', | ||
else { | ||
const jsModule = res; | ||
const { value: jsModule } = res; | ||
return { | ||
@@ -71,0 +77,0 @@ _kind: 'js', |
import * as postcss from 'postcss'; | ||
import type { FileProcessor } from './cached-process-file'; | ||
import type { Diagnostics } from './diagnostics'; | ||
import { SelectorAstNode, SelectorChunk2 } from './selector-utils'; | ||
import type { ClassSymbol, ElementSymbol, StylableMeta, StylableSymbol } from './stylable-processor'; | ||
import { CSSResolve, StylableResolver, StylableResolverCache } from './stylable-resolver'; | ||
import { SelectorNode, Selector, SelectorList, CompoundSelector } from '@tokey/css-selector-parser'; | ||
import type { ClassSymbol, ElementSymbol } from './features'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import { CSSResolve, StylableResolverCache, StylableResolver } from './stylable-resolver'; | ||
export interface ResolvedElement { | ||
@@ -26,9 +27,2 @@ name: string; | ||
} | ||
export interface ScopedSelectorResults { | ||
current: StylableMeta; | ||
symbol: StylableSymbol | null; | ||
selectorAst: SelectorAstNode; | ||
selector: string; | ||
elements: ResolvedElement[][]; | ||
} | ||
export declare type replaceValueHook = (value: string, name: string | { | ||
@@ -55,7 +49,2 @@ name: string; | ||
} | ||
export interface AdditionalSelector { | ||
selectorNode: SelectorAstNode; | ||
node: SelectorAstNode; | ||
customElementChunk: string; | ||
} | ||
export declare const transformerWarnings: { | ||
@@ -87,3 +76,3 @@ UNKNOWN_PSEUDO_ELEMENT(name: string): string; | ||
getScopedCSSVar(decl: postcss.Declaration, meta: StylableMeta, cssVarsMapping: Record<string, string>): string; | ||
addGlobalsToMeta(selectorAst: SelectorAstNode[], meta?: StylableMeta): void; | ||
addGlobalsToMeta(selectorAst: SelectorNode[], meta?: StylableMeta): void; | ||
transformGlobals(ast: postcss.Root, meta: StylableMeta): void; | ||
@@ -93,2 +82,3 @@ resolveSelectorElements(meta: StylableMeta, selector: string): ResolvedElement[][]; | ||
scope(name: string, namespace: string, delimiter?: string): string; | ||
scopeEscape(name: string, namespace: string, delimiter?: string): string; | ||
exportClasses(meta: StylableMeta): Record<string, string>; | ||
@@ -99,6 +89,6 @@ getPartExports(resolved: Array<CSSResolve<ClassSymbol | ElementSymbol>>): string[]; | ||
elements: ResolvedElement[][]; | ||
targetSelectorAst: SelectorAstNode; | ||
targetSelectorAst: SelectorList; | ||
}; | ||
scopeSelectorAst(context: ScopeContext): SelectorAstNode; | ||
private handleChunkNode; | ||
scopeSelectorAst(context: ScopeContext): SelectorList; | ||
private handleCompoundNode; | ||
private isDuplicateStScopeDiagnostic; | ||
@@ -118,5 +108,5 @@ private handleCustomSelector; | ||
originMeta: StylableMeta; | ||
selectorAst: SelectorAstNode; | ||
selectorAst: SelectorList; | ||
rule: postcss.Rule; | ||
additionalSelectors: Array<() => void>; | ||
additionalSelectors: Array<() => Selector>; | ||
selectorIndex: number; | ||
@@ -126,10 +116,11 @@ elements: any[]; | ||
metaParts?: MetaParts; | ||
chunks?: SelectorChunk2[]; | ||
chunk?: SelectorChunk2; | ||
node?: SelectorAstNode; | ||
selector?: Selector; | ||
compoundSelector?: CompoundSelector; | ||
node?: CompoundSelector['nodes'][number]; | ||
currentAnchor?: ScopeAnchor; | ||
constructor(originMeta: StylableMeta, selectorAst: SelectorAstNode, rule: postcss.Rule); | ||
constructor(originMeta: StylableMeta, selectorAst: SelectorList, rule: postcss.Rule); | ||
initRootAnchor(anchor: ScopeAnchor): void; | ||
setCurrentAnchor(anchor: ScopeAnchor): void; | ||
createNestedContext(selectorAst: SelectorAstNode): ScopeContext; | ||
insertDescendantCombinatorBeforePseudoElement(): void; | ||
createNestedContext(selectorAst: SelectorList): ScopeContext; | ||
} | ||
@@ -136,0 +127,0 @@ interface MetaParts { |
@@ -35,3 +35,7 @@ "use strict"; | ||
const pseudo_states_1 = require("./pseudo-states"); | ||
const selector_utils_1 = require("./selector-utils"); | ||
const selector_1 = require("./helpers/selector"); | ||
const custom_state_1 = require("./helpers/custom-state"); | ||
const css_selector_parser_1 = require("@tokey/css-selector-parser"); | ||
const rule_1 = require("./helpers/rule"); | ||
const resolve_1 = require("./helpers/resolve"); | ||
const stylable_mixins_1 = require("./stylable-mixins"); | ||
@@ -41,2 +45,4 @@ const stylable_resolver_1 = require("./stylable-resolver"); | ||
const stylable_value_parsers_1 = require("./stylable-value-parsers"); | ||
const cssesc_1 = __importDefault(require("cssesc")); | ||
const escape_1 = require("./helpers/escape"); | ||
const utils_1 = require("./utils"); | ||
@@ -93,3 +99,3 @@ const { hasOwnProperty } = Object.prototype; | ||
ast.walkRules((rule) => { | ||
if ((0, selector_utils_1.isChildOfAtRule)(rule, 'keyframes')) { | ||
if ((0, rule_1.isChildOfAtRule)(rule, 'keyframes')) { | ||
return; | ||
@@ -115,3 +121,3 @@ } | ||
ast.walkDecls((decl) => { | ||
(0, stylable_utils_1.getDeclStylable)(decl).sourceValue = decl.value; | ||
decl.stylable = { sourceValue: decl.value }; | ||
if ((0, stylable_utils_1.isCSSVarProp)(decl.prop)) { | ||
@@ -123,5 +129,3 @@ decl.prop = this.getScopedCSSVar(decl, meta, cssVarsMapping); | ||
case stylable_value_parsers_1.valueMapping.mixin: | ||
break; | ||
case stylable_value_parsers_1.valueMapping.states: | ||
(0, pseudo_states_1.validateStateDefinition)(decl, meta, this.resolver, this.diagnostics); | ||
break; | ||
@@ -230,5 +234,5 @@ default: | ||
for (const ast of selectorAst) { | ||
(0, selector_utils_1.traverseNode)(ast, (inner) => { | ||
(0, selector_1.walkSelector)(ast, (inner) => { | ||
if (inner.type === 'class') { | ||
meta.globals[inner.name] = true; | ||
meta.globals[inner.value] = true; | ||
} | ||
@@ -240,13 +244,13 @@ }); | ||
ast.walkRules((r) => { | ||
const selectorAst = (0, selector_utils_1.parseSelector)(r.selector); | ||
(0, selector_utils_1.traverseNode)(selectorAst, (node) => { | ||
if (node.type === 'nested-pseudo-class' && node.name === 'global') { | ||
const selectorAst = (0, selector_1.parseSelectorWithCache)(r.selector, { clone: true }); | ||
(0, selector_1.walkSelector)(selectorAst, (node) => { | ||
if (node.type === 'pseudo_class' && node.value === 'global') { | ||
this.addGlobalsToMeta([node], meta); | ||
node.type = 'selector'; | ||
return true; | ||
(0, selector_1.flattenFunctionalSelector)(node); | ||
return selector_1.walkSelector.skipNested; | ||
} | ||
return undefined; | ||
return; | ||
}); | ||
// this.addGlobalsToMeta([selectorAst], meta); | ||
r.selector = (0, selector_utils_1.stringifySelector)(selectorAst); | ||
r.selector = (0, selector_1.stringifySelector)(selectorAst); | ||
}); | ||
@@ -263,2 +267,5 @@ } | ||
} | ||
scopeEscape(name, namespace, delimiter = this.delimiter) { | ||
return namespace ? (0, cssesc_1.default)(namespace, { isIdentifier: true }) + delimiter + name : name; | ||
} | ||
exportClasses(meta) { | ||
@@ -269,3 +276,3 @@ const locals = {}; | ||
const exportedClasses = this.getPartExports(resolved); | ||
locals[localName] = exportedClasses.join(' '); | ||
locals[localName] = (0, escape_1.unescapeCSS)(exportedClasses.join(' ')); | ||
} | ||
@@ -291,7 +298,7 @@ return locals; | ||
scopeSelector(originMeta, selector, rule) { | ||
const context = new ScopeContext(originMeta, (0, selector_utils_1.parseSelector)(selector), rule || postcss.rule({ selector })); | ||
const context = new ScopeContext(originMeta, (0, selector_1.parseSelectorWithCache)(selector, { clone: true }), rule || postcss.rule({ selector })); | ||
const targetSelectorAst = this.scopeSelectorAst(context); | ||
return { | ||
targetSelectorAst, | ||
selector: (0, selector_utils_1.stringifySelector)(targetSelectorAst), | ||
selector: (0, selector_1.stringifySelector)(targetSelectorAst), | ||
elements: context.elements, | ||
@@ -302,4 +309,4 @@ }; | ||
const { originMeta, selectorAst } = context; | ||
// split selectors to chunks: .a.b .c:hover, a .c:hover -> [[[.a.b], [.c:hover]], [[.a], [.c:hover]]] | ||
const selectorListChunks = (0, selector_utils_1.separateChunks2)(selectorAst); | ||
// group compound selectors: .a.b .c:hover, a .c:hover -> [[[.a.b], [.c:hover]], [[.a], [.c:hover]]] | ||
const selectorList = (0, css_selector_parser_1.groupCompoundSelectors)(selectorAst); | ||
// resolve meta classes and elements | ||
@@ -317,17 +324,20 @@ context.metaParts = this.resolveMetaParts(originMeta); | ||
// loop over selectors | ||
for (const selectorChunks of selectorListChunks) { | ||
for (const selector of selectorList) { | ||
context.elements.push([]); | ||
context.selectorIndex++; | ||
context.chunks = selectorChunks; | ||
// loop over chunks | ||
for (const chunk of selectorChunks) { | ||
context.chunk = chunk; | ||
// loop over each node in a chunk | ||
for (const node of chunk.nodes) { | ||
context.node = node; | ||
context.selector = selector; | ||
// loop over nodes | ||
for (const node of [...selector.nodes]) { | ||
if (node.type !== `compound_selector`) { | ||
continue; | ||
} | ||
context.compoundSelector = node; | ||
// loop over each node in a compound selector | ||
for (const compoundNode of node.nodes) { | ||
context.node = compoundNode; | ||
// transform node | ||
this.handleChunkNode(context); | ||
this.handleCompoundNode(context); | ||
} | ||
} | ||
if (selectorListChunks.length - 1 > context.selectorIndex) { | ||
if (selectorList.length - 1 > context.selectorIndex) { | ||
// reset current anchor | ||
@@ -337,31 +347,43 @@ context.initRootAnchor(startedAnchor); | ||
} | ||
const outputAst = (0, selector_utils_1.mergeChunks)(selectorListChunks); | ||
context.additionalSelectors.forEach((addSelector) => outputAst.nodes.push(addSelector())); | ||
// backwards compatibility for elements - empty selector still have an empty first target | ||
if (selectorList.length === 0) { | ||
context.elements.push([]); | ||
} | ||
const outputAst = (0, css_selector_parser_1.splitCompoundSelectors)(selectorList); | ||
context.additionalSelectors.forEach((addSelector) => outputAst.push(addSelector())); | ||
return outputAst; | ||
} | ||
handleChunkNode(context) { | ||
handleCompoundNode(context) { | ||
const { currentAnchor, metaParts, node, originMeta, transformGlobals } = context; | ||
const { type, name } = node; | ||
if (type === 'class') { | ||
const resolved = metaParts.class[name] || [ | ||
if (node.type === 'class') { | ||
const resolved = metaParts.class[node.value] || [ | ||
// used to scope classes from js mixins | ||
{ _kind: 'css', meta: originMeta, symbol: { _kind: 'class', name } }, | ||
{ _kind: 'css', meta: originMeta, symbol: { _kind: 'class', name: node.value } }, | ||
]; | ||
context.setCurrentAnchor({ name, type: 'class', resolved }); | ||
const { symbol, meta } = (0, selector_utils_1.getOriginDefinition)(resolved); | ||
context.setCurrentAnchor({ name: node.value, type: 'class', resolved }); | ||
const { symbol, meta } = (0, resolve_1.getOriginDefinition)(resolved); | ||
if (context.originMeta === meta && symbol[stylable_value_parsers_1.valueMapping.states]) { | ||
(0, custom_state_1.validateRuleStateDefinition)(context.rule, meta, this.resolver, this.diagnostics); | ||
} | ||
this.scopeClassNode(symbol, meta, node, originMeta); | ||
} | ||
else if (type === 'element') { | ||
const resolved = metaParts.element[name] || [ | ||
else if (node.type === 'type') { | ||
const resolved = metaParts.element[node.value] || [ | ||
// provides resolution for native elements | ||
{ _kind: 'css', meta: originMeta, symbol: { _kind: 'element', name } }, | ||
{ _kind: 'css', meta: originMeta, symbol: { _kind: 'element', name: node.value } }, | ||
]; | ||
context.setCurrentAnchor({ name, type: 'element', resolved }); | ||
context.setCurrentAnchor({ name: node.value, type: 'element', resolved }); | ||
// native node does not resolve e.g. div | ||
if (resolved && resolved.length > 1) { | ||
const { symbol, meta } = (0, selector_utils_1.getOriginDefinition)(resolved); | ||
const { symbol, meta } = (0, resolve_1.getOriginDefinition)(resolved); | ||
this.scopeClassNode(symbol, meta, node, originMeta); | ||
} | ||
} | ||
else if (type === 'pseudo-element') { | ||
else if (node.type === 'pseudo_element') { | ||
if (node.value === ``) { | ||
// partial psuedo elemennt: `.x::` | ||
// ToDo: currently the transformer corrects the css without warning, | ||
// should stylable warn? | ||
return; | ||
} | ||
const len = currentAnchor.resolved.length; | ||
@@ -375,8 +397,8 @@ const lookupStartingPoint = len === 1 /* no extends */ ? 0 : 1; | ||
} | ||
const customSelector = meta.customSelectors[':--' + name]; | ||
const customSelector = meta.customSelectors[':--' + node.value]; | ||
if (customSelector) { | ||
this.handleCustomSelector(customSelector, meta, context, name, node); | ||
this.handleCustomSelector(customSelector, meta, context, node.value, node); | ||
return; | ||
} | ||
const requestedPart = meta.classes[name]; | ||
const requestedPart = meta.classes[node.value]; | ||
if (symbol.alias || !requestedPart) { | ||
@@ -386,11 +408,14 @@ // skip alias since they cannot add parts | ||
} | ||
resolved = this.resolveMetaParts(meta).class[name]; | ||
resolved = this.resolveMetaParts(meta).class[node.value]; | ||
// first definition of a part in the extends/alias chain | ||
context.setCurrentAnchor({ | ||
name, | ||
name: node.value, | ||
type: 'pseudo-element', | ||
resolved, | ||
}); | ||
const resolvedPart = (0, selector_utils_1.getOriginDefinition)(resolved); | ||
node.before = resolvedPart.symbol[stylable_value_parsers_1.valueMapping.root] ? '' : ' '; | ||
const resolvedPart = (0, resolve_1.getOriginDefinition)(resolved); | ||
if (!resolvedPart.symbol[stylable_value_parsers_1.valueMapping.root]) { | ||
// insert nested combinator before internal custom element | ||
context.insertDescendantCombinatorBeforePseudoElement(); | ||
} | ||
this.scopeClassNode(resolvedPart.symbol, resolvedPart.meta, node, originMeta); | ||
@@ -402,11 +427,11 @@ break; | ||
context.setCurrentAnchor({ | ||
name, | ||
name: node.value, | ||
type: 'pseudo-element', | ||
resolved: [], | ||
}); | ||
if (!native_reserved_lists_1.nativePseudoElements.includes(name) && | ||
!(0, is_vendor_prefixed_1.default)(name) && | ||
if (!native_reserved_lists_1.nativePseudoElements.includes(node.value) && | ||
!(0, is_vendor_prefixed_1.default)(node.value) && | ||
!this.isDuplicateStScopeDiagnostic(context)) { | ||
this.diagnostics.warn(context.rule, exports.transformerWarnings.UNKNOWN_PSEUDO_ELEMENT(name), { | ||
word: name, | ||
this.diagnostics.warn(context.rule, exports.transformerWarnings.UNKNOWN_PSEUDO_ELEMENT(node.value), { | ||
word: node.value, | ||
}); | ||
@@ -416,48 +441,58 @@ } | ||
} | ||
else if (type === 'pseudo-class') { | ||
let found = false; | ||
else if (node.type === 'pseudo_class') { | ||
// find matching custom state | ||
let foundCustomState = false; | ||
for (const { symbol, meta } of currentAnchor.resolved) { | ||
const states = symbol[stylable_value_parsers_1.valueMapping.states]; | ||
if (states && hasOwnProperty.call(states, name)) { | ||
found = true; | ||
(0, pseudo_states_1.setStateToNode)(states, meta, name, node, meta.namespace, this.resolver, this.diagnostics, context.rule); | ||
if (states && hasOwnProperty.call(states, node.value)) { | ||
foundCustomState = true; | ||
// transform custom state | ||
(0, pseudo_states_1.setStateToNode)(states, meta, node.value, node, meta.namespace, this.resolver, this.diagnostics, context.rule); | ||
break; | ||
} | ||
} | ||
if (!found && | ||
!native_reserved_lists_1.nativePseudoClasses.includes(name) && | ||
!(0, is_vendor_prefixed_1.default)(name) && | ||
!this.isDuplicateStScopeDiagnostic(context)) { | ||
this.diagnostics.warn(context.rule, pseudo_states_1.stateErrors.UNKNOWN_STATE_USAGE(name), { | ||
word: name, | ||
}); | ||
} | ||
} | ||
else if (type === 'nested-pseudo-class') { | ||
if (name === 'global') { | ||
// :global(.a) -> .a | ||
if (transformGlobals) { | ||
node.type = 'selector'; | ||
// handle nested pseudo classes | ||
if (node.nodes && !foundCustomState) { | ||
if (node.value === 'global') { | ||
// :global(.a) -> .a | ||
if (transformGlobals) { | ||
(0, selector_1.flattenFunctionalSelector)(node); | ||
} | ||
return; | ||
} | ||
else { | ||
// pickup all nested selectors except nth initial selector | ||
const innerSelectors = (node.nodes[0] && node.nodes[0].type === `nth` | ||
? node.nodes.slice(1) | ||
: node.nodes); | ||
const nestedContext = context.createNestedContext(innerSelectors); | ||
this.scopeSelectorAst(nestedContext); | ||
/** | ||
* ToDo: remove once elements is deprecated! | ||
* support deprecated elements. | ||
* used to flatten nested elements for some native pseudo classes. | ||
*/ | ||
if (node.value.match(/not|any|-\w+?-any|matches|is|where|has|local/)) { | ||
// delegate elements of first selector | ||
context.elements[context.selectorIndex].push(...nestedContext.elements[0]); | ||
} | ||
} | ||
} | ||
else { | ||
const nestedContext = context.createNestedContext({ | ||
type: 'selectors', | ||
name: `${name}`, | ||
nodes: node.nodes, | ||
// warn unknown state | ||
if (!foundCustomState && | ||
!native_reserved_lists_1.nativePseudoClasses.includes(node.value) && | ||
!(0, is_vendor_prefixed_1.default)(node.value) && | ||
!this.isDuplicateStScopeDiagnostic(context)) { | ||
this.diagnostics.warn(context.rule, pseudo_states_1.stateErrors.UNKNOWN_STATE_USAGE(node.value), { | ||
word: node.value, | ||
}); | ||
this.scopeSelectorAst(nestedContext); | ||
// delegate elements of first selector | ||
context.elements[context.selectorIndex].push(...nestedContext.elements[0]); | ||
} | ||
} | ||
else if (type === 'invalid' && node.value === '&') { | ||
if ( /* maybe should be currentAnchor meta */originMeta.parent) { | ||
const origin = originMeta.mappedSymbols[originMeta.root]; | ||
context.setCurrentAnchor({ | ||
name: origin.name, | ||
type: 'class', | ||
resolved: metaParts.class[origin.name], | ||
}); | ||
} | ||
else if (node.type === `nesting`) { | ||
const origin = originMeta.mappedSymbols[originMeta.root]; | ||
context.setCurrentAnchor({ | ||
name: origin.name, | ||
type: 'class', | ||
resolved: metaParts.class[origin.name], | ||
}); | ||
} | ||
@@ -467,21 +502,13 @@ } | ||
var _a; | ||
const transformedScope = (_a = context.originMeta.transformedScopes) === null || _a === void 0 ? void 0 : _a[context.rule.stScopeSelector]; | ||
if (transformedScope && context.chunks && context.chunk) { | ||
const currentChunkSelector = (0, selector_utils_1.stringifySelector)({ | ||
type: 'selector', | ||
nodes: context.chunk.nodes, | ||
name: '', | ||
}); | ||
const i = context.chunks.indexOf(context.chunk); | ||
for (const stScopeSelectorChunks of transformedScope) { | ||
const transformedScope = (_a = context.originMeta.transformedScopes) === null || _a === void 0 ? void 0 : _a[(0, rule_1.getRuleScopeSelector)(context.rule) || ``]; | ||
if (transformedScope && context.selector && context.compoundSelector) { | ||
const currentCompoundSelector = (0, selector_1.stringifySelector)(context.compoundSelector); | ||
const i = context.selector.nodes.indexOf(context.compoundSelector); | ||
for (const stScopeSelectorCompounded of transformedScope) { | ||
// if we are in a chunk index that is in the rage of the @st-scope param | ||
if (i <= stScopeSelectorChunks.length) { | ||
for (const chunk of stScopeSelectorChunks) { | ||
const scopeChunkSelector = (0, selector_utils_1.stringifySelector)({ | ||
type: 'selector', | ||
nodes: chunk.nodes, | ||
name: '', | ||
}); | ||
if (i <= stScopeSelectorCompounded.nodes.length) { | ||
for (const scopeNode of stScopeSelectorCompounded.nodes) { | ||
const scopeNodeSelector = (0, selector_1.stringifySelector)(scopeNode); | ||
// if the two chunks match the error is already reported by the @st-scope validation | ||
if (scopeChunkSelector === currentChunkSelector) { | ||
if (scopeNodeSelector === currentCompoundSelector) { | ||
return true; | ||
@@ -496,8 +523,7 @@ } | ||
handleCustomSelector(customSelector, meta, context, name, node) { | ||
const selectorListChunks = (0, selector_utils_1.separateChunks2)((0, selector_utils_1.parseSelector)(customSelector)); | ||
const hasSingleSelector = selectorListChunks.length === 1; | ||
removeFirstRootInEachSelectorChunk(selectorListChunks, meta); | ||
const internalContext = new ScopeContext(meta, (0, selector_utils_1.mergeChunks)(selectorListChunks), context.rule); | ||
const customAstSelectors = this.scopeSelectorAst(internalContext).nodes; | ||
customAstSelectors.forEach(trimLeftSelectorAst); | ||
const selectorList = (0, selector_1.parseSelectorWithCache)(customSelector, { clone: true }); | ||
const hasSingleSelector = selectorList.length === 1; | ||
const internalContext = new ScopeContext(meta, removeFirstRootInFirstCompound(selectorList, meta), context.rule); | ||
const customAstSelectors = this.scopeSelectorAst(internalContext); | ||
customAstSelectors.forEach(setSingleSpaceOnSelectorLeft); | ||
if (hasSingleSelector && internalContext.currentAnchor) { | ||
@@ -521,3 +547,3 @@ context.setCurrentAnchor({ | ||
for (let i = 1; i < customAstSelectors.length; i++) { | ||
const selectorNode = context.selectorAst.nodes[context.selectorIndex]; | ||
const selectorNode = context.selectorAst[context.selectorIndex]; | ||
const nodeIndex = selectorNode.nodes.indexOf(node); | ||
@@ -530,9 +556,10 @@ context.additionalSelectors.push(lazyCreateSelector(customAstSelectors[i], selectorNode, nodeIndex)); | ||
const globalMappedNodes = symbol[stylable_value_parsers_1.valueMapping.global]; | ||
node.type = 'selector'; | ||
(0, selector_1.flattenFunctionalSelector)(node); | ||
node.nodes = globalMappedNodes; | ||
// ToDo: check if this is causes an issue with globals from an imported alias | ||
this.addGlobalsToMeta(globalMappedNodes, originMeta); | ||
} | ||
else { | ||
node.type = 'class'; | ||
node.name = this.scope(symbol.name, meta.namespace); | ||
(0, selector_1.convertToClass)(node); | ||
node.value = this.scopeEscape(symbol.name, meta.namespace); | ||
} | ||
@@ -546,3 +573,3 @@ } | ||
resolvedClasses[className] = this.resolver.resolveExtends(meta, className, false, undefined, (res, extend) => { | ||
const decl = (0, stylable_utils_1.findRule)(meta.ast, '.' + className); | ||
const decl = (0, rule_1.findRule)(meta.ast, '.' + className); | ||
if (decl) { | ||
@@ -584,6 +611,6 @@ if (res && res._kind === 'js') { | ||
if (resolved.length > 1) { | ||
meta.outputAst.walkRules('.' + this.scope(className, meta.namespace), (rule) => { | ||
meta.outputAst.walkRules('.' + this.scopeEscape(className, meta.namespace), (rule) => { | ||
const a = resolved[0]; | ||
const b = resolved[resolved.length - 1]; | ||
rule.after((0, selector_utils_1.createWarningRule)(b.symbol.name, this.scope(b.symbol.name, b.meta.namespace), (0, path_1.basename)(b.meta.source), a.symbol.name, this.scope(a.symbol.name, a.meta.namespace), (0, path_1.basename)(a.meta.source), true)); | ||
rule.after((0, rule_1.createWarningRule)(b.symbol.name, this.scopeEscape(b.symbol.name, b.meta.namespace), (0, path_1.basename)(b.meta.source), a.symbol.name, this.scopeEscape(a.symbol.name, a.meta.namespace), (0, path_1.basename)(a.meta.source), true)); | ||
}); | ||
@@ -605,4 +632,4 @@ } | ||
const rule = postcss.rule({ selector: scope.params }); | ||
const context = new ScopeContext(meta, (0, selector_utils_1.parseSelector)(rule.selector), rule); | ||
transformedScopes[rule.selector] = (0, selector_utils_1.separateChunks2)(transformer.scopeSelectorAst(context)); | ||
const context = new ScopeContext(meta, (0, selector_1.parseSelectorWithCache)(rule.selector, { clone: true }), rule); | ||
transformedScopes[rule.selector] = (0, css_selector_parser_1.groupCompoundSelectors)(transformer.scopeSelectorAst(context)); | ||
const ruleReports = transformer.diagnostics.reports.splice(len); | ||
@@ -620,19 +647,33 @@ ruleReports.forEach(({ message, type, options: { word } = {} }) => { | ||
} | ||
function removeFirstRootInEachSelectorChunk(selectorListChunks, meta) { | ||
selectorListChunks.forEach((selectorChunks) => { | ||
selectorChunks[0].nodes = selectorChunks[0].nodes.filter(({ type, name }) => { | ||
return !(type === 'class' && name === meta.root); | ||
}); | ||
}); | ||
function removeFirstRootInFirstCompound(selectorList, meta) { | ||
const compounded = (0, css_selector_parser_1.groupCompoundSelectors)(selectorList); | ||
for (const selector of compounded) { | ||
const first = selector.nodes.find(({ type }) => type === `compound_selector`); | ||
if (first && first.type === `compound_selector`) { | ||
first.nodes = first.nodes.filter((node) => { | ||
return !(node.type === 'class' && node.value === meta.root); | ||
}); | ||
} | ||
} | ||
return (0, css_selector_parser_1.splitCompoundSelectors)(compounded); | ||
} | ||
function trimLeftSelectorAst(n, i = 0) { | ||
if (n) { | ||
if (n.type === 'spacing') { | ||
n.value = ''; | ||
function setSingleSpaceOnSelectorLeft(n) { | ||
n.before = ` `; | ||
let parent = n; | ||
let nextLeft = n.nodes[0]; | ||
while (nextLeft) { | ||
if (`before` in nextLeft) { | ||
nextLeft.before = ``; | ||
} | ||
n.before = ''; | ||
trimLeftSelectorAst(n.nodes && n.nodes[0], i + 1); | ||
if (i === 0) { | ||
n.before = ' '; | ||
if (nextLeft.type === `selector`) { | ||
nextLeft = nextLeft.nodes[0]; | ||
parent = nextLeft; | ||
} | ||
else if (nextLeft.type === `combinator` && nextLeft.combinator === `space`) { | ||
parent.nodes.shift(); | ||
nextLeft = parent.nodes[0]; | ||
} | ||
else { | ||
return; | ||
} | ||
} | ||
@@ -659,2 +700,5 @@ } | ||
constructor(originMeta, selectorAst, rule) { | ||
this.originMeta = originMeta; | ||
this.selectorAst = selectorAst; | ||
this.rule = rule; | ||
this.additionalSelectors = []; | ||
@@ -664,5 +708,2 @@ this.selectorIndex = -1; | ||
this.transformGlobals = false; | ||
this.originMeta = originMeta; | ||
this.selectorAst = selectorAst; | ||
this.rule = rule; | ||
} | ||
@@ -678,2 +719,22 @@ initRootAnchor(anchor) { | ||
} | ||
insertDescendantCombinatorBeforePseudoElement() { | ||
if (this.selector && | ||
this.compoundSelector && | ||
this.node && | ||
this.node.type === `pseudo_element`) { | ||
if (this.compoundSelector.nodes[0] === this.node) { | ||
const compoundIndex = this.selector.nodes.indexOf(this.compoundSelector); | ||
this.selector.nodes.splice(compoundIndex, 0, { | ||
type: `combinator`, | ||
combinator: `space`, | ||
value: ` `, | ||
before: ``, | ||
after: ``, | ||
start: this.node.start, | ||
end: this.node.start, | ||
invalid: false, | ||
}); | ||
} | ||
} | ||
} | ||
createNestedContext(selectorAst) { | ||
@@ -680,0 +741,0 @@ const ctx = new ScopeContext(this.originMeta, selectorAst, this.rule); |
@@ -1,6 +0,5 @@ | ||
import * as postcss from 'postcss'; | ||
import type * as postcss from 'postcss'; | ||
import type { Diagnostics } from './diagnostics'; | ||
import type { DeclStylableProps, Imported, SDecl, StylableMeta, StylableSymbol } from './stylable-processor'; | ||
import { SelectorAstNode } from './selector-utils'; | ||
import type { ImportSymbol } from './stylable-meta'; | ||
import type { Imported, ImportSymbol, StylableSymbol } from './features'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import type { StylableResolver } from './stylable-resolver'; | ||
@@ -11,12 +10,4 @@ export declare const CUSTOM_SELECTOR_RE: RegExp; | ||
export declare function transformMatchesOnRule(rule: postcss.Rule, lineBreak: boolean): string; | ||
export declare function scopeSelector(scopeSelectorRule: string, targetSelectorRule: string, rootScopeLevel?: boolean): { | ||
selector: string; | ||
selectorAst: SelectorAstNode; | ||
}; | ||
export declare function mergeRules(mixinAst: postcss.Root, rule: postcss.Rule): postcss.Rule; | ||
export declare function createSubsetAst<T extends postcss.Root | postcss.AtRule>(root: postcss.Root | postcss.AtRule, selectorPrefix: string, mixinTarget?: T, isRoot?: boolean): T; | ||
export declare function removeUnusedRules(ast: postcss.Root, meta: StylableMeta, _import: Imported, usedFiles: string[], resolvePath: (ctx: string, path: string) => string): void; | ||
export declare function findDeclaration(importNode: Imported, test: any): postcss.Declaration; | ||
export declare function findRule(root: postcss.Root, selector: string, test?: any): null | postcss.Declaration; | ||
export declare function getDeclStylable(decl: SDecl): DeclStylableProps; | ||
export declare function getSourcePath(root: postcss.Root, diagnostics: Diagnostics): string; | ||
@@ -23,0 +14,0 @@ export declare function getAlias(symbol: StylableSymbol): ImportSymbol | undefined; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isValidClassName = exports.scopeCSSVar = exports.isCSSVarProp = exports.generateScopedCSSVar = exports.getAlias = exports.getSourcePath = exports.getDeclStylable = exports.findRule = exports.findDeclaration = exports.removeUnusedRules = exports.createSubsetAst = exports.mergeRules = exports.scopeSelector = exports.transformMatchesOnRule = exports.expandCustomSelectors = exports.isValidDeclaration = exports.CUSTOM_SELECTOR_RE = void 0; | ||
const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep")); | ||
exports.isValidClassName = exports.scopeCSSVar = exports.isCSSVarProp = exports.generateScopedCSSVar = exports.getAlias = exports.getSourcePath = exports.findDeclaration = exports.mergeRules = exports.transformMatchesOnRule = exports.expandCustomSelectors = exports.isValidDeclaration = exports.CUSTOM_SELECTOR_RE = void 0; | ||
const path_1 = require("path"); | ||
const postcss = __importStar(require("postcss")); | ||
const replace_rule_selector_1 = require("./replace-rule-selector"); | ||
const selector_utils_1 = require("./selector-utils"); | ||
const rule_1 = require("./helpers/rule"); | ||
const selector_1 = require("./helpers/selector"); | ||
const stylable_value_parsers_1 = require("./stylable-value-parsers"); | ||
@@ -58,53 +35,6 @@ exports.CUSTOM_SELECTOR_RE = /:--[\w-]+/g; | ||
exports.transformMatchesOnRule = transformMatchesOnRule; | ||
function scopeSelector(scopeSelectorRule, targetSelectorRule, rootScopeLevel = false) { | ||
const scopingSelectorAst = (0, selector_utils_1.parseSelector)(scopeSelectorRule); | ||
const targetSelectorAst = (0, selector_utils_1.parseSelector)(targetSelectorRule); | ||
const nodes = []; | ||
targetSelectorAst.nodes.forEach((targetSelector) => { | ||
scopingSelectorAst.nodes.forEach((scopingSelector) => { | ||
const outputSelector = (0, lodash_clonedeep_1.default)(targetSelector); | ||
outputSelector.before = scopingSelector.before || outputSelector.before; | ||
const first = outputSelector.nodes[0]; | ||
const parentRef = first.type === 'invalid' && first.value === '&'; | ||
const globalSelector = first.type === 'nested-pseudo-class' && first.name === 'global'; | ||
const startsWithScoping = rootScopeLevel | ||
? scopingSelector.nodes.every((node, i) => { | ||
const o = outputSelector.nodes[i]; | ||
for (const k in node) { | ||
if (node[k] !== o[k]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}) | ||
: false; | ||
if (first && | ||
first.type !== 'spacing' && | ||
!parentRef && | ||
!startsWithScoping && | ||
!globalSelector) { | ||
outputSelector.nodes.unshift(...(0, lodash_clonedeep_1.default)(scopingSelector.nodes), { | ||
type: 'spacing', | ||
value: ' ', | ||
}); | ||
} | ||
(0, selector_utils_1.traverseNode)(outputSelector, (node, i, nodes) => { | ||
if (node.type === 'invalid' && node.value === '&') { | ||
nodes.splice(i, 1, ...(0, lodash_clonedeep_1.default)(scopingSelector.nodes)); | ||
} | ||
}); | ||
nodes.push(outputSelector); | ||
}); | ||
}); | ||
scopingSelectorAst.nodes = nodes; | ||
return { | ||
selector: (0, selector_utils_1.stringifySelector)(scopingSelectorAst), | ||
selectorAst: scopingSelectorAst, | ||
}; | ||
} | ||
exports.scopeSelector = scopeSelector; | ||
function mergeRules(mixinAst, rule) { | ||
let mixinRoot = null; | ||
mixinAst.walkRules((mixinRule) => { | ||
if ((0, selector_utils_1.isChildOfAtRule)(mixinRule, 'keyframes')) { | ||
if ((0, rule_1.isChildOfAtRule)(mixinRule, 'keyframes')) { | ||
return; | ||
@@ -117,8 +47,10 @@ } | ||
else { | ||
const { selector } = (0, selector_1.scopeNestedSelector)((0, selector_1.parseSelectorWithCache)(rule.selector), (0, selector_1.parseSelectorWithCache)(mixinRule.selector)); | ||
mixinRoot = 'NoRoot'; | ||
mixinRule.selector = scopeSelector(rule.selector, mixinRule.selector).selector; | ||
mixinRule.selector = selector; | ||
} | ||
} | ||
else { | ||
mixinRule.selector = scopeSelector(rule.selector, mixinRule.selector).selector; | ||
const { selector } = (0, selector_1.scopeNestedSelector)((0, selector_1.parseSelectorWithCache)(rule.selector), (0, selector_1.parseSelectorWithCache)(mixinRule.selector)); | ||
mixinRule.selector = selector; | ||
} | ||
@@ -159,83 +91,2 @@ }); | ||
exports.mergeRules = mergeRules; | ||
function createSubsetAst(root, selectorPrefix, mixinTarget, isRoot = false) { | ||
// keyframes on class mixin? | ||
const prefixType = (0, selector_utils_1.parseSelector)(selectorPrefix).nodes[0].nodes[0]; | ||
const containsPrefix = containsMatchInFirstChunk.bind(null, prefixType); | ||
const mixinRoot = mixinTarget ? mixinTarget : postcss.root(); | ||
root.nodes.forEach((node) => { | ||
if (node.type === 'rule') { | ||
const ast = isRoot | ||
? scopeSelector(selectorPrefix, node.selector, true).selectorAst | ||
: (0, selector_utils_1.parseSelector)(node.selector); | ||
const matchesSelectors = isRoot | ||
? ast.nodes | ||
: ast.nodes.filter((node) => containsPrefix(node)); | ||
if (matchesSelectors.length) { | ||
const selector = (0, selector_utils_1.stringifySelector)({ | ||
...ast, | ||
nodes: matchesSelectors.map((selectorNode) => { | ||
if (!isRoot) { | ||
(0, selector_utils_1.fixChunkOrdering)(selectorNode, prefixType); | ||
} | ||
return destructiveReplaceNode(selectorNode, prefixType, { | ||
type: 'invalid', | ||
value: '&', | ||
}); | ||
}), | ||
}); | ||
mixinRoot.append(node.clone({ selector })); | ||
} | ||
} | ||
else if (node.type === 'atrule') { | ||
if (node.name === 'media' || node.name === 'supports') { | ||
const atRuleSubset = createSubsetAst(node, selectorPrefix, postcss.atRule({ | ||
params: node.params, | ||
name: node.name, | ||
}), isRoot); | ||
if (atRuleSubset.nodes) { | ||
mixinRoot.append(atRuleSubset); | ||
} | ||
} | ||
else if (isRoot) { | ||
mixinRoot.append(node.clone()); | ||
} | ||
} | ||
else { | ||
// TODO: add warn? | ||
} | ||
}); | ||
return mixinRoot; | ||
} | ||
exports.createSubsetAst = createSubsetAst; | ||
function removeUnusedRules(ast, meta, _import, usedFiles, resolvePath) { | ||
const isUnusedImport = !usedFiles.includes(_import.from); | ||
if (isUnusedImport) { | ||
const symbols = Object.keys(_import.named).concat(_import.defaultExport); // .filter(Boolean); | ||
ast.walkRules((rule) => { | ||
let shouldOutput = true; | ||
(0, selector_utils_1.traverseNode)(rule.selectorAst, (node) => { | ||
// TODO: remove. | ||
if (symbols.includes(node.name)) { | ||
return (shouldOutput = false); | ||
} | ||
const symbol = meta.mappedSymbols[node.name]; | ||
if (symbol && (symbol._kind === 'class' || symbol._kind === 'element')) { | ||
let extend = symbol[stylable_value_parsers_1.valueMapping.extends] || symbol.alias; | ||
extend = extend && extend._kind !== 'import' ? extend.alias || extend : extend; | ||
if (extend && | ||
extend._kind === 'import' && | ||
!usedFiles.includes(resolvePath(meta.source, extend.import.from))) { | ||
return (shouldOutput = false); | ||
} | ||
} | ||
return undefined; | ||
}); | ||
// TODO: optimize the multiple selectors | ||
if (!shouldOutput && rule.selectorAst.nodes.length <= 1) { | ||
rule.remove(); | ||
} | ||
}); | ||
} | ||
} | ||
exports.removeUnusedRules = removeUnusedRules; | ||
function findDeclaration(importNode, test) { | ||
@@ -246,50 +97,2 @@ const fromIndex = importNode.rule.nodes.findIndex(test); | ||
exports.findDeclaration = findDeclaration; | ||
// TODO: What is this? | ||
function findRule(root, selector, test = (statement) => statement.prop === stylable_value_parsers_1.valueMapping.extends) { | ||
let found = null; | ||
root.walkRules(selector, (rule) => { | ||
const declarationIndex = rule.nodes ? rule.nodes.findIndex(test) : -1; | ||
if (rule.isSimpleSelector && !!~declarationIndex) { | ||
found = rule.nodes[declarationIndex]; | ||
} | ||
}); | ||
return found; | ||
} | ||
exports.findRule = findRule; | ||
function getDeclStylable(decl) { | ||
if (decl.stylable) { | ||
return decl.stylable; | ||
} | ||
else { | ||
decl.stylable = decl.stylable ? decl.stylable : { sourceValue: '' }; | ||
return decl.stylable; | ||
} | ||
} | ||
exports.getDeclStylable = getDeclStylable; | ||
function destructiveReplaceNode(ast, matchNode, replacementNode) { | ||
(0, selector_utils_1.traverseNode)(ast, (node) => { | ||
if ((0, selector_utils_1.isNodeMatch)(node, matchNode)) { | ||
node.type = 'selector'; | ||
node.nodes = [replacementNode]; | ||
} | ||
}); | ||
return ast; | ||
} | ||
function containsMatchInFirstChunk(prefixType, selectorNode) { | ||
let isMatch = false; | ||
(0, selector_utils_1.traverseNode)(selectorNode, (node) => { | ||
if (node.type === 'operator' || node.type === 'spacing') { | ||
return false; | ||
} | ||
else if (node.type === 'nested-pseudo-class') { | ||
return true; | ||
} | ||
else if ((0, selector_utils_1.isNodeMatch)(node, prefixType)) { | ||
isMatch = true; | ||
return false; | ||
} | ||
return undefined; | ||
}); | ||
return isMatch; | ||
} | ||
function getSourcePath(root, diagnostics) { | ||
@@ -296,0 +99,0 @@ const source = (root.source && root.source.input.file) || ''; |
@@ -69,3 +69,3 @@ import type * as postcss from 'postcss'; | ||
'-st-root'(value: string): boolean; | ||
'-st-global'(decl: postcss.Declaration, _diagnostics: Diagnostics): any; | ||
'-st-global'(decl: postcss.Declaration, _diagnostics: Diagnostics): import("@tokey/css-selector-parser").SelectorNodes; | ||
'-st-states'(value: string, decl: postcss.Declaration, diagnostics: Diagnostics): MappedStates; | ||
@@ -72,0 +72,0 @@ '-st-extends'(value: string): { |
@@ -9,3 +9,3 @@ "use strict"; | ||
const pseudo_states_1 = require("./pseudo-states"); | ||
const selector_utils_1 = require("./selector-utils"); | ||
const selector_1 = require("./helpers/selector"); | ||
exports.valueParserWarnings = { | ||
@@ -61,4 +61,5 @@ VALUE_CANNOT_BE_STRING() { | ||
// Experimental | ||
const selector = (0, selector_utils_1.parseSelector)(decl.value.replace(/^['"]/, '').replace(/['"]$/, '')); | ||
return selector.nodes[0].nodes; | ||
const selector = (0, selector_1.parseSelectorWithCache)(decl.value.replace(/^['"]/, '').replace(/['"]$/, ''), { clone: true }); | ||
// ToDo: handle or warn on multiple selectors | ||
return selector[0].nodes; | ||
}, | ||
@@ -65,0 +66,0 @@ '-st-states'(value, decl, diagnostics) { |
import type { FileProcessor, MinimalFS } from './cached-process-file'; | ||
import { Diagnostics } from './diagnostics'; | ||
import { CssParser } from './parser'; | ||
import { processNamespace, StylableMeta, StylableProcessor } from './stylable-processor'; | ||
import { processNamespace, StylableProcessor } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import { StylableResolverCache, StylableResolver } from './stylable-resolver'; | ||
@@ -13,9 +14,11 @@ import { StylableResults, StylableTransformer, TransformerOptions, TransformHooks } from './stylable-transformer'; | ||
requireModule?: (path: string) => any; | ||
/** @deprecated */ | ||
delimiter?: string; | ||
onProcess?: (meta: StylableMeta, path: string) => StylableMeta; | ||
/** @deprecated */ | ||
diagnostics?: Diagnostics; | ||
hooks?: TransformHooks; | ||
resolveOptions?: { | ||
alias: any; | ||
symlinks: boolean; | ||
alias?: any; | ||
symlinks?: boolean; | ||
[key: string]: any; | ||
@@ -22,0 +25,0 @@ }; |
import type { StylableMeta } from './stylable-meta'; | ||
import type { Imported } from './stylable-processor'; | ||
import type { Imported } from './features'; | ||
import type { StylableResolver } from './stylable-resolver'; | ||
export declare function visitMetaCSSDependenciesBFS(meta: StylableMeta, onMetaDependency: (meta: StylableMeta, imported: Imported, depth: number) => void, resolver: StylableResolver): void; | ||
//# sourceMappingURL=visit-meta-css-dependencies.d.ts.map |
{ | ||
"name": "@stylable/core", | ||
"version": "4.7.4", | ||
"version": "4.8.0", | ||
"description": "CSS for Components", | ||
@@ -11,4 +11,7 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@tokey/css-selector-parser": "^0.5.1", | ||
"@tokey/imports-parser": "^0.0.2", | ||
"balanced-match": "^2.0.0", | ||
"css-selector-tokenizer": "^0.8.0", | ||
"cssesc": "^3.0.0", | ||
"deindent": "^0.1.0", | ||
@@ -19,8 +22,7 @@ "enhanced-resolve": "^5.8.3", | ||
"lodash.clonedeepwith": "^4.5.0", | ||
"postcss": "^8.3.9", | ||
"postcss": "^8.3.11", | ||
"postcss-js": "^3.0.3", | ||
"postcss-nested": "^5.0.6", | ||
"postcss-safe-parser": "^6.0.0", | ||
"postcss-value-parser": "^4.1.0", | ||
"toky": "^0.1.0" | ||
"postcss-value-parser": "^4.1.0" | ||
}, | ||
@@ -27,0 +29,0 @@ "files": [ |
import path from 'path'; | ||
import { cachedProcessFile, FileProcessor, MinimalFS } from './cached-process-file'; | ||
import { cssParse, CssParser } from './parser'; | ||
import { process, processNamespace, StylableMeta } from './stylable-processor'; | ||
import { process, processNamespace } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import { timedCache, TimedCacheOptions } from './timed-cache'; | ||
@@ -6,0 +7,0 @@ import { createDefaultResolver } from './module-resolver'; |
@@ -8,3 +8,3 @@ import { dirname, relative } from 'path'; | ||
import { assureRelativeUrlPrefix } from './stylable-assets'; | ||
import type { StylableMeta } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import type { CSSResolve, JSResolve, StylableResolver } from './stylable-resolver'; | ||
@@ -248,2 +248,4 @@ import type { replaceValueHook, StylableTransformer } from './stylable-transformer'; | ||
} | ||
} else { | ||
// TODO: warn | ||
} | ||
@@ -352,5 +354,2 @@ } else if (value === '') { | ||
return { outputValue, topLevelType, typeError }; | ||
// TODO: handle calc (parse internals but maintain expression) | ||
// TODO: check this thing. native function that accent our function does not work | ||
// e.g: calc(getVarName()) | ||
} | ||
@@ -357,0 +356,0 @@ |
221
src/index.ts
@@ -9,6 +9,5 @@ export { CssParser, cssObjectToAst, cssParse, safeParse } from './parser'; | ||
} from './cached-process-file'; | ||
export { | ||
export type { | ||
CSSVarSymbol, | ||
ClassSymbol, | ||
DeclStylableProps, | ||
ElementSymbol, | ||
@@ -18,12 +17,10 @@ ImportSymbol, | ||
KeyframesSymbol, | ||
RESERVED_ROOT_NAME, | ||
RefedMixin, | ||
SDecl, | ||
SRule, | ||
SimpleSelector, | ||
StylableDirectives, | ||
StylableMeta, | ||
StylableProcessor, | ||
StylableSymbol, | ||
VarSymbol, | ||
} from './features'; | ||
export { | ||
StylableProcessor, | ||
createEmptyMeta, | ||
@@ -34,9 +31,10 @@ process, | ||
validateScopingSelector, | ||
parsePseudoImport, | ||
} from './stylable-processor'; | ||
export { ensureStylableImports } from './stylable-imports-tools'; | ||
export { StylableMeta, RESERVED_ROOT_NAME } from './stylable-meta'; | ||
export { | ||
AdditionalSelector, | ||
KeyFrameWithNode, | ||
ResolvedElement, | ||
ScopedSelectorResults, | ||
StylableExports, | ||
@@ -53,9 +51,6 @@ StylableResults, | ||
CUSTOM_SELECTOR_RE, | ||
createSubsetAst, | ||
expandCustomSelectors, | ||
findDeclaration, | ||
findRule, | ||
generateScopedCSSVar, | ||
getAlias, | ||
getDeclStylable, | ||
getSourcePath, | ||
@@ -66,5 +61,3 @@ isCSSVarProp, | ||
mergeRules, | ||
removeUnusedRules, | ||
scopeCSSVar, | ||
scopeSelector, | ||
transformMatchesOnRule, | ||
@@ -74,3 +67,2 @@ } from './stylable-utils'; | ||
CSSResolve, | ||
CachedModule, | ||
JSResolve, | ||
@@ -165,32 +157,2 @@ JsModule, | ||
export { | ||
PseudoSelectorAstNode, | ||
SelectorAstNode, | ||
SelectorChunk, | ||
SelectorChunk2, | ||
Visitor, | ||
createChecker, | ||
createSimpleSelectorChecker, | ||
createWarningRule, | ||
filterChunkNodesByType, | ||
fixChunkOrdering, | ||
getOriginDefinition, | ||
isChildOfAtRule, | ||
isCompRoot, | ||
isGlobal, | ||
isImport, | ||
isNested, | ||
isNodeMatch, | ||
isRootValid, | ||
isSimpleSelector, | ||
matchAtKeyframes, | ||
matchAtMedia, | ||
matchSelectorTarget, | ||
mergeChunks, | ||
parseSelector, | ||
separateChunks, | ||
separateChunks2, | ||
stringifySelector, | ||
traverseNode, | ||
} from './selector-utils'; | ||
export { | ||
isCssNativeFunction, | ||
@@ -235,1 +197,168 @@ nativeFunctions, | ||
}; | ||
export { getRuleScopeSelector } from './helpers/rule'; | ||
// *** deprecated *** | ||
import { wrapFunctionForDeprecation } from './helpers/deprecation'; | ||
import { isCompRoot as deprecatedIsCompRoot } from './helpers/selector'; | ||
/**@deprecated*/ | ||
export const isCompRoot = wrapFunctionForDeprecation(deprecatedIsCompRoot, { | ||
name: `isCompRoot`, | ||
}); | ||
import { | ||
isChildOfAtRule as deprecatedIsChildOfAtRule, | ||
createWarningRule as deprecatedCreateWarningRule, | ||
} from './helpers/rule'; | ||
/**@deprecated*/ | ||
export const isChildOfAtRule = wrapFunctionForDeprecation(deprecatedIsChildOfAtRule, { | ||
name: `isChildOfAtRule`, | ||
}); | ||
/**@deprecated*/ | ||
export const createWarningRule = wrapFunctionForDeprecation(deprecatedCreateWarningRule, { | ||
name: `createWarningRule`, | ||
}); | ||
import { getOriginDefinition as deprecatedGetOriginDefinition } from './helpers/resolve'; | ||
/**@deprecated*/ | ||
export const getOriginDefinition = wrapFunctionForDeprecation(deprecatedGetOriginDefinition, { | ||
name: `getOriginDefinition`, | ||
}); | ||
export type { SRule, SDecl, DeclStylableProps } from './deprecated/postcss-ast-extension'; | ||
import { getDeclStylable as deprecatedGetDeclStylable } from './deprecated/postcss-ast-extension'; | ||
/**@deprecated*/ | ||
export const getDeclStylable = wrapFunctionForDeprecation(deprecatedGetDeclStylable, { | ||
name: `getDeclStylable`, | ||
}); | ||
import { | ||
scopeSelector as deprecatedScopeSelector, | ||
createSubsetAst as deprecatedCreateSubsetAst, | ||
removeUnusedRules as deprecatedRemoveUnusedRules, | ||
findRule as deprecatedFindRule, | ||
} from './deprecated/deprecated-stylable-utils'; | ||
/**@deprecated*/ | ||
export const scopeSelector = wrapFunctionForDeprecation(deprecatedScopeSelector, { | ||
name: `scopeSelector`, | ||
}); | ||
/**@deprecated*/ | ||
export const createSubsetAst = deprecatedCreateSubsetAst; | ||
/**@deprecated*/ | ||
export const removeUnusedRules = wrapFunctionForDeprecation(deprecatedRemoveUnusedRules, { | ||
name: `removeUnusedRules`, | ||
}); | ||
/**@deprecated*/ | ||
export const findRule = wrapFunctionForDeprecation(deprecatedFindRule, { | ||
name: `findRule`, | ||
}); | ||
export type { | ||
SelectorChunk, | ||
SelectorChunk2, | ||
Visitor, | ||
SelectorAstNode, | ||
PseudoSelectorAstNode, | ||
} from './deprecated/deprecated-selector-utils'; | ||
import { | ||
matchSelectorTarget as deprecatedMatchSelectorTarget, | ||
fixChunkOrdering as deprecatedFixChunkOrdering, | ||
filterChunkNodesByType as deprecatedFilterChunkNodesByType, | ||
separateChunks as deprecatedSeparateChunks, | ||
separateChunks2 as deprecatedSeparateChunks2, | ||
mergeChunks as deprecatedMergeChunks, | ||
matchAtMedia as deprecatedMatchAtMedia, | ||
matchAtKeyframes as deprecatedMatchAtKeyframes, | ||
isImport as deprecatedIsImport, | ||
isSimpleSelector as deprecatedIsSimpleSelector, | ||
isRootValid as deprecatedIsRootValid, | ||
isGlobal as deprecatedIsGlobal, | ||
createChecker as deprecatedCreateChecker, | ||
isNested as deprecatedIsNested, | ||
traverseNode as deprecatedTraverseNode, | ||
parseSelector as deprecatedParseSelector, | ||
stringifySelector as deprecatedStringifySelector, | ||
isNodeMatch as deprecatedIsNodeMatch, | ||
createSimpleSelectorChecker as deprecatedCreateSimpleSelectorChecker, | ||
} from './deprecated/deprecated-selector-utils'; | ||
/**@deprecated*/ | ||
export const matchSelectorTarget = deprecatedMatchSelectorTarget; | ||
/**@deprecated*/ | ||
export const fixChunkOrdering = wrapFunctionForDeprecation(deprecatedFixChunkOrdering, { | ||
name: `fixChunkOrdering`, | ||
}); | ||
/**@deprecated*/ | ||
export const filterChunkNodesByType = wrapFunctionForDeprecation(deprecatedFilterChunkNodesByType, { | ||
name: `filterChunkNodesByType`, | ||
}); | ||
/**@deprecated*/ | ||
export const separateChunks = wrapFunctionForDeprecation(deprecatedSeparateChunks, { | ||
name: `separateChunks`, | ||
}); | ||
/**@deprecated*/ | ||
export const separateChunks2 = wrapFunctionForDeprecation(deprecatedSeparateChunks2, { | ||
name: `separateChunks2`, | ||
}); | ||
/**@deprecated*/ | ||
export const mergeChunks = wrapFunctionForDeprecation(deprecatedMergeChunks, { | ||
name: `mergeChunks`, | ||
}); | ||
/**@deprecated*/ | ||
export const matchAtMedia = wrapFunctionForDeprecation(deprecatedMatchAtMedia, { | ||
name: `matchAtMedia`, | ||
}); | ||
/**@deprecated*/ | ||
export const matchAtKeyframes = wrapFunctionForDeprecation(deprecatedMatchAtKeyframes, { | ||
name: `matchAtKeyframes`, | ||
}); | ||
/**@deprecated*/ | ||
export const isImport = wrapFunctionForDeprecation(deprecatedIsImport, { | ||
name: `isImport`, | ||
}); | ||
/**@deprecated*/ | ||
export const isSimpleSelector = wrapFunctionForDeprecation(deprecatedIsSimpleSelector, { | ||
name: `isSimpleSelector`, | ||
}); | ||
/**@deprecated*/ | ||
export const isRootValid = wrapFunctionForDeprecation(deprecatedIsRootValid, { | ||
name: `isRootValid`, | ||
}); | ||
/**@deprecated*/ | ||
export const isGlobal = wrapFunctionForDeprecation(deprecatedIsGlobal, { | ||
name: `isGlobal`, | ||
}); | ||
/**@deprecated*/ | ||
export const createChecker = wrapFunctionForDeprecation(deprecatedCreateChecker, { | ||
name: `createChecker`, | ||
}); | ||
/**@deprecated*/ | ||
export const isNested = wrapFunctionForDeprecation(deprecatedIsNested, { | ||
name: `isNested`, | ||
}); | ||
/**@deprecated*/ | ||
export const isNodeMatch = wrapFunctionForDeprecation(deprecatedIsNodeMatch, { | ||
name: `isNodeMatch`, | ||
}); | ||
/**@deprecated*/ | ||
export const traverseNode = wrapFunctionForDeprecation(deprecatedTraverseNode, { | ||
name: `traverseNode`, | ||
pleaseUse: `"import { walk } from '@tokey/css-selector-parser'"`, | ||
}); | ||
/**@deprecated*/ | ||
export const parseSelector = wrapFunctionForDeprecation(deprecatedParseSelector, { | ||
name: `parseSelector`, | ||
pleaseUse: `"import { parseCssSelector } from '@tokey/css-selector-parser'"`, | ||
}); | ||
/**@deprecated*/ | ||
export const stringifySelector = wrapFunctionForDeprecation(deprecatedStringifySelector, { | ||
name: `stringifySelector`, | ||
pleaseUse: `"import { stringifySelector } from '@tokey/css-selector-parser'"`, | ||
}); | ||
/**@deprecated*/ | ||
export const createSimpleSelectorChecker = wrapFunctionForDeprecation( | ||
deprecatedCreateSimpleSelectorChecker, | ||
{ | ||
name: `createSimpleSelectorChecker`, | ||
} | ||
); |
@@ -53,2 +53,19 @@ // MDN reference: https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes | ||
/** | ||
* list names of pseudo classes that cannot be override by custom states | ||
* // [breaking] ToDo: add names of general pseudo classes that are not specific to elements | ||
* // like: root, only-child, nth-of-type, nth-last-child, nth-last-of-type, only-of-type... | ||
*/ | ||
export const reservedPseudoClasses = [ | ||
`not`, | ||
`any`, | ||
`matches`, | ||
`is`, | ||
`where`, | ||
`has`, | ||
// not native | ||
`global`, | ||
`local`, | ||
]; | ||
export const nativePseudoElements = [ | ||
@@ -55,0 +72,0 @@ 'after', |
@@ -5,5 +5,12 @@ import type * as postcss from 'postcss'; | ||
import { evalDeclarationValue } from './functions'; | ||
import type { SelectorAstNode } from './selector-utils'; | ||
import { | ||
parseSelectorWithCache, | ||
convertToClass, | ||
stringifySelector, | ||
convertToInvalid, | ||
} from './helpers/selector'; | ||
import { wrapFunctionForDeprecation } from './helpers/deprecation'; | ||
import type { PseudoClass } from '@tokey/css-selector-parser'; | ||
import { StateResult, systemValidators } from './state-validators'; | ||
import type { SRule, StylableMeta } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import type { StylableResolver } from './stylable-resolver'; | ||
@@ -14,2 +21,4 @@ import { groupValues, listOptions, MappedStates } from './stylable-value-parsers'; | ||
import { stripQuotation } from './utils'; | ||
import { reservedPseudoClasses } from './native-reserved-lists'; | ||
import cssesc from 'cssesc'; | ||
@@ -36,2 +45,3 @@ export const stateMiddleDelimiter = '-'; | ||
`state "${name}" declaration cannot begin with a "${stateMiddleDelimiter}" character`, | ||
RESERVED_NATIVE_STATE: (name: string) => `state "${name}" is reserved for native pseudo-class`, | ||
}; | ||
@@ -57,2 +67,7 @@ | ||
}); | ||
} else if (reservedPseudoClasses.includes(stateDefinition.value)) { | ||
diagnostics.warn(decl, stateErrors.RESERVED_NATIVE_STATE(stateDefinition.value), { | ||
word: stateDefinition.value, | ||
}); | ||
return; | ||
} | ||
@@ -99,3 +114,3 @@ | ||
const stateType: StateParsedValue = { | ||
type: stateDefinition.nodes[0].value, | ||
type: paramType.value, | ||
arguments: [], | ||
@@ -174,49 +189,53 @@ defaultValue: postcssValueParser | ||
export function validateStateDefinition( | ||
decl: postcss.Declaration, | ||
meta: StylableMeta, | ||
resolver: StylableResolver, | ||
diagnostics: Diagnostics | ||
) { | ||
if (decl.parent && decl.parent.type !== 'root') { | ||
const container = decl.parent; | ||
if (container.type !== 'atrule') { | ||
const sRule: SRule = container as SRule; | ||
if (sRule.selectorAst.nodes && sRule.selectorAst.nodes.length === 1) { | ||
const singleSelectorAst = sRule.selectorAst.nodes[0]; | ||
const selectorChunk = singleSelectorAst.nodes; | ||
/* @deprecated */ | ||
export const validateStateDefinition = wrapFunctionForDeprecation( | ||
function ( | ||
decl: postcss.Declaration, | ||
meta: StylableMeta, | ||
resolver: StylableResolver, | ||
diagnostics: Diagnostics | ||
) { | ||
if (decl.parent && decl.parent.type !== 'root') { | ||
const container = decl.parent; | ||
if (container.type !== 'atrule') { | ||
const parentRule = container as postcss.Rule; | ||
const selectorAst = parseSelectorWithCache(parentRule.selector); | ||
if (selectorAst.length && selectorAst.length === 1) { | ||
const singleSelectorAst = selectorAst[0]; | ||
const selectorChunk = singleSelectorAst.nodes; | ||
if (selectorChunk.length === 1 && selectorChunk[0].type === 'class') { | ||
const className = selectorChunk[0].name; | ||
const classMeta = meta.classes[className]; | ||
const states = classMeta[valueMapping.states]; | ||
if (selectorChunk.length === 1 && selectorChunk[0].type === 'class') { | ||
const className = selectorChunk[0].value; | ||
const classMeta = meta.classes[className]; | ||
const states = classMeta[valueMapping.states]; | ||
if (classMeta && classMeta._kind === 'class' && states) { | ||
for (const stateName in states) { | ||
// TODO: Sort out types | ||
const state = states[stateName]; | ||
if (state && typeof state === 'object') { | ||
const res = validateStateArgument( | ||
state, | ||
meta, | ||
state.defaultValue || '', | ||
resolver, | ||
diagnostics, | ||
sRule, | ||
true, | ||
!!state.defaultValue | ||
); | ||
if (classMeta && classMeta._kind === 'class' && states) { | ||
for (const stateName in states) { | ||
// TODO: Sort out types | ||
const state = states[stateName]; | ||
if (state && typeof state === 'object') { | ||
const res = validateStateArgument( | ||
state, | ||
meta, | ||
state.defaultValue || '', | ||
resolver, | ||
diagnostics, | ||
parentRule, | ||
true, | ||
!!state.defaultValue | ||
); | ||
if (res.errors) { | ||
res.errors.unshift( | ||
`pseudo-state "${stateName}" default value "${state.defaultValue}" failed validation:` | ||
); | ||
diagnostics.warn(decl, res.errors.join('\n'), { | ||
word: decl.value, | ||
}); | ||
if (res.errors) { | ||
res.errors.unshift( | ||
`pseudo-state "${stateName}" default value "${state.defaultValue}" failed validation:` | ||
); | ||
diagnostics.warn(decl, res.errors.join('\n'), { | ||
word: decl.value, | ||
}); | ||
} | ||
} | ||
} | ||
} else { | ||
// TODO: error state on non-class | ||
} | ||
} else { | ||
// TODO: error state on non-class | ||
} | ||
@@ -226,4 +245,5 @@ } | ||
} | ||
} | ||
} | ||
}, | ||
{ name: `validateStateDefinition` } | ||
); | ||
@@ -270,3 +290,3 @@ export function validateStateArgument( | ||
name: string, | ||
node: SelectorAstNode, | ||
node: PseudoClass, | ||
namespace: string, | ||
@@ -280,10 +300,10 @@ resolver: StylableResolver, | ||
if (stateDef === null) { | ||
node.type = 'class'; | ||
node.name = createBooleanStateClassName(name, namespace); | ||
convertToClass(node).value = createBooleanStateClassName(name, namespace); | ||
} else if (typeof stateDef === 'string') { | ||
node.type = 'invalid'; // simply concat global mapped selector - ToDo: maybe change to 'selector' | ||
node.value = stateDef; | ||
// simply concat global mapped selector - ToDo: maybe change to 'selector' | ||
convertToInvalid(node).value = stateDef; | ||
} else if (typeof stateDef === 'object') { | ||
resolveStateValue(meta, resolver, diagnostics, rule, node, stateDef, name, namespace); | ||
} | ||
delete node.nodes; | ||
} | ||
@@ -296,3 +316,3 @@ | ||
rule: postcss.Rule | undefined, | ||
node: SelectorAstNode, | ||
node: PseudoClass, | ||
stateDef: StateParsedValue, | ||
@@ -302,2 +322,3 @@ name: string, | ||
) { | ||
const inputValue = node.nodes && node.nodes.length ? stringifySelector(node.nodes) : ``; | ||
let actualParam = resolveParam( | ||
@@ -308,6 +329,6 @@ meta, | ||
rule, | ||
node.content || stateDef.defaultValue | ||
inputValue ? inputValue : stateDef.defaultValue | ||
); | ||
if (rule && !node.content && !stateDef.defaultValue) { | ||
if (rule && !inputValue && !stateDef.defaultValue) { | ||
diagnostics.warn(rule, stateErrors.NO_STATE_ARGUMENT_GIVEN(name, stateDef.type), { | ||
@@ -348,4 +369,3 @@ word: name, | ||
const strippedParam = stripQuotation(actualParam); | ||
node.type = 'class'; | ||
node.name = createStateWithParamClassName(name, namespace, strippedParam); | ||
convertToClass(node).value = createStateWithParamClassName(name, namespace, strippedParam); | ||
} | ||
@@ -366,14 +386,21 @@ | ||
export function createBooleanStateClassName(stateName: string, namespace: string) { | ||
return `${namespace}${booleanStateDelimiter}${stateName}`; | ||
const escapedNamespace = cssesc(namespace, { isIdentifier: true }); | ||
return `${escapedNamespace}${booleanStateDelimiter}${stateName}`; | ||
} | ||
export function createStateWithParamClassName(stateName: string, namespace: string, param: string) { | ||
return `${namespace}${stateWithParamDelimiter}${stateName}${resolveStateParam(param)}`; | ||
const escapedNamespace = cssesc(namespace, { isIdentifier: true }); | ||
return `${escapedNamespace}${stateWithParamDelimiter}${stateName}${resolveStateParam( | ||
param, | ||
true | ||
)}`; | ||
} | ||
export function resolveStateParam(param: string) { | ||
return `${stateMiddleDelimiter}${param.length}${stateMiddleDelimiter}${param.replace( | ||
export function resolveStateParam(param: string, escape = false) { | ||
const result = `${stateMiddleDelimiter}${param.length}${stateMiddleDelimiter}${param.replace( | ||
/\s/gm, | ||
'_' | ||
)}`; | ||
// adding/removing initial `s` to indicate that it's not the first param of the identifier | ||
return escape ? cssesc(`s` + result, { isIdentifier: true }).slice(1) : result; | ||
} |
import type { Diagnostic, DiagnosticType } from './diagnostics'; | ||
import type { StylableMeta } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
@@ -4,0 +4,0 @@ export interface EmitDiagnosticsContext { |
import type * as postcss from 'postcss'; | ||
import type { | ||
CSSVarSymbol, | ||
ClassSymbol, | ||
ElementSymbol, | ||
Imported, | ||
KeyframesSymbol, | ||
RefedMixin, | ||
SimpleSelector, | ||
StylableSymbol, | ||
VarSymbol, | ||
} from './features'; | ||
import type { Diagnostics } from './diagnostics'; | ||
import type { SelectorAstNode, SelectorChunk2 } from './selector-utils'; | ||
import type { SelectorList } from '@tokey/css-selector-parser'; | ||
import { getSourcePath } from './stylable-utils'; | ||
import { MappedStates, MixinValue, valueMapping } from './stylable-value-parsers'; | ||
import { setFieldForDeprecation } from './helpers/deprecation'; | ||
import { valueMapping } from './stylable-value-parsers'; | ||
export const RESERVED_ROOT_NAME = 'root'; | ||
@@ -25,3 +38,3 @@ | ||
public transformDiagnostics: Diagnostics | null; | ||
public transformedScopes: Record<string, SelectorChunk2[][]> | null; | ||
public transformedScopes: Record<string, SelectorList> | null; | ||
public scopes: postcss.AtRule[]; | ||
@@ -60,2 +73,3 @@ public simpleSelectors: Record<string, SimpleSelector>; | ||
this.simpleSelectors = {}; | ||
setFieldForDeprecation(this, `mixins`, { objectType: `stylableMeta` }); | ||
this.mixins = []; | ||
@@ -66,80 +80,1 @@ this.transformDiagnostics = null; | ||
} | ||
export interface Imported { | ||
from: string; | ||
defaultExport: string; | ||
named: Record<string, string>; | ||
keyframes: Record<string, string>; | ||
rule: postcss.Rule | postcss.AtRule; | ||
request: string; | ||
context: string; | ||
} | ||
export interface StylableDirectives { | ||
'-st-root'?: boolean; | ||
'-st-states'?: MappedStates; | ||
'-st-extends'?: ImportSymbol | ClassSymbol | ElementSymbol; | ||
'-st-global'?: SelectorAstNode[]; | ||
} | ||
export interface ClassSymbol extends StylableDirectives { | ||
_kind: 'class'; | ||
name: string; | ||
alias?: ImportSymbol; | ||
scoped?: string; | ||
} | ||
export interface ElementSymbol extends StylableDirectives { | ||
_kind: 'element'; | ||
name: string; | ||
alias?: ImportSymbol; | ||
} | ||
export interface ImportSymbol { | ||
_kind: 'import'; | ||
type: 'named' | 'default'; | ||
name: string; | ||
import: Imported; | ||
context: string; | ||
} | ||
export interface VarSymbol { | ||
_kind: 'var'; | ||
name: string; | ||
value: string; | ||
text: string; | ||
valueType: string | null; | ||
node: postcss.Node; | ||
} | ||
export interface KeyframesSymbol { | ||
_kind: 'keyframes'; | ||
alias: string; | ||
name: string; | ||
import?: Imported; | ||
global?: boolean; | ||
} | ||
export interface CSSVarSymbol { | ||
_kind: 'cssVar'; | ||
name: string; | ||
global: boolean; | ||
} | ||
export type StylableSymbol = | ||
| ImportSymbol | ||
| VarSymbol | ||
| ClassSymbol | ||
| ElementSymbol | ||
| CSSVarSymbol | ||
| KeyframesSymbol; | ||
export interface RefedMixin { | ||
mixin: MixinValue; | ||
ref: ImportSymbol | ClassSymbol; | ||
} | ||
export interface SimpleSelector { | ||
symbol: ClassSymbol | ElementSymbol; | ||
node: postcss.Rule | postcss.Root; | ||
} |
import { dirname } from 'path'; | ||
import * as postcss from 'postcss'; | ||
import type { Diagnostics } from './diagnostics'; | ||
import { resolveArgumentsValue } from './functions'; | ||
import { cssObjectToAst } from './parser'; | ||
import { fixRelativeUrls } from './stylable-assets'; | ||
import type { ImportSymbol } from './stylable-meta'; | ||
import type { RefedMixin, SRule, StylableMeta } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import type { RefedMixin, ImportSymbol } from './features'; | ||
import type { SRule } from './deprecated/postcss-ast-extension'; | ||
import type { CSSResolve } from './stylable-resolver'; | ||
import type { StylableTransformer } from './stylable-transformer'; | ||
import { createSubsetAst, isValidDeclaration, mergeRules } from './stylable-utils'; | ||
import { createSubsetAst } from './helpers/rule'; | ||
import { isValidDeclaration, mergeRules } from './stylable-utils'; | ||
import { valueMapping, mixinDeclRegExp, strategies } from './stylable-value-parsers'; | ||
import { ignoreDeprecationWarn } from './helpers/deprecation'; | ||
@@ -38,9 +40,10 @@ export const mixinWarnings = { | ||
) { | ||
if (!rule.mixins || rule.mixins.length === 0) { | ||
const mixins = ignoreDeprecationWarn(() => rule.mixins); | ||
if (!mixins || mixins.length === 0) { | ||
return; | ||
} | ||
rule.mixins.forEach((mix) => { | ||
mixins.forEach((mix) => { | ||
appendMixin(mix, transformer, rule, meta, variableOverride, cssVarsMapping, path); | ||
}); | ||
rule.mixins.length = 0; | ||
mixins.length = 0; | ||
rule.walkDecls(mixinDeclRegExp, (node) => { | ||
@@ -47,0 +50,0 @@ node.remove(); |
import path from 'path'; | ||
import * as postcss from 'postcss'; | ||
import postcssValueParser from 'postcss-value-parser'; | ||
import { tokenizeImports } from 'toky'; | ||
import { deprecatedStFunctions } from './custom-values'; | ||
import { Diagnostics } from './diagnostics'; | ||
import { parseSelector as deprecatedParseSelector } from './deprecated/deprecated-selector-utils'; | ||
import { murmurhash3_32_gc } from './murmurhash'; | ||
import { reservedKeyFrames } from './native-reserved-lists'; | ||
import { | ||
createSimpleSelectorChecker, | ||
isChildOfAtRule, | ||
isCompRoot, | ||
isNested, | ||
isRootValid, | ||
parseSelector, | ||
SelectorAstNode, | ||
traverseNode, | ||
} from './selector-utils'; | ||
import { | ||
import { StylableMeta } from './stylable-meta'; | ||
import type { | ||
ClassSymbol, | ||
@@ -27,5 +18,4 @@ CSSVarSymbol, | ||
StylableDirectives, | ||
StylableMeta, | ||
VarSymbol, | ||
} from './stylable-meta'; | ||
} from './features'; | ||
import { | ||
@@ -36,6 +26,18 @@ CUSTOM_SELECTOR_RE, | ||
isCSSVarProp, | ||
scopeSelector, | ||
} from './stylable-utils'; | ||
import { processDeclarationFunctions } from "./process-declaration-functions"; | ||
import { processDeclarationFunctions } from './process-declaration-functions'; | ||
import { | ||
walkSelector, | ||
isSimpleSelector, | ||
isInPseudoClassContext, | ||
isRootValid, | ||
isCompRoot, | ||
scopeNestedSelector, | ||
parseSelectorWithCache, | ||
stringifySelector, | ||
} from './helpers/selector'; | ||
import type { ImmutableSelectorNode } from '@tokey/css-selector-parser'; | ||
import { isChildOfAtRule } from './helpers/rule'; | ||
import type { SRule } from './deprecated/postcss-ast-extension'; | ||
import { | ||
paramMapping, | ||
@@ -49,6 +51,7 @@ rootValueMapping, | ||
import { deprecated, filename2varname, globalValue, stripQuotation } from './utils'; | ||
import { ignoreDeprecationWarn } from './helpers/deprecation'; | ||
import { validateAtProperty } from './validate-at-property'; | ||
import { parsePseudoImport, parseStImport } from './stylable-imports-tools'; | ||
export * from './stylable-meta'; /* TEMP EXPORT */ | ||
const parseNamed = SBTypesParsers[valueMapping.named]; | ||
const parseStates = SBTypesParsers[valueMapping.states]; | ||
@@ -62,4 +65,4 @@ const parseGlobal = SBTypesParsers[valueMapping.global]; | ||
}, | ||
UNSCOPED_ELEMENT(name: string) { | ||
return `unscoped element "${name}" will affect all elements of the same type in the document`; | ||
UNSCOPED_TYPE_SELECTOR(name: string) { | ||
return `unscoped type selector "${name}" will affect all elements of the same type in the document`; | ||
}, | ||
@@ -72,10 +75,4 @@ FORBIDDEN_DEF_IN_COMPLEX_SELECTOR(name: string) { | ||
}, | ||
DEFAULT_IMPORT_IS_LOWER_CASE() { | ||
return 'Default import of a Stylable stylesheet must start with an upper-case letter'; | ||
}, | ||
ILLEGAL_PROP_IN_IMPORT(propName: string) { | ||
return `"${propName}" css attribute cannot be used inside ${rootValueMapping.import} block`; | ||
}, | ||
STATE_DEFINITION_IN_ELEMENT() { | ||
return 'cannot define pseudo states inside element selectors'; | ||
return 'cannot define pseudo states inside a type selector'; | ||
}, | ||
@@ -112,5 +109,2 @@ STATE_DEFINITION_IN_COMPLEX() { | ||
}, | ||
FROM_PROP_MISSING_IN_IMPORT() { | ||
return `"${valueMapping.from}" is missing in ${rootValueMapping.import} block`; | ||
}, | ||
INVALID_NAMESPACE_DEF() { | ||
@@ -122,8 +116,2 @@ return 'invalid @namespace'; | ||
}, | ||
EMPTY_IMPORT_FROM() { | ||
return '"-st-from" cannot be empty'; | ||
}, | ||
MULTIPLE_FROM_IN_IMPORT() { | ||
return `cannot define multiple "${valueMapping.from}" declarations in a single import`; | ||
}, | ||
NO_VARS_DEF_IN_ST_SCOPE() { | ||
@@ -138,11 +126,2 @@ return `cannot define "${rootValueMapping.vars}" inside of "@st-scope"`; | ||
}, | ||
ST_IMPORT_STAR() { | ||
return '@st-import * is not supported'; | ||
}, | ||
ST_IMPORT_EMPTY_FROM() { | ||
return '@st-import must specify a valid "from" string value'; | ||
}, | ||
INVALID_ST_IMPORT_FORMAT(errors: string[]) { | ||
return `Invalid @st-import format:\n - ${errors.join('\n - ')}`; | ||
}, | ||
NO_KEYFRAMES_IN_ST_SCOPE() { | ||
@@ -181,2 +160,5 @@ return `cannot use "@keyframes" inside of "@st-scope"`; | ||
}, | ||
INVALID_FUNCTIONAL_SELECTOR(selector: string, type: string) { | ||
return `"${selector}" ${type} is not functional`; | ||
}, | ||
DEPRECATED_ST_GLOBAL_CUSTOM_PROPERTY() { | ||
@@ -204,3 +186,3 @@ return `"st-global-custom-property" is deprecated and will be removed in the next version. Use "@property" with ${paramMapping.global}`; | ||
this.handleAtRules(root); | ||
const stubs = this.insertCustomSelectorsStubs(); | ||
@@ -334,3 +316,3 @@ | ||
} else { | ||
this.diagnostics.warn(atRule, processorWarnings.NO_KEYFRAMES_IN_ST_SCOPE()); | ||
this.diagnostics.error(atRule, processorWarnings.NO_KEYFRAMES_IN_ST_SCOPE()); | ||
} | ||
@@ -362,3 +344,4 @@ break; | ||
} else { | ||
const stImport = this.handleStImport(atRule); | ||
const stImport = parseStImport(atRule, this.dirContext, this.diagnostics); | ||
atRule.remove(); | ||
this.meta.imports.push(stImport); | ||
@@ -481,18 +464,19 @@ this.addImportSymbols(stImport); | ||
protected handleRule(rule: SRule, inStScope = false) { | ||
rule.selectorAst = parseSelector(rule.selector); | ||
rule.selectorAst = deprecatedParseSelector(rule.selector); | ||
const checker = createSimpleSelectorChecker(); | ||
const selectorAst = parseSelectorWithCache(rule.selector); | ||
let locallyScoped = false; | ||
traverseNode(rule.selectorAst, (node, index, nodes, parents) => { | ||
if (node.type === 'selector' && !isNested(parents)) { | ||
let simpleSelector: boolean; | ||
walkSelector(selectorAst, (node, index, nodes, parents) => { | ||
const type = node.type; | ||
if (type === 'selector' && !isInPseudoClassContext(parents)) { | ||
locallyScoped = false; | ||
} | ||
if (!checker(node)) { | ||
rule.isSimpleSelector = false; | ||
if (type !== `selector` && type !== `class` && type !== `type`) { | ||
simpleSelector = false; | ||
} | ||
const { name, type } = node; | ||
if (type === 'pseudo-class') { | ||
if (name === 'import') { | ||
if (node.type === 'pseudo_class') { | ||
if (node.value === 'import') { | ||
if (rule.selector === rootValueMapping.import) { | ||
@@ -502,6 +486,6 @@ if (isChildOfAtRule(rule, rootValueMapping.stScope)) { | ||
rule.remove(); | ||
return false; | ||
return walkSelector.stopAll; | ||
} | ||
rule.remove(); | ||
return false; | ||
return walkSelector.stopAll; | ||
} else { | ||
@@ -515,3 +499,3 @@ this.diagnostics.warn( | ||
} | ||
} else if (name === 'vars') { | ||
} else if (node.value === 'vars') { | ||
if (rule.selector === rootValueMapping.vars) { | ||
@@ -524,7 +508,7 @@ if (isChildOfAtRule(rule, rootValueMapping.stScope)) { | ||
rule.remove(); | ||
return false; | ||
return walkSelector.stopAll; | ||
} | ||
this.addVarSymbols(rule); | ||
return false; | ||
return walkSelector.stopAll; | ||
} else { | ||
@@ -538,14 +522,28 @@ this.diagnostics.warn( | ||
} | ||
} else if (node.value === `global`) { | ||
return walkSelector.skipNested; | ||
} | ||
} else if (type === 'class') { | ||
this.addClassSymbolOnce(name, rule); | ||
if (this.meta.classes[name]) { | ||
if (!this.meta.classes[name].alias) { | ||
} else if (node.type === 'class') { | ||
this.addClassSymbolOnce(node.value, rule); | ||
if (node.nodes) { | ||
this.diagnostics.error( | ||
rule, | ||
processorWarnings.INVALID_FUNCTIONAL_SELECTOR(`.` + node.value, `class`), | ||
{ | ||
word: stringifySelector(node), | ||
} | ||
); | ||
} | ||
if (this.meta.classes[node.value]) { | ||
if (!this.meta.classes[node.value].alias) { | ||
locallyScoped = true; | ||
} else if (locallyScoped === false && !inStScope) { | ||
if (this.checkForScopedNodeAfter(rule, nodes, index) === false) { | ||
this.diagnostics.warn(rule, processorWarnings.UNSCOPED_CLASS(name), { | ||
word: name, | ||
}); | ||
this.diagnostics.warn( | ||
rule, | ||
processorWarnings.UNSCOPED_CLASS(node.value), | ||
{ | ||
word: node.value, | ||
} | ||
); | ||
} else { | ||
@@ -556,10 +554,32 @@ locallyScoped = true; | ||
} | ||
} else if (type === 'element') { | ||
this.addElementSymbolOnce(name, rule); | ||
} else if (node.type === 'type') { | ||
this.addElementSymbolOnce(node.value, rule); | ||
/** | ||
* intent to deprecate: currently `value(param)` can be used | ||
* as a custom state value. Unless there is a reasonable | ||
* use case, this should be removed. | ||
*/ | ||
if ( | ||
node.nodes && | ||
(parents.length < 2 || | ||
parents[parents.length - 2].type !== `pseudo_class` || | ||
node.value !== `value`) | ||
) { | ||
this.diagnostics.error( | ||
rule, | ||
processorWarnings.INVALID_FUNCTIONAL_SELECTOR(node.value, `type`), | ||
{ | ||
word: stringifySelector(node), | ||
} | ||
); | ||
} | ||
if (locallyScoped === false && !inStScope) { | ||
if (this.checkForScopedNodeAfter(rule, nodes, index) === false) { | ||
this.diagnostics.warn(rule, processorWarnings.UNSCOPED_ELEMENT(name), { | ||
word: name, | ||
}); | ||
this.diagnostics.warn( | ||
rule, | ||
processorWarnings.UNSCOPED_TYPE_SELECTOR(node.value), | ||
{ | ||
word: node.value, | ||
} | ||
); | ||
} else { | ||
@@ -569,9 +589,40 @@ locallyScoped = true; | ||
} | ||
} else if (type === 'nested-pseudo-class' && name === 'global') { | ||
return true; | ||
} else if (node.type === `id`) { | ||
if (node.nodes) { | ||
this.diagnostics.error( | ||
rule, | ||
processorWarnings.INVALID_FUNCTIONAL_SELECTOR(`#` + node.value, `id`), | ||
{ | ||
word: stringifySelector(node), | ||
} | ||
); | ||
} | ||
} else if (node.type === `attribute`) { | ||
if (node.nodes) { | ||
this.diagnostics.error( | ||
rule, | ||
processorWarnings.INVALID_FUNCTIONAL_SELECTOR( | ||
`[${node.value}]`, | ||
`attribute` | ||
), | ||
{ | ||
word: stringifySelector(node), | ||
} | ||
); | ||
} | ||
} else if (node.type === `nesting`) { | ||
if (node.nodes) { | ||
this.diagnostics.error( | ||
rule, | ||
processorWarnings.INVALID_FUNCTIONAL_SELECTOR(node.value, `nesting`), | ||
{ | ||
word: stringifySelector(node), | ||
} | ||
); | ||
} | ||
} | ||
return void 0; | ||
return; | ||
}); | ||
if (rule.isSimpleSelector !== false) { | ||
if (simpleSelector! !== false) { | ||
rule.isSimpleSelector = true; | ||
@@ -583,3 +634,4 @@ rule.selectorType = rule.selector.match(/^\./) ? 'class' : 'element'; | ||
if (!isRootValid(rule.selectorAst, 'root')) { | ||
// ToDo: check cases of root in nested selectors? | ||
if (!isRootValid(selectorAst)) { | ||
this.diagnostics.warn(rule, processorWarnings.ROOT_AFTER_SPACING()); | ||
@@ -608,16 +660,21 @@ } | ||
protected checkForScopedNodeAfter(rule: postcss.Rule, nodes: SelectorAstNode[], index: number) { | ||
protected checkForScopedNodeAfter( | ||
rule: postcss.Rule, | ||
nodes: ImmutableSelectorNode[], | ||
index: number | ||
) { | ||
for (let i = index + 1; i < nodes.length; i++) { | ||
const element = nodes[i]; | ||
if (!element) { | ||
// ToDo: can this get here??? | ||
break; | ||
} | ||
if (element.type === 'spacing' || element.type === 'operator') { | ||
if (element.type === 'combinator') { | ||
break; | ||
} | ||
if (element.type === 'class') { | ||
this.addClassSymbolOnce(element.name, rule); | ||
this.addClassSymbolOnce(element.value, rule); | ||
if (this.meta.classes[element.name]) { | ||
if (!this.meta.classes[element.name].alias) { | ||
if (this.meta.classes[element.value]) { | ||
if (!this.meta.classes[element.value].alias) { | ||
return true; | ||
@@ -802,4 +859,9 @@ } | ||
protected handleDirectives(rule: SRule, decl: postcss.Declaration) { | ||
const isSimplePerSelector = isSimpleSelector(rule.selector); | ||
const type = isSimplePerSelector.reduce((accType, { type }) => { | ||
return !accType ? type : accType !== type ? `complex` : type; | ||
}, `` as typeof isSimplePerSelector[number]['type']); | ||
const isSimple = type !== `complex`; | ||
if (decl.prop === valueMapping.states) { | ||
if (rule.isSimpleSelector && rule.selectorType !== 'element') { | ||
if (isSimple && type !== 'type') { | ||
this.extendTypedRule( | ||
@@ -812,3 +874,3 @@ decl, | ||
} else { | ||
if (rule.selectorType === 'element') { | ||
if (type === 'type') { | ||
this.diagnostics.warn(decl, processorWarnings.STATE_DEFINITION_IN_ELEMENT()); | ||
@@ -820,3 +882,3 @@ } else { | ||
} else if (decl.prop === valueMapping.extends) { | ||
if (rule.isSimpleSelector) { | ||
if (isSimple) { | ||
const parsed = parseExtends(decl.value); | ||
@@ -885,3 +947,3 @@ const symbolName = parsed.types[0] && parsed.types[0].symbolName; | ||
mixins.push(refedMixin); | ||
this.meta.mixins.push(refedMixin); | ||
ignoreDeprecationWarn(() => this.meta.mixins).push(refedMixin); | ||
} else { | ||
@@ -894,5 +956,6 @@ this.diagnostics.warn(decl, processorWarnings.UNKNOWN_MIXIN(mixin.type), { | ||
if (rule.mixins) { | ||
const partials = rule.mixins.filter((r) => r.mixin.partial); | ||
const nonPartials = rule.mixins.filter((r) => !r.mixin.partial); | ||
const previousMixins = ignoreDeprecationWarn(() => rule.mixins); | ||
if (previousMixins) { | ||
const partials = previousMixins.filter((r) => r.mixin.partial); | ||
const nonPartials = previousMixins.filter((r) => !r.mixin.partial); | ||
const isInPartial = decl.prop === valueMapping.partialMixin; | ||
@@ -918,3 +981,3 @@ if ( | ||
} else if (decl.prop === valueMapping.global) { | ||
if (rule.isSimpleSelector && rule.selectorType !== 'element') { | ||
if (isSimple && type !== 'type') { | ||
this.setClassGlobalMapping(decl, rule); | ||
@@ -952,47 +1015,3 @@ } else { | ||
} | ||
protected handleStImport(atRule: postcss.AtRule) { | ||
const importObj: Imported = { | ||
defaultExport: '', | ||
from: '', | ||
request: '', | ||
named: {}, | ||
rule: atRule, | ||
context: this.dirContext, | ||
keyframes: {}, | ||
}; | ||
const imports = tokenizeImports(`import ${atRule.params}`, '[', ']', true)[0]; | ||
if (imports && imports.star) { | ||
this.diagnostics.error(atRule, processorWarnings.ST_IMPORT_STAR()); | ||
} else { | ||
importObj.defaultExport = imports.defaultName || ''; | ||
setImportObjectFrom(imports.from || '', this.dirContext, importObj); | ||
if (imports.tagged?.keyframes) { | ||
// importObj.keyframes = imports.tagged?.keyframes; | ||
for (const [impName, impAsName] of Object.entries(imports.tagged.keyframes)) { | ||
importObj.keyframes[impAsName] = impName; | ||
} | ||
} | ||
if (imports.named) { | ||
for (const [impName, impAsName] of Object.entries(imports.named)) { | ||
importObj.named[impAsName] = impName; | ||
} | ||
} | ||
if (imports.errors.length) { | ||
this.diagnostics.error( | ||
atRule, | ||
processorWarnings.INVALID_ST_IMPORT_FORMAT(imports.errors) | ||
); | ||
} else if (!imports.from?.trim()) { | ||
this.diagnostics.error(atRule, processorWarnings.ST_IMPORT_EMPTY_FROM()); | ||
} | ||
} | ||
atRule.remove(); | ||
return importObj; | ||
} | ||
private handleScope(atRule: postcss.AtRule) { | ||
@@ -1006,3 +1025,6 @@ const scopingRule = postcss.rule({ selector: atRule.params }) as SRule; | ||
const scopedRule = rule.clone({ | ||
selector: scopeSelector(scopingRule.selector, rule.selector, false).selector, | ||
selector: scopeNestedSelector( | ||
parseSelectorWithCache(scopingRule.selector), | ||
parseSelectorWithCache(rule.selector) | ||
).selector, | ||
}); | ||
@@ -1028,73 +1050,2 @@ (scopedRule as SRule).stScopeSelector = atRule.params; | ||
function setImportObjectFrom(importPath: string, dirPath: string, importObj: Imported) { | ||
if (!path.isAbsolute(importPath) && !importPath.startsWith('.')) { | ||
importObj.request = importPath; | ||
importObj.from = importPath; | ||
} else { | ||
importObj.request = importPath; | ||
importObj.from = | ||
path.posix && path.posix.isAbsolute(dirPath) // browser has no posix methods | ||
? path.posix.resolve(dirPath, importPath) | ||
: path.resolve(dirPath, importPath); | ||
} | ||
} | ||
export function parsePseudoImport(rule: postcss.Rule, context: string, diagnostics: Diagnostics) { | ||
let fromExists = false; | ||
const importObj: Imported = { | ||
defaultExport: '', | ||
from: '', | ||
request: '', | ||
named: {}, | ||
keyframes: {}, | ||
rule, | ||
context, | ||
}; | ||
rule.walkDecls((decl) => { | ||
switch (decl.prop) { | ||
case valueMapping.from: { | ||
const importPath = stripQuotation(decl.value); | ||
if (!importPath.trim()) { | ||
diagnostics.error(decl, processorWarnings.EMPTY_IMPORT_FROM()); | ||
} | ||
if (fromExists) { | ||
diagnostics.warn(rule, processorWarnings.MULTIPLE_FROM_IN_IMPORT()); | ||
} | ||
setImportObjectFrom(importPath, context, importObj); | ||
fromExists = true; | ||
break; | ||
} | ||
case valueMapping.default: | ||
importObj.defaultExport = decl.value; | ||
if (!isCompRoot(importObj.defaultExport) && importObj.from.match(/\.css$/)) { | ||
diagnostics.warn(decl, processorWarnings.DEFAULT_IMPORT_IS_LOWER_CASE(), { | ||
word: importObj.defaultExport, | ||
}); | ||
} | ||
break; | ||
case valueMapping.named: | ||
{ | ||
const { keyframesMap, namedMap } = parseNamed(decl.value, decl, diagnostics); | ||
importObj.named = namedMap; | ||
importObj.keyframes = keyframesMap; | ||
} | ||
break; | ||
default: | ||
diagnostics.warn(decl, processorWarnings.ILLEGAL_PROP_IN_IMPORT(decl.prop), { | ||
word: decl.prop, | ||
}); | ||
break; | ||
} | ||
}); | ||
if (!importObj.from) { | ||
diagnostics.error(rule, processorWarnings.FROM_PROP_MISSING_IN_IMPORT()); | ||
} | ||
return importObj; | ||
} | ||
export function validateScopingSelector( | ||
@@ -1128,19 +1079,1 @@ atRule: postcss.AtRule, | ||
} | ||
// TODO: maybe put under stylable namespace object in v2 | ||
export interface SRule extends postcss.Rule { | ||
selectorAst: SelectorAstNode; | ||
isSimpleSelector: boolean; | ||
selectorType: 'class' | 'element' | 'complex'; | ||
mixins?: RefedMixin[]; | ||
stScopeSelector?: string; | ||
} | ||
// TODO: maybe put under stylable namespace object in v2 | ||
export interface DeclStylableProps { | ||
sourceValue: string; | ||
} | ||
export interface SDecl extends postcss.Declaration { | ||
stylable: DeclStylableProps; | ||
} |
import type { FileProcessor } from './cached-process-file'; | ||
import type { Diagnostics } from './diagnostics'; | ||
import type { ClassSymbol, ElementSymbol, Imported } from './stylable-meta'; | ||
import type { ImportSymbol, StylableMeta, StylableSymbol } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import type { | ||
ImportSymbol, | ||
ClassSymbol, | ||
ElementSymbol, | ||
Imported, | ||
StylableSymbol, | ||
} from './features'; | ||
import type { StylableTransformer } from './stylable-transformer'; | ||
@@ -21,5 +27,26 @@ import { valueMapping } from './stylable-value-parsers'; | ||
}; | ||
export type CachedModule = StylableMeta | JsModule | null; | ||
export type StylableResolverCache = Map<string, StylableMeta | JsModule | null>; | ||
export interface InvalidCachedModule { | ||
kind: 'js' | 'css'; | ||
value: null; | ||
error: unknown; | ||
request: string; | ||
context: string; | ||
} | ||
export interface CachedStylableMeta { | ||
resolvedPath: string; | ||
kind: 'css'; | ||
value: StylableMeta; | ||
} | ||
export interface CachedJsModule { | ||
resolvedPath: string; | ||
kind: 'js'; | ||
value: JsModule; | ||
} | ||
export type CachedModuleEntity = InvalidCachedModule | CachedStylableMeta | CachedJsModule; | ||
export type StylableResolverCache = Map<string, CachedModuleEntity>; | ||
export interface CSSResolve<T extends StylableSymbol = StylableSymbol> { | ||
@@ -55,3 +82,3 @@ _kind: 'css'; | ||
) {} | ||
private getModule({ context, from }: Imported): CachedModule { | ||
private getModule({ context, from }: Imported): CachedModuleEntity { | ||
const key = `${context}${safePathDelimiter}${from}`; | ||
@@ -61,18 +88,30 @@ if (this.cache?.has(key)) { | ||
} | ||
let res; | ||
if (from.match(/\.css$/)) { | ||
let entity: CachedModuleEntity; | ||
if (from.endsWith('.css')) { | ||
const kind = 'css'; | ||
try { | ||
res = this.fileProcessor.process(from, false, context); | ||
} catch (e) { | ||
res = null; | ||
const resolvedPath = this.fileProcessor.resolvePath(from, context); | ||
const value = this.fileProcessor.process(resolvedPath, false, context); | ||
entity = { kind, value, resolvedPath }; | ||
} catch (error) { | ||
entity = { kind, value: null, error, request: from, context }; | ||
} | ||
} else { | ||
const kind = 'js'; | ||
try { | ||
res = this.requireModule(this.fileProcessor.resolvePath(from, context)); | ||
} catch { | ||
res = null; | ||
const resolvedPath = this.fileProcessor.resolvePath(from, context); | ||
const value = this.requireModule(resolvedPath); | ||
entity = { kind, value, resolvedPath }; | ||
} catch (error) { | ||
entity = { kind, value: null, error, request: from, context }; | ||
} | ||
} | ||
this.cache?.set(key, res); | ||
return res; | ||
this.cache?.set(key, entity); | ||
return entity; | ||
} | ||
@@ -86,8 +125,8 @@ | ||
const res = this.getModule(imported); | ||
if (res === null) { | ||
if (res.value === null) { | ||
return null; | ||
} | ||
if (imported.from.match(/\.css$/)) { | ||
const meta = res as StylableMeta; | ||
if (res.kind === 'css') { | ||
const { value: meta } = res; | ||
return { | ||
@@ -99,3 +138,3 @@ _kind: 'css', | ||
} else { | ||
const jsModule = res as JsModule; | ||
const { value: jsModule } = res; | ||
return { | ||
@@ -102,0 +141,0 @@ _kind: 'js', |
@@ -11,27 +11,30 @@ import isVendorPrefixed from 'is-vendor-prefixed'; | ||
import { nativePseudoClasses, nativePseudoElements } from './native-reserved-lists'; | ||
import { setStateToNode, stateErrors, validateStateDefinition } from './pseudo-states'; | ||
import { setStateToNode, stateErrors } from './pseudo-states'; | ||
import { | ||
createWarningRule, | ||
getOriginDefinition, | ||
isChildOfAtRule, | ||
mergeChunks, | ||
parseSelector, | ||
SelectorAstNode, | ||
SelectorChunk2, | ||
separateChunks2, | ||
walkSelector, | ||
parseSelectorWithCache, | ||
stringifySelector, | ||
traverseNode, | ||
} from './selector-utils'; | ||
flattenFunctionalSelector, | ||
convertToClass, | ||
} from './helpers/selector'; | ||
import { validateRuleStateDefinition } from './helpers/custom-state'; | ||
import { | ||
SelectorNode, | ||
Selector, | ||
SelectorList, | ||
groupCompoundSelectors, | ||
CompoundSelector, | ||
splitCompoundSelectors, | ||
} from '@tokey/css-selector-parser'; | ||
import { createWarningRule, isChildOfAtRule, findRule, getRuleScopeSelector } from './helpers/rule'; | ||
import { getOriginDefinition } from './helpers/resolve'; | ||
import { appendMixins } from './stylable-mixins'; | ||
import type { | ||
ClassSymbol, | ||
ElementSymbol, | ||
SDecl, | ||
SRule, | ||
StylableMeta, | ||
StylableSymbol, | ||
} from './stylable-processor'; | ||
import { CSSResolve, StylableResolver, StylableResolverCache } from './stylable-resolver'; | ||
import { findRule, generateScopedCSSVar, getDeclStylable, isCSSVarProp } from './stylable-utils'; | ||
import type { ClassSymbol, ElementSymbol } from './features'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import type { SRule, SDecl } from './deprecated/postcss-ast-extension'; | ||
import { CSSResolve, StylableResolverCache, StylableResolver } from './stylable-resolver'; | ||
import { generateScopedCSSVar, isCSSVarProp } from './stylable-utils'; | ||
import { animationPropRegExp, valueMapping } from './stylable-value-parsers'; | ||
import cssesc from 'cssesc'; | ||
import { unescapeCSS } from './helpers/escape'; | ||
import { globalValue } from './utils'; | ||
@@ -64,10 +67,2 @@ | ||
export interface ScopedSelectorResults { | ||
current: StylableMeta; | ||
symbol: StylableSymbol | null; | ||
selectorAst: SelectorAstNode; | ||
selector: string; | ||
elements: ResolvedElement[][]; | ||
} | ||
export type replaceValueHook = ( | ||
@@ -104,8 +99,2 @@ value: string, | ||
export interface AdditionalSelector { | ||
selectorNode: SelectorAstNode; | ||
node: SelectorAstNode; | ||
customElementChunk: string; | ||
} | ||
export const transformerWarnings = { | ||
@@ -214,3 +203,3 @@ UNKNOWN_PSEUDO_ELEMENT(name: string) { | ||
ast.walkDecls((decl) => { | ||
getDeclStylable(decl as SDecl).sourceValue = decl.value; | ||
(decl as SDecl).stylable = { sourceValue: decl.value }; | ||
@@ -224,5 +213,3 @@ if (isCSSVarProp(decl.prop)) { | ||
case valueMapping.mixin: | ||
break; | ||
case valueMapping.states: | ||
validateStateDefinition(decl, meta, this.resolver, this.diagnostics); | ||
break; | ||
@@ -379,3 +366,3 @@ default: | ||
} | ||
public addGlobalsToMeta(selectorAst: SelectorAstNode[], meta?: StylableMeta) { | ||
public addGlobalsToMeta(selectorAst: SelectorNode[], meta?: StylableMeta) { | ||
if (!meta) { | ||
@@ -386,5 +373,5 @@ return; | ||
for (const ast of selectorAst) { | ||
traverseNode(ast, (inner) => { | ||
walkSelector(ast, (inner) => { | ||
if (inner.type === 'class') { | ||
meta.globals[inner.name] = true; | ||
meta.globals[inner.value] = true; | ||
} | ||
@@ -396,10 +383,10 @@ }); | ||
ast.walkRules((r) => { | ||
const selectorAst = parseSelector(r.selector); | ||
traverseNode(selectorAst, (node) => { | ||
if (node.type === 'nested-pseudo-class' && node.name === 'global') { | ||
const selectorAst = parseSelectorWithCache(r.selector, { clone: true }); | ||
walkSelector(selectorAst, (node) => { | ||
if (node.type === 'pseudo_class' && node.value === 'global') { | ||
this.addGlobalsToMeta([node], meta); | ||
node.type = 'selector'; | ||
return true; | ||
flattenFunctionalSelector(node); | ||
return walkSelector.skipNested; | ||
} | ||
return undefined; | ||
return; | ||
}); | ||
@@ -420,2 +407,5 @@ // this.addGlobalsToMeta([selectorAst], meta); | ||
} | ||
public scopeEscape(name: string, namespace: string, delimiter: string = this.delimiter) { | ||
return namespace ? cssesc(namespace, { isIdentifier: true }) + delimiter + name : name; | ||
} | ||
public exportClasses(meta: StylableMeta) { | ||
@@ -426,3 +416,3 @@ const locals: Record<string, string> = {}; | ||
const exportedClasses = this.getPartExports(resolved); | ||
locals[localName] = exportedClasses.join(' '); | ||
locals[localName] = unescapeCSS(exportedClasses.join(' ')); | ||
} | ||
@@ -451,6 +441,6 @@ return locals; | ||
rule?: postcss.Rule | ||
): { selector: string; elements: ResolvedElement[][]; targetSelectorAst: SelectorAstNode } { | ||
): { selector: string; elements: ResolvedElement[][]; targetSelectorAst: SelectorList } { | ||
const context = new ScopeContext( | ||
originMeta, | ||
parseSelector(selector), | ||
parseSelectorWithCache(selector, { clone: true }), | ||
rule || postcss.rule({ selector }) | ||
@@ -465,7 +455,7 @@ ); | ||
} | ||
public scopeSelectorAst(context: ScopeContext): SelectorAstNode { | ||
public scopeSelectorAst(context: ScopeContext): SelectorList { | ||
const { originMeta, selectorAst } = context; | ||
// split selectors to chunks: .a.b .c:hover, a .c:hover -> [[[.a.b], [.c:hover]], [[.a], [.c:hover]]] | ||
const selectorListChunks = separateChunks2(selectorAst); | ||
// group compound selectors: .a.b .c:hover, a .c:hover -> [[[.a.b], [.c:hover]], [[.a], [.c:hover]]] | ||
const selectorList = groupCompoundSelectors(selectorAst); | ||
// resolve meta classes and elements | ||
@@ -483,17 +473,20 @@ context.metaParts = this.resolveMetaParts(originMeta); | ||
// loop over selectors | ||
for (const selectorChunks of selectorListChunks) { | ||
for (const selector of selectorList) { | ||
context.elements.push([]); | ||
context.selectorIndex++; | ||
context.chunks = selectorChunks; | ||
// loop over chunks | ||
for (const chunk of selectorChunks) { | ||
context.chunk = chunk; | ||
// loop over each node in a chunk | ||
for (const node of chunk.nodes) { | ||
context.node = node; | ||
context.selector = selector; | ||
// loop over nodes | ||
for (const node of [...selector.nodes]) { | ||
if (node.type !== `compound_selector`) { | ||
continue; | ||
} | ||
context.compoundSelector = node; | ||
// loop over each node in a compound selector | ||
for (const compoundNode of node.nodes) { | ||
context.node = compoundNode; | ||
// transform node | ||
this.handleChunkNode(context); | ||
this.handleCompoundNode(context); | ||
} | ||
} | ||
if (selectorListChunks.length - 1 > context.selectorIndex) { | ||
if (selectorList.length - 1 > context.selectorIndex) { | ||
// reset current anchor | ||
@@ -503,24 +496,30 @@ context.initRootAnchor(startedAnchor); | ||
} | ||
const outputAst = mergeChunks(selectorListChunks); | ||
context.additionalSelectors.forEach((addSelector) => outputAst.nodes.push(addSelector())); | ||
// backwards compatibility for elements - empty selector still have an empty first target | ||
if (selectorList.length === 0) { | ||
context.elements.push([]); | ||
} | ||
const outputAst = splitCompoundSelectors(selectorList); | ||
context.additionalSelectors.forEach((addSelector) => outputAst.push(addSelector())); | ||
return outputAst; | ||
} | ||
private handleChunkNode(context: ScopeContext) { | ||
private handleCompoundNode(context: ScopeContext) { | ||
const { currentAnchor, metaParts, node, originMeta, transformGlobals } = | ||
context as Required<ScopeContext>; | ||
const { type, name } = node; | ||
if (type === 'class') { | ||
const resolved = metaParts.class[name] || [ | ||
if (node.type === 'class') { | ||
const resolved = metaParts.class[node.value] || [ | ||
// used to scope classes from js mixins | ||
{ _kind: 'css', meta: originMeta, symbol: { _kind: 'class', name } }, | ||
{ _kind: 'css', meta: originMeta, symbol: { _kind: 'class', name: node.value } }, | ||
]; | ||
context.setCurrentAnchor({ name, type: 'class', resolved }); | ||
context.setCurrentAnchor({ name: node.value, type: 'class', resolved }); | ||
const { symbol, meta } = getOriginDefinition(resolved); | ||
if (context.originMeta === meta && symbol[valueMapping.states]) { | ||
validateRuleStateDefinition(context.rule, meta, this.resolver, this.diagnostics); | ||
} | ||
this.scopeClassNode(symbol, meta, node, originMeta); | ||
} else if (type === 'element') { | ||
const resolved = metaParts.element[name] || [ | ||
} else if (node.type === 'type') { | ||
const resolved = metaParts.element[node.value] || [ | ||
// provides resolution for native elements | ||
{ _kind: 'css', meta: originMeta, symbol: { _kind: 'element', name } }, | ||
{ _kind: 'css', meta: originMeta, symbol: { _kind: 'element', name: node.value } }, | ||
]; | ||
context.setCurrentAnchor({ name, type: 'element', resolved }); | ||
context.setCurrentAnchor({ name: node.value, type: 'element', resolved }); | ||
// native node does not resolve e.g. div | ||
@@ -531,3 +530,9 @@ if (resolved && resolved.length > 1) { | ||
} | ||
} else if (type === 'pseudo-element') { | ||
} else if (node.type === 'pseudo_element') { | ||
if (node.value === ``) { | ||
// partial psuedo elemennt: `.x::` | ||
// ToDo: currently the transformer corrects the css without warning, | ||
// should stylable warn? | ||
return; | ||
} | ||
const len = currentAnchor.resolved.length; | ||
@@ -543,9 +548,9 @@ const lookupStartingPoint = len === 1 /* no extends */ ? 0 : 1; | ||
const customSelector = meta.customSelectors[':--' + name]; | ||
const customSelector = meta.customSelectors[':--' + node.value]; | ||
if (customSelector) { | ||
this.handleCustomSelector(customSelector, meta, context, name, node); | ||
this.handleCustomSelector(customSelector, meta, context, node.value, node); | ||
return; | ||
} | ||
const requestedPart = meta.classes[name]; | ||
const requestedPart = meta.classes[node.value]; | ||
@@ -557,7 +562,7 @@ if (symbol.alias || !requestedPart) { | ||
resolved = this.resolveMetaParts(meta).class[name]; | ||
resolved = this.resolveMetaParts(meta).class[node.value]; | ||
// first definition of a part in the extends/alias chain | ||
context.setCurrentAnchor({ | ||
name, | ||
name: node.value, | ||
type: 'pseudo-element', | ||
@@ -569,3 +574,6 @@ resolved, | ||
node.before = resolvedPart.symbol[valueMapping.root] ? '' : ' '; | ||
if (!resolvedPart.symbol[valueMapping.root]) { | ||
// insert nested combinator before internal custom element | ||
context.insertDescendantCombinatorBeforePseudoElement(); | ||
} | ||
this.scopeClassNode(resolvedPart.symbol, resolvedPart.meta, node, originMeta); | ||
@@ -579,3 +587,3 @@ | ||
context.setCurrentAnchor({ | ||
name, | ||
name: node.value, | ||
type: 'pseudo-element', | ||
@@ -586,4 +594,4 @@ resolved: [], | ||
if ( | ||
!nativePseudoElements.includes(name) && | ||
!isVendorPrefixed(name) && | ||
!nativePseudoElements.includes(node.value) && | ||
!isVendorPrefixed(node.value) && | ||
!this.isDuplicateStScopeDiagnostic(context) | ||
@@ -593,5 +601,5 @@ ) { | ||
context.rule, | ||
transformerWarnings.UNKNOWN_PSEUDO_ELEMENT(name), | ||
transformerWarnings.UNKNOWN_PSEUDO_ELEMENT(node.value), | ||
{ | ||
word: name, | ||
word: node.value, | ||
} | ||
@@ -601,13 +609,14 @@ ); | ||
} | ||
} else if (type === 'pseudo-class') { | ||
let found = false; | ||
} else if (node.type === 'pseudo_class') { | ||
// find matching custom state | ||
let foundCustomState = false; | ||
for (const { symbol, meta } of currentAnchor.resolved) { | ||
const states = symbol[valueMapping.states]; | ||
if (states && hasOwnProperty.call(states, name)) { | ||
found = true; | ||
if (states && hasOwnProperty.call(states, node.value)) { | ||
foundCustomState = true; | ||
// transform custom state | ||
setStateToNode( | ||
states, | ||
meta, | ||
name, | ||
node.value, | ||
node, | ||
@@ -622,37 +631,48 @@ meta.namespace, | ||
} | ||
// handle nested pseudo classes | ||
if (node.nodes && !foundCustomState) { | ||
if (node.value === 'global') { | ||
// :global(.a) -> .a | ||
if (transformGlobals) { | ||
flattenFunctionalSelector(node); | ||
} | ||
return; | ||
} else { | ||
// pickup all nested selectors except nth initial selector | ||
const innerSelectors = ( | ||
node.nodes[0] && node.nodes[0].type === `nth` | ||
? node.nodes.slice(1) | ||
: node.nodes | ||
) as Selector[]; | ||
const nestedContext = context.createNestedContext(innerSelectors); | ||
this.scopeSelectorAst(nestedContext); | ||
/** | ||
* ToDo: remove once elements is deprecated! | ||
* support deprecated elements. | ||
* used to flatten nested elements for some native pseudo classes. | ||
*/ | ||
if (node.value.match(/not|any|-\w+?-any|matches|is|where|has|local/)) { | ||
// delegate elements of first selector | ||
context.elements[context.selectorIndex].push(...nestedContext.elements[0]); | ||
} | ||
} | ||
} | ||
// warn unknown state | ||
if ( | ||
!found && | ||
!nativePseudoClasses.includes(name) && | ||
!isVendorPrefixed(name) && | ||
!foundCustomState && | ||
!nativePseudoClasses.includes(node.value) && | ||
!isVendorPrefixed(node.value) && | ||
!this.isDuplicateStScopeDiagnostic(context) | ||
) { | ||
this.diagnostics.warn(context.rule, stateErrors.UNKNOWN_STATE_USAGE(name), { | ||
word: name, | ||
this.diagnostics.warn(context.rule, stateErrors.UNKNOWN_STATE_USAGE(node.value), { | ||
word: node.value, | ||
}); | ||
} | ||
} else if (type === 'nested-pseudo-class') { | ||
if (name === 'global') { | ||
// :global(.a) -> .a | ||
if (transformGlobals) { | ||
node.type = 'selector'; | ||
} | ||
} else { | ||
const nestedContext = context.createNestedContext({ | ||
type: 'selectors', | ||
name: `${name}`, | ||
nodes: node.nodes, | ||
}); | ||
this.scopeSelectorAst(nestedContext); | ||
// delegate elements of first selector | ||
context.elements[context.selectorIndex].push(...nestedContext.elements[0]); | ||
} | ||
} else if (type === 'invalid' && node.value === '&') { | ||
if (/* maybe should be currentAnchor meta */ originMeta.parent) { | ||
const origin = originMeta.mappedSymbols[originMeta.root] as ClassSymbol; | ||
context.setCurrentAnchor({ | ||
name: origin.name, | ||
type: 'class', | ||
resolved: metaParts.class[origin.name], | ||
}); | ||
} | ||
} else if (node.type === `nesting`) { | ||
const origin = originMeta.mappedSymbols[originMeta.root] as ClassSymbol; | ||
context.setCurrentAnchor({ | ||
name: origin.name, | ||
type: 'class', | ||
resolved: metaParts.class[origin.name], | ||
}); | ||
} | ||
@@ -662,21 +682,13 @@ } | ||
const transformedScope = | ||
context.originMeta.transformedScopes?.[(context.rule as any).stScopeSelector]; | ||
if (transformedScope && context.chunks && context.chunk) { | ||
const currentChunkSelector = stringifySelector({ | ||
type: 'selector', | ||
nodes: context.chunk.nodes, | ||
name: '', | ||
}); | ||
const i = context.chunks.indexOf(context.chunk); | ||
for (const stScopeSelectorChunks of transformedScope) { | ||
context.originMeta.transformedScopes?.[getRuleScopeSelector(context.rule) || ``]; | ||
if (transformedScope && context.selector && context.compoundSelector) { | ||
const currentCompoundSelector = stringifySelector(context.compoundSelector); | ||
const i = context.selector.nodes.indexOf(context.compoundSelector); | ||
for (const stScopeSelectorCompounded of transformedScope) { | ||
// if we are in a chunk index that is in the rage of the @st-scope param | ||
if (i <= stScopeSelectorChunks.length) { | ||
for (const chunk of stScopeSelectorChunks) { | ||
const scopeChunkSelector = stringifySelector({ | ||
type: 'selector', | ||
nodes: chunk.nodes, | ||
name: '', | ||
}); | ||
if (i <= stScopeSelectorCompounded.nodes.length) { | ||
for (const scopeNode of stScopeSelectorCompounded.nodes) { | ||
const scopeNodeSelector = stringifySelector(scopeNode); | ||
// if the two chunks match the error is already reported by the @st-scope validation | ||
if (scopeChunkSelector === currentChunkSelector) { | ||
if (scopeNodeSelector === currentCompoundSelector) { | ||
return true; | ||
@@ -695,14 +707,13 @@ } | ||
name: string, | ||
node: SelectorAstNode | ||
node: SelectorNode | ||
) { | ||
const selectorListChunks = separateChunks2(parseSelector(customSelector)); | ||
const hasSingleSelector = selectorListChunks.length === 1; | ||
removeFirstRootInEachSelectorChunk(selectorListChunks, meta); | ||
const selectorList = parseSelectorWithCache(customSelector, { clone: true }); | ||
const hasSingleSelector = selectorList.length === 1; | ||
const internalContext = new ScopeContext( | ||
meta, | ||
mergeChunks(selectorListChunks), | ||
removeFirstRootInFirstCompound(selectorList, meta), | ||
context.rule | ||
); | ||
const customAstSelectors = this.scopeSelectorAst(internalContext).nodes; | ||
customAstSelectors.forEach(trimLeftSelectorAst); | ||
const customAstSelectors = this.scopeSelectorAst(internalContext); | ||
customAstSelectors.forEach(setSingleSpaceOnSelectorLeft); | ||
if (hasSingleSelector && internalContext.currentAnchor) { | ||
@@ -725,3 +736,3 @@ context.setCurrentAnchor({ | ||
for (let i = 1; i < customAstSelectors.length; i++) { | ||
const selectorNode = context.selectorAst.nodes[context.selectorIndex]; | ||
const selectorNode = context.selectorAst[context.selectorIndex]; | ||
const nodeIndex = selectorNode.nodes.indexOf(node); | ||
@@ -733,11 +744,12 @@ context.additionalSelectors.push( | ||
} | ||
private scopeClassNode(symbol: any, meta: any, node: any, originMeta: any) { | ||
private scopeClassNode(symbol: any, meta: StylableMeta, node: any, originMeta: any) { | ||
if (symbol[valueMapping.global]) { | ||
const globalMappedNodes = symbol[valueMapping.global]; | ||
node.type = 'selector'; | ||
flattenFunctionalSelector(node); | ||
node.nodes = globalMappedNodes; | ||
// ToDo: check if this is causes an issue with globals from an imported alias | ||
this.addGlobalsToMeta(globalMappedNodes, originMeta); | ||
} else { | ||
node.type = 'class'; | ||
node.name = this.scope(symbol.name, meta.namespace); | ||
convertToClass(node); | ||
node.value = this.scopeEscape(symbol.name, meta.namespace); | ||
} | ||
@@ -814,17 +826,20 @@ } | ||
if (resolved.length > 1) { | ||
meta.outputAst!.walkRules('.' + this.scope(className, meta.namespace), (rule) => { | ||
const a = resolved[0]; | ||
const b = resolved[resolved.length - 1]; | ||
rule.after( | ||
createWarningRule( | ||
b.symbol.name, | ||
this.scope(b.symbol.name, b.meta.namespace), | ||
basename(b.meta.source), | ||
a.symbol.name, | ||
this.scope(a.symbol.name, a.meta.namespace), | ||
basename(a.meta.source), | ||
true | ||
) | ||
); | ||
}); | ||
meta.outputAst!.walkRules( | ||
'.' + this.scopeEscape(className, meta.namespace), | ||
(rule) => { | ||
const a = resolved[0]; | ||
const b = resolved[resolved.length - 1]; | ||
rule.after( | ||
createWarningRule( | ||
b.symbol.name, | ||
this.scopeEscape(b.symbol.name, b.meta.namespace), | ||
basename(b.meta.source), | ||
a.symbol.name, | ||
this.scopeEscape(a.symbol.name, a.meta.namespace), | ||
basename(a.meta.source), | ||
true | ||
) | ||
); | ||
} | ||
); | ||
} | ||
@@ -841,3 +856,3 @@ } | ||
function validateScopes(transformer: StylableTransformer, meta: StylableMeta) { | ||
const transformedScopes: Record<string, SelectorChunk2[][]> = {}; | ||
const transformedScopes: Record<string, SelectorList> = {}; | ||
for (const scope of meta.scopes) { | ||
@@ -847,4 +862,10 @@ const len = transformer.diagnostics.reports.length; | ||
const context = new ScopeContext(meta, parseSelector(rule.selector), rule); | ||
transformedScopes[rule.selector] = separateChunks2(transformer.scopeSelectorAst(context)); | ||
const context = new ScopeContext( | ||
meta, | ||
parseSelectorWithCache(rule.selector, { clone: true }), | ||
rule | ||
); | ||
transformedScopes[rule.selector] = groupCompoundSelectors( | ||
transformer.scopeSelectorAst(context) | ||
); | ||
const ruleReports = transformer.diagnostics.reports.splice(len); | ||
@@ -863,22 +884,31 @@ | ||
function removeFirstRootInEachSelectorChunk( | ||
selectorListChunks: SelectorChunk2[][], | ||
meta: StylableMeta | ||
) { | ||
selectorListChunks.forEach((selectorChunks) => { | ||
selectorChunks[0].nodes = selectorChunks[0].nodes.filter(({ type, name }) => { | ||
return !(type === 'class' && name === meta.root); | ||
}); | ||
}); | ||
function removeFirstRootInFirstCompound(selectorList: SelectorList, meta: StylableMeta) { | ||
const compounded = groupCompoundSelectors(selectorList); | ||
for (const selector of compounded) { | ||
const first = selector.nodes.find(({ type }) => type === `compound_selector`); | ||
if (first && first.type === `compound_selector`) { | ||
first.nodes = first.nodes.filter((node) => { | ||
return !(node.type === 'class' && node.value === meta.root); | ||
}); | ||
} | ||
} | ||
return splitCompoundSelectors(compounded); | ||
} | ||
function trimLeftSelectorAst(n: SelectorAstNode, i = 0) { | ||
if (n) { | ||
if (n.type === 'spacing') { | ||
n.value = ''; | ||
function setSingleSpaceOnSelectorLeft(n: Selector) { | ||
n.before = ` `; | ||
let parent: Selector = n; | ||
let nextLeft: SelectorNode | undefined = n.nodes[0]; | ||
while (nextLeft) { | ||
if (`before` in nextLeft) { | ||
nextLeft.before = ``; | ||
} | ||
n.before = ''; | ||
trimLeftSelectorAst(n.nodes && n.nodes[0], i + 1); | ||
if (i === 0) { | ||
n.before = ' '; | ||
if (nextLeft.type === `selector`) { | ||
nextLeft = nextLeft.nodes[0]; | ||
parent = nextLeft as Selector; | ||
} else if (nextLeft.type === `combinator` && nextLeft.combinator === `space`) { | ||
parent.nodes.shift(); | ||
nextLeft = parent.nodes[0]; | ||
} else { | ||
return; | ||
} | ||
@@ -901,12 +931,12 @@ } | ||
function lazyCreateSelector( | ||
customElementChunk: SelectorAstNode, | ||
selectorNode: SelectorAstNode, | ||
customElementChunk: Selector, | ||
selectorNode: Selector, | ||
nodeIndex: number | ||
) { | ||
): () => Selector { | ||
if (nodeIndex === -1) { | ||
throw new Error('not supported inside nested classes'); | ||
} | ||
return () => { | ||
return (): Selector => { | ||
const clone = cloneDeep(selectorNode); | ||
clone.nodes[nodeIndex].nodes = customElementChunk.nodes; | ||
(clone.nodes[nodeIndex] as any).nodes = customElementChunk.nodes; | ||
return clone; | ||
@@ -923,6 +953,3 @@ }; | ||
class ScopeContext { | ||
public originMeta: StylableMeta; | ||
public selectorAst: SelectorAstNode; | ||
public rule: postcss.Rule; | ||
public additionalSelectors: Array<() => void> = []; | ||
public additionalSelectors: Array<() => Selector> = []; | ||
public selectorIndex = -1; | ||
@@ -932,11 +959,11 @@ public elements: any[] = []; | ||
public metaParts?: MetaParts; | ||
public chunks?: SelectorChunk2[]; | ||
public chunk?: SelectorChunk2; | ||
public node?: SelectorAstNode; | ||
public selector?: Selector; | ||
public compoundSelector?: CompoundSelector; | ||
public node?: CompoundSelector['nodes'][number]; | ||
public currentAnchor?: ScopeAnchor; | ||
constructor(originMeta: StylableMeta, selectorAst: SelectorAstNode, rule: postcss.Rule) { | ||
this.originMeta = originMeta; | ||
this.selectorAst = selectorAst; | ||
this.rule = rule; | ||
} | ||
constructor( | ||
public originMeta: StylableMeta, | ||
public selectorAst: SelectorList, | ||
public rule: postcss.Rule | ||
) {} | ||
public initRootAnchor(anchor: ScopeAnchor) { | ||
@@ -951,3 +978,25 @@ this.currentAnchor = anchor; | ||
} | ||
public createNestedContext(selectorAst: SelectorAstNode) { | ||
public insertDescendantCombinatorBeforePseudoElement() { | ||
if ( | ||
this.selector && | ||
this.compoundSelector && | ||
this.node && | ||
this.node.type === `pseudo_element` | ||
) { | ||
if (this.compoundSelector.nodes[0] === this.node) { | ||
const compoundIndex = this.selector.nodes.indexOf(this.compoundSelector); | ||
this.selector.nodes.splice(compoundIndex, 0, { | ||
type: `combinator`, | ||
combinator: `space`, | ||
value: ` `, | ||
before: ``, | ||
after: ``, | ||
start: this.node.start, | ||
end: this.node.start, | ||
invalid: false, | ||
}); | ||
} | ||
} | ||
} | ||
public createNestedContext(selectorAst: SelectorList) { | ||
const ctx = new ScopeContext(this.originMeta, selectorAst, this.rule); | ||
@@ -954,0 +1003,0 @@ Object.assign(ctx, this); |
@@ -1,25 +0,9 @@ | ||
import cloneDeep from 'lodash.clonedeep'; | ||
import { isAbsolute } from 'path'; | ||
import * as postcss from 'postcss'; | ||
import type * as postcss from 'postcss'; | ||
import { replaceRuleSelector } from './replace-rule-selector'; | ||
import type { Diagnostics } from './diagnostics'; | ||
import type { | ||
DeclStylableProps, | ||
Imported, | ||
SDecl, | ||
SRule, | ||
StylableMeta, | ||
StylableSymbol, | ||
} from './stylable-processor'; | ||
import { | ||
fixChunkOrdering, | ||
isChildOfAtRule, | ||
isNodeMatch, | ||
parseSelector, | ||
SelectorAstNode, | ||
stringifySelector, | ||
traverseNode, | ||
} from './selector-utils'; | ||
import type { ImportSymbol } from './stylable-meta'; | ||
import type { Imported, ImportSymbol, StylableSymbol } from './features'; | ||
import { isChildOfAtRule } from './helpers/rule'; | ||
import { scopeNestedSelector, parseSelectorWithCache } from './helpers/selector'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import { valueMapping, mixinDeclRegExp } from './stylable-value-parsers'; | ||
@@ -63,64 +47,2 @@ import type { StylableResolver } from './stylable-resolver'; | ||
export function scopeSelector( | ||
scopeSelectorRule: string, | ||
targetSelectorRule: string, | ||
rootScopeLevel = false | ||
): { selector: string; selectorAst: SelectorAstNode } { | ||
const scopingSelectorAst = parseSelector(scopeSelectorRule); | ||
const targetSelectorAst = parseSelector(targetSelectorRule); | ||
const nodes: any[] = []; | ||
targetSelectorAst.nodes.forEach((targetSelector) => { | ||
scopingSelectorAst.nodes.forEach((scopingSelector) => { | ||
const outputSelector: any = cloneDeep(targetSelector); | ||
outputSelector.before = scopingSelector.before || outputSelector.before; | ||
const first = outputSelector.nodes[0]; | ||
const parentRef = first.type === 'invalid' && first.value === '&'; | ||
const globalSelector = first.type === 'nested-pseudo-class' && first.name === 'global'; | ||
const startsWithScoping = rootScopeLevel | ||
? scopingSelector.nodes.every((node: any, i) => { | ||
const o = outputSelector.nodes[i]; | ||
for (const k in node) { | ||
if (node[k] !== o[k]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}) | ||
: false; | ||
if ( | ||
first && | ||
first.type !== 'spacing' && | ||
!parentRef && | ||
!startsWithScoping && | ||
!globalSelector | ||
) { | ||
outputSelector.nodes.unshift(...cloneDeep(scopingSelector.nodes), { | ||
type: 'spacing', | ||
value: ' ', | ||
}); | ||
} | ||
traverseNode(outputSelector, (node, i, nodes) => { | ||
if (node.type === 'invalid' && node.value === '&') { | ||
nodes.splice(i, 1, ...cloneDeep(scopingSelector.nodes)); | ||
} | ||
}); | ||
nodes.push(outputSelector); | ||
}); | ||
}); | ||
scopingSelectorAst.nodes = nodes; | ||
return { | ||
selector: stringifySelector(scopingSelectorAst), | ||
selectorAst: scopingSelectorAst, | ||
}; | ||
} | ||
export function mergeRules(mixinAst: postcss.Root, rule: postcss.Rule) { | ||
@@ -136,7 +58,15 @@ let mixinRoot: postcss.Rule | null | 'NoRoot' = null; | ||
} else { | ||
const { selector } = scopeNestedSelector( | ||
parseSelectorWithCache(rule.selector), | ||
parseSelectorWithCache(mixinRule.selector) | ||
); | ||
mixinRoot = 'NoRoot'; | ||
mixinRule.selector = scopeSelector(rule.selector, mixinRule.selector).selector; | ||
mixinRule.selector = selector; | ||
} | ||
} else { | ||
mixinRule.selector = scopeSelector(rule.selector, mixinRule.selector).selector; | ||
const { selector } = scopeNestedSelector( | ||
parseSelectorWithCache(rule.selector), | ||
parseSelectorWithCache(mixinRule.selector) | ||
); | ||
mixinRule.selector = selector; | ||
} | ||
@@ -177,107 +107,2 @@ }); | ||
export function createSubsetAst<T extends postcss.Root | postcss.AtRule>( | ||
root: postcss.Root | postcss.AtRule, | ||
selectorPrefix: string, | ||
mixinTarget?: T, | ||
isRoot = false | ||
): T { | ||
// keyframes on class mixin? | ||
const prefixType = parseSelector(selectorPrefix).nodes[0].nodes[0]; | ||
const containsPrefix = containsMatchInFirstChunk.bind(null, prefixType); | ||
const mixinRoot = mixinTarget ? mixinTarget : postcss.root(); | ||
root.nodes.forEach((node) => { | ||
if (node.type === 'rule') { | ||
const ast = isRoot | ||
? scopeSelector(selectorPrefix, node.selector, true).selectorAst | ||
: parseSelector(node.selector); | ||
const matchesSelectors = isRoot | ||
? ast.nodes | ||
: ast.nodes.filter((node) => containsPrefix(node)); | ||
if (matchesSelectors.length) { | ||
const selector = stringifySelector({ | ||
...ast, | ||
nodes: matchesSelectors.map((selectorNode) => { | ||
if (!isRoot) { | ||
fixChunkOrdering(selectorNode, prefixType); | ||
} | ||
return destructiveReplaceNode(selectorNode, prefixType, { | ||
type: 'invalid', | ||
value: '&', | ||
} as SelectorAstNode); | ||
}), | ||
}); | ||
mixinRoot.append(node.clone({ selector })); | ||
} | ||
} else if (node.type === 'atrule') { | ||
if (node.name === 'media' || node.name === 'supports') { | ||
const atRuleSubset = createSubsetAst( | ||
node, | ||
selectorPrefix, | ||
postcss.atRule({ | ||
params: node.params, | ||
name: node.name, | ||
}), | ||
isRoot | ||
); | ||
if (atRuleSubset.nodes) { | ||
mixinRoot.append(atRuleSubset); | ||
} | ||
} else if (isRoot) { | ||
mixinRoot.append(node.clone()); | ||
} | ||
} else { | ||
// TODO: add warn? | ||
} | ||
}); | ||
return mixinRoot as T; | ||
} | ||
export function removeUnusedRules( | ||
ast: postcss.Root, | ||
meta: StylableMeta, | ||
_import: Imported, | ||
usedFiles: string[], | ||
resolvePath: (ctx: string, path: string) => string | ||
): void { | ||
const isUnusedImport = !usedFiles.includes(_import.from); | ||
if (isUnusedImport) { | ||
const symbols = Object.keys(_import.named).concat(_import.defaultExport); // .filter(Boolean); | ||
ast.walkRules((rule) => { | ||
let shouldOutput = true; | ||
traverseNode((rule as SRule).selectorAst, (node) => { | ||
// TODO: remove. | ||
if (symbols.includes(node.name)) { | ||
return (shouldOutput = false); | ||
} | ||
const symbol = meta.mappedSymbols[node.name]; | ||
if (symbol && (symbol._kind === 'class' || symbol._kind === 'element')) { | ||
let extend = symbol[valueMapping.extends] || symbol.alias; | ||
extend = extend && extend._kind !== 'import' ? extend.alias || extend : extend; | ||
if ( | ||
extend && | ||
extend._kind === 'import' && | ||
!usedFiles.includes(resolvePath(meta.source, extend.import.from)) | ||
) { | ||
return (shouldOutput = false); | ||
} | ||
} | ||
return undefined; | ||
}); | ||
// TODO: optimize the multiple selectors | ||
if (!shouldOutput && (rule as SRule).selectorAst.nodes.length <= 1) { | ||
rule.remove(); | ||
} | ||
}); | ||
} | ||
} | ||
export function findDeclaration(importNode: Imported, test: any) { | ||
@@ -288,57 +113,2 @@ const fromIndex = importNode.rule.nodes.findIndex(test); | ||
// TODO: What is this? | ||
export function findRule( | ||
root: postcss.Root, | ||
selector: string, | ||
test: any = (statement: any) => statement.prop === valueMapping.extends | ||
): null | postcss.Declaration { | ||
let found: any = null; | ||
root.walkRules(selector, (rule) => { | ||
const declarationIndex = rule.nodes ? rule.nodes.findIndex(test) : -1; | ||
if ((rule as SRule).isSimpleSelector && !!~declarationIndex) { | ||
found = rule.nodes[declarationIndex]; | ||
} | ||
}); | ||
return found; | ||
} | ||
export function getDeclStylable(decl: SDecl): DeclStylableProps { | ||
if (decl.stylable) { | ||
return decl.stylable; | ||
} else { | ||
decl.stylable = decl.stylable ? decl.stylable : { sourceValue: '' }; | ||
return decl.stylable; | ||
} | ||
} | ||
function destructiveReplaceNode( | ||
ast: SelectorAstNode, | ||
matchNode: SelectorAstNode, | ||
replacementNode: SelectorAstNode | ||
) { | ||
traverseNode(ast, (node) => { | ||
if (isNodeMatch(node, matchNode)) { | ||
node.type = 'selector'; | ||
node.nodes = [replacementNode]; | ||
} | ||
}); | ||
return ast; | ||
} | ||
function containsMatchInFirstChunk(prefixType: SelectorAstNode, selectorNode: SelectorAstNode) { | ||
let isMatch = false; | ||
traverseNode(selectorNode, (node) => { | ||
if (node.type === 'operator' || node.type === 'spacing') { | ||
return false; | ||
} else if (node.type === 'nested-pseudo-class') { | ||
return true; | ||
} else if (isNodeMatch(node, prefixType)) { | ||
isMatch = true; | ||
return false; | ||
} | ||
return undefined; | ||
}); | ||
return isMatch; | ||
} | ||
export function getSourcePath(root: postcss.Root, diagnostics: Diagnostics) { | ||
@@ -345,0 +115,0 @@ const source = (root.source && root.source.input.file) || ''; |
@@ -10,3 +10,3 @@ import type * as postcss from 'postcss'; | ||
import { processPseudoStates } from './pseudo-states'; | ||
import { parseSelector } from './selector-utils'; | ||
import { parseSelectorWithCache } from './helpers/selector'; | ||
import type { ParsedValue, StateParsedValue } from './types'; | ||
@@ -108,4 +108,8 @@ | ||
// Experimental | ||
const selector: any = parseSelector(decl.value.replace(/^['"]/, '').replace(/['"]$/, '')); | ||
return selector.nodes[0].nodes; | ||
const selector = parseSelectorWithCache( | ||
decl.value.replace(/^['"]/, '').replace(/['"]$/, ''), | ||
{ clone: true } | ||
); | ||
// ToDo: handle or warn on multiple selectors | ||
return selector[0].nodes; | ||
}, | ||
@@ -112,0 +116,0 @@ '-st-states'(value: string, decl: postcss.Declaration, diagnostics: Diagnostics) { |
@@ -5,3 +5,4 @@ import type { FileProcessor, MinimalFS } from './cached-process-file'; | ||
import { CssParser, cssParse } from './parser'; | ||
import { processNamespace, StylableMeta, StylableProcessor } from './stylable-processor'; | ||
import { processNamespace, StylableProcessor } from './stylable-processor'; | ||
import type { StylableMeta } from './stylable-meta'; | ||
import { StylableResolverCache, StylableResolver } from './stylable-resolver'; | ||
@@ -21,9 +22,11 @@ import { | ||
requireModule?: (path: string) => any; | ||
/** @deprecated */ | ||
delimiter?: string; | ||
onProcess?: (meta: StylableMeta, path: string) => StylableMeta; | ||
/** @deprecated */ | ||
diagnostics?: Diagnostics; | ||
hooks?: TransformHooks; | ||
resolveOptions?: { | ||
alias: any; | ||
symlinks: boolean; | ||
alias?: any; | ||
symlinks?: boolean; | ||
[key: string]: any; | ||
@@ -30,0 +33,0 @@ }; |
import type { StylableMeta } from './stylable-meta'; | ||
import type { Imported } from './stylable-processor'; | ||
import type { Imported } from './features'; | ||
import type { StylableResolver } from './stylable-resolver'; | ||
@@ -4,0 +4,0 @@ |
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
896641
218
15269
15
+ Added@tokey/imports-parser@^0.0.2
+ Addedcssesc@^3.0.0
+ Added@tokey/core@1.4.0(transitive)
+ Added@tokey/css-selector-parser@0.5.1(transitive)
+ Added@tokey/imports-parser@0.0.2(transitive)
- Removedtoky@^0.1.0
- Removedtoky@0.1.0(transitive)
Updatedpostcss@^8.3.11