cahilfoley
10/27/2018 - 4:01 AM

Browser Platform Detection

Snippets to detect browser, operating system and device information from JavaScript

/**
 * Gets whether running on a certain browser according to browser data.
 * Functions to test for a certain browser (each returns bool):
 * * isOpera
 * * isFirefox
 * * isSafari
 * * isIE
 * * isEdge
 * * isChrome
 * * isBlink
 *
 * Function to get the browser by name:
 * * get (possible return values: Opera, Firefox, Safari, IE, Edge, Chrome, Blink, Unknown)
 * @example
 * ```js
 * detectBrowser.isOpera() => true/false
 * detectBrowser.isFirefox() => true/false
 * detectBrowser.isSafari() => true/false
 * detectBrowser.isIE() => true/false
 * detectBrowser.isEdge() => true/false
 * detectBrowser.isChrome() => true/false
 * detectBrowser.isBlink() => true/false
 * detectBrowser.get() => Opera/Firefox/Safari/IE/Edge/Chrome/Blink/Unknown
 * ```
 */

const detectBrowser = {
  get userAgent() {
    return navigator.userAgent
  },
  isOpera: () =>
    (!!window.opr && !!window.opr.addons) ||
    !!window.opera ||
    detectBrowser.userAgent().indexOf(' OPR/') >= 0,
  isFirefox: () => typeof InstallTrigger !== 'undefined',
  isSafari: () =>
    /constructor/i.test(window.HTMLElement) ||
    (p => p.toString() === '[object SafariRemoteNotification]')(
      !window.safari || window.safari.pushNotification
    ),
  // eslint-disable-next-line
  isIE: () => /*@cc_on!@*/ false || !!document.documentMode,
  isEdge: () => !detectBrowser.isIE && !!window.StyleMedia,
  isChrome: () => !!window.chrome && !!window.chrome.webstore,
  isBlink: () =>
    (detectBrowser.isChrome || detectBrowser.isOpera) && !!window.CSS,
  get: () => {
    if (detectBrowser.isOpera()) return 'Opera'
    if (detectBrowser.isFirefox()) return 'Firefox'
    if (detectBrowser.isSafari()) return 'Safari'
    if (detectBrowser.isIE()) return 'IE'
    if (detectBrowser.isEdge()) return 'Edge'
    if (detectBrowser.isChrome()) return 'Chrome'
    if (detectBrowser.isBlink()) return 'Blink'
    return 'Unknown'
  }
}

export default detectBrowser
/**
 * Gets whether running on a certain operating system according to browser data.
 * Functions to test for a certain operating system (each returns bool):
 * * isAndroid
 * * isBlackBerry
 * * isIos
 * * isMac
 * * isWindows
 * * isLinux
 *
 * Function to get the operating system by name:
 * * get (possible return values: iOS, Android, Windows, Linux, Mac, BlackBerry, Unknown)
 * @example
 * ```js
 * detectOs.isAndroid() => true/false
 * detectOs.isIos() => true/false
 * detectOs.isWindows() => true/false
 * detectOs.isBlackBerry() => true/false
 * detectOs.isMac() => true/false
 * detectOs.isLinux() => true/false
 * detectOs.get() => iOS/Android/Windows/Linux/Mac/BlackBerry/Unknown
 * ```
 */

export const detectOs = {
  getUserAgent: () => navigator.userAgent,
  getPlatform: () => navigator.platform,
  isIos: () => /iPhone|iPad|iPod/.test(detectOs.getPlatform()),
  isAndroid: () => /Android/.test(detectOs.getUserAgent()),
  isBlackBerry: () => /BlackBerry/.test(detectOs.getPlatform()),
  isMac: () => /Mac/.test(detectOs.getPlatform()),
  isWindows: () => /Win/.test(detectOs.getPlatform()),
  isLinux: () => /Linux/.test(detectOs.getPlatform()) && !detectOs.isAndroid(),
  get: () => {
    if (detectOs.isIos()) return 'iOS'
    if (detectOs.isAndroid()) return 'Android'
    if (detectOs.isBlackBerry()) return 'BlackBerry'
    if (detectOs.isMac()) return 'Mac'
    if (detectOs.isWindows()) return 'Windows'
    if (detectOs.isLinux()) return 'Linux'
    return 'Unknown'
  }
}

/**
 * Gets the operating system and version the device is running on.
 * Works for Windows, Android, iOS, Mac OS X and BlackBerry.
 * @bit
 */

/**
 * @name get
 * @returns {{os:string, version:string}}
 * @example
 * ```js
 * detectOsVersion.get() => {os: 'Windows', version: '8.1'}
 * detectOsVersion.get() => {os: 'Android', version: '4.2.2'}
 * detectOsVersion.get() => {os: 'iOS', version: '5.1.1'}
 * detectOsVersion.get() => {os: 'Mac', version: '10.7.1'}
 * detectOsVersion.get() => {os: 'Linux', version: 'Unknown'}
 * detectOsVersion.get() => {os: 'Unknown', version: 'Unknown'}
 * ```
 * @bit
 */

export const detectOsVersion = {
  getUserAgent: () => {
    console.log('original invoked')
    return navigator.userAgent
  },
  get: () => {
    const os = detectOs.get()
    let version = 'Unknown'

    switch (os) {
      case 'Android':
        {
          const splitUserAgent = detectOsVersion
            .getUserAgent()
            .split('Android ')
          if (splitUserAgent.length > 1) {
            version = splitUserAgent[1].split(';')[0]
          }
        }
        break

      case 'Windows':
        {
          const splitUserAgent = detectOsVersion
            .getUserAgent()
            .split('Windows NT ')
          if (splitUserAgent.length > 1) {
            const versionSubStr = splitUserAgent[1]

            if (versionSubStr.startsWith('5.0')) {
              version = '2000'
            } else if (versionSubStr.startsWith('5.1')) {
              version = 'XP'
            } else if (versionSubStr.startsWith('5.2')) {
              version = 'Server'
            } else if (versionSubStr.startsWith('6.0')) {
              version = 'Vista'
            } else if (versionSubStr.startsWith('6.1')) {
              version = '7'
            } else if (versionSubStr.startsWith('6.2')) {
              version = '8'
            } else if (versionSubStr.startsWith('6.3')) {
              version = '8.1'
            } else if (versionSubStr.startsWith('10.0')) {
              version = '10'
            }
          }
        }
        break

      case 'iOS':
        {
          const splitUserAgent = detectOsVersion.getUserAgent().split('OS ')
          if (splitUserAgent.length > 1) {
            const unformattedVersion = splitUserAgent[1].split(' ')[0]
            version = unformattedVersion.split('_').join('.')
          }
        }
        break

      case 'Mac':
        {
          const splitUserAgent = detectOsVersion
            .getUserAgent()
            .split('Mac OS X ')
          if (splitUserAgent.length > 1) {
            let endOfVersion = splitUserAgent[1].indexOf(';')
            const firstParantheses = splitUserAgent[1].indexOf(')')
            if (
              firstParantheses > -1 &&
              (firstParantheses < endOfVersion || endOfVersion == -1)
            ) {
              endOfVersion = firstParantheses
            }

            const unformattedVersion = splitUserAgent[1].substring(
              0,
              endOfVersion
            )
            version = unformattedVersion.split('_').join('.')
          }
        }
        break

      case 'BlackBerry':
        {
          let splitUserAgent = detectOsVersion
            .getUserAgent()
            .split('BlackBerry9700/')
          if (splitUserAgent.length > 1) {
            version = splitUserAgent[1].split(' ')[0]
          } else {
            splitUserAgent = detectOsVersion.getUserAgent().split('Version/')
            if (splitUserAgent.length > 1) {
              version = splitUserAgent[1].split(' ')[0]
            }
          }
        }
        break

      default:
        break
    }

    return {
      os: os,
      version: version
    }
  }
}

export default detectOsVersion
/**
 * # Checks whether running on a mobile device according to browser data.
 * Functions (each returns bool):
 * * Android
 * * BlackBerry
 * * iPhone
 * * iPod
 * * iPad
 * * iOS
 * * Opera
 * * Windows
 * * Kindle Fire
 * * any
 * @example
 * isMobile.Android() => true/false
 * isMobile.iOS() => true/false
 * isMobile.any() => true/false
 * isMobile.KindleFire() => true/false
 * isMobile.BlackBerry() => true/false
 */

const isMobile = {
  getUserAgent: () => navigator.userAgent,
  Android: function() {
    return /Android/i.test(isMobile.getUserAgent()) && !isMobile.Windows()
  },
  BlackBerry: function() {
    return /BlackBerry|BB10|PlayBook/i.test(isMobile.getUserAgent())
  },
  iPhone: function() {
    return (
      /iPhone/i.test(isMobile.getUserAgent()) &&
      !isMobile.iPad() &&
      !isMobile.Windows()
    )
  },
  iPod: function() {
    return /iPod/i.test(isMobile.getUserAgent())
  },
  iPad: function() {
    return /iPad/i.test(isMobile.getUserAgent())
  },
  iOS: function() {
    return isMobile.iPad() || isMobile.iPod() || isMobile.iPhone()
  },
  Opera: function() {
    return /Opera Mini/i.test(isMobile.getUserAgent())
  },
  Windows: function() {
    return /Windows Phone|IEMobile|WPDesktop/i.test(isMobile.getUserAgent())
  },
  KindleFire: function() {
    return /Kindle Fire|Silk|KFAPWA|KFSOWI|KFJWA|KFJWI|KFAPWI|KFAPWI|KFOT|KFTT|KFTHWI|KFTHWA|KFASWI|KFTBWI|KFMEWI|KFFOWI|KFSAWA|KFSAWI|KFARWI/i.test(
      isMobile.getUserAgent()
    )
  },
  any: function() {
    return (
      isMobile.Android() ||
      isMobile.BlackBerry() ||
      isMobile.iOS() ||
      isMobile.Opera() ||
      isMobile.Windows()
    )
  }
}

export default isMobile
import detectBrowser from './detect-browser'
import { detectOs, detectOsVersion } from './detect-os'
import isMobile from './is-mobile'

export {
  detectBrowser,
  detectOs,
  detectOsVersion,
  isMobile
}

export default detectBrowser