UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

141 lines (130 loc) 5.73 kB
import memorizeOne from 'memoize-one'; const getFirstMatch = (regexp, ua) => { const match = ua.match(regexp); return match && match.length > 0 && match[1] || ''; }; const getSecondMatch = (regexp, ua) => { const match = ua.match(regexp); return match && match.length > 0 && match[2] || ''; }; // Helper functions to safely access browser properties const getSafeUserAgent = () => { var _window$navigator; if (typeof window === 'undefined') { return undefined; } // Check for SSR user agent first if (process.env.REACT_SSR) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const ssrUserAgent = window.__SSR_USER_AGENT__; if (ssrUserAgent) { return ssrUserAgent; } } // Fallback to navigator.userAgent with proper null checking return (_window$navigator = window.navigator) === null || _window$navigator === void 0 ? void 0 : _window$navigator.userAgent; }; const getSafePlatform = () => { var _window$navigator2; if (typeof window === 'undefined') { return undefined; } return (_window$navigator2 = window.navigator) === null || _window$navigator2 === void 0 ? void 0 : _window$navigator2.platform; }; const hasIntersectionObserver = () => { return typeof window !== 'undefined' && 'IntersectionObserver' in window && 'IntersectionObserverEntry' in window && // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any 'intersectionRatio' in window.IntersectionObserverEntry.prototype; }; const hasResizeObserver = () => { return typeof window !== 'undefined' && 'ResizeObserver' in window && 'ResizeObserverEntry' in window; }; // New API to get the browser info on demand export const getBrowserInfo = memorizeOne(() => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const result = { mac: false, windows: false, ie: false, ie_version: 0, gecko: false, gecko_version: 0, chrome: false, chrome_version: 0, android: false, ios: false, webkit: false, safari: false, safari_version: 0, supportsIntersectionObserver: false, supportsResizeObserver: false }; const userAgent = getSafeUserAgent(); const platform = getSafePlatform(); if (userAgent) { // inspired from https://github.com/bowser-js/bowser/blob/master/src/parser-browsers.js // Ignored via go/ees005 // eslint-disable-next-line require-unicode-regexp const ieEdge = /\sedg\//i.test(userAgent); // eslint-disable-next-line require-unicode-regexp const ieEdge2 = /edg([ea]|ios)/i.test(userAgent); // eslint-disable-next-line require-unicode-regexp const internetExplorer = /msie|trident/i.test(userAgent); // Ideally we should use userAgent instead of platform, but we have lots of keymap tests failure when we change it // So leave it as is for now. // Ignored via go/ees005 // eslint-disable-next-line require-unicode-regexp result.mac = platform && /Mac/.test(platform); // Previously relied on navigator.userAgentData?.platform and userAgent, now used only userAgent result.windows = // Ignored via go/ees005 // eslint-disable-next-line require-unicode-regexp /Windows|Win\d+/i.test(userAgent); // used userAgent rather than relying on documentMode const ie = ieEdge || ieEdge2 || internetExplorer; result.ie = ie; // inspired from https://github.com/bowser-js/bowser/blob/master/src/parser-browsers.js result.ie_version = ieEdge ? // eslint-disable-next-line require-unicode-regexp parseInt(getFirstMatch(/\sedg\/(\d+(\.?_?\d+)+)/i, userAgent), 10) : // eslint-disable-next-line require-unicode-regexp ieEdge2 ? // eslint-disable-next-line require-unicode-regexp parseInt(getSecondMatch(/edg([ea]|ios)\/(\d+(\.?_?\d+)+)/i, userAgent), 10) : // eslint-disable-next-line require-unicode-regexp parseInt(getFirstMatch(/(?:msie |rv:)(\d+(\.?_?\d+)+)/i, userAgent), 10); // Ignored via go/ees005 // eslint-disable-next-line require-unicode-regexp result.gecko = !ie && /gecko\/\d/i.test(userAgent); // Ignored via go/ees005 // eslint-disable-next-line require-unicode-regexp result.gecko_version = parseInt((userAgent.match(/Firefox\/(\d+)/) || [])[1], 10); // Ignored via go/ees005 // eslint-disable-next-line require-unicode-regexp result.chrome = !ie && /Chrome\//.test(userAgent); // Ignored via go/ees005 // eslint-disable-next-line require-unicode-regexp result.chrome_version = parseInt((userAgent.match(/Chrome\/(\d+)/) || [])[1], 10); // Ignored via go/ees005 // eslint-disable-next-line require-unicode-regexp result.android = /Android \d/.test(userAgent); result.ios = // Ignored via go/ees005 // eslint-disable-next-line require-unicode-regexp !ie && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent); // Previously relied on navigator.vendor, now used userAgent result.safari = !result.chrome && !result.ie && !result.gecko && !result.android && !userAgent.includes('CriOS') && !userAgent.includes('FxiOS') && // eslint-disable-next-line require-unicode-regexp /safari|applewebkit/i.test(userAgent); result.safari_version = parseInt( // eslint-disable-next-line require-unicode-regexp (userAgent.match(/Version\/([0-9\._]+).*Safari/) || [])[1], 10); // Previously we relied on documentElement.style.WebkitAppearance, now changed to userAgent // eslint-disable-next-line require-unicode-regexp result.webkit = /(apple)?webkit/i.test(userAgent); result.supportsIntersectionObserver = hasIntersectionObserver(); result.supportsResizeObserver = hasResizeObserver(); } return result; });