@wordpress/core-data 6.15.0 → 6.17.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 +4 -0
- package/README.md +1 -1
- package/build/actions.js +70 -135
- package/build/actions.js.map +1 -1
- package/build/batch/create-batch.js +0 -22
- package/build/batch/create-batch.js.map +1 -1
- package/build/batch/default-processor.js +3 -15
- package/build/batch/default-processor.js.map +1 -1
- package/build/batch/index.js +0 -3
- package/build/batch/index.js.map +1 -1
- package/build/entities.js +109 -36
- package/build/entities.js.map +1 -1
- package/build/entity-provider.js +34 -53
- package/build/entity-provider.js.map +1 -1
- package/build/entity-types/attachment.js.map +1 -1
- package/build/entity-types/base-entity-records.js +0 -3
- package/build/entity-types/base-entity-records.js.map +1 -1
- package/build/entity-types/comment.js.map +1 -1
- package/build/entity-types/helpers.js.map +1 -1
- package/build/entity-types/index.js.map +1 -1
- package/build/entity-types/menu-location.js.map +1 -1
- package/build/entity-types/nav-menu-item.js.map +1 -1
- package/build/entity-types/nav-menu.js.map +1 -1
- package/build/entity-types/page.js.map +1 -1
- package/build/entity-types/plugin.js.map +1 -1
- package/build/entity-types/post.js.map +1 -1
- package/build/entity-types/settings.js.map +1 -1
- package/build/entity-types/sidebar.js.map +1 -1
- package/build/entity-types/taxonomy.js.map +1 -1
- package/build/entity-types/theme.js.map +1 -1
- package/build/entity-types/type.js.map +1 -1
- package/build/entity-types/user.js.map +1 -1
- package/build/entity-types/widget-type.js.map +1 -1
- package/build/entity-types/widget.js.map +1 -1
- package/build/entity-types/wp-template-part.js.map +1 -1
- package/build/entity-types/wp-template.js.map +1 -1
- package/build/fetch/__experimental-fetch-link-suggestions.js +14 -20
- package/build/fetch/__experimental-fetch-link-suggestions.js.map +1 -1
- package/build/fetch/__experimental-fetch-url-data.js +4 -13
- package/build/fetch/__experimental-fetch-url-data.js.map +1 -1
- package/build/fetch/index.js +0 -3
- package/build/fetch/index.js.map +1 -1
- package/build/hooks/constants.js +4 -5
- package/build/hooks/constants.js.map +1 -1
- package/build/hooks/index.js +0 -5
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/memoize.js +0 -3
- package/build/hooks/memoize.js.map +1 -1
- package/build/hooks/use-entity-record.js +0 -9
- package/build/hooks/use-entity-record.js.map +1 -1
- package/build/hooks/use-entity-records.js +2 -9
- package/build/hooks/use-entity-records.js.map +1 -1
- package/build/hooks/use-query-select.js +1 -13
- package/build/hooks/use-query-select.js.map +1 -1
- package/build/hooks/use-resource-permissions.js +0 -15
- package/build/hooks/use-resource-permissions.js.map +1 -1
- package/build/index.js +9 -41
- package/build/index.js.map +1 -1
- package/build/locks/actions.js +1 -6
- package/build/locks/actions.js.map +1 -1
- package/build/locks/engine.js +1 -9
- package/build/locks/engine.js.map +1 -1
- package/build/locks/reducer.js +8 -9
- package/build/locks/reducer.js.map +1 -1
- package/build/locks/selectors.js +8 -11
- package/build/locks/selectors.js.map +1 -1
- package/build/locks/utils.js +4 -19
- package/build/locks/utils.js.map +1 -1
- package/build/name.js +0 -1
- package/build/name.js.map +1 -1
- package/build/private-apis.js +1 -2
- package/build/private-apis.js.map +1 -1
- package/build/private-selectors.js +2 -5
- package/build/private-selectors.js.map +1 -1
- package/build/queried-data/actions.js +4 -6
- package/build/queried-data/actions.js.map +1 -1
- package/build/queried-data/get-query-parts.js +11 -24
- package/build/queried-data/get-query-parts.js.map +1 -1
- package/build/queried-data/index.js +0 -6
- package/build/queried-data/index.js.map +1 -1
- package/build/queried-data/reducer.js +33 -51
- package/build/queried-data/reducer.js.map +1 -1
- package/build/queried-data/selectors.js +4 -25
- package/build/queried-data/selectors.js.map +1 -1
- package/build/reducer.js +76 -128
- package/build/reducer.js.map +1 -1
- package/build/resolvers.js +91 -133
- package/build/resolvers.js.map +1 -1
- package/build/selectors.js +51 -145
- package/build/selectors.js.map +1 -1
- package/build/sync.js +19 -0
- package/build/sync.js.map +1 -0
- package/build/types.js.map +1 -1
- package/build/utils/conservative-map-item.js +3 -10
- package/build/utils/conservative-map-item.js.map +1 -1
- package/build/utils/forward-resolver.js +0 -2
- package/build/utils/forward-resolver.js.map +1 -1
- package/build/utils/get-normalized-comma-separable.js +0 -3
- package/build/utils/get-normalized-comma-separable.js.map +1 -1
- package/build/utils/if-matching-action.js +0 -3
- package/build/utils/if-matching-action.js.map +1 -1
- package/build/utils/index.js +0 -10
- package/build/utils/index.js.map +1 -1
- package/build/utils/is-raw-attribute.js +0 -1
- package/build/utils/is-raw-attribute.js.map +1 -1
- package/build/utils/on-sub-key.js +5 -9
- package/build/utils/on-sub-key.js.map +1 -1
- package/build/utils/replace-action.js +0 -2
- package/build/utils/replace-action.js.map +1 -1
- package/build/utils/set-nested-value.js +0 -4
- package/build/utils/set-nested-value.js.map +1 -1
- package/build/utils/with-weak-map-cache.js +3 -6
- package/build/utils/with-weak-map-cache.js.map +1 -1
- package/build-module/actions.js +73 -96
- package/build-module/actions.js.map +1 -1
- package/build-module/batch/create-batch.js +1 -20
- package/build-module/batch/create-batch.js.map +1 -1
- package/build-module/batch/default-processor.js +4 -13
- package/build-module/batch/default-processor.js.map +1 -1
- package/build-module/batch/index.js.map +1 -1
- package/build-module/entities.js +109 -25
- package/build-module/entities.js.map +1 -1
- package/build-module/entity-provider.js +35 -45
- package/build-module/entity-provider.js.map +1 -1
- package/build-module/entity-types/attachment.js.map +1 -1
- package/build-module/entity-types/base-entity-records.js +0 -2
- package/build-module/entity-types/base-entity-records.js.map +1 -1
- package/build-module/entity-types/comment.js.map +1 -1
- package/build-module/entity-types/helpers.js.map +1 -1
- package/build-module/entity-types/index.js.map +1 -1
- package/build-module/entity-types/menu-location.js.map +1 -1
- package/build-module/entity-types/nav-menu-item.js.map +1 -1
- package/build-module/entity-types/nav-menu.js.map +1 -1
- package/build-module/entity-types/page.js.map +1 -1
- package/build-module/entity-types/plugin.js.map +1 -1
- package/build-module/entity-types/post.js.map +1 -1
- package/build-module/entity-types/settings.js.map +1 -1
- package/build-module/entity-types/sidebar.js.map +1 -1
- package/build-module/entity-types/taxonomy.js.map +1 -1
- package/build-module/entity-types/theme.js.map +1 -1
- package/build-module/entity-types/type.js.map +1 -1
- package/build-module/entity-types/user.js.map +1 -1
- package/build-module/entity-types/widget-type.js.map +1 -1
- package/build-module/entity-types/widget.js.map +1 -1
- package/build-module/entity-types/wp-template-part.js.map +1 -1
- package/build-module/entity-types/wp-template.js.map +1 -1
- package/build-module/fetch/__experimental-fetch-link-suggestions.js +15 -15
- package/build-module/fetch/__experimental-fetch-link-suggestions.js.map +1 -1
- package/build-module/fetch/__experimental-fetch-url-data.js +5 -10
- package/build-module/fetch/__experimental-fetch-url-data.js.map +1 -1
- package/build-module/fetch/index.js.map +1 -1
- package/build-module/hooks/constants.js +3 -4
- package/build-module/hooks/constants.js.map +1 -1
- package/build-module/hooks/index.js.map +1 -1
- package/build-module/hooks/memoize.js +2 -1
- package/build-module/hooks/memoize.js.map +1 -1
- package/build-module/hooks/use-entity-record.js +1 -3
- package/build-module/hooks/use-entity-record.js.map +1 -1
- package/build-module/hooks/use-entity-records.js +2 -3
- package/build-module/hooks/use-entity-records.js.map +1 -1
- package/build-module/hooks/use-query-select.js +1 -9
- package/build-module/hooks/use-query-select.js.map +1 -1
- package/build-module/hooks/use-resource-permissions.js +1 -10
- package/build-module/hooks/use-resource-permissions.js.map +1 -1
- package/build-module/index.js +11 -19
- package/build-module/index.js.map +1 -1
- package/build-module/locks/actions.js +0 -3
- package/build-module/locks/actions.js.map +1 -1
- package/build-module/locks/engine.js +0 -5
- package/build-module/locks/engine.js.map +1 -1
- package/build-module/locks/reducer.js +7 -7
- package/build-module/locks/reducer.js.map +1 -1
- package/build-module/locks/selectors.js +7 -8
- package/build-module/locks/selectors.js.map +1 -1
- package/build-module/locks/utils.js +4 -14
- package/build-module/locks/utils.js.map +1 -1
- package/build-module/name.js.map +1 -1
- package/build-module/private-apis.js.map +1 -1
- package/build-module/private-selectors.js +2 -2
- package/build-module/private-selectors.js.map +1 -1
- package/build-module/queried-data/actions.js +4 -3
- package/build-module/queried-data/actions.js.map +1 -1
- package/build-module/queried-data/get-query-parts.js +13 -21
- package/build-module/queried-data/get-query-parts.js.map +1 -1
- package/build-module/queried-data/index.js.map +1 -1
- package/build-module/queried-data/reducer.js +33 -42
- package/build-module/queried-data/reducer.js.map +1 -1
- package/build-module/queried-data/selectors.js +6 -21
- package/build-module/queried-data/selectors.js.map +1 -1
- package/build-module/reducer.js +79 -104
- package/build-module/reducer.js.map +1 -1
- package/build-module/resolvers.js +94 -96
- package/build-module/resolvers.js.map +1 -1
- package/build-module/selectors.js +56 -92
- package/build-module/selectors.js.map +1 -1
- package/build-module/sync.js +12 -0
- package/build-module/sync.js.map +1 -0
- package/build-module/types.js.map +1 -1
- package/build-module/utils/conservative-map-item.js +4 -8
- package/build-module/utils/conservative-map-item.js.map +1 -1
- package/build-module/utils/forward-resolver.js +0 -1
- package/build-module/utils/forward-resolver.js.map +1 -1
- package/build-module/utils/get-normalized-comma-separable.js +0 -2
- package/build-module/utils/get-normalized-comma-separable.js.map +1 -1
- package/build-module/utils/if-matching-action.js +0 -2
- package/build-module/utils/if-matching-action.js.map +1 -1
- package/build-module/utils/index.js.map +1 -1
- package/build-module/utils/is-raw-attribute.js.map +1 -1
- package/build-module/utils/on-sub-key.js +5 -7
- package/build-module/utils/on-sub-key.js.map +1 -1
- package/build-module/utils/replace-action.js +0 -1
- package/build-module/utils/replace-action.js.map +1 -1
- package/build-module/utils/set-nested-value.js +0 -3
- package/build-module/utils/set-nested-value.js.map +1 -1
- package/build-module/utils/with-weak-map-cache.js +3 -5
- package/build-module/utils/with-weak-map-cache.js.map +1 -1
- package/build-types/actions.d.ts.map +1 -1
- package/build-types/entities.d.ts +53 -0
- package/build-types/entities.d.ts.map +1 -1
- package/build-types/entity-provider.d.ts +1 -1
- package/build-types/entity-provider.d.ts.map +1 -1
- package/build-types/hooks/memoize.d.ts +1 -1
- package/build-types/hooks/memoize.d.ts.map +1 -1
- package/build-types/index.d.ts +4 -4
- package/build-types/index.d.ts.map +1 -1
- 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/sync.d.ts +2 -0
- package/build-types/sync.d.ts.map +1 -0
- package/package.json +17 -15
- package/src/actions.js +30 -17
- package/src/entities.js +91 -0
- package/src/entity-provider.js +11 -2
- package/src/resolvers.js +89 -41
- package/src/selectors.ts +1 -1
- package/src/sync.js +18 -0
- package/src/test/entity-provider.js +272 -0
- package/tsconfig.json +1 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/resolvers.js
CHANGED
|
@@ -15,6 +15,7 @@ import apiFetch from '@wordpress/api-fetch';
|
|
|
15
15
|
import { STORE_NAME } from './name';
|
|
16
16
|
import { getOrLoadEntitiesConfig, DEFAULT_ENTITY_KEY } from './entities';
|
|
17
17
|
import { forwardResolver, getNormalizedCommaSeparable } from './utils';
|
|
18
|
+
import { getSyncProvider } from './sync';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Requests authors from the REST API.
|
|
@@ -71,51 +72,98 @@ export const getEntityRecord =
|
|
|
71
72
|
);
|
|
72
73
|
|
|
73
74
|
try {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
75
|
+
// Entity supports configs,
|
|
76
|
+
// use the sync algorithm instead of the old fetch behavior.
|
|
77
|
+
if (
|
|
78
|
+
window.__experimentalEnableSync &&
|
|
79
|
+
entityConfig.syncConfig &&
|
|
80
|
+
! query
|
|
81
|
+
) {
|
|
82
|
+
const objectId = entityConfig.getSyncObjectId( key );
|
|
83
|
+
|
|
84
|
+
// Loads the persisted document.
|
|
85
|
+
await getSyncProvider().bootstrap(
|
|
86
|
+
entityConfig.syncObjectType,
|
|
87
|
+
objectId,
|
|
88
|
+
( record ) => {
|
|
89
|
+
dispatch.receiveEntityRecords(
|
|
90
|
+
kind,
|
|
91
|
+
name,
|
|
92
|
+
record,
|
|
93
|
+
query
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// Boostraps the edited document as well (and load from peers).
|
|
99
|
+
await getSyncProvider().bootstrap(
|
|
100
|
+
entityConfig.syncObjectType + '--edit',
|
|
101
|
+
objectId,
|
|
102
|
+
( record ) => {
|
|
103
|
+
dispatch( {
|
|
104
|
+
type: 'EDIT_ENTITY_RECORD',
|
|
105
|
+
kind,
|
|
106
|
+
name,
|
|
107
|
+
recordId: key,
|
|
108
|
+
edits: record,
|
|
109
|
+
meta: {
|
|
110
|
+
undo: undefined,
|
|
111
|
+
},
|
|
112
|
+
} );
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
} else {
|
|
116
|
+
if ( query !== undefined && query._fields ) {
|
|
117
|
+
// If requesting specific fields, items and query association to said
|
|
118
|
+
// records are stored by ID reference. Thus, fields must always include
|
|
119
|
+
// the ID.
|
|
120
|
+
query = {
|
|
121
|
+
...query,
|
|
122
|
+
_fields: [
|
|
123
|
+
...new Set( [
|
|
124
|
+
...( getNormalizedCommaSeparable(
|
|
125
|
+
query._fields
|
|
126
|
+
) || [] ),
|
|
127
|
+
entityConfig.key || DEFAULT_ENTITY_KEY,
|
|
128
|
+
] ),
|
|
129
|
+
].join(),
|
|
130
|
+
};
|
|
102
131
|
}
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
if ( query !== undefined ) {
|
|
106
|
-
query = { ...query, include: [ key ] };
|
|
107
132
|
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
133
|
+
// Disable reason: While true that an early return could leave `path`
|
|
134
|
+
// unused, it's important that path is derived using the query prior to
|
|
135
|
+
// additional query modifications in the condition below, since those
|
|
136
|
+
// modifications are relevant to how the data is tracked in state, and not
|
|
137
|
+
// for how the request is made to the REST API.
|
|
138
|
+
|
|
139
|
+
// eslint-disable-next-line @wordpress/no-unused-vars-before-return
|
|
140
|
+
const path = addQueryArgs(
|
|
141
|
+
entityConfig.baseURL + ( key ? '/' + key : '' ),
|
|
142
|
+
{
|
|
143
|
+
...entityConfig.baseURLParams,
|
|
144
|
+
...query,
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
if ( query !== undefined ) {
|
|
149
|
+
query = { ...query, include: [ key ] };
|
|
150
|
+
|
|
151
|
+
// The resolution cache won't consider query as reusable based on the
|
|
152
|
+
// fields, so it's tested here, prior to initiating the REST request,
|
|
153
|
+
// and without causing `getEntityRecords` resolution to occur.
|
|
154
|
+
const hasRecords = select.hasEntityRecords(
|
|
155
|
+
kind,
|
|
156
|
+
name,
|
|
157
|
+
query
|
|
158
|
+
);
|
|
159
|
+
if ( hasRecords ) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
114
162
|
}
|
|
115
|
-
}
|
|
116
163
|
|
|
117
|
-
|
|
118
|
-
|
|
164
|
+
const record = await apiFetch( { path } );
|
|
165
|
+
dispatch.receiveEntityRecords( kind, name, record, query );
|
|
166
|
+
}
|
|
119
167
|
} finally {
|
|
120
168
|
dispatch.__unstableReleaseStoreLock( lock );
|
|
121
169
|
}
|
package/src/selectors.ts
CHANGED
|
@@ -1266,7 +1266,7 @@ export function getBlockPatternCategories( state: State ): Array< any > {
|
|
|
1266
1266
|
*/
|
|
1267
1267
|
export function getCurrentThemeGlobalStylesRevisions(
|
|
1268
1268
|
state: State
|
|
1269
|
-
):
|
|
1269
|
+
): Array< object > | null {
|
|
1270
1270
|
const currentGlobalStylesId =
|
|
1271
1271
|
__experimentalGetCurrentGlobalStylesId( state );
|
|
1272
1272
|
|
package/src/sync.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
createSyncProvider,
|
|
6
|
+
connectIndexDb,
|
|
7
|
+
connectWebRTC,
|
|
8
|
+
} from '@wordpress/sync';
|
|
9
|
+
|
|
10
|
+
let syncProvider;
|
|
11
|
+
|
|
12
|
+
export function getSyncProvider() {
|
|
13
|
+
if ( ! syncProvider ) {
|
|
14
|
+
syncProvider = createSyncProvider( connectIndexDb, connectWebRTC );
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return syncProvider;
|
|
18
|
+
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { act, render } from '@testing-library/react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import {
|
|
10
|
+
createBlock,
|
|
11
|
+
registerBlockType,
|
|
12
|
+
unregisterBlockType,
|
|
13
|
+
getBlockTypes,
|
|
14
|
+
} from '@wordpress/blocks';
|
|
15
|
+
import { RichText, useBlockProps } from '@wordpress/block-editor';
|
|
16
|
+
import { createRegistry, RegistryProvider } from '@wordpress/data';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Internal dependencies
|
|
20
|
+
*/
|
|
21
|
+
import { store as coreDataStore } from '../index';
|
|
22
|
+
import { useEntityBlockEditor } from '../entity-provider';
|
|
23
|
+
|
|
24
|
+
const postTypeConfig = {
|
|
25
|
+
kind: 'postType',
|
|
26
|
+
name: 'post',
|
|
27
|
+
baseURL: '/wp/v2/posts',
|
|
28
|
+
transientEdits: { blocks: true, selection: true },
|
|
29
|
+
mergedEdits: { meta: true },
|
|
30
|
+
rawAttributes: [ 'title', 'excerpt', 'content' ],
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const postTypeEntity = {
|
|
34
|
+
slug: 'post',
|
|
35
|
+
rest_base: 'posts',
|
|
36
|
+
labels: {
|
|
37
|
+
item_updated: 'Updated Post',
|
|
38
|
+
item_published: 'Post published',
|
|
39
|
+
item_reverted_to_draft: 'Post reverted to draft.',
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const aSinglePost = {
|
|
44
|
+
id: 1,
|
|
45
|
+
type: 'post',
|
|
46
|
+
content: {
|
|
47
|
+
raw: '<!-- wp:test-block-with-array-of-strings --><div><p>apples</p><p></p><p>oranges</p></div><!-- /wp:test-block-with-array-of-strings --><!-- wp:test-block --><p>A paragraph</p><!-- /wp:test-block -->',
|
|
48
|
+
rendered: '<p>A paragraph</p>',
|
|
49
|
+
},
|
|
50
|
+
meta: {
|
|
51
|
+
footnotes: '[]',
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
function createRegistryWithStores() {
|
|
56
|
+
// Create a registry.
|
|
57
|
+
const registry = createRegistry();
|
|
58
|
+
|
|
59
|
+
// Register store.
|
|
60
|
+
registry.register( coreDataStore );
|
|
61
|
+
|
|
62
|
+
// Register post type entity.
|
|
63
|
+
registry.dispatch( coreDataStore ).addEntities( [ postTypeConfig ] );
|
|
64
|
+
|
|
65
|
+
// Store post type entity.
|
|
66
|
+
registry
|
|
67
|
+
.dispatch( coreDataStore )
|
|
68
|
+
.receiveEntityRecords( 'root', 'postType', [ postTypeEntity ] );
|
|
69
|
+
|
|
70
|
+
// Store a single post for use by the tests.
|
|
71
|
+
registry
|
|
72
|
+
.dispatch( coreDataStore )
|
|
73
|
+
.receiveEntityRecords( 'postType', 'post', [ aSinglePost ] );
|
|
74
|
+
|
|
75
|
+
return registry;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
describe( 'useEntityBlockEditor', () => {
|
|
79
|
+
let registry;
|
|
80
|
+
|
|
81
|
+
beforeEach( () => {
|
|
82
|
+
registry = createRegistryWithStores();
|
|
83
|
+
|
|
84
|
+
const edit = ( { children } ) => <>{ children }</>;
|
|
85
|
+
|
|
86
|
+
registerBlockType( 'core/test-block', {
|
|
87
|
+
supports: {
|
|
88
|
+
className: false,
|
|
89
|
+
},
|
|
90
|
+
save: ( { attributes } ) => {
|
|
91
|
+
const { content } = attributes;
|
|
92
|
+
return (
|
|
93
|
+
<p { ...useBlockProps.save() }>
|
|
94
|
+
<RichText.Content value={ content } />
|
|
95
|
+
</p>
|
|
96
|
+
);
|
|
97
|
+
},
|
|
98
|
+
category: 'text',
|
|
99
|
+
attributes: {
|
|
100
|
+
content: {
|
|
101
|
+
type: 'string',
|
|
102
|
+
source: 'html',
|
|
103
|
+
selector: 'p',
|
|
104
|
+
default: '',
|
|
105
|
+
__experimentalRole: 'content',
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
title: 'block title',
|
|
109
|
+
edit,
|
|
110
|
+
} );
|
|
111
|
+
|
|
112
|
+
registerBlockType( 'core/test-block-with-array-of-strings', {
|
|
113
|
+
supports: {
|
|
114
|
+
className: false,
|
|
115
|
+
},
|
|
116
|
+
save: ( { attributes } ) => {
|
|
117
|
+
const { items } = attributes;
|
|
118
|
+
return (
|
|
119
|
+
<div>
|
|
120
|
+
{ items.map( ( item, index ) => (
|
|
121
|
+
<p key={ index }>{ item }</p>
|
|
122
|
+
) ) }
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
125
|
+
},
|
|
126
|
+
category: 'text',
|
|
127
|
+
attributes: {
|
|
128
|
+
items: {
|
|
129
|
+
type: 'array',
|
|
130
|
+
items: {
|
|
131
|
+
type: 'string',
|
|
132
|
+
},
|
|
133
|
+
default: [ 'apples', null, 'oranges' ],
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
title: 'block title',
|
|
137
|
+
edit,
|
|
138
|
+
} );
|
|
139
|
+
} );
|
|
140
|
+
|
|
141
|
+
afterEach( () => {
|
|
142
|
+
getBlockTypes().forEach( ( block ) => {
|
|
143
|
+
unregisterBlockType( block.name );
|
|
144
|
+
} );
|
|
145
|
+
} );
|
|
146
|
+
|
|
147
|
+
it( 'does not mutate block attributes that include an array of strings or null values', async () => {
|
|
148
|
+
let blocks, onChange;
|
|
149
|
+
const TestComponent = () => {
|
|
150
|
+
[ blocks, , onChange ] = useEntityBlockEditor( 'postType', 'post', {
|
|
151
|
+
id: 1,
|
|
152
|
+
} );
|
|
153
|
+
|
|
154
|
+
return <div />;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
render(
|
|
158
|
+
<RegistryProvider value={ registry }>
|
|
159
|
+
<TestComponent />
|
|
160
|
+
</RegistryProvider>
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
expect( blocks[ 0 ].name ).toEqual(
|
|
164
|
+
'core/test-block-with-array-of-strings'
|
|
165
|
+
);
|
|
166
|
+
expect( blocks[ 0 ].attributes.items ).toEqual( [
|
|
167
|
+
'apples',
|
|
168
|
+
null,
|
|
169
|
+
'oranges',
|
|
170
|
+
] );
|
|
171
|
+
|
|
172
|
+
// Add a block with content that will match against footnotes logic, causing
|
|
173
|
+
// `updateFootnotes` to iterate over blocks and their attributes.
|
|
174
|
+
act( () => {
|
|
175
|
+
onChange(
|
|
176
|
+
[
|
|
177
|
+
...blocks,
|
|
178
|
+
createBlock( 'core/test-block', {
|
|
179
|
+
content:
|
|
180
|
+
'<p><sup data-fn="1234" class="fn"><a href="#1234" id="1234-link">1</a></sup></p>',
|
|
181
|
+
} ),
|
|
182
|
+
],
|
|
183
|
+
{
|
|
184
|
+
selection: {
|
|
185
|
+
selectionStart: {},
|
|
186
|
+
selectionEnd: {},
|
|
187
|
+
initialPosition: {},
|
|
188
|
+
},
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
} );
|
|
192
|
+
|
|
193
|
+
// Ensure the first block remains the same, with unaltered attributes.
|
|
194
|
+
expect( blocks[ 0 ].name ).toEqual(
|
|
195
|
+
'core/test-block-with-array-of-strings'
|
|
196
|
+
);
|
|
197
|
+
expect( blocks[ 0 ].attributes.items ).toEqual( [
|
|
198
|
+
'apples',
|
|
199
|
+
null,
|
|
200
|
+
'oranges',
|
|
201
|
+
] );
|
|
202
|
+
} );
|
|
203
|
+
|
|
204
|
+
it( 'updates the order of footnotes when a new footnote is inserted', async () => {
|
|
205
|
+
// Start with a post containing a block with a single footnote (set to 1).
|
|
206
|
+
registry
|
|
207
|
+
.dispatch( coreDataStore )
|
|
208
|
+
.receiveEntityRecords( 'postType', 'post', [
|
|
209
|
+
{
|
|
210
|
+
id: 1,
|
|
211
|
+
type: 'post',
|
|
212
|
+
content: {
|
|
213
|
+
raw: '<!-- wp:test-block --><p>A paragraph<sup data-fn="abcd" class="fn"><a href="#abcd" id="abcd-link">1</a></sup></p><!-- /wp:test-block -->',
|
|
214
|
+
rendered: '<p>A paragraph</p>',
|
|
215
|
+
},
|
|
216
|
+
meta: {
|
|
217
|
+
footnotes: '[]',
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
] );
|
|
221
|
+
|
|
222
|
+
let blocks, onChange;
|
|
223
|
+
|
|
224
|
+
const TestComponent = () => {
|
|
225
|
+
[ blocks, , onChange ] = useEntityBlockEditor( 'postType', 'post', {
|
|
226
|
+
id: 1,
|
|
227
|
+
} );
|
|
228
|
+
|
|
229
|
+
return <div />;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
render(
|
|
233
|
+
<RegistryProvider value={ registry }>
|
|
234
|
+
<TestComponent />
|
|
235
|
+
</RegistryProvider>
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
// The first block should have the footnote number 1.
|
|
239
|
+
expect( blocks[ 0 ].attributes.content ).toEqual(
|
|
240
|
+
'A paragraph<sup data-fn="abcd" class="fn"><a href="#abcd" id="abcd-link">1</a></sup>'
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
// Add a block with a new footnote with an arbitrary footnote number that will be overwritten after insertion.
|
|
244
|
+
act( () => {
|
|
245
|
+
onChange(
|
|
246
|
+
[
|
|
247
|
+
createBlock( 'core/test-block', {
|
|
248
|
+
content:
|
|
249
|
+
'A new paragraph<sup data-fn="xyz" class="xyz"><a href="#xyz" id="xyz-link">999</a></sup>',
|
|
250
|
+
} ),
|
|
251
|
+
...blocks,
|
|
252
|
+
],
|
|
253
|
+
{
|
|
254
|
+
selection: {
|
|
255
|
+
selectionStart: {},
|
|
256
|
+
selectionEnd: {},
|
|
257
|
+
initialPosition: {},
|
|
258
|
+
},
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
} );
|
|
262
|
+
|
|
263
|
+
// The newly inserted block should have the footnote number 1, and the
|
|
264
|
+
// existing footnote number 1 should be updated to 2.
|
|
265
|
+
expect( blocks[ 0 ].attributes.content ).toEqual(
|
|
266
|
+
'A new paragraph<sup data-fn="xyz" class="xyz"><a href="#xyz" id="xyz-link">1</a></sup>'
|
|
267
|
+
);
|
|
268
|
+
expect( blocks[ 1 ].attributes.content ).toEqual(
|
|
269
|
+
'A paragraph<sup data-fn="abcd" class="fn"><a href="#abcd" id="abcd-link">2</a></sup>'
|
|
270
|
+
);
|
|
271
|
+
} );
|
|
272
|
+
} );
|