Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

stylelint

Package Overview
Dependencies
Maintainers
6
Versions
239
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

stylelint - npm Package Compare versions

Comparing version 15.5.0 to 15.6.0

4

lib/augmentConfig.js

@@ -427,2 +427,6 @@ 'use strict';

if (stylelint._options.fix) {
augmentedConfig.fix = stylelint._options.fix;
}
return augmentedConfig;

@@ -429,0 +433,0 @@ }

2

lib/lintPostcssResult.js

@@ -115,3 +115,3 @@ 'use strict';

!disableFix &&
stylelintOptions.fix &&
config.fix &&
// Next two conditionals are temporary measures until #2643 is resolved

@@ -118,0 +118,0 @@ isFileFixCompatible &&

@@ -13,2 +13,3 @@ 'use strict';

const validateOptions = require('../../utils/validateOptions');
const optionsMatches = require('../../utils/optionsMatches');

@@ -30,11 +31,24 @@ const ruleName = 'color-function-notation';

/** @type {import('stylelint').Rule} */
const rule = (primary, _secondaryOptions, context) => {
const rule = (primary, secondaryOptions, context) => {
return (root, result) => {
const validOptions = validateOptions(result, ruleName, {
actual: primary,
possible: ['modern', 'legacy'],
});
const validOptions = validateOptions(
result,
ruleName,
{
actual: primary,
possible: ['modern', 'legacy'],
},
{
actual: secondaryOptions,
possible: {
ignore: ['with-var-inside'],
},
optional: true,
},
);
if (!validOptions) return;
const ignoreWithVarInside = optionsMatches(secondaryOptions, 'ignore', 'with-var-inside');
root.walkDecls((decl) => {

@@ -51,2 +65,6 @@ let needsFix = false;

if (ignoreWithVarInside && containsVariable(nodes)) {
return;
}
if (!LEGACY_NOTATION_FUNCS.has(value.toLowerCase())) return;

@@ -119,2 +137,9 @@

/**
* @param {import('postcss-value-parser').Node[]} nodes
*/
function containsVariable(nodes) {
return nodes.some(({ type, value }) => type === 'function' && value.toLowerCase() === 'var');
}
/**
* @param {import('postcss-value-parser').Node} node

@@ -121,0 +146,0 @@ * @returns {node is import('postcss-value-parser').DivNode}

@@ -119,1 +119,35 @@ # color-function-notation

```
## Optional secondary options
### `ignore: ["with-var-inside"]`
Ignore color functions containing variables.
Given:
```json
["modern", { "ignore": ["with-var-inside"] }]
```
The following patterns are _not_ considered problems:
```css
a {
color: rgba(var(--foo), 0.5);
}
```
Given:
```json
["legacy", { "ignore": ["with-var-inside"] }]
```
The following patterns are _not_ considered problems:
```css
a {
color: rgba(var(--foo) / 0.5);
}
```

@@ -7,2 +7,3 @@ 'use strict';

const isStandardSyntaxProperty = require('../../utils/isStandardSyntaxProperty');
const isStandardSyntaxValue = require('../../utils/isStandardSyntaxValue');
const optionsMatches = require('../../utils/optionsMatches');

@@ -33,2 +34,3 @@ const report = require('../../utils/report');

const isEqualValueNodes = (nodes1, nodes2) => {
// Different lengths indicate different syntaxes.
if (nodes1.length !== nodes2.length) {

@@ -42,2 +44,3 @@ return false;

// Different types indicate different syntaxes.
if (typeof node1 === 'undefined' || typeof node2 === 'undefined' || node1.type !== node2.type) {

@@ -47,2 +50,28 @@ return false;

const node1Name = 'name' in node1 ? String(node1.name) : '';
const node2Name = 'name' in node2 ? String(node2.name) : '';
// Custom properties have unknown value syntaxes but are equal for CSS parsers.
if (
node1.type === 'Identifier' &&
isCustomProperty(node1Name) &&
node2.type === 'Identifier' &&
isCustomProperty(node2Name)
) {
continue;
}
// Different ident or function names indicate different syntaxes.
if (node1Name.toLowerCase() !== node2Name.toLowerCase()) {
return false;
}
const node1Unit = 'unit' in node1 ? node1.unit : '';
const node2Unit = 'unit' in node2 ? node2.unit : '';
// Different units indicate different syntaxes.
if (node1Unit !== node2Unit) {
return false;
}
const node1Children = hasChildren(node1) ? node1.children.toArray() : null;

@@ -52,9 +81,2 @@ const node2Children = hasChildren(node2) ? node2.children.toArray() : null;

if (Array.isArray(node1Children) && Array.isArray(node2Children)) {
const node1Name = 'name' in node1 ? String(node1.name) : '';
const node2Name = 'name' in node2 ? String(node2.name) : '';
if (node1Name.toLowerCase() !== node2Name.toLowerCase()) {
return false;
}
if (isEqualValueNodes(node1Children, node2Children)) {

@@ -66,9 +88,2 @@ continue;

}
const node1Unit = 'unit' in node1 ? node1.unit : '';
const node2Unit = 'unit' in node2 ? node2.unit : '';
if (node1Unit !== node2Unit) {
return false;
}
}

@@ -85,4 +100,16 @@

const value1Node = parse(value1, { context: 'value' });
const value2Node = parse(value2, { context: 'value' });
if (!(isStandardSyntaxValue(value1) && isStandardSyntaxValue(value2))) {
return false;
}
let value1Node;
let value2Node;
try {
value1Node = parse(value1, { context: 'value' });
value2Node = parse(value2, { context: 'value' });
} catch (error) {
return false;
}
const node1Children = hasChildren(value1Node) ? value1Node.children.toArray() : [];

@@ -200,2 +227,5 @@ const node2Children = hasChildren(value2Node) ? value2Node.children.toArray() : [];

// replace previous "active" decl with current one
decls[indexDuplicate] = decl;
return duplicateDecl.remove();

@@ -202,0 +232,0 @@ };

@@ -27,2 +27,53 @@ 'use strict';

/** @type {Map<string, (decls: Map<string, Declaration>) => (string | undefined)>} */
const customResolvers = new Map([
[
'grid-template',
(decls) => {
const areas = decls.get('grid-template-areas')?.value.trim();
const columns = decls.get('grid-template-columns')?.value.trim();
const rows = decls.get('grid-template-rows')?.value.trim();
if (!(areas && columns && rows)) return;
const splitAreas = [...areas.matchAll(/"[^"]+"/g)].map((x) => x[0]);
const splitRows = rows.split(' ');
if (splitAreas.length === 0 || splitRows.length === 0) return;
if (splitAreas.length !== splitRows.length) return;
const zipped = splitAreas.map((area, i) => `${area} ${splitRows[i]}`).join(' ');
return `${zipped} / ${columns}`;
},
],
]);
/**
* @param {string} prefixedShorthandProperty
* @param {string[]} prefixedShorthandData
* @param {Map<string, Declaration>} transformedDeclarationNodes
* @returns {string | undefined}
*/
const resolveShorthandValue = (
prefixedShorthandProperty,
prefixedShorthandData,
transformedDeclarationNodes,
) => {
const resolver = customResolvers.get(prefixedShorthandProperty);
if (resolver === undefined) {
// the "default" resolver: sort the longhand values in the order
// of their properties
const values = prefixedShorthandData
.map((p) => transformedDeclarationNodes.get(p)?.value.trim())
.filter(Boolean);
return values.length > 0 ? values.join(' ') : undefined;
}
return resolver(transformedDeclarationNodes);
};
/** @type {import('stylelint').Rule} */

@@ -117,17 +168,20 @@ const rule = (primary, secondaryOptions, context) => {

);
const resolvedShorthandValue = prefixedShorthandData
.map((p) => transformedDeclarationNodes.get(p)?.value.trim())
.filter(Boolean)
.join(' ');
const resolvedShorthandValue = resolveShorthandValue(
prefixedShorthandProperty,
prefixedShorthandData,
transformedDeclarationNodes,
);
const newShorthandDeclarationNode = firstDeclNode.clone({
prop: prefixedShorthandProperty,
value: resolvedShorthandValue,
});
if (resolvedShorthandValue) {
const newShorthandDeclarationNode = firstDeclNode.clone({
prop: prefixedShorthandProperty,
value: resolvedShorthandValue,
});
firstDeclNode.replaceWith(newShorthandDeclarationNode);
firstDeclNode.replaceWith(newShorthandDeclarationNode);
declNodes.forEach((node) => node.remove());
declNodes.forEach((node) => node.remove());
return;
return;
}
}

@@ -134,0 +188,0 @@ }

@@ -74,2 +74,9 @@ 'use strict';

/**
* @param {import('postcss-value-parser').Node} node
*/
function containsOnlyComments(node) {
return 'nodes' in node && node.nodes.every((child) => child.type === 'comment');
}
/**
* @param {import('postcss').AtRule} atRule

@@ -84,2 +91,8 @@ */

const [funcNode] = parsed.nodes;
if (funcNode && containsOnlyComments(funcNode)) {
return;
}
if (context.fix) {

@@ -86,0 +99,0 @@ atRule.params = parsed.toString();

@@ -32,4 +32,4 @@ 'use strict';

async function standalone({
allowEmptyInput = false,
cache: useCache = false,
allowEmptyInput,
cache,
cacheLocation,

@@ -138,3 +138,5 @@ cacheStrategy,

if (fix && postcssResult && !postcssResult.stylelint.ignored) {
const autofix = fix ?? config?.fix ?? false;
if (autofix && postcssResult && !postcssResult.stylelint.ignored) {
returnValue.output =

@@ -169,2 +171,5 @@ !postcssResult.stylelint.disableWritingFix && postcssResult.opts

// do not cache if config is explicitly overrided by option
const useCache = cache ?? config?.cache ?? false;
if (!useCache) {

@@ -252,3 +257,3 @@ stylelint._fileCache.destroy();

stylelintResults = await Promise.all(getStylelintResults);
} else if (allowEmptyInput) {
} else if (allowEmptyInput ?? config?.allowEmptyInput) {
stylelintResults = await Promise.all([]);

@@ -255,0 +260,0 @@ } else if (filePathsLengthBeforeIgnore) {

{
"name": "stylelint",
"version": "15.5.0",
"version": "15.6.0",
"description": "A mighty CSS linter that helps you avoid errors and enforce conventions.",

@@ -115,5 +115,5 @@ "keywords": [

"dependencies": {
"@csstools/css-parser-algorithms": "^2.1.0",
"@csstools/css-tokenizer": "^2.1.0",
"@csstools/media-query-list-parser": "^2.0.2",
"@csstools/css-parser-algorithms": "^2.1.1",
"@csstools/css-tokenizer": "^2.1.1",
"@csstools/media-query-list-parser": "^2.0.4",
"@csstools/selector-specificity": "^2.2.0",

@@ -143,3 +143,3 @@ "balanced-match": "^2.0.0",

"picocolors": "^1.0.0",
"postcss": "^8.4.21",
"postcss": "^8.4.22",
"postcss-media-query-parser": "^0.2.3",

@@ -146,0 +146,0 @@ "postcss-resolve-nested-selector": "^0.1.1",

@@ -109,2 +109,5 @@ import type * as PostCSS from 'postcss';

customSyntax?: CustomSyntax;
allowEmptyInput?: boolean;
cache?: boolean;
fix?: boolean;
};

@@ -111,0 +114,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc