@wordpress/block-editor
Version:
179 lines (177 loc) • 6.42 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// packages/block-editor/src/components/provider/use-block-sync.js
var use_block_sync_exports = {};
__export(use_block_sync_exports, {
default: () => useBlockSync
});
module.exports = __toCommonJS(use_block_sync_exports);
var import_element = require("@wordpress/element");
var import_data = require("@wordpress/data");
var import_blocks = require("@wordpress/blocks");
var import_store = require("../../store");
var noop = () => {
};
function useBlockSync({
clientId = null,
value: controlledBlocks,
selection: controlledSelection,
onChange = noop,
onInput = noop
}) {
const registry = (0, import_data.useRegistry)();
const {
resetBlocks,
resetSelection,
replaceInnerBlocks,
setHasControlledInnerBlocks,
__unstableMarkNextChangeAsNotPersistent
} = registry.dispatch(import_store.store);
const { getBlockName, getBlocks, getSelectionStart, getSelectionEnd } = registry.select(import_store.store);
const isControlled = (0, import_data.useSelect)(
(select) => {
return !clientId || select(import_store.store).areInnerBlocksControlled(clientId);
},
[clientId]
);
const pendingChangesRef = (0, import_element.useRef)({ incoming: null, outgoing: [] });
const subscribedRef = (0, import_element.useRef)(false);
const setControlledBlocks = () => {
if (!controlledBlocks) {
return;
}
__unstableMarkNextChangeAsNotPersistent();
if (clientId) {
registry.batch(() => {
setHasControlledInnerBlocks(clientId, true);
const storeBlocks = controlledBlocks.map(
(block) => (0, import_blocks.cloneBlock)(block)
);
if (subscribedRef.current) {
pendingChangesRef.current.incoming = storeBlocks;
}
__unstableMarkNextChangeAsNotPersistent();
replaceInnerBlocks(clientId, storeBlocks);
});
} else {
if (subscribedRef.current) {
pendingChangesRef.current.incoming = controlledBlocks;
}
resetBlocks(controlledBlocks);
}
};
const unsetControlledBlocks = () => {
__unstableMarkNextChangeAsNotPersistent();
if (clientId) {
setHasControlledInnerBlocks(clientId, false);
__unstableMarkNextChangeAsNotPersistent();
replaceInnerBlocks(clientId, []);
} else {
resetBlocks([]);
}
};
const onInputRef = (0, import_element.useRef)(onInput);
const onChangeRef = (0, import_element.useRef)(onChange);
(0, import_element.useEffect)(() => {
onInputRef.current = onInput;
onChangeRef.current = onChange;
}, [onInput, onChange]);
(0, import_element.useEffect)(() => {
if (pendingChangesRef.current.outgoing.includes(controlledBlocks)) {
if (pendingChangesRef.current.outgoing[pendingChangesRef.current.outgoing.length - 1] === controlledBlocks) {
pendingChangesRef.current.outgoing = [];
}
} else if (getBlocks(clientId) !== controlledBlocks) {
pendingChangesRef.current.outgoing = [];
setControlledBlocks();
if (controlledSelection) {
resetSelection(
controlledSelection.selectionStart,
controlledSelection.selectionEnd,
controlledSelection.initialPosition
);
}
}
}, [controlledBlocks, clientId]);
const isMountedRef = (0, import_element.useRef)(false);
(0, import_element.useEffect)(() => {
if (!isMountedRef.current) {
isMountedRef.current = true;
return;
}
if (!isControlled) {
pendingChangesRef.current.outgoing = [];
setControlledBlocks();
}
}, [isControlled]);
(0, import_element.useEffect)(() => {
const {
getSelectedBlocksInitialCaretPosition,
isLastBlockChangePersistent,
__unstableIsLastBlockChangeIgnored,
areInnerBlocksControlled
} = registry.select(import_store.store);
let blocks = getBlocks(clientId);
let isPersistent = isLastBlockChangePersistent();
let previousAreBlocksDifferent = false;
subscribedRef.current = true;
const unsubscribe = registry.subscribe(() => {
if (clientId !== null && getBlockName(clientId) === null) {
return;
}
const isStillControlled = !clientId || areInnerBlocksControlled(clientId);
if (!isStillControlled) {
return;
}
const newIsPersistent = isLastBlockChangePersistent();
const newBlocks = getBlocks(clientId);
const areBlocksDifferent = newBlocks !== blocks;
blocks = newBlocks;
if (areBlocksDifferent && (pendingChangesRef.current.incoming || __unstableIsLastBlockChangeIgnored())) {
pendingChangesRef.current.incoming = null;
isPersistent = newIsPersistent;
return;
}
const didPersistenceChange = previousAreBlocksDifferent && !areBlocksDifferent && newIsPersistent && !isPersistent;
if (areBlocksDifferent || didPersistenceChange) {
isPersistent = newIsPersistent;
pendingChangesRef.current.outgoing.push(blocks);
const updateParent = isPersistent ? onChangeRef.current : onInputRef.current;
updateParent(blocks, {
selection: {
selectionStart: getSelectionStart(),
selectionEnd: getSelectionEnd(),
initialPosition: getSelectedBlocksInitialCaretPosition()
}
});
}
previousAreBlocksDifferent = areBlocksDifferent;
}, import_store.store);
return () => {
subscribedRef.current = false;
unsubscribe();
};
}, [registry, clientId]);
(0, import_element.useEffect)(() => {
return () => {
unsetControlledBlocks();
};
}, []);
}
//# sourceMappingURL=use-block-sync.js.map