Skip to content

Commit

Permalink
Refactor no-duplicate-at-import-rules to remove `postcss-media-quer…
Browse files Browse the repository at this point in the history
…y-parser` (#6996)

* Refactor `no-duplicate-at-import-rules` to remove `postcss-media-query-parser`

* fix

* rename

* reduce change

* poke

* increase test coverage

* use a typedef

* apply suggestions from code review

* Update lib/rules/no-duplicate-at-import-rules/index.js

Co-authored-by: Masafumi Koba <473530+ybiquitous@users.noreply.github.com>

* cleanup and fix whitespace removal

---------

Co-authored-by: Masafumi Koba <473530+ybiquitous@users.noreply.github.com>
  • Loading branch information
romainmenke and ybiquitous committed Jun 29, 2023
1 parent 067cb27 commit 26f9351
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 6 deletions.
12 changes: 12 additions & 0 deletions lib/rules/no-duplicate-at-import-rules/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ testRule({
line: 1,
column: 38,
},
{
code: "@import url('a.css') /* a comment */ tv; @import 'a.css' tv /* a comment */;",
message: messages.rejected(`a.css`),
line: 1,
column: 42,
},
{
code: '@import "a.css" (min-width : 500px);@import url(a.css) ( min-width:500px );',
message: messages.rejected(`a.css`),
line: 1,
column: 37,
},
{
code: '@import "a.css" tv, (min-width : 500px);@import url(a.css) ( min-width:500px ), tv;',
message: messages.rejected(`a.css`),
Expand Down
47 changes: 41 additions & 6 deletions lib/rules/no-duplicate-at-import-rules/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const mediaParser = require('postcss-media-query-parser').default;
const getAtRuleParams = require('../../utils/getAtRuleParams');
const report = require('../../utils/report');
const ruleMessages = require('../../utils/ruleMessages');
const validateOptions = require('../../utils/validateOptions');
Expand Down Expand Up @@ -29,7 +29,7 @@ const rule = (primary) => {
const imports = {};

root.walkAtRules(/^import$/i, (atRule) => {
const [firstParam, ...restParams] = valueParser(atRule.params).nodes;
const [firstParam, ...restParams] = valueParser(getAtRuleParams(atRule)).nodes;

if (!firstParam) {
return;
Expand All @@ -41,10 +41,7 @@ const rule = (primary) => {
? firstParam.nodes[0].value
: firstParam.value;

// extract media queries if any
const media = (mediaParser(valueParser.stringify(restParams)).nodes || [])
.map((n) => n.value.replace(/\s/g, ''))
.filter((n) => n.length);
const media = listImportConditions(restParams);

let importedUris = imports[uri];
const isDuplicate = media.length
Expand Down Expand Up @@ -73,6 +70,44 @@ const rule = (primary) => {
};
};

/**
* List the import conditions found in the prelude of an `@import` rule
*
* @param {Node[]} params
* @typedef {import('postcss-value-parser').Node} Node
* @returns {Array<string>}
*/
function listImportConditions(params) {
if (!params.length) return [];

/** @type {Array<String>} */
let media = [];
/** @type {Array<Node>} */
let lastMediaQuery = [];

for (const param of params) {
// remove top level whitespace and comments to get a more consistent key
if (param.type === 'space' || param.type === 'comment') {
continue;
}

if (param.type === 'div' && param.value === ',') {
media.push(valueParser.stringify(lastMediaQuery));
lastMediaQuery = [];
continue;
}

lastMediaQuery.push(param);
}

if (lastMediaQuery.length) {
media.push(valueParser.stringify(lastMediaQuery));
}

// remove remaining whitespace to get a more consistent key
return media.map((m) => m.replace(/\s/g, ''));
}

rule.ruleName = ruleName;
rule.messages = messages;
rule.meta = meta;
Expand Down

0 comments on commit 26f9351

Please sign in to comment.