Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/d…
Browse files Browse the repository at this point in the history
…ev-19130-upgrade-plate-to-v42
  • Loading branch information
e1himself committed Jan 15, 2025
2 parents 42ff650 + 8516fff commit a1f16bd
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 171 deletions.
8 changes: 1 addition & 7 deletions packages/slate-commons/src/types/Extension.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Element, Node } from 'slate';
import type { Node } from 'slate';

import type { DecorateFactory } from './DecorateFactory';
import type { DeserializeHtml } from './DeserializeHtml';
Expand All @@ -12,12 +12,6 @@ export interface Extension {
id: string;
decorate?: DecorateFactory;
deserialize?: DeserializeHtml;
/**
* Compare two elements.
* `children` arrays can be omitted from the comparison,
* as the outer code will compare them anyway.
*/
isElementEqual?: (node: Element, another: Element) => boolean | undefined;
isInline?: (node: Node) => boolean;
isRichBlock?: (node: Node) => boolean;
isVoid?: (node: Node) => boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,18 @@ export const EXTENSION_ID = 'CoverageExtension';

export interface Parameters extends CoverageExtensionConfiguration {}

export const CoverageExtension = ({ dateFormat, fetchCoverage, onEdit, withLayoutOptions }: Parameters): Extension => ({
export const CoverageExtension = ({
dateFormat,
fetchCoverage,
onEdit,
withLayoutOptions,
}: Parameters): Extension => ({
id: EXTENSION_ID,
deserialize: {
element: composeElementDeserializer({
[COVERAGE_NODE_TYPE]: createDeserializeElement(parseSerializedElement),
}),
},
isElementEqual: (node, another) => {
if (isCoverageNode(node) && isCoverageNode(another)) {
return (
node.coverage.id === another.coverage.id &&
node.layout === another.layout &&
node.new_tab === another.new_tab &&
node.show_thumbnail === another.show_thumbnail
);
}
return undefined;
},
isRichBlock: isCoverageNode,
isVoid: isCoverageNode,
normalizeNode: normalizeRedundantCoverageAttributes,
Expand Down
11 changes: 0 additions & 11 deletions packages/slate-editor/src/extensions/embed/EmbedExtension.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { OEmbedInfo } from '@prezly/sdk';
import type { Extension } from '@prezly/slate-commons';
import { createDeserializeElement } from '@prezly/slate-commons';
import { isEqual } from '@technically/lodash';
import React from 'react';
import type { RenderElementProps } from 'slate-react';

Expand Down Expand Up @@ -45,16 +44,6 @@ export const EmbedExtension = ({
[EmbedNode.TYPE]: createDeserializeElement(parseSerializedElement),
}),
},
isElementEqual: (node, another) => {
if (EmbedNode.isEmbedNode(node) && EmbedNode.isEmbedNode(another)) {
return (
node.url === another.url &&
node.layout === another.layout &&
isEqual(node.oembed, another.oembed)
);
}
return undefined;
},
isRichBlock: EmbedNode.isEmbedNode,
isVoid: EmbedNode.isEmbedNode,
normalizeNode: [fixUuidCollisions, normalizeRedundantEmbedAttributes],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Extension } from '@prezly/slate-commons';
import { createDeserializeElement } from '@prezly/slate-commons';
import type { AttachmentNode } from '@prezly/slate-types';
import { ATTACHMENT_NODE_TYPE, isAttachmentNode } from '@prezly/slate-types';
import { isEqual, noop } from '@technically/lodash';
import { noop } from '@technically/lodash';
import type { SlateEditor } from '@udecode/plate-common';
import React from 'react';
import type { RenderElementProps } from 'slate-react';
Expand Down Expand Up @@ -31,13 +31,6 @@ export const FileAttachmentExtension = ({
[ATTACHMENT_NODE_TYPE]: createDeserializeElement(parseSerializedElement),
}),
},
isElementEqual: (node, another) => {
if (isAttachmentNode(node) && isAttachmentNode(another)) {
// Compare ignoring `uuid`
return node.description === another.description && isEqual(node.file, another.file);
}
return undefined;
},
isRichBlock: isAttachmentNode,
isVoid: isAttachmentNode,
normalizeNode: normalizeRedundantFileAttachmentAttributes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { Extension } from '@prezly/slate-commons';
import { createDeserializeElement } from '@prezly/slate-commons';
import type { GalleryLayout, GalleryNode, GalleryPadding } from '@prezly/slate-types';
import { GALLERY_NODE_TYPE, isGalleryNode } from '@prezly/slate-types';
import { isEqual } from '@technically/lodash';
import type { SlateEditor } from '@udecode/plate-common';
import React from 'react';
import type { RenderElementProps } from 'slate-react';
Expand Down Expand Up @@ -62,17 +61,6 @@ export const GalleriesExtension = ({
[GALLERY_NODE_TYPE]: createDeserializeElement(parseSerializedElement),
}),
},
isElementEqual: (node, another) => {
if (isGalleryNode(node) && isGalleryNode(another)) {
return (
node.layout === another.layout &&
node.padding === another.padding &&
node.thumbnail_size === another.thumbnail_size &&
isEqual(node.images, another.images)
);
}
return undefined;
},
isRichBlock: isGalleryNode,
isVoid: isGalleryNode,
normalizeNode: [normalizeInvalidGallery, normalizeRedundantGalleryAttributes],
Expand Down
15 changes: 1 addition & 14 deletions packages/slate-editor/src/extensions/image/ImageExtension.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createDeserializeElement, EditorCommands } from '@prezly/slate-commons'
import type { ImageNode } from '@prezly/slate-types';
import { IMAGE_NODE_TYPE, isImageNode } from '@prezly/slate-types';
import { toProgressPromise, UploadcareImage } from '@prezly/uploadcare';
import { isEqual, noop } from '@technically/lodash';
import { noop } from '@technically/lodash';
import type { SlateEditor } from '@udecode/plate-common';
import { isHotkey } from 'is-hotkey';
import React from 'react';
Expand Down Expand Up @@ -101,19 +101,6 @@ export const ImageExtension = ({
},
}),
},
isElementEqual: (node, another) => {
if (isImageNode(node) && isImageNode(another)) {
return (
node.href === another.href &&
node.layout === another.layout &&
node.align === another.align &&
node.new_tab === another.new_tab &&
node.width === another.width &&
isEqual(node.file, another.file)
);
}
return undefined;
},
isRichBlock: isImageNode,
isVoid: (node) => {
if (isImageNode(node)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Extension } from '@prezly/slate-commons';
import { createDeserializeElement } from '@prezly/slate-commons';
import { CONTACT_NODE_TYPE, isContactNode } from '@prezly/slate-types';
import { isEqual } from '@technically/lodash';
import React from 'react';

import { composeElementDeserializer } from '#modules/html-deserialization';
Expand All @@ -24,17 +23,6 @@ export function InlineContactsExtension(): Extension {
[CONTACT_NODE_TYPE]: createDeserializeElement(parseSerializedElement),
}),
},
isElementEqual(element, another) {
if (isContactNode(element) && isContactNode(another)) {
// If these are contact references, then ContactInfo object is irrelevant
if (element.reference || another.reference) {
return element.reference === another.reference;
}
// Otherwise, compare ContactInfo ignoring node `uuid` and `reference`
return isEqual(element.contact, another.contact);
}
return undefined;
},
isRichBlock: isContactNode,
isVoid: isContactNode,
normalizeNode: [normalizeContactNodeAttributes, normalizeContactInfoAttributes],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,6 @@ export function PlaceholdersExtension({
}: Parameters = {}): Extension {
return {
id: EXTENSION_ID,
isElementEqual(element, another) {
if (isPlaceholderNode(element) && isPlaceholderNode(another)) {
// Consider placeholders equal, if they are of the same type
// ignoring `uuid`
return element.type === another.type;
}
return undefined;
},
isRichBlock: PlaceholderNode.isPlaceholderNode,
isVoid: PlaceholderNode.isPlaceholderNode,
normalizeNode: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Extension } from '@prezly/slate-commons';
import { createDeserializeElement } from '@prezly/slate-commons';
import { CONTACT_NODE_TYPE, isContactNode } from '@prezly/slate-types';
import { isEqual } from '@technically/lodash';
import React from 'react';

import { composeElementDeserializer } from '#modules/html-deserialization';
Expand All @@ -23,21 +22,6 @@ export const PressContactsExtension = (params: PressContactsExtensionParameters)
[CONTACT_NODE_TYPE]: createDeserializeElement(parseSerializedElement),
}),
},
isElementEqual(element, another) {
if (isContactNode(element) && isContactNode(another)) {
if (element.layout !== another.layout || element.show_avatar !== another.show_avatar) {
return false;
}

// If these are contact references, then ContactInfo object is irrelevant
if (element.reference || another.reference) {
return element.reference === another.reference;
}
// Otherwise, compare ContactInfo ignoring node `uuid` and `reference`
return isEqual(element.contact, another.contact);
}
return undefined;
},
isRichBlock: isContactNode,
isVoid: isContactNode,
normalizeNode: [normalizeContactNodeAttributes, normalizeContactInfoAttributes],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,6 @@ export const StoryBookmarkExtension = (params: StoryBookmarkExtensionParameters)
[STORY_BOOKMARK_NODE_TYPE]: createDeserializeElement(parseSerializedElement),
}),
},
isElementEqual: (node, another) => {
if (isStoryBookmarkNode(node) && isStoryBookmarkNode(another)) {
return (
node.story.uuid === another.story.uuid &&
node.show_thumbnail === another.show_thumbnail &&
node.new_tab === another.new_tab &&
node.layout === another.layout
);
}
return undefined;
},
isRichBlock: isStoryBookmarkNode,
isVoid: isStoryBookmarkNode,
normalizeNode: normalizeRedundantStoryBookmarkAttributes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,6 @@ export const StoryEmbedExtension = ({ render }: StoryEmbedExtensionParameters):
[STORY_EMBED_NODE_TYPE]: createDeserializeElement(parseSerializedElement),
}),
},
isElementEqual: (node, another) => {
if (isStoryEmbedNode(node) && isStoryEmbedNode(another)) {
return (
node.story.uuid === another.story.uuid &&
node.appearance === another.appearance &&
node.position === another.position &&
node.header_footer === another.header_footer
);
}
return undefined;
},
isRichBlock: isStoryEmbedNode,
isVoid: isStoryEmbedNode,
normalizeNode: normalizeRedundantStoryEmbedAttributes,
Expand Down
11 changes: 0 additions & 11 deletions packages/slate-editor/src/extensions/video/VideoExtension.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { OEmbedInfo } from '@prezly/sdk';
import type { Extension } from '@prezly/slate-commons';
import { createDeserializeElement } from '@prezly/slate-commons';
import { VideoNode } from '@prezly/slate-types';
import { isEqual } from '@technically/lodash';
import React from 'react';

import type { InfoText } from '#components';
Expand Down Expand Up @@ -37,16 +36,6 @@ export function VideoExtension({
[VideoNode.TYPE]: createDeserializeElement(parseSerializedElement),
}),
},
isElementEqual: (node, another) => {
if (VideoNode.isVideoNode(node) && VideoNode.isVideoNode(another)) {
return (
node.url === another.url &&
node.layout === another.layout &&
isEqual(node.oembed, another.oembed)
);
}
return undefined;
},
isRichBlock: VideoNode.isVideoNode,
isVoid: VideoNode.isVideoNode,
normalizeNode: normalizeRedundantVideoAttributes,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Extension } from '@prezly/slate-commons';
import { createDeserializeElement } from '@prezly/slate-commons';
import { BookmarkNode } from '@prezly/slate-types';
import { isEqual } from '@technically/lodash';
import React from 'react';
import type { RenderElementProps } from 'slate-react';

Expand All @@ -28,19 +27,6 @@ export const WebBookmarkExtension = ({
[BookmarkNode.TYPE]: createDeserializeElement(parseSerializedElement),
}),
},
isElementEqual: (node, another) => {
if (BookmarkNode.isBookmarkNode(node) && BookmarkNode.isBookmarkNode(another)) {
// Compare ignoring `uuid` and `children`
return (
node.url === another.url &&
node.show_thumbnail === another.show_thumbnail &&
node.layout === another.layout &&
node.new_tab === another.new_tab &&
isEqual(node.oembed, another.oembed)
);
}
return undefined;
},
isRichBlock: BookmarkNode.isBookmarkNode,
isVoid: BookmarkNode.isBookmarkNode,
normalizeNode: [unsetUnknownAttributes, normalizeUrlAttribute, fixUuidCollisions],
Expand Down
2 changes: 1 addition & 1 deletion packages/slate-editor/src/modules/editor/createEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export function createEditor(
withUserFriendlyDeleteBehavior,
withDeserializeHtml(getExtensions),
withRichBlocks(getExtensions),
withElementsEqualityCheck(getExtensions),
withElementsEqualityCheck,
...overrides,
])(baseEditor);
}
21 changes: 13 additions & 8 deletions packages/slate-editor/src/modules/editor/lib/isEditorValueEqual.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { isEqual } from '@technically/lodash';
import { isVoid, type SlateEditor } from '@udecode/plate-common';
import { type SlateEditor } from '@udecode/plate-common';
import type { Element, Text, Descendant } from 'slate';

import type { ElementsEqualityCheckEditor } from '../plugins';

export function isEditorValueEqual<T extends Descendant>(
editor: SlateEditor,
editor: SlateEditor & ElementsEqualityCheckEditor,
a: T[],
b: T[],
): boolean {
Expand All @@ -18,7 +20,7 @@ export function isEditorValueEqual<T extends Descendant>(
if (!isNodeText && !isAnotherText) {
const equal = editor.isElementEqual(node as Element, another as Element);
if (typeof equal !== 'undefined') {
if (isVoid(editor, node) || isVoid(editor, another)) {
if (editor.isVoid(node) || editor.isVoid(another)) {
// Do not compare void elements children
return equal;
}
Expand Down Expand Up @@ -49,14 +51,17 @@ function isText(node: Descendant): node is Text {
// CACHE

const CACHE: WeakMap<
SlateEditor,
ElementsEqualityCheckEditor,
WeakMap<Descendant, WeakMap<Descendant, boolean>>
> = new WeakMap();

type WeakMatrix = WeakMap<SlateEditor, WeakMap<Descendant, WeakMap<Descendant, boolean>>>;
type WeakMatrix = WeakMap<
ElementsEqualityCheckEditor,
WeakMap<Descendant, WeakMap<Descendant, boolean>>
>;
type NodesComparator = (node: Descendant, another: Descendant) => boolean;

function cached(editor: SlateEditor, fn: NodesComparator): NodesComparator {
function cached(editor: ElementsEqualityCheckEditor, fn: NodesComparator): NodesComparator {
return (node, another) => {
const cached = get(CACHE, editor, node, another) ?? get(CACHE, editor, another, node);

Expand All @@ -75,7 +80,7 @@ function cached(editor: SlateEditor, fn: NodesComparator): NodesComparator {

function get(
matrix: WeakMatrix,
editor: SlateEditor,
editor: ElementsEqualityCheckEditor,
node: Descendant,
another: Descendant,
): boolean | undefined {
Expand All @@ -84,7 +89,7 @@ function get(

function set(
matrix: WeakMatrix,
editor: SlateEditor,
editor: ElementsEqualityCheckEditor,
node: Descendant,
another: Descendant,
value: boolean,
Expand Down
Loading

0 comments on commit a1f16bd

Please sign in to comment.