Skip to content

Commit

Permalink
feat(core): add registerPlugin for importing from plugin packages (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
imhoffd committed Jul 23, 2020
1 parent 896470d commit 95475cc
Show file tree
Hide file tree
Showing 23 changed files with 229 additions and 178 deletions.
10 changes: 8 additions & 2 deletions cli/src/tasks/new-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ async function createTSPlugin(
) {
const newPluginPath = join(pluginPath, 'src');

const originalIndex = await readFileAsync(
join(newPluginPath, 'index.ts'),
'utf8',
);
const originalDefinitions = await readFileAsync(
join(newPluginPath, 'definitions.ts'),
'utf8',
Expand All @@ -166,9 +170,11 @@ async function createTSPlugin(
join(newPluginPath, 'web.ts'),
'utf8',
);
let definitions = originalDefinitions.replace(/Echo/g, className);
const index = originalIndex.replace(/MyPlugin/g, className);
const definitions = originalDefinitions.replace(/MyPlugin/g, className);
const web = originalWeb.replace(/MyPlugin/g, className);

await writeFileAsync(join(newPluginPath, `index.ts`), index, 'utf8');
await writeFileAsync(
join(newPluginPath, `definitions.ts`),
definitions,
Expand Down Expand Up @@ -321,7 +327,7 @@ function generatePackageJSON(answers: NewPluginAnswers, cliVersion: string) {
rimraf: '^3.0.0',
rollup: '^2.21.0',
swiftlint: '^1.0.1',
typescript: '~3.8.3',
typescript: '~3.9.7',
},
peerDependencies: {
'@capacitor/core': `^${cliVersion}`,
Expand Down
3 changes: 2 additions & 1 deletion core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ export {

export * from './core-plugin-definitions';
export * from './global';
export * from './plugins';
export * from './web-plugins';
export * from './web/index';
export * from './web';
133 changes: 133 additions & 0 deletions core/src/plugins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { Capacitor, Plugins } from './global';
import { WebPlugin } from './web';

const PLUGIN_REGISTRY = new (class {
protected readonly plugins: {
[plugin: string]: RegisteredPlugin<unknown>;
} = {};

get(name: string): RegisteredPlugin<unknown> | undefined {
return this.plugins[name];
}

getAll(): RegisteredPlugin<unknown>[] {
return Object.values(this.plugins);
}

has(name: string): boolean {
return !!this.get(name);
}

register(plugin: RegisteredPlugin<unknown>): void {
this.plugins[plugin.name] = plugin;
}
})();

/**
* A map of plugin implementations.
*
* Each key should be the lowercased platform name as recognized by Capacitor,
* e.g. 'android', 'ios', and 'web'. Each value must be an instance of a plugin
* implementation for the respective platform.
*/
export type PluginImplementations<T> = {
[platform: string]: T;
};

/**
* Represents a plugin registered with Capacitor.
*/
export class RegisteredPlugin<T> {
constructor(
readonly name: string,
readonly implementations: Readonly<PluginImplementations<T>>,
) {}

/**
* Return the appropriate implementation of this plugin.
*
* Supply a platform to return the implementation for it, otherwise this
* method will return the implementation for the current platform as detected
* by Capacitor.
*
* @param platform Optionally return the implementation of the given
* platform.
*/
getImplementation(platform?: string): T | undefined {
return this.implementations[platform ? platform : Capacitor.platform];
}
}

/**
* Register plugin implementations with Capacitor.
*
* This function will create and register an instance that contains the
* implementations of the plugin.
*
* Each plugin has multiple implementations, one per platform. Each
* implementation must adhere to a common interface to ensure client code
* behaves consistently across each platform.
*
* @param name The unique CamelCase name of this plugin.
* @param implementations The map of plugin implementations.
*/
export const registerPlugin = <T>(
name: string,
implementations: Readonly<PluginImplementations<T>>,
): RegisteredPlugin<T> => {
const plugin = new RegisteredPlugin(name, implementations);
PLUGIN_REGISTRY.register(plugin);

return plugin;
};

/**
* TODO
*
* @deprecated Don't use this.
*/
export const registerWebPlugin = (plugin: WebPlugin) => {
console.warn(
`Capacitor plugin ${plugin.config.name} is using deprecated method 'registerWebPlugin'`,
); // TODO: add link to upgrade guide

if (!PLUGIN_REGISTRY.has(plugin.config.name)) {
const { name, platforms = ['web'] } = plugin.config;
const implementations: PluginImplementations<unknown> = {};

PLUGIN_REGISTRY.register(
new RegisteredPlugin(
name,
platforms.reduce((acc, value) => {
acc[value] = plugin;
return acc;
}, implementations),
),
);

mergeWebPlugin(plugin);
}
};

const shouldMergeWebPlugin = (plugin: WebPlugin) => {
return (
plugin.config.platforms &&
plugin.config.platforms.indexOf(Capacitor.platform) >= 0
);
};

/**
* TODO
*
* @deprecated Don't use this.
*/
export const mergeWebPlugin = (plugin: WebPlugin) => {
if (
Plugins.hasOwnProperty(plugin.config.name) &&
!shouldMergeWebPlugin(plugin)
) {
return;
}

Plugins[plugin.config.name] = plugin;
};
47 changes: 38 additions & 9 deletions core/src/web-plugins.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,55 @@
import { Plugins } from './global';
import { mergeWebPlugins, mergeWebPlugin, WebPlugin } from './web/index';
import { mergeWebPlugin } from './plugins';

import { Accessibility } from './web/accessibility';
import { App } from './web/app';
import { Browser } from './web/browser';
import { Camera } from './web/camera';
import { Clipboard } from './web/clipboard';
import { Device } from './web/device';
import { Filesystem } from './web/filesystem';
import { Geolocation } from './web/geolocation';
import { LocalNotifications } from './web/local-notifications';
import { Modals } from './web/modals';
import { Motion } from './web/motion';
import { Network } from './web/network';
import { Permissions } from './web/permissions';
import { Share } from './web/share';
import { SplashScreen } from './web/splash-screen';
import { Storage } from './web/storage';
import { Toast } from './web/toast';

export * from './web/accessibility';
export * from './web/app';
export * from './web/browser';
export * from './web/camera';
export * from './web/clipboard';
export * from './web/device';
export * from './web/filesystem';
export * from './web/geolocation';
export * from './web/device';
export * from './web/local-notifications';
export * from './web/share';
export * from './web/modals';
export * from './web/motion';
export * from './web/network';
export * from './web/permissions';
export * from './web/share';
export * from './web/splash-screen';
export * from './web/storage';
export * from './web/toast';

mergeWebPlugins(Plugins);

export const registerWebPlugin = (plugin: WebPlugin) => {
mergeWebPlugin(Plugins, plugin);
};
mergeWebPlugin(Accessibility);
mergeWebPlugin(App);
mergeWebPlugin(Browser);
mergeWebPlugin(Camera);
mergeWebPlugin(Clipboard);
mergeWebPlugin(Device);
mergeWebPlugin(Filesystem);
mergeWebPlugin(Geolocation);
mergeWebPlugin(LocalNotifications);
mergeWebPlugin(Modals);
mergeWebPlugin(Motion);
mergeWebPlugin(Network);
mergeWebPlugin(Permissions);
mergeWebPlugin(Share);
mergeWebPlugin(SplashScreen);
mergeWebPlugin(Storage);
mergeWebPlugin(Toast);
5 changes: 1 addition & 4 deletions core/src/web/accessibility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ import {
export class AccessibilityPluginWeb extends WebPlugin
implements AccessibilityPlugin {
constructor() {
super({
name: 'Accessibility',
platforms: ['web'],
});
super({ name: 'Accessibility' });
}

isScreenReaderEnabled(): Promise<ScreenReaderEnabledResult> {
Expand Down
5 changes: 1 addition & 4 deletions core/src/web/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import { AppPlugin, AppLaunchUrl, AppState } from '../core-plugin-definitions';

export class AppPluginWeb extends WebPlugin implements AppPlugin {
constructor() {
super({
name: 'App',
platforms: ['web'],
});
super({ name: 'App' });

if (typeof document !== 'undefined') {
document.addEventListener(
Expand Down
5 changes: 1 addition & 4 deletions core/src/web/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ export class BrowserPluginWeb extends WebPlugin implements BrowserPlugin {
_lastWindow: Window;

constructor() {
super({
name: 'Browser',
platforms: ['web'],
});
super({ name: 'Browser' });
}

async open(options: BrowserOpenOptions): Promise<void> {
Expand Down
5 changes: 1 addition & 4 deletions core/src/web/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ import {

export class CameraPluginWeb extends WebPlugin implements CameraPlugin {
constructor() {
super({
name: 'Camera',
platforms: ['web'],
});
super({ name: 'Camera' });
}

async getPhoto(options: CameraOptions): Promise<CameraPhoto> {
Expand Down
5 changes: 1 addition & 4 deletions core/src/web/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ declare var ClipboardItem: any;

export class ClipboardPluginWeb extends WebPlugin implements ClipboardPlugin {
constructor() {
super({
name: 'Clipboard',
platforms: ['web'],
});
super({ name: 'Clipboard' });
}

async write(options: ClipboardWrite): Promise<void> {
Expand Down
5 changes: 1 addition & 4 deletions core/src/web/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ declare var navigator: any;

export class DevicePluginWeb extends WebPlugin implements DevicePlugin {
constructor() {
super({
name: 'Device',
platforms: ['web'],
});
super({ name: 'Device' });
}

async getInfo(): Promise<DeviceInfo> {
Expand Down
5 changes: 1 addition & 4 deletions core/src/web/filesystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ export class FilesystemPluginWeb extends WebPlugin implements FilesystemPlugin {
static _debug: boolean = true;

constructor() {
super({
name: 'Filesystem',
platforms: ['web'],
});
super({ name: 'Filesystem' });
}

async initDb(): Promise<IDBDatabase> {
Expand Down
5 changes: 1 addition & 4 deletions core/src/web/geolocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ import { extend } from '../util';
export class GeolocationPluginWeb extends WebPlugin
implements GeolocationPlugin {
constructor() {
super({
name: 'Geolocation',
platforms: ['web'],
});
super({ name: 'Geolocation' });
}

getCurrentPosition(
Expand Down
Loading

0 comments on commit 95475cc

Please sign in to comment.