Skip to content

Commit

Permalink
Make copies for *-blacklist/*-requirelist/*-whitelist rules
Browse files Browse the repository at this point in the history
As discussed in issue stylelint#4854, the desired approach is to deprecate the
*-blacklist/*-requirelist/*-whitelist rules. The first step I've taken
to doing this is to make copies of all the rules. The commands used to
generate this commit were:

- find . -name '*-allowed-list' -exec sh -c 'cp -R "$1" "${1%-allowed-list}-whitelist"' _ {} \;
- find . -name '*-disallowed-list' -exec sh -c 'cp -R "$1" "${1%-disallowed-list}-blacklist"' _ {} \;
- find . -name '*-required-list' -exec sh -c 'cp -R "$1" "${1%-required-list}-requirelist"' _ {} \;
  • Loading branch information
kevindew committed Aug 24, 2020
1 parent 858dcd5 commit 42c68d6
Show file tree
Hide file tree
Showing 81 changed files with 8,920 additions and 0 deletions.
52 changes: 52 additions & 0 deletions lib/rules/at-rule-blacklist/README.md
@@ -0,0 +1,52 @@
# at-rule-disallowed-list

Specify a list of disallowed at-rules.

<!-- prettier-ignore -->
```css
@keyframes name {}
/** ↑
* At-rules like this */
```

This rule was previously called, and is aliased as, `at-rule-blacklist`.

## Options

`array|string`: `["array", "of", "unprefixed", "at-rules"]|"at-rule"`

Given:

```
["extend", "keyframes"]
```

The following patterns are considered violations:

<!-- prettier-ignore -->
```css
a { @extend placeholder; }
```

<!-- prettier-ignore -->
```css
@keyframes name {
from { top: 10px; }
to { top: 20px; }
}
```

<!-- prettier-ignore -->
```css
@-moz-keyframes name {
from { top: 10px; }
to { top: 20px; }
}
```

The following patterns are _not_ considered violations:

<!-- prettier-ignore -->
```css
@import "path/to/file.css";
```
174 changes: 174 additions & 0 deletions lib/rules/at-rule-blacklist/__tests__/index.js
@@ -0,0 +1,174 @@
'use strict';

const { messages, ruleName } = require('..');

testRule({
ruleName,

config: ['extend', 'supports', 'keyframes'],

accept: [
{
code: 'a { color: pink; }',
description: 'Some random code.',
},
{
code: '@mixin name ($p) {}',
description: '@rule not from a disallowed list.',
},
],

reject: [
{
code: 'a { @extend %placeholder; }',
message: messages.rejected('extend'),
line: 1,
column: 5,
description: '@rule from a disallowed list, is a Sass directive.',
},
{
code: `
a {
@extend
%placeholder;
}
`,
message: messages.rejected('extend'),
line: 3,
column: 9,
description: '@rule from a disallowed list; newline after its name.',
},
{
code: `
@keyframes name {
from { top: 10px; }
to { top: 20px; }
}
`,
message: messages.rejected('keyframes'),
line: 2,
description: '@rule from a disallowed list; independent rule.',
},
{
code: `
@Keyframes name {
from { top: 10px; }
to { top: 20px; }
}
`,
message: messages.rejected('Keyframes'),
line: 2,
column: 7,
description: '@rule from a disallowed list; independent rule; messed case.',
},
{
code: `
@-moz-keyframes name {
from { top: 10px; }
to { top: 20px; }
}
`,
message: messages.rejected('-moz-keyframes'),
line: 2,
column: 7,
description: '@rule from a disallowed list; independent rule; has vendor prefix.',
},
{
code: `
@-WEBKET-KEYFRAMES name {
from { top: 10px; }
to { top: 20px; }
}
`,
message: messages.rejected('-WEBKET-KEYFRAMES'),
line: 2,
column: 7,
description: '@rule from a disallowed list; independent rule; has vendor prefix.',
},
],
});

testRule({
ruleName,

config: ['keyframes'],

accept: [
{
code: 'a { color: pink; }',
description: 'Some random code.',
},
{
code: '@mixin name ($p) {}',
description: '@rule not from a disallowed list.',
},
],

reject: [
{
code: `
@keyframes name {
from { top: 10px; }
to { top: 20px; }
}
`,
message: messages.rejected('keyframes'),
line: 2,
column: 7,
description: '@rule from a disallowed list; independent rule.',
},
{
code: `
@Keyframes name {
from { top: 10px; }
to { top: 20px; }
}
`,
message: messages.rejected('Keyframes'),
line: 2,
column: 7,
description: '@rule from a disallowed list; independent rule; messed case.',
},
{
code: `
@-moz-keyframes name {
from { top: 10px; }
to { top: 20px; }
}
`,
message: messages.rejected('-moz-keyframes'),
line: 2,
column: 7,
description: '@rule from a disallowed list; independent rule; has vendor prefix.',
},
{
code: `
@-WEBKET-KEYFRAMES name {
from { top: 10px; }
to { top: 20px; }
}
`,
message: messages.rejected('-WEBKET-KEYFRAMES'),
line: 2,
column: 7,
description: '@rule from a disallowed list; independent rule; has vendor prefix.',
},
],
});

testRule({
ruleName,
syntax: 'less',
config: ['keyframes'],

accept: [
{
code: `
.keyframes() { margin: 0; }
span { .keyframes(); }
`,
description: 'ignore Less mixin which are treated as at-rule',
},
],
});
57 changes: 57 additions & 0 deletions lib/rules/at-rule-blacklist/index.js
@@ -0,0 +1,57 @@
// @ts-nocheck

'use strict';

const _ = require('lodash');
const isStandardSyntaxAtRule = require('../../utils/isStandardSyntaxAtRule');
const postcss = require('postcss');
const report = require('../../utils/report');
const ruleMessages = require('../../utils/ruleMessages');
const validateOptions = require('../../utils/validateOptions');

const ruleName = 'at-rule-disallowed-list';

const messages = ruleMessages(ruleName, {
rejected: (name) => `Unexpected at-rule "${name}"`,
});

function rule(listInput) {
// To allow for just a string as a parameter (not only arrays of strings)
const list = [].concat(listInput);

return (root, result) => {
const validOptions = validateOptions(result, ruleName, {
actual: list,
possible: [_.isString],
});

if (!validOptions) {
return;
}

root.walkAtRules((atRule) => {
const name = atRule.name;

if (!isStandardSyntaxAtRule(atRule)) {
return;
}

if (!list.includes(postcss.vendor.unprefixed(name).toLowerCase())) {
return;
}

report({
message: messages.rejected(name),
node: atRule,
result,
ruleName,
});
});
};
}

rule.primaryOptionArray = true;

rule.ruleName = ruleName;
rule.messages = messages;
module.exports = rule;
55 changes: 55 additions & 0 deletions lib/rules/at-rule-property-requirelist/README.md
@@ -0,0 +1,55 @@
# at-rule-property-required-list

Specify a list of required properties for an at-rule.

<!-- prettier-ignore -->
```css
@font-face { font-display: swap; font-family: 'foo'; }
/** ↑ ↑ ↑
* At-rule and required property names */
```

This rule was previously called, and is aliased as, `at-rule-requirelist`.

## Options

`object`: `{ "at-rule-name": ["array", "of", "properties"] }`

Given:

```
{
"font-face": ["font-display", "font-family", "font-style"]
}
```

The following patterns are considered violations:

<!-- prettier-ignore -->
```css
@font-face {
font-family: 'foo';
src: url('./fonts/foo.woff2') format('woff2');
}
```

<!-- prettier-ignore -->
```css
@font-face {
font-family: 'foo';
font-style: normal;
src: url('./fonts/foo.woff2') format('woff2');
}
```

The following patterns are _not_ considered violations:

<!-- prettier-ignore -->
```css
@font-face {
font-display: swap;
font-family: 'foo';
font-style: normal;
src: url('./fonts/foo.woff2') format('woff2');
}
```

0 comments on commit 42c68d6

Please sign in to comment.