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.

78 lines
2.5 KiB

4 years ago
  1. var canReorder = require('./reorderable').canReorder;
  2. var extractProperties = require('./extract-properties');
  3. var optimizeProperties = require('./properties/optimize');
  4. var serializeRules = require('../../writer/one-time').rules;
  5. var Token = require('../../tokenizer/token');
  6. function mergeNonAdjacentBySelector(tokens, context) {
  7. var specificityCache = context.cache.specificity;
  8. var allSelectors = {};
  9. var repeatedSelectors = [];
  10. var i;
  11. for (i = tokens.length - 1; i >= 0; i--) {
  12. if (tokens[i][0] != Token.RULE)
  13. continue;
  14. if (tokens[i][2].length === 0)
  15. continue;
  16. var selector = serializeRules(tokens[i][1]);
  17. allSelectors[selector] = [i].concat(allSelectors[selector] || []);
  18. if (allSelectors[selector].length == 2)
  19. repeatedSelectors.push(selector);
  20. }
  21. for (i = repeatedSelectors.length - 1; i >= 0; i--) {
  22. var positions = allSelectors[repeatedSelectors[i]];
  23. selectorIterator:
  24. for (var j = positions.length - 1; j > 0; j--) {
  25. var positionOne = positions[j - 1];
  26. var tokenOne = tokens[positionOne];
  27. var positionTwo = positions[j];
  28. var tokenTwo = tokens[positionTwo];
  29. directionIterator:
  30. for (var direction = 1; direction >= -1; direction -= 2) {
  31. var topToBottom = direction == 1;
  32. var from = topToBottom ? positionOne + 1 : positionTwo - 1;
  33. var to = topToBottom ? positionTwo : positionOne;
  34. var delta = topToBottom ? 1 : -1;
  35. var moved = topToBottom ? tokenOne : tokenTwo;
  36. var target = topToBottom ? tokenTwo : tokenOne;
  37. var movedProperties = extractProperties(moved);
  38. while (from != to) {
  39. var traversedProperties = extractProperties(tokens[from]);
  40. from += delta;
  41. // traversed then moved as we move selectors towards the start
  42. var reorderable = topToBottom ?
  43. canReorder(movedProperties, traversedProperties, specificityCache) :
  44. canReorder(traversedProperties, movedProperties, specificityCache);
  45. if (!reorderable && !topToBottom)
  46. continue selectorIterator;
  47. if (!reorderable && topToBottom)
  48. continue directionIterator;
  49. }
  50. if (topToBottom) {
  51. Array.prototype.push.apply(moved[2], target[2]);
  52. target[2] = moved[2];
  53. } else {
  54. Array.prototype.push.apply(target[2], moved[2]);
  55. }
  56. optimizeProperties(target[2], true, true, context);
  57. moved[2] = [];
  58. }
  59. }
  60. }
  61. }
  62. module.exports = mergeNonAdjacentBySelector;