Skip to content

Commit

Permalink
feat: add toChromium and toDesktop normalizers
Browse files Browse the repository at this point in the history
  • Loading branch information
ylemkimon committed Jul 23, 2020
1 parent cd652ee commit 5f7cec5
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 1 deletion.
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -522,6 +522,13 @@ Options:
* `normalizers`: An array of names of normalizers below and functions
that accept a browser and return the normalized versions, which are
applied to resolved browsers in order. For instance, `['toChromium', 'toDesktop']`.
* `toChromium`: Normalize Chromium-based browsers to Chrome. For instance,
UC Browser, QQ Browser, Baidu browser for Android, and Samsung Internet
will return `and_chr` with the version of Chromium they are based on.
Note Edge and Opera is not normalized. Gecko-based browsers are
also normalized to Firefox, e.g., KaiOS Browser will return `and_ff`.
* `toDesktop`: Normalize mobile browsers to desktop browsers.
For instance, Browserslist will return `chrome 20` on `and_chr 20`
* `keepOriginal`: Keep the original browser when normalizing with `normalizers`

For non-JS environment and debug purpose you can use CLI tool:
Expand Down
56 changes: 55 additions & 1 deletion index.js
Expand Up @@ -9,6 +9,7 @@ var env = require('./node') // Will load browser.js in webpack

var YEAR = 365.259641 * 24 * 60 * 60 * 1000
var ANDROID_EVERGREEN_FIRST = 37
var ANDROID_CLASSIC_REGEX = /^(?:[2-4]\.|[34]$)/

var QUERY_OR = 1
var QUERY_AND = 2
Expand Down Expand Up @@ -265,7 +266,7 @@ function normalizeAndroidVersions (androidVersions, chromeVersions) {
var firstEvergreen = ANDROID_EVERGREEN_FIRST
var last = chromeVersions[chromeVersions.length - 1]
return androidVersions
.filter(function (version) { return /^(?:[2-4]\.|[34]$)/.test(version) })
.filter(function (version) { return ANDROID_CLASSIC_REGEX.test(version) })
.concat(chromeVersions.slice(firstEvergreen - last - 1))
}

Expand Down Expand Up @@ -564,6 +565,39 @@ browserslist.desktopNames = {
android: 'chrome' // has extra processing logic
}

// Tools such as compat-table only provides compatibility data for
// popular browsers. Fallback to Chrome for Chromium-based browsers
// and Firefox for Gecko-based browsers. A number indicates `and_chr`
// If other mobile browsers are used than `and_chr` or `and_ff`,
// mobileToDesktop logic should be updated in `resolve`
browserslist.normalizedVersions = {
// From Samsung Internet release notes at
// https://developer.samsung.com/internet/release-note.html,
// Chrome version page (chrome://version), and the user agent string
'samsung 4': 44,
'samsung 5': 51,
'samsung 6': 56,
'samsung 7': 59,
'samsung 8': 63,
'samsung 9': 67,
'samsung 10': 71,
'samsung 11': 75,
'samsung 12': 79,

// From the kernel version at https://plus.ucweb.com/download/
// and the user agent string
'and_uc 12': 57,

// From https://browser.qq.com/ and the user agent string
'and_qq 10': 70,

// From the user agent string
'baidu 7': 48,

// From https://github.com/kaiostech/gecko-b2g and the user agent string
'kaios 2': 'and_ff 48'
}

// Aliases to work with joined versions like `ios_saf 7.0-7.1`
browserslist.versionAliases = { }

Expand Down Expand Up @@ -1162,6 +1196,26 @@ var QUERIES = [
]

var NORMALIZERS = {
toChromium: function (browser) {
var major = browser.split('.')[0]
var normalized = browserslist.normalizedVersions[major]
if (!normalized) {
return browser
} else if (typeof normalized === 'number') {
normalized = 'and_chr ' + normalized
}
return normalized
},
toDesktop: function (browser) {
browser = browser.split(' ')
var name = browser[0]
var version = browser[1]
if (browserslist.desktopNames[name] &&
!(name === 'android' && ANDROID_CLASSIC_REGEX.test(version))) {
name = browserslist.desktopNames[name]
}
return name + ' ' + version
}
};

// Get and convert Can I Use data
Expand Down
42 changes: 42 additions & 0 deletions test/normalizer.test.js
@@ -1,6 +1,7 @@
let browserslist = require('../')

let originData = browserslist.data
let originNormalizedVersions = browserslist.normalizedVersions

beforeEach(() => {
browserslist.data = {
Expand All @@ -25,10 +26,44 @@ beforeEach(() => {
versions: ['83']
}
}

browserslist.normalizedVersions = {
'samsung 4': 44,
'kaios 2': 'and_ff 48'
}
})

afterEach(() => {
browserslist.data = originData
browserslist.normalizedVersions = originNormalizedVersions
})

it('normalizes mobile browsers to desktop browsers', () => {
let opts = { normalizers: ['toDesktop'] }
expect(browserslist('android 37', opts)).toEqual(['chrome 37'])
expect(browserslist('last 1 and_chr versions', opts)).toEqual(['chrome 83'])
expect(browserslist('samsung 4', opts)).toEqual(['samsung 4'])
})

it('does not normalize classic Android webview versions', () => {
let opts = { normalizers: ['toDesktop'] }
expect(browserslist('android 4.4-37', opts)).toEqual([
'android 4.4.3-4.4.4', 'android 4.4', 'chrome 37'
])
})

it('normalizes Chromium-based browsers to Chrome', () => {
let opts = { normalizers: ['toChromium'] }
expect(browserslist('samsung 4', opts)).toEqual(['and_chr 44'])
expect(browserslist('kaios 2.5', opts)).toEqual(['and_ff 48'])
expect(browserslist('and_chr 83', opts)).toEqual(['and_chr 83'])
})

it('should apply each normalizer in order', () => {
let opts = { normalizers: ['toChromium', 'toDesktop'] }
expect(browserslist('samsung 4', opts)).toEqual(['chrome 44'])
expect(browserslist('kaios 2.5', opts)).toEqual(['firefox 48'])
expect(browserslist('and_chr 83', opts)).toEqual(['chrome 83'])
})

it('accepts a normalizer function', () => {
Expand All @@ -46,3 +81,10 @@ it('raises on unknown normalizer', () => {
browserslist('samsung 4', opts2)
}).toThrow('Unknown normalizer [object Object]')
})

it('keeps original browsers', () => {
let opts = { normalizers: ['toChromium'], keepOriginal: true }
expect(browserslist('samsung 4', opts)).toEqual(['and_chr 44', 'samsung 4'])
expect(browserslist('kaios 2.5', opts)).toEqual(['and_ff 48', 'kaios 2.5'])
expect(browserslist('and_chr 83', opts)).toEqual(['and_chr 83'])
})

0 comments on commit 5f7cec5

Please sign in to comment.