improve plugin loading

This commit is contained in:
Nathan Woulfe
2023-03-28 17:51:39 +10:00
parent b72effb6fc
commit a0cfea8f4d
8 changed files with 36 additions and 54 deletions

View File

@@ -1,11 +1,6 @@
import type { ManifestWithMeta } from "./models";
import { TinyMcePluginBase } from "../../src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-plugin";
import type { ManifestClass } from "./models";
export interface ManifestTinyMcePlugin extends ManifestWithMeta {
export interface ManifestTinyMcePlugin extends ManifestClass<TinyMcePluginBase> {
type: 'tinyMcePlugin';
meta: MetaTinyMcePlugin;
}
export interface MetaTinyMcePlugin {
exportName: string;
js: string;
}

View File

@@ -11,13 +11,11 @@ import {
import { TinyMcePluginArguments, TinyMcePluginBase } from '../../property-editors/uis/tiny-mce/plugins/tiny-mce-plugin';
import { UmbMediaHelper } from '@umbraco-cms/backoffice/utils';
import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal';
import type { UserDetails } from '@umbraco-cms/backoffice/models';
import type { ClassConstructor, UserDetails } from '@umbraco-cms/backoffice/models';
import { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api';
import { hasDefaultExport, loadExtension, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import {
ManifestTinyMcePlugin,
} from 'libs/extensions-registry/tinymce-plugin.model';
import { ManifestTinyMcePlugin } from 'libs/extensions-registry/tinymce-plugin.model';
// TODO => determine optimal method for including tiny. Currently using public assets
// as we need to ship all core plugins to allow implementors to register these. Have not considered
@@ -247,20 +245,21 @@ export class UmbInputTinyMceElement extends FormControlMixin(UmbLitElement) {
this.#setTinyConfig();
}
/**
* Load all custom plugins - need to split loading and instantiating as these
* need the editor instance as a ctor argument. If we load them in the editor
* setup method, the asynchronous nature means the editor is loaded before
* the plugins are ready and so are not associated with the editor.
*/
async #loadPlugins() {
const observable = umbExtensionsRegistry?.extensionsOfType('tinyMcePlugin');
const plugins = (await firstValueFrom(observable)) as ManifestTinyMcePlugin[];
for (const plugin of plugins) {
if (!plugin.meta.exportName || !plugin.meta.js) {
return;
const module = await loadExtension(plugin);
if (hasDefaultExport<ClassConstructor<TinyMcePluginBase>>(module)) {
this.#plugins.push(module.default);
}
const module = await import(/* @vite-ignore */ plugin.meta.js);
if (!module) {
continue;
}
this.#plugins.push(module[plugin.meta.exportName]);
}
}
@@ -414,11 +413,9 @@ export class UmbInputTinyMceElement extends FormControlMixin(UmbLitElement) {
// instantiate plugins - these are already loaded in this.#loadPlugins
// to ensure they are available before setting up the editor.
this.#plugins.forEach((p) => new p({
host: this,
editor,
configuration: this.configuration,
}));
for (const plugin of this.#plugins) {
new plugin({ host: this, editor, configuration: this.configuration });
}
// define keyboard shortcuts
editor.addShortcut('Ctrl+S', '', () =>

View File

@@ -1,48 +1,38 @@
import { ManifestTinyMcePlugin } from 'libs/extensions-registry/tinymce-plugin.model';
const pluginBaseUrl = '/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/';
const pluginManifests: Array<ManifestTinyMcePlugin> = [
{
{
type: 'tinyMcePlugin',
alias: 'Umb.TinyMcePlugin.CodeEditor',
name: 'Code Editor TinyMCE Plugin',
meta: {
exportName: 'TinyMceCodeEditorPlugin',
js: '/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-code-editor.plugin',
},
js: `${pluginBaseUrl}tiny-mce-code-editor.plugin`,
},
{
{
type: 'tinyMcePlugin',
alias: 'Umb.TinyMcePlugin.LinkPicker',
name: 'Link Picker TinyMCE Plugin',
meta: {
exportName: 'TinyMceLinkPickerPlugin',
js: '/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-linkpicker.plugin',
},
js: `${pluginBaseUrl}tiny-mce-linkpicker.plugin`,
},
{
{
type: 'tinyMcePlugin',
alias: 'Umb.TinyMcePlugin.MediaPicker',
name: 'Media Picker TinyMCE Plugin',
meta: {
exportName: 'TinyMceMediaPickerPlugin',
js: '/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-mediapicker.plugin', },
js: `${pluginBaseUrl}tiny-mce-mediapicker.plugin`,
},
{
{
type: 'tinyMcePlugin',
alias: 'Umb.TinyMcePlugin.EmbeddedMedia',
name: 'Embedded Media TinyMCE Plugin',
meta: {
exportName: 'TinyMceEmbeddedMediaPlugin',
js: '/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-embeddedmedia.plugin', },
js: `${pluginBaseUrl}tiny-mce-embeddedmedia.plugin`,
},
{
{
type: 'tinyMcePlugin',
alias: 'Umb.TinyMcePlugin.MacroPicker',
name: 'Macro Picker TinyMCE Plugin',
meta: {
exportName: 'TinyMceMacroPickerPlugin',
js: '/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-macropicker.plugin', },
js: `${pluginBaseUrl}tiny-mce-macropicker.plugin`,
},
];
export const manifests = [...pluginManifests];
export const manifests = [...pluginManifests];

View File

@@ -2,7 +2,7 @@ import { UmbCodeEditorModalData, UmbCodeEditorModalResult, UMB_CODE_EDITOR_MODAL
import { TinyMcePluginArguments, TinyMcePluginBase } from './tiny-mce-plugin';
import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal';
export class TinyMceCodeEditorPlugin extends TinyMcePluginBase {
export default class TinyMceCodeEditorPlugin extends TinyMcePluginBase {
#modalContext?: UmbModalContext;

View File

@@ -3,7 +3,7 @@ import { UmbEmbeddedMediaModalElement as ModalElement } from '../../../../modals
import { TinyMcePluginArguments, TinyMcePluginBase } from './tiny-mce-plugin';
import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal';
export class TinyMceEmbeddedMediaPlugin extends TinyMcePluginBase {
export default class TinyMceEmbeddedMediaPlugin extends TinyMcePluginBase {
#modalContext?: UmbModalContext;

View File

@@ -19,7 +19,7 @@ export interface LinkListItem {
menu?: unknown;
}
export class TinyMceLinkPickerPlugin extends TinyMcePluginBase {
export default class TinyMceLinkPickerPlugin extends TinyMcePluginBase {
#modalContext?: UmbModalContext;

View File

@@ -12,7 +12,7 @@ interface DialogData {
// TODO => This is a quick transplant of the existing macro plugin - needs to be finished, and need to
// determine how to replicate the existing macro service (backend doens')
export class TinyMceMacroPickerPlugin extends TinyMcePluginBase {
export default class TinyMceMacroPickerPlugin extends TinyMcePluginBase {
#macroService = new UmbMacroService();
#modalContext?: UmbModalContext;

View File

@@ -22,7 +22,7 @@ interface MediaPickerResultData {
'data-caption'?: string;
}
export class TinyMceMediaPickerPlugin extends TinyMcePluginBase {
export default class TinyMceMediaPickerPlugin extends TinyMcePluginBase {
#mediaHelper: UmbMediaHelper;
#currentUser?: UserDetails;
#modalContext?: UmbModalContext;