-
-
Notifications
You must be signed in to change notification settings - Fork 374
/
tag-pair.js
56 lines (56 loc) · 2.34 KB
/
tag-pair.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
* Copyright (c) 2015, Yanis Wang <yanis.wang@gmail.com>
* MIT Licensed
*/
HTMLHint.addRule({
id: 'tag-pair',
description: 'Tag must be paired.',
init: function(parser, reporter){
var self = this;
var stack=[],
mapEmptyTags = parser.makeMap("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,track,command,source,keygen,wbr");//HTML 4.01 + HTML 5
parser.addListener('tagstart', function(event){
var tagName = event.tagName.toLowerCase();
if (mapEmptyTags[tagName] === undefined && !event.close){
stack.push({
tagName: tagName,
line: event.line,
raw: event.raw
});
}
});
parser.addListener('tagend', function(event){
var tagName = event.tagName.toLowerCase();
// Look up the matching start tag
for(var pos = stack.length-1;pos >= 0; pos--){
if(stack[pos].tagName === tagName){
break;
}
}
if(pos >= 0){
var arrTags = [];
for(var i=stack.length-1;i>pos;i--){
arrTags.push('</'+stack[i].tagName+'>');
}
if(arrTags.length > 0){
var lastEvent = stack[stack.length-1];
reporter.error('Tag must be paired, missing: [ '+ arrTags.join('') + ' ], start tag match failed [ ' + lastEvent.raw + ' ] on line ' + lastEvent.line + '.', event.line, event.col, self, event.raw);
}
stack.length=pos;
}
else{
reporter.error('Tag must be paired, no start tag: [ ' + event.raw + ' ]', event.line, event.col, self, event.raw);
}
});
parser.addListener('end', function(event){
var arrTags = [];
for(var i=stack.length-1;i>=0;i--){
arrTags.push('</'+stack[i].tagName+'>');
}
if(arrTags.length > 0){
var lastEvent = stack[stack.length-1];
reporter.error('Tag must be paired, missing: [ '+ arrTags.join('') + ' ], open tag match failed [ ' + lastEvent.raw + ' ] on line ' + lastEvent.line + '.', event.line, event.col, self, '');
}
});
}
});