@wordpress/core-data 7.45.0 → 7.45.1-next.v.202605131032.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/actions.cjs +8 -6
- package/build/actions.cjs.map +2 -2
- package/build/awareness/post-editor-awareness.cjs +1 -1
- package/build/awareness/post-editor-awareness.cjs.map +2 -2
- package/build/resolvers.cjs +2 -1
- package/build/resolvers.cjs.map +2 -2
- package/build/types.cjs.map +2 -2
- package/build/utils/block-selection-history.cjs +4 -1
- package/build/utils/block-selection-history.cjs.map +2 -2
- package/build/utils/crdt-blocks.cjs +157 -89
- package/build/utils/crdt-blocks.cjs.map +2 -2
- package/build/utils/crdt-selection.cjs +1 -1
- package/build/utils/crdt-selection.cjs.map +2 -2
- package/build/utils/crdt-user-selections.cjs +4 -1
- package/build/utils/crdt-user-selections.cjs.map +2 -2
- package/build/utils/crdt-utils.cjs +18 -6
- package/build/utils/crdt-utils.cjs.map +2 -2
- package/build/utils/crdt.cjs +12 -2
- package/build/utils/crdt.cjs.map +2 -2
- package/build-module/actions.mjs +8 -6
- package/build-module/actions.mjs.map +2 -2
- package/build-module/awareness/post-editor-awareness.mjs +5 -2
- package/build-module/awareness/post-editor-awareness.mjs.map +2 -2
- package/build-module/resolvers.mjs +2 -1
- package/build-module/resolvers.mjs.map +2 -2
- package/build-module/types.mjs.map +2 -2
- package/build-module/utils/block-selection-history.mjs +5 -1
- package/build-module/utils/block-selection-history.mjs.map +2 -2
- package/build-module/utils/crdt-blocks.mjs +162 -90
- package/build-module/utils/crdt-blocks.mjs.map +2 -2
- package/build-module/utils/crdt-selection.mjs +2 -1
- package/build-module/utils/crdt-selection.mjs.map +2 -2
- package/build-module/utils/crdt-user-selections.mjs +9 -2
- package/build-module/utils/crdt-user-selections.mjs.map +2 -2
- package/build-module/utils/crdt-utils.mjs +16 -6
- package/build-module/utils/crdt-utils.mjs.map +2 -2
- package/build-module/utils/crdt.mjs +13 -2
- package/build-module/utils/crdt.mjs.map +2 -2
- package/build-types/actions.d.ts +177 -64
- package/build-types/actions.d.ts.map +1 -1
- package/build-types/awareness/awareness-state.d.ts.map +1 -1
- package/build-types/awareness/base-awareness.d.ts +0 -3
- package/build-types/awareness/base-awareness.d.ts.map +1 -1
- package/build-types/awareness/post-editor-awareness.d.ts +1 -8
- package/build-types/awareness/post-editor-awareness.d.ts.map +1 -1
- package/build-types/awareness/typed-awareness.d.ts.map +1 -1
- package/build-types/batch/create-batch.d.ts +1 -1
- package/build-types/batch/create-batch.d.ts.map +1 -1
- package/build-types/batch/default-processor.d.ts.map +1 -1
- package/build-types/batch/index.d.ts +2 -2
- package/build-types/batch/index.d.ts.map +1 -1
- package/build-types/entities.d.ts +114 -87
- package/build-types/entities.d.ts.map +1 -1
- package/build-types/entity-context.d.ts +1 -1
- package/build-types/entity-context.d.ts.map +1 -1
- package/build-types/entity-provider.d.ts +2 -2
- package/build-types/entity-provider.d.ts.map +1 -1
- package/build-types/entity-types/attachment.d.ts.map +1 -1
- package/build-types/entity-types/base-entity-records.d.ts.map +1 -1
- package/build-types/entity-types/base.d.ts.map +1 -1
- package/build-types/entity-types/comment.d.ts.map +1 -1
- package/build-types/entity-types/font-collection.d.ts.map +1 -1
- package/build-types/entity-types/font-family.d.ts.map +1 -1
- package/build-types/entity-types/global-styles-revision.d.ts.map +1 -1
- package/build-types/entity-types/icon.d.ts.map +1 -1
- package/build-types/entity-types/menu-location.d.ts.map +1 -1
- package/build-types/entity-types/nav-menu-item.d.ts.map +1 -1
- package/build-types/entity-types/nav-menu.d.ts.map +1 -1
- package/build-types/entity-types/page.d.ts.map +1 -1
- package/build-types/entity-types/plugin.d.ts.map +1 -1
- package/build-types/entity-types/post-revision.d.ts.map +1 -1
- package/build-types/entity-types/post-status.d.ts.map +1 -1
- package/build-types/entity-types/post.d.ts.map +1 -1
- package/build-types/entity-types/settings.d.ts.map +1 -1
- package/build-types/entity-types/sidebar.d.ts.map +1 -1
- package/build-types/entity-types/taxonomy.d.ts.map +1 -1
- package/build-types/entity-types/term.d.ts.map +1 -1
- package/build-types/entity-types/theme.d.ts.map +1 -1
- package/build-types/entity-types/type.d.ts.map +1 -1
- package/build-types/entity-types/user.d.ts.map +1 -1
- package/build-types/entity-types/widget-type.d.ts.map +1 -1
- package/build-types/entity-types/widget.d.ts.map +1 -1
- package/build-types/entity-types/wp-template-part.d.ts.map +1 -1
- package/build-types/entity-types/wp-template.d.ts.map +1 -1
- package/build-types/fetch/__experimental-fetch-url-data.d.ts +2 -5
- package/build-types/fetch/__experimental-fetch-url-data.d.ts.map +1 -1
- package/build-types/fetch/index.d.ts +3 -3
- package/build-types/fetch/index.d.ts.map +1 -1
- package/build-types/footnotes/get-footnotes-order.d.ts.map +1 -1
- package/build-types/footnotes/get-rich-text-values-cached.d.ts.map +1 -1
- package/build-types/footnotes/index.d.ts +1 -1
- package/build-types/footnotes/index.d.ts.map +1 -1
- package/build-types/hooks/use-entity-block-editor.d.ts +1 -1
- package/build-types/hooks/use-entity-block-editor.d.ts.map +1 -1
- package/build-types/hooks/use-entity-id.d.ts.map +1 -1
- package/build-types/hooks/use-entity-prop.d.ts.map +1 -1
- package/build-types/hooks/use-resource-permissions.d.ts.map +1 -1
- package/build-types/index.d.ts +155 -153
- package/build-types/index.d.ts.map +1 -1
- package/build-types/locks/actions.d.ts +1 -1
- package/build-types/locks/actions.d.ts.map +1 -1
- package/build-types/locks/engine.d.ts +1 -1
- package/build-types/locks/engine.d.ts.map +1 -1
- package/build-types/locks/reducer.d.ts.map +1 -1
- package/build-types/locks/selectors.d.ts +2 -2
- package/build-types/locks/selectors.d.ts.map +1 -1
- package/build-types/locks/utils.d.ts +5 -5
- package/build-types/locks/utils.d.ts.map +1 -1
- package/build-types/name.d.ts +1 -1
- package/build-types/name.d.ts.map +1 -1
- package/build-types/private-actions.d.ts +45 -29
- package/build-types/private-actions.d.ts.map +1 -1
- package/build-types/private-apis.d.ts +1 -1
- package/build-types/private-apis.d.ts.map +1 -1
- package/build-types/queried-data/actions.d.ts +3 -3
- package/build-types/queried-data/actions.d.ts.map +1 -1
- package/build-types/queried-data/get-query-parts.d.ts +10 -34
- package/build-types/queried-data/get-query-parts.d.ts.map +1 -1
- package/build-types/queried-data/index.d.ts +3 -3
- package/build-types/queried-data/index.d.ts.map +1 -1
- package/build-types/queried-data/reducer.d.ts +7 -23
- package/build-types/queried-data/reducer.d.ts.map +1 -1
- package/build-types/queried-data/selectors.d.ts +3 -3
- package/build-types/queried-data/selectors.d.ts.map +1 -1
- package/build-types/reducer.d.ts +40 -32
- package/build-types/reducer.d.ts.map +1 -1
- package/build-types/resolvers.d.ts +130 -47
- package/build-types/resolvers.d.ts.map +1 -1
- package/build-types/selectors.d.ts +1 -1
- package/build-types/selectors.d.ts.map +1 -1
- package/build-types/types.d.ts +61 -6
- package/build-types/types.d.ts.map +1 -1
- package/build-types/utils/block-selection-history.d.ts.map +1 -1
- package/build-types/utils/conservative-map-item.d.ts.map +1 -1
- package/build-types/utils/crdt-blocks.d.ts +19 -9
- package/build-types/utils/crdt-blocks.d.ts.map +1 -1
- package/build-types/utils/crdt-selection.d.ts.map +1 -1
- package/build-types/utils/crdt-user-selections.d.ts.map +1 -1
- package/build-types/utils/crdt-utils.d.ts +35 -2
- package/build-types/utils/crdt-utils.d.ts.map +1 -1
- package/build-types/utils/crdt.d.ts.map +1 -1
- package/build-types/utils/forward-resolver.d.ts +2 -2
- package/build-types/utils/forward-resolver.d.ts.map +1 -1
- package/build-types/utils/get-nested-value.d.ts.map +1 -1
- package/build-types/utils/get-normalized-comma-separable.d.ts +1 -1
- package/build-types/utils/get-normalized-comma-separable.d.ts.map +1 -1
- package/build-types/utils/if-matching-action.d.ts +3 -3
- package/build-types/utils/if-matching-action.d.ts.map +1 -1
- package/build-types/utils/index.d.ts +12 -12
- package/build-types/utils/index.d.ts.map +1 -1
- package/build-types/utils/is-numeric-id.d.ts.map +1 -1
- package/build-types/utils/log-entity-deprecation.d.ts +1 -1
- package/build-types/utils/log-entity-deprecation.d.ts.map +1 -1
- package/build-types/utils/normalize-query-for-resolution.d.ts.map +1 -1
- package/build-types/utils/receive-intermediate-results.d.ts +1 -1
- package/build-types/utils/receive-intermediate-results.d.ts.map +1 -1
- package/build-types/utils/replace-action.d.ts +3 -3
- package/build-types/utils/replace-action.d.ts.map +1 -1
- package/build-types/utils/set-nested-value.d.ts.map +1 -1
- package/build-types/utils/user-permissions.d.ts +3 -3
- package/build-types/utils/user-permissions.d.ts.map +1 -1
- package/build-types/utils/with-weak-map-cache.d.ts +1 -1
- package/build-types/utils/with-weak-map-cache.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/actions.js +7 -9
- package/src/awareness/post-editor-awareness.ts +5 -2
- package/src/resolvers.js +2 -1
- package/src/test/actions.js +58 -0
- package/src/test/resolvers.js +115 -2
- package/src/test/rtc-rich-text-offset-space.test.js +204 -0
- package/src/types.ts +63 -6
- package/src/utils/block-selection-history.ts +5 -1
- package/src/utils/crdt-blocks.ts +316 -116
- package/src/utils/crdt-selection.ts +2 -1
- package/src/utils/crdt-user-selections.ts +9 -2
- package/src/utils/crdt-utils.ts +53 -10
- package/src/utils/crdt.ts +30 -4
- package/src/utils/test/crdt-blocks.ts +74 -18
- package/src/utils/test/crdt-utils.ts +18 -2
- package/src/utils/test/rtc-rich-text-cursor-scope.test.js +267 -0
- package/src/utils/test/rtc-rich-text-offset-space.test.js +469 -0
package/src/utils/crdt-utils.ts
CHANGED
|
@@ -84,6 +84,47 @@ export function isYMap< T extends YMapRecord >(
|
|
|
84
84
|
return value instanceof Y.Map;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
declare const richTextOffsetBrand: unique symbol;
|
|
88
|
+
declare const htmlStringIndexBrand: unique symbol;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Branded type to prevent confusion between HTML string indices and RichText offsets.
|
|
92
|
+
*
|
|
93
|
+
* @see asRichTextOffset()
|
|
94
|
+
*/
|
|
95
|
+
export type RichTextOffset = number & {
|
|
96
|
+
readonly [ richTextOffsetBrand ]: 'RichTextOffset';
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Branded type to prevent confusion between HTML string indices and RichText offsets.
|
|
101
|
+
*
|
|
102
|
+
* @see asHtmlStringIndex()
|
|
103
|
+
*/
|
|
104
|
+
export type HtmlStringIndex = number & {
|
|
105
|
+
readonly [ htmlStringIndexBrand ]: 'HtmlStringIndex';
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Brand a number as an offset into a RichText’s text content.
|
|
110
|
+
*
|
|
111
|
+
* @param offset The rich-text offset to brand.
|
|
112
|
+
* @return The branded rich-text offset.
|
|
113
|
+
*/
|
|
114
|
+
export function asRichTextOffset( offset: number ): RichTextOffset {
|
|
115
|
+
return offset as RichTextOffset;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Brand a number as a string index into serialized HTML.
|
|
120
|
+
*
|
|
121
|
+
* @param index The HTML string index to brand.
|
|
122
|
+
* @return The branded HTML string index.
|
|
123
|
+
*/
|
|
124
|
+
export function asHtmlStringIndex( index: number ): HtmlStringIndex {
|
|
125
|
+
return index as HtmlStringIndex;
|
|
126
|
+
}
|
|
127
|
+
|
|
87
128
|
/**
|
|
88
129
|
* Given a block ID and a Y.Doc, find the block in the document.
|
|
89
130
|
*
|
|
@@ -141,15 +182,15 @@ function pickMarker( text: string ): string | null {
|
|
|
141
182
|
*/
|
|
142
183
|
export function htmlIndexToRichTextOffset(
|
|
143
184
|
html: string,
|
|
144
|
-
htmlIndex:
|
|
145
|
-
):
|
|
185
|
+
htmlIndex: HtmlStringIndex
|
|
186
|
+
): RichTextOffset {
|
|
146
187
|
if ( ! html.includes( '<' ) && ! html.includes( '&' ) ) {
|
|
147
|
-
return htmlIndex;
|
|
188
|
+
return asRichTextOffset( htmlIndex );
|
|
148
189
|
}
|
|
149
190
|
|
|
150
191
|
const marker = pickMarker( html );
|
|
151
192
|
if ( ! marker ) {
|
|
152
|
-
return htmlIndex;
|
|
193
|
+
return asRichTextOffset( htmlIndex );
|
|
153
194
|
}
|
|
154
195
|
|
|
155
196
|
// Insert marker and let create() do the parsing.
|
|
@@ -158,7 +199,7 @@ export function htmlIndexToRichTextOffset(
|
|
|
158
199
|
const value = create( { html: withMarker } );
|
|
159
200
|
const markerPos = value.text.indexOf( marker );
|
|
160
201
|
|
|
161
|
-
return markerPos === -1 ? htmlIndex : markerPos;
|
|
202
|
+
return asRichTextOffset( markerPos === -1 ? htmlIndex : markerPos );
|
|
162
203
|
}
|
|
163
204
|
|
|
164
205
|
/**
|
|
@@ -172,15 +213,15 @@ export function htmlIndexToRichTextOffset(
|
|
|
172
213
|
*/
|
|
173
214
|
export function richTextOffsetToHtmlIndex(
|
|
174
215
|
html: string,
|
|
175
|
-
richTextOffset:
|
|
176
|
-
):
|
|
216
|
+
richTextOffset: RichTextOffset
|
|
217
|
+
): HtmlStringIndex {
|
|
177
218
|
if ( ! html.includes( '<' ) && ! html.includes( '&' ) ) {
|
|
178
|
-
return richTextOffset;
|
|
219
|
+
return asHtmlStringIndex( richTextOffset );
|
|
179
220
|
}
|
|
180
221
|
|
|
181
222
|
const marker = pickMarker( html );
|
|
182
223
|
if ( ! marker ) {
|
|
183
|
-
return richTextOffset;
|
|
224
|
+
return asHtmlStringIndex( richTextOffset );
|
|
184
225
|
}
|
|
185
226
|
|
|
186
227
|
const value = create( { html } );
|
|
@@ -200,7 +241,9 @@ export function richTextOffsetToHtmlIndex(
|
|
|
200
241
|
|
|
201
242
|
const htmlWithMarker = toHTMLString( { value: withMarker } );
|
|
202
243
|
const markerIndex = htmlWithMarker.indexOf( marker );
|
|
203
|
-
return
|
|
244
|
+
return asHtmlStringIndex(
|
|
245
|
+
markerIndex === -1 ? richTextOffset : markerIndex
|
|
246
|
+
);
|
|
204
247
|
}
|
|
205
248
|
|
|
206
249
|
function findBlockByClientIdInBlocks(
|
package/src/utils/crdt.ts
CHANGED
|
@@ -21,10 +21,11 @@ import {
|
|
|
21
21
|
*/
|
|
22
22
|
import { BaseAwareness } from '../awareness/base-awareness';
|
|
23
23
|
import {
|
|
24
|
+
type Block,
|
|
24
25
|
deserializeBlockAttributes,
|
|
25
26
|
mergeCrdtBlocks,
|
|
27
|
+
type MergeCursorPosition,
|
|
26
28
|
mergeRichTextUpdate,
|
|
27
|
-
type Block,
|
|
28
29
|
type YBlock,
|
|
29
30
|
type YBlocks,
|
|
30
31
|
} from './crdt-blocks';
|
|
@@ -37,6 +38,7 @@ import {
|
|
|
37
38
|
updateSelectionHistory,
|
|
38
39
|
} from './crdt-selection';
|
|
39
40
|
import {
|
|
41
|
+
asRichTextOffset,
|
|
40
42
|
createYMap,
|
|
41
43
|
getRootMap,
|
|
42
44
|
isYMap,
|
|
@@ -161,12 +163,13 @@ export function applyPostChangesToCRDTDoc(
|
|
|
161
163
|
|
|
162
164
|
// Block changes from typing are bundled with a 'selection' update.
|
|
163
165
|
// Pass the resulting cursor position to the mergeCrdtBlocks function.
|
|
164
|
-
const
|
|
165
|
-
changes.selection
|
|
166
|
+
const newCursorPosition = parseCursorSelection(
|
|
167
|
+
changes.selection
|
|
168
|
+
);
|
|
166
169
|
|
|
167
170
|
// Merge blocks does not need `setValue` because it is operating on a
|
|
168
171
|
// Yjs type that is already in the Y.Doc.
|
|
169
|
-
mergeCrdtBlocks( currentBlocks, newValue,
|
|
172
|
+
mergeCrdtBlocks( currentBlocks, newValue, newCursorPosition );
|
|
170
173
|
break;
|
|
171
174
|
}
|
|
172
175
|
|
|
@@ -260,6 +263,29 @@ export function applyPostChangesToCRDTDoc(
|
|
|
260
263
|
}
|
|
261
264
|
}
|
|
262
265
|
|
|
266
|
+
/**
|
|
267
|
+
* Only returns a selection object if it describes a selection within a block, with
|
|
268
|
+
* a cursor inside a RichText field associated with one of that block’s attributes.
|
|
269
|
+
*
|
|
270
|
+
* @param selection Selection object which might represent a selection within a block,
|
|
271
|
+
* within a RichText field associated with a particular attribute of
|
|
272
|
+
* that block, or none at all.
|
|
273
|
+
*/
|
|
274
|
+
function parseCursorSelection( selection?: WPSelection ): MergeCursorPosition {
|
|
275
|
+
const selectionStart = selection?.selectionStart;
|
|
276
|
+
|
|
277
|
+
return selectionStart?.clientId &&
|
|
278
|
+
selectionStart.attributeKey &&
|
|
279
|
+
'number' === typeof selectionStart.offset &&
|
|
280
|
+
Number.isInteger( selectionStart.offset )
|
|
281
|
+
? {
|
|
282
|
+
attributeKey: selectionStart.attributeKey,
|
|
283
|
+
clientId: selectionStart.clientId,
|
|
284
|
+
offset: asRichTextOffset( selectionStart.offset ),
|
|
285
|
+
}
|
|
286
|
+
: null;
|
|
287
|
+
}
|
|
288
|
+
|
|
263
289
|
function defaultGetChangesFromCRDTDoc( crdtDoc: CRDTDoc ): ObjectData {
|
|
264
290
|
return getRootMap( crdtDoc, CRDT_RECORD_MAP_KEY ).toJSON();
|
|
265
291
|
}
|
|
@@ -119,6 +119,16 @@ import {
|
|
|
119
119
|
type YBlockAttributes,
|
|
120
120
|
} from '../crdt-blocks';
|
|
121
121
|
import { getCachedRichTextData, createRichTextDataCache } from '../crdt-text';
|
|
122
|
+
import { asHtmlStringIndex, asRichTextOffset } from '../crdt-utils';
|
|
123
|
+
import { type WPBlockSelection } from '../../types';
|
|
124
|
+
|
|
125
|
+
function createCursorSelection( offset: number ): WPBlockSelection {
|
|
126
|
+
return {
|
|
127
|
+
attributeKey: 'content',
|
|
128
|
+
clientId: 'block-1',
|
|
129
|
+
offset: asRichTextOffset( offset ),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
122
132
|
|
|
123
133
|
describe( 'crdt-blocks', () => {
|
|
124
134
|
let doc: Y.Doc;
|
|
@@ -1006,6 +1016,7 @@ describe( 'crdt-blocks', () => {
|
|
|
1006
1016
|
name: 'core/paragraph',
|
|
1007
1017
|
attributes: { content: 'Hello World' },
|
|
1008
1018
|
innerBlocks: [],
|
|
1019
|
+
clientId: 'block-1',
|
|
1009
1020
|
},
|
|
1010
1021
|
];
|
|
1011
1022
|
|
|
@@ -1016,10 +1027,15 @@ describe( 'crdt-blocks', () => {
|
|
|
1016
1027
|
name: 'core/paragraph',
|
|
1017
1028
|
attributes: { content: 'XHello World' },
|
|
1018
1029
|
innerBlocks: [],
|
|
1030
|
+
clientId: 'block-1',
|
|
1019
1031
|
},
|
|
1020
1032
|
];
|
|
1021
1033
|
|
|
1022
|
-
mergeCrdtBlocks(
|
|
1034
|
+
mergeCrdtBlocks(
|
|
1035
|
+
yblocks,
|
|
1036
|
+
updatedBlocks,
|
|
1037
|
+
createCursorSelection( 0 )
|
|
1038
|
+
);
|
|
1023
1039
|
|
|
1024
1040
|
const block = yblocks.get( 0 );
|
|
1025
1041
|
const content = (
|
|
@@ -1034,6 +1050,7 @@ describe( 'crdt-blocks', () => {
|
|
|
1034
1050
|
name: 'core/paragraph',
|
|
1035
1051
|
attributes: { content: 'Hello World' },
|
|
1036
1052
|
innerBlocks: [],
|
|
1053
|
+
clientId: 'block-1',
|
|
1037
1054
|
},
|
|
1038
1055
|
];
|
|
1039
1056
|
|
|
@@ -1044,10 +1061,15 @@ describe( 'crdt-blocks', () => {
|
|
|
1044
1061
|
name: 'core/paragraph',
|
|
1045
1062
|
attributes: { content: 'Hello World!' },
|
|
1046
1063
|
innerBlocks: [],
|
|
1064
|
+
clientId: 'block-1',
|
|
1047
1065
|
},
|
|
1048
1066
|
];
|
|
1049
1067
|
|
|
1050
|
-
mergeCrdtBlocks(
|
|
1068
|
+
mergeCrdtBlocks(
|
|
1069
|
+
yblocks,
|
|
1070
|
+
updatedBlocks,
|
|
1071
|
+
createCursorSelection( 11 )
|
|
1072
|
+
);
|
|
1051
1073
|
|
|
1052
1074
|
const block = yblocks.get( 0 );
|
|
1053
1075
|
const content = (
|
|
@@ -1062,6 +1084,7 @@ describe( 'crdt-blocks', () => {
|
|
|
1062
1084
|
name: 'core/paragraph',
|
|
1063
1085
|
attributes: { content: 'Hello' },
|
|
1064
1086
|
innerBlocks: [],
|
|
1087
|
+
clientId: 'block-1',
|
|
1065
1088
|
},
|
|
1066
1089
|
];
|
|
1067
1090
|
|
|
@@ -1072,10 +1095,15 @@ describe( 'crdt-blocks', () => {
|
|
|
1072
1095
|
name: 'core/paragraph',
|
|
1073
1096
|
attributes: { content: 'Hello World' },
|
|
1074
1097
|
innerBlocks: [],
|
|
1098
|
+
clientId: 'block-1',
|
|
1075
1099
|
},
|
|
1076
1100
|
];
|
|
1077
1101
|
|
|
1078
|
-
mergeCrdtBlocks(
|
|
1102
|
+
mergeCrdtBlocks(
|
|
1103
|
+
yblocks,
|
|
1104
|
+
updatedBlocks,
|
|
1105
|
+
createCursorSelection( 999 )
|
|
1106
|
+
);
|
|
1079
1107
|
|
|
1080
1108
|
const block = yblocks.get( 0 );
|
|
1081
1109
|
const content = (
|
|
@@ -2602,7 +2630,11 @@ describe( 'crdt-blocks', () => {
|
|
|
2602
2630
|
];
|
|
2603
2631
|
|
|
2604
2632
|
// Cursor after 'Hello 😀' = 6 + 2 = 8
|
|
2605
|
-
mergeCrdtBlocks(
|
|
2633
|
+
mergeCrdtBlocks(
|
|
2634
|
+
yblocks,
|
|
2635
|
+
updatedBlocks,
|
|
2636
|
+
createCursorSelection( 8 )
|
|
2637
|
+
);
|
|
2606
2638
|
|
|
2607
2639
|
const block = yblocks.get( 0 );
|
|
2608
2640
|
const content = (
|
|
@@ -2633,7 +2665,11 @@ describe( 'crdt-blocks', () => {
|
|
|
2633
2665
|
];
|
|
2634
2666
|
|
|
2635
2667
|
// Cursor at position 6 (after 'Hello ', emoji was deleted)
|
|
2636
|
-
mergeCrdtBlocks(
|
|
2668
|
+
mergeCrdtBlocks(
|
|
2669
|
+
yblocks,
|
|
2670
|
+
updatedBlocks,
|
|
2671
|
+
createCursorSelection( 6 )
|
|
2672
|
+
);
|
|
2637
2673
|
|
|
2638
2674
|
const block = yblocks.get( 0 );
|
|
2639
2675
|
const content = (
|
|
@@ -2664,7 +2700,11 @@ describe( 'crdt-blocks', () => {
|
|
|
2664
2700
|
];
|
|
2665
2701
|
|
|
2666
2702
|
// Cursor after 'a😀x' = 1 + 2 + 1 = 4
|
|
2667
|
-
mergeCrdtBlocks(
|
|
2703
|
+
mergeCrdtBlocks(
|
|
2704
|
+
yblocks,
|
|
2705
|
+
updatedBlocks,
|
|
2706
|
+
createCursorSelection( 4 )
|
|
2707
|
+
);
|
|
2668
2708
|
|
|
2669
2709
|
const block = yblocks.get( 0 );
|
|
2670
2710
|
const content = (
|
|
@@ -2696,7 +2736,11 @@ describe( 'crdt-blocks', () => {
|
|
|
2696
2736
|
];
|
|
2697
2737
|
|
|
2698
2738
|
// Cursor after '😀 hello ' = 2 + 7 = 9
|
|
2699
|
-
mergeCrdtBlocks(
|
|
2739
|
+
mergeCrdtBlocks(
|
|
2740
|
+
yblocks,
|
|
2741
|
+
updatedBlocks,
|
|
2742
|
+
createCursorSelection( 9 )
|
|
2743
|
+
);
|
|
2700
2744
|
|
|
2701
2745
|
const block = yblocks.get( 0 );
|
|
2702
2746
|
const content = (
|
|
@@ -2729,7 +2773,7 @@ describe( 'crdt-blocks', () => {
|
|
|
2729
2773
|
const yText = doc.getText( 'test' );
|
|
2730
2774
|
yText.insert( 0, 'a😀b' );
|
|
2731
2775
|
|
|
2732
|
-
mergeRichTextUpdate( yText, 'a😀c', 4 );
|
|
2776
|
+
mergeRichTextUpdate( yText, 'a😀c', asHtmlStringIndex( 4 ) );
|
|
2733
2777
|
|
|
2734
2778
|
expect( yText.toString() ).toBe( 'a😀c' );
|
|
2735
2779
|
} );
|
|
@@ -2738,7 +2782,7 @@ describe( 'crdt-blocks', () => {
|
|
|
2738
2782
|
const yText = doc.getText( 'test' );
|
|
2739
2783
|
yText.insert( 0, 'ab' );
|
|
2740
2784
|
|
|
2741
|
-
mergeRichTextUpdate( yText, 'a😀b', 3 );
|
|
2785
|
+
mergeRichTextUpdate( yText, 'a😀b', asHtmlStringIndex( 3 ) );
|
|
2742
2786
|
|
|
2743
2787
|
expect( yText.toString() ).toBe( 'a😀b' );
|
|
2744
2788
|
} );
|
|
@@ -2747,7 +2791,7 @@ describe( 'crdt-blocks', () => {
|
|
|
2747
2791
|
const yText = doc.getText( 'test' );
|
|
2748
2792
|
yText.insert( 0, 'a😀b' );
|
|
2749
2793
|
|
|
2750
|
-
mergeRichTextUpdate( yText, 'ab', 1 );
|
|
2794
|
+
mergeRichTextUpdate( yText, 'ab', asHtmlStringIndex( 1 ) );
|
|
2751
2795
|
|
|
2752
2796
|
expect( yText.toString() ).toBe( 'ab' );
|
|
2753
2797
|
} );
|
|
@@ -2756,7 +2800,11 @@ describe( 'crdt-blocks', () => {
|
|
|
2756
2800
|
const yText = doc.getText( 'test' );
|
|
2757
2801
|
yText.insert( 0, 'Hello 😀 World 🎉' );
|
|
2758
2802
|
|
|
2759
|
-
mergeRichTextUpdate(
|
|
2803
|
+
mergeRichTextUpdate(
|
|
2804
|
+
yText,
|
|
2805
|
+
'Hello 😀 Beautiful World 🎉',
|
|
2806
|
+
asHtmlStringIndex( 19 )
|
|
2807
|
+
);
|
|
2760
2808
|
|
|
2761
2809
|
expect( yText.toString() ).toBe( 'Hello 😀 Beautiful World 🎉' );
|
|
2762
2810
|
} );
|
|
@@ -2766,7 +2814,7 @@ describe( 'crdt-blocks', () => {
|
|
|
2766
2814
|
const yText = doc.getText( 'test' );
|
|
2767
2815
|
yText.insert( 0, 'a🏳️🌈b' );
|
|
2768
2816
|
|
|
2769
|
-
mergeRichTextUpdate( yText, 'a🏳️🌈xb', 7 );
|
|
2817
|
+
mergeRichTextUpdate( yText, 'a🏳️🌈xb', asHtmlStringIndex( 7 ) );
|
|
2770
2818
|
|
|
2771
2819
|
expect( yText.toString() ).toBe( 'a🏳️🌈xb' );
|
|
2772
2820
|
} );
|
|
@@ -2776,7 +2824,7 @@ describe( 'crdt-blocks', () => {
|
|
|
2776
2824
|
const yText = doc.getText( 'test' );
|
|
2777
2825
|
yText.insert( 0, 'Hi 👋🏽' );
|
|
2778
2826
|
|
|
2779
|
-
mergeRichTextUpdate( yText, 'Hi 👋🏽!', 6 );
|
|
2827
|
+
mergeRichTextUpdate( yText, 'Hi 👋🏽!', asHtmlStringIndex( 6 ) );
|
|
2780
2828
|
|
|
2781
2829
|
expect( yText.toString() ).toBe( 'Hi 👋🏽!' );
|
|
2782
2830
|
} );
|
|
@@ -2812,7 +2860,11 @@ describe( 'crdt-blocks', () => {
|
|
|
2812
2860
|
];
|
|
2813
2861
|
|
|
2814
2862
|
// Cursor after '𠮷野家は美味しい' = 2+1+1+1+1+1+1+1 = 9
|
|
2815
|
-
mergeCrdtBlocks(
|
|
2863
|
+
mergeCrdtBlocks(
|
|
2864
|
+
yblocks,
|
|
2865
|
+
updatedBlocks,
|
|
2866
|
+
createCursorSelection( 9 )
|
|
2867
|
+
);
|
|
2816
2868
|
|
|
2817
2869
|
const block = yblocks.get( 0 );
|
|
2818
2870
|
const content = (
|
|
@@ -2843,7 +2895,11 @@ describe( 'crdt-blocks', () => {
|
|
|
2843
2895
|
},
|
|
2844
2896
|
];
|
|
2845
2897
|
|
|
2846
|
-
mergeCrdtBlocks(
|
|
2898
|
+
mergeCrdtBlocks(
|
|
2899
|
+
yblocks,
|
|
2900
|
+
updatedBlocks,
|
|
2901
|
+
createCursorSelection( 18 )
|
|
2902
|
+
);
|
|
2847
2903
|
|
|
2848
2904
|
const block = yblocks.get( 0 );
|
|
2849
2905
|
const content = (
|
|
@@ -2867,7 +2923,7 @@ describe( 'crdt-blocks', () => {
|
|
|
2867
2923
|
const yText = doc.getText( 'test' );
|
|
2868
2924
|
yText.insert( 0, 'a𠮷b' );
|
|
2869
2925
|
|
|
2870
|
-
mergeRichTextUpdate( yText, 'a𠮷xb', 4 );
|
|
2926
|
+
mergeRichTextUpdate( yText, 'a𠮷xb', asHtmlStringIndex( 4 ) );
|
|
2871
2927
|
|
|
2872
2928
|
expect( yText.toString() ).toBe( 'a𠮷xb' );
|
|
2873
2929
|
} );
|
|
@@ -2877,7 +2933,7 @@ describe( 'crdt-blocks', () => {
|
|
|
2877
2933
|
const yText = doc.getText( 'test' );
|
|
2878
2934
|
yText.insert( 0, 'a𝐀b' );
|
|
2879
2935
|
|
|
2880
|
-
mergeRichTextUpdate( yText, 'a𝐀xb', 4 );
|
|
2936
|
+
mergeRichTextUpdate( yText, 'a𝐀xb', asHtmlStringIndex( 4 ) );
|
|
2881
2937
|
|
|
2882
2938
|
expect( yText.toString() ).toBe( 'a𝐀xb' );
|
|
2883
2939
|
} );
|
|
@@ -2897,7 +2953,7 @@ describe( 'crdt-blocks', () => {
|
|
|
2897
2953
|
const yText = doc.getText( 'test' );
|
|
2898
2954
|
yText.insert( 0, 'a𝄞b' );
|
|
2899
2955
|
|
|
2900
|
-
mergeRichTextUpdate( yText, 'a𝄞xb', 4 );
|
|
2956
|
+
mergeRichTextUpdate( yText, 'a𝄞xb', asHtmlStringIndex( 4 ) );
|
|
2901
2957
|
|
|
2902
2958
|
expect( yText.toString() ).toBe( 'a𝄞xb' );
|
|
2903
2959
|
} );
|
|
@@ -7,10 +7,26 @@ import { describe, expect, it } from '@jest/globals';
|
|
|
7
7
|
* Internal dependencies
|
|
8
8
|
*/
|
|
9
9
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
asHtmlStringIndex,
|
|
11
|
+
asRichTextOffset,
|
|
12
|
+
htmlIndexToRichTextOffset as typedHtmlIndexToRichTextOffset,
|
|
13
|
+
richTextOffsetToHtmlIndex as typedRichTextOffsetToHtmlIndex,
|
|
12
14
|
} from '../crdt-utils';
|
|
13
15
|
|
|
16
|
+
function htmlIndexToRichTextOffset( html: string, htmlIndex: number ) {
|
|
17
|
+
return typedHtmlIndexToRichTextOffset(
|
|
18
|
+
html,
|
|
19
|
+
asHtmlStringIndex( htmlIndex )
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function richTextOffsetToHtmlIndex( html: string, richTextOffset: number ) {
|
|
24
|
+
return typedRichTextOffsetToHtmlIndex(
|
|
25
|
+
html,
|
|
26
|
+
asRichTextOffset( richTextOffset )
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
14
30
|
describe( 'htmlIndexToRichTextOffset', () => {
|
|
15
31
|
it( 'returns the index unchanged when there are no tags', () => {
|
|
16
32
|
expect( htmlIndexToRichTextOffset( 'hello world', 5 ) ).toBe( 5 );
|