declaration.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. (function() {
  2. var Browsers, Declaration, Prefixer, utils,
  3. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  4. hasProp = {}.hasOwnProperty;
  5. Prefixer = require('./prefixer');
  6. Browsers = require('./browsers');
  7. utils = require('./utils');
  8. Declaration = (function(superClass) {
  9. extend(Declaration, superClass);
  10. function Declaration() {
  11. return Declaration.__super__.constructor.apply(this, arguments);
  12. }
  13. Declaration.prototype.check = function(decl) {
  14. return true;
  15. };
  16. Declaration.prototype.prefixed = function(prop, prefix) {
  17. return prefix + prop;
  18. };
  19. Declaration.prototype.normalize = function(prop) {
  20. return prop;
  21. };
  22. Declaration.prototype.otherPrefixes = function(value, prefix) {
  23. var j, len, other, ref;
  24. ref = Browsers.prefixes();
  25. for (j = 0, len = ref.length; j < len; j++) {
  26. other = ref[j];
  27. if (other === prefix) {
  28. continue;
  29. }
  30. if (value.indexOf(other) !== -1) {
  31. return true;
  32. }
  33. }
  34. return false;
  35. };
  36. Declaration.prototype.set = function(decl, prefix) {
  37. decl.prop = this.prefixed(decl.prop, prefix);
  38. return decl;
  39. };
  40. Declaration.prototype.needCascade = function(decl) {
  41. return decl._autoprefixerCascade || (decl._autoprefixerCascade = this.all.options.cascade !== false && decl.raw('before').indexOf('\n') !== -1);
  42. };
  43. Declaration.prototype.maxPrefixed = function(prefixes, decl) {
  44. var j, len, max, prefix;
  45. if (decl._autoprefixerMax) {
  46. return decl._autoprefixerMax;
  47. }
  48. max = 0;
  49. for (j = 0, len = prefixes.length; j < len; j++) {
  50. prefix = prefixes[j];
  51. prefix = utils.removeNote(prefix);
  52. if (prefix.length > max) {
  53. max = prefix.length;
  54. }
  55. }
  56. return decl._autoprefixerMax = max;
  57. };
  58. Declaration.prototype.calcBefore = function(prefixes, decl, prefix) {
  59. var before, diff, i, j, max, ref;
  60. if (prefix == null) {
  61. prefix = '';
  62. }
  63. before = decl.raw('before');
  64. max = this.maxPrefixed(prefixes, decl);
  65. diff = max - utils.removeNote(prefix).length;
  66. for (i = j = 0, ref = diff; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
  67. before += ' ';
  68. }
  69. return before;
  70. };
  71. Declaration.prototype.restoreBefore = function(decl) {
  72. var lines, min;
  73. lines = decl.raw('before').split("\n");
  74. min = lines[lines.length - 1];
  75. this.all.group(decl).up(function(prefixed) {
  76. var array, last;
  77. array = prefixed.raw('before').split("\n");
  78. last = array[array.length - 1];
  79. if (last.length < min.length) {
  80. return min = last;
  81. }
  82. });
  83. lines[lines.length - 1] = min;
  84. return decl.raws.before = lines.join("\n");
  85. };
  86. Declaration.prototype.insert = function(decl, prefix, prefixes) {
  87. var already, cloned;
  88. cloned = this.set(this.clone(decl), prefix);
  89. if (!cloned) {
  90. return;
  91. }
  92. already = decl.parent.some(function(i) {
  93. return i.prop === cloned.prop && i.value === cloned.value;
  94. });
  95. if (already) {
  96. return;
  97. }
  98. if (this.needCascade(decl)) {
  99. cloned.raws.before = this.calcBefore(prefixes, decl, prefix);
  100. }
  101. return decl.parent.insertBefore(decl, cloned);
  102. };
  103. Declaration.prototype.isAlready = function(decl, prefixed) {
  104. var already;
  105. already = this.all.group(decl).up(function(i) {
  106. return i.prop === prefixed;
  107. });
  108. already || (already = this.all.group(decl).down(function(i) {
  109. return i.prop === prefixed;
  110. }));
  111. return already;
  112. };
  113. Declaration.prototype.add = function(decl, prefix, prefixes) {
  114. var prefixed;
  115. prefixed = this.prefixed(decl.prop, prefix);
  116. if (this.isAlready(decl, prefixed) || this.otherPrefixes(decl.value, prefix)) {
  117. return;
  118. }
  119. return this.insert(decl, prefix, prefixes);
  120. };
  121. Declaration.prototype.process = function(decl) {
  122. var prefixes;
  123. if (this.needCascade(decl)) {
  124. prefixes = Declaration.__super__.process.apply(this, arguments);
  125. if (prefixes != null ? prefixes.length : void 0) {
  126. this.restoreBefore(decl);
  127. return decl.raws.before = this.calcBefore(prefixes, decl);
  128. }
  129. } else {
  130. return Declaration.__super__.process.apply(this, arguments);
  131. }
  132. };
  133. Declaration.prototype.old = function(prop, prefix) {
  134. return [this.prefixed(prop, prefix)];
  135. };
  136. return Declaration;
  137. })(Prefixer);
  138. module.exports = Declaration;
  139. }).call(this);