Skip to content

Commit

Permalink
add selector-not-notation
Browse files Browse the repository at this point in the history
  • Loading branch information
Mouvedia committed Mar 26, 2022
1 parent e026f57 commit 6e1ebd3
Show file tree
Hide file tree
Showing 5 changed files with 387 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/user-guide/rules/list.md
Expand Up @@ -198,6 +198,7 @@ Within each cateogory, the rules are grouped by the [_thing_](http://apps.workfl
- [`selector-nested-pattern`](../../../lib/rules/selector-nested-pattern/README.md): Specify a pattern for the selectors of rules nested within rules.
- [`selector-no-qualifying-type`](../../../lib/rules/selector-no-qualifying-type/README.md): Disallow qualifying a selector by type.
- [`selector-no-vendor-prefix`](../../../lib/rules/selector-no-vendor-prefix/README.md): Disallow vendor prefixes for selectors (Autofixable).
- [`selector-not-notation`](../../../lib/rules/selector-not-notation/README.md): Specify simple or complex notation for `:not()` pseudo-classes (Autofixable).
- [`selector-pseudo-class-allowed-list`](../../../lib/rules/selector-pseudo-class-allowed-list/README.md): Specify a list of allowed pseudo-class selectors.
- [`selector-pseudo-class-disallowed-list`](../../../lib/rules/selector-pseudo-class-disallowed-list/README.md): Specify a list of disallowed pseudo-class selectors.
- [`selector-pseudo-element-allowed-list`](../../../lib/rules/selector-pseudo-element-allowed-list/README.md): Specify a list of allowed pseudo-element selectors.
Expand Down
1 change: 1 addition & 0 deletions lib/rules/index.js
Expand Up @@ -214,6 +214,7 @@ const rules = {
'selector-nested-pattern': importLazy('./selector-nested-pattern'),
'selector-no-qualifying-type': importLazy('./selector-no-qualifying-type'),
'selector-no-vendor-prefix': importLazy('./selector-no-vendor-prefix'),
'selector-not-notation': importLazy('./selector-not-notation'),
'selector-pseudo-class-allowed-list': importLazy('./selector-pseudo-class-allowed-list'),
'selector-pseudo-class-case': importLazy('./selector-pseudo-class-case'),
'selector-pseudo-class-disallowed-list': importLazy('./selector-pseudo-class-disallowed-list'),
Expand Down
75 changes: 75 additions & 0 deletions lib/rules/selector-not-notation/README.md
@@ -0,0 +1,75 @@
# selector-not-notation

Specify simple or complex notation for `:not()` pseudo-classes.

<!-- prettier-ignore -->
```css
a:not(.foo, .bar) {}
/** ↑
* This notation */
```

In Selectors Level 3, only a single _simple selector_ was allowed as the argument to `:not()`, whereas Selectors Level 4 allows a _selector list_.

Use:

- `"complex"` to author modern Selectors Level 4 CSS
- `"simple"` for backwards compatibility with older browsers

The [`fix` option](../../../docs/user-guide/usage/options.md#fix) option can automatically fix most of the problems reported by this rule.

## Options

`string`: `"simple"|"complex"`

### `"simple"`

The following patterns are considered problems:

<!-- prettier-ignore -->
```css
:not(a, div) {}
```

<!-- prettier-ignore -->
```css
:not(a.foo) {}
```

The following patterns are _not_ considered problems:

<!-- prettier-ignore -->
```css
:not(a):not(div) {}
```

<!-- prettier-ignore -->
```css
:not(a) {}
```

### `"complex"`

The following pattern is considered a problem:

<!-- prettier-ignore -->
```css
:not(a):not(div) {}
```

The following patterns are _not_ considered problems:

<!-- prettier-ignore -->
```css
:not(a, div) {}
```

<!-- prettier-ignore -->
```css
:not(a.foo) {}
```

<!-- prettier-ignore -->
```css
:not(a).foo:not(:empty) {}
```
117 changes: 117 additions & 0 deletions lib/rules/selector-not-notation/__tests__/index.js
@@ -0,0 +1,117 @@
'use strict';

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

testRule({
ruleName,
config: ['simple'],
fix: true,

accept: [
{
code: ':not() {}',
},
{
code: ':not( a ) {}',
},
{
code: ':nOt(a) {}',
},
{
code: ':not(*) {}',
},
{
code: ':not(:link) {}',
},
{
code: ':not(.foo) {}',
},
{
code: ':not([title]) {}',
},
],

reject: [
{
code: ':not(:not()) {}',
unfixable: true,
message: messages.expected('simple'),
line: 1,
column: 1,
},
{
code: ':not(::before) {}',
unfixable: true,
message: messages.expected('simple'),
line: 1,
column: 1,
},
{
code: ':not(:first-line) {}',
unfixable: true,
message: messages.expected('simple'),
line: 1,
column: 1,
},
{
code: ':not(a, div) {}',
fixed: ':not(a):not(div) {}',
message: messages.expected('simple'),
line: 1,
column: 1,
},
{
code: ':not(a ,) {}',
fixed: ':not(a) {}',
message: messages.expected('simple'),
line: 1,
column: 1,
},
{
code: ':not(a.foo) {}',
unfixable: true,
message: messages.expected('simple'),
line: 1,
column: 1,
},
],
});

testRule({
ruleName,
config: ['complex'],
fix: true,

accept: [
{
code: ':not()::after {}',
},
{
code: ':not(a, div) {}',
},
{
code: ':not(a.foo) {}',
},
{
code: ':not(a).foo:not(:empty) {}',
},
],

reject: [
{
code: ':not( .foo ,:hover ):not(a,div) {}',
fixed: ':not(.foo, :hover, a, div) {}',
message: messages.expected('complex'),
line: 1,
column: 21,
},
{
code: ':not():not(a) {}',
fixed: ':not(a) {}',
message: messages.expected('complex'),
line: 1,
column: 7,
skip: true,
},
],
});

0 comments on commit 6e1ebd3

Please sign in to comment.