[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/dist/ -> reusable-blocks.js (source)

   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.js
 112    var index_exports = {};
 113    __export(index_exports, {
 114      ReusableBlocksMenuItems: () => ReusableBlocksMenuItems,
 115      store: () => store
 116    });
 117  
 118    // packages/reusable-blocks/build-module/store/index.js
 119    var import_data2 = __toESM(require_data());
 120  
 121    // packages/reusable-blocks/build-module/store/actions.js
 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());
 130    var import_blocks = __toESM(require_blocks());
 131    var import_i18n = __toESM(require_i18n());
 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.js
 195    var import_data = __toESM(require_data());
 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.js
 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.js
 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.js
 228    var import_block_editor4 = __toESM(require_block_editor());
 229  
 230    // packages/reusable-blocks/build-module/components/reusable-blocks-menu-items/reusable-block-convert-button.js
 231    var import_blocks2 = __toESM(require_blocks());
 232    var import_block_editor2 = __toESM(require_block_editor());
 233    var import_element = __toESM(require_element());
 234    var import_components = __toESM(require_components());
 235  
 236    // packages/icons/build-module/library/symbol.js
 237    var import_primitives = __toESM(require_primitives());
 238    var import_jsx_runtime = __toESM(require_jsx_runtime());
 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.js
 242    var import_data3 = __toESM(require_data());
 243    var import_i18n2 = __toESM(require_i18n());
 244    var import_notices = __toESM(require_notices());
 245    var import_core_data = __toESM(require_core_data());
 246    var import_jsx_runtime2 = __toESM(require_jsx_runtime());
 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.js
 413    var import_components2 = __toESM(require_components());
 414    var import_i18n3 = __toESM(require_i18n());
 415    var import_blocks3 = __toESM(require_blocks());
 416    var import_data4 = __toESM(require_data());
 417    var import_block_editor3 = __toESM(require_block_editor());
 418    var import_url = __toESM(require_url());
 419    var import_core_data2 = __toESM(require_core_data());
 420    var import_jsx_runtime3 = __toESM(require_jsx_runtime());
 421    function ReusableBlocksManageButton({ clientId }) {
 422      const { canRemove, isVisible, managePatternsUrl } = (0, import_data4.useSelect)(
 423        (select) => {
 424          const { getBlock, canRemoveBlock } = select(import_block_editor3.store);
 425          const { canUser } = select(import_core_data2.store);
 426          const reusableBlock = getBlock(clientId);
 427          return {
 428            canRemove: canRemoveBlock(clientId),
 429            isVisible: !!reusableBlock && (0, import_blocks3.isReusableBlock)(reusableBlock) && !!canUser("update", {
 430              kind: "postType",
 431              name: "wp_block",
 432              id: reusableBlock.attributes.ref
 433            }),
 434            // The site editor and templates both check whether the user
 435            // has edit_theme_options capabilities. We can leverage that here
 436            // and omit the manage patterns link if the user can't access it.
 437            managePatternsUrl: canUser("create", {
 438              kind: "postType",
 439              name: "wp_template"
 440            }) ? (0, import_url.addQueryArgs)("site-editor.php", {
 441              p: "/pattern"
 442            }) : (0, import_url.addQueryArgs)("edit.php", {
 443              post_type: "wp_block"
 444            })
 445          };
 446        },
 447        [clientId]
 448      );
 449      const { __experimentalConvertBlockToStatic: convertBlockToStatic } = (0, import_data4.useDispatch)(store);
 450      if (!isVisible) {
 451        return null;
 452      }
 453      return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
 454        /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components2.MenuItem, { href: managePatternsUrl, children: (0, import_i18n3.__)("Manage patterns") }),
 455        canRemove && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components2.MenuItem, { onClick: () => convertBlockToStatic(clientId), children: (0, import_i18n3.__)("Disconnect pattern") })
 456      ] });
 457    }
 458    var reusable_blocks_manage_button_default = ReusableBlocksManageButton;
 459  
 460    // packages/reusable-blocks/build-module/components/reusable-blocks-menu-items/index.js
 461    var import_jsx_runtime4 = __toESM(require_jsx_runtime());
 462    function ReusableBlocksMenuItems({ rootClientId }) {
 463      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: [
 464        /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
 465          ReusableBlockConvertButton,
 466          {
 467            clientIds: selectedClientIds,
 468            rootClientId,
 469            onClose
 470          }
 471        ),
 472        selectedClientIds.length === 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
 473          reusable_blocks_manage_button_default,
 474          {
 475            clientId: selectedClientIds[0]
 476          }
 477        )
 478      ] }) });
 479    }
 480    return __toCommonJS(index_exports);
 481  })();


Generated : Thu Apr 23 08:20:11 2026 Cross-referenced by PHPXref