@wordpress/reusable-blocks 3.0.1 → 3.0.5

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.
@@ -1,17 +1,271 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { createRegistry } from '@wordpress/data';
5
+ import { store as blockEditorStore } from '@wordpress/block-editor';
6
+ import {
7
+ store as blocksStore,
8
+ createBlock,
9
+ registerBlockType,
10
+ unregisterBlockType,
11
+ } from '@wordpress/blocks';
12
+
13
+ import { store as coreStore } from '@wordpress/core-data';
14
+ import apiFetch from '@wordpress/api-fetch';
15
+
1
16
  /**
2
17
  * Internal dependencies
3
18
  */
4
- import { __experimentalSetEditingReusableBlock } from '../actions';
19
+ import { store as reusableBlocksStore } from '../index';
20
+
21
+ jest.mock( '@wordpress/api-fetch', () => ( {
22
+ __esModule: true,
23
+ default: jest.fn(),
24
+ } ) );
25
+
26
+ function createRegistryWithStores() {
27
+ // create a registry and register stores
28
+ const registry = createRegistry();
29
+
30
+ registry.register( coreStore );
31
+ registry.register( blockEditorStore );
32
+ registry.register( reusableBlocksStore );
33
+ registry.register( blocksStore );
34
+
35
+ // Register entity here instead of mocking API handlers for loadPostTypeEntities()
36
+ registry.dispatch( coreStore ).addEntities( [
37
+ {
38
+ baseURL: '/wp/v2/reusable-blocks',
39
+ kind: 'postType',
40
+ name: 'wp_block',
41
+ label: 'Reusable blocks',
42
+ },
43
+ ] );
44
+
45
+ return registry;
46
+ }
5
47
 
6
48
  describe( 'Actions', () => {
49
+ beforeAll( () => {
50
+ registerBlockType( 'core/test-block', {
51
+ title: 'Test block',
52
+ category: 'text',
53
+ save: () => null,
54
+ attributes: {
55
+ name: { type: 'string' },
56
+ },
57
+ } );
58
+
59
+ registerBlockType( 'core/block', {
60
+ title: 'Reusable block',
61
+ category: 'text',
62
+ save: () => null,
63
+ attributes: {
64
+ ref: { type: 'string' },
65
+ },
66
+ } );
67
+ } );
68
+
69
+ afterAll( () => {
70
+ unregisterBlockType( 'core/test-block' );
71
+ unregisterBlockType( 'core/block' );
72
+ } );
73
+
7
74
  describe( '__experimentalSetEditingReusableBlock', () => {
8
- it( 'should return the SET_EDITING_REUSABLE_BLOCK action', () => {
9
- const result = __experimentalSetEditingReusableBlock( 3, true );
10
- expect( result ).toEqual( {
11
- type: 'SET_EDITING_REUSABLE_BLOCK',
12
- clientId: 3,
13
- isEditing: true,
75
+ it( 'should flip the editing state', () => {
76
+ const registry = createRegistryWithStores();
77
+
78
+ registry
79
+ .dispatch( reusableBlocksStore )
80
+ .__experimentalSetEditingReusableBlock( 3, true );
81
+ expect(
82
+ registry
83
+ .select( reusableBlocksStore )
84
+ .__experimentalIsEditingReusableBlock( 3 )
85
+ ).toBe( true );
86
+
87
+ registry
88
+ .dispatch( reusableBlocksStore )
89
+ .__experimentalSetEditingReusableBlock( 3, false );
90
+ expect(
91
+ registry
92
+ .select( reusableBlocksStore )
93
+ .__experimentalIsEditingReusableBlock( 3 )
94
+ ).toBe( false );
95
+ } );
96
+ } );
97
+
98
+ describe( '__experimentalConvertBlocksToReusable', () => {
99
+ it( 'should convert a static block into a reusable block', async () => {
100
+ const staticBlock = createBlock( 'core/test-block', {
101
+ name: 'Big Bird',
14
102
  } );
103
+
104
+ const registry = createRegistryWithStores();
105
+ // mock the api-fetch
106
+ apiFetch.mockImplementation( async ( args ) => {
107
+ const { path, data } = args;
108
+ switch ( path ) {
109
+ case '/wp/v2/reusable-blocks':
110
+ return {
111
+ id: 'new-id',
112
+ ...data,
113
+ };
114
+ default:
115
+ throw new Error( `unexpected API endpoint: ${ path }` );
116
+ }
117
+ } );
118
+
119
+ registry.dispatch( blockEditorStore ).insertBlock( staticBlock );
120
+
121
+ await registry
122
+ .dispatch( reusableBlocksStore )
123
+ .__experimentalConvertBlocksToReusable( [
124
+ staticBlock.clientId,
125
+ ] );
126
+
127
+ // check that blocks were converted to reusable
128
+ const updatedBlocks = registry
129
+ .select( blockEditorStore )
130
+ .getBlocks();
131
+
132
+ const newClientId = updatedBlocks[ 0 ].clientId;
133
+
134
+ expect( updatedBlocks ).toHaveLength( 1 );
135
+
136
+ // Delete random clientId before matching with snapshot
137
+ delete updatedBlocks[ 0 ].clientId;
138
+ expect( updatedBlocks ).toMatchSnapshot();
139
+
140
+ expect(
141
+ registry
142
+ .select( reusableBlocksStore )
143
+ .__experimentalIsEditingReusableBlock( newClientId )
144
+ ).toBe( true );
145
+ } );
146
+ } );
147
+
148
+ describe( '__experimentalConvertBlockToStatic', () => {
149
+ it( 'should convert a static reusable into a static block', async () => {
150
+ const associatedBlock = createBlock( 'core/block', {
151
+ ref: 123,
152
+ } );
153
+ const reusableBlock = {
154
+ id: 123,
155
+ title: 'My cool block',
156
+ content:
157
+ '<!-- wp:test-block {"name":"Big Bird"} --><!-- wp:test-block {"name":"Oscar the Grouch"} /--><!-- wp:test-block {"name":"Cookie Monster"} /--><!-- /wp:test-block -->',
158
+ };
159
+
160
+ const registry = createRegistryWithStores();
161
+ // mock the api-fetch
162
+ apiFetch.mockImplementation( async ( args ) => {
163
+ const { path, data } = args;
164
+ switch ( path ) {
165
+ case '/wp/v2/reusable-blocks/123':
166
+ return data;
167
+ default:
168
+ throw new Error( `unexpected API endpoint: ${ path }` );
169
+ }
170
+ } );
171
+
172
+ registry
173
+ .dispatch( blockEditorStore )
174
+ .insertBlock( associatedBlock );
175
+ await registry
176
+ .dispatch( coreStore )
177
+ .saveEntityRecord( 'postType', 'wp_block', reusableBlock );
178
+
179
+ await registry
180
+ .dispatch( reusableBlocksStore )
181
+ .__experimentalConvertBlockToStatic( [
182
+ associatedBlock.clientId,
183
+ ] );
184
+
185
+ // check that blocks were converted to reusable
186
+ const updatedBlocks = registry
187
+ .select( blockEditorStore )
188
+ .getBlocks();
189
+
190
+ expect( updatedBlocks ).toHaveLength( 1 );
191
+
192
+ // Delete random clientIds before matching with snapshot
193
+ delete updatedBlocks[ 0 ].clientId;
194
+ delete updatedBlocks[ 0 ].innerBlocks[ 0 ].clientId;
195
+ delete updatedBlocks[ 0 ].innerBlocks[ 1 ].clientId;
196
+ expect( updatedBlocks ).toMatchSnapshot();
197
+ } );
198
+ } );
199
+
200
+ describe( '__experimentalDeleteReusableBlock', () => {
201
+ it( 'should delete a reusable block and remove all its instances from the store', async () => {
202
+ const reusableBlock = {
203
+ id: 123,
204
+ };
205
+ const availableBlocks = [
206
+ createBlock( 'core/block' ),
207
+ createBlock( 'core/block', {
208
+ ref: 123,
209
+ } ),
210
+ createBlock( 'core/block', {
211
+ ref: 456,
212
+ } ),
213
+ createBlock( 'core/block', {
214
+ ref: 123,
215
+ } ),
216
+ createBlock( 'core/test-block', {
217
+ ref: 123,
218
+ } ),
219
+ ];
220
+
221
+ const registry = createRegistryWithStores();
222
+ // mock the api-fetch
223
+ apiFetch.mockImplementation( async ( args ) => {
224
+ const { path, data, method } = args;
225
+ if (
226
+ path.startsWith( '/wp/v2/reusable-blocks' ) &&
227
+ method === 'DELETE'
228
+ ) {
229
+ return data;
230
+ } else if (
231
+ path === '/wp/v2/reusable-blocks/123' &&
232
+ method === 'PUT'
233
+ ) {
234
+ return data;
235
+ }
236
+ throw new Error(
237
+ `unexpected API request: ${ path } ${ method }`
238
+ );
239
+ } );
240
+
241
+ await registry
242
+ .dispatch( coreStore )
243
+ .saveEntityRecord( 'postType', 'wp_block', reusableBlock );
244
+
245
+ registry
246
+ .dispatch( blockEditorStore )
247
+ .insertBlocks( availableBlocks );
248
+
249
+ // confirm that reusable block is stored
250
+ const reusableBlockBefore = registry
251
+ .select( coreStore )
252
+ .getEntityRecord( 'postType', 'wp_block', reusableBlock.id );
253
+
254
+ expect( reusableBlockBefore ).toBeTruthy();
255
+
256
+ await registry
257
+ .dispatch( reusableBlocksStore )
258
+ .__experimentalDeleteReusableBlock( reusableBlock.id );
259
+
260
+ // check if reusable block was deleted
261
+ const reusableBlockAfter = registry
262
+ .select( coreStore )
263
+ .getEntityRecord( 'postType', 'wp_block', reusableBlock.id );
264
+ expect( reusableBlockAfter ).toBeFalsy();
265
+
266
+ // check if block instances were removed from the editor
267
+ const blocksAfter = registry.select( blockEditorStore ).getBlocks();
268
+ expect( blocksAfter ).toHaveLength( 3 );
15
269
  } );
16
270
  } );
17
271
  } );
@@ -1,127 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.convertBlockToStatic = convertBlockToStatic;
7
- exports.convertBlocksToReusable = convertBlocksToReusable;
8
- exports.deleteReusableBlock = deleteReusableBlock;
9
- exports.default = void 0;
10
-
11
- var _lodash = require("lodash");
12
-
13
- var _blocks = require("@wordpress/blocks");
14
-
15
- var _data = require("@wordpress/data");
16
-
17
- var _i18n = require("@wordpress/i18n");
18
-
19
- var _blockEditor = require("@wordpress/block-editor");
20
-
21
- var _index = require("./index.js");
22
-
23
- /**
24
- * External dependencies
25
- */
26
-
27
- /**
28
- * WordPress dependencies
29
- */
30
-
31
- /**
32
- * Internal dependencies
33
- */
34
-
35
- /**
36
- * Convert a reusable block to a static block effect handler
37
- *
38
- * @param {string} clientId Block ID.
39
- * @return {Object} control descriptor.
40
- */
41
- function convertBlockToStatic(clientId) {
42
- return {
43
- type: 'CONVERT_BLOCK_TO_STATIC',
44
- clientId
45
- };
46
- }
47
- /**
48
- * Convert a static block to a reusable block effect handler
49
- *
50
- * @param {Array} clientIds Block IDs.
51
- * @param {string} title Reusable block title.
52
- * @return {Object} control descriptor.
53
- */
54
-
55
-
56
- function convertBlocksToReusable(clientIds, title) {
57
- return {
58
- type: 'CONVERT_BLOCKS_TO_REUSABLE',
59
- clientIds,
60
- title
61
- };
62
- }
63
- /**
64
- * Deletes a reusable block.
65
- *
66
- * @param {string} id Reusable block ID.
67
- * @return {Object} control descriptor.
68
- */
69
-
70
-
71
- function deleteReusableBlock(id) {
72
- return {
73
- type: 'DELETE_REUSABLE_BLOCK',
74
- id
75
- };
76
- }
77
-
78
- const controls = {
79
- CONVERT_BLOCK_TO_STATIC: (0, _data.createRegistryControl)(registry => ({
80
- clientId
81
- }) => {
82
- const oldBlock = registry.select(_blockEditor.store).getBlock(clientId);
83
- const reusableBlock = registry.select('core').getEditedEntityRecord('postType', 'wp_block', oldBlock.attributes.ref);
84
- const newBlocks = (0, _blocks.parse)((0, _lodash.isFunction)(reusableBlock.content) ? reusableBlock.content(reusableBlock) : reusableBlock.content);
85
- registry.dispatch(_blockEditor.store).replaceBlocks(oldBlock.clientId, newBlocks);
86
- }),
87
- CONVERT_BLOCKS_TO_REUSABLE: (0, _data.createRegistryControl)(registry => async function ({
88
- clientIds,
89
- title
90
- }) {
91
- const reusableBlock = {
92
- title: title || (0, _i18n.__)('Untitled Reusable block'),
93
- content: (0, _blocks.serialize)(registry.select(_blockEditor.store).getBlocksByClientId(clientIds)),
94
- status: 'publish'
95
- };
96
- const updatedRecord = await registry.dispatch('core').saveEntityRecord('postType', 'wp_block', reusableBlock);
97
- const newBlock = (0, _blocks.createBlock)('core/block', {
98
- ref: updatedRecord.id
99
- });
100
- registry.dispatch(_blockEditor.store).replaceBlocks(clientIds, newBlock);
101
-
102
- registry.dispatch(_index.store).__experimentalSetEditingReusableBlock(newBlock.clientId, true);
103
- }),
104
- DELETE_REUSABLE_BLOCK: (0, _data.createRegistryControl)(registry => async function ({
105
- id
106
- }) {
107
- const reusableBlock = registry.select('core').getEditedEntityRecord('postType', 'wp_block', id); // Don't allow a reusable block with a temporary ID to be deleted
108
-
109
- if (!reusableBlock) {
110
- return;
111
- } // Remove any other blocks that reference this reusable block
112
-
113
-
114
- const allBlocks = registry.select(_blockEditor.store).getBlocks();
115
- const associatedBlocks = allBlocks.filter(block => (0, _blocks.isReusableBlock)(block) && block.attributes.ref === id);
116
- const associatedBlockClientIds = associatedBlocks.map(block => block.clientId); // Remove the parsed block.
117
-
118
- if (associatedBlockClientIds.length) {
119
- registry.dispatch(_blockEditor.store).removeBlocks(associatedBlockClientIds);
120
- }
121
-
122
- await registry.dispatch('core').deleteEntityRecord('postType', 'wp_block', id);
123
- })
124
- };
125
- var _default = controls;
126
- exports.default = _default;
127
- //# sourceMappingURL=controls.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["@wordpress/reusable-blocks/src/store/controls.js"],"names":["convertBlockToStatic","clientId","type","convertBlocksToReusable","clientIds","title","deleteReusableBlock","id","controls","CONVERT_BLOCK_TO_STATIC","registry","oldBlock","select","blockEditorStore","getBlock","reusableBlock","getEditedEntityRecord","attributes","ref","newBlocks","content","dispatch","replaceBlocks","CONVERT_BLOCKS_TO_REUSABLE","getBlocksByClientId","status","updatedRecord","saveEntityRecord","newBlock","reusableBlocksStore","__experimentalSetEditingReusableBlock","DELETE_REUSABLE_BLOCK","allBlocks","getBlocks","associatedBlocks","filter","block","associatedBlockClientIds","map","length","removeBlocks","deleteEntityRecord"],"mappings":"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","sourcesContent":["/**\n * External dependencies\n */\nimport { isFunction } from 'lodash';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tisReusableBlock,\n\tcreateBlock,\n\tparse,\n\tserialize,\n} from '@wordpress/blocks';\nimport { createRegistryControl } from '@wordpress/data';\nimport { __ } from '@wordpress/i18n';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { store as reusableBlocksStore } from './index.js';\n\n/**\n * Convert a reusable block to a static block effect handler\n *\n * @param {string} clientId Block ID.\n * @return {Object} control descriptor.\n */\nexport function convertBlockToStatic( clientId ) {\n\treturn {\n\t\ttype: 'CONVERT_BLOCK_TO_STATIC',\n\t\tclientId,\n\t};\n}\n\n/**\n * Convert a static block to a reusable block effect handler\n *\n * @param {Array} clientIds Block IDs.\n * @param {string} title Reusable block title.\n * @return {Object} control descriptor.\n */\nexport function convertBlocksToReusable( clientIds, title ) {\n\treturn {\n\t\ttype: 'CONVERT_BLOCKS_TO_REUSABLE',\n\t\tclientIds,\n\t\ttitle,\n\t};\n}\n\n/**\n * Deletes a reusable block.\n *\n * @param {string} id Reusable block ID.\n * @return {Object} control descriptor.\n */\nexport function deleteReusableBlock( id ) {\n\treturn {\n\t\ttype: 'DELETE_REUSABLE_BLOCK',\n\t\tid,\n\t};\n}\n\nconst controls = {\n\tCONVERT_BLOCK_TO_STATIC: createRegistryControl(\n\t\t( registry ) => ( { clientId } ) => {\n\t\t\tconst oldBlock = registry\n\t\t\t\t.select( blockEditorStore )\n\t\t\t\t.getBlock( clientId );\n\t\t\tconst reusableBlock = registry\n\t\t\t\t.select( 'core' )\n\t\t\t\t.getEditedEntityRecord(\n\t\t\t\t\t'postType',\n\t\t\t\t\t'wp_block',\n\t\t\t\t\toldBlock.attributes.ref\n\t\t\t\t);\n\n\t\t\tconst newBlocks = parse(\n\t\t\t\tisFunction( reusableBlock.content )\n\t\t\t\t\t? reusableBlock.content( reusableBlock )\n\t\t\t\t\t: reusableBlock.content\n\t\t\t);\n\t\t\tregistry\n\t\t\t\t.dispatch( blockEditorStore )\n\t\t\t\t.replaceBlocks( oldBlock.clientId, newBlocks );\n\t\t}\n\t),\n\n\tCONVERT_BLOCKS_TO_REUSABLE: createRegistryControl(\n\t\t( registry ) =>\n\t\t\tasync function ( { clientIds, title } ) {\n\t\t\t\tconst reusableBlock = {\n\t\t\t\t\ttitle: title || __( 'Untitled Reusable block' ),\n\t\t\t\t\tcontent: serialize(\n\t\t\t\t\t\tregistry\n\t\t\t\t\t\t\t.select( blockEditorStore )\n\t\t\t\t\t\t\t.getBlocksByClientId( clientIds )\n\t\t\t\t\t),\n\t\t\t\t\tstatus: 'publish',\n\t\t\t\t};\n\n\t\t\t\tconst updatedRecord = await registry\n\t\t\t\t\t.dispatch( 'core' )\n\t\t\t\t\t.saveEntityRecord( 'postType', 'wp_block', reusableBlock );\n\n\t\t\t\tconst newBlock = createBlock( 'core/block', {\n\t\t\t\t\tref: updatedRecord.id,\n\t\t\t\t} );\n\t\t\t\tregistry\n\t\t\t\t\t.dispatch( blockEditorStore )\n\t\t\t\t\t.replaceBlocks( clientIds, newBlock );\n\t\t\t\tregistry\n\t\t\t\t\t.dispatch( reusableBlocksStore )\n\t\t\t\t\t.__experimentalSetEditingReusableBlock(\n\t\t\t\t\t\tnewBlock.clientId,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t);\n\t\t\t}\n\t),\n\n\tDELETE_REUSABLE_BLOCK: createRegistryControl(\n\t\t( registry ) =>\n\t\t\tasync function ( { id } ) {\n\t\t\t\tconst reusableBlock = registry\n\t\t\t\t\t.select( 'core' )\n\t\t\t\t\t.getEditedEntityRecord( 'postType', 'wp_block', id );\n\n\t\t\t\t// Don't allow a reusable block with a temporary ID to be deleted\n\t\t\t\tif ( ! reusableBlock ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Remove any other blocks that reference this reusable block\n\t\t\t\tconst allBlocks = registry\n\t\t\t\t\t.select( blockEditorStore )\n\t\t\t\t\t.getBlocks();\n\t\t\t\tconst associatedBlocks = allBlocks.filter(\n\t\t\t\t\t( block ) =>\n\t\t\t\t\t\tisReusableBlock( block ) && block.attributes.ref === id\n\t\t\t\t);\n\t\t\t\tconst associatedBlockClientIds = associatedBlocks.map(\n\t\t\t\t\t( block ) => block.clientId\n\t\t\t\t);\n\n\t\t\t\t// Remove the parsed block.\n\t\t\t\tif ( associatedBlockClientIds.length ) {\n\t\t\t\t\tregistry\n\t\t\t\t\t\t.dispatch( blockEditorStore )\n\t\t\t\t\t\t.removeBlocks( associatedBlockClientIds );\n\t\t\t\t}\n\n\t\t\t\tawait registry\n\t\t\t\t\t.dispatch( 'core' )\n\t\t\t\t\t.deleteEntityRecord( 'postType', 'wp_block', id );\n\t\t\t}\n\t),\n};\n\nexport default controls;\n"]}
@@ -1,107 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { isFunction } from 'lodash';
5
- /**
6
- * WordPress dependencies
7
- */
8
-
9
- import { isReusableBlock, createBlock, parse, serialize } from '@wordpress/blocks';
10
- import { createRegistryControl } from '@wordpress/data';
11
- import { __ } from '@wordpress/i18n';
12
- import { store as blockEditorStore } from '@wordpress/block-editor';
13
- /**
14
- * Internal dependencies
15
- */
16
-
17
- import { store as reusableBlocksStore } from './index.js';
18
- /**
19
- * Convert a reusable block to a static block effect handler
20
- *
21
- * @param {string} clientId Block ID.
22
- * @return {Object} control descriptor.
23
- */
24
-
25
- export function convertBlockToStatic(clientId) {
26
- return {
27
- type: 'CONVERT_BLOCK_TO_STATIC',
28
- clientId
29
- };
30
- }
31
- /**
32
- * Convert a static block to a reusable block effect handler
33
- *
34
- * @param {Array} clientIds Block IDs.
35
- * @param {string} title Reusable block title.
36
- * @return {Object} control descriptor.
37
- */
38
-
39
- export function convertBlocksToReusable(clientIds, title) {
40
- return {
41
- type: 'CONVERT_BLOCKS_TO_REUSABLE',
42
- clientIds,
43
- title
44
- };
45
- }
46
- /**
47
- * Deletes a reusable block.
48
- *
49
- * @param {string} id Reusable block ID.
50
- * @return {Object} control descriptor.
51
- */
52
-
53
- export function deleteReusableBlock(id) {
54
- return {
55
- type: 'DELETE_REUSABLE_BLOCK',
56
- id
57
- };
58
- }
59
- const controls = {
60
- CONVERT_BLOCK_TO_STATIC: createRegistryControl(registry => ({
61
- clientId
62
- }) => {
63
- const oldBlock = registry.select(blockEditorStore).getBlock(clientId);
64
- const reusableBlock = registry.select('core').getEditedEntityRecord('postType', 'wp_block', oldBlock.attributes.ref);
65
- const newBlocks = parse(isFunction(reusableBlock.content) ? reusableBlock.content(reusableBlock) : reusableBlock.content);
66
- registry.dispatch(blockEditorStore).replaceBlocks(oldBlock.clientId, newBlocks);
67
- }),
68
- CONVERT_BLOCKS_TO_REUSABLE: createRegistryControl(registry => async function ({
69
- clientIds,
70
- title
71
- }) {
72
- const reusableBlock = {
73
- title: title || __('Untitled Reusable block'),
74
- content: serialize(registry.select(blockEditorStore).getBlocksByClientId(clientIds)),
75
- status: 'publish'
76
- };
77
- const updatedRecord = await registry.dispatch('core').saveEntityRecord('postType', 'wp_block', reusableBlock);
78
- const newBlock = createBlock('core/block', {
79
- ref: updatedRecord.id
80
- });
81
- registry.dispatch(blockEditorStore).replaceBlocks(clientIds, newBlock);
82
-
83
- registry.dispatch(reusableBlocksStore).__experimentalSetEditingReusableBlock(newBlock.clientId, true);
84
- }),
85
- DELETE_REUSABLE_BLOCK: createRegistryControl(registry => async function ({
86
- id
87
- }) {
88
- const reusableBlock = registry.select('core').getEditedEntityRecord('postType', 'wp_block', id); // Don't allow a reusable block with a temporary ID to be deleted
89
-
90
- if (!reusableBlock) {
91
- return;
92
- } // Remove any other blocks that reference this reusable block
93
-
94
-
95
- const allBlocks = registry.select(blockEditorStore).getBlocks();
96
- const associatedBlocks = allBlocks.filter(block => isReusableBlock(block) && block.attributes.ref === id);
97
- const associatedBlockClientIds = associatedBlocks.map(block => block.clientId); // Remove the parsed block.
98
-
99
- if (associatedBlockClientIds.length) {
100
- registry.dispatch(blockEditorStore).removeBlocks(associatedBlockClientIds);
101
- }
102
-
103
- await registry.dispatch('core').deleteEntityRecord('postType', 'wp_block', id);
104
- })
105
- };
106
- export default controls;
107
- //# sourceMappingURL=controls.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["@wordpress/reusable-blocks/src/store/controls.js"],"names":["isFunction","isReusableBlock","createBlock","parse","serialize","createRegistryControl","__","store","blockEditorStore","reusableBlocksStore","convertBlockToStatic","clientId","type","convertBlocksToReusable","clientIds","title","deleteReusableBlock","id","controls","CONVERT_BLOCK_TO_STATIC","registry","oldBlock","select","getBlock","reusableBlock","getEditedEntityRecord","attributes","ref","newBlocks","content","dispatch","replaceBlocks","CONVERT_BLOCKS_TO_REUSABLE","getBlocksByClientId","status","updatedRecord","saveEntityRecord","newBlock","__experimentalSetEditingReusableBlock","DELETE_REUSABLE_BLOCK","allBlocks","getBlocks","associatedBlocks","filter","block","associatedBlockClientIds","map","length","removeBlocks","deleteEntityRecord"],"mappings":"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","sourcesContent":["/**\n * External dependencies\n */\nimport { isFunction } from 'lodash';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tisReusableBlock,\n\tcreateBlock,\n\tparse,\n\tserialize,\n} from '@wordpress/blocks';\nimport { createRegistryControl } from '@wordpress/data';\nimport { __ } from '@wordpress/i18n';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { store as reusableBlocksStore } from './index.js';\n\n/**\n * Convert a reusable block to a static block effect handler\n *\n * @param {string} clientId Block ID.\n * @return {Object} control descriptor.\n */\nexport function convertBlockToStatic( clientId ) {\n\treturn {\n\t\ttype: 'CONVERT_BLOCK_TO_STATIC',\n\t\tclientId,\n\t};\n}\n\n/**\n * Convert a static block to a reusable block effect handler\n *\n * @param {Array} clientIds Block IDs.\n * @param {string} title Reusable block title.\n * @return {Object} control descriptor.\n */\nexport function convertBlocksToReusable( clientIds, title ) {\n\treturn {\n\t\ttype: 'CONVERT_BLOCKS_TO_REUSABLE',\n\t\tclientIds,\n\t\ttitle,\n\t};\n}\n\n/**\n * Deletes a reusable block.\n *\n * @param {string} id Reusable block ID.\n * @return {Object} control descriptor.\n */\nexport function deleteReusableBlock( id ) {\n\treturn {\n\t\ttype: 'DELETE_REUSABLE_BLOCK',\n\t\tid,\n\t};\n}\n\nconst controls = {\n\tCONVERT_BLOCK_TO_STATIC: createRegistryControl(\n\t\t( registry ) => ( { clientId } ) => {\n\t\t\tconst oldBlock = registry\n\t\t\t\t.select( blockEditorStore )\n\t\t\t\t.getBlock( clientId );\n\t\t\tconst reusableBlock = registry\n\t\t\t\t.select( 'core' )\n\t\t\t\t.getEditedEntityRecord(\n\t\t\t\t\t'postType',\n\t\t\t\t\t'wp_block',\n\t\t\t\t\toldBlock.attributes.ref\n\t\t\t\t);\n\n\t\t\tconst newBlocks = parse(\n\t\t\t\tisFunction( reusableBlock.content )\n\t\t\t\t\t? reusableBlock.content( reusableBlock )\n\t\t\t\t\t: reusableBlock.content\n\t\t\t);\n\t\t\tregistry\n\t\t\t\t.dispatch( blockEditorStore )\n\t\t\t\t.replaceBlocks( oldBlock.clientId, newBlocks );\n\t\t}\n\t),\n\n\tCONVERT_BLOCKS_TO_REUSABLE: createRegistryControl(\n\t\t( registry ) =>\n\t\t\tasync function ( { clientIds, title } ) {\n\t\t\t\tconst reusableBlock = {\n\t\t\t\t\ttitle: title || __( 'Untitled Reusable block' ),\n\t\t\t\t\tcontent: serialize(\n\t\t\t\t\t\tregistry\n\t\t\t\t\t\t\t.select( blockEditorStore )\n\t\t\t\t\t\t\t.getBlocksByClientId( clientIds )\n\t\t\t\t\t),\n\t\t\t\t\tstatus: 'publish',\n\t\t\t\t};\n\n\t\t\t\tconst updatedRecord = await registry\n\t\t\t\t\t.dispatch( 'core' )\n\t\t\t\t\t.saveEntityRecord( 'postType', 'wp_block', reusableBlock );\n\n\t\t\t\tconst newBlock = createBlock( 'core/block', {\n\t\t\t\t\tref: updatedRecord.id,\n\t\t\t\t} );\n\t\t\t\tregistry\n\t\t\t\t\t.dispatch( blockEditorStore )\n\t\t\t\t\t.replaceBlocks( clientIds, newBlock );\n\t\t\t\tregistry\n\t\t\t\t\t.dispatch( reusableBlocksStore )\n\t\t\t\t\t.__experimentalSetEditingReusableBlock(\n\t\t\t\t\t\tnewBlock.clientId,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t);\n\t\t\t}\n\t),\n\n\tDELETE_REUSABLE_BLOCK: createRegistryControl(\n\t\t( registry ) =>\n\t\t\tasync function ( { id } ) {\n\t\t\t\tconst reusableBlock = registry\n\t\t\t\t\t.select( 'core' )\n\t\t\t\t\t.getEditedEntityRecord( 'postType', 'wp_block', id );\n\n\t\t\t\t// Don't allow a reusable block with a temporary ID to be deleted\n\t\t\t\tif ( ! reusableBlock ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Remove any other blocks that reference this reusable block\n\t\t\t\tconst allBlocks = registry\n\t\t\t\t\t.select( blockEditorStore )\n\t\t\t\t\t.getBlocks();\n\t\t\t\tconst associatedBlocks = allBlocks.filter(\n\t\t\t\t\t( block ) =>\n\t\t\t\t\t\tisReusableBlock( block ) && block.attributes.ref === id\n\t\t\t\t);\n\t\t\t\tconst associatedBlockClientIds = associatedBlocks.map(\n\t\t\t\t\t( block ) => block.clientId\n\t\t\t\t);\n\n\t\t\t\t// Remove the parsed block.\n\t\t\t\tif ( associatedBlockClientIds.length ) {\n\t\t\t\t\tregistry\n\t\t\t\t\t\t.dispatch( blockEditorStore )\n\t\t\t\t\t\t.removeBlocks( associatedBlockClientIds );\n\t\t\t\t}\n\n\t\t\t\tawait registry\n\t\t\t\t\t.dispatch( 'core' )\n\t\t\t\t\t.deleteEntityRecord( 'postType', 'wp_block', id );\n\t\t\t}\n\t),\n};\n\nexport default controls;\n"]}