Skip to content

Commit

Permalink
correctly parse import arguments (#36)
Browse files Browse the repository at this point in the history
Co-authored-by: Romain Menke <[email protected]>
  • Loading branch information
edoardocavazza and romainmenke authored Dec 28, 2023
1 parent 742419b commit 35c00e9
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changes to Stylelint Value No Unknown Custom Properties

### Unreleased

- Fix `@import` prelude parsing

### 6.0.0 (Dec 28, 2023)

- Updated: peer `stylelint` to >=16 (breaking)
Expand Down
9 changes: 9 additions & 0 deletions index.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ accept = [
{ code: '.anything { --brand-blue: #33f; } body { color: var(--brand-blue); }' },
{ code: ':root { --brand-blue: #33f; --brand-color: var(--brand-blue); }' },
{ code: '@import \'./test/import-custom-properties.css\'; body { color: var(--brand-red); }' },
{ code: '@import "./test/import-custom-properties.css" screen; body { color: var(--brand-red); }' },
{ code: '@import "./test/import-custom-properties.css"/**/; body { color: var(--brand-red); }' },
{ code: '@import url(./test/import-custom-properties.css); body { color: var(--brand-red); }' },
{ code: '@import url(\'./test/import-custom-properties.css\'); body { color: var(--brand-red); }' },
{ code: '@import url( \'./test/import-custom-properties.css\'/**/)/**/; body { color: var(--brand-red); }' },
{ code: '@import url(\t\'./test/import-custom-properties.css\'\t)\t; body { color: var(--brand-red); }' },
{ code: '@import url(./test/import-custom-properties.css) screen; body { color: var(--brand-red); }' },
{ code: '@import url("./test/import-custom-properties.css") screen; body { color: var(--brand-red); }' },
{ code: '@import url("./test/import-custom-properties.css" url-mod); body { color: var(--brand-red); }' },
{ code: '@import \'./test/import-custom-properties.css\'; @import \'./test/import-custom-properties123.css\'; body { color: var(--brand-red); }' },
];
reject = [
Expand Down
59 changes: 51 additions & 8 deletions src/lib/get-custom-properties-from-root.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import postcss from 'postcss';
import valueParser from 'postcss-value-parser';
import { resolveId } from './resolve-id.mjs';

// return custom selectors from the css root, conditionally removing them
Expand All @@ -17,7 +18,10 @@ export default async function getCustomPropertiesFromRoot(root, resolver) {
// recursively add custom properties from @import statements
const importPromises = [];
root.walkAtRules('import', atRule => {
const fileName = atRule.params.replace(/['|"]/g, '');
const fileName = parseImportParams(atRule.params);
if (!fileName) {
return;
}

if (path.isAbsolute(fileName)) {
importPromises.push(getCustomPropertiesFromCSSFile(fileName, resolver));
Expand All @@ -39,21 +43,19 @@ export default async function getCustomPropertiesFromRoot(root, resolver) {
});

// for each custom property declaration
root.walkDecls(customPropertyRegExp, decl => {
const { prop } = decl;
root.walkDecls(decl => {
if (!decl.variable || !decl.prop.startsWith('--')) {
return;
}

// write the parsed value to the custom property
customProperties[prop] = decl.value;
customProperties[decl.prop] = decl.value;
});

// return all custom properties, preferring :root properties over html properties
return customProperties;
}

// match custom properties
const customPropertyRegExp = /^--[A-z][\w-]*$/;


async function getCustomPropertiesFromCSSFile(from, resolver) {
try {
const css = await fs.readFile(from, 'utf8');
Expand All @@ -64,3 +66,44 @@ async function getCustomPropertiesFromCSSFile(from, resolver) {
return {};
}
}

function parseImportParams(params) {
const nodes = valueParser(params).nodes;
if (!nodes.length) {
return;
}

for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
if (node.type === 'space' || node.type === 'comment') {
continue;
}

if (node.type === 'string') {
return node.value;
}

if (node.type === 'function' && /url/i.test(node.value)) {
for (let j = 0; j < node.nodes.length; j++) {
const urlNode = node.nodes[j];
if (urlNode.type === 'space' || urlNode.type === 'comment') {
continue;
}

if (urlNode.type === 'word') {
return urlNode.value;
}

if (urlNode.type === 'string') {
return urlNode.value;
}

return false;
}
}

return false;
}

return false;
}

0 comments on commit 35c00e9

Please sign in to comment.