UNPKG

3.25 kBJavaScriptView Raw
1const caniuse = require('caniuse-lite');
2
3const features = require('../data/features');
4
5const BrowserSelection = require('./browsers');
6
7const formatBrowserName = require('./util').formatBrowserName;
8
9const filterStats = (browsers, stats) => Object.keys(stats).reduce((result, browser) => {
10 const versions = stats[browser];
11 const feature = Object.keys(versions).reduce((feat, version) => {
12 const support = versions[version];
13 const selected = browsers.test(browser, version);
14
15 if (selected) {
16 // check if browser is NOT fully (i.e., don't have 'y' in their stats) supported
17 if (!/(^|\s)y($|\s)/.test(support)) {
18 // when it's not partially supported ('a'), it's missing
19 const type = /(^|\s)a($|\s)/.test(support) ? 'partial' : 'missing';
20
21 if (!feat[type]) {
22 feat[type] = {};
23 }
24
25 feat[type][selected[1]] = support;
26 }
27 }
28
29 return feat;
30 }, {
31 missing: {},
32 partial: {}
33 });
34
35 if (Object.keys(feature.missing).length !== 0) {
36 result.missing[browser] = feature.missing;
37 }
38
39 if (Object.keys(feature.partial).length !== 0) {
40 result.partial[browser] = feature.partial;
41 }
42
43 return result;
44}, {
45 missing: {},
46 partial: {}
47});
48
49const lackingBrowsers = browserStats => Object.keys(browserStats).map(browser => formatBrowserName(browser, Object.keys(browserStats[browser]))).join(', ');
50/**
51 * Get data on CSS features not supported by the given autoprefixer-like
52 * browser selection.
53 *
54 * @returns `{browsers, features}`, where `features` is an array of:
55 * ```
56 * {
57 * 'feature-name': {
58 * title: 'Title of feature'
59 * missing: "IE (8), Chrome (31)"
60 * missingData: {
61 * // map of browser -> version -> (lack of)support code
62 * ie: { '8': 'n' },
63 * chrome: { '31': 'n' }
64 * }
65 * partialData: {
66 * // map of browser -> version -> (partial)support code
67 * ie: { '7': 'a' },
68 * ff: { '29': 'a #1' }
69 * }
70 * caniuseData: {
71 * // caniuse-db json data for this feature
72 * }
73 * },
74 * 'feature-name-2': {} // etc.
75 * }
76 * ```
77 *
78 * `feature-name` is a caniuse-db slug.
79 */
80
81
82function missingSupport(browserRequest, from) {
83 const browsers = new BrowserSelection(browserRequest, from);
84 let result = {};
85 Object.keys(features).forEach(function (feature) {
86 const featureData = caniuse.feature(caniuse.features[feature]);
87 const lackData = filterStats(browsers, featureData.stats);
88 const missingData = lackData.missing;
89 const partialData = lackData.partial; // browsers with missing or partial support for this feature
90
91 const missing = lackingBrowsers(missingData);
92 const partial = lackingBrowsers(partialData);
93
94 if (missing.length > 0 || partial.length > 0) {
95 result[feature] = {
96 title: featureData.title,
97 caniuseData: featureData
98 };
99
100 if (missing.length > 0) {
101 result[feature].missingData = missingData;
102 result[feature].missing = missing;
103 }
104
105 if (partial.length > 0) {
106 result[feature].partialData = partialData;
107 result[feature].partial = partial;
108 }
109 }
110 });
111 return {
112 browsers: browsers.list(),
113 features: result
114 };
115}
116
117module.exports = missingSupport;
\No newline at end of file