nav tabs on admin dashboard

This commit is contained in:
2019-03-07 00:20:34 -06:00
parent f73d6ae228
commit e4f473f376
11661 changed files with 216240 additions and 1544253 deletions
+324 -82
View File
@@ -1,13 +1,31 @@
var jsReleases = require('node-releases/data/processed/envs.json')
var agents = require('caniuse-lite/dist/unpacker/agents').agents
var jsEOL = require('node-releases/data/release-schedule/release-schedule.json')
var path = require('path')
var e2c = require('electron-to-chromium/versions')
var agents = require('caniuse-lite/dist/unpacker/agents').agents
var region = require('caniuse-lite/dist/unpacker/region').default
var BrowserslistError = require('./error')
var env = require('./node') // Will load browser.js in webpack
var FLOAT_RANGE = /^\d+(\.\d+)?(-\d+(\.\d+)?)*$/
var YEAR = 365.259641 * 24 * 60 * 60 * 1000
// Enum values MUST be powers of 2, so combination are safe
/** @constant {number} */
var QUERY_OR = 1
/** @constant {number} */
var QUERY_AND = 2
function isVersionsMatch (versionA, versionB) {
return (versionA + '.').indexOf(versionB + '.') === 0
}
function isEolReleased (name) {
var version = name.slice(1)
return jsReleases.some(function (i) {
return isVersionsMatch(i.version, version)
})
}
function normalize (versions) {
return versions.filter(function (version) {
@@ -91,21 +109,8 @@ function normalizeVersion (data, version) {
}
}
function loadCountryStatistics (country) {
country = country.replace(/[^\w-]/g, '')
if (!browserslist.usage[country]) {
var usage = { }
// eslint-disable-next-line security/detect-non-literal-require
var compressed = require('caniuse-lite/data/regions/' + country + '.js')
var data = region(compressed)
for (var i in data) {
fillUsage(usage, i, data[i])
}
browserslist.usage[country] = usage
}
}
function filterByYear (since) {
since = since / 1000
return Object.keys(agents).reduce(function (selected, name) {
var data = byName(name)
if (!data) return selected
@@ -128,10 +133,30 @@ function checkName (name) {
return data
}
function unknownQuery (query) {
return new BrowserslistError(
'Unknown browser query `' + query + '`. ' +
'Maybe you are using old Browserslist or made typo in query.'
)
}
/**
* Resolves queries into a browser list.
* @param {string|string[]} queries Queries to combine.
* Either an array of queries or a long string of queries.
* @param {object} [context] Optional arguments to
* the select function in `queries`.
* @returns {string[]} A list of browsers
*/
function resolve (queries, context) {
return queries.reduce(function (result, selection, index) {
selection = selection.trim()
if (selection === '') return result
if (Array.isArray(queries)) {
queries = flatten(queries.map(parse))
} else {
queries = parse(queries)
}
return queries.reduce(function (result, query, index) {
var selection = query.queryString
var isExclude = selection.indexOf('not ') === 0
if (isExclude) {
@@ -148,20 +173,48 @@ function resolve (queries, context) {
var match = selection.match(type.regexp)
if (match) {
var args = [context].concat(match.slice(1))
var array = type.select.apply(browserslist, args)
if (isExclude) {
array = array.concat(array.map(function (j) {
return j.replace(/\s\d+/, ' 0')
}))
return result.filter(function (j) {
return array.indexOf(j) === -1
})
var array = type.select.apply(browserslist, args).map(function (j) {
var parts = j.split(' ')
if (parts[1] === '0') {
return parts[0] + ' ' + byName(parts[0]).versions[0]
} else {
return j
}
})
switch (query.type) {
case QUERY_AND:
if (isExclude) {
return result.filter(function (j) {
// remove result items that are in array
// (the relative complement of array in result)
return array.indexOf(j) === -1
})
} else {
return result.filter(function (j) {
// remove result items not in array
// (intersect of result and array)
return array.indexOf(j) !== -1
})
}
case QUERY_OR:
default:
if (isExclude) {
var filter = { }
array.forEach(function (j) {
filter[j] = true
})
return result.filter(function (j) {
return !filter[j]
})
}
// union of result and array
return result.concat(array)
}
return result.concat(array)
}
}
throw new BrowserslistError('Unknown browser query `' + selection + '`')
throw unknownQuery(selection)
}, [])
}
@@ -169,16 +222,20 @@ function resolve (queries, context) {
* Return array of browsers by selection queries.
*
* @param {(string|string[])} [queries=browserslist.defaults] Browser queries.
* @param {object} opts Options.
* @param {object} [opts] Options.
* @param {string} [opts.path="."] Path to processed file.
* It will be used to find config files.
* @param {string} [opts.env="development"] Processing environment.
* It will be used to take right
* queries from config file.
* @param {string} [opts.env="production"] Processing environment.
* It will be used to take right
* queries from config file.
* @param {string} [opts.config] Path to config file with queries.
* @param {object} [opts.stats] Custom browser usage statistics
* for "> 1% in my stats" query.
* @return {string[]} Array with browser names in Can I Use.
* @param {boolean} [opts.ignoreUnknownVersions=false] Do not throw on unknown
* version in direct query.
* @param {boolean} [opts.dangerousExtend] Disable security checks
* for extend query.
* @returns {string[]} Array with browser names in Can I Use.
*
* @example
* browserslist('IE >= 10, IE 8') //=> ['ie 11', 'ie 10', 'ie 8']
@@ -186,12 +243,12 @@ function resolve (queries, context) {
function browserslist (queries, opts) {
if (typeof opts === 'undefined') opts = { }
if (!opts.hasOwnProperty('path')) {
if (typeof opts.path === 'undefined') {
opts.path = path.resolve ? path.resolve('.') : '.'
}
if (typeof queries === 'undefined' || queries === null) {
var config = env.loadConfig(opts)
var config = browserslist.loadConfig(opts)
if (config) {
queries = config
} else {
@@ -199,38 +256,26 @@ function browserslist (queries, opts) {
}
}
if (typeof queries === 'string') {
queries = queries.split(/,\s*/)
}
if (!Array.isArray(queries)) {
if (!(typeof queries === 'string' || Array.isArray(queries))) {
throw new BrowserslistError(
'Browser queries must be an array. Got ' + typeof queries + '.')
'Browser queries must be an array or string. Got ' + typeof queries + '.')
}
var context = { dangerousExtend: opts.dangerousExtend }
var context = {
ignoreUnknownVersions: opts.ignoreUnknownVersions,
dangerousExtend: opts.dangerousExtend
}
var stats = env.getStat(opts)
env.oldDataWarning(browserslist.data)
var stats = env.getStat(opts, browserslist.data)
if (stats) {
if ('dataByBrowser' in stats) {
stats = stats.dataByBrowser
}
context.customUsage = { }
for (var browser in stats) {
fillUsage(context.customUsage, browser, stats[browser])
}
}
var result = resolve(queries, context).map(function (i) {
var parts = i.split(' ')
var name = parts[0]
var version = parts[1]
if (version === '0') {
return name + ' ' + byName(name).versions[0]
} else {
return i
}
}).sort(function (name1, name2) {
var result = resolve(queries, context).sort(function (name1, name2) {
name1 = name1.split(' ')
name2 = name2.split(' ')
if (name1[0] === name2[0]) {
@@ -247,6 +292,74 @@ function browserslist (queries, opts) {
return uniq(result)
}
/**
* @typedef {object} BrowserslistQuery
* @property {number} type A type constant like QUERY_OR @see QUERY_OR.
* @property {string} queryString A query like "not ie < 11".
*/
/**
* Parse a browserslist string query
* @param {string} queries One or more queries as a string
* @returns {BrowserslistQuery[]} An array of BrowserslistQuery
*/
function parse (queries) {
var qs = []
do {
queries = doMatch(queries, qs)
} while (queries)
return qs
}
/**
* Find query matches in a string. This function is meant to be called
* repeatedly with the returned query string until there is no more matches.
* @param {string} string A string with one or more queries.
* @param {BrowserslistQuery[]} qs Out parameter,
* will be filled with `BrowserslistQuery`.
* @returns {string} The rest of the query string minus the matched part.
*/
function doMatch (string, qs) {
var or = /^(?:,\s*|\s+OR\s+)(.*)/i
var and = /^\s+AND\s+(.*)/i
return find(
string,
function (parsed, n, max) {
if (and.test(parsed)) {
qs.unshift({ type: QUERY_AND, queryString: parsed.match(and)[1] })
return true
} else if (or.test(parsed)) {
qs.unshift({ type: QUERY_OR, queryString: parsed.match(or)[1] })
return true
} else if (n === max) {
qs.unshift({ type: QUERY_OR, queryString: parsed.trim() })
return true
}
return false
}
)
}
function find (string, predicate) {
for (var n = 1, max = string.length; n <= max; n++) {
var parsed = string.substr(-n, n)
if (predicate(parsed, n, max)) {
return string.replace(parsed, '')
}
}
return ''
}
function flatten (array) {
if (!Array.isArray(array)) return [array]
return array.reduce(function (a, b) {
return a.concat(flatten(b))
}, [])
}
// Will be filled by Can I Use data below
browserslist.data = { }
browserslist.usage = {
@@ -256,9 +369,10 @@ browserslist.usage = {
// Default browsers query
browserslist.defaults = [
'> 1%',
'> 0.5%',
'last 2 versions',
'Firefox ESR'
'Firefox ESR',
'not dead'
]
// Browser names aliases
@@ -284,34 +398,61 @@ browserslist.clearCaches = env.clearCaches
browserslist.parseConfig = env.parseConfig
browserslist.readConfig = env.readConfig
browserslist.findConfig = env.findConfig
browserslist.loadConfig = env.loadConfig
/**
* Return browsers market coverage.
*
* @param {string[]} browsers Browsers names in Can I Use.
* @param {string} [country="global"] Which country statistics should be used.
* @param {string|object} [stats="global"] Which statistics should be used.
* Country code or custom statistics.
* Pass `"my stats"` to load statistics
* from Browserslist files.
*
* @return {number} Total market coverage for all selected browsers.
*
* @example
* browserslist.coverage(browserslist('> 1% in US'), 'US') //=> 83.1
*/
browserslist.coverage = function (browsers, country) {
if (country && country !== 'global') {
if (country.length > 2) {
country = country.toLowerCase()
} else {
country = country.toUpperCase()
browserslist.coverage = function (browsers, stats) {
var data
if (typeof stats === 'undefined') {
data = browserslist.usage.global
} else if (stats === 'my stats') {
var opts = {}
opts.path = path.resolve ? path.resolve('.') : '.'
var customStats = env.getStat(opts)
if (!customStats) {
throw new BrowserslistError('Custom usage statistics was not provided')
}
loadCountryStatistics(country)
data = {}
for (var browser in customStats) {
fillUsage(data, browser, customStats[browser])
}
} else if (typeof stats === 'string') {
if (stats.length > 2) {
stats = stats.toLowerCase()
} else {
stats = stats.toUpperCase()
}
env.loadCountry(browserslist.usage, stats)
data = browserslist.usage[stats]
} else {
country = 'global'
if ('dataByBrowser' in stats) {
stats = stats.dataByBrowser
}
data = { }
for (var name in stats) {
for (var version in stats[name]) {
data[name + ' ' + version] = stats[name][version]
}
}
}
return browsers.reduce(function (all, i) {
var usage = browserslist.usage[country][i]
var usage = data[i]
if (usage === undefined) {
usage = browserslist.usage[country][i.replace(/ [\d.]+$/, ' 0')]
usage = data[i.replace(/ \S+$/, ' 0')]
}
return all + (usage || 0)
}, 0)
@@ -407,12 +548,9 @@ var QUERIES = [
}
},
{
regexp: /^last\s+(\d+)\s+years?$/i,
regexp: /^last\s+(\d*.?\d+)\s+years?$/i,
select: function (context, years) {
var date = new Date()
var since = date.setFullYear(date.getFullYear() - years) / 1000
return filterByYear(since)
return filterByYear(Date.now() - YEAR * years)
}
},
{
@@ -421,9 +559,7 @@ var QUERIES = [
year = parseInt(year)
month = parseInt(month || '01') - 1
date = parseInt(date || '01')
var since = Date.UTC(year, month, date, 0, 0, 0) / 1000
return filterByYear(since)
return filterByYear(Date.UTC(year, month, date, 0, 0, 0))
}
},
{
@@ -494,7 +630,7 @@ var QUERIES = [
place = place.toLowerCase()
}
loadCountryStatistics(place)
env.loadCountry(browserslist.usage, place)
var usage = browserslist.usage[place]
return Object.keys(usage).reduce(function (result, version) {
@@ -517,6 +653,52 @@ var QUERIES = [
}, [])
}
},
{
regexp: /^cover\s+(\d*\.?\d+)%(\s+in\s+(my\s+stats|(alt-)?\w\w))?$/,
select: function (context, coverage, statMode) {
coverage = parseFloat(coverage)
var usage = browserslist.usage.global
if (statMode) {
if (statMode.match(/^\s+in\s+my\s+stats$/)) {
if (!context.customUsage) {
throw new BrowserslistError(
'Custom usage statistics was not provided'
)
}
usage = context.customUsage
} else {
var match = statMode.match(/\s+in\s+((alt-)?\w\w)/)
var place = match[1]
if (place.length === 2) {
place = place.toUpperCase()
} else {
place = place.toLowerCase()
}
env.loadCountry(browserslist.usage, place)
usage = browserslist.usage[place]
}
}
var versions = Object.keys(usage).sort(function (a, b) {
return usage[b] - usage[a]
})
var coveraged = 0
var result = []
var version
for (var i = 0; i <= versions.length; i++) {
version = versions[i]
if (usage[version] === 0) break
coveraged += usage[version]
result.push(version)
if (coveraged >= coverage) break
}
return result
}
},
{
regexp: /^electron\s+([\d.]+)\s*-\s*([\d.]+)$/i,
select: function (context, from, to) {
@@ -581,7 +763,7 @@ var QUERIES = [
{
regexp: /^(firefox|ff|fx)\s+esr$/i,
select: function () {
return ['firefox 52']
return ['firefox 60']
}
},
{
@@ -601,6 +783,46 @@ var QUERIES = [
return ['chrome ' + chrome]
}
},
{
regexp: /^node\s+(\d+(\.\d+)?(\.\d+)?)$/i,
select: function (context, version) {
var nodeReleases = jsReleases.filter(function (i) {
return i.name === 'nodejs'
})
var matched = nodeReleases.filter(function (i) {
return isVersionsMatch(i.version, version)
})
if (matched.length === 0) {
if (context.ignoreUnknownVersions) {
return []
} else {
throw new BrowserslistError(
'Unknown version ' + version + ' of Node.js')
}
}
return ['node ' + matched[matched.length - 1].version]
}
},
{
regexp: /^current\s+node$/i,
select: function (context) {
return [env.currentNode(resolve, context)]
}
},
{
regexp: /^maintained\s+node\s+versions$/i,
select: function (context) {
var now = Date.now()
var queries = Object.keys(jsEOL).filter(function (key) {
return now < Date.parse(jsEOL[key].end) &&
now > Date.parse(jsEOL[key].start) &&
isEolReleased(key)
}).map(function (key) {
return 'node ' + key.slice(1)
})
return resolve(queries, context)
}
},
{
regexp: /^(\w+)\s+(tp|[\d.]+)$/i,
select: function (context, name, version) {
@@ -612,12 +834,14 @@ var QUERIES = [
} else {
if (version.indexOf('.') === -1) {
alias = version + '.0'
} else if (/\.0$/.test(version)) {
} else {
alias = version.replace(/\.0$/, '')
}
alias = normalizeVersion(data, alias)
if (alias) {
version = alias
} else if (context.ignoreUnknownVersions) {
return []
} else {
throw new BrowserslistError(
'Unknown version ' + version + ' of ' + name)
@@ -637,6 +861,24 @@ var QUERIES = [
select: function () {
return browserslist(browserslist.defaults)
}
},
{
regexp: /^dead$/i,
select: function (context) {
var dead = ['ie <= 10', 'ie_mob <= 10', 'bb <= 10', 'op_mob <= 12.1']
return resolve(dead, context)
}
},
{
regexp: /^(\w+)$/i,
select: function (context, name) {
if (byName(name)) {
throw new BrowserslistError(
'Specify versions in Browserslist query for browser ' + name)
} else {
throw unknownQuery(name)
}
}
}
];