sass-lint
Version:
All Node Sass linter!
120 lines (106 loc) • 3.83 kB
JavaScript
;
var helpers = require('../helpers');
// The whitelisted ident values
var whitelistedValues = ['inherit', 'initial', 'transparent', 'none', 'currentColor'],
ignoredValueTypes = ['important', 'space'];
/**
* Checks If the property is of a valid type, either its a variable or it's a whitelisted ident value
*
* @param {Object} propertyElem - The property element
* @returns {boolean} Whether the property is valid or not
*/
var isValidProperty = function (propertyElem) {
if (propertyElem) {
if (propertyElem.is('variable')) {
return true;
}
else if (propertyElem.is('ident') && whitelistedValues.indexOf(propertyElem.content) !== -1) {
return true;
}
}
return false;
};
/**
* Checks If the property type is an ignored value type
*
* @param {Object} propertyElem - The property element
* @returns {boolean} Whether the property is an ignored type or not
*/
var isIgnoredType = function (propertyElem) {
if (propertyElem) {
return ignoredValueTypes.indexOf(propertyElem.type) !== -1;
}
return false;
};
/**
* Checks If the property type is a function and whether it is allowed
*
* @param {Object} propertyElem - The property element
* @param {boolean} allowMap - Whether the user has specified to allow Sass function map-get
* @param {Array} functionWhitelist - An array of string - function names we wish to allow
* @returns {boolean} Whether the property is an ignored type or not
*/
var isIgnoredFunction = function (propertyElem, allowMap, functionWhitelist) {
if (propertyElem && propertyElem.is('function')) {
var funcIdent = propertyElem.first('ident');
// allow custom properties as values
if (funcIdent.content === 'var') {
return true;
}
if (allowMap && funcIdent.content === 'map-get') {
return true;
}
if (functionWhitelist.length) {
return functionWhitelist.indexOf(funcIdent.content) !== -1;
}
}
return false;
};
module.exports = {
'name': 'variable-for-property',
'defaults': {
'properties': [],
'allow-map-get': true,
'allowed-functions': []
},
'detect': function (ast, parser) {
var result = [];
if (parser.options.properties.length) {
ast.traverseByType('value', function (node, i, parent) {
var declaration = parent.content[0].content[0],
declarationType = declaration.type,
declarationIdent = declaration.content;
if (declarationType === 'ident') {
if (parser.options.properties.indexOf(declarationIdent) !== -1) {
node.forEach(function (valElem) {
if (valElem.is('function') && !isIgnoredFunction(valElem, parser.options['allow-map-get'], parser.options['allowed-functions'])) {
result = helpers.addUnique(result, {
'ruleId': parser.rule.name,
'line': declaration.start.line,
'column': declaration.start.column,
'message': 'The function passed to \'' + declarationIdent + '\' is not allowed',
'severity': parser.severity
});
}
else if (
!valElem.is('function') &&
!isValidProperty(valElem) &&
!isIgnoredType(valElem) &&
!valElem.is('interpolation')
) {
result = helpers.addUnique(result, {
'ruleId': parser.rule.name,
'line': declaration.start.line,
'column': declaration.start.column,
'message': 'Values for properties of type \'' + declarationIdent + '\' may only be variables',
'severity': parser.severity
});
}
});
}
}
});
}
return result;
}
};