UNPKG

nwa-client

Version:

Native WebApp client library

334 lines 13.3 kB
var _a; function generateDeviceId() { const deviceId = self.crypto.randomUUID(); localStorage.setItem('deviceId', deviceId); return deviceId; } function hasMinVersion(version) { const matchApp = /(\d+)\.(\d+)\.(\d+)\+(\d+) NWA/i.exec(navigator.userAgent); const matchMin = /(\d+)\.(\d+)\.(\d+)/i.exec(version); if (!matchApp || !matchMin) { return false; } const [majorA, minorA, patchA] = matchApp.slice(1).map(Number); const [majorB, minorB, patchB] = matchMin.slice(1).map(Number); if (majorA !== majorB) { return majorA > majorB; } if (minorA !== minorB) { return minorA > minorB; } return patchA >= patchB; } function getMeta(name) { const meta = document.querySelector('meta[name="' + name + '"]'); if (meta) { return meta.getAttribute('content'); } else { return '#FFFFFFFF'; } } function getInfos() { const nVer = navigator.appVersion; const nAgt = navigator.userAgent; let browserName = navigator.appName; let fullVersion = '' + parseFloat(navigator.appVersion); let majorVersion = parseInt(navigator.appVersion, 10); let nameOffset, verOffset, ix; // In Opera, the true version is after "Opera" or after "Version" if ((verOffset = nAgt.indexOf('Opera')) !== -1) { browserName = 'Opera'; fullVersion = nAgt.substring(verOffset + 6); if ((verOffset = nAgt.indexOf('Version')) !== -1) { fullVersion = nAgt.substring(verOffset + 8); } } // In MSIE, the true version is after "MSIE" in userAgent else if ((verOffset = nAgt.indexOf('MSIE')) !== -1) { browserName = 'Microsoft Internet Explorer'; fullVersion = nAgt.substring(verOffset + 5); } // In Chrome, the true version is after "Chrome" else if ((verOffset = nAgt.indexOf('Chrome')) !== -1) { browserName = 'Chrome'; fullVersion = nAgt.substring(verOffset + 7); } // In Safari, the true version is after "Safari" or after "Version" else if ((verOffset = nAgt.indexOf('Safari')) !== -1) { browserName = 'Safari'; fullVersion = nAgt.substring(verOffset + 7); if ((verOffset = nAgt.indexOf('Version')) !== -1) { fullVersion = nAgt.substring(verOffset + 8); } } // In Firefox, the true version is after "Firefox" else if ((verOffset = nAgt.indexOf('Firefox')) !== -1) { browserName = 'Firefox'; fullVersion = nAgt.substring(verOffset + 8); } // In most other browsers, "name/version" is at the end of userAgent else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) { browserName = nAgt.substring(nameOffset, verOffset); fullVersion = nAgt.substring(verOffset + 1); if (browserName.toLowerCase() === browserName.toUpperCase()) { browserName = navigator.appName; } } // trim the fullVersion string at semicolon/space if present if ((ix = fullVersion.indexOf(';')) !== -1) { fullVersion = fullVersion.substring(0, ix); } if ((ix = fullVersion.indexOf(' ')) !== -1) { fullVersion = fullVersion.substring(0, ix); } majorVersion = parseInt('' + fullVersion, 10); if (isNaN(majorVersion)) { fullVersion = '' + parseFloat(navigator.appVersion); majorVersion = parseInt(navigator.appVersion, 10); } return { browserName, fullVersion, majorVersion, }; } let App; const isNativeWebApp = /NWA/i.test(navigator.userAgent); const isUpToDate = hasMinVersion('2.6.0'); if (isNativeWebApp && isUpToDate && window.NwaHandler) { const isAndroid = /android/i.test(navigator.userAgent); let requestId = 0; const handlers = []; const requests = []; App = new Proxy(window.NwaHandler, { // eslint-disable-next-line @typescript-eslint/no-explicit-any get(target, propKey) { if (propKey === 'isWeb') { return false; } if (propKey === 'mobile' || propKey === 'nwa') { return true; } return (...args) => { if (propKey === 'notify' || propKey === 'emit') { const channel = args.shift(); if (channel in handlers) { try { let success = true; for (const handler of handlers[channel]) { success = success && handler(...args) !== false; } return success; } catch (e) { return false; } } else { return false; } } else if (propKey === 'resolve' || propKey === 'reject' || propKey === 'onSuccess' || propKey === 'onError') { const request = requests[args[0]]; if (request) { if (args.length > 1) { return request[propKey](args[1]); } else { return request[propKey](); } } else { // eslint-disable-next-line max-len, no-console console.error('Unable to resolve request. (id=' + args[0] + ', now=' + Date.now() + ', data=' + JSON.stringify(args[1]) + ')'); } } else if (target[propKey] === undefined) { if (propKey === 'on') { if (!handlers[args[0]]) { handlers[args[0]] = []; } handlers[args[0]].push(args[1]); } const id = 'req-' + (requestId++) + '-' + Date.now(); if (isAndroid) { if (target.request) { return new Promise((resolve, reject) => { requests[id] = { resolve, reject }; target.request(propKey, id, JSON.stringify(args)); }); } else { return new Promise((resolve, reject) => { requests[id] = { resolve, reject }; target.postMessage(propKey, id, JSON.stringify(args)); }); } } else { return target.postMessage(JSON.stringify({ method: propKey, params: args })).then((result) => { if (result && result.compatError) { throw result.compatError; } else { return result; } }); } } }; }, }); // Register callbacks window.NwaHandler.resolve = App.resolve; window.NwaHandler.reject = App.reject; window.NwaHandler.notify = App.notify; window.NwaHandler.emit = App.notify; // Compat, to remove window.NwaHandler.onNotification = App.notify; // Compat, to remove // Bypass native browser functionalities if (isAndroid) { window.print = () => App.print(); navigator.share = (data) => App.share(data); navigator.clipboard.writeText = (data) => App.copy(data); navigator.clipboard.readText = () => App.paste(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore navigator.setAppBadge = (data) => App.setAppBadge(data); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore navigator.clearAppBadge = () => App.clearAppBadge(); navigator.vibrate = (data) => App.vibrate(data); window.open = (url, name) => App.openUrl(url, name); if (!('permissions' in navigator)) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore navigator.permissions = {}; } navigator.permissions.query = App.hasPermission; } else { const positionCallbacks = []; window.print = () => App.print(); window.open = (url, name) => App.openUrl(url, name); navigator.share = (data) => App.share(data); navigator.clipboard.writeText = (data) => App.copy(data); navigator.clipboard.readText = () => App.paste(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore navigator.setAppBadge = (data) => App.setAppBadge(data); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore navigator.clearAppBadge = () => App.clearAppBadge(); navigator.vibrate = (data) => App.vibrate(data); App.on('position', location => { if (positionCallbacks.length) { positionCallbacks.forEach(obj => obj.callback(location)); } else { App.watchPosition(false); } }); navigator.geolocation.watchPosition = (callback, errorCallback, options) => { const watchId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); if (!positionCallbacks.length) { App.watchPosition(true, options).then(callback).catch(errorCallback); } positionCallbacks.push({ id: watchId, callback, }); return watchId; }; navigator.geolocation.clearWatch = (watchId) => { positionCallbacks.filter((cb, i, arr) => { if (cb.id === watchId) { arr.splice(i, 1); return true; } else { return false; } }); if (!positionCallbacks.length) { App.watchPosition(false); } }; navigator.geolocation.getCurrentPosition = (callback, errorCallback, settings) => { return App.getCurrentPosition(settings).then(callback).catch(errorCallback); }; } window.select = function (params) { return App.select(params).then((files) => { const dataTransfer = new DataTransfer(); for (const file of files) { const bytes = atob(file.data); let length = bytes.length; const out = new Uint8Array(length); // Loop and convert. while (length--) { out[length] = bytes.charCodeAt(length); } dataTransfer.items.add(new File([out], file.name, { type: file.type })); } return dataTransfer; }); }; document.addEventListener('DOMContentLoaded', () => { try { const viewport = getMeta('viewport'); const keyboardResize = !!viewport && viewport.includes('interactive-widget=resizes-content'); const appBarOffset = !!viewport && !viewport.includes('viewport-fit=cover'); const navBarOffset = !!viewport && !viewport.includes('viewport-fit=cover'); const backgroundColor = parseInt(getMeta('theme-color').substring(1), 16); const appBarColor = parseInt(getMeta('app-bar-color').substring(1), 16); const navBarColor = parseInt(getMeta('nav-bar-color').substring(1), 16); App.updateAppStyle({ backgroundColor, appBarColor, navBarColor, appBarOffset, navBarOffset, keyboardResize, }); } catch (e) { console.error('Unable to update app style', e); } }, false); App.getDeviceId().then((deviceId) => localStorage.setItem('deviceId', deviceId)); } else { if (isNativeWebApp) { if (!isUpToDate) { console.error('Deprecated NWA version'); } if (!window.NwaHandler) { console.error('NwaHandler not registered'); } } const deviceId = (_a = localStorage.getItem('deviceId')) !== null && _a !== void 0 ? _a : generateDeviceId(); App = { isWeb: true, mobile: false, nwa: false, getDeviceInfos: async () => { const infos = getInfos(); return { id: deviceId, os: 'browser', version: infos.fullVersion, model: infos.browserName, name: infos.browserName, appVersion: null, registrationToken: null, }; }, getDeviceId: async () => deviceId, on: async (event, handler) => { // }, }; } export default App; //# sourceMappingURL=index.js.map