@stylable/core
Advanced tools
Comparing version 3.9.1 to 3.10.0
import postcss from 'postcss'; | ||
import { Diagnostics } from './diagnostics'; | ||
import { SelectorAstNode } from './selector-utils'; | ||
import { SelectorAstNode, SelectorChunk2 } from './selector-utils'; | ||
import { MappedStates, MixinValue } from './stylable-value-parsers'; | ||
@@ -25,2 +25,3 @@ export declare const RESERVED_ROOT_NAME = "root"; | ||
transformDiagnostics: Diagnostics | null; | ||
transformedScopes: Record<string, SelectorChunk2[][]> | null; | ||
scopes: postcss.AtRule[]; | ||
@@ -27,0 +28,0 @@ simpleSelectors: Record<string, SimpleSelector>; |
@@ -39,2 +39,3 @@ "use strict"; | ||
this.transformDiagnostics = null; | ||
this.transformedScopes = null; | ||
} | ||
@@ -41,0 +42,0 @@ } |
@@ -30,3 +30,2 @@ import postcss from 'postcss'; | ||
NO_KEYFRAMES_IN_ST_SCOPE(): string; | ||
SCOPE_PARAM_NOT_SIMPLE_SELECTOR(selector: string): string; | ||
MISSING_SCOPING_PARAM(): string; | ||
@@ -63,3 +62,3 @@ ILLEGAL_GLOBAL_CSS_VAR(name: string): string; | ||
} | ||
export declare function validateScopingSelector(atRule: postcss.AtRule, { selector: scopingSelector, isSimpleSelector }: SRule, diagnostics: Diagnostics): void; | ||
export declare function validateScopingSelector(atRule: postcss.AtRule, { selector: scopingSelector }: SRule, diagnostics: Diagnostics): void; | ||
export declare function createEmptyMeta(root: postcss.Root, diagnostics: Diagnostics): StylableMeta; | ||
@@ -66,0 +65,0 @@ export declare function processNamespace(namespace: string, source: string): string; |
@@ -104,5 +104,2 @@ "use strict"; | ||
}, | ||
SCOPE_PARAM_NOT_SIMPLE_SELECTOR(selector) { | ||
return `"@st-scope" must receive a simple selector, but instead got: "${selector}"`; | ||
}, | ||
MISSING_SCOPING_PARAM() { | ||
@@ -673,9 +670,6 @@ return '"@st-scope" must receive a simple selector or stylesheet "root" as its scoping parameter'; | ||
exports.StylableProcessor = StylableProcessor; | ||
function validateScopingSelector(atRule, { selector: scopingSelector, isSimpleSelector }, diagnostics) { | ||
function validateScopingSelector(atRule, { selector: scopingSelector }, diagnostics) { | ||
if (!scopingSelector) { | ||
diagnostics.warn(atRule, exports.processorWarnings.MISSING_SCOPING_PARAM()); | ||
} | ||
else if (!isSimpleSelector) { | ||
diagnostics.warn(atRule, exports.processorWarnings.SCOPE_PARAM_NOT_SIMPLE_SELECTOR(scopingSelector), { word: scopingSelector }); | ||
} | ||
} | ||
@@ -682,0 +676,0 @@ exports.validateScopingSelector = validateScopingSelector; |
@@ -65,5 +65,2 @@ import postcss from 'postcss'; | ||
UNKNOWN_IMPORT_ALIAS(name: string): string; | ||
SCOPE_PARAM_NOT_ROOT(name: string): string; | ||
SCOPE_PARAM_NOT_CSS(name: string): string; | ||
UNKNOWN_SCOPING_PARAM(name: string): string; | ||
}; | ||
@@ -110,5 +107,7 @@ export declare class StylableTransformer { | ||
elements: ResolvedElement[][]; | ||
targetSelectorAst: SelectorAstNode; | ||
}; | ||
scopeSelectorAst(context: ScopeContext): SelectorAstNode; | ||
private handleChunkNode; | ||
private isDuplicateStScopeDiagnostic; | ||
private handleCustomSelector; | ||
@@ -115,0 +114,0 @@ private scopeClassNode; |
@@ -42,11 +42,2 @@ "use strict"; | ||
}, | ||
SCOPE_PARAM_NOT_ROOT(name) { | ||
return `"@st-scope" parameter "${name}" does not resolve to a stylesheet root`; | ||
}, | ||
SCOPE_PARAM_NOT_CSS(name) { | ||
return `"@st-scope" parameter "${name}" must be a Stylable stylesheet, instead name originated from a JavaScript file`; | ||
}, | ||
UNKNOWN_SCOPING_PARAM(name) { | ||
return `"@st-scope" received an unknown symbol: "${name}"`; | ||
}, | ||
}; | ||
@@ -74,3 +65,3 @@ class StylableTransformer { | ||
this.resolver.validateImports(meta, this.diagnostics); | ||
validateScopes(meta, this.resolver, this.diagnostics); | ||
meta.transformedScopes = validateScopes(this, meta); | ||
this.transformAst(ast, meta, metaExports); | ||
@@ -653,4 +644,6 @@ this.transformGlobals(ast, meta); | ||
const context = new ScopeContext(originMeta, selector_utils_1.parseSelector(selector), rule || postcss_1.default.rule({ selector })); | ||
const targetSelectorAst = this.scopeSelectorAst(context); | ||
return { | ||
selector: selector_utils_1.stringifySelector(this.scopeSelectorAst(context)), | ||
targetSelectorAst, | ||
selector: selector_utils_1.stringifySelector(targetSelectorAst), | ||
elements: context.elements, | ||
@@ -684,3 +677,3 @@ }; | ||
context.node = node; | ||
// transfrom node | ||
// transform node | ||
this.handleChunkNode(context); | ||
@@ -732,3 +725,2 @@ } | ||
if (!symbol[stylable_value_parsers_1.valueMapping.root]) { | ||
// debugger | ||
continue; | ||
@@ -743,3 +735,3 @@ } | ||
if (symbol.alias || !requestedPart) { | ||
// skip alias since thay cannot add parts | ||
// skip alias since they cannot add parts | ||
continue; | ||
@@ -766,3 +758,5 @@ } | ||
}); | ||
if (!native_reserved_lists_1.nativePseudoElements.includes(name) && !is_vendor_prefixed_1.default(name)) { | ||
if (!native_reserved_lists_1.nativePseudoElements.includes(name) && | ||
!is_vendor_prefixed_1.default(name) && | ||
!this.isDuplicateStScopeDiagnostic(context)) { | ||
this.diagnostics.warn(context.rule, exports.transformerWarnings.UNKNOWN_PSEUDO_ELEMENT(name), { | ||
@@ -784,3 +778,6 @@ word: name, | ||
} | ||
if (!found && !native_reserved_lists_1.nativePseudoClasses.includes(name) && !is_vendor_prefixed_1.default(name)) { | ||
if (!found && | ||
!native_reserved_lists_1.nativePseudoClasses.includes(name) && | ||
!is_vendor_prefixed_1.default(name) && | ||
!this.isDuplicateStScopeDiagnostic(context)) { | ||
this.diagnostics.warn(context.rule, pseudo_states_1.stateErrors.UNKNOWN_STATE_USAGE(name), { | ||
@@ -820,2 +817,31 @@ word: name, | ||
} | ||
isDuplicateStScopeDiagnostic(context) { | ||
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 = selector_utils_1.stringifySelector({ | ||
type: 'selector', | ||
nodes: context.chunk.nodes, | ||
name: '', | ||
}); | ||
const i = context.chunks.indexOf(context.chunk); | ||
for (const stScopeSelectorChunks 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 = selector_utils_1.stringifySelector({ | ||
type: 'selector', | ||
nodes: chunk.nodes, | ||
name: '', | ||
}); | ||
// if the two chunks match the error is already reported by the @st-scope validation | ||
if (scopeChunkSelector === currentChunkSelector) { | ||
return true; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
handleCustomSelector(customSelector, meta, context, name, node) { | ||
@@ -916,2 +942,3 @@ const selectorListChunks = selector_utils_1.separateChunks2(selector_utils_1.parseSelector(customSelector)); | ||
meta.globals = {}; | ||
meta.transformedScopes = null; | ||
return (meta.outputAst = meta.ast.clone()); | ||
@@ -954,38 +981,20 @@ } | ||
exports.removeSTDirective = removeSTDirective; | ||
function validateScopes(meta, resolver, diagnostics) { | ||
function validateScopes(transformer, meta) { | ||
const transformedScopes = {}; | ||
for (const scope of meta.scopes) { | ||
const name = scope.params.startsWith('.') ? scope.params.slice(1) : scope.params; | ||
if (!name) { | ||
continue; | ||
} | ||
else if (!meta.mappedSymbols[name]) { | ||
diagnostics.error(scope, exports.transformerWarnings.UNKNOWN_SCOPING_PARAM(scope.params), { | ||
word: scope.params, | ||
}); | ||
continue; | ||
} | ||
const resolvedScope = resolver.deepResolve(meta.mappedSymbols[name]); | ||
if (resolvedScope && resolvedScope._kind === 'css') { | ||
const { meta: scopingMeta, symbol: scopingSymbol } = resolvedScope; | ||
if (scopingSymbol.name !== scopingMeta.root) { | ||
diagnostics.error(scope, exports.transformerWarnings.SCOPE_PARAM_NOT_ROOT(scope.params), { | ||
word: scope.params, | ||
}); | ||
const len = transformer.diagnostics.reports.length; | ||
const rule = postcss_1.default.rule({ selector: scope.params }); | ||
const context = new ScopeContext(meta, selector_utils_1.parseSelector(rule.selector), rule); | ||
transformedScopes[rule.selector] = selector_utils_1.separateChunks2(transformer.scopeSelectorAst(context)); | ||
const ruleReports = transformer.diagnostics.reports.splice(len); | ||
ruleReports.forEach(({ message, type, options: { word } = {} }) => { | ||
if (type === 'error') { | ||
transformer.diagnostics.error(scope, message, { word: word || scope.params }); | ||
} | ||
} | ||
else if (resolvedScope && resolvedScope._kind === 'js') { | ||
diagnostics.error(scope, exports.transformerWarnings.SCOPE_PARAM_NOT_CSS(scope.params), { | ||
word: scope.params, | ||
}); | ||
} | ||
else if (meta.classes[name] || | ||
(meta.elements[scope.params] && meta.elements[scope.params].alias)) { | ||
// do nothing valid input | ||
} | ||
else { | ||
diagnostics.error(scope, exports.transformerWarnings.UNKNOWN_SCOPING_PARAM(scope.params), { | ||
word: scope.params, | ||
}); | ||
} | ||
else { | ||
transformer.diagnostics.warn(scope, message, { word: word || scope.params }); | ||
} | ||
}); | ||
} | ||
return transformedScopes; | ||
} | ||
@@ -992,0 +1001,0 @@ function removeFirstRootInEachSelectorChunk(selectorListChunks, meta) { |
{ | ||
"name": "@stylable/core", | ||
"version": "3.9.1", | ||
"version": "3.10.0", | ||
"description": "CSS for Components", | ||
@@ -11,4 +11,3 @@ "main": "./cjs/index.js", | ||
"test": "mocha \"./test/**/*.spec.ts\"", | ||
"start": "webpack-dev-server --hot --inline", | ||
"prepack": "yarn build" | ||
"start": "webpack-dev-server --hot --inline" | ||
}, | ||
@@ -15,0 +14,0 @@ "dependencies": { |
import postcss from 'postcss'; | ||
import { Diagnostics } from './diagnostics'; | ||
import { SelectorAstNode } from './selector-utils'; | ||
import { SelectorAstNode, SelectorChunk2 } from './selector-utils'; | ||
import { getSourcePath } from './stylable-utils'; | ||
@@ -25,2 +25,3 @@ import { MappedStates, MixinValue, valueMapping } from './stylable-value-parsers'; | ||
public transformDiagnostics: Diagnostics | null; | ||
public transformedScopes: Record<string, SelectorChunk2[][]> | null; | ||
public scopes: postcss.AtRule[]; | ||
@@ -61,2 +62,3 @@ public simpleSelectors: Record<string, SimpleSelector>; | ||
this.transformDiagnostics = null; | ||
this.transformedScopes = null; | ||
} | ||
@@ -63,0 +65,0 @@ } |
@@ -120,5 +120,2 @@ import hash from 'murmurhash'; | ||
}, | ||
SCOPE_PARAM_NOT_SIMPLE_SELECTOR(selector: string) { | ||
return `"@st-scope" must receive a simple selector, but instead got: "${selector}"`; | ||
}, | ||
MISSING_SCOPING_PARAM() { | ||
@@ -792,3 +789,3 @@ return '"@st-scope" must receive a simple selector or stylesheet "root" as its scoping parameter'; | ||
atRule: postcss.AtRule, | ||
{ selector: scopingSelector, isSimpleSelector }: SRule, | ||
{ selector: scopingSelector }: SRule, | ||
diagnostics: Diagnostics | ||
@@ -798,8 +795,2 @@ ) { | ||
diagnostics.warn(atRule, processorWarnings.MISSING_SCOPING_PARAM()); | ||
} else if (!isSimpleSelector) { | ||
diagnostics.warn( | ||
atRule, | ||
processorWarnings.SCOPE_PARAM_NOT_SIMPLE_SELECTOR(scopingSelector), | ||
{ word: scopingSelector } | ||
); | ||
} | ||
@@ -806,0 +797,0 @@ } |
@@ -136,11 +136,2 @@ import { basename } from 'path'; | ||
}, | ||
SCOPE_PARAM_NOT_ROOT(name: string) { | ||
return `"@st-scope" parameter "${name}" does not resolve to a stylesheet root`; | ||
}, | ||
SCOPE_PARAM_NOT_CSS(name: string) { | ||
return `"@st-scope" parameter "${name}" must be a Stylable stylesheet, instead name originated from a JavaScript file`; | ||
}, | ||
UNKNOWN_SCOPING_PARAM(name: string) { | ||
return `"@st-scope" received an unknown symbol: "${name}"`; | ||
}, | ||
}; | ||
@@ -178,3 +169,3 @@ | ||
this.resolver.validateImports(meta, this.diagnostics); | ||
validateScopes(meta, this.resolver, this.diagnostics); | ||
meta.transformedScopes = validateScopes(this, meta); | ||
this.transformAst(ast, meta, metaExports); | ||
@@ -959,3 +950,3 @@ this.transformGlobals(ast, meta); | ||
rule?: postcss.Rule | ||
): { selector: string; elements: ResolvedElement[][] } { | ||
): { selector: string; elements: ResolvedElement[][]; targetSelectorAst: SelectorAstNode } { | ||
const context = new ScopeContext( | ||
@@ -966,4 +957,6 @@ originMeta, | ||
); | ||
const targetSelectorAst = this.scopeSelectorAst(context); | ||
return { | ||
selector: stringifySelector(this.scopeSelectorAst(context)), | ||
targetSelectorAst, | ||
selector: stringifySelector(targetSelectorAst), | ||
elements: context.elements, | ||
@@ -998,3 +991,3 @@ }; | ||
context.node = node; | ||
// transfrom node | ||
// transform node | ||
this.handleChunkNode(context); | ||
@@ -1051,3 +1044,2 @@ } | ||
if (!symbol[valueMapping.root]) { | ||
// debugger | ||
continue; | ||
@@ -1065,3 +1057,3 @@ } | ||
if (symbol.alias || !requestedPart) { | ||
// skip alias since thay cannot add parts | ||
// skip alias since they cannot add parts | ||
continue; | ||
@@ -1095,3 +1087,7 @@ } | ||
if (!nativePseudoElements.includes(name) && !isVendorPrefixed(name)) { | ||
if ( | ||
!nativePseudoElements.includes(name) && | ||
!isVendorPrefixed(name) && | ||
!this.isDuplicateStScopeDiagnostic(context) | ||
) { | ||
this.diagnostics.warn( | ||
@@ -1126,3 +1122,8 @@ context.rule, | ||
} | ||
if (!found && !nativePseudoClasses.includes(name) && !isVendorPrefixed(name)) { | ||
if ( | ||
!found && | ||
!nativePseudoClasses.includes(name) && | ||
!isVendorPrefixed(name) && | ||
!this.isDuplicateStScopeDiagnostic(context) | ||
) { | ||
this.diagnostics.warn(context.rule, stateErrors.UNKNOWN_STATE_USAGE(name), { | ||
@@ -1159,2 +1160,32 @@ word: name, | ||
} | ||
private isDuplicateStScopeDiagnostic(context: ScopeContext) { | ||
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) { | ||
// 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 the two chunks match the error is already reported by the @st-scope validation | ||
if (scopeChunkSelector === currentChunkSelector) { | ||
return true; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
private handleCustomSelector( | ||
@@ -1201,3 +1232,2 @@ customSelector: string, | ||
} | ||
private scopeClassNode(symbol: any, meta: any, node: any, originMeta: any) { | ||
@@ -1303,2 +1333,3 @@ if (symbol[valueMapping.global]) { | ||
meta.globals = {}; | ||
meta.transformedScopes = null; | ||
return (meta.outputAst = meta.ast.clone()); | ||
@@ -1344,40 +1375,21 @@ } | ||
function validateScopes(meta: StylableMeta, resolver: StylableResolver, diagnostics: Diagnostics) { | ||
function validateScopes(transformer: StylableTransformer, meta: StylableMeta) { | ||
const transformedScopes: Record<string, SelectorChunk2[][]> = {}; | ||
for (const scope of meta.scopes) { | ||
const name = scope.params.startsWith('.') ? scope.params.slice(1) : scope.params; | ||
const len = transformer.diagnostics.reports.length; | ||
const rule = postcss.rule({ selector: scope.params }); | ||
if (!name) { | ||
continue; | ||
} else if (!meta.mappedSymbols[name]) { | ||
diagnostics.error(scope, transformerWarnings.UNKNOWN_SCOPING_PARAM(scope.params), { | ||
word: scope.params, | ||
}); | ||
continue; | ||
} | ||
const context = new ScopeContext(meta, parseSelector(rule.selector), rule); | ||
transformedScopes[rule.selector] = separateChunks2(transformer.scopeSelectorAst(context)); | ||
const ruleReports = transformer.diagnostics.reports.splice(len); | ||
const resolvedScope = resolver.deepResolve(meta.mappedSymbols[name]); | ||
if (resolvedScope && resolvedScope._kind === 'css') { | ||
const { meta: scopingMeta, symbol: scopingSymbol } = resolvedScope; | ||
if (scopingSymbol.name !== scopingMeta.root) { | ||
diagnostics.error(scope, transformerWarnings.SCOPE_PARAM_NOT_ROOT(scope.params), { | ||
word: scope.params, | ||
}); | ||
ruleReports.forEach(({ message, type, options: { word } = {} }) => { | ||
if (type === 'error') { | ||
transformer.diagnostics.error(scope, message, { word: word || scope.params }); | ||
} else { | ||
transformer.diagnostics.warn(scope, message, { word: word || scope.params }); | ||
} | ||
} else if (resolvedScope && resolvedScope._kind === 'js') { | ||
diagnostics.error(scope, transformerWarnings.SCOPE_PARAM_NOT_CSS(scope.params), { | ||
word: scope.params, | ||
}); | ||
} else if ( | ||
meta.classes[name] || | ||
(meta.elements[scope.params] && meta.elements[scope.params].alias) | ||
) { | ||
// do nothing valid input | ||
} else { | ||
diagnostics.error(scope, transformerWarnings.UNKNOWN_SCOPING_PARAM(scope.params), { | ||
word: scope.params, | ||
}); | ||
} | ||
}); | ||
} | ||
return transformedScopes; | ||
} | ||
@@ -1384,0 +1396,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
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
690893
11857