declaration.js 4.9 KB

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