Move generated .mjs file to /src

This commit is contained in:
Faisal Salman 2023-03-27 22:25:17 +07:00
parent 82567c28ab
commit ba28d33d51
3 changed files with 304 additions and 358 deletions

View File

@ -142,19 +142,19 @@
], ],
"type": "commonjs", "type": "commonjs",
"main": "src/ua-parser.js", "main": "src/ua-parser.js",
"module": "dist/ua-parser.mjs", "module": "src/ua-parser.mjs",
"exports": { "exports": {
"require": "./src/ua-parser.js", "require": "./src/ua-parser.js",
"import": "./dist/ua-parser.mjs" "import": "./src/ua-parser.mjs"
}, },
"files": [ "files": [
"dist", "dist",
"src" "src"
], ],
"scripts": { "scripts": {
"build": "uglifyjs src/ua-parser.js -o dist/ua-parser.min.js --comments '/^ UA/' && uglifyjs src/ua-parser.js -o dist/ua-parser.pack.js --comments '/^ UA/' --compress --mangle && node -e \"const fs=require('fs');fs.writeFileSync('dist/ua-parser.mjs','// Generated ESM version of UAParser.js\\n// Source file: /src/ua-parser.js\\n\\n'+fs.readFileSync('src/ua-parser.js','utf-8').replace(/\\(func[\\s\\S]+strict\\';/ig,'const window = undefined;').replace(/\\/[\\/\\s]+export[\\s\\S]+/ig,'export {UAParser};'),'utf-8')\"", "build": "uglifyjs src/ua-parser.js -o dist/ua-parser.min.js --comments '/^ UA/' && uglifyjs src/ua-parser.js -o dist/ua-parser.pack.js --comments '/^ UA/' --compress --mangle && node -e \"const fs=require('fs');fs.writeFileSync('src/ua-parser.mjs','// Generated ESM version of UAParser.js\\n// Source file: /src/ua-parser.js\\n\\nconst window = undefined;\\n\\n'+fs.readFileSync('src/ua-parser.js','utf-8').replace(/\\(func[\\s\\S]+strict\\';/ig,'').replace(/\\/[\\/\\s]+export[\\s\\S]+/ig,'export {UAParser};'),'utf-8')\"",
"test": "jshint src/ua-parser.js && mocha -R spec test/test.js && mocha -R spec test/es6-test.mjs", "test": "jshint src/ua-parser.js && mocha -R nyan test",
"test-ci": "jshint src/ua-parser.js && mocha -R spec test/test.js", "test-ci": "jshint src/ua-parser.js && mocha -R spec test",
"verup": "node ./node_modules/verup", "verup": "node ./node_modules/verup",
"version": "node ./node_modules/verup 0" "version": "node ./node_modules/verup 0"
}, },

View File

@ -1,6 +1,8 @@
// Generated ESM version of UAParser.js // Generated ESM version of UAParser.js
// Source file: /src/ua-parser.js // Source file: /src/ua-parser.js
const window = undefined;
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
/* UAParser.js v1.1.34 /* UAParser.js v1.1.34
Copyright © 2012-2023 Faisal Salman <f@faisalman.com> Copyright © 2012-2023 Faisal Salman <f@faisalman.com>
@ -11,7 +13,7 @@
Source : https://github.com/faisalman/ua-parser-js */ Source : https://github.com/faisalman/ua-parser-js */
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
const window = undefined;
////////////// //////////////
// Constants // Constants
@ -53,39 +55,37 @@ const window = undefined;
CH_HEADER_MODEL = CH_HEADER + '-model', CH_HEADER_MODEL = CH_HEADER + '-model',
CH_HEADER_PLATFORM = CH_HEADER + '-platform', CH_HEADER_PLATFORM = CH_HEADER + '-platform',
CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version', CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
CH_ALL_VALUES = ['brands', 'fullVersionList', MOBILE, MODEL, 'platform', 'platformVersion', ARCHITECTURE, 'bitness'], CH_ALL_VALUES = ['brands', 'fullVersionList', MOBILE, MODEL, 'platform', 'platformVersion', ARCHITECTURE, 'bitness'],
UA_BROWSER = 'browser', UA_BROWSER = 'browser',
UA_CPU = 'cpu', UA_CPU = 'cpu',
UA_DEVICE = 'device', UA_DEVICE = 'device',
UA_ENGINE = 'engine', UA_ENGINE = 'engine',
UA_OS = 'os', UA_OS = 'os',
UA_RESULT = 'result'; UA_RESULT = 'result',
AMAZON = 'Amazon',
var AMAZON = 'Amazon', APPLE = 'Apple',
APPLE = 'Apple', ASUS = 'ASUS',
ASUS = 'ASUS', BLACKBERRY = 'BlackBerry',
BLACKBERRY = 'BlackBerry', GOOGLE = 'Google',
GOOGLE = 'Google', HUAWEI = 'Huawei',
HUAWEI = 'Huawei', LG = 'LG',
LG = 'LG', MICROSOFT = 'Microsoft',
MICROSOFT = 'Microsoft', MOTOROLA = 'Motorola',
MOTOROLA = 'Motorola', SAMSUNG = 'Samsung',
SAMSUNG = 'Samsung', SHARP = 'Sharp',
SHARP = 'Sharp', SONY = 'Sony',
SONY = 'Sony', SWISS = 'Swiss',
SWISS = 'Swiss', XIAOMI = 'Xiaomi',
XIAOMI = 'Xiaomi', ZEBRA = 'Zebra',
ZEBRA = 'Zebra', ZTE = 'ZTE',
ZTE = 'ZTE', PREFIX_MOBILE = 'Mobile ',
SUFFIX_BROWSER = ' Browser',
BROWSER = 'Browser', CHROME = 'Chrome',
CHROME = 'Chrome', EDGE = 'Edge',
EDGE = 'Edge', FIREFOX = 'Firefox',
FIREFOX = 'Firefox', OPERA = 'Opera',
OPERA = 'Opera',
FACEBOOK = 'Facebook', FACEBOOK = 'Facebook',
WINDOWS = 'Windows';
WINDOWS = 'Windows';
var NAVIGATOR = (typeof window !== UNDEF_TYPE && window.navigator) ? var NAVIGATOR = (typeof window !== UNDEF_TYPE && window.navigator) ?
window.navigator : window.navigator :
@ -98,7 +98,18 @@ const window = undefined;
// Helper // Helper
////////// //////////
var extend = function (regexes, extensions) { var assignFromEntries = function (arr) {
for (var i in arr) {
var propName = arr[i];
if (typeof propName == OBJ_TYPE && propName.length == 2) {
this[propName[0]] = propName[1];
} else {
this[propName] = undefined;
}
}
return this;
},
extend = function (regexes, extensions) {
var mergedRegexes = {}; var mergedRegexes = {};
for (var i in regexes) { for (var i in regexes) {
mergedRegexes[i] = extensions[i] && extensions[i].length % 2 === 0 ? extensions[i].concat(regexes[i]) : regexes[i]; mergedRegexes[i] = extensions[i] && extensions[i].length % 2 === 0 ? extensions[i].concat(regexes[i]) : regexes[i];
@ -113,18 +124,13 @@ const window = undefined;
return enums; return enums;
}, },
has = function (str1, str2) { has = function (str1, str2) {
return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false; if (typeof str1 === OBJ_TYPE && str1.length > 0) {
}, for (var i in str1) {
initialize = function (arr) { if (lowerize(str1[i]) == lowerize(str2)) return true;
for (var i in arr) {
var propName = arr[i];
if (typeof propName == OBJ_TYPE && propName.length == 2) {
this[propName[0]] = propName[1];
} else {
this[propName] = undefined;
} }
return false;
} }
return this; return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
}, },
isExtensions = function (obj) { isExtensions = function (obj) {
for (var prop in obj) { for (var prop in obj) {
@ -141,8 +147,8 @@ const window = undefined;
} }
return arr; return arr;
}, },
lowerize = function (str, rgx) { lowerize = function (str) {
return typeof(str) === STR_TYPE ? strip((rgx ? new RegExp(rgx, 'i') : EMPTY), str.toLowerCase()) : str; return typeof(str) === STR_TYPE ? str.toLowerCase() : str;
}, },
majorize = function (version) { majorize = function (version) {
return typeof(version) === STR_TYPE ? strip(/[^\d\.]/g, version).split('.')[0] : undefined; return typeof(version) === STR_TYPE ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
@ -273,12 +279,13 @@ const window = undefined;
// Regex map // Regex map
///////////// /////////////
var regexes = { var defaultRegexes = {
browser : [[ browser : [[
// Most common regardless engine
/\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
], [VERSION, [NAME, 'Chrome']], [ ], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [
/edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge /edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge
], [VERSION, [NAME, 'Edge']], [ ], [VERSION, [NAME, 'Edge']], [
@ -302,11 +309,12 @@ const window = undefined;
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i, /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i,
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo
/(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
/(weibo)__([\d\.]+)/i // Weibo /(weibo)__([\d\.]+)/i // Weibo
], [NAME, VERSION], [ ], [NAME, VERSION], [
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
], [VERSION, [NAME, 'UC'+BROWSER]], [ ], [VERSION, [NAME, 'UCBrowser']], [
/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser /microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
/\bqbcore\/([\w\.]+).+microm/i /\bqbcore\/([\w\.]+).+microm/i
], [VERSION, [NAME, 'WeChat(Win) Desktop']], [ ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [
@ -316,10 +324,10 @@ const window = undefined;
], [VERSION, [NAME, 'Konqueror']], [ ], [VERSION, [NAME, 'Konqueror']], [
/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11 /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11
], [VERSION, [NAME, 'IE']], [ ], [VERSION, [NAME, 'IE']], [
/yabrowser\/([\w\.]+)/i // Yandex /ya(?:search)?browser\/([\w\.]+)/i // Yandex
], [VERSION, [NAME, 'Yandex']], [ ], [VERSION, [NAME, 'Yandex']], [
/(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
], [[NAME, /(.+)/, '$1 Secure '+BROWSER], VERSION], [ ], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [
/\bfocus\/([\w\.]+)/i // Firefox Focus /\bfocus\/([\w\.]+)/i // Firefox Focus
], [VERSION, [NAME, FIREFOX+' Focus']], [ ], [VERSION, [NAME, FIREFOX+' Focus']], [
/\bopt\/([\w\.]+)/i // Opera Touch /\bopt\/([\w\.]+)/i // Opera Touch
@ -331,13 +339,13 @@ const window = undefined;
/coast\/([\w\.]+)/i // Opera Coast /coast\/([\w\.]+)/i // Opera Coast
], [VERSION, [NAME, OPERA+' Coast']], [ ], [VERSION, [NAME, OPERA+' Coast']], [
/miuibrowser\/([\w\.]+)/i // MIUI Browser /miuibrowser\/([\w\.]+)/i // MIUI Browser
], [VERSION, [NAME, 'MIUI '+BROWSER]], [ ], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [
/fxios\/([-\w\.]+)/i // Firefox for iOS /fxios\/([\w\.-]+)/i // Firefox for iOS
], [VERSION, [NAME, FIREFOX]], [ ], [VERSION, [NAME, PREFIX_MOBILE + 'Firefox']], [
/\bqihu|(qi?ho?o?|360)browser/i // 360 /\bqihu|(qi?ho?o?|360)browser/i // 360
], [[NAME, '360 '+BROWSER]], [ ], [[NAME, '360' + SUFFIX_BROWSER]], [
/(oculus|samsung|sailfish|huawei)browser\/([\w\.]+)/i /(oculus|samsung|sailfish|huawei)browser\/([\w\.]+)/i
], [[NAME, /(.+)/, '$1 '+BROWSER], VERSION], [ // Oculus/Samsung/Sailfish/Huawei Browser ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Samsung/Sailfish/Huawei Browser
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
], [[NAME, /_/g, ' '], VERSION], [ ], [[NAME, /_/g, ' '], VERSION], [
/(electron)\/([\w\.]+) safari/i, // Electron-based App /(electron)\/([\w\.]+) safari/i, // Electron-based App
@ -368,14 +376,19 @@ const window = undefined;
], [[NAME, CHROME+' WebView'], VERSION], [ ], [[NAME, CHROME+' WebView'], VERSION], [
/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser
], [VERSION, [NAME, 'Android '+BROWSER]], [ ], [VERSION, [NAME, 'Android' + SUFFIX_BROWSER]], [
/chrome\/([\w\.]+) mobile/i // Chrome Mobile
], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [
/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia
], [NAME, VERSION], [ ], [NAME, VERSION], [
/version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i // Mobile Safari /version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i // Safari Mobile
], [VERSION, [NAME, 'Mobile Safari']], [ ], [VERSION, [NAME, PREFIX_MOBILE + 'Safari']], [
/version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile /iphone .*mobile(?:\/\w+ | ?)safari/i
], [[NAME, PREFIX_MOBILE + 'Safari']], [
/version\/([\w\.\,]+) .*(safari)/i // Safari
], [VERSION, NAME], [ ], [VERSION, NAME], [
/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0
], [NAME, [VERSION, strMapper, oldSafariMap]], [ ], [NAME, [VERSION, strMapper, oldSafariMap]], [
@ -384,6 +397,8 @@ const window = undefined;
], [NAME, VERSION], [ ], [NAME, VERSION], [
// Gecko based // Gecko based
/(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i // Firefox Mobile
], [[NAME, PREFIX_MOBILE + 'Firefox'], VERSION], [
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
], [[NAME, 'Netscape'], VERSION], [ ], [[NAME, 'Netscape'], VERSION], [
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
@ -453,7 +468,7 @@ const window = undefined;
], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [
// Apple // Apple
/\((ip(?:hone|od)[\w ]*);/i // iPod/iPhone /(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i // iPod/iPhone
], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [
/\((ipad);[-\w\),; ]+apple/i, // iPad /\((ipad);[-\w\),; ]+apple/i, // iPad
/applecoremedia\/[\w\.]+ \((ipad)/i, /applecoremedia\/[\w\.]+ \((ipad)/i,
@ -543,7 +558,7 @@ const window = undefined;
// Amazon // Amazon
/(alexa)webm/i, /(alexa)webm/i,
/(kf[a-z]{2}wi)( bui|\))/i, // Kindle Fire without Silk /(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i, // Kindle Fire without Silk / Echo Show
/(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD /(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD
], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [ ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [
/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone
@ -728,6 +743,8 @@ const window = undefined;
/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla
], [VENDOR, [TYPE, EMBEDDED]], [ ], [VENDOR, [TYPE, EMBEDDED]], [
/(aeobc)\b/i // Echo Dot
], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [
//////////////////// ////////////////////
// MIXED (GENERIC) // MIXED (GENERIC)
@ -778,6 +795,7 @@ const window = undefined;
// iOS/macOS // iOS/macOS
/ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
/ios;fbsv\/([\d\.]+)/i,
/cfnetwork\/.+darwin/i /cfnetwork\/.+darwin/i
], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
/(mac os x) ?([\w\. ]*)/i, /(mac os x) ?([\w\. ]*)/i,
@ -840,15 +858,108 @@ const window = undefined;
] ]
}; };
/////////////////
// Factories
////////////////
var defaultProps = (function () {
var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
assignFromEntries.call(props.init, [
[UA_BROWSER, [NAME, VERSION, MAJOR]],
[UA_CPU, [ARCHITECTURE]],
[UA_DEVICE, [TYPE, MODEL, VENDOR]],
[UA_ENGINE, [NAME, VERSION]],
[UA_OS, [NAME, VERSION]]
]);
assignFromEntries.call(props.isIgnore, [
[UA_BROWSER, [VERSION, MAJOR]],
[UA_ENGINE, [VERSION]],
[UA_OS, [VERSION]]
]);
assignFromEntries.call(props.isIgnoreRgx, [
[UA_BROWSER, / ?browser$/i],
[UA_OS, / ?os$/i]
]);
assignFromEntries.call(props.toString, [
[UA_BROWSER, [NAME, VERSION]],
[UA_CPU, [ARCHITECTURE]],
[UA_DEVICE, [VENDOR, MODEL]],
[UA_ENGINE, [NAME, VERSION]],
[UA_OS, [NAME, VERSION]]
]);
return props;
})();
var createUAParserData = function (itemType, ua, rgxMap, uaCH) {
var init_props = defaultProps.init[itemType],
is_ignoreProps = defaultProps.isIgnore[itemType] || 0,
is_ignoreRgx = defaultProps.isIgnoreRgx[itemType] || 0,
toString_props = defaultProps.toString[itemType] || 0;
function UAParserData () {
assignFromEntries.call(this, init_props);
}
UAParserData.prototype.withClientHints = function () {
// nodejs / non-client-hints browsers
if (!NAVIGATOR_UADATA) {
return new UAParserItem(itemType, ua, rgxMap, uaCH).parseCH().get();
}
// browsers based on chromium 85+
return NAVIGATOR_UADATA
.getHighEntropyValues(CH_ALL_VALUES)
.then(function (res) {
var JS_UACH = new UAParserDataCH(res, false);
return new UAParserItem(itemType, ua, rgxMap, JS_UACH).parseCH().get();
});
};
if (itemType != UA_RESULT) {
UAParserData.prototype.is = function (strToCheck) {
var is = false;
for (var i in this) {
if (this.hasOwnProperty(i) && !has(is_ignoreProps, i) && lowerize(is_ignoreRgx ? strip(is_ignoreRgx, this[i]) : this[i]) == lowerize(is_ignoreRgx ? strip(is_ignoreRgx, strToCheck) : strToCheck)) {
is = true;
if (strToCheck != UNDEF_TYPE) break;
} else if (strToCheck == UNDEF_TYPE && is) {
is = !is;
break;
}
}
return is;
};
UAParserData.prototype.toString = function () {
var str = EMPTY;
for (var i in toString_props) {
if (typeof(this[toString_props[i]]) !== UNDEF_TYPE) {
str += (str ? ' ' : EMPTY) + this[toString_props[i]];
}
}
return str || UNDEF_TYPE;
};
}
if (!NAVIGATOR_UADATA) {
UAParserData.prototype.then = function (cb) {
cb(this);
return this;
};
}
return new UAParserData();
};
///////////////// /////////////////
// Constructor // Constructor
//////////////// ////////////////
function UAParserDataCH (uach, isHTTP_UACH) { function UAParserDataCH (uach, isHTTP_UACH) {
uach = uach || {}; uach = uach || {};
initialize.call(this, CH_ALL_VALUES); assignFromEntries.call(this, CH_ALL_VALUES);
if (isHTTP_UACH) { if (isHTTP_UACH) {
initialize.call(this, [ assignFromEntries.call(this, [
[BRANDS, itemListToArray(uach[CH_HEADER])], [BRANDS, itemListToArray(uach[CH_HEADER])],
[FULLVERLIST, itemListToArray(uach[CH_HEADER_FULL_VER_LIST])], [FULLVERLIST, itemListToArray(uach[CH_HEADER_FULL_VER_LIST])],
[BRANDS, itemListToArray(uach[CH_HEADER])], [BRANDS, itemListToArray(uach[CH_HEADER])],
@ -861,129 +972,125 @@ const window = undefined;
]); ]);
} else { } else {
for (var prop in uach) { for (var prop in uach) {
if(this.hasOwnProperty(prop) && uach[prop]) this[prop] = stripQuotes(uach[prop]); if(this.hasOwnProperty(prop) && typeof uach[prop] !== UNDEF_TYPE) this[prop] = uach[prop];
} }
} }
return this; return this;
} }
function UAParserItem (data) { function UAParserItem (itemType, ua, rgxMap, uaCH) {
if (!data) return; assignFromEntries.call(this, [
this.ua = data[0]; ['itemType', itemType],
this.uaCH = data[1]; ['ua', ua],
this.rgxMap = data[3]; ['uaCH', uaCH],
this.data = (function (data) { ['rgxMap', rgxMap],
var ua = data[0], ['data', createUAParserData(itemType, ua, rgxMap, uaCH)]
uaCH = data[1], ]);
itemType = data[2], this.parse();
rgxMap = data[3], switch(this.itemType) {
init_props = data[4], case UA_BROWSER:
is_ignoreProps = data[5], // Brave-specific detection
is_ignoreRgx = data[6], if (NAVIGATOR && NAVIGATOR.userAgent == ua && NAVIGATOR.brave && typeof NAVIGATOR.brave.isBrave == FUNC_TYPE) {
toString_props = data[7]; this.set(NAME, 'Brave');
function UAParserData () {
initialize.call(this, init_props);
}
UAParserData.prototype.withClientHints = function () {
// nodejs / non-client-hints browsers
if (!NAVIGATOR_UADATA) {
var HTTP_UACH = uaCH;
switch (itemType) {
case UA_BROWSER:
return new UAParserBrowser(ua, rgxMap, HTTP_UACH).parseCH().get();
case UA_CPU:
return new UAParserCPU(ua, rgxMap, HTTP_UACH).parseCH().get();
case UA_DEVICE:
return new UAParserDevice(ua, rgxMap, HTTP_UACH).parseCH().get();
case UA_ENGINE:
return new UAParserEngine(ua, rgxMap).get();
case UA_OS:
return new UAParserOS(ua, rgxMap, HTTP_UACH).parseCH().get();
default :
return new UAParserResult(ua, rgxMap, HTTP_UACH)
.set('ua', ua)
.set('ua_ch', uaCH)
.set(UA_BROWSER, new UAParserBrowser(ua, rgxMap[UA_BROWSER], HTTP_UACH).parseCH().get())
.set(UA_CPU, new UAParserCPU(ua, rgxMap[UA_CPU], HTTP_UACH).parseCH().get())
.set(UA_DEVICE, new UAParserDevice(ua, rgxMap[UA_DEVICE], HTTP_UACH).parseCH().get())
.set(UA_ENGINE, new UAParserEngine(ua, rgxMap[UA_ENGINE]).get())
.set(UA_OS, new UAParserOS(ua, rgxMap[UA_OS], HTTP_UACH).parseCH().get())
.get();
}
} }
this.set(MAJOR, majorize(this.get(VERSION)));
// browsers based on chromium 85+ break;
return NAVIGATOR_UADATA case UA_DEVICE:
.getHighEntropyValues(CH_ALL_VALUES) if (!this.get(TYPE) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[MOBILE]) {
.then(function (res) { this.set(TYPE, MOBILE);
}
var JS_UACH = new UAParserDataCH(res, false); // iPadOS-specific detection: identified as Mac, but has some iOS-only properties
switch (itemType) { if (this.get(MODEL) == 'Macintosh' && NAVIGATOR && typeof NAVIGATOR.standalone !== UNDEF_TYPE && NAVIGATOR.maxTouchPoints && NAVIGATOR.maxTouchPoints > 2) {
case UA_BROWSER: this.set(MODEL, 'iPad')
return UAParserBrowser(ua, rgxMap, JS_UACH).parseCH().get(); .set(TYPE, TABLET);
case UA_CPU: }
return new UAParserCPU(ua, rgxMap, JS_UACH).parseCH().get(); break;
case UA_DEVICE: case UA_OS:
return new UAParserDevice(ua, rgxMap, JS_UACH).parseCH().get(); if (!this.get(NAME) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[PLATFORM] && NAVIGATOR_UADATA[PLATFORM] != 'Unknown') {
case UA_ENGINE: this.set(NAME, NAVIGATOR_UADATA[PLATFORM]);
return new UAParserEngine(ua, rgxMap).get(); }
case UA_OS: break;
return new UAParserOS(ua, rgxMap, JS_UACH).parseCH().get(); case UA_RESULT:
default : var createUAParserItem = function (itemType) {
return new UAParserResult(ua, rgxMap, JS_UACH) return new UAParserItem(itemType, ua, rgxMap[itemType], uaCH).get();
.set('ua', ua)
.set('ua_ch', JS_UACH)
.set(UA_BROWSER, new UAParserBrowser(ua, rgxMap[UA_BROWSER], JS_UACH).parseCH().get())
.set(UA_CPU, new UAParserCPU(ua, rgxMap[UA_CPU], JS_UACH).parseCH().get())
.set(UA_DEVICE, new UAParserDevice(ua, rgxMap[UA_DEVICE], JS_UACH).parseCH().get())
.set(UA_ENGINE, new UAParserEngine(ua, rgxMap[UA_ENGINE]).get())
.set(UA_OS, new UAParserOS(ua, rgxMap[UA_OS], JS_UACH).parseCH().get())
.get();
}
});
};
if(itemType != UA_RESULT) {
UAParserData.prototype.is = function (strToCheck) {
var is = false;
for (var i in this) {
if (this.hasOwnProperty(i) && !is_ignoreProps[i] && lowerize(this[i], is_ignoreRgx) === lowerize(strToCheck, is_ignoreRgx)) {
is = true;
if (strToCheck != UNDEF_TYPE) break;
} else if (strToCheck == UNDEF_TYPE && is) {
is = !is;
break;
}
}
return is;
}; };
UAParserData.prototype.toString = function () { this.set('ua', ua)
var str = EMPTY; .set('ua_ch', uaCH)
for (var i in toString_props) { .set(UA_BROWSER, createUAParserItem(UA_BROWSER))
if (typeof(this[toString_props[i]]) !== UNDEF_TYPE) { .set(UA_CPU, createUAParserItem(UA_CPU))
str += (str ? ' ' : EMPTY) + this[toString_props[i]]; .set(UA_DEVICE, createUAParserItem(UA_DEVICE))
} .set(UA_ENGINE, createUAParserItem(UA_ENGINE))
} .set(UA_OS, createUAParserItem(UA_OS))
return str ? str : UNDEF_TYPE; .get();
}; }
} return this;
if (!NAVIGATOR_UADATA) {
UAParserData.prototype.then = function (cb) {
cb(this);
return this;
};
}
return new UAParserData();
})(data);
} }
UAParserItem.prototype.get = function (prop) { UAParserItem.prototype.get = function (prop) {
if (!prop) return this.data; if (!prop) return this.data;
return this.data.hasOwnProperty(prop) ? this.data[prop] : undefined; return this.data.hasOwnProperty(prop) ? this.data[prop] : undefined;
}; };
UAParserItem.prototype.parse = function () { UAParserItem.prototype.parse = function () {
rgxMapper.call(this.data, this.ua, this.rgxMap); if (this.itemType != UA_RESULT) {
rgxMapper.call(this.data, this.ua, this.rgxMap);
}
return this;
};
UAParserItem.prototype.parseCH = function () {
var ua = this.ua,
uaCH = this.uaCH,
rgxMap = this.rgxMap;
switch (this.itemType) {
case UA_BROWSER:
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS];
if (brands) {
for (var i in brands) {
var brandName = brands[i].brand,
brandVersion = brands[i].version;
if (!/not.a.brand/i.test(brandName) || /chromi/i.test(this.get(NAME))) {
this.set(NAME, strip(GOOGLE+' ', brandName))
.set(VERSION, brandVersion)
.set(MAJOR, majorize(brandVersion));
}
}
}
break;
case UA_CPU:
var archName = uaCH[ARCHITECTURE];
if (archName) {
if (archName && uaCH[BITNESS] == '64') archName += '64';
rgxMapper.call(this.data, archName + ';', rgxMap);
}
break;
case UA_DEVICE:
if (uaCH[MOBILE]) {
this.set(TYPE, MOBILE);
}
if (uaCH[MODEL]) {
this.set(MODEL, uaCH[MODEL]);
}
break;
case UA_OS:
var osName = uaCH[PLATFORM];
if(osName) {
var osVersion = uaCH[PLATFORMVER];
if (osName == WINDOWS) osVersion = (parseInt(majorize(osVersion), 10) >= 13 ? '11' : '10');
this.set(NAME, osName)
.set(VERSION, osVersion);
}
break;
case UA_RESULT:
var createUAParserItemWithCH = function (itemType) {
return new UAParserItem(itemType, ua, rgxMap[itemType], uaCH).parseCH().get();
};
this.set('ua', ua)
.set('ua_ch', uaCH)
.set(UA_BROWSER, createUAParserItemWithCH(UA_BROWSER))
.set(UA_CPU, createUAParserItemWithCH(UA_CPU))
.set(UA_DEVICE, createUAParserItemWithCH(UA_DEVICE))
.set(UA_ENGINE, createUAParserItemWithCH(UA_ENGINE))
.set(UA_OS, createUAParserItemWithCH(UA_OS));
}
return this; return this;
}; };
UAParserItem.prototype.set = function (prop, val) { UAParserItem.prototype.set = function (prop, val) {
@ -991,144 +1098,6 @@ const window = undefined;
return this; return this;
}; };
function UAParserBrowser (ua, browserMap, uach) {
UAParserItem.call(this, [
ua,
uach,
UA_BROWSER,
browserMap,
[NAME, VERSION, MAJOR],
[VERSION, MAJOR],
' ?browser$',
[NAME, VERSION]
]);
this.parse();
// Brave-specific detection
if (NAVIGATOR && NAVIGATOR.brave && typeof NAVIGATOR.brave.isBrave == FUNC_TYPE) {
this.set(NAME, 'Brave');
}
this.set(MAJOR, majorize(this.get(VERSION)));
}
UAParserBrowser.prototype = new UAParserItem();
UAParserBrowser.prototype.parseCH = function () {
var brands = this.uaCH[FULLVERLIST] || this.uaCH[BRANDS];
if (brands) {
for (var i in brands) {
var brandName = brands[i].brand,
brandVersion = brands[i].version;
if (!/not.a.brand/i.test(brandName) || /chromi/i.test(this.get(NAME))) {
this.set(NAME, strip(GOOGLE+' ', brandName))
.set(VERSION, brandVersion)
.set(MAJOR, majorize(brandVersion));
}
}
}
return this;
};
function UAParserCPU (ua, cpuMap, uach) {
UAParserItem.call(this, [
ua,
uach,
UA_CPU,
cpuMap,
[ARCHITECTURE],
[],
null,
[ARCHITECTURE]
]);
this.parse();
}
UAParserCPU.prototype = new UAParserItem();
UAParserCPU.prototype.parseCH = function () {
var archName = this.uaCH[ARCHITECTURE];
if (archName) {
archName += (archName && this.uaCH[BITNESS] == '64') ? '64' : EMPTY;
rgxMapper.call(this.data, archName, this.rgxMap);
}
return this;
};
function UAParserDevice (ua, deviceMap, uach) {
UAParserItem.call(this, [
ua,
uach,
UA_DEVICE,
deviceMap,
[TYPE, MODEL, VENDOR],
[],
null,
[VENDOR, MODEL]
]);
this.parse();
if (!this.get(TYPE) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[MOBILE]) {
this.set(TYPE, MOBILE);
}
// iPadOS-specific detection: identified as Mac, but has some iOS-only properties
if (this.get(NAME) == 'Macintosh' && NAVIGATOR && typeof NAVIGATOR.standalone !== UNDEF_TYPE && NAVIGATOR.maxTouchPoints && NAVIGATOR.maxTouchPoints > 2) {
this.set(MODEL, 'iPad')
.set(TYPE, TABLET);
}
}
UAParserDevice.prototype = new UAParserItem();
UAParserDevice.prototype.parseCH = function () {
if (this.uaCH[MOBILE]) {
this.set(TYPE, MOBILE);
}
if (this.uaCH[MODEL]) {
this.set(MODEL, this.uaCH[MODEL]);
}
return this;
};
function UAParserEngine (ua, engineMap) {
UAParserItem.call(this, [
ua,
null,
UA_ENGINE,
engineMap,
[NAME, VERSION],
[VERSION],
null,
[NAME, VERSION]
]);
this.parse();
}
UAParserEngine.prototype = new UAParserItem();
function UAParserOS (ua, osMap, uach) {
UAParserItem.call(this, [
ua,
uach,
UA_OS,
osMap,
[NAME, VERSION],
[VERSION],
' ?os$',
[NAME, VERSION]
]);
this.parse();
if (!this.get(NAME) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[PLATFORM] && NAVIGATOR_UADATA[PLATFORM] != 'Unknown') {
this.set(NAME, NAVIGATOR_UADATA[PLATFORM]);
}
}
UAParserOS.prototype = new UAParserItem();
UAParserOS.prototype.parseCH = function () {
var osName = this.uaCH[PLATFORM];
if(osName) {
var osVersion = this.uaCH[PLATFORMVER];
osVersion = (osName == WINDOWS) ? (parseInt(majorize(osVersion), 10) >= 13 ? '11' : '10') : osVersion;
this.set(NAME, osName)
.set(VERSION, osVersion);
}
return this;
};
function UAParserResult (ua, resMap, uach) {
UAParserItem.call(this, [ua, uach, UA_RESULT, resMap]);
}
UAParserResult.prototype = new UAParserItem();
function UAParser (ua, extensions, headers) { function UAParser (ua, extensions, headers) {
if (typeof ua === OBJ_TYPE) { if (typeof ua === OBJ_TYPE) {
@ -1161,52 +1130,29 @@ const window = undefined;
HTTP_UACH = new UAParserDataCH(headers, true), HTTP_UACH = new UAParserDataCH(headers, true),
regexMap = extensions ? regexMap = extensions ?
extend(regexes, extensions) : extend(defaultRegexes, extensions) :
regexes; defaultRegexes,
createUAParserItemFunc = function (itemType) {
return function () {
return new UAParserItem(itemType, userAgent, itemType == UA_RESULT ? regexMap : regexMap[itemType], HTTP_UACH).get();
};
};
// public methods // public methods
this.getBrowser = function () { assignFromEntries.call(this, [
return new UAParserBrowser(userAgent, regexMap[UA_BROWSER], HTTP_UACH).get(); ['getBrowser', createUAParserItemFunc(UA_BROWSER)],
}; ['getCPU', createUAParserItemFunc(UA_CPU)],
['getDevice', createUAParserItemFunc(UA_DEVICE)],
this.getCPU = function () { ['getEngine', createUAParserItemFunc(UA_ENGINE)],
return new UAParserCPU(userAgent, regexMap[UA_CPU], HTTP_UACH).get(); ['getOS', createUAParserItemFunc(UA_OS)],
}; ['getResult', createUAParserItemFunc(UA_RESULT)],
['getUA', function () { return userAgent; }],
this.getDevice = function () { ['setUA', function (ua) {
return new UAParserDevice(userAgent, regexMap[UA_DEVICE], HTTP_UACH).get(); userAgent = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua;
}; return this;
}]
this.getEngine = function () { ]).setUA(userAgent);
return new UAParserEngine(userAgent, regexMap[UA_ENGINE]).get();
};
this.getOS = function () {
return new UAParserOS(userAgent, regexMap[UA_OS], HTTP_UACH).get();
};
this.getResult = function () {
return new UAParserResult(userAgent, regexMap, HTTP_UACH)
.set('ua', userAgent)
.set('ua_ch', HTTP_UACH)
.set(UA_BROWSER, this.getBrowser())
.set(UA_CPU, this.getCPU())
.set(UA_DEVICE, this.getDevice())
.set(UA_ENGINE, this.getEngine())
.set(UA_OS, this.getOS())
.get();
};
this.getUA = function () {
return userAgent;
};
this.setUA = function (ua) {
userAgent = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua;
return this;
};
this.setUA(userAgent);
return this; return this;
} }

View File

@ -1,4 +1,4 @@
import { UAParser } from '../dist/ua-parser.mjs' import { UAParser } from '../src/ua-parser.mjs'
import * as assert from 'assert' import * as assert from 'assert'
describe('Returns', () => { describe('Returns', () => {