@wordpress/core-data 7.38.1-next.v.0 → 7.39.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/CHANGELOG.md +2 -0
- package/build/actions.cjs +17 -6
- package/build/actions.cjs.map +2 -2
- package/build/awareness/base-awareness.cjs +62 -0
- package/build/awareness/base-awareness.cjs.map +7 -0
- package/build/awareness/post-editor-awareness.cjs +4 -18
- package/build/awareness/post-editor-awareness.cjs.map +3 -3
- package/build/entities.cjs +14 -2
- package/build/entities.cjs.map +2 -2
- package/build/resolvers.cjs +40 -0
- package/build/resolvers.cjs.map +2 -2
- package/build/types.cjs.map +1 -1
- package/build/utils/block-selection-history.cjs +101 -0
- package/build/utils/block-selection-history.cjs.map +7 -0
- package/build/utils/crdt-selection.cjs +139 -0
- package/build/utils/crdt-selection.cjs.map +7 -0
- package/build/utils/crdt-user-selections.cjs +2 -2
- package/build/utils/crdt-user-selections.cjs.map +2 -2
- package/build/utils/crdt-utils.cjs +29 -0
- package/build/utils/crdt-utils.cjs.map +3 -3
- package/build/utils/crdt.cjs +16 -4
- package/build/utils/crdt.cjs.map +2 -2
- package/build-module/actions.mjs +17 -6
- package/build-module/actions.mjs.map +2 -2
- package/build-module/awareness/base-awareness.mjs +35 -0
- package/build-module/awareness/base-awareness.mjs.map +7 -0
- package/build-module/awareness/post-editor-awareness.mjs +4 -18
- package/build-module/awareness/post-editor-awareness.mjs.map +2 -2
- package/build-module/entities.mjs +15 -2
- package/build-module/entities.mjs.map +2 -2
- package/build-module/resolvers.mjs +40 -0
- package/build-module/resolvers.mjs.map +2 -2
- package/build-module/utils/block-selection-history.mjs +75 -0
- package/build-module/utils/block-selection-history.mjs.map +7 -0
- package/build-module/utils/crdt-selection.mjs +115 -0
- package/build-module/utils/crdt-selection.mjs.map +7 -0
- package/build-module/utils/crdt-user-selections.mjs +2 -2
- package/build-module/utils/crdt-user-selections.mjs.map +2 -2
- package/build-module/utils/crdt-utils.mjs +28 -0
- package/build-module/utils/crdt-utils.mjs.map +2 -2
- package/build-module/utils/crdt.mjs +18 -3
- package/build-module/utils/crdt.mjs.map +2 -2
- package/build-types/actions.d.ts.map +1 -1
- package/build-types/awareness/base-awareness.d.ts +19 -0
- package/build-types/awareness/base-awareness.d.ts.map +1 -0
- package/build-types/awareness/post-editor-awareness.d.ts +7 -8
- package/build-types/awareness/post-editor-awareness.d.ts.map +1 -1
- package/build-types/entities.d.ts.map +1 -1
- package/build-types/entity-types/test/attachment.test.d.ts +10 -0
- package/build-types/entity-types/test/attachment.test.d.ts.map +1 -0
- package/build-types/index.d.ts.map +1 -1
- package/build-types/resolvers.d.ts.map +1 -1
- package/build-types/types.d.ts +12 -2
- package/build-types/types.d.ts.map +1 -1
- package/build-types/utils/block-selection-history.d.ts +47 -0
- package/build-types/utils/block-selection-history.d.ts.map +1 -0
- package/build-types/utils/crdt-selection.d.ts +16 -0
- package/build-types/utils/crdt-selection.d.ts.map +1 -0
- package/build-types/utils/crdt-user-selections.d.ts.map +1 -1
- package/build-types/utils/crdt-utils.d.ts +12 -0
- package/build-types/utils/crdt-utils.d.ts.map +1 -1
- package/build-types/utils/crdt.d.ts +8 -14
- package/build-types/utils/crdt.d.ts.map +1 -1
- package/build-types/utils/test/block-selection-history.test.d.ts +2 -0
- package/build-types/utils/test/block-selection-history.test.d.ts.map +1 -0
- package/build-types/utils/test/crdt-blocks.d.ts +2 -0
- package/build-types/utils/test/crdt-blocks.d.ts.map +1 -0
- package/build-types/utils/test/crdt.d.ts +2 -0
- package/build-types/utils/test/crdt.d.ts.map +1 -0
- package/package.json +21 -19
- package/src/actions.js +40 -7
- package/src/awareness/base-awareness.ts +50 -0
- package/src/awareness/post-editor-awareness.ts +4 -24
- package/src/entities.js +18 -2
- package/src/entity-types/test/attachment.test.ts +4 -4
- package/src/resolvers.js +51 -0
- package/src/test/actions.js +402 -0
- package/src/test/resolvers.js +4 -0
- package/src/types.ts +12 -3
- package/src/utils/block-selection-history.ts +176 -0
- package/src/utils/crdt-selection.ts +205 -0
- package/src/utils/crdt-user-selections.ts +7 -3
- package/src/utils/crdt-utils.ts +54 -0
- package/src/utils/crdt.ts +36 -3
- package/src/utils/test/block-selection-history.test.ts +764 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/core-data",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.39.0",
|
|
4
4
|
"description": "Access to and manipulation of core WordPress entities.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -49,22 +49,22 @@
|
|
|
49
49
|
"build-module/index.mjs"
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@wordpress/api-fetch": "^7.
|
|
53
|
-
"@wordpress/block-editor": "^15.
|
|
54
|
-
"@wordpress/blocks": "^15.
|
|
55
|
-
"@wordpress/compose": "^7.
|
|
56
|
-
"@wordpress/data": "^10.
|
|
57
|
-
"@wordpress/deprecated": "^4.
|
|
58
|
-
"@wordpress/element": "^6.
|
|
59
|
-
"@wordpress/html-entities": "^4.
|
|
60
|
-
"@wordpress/i18n": "^6.
|
|
61
|
-
"@wordpress/is-shallow-equal": "^5.
|
|
62
|
-
"@wordpress/private-apis": "^1.
|
|
63
|
-
"@wordpress/rich-text": "^7.
|
|
64
|
-
"@wordpress/sync": "^1.
|
|
65
|
-
"@wordpress/undo-manager": "^1.
|
|
66
|
-
"@wordpress/url": "^4.
|
|
67
|
-
"@wordpress/warning": "^3.
|
|
52
|
+
"@wordpress/api-fetch": "^7.39.0",
|
|
53
|
+
"@wordpress/block-editor": "^15.12.0",
|
|
54
|
+
"@wordpress/blocks": "^15.12.0",
|
|
55
|
+
"@wordpress/compose": "^7.39.0",
|
|
56
|
+
"@wordpress/data": "^10.39.0",
|
|
57
|
+
"@wordpress/deprecated": "^4.39.0",
|
|
58
|
+
"@wordpress/element": "^6.39.0",
|
|
59
|
+
"@wordpress/html-entities": "^4.39.0",
|
|
60
|
+
"@wordpress/i18n": "^6.12.0",
|
|
61
|
+
"@wordpress/is-shallow-equal": "^5.39.0",
|
|
62
|
+
"@wordpress/private-apis": "^1.39.0",
|
|
63
|
+
"@wordpress/rich-text": "^7.39.0",
|
|
64
|
+
"@wordpress/sync": "^1.39.0",
|
|
65
|
+
"@wordpress/undo-manager": "^1.39.0",
|
|
66
|
+
"@wordpress/url": "^4.39.0",
|
|
67
|
+
"@wordpress/warning": "^3.39.0",
|
|
68
68
|
"change-case": "^4.1.2",
|
|
69
69
|
"equivalent-key-map": "^0.2.2",
|
|
70
70
|
"fast-deep-equal": "^3.1.3",
|
|
@@ -72,7 +72,9 @@
|
|
|
72
72
|
"uuid": "^9.0.1"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@
|
|
75
|
+
"@jest/globals": "^30.2.0",
|
|
76
|
+
"@types/jest": "^29.5.14",
|
|
77
|
+
"@types/node": "^20.19.0",
|
|
76
78
|
"deep-freeze": "0.0.1"
|
|
77
79
|
},
|
|
78
80
|
"peerDependencies": {
|
|
@@ -82,5 +84,5 @@
|
|
|
82
84
|
"publishConfig": {
|
|
83
85
|
"access": "public"
|
|
84
86
|
},
|
|
85
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "eee1cfb1472f11183e40fb77465a5f13145df7ad"
|
|
86
88
|
}
|
package/src/actions.js
CHANGED
|
@@ -339,6 +339,15 @@ export const deleteEntityRecord =
|
|
|
339
339
|
} );
|
|
340
340
|
|
|
341
341
|
await dispatch( removeItems( kind, name, recordId, true ) );
|
|
342
|
+
|
|
343
|
+
if ( globalThis.IS_GUTENBERG_PLUGIN ) {
|
|
344
|
+
if ( entityConfig.syncConfig ) {
|
|
345
|
+
const objectType = `${ kind }/${ name }`;
|
|
346
|
+
const objectId = recordId;
|
|
347
|
+
|
|
348
|
+
getSyncManager()?.unload( objectType, objectId );
|
|
349
|
+
}
|
|
350
|
+
}
|
|
342
351
|
} catch ( _error ) {
|
|
343
352
|
hasError = true;
|
|
344
353
|
error = _error;
|
|
@@ -393,6 +402,16 @@ export const editEntityRecord =
|
|
|
393
402
|
recordId
|
|
394
403
|
);
|
|
395
404
|
|
|
405
|
+
// Some fields are merged with the existing value instead of replaced.
|
|
406
|
+
// See `mergedEdits` definition on the entity config.
|
|
407
|
+
const editsWithMerges = Object.keys( edits ).reduce( ( acc, key ) => {
|
|
408
|
+
acc[ key ] = mergedEdits[ key ]
|
|
409
|
+
? { ...editedRecord[ key ], ...edits[ key ] }
|
|
410
|
+
: edits[ key ];
|
|
411
|
+
|
|
412
|
+
return acc;
|
|
413
|
+
}, {} );
|
|
414
|
+
|
|
396
415
|
const edit = {
|
|
397
416
|
kind,
|
|
398
417
|
name,
|
|
@@ -401,10 +420,7 @@ export const editEntityRecord =
|
|
|
401
420
|
// so that the property is not considered dirty.
|
|
402
421
|
edits: Object.keys( edits ).reduce( ( acc, key ) => {
|
|
403
422
|
const recordValue = record[ key ];
|
|
404
|
-
const
|
|
405
|
-
const value = mergedEdits[ key ]
|
|
406
|
-
? { ...editedRecordValue, ...edits[ key ] }
|
|
407
|
-
: edits[ key ];
|
|
423
|
+
const value = editsWithMerges[ key ];
|
|
408
424
|
acc[ key ] = fastDeepEqual( recordValue, value )
|
|
409
425
|
? undefined
|
|
410
426
|
: value;
|
|
@@ -416,11 +432,28 @@ export const editEntityRecord =
|
|
|
416
432
|
const objectType = `${ kind }/${ name }`;
|
|
417
433
|
const objectId = recordId;
|
|
418
434
|
|
|
435
|
+
// Determine whether this edit should create a new undo level.
|
|
436
|
+
//
|
|
437
|
+
// In Gutenberg, block changes flow through two callbacks:
|
|
438
|
+
// - `onInput`: For transient/in-progress changes (e.g., typing each
|
|
439
|
+
// character). These use `isCached: true` and get merged into
|
|
440
|
+
// the current undo item.
|
|
441
|
+
// - `onChange`: For persistent/completed changes (e.g., formatting
|
|
442
|
+
// transforms, block insertions). These use `isCached: false` and
|
|
443
|
+
// should create a new undo level.
|
|
444
|
+
//
|
|
445
|
+
// Additionally, `undoIgnore: true` means the change should not
|
|
446
|
+
// affect the undo history at all (e.g., selection-only changes).
|
|
447
|
+
const isNewUndoLevel = options.undoIgnore
|
|
448
|
+
? false
|
|
449
|
+
: ! options.isCached;
|
|
450
|
+
|
|
419
451
|
getSyncManager()?.update(
|
|
420
452
|
objectType,
|
|
421
453
|
objectId,
|
|
422
|
-
|
|
423
|
-
LOCAL_EDITOR_ORIGIN
|
|
454
|
+
editsWithMerges,
|
|
455
|
+
LOCAL_EDITOR_ORIGIN,
|
|
456
|
+
{ isNewUndoLevel }
|
|
424
457
|
);
|
|
425
458
|
}
|
|
426
459
|
}
|
|
@@ -721,7 +754,7 @@ export const saveEntityRecord =
|
|
|
721
754
|
recordId,
|
|
722
755
|
updatedRecord,
|
|
723
756
|
LOCAL_EDITOR_ORIGIN,
|
|
724
|
-
true
|
|
757
|
+
{ isSave: true }
|
|
725
758
|
);
|
|
726
759
|
}
|
|
727
760
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { select } from '@wordpress/data';
|
|
5
|
+
import { AwarenessState } from '@wordpress/sync';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import { STORE_NAME as coreStore } from '../name';
|
|
11
|
+
import { generateUserInfo, areUserInfosEqual } from './utils';
|
|
12
|
+
|
|
13
|
+
import type { BaseState } from './types';
|
|
14
|
+
|
|
15
|
+
export abstract class BaseAwarenessState<
|
|
16
|
+
State extends BaseState,
|
|
17
|
+
> extends AwarenessState< State > {
|
|
18
|
+
public setUp(): void {
|
|
19
|
+
super.setUp();
|
|
20
|
+
|
|
21
|
+
this.setCurrentUserInfo();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Set the current user info in the local state.
|
|
26
|
+
*/
|
|
27
|
+
private setCurrentUserInfo(): void {
|
|
28
|
+
const states = this.getStates();
|
|
29
|
+
const otherUserColors = Array.from( states.entries() )
|
|
30
|
+
.filter(
|
|
31
|
+
( [ clientId, state ] ) =>
|
|
32
|
+
state.userInfo && clientId !== this.clientID
|
|
33
|
+
)
|
|
34
|
+
.map( ( [ , state ] ) => state.userInfo.color )
|
|
35
|
+
.filter( Boolean );
|
|
36
|
+
|
|
37
|
+
// Get current user info and set it in local state.
|
|
38
|
+
const currentUser = select( coreStore ).getCurrentUser();
|
|
39
|
+
const userInfo = generateUserInfo( currentUser, otherUserColors );
|
|
40
|
+
this.setLocalStateField( 'userInfo', userInfo );
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const baseEqualityFieldChecks = {
|
|
45
|
+
userInfo: areUserInfosEqual,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export class BaseAwareness extends BaseAwarenessState< BaseState > {
|
|
49
|
+
protected equalityFieldChecks = baseEqualityFieldChecks;
|
|
50
|
+
}
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { dispatch, select, subscribe } from '@wordpress/data';
|
|
5
|
-
import {
|
|
5
|
+
import type { Y } from '@wordpress/sync';
|
|
6
6
|
// @ts-ignore No exported types for block editor store selectors.
|
|
7
7
|
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Internal dependencies
|
|
11
11
|
*/
|
|
12
|
+
import { BaseAwarenessState, baseEqualityFieldChecks } from './base-awareness';
|
|
12
13
|
import {
|
|
13
14
|
AWARENESS_CURSOR_UPDATE_THROTTLE_IN_MS,
|
|
14
15
|
LOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS,
|
|
15
16
|
} from './config';
|
|
16
17
|
import { STORE_NAME as coreStore } from '../name';
|
|
17
|
-
import { generateUserInfo, areUserInfosEqual } from './utils';
|
|
18
18
|
import {
|
|
19
19
|
areSelectionsStatesEqual,
|
|
20
20
|
getSelectionState,
|
|
@@ -23,10 +23,10 @@ import {
|
|
|
23
23
|
import type { WPBlockSelection } from '../types';
|
|
24
24
|
import type { EditorState, PostEditorState } from './types';
|
|
25
25
|
|
|
26
|
-
export class PostEditorAwareness extends
|
|
26
|
+
export class PostEditorAwareness extends BaseAwarenessState< PostEditorState > {
|
|
27
27
|
protected equalityFieldChecks = {
|
|
28
|
+
...baseEqualityFieldChecks,
|
|
28
29
|
editorState: this.areEditorStatesEqual,
|
|
29
|
-
userInfo: areUserInfosEqual,
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
public constructor(
|
|
@@ -41,29 +41,9 @@ export class PostEditorAwareness extends AwarenessState< PostEditorState > {
|
|
|
41
41
|
public setUp(): void {
|
|
42
42
|
super.setUp();
|
|
43
43
|
|
|
44
|
-
this.setCurrentUserInfo();
|
|
45
44
|
this.subscribeToUserSelectionChanges();
|
|
46
45
|
}
|
|
47
46
|
|
|
48
|
-
/**
|
|
49
|
-
* Set the current user info in the local state.
|
|
50
|
-
*/
|
|
51
|
-
private setCurrentUserInfo(): void {
|
|
52
|
-
const states = this.getStates();
|
|
53
|
-
const otherUserColors = Array.from( states.entries() )
|
|
54
|
-
.filter(
|
|
55
|
-
( [ clientId, state ] ) =>
|
|
56
|
-
state.userInfo && clientId !== this.clientID
|
|
57
|
-
)
|
|
58
|
-
.map( ( [ , state ] ) => state.userInfo.color )
|
|
59
|
-
.filter( Boolean );
|
|
60
|
-
|
|
61
|
-
// Get current user info and set it in local state.
|
|
62
|
-
const currentUser = select( coreStore ).getCurrentUser();
|
|
63
|
-
const userInfo = generateUserInfo( currentUser, otherUserColors );
|
|
64
|
-
this.setLocalStateField( 'userInfo', userInfo );
|
|
65
|
-
}
|
|
66
|
-
|
|
67
47
|
/**
|
|
68
48
|
* Subscribe to user selection changes and update the selection state.
|
|
69
49
|
*/
|
package/src/entities.js
CHANGED
|
@@ -17,6 +17,7 @@ import { PostEditorAwareness } from './awareness/post-editor-awareness';
|
|
|
17
17
|
import { getSyncManager } from './sync';
|
|
18
18
|
import {
|
|
19
19
|
applyPostChangesToCRDTDoc,
|
|
20
|
+
defaultSyncConfig,
|
|
20
21
|
getPostChangesFromCRDTDoc,
|
|
21
22
|
} from './utils/crdt';
|
|
22
23
|
|
|
@@ -219,7 +220,16 @@ export const rootEntitiesConfig = [
|
|
|
219
220
|
plural: 'fontCollections',
|
|
220
221
|
key: 'slug',
|
|
221
222
|
},
|
|
222
|
-
]
|
|
223
|
+
].map( ( entity ) => {
|
|
224
|
+
const syncEnabledRootEntities = new Set( [ 'comment' ] );
|
|
225
|
+
|
|
226
|
+
if ( globalThis.IS_GUTENBERG_PLUGIN ) {
|
|
227
|
+
if ( syncEnabledRootEntities.has( entity.name ) ) {
|
|
228
|
+
entity.syncConfig = defaultSyncConfig;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return entity;
|
|
232
|
+
} );
|
|
223
233
|
|
|
224
234
|
export const deprecatedEntities = {
|
|
225
235
|
root: {
|
|
@@ -413,7 +423,7 @@ async function loadTaxonomyEntities() {
|
|
|
413
423
|
} );
|
|
414
424
|
return Object.entries( taxonomies ?? {} ).map( ( [ name, taxonomy ] ) => {
|
|
415
425
|
const namespace = taxonomy?.rest_namespace ?? 'wp/v2';
|
|
416
|
-
|
|
426
|
+
const entity = {
|
|
417
427
|
kind: 'taxonomy',
|
|
418
428
|
baseURL: `/${ namespace }/${ taxonomy.rest_base }`,
|
|
419
429
|
baseURLParams: { context: 'edit' },
|
|
@@ -422,6 +432,12 @@ async function loadTaxonomyEntities() {
|
|
|
422
432
|
getTitle: ( record ) => record?.name,
|
|
423
433
|
supportsPagination: true,
|
|
424
434
|
};
|
|
435
|
+
|
|
436
|
+
if ( globalThis.IS_GUTENBERG_PLUGIN ) {
|
|
437
|
+
entity.syncConfig = defaultSyncConfig;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return entity;
|
|
425
441
|
} );
|
|
426
442
|
}
|
|
427
443
|
|
|
@@ -20,7 +20,7 @@ describe( 'Attachment type', () => {
|
|
|
20
20
|
describe( 'Image attachment', () => {
|
|
21
21
|
it( 'should validate against real image attachment from REST API', () => {
|
|
22
22
|
const attachment: Attachment< 'edit' > =
|
|
23
|
-
imageAttachmentFixture as Attachment< 'edit' >;
|
|
23
|
+
imageAttachmentFixture as unknown as Attachment< 'edit' >;
|
|
24
24
|
|
|
25
25
|
// Edit-context fields
|
|
26
26
|
expect( attachment.permalink_template ).toBeDefined();
|
|
@@ -38,7 +38,7 @@ describe( 'Attachment type', () => {
|
|
|
38
38
|
describe( 'Zip file attachment', () => {
|
|
39
39
|
it( 'should validate against real zip file attachment from REST API', () => {
|
|
40
40
|
const attachment: Attachment< 'edit' > =
|
|
41
|
-
zipAttachmentFixture as Attachment< 'edit' >;
|
|
41
|
+
zipAttachmentFixture as unknown as Attachment< 'edit' >;
|
|
42
42
|
|
|
43
43
|
// Edit-context fields
|
|
44
44
|
expect( attachment.permalink_template ).toBeDefined();
|
|
@@ -58,7 +58,7 @@ describe( 'Attachment type', () => {
|
|
|
58
58
|
describe( 'Audio file attachment', () => {
|
|
59
59
|
it( 'should validate against real audio attachment from REST API', () => {
|
|
60
60
|
const attachment: Attachment< 'edit' > =
|
|
61
|
-
audioAttachmentFixture as Attachment< 'edit' >;
|
|
61
|
+
audioAttachmentFixture as unknown as Attachment< 'edit' >;
|
|
62
62
|
|
|
63
63
|
// Edit-context fields
|
|
64
64
|
expect( attachment.permalink_template ).toBeDefined();
|
|
@@ -79,7 +79,7 @@ describe( 'Attachment type', () => {
|
|
|
79
79
|
describe( 'Video file attachment', () => {
|
|
80
80
|
it( 'should validate against real video attachment from REST API', () => {
|
|
81
81
|
const attachment: Attachment< 'edit' > =
|
|
82
|
-
videoAttachmentFixture as Attachment< 'edit' >;
|
|
82
|
+
videoAttachmentFixture as unknown as Attachment< 'edit' >;
|
|
83
83
|
|
|
84
84
|
// Edit-context fields
|
|
85
85
|
expect( attachment.permalink_template ).toBeDefined();
|
package/src/resolvers.js
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
isNumericID,
|
|
27
27
|
} from './utils';
|
|
28
28
|
import { fetchBlockPatterns } from './fetch';
|
|
29
|
+
import { restoreSelection, getSelectionHistory } from './utils/crdt-selection';
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* Requests authors from the REST API.
|
|
@@ -233,6 +234,36 @@ export const getEntityRecord =
|
|
|
233
234
|
key
|
|
234
235
|
);
|
|
235
236
|
},
|
|
237
|
+
addUndoMeta: ( ydoc, meta ) => {
|
|
238
|
+
const selectionHistory =
|
|
239
|
+
getSelectionHistory( ydoc );
|
|
240
|
+
|
|
241
|
+
if ( selectionHistory ) {
|
|
242
|
+
meta.set(
|
|
243
|
+
'selectionHistory',
|
|
244
|
+
selectionHistory
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
restoreUndoMeta: ( ydoc, meta ) => {
|
|
249
|
+
const selectionHistory =
|
|
250
|
+
meta.get( 'selectionHistory' );
|
|
251
|
+
|
|
252
|
+
if ( selectionHistory ) {
|
|
253
|
+
// Because Yjs initiates an undo, we need to
|
|
254
|
+
// wait until the content is restored before
|
|
255
|
+
// we can update the selection.
|
|
256
|
+
// Use setTimeout() to wait until content is
|
|
257
|
+
// finished updating, and then set the correct
|
|
258
|
+
// selection.
|
|
259
|
+
setTimeout( () => {
|
|
260
|
+
restoreSelection(
|
|
261
|
+
selectionHistory,
|
|
262
|
+
ydoc
|
|
263
|
+
);
|
|
264
|
+
}, 0 );
|
|
265
|
+
}
|
|
266
|
+
},
|
|
236
267
|
}
|
|
237
268
|
);
|
|
238
269
|
}
|
|
@@ -431,6 +462,26 @@ export const getEntityRecords =
|
|
|
431
462
|
};
|
|
432
463
|
}
|
|
433
464
|
|
|
465
|
+
if ( globalThis.IS_GUTENBERG_PLUGIN ) {
|
|
466
|
+
if ( entityConfig.syncConfig && -1 === query.per_page ) {
|
|
467
|
+
const objectType = `${ kind }/${ name }`;
|
|
468
|
+
getSyncManager()?.loadCollection(
|
|
469
|
+
entityConfig.syncConfig,
|
|
470
|
+
objectType,
|
|
471
|
+
{
|
|
472
|
+
refetchRecords: async () => {
|
|
473
|
+
dispatch.receiveEntityRecords(
|
|
474
|
+
kind,
|
|
475
|
+
name,
|
|
476
|
+
await apiFetch( { path, parse: true } ),
|
|
477
|
+
query
|
|
478
|
+
);
|
|
479
|
+
},
|
|
480
|
+
}
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
434
485
|
// If we request fields but the result doesn't contain the fields,
|
|
435
486
|
// explicitly set these fields as "undefined"
|
|
436
487
|
// that way we consider the query "fulfilled".
|