feature.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. 'use strict'
  2. const statuses = require('../lib/statuses')
  3. const supported = require('../lib/supported')
  4. const browsers = require('./browsers').browsers
  5. const versions = require('./browserVersions').browserVersions
  6. const versionGroups = require('./versionGroups.js').versionGroups
  7. const MATH2LOG = Math.log(2)
  8. const groupCache = {}
  9. function expandKey(key) {
  10. let cached = groupCache[key]
  11. if (cached === undefined) {
  12. cached = groupCache[key] = expandGroups(versionGroups[key], [])
  13. }
  14. return cached
  15. }
  16. function expandGroups(value, out) {
  17. let start = 0
  18. for (let i = 0, len = value.length; i <= len; i++) {
  19. if (i === len || value.charCodeAt(i) === 32) {
  20. if (i > start) {
  21. if (value.charCodeAt(start) === 95) {
  22. let group = expandKey(value.slice(start + 1, i))
  23. for (let j = 0; j < group.length; j++) out.push(group[j])
  24. } else {
  25. out.push(value.slice(start, i))
  26. }
  27. }
  28. start = i + 1
  29. }
  30. }
  31. return out
  32. }
  33. function unpackSupport(cipher) {
  34. // bit flags
  35. let stats = Object.keys(supported).reduce((list, support) => {
  36. if (cipher & supported[support]) list.push(support)
  37. return list
  38. }, [])
  39. // notes
  40. let notes = cipher >> 7
  41. let notesArray = []
  42. while (notes) {
  43. let note = Math.floor(Math.log(notes) / MATH2LOG) + 1
  44. notesArray.unshift(`#${note}`)
  45. notes -= Math.pow(2, note - 1)
  46. }
  47. return stats.concat(notesArray).join(' ')
  48. }
  49. function unpackFeature(packed) {
  50. let unpacked = {
  51. status: statuses[packed.B],
  52. title: packed.C,
  53. shown: packed.D
  54. }
  55. unpacked.stats = Object.keys(packed.A).reduce((browserStats, key) => {
  56. let browser = packed.A[key]
  57. browserStats[browsers[key]] = Object.keys(browser).reduce(
  58. (stats, support) => {
  59. let packedVersions = expandGroups(browser[support], [])
  60. let unpacked2 = unpackSupport(support)
  61. packedVersions.forEach(v => (stats[versions[v]] = unpacked2))
  62. return stats
  63. },
  64. {}
  65. )
  66. return browserStats
  67. }, {})
  68. return unpacked
  69. }
  70. module.exports = unpackFeature
  71. module.exports.default = unpackFeature