From 53f5c1848863c7c49b2d689b72dad5ee17e3abbb Mon Sep 17 00:00:00 2001 From: Yevgeny Petukhov Date: Sun, 9 Aug 2020 19:41:00 +0300 Subject: [PATCH] Add autofix to *-no-vendor rules (#4859) --- docs/user-guide/rules/list.md | 10 +++++----- lib/rules/at-rule-no-vendor-prefix/README.md | 2 ++ .../at-rule-no-vendor-prefix/__tests__/index.js | 6 ++++++ lib/rules/at-rule-no-vendor-prefix/index.js | 8 +++++++- .../README.md | 2 ++ .../__tests__/index.js | 13 ++++++++++++- .../media-feature-name-no-vendor-prefix/index.js | 10 ++++++++-- lib/rules/property-no-vendor-prefix/README.md | 2 ++ .../property-no-vendor-prefix/__tests__/index.js | 16 ++++++++++++++++ lib/rules/property-no-vendor-prefix/index.js | 8 +++++++- lib/rules/selector-no-vendor-prefix/README.md | 2 ++ .../selector-no-vendor-prefix/__tests__/index.js | 10 ++++++++++ lib/rules/selector-no-vendor-prefix/index.js | 8 +++++++- lib/rules/value-no-vendor-prefix/README.md | 2 ++ .../value-no-vendor-prefix/__tests__/index.js | 16 ++++++++++++++++ lib/rules/value-no-vendor-prefix/index.js | 8 +++++++- lib/utils/isAutoprefixable.js | 9 +++++++++ 17 files changed, 120 insertions(+), 12 deletions(-) diff --git a/docs/user-guide/rules/list.md b/docs/user-guide/rules/list.md index 2fb3483afa..6cd7c29dd7 100644 --- a/docs/user-guide/rules/list.md +++ b/docs/user-guide/rules/list.md @@ -130,7 +130,7 @@ Grouped first by the following categories and then by the [_thing_](http://apps. ### Value -- [`value-no-vendor-prefix`](../../../lib/rules/value-no-vendor-prefix/README.md): Disallow vendor prefixes for values. +- [`value-no-vendor-prefix`](../../../lib/rules/value-no-vendor-prefix/README.md): Disallow vendor prefixes for values (Autofixable). ### Custom property @@ -140,7 +140,7 @@ Grouped first by the following categories and then by the [_thing_](http://apps. - [`property-allowed-list`](../../../lib/rules/property-allowed-list/README.md): Specify a list of allowed properties. - [`property-disallowed-list`](../../../lib/rules/property-disallowed-list/README.md): Specify a list of disallowed properties. -- [`property-no-vendor-prefix`](../../../lib/rules/property-no-vendor-prefix/README.md): Disallow vendor prefixes for properties. +- [`property-no-vendor-prefix`](../../../lib/rules/property-no-vendor-prefix/README.md): Disallow vendor prefixes for properties (Autofixable). ### Declaration @@ -175,7 +175,7 @@ Grouped first by the following categories and then by the [_thing_](http://apps. - [`selector-max-universal`](../../../lib/rules/selector-max-universal/README.md): Limit the number of universal selectors in a selector. - [`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. +- [`selector-no-vendor-prefix`](../../../lib/rules/selector-no-vendor-prefix/README.md): Disallow vendor prefixes for selectors (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. @@ -186,7 +186,7 @@ Grouped first by the following categories and then by the [_thing_](http://apps. - [`media-feature-name-allowed-list`](../../../lib/rules/media-feature-name-allowed-list/README.md): Specify a list of allowed media feature names. - [`media-feature-name-disallowed-list`](../../../lib/rules/media-feature-name-disallowed-list/README.md): Specify a list of disallowed media feature names. -- [`media-feature-name-no-vendor-prefix`](../../../lib/rules/media-feature-name-no-vendor-prefix/README.md): Disallow vendor prefixes for media feature names. +- [`media-feature-name-no-vendor-prefix`](../../../lib/rules/media-feature-name-no-vendor-prefix/README.md): Disallow vendor prefixes for media feature names (Autofixable). - [`media-feature-name-value-allowed-list`](../../../lib/rules/media-feature-name-value-allowed-list/README.md): Specify a list of allowed media feature name and value pairs. ### Custom media @@ -197,7 +197,7 @@ Grouped first by the following categories and then by the [_thing_](http://apps. - [`at-rule-allowed-list`](../../../lib/rules/at-rule-allowed-list/README.md): Specify a list of allowed at-rules. - [`at-rule-disallowed-list`](../../../lib/rules/at-rule-disallowed-list/README.md): Specify a list of disallowed at-rules. -- [`at-rule-no-vendor-prefix`](../../../lib/rules/at-rule-no-vendor-prefix/README.md): Disallow vendor prefixes for at-rules. +- [`at-rule-no-vendor-prefix`](../../../lib/rules/at-rule-no-vendor-prefix/README.md): Disallow vendor prefixes for at-rules (Autofixable). - [`at-rule-property-required-list`](../../../lib/rules/at-rule-property-required-list/README.md): Specify a list of required properties for an at-rule. ### Comment diff --git a/lib/rules/at-rule-no-vendor-prefix/README.md b/lib/rules/at-rule-no-vendor-prefix/README.md index a84d210638..b39d3de552 100644 --- a/lib/rules/at-rule-no-vendor-prefix/README.md +++ b/lib/rules/at-rule-no-vendor-prefix/README.md @@ -9,6 +9,8 @@ Disallow vendor prefixes for at-rules. * This prefix */ ``` +The [`fix` option](../../../docs/user-guide/usage/options.md#fix) can automatically fix all of the problems reported by this rule. + ## Options ### `true` diff --git a/lib/rules/at-rule-no-vendor-prefix/__tests__/index.js b/lib/rules/at-rule-no-vendor-prefix/__tests__/index.js index 37622f06af..006f727fda 100644 --- a/lib/rules/at-rule-no-vendor-prefix/__tests__/index.js +++ b/lib/rules/at-rule-no-vendor-prefix/__tests__/index.js @@ -5,6 +5,7 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, config: [true], + fix: true, accept: [ { @@ -18,22 +19,27 @@ testRule({ reject: [ { code: '@-webkit-keyframes { 0% { top: 0; } }', + fixed: '@keyframes { 0% { top: 0; } }', message: messages.rejected('-webkit-keyframes'), }, { code: '@-wEbKiT-kEyFrAmEs { 0% { top: 0; } }', + fixed: '@kEyFrAmEs { 0% { top: 0; } }', message: messages.rejected('-wEbKiT-kEyFrAmEs'), }, { code: '@-WEBKIT-KEYFRAMES { 0% { top: 0; } }', + fixed: '@KEYFRAMES { 0% { top: 0; } }', message: messages.rejected('-WEBKIT-KEYFRAMES'), }, { code: '@-moz-keyframes { 0% { top: 0; } }', + fixed: '@keyframes { 0% { top: 0; } }', message: messages.rejected('-moz-keyframes'), }, { code: '@-ms-viewport { orientation: landscape; }', + fixed: '@viewport { orientation: landscape; }', message: messages.rejected('-ms-viewport'), }, ], diff --git a/lib/rules/at-rule-no-vendor-prefix/index.js b/lib/rules/at-rule-no-vendor-prefix/index.js index 810b94c356..c3036f1974 100644 --- a/lib/rules/at-rule-no-vendor-prefix/index.js +++ b/lib/rules/at-rule-no-vendor-prefix/index.js @@ -14,7 +14,7 @@ const messages = ruleMessages(ruleName, { rejected: (p) => `Unexpected vendor-prefixed at-rule "@${p}"`, }); -function rule(actual) { +function rule(actual, options, context) { return function (root, result) { const validOptions = validateOptions(result, ruleName, { actual }); @@ -37,6 +37,12 @@ function rule(actual) { return; } + if (context.fix) { + atRule.name = isAutoprefixable.unprefix(atRule.name); + + return; + } + report({ message: messages.rejected(name), node: atRule, diff --git a/lib/rules/media-feature-name-no-vendor-prefix/README.md b/lib/rules/media-feature-name-no-vendor-prefix/README.md index 53ec93df7b..91c113cf5f 100644 --- a/lib/rules/media-feature-name-no-vendor-prefix/README.md +++ b/lib/rules/media-feature-name-no-vendor-prefix/README.md @@ -11,6 +11,8 @@ Disallow vendor prefixes for media feature names. Right now this rule simply checks for prefixed _resolutions_. +The [`fix` option](../../../docs/user-guide/usage/options.md#fix) can automatically fix all of the problems reported by this rule. + ## Options ### `true` diff --git a/lib/rules/media-feature-name-no-vendor-prefix/__tests__/index.js b/lib/rules/media-feature-name-no-vendor-prefix/__tests__/index.js index aaad9dff7f..89a70ff5c9 100644 --- a/lib/rules/media-feature-name-no-vendor-prefix/__tests__/index.js +++ b/lib/rules/media-feature-name-no-vendor-prefix/__tests__/index.js @@ -5,6 +5,7 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, config: [true], + fix: true, accept: [ { @@ -13,47 +14,57 @@ testRule({ { code: '@media (device-pixel-ratio: 2) {}', }, + { + code: '@media (min-device-pixel-ratio: 2) {}', + }, ], reject: [ { code: '@media (-webkit-min-device-pixel-ratio: 1) {}', + fixed: '@media (min-device-pixel-ratio: 1) {}', message: messages.rejected, line: 1, column: 9, }, { code: '@media (-wEbKiT-mIn-DeViCe-PiXeL-rAtIo: 1) {}', + fixed: '@media (mIn-DeViCe-PiXeL-rAtIo: 1) {}', message: messages.rejected, line: 1, column: 9, }, { code: '@media (-WEBKIT-MIN-DEVICE-PIXEL-RATIO: 1) {}', + fixed: '@media (MIN-DEVICE-PIXEL-RATIO: 1) {}', message: messages.rejected, line: 1, column: 9, }, { code: '@media\n\t(min--moz-device-pixel-ratio: 1) {}', + fixed: '@media\n\t(min-device-pixel-ratio: 1) {}', message: messages.rejected, line: 2, - column: 3, + column: 6, }, { code: '@media (-o-max-device-pixel-ratio: 1/1) {}', + fixed: '@media (max-device-pixel-ratio: 1/1) {}', message: messages.rejected, line: 1, column: 11, }, { code: '@media (-o-max-device-pixel-ratio > 1) {}', + fixed: '@media (max-device-pixel-ratio > 1) {}', message: messages.rejected, line: 1, column: 9, }, { code: '@media (1 < -o-max-device-pixel-ratio < 2) {}', + fixed: '@media (1 < max-device-pixel-ratio < 2) {}', message: messages.rejected, line: 1, column: 13, diff --git a/lib/rules/media-feature-name-no-vendor-prefix/index.js b/lib/rules/media-feature-name-no-vendor-prefix/index.js index 5c777335d4..bfdbd2b6d4 100644 --- a/lib/rules/media-feature-name-no-vendor-prefix/index.js +++ b/lib/rules/media-feature-name-no-vendor-prefix/index.js @@ -13,7 +13,7 @@ const messages = ruleMessages(ruleName, { rejected: 'Unexpected vendor-prefix', }); -function rule(actual) { +function rule(actual, options, context) { return (root, result) => { const validOptions = validateOptions(result, ruleName, { actual }); @@ -28,12 +28,18 @@ function rule(actual) { return; } - const matches = atRule.toString().match(/[a-z-]+device-pixel-ratio/gi); + const matches = atRule.toString().match(/-[a-z-]+device-pixel-ratio/gi); if (!matches) { return; } + if (context.fix) { + atRule.params = isAutoprefixable.unprefix(atRule.params); + + return; + } + matches.forEach((match) => { report({ message: messages.rejected, diff --git a/lib/rules/property-no-vendor-prefix/README.md b/lib/rules/property-no-vendor-prefix/README.md index 89f237302b..7833e0f16f 100644 --- a/lib/rules/property-no-vendor-prefix/README.md +++ b/lib/rules/property-no-vendor-prefix/README.md @@ -11,6 +11,8 @@ a { -webkit-transform: scale(1); } This rule does not blanketly condemn vendor prefixes. Instead, it uses [Autoprefixer's](https://github.com/postcss/autoprefixer) up-to-date data (from [caniuse.com](http://caniuse.com/)) to know whether a vendor prefix should cause a violation or not. _If you've included a vendor prefixed property that has a standard alternative, one that Autoprefixer could take care of for you, this rule will complain about it_. If, however, you use a non-standard vendor-prefixed property, one that Autoprefixer would ignore and could not provide (such as `-webkit-touch-callout`), this rule will ignore it. +The [`fix` option](../../../docs/user-guide/usage/options.md#fix) can automatically fix all of the problems reported by this rule. + ## Options ### `true` diff --git a/lib/rules/property-no-vendor-prefix/__tests__/index.js b/lib/rules/property-no-vendor-prefix/__tests__/index.js index d81b624e8a..424c03e553 100644 --- a/lib/rules/property-no-vendor-prefix/__tests__/index.js +++ b/lib/rules/property-no-vendor-prefix/__tests__/index.js @@ -5,6 +5,7 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, config: [true], + fix: true, accept: [ { @@ -40,48 +41,56 @@ testRule({ reject: [ { code: 'a { -webkit-transform: scale(1); }', + fixed: 'a { transform: scale(1); }', message: messages.rejected('-webkit-transform'), line: 1, column: 5, }, { code: 'a { -wEbKiT-tRaNsFoRm: scale(1); }', + fixed: 'a { tRaNsFoRm: scale(1); }', message: messages.rejected('-wEbKiT-tRaNsFoRm'), line: 1, column: 5, }, { code: 'a { -WEBKIT-TRANSFORM: scale(1); }', + fixed: 'a { TRANSFORM: scale(1); }', message: messages.rejected('-WEBKIT-TRANSFORM'), line: 1, column: 5, }, { code: 'a { -webkit-transform: scale(1); transform: scale(1); }', + fixed: 'a { transform: scale(1); transform: scale(1); }', message: messages.rejected('-webkit-transform'), line: 1, column: 5, }, { code: 'a { transform: scale(1); -webkit-transform: scale(1); }', + fixed: 'a { transform: scale(1); transform: scale(1); }', message: messages.rejected('-webkit-transform'), line: 1, column: 26, }, { code: 'a { -moz-transition: all 3s; }', + fixed: 'a { transition: all 3s; }', message: messages.rejected('-moz-transition'), line: 1, column: 5, }, { code: 'a { -moz-columns: 2; }', + fixed: 'a { columns: 2; }', message: messages.rejected('-moz-columns'), line: 1, column: 5, }, { code: 'a { -o-columns: 2; }', + fixed: 'a { columns: 2; }', description: 'mistaken prefix', message: messages.rejected('-o-columns'), line: 1, @@ -89,6 +98,7 @@ testRule({ }, { code: 'a { -ms-interpolation-mode: nearest-neighbor; }', + fixed: 'a { interpolation-mode: nearest-neighbor; }', description: '"hack" prefix', message: messages.rejected('-ms-interpolation-mode'), line: 1, @@ -100,6 +110,7 @@ testRule({ testRule({ ruleName, config: [true, { ignoreProperties: ['transform', 'columns', '/^animation-/i'] }], + fix: true, accept: [ { @@ -121,18 +132,21 @@ testRule({ reject: [ { code: 'a { -webkit-border-radius: 10px; }', + fixed: 'a { border-radius: 10px; }', message: messages.rejected('-webkit-border-radius'), line: 1, column: 5, }, { code: 'a { -moz-background-size: cover; }', + fixed: 'a { background-size: cover; }', message: messages.rejected('-moz-background-size'), line: 1, column: 5, }, { code: 'a { -WEBKIT-tranSFoRM: translateY(-50%); }', + fixed: 'a { tranSFoRM: translateY(-50%); }', message: messages.rejected('-WEBKIT-tranSFoRM'), line: 1, column: 5, @@ -143,6 +157,7 @@ testRule({ testRule({ ruleName, config: [true, { ignoreProperties: [/^animation-/i] }], + fix: true, accept: [ { @@ -152,6 +167,7 @@ testRule({ reject: [ { code: 'a { -webkit-border-radius: 10px; }', + fixed: 'a { border-radius: 10px; }', message: messages.rejected('-webkit-border-radius'), line: 1, column: 5, diff --git a/lib/rules/property-no-vendor-prefix/index.js b/lib/rules/property-no-vendor-prefix/index.js index 0771731993..d5fbcc0969 100644 --- a/lib/rules/property-no-vendor-prefix/index.js +++ b/lib/rules/property-no-vendor-prefix/index.js @@ -16,7 +16,7 @@ const messages = ruleMessages(ruleName, { rejected: (property) => `Unexpected vendor-prefix "${property}"`, }); -function rule(actual, options) { +function rule(actual, options, context) { return (root, result) => { const validOptions = validateOptions( result, @@ -55,6 +55,12 @@ function rule(actual, options) { return; } + if (context.fix) { + decl.prop = isAutoprefixable.unprefix(decl.prop); + + return; + } + report({ message: messages.rejected(prop), node: decl, diff --git a/lib/rules/selector-no-vendor-prefix/README.md b/lib/rules/selector-no-vendor-prefix/README.md index adf3b0b6ce..8555ec6d10 100644 --- a/lib/rules/selector-no-vendor-prefix/README.md +++ b/lib/rules/selector-no-vendor-prefix/README.md @@ -11,6 +11,8 @@ input::-moz-placeholder {} This rule does not blanketly condemn vendor prefixes. Instead, it uses [Autoprefixer's](https://github.com/postcss/autoprefixer) up-to-date data (from [caniuse.com](http://caniuse.com/)) to know whether a vendor prefix should cause a violation or not. _If you've included a vendor prefixed selector that has a standard alternative, one that Autoprefixer could take care of for you, this rule will complain about it_. If, however, you use a non-standard vendor-prefixed selector, one that Autoprefixer would ignore and could not provide, this rule will ignore it. +The [`fix` option](../../../docs/user-guide/usage/options.md#fix) can automatically fix all of the problems reported by this rule. + ## Options ### `true` diff --git a/lib/rules/selector-no-vendor-prefix/__tests__/index.js b/lib/rules/selector-no-vendor-prefix/__tests__/index.js index 3fa68a4d2b..f22ea1897c 100644 --- a/lib/rules/selector-no-vendor-prefix/__tests__/index.js +++ b/lib/rules/selector-no-vendor-prefix/__tests__/index.js @@ -5,6 +5,7 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, config: [true], + fix: true, accept: [ { @@ -46,42 +47,49 @@ testRule({ reject: [ { code: ':-webkit-full-screen a {}', + fixed: ':full-screen a {}', message: messages.rejected(':-webkit-full-screen'), line: 1, column: 1, }, { code: ':-wEbKiT-fUlL-sCrEeN a {}', + fixed: ':fUlL-sCrEeN a {}', message: messages.rejected(':-wEbKiT-fUlL-sCrEeN'), line: 1, column: 1, }, { code: ':-WEBKIT-FULL-SCREEN a {}', + fixed: ':FULL-SCREEN a {}', message: messages.rejected(':-WEBKIT-FULL-SCREEN'), line: 1, column: 1, }, { code: 'body, :-ms-fullscreen a {}', + fixed: 'body, :fullscreen a {}', message: messages.rejected(':-ms-fullscreen'), line: 1, column: 7, }, { code: 'input::-moz-placeholder, input::placeholder { color: pink; }', + fixed: 'input::placeholder, input::placeholder { color: pink; }', message: messages.rejected('::-moz-placeholder'), line: 1, column: 6, }, { code: 'input::-moz-placeholder { color: pink; }', + fixed: 'input::placeholder { color: pink; }', message: messages.rejected('::-moz-placeholder'), line: 1, column: 6, }, { code: 'input::-webkit-input-placeholder { color: pink; }', + fixed: 'input::input-placeholder { color: pink; }', message: messages.rejected('::-webkit-input-placeholder'), }, ], @@ -90,6 +98,7 @@ testRule({ testRule({ ruleName, config: [true, { ignoreSelectors: ['::-webkit-input-placeholder', '/-moz-.*/'] }], + fix: true, accept: [ { @@ -103,6 +112,7 @@ testRule({ reject: [ { code: 'input::-ms-input-placeholder { color: pink; }', + fixed: 'input::input-placeholder { color: pink; }', message: messages.rejected('::-ms-input-placeholder'), }, ], diff --git a/lib/rules/selector-no-vendor-prefix/index.js b/lib/rules/selector-no-vendor-prefix/index.js index 4e37e01865..9f768f586e 100644 --- a/lib/rules/selector-no-vendor-prefix/index.js +++ b/lib/rules/selector-no-vendor-prefix/index.js @@ -17,7 +17,7 @@ const messages = ruleMessages(ruleName, { rejected: (selector) => `Unexpected vendor-prefix "${selector}"`, }); -function rule(actual, options) { +function rule(actual, options, context) { return (root, result) => { const validOptions = validateOptions( result, @@ -50,6 +50,12 @@ function rule(actual, options) { return; } + if (context.fix) { + rule.selector = isAutoprefixable.unprefix(rule.selector); + + return; + } + report({ result, ruleName, diff --git a/lib/rules/value-no-vendor-prefix/README.md b/lib/rules/value-no-vendor-prefix/README.md index 08a8c10f1e..9a08e40582 100644 --- a/lib/rules/value-no-vendor-prefix/README.md +++ b/lib/rules/value-no-vendor-prefix/README.md @@ -11,6 +11,8 @@ a { display: -webkit-flex; } This rule will only complain for prefixed _standard_ values, and not for prefixed _proprietary_ or _unknown_ ones. +The [`fix` option](../../../docs/user-guide/usage/options.md#fix) can automatically fix all of the problems reported by this rule. + ## Options ### `true` diff --git a/lib/rules/value-no-vendor-prefix/__tests__/index.js b/lib/rules/value-no-vendor-prefix/__tests__/index.js index 8c9ef0e663..39934295e1 100644 --- a/lib/rules/value-no-vendor-prefix/__tests__/index.js +++ b/lib/rules/value-no-vendor-prefix/__tests__/index.js @@ -5,6 +5,7 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, config: [true], + fix: true, accept: [ { @@ -33,54 +34,63 @@ testRule({ reject: [ { code: '.foo { display: -webkit-flex; }', + fixed: '.foo { display: flex; }', message: messages.rejected('-webkit-flex'), line: 1, column: 17, }, { code: '.foo { display: -wEbKiT-fLeX; }', + fixed: '.foo { display: fLeX; }', message: messages.rejected('-wEbKiT-fLeX'), line: 1, column: 17, }, { code: '.foo { display: -WEBKIT-FLEX; }', + fixed: '.foo { display: FLEX; }', message: messages.rejected('-WEBKIT-FLEX'), line: 1, column: 17, }, { code: '.foo { dIsPlAy: -webkit-flex; }', + fixed: '.foo { dIsPlAy: flex; }', message: messages.rejected('-webkit-flex'), line: 1, column: 17, }, { code: '.foo { DISPLAY: -webkit-flex; }', + fixed: '.foo { DISPLAY: flex; }', message: messages.rejected('-webkit-flex'), line: 1, column: 17, }, { code: '.foo { color: pink; display: -webkit-flex; }', + fixed: '.foo { color: pink; display: flex; }', message: messages.rejected('-webkit-flex'), line: 1, column: 30, }, { code: '.foo { display: -webkit-box; }', + fixed: '.foo { display: box; }', message: messages.rejected('-webkit-box'), line: 1, column: 17, }, { code: '.foo { background: -webkit-linear-gradient(bottom, #000, #fff); }', + fixed: '.foo { background: linear-gradient(bottom, #000, #fff); }', message: messages.rejected('-webkit-linear-gradient'), line: 1, column: 20, }, { code: '.foo { max-width: -moz-max-content; }', + fixed: '.foo { max-width: max-content; }', message: messages.rejected('-moz-max-content'), line: 1, column: 19, @@ -92,6 +102,7 @@ testRule({ ruleName, config: [true], syntax: 'scss', + fix: true, accept: [ { @@ -113,6 +124,7 @@ testRule({ ruleName, config: [true], syntax: 'less', + fix: true, accept: [ { @@ -127,6 +139,7 @@ testRule({ testRule({ ruleName, config: [true, { ignoreValues: ['grab', 'max-content', '/^linear-/'] }], + fix: true, accept: [ { @@ -142,18 +155,21 @@ testRule({ reject: [ { code: '.foo { display: -webkit-flex; }', + fixed: '.foo { display: flex; }', message: messages.rejected('-webkit-flex'), line: 1, column: 17, }, { code: '.foo { display: -wEbKiT-fLeX; }', + fixed: '.foo { display: fLeX; }', message: messages.rejected('-wEbKiT-fLeX'), line: 1, column: 17, }, { code: '.foo { display: -WEBKIT-FLEX; }', + fixed: '.foo { display: FLEX; }', message: messages.rejected('-WEBKIT-FLEX'), line: 1, column: 17, diff --git a/lib/rules/value-no-vendor-prefix/index.js b/lib/rules/value-no-vendor-prefix/index.js index f82718d921..ba4b3609c3 100644 --- a/lib/rules/value-no-vendor-prefix/index.js +++ b/lib/rules/value-no-vendor-prefix/index.js @@ -21,7 +21,7 @@ const messages = ruleMessages(ruleName, { const valuePrefixes = ['-webkit-', '-moz-', '-ms-', '-o-']; -function rule(actual, options) { +function rule(actual, options, context) { return (root, result) => { const validOptions = validateOptions( result, @@ -67,6 +67,12 @@ function rule(actual, options) { return; } + if (context.fix) { + decl.value = isAutoprefixable.unprefix(decl.value); + + return; + } + report({ message: messages.rejected(fullIdentifier), node: decl, diff --git a/lib/utils/isAutoprefixable.js b/lib/utils/isAutoprefixable.js index 521aee12bb..051e23ea32 100644 --- a/lib/utils/isAutoprefixable.js +++ b/lib/utils/isAutoprefixable.js @@ -74,4 +74,13 @@ module.exports = { }) ); }, + + /** + * + * @param {string} value + * @returns {string} + */ + unprefix(value) { + return value.replace(/-\w+-/, ''); + }, };