V16: Removes TinyMCE (server-side) (#18913)

* Create new migration

* Migrate UI to tiptap

* remember to overwrite toolbar

* Add setting to disable migration

* Add default extensions when migrating

* Remove places where editorUI alias is used

* Remove more tinyMCE stuff

* Make sure that blocks also works

* Reverted files from bad merge

* bring back value converters

* Class name casing

---------

Co-authored-by: leekelleher <leekelleher@gmail.com>
This commit is contained in:
Nikolaj Geisle
2025-04-09 11:00:59 +01:00
committed by GitHub
parent 3bd66b89e1
commit 10e56a52f3
13 changed files with 15 additions and 134 deletions

View File

@@ -170,12 +170,6 @@ public static partial class Constants
/// </summary>
public const string RichText = "Umbraco.RichText";
/// <summary>
/// TinyMCE
/// </summary>
[Obsolete("Please use RichText constant instead, scheduled for removal in v16")]
public const string TinyMce = "Umbraco.TinyMCE";
/// <summary>
/// Boolean.
/// </summary>

View File

@@ -23,9 +23,4 @@ public class RichTextBlockValue : BlockValue<RichTextBlockLayoutItem>
/// <inheritdoc />
[JsonIgnore]
public override string PropertyEditorAlias => Constants.PropertyEditors.Aliases.RichText;
// RTE block layouts uses "Umbraco.TinyMCE" in V14 and below, but should use "Umbraco.RichText" for V15+
[Obsolete("Will be removed in V18.")]
public override bool SupportsBlockLayoutAlias(string alias)
=> base.SupportsBlockLayoutAlias(alias) || alias.Equals(Constants.PropertyEditors.Aliases.TinyMce);
}

View File

@@ -7,7 +7,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters;
/// Value converter for the RTE so that it always returns IHtmlString so that Html.Raw doesn't have to be used.
/// </summary>
[DefaultPropertyValueConverter]
public class SimpleTinyMceValueConverter : PropertyValueConverterBase
public class SimpleRichTextValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(IPublishedPropertyType propertyType)
=> propertyType.EditorAlias == Constants.PropertyEditors.Aliases.RichText;

View File

@@ -164,7 +164,7 @@ public static partial class UmbracoBuilderExtensions
// discovered when CoreBootManager configures the converters. We will remove the basic one defined
// in core so that the more enhanced version is active.
builder.PropertyValueConverters()
.Remove<SimpleTinyMceValueConverter>();
.Remove<SimpleRichTextValueConverter>();
// register *all* checks, except those marked [HideFromTypeFinder] of course
builder.Services.AddSingleton<IMarkdownToHtmlConverter, MarkdownToHtmlConverter>();

View File

@@ -68,7 +68,7 @@ public class AddEditorUiToDataType : MigrationBase
Constants.PropertyEditors.Aliases.TextBox => "Umb.PropertyEditorUi.TextBox",
Constants.PropertyEditors.Aliases.TextArea => "Umb.PropertyEditorUi.TextArea",
Constants.PropertyEditors.Aliases.RichText => "Umb.PropertyEditorUi.TinyMCE",
Constants.PropertyEditors.Aliases.TinyMce => "Umb.PropertyEditorUi.TinyMCE",
"Umbraco.TinyMCE" => "Umb.PropertyEditorUi.TinyMCE",
Constants.PropertyEditors.Aliases.Boolean => "Umb.PropertyEditorUi.Toggle",
Constants.PropertyEditors.Aliases.MarkdownEditor => "Umb.PropertyEditorUi.MarkdownEditor",
Constants.PropertyEditors.Aliases.UserPicker => "Umb.PropertyEditorUi.UserPicker",

View File

@@ -102,7 +102,7 @@ public class MigrateDataTypeConfigurations : MigrationBase
PropertyEditorAliases.RichText => HandleRichText(ref configurationData),
PropertyEditorAliases.TextBox => HandleTextBoxAndTextArea(ref configurationData),
PropertyEditorAliases.TextArea => HandleTextBoxAndTextArea(ref configurationData),
PropertyEditorAliases.TinyMce => HandleRichText(ref configurationData),
"Umbraco.TinyMCE" => HandleRichText(ref configurationData),
PropertyEditorAliases.UploadField => HandleUploadField(ref configurationData),
_ => false
};

View File

@@ -31,7 +31,7 @@ public partial class ConvertRichTextEditorProperties : ConvertBlockEditorPropert
}
protected override IEnumerable<string> PropertyEditorAliases
=> new[] { Constants.PropertyEditors.Aliases.TinyMce, Constants.PropertyEditors.Aliases.RichText };
=> new[] { "Umbraco.TinyMCE", Constants.PropertyEditors.Aliases.RichText };
protected override EditorValueHandling DetermineEditorValueHandling(object editorValue)
=> editorValue is RichTextEditorValue richTextEditorValue

View File

@@ -11,7 +11,7 @@ public class LocalLinkRteProcessor : ITypedLocalLinkProcessor
public IEnumerable<string> PropertyEditorAliases =>
[
Constants.PropertyEditors.Aliases.TinyMce, Constants.PropertyEditors.Aliases.RichText
"Umbraco.TinyMCE", Constants.PropertyEditors.Aliases.RichText
];
public Func<object?, Func<object?, bool>, Func<string, string>, bool> Process => ProcessRichText;

View File

@@ -26,7 +26,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters;
/// used dynamically.
/// </summary>
[DefaultPropertyValueConverter]
public class RteBlockRenderingValueConverter : SimpleTinyMceValueConverter, IDeliveryApiPropertyValueConverter
public class RteBlockRenderingValueConverter : SimpleRichTextValueConverter, IDeliveryApiPropertyValueConverter
{
private readonly HtmlImageSourceParser _imageSourceParser;
private readonly HtmlLocalLinkParser _linkParser;

View File

@@ -277,114 +277,6 @@ internal sealed class BlockEditorBackwardsCompatibilityTests : UmbracoIntegratio
});
}
[TestCase]
public async Task RichTextIsBackwardsCompatible()
{
var elementType = await CreateElementType();
var richTextDataType = await CreateRichTextDataType(elementType);
var contentType = await CreateContentType(richTextDataType);
var json = $$"""
{
"markup": "<p>huh?</p>",
"blocks": {
"layout": {
"{{Constants.PropertyEditors.Aliases.TinyMce}}": [
{
"contentUdi": "umb://element/1304e1ddac87439684fe8a399231cb3d",
"settingsUdi": "umb://element/1f613e26ce274898908a561437af5100"
},
{
"contentUdi": "umb://element/0a4a416e547d464fabcc6f345c17809a",
"settingsUdi": "umb://element/63027539b0db45e7b70459762d4e83dd"
}
]
},
"contentData": [
{
"contentTypeKey": "{{elementType.Key}}",
"udi": "umb://element/1304e1ddac87439684fe8a399231cb3d",
"title": "Content Title One",
"text": "Content Text One"
},
{
"contentTypeKey": "{{elementType.Key}}",
"udi": "umb://element/0a4a416e547d464fabcc6f345c17809a",
"title": "Content Title Two",
"text": "Content Text Two"
}
],
"settingsData": [
{
"contentTypeKey": "{{elementType.Key}}",
"udi": "umb://element/1f613e26ce274898908a561437af5100",
"title": "Settings Title One",
"text": "Settings Text One"
},
{
"contentTypeKey": "{{elementType.Key}}",
"udi": "umb://element/63027539b0db45e7b70459762d4e83dd",
"title": "Settings Title Two",
"text": "Settings Text Two"
}
]
}
}
""";
var contentBuilder = new ContentBuilder()
.WithContentType(contentType)
.WithName("Home");
var content = contentBuilder.Build();
content.Properties["blocks"]!.SetValue(json);
ContentService.Save(content);
var toEditor = richTextDataType.Editor!.GetValueEditor().ToEditor(content.Properties["blocks"]!) as RichTextEditorValue;
Assert.IsNotNull(toEditor);
Assert.IsNotNull(toEditor.Blocks);
Assert.Multiple(() =>
{
Assert.AreEqual(2, toEditor.Blocks.ContentData.Count);
Assert.AreEqual("1304e1ddac87439684fe8a399231cb3d", toEditor.Blocks.ContentData[0].Key.ToString("N"));
Assert.AreEqual("0a4a416e547d464fabcc6f345c17809a", toEditor.Blocks.ContentData[1].Key.ToString("N"));
AssertValueEquals(toEditor.Blocks.ContentData[0], "title", "Content Title One");
AssertValueEquals(toEditor.Blocks.ContentData[0], "text", "Content Text One");
AssertValueEquals(toEditor.Blocks.ContentData[1], "title", "Content Title Two");
AssertValueEquals(toEditor.Blocks.ContentData[1], "text", "Content Text Two");
Assert.IsFalse(toEditor.Blocks.ContentData[0].RawPropertyValues.Any());
Assert.IsFalse(toEditor.Blocks.ContentData[1].RawPropertyValues.Any());
});
Assert.Multiple(() =>
{
Assert.AreEqual(2, toEditor.Blocks.SettingsData.Count);
Assert.AreEqual("1f613e26ce274898908a561437af5100", toEditor.Blocks.SettingsData[0].Key.ToString("N"));
Assert.AreEqual("63027539b0db45e7b70459762d4e83dd", toEditor.Blocks.SettingsData[1].Key.ToString("N"));
AssertValueEquals(toEditor.Blocks.SettingsData[0], "title", "Settings Title One");
AssertValueEquals(toEditor.Blocks.SettingsData[0], "text", "Settings Text One");
AssertValueEquals(toEditor.Blocks.SettingsData[1], "title", "Settings Title Two");
AssertValueEquals(toEditor.Blocks.SettingsData[1], "text", "Settings Text Two");
Assert.IsFalse(toEditor.Blocks.SettingsData[0].RawPropertyValues.Any());
Assert.IsFalse(toEditor.Blocks.SettingsData[1].RawPropertyValues.Any());
});
Assert.Multiple(() =>
{
Assert.AreEqual(2, toEditor.Blocks.Expose.Count);
Assert.AreEqual("1304e1ddac87439684fe8a399231cb3d", toEditor.Blocks.Expose[0].ContentKey.ToString("N"));
Assert.AreEqual("0a4a416e547d464fabcc6f345c17809a", toEditor.Blocks.Expose[1].ContentKey.ToString("N"));
});
}
private static void AssertValueEquals(BlockItemData blockItemData, string propertyAlias, string expectedValue)
{
var blockPropertyValue = blockItemData.Values.FirstOrDefault(v => v.Alias == propertyAlias);

View File

@@ -1,4 +1,4 @@
using NUnit.Framework;
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Blocks;
@@ -50,7 +50,7 @@ internal sealed class PropertyIndexValueFactoryTests : UmbracoIntegrationTest
Blocks = JsonSerializer.Deserialize<RichTextBlockValue>($$"""
{
"layout": {
"Umbraco.TinyMCE": [{
"Umbraco.RichText": [{
"contentKey": "{{elementId:D}}"
}
]

View File

@@ -98,7 +98,7 @@ internal sealed class RichTextPropertyEditorTests : UmbracoIntegrationTest
Blocks = JsonSerializer.Deserialize<RichTextBlockValue>($$"""
{
"layout": {
"Umbraco.TinyMCE": [{
"{{Constants.PropertyEditors.Aliases.RichText}}": [{
"contentKey": "{{elementId:D}}"
}
]
@@ -151,7 +151,7 @@ internal sealed class RichTextPropertyEditorTests : UmbracoIntegrationTest
Blocks = JsonSerializer.Deserialize<RichTextBlockValue>($$"""
{
"layout": {
"Umbraco.TinyMCE": [{
"{{Constants.PropertyEditors.Aliases.RichText}}": [{
"contentKey": "{{elementId:D}}"
}
]

View File

@@ -30,7 +30,7 @@ public class RichTextPropertyEditorHelperTests
"markup": "<p>this is some markup</p><umb-rte-block data-content-key=\"36cc710a-d8a6-45d0-a07f-7bbd8742cf02\"><!--Umbraco-Block--></umb-rte-block>",
"blocks": {
"layout": {
"Umbraco.TinyMCE": [{
"Umbraco.RichText": [{
"contentKey": "36cc710a-d8a6-45d0-a07f-7bbd8742cf02",
"settingsKey": "d2eeef66-4111-42f4-a164-7a523eaffbc2"
}
@@ -118,7 +118,7 @@ public class RichTextPropertyEditorHelperTests
"markup": "<p>this is some markup</p><umb-rte-block data-content-key=\"36cc710a-d8a6-45d0-a07f-7bbd8742cf02\"><!--Umbraco-Block--></umb-rte-block>",
"blocks": {
"layout": {
"Umbraco.TinyMCE": [{
"Umbraco.RichText": [{
"contentKey": "36cc710a-d8a6-45d0-a07f-7bbd8742cf02",
"settingsKey": "d2eeef66-4111-42f4-a164-7a523eaffbc2"
}
@@ -190,7 +190,7 @@ public class RichTextPropertyEditorHelperTests
"markup": "<p>this is some markup</p><umb-rte-block data-content-key=\"36cc710a-d8a6-45d0-a07f-7bbd8742cf02\"></umb-rte-block>",
"blocks": {
"layout": {
"Umbraco.TinyMCE": [{
"Umbraco.RichText": [{
"contentKey": "36cc710a-d8a6-45d0-a07f-7bbd8742cf02"
}
]
@@ -241,7 +241,7 @@ public class RichTextPropertyEditorHelperTests
"markup": "<p>this is <umb-rte-block-inline data-content-key=\"36cc710a-d8a6-45d0-a07f-7bbd8742cf03\"></umb-rte-block-inline> some markup</p><umb-rte-block data-content-key=\"36cc710a-d8a6-45d0-a07f-7bbd8742cf02\"></umb-rte-block>",
"blocks": {
"layout": {
"Umbraco.TinyMCE": [{
"Umbraco.RichText": [{
"contentKey": "36cc710a-d8a6-45d0-a07f-7bbd8742cf02"
}, {
"contentKey": "36cc710a-d8a6-45d0-a07f-7bbd8742cf03"