) & MemizeMemoizedFunction} Memoized function.
*/
function memize(fn, options) {
var size = 0;
/** @type {?MemizeCacheNode|undefined} */
var head;
/** @type {?MemizeCacheNode|undefined} */
var tail;
options = options || {};
function memoized(/* ...args */) {
var node = head,
len = arguments.length,
args,
i;
searchCache: while (node) {
// Perform a shallow equality test to confirm that whether the node
// under test is a candidate for the arguments passed. Two arrays
// are shallowly equal if their length matches and each entry is
// strictly equal between the two sets. Avoid abstracting to a
// function which could incur an arguments leaking deoptimization.
// Check whether node arguments match arguments length
if (node.args.length !== arguments.length) {
node = node.next;
continue;
}
// Check whether node arguments match arguments values
for (i = 0; i < len; i++) {
if (node.args[i] !== arguments[i]) {
node = node.next;
continue searchCache;
}
}
// At this point we can assume we've found a match
// Surface matched node to head if not already
if (node !== head) {
// As tail, shift to previous. Must only shift if not also
// head, since if both head and tail, there is no previous.
if (node === tail) {
tail = node.prev;
}
// Adjust siblings to point to each other. If node was tail,
// this also handles new tail's empty `next` assignment.
/** @type {MemizeCacheNode} */ (node.prev).next = node.next;
if (node.next) {
node.next.prev = node.prev;
}
node.next = head;
node.prev = null;
/** @type {MemizeCacheNode} */ (head).prev = node;
head = node;
}
// Return immediately
return node.val;
}
// No cached value found. Continue to insertion phase:
// Create a copy of arguments (avoid leaking deoptimization)
args = new Array(len);
for (i = 0; i < len; i++) {
args[i] = arguments[i];
}
node = {
args: args,
// Generate the result from original function
val: fn.apply(null, args),
};
// Don't need to check whether node is already head, since it would
// have been returned above already if it was
// Shift existing head down list
if (head) {
head.prev = node;
node.next = head;
} else {
// If no head, follows that there's no tail (at initial or reset)
tail = node;
}
// Trim tail if we're reached max size and are pending cache insertion
if (size === /** @type {MemizeOptions} */ (options).maxSize) {
tail = /** @type {MemizeCacheNode} */ (tail).prev;
/** @type {MemizeCacheNode} */ (tail).next = null;
} else {
size++;
}
head = node;
return node.val;
}
memoized.clear = function () {
head = null;
tail = null;
size = 0;
};
// Ignore reason: There's not a clear solution to create an intersection of
// the function with additional properties, where the goal is to retain the
// function signature of the incoming argument and add control properties
// on the return value.
// @ts-ignore
return memoized;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/hooks/memoize.js
/**
* External dependencies
*/
// re-export due to restrictive esModuleInterop setting
/* harmony default export */ const memoize = (memize);
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/hooks/constants.js
let Status = /*#__PURE__*/function (Status) {
Status["Idle"] = "IDLE";
Status["Resolving"] = "RESOLVING";
Status["Error"] = "ERROR";
Status["Success"] = "SUCCESS";
return Status;
}({});
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/hooks/use-query-select.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const META_SELECTORS = ['getIsResolving', 'hasStartedResolution', 'hasFinishedResolution', 'isResolving', 'getCachedResolvers'];
/**
* Like useSelect, but the selectors return objects containing
* both the original data AND the resolution info.
*
* @since 6.1.0 Introduced in WordPress core.
* @private
*
* @param {Function} mapQuerySelect see useSelect
* @param {Array} deps see useSelect
*
* @example
* ```js
* import { useQuerySelect } from '@wordpress/data';
* import { store as coreDataStore } from '@wordpress/core-data';
*
* function PageTitleDisplay( { id } ) {
* const { data: page, isResolving } = useQuerySelect( ( query ) => {
* return query( coreDataStore ).getEntityRecord( 'postType', 'page', id )
* }, [ id ] );
*
* if ( isResolving ) {
* return 'Loading...';
* }
*
* return page.title;
* }
*
* // Rendered in the application:
* //
* ```
*
* In the above example, when `PageTitleDisplay` is rendered into an
* application, the page and the resolution details will be retrieved from
* the store state using the `mapSelect` callback on `useQuerySelect`.
*
* If the id prop changes then any page in the state for that id is
* retrieved. If the id prop doesn't change and other props are passed in
* that do change, the title will not change because the dependency is just
* the id.
* @see useSelect
*
* @return {QuerySelectResponse} Queried data.
*/
function useQuerySelect(mapQuerySelect, deps) {
return (0,external_wp_data_namespaceObject.useSelect)((select, registry) => {
const resolve = store => enrichSelectors(select(store));
return mapQuerySelect(resolve, registry);
}, deps);
}
/**
* Transform simple selectors into ones that return an object with the
* original return value AND the resolution info.
*
* @param {Object} selectors Selectors to enrich
* @return {EnrichedSelectors} Enriched selectors
*/
const enrichSelectors = memoize(selectors => {
const resolvers = {};
for (const selectorName in selectors) {
if (META_SELECTORS.includes(selectorName)) {
continue;
}
Object.defineProperty(resolvers, selectorName, {
get: () => (...args) => {
const data = selectors[selectorName](...args);
const resolutionStatus = selectors.getResolutionState(selectorName, args)?.status;
let status;
switch (resolutionStatus) {
case 'resolving':
status = Status.Resolving;
break;
case 'finished':
status = Status.Success;
break;
case 'error':
status = Status.Error;
break;
case undefined:
status = Status.Idle;
break;
}
return {
data,
status,
isResolving: status === Status.Resolving,
hasStarted: status !== Status.Idle,
hasResolved: status === Status.Success || status === Status.Error
};
}
});
}
return resolvers;
});
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/hooks/use-entity-record.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const use_entity_record_EMPTY_OBJECT = {};
/**
* Resolves the specified entity record.
*
* @since 6.1.0 Introduced in WordPress core.
*
* @param kind Kind of the entity, e.g. `root` or a `postType`. See rootEntitiesConfig in ../entities.ts for a list of available kinds.
* @param name Name of the entity, e.g. `plugin` or a `post`. See rootEntitiesConfig in ../entities.ts for a list of available names.
* @param recordId ID of the requested entity record.
* @param options Optional hook options.
* @example
* ```js
* import { useEntityRecord } from '@wordpress/core-data';
*
* function PageTitleDisplay( { id } ) {
* const { record, isResolving } = useEntityRecord( 'postType', 'page', id );
*
* if ( isResolving ) {
* return 'Loading...';
* }
*
* return record.title;
* }
*
* // Rendered in the application:
* //
* ```
*
* In the above example, when `PageTitleDisplay` is rendered into an
* application, the page and the resolution details will be retrieved from
* the store state using `getEntityRecord()`, or resolved if missing.
*
* @example
* ```js
* import { useCallback } from 'react';
* import { useDispatch } from '@wordpress/data';
* import { __ } from '@wordpress/i18n';
* import { TextControl } from '@wordpress/components';
* import { store as noticeStore } from '@wordpress/notices';
* import { useEntityRecord } from '@wordpress/core-data';
*
* function PageRenameForm( { id } ) {
* const page = useEntityRecord( 'postType', 'page', id );
* const { createSuccessNotice, createErrorNotice } =
* useDispatch( noticeStore );
*
* const setTitle = useCallback( ( title ) => {
* page.edit( { title } );
* }, [ page.edit ] );
*
* if ( page.isResolving ) {
* return 'Loading...';
* }
*
* async function onRename( event ) {
* event.preventDefault();
* try {
* await page.save();
* createSuccessNotice( __( 'Page renamed.' ), {
* type: 'snackbar',
* } );
* } catch ( error ) {
* createErrorNotice( error.message, { type: 'snackbar' } );
* }
* }
*
* return (
*
* );
* }
*
* // Rendered in the application:
* //
* ```
*
* In the above example, updating and saving the page title is handled
* via the `edit()` and `save()` mutation helpers provided by
* `useEntityRecord()`;
*
* @return Entity record data.
* @template RecordType
*/
function useEntityRecord(kind, name, recordId, options = {
enabled: true
}) {
const {
editEntityRecord,
saveEditedEntityRecord
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const mutations = (0,external_wp_element_namespaceObject.useMemo)(() => ({
edit: (record, editOptions = {}) => editEntityRecord(kind, name, recordId, record, editOptions),
save: (saveOptions = {}) => saveEditedEntityRecord(kind, name, recordId, {
throwOnError: true,
...saveOptions
})
}), [editEntityRecord, kind, name, recordId, saveEditedEntityRecord]);
const {
editedRecord,
hasEdits,
edits
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
if (!options.enabled) {
return {
editedRecord: use_entity_record_EMPTY_OBJECT,
hasEdits: false,
edits: use_entity_record_EMPTY_OBJECT
};
}
return {
editedRecord: select(store).getEditedEntityRecord(kind, name, recordId),
hasEdits: select(store).hasEditsForEntityRecord(kind, name, recordId),
edits: select(store).getEntityRecordNonTransientEdits(kind, name, recordId)
};
}, [kind, name, recordId, options.enabled]);
const {
data: record,
...querySelectRest
} = useQuerySelect(query => {
if (!options.enabled) {
return {
data: null
};
}
return query(store).getEntityRecord(kind, name, recordId);
}, [kind, name, recordId, options.enabled]);
return {
record,
editedRecord,
hasEdits,
edits,
...querySelectRest,
...mutations
};
}
function __experimentalUseEntityRecord(kind, name, recordId, options) {
external_wp_deprecated_default()(`wp.data.__experimentalUseEntityRecord`, {
alternative: 'wp.data.useEntityRecord',
since: '6.1'
});
return useEntityRecord(kind, name, recordId, options);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/hooks/use-entity-records.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const EMPTY_ARRAY = [];
/**
* Resolves the specified entity records.
*
* @since 6.1.0 Introduced in WordPress core.
*
* @param kind Kind of the entity, e.g. `root` or a `postType`. See rootEntitiesConfig in ../entities.ts for a list of available kinds.
* @param name Name of the entity, e.g. `plugin` or a `post`. See rootEntitiesConfig in ../entities.ts for a list of available names.
* @param queryArgs Optional HTTP query description for how to fetch the data, passed to the requested API endpoint.
* @param options Optional hook options.
* @example
* ```js
* import { useEntityRecords } from '@wordpress/core-data';
*
* function PageTitlesList() {
* const { records, isResolving } = useEntityRecords( 'postType', 'page' );
*
* if ( isResolving ) {
* return 'Loading...';
* }
*
* return (
*
* {records.map(( page ) => (
* - { page.title }
* ))}
*
* );
* }
*
* // Rendered in the application:
* //
* ```
*
* In the above example, when `PageTitlesList` is rendered into an
* application, the list of records and the resolution details will be retrieved from
* the store state using `getEntityRecords()`, or resolved if missing.
*
* @return Entity records data.
* @template RecordType
*/
function useEntityRecords(kind, name, queryArgs = {}, options = {
enabled: true
}) {
// Serialize queryArgs to a string that can be safely used as a React dep.
// We can't just pass queryArgs as one of the deps, because if it is passed
// as an object literal, then it will be a different object on each call even
// if the values remain the same.
const queryAsString = (0,external_wp_url_namespaceObject.addQueryArgs)('', queryArgs);
const {
data: records,
...rest
} = useQuerySelect(query => {
if (!options.enabled) {
return {
// Avoiding returning a new reference on every execution.
data: EMPTY_ARRAY
};
}
return query(store).getEntityRecords(kind, name, queryArgs);
}, [kind, name, queryAsString, options.enabled]);
const {
totalItems,
totalPages
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
if (!options.enabled) {
return {
totalItems: null,
totalPages: null
};
}
return {
totalItems: select(store).getEntityRecordsTotalItems(kind, name, queryArgs),
totalPages: select(store).getEntityRecordsTotalPages(kind, name, queryArgs)
};
}, [kind, name, queryAsString, options.enabled]);
return {
records,
totalItems,
totalPages,
...rest
};
}
function __experimentalUseEntityRecords(kind, name, queryArgs, options) {
external_wp_deprecated_default()(`wp.data.__experimentalUseEntityRecords`, {
alternative: 'wp.data.useEntityRecords',
since: '6.1'
});
return useEntityRecords(kind, name, queryArgs, options);
}
function useEntityRecordsWithPermissions(kind, name, queryArgs = {}, options = {
enabled: true
}) {
const entityConfig = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getEntityConfig(kind, name), [kind, name]);
const {
records: data,
...ret
} = useEntityRecords(kind, name, queryArgs, options);
const ids = (0,external_wp_element_namespaceObject.useMemo)(() => {
var _data$map;
return (_data$map = data?.map(
// @ts-ignore
record => {
var _entityConfig$key;
return record[(_entityConfig$key = entityConfig?.key) !== null && _entityConfig$key !== void 0 ? _entityConfig$key : 'id'];
})) !== null && _data$map !== void 0 ? _data$map : [];
}, [data, entityConfig?.key]);
const permissions = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEntityRecordsPermissions
} = unlock(select(store));
return getEntityRecordsPermissions(kind, name, ids);
}, [ids, kind, name]);
const dataWithPermissions = (0,external_wp_element_namespaceObject.useMemo)(() => {
var _data$map2;
return (_data$map2 = data?.map((record, index) => ({
// @ts-ignore
...record,
permissions: permissions[index]
}))) !== null && _data$map2 !== void 0 ? _data$map2 : [];
}, [data, permissions]);
return {
records: dataWithPermissions,
...ret
};
}
;// CONCATENATED MODULE: external ["wp","warning"]
const external_wp_warning_namespaceObject = window["wp"]["warning"];
var external_wp_warning_default = /*#__PURE__*/__webpack_require__.n(external_wp_warning_namespaceObject);
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/hooks/use-resource-permissions.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Is the data resolved by now?
*/
/**
* Resolves resource permissions.
*
* @since 6.1.0 Introduced in WordPress core.
*
* @param resource Entity resource to check. Accepts entity object `{ kind: 'root', name: 'media', id: 1 }`
* or REST base as a string - `media`.
* @param id Optional ID of the resource to check, e.g. 10. Note: This argument is discouraged
* when using an entity object as a resource to check permissions and will be ignored.
*
* @example
* ```js
* import { useResourcePermissions } from '@wordpress/core-data';
*
* function PagesList() {
* const { canCreate, isResolving } = useResourcePermissions( { kind: 'postType', name: 'page' } );
*
* if ( isResolving ) {
* return 'Loading ...';
* }
*
* return (
*
* {canCreate ? () : false}
* // ...
*
* );
* }
*
* // Rendered in the application:
* //
* ```
*
* @example
* ```js
* import { useResourcePermissions } from '@wordpress/core-data';
*
* function Page({ pageId }) {
* const {
* canCreate,
* canUpdate,
* canDelete,
* isResolving
* } = useResourcePermissions( { kind: 'postType', name: 'page', id: pageId } );
*
* if ( isResolving ) {
* return 'Loading ...';
* }
*
* return (
*
* {canCreate ? () : false}
* {canUpdate ? () : false}
* {canDelete ? () : false}
* // ...
*
* );
* }
*
* // Rendered in the application:
* //
* ```
*
* In the above example, when `PagesList` is rendered into an
* application, the appropriate permissions and the resolution details will be retrieved from
* the store state using `canUser()`, or resolved if missing.
*
* @return Entity records data.
* @template IdType
*/
function useResourcePermissions(resource, id) {
// Serialize `resource` to a string that can be safely used as a React dep.
// We can't just pass `resource` as one of the deps, because if it is passed
// as an object literal, then it will be a different object on each call even
// if the values remain the same.
const isEntity = typeof resource === 'object';
const resourceAsString = isEntity ? JSON.stringify(resource) : resource;
if (isEntity && typeof id !== 'undefined') {
true ? external_wp_warning_default()(`When 'resource' is an entity object, passing 'id' as a separate argument isn't supported.`) : 0;
}
return useQuerySelect(resolve => {
const hasId = isEntity ? !!resource.id : !!id;
const {
canUser
} = resolve(store);
const create = canUser('create', isEntity ? {
kind: resource.kind,
name: resource.name
} : resource);
if (!hasId) {
const read = canUser('read', resource);
const isResolving = create.isResolving || read.isResolving;
const hasResolved = create.hasResolved && read.hasResolved;
let status = Status.Idle;
if (isResolving) {
status = Status.Resolving;
} else if (hasResolved) {
status = Status.Success;
}
return {
status,
isResolving,
hasResolved,
canCreate: create.hasResolved && create.data,
canRead: read.hasResolved && read.data
};
}
const read = canUser('read', resource, id);
const update = canUser('update', resource, id);
const _delete = canUser('delete', resource, id);
const isResolving = read.isResolving || create.isResolving || update.isResolving || _delete.isResolving;
const hasResolved = read.hasResolved && create.hasResolved && update.hasResolved && _delete.hasResolved;
let status = Status.Idle;
if (isResolving) {
status = Status.Resolving;
} else if (hasResolved) {
status = Status.Success;
}
return {
status,
isResolving,
hasResolved,
canRead: hasResolved && read.data,
canCreate: hasResolved && create.data,
canUpdate: hasResolved && update.data,
canDelete: hasResolved && _delete.data
};
}, [resourceAsString, id]);
}
/* harmony default export */ const use_resource_permissions = (useResourcePermissions);
function __experimentalUseResourcePermissions(resource, id) {
external_wp_deprecated_default()(`wp.data.__experimentalUseResourcePermissions`, {
alternative: 'wp.data.useResourcePermissions',
since: '6.1'
});
return useResourcePermissions(resource, id);
}
;// CONCATENATED MODULE: external ["wp","blocks"]
const external_wp_blocks_namespaceObject = window["wp"]["blocks"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/hooks/use-entity-id.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Hook that returns the ID for the nearest
* provided entity of the specified type.
*
* @param {string} kind The entity kind.
* @param {string} name The entity name.
*/
function useEntityId(kind, name) {
const context = (0,external_wp_element_namespaceObject.useContext)(EntityContext);
return context?.[kind]?.[name];
}
;// CONCATENATED MODULE: external ["wp","blockEditor"]
const external_wp_blockEditor_namespaceObject = window["wp"]["blockEditor"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/footnotes/get-rich-text-values-cached.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
// TODO: The following line should have been:
//
// const unlockedApis = unlock( blockEditorPrivateApis );
//
// But there are hidden circular dependencies in RNMobile code, specifically in
// certain native components in the `components` package that depend on
// `block-editor`. What follows is a workaround that defers the `unlock` call
// to prevent native code from failing.
//
// Fix once https://github.com/WordPress/gutenberg/issues/52692 is closed.
let unlockedApis;
const cache = new WeakMap();
function getRichTextValuesCached(block) {
if (!unlockedApis) {
unlockedApis = unlock(external_wp_blockEditor_namespaceObject.privateApis);
}
if (!cache.has(block)) {
const values = unlockedApis.getRichTextValues([block]);
cache.set(block, values);
}
return cache.get(block);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/footnotes/get-footnotes-order.js
/**
* Internal dependencies
*/
const get_footnotes_order_cache = new WeakMap();
function getBlockFootnotesOrder(block) {
if (!get_footnotes_order_cache.has(block)) {
const order = [];
for (const value of getRichTextValuesCached(block)) {
if (!value) {
continue;
}
// replacements is a sparse array, use forEach to skip empty slots.
value.replacements.forEach(({
type,
attributes
}) => {
if (type === 'core/footnote') {
order.push(attributes['data-fn']);
}
});
}
get_footnotes_order_cache.set(block, order);
}
return get_footnotes_order_cache.get(block);
}
function getFootnotesOrder(blocks) {
// We can only separate getting order from blocks at the root level. For
// deeper inner blocks, this will not work since it's possible to have both
// inner blocks and block attributes, so order needs to be computed from the
// Edit functions as a whole.
return blocks.flatMap(getBlockFootnotesOrder);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/footnotes/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
let oldFootnotes = {};
function updateFootnotesFromMeta(blocks, meta) {
const output = {
blocks
};
if (!meta) {
return output;
}
// If meta.footnotes is empty, it means the meta is not registered.
if (meta.footnotes === undefined) {
return output;
}
const newOrder = getFootnotesOrder(blocks);
const footnotes = meta.footnotes ? JSON.parse(meta.footnotes) : [];
const currentOrder = footnotes.map(fn => fn.id);
if (currentOrder.join('') === newOrder.join('')) {
return output;
}
const newFootnotes = newOrder.map(fnId => footnotes.find(fn => fn.id === fnId) || oldFootnotes[fnId] || {
id: fnId,
content: ''
});
function updateAttributes(attributes) {
// Only attempt to update attributes, if attributes is an object.
if (!attributes || Array.isArray(attributes) || typeof attributes !== 'object') {
return attributes;
}
attributes = {
...attributes
};
for (const key in attributes) {
const value = attributes[key];
if (Array.isArray(value)) {
attributes[key] = value.map(updateAttributes);
continue;
}
// To do, remove support for string values?
if (typeof value !== 'string' && !(value instanceof external_wp_richText_namespaceObject.RichTextData)) {
continue;
}
const richTextValue = typeof value === 'string' ? external_wp_richText_namespaceObject.RichTextData.fromHTMLString(value) : new external_wp_richText_namespaceObject.RichTextData(value);
let hasFootnotes = false;
richTextValue.replacements.forEach(replacement => {
if (replacement.type === 'core/footnote') {
const id = replacement.attributes['data-fn'];
const index = newOrder.indexOf(id);
// The innerHTML contains the count wrapped in a link.
const countValue = (0,external_wp_richText_namespaceObject.create)({
html: replacement.innerHTML
});
countValue.text = String(index + 1);
countValue.formats = Array.from({
length: countValue.text.length
}, () => countValue.formats[0]);
countValue.replacements = Array.from({
length: countValue.text.length
}, () => countValue.replacements[0]);
replacement.innerHTML = (0,external_wp_richText_namespaceObject.toHTMLString)({
value: countValue
});
hasFootnotes = true;
}
});
if (hasFootnotes) {
attributes[key] = typeof value === 'string' ? richTextValue.toHTMLString() : richTextValue;
}
}
return attributes;
}
function updateBlocksAttributes(__blocks) {
return __blocks.map(block => {
return {
...block,
attributes: updateAttributes(block.attributes),
innerBlocks: updateBlocksAttributes(block.innerBlocks)
};
});
}
// We need to go through all block attributes deeply and update the
// footnote anchor numbering (textContent) to match the new order.
const newBlocks = updateBlocksAttributes(blocks);
oldFootnotes = {
...oldFootnotes,
...footnotes.reduce((acc, fn) => {
if (!newOrder.includes(fn.id)) {
acc[fn.id] = fn;
}
return acc;
}, {})
};
return {
meta: {
...meta,
footnotes: JSON.stringify(newFootnotes)
},
blocks: newBlocks
};
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/hooks/use-entity-block-editor.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const use_entity_block_editor_EMPTY_ARRAY = [];
const parsedBlocksCache = new WeakMap();
/**
* Hook that returns block content getters and setters for
* the nearest provided entity of the specified type.
*
* The return value has the shape `[ blocks, onInput, onChange ]`.
* `onInput` is for block changes that don't create undo levels
* or dirty the post, non-persistent changes, and `onChange` is for
* persistent changes. They map directly to the props of a
* `BlockEditorProvider` and are intended to be used with it,
* or similar components or hooks.
*
* @param {string} kind The entity kind.
* @param {string} name The entity name.
* @param {Object} options
* @param {string} [options.id] An entity ID to use instead of the context-provided one.
*
* @return {[unknown[], Function, Function]} The block array and setters.
*/
function useEntityBlockEditor(kind, name, {
id: _id
} = {}) {
const providerId = useEntityId(kind, name);
const id = _id !== null && _id !== void 0 ? _id : providerId;
const {
getEntityRecord,
getEntityRecordEdits
} = (0,external_wp_data_namespaceObject.useSelect)(STORE_NAME);
const {
content,
editedBlocks,
meta
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
if (!id) {
return {};
}
const {
getEditedEntityRecord
} = select(STORE_NAME);
const editedRecord = getEditedEntityRecord(kind, name, id);
return {
editedBlocks: editedRecord.blocks,
content: editedRecord.content,
meta: editedRecord.meta
};
}, [kind, name, id]);
const {
__unstableCreateUndoLevel,
editEntityRecord
} = (0,external_wp_data_namespaceObject.useDispatch)(STORE_NAME);
const blocks = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (!id) {
return undefined;
}
if (editedBlocks) {
return editedBlocks;
}
if (!content || typeof content !== 'string') {
return use_entity_block_editor_EMPTY_ARRAY;
}
// If there's an edit, cache the parsed blocks by the edit.
// If not, cache by the original enity record.
const edits = getEntityRecordEdits(kind, name, id);
const isUnedited = !edits || !Object.keys(edits).length;
const cackeKey = isUnedited ? getEntityRecord(kind, name, id) : edits;
let _blocks = parsedBlocksCache.get(cackeKey);
if (!_blocks) {
_blocks = (0,external_wp_blocks_namespaceObject.parse)(content);
parsedBlocksCache.set(cackeKey, _blocks);
}
return _blocks;
}, [kind, name, id, editedBlocks, content, getEntityRecord, getEntityRecordEdits]);
const updateFootnotes = (0,external_wp_element_namespaceObject.useCallback)(_blocks => updateFootnotesFromMeta(_blocks, meta), [meta]);
const onChange = (0,external_wp_element_namespaceObject.useCallback)((newBlocks, options) => {
const noChange = blocks === newBlocks;
if (noChange) {
return __unstableCreateUndoLevel(kind, name, id);
}
const {
selection,
...rest
} = options;
// We create a new function here on every persistent edit
// to make sure the edit makes the post dirty and creates
// a new undo level.
const edits = {
selection,
content: ({
blocks: blocksForSerialization = []
}) => (0,external_wp_blocks_namespaceObject.__unstableSerializeAndClean)(blocksForSerialization),
...updateFootnotes(newBlocks)
};
editEntityRecord(kind, name, id, edits, {
isCached: false,
...rest
});
}, [kind, name, id, blocks, updateFootnotes, __unstableCreateUndoLevel, editEntityRecord]);
const onInput = (0,external_wp_element_namespaceObject.useCallback)((newBlocks, options) => {
const {
selection,
...rest
} = options;
const footnotesChanges = updateFootnotes(newBlocks);
const edits = {
selection,
...footnotesChanges
};
editEntityRecord(kind, name, id, edits, {
isCached: true,
...rest
});
}, [kind, name, id, updateFootnotes, editEntityRecord]);
return [blocks, onInput, onChange];
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/hooks/use-entity-prop.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Hook that returns the value and a setter for the
* specified property of the nearest provided
* entity of the specified type.
*
* @param {string} kind The entity kind.
* @param {string} name The entity name.
* @param {string} prop The property name.
* @param {number|string} [_id] An entity ID to use instead of the context-provided one.
*
* @return {[*, Function, *]} An array where the first item is the
* property value, the second is the
* setter and the third is the full value
* object from REST API containing more
* information like `raw`, `rendered` and
* `protected` props.
*/
function useEntityProp(kind, name, prop, _id) {
const providerId = useEntityId(kind, name);
const id = _id !== null && _id !== void 0 ? _id : providerId;
const {
value,
fullValue
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEntityRecord,
getEditedEntityRecord
} = select(STORE_NAME);
const record = getEntityRecord(kind, name, id); // Trigger resolver.
const editedRecord = getEditedEntityRecord(kind, name, id);
return record && editedRecord ? {
value: editedRecord[prop],
fullValue: record[prop]
} : {};
}, [kind, name, id, prop]);
const {
editEntityRecord
} = (0,external_wp_data_namespaceObject.useDispatch)(STORE_NAME);
const setValue = (0,external_wp_element_namespaceObject.useCallback)(newValue => {
editEntityRecord(kind, name, id, {
[prop]: newValue
});
}, [editEntityRecord, kind, name, id, prop]);
return [value, setValue, fullValue];
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/hooks/index.js
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/private-apis.js
/**
* Internal dependencies
*/
const privateApis = {};
lock(privateApis, {
useEntityRecordsWithPermissions: useEntityRecordsWithPermissions
});
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
// The entity selectors/resolvers and actions are shortcuts to their generic equivalents
// (getEntityRecord, getEntityRecords, updateEntityRecord, updateEntityRecords)
// Instead of getEntityRecord, the consumer could use more user-friendly named selector: getPostType, getTaxonomy...
// The "kind" and the "name" of the entity are combined to generate these shortcuts.
const build_module_entitiesConfig = [...rootEntitiesConfig, ...additionalEntityConfigLoaders.filter(config => !!config.name)];
const entitySelectors = build_module_entitiesConfig.reduce((result, entity) => {
const {
kind,
name,
plural
} = entity;
result[getMethodName(kind, name)] = (state, key, query) => getEntityRecord(state, kind, name, key, query);
if (plural) {
result[getMethodName(kind, plural, 'get')] = (state, query) => getEntityRecords(state, kind, name, query);
}
return result;
}, {});
const entityResolvers = build_module_entitiesConfig.reduce((result, entity) => {
const {
kind,
name,
plural
} = entity;
result[getMethodName(kind, name)] = (key, query) => resolvers_getEntityRecord(kind, name, key, query);
if (plural) {
const pluralMethodName = getMethodName(kind, plural, 'get');
result[pluralMethodName] = (...args) => resolvers_getEntityRecords(kind, name, ...args);
result[pluralMethodName].shouldInvalidate = action => resolvers_getEntityRecords.shouldInvalidate(action, kind, name);
}
return result;
}, {});
const entityActions = build_module_entitiesConfig.reduce((result, entity) => {
const {
kind,
name
} = entity;
result[getMethodName(kind, name, 'save')] = (record, options) => saveEntityRecord(kind, name, record, options);
result[getMethodName(kind, name, 'delete')] = (key, query, options) => deleteEntityRecord(kind, name, key, query, options);
return result;
}, {});
const storeConfig = () => ({
reducer: build_module_reducer,
actions: {
...build_module_actions_namespaceObject,
...entityActions,
...createLocksActions()
},
selectors: {
...build_module_selectors_namespaceObject,
...entitySelectors
},
resolvers: {
...resolvers_namespaceObject,
...entityResolvers
}
});
/**
* Store definition for the code data namespace.
*
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore
*/
const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, storeConfig());
unlock(store).registerPrivateSelectors(private_selectors_namespaceObject);
unlock(store).registerPrivateActions(private_actions_namespaceObject);
(0,external_wp_data_namespaceObject.register)(store); // Register store after unlocking private selectors to allow resolvers to use them.
})();
(window.wp = window.wp || {}).coreData = __webpack_exports__;
/******/ })()
;