Tiptap RTE: Codesweep for 16.2 (#19879)

* RTE mock data updates

* TODO comment typo correction

* Corrected typo in class name

This could technically be a breaking-change, but since the class name
conflicted with the exported `UmbTiptapToolbarFontFamilyExtensionApi`,
then no one could use it anyway. ¯\_(ツ)_/¯

* Tiptap extension code tidy-up

Also, makes use of `this.name` instead of hardcoded strings.
This commit is contained in:
Lee Kelleher
2025-08-08 07:40:35 +01:00
committed by GitHub
parent ba8e1ae5dd
commit 5f1ecbae94
9 changed files with 32 additions and 25 deletions

View File

@@ -2,4 +2,4 @@
This example demonstrates how you can append extra validation messages to the Validation Context based on the value of a Property of a property Editor that this Customization is not interested in overriding/replacing.
See this having an effect on the All RTEs page, where too long words are invalid.
See this having an effect on the "Rich Text Editor" page, where too long words are invalid.

View File

@@ -33,19 +33,12 @@ export const Anchor = Node.create({
addOptions() {
return {
HTMLAttributes: {
id: 'id',
},
HTMLAttributes: { id: '' },
};
},
parseHTML() {
return [
{
tag: 'a[id]',
getAttrs: (element) => (element.innerHTML === '' ? {} : false),
},
];
return [{ tag: 'a[id]', getAttrs: (element) => (element.innerHTML === '' ? {} : false) }];
},
renderHTML({ HTMLAttributes }) {

View File

@@ -27,11 +27,7 @@ export const Figcaption = Node.create<FigcaptionOptions>({
draggable: false,
parseHTML() {
return [
{
tag: 'figcaption',
},
];
return [{ tag: this.name }];
},
renderHTML({ HTMLAttributes }) {

View File

@@ -35,7 +35,7 @@ export const Figure = Node.create<FigureOptions>({
parseHTML() {
return [
{
tag: 'figure',
tag: this.name,
getAttrs: (dom) => {
const figcaption = dom.querySelector('figcaption');
return {

View File

@@ -1746,7 +1746,7 @@ export const data: Array<UmbMockDocumentTypeModel> = [
defaultTemplate: { id: 'all-rtes-document-type-id' },
id: 'all-rtes-document-type-id',
alias: 'allRtesDocumentType',
name: 'All RTEs document type',
name: 'Rich Text Editor document type',
description: null,
icon: 'icon-document',
allowedAsRoot: true,

View File

@@ -77,9 +77,9 @@ export const data: Array<UmbMockDocumentModel> = [
<p>
Some value for the RTE with an <a href="https://google.com">external link</a> and an <a type="document" href="/{localLink:c05da24d-7740-447b-9cdc-bd8ce2172e38}">internal link</a> foo foo
</p>
<div class="umb-macro-holder TestMacro umb-macro-mce_1 mceNonEditable"><!-- <?UMBRACO_MACRO macroAlias="TestMacro" /> --><ins>Macro alias: <strong>TestMacro</strong></ins></div>
<div class="umb-macro-holder TestMacro umb-macro-mce_1"><!-- <?UMBRACO_MACRO macroAlias="TestMacro" /> --><ins>Macro alias: <strong>TestMacro</strong></ins></div>
<p>The following tests the embed plugin:</p>
<div class="mceNonEditable umb-embed-holder" data-embed-height="240" data-embed-width="360" data-embed-constrain="false"><iframe width="360" height="240" src="https://www.youtube.com/embed/QRIWz9SotY4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" title="Sleep Token - The Summoning"></iframe></div>
<div class="umb-embed-holder" data-embed-height="240" data-embed-width="360" data-embed-constrain="false"><iframe width="360" height="240" src="https://www.youtube.com/embed/QRIWz9SotY4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" title="Sleep Token - The Summoning"></iframe></div>
<p>End of test content</p>
`,
},
@@ -939,7 +939,7 @@ export const data: Array<UmbMockDocumentModel> = [
publishDate: '2023-02-06T15:32:24.957009',
culture: 'en-US',
segment: null,
name: 'All RTEs',
name: 'Rich Text Editor',
createDate: '2023-02-06T15:32:05.350038',
updateDate: '2023-02-06T15:32:24.957009',
},
@@ -947,7 +947,7 @@ export const data: Array<UmbMockDocumentModel> = [
values: [
{
alias: 'tiptap',
editorAlias: 'Umb.PropertyEditorUi.Tiptap',
editorAlias: 'Umbraco.RichText',
culture: null,
segment: null,
value: {
@@ -957,7 +957,25 @@ export const data: Array<UmbMockDocumentModel> = [
settingsData: [],
expose: [],
},
markup: `<p><a id="anchor"></a> Here is a link for <a target="_blank" data-router-slot="disabled" href="https://gist.github.com/leekelleher/9490718" type="external">all HTML tags</a>.</p><p><span id="foo">Some</span> value for the RTE with an <a target="" data-router-slot="disabled" href="https://google.com" type="external">external link</a> and an <a target="" data-router-slot="disabled" href="/{localLink:c05da24d-7740-447b-9cdc-bd8ce2172e38}" type="document">internal link</a>.</p><div data-foo-bar="123"><span>This is a plain old span tag.</span> <span style="color: red;">Hello </span><span style="color: blue;">world</span><span style="color: red;">.</span></div><table style="min-width: 50px"><colgroup><col style="min-width: 25px"><col style="min-width: 25px"></colgroup><tbody><tr><th colspan="1" rowspan="1"><p> Version</p></th><th colspan="1" rowspan="1"><p>Date</p></th></tr><tr><td colspan="1" rowspan="1"><p>15.3</p></td><td colspan="1" rowspan="1"><p>2025-03-20</p></td></tr><tr><td colspan="1" rowspan="1"><p>16.0</p></td><td colspan="1" rowspan="1"><p>2025-06-12</p></td></tr><tr><td colspan="1" rowspan="1"><p>17.0</p></td><td colspan="1" rowspan="1"><p>2025-11-27</p></td></tr></tbody></table><p><img src="/umbraco/backoffice/assets/installer-illustration.svg" alt="Installer illustration" width="384" height="228" loading="lazy"></p><p>End of test content</p>`,
markup: `
<p><a id="anchor"></a> Here is a link for <a target="_blank" data-router-slot="disabled" href="https://gist.github.com/leekelleher/9490718" type="external">all HTML tags</a>.</p>
<p>Some value for the RTE with an <a href="https://google.com">external link</a> and an <a type="document" href="/{localLink:c05da24d-7740-447b-9cdc-bd8ce2172e38}">internal link</a> foo foo</p>
<p>The following tests the embed plugin:</p>
<p><div class="umb-embed-holder" data-embed-height="240" data-embed-width="360" data-embed-constrain="false" data-embed-url="https://www.youtube.com/watch?v=QRIWz9SotY4"><iframe width="360" height="240" src="https://www.youtube.com/embed/QRIWz9SotY4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" title="Deep dive into Rich Text Editor"></iframe></div></p>
<p><span id="foo">Some</span> value for the RTE with an <a target="" data-router-slot="disabled" href="https://google.com" type="external">external link</a> and an <a target="" data-router-slot="disabled" href="/{localLink:c05da24d-7740-447b-9cdc-bd8ce2172e38}" type="document">internal link</a>.</p>
<div data-foo-bar="123"><span>This is a plain old span tag.</span> <span style="color: red;">Hello </span><span style="color: blue;">world</span><span style="color: red;">.</span></div>
<table style="min-width: 50px"><colgroup><col style="min-width: 25px"><col style="min-width: 25px"></colgroup><tbody><tr><th colspan="1" rowspan="1"><p> Version</p></th><th colspan="1" rowspan="1"><p>Date</p></th></tr><tr><td colspan="1" rowspan="1"><p>15.3</p></td><td colspan="1" rowspan="1"><p>2025-03-20</p></td></tr><tr><td colspan="1" rowspan="1"><p>16.0</p></td><td colspan="1" rowspan="1"><p>2025-06-12</p></td></tr><tr><td colspan="1" rowspan="1"><p>17.0</p></td><td colspan="1" rowspan="1"><p>2025-11-27</p></td></tr></tbody></table>
<p><img src="/umbraco/backoffice/assets/installer-illustration.svg" alt="Installer illustration" width="384" height="228" loading="lazy"></p>
<div class="umb-macro-holder"><!-- <?UMBRACO_MACRO macroAlias="TestMacro" /> --><ins>Macro alias: <strong>TestMacro</strong></ins></div>
<p>End of test content</p>`,
},
},
],

View File

@@ -11,7 +11,7 @@ export const handlers = [
const height = heightParam ? parseInt(heightParam) : 240;
const response: OEmbedResponseModel = {
markup: `<iframe width="${width}" height="${height}" src="https://www.youtube.com/embed/wJNbtYdr-Hg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="Sleep Token - The Summoning"></iframe>`,
markup: `<iframe width="${width}" height="${height}" src="https://www.youtube.com/embed/QRIWz9SotY4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="Deep dive into Rich Text Editor"></iframe>`,
};
return res(ctx.status(200), ctx.json(response));

View File

@@ -147,7 +147,7 @@ export class UmbBlockRteEntriesContext extends UmbBlockEntriesContext<
await Promise.all(
layoutEntries.map(async (layoutEntry) => {
this._insertBlockFromPropertyValue(layoutEntry, value, originData);
// TODO: Missing some way to insert a Block HTML Element into the RTE at the current cursor point. (hopefully the responsibilit can be avoided here, but there is some connection missing at this point) [NL]
// TODO: Missing some way to insert a Block HTML Element into the RTE at the current cursor point. (hopefully the responsibility can be avoided here, but there is some connection missing at this point) [NL]
}),
);

View File

@@ -2,7 +2,7 @@ import { UmbTiptapToolbarElementApiBase } from '../base.js';
import type { MetaTiptapToolbarMenuItem } from '../types.js';
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
export default class UmbTiptapToolbarFontFamilyExtensionApi extends UmbTiptapToolbarElementApiBase {
export default class UmbTiptapToolbarFontSizeExtensionApi extends UmbTiptapToolbarElementApiBase {
override isActive(editor?: Editor, item?: MetaTiptapToolbarMenuItem) {
const styles = editor?.getAttributes('span')?.style;
return styles?.includes(`font-size: ${item?.data};`) === true;