feature-matrix
Advanced tools
Comparing version
{ | ||
"name": "feature-matrix", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "A library for displaying a product's browser version requirements based on the underlying features", | ||
@@ -8,2 +8,3 @@ "author": "Concept Safety Systems", | ||
"scripts": { | ||
"test": "mocha --compilers js:babel-core/register", | ||
"build": "webpack --config=webpack.config.dev.js", | ||
@@ -14,11 +15,19 @@ "build-prod": "webpack --config=webpack.config.prod.js", | ||
"devDependencies": { | ||
"autoprefixer-loader": "^3.2.0", | ||
"babel-core": "^6.9.1", | ||
"babel-loader": "^6.2.4", | ||
"babel-preset-es2015": "^6.9.0", | ||
"chai": "^3.5.0", | ||
"css-loader": "^0.23.1", | ||
"extract-text-webpack-plugin": "^1.0.1", | ||
"mocha": "^2.5.3", | ||
"node-sass": "^3.8.0", | ||
"sass-loader": "^3.2.1", | ||
"style-loader": "^0.13.1", | ||
"webpack": "^1.13.1" | ||
}, | ||
"dependencies": { | ||
"jquery": "^1.12.4" | ||
"jquery": "^1.12.4", | ||
"xhr": "^2.2.0" | ||
} | ||
} |
@@ -0,1 +1,3 @@ | ||
import parseProductVersionString from './parseProductVersionString'; | ||
export const browsers = { | ||
@@ -7,5 +9,5 @@ 'chrome': { | ||
'matches': [ | ||
/chrome/gi, | ||
/google chrome/gi | ||
] | ||
/^chrome$/i, | ||
], | ||
'minVersion': 5 | ||
}, | ||
@@ -17,4 +19,3 @@ 'ie': { | ||
'matches': [ | ||
/ie/gi, | ||
/internet explorer/gi | ||
/^ie$/i | ||
], | ||
@@ -28,4 +29,3 @@ 'minVersion': 6 | ||
'matches': [ | ||
/edge/gi, | ||
/microsoft edge/gi | ||
/^edge$/i, | ||
], | ||
@@ -39,6 +39,46 @@ 'minVersion': 12 | ||
'matches': [ | ||
/ff/gi, | ||
/firefox/gi, | ||
/mozilla firefox/gi | ||
/^ff$/i, | ||
/^firefox$/i, | ||
], | ||
'minVersion': 2 | ||
}, | ||
'safari': { | ||
'icon': 'https://www.browserfeatures.io/images/safari/safari_128x128.png', | ||
'name': 'Safari', | ||
'shortName': 'Safari', | ||
'matches': [ | ||
/^safari$/i, | ||
] | ||
}, | ||
'opera': { | ||
'icon': 'https://www.browserfeatures.io/images/opera/opera_128x128.png', | ||
'name': 'Opera', | ||
'shortName': 'Opera', | ||
'matches': [ | ||
/^opera$/i, | ||
] | ||
}, | ||
'ios': { | ||
'icon': 'https://www.browserfeatures.io/images/safari-ios/safari-ios_128x128.png', | ||
'name': 'iOS Safari', | ||
'shortName': 'iOS', | ||
'matches': [ | ||
/^ios_saf$/i, | ||
] | ||
}, | ||
'android-browser': { | ||
'icon': 'http://cdn.rawgit.com/alrra/browser-logos/master/android/android_128x128.png', | ||
'name': 'Android Browser', | ||
'shortName': 'Android Browser', | ||
'matches': [ | ||
/^android$/i, | ||
] | ||
}, | ||
'android-chrome': { | ||
'icon': 'https://www.browserfeatures.io/images/chrome-android/chrome-android_128x128.png', | ||
'name': 'Android Chrome', | ||
'shortName': 'Android Chrome', | ||
'matches': [ | ||
/^and_chr$/i, | ||
] | ||
} | ||
@@ -50,9 +90,5 @@ }; | ||
// a match on our name | ||
for (var key in browsers) { | ||
if (!browsers.hasOwnProperty(key)) { | ||
continue; | ||
} | ||
for (var i = 0; i < browsers[key].matches.length; ++i) { | ||
if (browsers[key].matches[i].test(name)) { | ||
for (let key of Object.keys(browsers)) { | ||
for (let match of browsers[key].matches) { | ||
if (match.test(name)) { | ||
return key; | ||
@@ -65,1 +101,17 @@ } | ||
} | ||
export function parseBrowserVersionString(str) { | ||
let parsed = parseProductVersionString(str); | ||
if (!parsed) { | ||
throw new Error('unable to parse browser product/version string'); | ||
} | ||
parsed.product = parseBrowserName(parsed.product); | ||
if (!parsed.product) { | ||
throw new Error('browser ' + str + ' is unknown'); | ||
} | ||
return parsed; | ||
} |
@@ -0,175 +1,185 @@ | ||
import $ from 'jquery'; | ||
import browserFeatureProviders from './featureProviders'; | ||
import { browsers } from './browsers'; | ||
import FeatureMatrixRequirements from './FeatureMatrixRequirements'; | ||
import { pivot, groupColumns } from './columns'; | ||
require('./featureMatrix.scss') | ||
var plugins = { | ||
'Flash': { | ||
'blacklist': [ | ||
'Mobile Safari', | ||
'Opera Mini', | ||
'Android Chrome' | ||
], | ||
'whitelist': [ | ||
'IE', | ||
'Chrome', | ||
'Firefox', | ||
'Safari', | ||
'Opera' | ||
] | ||
function getBrowsers(columns) { | ||
var browsers = []; | ||
for (let c of columns) { | ||
if (browsers.length == 0 || browsers[browsers.length - 1].name != c.name) { | ||
browsers.push({ | ||
name: c.name, | ||
icon: c.icon, | ||
span: 1 | ||
}); | ||
} else { | ||
browsers[browsers.length - 1].span += 1; | ||
} | ||
} | ||
}; | ||
return browsers; | ||
} | ||
// can't use export default syntax due to UMD library shenanigans with webpack, | ||
// we set module.exports at the bottom of the file instead. | ||
class FeatureMatrix { | ||
// hello fancy ES6 syntax for specifying default options | ||
// https://gist.github.com/ericelliott/f3c2a53a1d4100539f71 | ||
constructor(mountpoint, requirements, { | ||
supportedText = '\u2714', | ||
partialText = '\u2714', | ||
unsupportedText = '-', | ||
unknownText = '?', | ||
featureColumnLabel = 'Feature', | ||
pluginRequirementGenerator = (plugin, version) => `Requires the installation of ${plugin} ${version}` | ||
} = {}) { | ||
this.mountpoint = $(mountpoint); | ||
Object.assign(this, { | ||
requirements, supportedText, unsupportedText, unknownText, | ||
featureColumnLabel, pluginRequirementGenerator, partialText | ||
}); | ||
requirements.onLoad((r) => { | ||
this.render(); | ||
}); | ||
} | ||
render() { | ||
this.mountpoint.addClass("feature-matrix"); | ||
let table = $('<table>'); | ||
let columns = []; | ||
Object.keys(browsers).forEach((browser) => { | ||
let cols = this.requirements.getBrowserSupport(browser, this.pluginRequirementGenerator); | ||
columns = columns.concat(cols); | ||
}); | ||
columns = groupColumns(columns); | ||
let rows = pivot(columns, this.requirements.features.length); | ||
let header = $("<thead>"); | ||
let browserHeaderRow = $("<tr>"); | ||
let versionHeaderRow = $("<tr>"); | ||
header.append(browserHeaderRow); | ||
header.append(versionHeaderRow); | ||
browserHeaderRow.append('<th rowspan="2" class="feature">' + this.featureColumnLabel + "</th>"); | ||
getBrowsers(columns).forEach((b) => { | ||
browserHeaderRow.append('<th colspan="' + b.span + '" class="browser"><img src="' + b.icon + '" alt="" /><br />' + b.name.replace(/\s+/g, '<br />') + "</th>") | ||
}); | ||
// the image is purely decorative, so we use an empty alt="" attribute | ||
columns.forEach(col => versionHeaderRow.append('<th class="version">' + col.version + "</th>")); | ||
function pivot(columns, numRows) { | ||
var rows = []; | ||
table.append(header); | ||
for (var i = 0; i < numRows; ++i) { | ||
var feature = columns[0].features[i].name; | ||
var featureSupport = []; | ||
let body = $("<tbody>"); | ||
columns.forEach(function (column) { | ||
featureSupport.push(column.features[i].support); | ||
// first pass to pull out any conditions and map them to superscript numbers | ||
let conditions = {}; | ||
let conditionsInOrder = []; | ||
let nextCondition = 1; | ||
rows.forEach((row) => { | ||
row.support.forEach((s) => { | ||
if (s.conditions) { | ||
s.conditions.forEach((c) => { | ||
if (!conditions[c]) { | ||
conditions[c] = nextCondition++; | ||
conditionsInOrder.push(c); | ||
} | ||
}); | ||
} | ||
}); | ||
}); | ||
rows.push({ | ||
feature: feature, | ||
support: featureSupport | ||
}); | ||
} | ||
const getSuperscripts = (supportColumn) => { | ||
let superscripts = []; | ||
if (supportColumn.conditions) { | ||
supportColumn.conditions.forEach((c) => { | ||
superscripts.push('' + conditions[c]); | ||
}); | ||
} | ||
return rows; | ||
} | ||
function combineColumnsIntoGroup(columns) { | ||
if (columns.length == 1) { | ||
return columns[0]; | ||
} else if (columns.length == 2) { | ||
var versions = columns.map(function (c) { return c.version; }).join(", "); | ||
return { | ||
name: columns[0].name, | ||
version: versions, | ||
features: columns[0].features | ||
return superscripts; | ||
}; | ||
} else { | ||
var version = columns[0].version + " - " + columns[columns.length - 1].version; | ||
const toObj = (arr) => { | ||
let obj = {}; | ||
if (columns[0].isOldest) { | ||
version = "< " + columns[columns.length - 1].nextVersion; | ||
} | ||
for (let item of arr) { | ||
obj[item] = true; | ||
} | ||
if (columns[columns.length - 1].isNewest) { | ||
version = columns[0].version + "+"; | ||
} | ||
return obj; | ||
}; | ||
return { | ||
name: columns[0].name, | ||
version: version, | ||
features: columns[0].features | ||
// http://stackoverflow.com/questions/34392741/best-way-to-get-intersection-of-keys-of-two-objects | ||
const intersect = (a, b) => { | ||
return Object.keys(a).filter({}.hasOwnProperty.bind(b)); | ||
}; | ||
} | ||
} | ||
function columnsAreGroupable(a, b) { | ||
if (a.name != b.name || a.features.length != b.features.length) { | ||
return false; | ||
} | ||
const getCommonSuperscrips = (row) => { | ||
let intersection = null; | ||
// HACK: quick and dirty way to deeply compare objects but is very | ||
// dependent on the order of serialization | ||
return JSON.stringify(a.features) == JSON.stringify(b.features); | ||
} | ||
for (let column of row.support) { | ||
if (intersection == null) { | ||
intersection = toObj(getSuperscripts(column)); | ||
} else { | ||
intersection = toObj(intersect(intersection, toObj(getSuperscripts(column)))); | ||
} | ||
} | ||
// takes columns of IE6, IE7, IE8, IE9, etc and groups them into columns | ||
// of IE6-IE8, IE9 (etc) based on whether those columns all have the same | ||
// compatibility | ||
function groupColumns(columns) { | ||
let grouped = []; | ||
let currGroup = null; | ||
return intersection; | ||
}; | ||
columns.forEach(function (column) { | ||
if (currGroup == null) { | ||
currGroup = [ column ]; | ||
} else if (columnsAreGroupable(currGroup[currGroup.length - 1], column)) { | ||
// this column has the same compatibility/browser as the previous | ||
// one so add it in | ||
currGroup.push(column); | ||
} else { | ||
// this is different, push the current group into our list and | ||
// create a new group | ||
grouped.push(combineColumnsIntoGroup(currGroup)); | ||
currGroup = [ column ]; | ||
} | ||
}); | ||
const renderSuperscripts = (supportColumn, exclude) => { | ||
let superscripts = null; | ||
if (currGroup != null && currGroup.length > 0) { | ||
grouped.push(combineColumnsIntoGroup(currGroup)); | ||
} | ||
if (supportColumn instanceof Array) { | ||
superscripts = supportColumn; | ||
} else { | ||
superscripts = getSuperscripts(supportColumn).filter(ss => !exclude[ss]); | ||
} | ||
return grouped; | ||
} | ||
superscripts.sort(); | ||
// can't use export default syntax due to UMD library shenanigans with webpack, | ||
// we set module.exports later on | ||
class FeatureMatrix { | ||
constructor(mountpoint, requirements) { | ||
this.mountpoint = $(mountpoint); | ||
this.requirements = requirements; | ||
if (superscripts.length > 0) { | ||
return "<sup>" + superscripts.join(',') + "</sup>"; | ||
} else { | ||
return ''; | ||
} | ||
}; | ||
requirements.onLoad((r) => { | ||
this.render(); | ||
}); | ||
} | ||
rows.forEach((row) => { | ||
let tr = $("<tr>"); | ||
render() { | ||
let table = $("<table>"); | ||
let columns = []; | ||
//let common = getCommonSuperscrips(row); | ||
let common = {}; | ||
Object.keys(browsers).forEach((browser) => { | ||
columns = columns.concat(this.requirements.getBrowserSupport(browser)); | ||
}); | ||
tr.append('<td class="feature"><span>' + row.feature + '</span>' + renderSuperscripts(Object.keys(common), {}) + "</td>"); | ||
columns = groupColumns(columns); | ||
let rows = pivot(columns, this.requirements.features.length); | ||
let header = $("<thead>"); | ||
header.append("<th>Feature</th>"); | ||
columns.forEach(col => header.append("<th>" + col.name + " " + col.version + "</th>")); | ||
table.append(header); | ||
let body = $("<tbody>"); | ||
rows.forEach((row) => { | ||
let tr = $("<tr>"); | ||
tr.append("<td>" + row.feature + "</td>"); | ||
row.support.forEach((s) => { | ||
switch (s.support) { | ||
case 'supported': | ||
tr.append("<td>Y</td>"); | ||
tr.append('<td class="support supported"><span>' + this.supportedText + "</span>" + renderSuperscripts(s, common) + "</td>"); | ||
break; | ||
case 'partial': | ||
tr.append('<td class="support partial"><span>' + this.partialText + "</span>" + renderSuperscripts(s, common) + "</td>"); | ||
break; | ||
case 'unsupported': | ||
tr.append("<td>X</td>"); | ||
tr.append('<td class="support unsupported"><span>' + this.unsupportedText + "</span>" + renderSuperscripts(s, common) + "</td>"); | ||
break; | ||
default: | ||
tr.append("<td>?</td>"); | ||
tr.append('<td class="support unknown"><span>' + this.unknownText + "</span>" + renderSuperscripts(s, common) + "</td>"); | ||
break; | ||
@@ -185,2 +195,11 @@ } | ||
this.mountpoint.append(table); | ||
// add superscript values | ||
let conditionsList = $('<div class="conditions">'); | ||
for (let [i, c] of conditionsInOrder.entries()) { | ||
conditionsList.append($("<p><sup>[" + (i + 1) + "]</sup> " + c + "</li>")); | ||
} | ||
this.mountpoint.append(conditionsList); | ||
} | ||
@@ -187,0 +206,0 @@ |
import $ from 'jquery'; | ||
import ProductFeature from './ProductFeature'; | ||
import BrowserSupportList from './BrowserSupportList'; | ||
import browserFeatureProviders from './featureProviders'; | ||
import parseCaniuseBrowserVersion from './parseCaniuseBrowserVersion'; | ||
import { parseBrowserName, browsers } from './browsers'; | ||
import { getBrowserNotes } from './notes'; | ||
@@ -14,5 +17,13 @@ export default class FeatureMatrixRequirements { | ||
if (requirements.forcePartialSupport) { | ||
this.forcePartialList = new BrowserSupportList(null, requirements.forcePartialSupport); | ||
} | ||
if (requirements.forceUnsupported) { | ||
this.forceUnsupportedList = new BrowserSupportList(null, requirements.forceUnsupported); | ||
} | ||
++this.numLookups; | ||
$.ajax({ | ||
url: 'http://api.browserfeatures.io/v1/browser/stable', | ||
url: 'http://cdn.rawgit.com/Fyrd/caniuse/master/sample-data.json', | ||
error: (xhr, textStatus, errorThrown) => { | ||
@@ -25,3 +36,3 @@ throw new Error('failed to lookup browsers'); | ||
} else { | ||
Object.keys(data.browsers).forEach((browser) => { | ||
Object.keys(data.stats).forEach((browser) => { | ||
var parsed = parseBrowserName(browser); | ||
@@ -32,3 +43,14 @@ if (!parsed) { | ||
this.browsers[parsed] = data.browsers[browser]; | ||
var versions = []; | ||
Object.keys(data.stats[browser]).forEach((version) => { | ||
parseCaniuseBrowserVersion('' + version, (v) => { | ||
if (versions.indexOf(v) == -1) { | ||
versions.push(v); | ||
} | ||
}); | ||
}); | ||
versions.sort((a, b) => a - b); | ||
this.browsers[parsed] = versions; | ||
}); | ||
@@ -84,26 +106,67 @@ | ||
getBrowserSupport(browser) { | ||
getBrowserNotesFromSupport(name, version, supportLevel) { | ||
if (!this.requirements.notes) { | ||
return []; | ||
} | ||
if (supportLevel == 'supported') { | ||
return getBrowserNotes(this.requirements.notes.supported, name, version); | ||
} else if (supportLevel == 'partial') { | ||
return getBrowserNotes(this.requirements.notes.partiallySupported, name, version); | ||
} else if (supportLevel == 'unsupported') { | ||
return getBrowserNotes(this.requirements.notes.unsupported, name, version); | ||
} else { | ||
return getBrowserNotes(this.requirements.notes.unknown, name, version); | ||
} | ||
} | ||
getBrowserSupport(browser, pluginRequirementGenerator) { | ||
var support = []; | ||
var maxVersion = this.browsers[browser]; | ||
var minVersion = browsers[browser].minVersion || 1; | ||
var versions = this.browsers[browser]; | ||
var minVersion = browsers[browser].minVersion || versions[0]; | ||
var maxVersion = versions[versions.length - 1]; | ||
for (var i = minVersion; i <= maxVersion; ++i) { | ||
versions.forEach((version, i) => { | ||
if (version < minVersion) { | ||
return; | ||
} | ||
var versionSupport = { | ||
name: browser, | ||
version: "" + i, | ||
nextVersion: "" + (i + 1), | ||
isOldest: (i == minVersion), | ||
isNewest: (i == maxVersion), | ||
name: browsers[browser].shortName, | ||
version: "" + version, | ||
icon: browsers[browser].icon, | ||
prevVersion: versions[i - 1], | ||
nextVersion: versions[i + 1], | ||
isOldest: (version == minVersion), | ||
isNewest: (version == maxVersion), | ||
features: [] | ||
}; | ||
this.features.forEach(function (feature) { | ||
versionSupport.features.push({ | ||
name: feature.humanReadableName, | ||
support: feature.getBrowserSupport(browser, i) | ||
}); | ||
this.features.forEach((feature) => { | ||
let column = null; | ||
if (this.forceUnsupportedList && this.forceUnsupportedList.check(browser, version)) { | ||
column = { | ||
name: feature.humanReadableName, | ||
support: { support: 'unsupported', conditions: feature.getNotes() } | ||
}; | ||
} else { | ||
column = { | ||
name: feature.humanReadableName, | ||
support: feature.getBrowserSupport(browser, version, pluginRequirementGenerator) | ||
}; | ||
} | ||
// what have I done | ||
if (column.support.support == 'supported' && this.forcePartialList && this.forcePartialList.check(browser, version)) { | ||
column.support.support = 'partial'; | ||
} | ||
column.support.conditions = column.support.conditions.concat(this.getBrowserNotesFromSupport(browser, version, column.support.support)); | ||
versionSupport.features.push(column); | ||
}); | ||
support.push(versionSupport); | ||
} | ||
}); | ||
@@ -110,0 +173,0 @@ return support; |
@@ -1,2 +0,2 @@ | ||
import $ from 'jquery'; | ||
import xhr from 'xhr'; | ||
import { parseBrowserName } from '../browsers'; | ||
@@ -7,38 +7,61 @@ | ||
$.ajax({ | ||
url: 'http://api.browserfeatures.io/v1/feature/' + featureName, | ||
error: function (xhr, textStatus, errorThrown) { | ||
onComplete({ status: textStatus, error: errorThrown }); | ||
}, | ||
success: function (data) { | ||
if (data.error) { | ||
onComplete(data); | ||
} else { | ||
// normalise the caniuse browser information into something | ||
// we can deal with | ||
var res = {}; | ||
xhr({ | ||
uri: 'http://cdn.rawgit.com/Fyrd/caniuse/master/features-json/' + featureName + '.json', | ||
useXDR: true | ||
}, function (err, resp, body) { | ||
if (err) { | ||
onComplete({ statusCode: err.statusCode, error: err.body}); | ||
} else { | ||
var data = JSON.parse(body); | ||
for (var key in data.browsers) { | ||
if (!data.browsers.hasOwnProperty(key)) { | ||
continue; | ||
// normalise the caniuse browser information into something | ||
// we can deal with | ||
var res = {}; | ||
for (const key of Object.keys(data.stats)) { | ||
const parsed = parseBrowserName(key); | ||
if (!parsed) { | ||
continue; | ||
} | ||
if (res[parsed]) { | ||
throw new Error('duplicate browser was parsed'); | ||
} | ||
const browserInfo = data.stats[key]; | ||
let supported = false; | ||
let minVersion = Number.MAX_VALUE; | ||
let maxVersion = Number.MIN_VALUE; | ||
for (const versionStr of Object.keys(browserInfo)) { | ||
const value = browserInfo[versionStr]; | ||
if (value[0] != 'y' && value[0] != 'a') { | ||
continue; // not supported | ||
} | ||
var parsed = parseBrowserName(key); | ||
if (!parsed) { | ||
// either fully or partially supported, we treat both as | ||
// being supported and rely on users to add blacklist | ||
// entries for the times where this assumption isn't ok | ||
supported = true; | ||
const version = parseFloat(versionStr); | ||
if (isNaN(version)) { | ||
continue; | ||
} | ||
var info = data.browsers[key]; | ||
minVersion = Math.min(version, minVersion); | ||
maxVersion = Math.max(version, maxVersion); | ||
} | ||
res[parsed] = { | ||
supported: info.supported, | ||
since: info.since | ||
}; | ||
res[parsed] = { supported: supported }; | ||
if (supported) { | ||
res[parsed].since = minVersion; | ||
} | ||
} | ||
onComplete(null, res); | ||
} | ||
onComplete(null, res); | ||
} | ||
}); | ||
} | ||
} |
@@ -0,54 +1,52 @@ | ||
import parseProductVersionString from './parseProductVersionString'; | ||
import { parseBrowserVersionString } from './browsers'; | ||
import { getBrowserNotes } from './notes'; | ||
import BrowserSupport from './BrowserSupport'; | ||
export default class ProductFeature { | ||
constructor(key, spec, lookupBrowserFeature) { | ||
this.supportedBrowsers = {}; | ||
this.unsupportedBrowsers = {}; | ||
this.notes = spec.notes; | ||
this.humanReadableName = spec.humanReadableName; | ||
this.key = key; | ||
if (spec.supported) { | ||
this.requiredSupport = new BrowserSupport(spec.supported, lookupBrowserFeature); | ||
} | ||
if (spec.requiredBrowserFeatures) { | ||
spec.requiredBrowserFeatures.forEach((browserFeature) => { | ||
var provider = browserFeature.split(':')[0]; | ||
var browserFeatureName = browserFeature.substring(browserFeature.indexOf(':') + 1); | ||
if (spec.partiallySupported) { | ||
this.partialSupport = new BrowserSupport(spec.partiallySupported, lookupBrowserFeature); | ||
} | ||
} | ||
lookupBrowserFeature(provider, browserFeatureName, (support) => { | ||
for (var key in support) { | ||
if (!support.hasOwnProperty(key)) { | ||
continue; | ||
} | ||
getNotes(name, version) { | ||
return getBrowserNotes(this.notes, name, version); | ||
} | ||
if (support[key].supported) { | ||
this.supportedBrowsers[key] = support[key]; | ||
} else { | ||
this.unsupportedBrowsers[key] = true; | ||
} | ||
} | ||
}); | ||
}); | ||
getBrowserSupport(name, version, pluginRequirementGenerator) { | ||
let notes = this.getNotes(name, version); | ||
let support = { support: "unknown" }; | ||
if (this.requiredSupport) { | ||
support = this.requiredSupport.getBrowserSupport(name, version, pluginRequirementGenerator); | ||
} | ||
} | ||
getBrowserSupport(name, version) { | ||
// are we blacklisted? if so, we *really* don't support this browser | ||
if (support.support != 'supported' && this.partialSupport) { | ||
let partialSupport = this.partialSupport.getBrowserSupport(name, version, pluginRequirementGenerator); | ||
// are we whitelisted? if so, we do support this browser | ||
if (partialSupport.support == 'supported') { | ||
support = partialSupport; | ||
support.support = 'partial'; | ||
} | ||
} | ||
// do all of our browser features work in this browser? | ||
// if so, we do support this browser | ||
// if there is a feature that would work in a newer version of this browser | ||
// or the feature flat-out isn't supported, we don't support this browser | ||
if (this.supportedBrowsers[name] && version >= this.supportedBrowsers[name].since) { | ||
return { support: 'supported' }; | ||
} else if (this.unsupportedBrowsers[name] || (this.supportedBrowsers[name] && version < this.supportedBrowsers[name].since)) { | ||
return { support: 'unsupported' }; | ||
if (!support.conditions) { | ||
support.conditions = []; | ||
} | ||
// do we require plugins which are supported in this browser? | ||
// if so, we do support this browser but only conditionally on the | ||
// presence of said plugin | ||
// if we've gotten to this point, we have no clue about this browser, | ||
// so we can't say whether we do or don't support it | ||
return { support: 'unknown' }; | ||
// add in our notes to the final conditions | ||
support.conditions = support.conditions.concat(notes); | ||
return support; | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
1146051
54.06%21
40%82
8100%2
100%12
140%1488
-84.93%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added