merge-non-adjacent-by-selector.js 2.5 KB

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