diff --git a/core/src/definitions-internal.ts b/core/src/definitions-internal.ts index e3b56eb8d..e896f665f 100644 --- a/core/src/definitions-internal.ts +++ b/core/src/definitions-internal.ts @@ -4,6 +4,7 @@ import type { PluginResultData, PluginResultError, } from './definitions'; +import { CapacitorPlatformsInstance } from './platforms'; export interface PluginHeaderMethod { readonly name: string; @@ -166,6 +167,7 @@ export interface StoredCallback { export interface WindowCapacitor { Capacitor?: CapacitorInstance; + CapacitorPlatforms: CapacitorPlatformsInstance; Ionic?: { WebView?: { getServerBasePath?: any; diff --git a/core/src/index.ts b/core/src/index.ts index 9620dd446..303012a5c 100644 --- a/core/src/index.ts +++ b/core/src/index.ts @@ -10,6 +10,9 @@ export type { PluginResultError, } from './definitions'; +// Platforms Map +export { CapacitorPlatforms, addPlatform, setPlatform } from './platforms'; + // Global APIs export { Capacitor, registerPlugin } from './global'; diff --git a/core/src/platforms.ts b/core/src/platforms.ts new file mode 100644 index 000000000..408fd1077 --- /dev/null +++ b/core/src/platforms.ts @@ -0,0 +1,61 @@ +import { PluginImplementations } from "./definitions"; +import { PluginHeader } from "./definitions-internal"; + +export interface CapacitorPlatform { + name: string; + getPlatform?(): string; + isPluginAvailable?(pluginName: string): boolean; + getPluginHeader?(pluginName: string): PluginHeader | undefined; + registerPlugin?(pluginName: string, jsImplementations: PluginImplementations): any; + isNativePlatform?(): boolean; +} + +export interface CapacitorPlatformsInstance { + currentPlatform: CapacitorPlatform; + platforms: Map, + addPlatform(name: string, platform: CapacitorPlatform): void; + setPlatform(name: string): void; +} + + +const createCapacitorPlatforms = (win: any): CapacitorPlatformsInstance => { + const defaultPlatformMap = new Map(); + defaultPlatformMap.set('web', {name: 'web'}); + + const capPlatforms: CapacitorPlatformsInstance = win.CapacitorPlatforms || { + currentPlatform: {name: 'web'}, + platforms: defaultPlatformMap, + }; + + const addPlatform = (name: string, platform: CapacitorPlatform) => { + capPlatforms.platforms.set(name, platform); + } + + const setPlatform = (name: string) => { + if (capPlatforms.platforms.has(name)) { + capPlatforms.currentPlatform = capPlatforms.platforms.get(name); + } + } + + capPlatforms.addPlatform = addPlatform; + capPlatforms.setPlatform = setPlatform; + + return capPlatforms +} + +const initPlatforms = (win: any) => (win.CapacitorPlatforms = createCapacitorPlatforms(win)) + +export const CapacitorPlatforms = /*#__PURE__*/ initPlatforms( + (typeof globalThis !== 'undefined' + ? globalThis + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : typeof global !== 'undefined' + ? global + : {}) as any, +); + +export const addPlatform = CapacitorPlatforms.addPlatform; +export const setPlatform = CapacitorPlatforms.setPlatform; diff --git a/core/src/runtime.ts b/core/src/runtime.ts index 2c5ce112a..1e5ea2cbe 100644 --- a/core/src/runtime.ts +++ b/core/src/runtime.ts @@ -5,6 +5,7 @@ import type { WindowCapacitor, } from './definitions-internal'; import { CapacitorException, getPlatformId, ExceptionCode } from './util'; +import type { CapacitorPlatformsInstance } from './platforms'; export interface RegisteredPlugin { readonly name: string; @@ -15,12 +16,15 @@ export interface RegisteredPlugin { export const createCapacitor = (win: WindowCapacitor): CapacitorInstance => { const cap: CapacitorInstance = win.Capacitor || ({} as any); const Plugins = (cap.Plugins = cap.Plugins || ({} as any)); + const capPlatforms: CapacitorPlatformsInstance = win.CapacitorPlatforms; - const getPlatform = () => getPlatformId(win); + const defaultGetPlatform = () => getPlatformId(win); + const getPlatform = capPlatforms.currentPlatform.getPlatform || defaultGetPlatform; - const isNativePlatform = () => getPlatformId(win) !== 'web'; + const defaultIsNativePlatform = () => getPlatformId(win) !== 'web'; + const isNativePlatform = capPlatforms.currentPlatform.isNativePlatform || defaultIsNativePlatform; - const isPluginAvailable = (pluginName: string): boolean => { + const defaultIsPluginAvailable = (pluginName: string): boolean => { const plugin = registeredPlugins.get(pluginName); if (plugin?.platforms.has(getPlatform())) { @@ -35,9 +39,10 @@ export const createCapacitor = (win: WindowCapacitor): CapacitorInstance => { return false; }; + const isPluginAvailable = capPlatforms.currentPlatform.isPluginAvailable || defaultIsPluginAvailable; - const getPluginHeader = (pluginName: string): PluginHeader | undefined => - cap.PluginHeaders?.find(h => h.name === pluginName); + const defaultGetPluginHeader = (pluginName: string): PluginHeader | undefined => cap.PluginHeaders?.find(h => h.name === pluginName); + const getPluginHeader = capPlatforms.currentPlatform.getPluginHeader || defaultGetPluginHeader; const handleError = (err: Error) => win.console.error(err); @@ -53,7 +58,7 @@ export const createCapacitor = (win: WindowCapacitor): CapacitorInstance => { const registeredPlugins = new Map(); - const registerPlugin = ( + const defaultRegisterPlugin = ( pluginName: string, jsImplementations: PluginImplementations = {}, ): any => { @@ -209,6 +214,7 @@ export const createCapacitor = (win: WindowCapacitor): CapacitorInstance => { return proxy; }; + const registerPlugin = capPlatforms.currentPlatform.registerPlugin || defaultRegisterPlugin; // Add in convertFileSrc for web, it will already be available in native context if (!cap.convertFileSrc) {