|
|
- 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;
|