3 var unpack = require('caniuse-lite').feature;
5 var browsersSort = function browsersSort(a, b) {
10 } else if (a[0] < b[0]) {
13 return Math.sign(parseFloat(a[1]) - parseFloat(b[1]));
17 // Convert Can I Use data
18 function f(data, opts, callback) {
22 var _ref = [opts, {}];
27 var match = opts.match || /\sx($|\s)/;
30 for (var browser in data.stats) {
31 var versions = data.stats[browser];
32 for (var version in versions) {
33 var support = versions[version];
34 if (support.match(match)) {
35 need.push(browser + ' ' + version);
40 callback(need.sort(browsersSort));
43 // Add data for all properties
46 var prefix = function prefix(names, data) {
47 for (var _iterator = names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
51 if (_i >= _iterator.length) break;
52 _ref2 = _iterator[_i++];
54 _i = _iterator.next();
61 result[name] = Object.assign({}, data);
65 var add = function add(names, data) {
66 for (var _iterator2 = names, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
70 if (_i2 >= _iterator2.length) break;
71 _ref3 = _iterator2[_i2++];
73 _i2 = _iterator2.next();
80 result[name].browsers = result[name].browsers.concat(data.browsers).sort(browsersSort);
84 module.exports = result;
87 f(require('caniuse-lite/data/features/border-radius.js'), function (browsers) {
88 return prefix(['border-radius', 'border-top-left-radius', 'border-top-right-radius', 'border-bottom-right-radius', 'border-bottom-left-radius'], {
89 mistakes: ['-khtml-', '-ms-', '-o-'],
90 feature: 'border-radius',
96 f(require('caniuse-lite/data/features/css-boxshadow.js'), function (browsers) {
97 return prefix(['box-shadow'], {
98 mistakes: ['-khtml-'],
99 feature: 'css-boxshadow',
105 f(require('caniuse-lite/data/features/css-animation.js'), function (browsers) {
106 return prefix(['animation', 'animation-name', 'animation-duration', 'animation-delay', 'animation-direction', 'animation-fill-mode', 'animation-iteration-count', 'animation-play-state', 'animation-timing-function', '@keyframes'], {
107 mistakes: ['-khtml-', '-ms-'],
108 feature: 'css-animation',
114 f(require('caniuse-lite/data/features/css-transitions.js'), function (browsers) {
115 return prefix(['transition', 'transition-property', 'transition-duration', 'transition-delay', 'transition-timing-function'], {
116 mistakes: ['-khtml-', '-ms-'],
118 feature: 'css-transitions'
123 f(require('caniuse-lite/data/features/transforms2d.js'), function (browsers) {
124 return prefix(['transform', 'transform-origin'], {
125 feature: 'transforms2d',
131 var transforms3d = require('caniuse-lite/data/features/transforms3d.js');
133 f(transforms3d, function (browsers) {
134 prefix(['perspective', 'perspective-origin'], {
135 feature: 'transforms3d',
138 return prefix(['transform-style'], {
139 mistakes: ['-ms-', '-o-'],
141 feature: 'transforms3d'
145 f(transforms3d, { match: /y\sx|y\s#2/ }, function (browsers) {
146 return prefix(['backface-visibility'], {
147 mistakes: ['-ms-', '-o-'],
148 feature: 'transforms3d',
154 var gradients = require('caniuse-lite/data/features/css-gradients.js');
156 f(gradients, { match: /y\sx/ }, function (browsers) {
157 return prefix(['linear-gradient', 'repeating-linear-gradient', 'radial-gradient', 'repeating-radial-gradient'], {
158 props: ['background', 'background-image', 'border-image', 'mask', 'list-style', 'list-style-image', 'content', 'mask-image'],
160 feature: 'css-gradients',
165 f(gradients, { match: /a\sx/ }, function (browsers) {
166 browsers = browsers.map(function (i) {
173 return add(['linear-gradient', 'repeating-linear-gradient', 'radial-gradient', 'repeating-radial-gradient'], {
174 feature: 'css-gradients',
180 f(require('caniuse-lite/data/features/css3-boxsizing.js'), function (browsers) {
181 return prefix(['box-sizing'], {
182 feature: 'css3-boxsizing',
188 f(require('caniuse-lite/data/features/css-filters.js'), function (browsers) {
189 return prefix(['filter'], {
190 feature: 'css-filters',
196 f(require('caniuse-lite/data/features/css-filter-function.js'), function (browsers) {
197 return prefix(['filter-function'], {
198 props: ['background', 'background-image', 'border-image', 'mask', 'list-style', 'list-style-image', 'content', 'mask-image'],
199 feature: 'css-filter-function',
205 f(require('caniuse-lite/data/features/css-backdrop-filter.js'), function (browsers) {
206 return prefix(['backdrop-filter'], {
207 feature: 'css-backdrop-filter',
212 // element() function
213 f(require('caniuse-lite/data/features/css-element-function.js'), function (browsers) {
214 return prefix(['element'], {
215 props: ['background', 'background-image', 'border-image', 'mask', 'list-style', 'list-style-image', 'content', 'mask-image'],
216 feature: 'css-element-function',
222 f(require('caniuse-lite/data/features/multicolumn.js'), function (browsers) {
223 prefix(['columns', 'column-width', 'column-gap', 'column-rule', 'column-rule-color', 'column-rule-width'], {
224 feature: 'multicolumn',
228 prefix(['column-count', 'column-rule-style', 'column-span', 'column-fill', 'break-before', 'break-after', 'break-inside'], {
229 feature: 'multicolumn',
235 f(require('caniuse-lite/data/features/user-select-none.js'), function (browsers) {
236 return prefix(['user-select'], {
237 mistakes: ['-khtml-'],
238 feature: 'user-select-none',
243 // Flexible Box Layout
244 var flexbox = require('caniuse-lite/data/features/flexbox.js');
245 f(flexbox, { match: /a\sx/ }, function (browsers) {
246 browsers = browsers.map(function (i) {
247 if (/ie|firefox/.test(i)) {
253 prefix(['display-flex', 'inline-flex'], {
258 prefix(['flex', 'flex-grow', 'flex-shrink', 'flex-basis'], {
262 prefix(['flex-direction', 'flex-wrap', 'flex-flow', 'justify-content', 'order', 'align-items', 'align-self', 'align-content'], {
268 f(flexbox, { match: /y\sx/ }, function (browsers) {
269 add(['display-flex', 'inline-flex'], {
273 add(['flex', 'flex-grow', 'flex-shrink', 'flex-basis'], {
277 add(['flex-direction', 'flex-wrap', 'flex-flow', 'justify-content', 'order', 'align-items', 'align-self', 'align-content'], {
284 f(require('caniuse-lite/data/features/calc.js'), function (browsers) {
285 return prefix(['calc'], {
292 // Background options
293 f(require('caniuse-lite/data/features/background-img-opts.js'), function (browsers) {
294 return prefix(['background-clip', 'background-origin', 'background-size'], {
295 feature: 'background-img-opts',
300 // Font feature settings
301 f(require('caniuse-lite/data/features/font-feature.js'), function (browsers) {
302 return prefix(['font-feature-settings', 'font-variant-ligatures', 'font-language-override'], {
303 feature: 'font-feature',
308 // CSS font-kerning property
309 f(require('caniuse-lite/data/features/font-kerning.js'), function (browsers) {
310 return prefix(['font-kerning'], {
311 feature: 'font-kerning',
317 f(require('caniuse-lite/data/features/border-image.js'), function (browsers) {
318 return prefix(['border-image'], {
319 feature: 'border-image',
324 // Selection selector
325 f(require('caniuse-lite/data/features/css-selection.js'), function (browsers) {
326 return prefix(['::selection'], {
328 feature: 'css-selection',
333 // Placeholder selector
334 f(require('caniuse-lite/data/features/css-placeholder.js'), function (browsers) {
335 browsers = browsers.map(function (i) {
336 var _i$split = i.split(' '),
338 version = _i$split[1];
340 if (name === 'firefox' && parseFloat(version) <= 18) {
342 } else if (name === 'ie') {
349 prefix(['::placeholder'], {
351 feature: 'css-placeholder',
357 f(require('caniuse-lite/data/features/css-hyphens.js'), function (browsers) {
358 return prefix(['hyphens'], {
359 feature: 'css-hyphens',
364 // Fullscreen selector
365 var fullscreen = require('caniuse-lite/data/features/fullscreen.js');
367 f(fullscreen, function (browsers) {
368 return prefix([':fullscreen'], {
370 feature: 'fullscreen',
375 f(fullscreen, { match: /x(\s#2|$)/ }, function (browsers) {
376 return prefix(['::backdrop'], {
378 feature: 'fullscreen',
384 f(require('caniuse-lite/data/features/css3-tabsize.js'), function (browsers) {
385 return prefix(['tab-size'], {
386 feature: 'css3-tabsize',
391 // Intrinsic & extrinsic sizing
392 f(require('caniuse-lite/data/features/intrinsic-width.js'), function (browsers) {
393 return prefix(['max-content', 'min-content', 'fit-content', 'fill', 'fill-available', 'stretch'], {
394 props: ['width', 'min-width', 'max-width', 'height', 'min-height', 'max-height', 'inline-size', 'min-inline-size', 'max-inline-size', 'block-size', 'min-block-size', 'max-block-size', 'grid', 'grid-template', 'grid-template-rows', 'grid-template-columns', 'grid-auto-columns', 'grid-auto-rows'],
395 feature: 'intrinsic-width',
401 f(require('caniuse-lite/data/features/css3-cursors-newer.js'), function (browsers) {
402 return prefix(['zoom-in', 'zoom-out'], {
404 feature: 'css3-cursors-newer',
410 f(require('caniuse-lite/data/features/css3-cursors-grab.js'), function (browsers) {
411 return prefix(['grab', 'grabbing'], {
413 feature: 'css3-cursors-grab',
419 f(require('caniuse-lite/data/features/css-sticky.js'), function (browsers) {
420 return prefix(['sticky'], {
422 feature: 'css-sticky',
428 f(require('caniuse-lite/data/features/pointer.js'), function (browsers) {
429 return prefix(['touch-action'], {
436 var decoration = require('caniuse-lite/data/features/text-decoration.js');
438 f(decoration, function (browsers) {
439 return prefix(['text-decoration-style', 'text-decoration-color', 'text-decoration-line', 'text-decoration'], {
440 feature: 'text-decoration',
445 f(decoration, { match: /x.*#[23]/ }, function (browsers) {
446 return prefix(['text-decoration-skip'], {
447 feature: 'text-decoration',
453 f(require('caniuse-lite/data/features/text-size-adjust.js'), function (browsers) {
454 return prefix(['text-size-adjust'], {
455 feature: 'text-size-adjust',
461 f(require('caniuse-lite/data/features/css-masks.js'), function (browsers) {
462 prefix(['mask-clip', 'mask-composite', 'mask-image', 'mask-origin', 'mask-repeat', 'mask-border-repeat', 'mask-border-source'], {
463 feature: 'css-masks',
466 prefix(['mask', 'mask-position', 'mask-size', 'mask-border', 'mask-border-outset', 'mask-border-width', 'mask-border-slice'], {
467 feature: 'css-masks',
472 // CSS clip-path property
473 f(require('caniuse-lite/data/features/css-clip-path.js'), function (browsers) {
474 return prefix(['clip-path'], {
475 feature: 'css-clip-path',
480 // Fragmented Borders and Backgrounds
481 f(require('caniuse-lite/data/features/css-boxdecorationbreak.js'), function (browsers) {
482 return prefix(['box-decoration-break'], {
483 feature: 'css-boxdecorationbreak',
488 // CSS3 object-fit/object-position
489 f(require('caniuse-lite/data/features/object-fit.js'), function (browsers) {
490 return prefix(['object-fit', 'object-position'], {
491 feature: 'object-fit',
497 f(require('caniuse-lite/data/features/css-shapes.js'), function (browsers) {
498 return prefix(['shape-margin', 'shape-outside', 'shape-image-threshold'], {
499 feature: 'css-shapes',
504 // CSS3 text-overflow
505 f(require('caniuse-lite/data/features/text-overflow.js'), function (browsers) {
506 return prefix(['text-overflow'], {
507 feature: 'text-overflow',
513 f(require('caniuse-lite/data/features/css-deviceadaptation.js'), function (browsers) {
514 return prefix(['@viewport'], {
515 feature: 'css-deviceadaptation',
520 // Resolution Media Queries
521 var resolut = require('caniuse-lite/data/features/css-media-resolution.js');
522 f(resolut, { match: /( x($| )|a #3)/ }, function (browsers) {
523 return prefix(['@resolution'], {
524 feature: 'css-media-resolution',
529 // CSS text-align-last
530 f(require('caniuse-lite/data/features/css-text-align-last.js'), function (browsers) {
531 return prefix(['text-align-last'], {
532 feature: 'css-text-align-last',
537 // Crisp Edges Image Rendering Algorithm
538 var crispedges = require('caniuse-lite/data/features/css-crisp-edges.js');
540 f(crispedges, { match: /y x|a x #1/ }, function (browsers) {
541 return prefix(['pixelated'], {
542 props: ['image-rendering'],
543 feature: 'css-crisp-edges',
548 f(crispedges, { match: /a x #2/ }, function (browsers) {
549 return prefix(['image-rendering'], {
550 feature: 'css-crisp-edges',
555 // Logical Properties
556 var logicalProps = require('caniuse-lite/data/features/css-logical-props.js');
558 f(logicalProps, function (browsers) {
559 return prefix(['border-inline-start', 'border-inline-end', 'margin-inline-start', 'margin-inline-end', 'padding-inline-start', 'padding-inline-end'], {
560 feature: 'css-logical-props',
565 f(logicalProps, { match: /x\s#2/ }, function (browsers) {
566 return prefix(['border-block-start', 'border-block-end', 'margin-block-start', 'margin-block-end', 'padding-block-start', 'padding-block-end'], {
567 feature: 'css-logical-props',
573 var appearance = require('caniuse-lite/data/features/css-appearance.js');
574 f(appearance, { match: /#2|x/ }, function (browsers) {
575 return prefix(['appearance'], {
576 feature: 'css-appearance',
581 // CSS Scroll snap points
582 f(require('caniuse-lite/data/features/css-snappoints.js'), function (browsers) {
583 return prefix(['scroll-snap-type', 'scroll-snap-coordinate', 'scroll-snap-destination', 'scroll-snap-points-x', 'scroll-snap-points-y'], {
584 feature: 'css-snappoints',
590 f(require('caniuse-lite/data/features/css-regions.js'), function (browsers) {
591 return prefix(['flow-into', 'flow-from', 'region-fragment'], {
592 feature: 'css-regions',
598 f(require('caniuse-lite/data/features/css-image-set.js'), function (browsers) {
599 return prefix(['image-set'], {
600 props: ['background', 'background-image', 'border-image', 'cursor', 'mask', 'mask-image', 'list-style', 'list-style-image', 'content'],
601 feature: 'css-image-set',
607 var writingMode = require('caniuse-lite/data/features/css-writing-mode.js');
608 f(writingMode, { match: /a|x/ }, function (browsers) {
609 return prefix(['writing-mode'], {
610 feature: 'css-writing-mode',
615 // Cross-Fade Function
616 f(require('caniuse-lite/data/features/css-cross-fade.js'), function (browsers) {
617 return prefix(['cross-fade'], {
618 props: ['background', 'background-image', 'border-image', 'mask', 'list-style', 'list-style-image', 'content', 'mask-image'],
619 feature: 'css-cross-fade',
624 // Read Only selector
625 f(require('caniuse-lite/data/features/css-read-only-write.js'), function (browsers) {
626 return prefix([':read-only', ':read-write'], {
628 feature: 'css-read-only-write',
634 f(require('caniuse-lite/data/features/text-emphasis.js'), function (browsers) {
635 return prefix(['text-emphasis', 'text-emphasis-position', 'text-emphasis-style', 'text-emphasis-color'], {
636 feature: 'text-emphasis',
642 var grid = require('caniuse-lite/data/features/css-grid.js');
644 f(grid, function (browsers) {
645 prefix(['display-grid', 'inline-grid'], {
650 prefix(['grid-template-columns', 'grid-template-rows', 'grid-row-start', 'grid-column-start', 'grid-row-end', 'grid-column-end', 'grid-row', 'grid-column', 'grid-area', 'grid-template', 'grid-template-areas'], {
656 f(grid, { match: /a x/ }, function (browsers) {
657 return prefix(['grid-column-align', 'grid-row-align'], {
664 f(require('caniuse-lite/data/features/css-text-spacing.js'), function (browsers) {
665 return prefix(['text-spacing'], {
666 feature: 'css-text-spacing',
671 // :any-link selector
672 f(require('caniuse-lite/data/features/css-any-link.js'), function (browsers) {
673 return prefix([':any-link'], {
675 feature: 'css-any-link',
681 var bidi = require('caniuse-lite/data/features/css-unicode-bidi.js');
683 f(bidi, function (browsers) {
684 return prefix(['isolate'], {
685 props: ['unicode-bidi'],
686 feature: 'css-unicode-bidi',
691 f(bidi, { match: /y x|a x #2/ }, function (browsers) {
692 return prefix(['plaintext'], {
693 props: ['unicode-bidi'],
694 feature: 'css-unicode-bidi',
699 f(bidi, { match: /y x/ }, function (browsers) {
700 return prefix(['isolate-override'], {
701 props: ['unicode-bidi'],
702 feature: 'css-unicode-bidi',