| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
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 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Wed Jun 17 08:20:09 2026 | Cross-referenced by PHPXref |