diff --git a/src/components/block/index.ts b/src/components/block/index.ts index f4cb5a4f..f99c06a8 100644 --- a/src/components/block/index.ts +++ b/src/components/block/index.ts @@ -202,25 +202,52 @@ export default class Block extends EventsDispatcher { /** * Is fired when DOM mutation has been happened + * + * mutationsOrInputEvent — actual changes + * - MutationRecord[] - any DOM change + * - InputEvent — 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