mcss icon indicating copy to clipboard operation
mcss copied to clipboard

80line implement more powerful csscss (https://github.com/zmoazeni/csscss) version

Open leeluolee opened this issue 11 years ago • 0 comments

作为parser使用的mcss 可以在80l 代码内 实现 csscss (一个检测冗余css的工具) 的功能,并且更加强大,可以检测多个文件内的重复 并且得到准确的位置信息 和 css 样式生命信息,如图所示 检查一个github.css

代码如下test/fixtures/csscss.js中可察看

/**
 * Example csscss.js 
 * 60 line code base on mcss we can have a more powerful csscss
 * @type {[type]}
 */
var mcss = require('mcss');
var path = require('path');
var node = mcss.node;
// 改变颜色帮助识别console.log
var color = mcss.helper.color;


var rulesets = [], 
    // 允许的delaration最大重复率
    MAX_DUPLICATES = 6,
    // 自定义walker,在这里我们只对rulset感兴趣
    walkers = {
        'ruleset': function(ast){
            // 获取ruleset的块中的declaration列表
            var list = ast.block.list,
                selector = node.toStr(ast.selector),
                res = {
                    selector:selector, 
                    filename:ast.filename,
                    lineno: ast.lineno,
                    map:{}
                },
                sign, map = res.map;

            list.forEach(function(declaration){

                if(declaration.type === 'declaration'){

                    sign = node.toStr(declaration.property)+':'+mcss.node.toStr(declaration.value);
                    if(!map[sign]) map[sign] = true;
                }
            });

            rulesets.push(res);
        }
    }
// use a map, achieve O(n) to find duplicates.
function findDupls(a, b){
    var alist = a.map,
        blist = b.map,
        duplicates = [];

    for(var i in blist){
        if(alist[i]) duplicates.push(i)
    }
    return duplicates;
}


// mcss 实例创建
var instance = mcss({
    // 这个css 来自 github.com 官网 的css  ... 重复率惊人
    filename: path.join(__dirname, '../data/csscss_1.css'),
    // 默认是不引入 css file的
    importCSS: true,
    // 传入我们的自定义walker
    walkers: [walkers]
})

// 所有mcss操作(解释、翻译、词法)都由统一的instance开始
// 以下是解释
instance.interpret().done(function(ast){
    var len = rulesets.length, 
        mapa, mapb, jlen, duplicates;

    for(; len-- ;){

        jlen = len; 
        mapa = rulesets[len];

        for(; jlen--;){
            mapb = rulesets[jlen];
            duplicates = findDupls(mapa, mapb);
            if(duplicates.length > MAX_DUPLICATES){
                console.log(
                    color(mapa.selector, 'red') + ' at ('+ color(mapa.filename + ':' + mapa.lineno, 'yellow') + ') and \n' +
                    color(mapb.selector, 'red') + ' at ('+ color(mapb.filename + ':' + mapb.lineno, 'yellow') + ') has ' + color(duplicates.length, 'blue') + ' duplicates:\n\t' +
                    duplicates.join(',\n\t')
                    )
            }
        }
    }
}).fail(function(err){
    throw err;
})

leeluolee avatar Jun 29 '13 12:06 leeluolee