UNPKG

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