all files / htmlcs/lib/rules/ no-duplication-id-and-name.js

100% Statements 35/35
100% Branches 22/22
100% Functions 8/8
100% Lines 35/35
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82                            103× 102×     13×     13×   13×         13×   13× 13×   13× 13×   13×     13×                                      
/**
 * @file rule: no-duplication-id-and-name
 * @author chris<wfsr@foxmail.com>
 */
 
module.exports = {
 
    name: 'no-duplication-id-and-name',
 
    desc: 'Element\'s id and name should be unique in page.',
 
    target: 'parser',
 
    lint: function (getCfg, parser, reporter) {
 
        if (!getCfg()) {
            return;
        }
 
        var stack = [];
        parser.tokenizer.on('opentagname', function () {
            stack.push({});
        });
 
        parser.tokenizer.on('attribdata', function (value) {
            var name = parser._attribname.toLowerCase();
 
            if (name !== 'id' && name !== 'name') {
                return;
            }
 
            var tag = stack[stack.length - 1];
            tag[name] = {type: name, value: value, pos: this._sectionStart};
        });
 
        var idMap = {};
        var nameMap = {};
        parser.tokenizer.on('opentagend', function () {
            var el = stack.pop();
 
            var id = el.id;
            var name = el.name;
 
            var idValue = id && id.value;
            var nameValue = name && name.value;
 
            if (name && !nameMap[nameValue]) {
                nameMap[nameValue] = name;
            }
 
            if (id && idValue !== nameValue) {
                idMap[idValue] = idMap[idValue] || [];
                idMap[idValue].push(id);
            }
        });
 
        function getMessage(item) {
            return ''
                + 'Expected id and name to be unique in page but found duplication('
                + item.value
                + ').';
        }
 
        parser.on('end', function () {
            stack.length = 0;
 
            Object.keys(nameMap).forEach(function (key) {
                if (!idMap[key]) {
                    return;
                }
 
                reporter.warn(nameMap[key].pos, '043', getMessage(nameMap[key]));
 
                idMap[key].forEach(function (item) {
                    reporter.warn(item.pos, '043', getMessage(item));
                });
            });
        });
    }
 
};