1
- import type { Extension } from '@prezly/slate-commons' ;
1
+ import {
2
+ BookmarkNode ,
3
+ isAttachmentNode ,
4
+ isContactNode ,
5
+ isCoverageNode ,
6
+ isGalleryNode ,
7
+ isImageNode ,
8
+ isStoryBookmarkNode ,
9
+ isStoryEmbedNode ,
10
+ VideoNode ,
11
+ } from '@prezly/slate-types' ;
12
+ import { isEqual } from '@technically/lodash' ;
2
13
import type { SlateEditor } from '@udecode/plate-common' ;
3
14
import type { Element } from 'slate' ;
4
15
16
+ import { EmbedNode } from '#extensions/embed' ;
17
+ import { PlaceholderNode } from '#extensions/placeholders' ;
18
+
5
19
export interface ElementsEqualityCheckEditor {
6
20
/**
7
21
* Compare two elements.
@@ -15,20 +29,100 @@ export interface ElementsEqualityCheckEditor {
15
29
isElementEqual ( node : Element , another : Element ) : boolean | undefined ;
16
30
}
17
31
18
- export function withElementsEqualityCheck ( getExtensions : ( ) => Extension [ ] ) {
19
- return function < T extends SlateEditor > ( editor : T ) : T & ElementsEqualityCheckEditor {
20
- function isElementEqual ( node : Element , another : Element ) : boolean | undefined {
21
- for ( const extension of getExtensions ( ) ) {
22
- const ret = extension . isElementEqual ?.( node , another ) ;
23
- if ( typeof ret !== 'undefined' ) {
24
- return ret ;
25
- }
26
- }
27
- return undefined ;
32
+ export function withElementsEqualityCheck < T extends SlateEditor > (
33
+ editor : T ,
34
+ ) : T & ElementsEqualityCheckEditor {
35
+ return Object . assign ( editor , {
36
+ isElementEqual,
37
+ } ) ;
38
+ }
39
+
40
+ function isElementEqual ( node : Element , another : Element ) : boolean | undefined {
41
+ if ( isAttachmentNode ( node ) && isAttachmentNode ( another ) ) {
42
+ // Compare ignoring `uuid`
43
+ return node . description === another . description && isEqual ( node . file , another . file ) ;
44
+ }
45
+ if ( BookmarkNode . isBookmarkNode ( node ) && BookmarkNode . isBookmarkNode ( another ) ) {
46
+ // Compare ignoring `uuid` and `children`
47
+ return (
48
+ node . url === another . url &&
49
+ node . show_thumbnail === another . show_thumbnail &&
50
+ node . layout === another . layout &&
51
+ node . new_tab === another . new_tab &&
52
+ isEqual ( node . oembed , another . oembed )
53
+ ) ;
54
+ }
55
+ if ( isContactNode ( node ) && isContactNode ( another ) ) {
56
+ if ( node . layout !== another . layout || node . show_avatar !== another . show_avatar ) {
57
+ return false ;
58
+ }
59
+ // If these are contact references, then ContactInfo object is irrelevant
60
+ if ( node . reference || another . reference ) {
61
+ return node . reference === another . reference ;
28
62
}
63
+ // Otherwise, compare ContactInfo ignoring node `uuid` and `reference`
64
+ return isEqual ( node . contact , another . contact ) ;
65
+ }
66
+ if ( isCoverageNode ( node ) && isCoverageNode ( another ) ) {
67
+ return (
68
+ node . coverage . id === another . coverage . id &&
69
+ node . layout === another . layout &&
70
+ node . new_tab === another . new_tab &&
71
+ node . show_thumbnail === another . show_thumbnail
72
+ ) ;
73
+ }
74
+ if ( EmbedNode . isEmbedNode ( node ) && EmbedNode . isEmbedNode ( another ) ) {
75
+ return (
76
+ node . url === another . url &&
77
+ node . layout === another . layout &&
78
+ isEqual ( node . oembed , another . oembed )
79
+ ) ;
80
+ }
81
+ if ( isGalleryNode ( node ) && isGalleryNode ( another ) ) {
82
+ return (
83
+ node . layout === another . layout &&
84
+ node . padding === another . padding &&
85
+ node . thumbnail_size === another . thumbnail_size &&
86
+ isEqual ( node . images , another . images )
87
+ ) ;
88
+ }
89
+ if ( isImageNode ( node ) && isImageNode ( another ) ) {
90
+ return (
91
+ node . href === another . href &&
92
+ node . layout === another . layout &&
93
+ node . align === another . align &&
94
+ node . new_tab === another . new_tab &&
95
+ node . width === another . width &&
96
+ isEqual ( node . file , another . file )
97
+ ) ;
98
+ }
99
+ if ( PlaceholderNode . isPlaceholderNode ( node ) && PlaceholderNode . isPlaceholderNode ( another ) ) {
100
+ // Consider placeholders equal, if they are of the same type ignoring `uuid`
101
+ return node . type === another . type ;
102
+ }
103
+ if ( isStoryBookmarkNode ( node ) && isStoryBookmarkNode ( another ) ) {
104
+ return (
105
+ node . story . uuid === another . story . uuid &&
106
+ node . show_thumbnail === another . show_thumbnail &&
107
+ node . new_tab === another . new_tab &&
108
+ node . layout === another . layout
109
+ ) ;
110
+ }
111
+ if ( isStoryEmbedNode ( node ) && isStoryEmbedNode ( another ) ) {
112
+ return (
113
+ node . story . uuid === another . story . uuid &&
114
+ node . appearance === another . appearance &&
115
+ node . position === another . position &&
116
+ node . header_footer === another . header_footer
117
+ ) ;
118
+ }
119
+ if ( VideoNode . isVideoNode ( node ) && VideoNode . isVideoNode ( another ) ) {
120
+ return (
121
+ node . url === another . url &&
122
+ node . layout === another . layout &&
123
+ isEqual ( node . oembed , another . oembed )
124
+ ) ;
125
+ }
29
126
30
- return Object . assign ( editor , {
31
- isElementEqual,
32
- } ) ;
33
- } ;
127
+ return undefined ;
34
128
}
0 commit comments