From 29987d171ee7567ffceb5c861f7f563e7e4b668c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Dec 2024 10:21:33 +0100 Subject: [PATCH 01/10] remove code duplication --- .../rte/components/rte-base.element.ts | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts index b6e7a4f42aa2..08c049a32ae1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts @@ -10,9 +10,11 @@ import type { import { UmbBlockRteEntriesContext, UmbBlockRteManagerContext, + type UmbBlockRteLayoutModel, type UmbBlockRteTypeModel, } from '@umbraco-cms/backoffice/block-rte'; import { UMB_PROPERTY_CONTEXT, UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; +import type { UmbBlockValueType } from '@umbraco-cms/backoffice/block'; // eslint-disable-next-line local-rules/enforce-element-suffix-on-element-class-name export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement implements UmbPropertyEditorUiElement { @@ -127,23 +129,22 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im // Observe the value of the property and update the editor value. this.observe(this.#managerContext.layouts, (layouts) => { - this._value = { - ...this._value, - blocks: { ...this._value.blocks, layout: { [UMB_BLOCK_RTE_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts } }, - }; - this._fireChangeEvent(); + this.#setBlocksValue({ + ...this._value.blocks, + layout: { [UMB_BLOCK_RTE_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts }, + }); }); + this.observe(this.#managerContext.contents, (contents) => { - this._value = { ...this._value, blocks: { ...this._value.blocks, contentData: contents } }; - this._fireChangeEvent(); + this.#setBlocksValue({ ...this._value.blocks, contentData: contents }); }); + this.observe(this.#managerContext.settings, (settings) => { - this._value = { ...this._value, blocks: { ...this._value.blocks, settingsData: settings } }; - this._fireChangeEvent(); + this.#setBlocksValue({ ...this._value.blocks, settingsData: settings }); }); + this.observe(this.#managerContext.exposes, (exposes) => { - this._value = { ...this._value, blocks: { ...this._value.blocks, expose: exposes } }; - this._fireChangeEvent(); + this.#setBlocksValue({ ...this._value.blocks, expose: exposes }); }); // The above could potentially be replaced with a single observeMultiple call, but it is not done for now to avoid potential issues with the order of the updates. @@ -191,6 +192,15 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im }); } + #setBlocksValue(blocksValue: UmbBlockValueType) { + this._value = { + ...this._value, + blocks: blocksValue, + }; + + this._fireChangeEvent(); + } + protected _fireChangeEvent() { this.dispatchEvent(new UmbPropertyValueChangeEvent()); } From 58c931bf68eca0ec3943a194b962964ee9f7d396 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Dec 2024 10:59:04 +0100 Subject: [PATCH 02/10] remove unused code --- .../rte/components/rte-base.element.ts | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts index 08c049a32ae1..aad8903767cc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts @@ -146,31 +146,8 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im this.observe(this.#managerContext.exposes, (exposes) => { this.#setBlocksValue({ ...this._value.blocks, expose: exposes }); }); - - // The above could potentially be replaced with a single observeMultiple call, but it is not done for now to avoid potential issues with the order of the updates. - /*this.observe( - observeMultiple([ - this.#managerContext.layouts, - this.#managerContext.contents, - this.#managerContext.settings, - this.#managerContext.exposes, - ]).pipe(debounceTime(20)), - ([layouts, contents, settings, exposes]) => { - this._value = { - ...this._value, - blocks: { - layout: { [UMB_BLOCK_RTE_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts }, - contentData: contents, - settingsData: settings, - expose: exposes, - }, - }; - - this._fireChangeEvent(); - }, - 'motherObserver', - );*/ }); + this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (context) => { this.#managerContext.setVariantId(context.getVariantId()); }); From 1e8e368b42e1d459490b682a3c8d49a9e7126d46 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Dec 2024 12:56:52 +0100 Subject: [PATCH 03/10] allow value to be undefined --- .../rte/components/rte-base.element.ts | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts index aad8903767cc..d5040769fdcb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts @@ -71,10 +71,7 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im protected _config?: UmbPropertyEditorConfigCollection; @state() - protected _value: UmbPropertyEditorUiValueType = { - markup: '', - blocks: { layout: {}, contentData: [], settingsData: [], expose: [] }, - }; + protected _value?: UmbPropertyEditorUiValueType | undefined; /** * Separate state for markup, to avoid re-rendering/re-setting the value of the Tiptap editor when the value does not really change. @@ -129,22 +126,26 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im // Observe the value of the property and update the editor value. this.observe(this.#managerContext.layouts, (layouts) => { - this.#setBlocksValue({ - ...this._value.blocks, - layout: { [UMB_BLOCK_RTE_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts }, - }); + const blocksValue = this._value + ? { ...this._value.blocks, layout: { [UMB_BLOCK_RTE_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts } } + : undefined; + + this.#setBlocksValue(blocksValue); }); this.observe(this.#managerContext.contents, (contents) => { - this.#setBlocksValue({ ...this._value.blocks, contentData: contents }); + const blocksValue = this._value ? { ...this._value.blocks, contentData: contents } : undefined; + this.#setBlocksValue(blocksValue); }); this.observe(this.#managerContext.settings, (settings) => { - this.#setBlocksValue({ ...this._value.blocks, settingsData: settings }); + const blocksValue = this._value ? { ...this._value.blocks, settingsData: settings } : undefined; + this.#setBlocksValue(blocksValue); }); this.observe(this.#managerContext.exposes, (exposes) => { - this.#setBlocksValue({ ...this._value.blocks, expose: exposes }); + const blocksValue = this._value ? { ...this._value.blocks, expose: exposes } : undefined; + this.#setBlocksValue(blocksValue); }); }); @@ -169,7 +170,11 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im }); } - #setBlocksValue(blocksValue: UmbBlockValueType) { + #setBlocksValue(blocksValue?: UmbBlockValueType) { + if (!blocksValue || !this._value) { + return; + } + this._value = { ...this._value, blocks: blocksValue, From 4c70aad1c743328c7c5fc4c09315f12aed3dd178 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Dec 2024 12:57:18 +0100 Subject: [PATCH 04/10] dot not build model if we have no markup --- .../tiny-mce/property-editor-ui-tiny-mce.element.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiny-mce/property-editors/tiny-mce/property-editor-ui-tiny-mce.element.ts b/src/Umbraco.Web.UI.Client/src/packages/tiny-mce/property-editors/tiny-mce/property-editor-ui-tiny-mce.element.ts index 6033e78ead78..1ea86ac638c6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiny-mce/property-editors/tiny-mce/property-editor-ui-tiny-mce.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiny-mce/property-editors/tiny-mce/property-editor-ui-tiny-mce.element.ts @@ -12,6 +12,12 @@ export class UmbPropertyEditorUITinyMceElement extends UmbPropertyEditorUiRteEle #onChange(event: CustomEvent & { target: UmbInputTinyMceElement }) { const value = typeof event.target.value === 'string' ? event.target.value : ''; + // If we don't get any markup value we consider the value to be undefined, and don't update the value. + if (value === '') { + this._value = undefined; + this._fireChangeEvent(); + } + // Clone the DOM, to remove the classes and attributes on the original: const div = document.createElement('div'); div.innerHTML = value; From 64adbbe82d71f841e50cc3b57324aaa54b732a89 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Dec 2024 13:22:30 +0100 Subject: [PATCH 05/10] do update the layout value if we don't get any layouts --- .../src/packages/rte/components/rte-base.element.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts index d5040769fdcb..717fd384f73b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts @@ -126,9 +126,10 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im // Observe the value of the property and update the editor value. this.observe(this.#managerContext.layouts, (layouts) => { - const blocksValue = this._value - ? { ...this._value.blocks, layout: { [UMB_BLOCK_RTE_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts } } - : undefined; + const blocksValue = + this._value && layouts?.length > 0 + ? { ...this._value.blocks, layout: { [UMB_BLOCK_RTE_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts } } + : undefined; this.#setBlocksValue(blocksValue); }); From f9ef9237b959143055c95a07b9600493b2b06bbb Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Dec 2024 13:38:40 +0100 Subject: [PATCH 06/10] reset internals if there are no value --- .../src/packages/rte/components/rte-base.element.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts index 717fd384f73b..60f61c75b3fd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts @@ -37,6 +37,16 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im }, }) public set value(value: UmbPropertyEditorUiValueType | undefined) { + if (!value) { + this._value = undefined; + this._markup = ''; + this.#managerContext.setLayouts([]); + this.#managerContext.setContents([]); + this.#managerContext.setSettings([]); + this.#managerContext.setExposes([]); + return; + } + const buildUpValue: Partial = value ? { ...value } : {}; buildUpValue.markup ??= ''; buildUpValue.blocks ??= { layout: {}, contentData: [], settingsData: [], expose: [] }; From 5a19982d28ed26067f3390d4b366dca87909d8e8 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Dec 2024 13:45:23 +0100 Subject: [PATCH 07/10] clear value if tiny mce doesn't have any markup --- .../property-editor-ui-tiny-mce.element.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiny-mce/property-editors/tiny-mce/property-editor-ui-tiny-mce.element.ts b/src/Umbraco.Web.UI.Client/src/packages/tiny-mce/property-editors/tiny-mce/property-editor-ui-tiny-mce.element.ts index 1ea86ac638c6..b10349366ceb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiny-mce/property-editors/tiny-mce/property-editor-ui-tiny-mce.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiny-mce/property-editors/tiny-mce/property-editor-ui-tiny-mce.element.ts @@ -12,10 +12,11 @@ export class UmbPropertyEditorUITinyMceElement extends UmbPropertyEditorUiRteEle #onChange(event: CustomEvent & { target: UmbInputTinyMceElement }) { const value = typeof event.target.value === 'string' ? event.target.value : ''; - // If we don't get any markup value we consider the value to be undefined, and don't update the value. + // If we don't get any markup clear the property editor value. if (value === '') { - this._value = undefined; + this.value = undefined; this._fireChangeEvent(); + return; } // Clone the DOM, to remove the classes and attributes on the original: @@ -44,10 +45,12 @@ export class UmbPropertyEditorUITinyMceElement extends UmbPropertyEditorUiRteEle this._latestMarkup = markup; - this._value = { - ...this._value, - markup: markup, - }; + this._value = this._value + ? { + ...this._value, + markup: markup, + } + : undefined; this._fireChangeEvent(); } From ac26d1698bb951098dd869bf37b137fea7bb6f52 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Dec 2024 13:45:34 +0100 Subject: [PATCH 08/10] clear value if tip tap doesn't have any markup --- .../tiptap/property-editor-ui-tiptap.element.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/property-editor-ui-tiptap.element.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/property-editor-ui-tiptap.element.ts index d0340572ffe3..7c5209479b65 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/property-editor-ui-tiptap.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/property-editor-ui-tiptap.element.ts @@ -14,6 +14,13 @@ export class UmbPropertyEditorUiTiptapElement extends UmbPropertyEditorUiRteElem #onChange(event: CustomEvent & { target: UmbInputTiptapElement }) { const value = event.target.value; + // If we don't get any markup clear the property editor value. + if (value === '') { + this.value = undefined; + this._fireChangeEvent(); + return; + } + // Remove unused Blocks of Blocks Layout. Leaving only the Blocks that are present in Markup. const usedContentKeys: string[] = []; @@ -32,10 +39,12 @@ export class UmbPropertyEditorUiTiptapElement extends UmbPropertyEditorUiRteElem this._latestMarkup = value; - this._value = { - ...this._value, - markup: this._latestMarkup, - }; + this._value = this._value + ? { + ...this._value, + markup: this._latestMarkup, + } + : undefined; this._fireChangeEvent(); } From b8defc3251557f9407b9e37377803fc0ae777699 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Dec 2024 13:54:59 +0100 Subject: [PATCH 09/10] add method to check if tip tap element is empty --- .../components/input-tiptap/input-tiptap.element.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/input-tiptap.element.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/input-tiptap.element.ts index 130d8aee6f07..4743f758d166 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/input-tiptap.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/input-tiptap.element.ts @@ -67,6 +67,14 @@ export class UmbInputTiptapElement extends UmbFormControlMixin((resolve) => { this.observe(umbExtensionsRegistry.byType('tiptapExtension'), async (manifests) => { From 2dac90d9ccffef2b36b79b3d00eac4b7beb2abcf Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 2 Dec 2024 13:55:15 +0100 Subject: [PATCH 10/10] use method to check for empty tip tap --- .../tiptap/property-editor-ui-tiptap.element.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/property-editor-ui-tiptap.element.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/property-editor-ui-tiptap.element.ts index 7c5209479b65..5cd865f02ce6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/property-editor-ui-tiptap.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/property-editor-ui-tiptap.element.ts @@ -12,10 +12,11 @@ const elementName = 'umb-property-editor-ui-tiptap'; @customElement(elementName) export class UmbPropertyEditorUiTiptapElement extends UmbPropertyEditorUiRteElementBase { #onChange(event: CustomEvent & { target: UmbInputTiptapElement }) { - const value = event.target.value; + const tipTapElement = event.target; + const value = tipTapElement.value; // If we don't get any markup clear the property editor value. - if (value === '') { + if (tipTapElement.isEmpty()) { this.value = undefined; this._fireChangeEvent(); return;