diff --git a/docs/user-guide/rules.md b/docs/user-guide/rules.md index aa3dbe6e9e..c69bf5826e 100644 --- a/docs/user-guide/rules.md +++ b/docs/user-guide/rules.md @@ -295,7 +295,7 @@ Here are all the rules within stylelint, grouped first [by category](../../VISIO - [`selector-attribute-brackets-space-inside`](../../lib/rules/selector-attribute-brackets-space-inside/README.md): Require a single space or disallow whitespace on the inside of the brackets within attribute selectors. - [`selector-attribute-operator-space-after`](../../lib/rules/selector-attribute-operator-space-after/README.md): Require a single space or disallow whitespace after operators within attribute selectors. -- [`selector-attribute-operator-space-before`](../../lib/rules/selector-attribute-operator-space-before/README.md): Require a single space or disallow whitespace before operators within attribute selectors. +- [`selector-attribute-operator-space-before`](../../lib/rules/selector-attribute-operator-space-before/README.md): Require a single space or disallow whitespace before operators within attribute selectors (Autofixable). - [`selector-attribute-quotes`](../../lib/rules/selector-attribute-quotes/README.md): Require or disallow quotes for attribute values. - [`selector-combinator-space-after`](../../lib/rules/selector-combinator-space-after/README.md): Require a single space or disallow whitespace after the combinators of selectors (Autofixable). - [`selector-combinator-space-before`](../../lib/rules/selector-combinator-space-before/README.md): Require a single space or disallow whitespace before the combinators of selectors (Autofixable). diff --git a/lib/rules/selector-attribute-operator-space-before/README.md b/lib/rules/selector-attribute-operator-space-before/README.md index 2139046b49..5454f1914c 100644 --- a/lib/rules/selector-attribute-operator-space-before/README.md +++ b/lib/rules/selector-attribute-operator-space-before/README.md @@ -8,6 +8,8 @@ Require a single space or disallow whitespace before operators within attribute * The space before operator */ ``` +The `--fix` option on the [command line](../../../docs/user-guide/cli.md#autofixing-errors) can automatically fix all of the problems reported by this rule. + ## Options `string`: `"always"|"never"` diff --git a/lib/rules/selector-attribute-operator-space-before/__tests__/index.js b/lib/rules/selector-attribute-operator-space-before/__tests__/index.js index df24d6167f..d42d709d97 100644 --- a/lib/rules/selector-attribute-operator-space-before/__tests__/index.js +++ b/lib/rules/selector-attribute-operator-space-before/__tests__/index.js @@ -6,6 +6,7 @@ const { messages, ruleName } = rule; testRule(rule, { ruleName, config: ["always"], + fix: true, accept: [ { @@ -275,459 +276,556 @@ testRule(rule, { reject: [ { code: "[target=_blank] { }", + fixed: "[target =_blank] { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target= _blank] { }", + fixed: "[target = _blank] { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target=_blank ] { }", + fixed: "[target =_blank ] { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target= _blank ] { }", + fixed: "[target = _blank ] { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[ target=_blank] { }", + fixed: "[ target =_blank] { }", message: messages.expectedBefore("="), line: 1, column: 9 }, { code: "[ target= _blank] { }", + fixed: "[ target = _blank] { }", message: messages.expectedBefore("="), line: 1, column: 9 }, { code: "[ target=_blank ] { }", + fixed: "[ target =_blank ] { }", message: messages.expectedBefore("="), line: 1, column: 9 }, { code: "[ target= _blank ] { }", + fixed: "[ target = _blank ] { }", message: messages.expectedBefore("="), line: 1, column: 9 }, { code: "[target='_blank'] { }", + fixed: "[target ='_blank'] { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target= '_blank'] { }", + fixed: "[target = '_blank'] { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target=' _blank'] { }", + fixed: "[target =' _blank'] { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target='_blank' ] { }", + fixed: "[target ='_blank' ] { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target='_blank '] { }", + fixed: "[target ='_blank '] { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target= '_blank' ] { }", + fixed: "[target = '_blank' ] { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target=' _blank '] { }", + fixed: "[target =' _blank '] { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[ target='_blank'] { }", + fixed: "[ target ='_blank'] { }", message: messages.expectedBefore("="), line: 1, column: 9 }, { code: "[ target= '_blank'] { }", + fixed: "[ target = '_blank'] { }", message: messages.expectedBefore("="), line: 1, column: 9 }, { code: "[ target=' _blank'] { }", + fixed: "[ target =' _blank'] { }", message: messages.expectedBefore("="), line: 1, column: 9 }, { code: "[ target='_blank' ] { }", + fixed: "[ target ='_blank' ] { }", message: messages.expectedBefore("="), line: 1, column: 9 }, { code: "[ target='_blank '] { }", + fixed: "[ target ='_blank '] { }", message: messages.expectedBefore("="), line: 1, column: 9 }, { code: "[ target= '_blank' ] { }", + fixed: "[ target = '_blank' ] { }", message: messages.expectedBefore("="), line: 1, column: 9 }, { code: "[ target=' _blank '] { }", + fixed: "[ target =' _blank '] { }", message: messages.expectedBefore("="), line: 1, column: 9 }, { code: '[target="_blank"] { }', + fixed: '[target ="_blank"] { }', message: messages.expectedBefore("="), line: 1, column: 8 }, { code: '[target= "_blank"] { }', + fixed: '[target = "_blank"] { }', message: messages.expectedBefore("="), line: 1, column: 8 }, { code: '[target=" _blank"] { }', + fixed: '[target =" _blank"] { }', message: messages.expectedBefore("="), line: 1, column: 8 }, { code: '[target="_blank" ] { }', + fixed: '[target ="_blank" ] { }', message: messages.expectedBefore("="), line: 1, column: 8 }, { code: '[target="_blank "] { }', + fixed: '[target ="_blank "] { }', message: messages.expectedBefore("="), line: 1, column: 8 }, { code: '[target= "_blank" ] { }', + fixed: '[target = "_blank" ] { }', message: messages.expectedBefore("="), line: 1, column: 8 }, { code: '[target=" _blank "] { }', + fixed: '[target =" _blank "] { }', message: messages.expectedBefore("="), line: 1, column: 8 }, { code: '[ target="_blank"] { }', + fixed: '[ target ="_blank"] { }', message: messages.expectedBefore("="), line: 1, column: 9 }, { code: '[ target= "_blank"] { }', + fixed: '[ target = "_blank"] { }', message: messages.expectedBefore("="), line: 1, column: 9 }, { code: '[ target=" _blank"] { }', + fixed: '[ target =" _blank"] { }', message: messages.expectedBefore("="), line: 1, column: 9 }, { code: '[ target="_blank" ] { }', + fixed: '[ target ="_blank" ] { }', message: messages.expectedBefore("="), line: 1, column: 9 }, { code: '[ target="_blank "] { }', + fixed: '[ target ="_blank "] { }', message: messages.expectedBefore("="), line: 1, column: 9 }, { code: '[ target= "_blank" ] { }', + fixed: '[ target = "_blank" ] { }', message: messages.expectedBefore("="), line: 1, column: 9 }, { code: '[ target=" _blank "] { }', + fixed: '[ target =" _blank "] { }', message: messages.expectedBefore("="), line: 1, column: 9 }, { code: "[title~=flower] { }", + fixed: "[title ~=flower] { }", message: messages.expectedBefore("~="), line: 1, column: 7 }, { code: "[title~= flower] { }", + fixed: "[title ~= flower] { }", message: messages.expectedBefore("~="), line: 1, column: 7 }, { code: "[title|=flower] { }", + fixed: "[title |=flower] { }", message: messages.expectedBefore("|="), line: 1, column: 7 }, { code: "[title|= flower] { }", + fixed: "[title |= flower] { }", message: messages.expectedBefore("|="), line: 1, column: 7 }, { code: "[title^=flower] { }", + fixed: "[title ^=flower] { }", message: messages.expectedBefore("^="), line: 1, column: 7 }, { code: "[title^= flower] { }", + fixed: "[title ^= flower] { }", message: messages.expectedBefore("^="), line: 1, column: 7 }, { code: "[title$=flower] { }", + fixed: "[title $=flower] { }", message: messages.expectedBefore("$="), line: 1, column: 7 }, { code: "[title$= flower] { }", + fixed: "[title $= flower] { }", message: messages.expectedBefore("$="), line: 1, column: 7 }, { code: "a[href*=w3schools] { }", + fixed: "a[href *=w3schools] { }", message: messages.expectedBefore("*="), line: 1, column: 7 }, { code: "a[href*= w3schools] { }", + fixed: "a[href *= w3schools] { }", message: messages.expectedBefore("*="), line: 1, column: 7 }, { code: "img[alt~=person][src *=lorem] { }", + fixed: "img[alt ~=person][src *=lorem] { }", message: messages.expectedBefore("~="), line: 1, column: 8 }, { code: "img[alt~= person][src *=lorem] { }", + fixed: "img[alt ~= person][src *=lorem] { }", message: messages.expectedBefore("~="), line: 1, column: 8 }, { code: "img[alt ~=person][src*= lorem] { }", + fixed: "img[alt ~=person][src *= lorem] { }", message: messages.expectedBefore("*="), line: 1, column: 22 }, { code: "img[alt ~= person][src*= lorem] { }", + fixed: "img[alt ~= person][src *= lorem] { }", message: messages.expectedBefore("*="), line: 1, column: 23 }, { code: "[target=_blank]:hover { }", + fixed: "[target =_blank]:hover { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target= _blank]:hover { }", + fixed: "[target = _blank]:hover { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target=_blank]::before { }", + fixed: "[target =_blank]::before { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target= _blank]::before { }", + fixed: "[target = _blank]::before { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "option[data-hidden=true] { }", + fixed: "option[data-hidden =true] { }", message: messages.expectedBefore("="), line: 1, column: 19 }, { code: "option[data-hidden= true] { }", + fixed: "option[data-hidden = true] { }", message: messages.expectedBefore("="), line: 1, column: 19 }, { code: "@media screen and (max-width: 480px) { img[align=right] {} }", + fixed: "@media screen and (max-width: 480px) { img[align =right] {} }", message: messages.expectedBefore("="), line: 1, column: 49 }, { code: "@media screen and (max-width: 480px) { img[align= right] {} }", + fixed: "@media screen and (max-width: 480px) { img[align = right] {} }", message: messages.expectedBefore("="), line: 1, column: 49 }, { code: "[target=_blank] .foo { }", + fixed: "[target =_blank] .foo { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "[target= _blank] .foo { }", + fixed: "[target = _blank] .foo { }", message: messages.expectedBefore("="), line: 1, column: 8 }, { code: "li[aria-hidden=false]:nth-child(1) { }", + fixed: "li[aria-hidden =false]:nth-child(1) { }", message: messages.expectedBefore("="), line: 1, column: 15 }, { code: "li[aria-hidden=false]:nth-child( 1) { }", + fixed: "li[aria-hidden =false]:nth-child( 1) { }", message: messages.expectedBefore("="), line: 1, column: 15 }, { code: "li[aria-hidden=false]:nth-child(1 ) { }", + fixed: "li[aria-hidden =false]:nth-child(1 ) { }", message: messages.expectedBefore("="), line: 1, column: 15 }, { code: "li[aria-hidden=false]:nth-child( 1 ) { }", + fixed: "li[aria-hidden =false]:nth-child( 1 ) { }", message: messages.expectedBefore("="), line: 1, column: 15 }, { code: "li[aria-hidden= false]:nth-child(1) { }", + fixed: "li[aria-hidden = false]:nth-child(1) { }", message: messages.expectedBefore("="), line: 1, column: 15 }, { code: "li[aria-hidden= false]:nth-child( 1) { }", + fixed: "li[aria-hidden = false]:nth-child( 1) { }", message: messages.expectedBefore("="), line: 1, column: 15 }, { code: "li[aria-hidden= false]:nth-child(1 ) { }", + fixed: "li[aria-hidden = false]:nth-child(1 ) { }", message: messages.expectedBefore("="), line: 1, column: 15 }, { code: "li[aria-hidden= false]:nth-child( 1 ) { }", + fixed: "li[aria-hidden = false]:nth-child( 1 ) { }", message: messages.expectedBefore("="), line: 1, column: 15 }, { code: "ul li[aria-hidden=false] + li[aria-hidden =false] a { }", + fixed: "ul li[aria-hidden =false] + li[aria-hidden =false] a { }", message: messages.expectedBefore("="), line: 1, column: 18 }, { code: "ul li[aria-hidden =false] + li[aria-hidden=false] a { }", + fixed: "ul li[aria-hidden =false] + li[aria-hidden =false] a { }", message: messages.expectedBefore("="), line: 1, column: 43 }, { code: "ul li[aria-hidden= false] + li[aria-hidden =false] a { }", + fixed: "ul li[aria-hidden = false] + li[aria-hidden =false] a { }", message: messages.expectedBefore("="), line: 1, column: 18 }, { code: "ul li[aria-hidden = false] + li[aria-hidden=false] a { }", + fixed: "ul li[aria-hidden = false] + li[aria-hidden =false] a { }", message: messages.expectedBefore("="), line: 1, column: 44 }, { code: "ul li[aria-hidden=false] + li[aria-hidden = false] a { }", + fixed: "ul li[aria-hidden =false] + li[aria-hidden = false] a { }", message: messages.expectedBefore("="), line: 1, column: 18 }, { code: "ul li[aria-hidden =false] + li[aria-hidden= false] a { }", + fixed: "ul li[aria-hidden =false] + li[aria-hidden = false] a { }", message: messages.expectedBefore("="), line: 1, column: 43 }, { code: "ul li[aria-hidden= false] + li[aria-hidden = false] a { }", + fixed: "ul li[aria-hidden = false] + li[aria-hidden = false] a { }", message: messages.expectedBefore("="), line: 1, column: 18 }, { code: "ul li[aria-hidden = false] + li[aria-hidden= false] a { }", + fixed: "ul li[aria-hidden = false] + li[aria-hidden = false] a { }", message: messages.expectedBefore("="), line: 1, column: 44 + }, + { + code: "ul li[aria-hidden= false] + li[aria-hidden= false] a { }", + fixed: "ul li[aria-hidden = false] + li[aria-hidden = false] a { }", + message: messages.expectedBefore("="), + line: 1, + column: 18 + }, + { + code: '[target/**/="_blank"] { }', + fixed: '[target/**/ ="_blank"] { }', + message: messages.expectedBefore("="), + line: 1, + column: 12 + }, + { + code: '[target /**/="_blank"] { }', + fixed: '[target /**/ ="_blank"] { }', + message: messages.expectedBefore("="), + line: 1, + column: 13 } ] }); @@ -735,6 +833,7 @@ testRule(rule, { testRule(rule, { ruleName, config: ["never"], + fix: true, accept: [ { @@ -988,459 +1087,556 @@ testRule(rule, { reject: [ { code: "[target =_blank] { }", + fixed: "[target=_blank] { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target = _blank] { }", + fixed: "[target= _blank] { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target =_blank ] { }", + fixed: "[target=_blank ] { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target = _blank ] { }", + fixed: "[target= _blank ] { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[ target =_blank] { }", + fixed: "[ target=_blank] { }", message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: "[ target = _blank] { }", + fixed: "[ target= _blank] { }", message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: "[ target =_blank ] { }", + fixed: "[ target=_blank ] { }", message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: "[ target = _blank ] { }", + fixed: "[ target= _blank ] { }", message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: "[target ='_blank'] { }", + fixed: "[target='_blank'] { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target = '_blank'] { }", + fixed: "[target= '_blank'] { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target =' _blank'] { }", + fixed: "[target=' _blank'] { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target ='_blank' ] { }", + fixed: "[target='_blank' ] { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target ='_blank '] { }", + fixed: "[target='_blank '] { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target = '_blank' ] { }", + fixed: "[target= '_blank' ] { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target =' _blank '] { }", + fixed: "[target=' _blank '] { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[ target ='_blank'] { }", + fixed: "[ target='_blank'] { }", message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: "[ target = '_blank'] { }", + fixed: "[ target= '_blank'] { }", message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: "[ target =' _blank'] { }", + fixed: "[ target=' _blank'] { }", message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: "[ target ='_blank' ] { }", + fixed: "[ target='_blank' ] { }", message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: "[ target ='_blank '] { }", + fixed: "[ target='_blank '] { }", message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: "[ target = '_blank' ] { }", + fixed: "[ target= '_blank' ] { }", message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: "[ target =' _blank '] { }", + fixed: "[ target=' _blank '] { }", message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: '[target ="_blank"] { }', + fixed: '[target="_blank"] { }', message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: '[target = "_blank"] { }', + fixed: '[target= "_blank"] { }', message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: '[target =" _blank"] { }', + fixed: '[target=" _blank"] { }', message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: '[target ="_blank" ] { }', + fixed: '[target="_blank" ] { }', message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: '[target ="_blank "] { }', + fixed: '[target="_blank "] { }', message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: '[target = "_blank" ] { }', + fixed: '[target= "_blank" ] { }', message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: '[target =" _blank "] { }', + fixed: '[target=" _blank "] { }', message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: '[ target ="_blank"] { }', + fixed: '[ target="_blank"] { }', message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: '[ target = "_blank"] { }', + fixed: '[ target= "_blank"] { }', message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: '[ target =" _blank"] { }', + fixed: '[ target=" _blank"] { }', message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: '[ target ="_blank" ] { }', + fixed: '[ target="_blank" ] { }', message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: '[ target ="_blank "] { }', + fixed: '[ target="_blank "] { }', message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: '[ target = "_blank" ] { }', + fixed: '[ target= "_blank" ] { }', message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: '[ target =" _blank "] { }', + fixed: '[ target=" _blank "] { }', message: messages.rejectedBefore("="), line: 1, column: 10 }, { code: "[title ~=flower] { }", + fixed: "[title~=flower] { }", message: messages.rejectedBefore("~="), line: 1, column: 8 }, { code: "[title ~= flower] { }", + fixed: "[title~= flower] { }", message: messages.rejectedBefore("~="), line: 1, column: 8 }, { code: "[title |=flower] { }", + fixed: "[title|=flower] { }", message: messages.rejectedBefore("|="), line: 1, column: 8 }, { code: "[title |= flower] { }", + fixed: "[title|= flower] { }", message: messages.rejectedBefore("|="), line: 1, column: 8 }, { code: "[title ^=flower] { }", + fixed: "[title^=flower] { }", message: messages.rejectedBefore("^="), line: 1, column: 8 }, { code: "[title ^= flower] { }", + fixed: "[title^= flower] { }", message: messages.rejectedBefore("^="), line: 1, column: 8 }, { code: "[title $=flower] { }", + fixed: "[title$=flower] { }", message: messages.rejectedBefore("$="), line: 1, column: 8 }, { code: "[title $= flower] { }", + fixed: "[title$= flower] { }", message: messages.rejectedBefore("$="), line: 1, column: 8 }, { code: "a[href *=w3schools] { }", + fixed: "a[href*=w3schools] { }", message: messages.rejectedBefore("*="), line: 1, column: 8 }, { code: "a[href *= w3schools] { }", + fixed: "a[href*= w3schools] { }", message: messages.rejectedBefore("*="), line: 1, column: 8 }, { code: "img[alt ~=person][src*=lorem] { }", + fixed: "img[alt~=person][src*=lorem] { }", message: messages.rejectedBefore("~="), line: 1, column: 9 }, { code: "img[alt ~= person][src*=lorem] { }", + fixed: "img[alt~= person][src*=lorem] { }", message: messages.rejectedBefore("~="), line: 1, column: 9 }, { code: "img[alt~=person][src *= lorem] { }", + fixed: "img[alt~=person][src*= lorem] { }", message: messages.rejectedBefore("*="), line: 1, column: 22 }, { code: "img[alt~= person][src *= lorem] { }", + fixed: "img[alt~= person][src*= lorem] { }", message: messages.rejectedBefore("*="), line: 1, column: 23 }, { code: "[target =_blank]:hover { }", + fixed: "[target=_blank]:hover { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target = _blank]:hover { }", + fixed: "[target= _blank]:hover { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target =_blank]::before { }", + fixed: "[target=_blank]::before { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target = _blank]::before { }", + fixed: "[target= _blank]::before { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "option[data-hidden =true] { }", + fixed: "option[data-hidden=true] { }", message: messages.rejectedBefore("="), line: 1, column: 20 }, { code: "option[data-hidden = true] { }", + fixed: "option[data-hidden= true] { }", message: messages.rejectedBefore("="), line: 1, column: 20 }, { code: "@media screen and (max-width: 480px) { img[align =right] {} }", + fixed: "@media screen and (max-width: 480px) { img[align=right] {} }", message: messages.rejectedBefore("="), line: 1, column: 50 }, { code: "@media screen and (max-width: 480px) { img[align = right] {} }", + fixed: "@media screen and (max-width: 480px) { img[align= right] {} }", message: messages.rejectedBefore("="), line: 1, column: 50 }, { code: "[target =_blank] .foo { }", + fixed: "[target=_blank] .foo { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "[target = _blank] .foo { }", + fixed: "[target= _blank] .foo { }", message: messages.rejectedBefore("="), line: 1, column: 9 }, { code: "li[aria-hidden =false]:nth-child(1) { }", + fixed: "li[aria-hidden=false]:nth-child(1) { }", message: messages.rejectedBefore("="), line: 1, column: 16 }, { code: "li[aria-hidden =false]:nth-child( 1) { }", + fixed: "li[aria-hidden=false]:nth-child( 1) { }", message: messages.rejectedBefore("="), line: 1, column: 16 }, { code: "li[aria-hidden =false]:nth-child(1 ) { }", + fixed: "li[aria-hidden=false]:nth-child(1 ) { }", message: messages.rejectedBefore("="), line: 1, column: 16 }, { code: "li[aria-hidden =false]:nth-child( 1 ) { }", + fixed: "li[aria-hidden=false]:nth-child( 1 ) { }", message: messages.rejectedBefore("="), line: 1, column: 16 }, { code: "li[aria-hidden = false]:nth-child(1) { }", + fixed: "li[aria-hidden= false]:nth-child(1) { }", message: messages.rejectedBefore("="), line: 1, column: 16 }, { code: "li[aria-hidden = false]:nth-child( 1) { }", + fixed: "li[aria-hidden= false]:nth-child( 1) { }", message: messages.rejectedBefore("="), line: 1, column: 16 }, { code: "li[aria-hidden = false]:nth-child(1 ) { }", + fixed: "li[aria-hidden= false]:nth-child(1 ) { }", message: messages.rejectedBefore("="), line: 1, column: 16 }, { code: "li[aria-hidden = false]:nth-child( 1 ) { }", + fixed: "li[aria-hidden= false]:nth-child( 1 ) { }", message: messages.rejectedBefore("="), line: 1, column: 16 }, { code: "ul li[aria-hidden =false] + li[aria-hidden=false] a { }", + fixed: "ul li[aria-hidden=false] + li[aria-hidden=false] a { }", message: messages.rejectedBefore("="), line: 1, column: 19 }, { code: "ul li[aria-hidden=false] + li[aria-hidden =false] a { }", + fixed: "ul li[aria-hidden=false] + li[aria-hidden=false] a { }", message: messages.rejectedBefore("="), line: 1, column: 43 }, { code: "ul li[aria-hidden = false] + li[aria-hidden=false] a { }", + fixed: "ul li[aria-hidden= false] + li[aria-hidden=false] a { }", message: messages.rejectedBefore("="), line: 1, column: 19 }, { code: "ul li[aria-hidden= false] + li[aria-hidden =false] a { }", + fixed: "ul li[aria-hidden= false] + li[aria-hidden=false] a { }", message: messages.rejectedBefore("="), line: 1, column: 44 }, { code: "ul li[aria-hidden =false] + li[aria-hidden= false] a { }", + fixed: "ul li[aria-hidden=false] + li[aria-hidden= false] a { }", message: messages.rejectedBefore("="), line: 1, column: 19 }, { code: "ul li[aria-hidden=false] + li[aria-hidden = false] a { }", + fixed: "ul li[aria-hidden=false] + li[aria-hidden= false] a { }", message: messages.rejectedBefore("="), line: 1, column: 43 }, { code: "ul li[aria-hidden = false] + li[aria-hidden= false] a { }", + fixed: "ul li[aria-hidden= false] + li[aria-hidden= false] a { }", message: messages.rejectedBefore("="), line: 1, column: 19 }, { code: "ul li[aria-hidden= false] + li[aria-hidden = false] a { }", + fixed: "ul li[aria-hidden= false] + li[aria-hidden= false] a { }", message: messages.rejectedBefore("="), line: 1, column: 44 + }, + { + code: "ul li[aria-hidden = false] + li[aria-hidden = false] a { }", + fixed: "ul li[aria-hidden= false] + li[aria-hidden= false] a { }", + message: messages.rejectedBefore("="), + line: 1, + column: 19 + }, + { + code: '[target/**/ ="_blank"] { }', + fixed: '[target/**/="_blank"] { }', + message: messages.rejectedBefore("="), + line: 1, + column: 13 + }, + { + code: '[target /**/ ="_blank"] { }', + fixed: '[target /**/="_blank"] { }', + message: messages.rejectedBefore("="), + line: 1, + column: 14 } ] }); diff --git a/lib/rules/selector-attribute-operator-space-before/index.js b/lib/rules/selector-attribute-operator-space-before/index.js index 7273c2663f..7f86c64d24 100644 --- a/lib/rules/selector-attribute-operator-space-before/index.js +++ b/lib/rules/selector-attribute-operator-space-before/index.js @@ -1,5 +1,6 @@ "use strict"; +const _ = require("lodash"); const ruleMessages = require("../../utils/ruleMessages"); const selectorAttributeOperatorSpaceChecker = require("../selectorAttributeOperatorSpaceChecker"); const validateOptions = require("../../utils/validateOptions"); @@ -12,7 +13,7 @@ const messages = ruleMessages(ruleName, { rejectedBefore: operator => `Unexpected whitespace before "${operator}"` }); -const rule = function(expectation) { +const rule = function(expectation, options, context) { const checker = whitespaceChecker("space", expectation, messages); return (root, result) => { const validOptions = validateOptions(result, ruleName, { @@ -28,7 +29,36 @@ const rule = function(expectation) { result, locationChecker: checker.before, checkedRuleName: ruleName, - checkBeforeOperator: true + checkBeforeOperator: true, + fix: context.fix + ? attributeNode => { + const rawAttrAfter = _.get( + attributeNode, + "raws.spaces.attribute.after" + ); + const { attrAfter, setAttrAfter } = rawAttrAfter + ? { + attrAfter: rawAttrAfter, + setAttrAfter(fixed) { + attributeNode.raws.spaces.attribute.after = fixed; + } + } + : { + attrAfter: _.get(attributeNode, "spaces.attribute.after", ""), + setAttrAfter(fixed) { + _.set(attributeNode, "spaces.attribute.after", fixed); + } + }; + + if (expectation === "always") { + setAttrAfter(attrAfter.replace(/\s*$/, " ")); + return true; + } else if (expectation === "never") { + setAttrAfter(attrAfter.replace(/\s*$/, "")); + return true; + } + } + : null }); }; }; diff --git a/lib/rules/selectorAttributeOperatorSpaceChecker.js b/lib/rules/selectorAttributeOperatorSpaceChecker.js index a72607552f..e1db7e2d08 100644 --- a/lib/rules/selectorAttributeOperatorSpaceChecker.js +++ b/lib/rules/selectorAttributeOperatorSpaceChecker.js @@ -16,40 +16,61 @@ module.exports = function(options) { ) { return; } + let hasFixed = false; + const selector = rule.raws.selector + ? rule.raws.selector.raw + : rule.selector; - parseSelector(rule.selector, options.result, rule, selectorTree => { - selectorTree.walkAttributes(attributeNode => { - const operator = attributeNode.operator; + const fixedSelector = parseSelector( + selector, + options.result, + rule, + selectorTree => { + selectorTree.walkAttributes(attributeNode => { + const operator = attributeNode.operator; - if (!operator) { - return; - } + if (!operator) { + return; + } - const attributeNodeString = attributeNode.toString(); + const attributeNodeString = attributeNode.toString(); - styleSearch( - { source: attributeNodeString, target: operator }, - match => { - const index = options.checkBeforeOperator - ? match.startIndex - : match.endIndex - 1; - checkOperator( - attributeNodeString, - index, - rule, - attributeNode.sourceIndex, - operator - ); - } - ); - }); - }); + styleSearch( + { source: attributeNodeString, target: operator }, + match => { + const index = options.checkBeforeOperator + ? match.startIndex + : match.endIndex - 1; + checkOperator( + attributeNodeString, + index, + rule, + attributeNode, + operator + ); + } + ); + }); + } + ); - function checkOperator(source, index, node, attributeIndex, operator) { + if (hasFixed) { + if (!rule.raws.selector) { + rule.selector = fixedSelector; + } else { + rule.raws.selector.raw = fixedSelector; + } + } + + function checkOperator(source, index, node, attributeNode, operator) { options.locationChecker({ source, index, - err: m => + err: m => { + if (options.fix && options.fix(attributeNode)) { + hasFixed = true; + return; + } report({ message: m.replace( options.checkBeforeOperator @@ -58,10 +79,11 @@ module.exports = function(options) { operator ), node, - index: attributeIndex + index, + index: attributeNode.sourceIndex + index, result: options.result, ruleName: options.checkedRuleName - }) + }); + } }); } });