forked from bkardell/bcd-watch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdelta.js
127 lines (112 loc) · 3.52 KB
/
delta.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
const browsers = ['firefox', 'chrome', 'safari']
const unimplemented = {
"support": {
"fake": {},
"chrome": {
"version_added": false
},
"edge": {
"version_added": false
},
"firefox": {
"version_added": false
},
"firefox_android": {
"version_added": false
},
"opera": {
"version_added": false
},
"safari": {
"version_added": false
},
"safari_ios": {
"version_added": false
}
}
}
function union(setA, setB) {
const _union = new Set(setA);
for (const elem of setB) {
_union.add(elem);
}
return _union;
}
/*
@key The node name/path
@past the past bcd entry under that name
@cur the cur bcd entry under that name, modified by ref where relevant
@out the output object, modified by ref (added/removed)
@latestBrowsers the browser keys with numeric arrays of the 'latest browsers'
returns whether or not there was any delta
*/
function deltaSupport(key, past, cur, out, latestBrowsers) {
let added = [],
removed = [],
backfilled = [],
total = 0,
changed = false;
browsers.forEach(browser => {
browsername = browser.charAt(0).toUpperCase() + browser.slice(1);
if (cur.support[browser].version_added) {
total++
}
if (!past.support[browser].version_added && cur.support[browser].version_added) {
cur.key = key
let v = parseFloat(cur.support[browser].version_added)
if (latestBrowsers[browser].indexOf(v) !== -1) {
added.push(browsername)
if (!changed) {
out.addedImplementations.push(cur)
}
changed = true
} else {
if (!changed) {
out.backfilledImplementations.push(cur)
}
changed = true
}
} else if (past.support[browser].version_added && !cur.support[browser].version_added) {
removed.push(browsername)
changed = true
}
})
if (added.length > 0) {
cur.addedImplementations = added
}
if (removed.length > 0) {
cur.removedImplementations = removed
}
cur.totalImplementations = total;
return changed
}
function delta(bcdObjA, bcdObjB, latestBrowsers) {
let out = { added: [], removed: [], changed: {}, addedImplementations: [], removedImplementations: [], backfilledImplementations: [] }
let keySetA = new Set(Object.keys(bcdObjA))
let keySetB = new Set(Object.keys(bcdObjB))
let allKeys = union(keySetA, keySetB)
for (const key of allKeys) {
let inA = keySetA.has(key)
let inB = keySetB.has(key)
let cur = bcdObjB[key] || unimplemented
let past = bcdObjA[key] || unimplemented
if (inA && !inB) {
out.removed.push(key)
} else if (!inA && inB) {
out.added.push(key)
}
let hasChanges = deltaSupport(key, past, cur, out, latestBrowsers)
if (hasChanges) {
out.changed[key] = cur[key]
}
}
out.addedImplementations.sort((a, b) => {
let one = a.key.match(/bcd ::: (\w)*/)[0].replace("bcd ::: ", "")
let two = b.key.match(/bcd ::: (\w)*/)[0].replace("bcd ::: ", "")
if (one < two) { return -1; }
if (two > one) { return +1; }
return 0;
})
return out
}
exports.delta = delta