Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

lesshint

Package Overview
Dependencies
Maintainers
2
Versions
91
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lesshint - npm Package Compare versions

Comparing version 4.0.2 to 4.1.0

25

CHANGELOG.md
# Changelog
## 4.1.0 (2017-07-24)
* `Lesshint.configure()` now returns the final config object. ([076f8fe](https://github.com/lesshint/lesshint/commit/076f8fe06a900e432c48b40a510dc7f865ad90cb))
* The `parseValue` util can now accept `postcss-values-parser` options. ([c2f8d53](https://github.com/lesshint/lesshint/commit/c2f8d53fd10c668be797194c586339731883e8f7))
* Updated `postcss-values-parser` to `1.3.0`. ([e49f4d7](https://github.com/lesshint/lesshint/commit/e49f4d793542ab3ce02f2a802f81a16b599430c2))
* Refactored position reporting in the following linters:
* `borderZero` ([836ff0f](https://github.com/lesshint/lesshint/commit/836ff0f53b3954dcf7a3201590f81899efb0dcef))
* `colorVariables` ([277f1aa](https://github.com/lesshint/lesshint/commit/277f1aa866ccf62781095552cf45de928b132c2a))
* `decimalZero` ([d33fa2c](https://github.com/lesshint/lesshint/commit/d33fa2ca05436d4ce0178a75ed97bd6990f38be6))
* `hexLength` ([e599d8b](https://github.com/lesshint/lesshint/commit/e599d8bd90b31046ff29da50dac0e6db58734fe5))
* `hexNotation` ([60e7485](https://github.com/lesshint/lesshint/commit/60e7485a61894f9967b3c840be8abf4fdf65ba28))
* `hexValidation` ([7b441aa](https://github.com/lesshint/lesshint/commit/7b441aac1947d0dc401085267077807f909b2415))
* `idSelector` ([d8b298b](https://github.com/lesshint/lesshint/commit/d8b298b1aa6e3199296c0e918dfa32f9a658834a))
* `importantRule` ([ba733a6](https://github.com/lesshint/lesshint/commit/ba733a666f1f77cc008b3f74abbfc02dd38ee8fd))
* `propertyUnits` ([da6353e](https://github.com/lesshint/lesshint/commit/da6353ee0afa0abe7d71c9b0137d9c8a4986c702))
* `qualifyingElement` ([58a3f03](https://github.com/lesshint/lesshint/commit/58a3f0327df1e753dc2fd2a1009c4782508605c1))
* `selectorNaming` ([7b2f08e](https://github.com/lesshint/lesshint/commit/7b2f08e8f3744febd257812d8b07324f96dcc6b6))
* `spaceAfterPropertyName` ([871bf2c](https://github.com/lesshint/lesshint/commit/871bf2c659dcfc197440aa69273d279fd4b1e391))
* `spaceAfterPropertyValue` ([7395a16](https://github.com/lesshint/lesshint/commit/7395a16d23872b992a7c29a2dab0dafbacba6b7c))
* `spaceBeforeBrace` ([36979f4](https://github.com/lesshint/lesshint/commit/36979f4e798d088e43c1e9f724980159cc848188))
* `universalSelector` ([4aaf666](https://github.com/lesshint/lesshint/commit/4aaf666782baedd3db206fccb30898dd849855bc))
* `urlFormat` ([56a4c64](https://github.com/lesshint/lesshint/commit/56a4c64f243d2d722a5a872c865e63fcccf4ec92))
* `urlQuotes` ([56a4c64](https://github.com/lesshint/lesshint/commit/56a4c64f243d2d722a5a872c865e63fcccf4ec92))
* `variableValue` ([de75d7e](https://github.com/lesshint/lesshint/commit/de75d7ed7c46558a614eb5dc4909a692e18f78b6))
* `zeroUnit` ([b24c91a](https://github.com/lesshint/lesshint/commit/b24c91a4e4fe39fdf51dfcbe736967ddfd092a67))
## 4.0.2 (2017-07-20)

@@ -3,0 +28,0 @@ * Lockdown `postcss-values-parser` to `~` range. ([d198ed6](https://github.com/lesshint/lesshint/commit/d198ed6b6807464a0d9b443c4e592368bb4ede05))

2

docs/developer-guide/api/lesshint.md

@@ -74,2 +74,4 @@ # Lesshint class

The merged, final, config object will be returned.
```js

@@ -76,0 +78,0 @@ const config = {

20

docs/developer-guide/api/utils.md

@@ -9,3 +9,3 @@ # Utils

## `isAbsoluteURL`
## `isAbsoluteURL(str)`
Check if a string is a absolute URL.

@@ -18,3 +18,3 @@

## `isVariable()`
## `isVariable(str)`
Check if a value is a Less variable.

@@ -27,3 +27,3 @@

## `parseSelector`
## `parseSelector(selector)`
Parse a selector using [`postcss-selector-parser`](https://github.com/postcss/postcss-selector-parser).

@@ -35,7 +35,17 @@

## `parseValue`
## `parseValue(value, options)`
Parse a value using [`postcss-values-parser`](https://github.com/lesshint/postcss-values-parser).
`options` is any valid `postcss-values-parser` options. The default values are:
```js
utils.parseValue('10px'); // Parser tree
{
loose: true
}
```
```js
utils.parseValue('10px', {
loose: false
}); // Parser tree
```

@@ -139,2 +139,4 @@ 'use strict';

this.config = merge(defaultConfig, config);
return this.config;
}

@@ -141,0 +143,0 @@

@@ -19,4 +19,6 @@ 'use strict';

const value = node.value;
// Bail if it's an actual border
if (node.value !== '0' && node.value !== 'none') {
if (value !== '0' && value !== 'none') {
return;

@@ -29,3 +31,3 @@ }

case 'none':
if (node.value === '0') {
if (value === '0') {
message = this.message.none;

@@ -36,3 +38,3 @@ }

case 'zero':
if (node.value === 'none') {
if (value === 'none') {
message = this.message.zero;

@@ -43,11 +45,13 @@ }

default:
throw new Error(
'Invalid setting value for borderZero: ' + config.style
);
throw new Error(`Invalid setting value for borderZero: ${ config.style }`);
}
if (message) {
const position = node.positionBy({
word: value
});
return [{
column: node.source.start.column + node.prop.length + node.raws.between.length,
line: node.source.start.line,
column: position.column,
line: position.line,
message: message

@@ -54,0 +58,0 @@ }];

@@ -13,13 +13,5 @@ 'use strict';

lint: function colorVariablesLinter (config, node) {
/**
* Just in case, since postcss will sometimes include the semicolon
* in declaration values
*/
node.value = node.value.replace(/;$/, '');
const ast = parseValue(node.value);
const results = [];
const ast = parseValue(node.value, {
loose: true
});
const results = [];
ast.first.walk((child) => {

@@ -31,12 +23,15 @@ // Only evaluate hex colors

// If this is a variable assignment, allow hex colors
const prop = node.prop;
if (isVariable(prop)) {
// If it's a variable assignment, allow hex colors
if (isVariable(node.prop)) {
return;
}
const color = child.value;
const position = node.positionBy({
word: color
});
// Hex color found, add to results
results.push({
column: node.source.start.column + node.prop.length + node.raws.between.length + (child.source.start.column - 1),
column: position.column,
line: position.line,
message: util.format(this.message, color)

@@ -43,0 +38,0 @@ });

@@ -63,5 +63,9 @@ 'use strict';

if (output.type) {
const position = node.positionBy({
word: number
});
results.push({
column: node.source.start.column + node.prop.length + node.raws.between.length + child.source.start.column - 1,
line: node.source.start.line,
column: position.column,
line: position.line,
message: util.format(this.message, number, output.inclusion, output.type)

@@ -68,0 +72,0 @@ });

@@ -52,4 +52,9 @@ 'use strict';

if (!valid) {
const position = node.positionBy({
word: color
});
results.push({
column: node.source.start.column + node.prop.length + node.raws.between.length + child.source.start.column - 1,
column: position.column,
line: position.line,
message: util.format(this.message, color, config.style)

@@ -56,0 +61,0 @@ });

@@ -42,4 +42,9 @@ 'use strict';

if (!styles[config.style].test(color)) {
const position = node.positionBy({
word: color
});
results.push({
column: node.source.start.column + node.prop.length + node.raws.between.length + child.source.start.column - 1,
column: position.column,
line: position.line,
message: util.format(this.message, color, config.style)

@@ -46,0 +51,0 @@ });

@@ -27,4 +27,9 @@ 'use strict';

if (child.isHex && !child.isColor) {
const position = node.positionBy({
word: child.value
});
results.push({
column: node.source.start.column + node.prop.length + node.raws.between.length + child.source.start.column - 1,
column: position.column,
line: position.line,
message: util.format(this.message, child.value)

@@ -31,0 +36,0 @@ });

@@ -21,9 +21,13 @@ 'use strict';

selector.walkIds((id) => {
if (excludes.indexOf(id.value) >= 0) {
if (excludes.indexOf(id.value) !== -1) {
return;
}
const position = node.positionBy({
word: id.toString()
});
results.push({
column: node.source.start.column + id.source.start.column - 1,
line: node.source.start.line + id.source.start.line - 1,
column: position.column,
line: position.line,
message: this.message

@@ -30,0 +34,0 @@ });

@@ -10,5 +10,9 @@ 'use strict';

if (node.important) {
const position = node.positionBy({
word: node.raws.important || '!important'
});
return [{
column: node.source.start.column + node.prop.length + node.raws.between.length + node.value.length + 1,
line: node.source.start.line,
column: position.column,
line: position.line,
message: this.message

@@ -15,0 +19,0 @@ }];

@@ -50,5 +50,9 @@ 'use strict';

const position = node.positionBy({
word: node.value
});
results.push({
column: node.source.start.column + node.raws.between.length + property.length + value.source.start.column - 1,
line: node.source.start.line + value.source.start.line - 1,
column: position.column,
line: position.line,
message: util.format(this.message.unit, unit, property)

@@ -55,0 +59,0 @@ });

@@ -94,5 +94,9 @@ 'use strict';

if (result) {
const position = node.positionBy({
word: result.toString().trim()
});
results.push({
column: node.source.start.column + result.source.start.column - 1,
line: node.source.start.line + result.source.start.line - 1,
column: position.column,
line: position.line,
message: util.format(this.message, result.type.charAt(0).toUpperCase() + result.type.substring(1))

@@ -99,0 +103,0 @@ });

@@ -33,5 +33,9 @@ 'use strict';

) {
const position = node.positionBy({
word: selector.toString().trim()
});
results.push({
column: node.source.start.column + selector.source.start.column - 1,
line: node.source.start.line + selector.source.start.line - 1,
column: position.column,
line: position.line,
message: util.format(this.message, name)

@@ -38,0 +42,0 @@ });

@@ -21,5 +21,9 @@ 'use strict';

if (!styles[config.style].test(node.raws.between)) {
const position = node.positionBy({
word: node.raws.between
});
return [{
column: node.source.start.column + node.prop.length,
line: node.source.start.line,
column: position.column,
line: position.line,
message: util.format(

@@ -26,0 +30,0 @@ this.message,

@@ -11,3 +11,3 @@ 'use strict';

lint: function spaceAfterPropertyValueLinter (config, node) {
const nodeEnd = node.source.end || {};
const nodeString = node.toString().trimRight();
const results = [];

@@ -18,5 +18,9 @@

if (/.*\s$/.test(node.raws.important) || node.raws.value && /.*\s$/.test(node.raws.value.raw)) {
const position = node.positionBy({
index: nodeString.length
});
results.push({
column: node.source.start.column + node.prop.length + node.raws.between.length + node.value.length,
line: nodeEnd.line,
column: position.column,
line: position.line,
message: util.format(this.message, ' not', 'any')

@@ -29,5 +33,9 @@ });

if (!/.*\s$/.test(node.raws.important) && !node.raws.value) {
const position = node.positionBy({
index: nodeString.length
});
results.push({
column: node.source.start.column + node.prop.length + node.raws.between.length + node.value.length,
line: nodeEnd.line,
column: position.column,
line: position.line,
message: util.format(this.message, '', 'one')

@@ -34,0 +42,0 @@ });

@@ -23,7 +23,4 @@ 'use strict';

/**
* If the node is a bodiless rule, or it's an import statement, or we
* are dealing with an atrule without a body, bail.
*/
if (node.empty || node.name === 'import' ||
// If the node is a bodiless rule or atrule, bail
if (node.empty ||
/**

@@ -38,13 +35,9 @@ * Hopefully node.empty will be implemented on AtRule nodes

if (!styles[config.style].test(node.raws.between)) {
let column = node.source.start.column;
const position = node.positionBy({
word: '{'
});
if (node.type === 'rule') {
column += node.selector.length;
} else if (node.type === 'atrule') {
column += node.name.length + node.raws.afterName.length + node.params.length + 1;
}
return [{
column: column,
line: node.source.start.line,
column: position.column,
line: position.line,
message: this.message[config.style]

@@ -51,0 +44,0 @@ }];

@@ -15,6 +15,10 @@ 'use strict';

tree.each((selector) => {
selector.walkUniversals((uni) => {
selector.walkUniversals((universal) => {
const position = node.positionBy({
index: universal.sourceIndex
});
results.push({
column: node.source.start.column + uni.source.start.column - 1,
line: node.source.start.line,
column: position.column,
line: position.line,
message: this.message

@@ -21,0 +25,0 @@ });

@@ -12,3 +12,3 @@ 'use strict';

lint: function urlFormatLinter (config, decl) {
lint: function urlFormatLinter (config, node) {
const style = {

@@ -29,4 +29,6 @@ absolute: isAbsoluteURL,

*/
const ast = parseValue(decl.params || decl.value);
const results = [];
const ast = parseValue(node.value, {
loose: false
});

@@ -40,12 +42,12 @@ ast.first.nodes.forEach((child) => {

const uri = child.first.next();
const value = uri.value.trim();
if (!style[config.style](uri.value)) {
const column = (decl.raws.between ? decl.raws.between.length : 0) +
decl.source.start.column +
decl.prop.length +
uri.source.start.column - 1;
if (!style[config.style](value)) {
const position = node.positionBy({
word: value
});
results.push({
column: column,
line: decl.source.start.line,
column: position.column,
line: position.line,
message: util.format(this.message, uri.value, config.style)

@@ -52,0 +54,0 @@ });

@@ -39,3 +39,5 @@ 'use strict';

*/
const ast = parseValue(node.params || node.value);
const ast = parseValue(node.params || node.value, {
loose: false
});

@@ -61,10 +63,9 @@ ast.first.nodes.forEach((child) => {

if ((uri.type === 'word' && !(rSingle.test(value) || rDouble.test(value))) && uri.type !== 'string') {
const column = (node.raws.between ? node.raws.between.length : 0) +
node.source.start.column +
(node.prop || node.name).length +
uri.source.start.column - 1;
const position = node.positionBy({
word: value
});
results.push({
column: column,
line: node.source.start.line,
column: position.column,
line: position.line,
message: this.message

@@ -71,0 +72,0 @@ });

@@ -14,7 +14,9 @@ 'use strict';

if (isVariable(node.value)) {
const position = node.positionBy({
word: node.value
});
return [{
column: node.source.start.column +
node.prop.length +
node.raws.between.length,
line: node.source.start.line,
column: position.column,
line: position.line,
message: util.format(this.message, 'Variable', node.prop)

@@ -27,7 +29,9 @@ }];

if (!isVariable(node.value)) {
const position = node.positionBy({
word: node.value
});
return [{
column: node.source.start.column +
node.prop.length +
node.raws.between.length,
line: node.source.start.line,
column: position.column,
line: position.line,
message: util.format(this.message, 'Non variable', node.prop)

@@ -34,0 +38,0 @@ }];

@@ -71,5 +71,9 @@ 'use strict';

if (!valid) {
const position = node.positionBy({
word: node.value
});
results.push({
column: node.source.start.column + node.prop.length + node.raws.between.length + child.source.start.column - 1,
line: node.source.start.line,
column: position.column,
line: position.line,
message: util.format(this.message, config.style === 'keep_unit' ? 'not ' : '')

@@ -76,0 +80,0 @@ });

@@ -5,8 +5,10 @@ 'use strict';

module.exports = function (value) {
const tree = parser(value, {
module.exports = function (value, options) {
const defaults = {
loose: true
}).parse();
};
return tree;
options = Object.assign(defaults, options);
return parser(value, options).parse();
};
{
"name": "lesshint",
"description": "A tool to aid you in writing clean and consistent Less.",
"version": "4.0.2",
"version": "4.1.0",
"main": "./lib/index.js",

@@ -30,3 +30,3 @@ "author": {

"postcss-selector-parser": "^2.0.0",
"postcss-values-parser": "~1.2.2",
"postcss-values-parser": "^1.3.0",
"rcfinder": "^0.1.8",

@@ -33,0 +33,0 @@ "strip-json-comments": "^2.0.0"

@@ -276,2 +276,9 @@ 'use strict';

});
it('should return the final config object', function () {
const expected = configLoader(path.resolve(process.cwd() + '/lib/config/defaults.json'));
const lesshint = new Lesshint();
expect(lesshint.configure(expected)).to.deep.equal(expected);
});
});

@@ -278,0 +285,0 @@

@@ -20,2 +20,3 @@ 'use strict';

column: 8,
line: 1,
message: '#ABC should be replaced with an existing variable.'

@@ -46,2 +47,3 @@ }];

column: 19,
line: 1,
message: '#ABC should be replaced with an existing variable.'

@@ -48,0 +50,0 @@ }];

@@ -20,2 +20,3 @@ 'use strict';

column: 8,
line: 1,
message: '#ABC should be written in the long-form format.'

@@ -52,2 +53,3 @@ }];

column: 8,
line: 1,
message: '#AABBCC should be written in the short-form format.'

@@ -97,2 +99,3 @@ }];

column: 37,
line: 1,
message: '#AABBCC should be written in the short-form format.'

@@ -116,2 +119,3 @@ }];

column: 9,
line: 1,
message: '#ABC should be written in the long-form format.'

@@ -135,2 +139,3 @@ }];

column: 9,
line: 1,
message: '#AABBCC should be written in the short-form format.'

@@ -137,0 +142,0 @@ }];

@@ -20,2 +20,3 @@ 'use strict';

column: 8,
line: 1,
message: '#AABBCC should be written in lowercase.'

@@ -52,2 +53,3 @@ }];

column: 8,
line: 1,
message: '#aabbcc should be written in uppercase.'

@@ -84,2 +86,3 @@ }];

column: 37,
line: 1,
message: '#AABBCC should be written in lowercase.'

@@ -103,2 +106,3 @@ }];

column: 9,
line: 1,
message: '#AABBCC should be written in lowercase.'

@@ -122,2 +126,3 @@ }];

column: 9,
line: 1,
message: '#aabbcc should be written in uppercase.'

@@ -124,0 +129,0 @@ }];

@@ -30,2 +30,3 @@ 'use strict';

column: 8,
line: 1,
message: 'Hexadecimal color "#AABBC" should be either three or six characters long.'

@@ -45,2 +46,3 @@ }];

column: 37,
line: 1,
message: 'Hexadecimal color "#AABBC" should be either three or six characters long.'

@@ -60,2 +62,3 @@ }];

column: 9,
line: 1,
message: 'Hexadecimal color "#AABBC" should be either three or six characters long.'

@@ -62,0 +65,0 @@ }];

@@ -64,3 +64,3 @@ 'use strict';

const expected = [{
column: 18,
column: 29,
line: 1,

@@ -129,3 +129,3 @@ message: 'Semicolon after property value should not be preceded by any space.'

const expected = [{
column: 18,
column: 29,
line: 1,

@@ -132,0 +132,0 @@ message: 'Semicolon after property value should be preceded by one space.'

@@ -32,3 +32,3 @@ 'use strict';

const expected = [{
column: 5,
column: 6,
line: 1,

@@ -52,3 +52,3 @@ message: 'Opening curly brace should not be preceded by a space or new line.'

const expected = [{
column: 5,
column: 7,
line: 1,

@@ -72,4 +72,4 @@ message: 'Opening curly brace should not be preceded by a space or new line.'

const expected = [{
column: 5,
line: 1,
column: 1,
line: 2,
message: 'Opening curly brace should not be preceded by a space or new line.'

@@ -92,4 +92,4 @@ }];

const expected = [{
column: 5,
line: 1,
column: 1,
line: 3,
message: 'Opening curly brace should not be preceded by a space or new line.'

@@ -176,3 +176,3 @@ }];

const expected = [{
column: 5,
column: 7,
line: 1,

@@ -193,26 +193,7 @@ message: 'Opening curly brace should be preceded by one space.'

it('should not allow multiple spaces when "style" is "one_space"', function () {
const source = '.foo {}';
const expected = [{
column: 5,
line: 1,
message: 'Opening curly brace should be preceded by one space.'
}];
const options = {
style: 'one_space'
};
return spec.parse(source, function (ast) {
const result = spec.linter.lint(options, ast.root.first);
expect(result).to.deep.equal(expected);
});
});
it('should not allow new line when "style" is "one_space"', function () {
const source = '.foo, .bar\n{}';
const expected = [{
column: 11,
line: 1,
column: 1,
line: 2,
message: 'Opening curly brace should be preceded by one space.'

@@ -235,3 +216,3 @@ }];

const expected = [{
column: 11,
column: 12,
line: 1,

@@ -255,3 +236,3 @@ message: 'Opening curly brace should be preceded by one space.'

const expected = [{
column: 11,
column: 13,
line: 1,

@@ -327,4 +308,4 @@ message: 'Opening curly brace should be preceded by one space.'

const expected = [{
column: 5,
line: 1,
column: 1,
line: 3,
message: 'Opening curly brace should be on its own line.'

@@ -347,4 +328,4 @@ }];

const expected = [{
column: 11,
line: 1,
column: 1,
line: 3,
message: 'Opening curly brace should be on its own line.'

@@ -434,4 +415,4 @@ }];

it('should not check imports', function () {
const source = '@import \'lib/colors\';';
it('should ignore nodes without a following block', function () {
const source = '.foo();';
const options = {

@@ -448,4 +429,4 @@ style: 'one_space'

it('should ignore nodes without a following block', function () {
const source = '.foo();';
it('should ignore atrule nodes without a following block', function () {
const source = '@foo();';
const options = {

@@ -462,4 +443,11 @@ style: 'one_space'

it('should ignore atrule nodes without a following block', function () {
const source = '@foo();';
it('should report the correct line on multi-line selectors (#231)', function () {
const source = '.foo,\n.bar { color: red; }';
const expected = [{
column: 7,
line: 2,
message: 'Opening curly brace should be preceded by one space.'
}];
const options = {

@@ -472,3 +460,3 @@ style: 'one_space'

expect(result).to.be.undefined;
expect(result).to.deep.equal(expected);
});

@@ -475,0 +463,0 @@ });

@@ -159,3 +159,3 @@ 'use strict';

const expected = [{
column: 30,
column: 31,
line: 1,

@@ -162,0 +162,0 @@ message: 'URLs should be enclosed in quotes.'

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc