diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/tinymce-plugin.model.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/tinymce-plugin.model.ts index ed61bc87c0..c386dccbb7 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/tinymce-plugin.model.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/tinymce-plugin.model.ts @@ -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 { type: 'tinyMcePlugin'; - meta: MetaTinyMcePlugin; -} - -export interface MetaTinyMcePlugin { - exportName: string; - js: string; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-tiny-mce/input-tiny-mce.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-tiny-mce/input-tiny-mce.element.ts index 08e2df3737..bb4fe275b9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-tiny-mce/input-tiny-mce.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-tiny-mce/input-tiny-mce.element.ts @@ -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>(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', '', () => diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/manifests.ts index d90308ec74..a8e29b0667 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/manifests.ts @@ -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 = [ - { + { 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]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-code-editor.plugin.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-code-editor.plugin.ts index e5f635d702..1ab79172b0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-code-editor.plugin.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-code-editor.plugin.ts @@ -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; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-embeddedmedia.plugin.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-embeddedmedia.plugin.ts index 212e27b982..83121bec4f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-embeddedmedia.plugin.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-embeddedmedia.plugin.ts @@ -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; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-linkpicker.plugin.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-linkpicker.plugin.ts index 1198c04afe..5d1a4a846b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-linkpicker.plugin.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-linkpicker.plugin.ts @@ -19,7 +19,7 @@ export interface LinkListItem { menu?: unknown; } -export class TinyMceLinkPickerPlugin extends TinyMcePluginBase { +export default class TinyMceLinkPickerPlugin extends TinyMcePluginBase { #modalContext?: UmbModalContext; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-macropicker.plugin.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-macropicker.plugin.ts index 6d2b2f50ba..1483daccc8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-macropicker.plugin.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-macropicker.plugin.ts @@ -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; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-mediapicker.plugin.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-mediapicker.plugin.ts index e1354f1985..c834424fee 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-mediapicker.plugin.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/plugins/tiny-mce-mediapicker.plugin.ts @@ -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;