stylelint-csstree-validator
Advanced tools
Comparing version 1.8.0 to 1.9.0
@@ -0,1 +1,7 @@ | ||
## 1.9.0 (October 27, 2020) | ||
- Bumped CSSTree to `^1.0.0` (mdn-data is bumped to `2.0.12`) | ||
- Added `properties` and `types` options to extend syntax dictionary | ||
- Added `ignoreValue` option (#14) | ||
## 1.8.0 (January 24, 2020) | ||
@@ -2,0 +8,0 @@ |
67
index.js
@@ -1,7 +0,6 @@ | ||
var stylelint = require('stylelint'); | ||
var csstree = require('css-tree').fork(require('./syntax-extension')); | ||
var syntax = csstree.lexer; | ||
const stylelint = require('stylelint'); | ||
const csstree = require('css-tree').fork(require('./syntax-extension')); | ||
var ruleName = 'csstree/validator' | ||
var messages = stylelint.utils.ruleMessages(ruleName, { | ||
const ruleName = 'csstree/validator' | ||
const messages = stylelint.utils.ruleMessages(ruleName, { | ||
parseError: function(value) { | ||
@@ -16,18 +15,38 @@ return 'Can\'t parse value "' + value + '"'; | ||
module.exports = stylelint.createPlugin(ruleName, function(options) { | ||
var ignore = false; | ||
options = options || {}; | ||
if (Array.isArray(options.ignore)) { | ||
ignore = options.ignore.reduce(function(res, name) { | ||
res[name] = true; | ||
return res; | ||
}, Object.create(null)); | ||
} | ||
const ignoreValue = options.ignoreValue && (typeof options.ignoreValue === 'string' || toString.call(options.ignoreValue) === '[object RegExp]') | ||
? new RegExp(options.ignoreValue) | ||
: false; | ||
const ignore = Array.isArray(options.ignore) | ||
? new Set(options.ignore.map(name => String(name).toLowerCase())) | ||
: false; | ||
const syntax = !options.properties && !options.types | ||
? csstree.lexer // default syntax | ||
: csstree.fork((syntaxConfig) => { // syntax with custom properties or/and types | ||
for (const [name, value] of Object.entries(options.properties || {})) { | ||
syntaxConfig.properties[name] = value | ||
.replace(/^\s*\|/, (m, index) => syntaxConfig.properties[name] | ||
? syntaxConfig.properties[name] + ' |' | ||
: '' | ||
); | ||
} | ||
for (const [name, value] of Object.entries(options.types || {})) { | ||
syntaxConfig.types[name] = value | ||
.replace(/^\s*\|/, (m, index) => syntaxConfig.types[name] | ||
? syntaxConfig.types[name] + ' |' | ||
: '' | ||
); | ||
} | ||
return syntaxConfig; | ||
}).lexer; | ||
return function(root, result) { | ||
root.walkDecls(function(decl) { | ||
var value; | ||
let value; | ||
// ignore properties from ignore list | ||
if (ignore && ignore[decl.prop.toLowerCase()]) { | ||
if (ignore && ignore.has(decl.prop.toLowerCase())) { | ||
return; | ||
@@ -56,11 +75,10 @@ } | ||
node: decl, | ||
result: result, | ||
ruleName: ruleName | ||
result, | ||
ruleName | ||
}); | ||
} | ||
var match = syntax.matchProperty(decl.prop, value); | ||
var error = match.error; | ||
const { error } = syntax.matchProperty(decl.prop, value); | ||
if (error) { | ||
var message = error.rawMessage || error.message || error; | ||
let message = error.rawMessage || error.message || error; | ||
@@ -75,9 +93,14 @@ // ignore errors except those which make sense | ||
message = messages.invalid(decl.prop); | ||
// ignore values by a pattern | ||
if (ignoreValue && ignoreValue.test(decl.value)) { | ||
return; | ||
} | ||
} | ||
stylelint.utils.report({ | ||
message: message, | ||
message, | ||
node: decl, | ||
result: result, | ||
ruleName: ruleName | ||
result, | ||
ruleName | ||
}); | ||
@@ -84,0 +107,0 @@ } |
{ | ||
"name": "stylelint-csstree-validator", | ||
"version": "1.8.0", | ||
"version": "1.9.0", | ||
"description": "Stylelint plugin to validate CSS syntax", | ||
@@ -21,4 +21,7 @@ "repository": "csstree/stylelint-validator", | ||
}, | ||
"engines": { | ||
"node": ">=8.0.0" | ||
}, | ||
"dependencies": { | ||
"css-tree": "1.0.0-alpha.38" | ||
"css-tree": "^1.0.0" | ||
}, | ||
@@ -25,0 +28,0 @@ "peerDependencies": { |
@@ -33,5 +33,75 @@ [![NPM version](https://img.shields.io/npm/v/stylelint-csstree-validator.svg)](https://www.npmjs.com/package/stylelint-csstree-validator) | ||
#### properties | ||
Type: `Object` or `null` | ||
Default: `null` | ||
Overrides or/and extends property definition dictionary. CSS [Value Definition Syntax](https://github.com/csstree/csstree/blob/master/docs/definition-syntax.md) is used to define value's syntax. If definition starts with `|` it added to existing definition if any. See [CSS syntax reference](https://csstree.github.io/docs/syntax/) for default definitions. | ||
In the following example we extend `width` property and defines `size`: | ||
```json | ||
{ | ||
"plugins": [ | ||
"stylelint-csstree-validator" | ||
], | ||
"rules": { | ||
"csstree/validator": { | ||
"properties": { | ||
"width": "| new-keyword | custom-function(<length>, <percentage>)", | ||
"size": "<length-percentage>" | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
Using property definitions with the syntax `<any-value>` is an alternative for `ignore` option. | ||
```json | ||
{ | ||
"plugins": [ | ||
"stylelint-csstree-validator" | ||
], | ||
"rules": { | ||
"csstree/validator": { | ||
"properties": { | ||
"my-custom-property": "<any-value>" | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
#### types | ||
Type: `Object` or `null` | ||
Default: `null` | ||
Overrides or/and extends type definition dictionary. CSS [Value Definition Syntax](https://github.com/csstree/csstree/blob/master/docs/definition-syntax.md) is used to define value's syntax. If definition starts with `|` it added to existing definition if any. See [CSS syntax reference](https://csstree.github.io/docs/syntax/) for default definitions. | ||
In the following example we define new functional type `my-fn()` and extend `color` type: | ||
```json | ||
{ | ||
"plugins": [ | ||
"stylelint-csstree-validator" | ||
], | ||
"rules": { | ||
"csstree/validator": { | ||
"properties": { | ||
"some-property": "<my-fn()>" | ||
}, | ||
"types": { | ||
"color": "| darken(<color>, [ <percentage> | <number [0, 1]> ])", | ||
"my-fn()": "my-fn( <length-percentage> )" | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
#### ignore | ||
Type: `Array` or `false` | ||
Type: `Array` or `false` | ||
Default: `false` | ||
@@ -56,4 +126,26 @@ | ||
#### ignoreValue | ||
Type: `RegExp` | ||
Default: `false` | ||
Defines a pattern for values that should be ignored by the validator. | ||
```json | ||
{ | ||
"plugins": [ | ||
"stylelint-csstree-validator" | ||
], | ||
"rules": { | ||
"csstree/validator": { | ||
"ignoreValue": "^pattern$" | ||
} | ||
} | ||
} | ||
``` | ||
In this example, the plugin will not report warnings for values that match the given pattern. Warnings will still be reported for properties. | ||
## License | ||
MIT |
@@ -1,11 +0,11 @@ | ||
var tokenize = require('css-tree').tokenize; | ||
var TYPE = tokenize.TYPE; | ||
var NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) | ||
var DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($) | ||
var PERCENTAGESIGN = 0x0025; // U+0025 PERCENTAGE SIGN (%) | ||
var COMMERCIALAT = 0x0040; // U+0040 COMMERCIAL AT (@) | ||
var TILDE = 0x007E; // U+007E TILDE (~) | ||
const { tokenize } = require('css-tree'); | ||
const TYPE = tokenize.TYPE; | ||
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) | ||
const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($) | ||
const PERCENTAGESIGN = 0x0025; // U+0025 PERCENTAGE SIGN (%) | ||
const COMMERCIALAT = 0x0040; // U+0040 COMMERCIAL AT (@) | ||
const TILDE = 0x007E; // U+007E TILDE (~) | ||
// custom | ||
var PreprocessorExtensionError = function() { | ||
const PreprocessorExtensionError = function() { | ||
this.type = 'PreprocessorExtensionError'; | ||
@@ -23,5 +23,5 @@ }; | ||
// extend parser value parser | ||
var originalGetNode = syntaxConfig.scope.Value.getNode; | ||
const originalGetNode = syntaxConfig.scope.Value.getNode; | ||
syntaxConfig.scope.Value.getNode = function(context) { | ||
var node = null; | ||
let node = null; | ||
@@ -28,0 +28,0 @@ switch (this.scanner.tokenType) { |
@@ -1,5 +0,4 @@ | ||
var tokenize = require('css-tree').tokenize; | ||
var TYPE = tokenize.TYPE; | ||
var STRING = TYPE.String; | ||
var TILDE = 0x007E; // U+007E TILDE (~) | ||
const { tokenize: { TYPE } } = require('css-tree'); | ||
const STRING = TYPE.String; | ||
const TILDE = 0x007E; // U+007E TILDE (~) | ||
@@ -12,3 +11,3 @@ module.exports = { | ||
parse: function LessEscaping() { | ||
var start = this.scanner.tokenStart; | ||
const start = this.scanner.tokenStart; | ||
@@ -15,0 +14,0 @@ if (!this.scanner.isDelim(TILDE)) { |
@@ -1,3 +0,3 @@ | ||
var TYPE = require('css-tree').tokenize.TYPE; | ||
var ATKEYWORD = TYPE.AtKeyword; | ||
const { tokenize: { TYPE } } = require('css-tree'); | ||
const ATKEYWORD = TYPE.AtKeyword; | ||
@@ -10,3 +10,3 @@ module.exports = { | ||
parse: function LessVariable() { | ||
var start = this.scanner.tokenStart; | ||
const start = this.scanner.tokenStart; | ||
@@ -13,0 +13,0 @@ this.eat(ATKEYWORD); |
@@ -1,5 +0,4 @@ | ||
var tokenize = require('css-tree').tokenize; | ||
var TYPE = tokenize.TYPE; | ||
var ATRULE = TYPE.Atrule; | ||
var COMMERCIALAT = 0x0040; // U+0040 COMMERCIAL AT (@) | ||
const { tokenize: { TYPE } } = require('css-tree'); | ||
const ATRULE = TYPE.Atrule; | ||
const COMMERCIALAT = 0x0040; // U+0040 COMMERCIAL AT (@) | ||
@@ -12,3 +11,3 @@ module.exports = { | ||
parse: function LessVariableReference() { | ||
var start = this.scanner.tokenStart; | ||
const start = this.scanner.tokenStart; | ||
@@ -15,0 +14,0 @@ if (!this.scanner.isDelim(COMMERCIALAT)) { |
@@ -1,7 +0,5 @@ | ||
var List = require('css-tree').List; | ||
var tokenize = require('css-tree').tokenize; | ||
var TYPE = tokenize.TYPE; | ||
var LEFTCURLYBRACKET = TYPE.LeftCurlyBracket; | ||
var RIGHTCURLYBRACKET = TYPE.RightCurlyBracket; | ||
var NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) | ||
const { List, tokenize: { TYPE } } = require('css-tree'); | ||
const LEFTCURLYBRACKET = TYPE.LeftCurlyBracket; | ||
const RIGHTCURLYBRACKET = TYPE.RightCurlyBracket; | ||
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) | ||
@@ -14,4 +12,4 @@ module.exports = { | ||
parse: function SassInterpolation(recognizer, readSequence) { | ||
var start = this.scanner.tokenStart; | ||
var children = new List(); | ||
const start = this.scanner.tokenStart; | ||
let children = new List(); | ||
@@ -18,0 +16,0 @@ if (!this.scanner.isDelim(NUMBERSIGN)) { |
@@ -1,4 +0,4 @@ | ||
var tokenize = require('css-tree').tokenize; | ||
var IDENT = tokenize.TYPE.Ident; | ||
var DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($) | ||
const { tokenize: { TYPE } } = require('css-tree'); | ||
const IDENT = TYPE.Ident; | ||
const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($) | ||
@@ -11,3 +11,3 @@ module.exports = { | ||
parse: function SassVariable() { | ||
var start = this.scanner.tokenStart; | ||
const start = this.scanner.tokenStart; | ||
@@ -14,0 +14,0 @@ if (!this.scanner.isDelim(DOLLARSIGN)) { |
18863
259
150
+ Addedcss-tree@1.1.3(transitive)
+ Addedmdn-data@2.0.14(transitive)
- Removedcss-tree@1.0.0-alpha.38(transitive)
- Removedmdn-data@2.0.6(transitive)
Updatedcss-tree@^1.0.0