compatibility.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. var util = require('util');
  2. var DEFAULTS = {
  3. '*': {
  4. colors: {
  5. opacity: true // rgba / hsla
  6. },
  7. properties: {
  8. backgroundClipMerging: false, // background-clip to shorthand
  9. backgroundOriginMerging: false, // background-origin to shorthand
  10. backgroundSizeMerging: false, // background-size to shorthand
  11. colors: true, // any kind of color transformations, like `#ff00ff` to `#f0f` or `#fff` into `red`
  12. ieBangHack: false, // !ie suffix hacks on IE<8
  13. iePrefixHack: false, // underscore / asterisk prefix hacks on IE
  14. ieSuffixHack: true, // \9 suffix hacks on IE6-9
  15. merging: true, // merging properties into one
  16. shorterLengthUnits: false, // optimize pixel units into `pt`, `pc` or `in` units
  17. spaceAfterClosingBrace: true, // 'url() no-repeat' to 'url()no-repeat'
  18. urlQuotes: false, // whether to wrap content of `url()` into quotes or not
  19. zeroUnits: true // 0[unit] -> 0
  20. },
  21. selectors: {
  22. adjacentSpace: false, // div+ nav Android stock browser hack
  23. ie7Hack: false, // *+html hack
  24. special: /(\-moz\-|\-ms\-|\-o\-|\-webkit\-|:dir\([a-z-]*\)|:first(?![a-z-])|:fullscreen|:left|:read-only|:read-write|:right|:placeholder|:host|:content|\/deep\/|:shadow|:selection|^,)/ // special selectors which prevent merging
  25. },
  26. units: {
  27. ch: true,
  28. in: true,
  29. pc: true,
  30. pt: true,
  31. rem: true,
  32. vh: true,
  33. vm: true, // vm is vmin on IE9+ see https://developer.mozilla.org/en-US/docs/Web/CSS/length
  34. vmax: true,
  35. vmin: true,
  36. vw: true
  37. }
  38. },
  39. 'ie8': {
  40. colors: {
  41. opacity: false
  42. },
  43. properties: {
  44. backgroundClipMerging: false,
  45. backgroundOriginMerging: false,
  46. backgroundSizeMerging: false,
  47. colors: true,
  48. ieBangHack: false,
  49. iePrefixHack: true,
  50. ieSuffixHack: true,
  51. merging: false,
  52. shorterLengthUnits: false,
  53. spaceAfterClosingBrace: true,
  54. urlQuotes: false,
  55. zeroUnits: true
  56. },
  57. selectors: {
  58. adjacentSpace: false,
  59. ie7Hack: false,
  60. special: /(\-moz\-|\-ms\-|\-o\-|\-webkit\-|:root|:nth|:first\-of|:last|:only|:empty|:target|:checked|::selection|:enabled|:disabled|:not|:placeholder|:host|::content|\/deep\/|::shadow|^,)/
  61. },
  62. units: {
  63. ch: false,
  64. in: true,
  65. pc: true,
  66. pt: true,
  67. rem: false,
  68. vh: false,
  69. vm: false,
  70. vmax: false,
  71. vmin: false,
  72. vw: false
  73. }
  74. },
  75. 'ie7': {
  76. colors: {
  77. opacity: false
  78. },
  79. properties: {
  80. backgroundClipMerging: false,
  81. backgroundOriginMerging: false,
  82. backgroundSizeMerging: false,
  83. colors: true,
  84. ieBangHack: true,
  85. iePrefixHack: true,
  86. ieSuffixHack: true,
  87. merging: false,
  88. shorterLengthUnits: false,
  89. spaceAfterClosingBrace: true,
  90. urlQuotes: false,
  91. zeroUnits: true
  92. },
  93. selectors: {
  94. adjacentSpace: false,
  95. ie7Hack: true,
  96. special: /(\-moz\-|\-ms\-|\-o\-|\-webkit\-|:focus|:before|:after|:root|:nth|:first\-of|:last|:only|:empty|:target|:checked|::selection|:enabled|:disabled|:not|:placeholder|:host|::content|\/deep\/|::shadow|^,)/
  97. },
  98. units: {
  99. ch: false,
  100. in: true,
  101. pc: true,
  102. pt: true,
  103. rem: false,
  104. vh: false,
  105. vm: false,
  106. vmax: false,
  107. vmin: false,
  108. vw: false,
  109. }
  110. }
  111. };
  112. function Compatibility(source) {
  113. this.source = source || {};
  114. }
  115. function merge(source, target) {
  116. for (var key in source) {
  117. var value = source[key];
  118. if (typeof value === 'object' && !util.isRegExp(value))
  119. target[key] = merge(value, target[key] || {});
  120. else
  121. target[key] = key in target ? target[key] : value;
  122. }
  123. return target;
  124. }
  125. function calculateSource(source) {
  126. if (typeof source == 'object')
  127. return source;
  128. if (!/[,\+\-]/.test(source))
  129. return DEFAULTS[source] || DEFAULTS['*'];
  130. var parts = source.split(',');
  131. var template = parts[0] in DEFAULTS ?
  132. DEFAULTS[parts.shift()] :
  133. DEFAULTS['*'];
  134. source = {};
  135. parts.forEach(function (part) {
  136. var isAdd = part[0] == '+';
  137. var key = part.substring(1).split('.');
  138. var group = key[0];
  139. var option = key[1];
  140. source[group] = source[group] || {};
  141. source[group][option] = isAdd;
  142. });
  143. return merge(template, source);
  144. }
  145. Compatibility.prototype.toOptions = function () {
  146. return merge(DEFAULTS['*'], calculateSource(this.source));
  147. };
  148. module.exports = Compatibility;