UNPKG

unserver-unify

Version:

443 lines (407 loc) 19.5 kB
(function (angular) { "use strict"; angular.module("ng.deviceDetector", ["reTree"]) .constant("BROWSERS", { CHROME: "chrome", FIREFOX: "firefox", SAFARI: "safari", OPERA: "opera", IE: "ie", MS_EDGE: "ms-edge", FB_MESSANGER: "fb-messanger", UNKNOWN: "unknown" }) .constant("DEVICES", { ANDROID: "android", I_PAD: "ipad", IPHONE: "iphone", I_POD: "ipod", BLACKBERRY: "blackberry", FIREFOX_OS: "firefox-os", CHROME_BOOK: "chrome-book", WINDOWS_PHONE: "windows-phone", PS4: "ps4", VITA: "vita", CHROMECAST: "chromecast", APPLE_TV:"apple-tv", GOOGLE_TV:"google-tv", UNKNOWN: "unknown" }) .constant("OS", { WINDOWS: "windows", MAC: "mac", IOS: "ios", ANDROID: "android", LINUX: "linux", UNIX: "unix", FIREFOX_OS: "firefox-os", CHROME_OS: "chrome-os", WINDOWS_PHONE: "windows-phone", UNKNOWN: "unknown" }) .constant("OS_VERSIONS", { WINDOWS_3_11: "windows-3-11", WINDOWS_95: "windows-95", WINDOWS_ME: "windows-me", WINDOWS_98: "windows-98", WINDOWS_CE: "windows-ce", WINDOWS_2000: "windows-2000", WINDOWS_XP: "windows-xp", WINDOWS_SERVER_2003: "windows-server-2003", WINDOWS_VISTA: "windows-vista", WINDOWS_7: "windows-7", WINDOWS_8_1: "windows-8-1", WINDOWS_8: "windows-8", WINDOWS_10: "windows-10", WINDOWS_PHONE_7_5: "windows-phone-7-5", WINDOWS_PHONE_8_1: "windows-phone-8-1", WINDOWS_PHONE_10: "windows-phone-10", WINDOWS_NT_4_0: "windows-nt-4-0", MACOSX_15: "mac-os-x-15", MACOSX_14: "mac-os-x-14", MACOSX_13: "mac-os-x-13", MACOSX_12: "mac-os-x-12", MACOSX_11: "mac-os-x-11", MACOSX_10: "mac-os-x-10", MACOSX_9: "mac-os-x-9", MACOSX_8: "mac-os-x-8", MACOSX_7: "mac-os-x-7", MACOSX_6: "mac-os-x-6", MACOSX_5: "mac-os-x-5", MACOSX_4: "mac-os-x-4", MACOSX_3: "mac-os-x-3", MACOSX_2: "mac-os-x-2", MACOSX: "mac-os-x", UNKNOWN: "unknown" }) .service("detectUtils", ["deviceDetector", "DEVICES", "BROWSERS", "OS", function (deviceDetector, DEVICES, BROWSERS, OS) { var deviceInfo = deviceDetector; this.isMobile = function () { return deviceInfo.device !== 'unknown'; }; this.isAndroid = function () { return (deviceInfo.device === DEVICES.ANDROID || deviceInfo.OS === OS.ANDROID); }; this.isIOS = function () { return (deviceInfo.os === OS.IOS || deviceInfo.device === DEVICES.I_POD || deviceInfo.device === DEVICES.IPHONE); }; } ]) .factory("deviceDetector", ["$window", "DEVICES", "BROWSERS", "OS", "OS_VERSIONS", "reTree", function ($window, DEVICES, BROWSERS, OS, OS_VERSIONS, reTree) { /* ES5 polyfills Start*/ // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys if (!Object.keys) { Object.keys = (function () { 'use strict'; var hasOwnProperty = Object.prototype.hasOwnProperty, hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), dontEnums = [ 'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor' ], dontEnumsLength = dontEnums.length; return function (obj) { if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { throw new TypeError('Object.keys called on non-object'); } var result = [], prop, i; for (prop in obj) { if (hasOwnProperty.call(obj, prop)) { result.push(prop); } } if (hasDontEnumBug) { for (i = 0; i < dontEnumsLength; i++) { if (hasOwnProperty.call(obj, dontEnums[i])) { result.push(dontEnums[i]); } } } return result; }; }()); } // Production steps of ECMA-262, Edition 5, 15.4.4.21 // Reference: http://es5.github.io/#x15.4.4.21 if (!Array.prototype.reduce) { Array.prototype.reduce = function (callback /*, initialValue*/) { 'use strict'; if (this == null) { throw new TypeError('Array.prototype.reduce called on null or undefined'); } if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } var t = Object(this), len = t.length >>> 0, k = 0, value; if (arguments.length == 2) { value = arguments[1]; } else { while (k < len && !(k in t)) { k++; } if (k >= len) { throw new TypeError('Reduce of empty array with no initial value'); } value = t[k++]; } for (; k < len; k++) { if (k in t) { value = callback(value, t[k], k, t); } } return value; }; } /* ES5 polyfills End*/ var OS_RE = { WINDOWS: {and: [{or: [/\bWindows|(Win\d\d)\b/, /\bWin 9x\b/]}, {not: /\bWindows Phone\b/}]}, MAC: {and: [/\bMac OS\b/, {not: /Windows Phone/}]}, IOS: {and: [{or: [/\biPad\b/, /\biPhone\b/, /\biPod\b/]}, {not: /Windows Phone/}]}, ANDROID: {and: [/\bAndroid\b/, {not: /Windows Phone/}]}, LINUX: /\bLinux\b/, UNIX: /\bUNIX\b/, FIREFOX_OS: {and: [/\bFirefox\b/, /Mobile\b/]}, CHROME_OS: /\bCrOS\b/, WINDOWS_PHONE: {or: [/\bIEMobile\b/, /\bWindows Phone\b/]}, PS4: /\bMozilla\/5.0 \(PlayStation 4\b/, VITA: /\bMozilla\/5.0 \(Play(S|s)tation Vita\b/ }; var BROWSERS_RE = { CHROME: {and: [{or: [/\bChrome\b/, /\bCriOS\b/]}, {not: {or: [/\bOPR\b/, /\bEdge\b/]}}]}, FIREFOX: /\bFirefox\b/, SAFARI: {and: [/^((?!CriOS).)*\Safari\b.*$/, {not: {or: [/\bOPR\b/, /\bEdge\b/, /Windows Phone/]}}]}, OPERA: {or: [/Opera\b/, /\bOPR\b/]}, IE: {or: [/\bMSIE\b/, /\bTrident\b/,/^Mozilla\/5\.0 \(Windows NT 10\.0; Win64; x64\)$/]}, MS_EDGE: {or: [/\bEdge\b/]}, PS4: /\bMozilla\/5.0 \(PlayStation 4\b/, VITA: /\bMozilla\/5.0 \(Play(S|s)tation Vita\b/, FB_MESSANGER: /\bFBAN\/MessengerForiOS\b/ }; var DEVICES_RE = { ANDROID: {and: [/\bAndroid\b/, {not: /Windows Phone/}]}, I_PAD: /\biPad\b/, IPHONE: {and: [/\biPhone\b/, {not: /Windows Phone/}]}, I_POD: /\biPod\b/, BLACKBERRY: /\bblackberry\b/, FIREFOX_OS: {and: [/\bFirefox\b/, /\bMobile\b/]}, CHROME_BOOK: /\bCrOS\b/, WINDOWS_PHONE: {or: [/\bIEMobile\b/, /\bWindows Phone\b/]}, PS4: /\bMozilla\/5.0 \(PlayStation 4\b/, CHROMECAST: /\bCrKey\b/, APPLE_TV:/^iTunes-AppleTV\/4.1$/, GOOGLE_TV:/\bGoogleTV\b/, VITA: /\bMozilla\/5.0 \(Play(S|s)tation Vita\b/ }; var OS_VERSIONS_RE = { WINDOWS_3_11: /Win16/, WINDOWS_95: /(Windows 95|Win95|Windows_95)/, WINDOWS_ME: /(Win 9x 4.90|Windows ME)/, WINDOWS_98: /(Windows 98|Win98)/, WINDOWS_CE: /Windows CE/, WINDOWS_2000: /(Windows NT 5.0|Windows 2000)/, WINDOWS_XP: /(Windows NT 5.1|Windows XP)/, WINDOWS_SERVER_2003: /Windows NT 5.2/, WINDOWS_VISTA: /Windows NT 6.0/, WINDOWS_7: /(Windows 7|Windows NT 6.1)/, WINDOWS_8_1: /(Windows 8.1|Windows NT 6.3)/, WINDOWS_8: /(Windows 8|Windows NT 6.2)/, WINDOWS_10: /(Windows NT 10.0)/, WINDOWS_PHONE_7_5: /(Windows Phone OS 7.5)/, WINDOWS_PHONE_8_1: /(Windows Phone 8.1)/, WINDOWS_PHONE_10: /(Windows Phone 10)/, WINDOWS_NT_4_0: {and: [/(Windows NT 4.0|WinNT4.0|WinNT|Windows NT)/, {not: /Windows NT 10.0/}]}, MACOSX: /(MAC OS X\s*[^ 0-9])/, MACOSX_3: /(Darwin 10.3|Mac OS X 10.3)/, MACOSX_4: /(Darwin 10.4|Mac OS X 10.4)/, MACOSX_5: /(Mac OS X 10.5)/, MACOSX_6: /(Mac OS X 10.6)/, MACOSX_7: /(Mac OS X 10.7)/, MACOSX_8: /(Mac OS X 10.8)/, MACOSX_9: /(Mac OS X 10.9)/, MACOSX_10: /(Mac OS X 10.10)/, MACOSX_11: /(Mac OS X 10.11)/, MACOSX_12: /(Mac OS X 10.12)/, MACOSX_13: /(Mac OS X 10.13)/, MACOSX_14: /(Mac OS X 10.14)/, MACOSX_15: /(Mac OS X 10.15)/ }; var BROWSER_VERSIONS_RE_MAP = { CHROME: [/\bChrome\/([\d\.]+)\b/, /\bCriOS\/([\d\.]+)\b/], FIREFOX: /\bFirefox\/([\d\.]+)\b/, SAFARI: /\bVersion\/([\d\.]+)\b/, OPERA: [/\bVersion\/([\d\.]+)\b/, /\bOPR\/([\d\.]+)\b/], IE: [/\bMSIE ([\d\.]+\w?)\b/, /\brv:([\d\.]+\w?)\b/], MS_EDGE: /\bEdge\/([\d\.]+)\b/ }; var BROWSER_VERSIONS_RE = Object.keys(BROWSER_VERSIONS_RE_MAP).reduce(function (obj, key) { obj[BROWSERS[key]] = BROWSER_VERSIONS_RE_MAP[key]; return obj; }, {}); var ua = $window.navigator.userAgent; var deviceInfo = { raw: { userAgent: ua, os: {}, browser: {}, device: {} } }; deviceInfo.raw.os = Object.keys(OS).reduce(function (obj, item) { obj[OS[item]] = reTree.test(ua, OS_RE[item]); return obj; }, {}); deviceInfo.raw.browser = Object.keys(BROWSERS).reduce(function (obj, item) { obj[BROWSERS[item]] = reTree.test(ua, BROWSERS_RE[item]); return obj; }, {}); deviceInfo.raw.device = Object.keys(DEVICES).reduce(function (obj, item) { obj[DEVICES[item]] = reTree.test(ua, DEVICES_RE[item]); return obj; }, {}); deviceInfo.raw.os_version = Object.keys(OS_VERSIONS).reduce(function (obj, item) { obj[OS_VERSIONS[item]] = reTree.test(ua, OS_VERSIONS_RE[item]); return obj; }, {}); deviceInfo.os = [ OS.WINDOWS, OS.IOS, OS.MAC, OS.ANDROID, OS.LINUX, OS.UNIX, OS.FIREFOX_OS, OS.CHROME_OS, OS.WINDOWS_PHONE ].reduce(function (previousValue, currentValue) { return (previousValue === OS.UNKNOWN && deviceInfo.raw.os[currentValue]) ? currentValue : previousValue; }, OS.UNKNOWN); deviceInfo.browser = [ BROWSERS.CHROME, BROWSERS.FIREFOX, BROWSERS.SAFARI, BROWSERS.OPERA, BROWSERS.IE, BROWSERS.MS_EDGE, BROWSERS.FB_MESSANGER ].reduce(function (previousValue, currentValue) { return (previousValue === BROWSERS.UNKNOWN && deviceInfo.raw.browser[currentValue]) ? currentValue : previousValue; }, BROWSERS.UNKNOWN); deviceInfo.device = [ DEVICES.ANDROID, DEVICES.I_PAD, DEVICES.IPHONE, DEVICES.I_POD, DEVICES.BLACKBERRY, DEVICES.FIREFOX_OS, DEVICES.CHROME_BOOK, DEVICES.WINDOWS_PHONE, DEVICES.PS4, DEVICES.CHROMECAST, DEVICES.APPLE_TV, DEVICES.GOOGLE_TV, DEVICES.VITA ].reduce(function (previousValue, currentValue) { return (previousValue === DEVICES.UNKNOWN && deviceInfo.raw.device[currentValue]) ? currentValue : previousValue; }, DEVICES.UNKNOWN); deviceInfo.os_version = [ OS_VERSIONS.WINDOWS_3_11, OS_VERSIONS.WINDOWS_95, OS_VERSIONS.WINDOWS_ME, OS_VERSIONS.WINDOWS_98, OS_VERSIONS.WINDOWS_CE, OS_VERSIONS.WINDOWS_2000, OS_VERSIONS.WINDOWS_XP, OS_VERSIONS.WINDOWS_SERVER_2003, OS_VERSIONS.WINDOWS_VISTA, OS_VERSIONS.WINDOWS_7, OS_VERSIONS.WINDOWS_8_1, OS_VERSIONS.WINDOWS_8, OS_VERSIONS.WINDOWS_10, OS_VERSIONS.WINDOWS_PHONE_7_5, OS_VERSIONS.WINDOWS_PHONE_8_1, OS_VERSIONS.WINDOWS_PHONE_10, OS_VERSIONS.WINDOWS_NT_4_0, OS_VERSIONS.MACOSX, OS_VERSIONS.MACOSX_3, OS_VERSIONS.MACOSX_4, OS_VERSIONS.MACOSX_5, OS_VERSIONS.MACOSX_6, OS_VERSIONS.MACOSX_7, OS_VERSIONS.MACOSX_8, OS_VERSIONS.MACOSX_9, OS_VERSIONS.MACOSX_10, OS_VERSIONS.MACOSX_11, OS_VERSIONS.MACOSX_12, OS_VERSIONS.MACOSX_13, OS_VERSIONS.MACOSX_14, OS_VERSIONS.MACOSX_15 ].reduce(function (previousValue, currentValue) { return (previousValue === OS_VERSIONS.UNKNOWN && deviceInfo.raw.os_version[currentValue]) ? currentValue : previousValue; }, OS_VERSIONS.UNKNOWN); deviceInfo.browser_version = "0"; if (deviceInfo.browser !== BROWSERS.UNKNOWN) { var re = BROWSER_VERSIONS_RE[deviceInfo.browser]; var res = reTree.exec(ua, re); if (!!res) { deviceInfo.browser_version = res[1]; } } // replace isMobile function with below function deviceInfo.isMobile = function () { var ua = deviceInfo.raw.userAgent; return ua.match(/Mobile/i); }; /* deviceInfo.isMobile = function () { return [ DEVICES.ANDROID, DEVICES.I_PAD, DEVICES.IPHONE, DEVICES.I_POD, DEVICES.BLACKBERRY, DEVICES.FIREFOX_OS, DEVICES.WINDOWS_PHONE, DEVICES.VITA ].some(function (item) { return deviceInfo.device == item; }); }; */ deviceInfo.isTablet = function () { return [ DEVICES.I_PAD, DEVICES.FIREFOX_OS ].some(function (item) { return deviceInfo.device == item; }); }; deviceInfo.isDesktop = function () { return [ DEVICES.PS4, DEVICES.CHROME_BOOK, DEVICES.UNKNOWN ].some(function (item) { return deviceInfo.device == item; }); }; return deviceInfo; } ]) .directive('deviceDetector', ["deviceDetector", function (deviceDetector) { return { restrict: "A", link: function (scope, elm/*, attrs*/) { elm.addClass('os-' + deviceDetector.os); elm.addClass('browser-' + deviceDetector.browser); elm.addClass('device-' + deviceDetector.device); } }; }]); })(angular);