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.
73 lines
2.5 KiB
73 lines
2.5 KiB
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;
|
|
|