You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

761 lines
27 KiB

1 year ago
  1. /******/ (function() { // webpackBootstrap
  2. /******/ "use strict";
  3. /******/ // The require scope
  4. /******/ var __webpack_require__ = {};
  5. /******/
  6. /************************************************************************/
  7. /******/ /* webpack/runtime/define property getters */
  8. /******/ !function() {
  9. /******/ // define getter functions for harmony exports
  10. /******/ __webpack_require__.d = function(exports, definition) {
  11. /******/ for(var key in definition) {
  12. /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
  13. /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
  14. /******/ }
  15. /******/ }
  16. /******/ };
  17. /******/ }();
  18. /******/
  19. /******/ /* webpack/runtime/hasOwnProperty shorthand */
  20. /******/ !function() {
  21. /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
  22. /******/ }();
  23. /******/
  24. /******/ /* webpack/runtime/make namespace object */
  25. /******/ !function() {
  26. /******/ // define __esModule on exports
  27. /******/ __webpack_require__.r = function(exports) {
  28. /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  29. /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  30. /******/ }
  31. /******/ Object.defineProperty(exports, '__esModule', { value: true });
  32. /******/ };
  33. /******/ }();
  34. /******/
  35. /************************************************************************/
  36. var __webpack_exports__ = {};
  37. // ESM COMPAT FLAG
  38. __webpack_require__.r(__webpack_exports__);
  39. // EXPORTS
  40. __webpack_require__.d(__webpack_exports__, {
  41. privateApis: function() { return /* reexport */ privateApis; },
  42. store: function() { return /* reexport */ store; }
  43. });
  44. // NAMESPACE OBJECT: ./node_modules/@wordpress/patterns/build-module/store/actions.js
  45. var actions_namespaceObject = {};
  46. __webpack_require__.r(actions_namespaceObject);
  47. __webpack_require__.d(actions_namespaceObject, {
  48. convertSyncedPatternToStatic: function() { return convertSyncedPatternToStatic; },
  49. createPattern: function() { return createPattern; },
  50. createPatternFromFile: function() { return createPatternFromFile; },
  51. setEditingPattern: function() { return setEditingPattern; }
  52. });
  53. // NAMESPACE OBJECT: ./node_modules/@wordpress/patterns/build-module/store/selectors.js
  54. var selectors_namespaceObject = {};
  55. __webpack_require__.r(selectors_namespaceObject);
  56. __webpack_require__.d(selectors_namespaceObject, {
  57. isEditingPattern: function() { return selectors_isEditingPattern; }
  58. });
  59. ;// CONCATENATED MODULE: external ["wp","data"]
  60. var external_wp_data_namespaceObject = window["wp"]["data"];
  61. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/store/reducer.js
  62. /**
  63. * WordPress dependencies
  64. */
  65. function isEditingPattern(state = {}, action) {
  66. if (action?.type === 'SET_EDITING_PATTERN') {
  67. return {
  68. ...state,
  69. [action.clientId]: action.isEditing
  70. };
  71. }
  72. return state;
  73. }
  74. /* harmony default export */ var reducer = ((0,external_wp_data_namespaceObject.combineReducers)({
  75. isEditingPattern
  76. }));
  77. ;// CONCATENATED MODULE: external ["wp","blocks"]
  78. var external_wp_blocks_namespaceObject = window["wp"]["blocks"];
  79. ;// CONCATENATED MODULE: external ["wp","coreData"]
  80. var external_wp_coreData_namespaceObject = window["wp"]["coreData"];
  81. ;// CONCATENATED MODULE: external ["wp","blockEditor"]
  82. var external_wp_blockEditor_namespaceObject = window["wp"]["blockEditor"];
  83. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/constants.js
  84. const PATTERN_TYPES = {
  85. theme: 'pattern',
  86. user: 'wp_block'
  87. };
  88. const PATTERN_DEFAULT_CATEGORY = 'all-patterns';
  89. const PATTERN_USER_CATEGORY = 'my-patterns';
  90. const PATTERN_CORE_SOURCES = ['core', 'pattern-directory/core', 'pattern-directory/featured', 'pattern-directory/theme'];
  91. const PATTERN_SYNC_TYPES = {
  92. full: 'fully',
  93. unsynced: 'unsynced'
  94. };
  95. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/store/actions.js
  96. /**
  97. * WordPress dependencies
  98. */
  99. /**
  100. * Internal dependencies
  101. */
  102. /**
  103. * Returns a generator converting one or more static blocks into a pattern, or creating a new empty pattern.
  104. *
  105. * @param {string} title Pattern title.
  106. * @param {'full'|'unsynced'} syncType They way block is synced, 'full' or 'unsynced'.
  107. * @param {string|undefined} [content] Optional serialized content of blocks to convert to pattern.
  108. * @param {number[]|undefined} [categories] Ids of any selected categories.
  109. */
  110. const createPattern = (title, syncType, content, categories) => async ({
  111. registry
  112. }) => {
  113. const meta = syncType === PATTERN_SYNC_TYPES.unsynced ? {
  114. wp_pattern_sync_status: syncType
  115. } : undefined;
  116. const reusableBlock = {
  117. title,
  118. content,
  119. status: 'publish',
  120. meta,
  121. wp_pattern_category: categories
  122. };
  123. const updatedRecord = await registry.dispatch(external_wp_coreData_namespaceObject.store).saveEntityRecord('postType', 'wp_block', reusableBlock);
  124. return updatedRecord;
  125. };
  126. /**
  127. * Create a pattern from a JSON file.
  128. * @param {File} file The JSON file instance of the pattern.
  129. * @param {number[]|undefined} [categories] Ids of any selected categories.
  130. */
  131. const createPatternFromFile = (file, categories) => async ({
  132. dispatch
  133. }) => {
  134. const fileContent = await file.text();
  135. /** @type {import('./types').PatternJSON} */
  136. let parsedContent;
  137. try {
  138. parsedContent = JSON.parse(fileContent);
  139. } catch (e) {
  140. throw new Error('Invalid JSON file');
  141. }
  142. if (parsedContent.__file !== 'wp_block' || !parsedContent.title || !parsedContent.content || typeof parsedContent.title !== 'string' || typeof parsedContent.content !== 'string' || parsedContent.syncStatus && typeof parsedContent.syncStatus !== 'string') {
  143. throw new Error('Invalid pattern JSON file');
  144. }
  145. const pattern = await dispatch.createPattern(parsedContent.title, parsedContent.syncStatus, parsedContent.content, categories);
  146. return pattern;
  147. };
  148. /**
  149. * Returns a generator converting a synced pattern block into a static block.
  150. *
  151. * @param {string} clientId The client ID of the block to attach.
  152. */
  153. const convertSyncedPatternToStatic = clientId => ({
  154. registry
  155. }) => {
  156. const oldBlock = registry.select(external_wp_blockEditor_namespaceObject.store).getBlock(clientId);
  157. const pattern = registry.select('core').getEditedEntityRecord('postType', 'wp_block', oldBlock.attributes.ref);
  158. const newBlocks = (0,external_wp_blocks_namespaceObject.parse)(typeof pattern.content === 'function' ? pattern.content(pattern) : pattern.content);
  159. registry.dispatch(external_wp_blockEditor_namespaceObject.store).replaceBlocks(oldBlock.clientId, newBlocks);
  160. };
  161. /**
  162. * Returns an action descriptor for SET_EDITING_PATTERN action.
  163. *
  164. * @param {string} clientId The clientID of the pattern to target.
  165. * @param {boolean} isEditing Whether the block should be in editing state.
  166. * @return {Object} Action descriptor.
  167. */
  168. function setEditingPattern(clientId, isEditing) {
  169. return {
  170. type: 'SET_EDITING_PATTERN',
  171. clientId,
  172. isEditing
  173. };
  174. }
  175. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/store/constants.js
  176. /**
  177. * Module Constants
  178. */
  179. const STORE_NAME = 'core/patterns';
  180. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/store/selectors.js
  181. /**
  182. * Returns true if pattern is in the editing state.
  183. *
  184. * @param {Object} state Global application state.
  185. * @param {number} clientId the clientID of the block.
  186. * @return {boolean} Whether the pattern is in the editing state.
  187. */
  188. function selectors_isEditingPattern(state, clientId) {
  189. return state.isEditingPattern[clientId];
  190. }
  191. ;// CONCATENATED MODULE: external ["wp","privateApis"]
  192. var external_wp_privateApis_namespaceObject = window["wp"]["privateApis"];
  193. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/lock-unlock.js
  194. /**
  195. * WordPress dependencies
  196. */
  197. const {
  198. lock,
  199. unlock
  200. } = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I know using unstable features means my theme or plugin will inevitably break in the next version of WordPress.', '@wordpress/patterns');
  201. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/store/index.js
  202. /**
  203. * WordPress dependencies
  204. */
  205. /**
  206. * Internal dependencies
  207. */
  208. /**
  209. * Post editor data store configuration.
  210. *
  211. * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#registerStore
  212. *
  213. * @type {Object}
  214. */
  215. const storeConfig = {
  216. reducer: reducer
  217. };
  218. /**
  219. * Store definition for the editor namespace.
  220. *
  221. * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore
  222. *
  223. * @type {Object}
  224. */
  225. const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, {
  226. ...storeConfig
  227. });
  228. (0,external_wp_data_namespaceObject.register)(store);
  229. unlock(store).registerPrivateActions(actions_namespaceObject);
  230. unlock(store).registerPrivateSelectors(selectors_namespaceObject);
  231. ;// CONCATENATED MODULE: external ["wp","element"]
  232. var external_wp_element_namespaceObject = window["wp"]["element"];
  233. ;// CONCATENATED MODULE: external ["wp","components"]
  234. var external_wp_components_namespaceObject = window["wp"]["components"];
  235. ;// CONCATENATED MODULE: external ["wp","i18n"]
  236. var external_wp_i18n_namespaceObject = window["wp"]["i18n"];
  237. ;// CONCATENATED MODULE: external ["wp","notices"]
  238. var external_wp_notices_namespaceObject = window["wp"]["notices"];
  239. ;// CONCATENATED MODULE: external ["wp","compose"]
  240. var external_wp_compose_namespaceObject = window["wp"]["compose"];
  241. ;// CONCATENATED MODULE: external ["wp","htmlEntities"]
  242. var external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"];
  243. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/components/category-selector.js
  244. /**
  245. * WordPress dependencies
  246. */
  247. const unescapeString = arg => {
  248. return (0,external_wp_htmlEntities_namespaceObject.decodeEntities)(arg);
  249. };
  250. const CATEGORY_SLUG = 'wp_pattern_category';
  251. function CategorySelector({
  252. categoryTerms,
  253. onChange,
  254. categoryMap
  255. }) {
  256. const [search, setSearch] = (0,external_wp_element_namespaceObject.useState)('');
  257. const debouncedSearch = (0,external_wp_compose_namespaceObject.useDebounce)(setSearch, 500);
  258. const suggestions = (0,external_wp_element_namespaceObject.useMemo)(() => {
  259. return Array.from(categoryMap.values()).map(category => unescapeString(category.label)).filter(category => {
  260. if (search !== '') {
  261. return category.toLowerCase().includes(search.toLowerCase());
  262. }
  263. return true;
  264. }).sort((a, b) => a.localeCompare(b));
  265. }, [search, categoryMap]);
  266. function handleChange(termNames) {
  267. const uniqueTerms = termNames.reduce((terms, newTerm) => {
  268. if (!terms.some(term => term.toLowerCase() === newTerm.toLowerCase())) {
  269. terms.push(newTerm);
  270. }
  271. return terms;
  272. }, []);
  273. onChange(uniqueTerms);
  274. }
  275. return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FormTokenField, {
  276. className: "patterns-menu-items__convert-modal-categories",
  277. value: categoryTerms,
  278. suggestions: suggestions,
  279. onChange: handleChange,
  280. onInputChange: debouncedSearch,
  281. label: (0,external_wp_i18n_namespaceObject.__)('Categories'),
  282. tokenizeOnBlur: true,
  283. __experimentalExpandOnFocus: true,
  284. __next40pxDefaultSize: true
  285. });
  286. }
  287. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/components/create-pattern-modal.js
  288. /**
  289. * WordPress dependencies
  290. */
  291. /**
  292. * Internal dependencies
  293. */
  294. /**
  295. * Internal dependencies
  296. */
  297. function CreatePatternModal({
  298. onSuccess,
  299. onError,
  300. content,
  301. onClose,
  302. className = 'patterns-menu-items__convert-modal'
  303. }) {
  304. const [syncType, setSyncType] = (0,external_wp_element_namespaceObject.useState)(PATTERN_SYNC_TYPES.full);
  305. const [categoryTerms, setCategoryTerms] = (0,external_wp_element_namespaceObject.useState)([]);
  306. const [title, setTitle] = (0,external_wp_element_namespaceObject.useState)('');
  307. const [isSaving, setIsSaving] = (0,external_wp_element_namespaceObject.useState)(false);
  308. const {
  309. createPattern
  310. } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store));
  311. const {
  312. saveEntityRecord,
  313. invalidateResolution
  314. } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_coreData_namespaceObject.store);
  315. const {
  316. createErrorNotice
  317. } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store);
  318. const {
  319. corePatternCategories,
  320. userPatternCategories
  321. } = (0,external_wp_data_namespaceObject.useSelect)(select => {
  322. const {
  323. getUserPatternCategories,
  324. getBlockPatternCategories
  325. } = select(external_wp_coreData_namespaceObject.store);
  326. return {
  327. corePatternCategories: getBlockPatternCategories(),
  328. userPatternCategories: getUserPatternCategories()
  329. };
  330. });
  331. const categoryMap = (0,external_wp_element_namespaceObject.useMemo)(() => {
  332. // Merge the user and core pattern categories and remove any duplicates.
  333. const uniqueCategories = new Map();
  334. [...userPatternCategories, ...corePatternCategories].forEach(category => {
  335. if (!uniqueCategories.has(category.label) &&
  336. // There are two core categories with `Post` label so explicitly remove the one with
  337. // the `query` slug to avoid any confusion.
  338. category.name !== 'query') {
  339. // We need to store the name separately as this is used as the slug in the
  340. // taxonomy and may vary from the label.
  341. uniqueCategories.set(category.label, {
  342. label: category.label,
  343. value: category.label,
  344. name: category.name
  345. });
  346. }
  347. });
  348. return uniqueCategories;
  349. }, [userPatternCategories, corePatternCategories]);
  350. async function onCreate(patternTitle, sync) {
  351. if (!title || isSaving) {
  352. return;
  353. }
  354. try {
  355. setIsSaving(true);
  356. const categories = await Promise.all(categoryTerms.map(termName => findOrCreateTerm(termName)));
  357. const newPattern = await createPattern(patternTitle, sync, typeof content === 'function' ? content() : content, categories);
  358. onSuccess({
  359. pattern: newPattern,
  360. categoryId: PATTERN_DEFAULT_CATEGORY
  361. });
  362. } catch (error) {
  363. createErrorNotice(error.message, {
  364. type: 'snackbar',
  365. id: 'convert-to-pattern-error'
  366. });
  367. onError();
  368. } finally {
  369. setIsSaving(false);
  370. setCategoryTerms([]);
  371. setTitle('');
  372. }
  373. }
  374. /**
  375. * @param {string} term
  376. * @return {Promise<number>} The pattern category id.
  377. */
  378. async function findOrCreateTerm(term) {
  379. try {
  380. // We need to match any existing term to the correct slug to prevent duplicates, eg.
  381. // the core `Headers` category uses the singular `header` as the slug.
  382. const existingTerm = categoryMap.get(term);
  383. const termData = existingTerm ? {
  384. name: existingTerm.label,
  385. slug: existingTerm.name
  386. } : {
  387. name: term
  388. };
  389. const newTerm = await saveEntityRecord('taxonomy', CATEGORY_SLUG, termData, {
  390. throwOnError: true
  391. });
  392. invalidateResolution('getUserPatternCategories');
  393. return newTerm.id;
  394. } catch (error) {
  395. if (error.code !== 'term_exists') {
  396. throw error;
  397. }
  398. return error.data.term_id;
  399. }
  400. }
  401. return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Modal, {
  402. title: (0,external_wp_i18n_namespaceObject.__)('Create pattern'),
  403. onRequestClose: () => {
  404. onClose();
  405. setTitle('');
  406. },
  407. overlayClassName: className
  408. }, (0,external_wp_element_namespaceObject.createElement)("form", {
  409. onSubmit: event => {
  410. event.preventDefault();
  411. onCreate(title, syncType);
  412. }
  413. }, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalVStack, {
  414. spacing: "5"
  415. }, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.TextControl, {
  416. __nextHasNoMarginBottom: true,
  417. label: (0,external_wp_i18n_namespaceObject.__)('Name'),
  418. value: title,
  419. onChange: setTitle,
  420. placeholder: (0,external_wp_i18n_namespaceObject.__)('My pattern'),
  421. className: "patterns-create-modal__name-input"
  422. }), (0,external_wp_element_namespaceObject.createElement)(CategorySelector, {
  423. categoryTerms: categoryTerms,
  424. onChange: setCategoryTerms,
  425. categoryMap: categoryMap
  426. }), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.ToggleControl, {
  427. label: (0,external_wp_i18n_namespaceObject.__)('Synced'),
  428. help: (0,external_wp_i18n_namespaceObject.__)('Editing the pattern will update it anywhere it is used.'),
  429. checked: syncType === PATTERN_SYNC_TYPES.full,
  430. onChange: () => {
  431. setSyncType(syncType === PATTERN_SYNC_TYPES.full ? PATTERN_SYNC_TYPES.unsynced : PATTERN_SYNC_TYPES.full);
  432. }
  433. }), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, {
  434. justify: "right"
  435. }, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
  436. variant: "tertiary",
  437. onClick: () => {
  438. onClose();
  439. setTitle('');
  440. }
  441. }, (0,external_wp_i18n_namespaceObject.__)('Cancel')), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
  442. variant: "primary",
  443. type: "submit",
  444. "aria-disabled": !title || isSaving,
  445. isBusy: isSaving
  446. }, (0,external_wp_i18n_namespaceObject.__)('Create'))))));
  447. }
  448. ;// CONCATENATED MODULE: external ["wp","primitives"]
  449. var external_wp_primitives_namespaceObject = window["wp"]["primitives"];
  450. ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/symbol.js
  451. /**
  452. * WordPress dependencies
  453. */
  454. const symbol = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
  455. xmlns: "http://www.w3.org/2000/svg",
  456. viewBox: "0 0 24 24"
  457. }, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
  458. 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"
  459. }));
  460. /* harmony default export */ var library_symbol = (symbol);
  461. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/components/pattern-convert-button.js
  462. /**
  463. * WordPress dependencies
  464. */
  465. /**
  466. * Internal dependencies
  467. */
  468. /**
  469. * Menu control to convert block(s) to a pattern block.
  470. *
  471. * @param {Object} props Component props.
  472. * @param {string[]} props.clientIds Client ids of selected blocks.
  473. * @param {string} props.rootClientId ID of the currently selected top-level block.
  474. * @return {import('@wordpress/element').WPComponent} The menu control or null.
  475. */
  476. function PatternConvertButton({
  477. clientIds,
  478. rootClientId
  479. }) {
  480. const {
  481. createSuccessNotice
  482. } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store);
  483. const {
  484. replaceBlocks
  485. } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_blockEditor_namespaceObject.store);
  486. // Ignore reason: false positive of the lint rule.
  487. // eslint-disable-next-line @wordpress/no-unused-vars-before-return
  488. const {
  489. setEditingPattern
  490. } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store));
  491. const [isModalOpen, setIsModalOpen] = (0,external_wp_element_namespaceObject.useState)(false);
  492. const canConvert = (0,external_wp_data_namespaceObject.useSelect)(select => {
  493. var _getBlocksByClientId;
  494. const {
  495. canUser
  496. } = select(external_wp_coreData_namespaceObject.store);
  497. const {
  498. getBlocksByClientId,
  499. canInsertBlockType,
  500. getBlockRootClientId
  501. } = select(external_wp_blockEditor_namespaceObject.store);
  502. const rootId = rootClientId || (clientIds.length > 0 ? getBlockRootClientId(clientIds[0]) : undefined);
  503. const blocks = (_getBlocksByClientId = getBlocksByClientId(clientIds)) !== null && _getBlocksByClientId !== void 0 ? _getBlocksByClientId : [];
  504. const isReusable = blocks.length === 1 && blocks[0] && (0,external_wp_blocks_namespaceObject.isReusableBlock)(blocks[0]) && !!select(external_wp_coreData_namespaceObject.store).getEntityRecord('postType', 'wp_block', blocks[0].attributes.ref);
  505. const _canConvert =
  506. // Hide when this is already a synced pattern.
  507. !isReusable &&
  508. // Hide when patterns are disabled.
  509. canInsertBlockType('core/block', rootId) && blocks.every(block =>
  510. // Guard against the case where a regular block has *just* been converted.
  511. !!block &&
  512. // Hide on invalid blocks.
  513. block.isValid &&
  514. // Hide when block doesn't support being made into a pattern.
  515. (0,external_wp_blocks_namespaceObject.hasBlockSupport)(block.name, 'reusable', true)) &&
  516. // Hide when current doesn't have permission to do that.
  517. !!canUser('create', 'blocks');
  518. return _canConvert;
  519. }, [clientIds, rootClientId]);
  520. const {
  521. getBlocksByClientId
  522. } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blockEditor_namespaceObject.store);
  523. const getContent = (0,external_wp_element_namespaceObject.useCallback)(() => (0,external_wp_blocks_namespaceObject.serialize)(getBlocksByClientId(clientIds)), [getBlocksByClientId, clientIds]);
  524. if (!canConvert) {
  525. return null;
  526. }
  527. const handleSuccess = ({
  528. pattern
  529. }) => {
  530. if (pattern.wp_pattern_sync_status !== PATTERN_SYNC_TYPES.unsynced) {
  531. const newBlock = (0,external_wp_blocks_namespaceObject.createBlock)('core/block', {
  532. ref: pattern.id
  533. });
  534. replaceBlocks(clientIds, newBlock);
  535. setEditingPattern(newBlock.clientId, true);
  536. }
  537. createSuccessNotice(pattern.wp_pattern_sync_status === PATTERN_SYNC_TYPES.unsynced ? (0,external_wp_i18n_namespaceObject.sprintf)(
  538. // translators: %s: the name the user has given to the pattern.
  539. (0,external_wp_i18n_namespaceObject.__)('Unsynced pattern created: %s'), pattern.title.raw) : (0,external_wp_i18n_namespaceObject.sprintf)(
  540. // translators: %s: the name the user has given to the pattern.
  541. (0,external_wp_i18n_namespaceObject.__)('Synced pattern created: %s'), pattern.title.raw), {
  542. type: 'snackbar',
  543. id: 'convert-to-pattern-success'
  544. });
  545. setIsModalOpen(false);
  546. };
  547. return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItem, {
  548. icon: library_symbol,
  549. onClick: () => setIsModalOpen(true),
  550. "aria-expanded": isModalOpen,
  551. "aria-haspopup": "dialog"
  552. }, (0,external_wp_i18n_namespaceObject.__)('Create pattern')), isModalOpen && (0,external_wp_element_namespaceObject.createElement)(CreatePatternModal, {
  553. content: getContent,
  554. onSuccess: pattern => {
  555. handleSuccess(pattern);
  556. },
  557. onError: () => {
  558. setIsModalOpen(false);
  559. },
  560. onClose: () => {
  561. setIsModalOpen(false);
  562. }
  563. }));
  564. }
  565. ;// CONCATENATED MODULE: external ["wp","url"]
  566. var external_wp_url_namespaceObject = window["wp"]["url"];
  567. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/components/patterns-manage-button.js
  568. /**
  569. * WordPress dependencies
  570. */
  571. /**
  572. * Internal dependencies
  573. */
  574. function PatternsManageButton({
  575. clientId
  576. }) {
  577. const {
  578. canRemove,
  579. isVisible,
  580. innerBlockCount,
  581. managePatternsUrl
  582. } = (0,external_wp_data_namespaceObject.useSelect)(select => {
  583. const {
  584. getBlock,
  585. canRemoveBlock,
  586. getBlockCount,
  587. getSettings
  588. } = select(external_wp_blockEditor_namespaceObject.store);
  589. const {
  590. canUser
  591. } = select(external_wp_coreData_namespaceObject.store);
  592. const reusableBlock = getBlock(clientId);
  593. const isBlockTheme = getSettings().__unstableIsBlockBasedTheme;
  594. return {
  595. canRemove: canRemoveBlock(clientId),
  596. isVisible: !!reusableBlock && (0,external_wp_blocks_namespaceObject.isReusableBlock)(reusableBlock) && !!canUser('update', 'blocks', reusableBlock.attributes.ref),
  597. innerBlockCount: getBlockCount(clientId),
  598. // The site editor and templates both check whether the user
  599. // has edit_theme_options capabilities. We can leverage that here
  600. // and omit the manage patterns link if the user can't access it.
  601. managePatternsUrl: isBlockTheme && canUser('read', 'templates') ? (0,external_wp_url_namespaceObject.addQueryArgs)('site-editor.php', {
  602. path: '/patterns'
  603. }) : (0,external_wp_url_namespaceObject.addQueryArgs)('edit.php', {
  604. post_type: 'wp_block'
  605. })
  606. };
  607. }, [clientId]);
  608. // Ignore reason: false positive of the lint rule.
  609. // eslint-disable-next-line @wordpress/no-unused-vars-before-return
  610. const {
  611. convertSyncedPatternToStatic
  612. } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store));
  613. if (!isVisible) {
  614. return null;
  615. }
  616. return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItem, {
  617. href: managePatternsUrl
  618. }, (0,external_wp_i18n_namespaceObject.__)('Manage patterns')), canRemove && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItem, {
  619. onClick: () => convertSyncedPatternToStatic(clientId)
  620. }, innerBlockCount > 1 ? (0,external_wp_i18n_namespaceObject.__)('Detach patterns') : (0,external_wp_i18n_namespaceObject.__)('Detach pattern')));
  621. }
  622. /* harmony default export */ var patterns_manage_button = (PatternsManageButton);
  623. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/components/index.js
  624. /**
  625. * WordPress dependencies
  626. */
  627. /**
  628. * Internal dependencies
  629. */
  630. function PatternsMenuItems({
  631. rootClientId
  632. }) {
  633. return (0,external_wp_element_namespaceObject.createElement)(external_wp_blockEditor_namespaceObject.BlockSettingsMenuControls, null, ({
  634. selectedClientIds
  635. }) => (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(PatternConvertButton, {
  636. clientIds: selectedClientIds,
  637. rootClientId: rootClientId
  638. }), selectedClientIds.length === 1 && (0,external_wp_element_namespaceObject.createElement)(patterns_manage_button, {
  639. clientId: selectedClientIds[0]
  640. })));
  641. }
  642. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/private-apis.js
  643. /**
  644. * Internal dependencies
  645. */
  646. const privateApis = {};
  647. lock(privateApis, {
  648. CreatePatternModal: CreatePatternModal,
  649. PatternsMenuItems: PatternsMenuItems,
  650. PATTERN_TYPES: PATTERN_TYPES,
  651. PATTERN_DEFAULT_CATEGORY: PATTERN_DEFAULT_CATEGORY,
  652. PATTERN_USER_CATEGORY: PATTERN_USER_CATEGORY,
  653. PATTERN_CORE_SOURCES: PATTERN_CORE_SOURCES,
  654. PATTERN_SYNC_TYPES: PATTERN_SYNC_TYPES
  655. });
  656. ;// CONCATENATED MODULE: ./node_modules/@wordpress/patterns/build-module/index.js
  657. /**
  658. * Internal dependencies
  659. */
  660. (window.wp = window.wp || {}).patterns = __webpack_exports__;
  661. /******/ })()
  662. ;