106 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
var canReorder = require('./reorderable').canReorder;
 | 
						|
var canReorderSingle = require('./reorderable').canReorderSingle;
 | 
						|
var extractProperties = require('./extract-properties');
 | 
						|
var rulesOverlap = require('./rules-overlap');
 | 
						|
 | 
						|
var serializeRules = require('../../writer/one-time').rules;
 | 
						|
var OptimizationLevel = require('../../options/optimization-level').OptimizationLevel;
 | 
						|
var Token = require('../../tokenizer/token');
 | 
						|
 | 
						|
function mergeMediaQueries(tokens, context) {
 | 
						|
  var mergeSemantically = context.options.level[OptimizationLevel.Two].mergeSemantically;
 | 
						|
  var specificityCache = context.cache.specificity;
 | 
						|
  var candidates = {};
 | 
						|
  var reduced = [];
 | 
						|
 | 
						|
  for (var i = tokens.length - 1; i >= 0; i--) {
 | 
						|
    var token = tokens[i];
 | 
						|
    if (token[0] != Token.NESTED_BLOCK) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    var key = serializeRules(token[1]);
 | 
						|
    var candidate = candidates[key];
 | 
						|
    if (!candidate) {
 | 
						|
      candidate = [];
 | 
						|
      candidates[key] = candidate;
 | 
						|
    }
 | 
						|
 | 
						|
    candidate.push(i);
 | 
						|
  }
 | 
						|
 | 
						|
  for (var name in candidates) {
 | 
						|
    var positions = candidates[name];
 | 
						|
 | 
						|
    positionLoop:
 | 
						|
    for (var j = positions.length - 1; j > 0; j--) {
 | 
						|
      var positionOne = positions[j];
 | 
						|
      var tokenOne = tokens[positionOne];
 | 
						|
      var positionTwo = positions[j - 1];
 | 
						|
      var tokenTwo = tokens[positionTwo];
 | 
						|
 | 
						|
      directionLoop:
 | 
						|
      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 source = topToBottom ? tokenOne : tokenTwo;
 | 
						|
        var target = topToBottom ? tokenTwo : tokenOne;
 | 
						|
        var movedProperties = extractProperties(source);
 | 
						|
 | 
						|
        while (from != to) {
 | 
						|
          var traversedProperties = extractProperties(tokens[from]);
 | 
						|
          from += delta;
 | 
						|
 | 
						|
          if (mergeSemantically
 | 
						|
            && allSameRulePropertiesCanBeReordered(movedProperties, traversedProperties, specificityCache)
 | 
						|
          ) {
 | 
						|
            continue;
 | 
						|
          }
 | 
						|
 | 
						|
          if (!canReorder(movedProperties, traversedProperties, specificityCache)) { continue directionLoop; }
 | 
						|
        }
 | 
						|
 | 
						|
        target[2] = topToBottom
 | 
						|
          ? source[2].concat(target[2])
 | 
						|
          : target[2].concat(source[2]);
 | 
						|
        source[2] = [];
 | 
						|
 | 
						|
        reduced.push(target);
 | 
						|
        continue positionLoop;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return reduced;
 | 
						|
}
 | 
						|
 | 
						|
function allSameRulePropertiesCanBeReordered(movedProperties, traversedProperties, specificityCache) {
 | 
						|
  var movedProperty;
 | 
						|
  var movedRule;
 | 
						|
  var traversedProperty;
 | 
						|
  var traversedRule;
 | 
						|
  var i, l;
 | 
						|
  var j, m;
 | 
						|
 | 
						|
  for (i = 0, l = movedProperties.length; i < l; i++) {
 | 
						|
    movedProperty = movedProperties[i];
 | 
						|
    movedRule = movedProperty[5];
 | 
						|
 | 
						|
    for (j = 0, m = traversedProperties.length; j < m; j++) {
 | 
						|
      traversedProperty = traversedProperties[j];
 | 
						|
      traversedRule = traversedProperty[5];
 | 
						|
 | 
						|
      if (rulesOverlap(movedRule, traversedRule, true)
 | 
						|
        && !canReorderSingle(movedProperty, traversedProperty, specificityCache)) {
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
module.exports = mergeMediaQueries;
 |