You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							86 lines
						
					
					
						
							2.5 KiB
						
					
					
				
			
		
		
	
	
							86 lines
						
					
					
						
							2.5 KiB
						
					
					
				var walk = require('css-tree').walk; | 
						|
var utils = require('./utils'); | 
						|
 | 
						|
/* | 
						|
    At this step all rules has single simple selector. We try to join by equal | 
						|
    declaration blocks to first rule, e.g. | 
						|
 | 
						|
    .a { color: red } | 
						|
    b { ... } | 
						|
    .b { color: red } | 
						|
    -> | 
						|
    .a, .b { color: red } | 
						|
    b { ... } | 
						|
*/ | 
						|
 | 
						|
function processRule(node, item, list) { | 
						|
    var selectors = node.prelude.children; | 
						|
    var declarations = node.block.children; | 
						|
    var nodeCompareMarker = selectors.first().compareMarker; | 
						|
    var skippedCompareMarkers = {}; | 
						|
 | 
						|
    list.nextUntil(item.next, function(next, nextItem) { | 
						|
        // skip non-ruleset node if safe | 
						|
        if (next.type !== 'Rule') { | 
						|
            return utils.unsafeToSkipNode.call(selectors, next); | 
						|
        } | 
						|
 | 
						|
        if (node.pseudoSignature !== next.pseudoSignature) { | 
						|
            return true; | 
						|
        } | 
						|
 | 
						|
        var nextFirstSelector = next.prelude.children.head; | 
						|
        var nextDeclarations = next.block.children; | 
						|
        var nextCompareMarker = nextFirstSelector.data.compareMarker; | 
						|
 | 
						|
        // if next ruleset has same marked as one of skipped then stop joining | 
						|
        if (nextCompareMarker in skippedCompareMarkers) { | 
						|
            return true; | 
						|
        } | 
						|
 | 
						|
        // try to join by selectors | 
						|
        if (selectors.head === selectors.tail) { | 
						|
            if (selectors.first().id === nextFirstSelector.data.id) { | 
						|
                declarations.appendList(nextDeclarations); | 
						|
                list.remove(nextItem); | 
						|
                return; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        // try to join by properties | 
						|
        if (utils.isEqualDeclarations(declarations, nextDeclarations)) { | 
						|
            var nextStr = nextFirstSelector.data.id; | 
						|
 | 
						|
            selectors.some(function(data, item) { | 
						|
                var curStr = data.id; | 
						|
 | 
						|
                if (nextStr < curStr) { | 
						|
                    selectors.insert(nextFirstSelector, item); | 
						|
                    return true; | 
						|
                } | 
						|
 | 
						|
                if (!item.next) { | 
						|
                    selectors.insert(nextFirstSelector); | 
						|
                    return true; | 
						|
                } | 
						|
            }); | 
						|
 | 
						|
            list.remove(nextItem); | 
						|
            return; | 
						|
        } | 
						|
 | 
						|
        // go to next ruleset if current one can be skipped (has no equal specificity nor element selector) | 
						|
        if (nextCompareMarker === nodeCompareMarker) { | 
						|
            return true; | 
						|
        } | 
						|
 | 
						|
        skippedCompareMarkers[nextCompareMarker] = true; | 
						|
    }); | 
						|
} | 
						|
 | 
						|
module.exports = function mergeRule(ast) { | 
						|
    walk(ast, { | 
						|
        visit: 'Rule', | 
						|
        enter: processRule | 
						|
    }); | 
						|
};
 | 
						|
 |