From ed58c8f62b7145dbed996cfc7096fb31a1f4163f Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Fri, 21 Feb 2020 10:42:58 -0500 Subject: [PATCH] ES6ify detect.js --- modules/util/detect.js | 257 +++++++++++++++++++++-------------------- 1 file changed, 130 insertions(+), 127 deletions(-) diff --git a/modules/util/detect.js b/modules/util/detect.js index da90d607d..8a08dcb8e 100644 --- a/modules/util/detect.js +++ b/modules/util/detect.js @@ -2,146 +2,149 @@ import { currentLocale, setTextDirection, setLanguageNames, setScriptNames } fro import { dataLocales } from '../../data/index'; import { utilStringQs } from './util'; -var detected; +let _detected; export function utilDetect(force) { - if (detected && !force) return detected; - detected = {}; + if (_detected && !force) return _detected; + _detected = {}; - var ua = navigator.userAgent, - m = null, - q = utilStringQs(window.location.hash.substring(1)); + const ua = navigator.userAgent; + const hash = utilStringQs(window.location.hash); + let m = null; - m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i); // Edge + /* Browser */ + m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i); // Edge + if (m !== null) { + _detected.browser = m[1]; + _detected.version = m[2]; + } + if (!_detected.browser) { + m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i); // IE11 if (m !== null) { - detected.browser = m[1]; - detected.version = m[2]; + _detected.browser = 'msie'; + _detected.version = m[1]; } - if (!detected.browser) { - m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i); // IE11 - if (m !== null) { - detected.browser = 'msie'; - detected.version = m[1]; - } + } + if (!_detected.browser) { + m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i); // Opera 15+ + if (m !== null) { + _detected.browser = 'Opera'; + _detected.version = m[2]; } - if (!detected.browser) { - m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i); // Opera 15+ - if (m !== null) { - detected.browser = 'Opera'; - detected.version = m[2]; - } + } + if (!_detected.browser) { + m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i); + if (m !== null) { + _detected.browser = m[1]; + _detected.version = m[2]; + m = ua.match(/version\/([\.\d]+)/i); + if (m !== null) _detected.version = m[1]; } - if (!detected.browser) { - m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i); - if (m !== null) { - detected.browser = m[1]; - detected.version = m[2]; - m = ua.match(/version\/([\.\d]+)/i); - if (m !== null) detected.version = m[1]; - } - } - if (!detected.browser) { - detected.browser = navigator.appName; - detected.version = navigator.appVersion; + } + if (!_detected.browser) { + _detected.browser = navigator.appName; + _detected.version = navigator.appVersion; + } + + // keep major.minor version only.. + _detected.version = _detected.version.split(/\W/).slice(0,2).join('.'); + + // detect other browser capabilities + // Legacy Opera has incomplete svg style support. See #715 + _detected.opera = (_detected.browser.toLowerCase() === 'opera' && parseFloat(_detected.version) < 15 ); + + if (_detected.browser.toLowerCase() === 'msie') { + _detected.ie = true; + _detected.browser = 'Internet Explorer'; + _detected.support = parseFloat(_detected.version) >= 11; + } else { + _detected.ie = false; + _detected.support = true; + } + + _detected.filedrop = (window.FileReader && 'ondrop' in window); + _detected.download = !(_detected.ie || _detected.browser.toLowerCase() === 'edge'); + _detected.cssfilters = !(_detected.ie || _detected.browser.toLowerCase() === 'edge'); + + + /* Platform */ + if (/Win/.test(ua)) { + _detected.os = 'win'; + _detected.platform = 'Windows'; + } else if (/Mac/.test(ua)) { + _detected.os = 'mac'; + _detected.platform = 'Macintosh'; + } else if (/X11/.test(ua) || /Linux/.test(ua)) { + _detected.os = 'linux'; + _detected.platform = 'Linux'; + } else { + _detected.os = 'win'; + _detected.platform = 'Unknown'; + } + + + /* Locale, Language */ + // The locale and language specified in the url hash + if (hash.locale) { + _detected.hashLocale = hash.locale; + _detected.hashLanguage = hash.locale.split('-')[0]; + } + + // The locale and language specified by the user's browser + _detected.browserLocale = (navigator.language || navigator.userLanguage || 'en-US'); + _detected.browserLanguage = _detected.browserLocale.split('-')[0]; + + // Search `navigator.languages` for a better locale. Prefer the first language, + // unless the second language is a culture-specific version of the first one, see #3842 + if (navigator.languages && navigator.languages.length > 0) { + const code0 = navigator.languages[0]; + const parts0 = code0.split('-'); + + _detected.browserLocale = code0; + _detected.browserLanguage = parts0[0]; + + if (navigator.languages.length > 1 && parts0.length === 1) { + const code1 = navigator.languages[1]; + const parts1 = code1.split('-'); + + if (parts1[0] === parts0[0]) { + _detected.browserLocale = code1; + } } + } - // keep major.minor version only.. - detected.version = detected.version.split(/\W/).slice(0,2).join('.'); + // The locale and language actually being used by iD. + // This can be changed at any time and is stored in the `currentLocale` export. + // So report those instead (except in the situation where 'en' might override 'en-US') + const current = currentLocale || 'en'; + if (current === 'en') { + _detected.locale = _detected.hashLocale || _detected.browserLocale; + _detected.language = _detected.hashLanguage || _detected.browserLanguage; + } else { + _detected.locale = current; + _detected.language = current.split('-')[0]; + } - if (detected.browser.toLowerCase() === 'msie') { - detected.ie = true; - detected.browser = 'Internet Explorer'; - detected.support = parseFloat(detected.version) >= 11; - } else { - detected.ie = false; - detected.support = true; - } + // detect text direction + const lang = dataLocales[_detected.locale] || dataLocales[_detected.language]; + if ((lang && lang.rtl) || (hash.rtl === 'true')) { + _detected.textDirection = 'rtl'; + } else { + _detected.textDirection = 'ltr'; + } + setTextDirection(_detected.textDirection); + setLanguageNames((lang && lang.languageNames) || {}); + setScriptNames((lang && lang.scriptNames) || {}); - // Added due to incomplete svg style support. See #715 - detected.opera = (detected.browser.toLowerCase() === 'opera' && parseFloat(detected.version) < 15 ); + /* Host */ + const loc = window.top.location; + let origin = loc.origin; + if (!origin) { // for unpatched IE11 + origin = loc.protocol + '//' + loc.hostname + (loc.port ? ':' + loc.port: ''); + } - // Set locale based on url param (format 'en-US') or browser lang (default) - if (q.hasOwnProperty('locale')) { - detected.locale = q.locale; - detected.language = q.locale.split('-')[0]; - } else { - detected.locale = (navigator.language || navigator.userLanguage || 'en-US'); - detected.language = detected.locale.split('-')[0]; + _detected.host = origin + loc.pathname; - // Search `navigator.languages` for a better locale. Prefer the first language, - // unless the second language is a culture-specific version of the first one, see #3842 - if (navigator.languages && navigator.languages.length > 0) { - var code0 = navigator.languages[0], - parts0 = code0.split('-'); - detected.locale = code0; - detected.language = parts0[0]; - - if (navigator.languages.length > 1 && parts0.length === 1) { - var code1 = navigator.languages[1], - parts1 = code1.split('-'); - - if (parts1[0] === parts0[0]) { - detected.locale = code1; - } - } - } - } - - // Loaded locale is stored in currentLocale - // return that instead (except in the situation where 'en' might override 'en-US') - var loadedLocale = currentLocale || 'en'; - if (loadedLocale !== 'en') { - detected.locale = loadedLocale; - detected.language = detected.locale.split('-')[0]; - } - - // detect text direction - var lang = dataLocales[detected.locale] || dataLocales[detected.language]; - if ((lang && lang.rtl) || (q.rtl === 'true')) { - detected.textDirection = 'rtl'; - } else { - detected.textDirection = 'ltr'; - } - setTextDirection(detected.textDirection); - setLanguageNames((lang && lang.languageNames) || {}); - setScriptNames((lang && lang.scriptNames) || {}); - - // detect host - var loc = window.top.location; - var origin = loc.origin; - if (!origin) { // for unpatched IE11 - origin = loc.protocol + '//' + loc.hostname + (loc.port ? ':' + loc.port: ''); - } - - detected.host = origin + loc.pathname; - - detected.filedrop = (window.FileReader && 'ondrop' in window); - - detected.download = !(detected.ie || detected.browser.toLowerCase() === 'edge'); - - detected.cssfilters = !(detected.ie || detected.browser.toLowerCase() === 'edge'); - - function nav(x) { - return navigator.userAgent.indexOf(x) !== -1; - } - - if (nav('Win')) { - detected.os = 'win'; - detected.platform = 'Windows'; - } - else if (nav('Mac')) { - detected.os = 'mac'; - detected.platform = 'Macintosh'; - } - else if (nav('X11') || nav('Linux')) { - detected.os = 'linux'; - detected.platform = 'Linux'; - } - else { - detected.os = 'win'; - detected.platform = 'Unknown'; - } - - return detected; + return _detected; }