74 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			74 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
var canReorder = require('./reorderable').canReorder;
 | 
						|
var extractProperties = require('./extract-properties');
 | 
						|
 | 
						|
var optimizeProperties = require('./properties/optimize');
 | 
						|
 | 
						|
var serializeRules = require('../../writer/one-time').rules;
 | 
						|
 | 
						|
var Token = require('../../tokenizer/token');
 | 
						|
 | 
						|
function mergeNonAdjacentBySelector(tokens, context) {
 | 
						|
  var specificityCache = context.cache.specificity;
 | 
						|
  var allSelectors = {};
 | 
						|
  var repeatedSelectors = [];
 | 
						|
  var i;
 | 
						|
 | 
						|
  for (i = tokens.length - 1; i >= 0; i--) {
 | 
						|
    if (tokens[i][0] != Token.RULE) { continue; }
 | 
						|
    if (tokens[i][2].length === 0) { continue; }
 | 
						|
 | 
						|
    var selector = serializeRules(tokens[i][1]);
 | 
						|
    allSelectors[selector] = [i].concat(allSelectors[selector] || []);
 | 
						|
 | 
						|
    if (allSelectors[selector].length == 2) { repeatedSelectors.push(selector); }
 | 
						|
  }
 | 
						|
 | 
						|
  for (i = repeatedSelectors.length - 1; i >= 0; i--) {
 | 
						|
    var positions = allSelectors[repeatedSelectors[i]];
 | 
						|
 | 
						|
    selectorIterator:
 | 
						|
    for (var j = positions.length - 1; j > 0; j--) {
 | 
						|
      var positionOne = positions[j - 1];
 | 
						|
      var tokenOne = tokens[positionOne];
 | 
						|
      var positionTwo = positions[j];
 | 
						|
      var tokenTwo = tokens[positionTwo];
 | 
						|
 | 
						|
      directionIterator:
 | 
						|
      for (var direction = 1; direction >= -1; direction -= 2) {
 | 
						|
        var topToBottom = direction == 1;
 | 
						|
        var from = topToBottom ? positionOne + 1 : positionTwo - 1;
 | 
						|
        var to = topToBottom ? positionTwo : positionOne;
 | 
						|
        var delta = topToBottom ? 1 : -1;
 | 
						|
        var moved = topToBottom ? tokenOne : tokenTwo;
 | 
						|
        var target = topToBottom ? tokenTwo : tokenOne;
 | 
						|
        var movedProperties = extractProperties(moved);
 | 
						|
 | 
						|
        while (from != to) {
 | 
						|
          var traversedProperties = extractProperties(tokens[from]);
 | 
						|
          from += delta;
 | 
						|
 | 
						|
          // traversed then moved as we move selectors towards the start
 | 
						|
          var reorderable = topToBottom
 | 
						|
            ? canReorder(movedProperties, traversedProperties, specificityCache)
 | 
						|
            : canReorder(traversedProperties, movedProperties, specificityCache);
 | 
						|
 | 
						|
          if (!reorderable && !topToBottom) { continue selectorIterator; }
 | 
						|
          if (!reorderable && topToBottom) { continue directionIterator; }
 | 
						|
        }
 | 
						|
 | 
						|
        if (topToBottom) {
 | 
						|
          Array.prototype.push.apply(moved[2], target[2]);
 | 
						|
          target[2] = moved[2];
 | 
						|
        } else {
 | 
						|
          Array.prototype.push.apply(target[2], moved[2]);
 | 
						|
        }
 | 
						|
 | 
						|
        optimizeProperties(target[2], true, true, context);
 | 
						|
        moved[2] = [];
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
module.exports = mergeNonAdjacentBySelector;
 |