compatibility.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. var DEFAULTS = {
  2. '*': {
  3. colors: {
  4. opacity: true // rgba / hsla
  5. },
  6. properties: {
  7. backgroundClipMerging: true, // background-clip to shorthand
  8. backgroundOriginMerging: true, // background-origin to shorthand
  9. backgroundSizeMerging: true, // background-size to shorthand
  10. colors: true, // any kind of color transformations, like `#ff00ff` to `#f0f` or `#fff` into `red`
  11. ieBangHack: false, // !ie suffix hacks on IE<8
  12. ieFilters: false, // whether to preserve `filter` and `-ms-filter` properties
  13. iePrefixHack: false, // underscore / asterisk prefix hacks on IE
  14. ieSuffixHack: false, // \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. mergeablePseudoClasses: [
  25. ':active',
  26. ':after',
  27. ':before',
  28. ':empty',
  29. ':checked',
  30. ':disabled',
  31. ':empty',
  32. ':enabled',
  33. ':first-child',
  34. ':first-letter',
  35. ':first-line',
  36. ':first-of-type',
  37. ':focus',
  38. ':hover',
  39. ':lang',
  40. ':last-child',
  41. ':last-of-type',
  42. ':link',
  43. ':not',
  44. ':nth-child',
  45. ':nth-last-child',
  46. ':nth-last-of-type',
  47. ':nth-of-type',
  48. ':only-child',
  49. ':only-of-type',
  50. ':root',
  51. ':target',
  52. ':visited'
  53. ], // selectors with these pseudo-classes can be merged as these are universally supported
  54. mergeablePseudoElements: [
  55. '::after',
  56. '::before',
  57. '::first-letter',
  58. '::first-line'
  59. ], // selectors with these pseudo-elements can be merged as these are universally supported
  60. mergeLimit: 8191, // number of rules that can be safely merged together
  61. multiplePseudoMerging: true
  62. },
  63. units: {
  64. ch: true,
  65. in: true,
  66. pc: true,
  67. pt: true,
  68. rem: true,
  69. vh: true,
  70. vm: true, // vm is vmin on IE9+ see https://developer.mozilla.org/en-US/docs/Web/CSS/length
  71. vmax: true,
  72. vmin: true,
  73. vw: true
  74. }
  75. }
  76. };
  77. DEFAULTS.ie11 = DEFAULTS['*'];
  78. DEFAULTS.ie10 = DEFAULTS['*'];
  79. DEFAULTS.ie9 = merge(DEFAULTS['*'], {
  80. properties: {
  81. ieFilters: true,
  82. ieSuffixHack: true
  83. }
  84. });
  85. DEFAULTS.ie8 = merge(DEFAULTS.ie9, {
  86. colors: {
  87. opacity: false
  88. },
  89. properties: {
  90. backgroundClipMerging: false,
  91. backgroundOriginMerging: false,
  92. backgroundSizeMerging: false,
  93. iePrefixHack: true,
  94. merging: false
  95. },
  96. selectors: {
  97. mergeablePseudoClasses: [
  98. ':after',
  99. ':before',
  100. ':first-child',
  101. ':first-letter',
  102. ':focus',
  103. ':hover',
  104. ':visited'
  105. ],
  106. mergeablePseudoElements: []
  107. },
  108. units: {
  109. ch: false,
  110. rem: false,
  111. vh: false,
  112. vm: false,
  113. vmax: false,
  114. vmin: false,
  115. vw: false
  116. }
  117. });
  118. DEFAULTS.ie7 = merge(DEFAULTS.ie8, {
  119. properties: {
  120. ieBangHack: true
  121. },
  122. selectors: {
  123. ie7Hack: true,
  124. mergeablePseudoClasses: [
  125. ':first-child',
  126. ':first-letter',
  127. ':hover',
  128. ':visited'
  129. ]
  130. },
  131. });
  132. function compatibilityFrom(source) {
  133. return merge(DEFAULTS['*'], calculateSource(source));
  134. }
  135. function merge(source, target) {
  136. for (var key in source) {
  137. var value = source[key];
  138. if (typeof value === 'object' && !Array.isArray(value)) {
  139. target[key] = merge(value, target[key] || {});
  140. } else {
  141. target[key] = key in target ? target[key] : value;
  142. }
  143. }
  144. return target;
  145. }
  146. function calculateSource(source) {
  147. if (typeof source == 'object')
  148. return source;
  149. if (!/[,\+\-]/.test(source))
  150. return DEFAULTS[source] || DEFAULTS['*'];
  151. var parts = source.split(',');
  152. var template = parts[0] in DEFAULTS ?
  153. DEFAULTS[parts.shift()] :
  154. DEFAULTS['*'];
  155. source = {};
  156. parts.forEach(function (part) {
  157. var isAdd = part[0] == '+';
  158. var key = part.substring(1).split('.');
  159. var group = key[0];
  160. var option = key[1];
  161. source[group] = source[group] || {};
  162. source[group][option] = isAdd;
  163. });
  164. return merge(template, source);
  165. }
  166. module.exports = compatibilityFrom;