From 649cfcab5807bfab46747619e86c42fbe79c4c19 Mon Sep 17 00:00:00 2001 From: Sven Geusens Date: Tue, 11 Feb 2025 12:45:09 +0100 Subject: [PATCH] Custom Partial variancy support for RTE as it uses a wrapped model (#18290) --- .../BlockValuePropertyValueEditorBase.cs | 14 +++- .../PropertyEditors/RichTextPropertyEditor.cs | 64 +++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Infrastructure/PropertyEditors/BlockValuePropertyValueEditorBase.cs b/src/Umbraco.Infrastructure/PropertyEditors/BlockValuePropertyValueEditorBase.cs index 88bc28acb5..22e9384bf2 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/BlockValuePropertyValueEditorBase.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/BlockValuePropertyValueEditorBase.cs @@ -296,6 +296,18 @@ public abstract class BlockValuePropertyValueEditorBase : DataV BlockEditorData? source = BlockEditorValues.DeserializeAndClean(sourceValue); BlockEditorData? target = BlockEditorValues.DeserializeAndClean(targetValue); + TValue? mergedBlockValue = + MergeVariantInvariantPropertyValueTyped(source, target, canUpdateInvariantData, allowedCultures); + + return _jsonSerializer.Serialize(mergedBlockValue); + } + + internal virtual TValue? MergeVariantInvariantPropertyValueTyped( + BlockEditorData? source, + BlockEditorData? target, + bool canUpdateInvariantData, + HashSet allowedCultures) + { source = UpdateSourceInvariantData(source, target, canUpdateInvariantData); if (source is null && target is null) @@ -328,7 +340,7 @@ public abstract class BlockValuePropertyValueEditorBase : DataV CleanupVariantValues(source.BlockValue.ContentData, target.BlockValue.ContentData, canUpdateInvariantData, allowedCultures); CleanupVariantValues(source.BlockValue.SettingsData, target.BlockValue.SettingsData, canUpdateInvariantData, allowedCultures); - return _jsonSerializer.Serialize(target.BlockValue); + return target.BlockValue; } private void CleanupVariantValues( diff --git a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs index 88a237ca24..92c0a05e94 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs @@ -274,6 +274,70 @@ public class RichTextPropertyEditor : DataEditor return configuration?.Blocks?.SelectMany(ConfiguredElementTypeKeys) ?? Enumerable.Empty(); } + internal override object? MergeVariantInvariantPropertyValue( + object? sourceValue, + object? targetValue, + bool canUpdateInvariantData, + HashSet allowedCultures) + { + TryParseEditorValue(sourceValue, out RichTextEditorValue? sourceRichTextEditorValue); + TryParseEditorValue(targetValue, out RichTextEditorValue? targetRichTextEditorValue); + + var mergedBlockValue = MergeBlockVariantInvariantData( + sourceRichTextEditorValue?.Blocks, + targetRichTextEditorValue?.Blocks, + canUpdateInvariantData, + allowedCultures); + + var mergedMarkupValue = MergeMarkupValue( + sourceRichTextEditorValue?.Markup ?? string.Empty, + targetRichTextEditorValue?.Markup ?? string.Empty, + mergedBlockValue, + canUpdateInvariantData); + + var mergedEditorValue = new RichTextEditorValue { Markup = mergedMarkupValue, Blocks = mergedBlockValue }; + return RichTextPropertyEditorHelper.SerializeRichTextEditorValue(mergedEditorValue, _jsonSerializer); + } + + private string MergeMarkupValue( + string source, + string target, + RichTextBlockValue? mergedBlockValue, + bool canUpdateInvariantData) + { + // pick source or target based on culture permissions + var mergedMarkup = canUpdateInvariantData ? target : source; + + // todo? strip all invalid block links from markup, those tat are no longer in the layout + return mergedMarkup; + } + + private RichTextBlockValue? MergeBlockVariantInvariantData( + RichTextBlockValue? sourceRichTextBlockValue, + RichTextBlockValue? targetRichTextBlockValue, + bool canUpdateInvariantData, + HashSet allowedCultures) + { + if (sourceRichTextBlockValue is null && targetRichTextBlockValue is null) + { + return null; + } + + BlockEditorData sourceBlockEditorData = + (sourceRichTextBlockValue is not null ? ConvertAndClean(sourceRichTextBlockValue) : null) + ?? new BlockEditorData([], new RichTextBlockValue()); + + BlockEditorData targetBlockEditorData = + (targetRichTextBlockValue is not null ? ConvertAndClean(targetRichTextBlockValue) : null) + ?? new BlockEditorData([], new RichTextBlockValue()); + + return MergeVariantInvariantPropertyValueTyped( + sourceBlockEditorData, + targetBlockEditorData, + canUpdateInvariantData, + allowedCultures); + } + internal override object? MergePartialPropertyValueForCulture(object? sourceValue, object? targetValue, string? culture) { if (sourceValue is null || TryParseEditorValue(sourceValue, out RichTextEditorValue? sourceRichTextEditorValue) is false)