This replaces our JSON-based richtext diffing with HTML-based richtext diffing for lexical. It uses [this HTML diff library](https://github.com/Arman19941113/html-diff) that I then modified to handle diffing more complex elements like links, uploads and relationships. This makes it way easier to spot changes, replacing the lengthy Lexical JSON with a clean visual diff that shows exactly what's different. ## Before  ## After  
629 lines
16 KiB
TypeScript
629 lines
16 KiB
TypeScript
import type { DefaultTypedEditorState, SerializedBlockNode } from '@payloadcms/richtext-lexical'
|
|
|
|
import { mediaCollectionSlug, textCollectionSlug } from '../../slugs.js'
|
|
|
|
export function generateLexicalData(args: {
|
|
mediaID: number | string
|
|
textID: number | string
|
|
updated: boolean
|
|
}): DefaultTypedEditorState {
|
|
return {
|
|
root: {
|
|
children: [
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: `Fugiat esse${args.updated ? ' new ' : ''}in dolor aleiqua ${args.updated ? 'gillum' : 'cillum'} proident ad cillum excepteur mollit reprehenderit mollit commodo. Pariatur incididunt non exercitation est mollit nisi labore${args.updated ? ' ' : 'delete'}officia cupidatat amet commodo commodo proident occaecat.`,
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'paragraph',
|
|
version: 1,
|
|
textFormat: 0,
|
|
textStyle: '',
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: args.updated ? 1 : 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'Some ',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
{
|
|
detail: 0,
|
|
format: args.updated ? 0 : 1,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'Bold',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: ' and ',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
{
|
|
detail: 0,
|
|
format: 1,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'Italic',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: ' text with ',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'a link',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'link',
|
|
version: 3,
|
|
fields: {
|
|
url: args.updated ? 'https://www.payloadcms.com' : 'https://www.google.com',
|
|
newTab: true,
|
|
linkType: 'custom',
|
|
},
|
|
id: '67d869aa706b36f346ecffd9',
|
|
},
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: ' and ',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'another link',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'link',
|
|
version: 3,
|
|
fields: {
|
|
url: 'https://www.payload.ai',
|
|
newTab: args.updated ? true : false,
|
|
linkType: 'custom',
|
|
},
|
|
id: '67d869aa706b36f346ecffd0',
|
|
},
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: ' text ',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: args.updated ? 'third link updated' : 'third link',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'link',
|
|
version: 3,
|
|
fields: {
|
|
url: 'https://www.payloadcms.com/docs',
|
|
newTab: true,
|
|
linkType: 'custom',
|
|
},
|
|
id: '67d869aa706b36f346ecffd0',
|
|
},
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: '.',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'link with description',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'link',
|
|
version: 3,
|
|
fields: {
|
|
url: 'https://www.payloadcms.com/docs',
|
|
description: args.updated ? 'updated description' : 'description',
|
|
newTab: true,
|
|
linkType: 'custom',
|
|
},
|
|
id: '67d869aa706b36f346ecffd0',
|
|
},
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'text',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'identical link',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'link',
|
|
version: 3,
|
|
fields: {
|
|
url: 'https://www.payloadcms.com/docs2',
|
|
description: 'description',
|
|
newTab: true,
|
|
linkType: 'custom',
|
|
},
|
|
id: '67d869aa706b36f346ecffd0',
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'paragraph',
|
|
version: 1,
|
|
textFormat: 0,
|
|
textStyle: '',
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'One',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'listitem',
|
|
version: 1,
|
|
value: 1,
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: args.updated ? 'Two updated' : 'Two',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'listitem',
|
|
version: 1,
|
|
value: 2,
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'Three',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'listitem',
|
|
version: 1,
|
|
value: 3,
|
|
},
|
|
...(args.updated
|
|
? [
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'Four',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'listitem',
|
|
version: 1,
|
|
value: 4,
|
|
},
|
|
]
|
|
: []),
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'list',
|
|
version: 1,
|
|
listType: 'number',
|
|
start: 1,
|
|
tag: 'ol',
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'One',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'listitem',
|
|
version: 1,
|
|
value: 1,
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'Two',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'listitem',
|
|
version: 1,
|
|
value: 2,
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: args.updated ? 'Three' : 'Three original',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'listitem',
|
|
version: 1,
|
|
value: 3,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'list',
|
|
version: 1,
|
|
listType: 'bullet',
|
|
start: 1,
|
|
tag: 'ul',
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'Checked',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'listitem',
|
|
version: 1,
|
|
checked: true,
|
|
value: 1,
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: 'Unchecked',
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'listitem',
|
|
version: 1,
|
|
checked: args.updated ? false : true,
|
|
value: 2,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'list',
|
|
version: 1,
|
|
listType: 'check',
|
|
start: 1,
|
|
tag: 'ul',
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: `Heading1${args.updated ? ' updated' : ''}`,
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'heading',
|
|
version: 1,
|
|
tag: 'h1',
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: `Heading2${args.updated ? ' updated' : ''}`,
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'heading',
|
|
version: 1,
|
|
tag: 'h2',
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: `Heading3${args.updated ? ' updated' : ''}`,
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'heading',
|
|
version: 1,
|
|
tag: 'h3',
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: `Heading4${args.updated ? ' updated' : ''}`,
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'heading',
|
|
version: 1,
|
|
tag: 'h4',
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: `Heading5${args.updated ? ' updated' : ''}`,
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'heading',
|
|
version: 1,
|
|
tag: 'h5',
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: `Heading6${args.updated ? ' updated' : ''}`,
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'heading',
|
|
version: 1,
|
|
tag: 'h6',
|
|
},
|
|
{
|
|
type: 'upload',
|
|
version: 3,
|
|
format: '',
|
|
id: '67d8693c76b36f346ecffd8',
|
|
relationTo: mediaCollectionSlug,
|
|
value: args.mediaID,
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
detail: 0,
|
|
format: 0,
|
|
mode: 'normal',
|
|
style: '',
|
|
text: `Quote${args.updated ? ' updated' : ''}`,
|
|
type: 'text',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'quote',
|
|
version: 1,
|
|
},
|
|
{
|
|
type: 'relationship',
|
|
version: 2,
|
|
format: '',
|
|
relationTo: textCollectionSlug,
|
|
value: args.textID,
|
|
},
|
|
{
|
|
type: 'block',
|
|
version: 2,
|
|
format: '',
|
|
fields: {
|
|
id: '67d8693c706b36f346ecffd7',
|
|
radios: args.updated ? 'option1' : 'option3',
|
|
someText: `Text1${args.updated ? ' updated' : ''}`,
|
|
blockName: '',
|
|
someTextRequired: 'Text2',
|
|
blockType: 'myBlock',
|
|
},
|
|
} as SerializedBlockNode,
|
|
],
|
|
direction: 'ltr',
|
|
format: '',
|
|
indent: 0,
|
|
type: 'root',
|
|
version: 1,
|
|
},
|
|
}
|
|
}
|