fix onChange firing by manual dispatchChange() call

This commit is contained in:
Peter Savchenko 2023-02-17 22:04:46 +02:00
commit a039a63a1a
No known key found for this signature in database
GPG key ID: E68306B1AB0F727C

View file

@ -202,25 +202,52 @@ export default class Block extends EventsDispatcher<BlockEvents> {
/**
* Is fired when DOM mutation has been happened
*
* mutationsOrInputEvent actual changes
* - MutationRecord[] - any DOM change
* - InputEvent <input> change
* - undefined manual triggering of block.dispatchChange()
*/
private didMutated = _.debounce((mutationsOrInputEvent: MutationRecord[] | InputEvent = []): void => {
private didMutated = _.debounce((mutationsOrInputEvent: MutationRecord[] | InputEvent = undefined): void => {
/**
* We won't fire a Block mutation event for nodes that contain 'data-mutation-free' attributes
*
* Update from 2023, Feb 17:
* Changed mutationsOrInputEvent.some() to mutationsOrInputEvent.every()
* since there could be a real mutations same-time with mutation-free changes,
* for example when Block Tune change: block is changing along with FakeCursor (mutation-free) removing
* we should fire 'didMutated' event in that case
*/
const shouldFireUpdate = mutationsOrInputEvent instanceof InputEvent ||
!mutationsOrInputEvent.every(({
addedNodes = [],
removedNodes,
}) => {
return [...Array.from(addedNodes), ...Array.from(removedNodes)]
.some(node => $.isElement(node) && (node as HTMLElement).dataset.mutationFree === 'true');
});
let shouldFireUpdate;
if (mutationsOrInputEvent === undefined) {
shouldFireUpdate = true;
} else if (mutationsOrInputEvent instanceof InputEvent) {
shouldFireUpdate = true;
} else {
/**
* Update from 2023, Feb 17:
* Changed mutationsOrInputEvent.some() to mutationsOrInputEvent.every()
* since there could be a real mutations same-time with mutation-free changes,
* for example when Block Tune change: block is changing along with FakeCursor (mutation-free) removing
* we should fire 'didMutated' event in that case
*/
const everyRecordIsMutationFree = mutationsOrInputEvent.length > 0 && mutationsOrInputEvent.every((record) => {
const { addedNodes, removedNodes } = record;
const changedNodes = [
...Array.from(addedNodes),
...Array.from(removedNodes)
];
return changedNodes.some((node) => {
if ($.isElement(node) === false) {
return false;
}
return (node as HTMLElement).dataset.mutationFree === 'true';
})
})
if (everyRecordIsMutationFree) {
shouldFireUpdate = false;
} else {
shouldFireUpdate = true;
}
}
/**
* In case some mutation free elements are added or removed, do not trigger didMutated event