@stylable/core
Advanced tools
Comparing version 5.15.2 to 5.16.0
@@ -66,2 +66,7 @@ import * as STSymbol from './st-symbol'; | ||
}; | ||
INVALID_RECURSIVE_MIXIN: { | ||
(): import("../diagnostics").DiagnosticBase; | ||
code: string; | ||
severity: import("../diagnostics").DiagnosticSeverity; | ||
}; | ||
PARTIAL_MIXIN_MISSING_ARGUMENTS: { | ||
@@ -68,0 +73,0 @@ (type: string): import("../diagnostics").DiagnosticBase; |
@@ -54,2 +54,3 @@ "use strict"; | ||
INVALID_MERGE_OF: stylable_utils_1.utilDiagnostics.INVALID_MERGE_OF, | ||
INVALID_RECURSIVE_MIXIN: stylable_utils_1.utilDiagnostics.INVALID_RECURSIVE_MIXIN, | ||
PARTIAL_MIXIN_MISSING_ARGUMENTS: (0, diagnostics_1.createDiagnosticReporter)('10001', 'error', (type) => `"${exports.MixinType.PARTIAL}" can only be used with override arguments provided, missing overrides on "${type}"`), | ||
@@ -56,0 +57,0 @@ UNKNOWN_MIXIN: (0, diagnostics_1.createDiagnosticReporter)('10002', 'error', (name) => `unknown mixin: "${name}"`), |
@@ -30,2 +30,7 @@ import { FeatureContext } from './feature'; | ||
}; | ||
NATIVE_OVERRIDE_DEPRECATION: { | ||
(): import("../diagnostics").DiagnosticBase; | ||
code: string; | ||
severity: import("../diagnostics").DiagnosticSeverity; | ||
}; | ||
}; | ||
@@ -32,0 +37,0 @@ export declare const hooks: import("./feature").FeatureHooks<import("./feature").NodeTypes>; |
@@ -21,2 +21,3 @@ "use strict"; | ||
INVALID_NAMESPACE_REFERENCE: (0, diagnostics_1.createDiagnosticReporter)('11010', 'error', () => 'st-namespace-reference dose not have any value'), | ||
NATIVE_OVERRIDE_DEPRECATION: (0, diagnostics_1.createDiagnosticReporter)('11014', 'info', () => '@namespace will stop working in version 6, use @st-namespace instead'), | ||
}; | ||
@@ -30,2 +31,3 @@ const dataKey = plugable_record_1.plugableRecord.key('namespace'); | ||
usedNativeNamespace: [], | ||
usedNativeNamespaceNodes: [], | ||
foundStNamespace: false, | ||
@@ -51,2 +53,3 @@ }); | ||
data.usedNativeNamespace.push(atRule.params); | ||
data.usedNativeNamespaceNodes.push(atRule); | ||
} | ||
@@ -56,2 +59,3 @@ else { | ||
data.usedNativeNamespace.length = 0; | ||
data.usedNativeNamespaceNodes.length = 0; | ||
// mark to prevent any further @namespace collection | ||
@@ -62,2 +66,10 @@ data.foundStNamespace = true; | ||
}, | ||
analyzeDone(context) { | ||
const { usedNativeNamespaceNodes } = plugable_record_1.plugableRecord.getUnsafe(context.meta.data, dataKey); | ||
for (const node of usedNativeNamespaceNodes) { | ||
context.diagnostics.report(exports.diagnostics.NATIVE_OVERRIDE_DEPRECATION(), { | ||
node, | ||
}); | ||
} | ||
}, | ||
prepareAST({ context, node, toRemove }) { | ||
@@ -64,0 +76,0 @@ // remove @st-namespace or @namespace that was used as @st-namespace |
@@ -96,3 +96,2 @@ "use strict"; | ||
let scopeSelector = node.name === 'st-scope' ? node.params : ''; | ||
let isNestedInMixin = false; | ||
if (scopeSelector) { | ||
@@ -99,0 +98,0 @@ const ast = (0, selector_1.parseSelectorWithCache)(scopeSelector, { clone: true }); |
@@ -46,2 +46,3 @@ "use strict"; | ||
}); | ||
features_2.STNamespace.hooks.analyzeDone(this); | ||
features_1.STCustomSelector.hooks.analyzeDone(this); | ||
@@ -48,0 +49,0 @@ features_2.STStructure.hooks.analyzeDone(this); |
@@ -1,2 +0,2 @@ | ||
import type * as postcss from 'postcss'; | ||
import * as postcss from 'postcss'; | ||
import { Diagnostics } from './diagnostics'; | ||
@@ -11,2 +11,7 @@ import type { ImportSymbol, StylableSymbol } from './features'; | ||
}; | ||
INVALID_RECURSIVE_MIXIN: { | ||
(): import("./diagnostics").DiagnosticBase; | ||
code: string; | ||
severity: import("./diagnostics").DiagnosticSeverity; | ||
}; | ||
}; | ||
@@ -13,0 +18,0 @@ export declare function mergeRules(mixinAst: postcss.Root, rule: postcss.Rule, mixinDecl: postcss.Declaration, report: Diagnostics, useNestingAsAnchor: boolean): postcss.Rule; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (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; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getAlias = exports.getSourcePath = exports.sourcePathDiagnostics = exports.mergeRules = exports.utilDiagnostics = exports.isValidDeclaration = void 0; | ||
const path_1 = require("path"); | ||
const postcss = __importStar(require("postcss")); | ||
const diagnostics_1 = require("./diagnostics"); | ||
@@ -14,2 +38,3 @@ const rule_1 = require("./helpers/rule"); | ||
INVALID_MERGE_OF: (0, diagnostics_1.createDiagnosticReporter)('14001', 'error', (mergeValue) => `invalid merge of: \n"${mergeValue}"`), | ||
INVALID_RECURSIVE_MIXIN: (0, diagnostics_1.createDiagnosticReporter)('10010', 'error', () => `invalid recursive mixin`), | ||
}; | ||
@@ -36,6 +61,14 @@ // ToDo: move to helpers/mixin | ||
} | ||
else { | ||
else if (!isChildOfMixinRoot(mixinRule, mixinRoot)) { | ||
// scope to mixin target if not already scoped by parent | ||
const { selector } = (0, selector_1.scopeNestedSelector)((0, selector_1.parseSelectorWithCache)(rule.selector), (0, selector_1.parseSelectorWithCache)(mixinRule.selector), false, anchorNodeCheck); | ||
mixinRule.selector = selector; | ||
} | ||
else if (mixinRule.selector.includes(anchorSelector)) { | ||
// report invalid nested mixin | ||
mixinRule.selector = mixinRule.selector.split(anchorSelector).join('&'); | ||
report?.report(exports.utilDiagnostics.INVALID_RECURSIVE_MIXIN(), { | ||
node: rule, | ||
}); | ||
} | ||
}); | ||
@@ -45,10 +78,29 @@ if (mixinAst.nodes) { | ||
// TODO: handle rules before and after decl on entry | ||
const inlineMixin = !hasNonDeclsBeforeDecl(mixinDecl); | ||
const mixInto = inlineMixin ? rule : postcss.rule({ selector: '&' }); | ||
const mixIntoRule = (node) => { | ||
// mix node into rule | ||
if (inlineMixin) { | ||
mixInto.insertBefore(mixinDecl, node); | ||
} | ||
else { | ||
// indent first level - doesn't change deep nested | ||
node.raws.before = (node.raws.before || '') + ' '; | ||
mixInto.append(node); | ||
} | ||
// mark following decls for nesting | ||
if (!nestFollowingDecls && node.type !== 'decl' && hasAnyDeclsAfter(mixinDecl)) { | ||
nestFollowingDecls = true; | ||
} | ||
}; | ||
let nestFollowingDecls = false; | ||
mixinAst.nodes.slice().forEach((node) => { | ||
if (node === mixinRoot) { | ||
for (const nested of [...node.nodes]) { | ||
rule.insertBefore(mixinDecl, nested); | ||
mixIntoRule(nested); | ||
} | ||
} | ||
else if (node.type === 'decl') { | ||
rule.insertBefore(mixinDecl, node); | ||
// stand alone decl - most likely from js mixin | ||
mixIntoRule(node); | ||
} | ||
@@ -73,2 +125,16 @@ else if (node.type === 'rule' || node.type === 'atrule') { | ||
}); | ||
// add nested mixin to rule body | ||
if (mixInto !== rule && mixInto.nodes.length) { | ||
mixinDecl.before(mixInto); | ||
} | ||
// nest following decls if needed | ||
if (nestFollowingDecls) { | ||
const nestFollowingDecls = postcss.rule({ selector: '&' }); | ||
while (mixinDecl.next()) { | ||
const nextNode = mixinDecl.next(); | ||
nextNode.raws.before = (nextNode.raws.before || '') + ' '; | ||
nestFollowingDecls.append(nextNode); | ||
} | ||
mixinDecl.after(nestFollowingDecls); | ||
} | ||
} | ||
@@ -78,2 +144,32 @@ return rule; | ||
exports.mergeRules = mergeRules; | ||
function hasNonDeclsBeforeDecl(decl) { | ||
let current = decl.prev(); | ||
while (current) { | ||
if (current.type !== 'decl' && current.type !== 'comment') { | ||
return true; | ||
} | ||
current = current.prev(); | ||
} | ||
return false; | ||
} | ||
function hasAnyDeclsAfter(decl) { | ||
let current = decl.next(); | ||
while (current) { | ||
if (current.type === 'decl') { | ||
return true; | ||
} | ||
current = current.prev(); | ||
} | ||
return false; | ||
} | ||
const isChildOfMixinRoot = (rule, mixinRoot) => { | ||
let current = rule.parent; | ||
while (current) { | ||
if (current === mixinRoot) { | ||
return true; | ||
} | ||
current = current.parent; | ||
} | ||
return false; | ||
}; | ||
exports.sourcePathDiagnostics = { | ||
@@ -80,0 +176,0 @@ MISSING_SOURCE_FILENAME: (0, diagnostics_1.createDiagnosticReporter)('17001', 'error', () => 'missing source filename'), |
{ | ||
"name": "@stylable/core", | ||
"version": "5.15.2", | ||
"version": "5.16.0", | ||
"description": "CSS for Components", | ||
@@ -13,4 +13,4 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@tokey/css-selector-parser": "^0.6.1", | ||
"@tokey/css-value-parser": "^0.1.3", | ||
"@tokey/css-selector-parser": "^0.6.2", | ||
"@tokey/css-value-parser": "^0.1.4", | ||
"@tokey/imports-parser": "^1.0.0", | ||
@@ -17,0 +17,0 @@ "balanced-match": "^2.0.0", |
@@ -66,2 +66,3 @@ import { createFeature, FeatureTransformContext } from './feature'; | ||
INVALID_MERGE_OF: utilDiagnostics.INVALID_MERGE_OF, | ||
INVALID_RECURSIVE_MIXIN: utilDiagnostics.INVALID_RECURSIVE_MIXIN, | ||
PARTIAL_MIXIN_MISSING_ARGUMENTS: createDiagnosticReporter( | ||
@@ -68,0 +69,0 @@ '10001', |
@@ -37,2 +37,7 @@ import path from 'path'; | ||
), | ||
NATIVE_OVERRIDE_DEPRECATION: createDiagnosticReporter( | ||
'11014', | ||
'info', | ||
() => '@namespace will stop working in version 6, use @st-namespace instead' | ||
), | ||
}; | ||
@@ -43,2 +48,3 @@ | ||
usedNativeNamespace: string[]; | ||
usedNativeNamespaceNodes: AtRule[]; | ||
foundStNamespace: boolean; | ||
@@ -54,2 +60,3 @@ }>('namespace'); | ||
usedNativeNamespace: [], | ||
usedNativeNamespaceNodes: [], | ||
foundStNamespace: false, | ||
@@ -75,5 +82,7 @@ }); | ||
data.usedNativeNamespace.push(atRule.params); | ||
data.usedNativeNamespaceNodes.push(atRule); | ||
} else { | ||
// clear @namespace matches once @st-namespace if found | ||
data.usedNativeNamespace.length = 0; | ||
data.usedNativeNamespaceNodes.length = 0; | ||
// mark to prevent any further @namespace collection | ||
@@ -84,2 +93,10 @@ data.foundStNamespace = true; | ||
}, | ||
analyzeDone(context) { | ||
const { usedNativeNamespaceNodes } = plugableRecord.getUnsafe(context.meta.data, dataKey); | ||
for (const node of usedNativeNamespaceNodes) { | ||
context.diagnostics.report(diagnostics.NATIVE_OVERRIDE_DEPRECATION(), { | ||
node, | ||
}); | ||
} | ||
}, | ||
prepareAST({ context, node, toRemove }) { | ||
@@ -86,0 +103,0 @@ // remove @st-namespace or @namespace that was used as @st-namespace |
@@ -109,3 +109,2 @@ import { | ||
let scopeSelector = node.name === 'st-scope' ? node.params : ''; | ||
let isNestedInMixin = false; | ||
if (scopeSelector) { | ||
@@ -112,0 +111,0 @@ const ast = parseSelectorWithCache(scopeSelector, { clone: true }); |
@@ -69,2 +69,3 @@ import type * as postcss from 'postcss'; | ||
}); | ||
STNamespace.hooks.analyzeDone(this); | ||
STCustomSelector.hooks.analyzeDone(this); | ||
@@ -71,0 +72,0 @@ STStructure.hooks.analyzeDone(this); |
import { isAbsolute } from 'path'; | ||
import type * as postcss from 'postcss'; | ||
import * as postcss from 'postcss'; | ||
import { createDiagnosticReporter, Diagnostics } from './diagnostics'; | ||
@@ -18,2 +18,7 @@ import type { ImportSymbol, StylableSymbol } from './features'; | ||
), | ||
INVALID_RECURSIVE_MIXIN: createDiagnosticReporter( | ||
'10010', | ||
'error', | ||
() => `invalid recursive mixin` | ||
), | ||
}; | ||
@@ -50,3 +55,4 @@ | ||
} | ||
} else { | ||
} else if (!isChildOfMixinRoot(mixinRule, mixinRoot)) { | ||
// scope to mixin target if not already scoped by parent | ||
const { selector } = scopeNestedSelector( | ||
@@ -59,2 +65,8 @@ parseSelectorWithCache(rule.selector), | ||
mixinRule.selector = selector; | ||
} else if (mixinRule.selector.includes(anchorSelector)) { | ||
// report invalid nested mixin | ||
mixinRule.selector = mixinRule.selector.split(anchorSelector).join('&'); | ||
report?.report(utilDiagnostics.INVALID_RECURSIVE_MIXIN(), { | ||
node: rule, | ||
}); | ||
} | ||
@@ -66,9 +78,27 @@ }); | ||
// TODO: handle rules before and after decl on entry | ||
const inlineMixin = !hasNonDeclsBeforeDecl(mixinDecl); | ||
const mixInto = inlineMixin ? rule : postcss.rule({ selector: '&' }); | ||
const mixIntoRule = (node: postcss.AnyNode) => { | ||
// mix node into rule | ||
if (inlineMixin) { | ||
mixInto.insertBefore(mixinDecl, node); | ||
} else { | ||
// indent first level - doesn't change deep nested | ||
node.raws.before = (node.raws.before || '') + ' '; | ||
mixInto.append(node); | ||
} | ||
// mark following decls for nesting | ||
if (!nestFollowingDecls && node.type !== 'decl' && hasAnyDeclsAfter(mixinDecl)) { | ||
nestFollowingDecls = true; | ||
} | ||
}; | ||
let nestFollowingDecls = false; | ||
mixinAst.nodes.slice().forEach((node) => { | ||
if (node === mixinRoot) { | ||
for (const nested of [...node.nodes]) { | ||
rule.insertBefore(mixinDecl, nested); | ||
mixIntoRule(nested); | ||
} | ||
} else if (node.type === 'decl') { | ||
rule.insertBefore(mixinDecl, node); | ||
// stand alone decl - most likely from js mixin | ||
mixIntoRule(node); | ||
} else if (node.type === 'rule' || node.type === 'atrule') { | ||
@@ -90,2 +120,16 @@ const valid = !nestedInKeyframes; | ||
}); | ||
// add nested mixin to rule body | ||
if (mixInto !== rule && mixInto.nodes.length) { | ||
mixinDecl.before(mixInto); | ||
} | ||
// nest following decls if needed | ||
if (nestFollowingDecls) { | ||
const nestFollowingDecls = postcss.rule({ selector: '&' }); | ||
while (mixinDecl.next()) { | ||
const nextNode = mixinDecl.next()!; | ||
nextNode.raws.before = (nextNode.raws.before || '') + ' '; | ||
nestFollowingDecls.append(nextNode); | ||
} | ||
mixinDecl.after(nestFollowingDecls); | ||
} | ||
} | ||
@@ -96,2 +140,34 @@ | ||
function hasNonDeclsBeforeDecl(decl: postcss.Declaration) { | ||
let current: postcss.AnyNode | undefined = decl.prev(); | ||
while (current) { | ||
if (current.type !== 'decl' && current.type !== 'comment') { | ||
return true; | ||
} | ||
current = current.prev(); | ||
} | ||
return false; | ||
} | ||
function hasAnyDeclsAfter(decl: postcss.Declaration) { | ||
let current: postcss.AnyNode | undefined = decl.next(); | ||
while (current) { | ||
if (current.type === 'decl') { | ||
return true; | ||
} | ||
current = current.prev(); | ||
} | ||
return false; | ||
} | ||
const isChildOfMixinRoot = (rule: postcss.Rule, mixinRoot: postcss.Rule | null | 'NoRoot') => { | ||
let current: postcss.Container | postcss.Document | undefined = rule.parent; | ||
while (current) { | ||
if (current === mixinRoot) { | ||
return true; | ||
} | ||
current = current.parent; | ||
} | ||
return false; | ||
}; | ||
export const sourcePathDiagnostics = { | ||
@@ -98,0 +174,0 @@ MISSING_SOURCE_FILENAME: createDiagnosticReporter( |
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
5209072
28616