diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/content-name/content-name.component.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/content-name/content-name.component.ts index 460befde95a4..fb4394d7c641 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/content-name/content-name.component.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/content-name/content-name.component.ts @@ -1,4 +1,4 @@ -import type { UfmToken } from '../../plugins/marked-ufm.plugin.js'; +import type { UfmToken } from '../../plugins/types.js'; import { UmbUfmComponentBase } from '../ufm-component-base.js'; import './content-name.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/label-value/label-value.component.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/label-value/label-value.component.ts index bbadd36dc5ee..b52da5dfdbcb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/label-value/label-value.component.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/label-value/label-value.component.ts @@ -1,4 +1,4 @@ -import type { UfmToken } from '../../plugins/marked-ufm.plugin.js'; +import type { UfmToken } from '../../plugins/types.js'; import { UmbUfmComponentBase } from '../ufm-component-base.js'; import './label-value.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.component.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.component.ts index c49258e30f74..7b9f9dff0b6c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.component.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.component.ts @@ -1,4 +1,4 @@ -import type { UfmToken } from '../../plugins/marked-ufm.plugin.js'; +import type { UfmToken } from '../../plugins/types.js'; import { UmbUfmComponentBase } from '../ufm-component-base.js'; import './link.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/localize/localize.component.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/localize/localize.component.ts index 8789e0545588..ead159bf26cd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/localize/localize.component.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/localize/localize.component.ts @@ -1,4 +1,4 @@ -import type { UfmToken } from '../../plugins/marked-ufm.plugin.js'; +import type { UfmToken } from '../../plugins/types.js'; import { UmbUfmComponentBase } from '../ufm-component-base.js'; import './localize.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/manifests.ts index c247af5a31e4..c12b295c801c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestUfmComponent } from '../ufm-component.extension.js'; +import type { ManifestUfmComponent } from '../extensions/ufm-component.extension.js'; export const manifests: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/ufm-component-base.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/ufm-component-base.ts index d344e01aa8dd..80ee96677e66 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/ufm-component-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/ufm-component-base.ts @@ -1,5 +1,5 @@ -import type { UfmToken } from '../plugins/marked-ufm.plugin.js'; -import type { UmbUfmComponentApi } from '../ufm-component.extension.js'; +import type { UfmToken } from '../plugins/types.js'; +import type { UmbUfmComponentApi } from '../extensions/ufm-component.extension.js'; export abstract class UmbUfmComponentBase implements UmbUfmComponentApi { protected getAttributes(text: string): string | null { diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/contexts/ufm.context.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/contexts/ufm.context.ts index 743a17c5d41d..bcf9b845107e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/contexts/ufm.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/contexts/ufm.context.ts @@ -1,19 +1,17 @@ -import { ufm } from '../plugins/marked-ufm.plugin.js'; -import type { UfmPlugin } from '../plugins/marked-ufm.plugin.js'; -import type { ManifestUfmComponent } from '../ufm-component.extension.js'; -import type { ManifestUfmFilter } from '../ufm-filter.extension.js'; -import { DOMPurify, type Config } from '@umbraco-cms/backoffice/external/dompurify'; +import type { ManifestUfmFilter } from '../extensions/ufm-filter.extension.js'; +import { DOMPurify } from '@umbraco-cms/backoffice/external/dompurify'; import { Marked } from '@umbraco-cms/backoffice/external/marked'; import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import { UmbExtensionsApiInitializer } from '@umbraco-cms/backoffice/extension-api'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import type { Config as DOMPurifyConfig } from '@umbraco-cms/backoffice/external/dompurify'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbExtensionApiInitializer } from '@umbraco-cms/backoffice/extension-api'; const UmbDomPurify = DOMPurify(window); -const UmbDomPurifyConfig: Config = { +const UmbDomPurifyConfig: DOMPurifyConfig = { USE_PROFILES: { html: true }, CUSTOM_ELEMENT_HANDLING: { tagNameCheck: /^(?:ufm|umb|uui)-.*$/, @@ -52,23 +50,7 @@ export class UmbUfmContext extends UmbContextBase { constructor(host: UmbControllerHost) { super(host, UMB_UFM_CONTEXT); - new UmbExtensionsApiInitializer(this, umbExtensionsRegistry, 'ufmComponent', [], undefined, (controllers) => { - UmbMarked.use( - ufm( - controllers - .map((controller) => { - const ctrl = controller as unknown as UmbExtensionApiInitializer; - if (!ctrl.manifest || !ctrl.api) return; - return { - alias: ctrl.manifest.meta.alias || ctrl.manifest.alias, - marker: ctrl.manifest.meta.marker, - render: ctrl.api.render, - }; - }) - .filter((x) => x) as Array, - ), - ); - }); + new UmbExtensionsApiInitializer(this, umbExtensionsRegistry, 'markedExtension', [UmbMarked]); new UmbExtensionsApiInitializer(this, umbExtensionsRegistry, 'ufmFilter', [], undefined, (controllers) => { const filters = controllers diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/manifests.ts new file mode 100644 index 000000000000..04000dac8162 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/manifests.ts @@ -0,0 +1,13 @@ +import type { ManifestMarkedExtension } from './marked-extension.extension.js'; + +export const manifests: Array = [ + { + type: 'markedExtension', + alias: 'Umb.MarkedExtension.Ufm', + name: 'UFM Marked Extension', + api: () => import('./ufm-marked-extension.api.js'), + meta: { + alias: 'ufm', + }, + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/marked-extension.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/marked-extension.extension.ts new file mode 100644 index 000000000000..6fc3f4efbdec --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/marked-extension.extension.ts @@ -0,0 +1,25 @@ +import type { ManifestApi, UmbApi } from '@umbraco-cms/backoffice/extension-api'; + +/** @internal */ +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface UmbMarkedExtensionApi extends UmbApi {} + +/** @internal */ +export interface MetaMarkedExtension { + alias: string; +} + +/** + * @internal + * @description The `markedExtension` extension-type is currently for internal use and should be considered experimental. + */ +export interface ManifestMarkedExtension extends ManifestApi { + type: 'markedExtension'; + meta: MetaMarkedExtension; +} + +declare global { + interface UmbExtensionManifestMap { + umbMarkedExtension: ManifestMarkedExtension; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/types.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/types.ts new file mode 100644 index 000000000000..581fc715b591 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/types.ts @@ -0,0 +1,5 @@ +export type * from './marked-extension.extension.js'; +export type * from './ufm-filter.extension.js'; +export type * from './ufm-component.extension.js'; + +export type { UmbUfmMarkedExtensionApi } from './ufm-marked-extension.api.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/ufm-component.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/ufm-component.extension.ts similarity index 90% rename from src/Umbraco.Web.UI.Client/src/packages/ufm/ufm-component.extension.ts rename to src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/ufm-component.extension.ts index 60c5354f92ba..19e47c6e0b59 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/ufm-component.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/ufm-component.extension.ts @@ -1,4 +1,4 @@ -import type { UfmToken } from './plugins/index.js'; +import type { UfmToken } from '../plugins/types.js'; import type { ManifestApi, UmbApi } from '@umbraco-cms/backoffice/extension-api'; export interface UmbUfmComponentApi extends UmbApi { diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/ufm-filter.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/ufm-filter.extension.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/ufm/ufm-filter.extension.ts rename to src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/ufm-filter.extension.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/ufm-marked-extension.api.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/ufm-marked-extension.api.ts new file mode 100644 index 000000000000..58497b7b8869 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/extensions/ufm-marked-extension.api.ts @@ -0,0 +1,35 @@ +import { ufm } from '../plugins/marked-ufm.plugin.js'; +import type { UfmPlugin } from '../plugins/types.js'; +import type { ManifestUfmComponent } from './ufm-component.extension.js'; +import type { UmbMarkedExtensionApi } from './marked-extension.extension.js'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import { UmbExtensionsApiInitializer } from '@umbraco-cms/backoffice/extension-api'; +import type { Marked } from '@umbraco-cms/backoffice/external/marked'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import type { UmbExtensionApiInitializer } from '@umbraco-cms/backoffice/extension-api'; + +export class UmbUfmMarkedExtensionApi implements UmbMarkedExtensionApi { + constructor(host: UmbControllerHost, marked: Marked) { + new UmbExtensionsApiInitializer(host, umbExtensionsRegistry, 'ufmComponent', [], undefined, (controllers) => { + marked.use( + ufm( + controllers + .map((controller) => { + const ctrl = controller as unknown as UmbExtensionApiInitializer; + if (!ctrl.manifest || !ctrl.api) return; + return { + alias: ctrl.manifest.meta.alias || ctrl.manifest.alias, + marker: ctrl.manifest.meta.marker, + render: ctrl.api.render, + }; + }) + .filter((x) => x) as Array, + ), + ); + }); + } + + destroy() {} +} + +export default UmbUfmMarkedExtensionApi; diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/filters/base.filter.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/filters/base.filter.ts index 76433cbe1760..30938f75ca3f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/filters/base.filter.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/filters/base.filter.ts @@ -1,4 +1,4 @@ -import type { UmbUfmFilterApi } from '../ufm-filter.extension.js'; +import type { UmbUfmFilterApi } from '../extensions/ufm-filter.extension.js'; export abstract class UmbUfmFilterBase implements UmbUfmFilterApi { abstract filter(...args: Array): string | undefined | null; diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/filters/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/filters/manifests.ts index eb12e0643c27..265b99358ced 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/filters/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/filters/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestUfmFilter } from '../ufm-filter.extension.js'; +import type { ManifestUfmFilter } from '../extensions/ufm-filter.extension.js'; export const manifests: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/manifests.ts index 4d41e13c08fb..e895fb875701 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/manifests.ts @@ -1,5 +1,11 @@ import { manifest as ufmContext } from './contexts/manifest.js'; +import { manifests as markedExtensions } from './extensions/manifests.js'; import { manifests as ufmComponents } from './components/manifests.js'; import { manifests as ufmFilters } from './filters/manifests.js'; -export const manifests: Array = [ufmContext, ...ufmComponents, ...ufmFilters]; +export const manifests: Array = [ + ufmContext, + ...markedExtensions, + ...ufmComponents, + ...ufmFilters, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/plugins/index.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/plugins/index.ts index 09836813d30a..da53f2d205f8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/plugins/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/plugins/index.ts @@ -1,2 +1 @@ export { ufm } from './marked-ufm.plugin.js'; -export type { UfmPlugin, UfmToken } from './marked-ufm.plugin.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/plugins/marked-ufm.plugin.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/plugins/marked-ufm.plugin.ts index 604b4a4b1ef6..4ea54de41d93 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/plugins/marked-ufm.plugin.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/plugins/marked-ufm.plugin.ts @@ -1,18 +1,7 @@ -import type { MarkedExtension, Tokens } from '@umbraco-cms/backoffice/external/marked'; - -export interface UfmPlugin { - alias: string; - marker?: string; - render?: (token: UfmToken) => string | undefined; -} - -export interface UfmToken extends Tokens.Generic { - prefix: string; - text?: string; -} +import type { UfmPlugin } from './types.js'; +import type { MarkedExtension } from '@umbraco-cms/backoffice/external/marked'; /** - * * @param {Array} plugins - An array of UFM plugins. * @returns {MarkedExtension} A Marked extension object. */ diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/plugins/types.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/plugins/types.ts new file mode 100644 index 000000000000..e4ae549e47d1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/plugins/types.ts @@ -0,0 +1,12 @@ +import type { Tokens } from '@umbraco-cms/backoffice/external/marked'; + +export interface UfmPlugin { + alias: string; + marker?: string; + render?: (token: UfmToken) => string | undefined; +} + +export interface UfmToken extends Tokens.Generic { + prefix: string; + text?: string; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/types.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/types.ts index c95539b10d81..42fac8a8a9e4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/types.ts @@ -1,2 +1,2 @@ -export type * from './ufm-filter.extension.js'; -export type * from './ufm-component.extension.js'; +export type * from './extensions/types.js'; +export type * from './plugins/types.js';