PluginProbe
Gutenberg / 23.3.1
Gutenberg v23.3.1
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / scripts / reusable-blocks / index.js

index.js in Gutenberg 23.3.1, at build/scripts/reusable-blocks/index.js

506 lines 20.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 var wp;
2 (wp ||= {}).reusableBlocks = (() => {
3 var __create = Object.create;
4 var __defProp = Object.defineProperty;
5 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6 var __getOwnPropNames = Object.getOwnPropertyNames;
7 var __getProtoOf = Object.getPrototypeOf;
8 var __hasOwnProp = Object.prototype.hasOwnProperty;
9 var __commonJS = (cb, mod) => function __require() {
10 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11 };
12 var __export = (target, all) => {
13 for (var name in all)
14 __defProp(target, name, { get: all[name], enumerable: true });
15 };
16 var __copyProps = (to, from, except, desc) => {
17 if (from && typeof from === "object" || typeof from === "function") {
18 for (let key of __getOwnPropNames(from))
19 if (!__hasOwnProp.call(to, key) && key !== except)
20 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21 }
22 return to;
23 };
24 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25 // If the importer is in node compatibility mode or this is not an ESM
26 // file that has been converted to a CommonJS file using a Babel-
27 // compatible transform (i.e. "__esModule" has not been set), then set
28 // "default" to the CommonJS "module.exports" for node compatibility.
29 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30 mod
31 ));
32 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
34 // package-external:@wordpress/data
35 var require_data = __commonJS({
36 "package-external:@wordpress/data"(exports, module) {
37 module.exports = window.wp.data;
38 }
39 });
40
41 // package-external:@wordpress/block-editor
42 var require_block_editor = __commonJS({
43 "package-external:@wordpress/block-editor"(exports, module) {
44 module.exports = window.wp.blockEditor;
45 }
46 });
47
48 // package-external:@wordpress/blocks
49 var require_blocks = __commonJS({
50 "package-external:@wordpress/blocks"(exports, module) {
51 module.exports = window.wp.blocks;
52 }
53 });
54
55 // package-external:@wordpress/i18n
56 var require_i18n = __commonJS({
57 "package-external:@wordpress/i18n"(exports, module) {
58 module.exports = window.wp.i18n;
59 }
60 });
61
62 // package-external:@wordpress/element
63 var require_element = __commonJS({
64 "package-external:@wordpress/element"(exports, module) {
65 module.exports = window.wp.element;
66 }
67 });
68
69 // package-external:@wordpress/components
70 var require_components = __commonJS({
71 "package-external:@wordpress/components"(exports, module) {
72 module.exports = window.wp.components;
73 }
74 });
75
76 // package-external:@wordpress/primitives
77 var require_primitives = __commonJS({
78 "package-external:@wordpress/primitives"(exports, module) {
79 module.exports = window.wp.primitives;
80 }
81 });
82
83 // vendor-external:react/jsx-runtime
84 var require_jsx_runtime = __commonJS({
85 "vendor-external:react/jsx-runtime"(exports, module) {
86 module.exports = window.ReactJSXRuntime;
87 }
88 });
89
90 // package-external:@wordpress/notices
91 var require_notices = __commonJS({
92 "package-external:@wordpress/notices"(exports, module) {
93 module.exports = window.wp.notices;
94 }
95 });
96
97 // package-external:@wordpress/core-data
98 var require_core_data = __commonJS({
99 "package-external:@wordpress/core-data"(exports, module) {
100 module.exports = window.wp.coreData;
101 }
102 });
103
104 // package-external:@wordpress/url
105 var require_url = __commonJS({
106 "package-external:@wordpress/url"(exports, module) {
107 module.exports = window.wp.url;
108 }
109 });
110
111 // packages/reusable-blocks/build-module/index.mjs
112 var index_exports = {};
113 __export(index_exports, {
114 ReusableBlocksMenuItems: () => ReusableBlocksMenuItems,
115 store: () => store
116 });
117
118 // packages/reusable-blocks/build-module/store/index.mjs
119 var import_data2 = __toESM(require_data(), 1);
120
121 // packages/reusable-blocks/build-module/store/actions.mjs
122 var actions_exports = {};
123 __export(actions_exports, {
124 __experimentalConvertBlockToStatic: () => __experimentalConvertBlockToStatic,
125 __experimentalConvertBlocksToReusable: () => __experimentalConvertBlocksToReusable,
126 __experimentalDeleteReusableBlock: () => __experimentalDeleteReusableBlock,
127 __experimentalSetEditingReusableBlock: () => __experimentalSetEditingReusableBlock
128 });
129 var import_block_editor = __toESM(require_block_editor(), 1);
130 var import_blocks = __toESM(require_blocks(), 1);
131 var import_i18n = __toESM(require_i18n(), 1);
132 var __experimentalConvertBlockToStatic = (clientId) => ({ registry }) => {
133 const oldBlock = registry.select(import_block_editor.store).getBlock(clientId);
134 const reusableBlock = registry.select("core").getEditedEntityRecord(
135 "postType",
136 "wp_block",
137 oldBlock.attributes.ref
138 );
139 const newBlocks = (0, import_blocks.parse)(
140 typeof reusableBlock.content === "function" ? reusableBlock.content(reusableBlock) : reusableBlock.content
141 );
142 registry.dispatch(import_block_editor.store).replaceBlocks(oldBlock.clientId, newBlocks);
143 };
144 var __experimentalConvertBlocksToReusable = (clientIds, title, syncType) => async ({ registry, dispatch }) => {
145 const meta = syncType === "unsynced" ? {
146 wp_pattern_sync_status: syncType
147 } : void 0;
148 const reusableBlock = {
149 title: title || (0, import_i18n.__)("Untitled pattern block"),
150 content: (0, import_blocks.serialize)(
151 registry.select(import_block_editor.store).getBlocksByClientId(clientIds)
152 ),
153 status: "publish",
154 meta
155 };
156 const updatedRecord = await registry.dispatch("core").saveEntityRecord("postType", "wp_block", reusableBlock);
157 if (syncType === "unsynced") {
158 return;
159 }
160 const newBlock = (0, import_blocks.createBlock)("core/block", {
161 ref: updatedRecord.id
162 });
163 registry.dispatch(import_block_editor.store).replaceBlocks(clientIds, newBlock);
164 dispatch.__experimentalSetEditingReusableBlock(
165 newBlock.clientId,
166 true
167 );
168 };
169 var __experimentalDeleteReusableBlock = (id) => async ({ registry }) => {
170 const reusableBlock = registry.select("core").getEditedEntityRecord("postType", "wp_block", id);
171 if (!reusableBlock) {
172 return;
173 }
174 const allBlocks = registry.select(import_block_editor.store).getBlocks();
175 const associatedBlocks = allBlocks.filter(
176 (block) => (0, import_blocks.isReusableBlock)(block) && block.attributes.ref === id
177 );
178 const associatedBlockClientIds = associatedBlocks.map(
179 (block) => block.clientId
180 );
181 if (associatedBlockClientIds.length) {
182 registry.dispatch(import_block_editor.store).removeBlocks(associatedBlockClientIds);
183 }
184 await registry.dispatch("core").deleteEntityRecord("postType", "wp_block", id);
185 };
186 function __experimentalSetEditingReusableBlock(clientId, isEditing) {
187 return {
188 type: "SET_EDITING_REUSABLE_BLOCK",
189 clientId,
190 isEditing
191 };
192 }
193
194 // packages/reusable-blocks/build-module/store/reducer.mjs
195 var import_data = __toESM(require_data(), 1);
196 function isEditingReusableBlock(state = {}, action) {
197 if (action?.type === "SET_EDITING_REUSABLE_BLOCK") {
198 return {
199 ...state,
200 [action.clientId]: action.isEditing
201 };
202 }
203 return state;
204 }
205 var reducer_default = (0, import_data.combineReducers)({
206 isEditingReusableBlock
207 });
208
209 // packages/reusable-blocks/build-module/store/selectors.mjs
210 var selectors_exports = {};
211 __export(selectors_exports, {
212 __experimentalIsEditingReusableBlock: () => __experimentalIsEditingReusableBlock
213 });
214 function __experimentalIsEditingReusableBlock(state, clientId) {
215 return state.isEditingReusableBlock[clientId];
216 }
217
218 // packages/reusable-blocks/build-module/store/index.mjs
219 var STORE_NAME = "core/reusable-blocks";
220 var store = (0, import_data2.createReduxStore)(STORE_NAME, {
221 actions: actions_exports,
222 reducer: reducer_default,
223 selectors: selectors_exports
224 });
225 (0, import_data2.register)(store);
226
227 // packages/reusable-blocks/build-module/components/reusable-blocks-menu-items/index.mjs
228 var import_block_editor4 = __toESM(require_block_editor(), 1);
229
230 // packages/reusable-blocks/build-module/components/reusable-blocks-menu-items/reusable-block-convert-button.mjs
231 var import_blocks2 = __toESM(require_blocks(), 1);
232 var import_block_editor2 = __toESM(require_block_editor(), 1);
233 var import_element = __toESM(require_element(), 1);
234 var import_components = __toESM(require_components(), 1);
235
236 // packages/icons/build-module/library/symbol.mjs
237 var import_primitives = __toESM(require_primitives(), 1);
238 var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
239 var symbol_default = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_primitives.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_primitives.Path, { d: "M21.3 10.8l-5.6-5.6c-.7-.7-1.8-.7-2.5 0l-5.6 5.6c-.7.7-.7 1.8 0 2.5l5.6 5.6c.3.3.8.5 1.2.5s.9-.2 1.2-.5l5.6-5.6c.8-.7.8-1.9.1-2.5zm-1 1.4l-5.6 5.6c-.1.1-.3.1-.4 0l-5.6-5.6c-.1-.1-.1-.3 0-.4l5.6-5.6s.1-.1.2-.1.1 0 .2.1l5.6 5.6c.1.1.1.3 0 .4zm-16.6-.4L10 5.5l-1-1-6.3 6.3c-.7.7-.7 1.8 0 2.5L9 19.5l1.1-1.1-6.3-6.3c-.2 0-.2-.2-.1-.3z" }) });
240
241 // packages/reusable-blocks/build-module/components/reusable-blocks-menu-items/reusable-block-convert-button.mjs
242 var import_data3 = __toESM(require_data(), 1);
243 var import_i18n2 = __toESM(require_i18n(), 1);
244 var import_notices = __toESM(require_notices(), 1);
245 var import_core_data = __toESM(require_core_data(), 1);
246 var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
247 function ReusableBlockConvertButton({
248 clientIds,
249 rootClientId,
250 onClose
251 }) {
252 const [syncType, setSyncType] = (0, import_element.useState)(void 0);
253 const [isModalOpen, setIsModalOpen] = (0, import_element.useState)(false);
254 const [title, setTitle] = (0, import_element.useState)("");
255 const canConvert = (0, import_data3.useSelect)(
256 (select) => {
257 const { canUser } = select(import_core_data.store);
258 const {
259 getBlocksByClientId,
260 canInsertBlockType,
261 getBlockRootClientId
262 } = select(import_block_editor2.store);
263 const rootId = rootClientId || (clientIds.length > 0 ? getBlockRootClientId(clientIds[0]) : void 0);
264 const blocks = getBlocksByClientId(clientIds) ?? [];
265 const isReusable = blocks.length === 1 && blocks[0] && (0, import_blocks2.isReusableBlock)(blocks[0]) && !!select(import_core_data.store).getEntityRecord(
266 "postType",
267 "wp_block",
268 blocks[0].attributes.ref
269 );
270 const _canConvert = (
271 // Hide when this is already a reusable block.
272 !isReusable && // Hide when reusable blocks are disabled.
273 canInsertBlockType("core/block", rootId) && blocks.every(
274 (block) => (
275 // Guard against the case where a regular block has *just* been converted.
276 !!block && // Hide on invalid blocks.
277 block.isValid && // Hide when block doesn't support being made reusable.
278 (0, import_blocks2.hasBlockSupport)(block.name, "reusable", true)
279 )
280 ) && // Hide when current doesn't have permission to do that.
281 // Blocks refers to the wp_block post type, this checks the ability to create a post of that type.
282 !!canUser("create", {
283 kind: "postType",
284 name: "wp_block"
285 })
286 );
287 return _canConvert;
288 },
289 [clientIds, rootClientId]
290 );
291 const { __experimentalConvertBlocksToReusable: convertBlocksToReusable } = (0, import_data3.useDispatch)(store);
292 const { createSuccessNotice, createErrorNotice } = (0, import_data3.useDispatch)(import_notices.store);
293 const onConvert = (0, import_element.useCallback)(
294 async function(reusableBlockTitle) {
295 try {
296 await convertBlocksToReusable(
297 clientIds,
298 reusableBlockTitle,
299 syncType
300 );
301 createSuccessNotice(
302 !syncType ? (0, import_i18n2.sprintf)(
303 // translators: %s: the name the user has given to the pattern.
304 (0, import_i18n2.__)("Synced pattern created: %s"),
305 reusableBlockTitle
306 ) : (0, import_i18n2.sprintf)(
307 // translators: %s: the name the user has given to the pattern.
308 (0, import_i18n2.__)("Unsynced pattern created: %s"),
309 reusableBlockTitle
310 ),
311 {
312 type: "snackbar",
313 id: "convert-to-reusable-block-success"
314 }
315 );
316 } catch (error) {
317 createErrorNotice(error.message, {
318 type: "snackbar",
319 id: "convert-to-reusable-block-error"
320 });
321 }
322 },
323 [
324 convertBlocksToReusable,
325 clientIds,
326 syncType,
327 createSuccessNotice,
328 createErrorNotice
329 ]
330 );
331 if (!canConvert) {
332 return null;
333 }
334 return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
335 /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_components.MenuItem, { icon: symbol_default, onClick: () => setIsModalOpen(true), children: (0, import_i18n2.__)("Create pattern") }),
336 isModalOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
337 import_components.Modal,
338 {
339 title: (0, import_i18n2.__)("Create pattern"),
340 onRequestClose: () => {
341 setIsModalOpen(false);
342 setTitle("");
343 },
344 overlayClassName: "reusable-blocks-menu-items__convert-modal",
345 children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
346 "form",
347 {
348 onSubmit: (event) => {
349 event.preventDefault();
350 onConvert(title);
351 setIsModalOpen(false);
352 setTitle("");
353 onClose();
354 },
355 children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_components.__experimentalVStack, { spacing: "5", children: [
356 /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
357 import_components.TextControl,
358 {
359 __next40pxDefaultSize: true,
360 label: (0, import_i18n2.__)("Name"),
361 value: title,
362 onChange: setTitle,
363 placeholder: (0, import_i18n2.__)("My pattern")
364 }
365 ),
366 /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
367 import_components.ToggleControl,
368 {
369 label: (0, import_i18n2._x)("Synced", "pattern (singular)"),
370 help: (0, import_i18n2.__)(
371 "Sync this pattern across multiple locations."
372 ),
373 checked: !syncType,
374 onChange: () => {
375 setSyncType(
376 !syncType ? "unsynced" : void 0
377 );
378 }
379 }
380 ),
381 /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_components.__experimentalHStack, { justify: "right", children: [
382 /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
383 import_components.Button,
384 {
385 __next40pxDefaultSize: true,
386 variant: "tertiary",
387 onClick: () => {
388 setIsModalOpen(false);
389 setTitle("");
390 },
391 children: (0, import_i18n2.__)("Cancel")
392 }
393 ),
394 /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
395 import_components.Button,
396 {
397 __next40pxDefaultSize: true,
398 variant: "primary",
399 type: "submit",
400 children: (0, import_i18n2.__)("Create")
401 }
402 )
403 ] })
404 ] })
405 }
406 )
407 }
408 )
409 ] });
410 }
411
412 // packages/reusable-blocks/build-module/components/reusable-blocks-menu-items/reusable-blocks-manage-button.mjs
413 var import_components2 = __toESM(require_components(), 1);
414 var import_i18n3 = __toESM(require_i18n(), 1);
415 var import_blocks3 = __toESM(require_blocks(), 1);
416 var import_data4 = __toESM(require_data(), 1);
417 var import_element2 = __toESM(require_element(), 1);
418 var import_block_editor3 = __toESM(require_block_editor(), 1);
419 var import_url = __toESM(require_url(), 1);
420 var import_core_data2 = __toESM(require_core_data(), 1);
421 var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
422 function ReusableBlocksManageButton({ clientId }) {
423 const [showConfirmDialog, setShowConfirmDialog] = (0, import_element2.useState)(false);
424 const { canRemove, isVisible, managePatternsUrl } = (0, import_data4.useSelect)(
425 (select) => {
426 const { getBlock, canRemoveBlock } = select(import_block_editor3.store);
427 const { canUser } = select(import_core_data2.store);
428 const reusableBlock = getBlock(clientId);
429 return {
430 canRemove: canRemoveBlock(clientId),
431 isVisible: !!reusableBlock && (0, import_blocks3.isReusableBlock)(reusableBlock) && !!canUser("update", {
432 kind: "postType",
433 name: "wp_block",
434 id: reusableBlock.attributes.ref
435 }),
436 // The site editor and templates both check whether the user
437 // has edit_theme_options capabilities. We can leverage that here
438 // and omit the manage patterns link if the user can't access it.
439 managePatternsUrl: canUser("create", {
440 kind: "postType",
441 name: "wp_template"
442 }) ? (0, import_url.addQueryArgs)("site-editor.php", {
443 p: "/pattern"
444 }) : (0, import_url.addQueryArgs)("edit.php", {
445 post_type: "wp_block"
446 })
447 };
448 },
449 [clientId]
450 );
451 const { __experimentalConvertBlockToStatic: convertBlockToStatic } = (0, import_data4.useDispatch)(store);
452 if (!isVisible) {
453 return null;
454 }
455 const handleDetach = () => {
456 convertBlockToStatic(clientId);
457 setShowConfirmDialog(false);
458 };
459 return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
460 /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components2.MenuItem, { href: managePatternsUrl, children: (0, import_i18n3.__)("Manage patterns") }),
461 canRemove && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
462 /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components2.MenuItem, { onClick: () => setShowConfirmDialog(true), children: (0, import_i18n3.__)("Disconnect pattern") }),
463 /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
464 import_components2.__experimentalConfirmDialog,
465 {
466 isOpen: showConfirmDialog,
467 onConfirm: handleDetach,
468 onCancel: () => setShowConfirmDialog(false),
469 confirmButtonText: (0, import_i18n3.__)("Disconnect"),
470 size: "medium",
471 title: (0, import_i18n3.__)("Disconnect pattern?"),
472 __experimentalHideHeader: false,
473 children: (0, import_i18n3.__)(
474 "Blocks will be separated from the original pattern and will be fully editable. Future changes to the pattern will not apply here."
475 )
476 }
477 )
478 ] })
479 ] });
480 }
481 var reusable_blocks_manage_button_default = ReusableBlocksManageButton;
482
483 // packages/reusable-blocks/build-module/components/reusable-blocks-menu-items/index.mjs
484 var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
485 function ReusableBlocksMenuItems({ rootClientId }) {
486 return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_block_editor4.BlockSettingsMenuControls, { children: ({ onClose, selectedClientIds }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
487 /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
488 ReusableBlockConvertButton,
489 {
490 clientIds: selectedClientIds,
491 rootClientId,
492 onClose
493 }
494 ),
495 selectedClientIds.length === 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
496 reusable_blocks_manage_button_default,
497 {
498 clientId: selectedClientIds[0]
499 }
500 )
501 ] }) });
502 }
503 return __toCommonJS(index_exports);
504 })();
505 //# sourceMappingURL=index.js.map
506