UNPKG

@readium/navigator

Version:

Next generation SDK for publications in Web Apps

143 lines (129 loc) 7.62 kB
/*! * (℠) * # sML.js | I'm a Simple and Middling Library. * * * Copyright (c) Satoru MATSUSHIMA - https://github.com/satorumurmur/sML * * Licensed under the MIT license. - http://www.opensource.org/licenses/mit-license.php * * Portions of this code come from the sML library * Current version: 1.0.36 */ /// <reference types="user-agent-data-types" /> declare interface OSFlags { iOS: number[]; macOS: number[]; iPadOS: number[]; WindowsPhone: number[]; ChromeOS: number[]; Windows: number[]; Android: number[]; Linux: number[]; Firefox: boolean; } declare interface UAFlags { Gecko: number[]; Firefox: number[]; Waterfox: number[]; Opera: number[]; Silk: number[]; Blink: number[]; EdgeHTML: number[]; Chrome: number[]; Chromium: number[]; Phoebe: number[]; UCBrowser: number[]; Vivaldi: number[]; Safari: number[]; Edge: number[]; WebKit: number[]; Trident: number[]; InternetExplorer: number[]; Flash: number[]; Facebook: number[]; LINE: number[]; } declare type iOSRequest = "mobile" | "desktop" | undefined; // Fallback when global 'navigator' is not available, such as in SSR environments. const userAgent = () => typeof navigator === "undefined" ? "" : (navigator.userAgent || ""); const userAgentData = () => typeof navigator === "undefined" ? undefined : (navigator.userAgentData || undefined); class sMLFactory { OS: OSFlags; UA: UAFlags; Env!: string[]; constructor() { const NUAD = userAgentData(), NUA = userAgent(); const _sV = (V?: string | number) => (typeof V === "string" || typeof V === "number") && V ? String(V).replace(/_/g, ".").split(".").map(I => parseInt(I) || 0) : []; const _dV = (Pre="") => { if(!Pre) return []; const RE = new RegExp("^.*" + Pre + "[ :\\/]?(\\d+([\\._]\\d+)*).*$"); if(!RE.test(NUA)) return []; return _sV(NUA.replace(RE, "$1")); }; this.OS = ((OS: OSFlags) => { if( /(macOS|Mac OS X)/.test(NUA)) { if(/\(iP(hone|od touch);/.test(NUA)) OS.iOS = _dV("CPU (?:iPhone )?OS "); if( /\(iPad;/.test(NUA)) OS.iOS = OS.iPadOS = _dV("CPU (?:iPhone )?OS "); else if( /(macOS|Mac OS X) \d/.test(NUA)) document.ontouchend !== undefined ? OS.iOS = OS.iPadOS = _dV() : OS.macOS = _dV("(?:macOS|Mac OS X) "); } else if( /Windows( NT)? \d/.test(NUA)) OS.Windows = (V => V[0] !== 6 || !V[1] ? V : V[1] === 1 ? [7] : V[1] === 2 ? [8] : [8, 1])(_dV("Windows(?: NT)?")); else if( /Android \d/.test(NUA)) OS.Android = _dV("Android"); else if( /CrOS/.test(NUA)) OS.ChromeOS = _dV(); else if( /X11;/.test(NUA)) OS.Linux = _dV(); return OS; })({} as OSFlags); if(NUAD) NUAD.getHighEntropyValues(["architecture", "model", "platform", "platformVersion", "uaFullVersion"]).then((HEUAD: any) => (OS => { const Pf = HEUAD.platform, PfV = HEUAD.platformVersion; if(!Pf || !PfV) return; if( /^i(OS|P(hone|od touch))$/.test(Pf)) OS.iOS = _sV(PfV); else if( /^iPad(OS)?$/.test(Pf)) OS.iOS = OS.iPadOS = _sV(PfV); else if(/^(macOS|(Mac )?OS X|Mac(Intel)?)$/.test(Pf)) document.ontouchend !== undefined ? OS.iOS = OS.iPadOS = _sV() : OS.macOS = _sV(PfV); else if( /^(Microsoft )?Windows$/.test(Pf)) OS.Windows = _sV(PfV); else if( /^(Google )?Android$/.test(Pf)) OS.Android = _sV(PfV); else if( /^((Google )?Chrome OS|CrOS)$/.test(Pf)) OS.ChromeOS = _sV(PfV); else if( /^(Linux|Ubuntu|X11)$/.test(Pf)) OS.Linux = _sV(PfV); else return; /**/ Object.keys(this.OS).forEach(Key => delete (this.OS as any)[Key]), Object.assign(this.OS, OS); })({} as OSFlags)); this.UA = ((UA: UAFlags) => { let _OK = false; if(NUAD && Array.isArray(NUAD.brands)) { const BnV = NUAD.brands.reduce((BnV: Record<string, number[]>, _: NavigatorUABrandVersion) => { BnV[_.brand] = [(_.version as any) * 1]; return BnV; }, {}); if(BnV["Google Chrome"]) _OK = true, UA.Blink = UA.Chromium = BnV["Chromium"] || [], UA.Chrome = BnV["Google Chrome"]; else if(BnV["Microsoft Edge"]) _OK = true, UA.Blink = UA.Chromium = BnV["Chromium"] || [], UA.Edge = BnV["Microsoft Edge"]; else if(BnV["Opera"]) _OK = true, UA.Blink = UA.Chromium = BnV["Chromium"] || [], UA.Opera = BnV["Opera"]; } if(!_OK) { if( / Gecko\/\d/.test(NUA)) { UA.Gecko = _dV("rv"); if( / Waterfox\/\d/.test(NUA)) UA.Waterfox = _dV("Waterfox"); else if( / Firefox\/\d/.test(NUA)) UA.Firefox = _dV("Firefox"); } else if( / Edge\/\d/.test(NUA)) { UA.EdgeHTML = _dV("Edge"); UA.Edge = UA.EdgeHTML; } else if(/ Chrom(ium|e)\/\d/.test(NUA)) { UA.Blink = UA.Chromium = (V => V[0] ? V : _dV("Chrome"))(_dV("Chromium")); if( / EdgA?\/\d/.test(NUA)) UA.Edge = (V => V[0] ? V : _dV("Edg"))(_dV("EdgA")); else if( / OPR\/\d/.test(NUA)) UA.Opera = _dV("OPR"); else if( / Vivaldi\/\d/.test(NUA)) UA.Vivaldi = _dV("Vivaldi"); else if( / Silk\/\d/.test(NUA)) UA.Silk = _dV("Silk"); else if( / UCBrowser\/\d/.test(NUA)) UA.UCBrowser = _dV("UCBrowser"); else if( / Phoebe\/\d/.test(NUA)) UA.Phoebe = _dV("Phoebe"); else UA.Chrome = (V => V[0] ? V : UA.Chromium)(_dV("Chrome")); } else if( / AppleWebKit\/\d/.test(NUA)) { UA.WebKit = _dV("AppleWebKit"); if( / CriOS \d/.test(NUA)) UA.Chrome = _dV("CriOS"); else if( / FxiOS \d/.test(NUA)) UA.Firefox = _dV("FxiOS"); else if( / EdgiOS\/\d/.test(NUA)) UA.Edge = _dV("EdgiOS"); else if( / Version\/\d/.test(NUA)) UA.Safari = _dV("Version"); } else if( / Trident\/\d/.test(NUA)) { UA.Trident = _dV("Trident"); UA.InternetExplorer = (V => V[0] ? V : _dV("MSIE"))(_dV("rv")); } } /*+*/ if( /[\[; ]FB(AN|_IAB)\//.test(NUA)) UA.Facebook = _dV("FBAV"); /*+*/ if( / Line\/\d/.test(NUA)) UA.LINE = _dV("Line"); return UA; })({} as UAFlags); (this.Env as any) = { get: () => [this.OS, this.UA].reduce((Env: string[], OS_UA) => { for(const Par in OS_UA) if((OS_UA as any)[Par]) Env.push(Par); return Env; }, []) }; } } class sMLFactoryWithRequest extends sMLFactory { get iOSRequest(): iOSRequest { const NUAD = userAgentData(), NUA = userAgent(); if (this.OS.iOS && !this.OS.iPadOS) { return "mobile"; } else if (this.OS.iPadOS) { return (/\(iPad;/.test(NUA) || (NUAD && /^iPad(OS)?$/.test(NUAD.platform))) ? "mobile" : "desktop" } return undefined; } } const sML = new sMLFactory(); const sMLWithRequest = new sMLFactoryWithRequest(); export { sML, sMLWithRequest };