From 372b59590843a97e976a69e10caaeb18e565fabb Mon Sep 17 00:00:00 2001 From: Jaya Allamsetty Date: Tue, 30 Jul 2024 15:45:38 -0400 Subject: [PATCH] ref(browser-detection) Convert to TS. Remove BrowserCapabilities class since lib-jitsi-meet no longer uses it. --- browser-capabilities/BrowserCapabilities.js | 123 ---------------- browser-capabilities/index.js | 1 - ...rowserDetection.js => BrowserDetection.ts} | 138 +++++++++--------- browser-detection/constants.js | 38 ----- browser-detection/constants.ts | 36 +++++ browser-detection/index.js | 4 +- index.js | 1 - package-lock.json | 17 ++- package.json | 1 + 9 files changed, 126 insertions(+), 233 deletions(-) delete mode 100644 browser-capabilities/BrowserCapabilities.js delete mode 100644 browser-capabilities/index.js rename browser-detection/{BrowserDetection.js => BrowserDetection.ts} (68%) delete mode 100644 browser-detection/constants.js create mode 100644 browser-detection/constants.ts diff --git a/browser-capabilities/BrowserCapabilities.js b/browser-capabilities/BrowserCapabilities.js deleted file mode 100644 index 2e56dd8..0000000 --- a/browser-capabilities/BrowserCapabilities.js +++ /dev/null @@ -1,123 +0,0 @@ -import BrowserDetection from '../browser-detection/BrowserDetection.js'; - -// TODO: Move BrowserCapabilities from lib-jitsi-meet here and use the JSON -// format for them. - -/** - * Implements browser capabilities for lib-jitsi-meet. - */ -export default class BrowserCapabilities { - /** - * Creates new BrowserCapabilities instance. - * - * @param {Object} capabilitiesDB - The JSON database with capabilities. - * @param {boolean} [isUsingIFrame] - True if Jitsi Meet is loaded in iframe - * and false otherwise. - * @param {Object} [browserInfo] - Information about the browser. - * @param {string} browserInfo.name - The name of the browser. - * @param {string} browserInfo.version - The version of the browser. - */ - constructor(capabilitiesDB = {}, isUsingIFrame = false, browserInfo) { - const browser = new BrowserDetection(browserInfo); - let capabilitiesByVersion; - - // If the capabilitiesDB is not in the correct format or the type of the - // version of the browser is undefined(the version is unknown) or the - // version type is not compatible (not a string) we'll consider the - // browser as not supported. - if (typeof capabilitiesDB === 'object' - && typeof browser.getVersion() === 'string') { - const browserCapabilities = capabilitiesDB[browser.getName()] || []; - - for (let i = 0; i < browserCapabilities.length; i++) { - const capabilities = browserCapabilities[i]; - - if (typeof capabilities !== 'object') { - // eslint-disable-next-line no-continue - continue; - } - - const version = capabilities.version; - - if (!version || !browser.isVersionGreaterThan(version)) { - capabilitiesByVersion = capabilities; - break; - } - } - } - - if (!capabilitiesByVersion || !capabilitiesByVersion.capabilities) { - this._capabilities = { isSupported: false }; - } else if (isUsingIFrame) { - this._capabilities = { - ...capabilitiesByVersion.capabilities, - ...capabilitiesByVersion.iframeCapabilities - }; - } else { - this._capabilities = capabilitiesByVersion.capabilities; - } - - if (typeof this._capabilities.isSupported === 'undefined') { - // we have some capabilities but isSupported property is not filled. - this._capabilities.isSupported = true; - } else if (this._capabilities.isSupported === false) { - // Clean the other capabilities. - this._capabilities = { isSupported: false }; - } - } - - /** - * Checks whether the browser is supported by Jitsi Meet. - * - * @returns {boolean} - */ - isSupported() { - return this._capabilities.isSupported; - } - - /** - * Checks whether the browser supports incoming audio. - * - * @returns {boolean} - */ - supportsAudioIn() { - return this._capabilities.audioIn || false; - } - - /** - * Checks whether the browser supports outgoing audio. - * - * @returns {boolean} - */ - supportsAudioOut() { - return this._capabilities.audioOut || false; - } - - - /** - * Checks whether the browser supports screen sharing. - * - * @returns {boolean} - */ - supportsScreenSharing() { - return this._capabilities.screenSharing || false; - } - - /** - * Checks whether the browser supports incomming video. - * - * @returns {boolean} - */ - supportsVideoIn() { - return this._capabilities.videoIn || false; - } - - /** - * Checks whether the browser supports outgoing video. - * - * @returns {boolean} - */ - supportsVideoOut() { - return this._capabilities.videoOut || false; - } -} diff --git a/browser-capabilities/index.js b/browser-capabilities/index.js deleted file mode 100644 index 70ec184..0000000 --- a/browser-capabilities/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default as BrowserCapabilities } from './BrowserCapabilities.js'; diff --git a/browser-detection/BrowserDetection.js b/browser-detection/BrowserDetection.ts similarity index 68% rename from browser-detection/BrowserDetection.js rename to browser-detection/BrowserDetection.ts index d21f423..ee2a2ff 100644 --- a/browser-detection/BrowserDetection.js +++ b/browser-detection/BrowserDetection.ts @@ -1,42 +1,40 @@ import { UAParser } from 'ua-parser-js'; import { - BLINK, - CHROME, - ELECTRON, + Browser, + Engine, ENGINES, - GECKO, - PARSER_TO_JITSI_NAME, - REACT_NATIVE, - SAFARI, - WEBKIT -} from './constants.js'; + PARSER_TO_JITSI_NAME, +} from './constants'; + +interface IBrowserInfo { + name: string; + version: string; + engine?: string; + engineVersion?: string; +} /** * Detects React Native environment. * @returns {Object|undefined} - The name (REACT_NATIVE) and version. */ -function _detectReactNative() { - const match - = navigator.userAgent.match(/\b(react[ \t_-]*native)(?:\/(\S+))?/i); - let version; - - // If we're remote debugging a React Native app, it may be treated as - // Chrome. Check navigator.product as well and always return some version - // even if we can't get the real one. +function _detectReactNative(): IBrowserInfo | undefined { + const match = navigator.userAgent.match(/\b(react[ \t_-]*native)(?:\/(\S+))?/i); + let version: string; + // If we're remote debugging a React Native app, it may be treated as Chrome. Check navigator.product as well and + // always return some version even if we can't get the real one. if (match || navigator.product === 'ReactNative') { - let name; + let name: string = Browser.REACT_NATIVE; + version = 'unknown'; if (match && match.length > 2) { name = match[1]; version = match[2]; } - name || (name = 'react-native'); - version || (version = 'unknown'); return { - name: REACT_NATIVE, + name, version }; } @@ -54,12 +52,14 @@ function _detectReactNative() { * @param {string} browserInfo.osVersion - The os version of the browser. * @returns */ -function _getJitsiBrowserInfo(browserInfo) { +function _getJitsiBrowserInfo(browserInfo: IBrowserInfo): IBrowserInfo { + const { engine, engineVersion, name, version} = browserInfo; + return { - name: PARSER_TO_JITSI_NAME[browserInfo.name], - version: browserInfo.version, - engine: ENGINES[browserInfo.engine], - engineVersion: browserInfo.engineVersion + name: PARSER_TO_JITSI_NAME[name], + version, + engine: ENGINES[engine], + engineVersion: engineVersion }; } @@ -68,7 +68,7 @@ function _getJitsiBrowserInfo(browserInfo) { * @param {Object} - The parser instance. * @returns {Object} - The name and version of the browser. */ -function _detect(parser) { +function _detect(parser: any): IBrowserInfo { const reactNativeInfo = _detectReactNative(); if (reactNativeInfo) { @@ -89,6 +89,12 @@ function _detect(parser) { * Implements browser detection. */ export default class BrowserDetection { + _parser: any; + _name: string; + _version: any; + _engine: string | undefined; + _engineVersion: string | undefined; + /** * Creates new BrowserDetection instance. * @@ -100,7 +106,7 @@ export default class BrowserDetection { * @param {string} browserInfo.os - The os of the browser. * @param {string} browserInfo.osVersion - The os version of the browser. */ - constructor(browserInfo) { + constructor(browserInfo: IBrowserInfo) { this._parser = new UAParser(navigator.userAgent); const { @@ -120,64 +126,64 @@ export default class BrowserDetection { * Checks if current browser is Chrome. * @returns {boolean} */ - isChrome() { + isChrome(): boolean { // for backward compatibility returns true for all Chromium browsers - return this._name === CHROME || this._engine === BLINK; + return this._name === Browser.CHROME || this._engine === Engine.BLINK; } /** * Checks if current browser is Firefox. * @returns {boolean} */ - isFirefox() { - return this._engine === GECKO; + isFirefox(): boolean { + return this._engine === Engine.GECKO; } /** * Checks if current browser is Safari. * @returns {boolean} */ - isSafari() { - return this._name === SAFARI; + isSafari(): boolean { + return this._name === Browser.SAFARI; } /** * Checks if current environment is Electron. * @returns {boolean} */ - isElectron() { - return this._name === ELECTRON; + isElectron(): boolean { + return this._name === Browser.ELECTRON; } /** * Checks if current environment is React Native. * @returns {boolean} */ - isReactNative() { - return this._name === REACT_NATIVE; + isReactNative(): boolean { + return this._name === Browser.REACT_NATIVE; } /** * Checks if current browser is based on chromium. * @returns {boolean} */ - isChromiumBased() { - return this._engine === BLINK; + isChromiumBased(): boolean { + return this._engine === Engine.BLINK; } /** * Checks if current browser is based on webkit. * @returns {boolean} */ - isWebKitBased() { - return this._engine === WEBKIT; + isWebKitBased(): boolean { + return this._engine === Engine.WEBKIT; } /** * Gets current browser name. * @returns {string} */ - getName() { + getName(): string { if (this._name) { return this._name; } @@ -189,7 +195,7 @@ export default class BrowserDetection { * Returns the version of the current browser. * @returns {string} */ - getVersion() { + getVersion(): string { if (this._version) { return this._version; } @@ -201,7 +207,7 @@ export default class BrowserDetection { * Gets current engine name of the browser. * @returns {string} */ - getEngine() { + getEngine(): string | undefined { return this._engine; } @@ -209,107 +215,107 @@ export default class BrowserDetection { * Returns the engine version of the current browser. * @returns the engine version */ - getEngineVersion() { + getEngineVersion(): string | undefined { return this._engineVersion; } /** * Returns the operating system. */ - getOS() { + getOS(): string { return this._parser.getOS().name; } /** * Return the os version. */ - getOSVersion() { + getOSVersion(): string { return this._parser.getOS().version; } /** * Compares the passed version with the current browser version. * - * @param {number|string} version - The version to compare with. + * @param {number} version - The version to compare with. * @returns {boolean|undefined} - Returns true if the current version is * greater than the passed version and false otherwise. Returns undefined if * the current browser version is unknown. */ - isVersionGreaterThan(version) { + isVersionGreaterThan(version: number): boolean | undefined { if (this._version) { - return parseInt(this._version, 10) > parseInt(version, 10); + return parseInt(this._version, 10) > version; } } /** * Compares the passed version with the current browser version. * - * @param {number|string} version - The version to compare with. + * @param {number} version - The version to compare with. * @returns {boolean|undefined} - Returns true if the current version is * lower than the passed version and false otherwise. Returns undefined if * the current browser version is unknown. */ - isVersionLessThan(version) { + isVersionLessThan(version: number): boolean | undefined { if (this._version) { - return parseInt(this._version, 10) < parseInt(version, 10); + return parseInt(this._version, 10) < version; } } /** * Compares the passed version with the current browser version. * - * @param {number|string} version - The version to compare with. + * @param {number} version - The version to compare with. * @returns {boolean|undefined} - Returns true if the current version is * equal to the passed version and false otherwise. Returns undefined if * the current browser version is unknown. * A loose-equality operator is used here so that it matches the sub-versions as well. */ - isVersionEqualTo(version) { + isVersionEqualTo(version: number): boolean | undefined { if (this._version) { - return parseInt(this._version, 10) === parseInt(version, 10); + return parseInt(this._version, 10) === version; } } /** * Compares the passed version with the current engine version. * - * @param {number|string} version - The version to compare with. + * @param {number} version - The version to compare with. * @returns {boolean|undefined} - Returns true if the current version is * greater than the passed version and false otherwise. Returns undefined if * the current engine version is unknown. */ - isEngineVersionGreaterThan(version) { + isEngineVersionGreaterThan(version: number): boolean | undefined { if (this._engineVersion) { - return parseInt(this._engineVersion, 10) > parseInt(version, 10); + return parseInt(this._engineVersion, 10) > version; } } /** * Compares the passed version with the current engine version. * - * @param {number|string} version - The version to compare with. + * @param {number} version - The version to compare with. * @returns {boolean|undefined} - Returns true if the current version is * lower than the passed version and false otherwise. Returns undefined if * the current engine version is unknown. */ - isEngineVersionLessThan(version) { + isEngineVersionLessThan(version: number): boolean | undefined { if (this._engineVersion) { - return parseInt(this._engineVersion, 10) < parseInt(version, 10); + return parseInt(this._engineVersion, 10) < version; } } /** * Compares the passed version with the current engine version. * - * @param {number|string} version - The version to compare with. + * @param {number} version - The version to compare with. * @returns {boolean|undefined} - Returns true if the current version is * equal to the passed version and false otherwise. Returns undefined if * the current engine version is unknown. * A loose-equality operator is used here so that it matches the sub-versions as well. */ - isEngineVersionEqualTo(version) { + isEngineVersionEqualTo(version: number): boolean | undefined { if (this._engineVersion) { - return parseInt(this._engineVersion, 10) === parseInt(version, 10); + return parseInt(this._engineVersion, 10) === version; } } } diff --git a/browser-detection/constants.js b/browser-detection/constants.js deleted file mode 100644 index 1fb0654..0000000 --- a/browser-detection/constants.js +++ /dev/null @@ -1,38 +0,0 @@ -// TODO: Maybe fix the values to 'Chrome', 'Internet Explorer', etc. Currently -// this values needs to be as they are becuse they are going to analytics, -// callstats, etc. - -export const CHROME = 'chrome'; - -export const FIREFOX = 'firefox'; - -export const SAFARI = 'safari'; - -export const ELECTRON = 'electron'; - -export const REACT_NATIVE = 'react-native'; - -export const WEBKIT_BROWSER = 'webkit-browser'; - -/** - * Maps the names of the browsers from ua-parser to the internal names defined in - * ./browsers.js - */ -export const PARSER_TO_JITSI_NAME = { - 'Chrome': CHROME, - 'Firefox': FIREFOX, - 'Safari': SAFARI, - 'Electron': ELECTRON -}; - -export const BLINK = 'blink'; - -export const WEBKIT = 'webkit'; - -export const GECKO = 'gecko'; - -export const ENGINES = { - 'Blink': BLINK, - 'WebKit': WEBKIT, - 'Gecko': GECKO -}; diff --git a/browser-detection/constants.ts b/browser-detection/constants.ts new file mode 100644 index 0000000..4cdf2f3 --- /dev/null +++ b/browser-detection/constants.ts @@ -0,0 +1,36 @@ + +// TODO: Maybe fix the values to 'Chrome', 'Internet Explorer', etc. Currently +// these values need to be as they are because they are going to analytics, +// callstats, etc. + +export enum Browser { + CHROME = 'chrome', + FIREFOX = 'firefox', + SAFARI = 'safari', + ELECTRON = 'electron', + REACT_NATIVE = 'react-native', + WEBKIT_BROWSER = 'webkit-browser' +} + +/** + * Maps the names of the browsers from ua-parser to the internal names defined in + * ./browsers.js + */ +export const PARSER_TO_JITSI_NAME: { [key: string]: Browser } = { + 'Chrome': Browser.CHROME, + 'Firefox': Browser.FIREFOX, + 'Safari': Browser.SAFARI, + 'Electron': Browser.ELECTRON +}; + +export enum Engine { + BLINK = 'blink', + WEBKIT = 'webkit', + GECKO = 'gecko' +} + +export const ENGINES: { [key: string]: Engine } = { + 'Blink': Engine.BLINK, + 'WebKit': Engine.WEBKIT, + 'Gecko': Engine.GECKO +}; \ No newline at end of file diff --git a/browser-detection/index.js b/browser-detection/index.js index 7583565..de622e7 100644 --- a/browser-detection/index.js +++ b/browser-detection/index.js @@ -1,3 +1,3 @@ -export { default as BrowserDetection } from './BrowserDetection.js'; -import * as browsers from './constants.js'; +export { default as BrowserDetection } from './BrowserDetection.ts'; +import * as browsers from './constants.ts'; export { browsers }; diff --git a/index.js b/index.js index dfcef10..fbf54cf 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,3 @@ export * from './avatar/index.js'; -export * from './browser-capabilities/index.js'; export * from './browser-detection/index.js'; export * from './jitsi-local-storage/index.js'; diff --git a/package-lock.json b/package-lock.json index 6d53995..fc3900f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@jitsi/js-utils", - "version": "2.2.1", + "version": "2.2.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@jitsi/js-utils", - "version": "2.2.1", + "version": "2.2.2", "license": "Apache-2.0", "dependencies": { "@hapi/bourne": "^3.0.0", @@ -16,6 +16,7 @@ "devDependencies": { "@babel/eslint-parser": "7.22.15", "@jitsi/eslint-config": "4.1.5", + "@types/ua-parser-js": "0.7.39", "eslint": "8.50.0", "eslint-plugin-import": "2.28.1" } @@ -592,6 +593,12 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/ua-parser-js": { + "version": "0.7.39", + "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.39.tgz", + "integrity": "sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg==", + "dev": true + }, "node_modules/acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -3531,6 +3538,12 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "@types/ua-parser-js": { + "version": "0.7.39", + "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.39.tgz", + "integrity": "sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg==", + "dev": true + }, "acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", diff --git a/package.json b/package.json index a053572..2818622 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "devDependencies": { "@jitsi/eslint-config": "4.1.5", "@babel/eslint-parser": "7.22.15", + "@types/ua-parser-js": "0.7.39", "eslint": "8.50.0", "eslint-plugin-import": "2.28.1" },