wrap-for-optimizing.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. var BACKSLASH_HACK = '\\';
  2. var IMPORTANT_WORD = 'important';
  3. var IMPORTANT_TOKEN = '!'+IMPORTANT_WORD;
  4. var IMPORTANT_WORD_MATCH = new RegExp(IMPORTANT_WORD+'$', 'i');
  5. var IMPORTANT_TOKEN_MATCH = new RegExp(IMPORTANT_TOKEN+'$', 'i');
  6. var STAR_HACK = '*';
  7. var UNDERSCORE_HACK = '_';
  8. var BANG_HACK = '!';
  9. function wrapAll(properties) {
  10. var wrapped = [];
  11. for (var i = properties.length - 1; i >= 0; i--) {
  12. if (typeof properties[i][0] == 'string')
  13. continue;
  14. var single = wrapSingle(properties[i]);
  15. single.all = properties;
  16. single.position = i;
  17. wrapped.unshift(single);
  18. }
  19. return wrapped;
  20. }
  21. function isMultiplex(property) {
  22. for (var i = 1, l = property.length; i < l; i++) {
  23. if (property[i][0] == ',' || property[i][0] == '/')
  24. return true;
  25. }
  26. return false;
  27. }
  28. function hackType(property) {
  29. var type = false;
  30. var name = property[0][0];
  31. var lastValue = property[property.length - 1];
  32. if (name[0] == UNDERSCORE_HACK) {
  33. type = 'underscore';
  34. } else if (name[0] == STAR_HACK) {
  35. type = 'star';
  36. } else if (lastValue[0][0] == BANG_HACK && !lastValue[0].match(IMPORTANT_WORD_MATCH)) {
  37. type = 'bang';
  38. } else if (lastValue[0].indexOf(BANG_HACK) > 0 && !lastValue[0].match(IMPORTANT_WORD_MATCH)) {
  39. type = 'bang';
  40. } else if (lastValue[0].indexOf(BACKSLASH_HACK) > 0 && lastValue[0].indexOf(BACKSLASH_HACK) == lastValue[0].length - BACKSLASH_HACK.length - 1) {
  41. type = 'backslash';
  42. } else if (lastValue[0].indexOf(BACKSLASH_HACK) === 0 && lastValue[0].length == 2) {
  43. type = 'backslash';
  44. }
  45. return type;
  46. }
  47. function isImportant(property) {
  48. if (property.length > 1) {
  49. var p = property[property.length - 1][0];
  50. if (typeof(p) === 'string') {
  51. return IMPORTANT_TOKEN_MATCH.test(p);
  52. }
  53. }
  54. return false;
  55. }
  56. function stripImportant(property) {
  57. if (property.length > 0)
  58. property[property.length - 1][0] = property[property.length - 1][0].replace(IMPORTANT_TOKEN_MATCH, '');
  59. }
  60. function stripPrefixHack(property) {
  61. property[0][0] = property[0][0].substring(1);
  62. }
  63. function stripSuffixHack(property, hackType) {
  64. var lastValue = property[property.length - 1];
  65. lastValue[0] = lastValue[0]
  66. .substring(0, lastValue[0].indexOf(hackType == 'backslash' ? BACKSLASH_HACK : BANG_HACK))
  67. .trim();
  68. if (lastValue[0].length === 0)
  69. property.pop();
  70. }
  71. function wrapSingle(property) {
  72. var _isImportant = isImportant(property);
  73. if (_isImportant)
  74. stripImportant(property);
  75. var _hackType = hackType(property);
  76. if (_hackType == 'star' || _hackType == 'underscore')
  77. stripPrefixHack(property);
  78. else if (_hackType == 'backslash' || _hackType == 'bang')
  79. stripSuffixHack(property, _hackType);
  80. var isVariable = property[0][0].indexOf('--') === 0;
  81. return {
  82. block: isVariable && property[1] && Array.isArray(property[1][0][0]),
  83. components: [],
  84. dirty: false,
  85. hack: _hackType,
  86. important: _isImportant,
  87. name: property[0][0],
  88. multiplex: property.length > 2 ? isMultiplex(property) : false,
  89. position: 0,
  90. shorthand: false,
  91. unused: property.length < 2,
  92. value: property.slice(1),
  93. variable: isVariable
  94. };
  95. }
  96. module.exports = {
  97. all: wrapAll,
  98. single: wrapSingle
  99. };