Spaces:
Sleeping
Sleeping
| 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; | |