isAutoprefixable.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. 'use strict';
  2. const vendor = require('./vendor');
  3. /**
  4. * Extract each list using the internal API of Autoprefixer 10.2.5.
  5. *
  6. * @see https://github.com/postcss/autoprefixer/tree/10.2.5
  7. *
  8. * @example
  9. * const autoprefixer = require('autoprefixer');
  10. * const Browsers = require('autoprefixer/lib/browsers');
  11. * const Prefixes = require('autoprefixer/lib/prefixes');
  12. * const utils = require('autoprefixer/lib/utils');
  13. *
  14. * const prefixes = new Prefixes(autoprefixer.data.prefixes, new Browsers(autoprefixer.data.browsers, []));
  15. */
  16. /**
  17. * @example
  18. * Object.keys(prefixes.remove).filter((s) => s.startsWith('@'));
  19. */
  20. const AT_RULES = new Set([
  21. '@-khtml-keyframes',
  22. '@-moz-keyframes',
  23. '@-ms-keyframes',
  24. '@-ms-viewport',
  25. '@-o-keyframes',
  26. '@-o-viewport',
  27. '@-webkit-keyframes',
  28. '@resolution',
  29. ]);
  30. /**
  31. * @example
  32. * prefixes.remove.selectors.map((s) => s.prefixed);
  33. */
  34. const SELECTORS = new Set([
  35. ':-moz-any-link',
  36. ':-moz-full-screen',
  37. ':-moz-placeholder',
  38. ':-moz-placeholder-shown',
  39. ':-moz-read-only',
  40. ':-moz-read-write',
  41. ':-ms-fullscreen',
  42. ':-ms-input-placeholder',
  43. ':-webkit-any-link',
  44. ':-webkit-full-screen',
  45. '::-moz-placeholder',
  46. '::-moz-selection',
  47. '::-ms-input-placeholder',
  48. '::-webkit-backdrop',
  49. '::-webkit-input-placeholder',
  50. ]);
  51. /**
  52. * @example
  53. * Object.entries(autoprefixer.data.prefixes)
  54. * .filter(([key, value]) => !value.selector && !value.props && !key.startsWith('@'))
  55. * .map(([key, value]) => key);
  56. */
  57. const PROPERTIES = new Set([
  58. 'align-content',
  59. 'align-items',
  60. 'align-self',
  61. 'animation',
  62. 'animation-delay',
  63. 'animation-direction',
  64. 'animation-duration',
  65. 'animation-fill-mode',
  66. 'animation-iteration-count',
  67. 'animation-name',
  68. 'animation-play-state',
  69. 'animation-timing-function',
  70. 'appearance',
  71. 'backdrop-filter',
  72. 'backface-visibility',
  73. 'background-clip',
  74. 'background-origin',
  75. 'background-size',
  76. 'border-block-end',
  77. 'border-block-start',
  78. 'border-bottom-left-radius',
  79. 'border-bottom-right-radius',
  80. 'border-image',
  81. 'border-inline-end',
  82. 'border-inline-start',
  83. 'border-radius',
  84. 'border-top-left-radius',
  85. 'border-top-right-radius',
  86. 'box-decoration-break',
  87. 'box-shadow',
  88. 'box-sizing',
  89. 'break-after',
  90. 'break-before',
  91. 'break-inside',
  92. 'clip-path',
  93. 'color-adjust',
  94. 'column-count',
  95. 'column-fill',
  96. 'column-gap',
  97. 'column-rule',
  98. 'column-rule-color',
  99. 'column-rule-style',
  100. 'column-rule-width',
  101. 'column-span',
  102. 'column-width',
  103. 'columns',
  104. 'filter',
  105. 'flex',
  106. 'flex-basis',
  107. 'flex-direction',
  108. 'flex-flow',
  109. 'flex-grow',
  110. 'flex-shrink',
  111. 'flex-wrap',
  112. 'flow-from',
  113. 'flow-into',
  114. 'font-feature-settings',
  115. 'font-kerning',
  116. 'font-language-override',
  117. 'font-variant-ligatures',
  118. 'grid-area',
  119. 'grid-column',
  120. 'grid-column-align',
  121. 'grid-column-end',
  122. 'grid-column-start',
  123. 'grid-row',
  124. 'grid-row-align',
  125. 'grid-row-end',
  126. 'grid-row-start',
  127. 'grid-template',
  128. 'grid-template-areas',
  129. 'grid-template-columns',
  130. 'grid-template-rows',
  131. 'hyphens',
  132. 'image-rendering',
  133. 'justify-content',
  134. 'margin-block-end',
  135. 'margin-block-start',
  136. 'margin-inline-end',
  137. 'margin-inline-start',
  138. 'mask',
  139. 'mask-border',
  140. 'mask-border-outset',
  141. 'mask-border-repeat',
  142. 'mask-border-slice',
  143. 'mask-border-source',
  144. 'mask-border-width',
  145. 'mask-clip',
  146. 'mask-composite',
  147. 'mask-image',
  148. 'mask-origin',
  149. 'mask-position',
  150. 'mask-repeat',
  151. 'mask-size',
  152. 'object-fit',
  153. 'object-position',
  154. 'order',
  155. 'overscroll-behavior',
  156. 'padding-block-end',
  157. 'padding-block-start',
  158. 'padding-inline-end',
  159. 'padding-inline-start',
  160. 'perspective',
  161. 'perspective-origin',
  162. 'place-self',
  163. 'region-fragment',
  164. 'scroll-snap-coordinate',
  165. 'scroll-snap-destination',
  166. 'scroll-snap-points-x',
  167. 'scroll-snap-points-y',
  168. 'scroll-snap-type',
  169. 'shape-image-threshold',
  170. 'shape-margin',
  171. 'shape-outside',
  172. 'tab-size',
  173. 'text-align-last',
  174. 'text-decoration',
  175. 'text-decoration-color',
  176. 'text-decoration-line',
  177. 'text-decoration-skip',
  178. 'text-decoration-skip-ink',
  179. 'text-decoration-style',
  180. 'text-emphasis',
  181. 'text-emphasis-color',
  182. 'text-emphasis-position',
  183. 'text-emphasis-style',
  184. 'text-orientation',
  185. 'text-overflow',
  186. 'text-size-adjust',
  187. 'text-spacing',
  188. 'touch-action',
  189. 'transform',
  190. 'transform-origin',
  191. 'transform-style',
  192. 'transition',
  193. 'transition-delay',
  194. 'transition-duration',
  195. 'transition-property',
  196. 'transition-timing-function',
  197. 'user-select',
  198. 'writing-mode',
  199. ]);
  200. /**
  201. * @example
  202. * Object.values(prefixes.remove)
  203. * .filter((p) => Array.isArray(p.values))
  204. * .flatMap((p) => p.values)
  205. * .map((p) => utils.removeNote(p.prefixed)) // normalize '-webkit- old'
  206. * .filter((p) => !p.endsWith('-')); // remove '-webkit-' only
  207. *
  208. * @see https://github.com/stylelint/stylelint/pull/5312/files#r636018013
  209. */
  210. const PROPERTY_VALUES = new Set([
  211. '-moz-available',
  212. '-moz-box',
  213. '-moz-calc',
  214. '-moz-crisp-edges',
  215. '-moz-element',
  216. '-moz-fit-content',
  217. '-moz-grab',
  218. '-moz-grabbing',
  219. '-moz-inline-box',
  220. '-moz-isolate',
  221. '-moz-isolate-override',
  222. '-moz-linear-gradient',
  223. '-moz-max-content',
  224. '-moz-min-content',
  225. '-moz-plaintext',
  226. '-moz-radial-gradient',
  227. '-moz-repeating-linear-gradient',
  228. '-moz-repeating-radial-gradient',
  229. '-moz-zoom-in',
  230. '-moz-zoom-out',
  231. '-ms-flexbox',
  232. '-ms-grid',
  233. '-ms-inline-flexbox',
  234. '-ms-inline-grid',
  235. '-ms-linear-gradient',
  236. '-ms-radial-gradient',
  237. '-ms-repeating-linear-gradient',
  238. '-ms-repeating-radial-gradient',
  239. '-o-linear-gradient',
  240. '-o-pixelated',
  241. '-o-radial-gradient',
  242. '-o-repeating-linear-gradient',
  243. '-o-repeating-radial-gradient',
  244. '-webkit-box',
  245. '-webkit-calc',
  246. '-webkit-cross-fade',
  247. '-webkit-fill-available',
  248. '-webkit-filter',
  249. '-webkit-fit-content',
  250. '-webkit-flex',
  251. '-webkit-grab',
  252. '-webkit-grabbing',
  253. '-webkit-image-set',
  254. '-webkit-inline-box',
  255. '-webkit-inline-flex',
  256. '-webkit-isolate',
  257. '-webkit-linear-gradient',
  258. '-webkit-max-content',
  259. '-webkit-min-content',
  260. '-webkit-optimize-contrast',
  261. '-webkit-radial-gradient',
  262. '-webkit-repeating-linear-gradient',
  263. '-webkit-repeating-radial-gradient',
  264. '-webkit-sticky',
  265. '-webkit-zoom-in',
  266. '-webkit-zoom-out',
  267. ]);
  268. /**
  269. * Most identifier types have to be looked up in a unique way,
  270. * so we're exposing special functions for each.
  271. */
  272. module.exports = {
  273. /**
  274. * @param {string} identifier
  275. * @returns {boolean}
  276. */
  277. atRuleName(identifier) {
  278. return AT_RULES.has(`@${identifier.toLowerCase()}`);
  279. },
  280. /**
  281. * @param {string} identifier
  282. * @returns {boolean}
  283. */
  284. selector(identifier) {
  285. return SELECTORS.has(identifier.toLowerCase());
  286. },
  287. /**
  288. * @param {string} identifier
  289. * @returns {boolean}
  290. */
  291. mediaFeatureName(identifier) {
  292. return identifier.toLowerCase().includes('device-pixel-ratio');
  293. },
  294. /**
  295. * @param {string} identifier
  296. * @returns {boolean}
  297. */
  298. property(identifier) {
  299. const ident = identifier.toLowerCase();
  300. // HACK: `interpolation-mode` does not exist. This is an IE extension for `image-rendering`.
  301. // See <https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering#examples>
  302. if (ident === '-ms-interpolation-mode') {
  303. return true;
  304. }
  305. if (vendor.prefix(ident).length === 0) {
  306. return false;
  307. }
  308. return PROPERTIES.has(vendor.unprefixed(ident));
  309. },
  310. /**
  311. * @param {string} value
  312. * @returns {boolean}
  313. */
  314. propertyValue(value) {
  315. return PROPERTY_VALUES.has(value.toLowerCase());
  316. },
  317. /**
  318. * @param {string} value
  319. * @returns {string}
  320. */
  321. unprefix(value) {
  322. return value.replace(/-\w+-/, '');
  323. },
  324. };