diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index e0fdd51..370116e 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -24,21 +24,21 @@ USER_AGENT = 'user-agent', EMPTY = '', UNKNOWN = '?', - - // typeof - FUNC_TYPE = 'function', - UNDEF_TYPE = 'undefined', - OBJ_TYPE = 'object', - STR_TYPE = 'string', + TYPEOF = { + FUNCTION : 'function', + OBJECT : 'object', + STRING : 'string', + UNDEFINED : 'undefined' + }, // properties - UA_BROWSER = 'browser', - UA_CPU = 'cpu', - UA_DEVICE = 'device', - UA_ENGINE = 'engine', - UA_OS = 'os', - UA_RESULT = 'result', - + BROWSER = 'browser', + CPU = 'cpu', + DEVICE = 'device', + ENGINE = 'engine', + OS = 'os', + RESULT = 'result', + NAME = 'name', TYPE = 'type', VENDOR = 'vendor', @@ -66,16 +66,16 @@ PLATFORM = 'platform', PLATFORMVER = 'platformVersion', BITNESS = 'bitness', - CH_HEADER = 'sec-ch-ua', - CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list', - CH_HEADER_ARCH = CH_HEADER + '-arch', - CH_HEADER_BITNESS = CH_HEADER + '-' + BITNESS, - CH_HEADER_FORM_FACTORS = CH_HEADER + '-form-factors', - CH_HEADER_MOBILE = CH_HEADER + '-' + MOBILE, - CH_HEADER_MODEL = CH_HEADER + '-' + MODEL, - CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM, - CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version', - CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS], + CH = 'sec-ch-ua', + CH_FULL_VER_LIST= CH + '-full-version-list', + CH_ARCH = CH + '-arch', + CH_BITNESS = CH + '-' + BITNESS, + CH_FORM_FACTORS = CH + '-form-factors', + CH_MOBILE = CH + '-' + MOBILE, + CH_MODEL = CH + '-' + MODEL, + CH_PLATFORM = CH + '-' + PLATFORM, + CH_PLATFORM_VER = CH_PLATFORM + '-version', + CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS], // device vendors AMAZON = 'Amazon', @@ -114,7 +114,7 @@ // os WINDOWS = 'Windows'; - var isWindow = typeof window !== UNDEF_TYPE, + var isWindow = typeof window !== TYPEOF.UNDEFINED, NAVIGATOR = (isWindow && window.navigator) ? window.navigator : undefined, @@ -150,7 +150,7 @@ return enums; }, has = function (str1, str2) { - if (typeof str1 === OBJ_TYPE && str1.length > 0) { + if (typeof str1 === TYPEOF.OBJECT && str1.length > 0) { for (var i in str1) { if (lowerize(str2) == lowerize(str1[i])) return true; } @@ -164,7 +164,7 @@ } }, isString = function (val) { - return typeof val === STR_TYPE; + return typeof val === TYPEOF.STRING; }, itemListToArray = function (header) { if (!header) return undefined; @@ -191,7 +191,7 @@ if (!arr.hasOwnProperty(i)) continue; var propName = arr[i]; - if (typeof propName == OBJ_TYPE && propName.length == 2) { + if (typeof propName == TYPEOF.OBJECT && propName.length == 2) { this[propName[0]] = propName[1]; } else { this[propName] = undefined; @@ -208,7 +208,7 @@ trim = function (str, len) { if (isString(str)) { str = strip(/^\s\s*/, str); - return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); + return typeof len === TYPEOF.UNDEFINED ? str : str.substring(0, UA_MAX_LENGTH); } }; @@ -240,9 +240,9 @@ match = matches[++k]; q = props[p]; // check if given property is actually array - if (typeof q === OBJ_TYPE && q.length > 0) { + if (typeof q === TYPEOF.OBJECT && q.length > 0) { if (q.length === 2) { - if (typeof q[1] == FUNC_TYPE) { + if (typeof q[1] == TYPEOF.FUNCTION) { // assign modified match this[q[0]] = q[1].call(this, match); } else { @@ -251,7 +251,7 @@ } } else if (q.length >= 3) { // Check whether q[1] FUNCTION or REGEX - if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) { + if (typeof q[1] === TYPEOF.FUNCTION && !(q[1].exec && q[1].test)) { if (q.length > 3) { this[q[0]] = match ? q[1].apply(this, q.slice(2)) : undefined; } else { @@ -283,7 +283,7 @@ for (var i in map) { // check if current value is array - if (typeof map[i] === OBJ_TYPE && map[i].length > 0) { + if (typeof map[i] === TYPEOF.OBJECT && map[i].length > 0) { for (var j = 0; j < map[i].length; j++) { if (has(map[i][j], str)) { return (i === UNKNOWN) ? undefined : i; @@ -1050,27 +1050,27 @@ var defaultProps = (function () { var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}}; setProps.call(props.init, [ - [UA_BROWSER, [NAME, VERSION, MAJOR, TYPE]], - [UA_CPU, [ARCHITECTURE]], - [UA_DEVICE, [TYPE, MODEL, VENDOR]], - [UA_ENGINE, [NAME, VERSION]], - [UA_OS, [NAME, VERSION]] + [BROWSER, [NAME, VERSION, MAJOR, TYPE]], + [CPU, [ARCHITECTURE]], + [DEVICE, [TYPE, MODEL, VENDOR]], + [ENGINE, [NAME, VERSION]], + [OS, [NAME, VERSION]] ]); setProps.call(props.isIgnore, [ - [UA_BROWSER, [VERSION, MAJOR]], - [UA_ENGINE, [VERSION]], - [UA_OS, [VERSION]] + [BROWSER, [VERSION, MAJOR]], + [ENGINE, [VERSION]], + [OS, [VERSION]] ]); setProps.call(props.isIgnoreRgx, [ - [UA_BROWSER, / ?browser$/i], - [UA_OS, / ?os$/i] + [BROWSER, / ?browser$/i], + [OS, / ?os$/i] ]); setProps.call(props.toString, [ - [UA_BROWSER, [NAME, VERSION]], - [UA_CPU, [ARCHITECTURE]], - [UA_DEVICE, [VENDOR, MODEL]], - [UA_ENGINE, [NAME, VERSION]], - [UA_OS, [NAME, VERSION]] + [BROWSER, [NAME, VERSION]], + [CPU, [ARCHITECTURE]], + [DEVICE, [VENDOR, MODEL]], + [ENGINE, [NAME, VERSION]], + [OS, [NAME, VERSION]] ]); return props; })(); @@ -1114,14 +1114,14 @@ return item.detectFeature().get(); }; - if (itemType != UA_RESULT) { + if (itemType != RESULT) { IData.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) { + if (strToCheck != TYPEOF.UNDEFINED) break; + } else if (strToCheck == TYPEOF.UNDEFINED && is) { is = !is; break; } @@ -1131,11 +1131,11 @@ IData.prototype.toString = function () { var str = EMPTY; for (var i in toString_props) { - if (typeof(this[toString_props[i]]) !== UNDEF_TYPE) { + if (typeof(this[toString_props[i]]) !== TYPEOF.UNDEFINED) { str += (str ? ' ' : EMPTY) + this[toString_props[i]]; } } - return str || UNDEF_TYPE; + return str || TYPEOF.UNDEFINED; }; } @@ -1171,19 +1171,19 @@ setProps.call(this, CH_ALL_VALUES); if (isHttpUACH) { setProps.call(this, [ - [BRANDS, itemListToArray(uach[CH_HEADER])], - [FULLVERLIST, itemListToArray(uach[CH_HEADER_FULL_VER_LIST])], - [MOBILE, /\?1/.test(uach[CH_HEADER_MOBILE])], - [MODEL, stripQuotes(uach[CH_HEADER_MODEL])], - [PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])], - [PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])], - [ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])], - [FORMFACTORS, itemListToArray(uach[CH_HEADER_FORM_FACTORS])], - [BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])] + [BRANDS, itemListToArray(uach[CH])], + [FULLVERLIST, itemListToArray(uach[CH_FULL_VER_LIST])], + [MOBILE, /\?1/.test(uach[CH_MOBILE])], + [MODEL, stripQuotes(uach[CH_MODEL])], + [PLATFORM, stripQuotes(uach[CH_PLATFORM])], + [PLATFORMVER, stripQuotes(uach[CH_PLATFORM_VER])], + [ARCHITECTURE, stripQuotes(uach[CH_ARCH])], + [FORMFACTORS, itemListToArray(uach[CH_FORM_FACTORS])], + [BITNESS, stripQuotes(uach[CH_BITNESS])] ]); } else { for (var prop in uach) { - if(this.hasOwnProperty(prop) && typeof uach[prop] !== UNDEF_TYPE) this[prop] = uach[prop]; + if(this.hasOwnProperty(prop) && typeof uach[prop] !== TYPEOF.UNDEFINED) this[prop] = uach[prop]; } } } @@ -1208,30 +1208,30 @@ this.detectFeature = function () { if (NAVIGATOR && NAVIGATOR.userAgent == this.ua) { switch (this.itemType) { - case UA_BROWSER: + case BROWSER: // Brave-specific detection - if (NAVIGATOR.brave && typeof NAVIGATOR.brave.isBrave == FUNC_TYPE) { + if (NAVIGATOR.brave && typeof NAVIGATOR.brave.isBrave == TYPEOF.FUNCTION) { this.set(NAME, 'Brave'); } break; - case UA_DEVICE: + case DEVICE: // Chrome-specific detection: check for 'mobile' value of navigator.userAgentData 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(MODEL) == 'Macintosh' && NAVIGATOR && typeof NAVIGATOR.standalone !== UNDEF_TYPE && NAVIGATOR.maxTouchPoints && NAVIGATOR.maxTouchPoints > 2) { + if (this.get(MODEL) == 'Macintosh' && NAVIGATOR && typeof NAVIGATOR.standalone !== TYPEOF.UNDEFINED && NAVIGATOR.maxTouchPoints && NAVIGATOR.maxTouchPoints > 2) { this.set(MODEL, 'iPad') .set(TYPE, TABLET); } break; - case UA_OS: + case OS: // Chrome-specific detection: check for 'platform' value of navigator.userAgentData if (!this.get(NAME) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[PLATFORM]) { this.set(NAME, NAVIGATOR_UADATA[PLATFORM]); } break; - case UA_RESULT: + case RESULT: var data = this.data; var detect = function (itemType) { return data[itemType] @@ -1239,25 +1239,25 @@ .detectFeature() .get(); }; - this.set(UA_BROWSER, detect(UA_BROWSER)) - .set(UA_CPU, detect(UA_CPU)) - .set(UA_DEVICE, detect(UA_DEVICE)) - .set(UA_ENGINE, detect(UA_ENGINE)) - .set(UA_OS, detect(UA_OS)); + this.set(BROWSER, detect(BROWSER)) + .set(CPU, detect(CPU)) + .set(DEVICE, detect(DEVICE)) + .set(ENGINE, detect(ENGINE)) + .set(OS, detect(OS)); } } return this; }; this.parseUA = function () { - if (this.itemType != UA_RESULT) { + if (this.itemType != RESULT) { rgxMapper.call(this.data, this.ua, this.rgxMap); } switch (this.itemType) { - case UA_BROWSER: + case BROWSER: this.set(MAJOR, majorize(this.get(VERSION))); break; - case UA_OS: + case OS: if (this.get(NAME) == 'iOS' && this.get(VERSION) == '18.6') { // Based on the assumption that iOS version is tightly coupled with Safari version var realVersion = /\) Version\/([\d\.]+)/.exec(this.ua); // Get Safari version @@ -1275,14 +1275,14 @@ rgxMap = this.rgxMap; switch (this.itemType) { - case UA_BROWSER: - case UA_ENGINE: + case BROWSER: + case ENGINE: var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName; if (brands) { for (var i=0; i