Skip to content

Commit

Permalink
add htmlhint
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswong committed Nov 20, 2014
1 parent 92e7120 commit baaed62
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 3 deletions.
101 changes: 101 additions & 0 deletions lib/html/checker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* @file jscs checker
* @author chris<wfsr@foxmail.com>
*/

var through = require('through2');
var HTMLHint = require('htmlhint').HTMLHint;
var RcLoader = require('rcloader2');

/**
* 根据文件路径中扩展名判断当前能否处理
*
* @param {string} path 文件路径
* @return {boolean} 是否可处理
*/
function canHandle(path) {
return /\.html$/.test(path);
}


/**
* 负责代码风格检查的转换流
*
* @param {Object} options 配置项
* @return {Transform} 转换流
*/
module.exports = function (options) {
var util = require('../util');

var config = require('./config');
var defaultHTMLHintConfig = config.htmlhint;
var htmlhintRcloader = new RcLoader('.htmlhintrc', defaultHTMLHintConfig, {loader: util.parseJSON});
var checked = {};

return through(
{
objectMode: true
},

function (file, enc, cb) {
if (checked[file.path] || !canHandle(file.path) || file.isNull()) {
cb(null, file);
return;
}

file.errors = [];
checked[file.path] = true;

var htmlhintConfig = options.lookup
? htmlhintRcloader.for(file.path)
: htmlhintRcloader;

try {

var contents = file.contents.toString();

HTMLHint.verify(contents, htmlhintConfig).forEach(function (error) {
file.errors.push(
util.parseError(
{
type: 'html',
checker: 'htmlhint',
rule: error.rule.id
},
error
)
);
});


cb(null, file);

}
catch (error) {
if (options.debug) {
throw error;
}

file.errors.push(
util.parseError(
{
type: 'html',
checker: 'htmlhint',
code: '999'
},
error
)
);
cb(null, file);
}


},

function (cb) {
htmlhintRcloader = null;
checked = null;
cb();
}
);
};
10 changes: 10 additions & 0 deletions lib/html/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* @file HTML 检查规则配置模块
* @author chris<wfsr@foxmail.com>
*/

var util = require('../util');

// 读取当前目录下的 json 文件,以文件名为 key 对外 export
// json 配置文件中可以使用 javascript 注释
util.readConfigs(__dirname, exports);
24 changes: 24 additions & 0 deletions lib/html/htmlhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"attr-lowercase": true,
"attr-no-duplication": true,
"attr-unsafe-chars": true,
"attr-value-double-quotes": true,
// "attr-value-not-empty": false,
// "csslint": {},
"doctype-first": true,
"doctype-html5": true,
"head-script-disabled": true,
// "href-abs-or-rel": true,
"id-class-ad-disabled": true,
"id-class-value": "dash",
"id-unique": true,
"imgalt-require": true,
// "jshint": {},
"space-tab-mixed-disabled": true,
"spec-char-escape": true,
"src-not-empty": true,
"style-disabled": true,
"tag-pair": true,
// "tag-self-close": true,
"tagname-lowercase": true
}
24 changes: 24 additions & 0 deletions lib/reporter/baidu/htmlhint-map.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"attr-lowercase": "017",
"attr-no-duplication": "997",
"attr-unsafe-chars": "998",
"attr-value-double-quotes": "018",
// "attr-value-not-empty": "019",
// "csslint": true,
"doctype-first": "998",
"doctype-html5": "021",
"head-script-disabled": "030",
// "href-abs-or-rel": "997",
"id-class-ad-disabled": "998",
"id-class-value": "006",
"id-unique": "005",
"img-alt-require": "038",
// "jshint": true,
"space-tab-mixed-disabled": "001",
"spec-char-escape": "997",
"src-not-empty": "036",
"style-disabled": "028",
"tag-pair": "012",
// "tag-self-close": "011",
"tagname-lowercase": "010"
}
32 changes: 31 additions & 1 deletion lib/reporter/baidu/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ var baidu = {

},


htmlhintRules: {},

/**
* 针对 csshint 校验错误的处理
Expand Down Expand Up @@ -140,6 +140,36 @@ var baidu = {
code = '000';
}

return 'rule ' + code + ': ' + desc;
},

/**
* 针对 htmlhint 校验错误的处理
*
* @param {!Object} error htmlhint 的错误对象
* @param {!Object} level 错误的等级数据
* @return {string} 对应的规则编码入描述信息
*/
htmlhint: function (error, level) {
var code;

if (baidu.htmlhintRules[error.rule]) {
code = baidu.htmlhintRules[error.rule](error);
}
else {
code = maps.htmlhintMap[error.rule] || error.code;
}

var rule = maps.html[code];
var desc = error.message.replace(BAIDU_CODE_REG, '');
if (rule) {
level.warn = rule.level < 2 ? 1 : 0;
desc = rule.desc;
}
else {
code = '000';
}

return 'rule ' + code + ': ' + desc;
}
};
Expand Down
4 changes: 2 additions & 2 deletions test/lib/util.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ describe('util', function () {
var maps = {};
util.readConfigs('lib/html', maps);

expect(maps).toEqual({});
expect(maps.htmlhint).not.toBeUndefined();
});

it('from lib/reporter/baidu', function () {
Expand All @@ -113,7 +113,7 @@ describe('util', function () {
expect(maps.html).not.toBeUndefined();
expect(maps.eslintMap).not.toBeUndefined();
expect(maps.csshintMap).not.toBeUndefined();
expect(maps.htmlhintMap).toBeUndefined();
expect(maps.htmlhintMap).not.toBeUndefined();
});

});
Expand Down

0 comments on commit baaed62

Please sign in to comment.