lesslint
Version:
lint your less code
128 lines (99 loc) • 13.6 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.check = undefined;
var _chalk = require('chalk');
var _chalk2 = _interopRequireDefault(_chalk);
var _postcss = require('postcss');
var _postcss2 = _interopRequireDefault(_postcss);
var _postcssValuesParser = require('postcss-values-parser');
var _postcssValuesParser2 = _interopRequireDefault(_postcssValuesParser);
var _util = require('../util');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @file 运算符检验
* + / - / * / / 四个运算符两侧必须(MUST)保留一个空格。
* https://github.com/ecomfe/spec/blob/master/less-code-style.md#%E8%BF%90%E7%AE%97
* @author ielgnaw(wuji0223@gmail.com)
*/
;
/**
* 规则名称
*
* @const
* @type {string}
*/
var RULENAME = 'require-around-space';
/**
* 错误信息
*
* @const
* @type {string}
*/
var MSG = '`+`、`-`、`*`、`/` four operators on both sides must keep a space';
/**
* 具体的检测逻辑
*
* @param {Object} opts 参数
* @param {*} opts.ruleVal 当前规则具体配置的值
* @param {string} opts.fileContent 文件内容
* @param {string} opts.filePath 文件路径
*/
var check = exports.check = _postcss2.default.plugin(RULENAME, function (opts) {
return function (css, result) {
if (!opts.ruleVal) {
return;
}
/* jshint maxcomplexity:false */
css.walkDecls(function (decl) {
var valueAst = (0, _postcssValuesParser2.default)(decl.value).parse();
valueAst.walk(function (child) {
if (child.type !== 'operator') {
return;
}
var parent = child.parent;
// 当前 child 的索引
var index = parent.index(child);
// child 的后一个元素
var nextElem = parent.nodes[index + 1];
// child 的前一个元素
var prevElem = parent.nodes[index - 1];
// 忽略负数 -1
if (child.value === '-' && (child.raws.before || decl.raws.between) && nextElem.type === 'number' && !nextElem.raws.before) {
return;
}
// 忽略变量 -@foo
if (child.value === '-' && (child.raws.before || decl.raws.between) && nextElem.type === 'atword' && !nextElem.raws.before) {
return;
}
// 忽略 font-size/line-height 简写定义
if (decl.prop === 'font' && child.value === '/' && prevElem.type === 'number' && nextElem.type === 'number') {
return;
}
// 判断 operator 前面是否有空格
var isBeforeValid = child.raws.before === ' ' || /^\s/.test(child.raws.before);
// 判断 operator 后面是否有空格
var isAfterValid = nextElem.raws.before === ' ' || /\s$/.test(nextElem.raws.before);
if (!isBeforeValid || !isAfterValid) {
var problemElem = !/\s$/.test(child.raws.before) ? child : nextElem;
var source = decl.source,
prop = decl.prop,
raws = decl.raws;
var line = source.start.line;
var lineContent = (0, _util.getLineContent)(line, source.input.css, true);
var col = 0 + source.start.column + prop.length + raws.between.length + problemElem.source.start.column - 1 - (isBeforeValid ? child.value.length : 0);
result.warn(RULENAME, {
node: decl,
ruleName: RULENAME,
line: line,
col: col,
message: '`' + lineContent + '` ' + MSG,
colorMessage: '`' + (0, _util.changeColorByStartAndEndIndex)(lineContent, col, col + child.value.length) + '` ' + _chalk2.default.grey(MSG)
});
}
});
});
};
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlL3JlcXVpcmUtYXJvdW5kLXNwYWNlLmpzIl0sIm5hbWVzIjpbIlJVTEVOQU1FIiwiTVNHIiwiY2hlY2siLCJwb3N0Y3NzIiwicGx1Z2luIiwiY3NzIiwicmVzdWx0Iiwib3B0cyIsInJ1bGVWYWwiLCJ3YWxrRGVjbHMiLCJ2YWx1ZUFzdCIsImRlY2wiLCJ2YWx1ZSIsInBhcnNlIiwid2FsayIsImNoaWxkIiwidHlwZSIsInBhcmVudCIsImluZGV4IiwibmV4dEVsZW0iLCJub2RlcyIsInByZXZFbGVtIiwicmF3cyIsImJlZm9yZSIsImJldHdlZW4iLCJwcm9wIiwiaXNCZWZvcmVWYWxpZCIsInRlc3QiLCJpc0FmdGVyVmFsaWQiLCJwcm9ibGVtRWxlbSIsInNvdXJjZSIsImxpbmUiLCJzdGFydCIsImxpbmVDb250ZW50IiwiaW5wdXQiLCJjb2wiLCJjb2x1bW4iLCJsZW5ndGgiLCJ3YXJuIiwibm9kZSIsInJ1bGVOYW1lIiwibWVzc2FnZSIsImNvbG9yTWVzc2FnZSIsImNoYWxrIiwiZ3JleSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQU9BOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUVBOzs7O0FBWEE7Ozs7Ozs7QUFhQTs7QUFFQTs7Ozs7O0FBTUEsSUFBTUEsV0FBVyxzQkFBakI7O0FBRUE7Ozs7OztBQU1BLElBQU1DLE1BQU0sZ0VBQVo7O0FBRUE7Ozs7Ozs7O0FBUU8sSUFBTUMsd0JBQVFDLGtCQUFRQyxNQUFSLENBQWVKLFFBQWYsRUFBeUI7QUFBQSxXQUMxQyxVQUFDSyxHQUFELEVBQU1DLE1BQU4sRUFBaUI7QUFDYixZQUFJLENBQUNDLEtBQUtDLE9BQVYsRUFBbUI7QUFDZjtBQUNIOztBQUVEO0FBQ0FILFlBQUlJLFNBQUosQ0FBYyxnQkFBUTtBQUNsQixnQkFBTUMsV0FBVyxtQ0FBT0MsS0FBS0MsS0FBWixFQUFtQkMsS0FBbkIsRUFBakI7O0FBRUFILHFCQUFTSSxJQUFULENBQWMsaUJBQVM7QUFDbkIsb0JBQUlDLE1BQU1D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eUIsTUFBbEUsQ0FEUSxHQUVSLElBRlEsR0FHUk0sZ0JBQU1DLElBQU4sQ0FBVzNDLEdBQVg7QUFUWSxxQkFBdEI7QUFXSDtBQUNKLGFBdkVEO0FBd0VILFNBM0VEO0FBNEVILEtBbkZ5QztBQUFBLENBQXpCLENBQWQiLCJmaWxlIjoicmVxdWlyZS1hcm91bmQtc3BhY2UuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmaWxlIOi/kOeul+espuajgOmqjFxuICogICAgICAgKyAvIC0gLyAqIC8gLyDlm5vkuKrov5DnrpfnrKbkuKTkvqflv4XpobvvvIhNVVNU77yJ5L+d55WZ5LiA5Liq56m65qC844CCXG4gKiAgICAgICBodHRwczovL2dpdGh1Yi5jb20vZWNvbWZlL3NwZWMvYmxvYi9tYXN0ZXIvbGVzcy1jb2RlLXN0eWxlLm1kIyVFOCVCRiU5MCVFNyVBRSU5N1xuICogQGF1dGhvciBpZWxnbmF3KHd1amkwMjIzQGdtYWlsLmNvbSlcbiAqL1xuXG5pbXBvcnQgY2hhbGsgZnJvbSAnY2hhbGsnO1xuaW1wb3J0IHBvc3Rjc3MgZnJvbSAncG9zdGNzcyc7XG5pbXBvcnQgcGFyc2VyIGZyb20gJ3Bvc3Rjc3MtdmFsdWVzLXBhcnNlcic7XG5cbmltcG9ydCB7Z2V0TGluZUNvbnRlbnQsIGNoYW5nZUNvbG9yQnlTdGFydEFuZEVuZEluZGV4fSBmcm9tICcuLi91dGlsJztcblxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIOinhOWImeWQjeensFxuICpcbiAqIEBjb25zdFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgUlVMRU5BTUUgPSAncmVxdWlyZS1hcm91bmQtc3BhY2UnO1xuXG4vKipcbiAqIOmUmeivr+S/oeaBr1xuICpcbiAqIEBjb25zdFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgTVNHID0gJ2ArYOOAgWAtYOOAgWAqYOOAgWAvYCBmb3VyIG9wZXJhdG9ycyBvbiBib3RoIHNpZGVzIG11c3Qga2VlcCBhIHNwYWNlJztcblxuLyoqXG4gKiDlhbfkvZPnmoTmo4DmtYvpgLvovpFcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cyDlj4LmlbBcbiAqIEBwYXJhbSB7Kn0gb3B0cy5ydWxlVmFsIOW9k+WJjeinhOWImeWFt+S9k+mFjee9rueahOWAvFxuICogQHBhcmFtIHtzdHJpbmd9IG9wdHMuZmlsZUNvbnRlbnQg5paH5Lu25YaF5a65XG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0cy5maWxlUGF0aCDmlofku7bot6/lvoRcbiAqL1xuZXhwb3J0IGNvbnN0IGNoZWNrID0gcG9zdGNzcy5wbHVnaW4oUlVMRU5BTUUsIG9wdHMgPT5cbiAgICAoY3NzLCByZXN1bHQpID0+IHtcbiAgICAgICAgaWYgKCFvcHRzLnJ1bGVWYWwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qIGpzaGludCBtYXhjb21wbGV4aXR5OmZhbHNlICovXG4gICAgICAgIGNzcy53YWxrRGVjbHMoZGVjbCA9PiB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZUFzdCA9IHBhcnNlcihkZWNsLnZhbHVlKS5wYXJzZSgpO1xuXG4gICAgICAgICAgICB2YWx1ZUFzdC53YWxrKGNoaWxkID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGQudHlwZSAhPT0gJ29wZXJhdG9yJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3Qge3BhcmVudH0gPSBjaGlsZDtcblxuICAgICAgICAgICAgICAgIC8vIOW9k+WJjSBjaGlsZCDnmoTntKLlvJVcbiAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcmVudC5pbmRleChjaGlsZCk7XG5cbiAgICAgICAgICAgICAgICAvLyBjaGlsZCDnmoTlkI7kuIDkuKrlhYPntKBcbiAgICAgICAgICAgICAgICBjb25zdCBuZXh0RWxlbSA9IHBhcmVudC5ub2Rlc1tpbmRleCArIDFdO1xuXG4gICAgICAgICAgICAgICAgLy8gY2hpbGQg55qE5YmN5LiA5Liq5YWD57SgXG4gICAgICAgICAgICAgICAgY29uc3QgcHJldkVsZW0gPSBwYXJlbnQubm9kZXNbaW5kZXggLSAxXTtcblxuICAgICAgICAgICAgICAgIC8vIOW/veeVpei0n+aVsCAtMVxuICAgICAgICAgICAgICAgIGlmIChjaGlsZC52YWx1ZSA9PT0gJy0nXG4gICAgICAgICAgICAgICAgICAgICYmIChjaGlsZC5yYXdzLmJlZm9yZSB8fCBkZWNsLnJhd3MuYmV0d2VlbilcbiAgICAgICAgICAgICAgICAgICAgJiYgbmV4dEVsZW0udHlwZSA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICAgICAgICAgJiYgIW5leHRFbGVtLnJhd3MuYmVmb3JlXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyDlv73nlaXlj5jph48gLUBmb29cbiAgICAgICAgICAgICAgICBpZiAoY2hpbGQudmFsdWUgPT09ICctJ1xuICAgICAgICAgICAgICAgICAgICAmJiAoY2hpbGQucmF3cy5iZWZvcmUgfHwgZGVjbC5yYXdzLmJldHdlZW4pXG4gICAgICAgICAgICAgICAgICAgICYmIG5leHRFbGVtLnR5cGUgPT09ICdhdHdvcmQnXG4gICAgICAgICAgICAgICAgICAgICYmICFuZXh0RWxlbS5yYXdzLmJlZm9yZVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8g5b+955WlIGZvbnQtc2l6ZS9saW5lLWhlaWdodCDnroDlhpnlrprkuYlcbiAgICAgICAgICAgICAgICBpZiAoZGVjbC5wcm9wID09PSAnZm9udCdcbiAgICAgICAgICAgICAgICAgICAgJiYgY2hpbGQudmFsdWUgPT09ICcvJ1xuICAgICAgICAgICAgICAgICAgICAmJiBwcmV2RWxlbS50eXBlID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgICAgICAgICAmJiBuZXh0RWxlbS50eXBlID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8g5Yik5patIG9wZXJhdG9yIOWJjemdouaYr+WQpuacieepuuagvFxuICAgICAgICAgICAgICAgIGNvbnN0IGlzQmVmb3JlVmFsaWQgPSBjaGlsZC5yYXdzLmJlZm9yZSA9PT0gJyAnIHx8IC9eXFxzLy50ZXN0KGNoaWxkLnJhd3MuYmVmb3JlKTtcblxuICAgICAgICAgICAgICAgIC8vIOWIpOaWrSBvcGVyYXRvciDlkI7pnaLmmK/lkKbmnInnqbrmoLxcbiAgICAgICAgICAgICAgICBjb25zdCBpc0FmdGVyVmFsaWQgPSBuZXh0RWxlbS5yYXdzLmJlZm9yZSA9PT0gJyAnIHx8IC9cXHMkLy50ZXN0KG5leHRFbGVtLnJhd3MuYmVmb3JlKTtcblxuICAgICAgICAgICAgICAgIGlmICghaXNCZWZvcmVWYWxpZCB8fCAhaXNBZnRlclZhbGlkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHByb2JsZW1FbGVtID0gIS9cXHMkLy50ZXN0KGNoaWxkLnJhd3MuYmVmb3JlKSA/IGNoaWxkIDogbmV4dEVsZW07XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHtzb3VyY2UsIHByb3AsIHJhd3N9ID0gZGVjbDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGluZSA9IHNvdXJjZS5zdGFydC5saW5lO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsaW5lQ29udGVudCA9IGdldExpbmVDb250ZW50KGxpbmUsIHNvdXJjZS5pbnB1dC5jc3MsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb2wgPSAwXG4gICAgICAgICAgICAgICAgICAgICAgICArIHNvdXJjZS5zdGFydC5jb2x1bW4gKyBwcm9wLmxlbmd0aCArIHJhd3MuYmV0d2Vlbi5sZW5ndGggKyBwcm9ibGVtRWxlbS5zb3VyY2Uuc3RhcnQuY29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAtIDFcbiAgICAgICAgICAgICAgICAgICAgICAgIC0gKGlzQmVmb3JlVmFsaWQgPyBjaGlsZC52YWx1ZS5sZW5ndGggOiAwKTtcblxuICAgICAgICAgICAgICAgICAgICByZXN1bHQud2FybihSVUxFTkFNRSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogZGVjbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVOYW1lOiBSVUxFTkFNRSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmU6IGxpbmUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2w6IGNvbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdgJyArIGxpbmVDb250ZW50ICsgJ2AgJyArIE1TRyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yTWVzc2FnZTogJ2AnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBjaGFuZ2VDb2xvckJ5U3RhcnRBbmRFbmRJbmRleChsaW5lQ29udGVudCwgY29sLCBjb2wgKyBjaGlsZC52YWx1ZS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAnYCAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBjaGFsay5ncmV5KE1TRylcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbik7XG4iXX0=
;