function spyOnChanges()

in src/legacy/createUndo.ts [36:135]


function spyOnChanges(event: any) {
    let undoStep: UndoStep;
    let modifiedObject = event.object;

    switch (event.type) {
        case 'update':
            if (event.index !== undefined) {
                // update (array)
                undoStep = {
                    verify: () => modifiedObject[event.index] === event.newValue,
                    objectName: event.name,
                    propertyName: event.index,
                    undo: () => {
                        modifiedObject[event.index] = event.oldValue;
                    },
                };
            } else if (typeof modifiedObject.get !== 'undefined') {
                // update (map)
                undoStep = {
                    verify: () => modifiedObject.get(event.key) === event.newValue,
                    objectName: event.name,
                    propertyName: event.key,
                    undo: () => {
                        modifiedObject.set(event.key, event.oldValue);
                    },
                };
            } else {
                // update (object)
                undoStep = {
                    verify: () => modifiedObject[event.key] === event.newValue,
                    objectName: event.name,
                    propertyName: event.key,
                    undo: () => {
                        modifiedObject[event.key] = event.oldValue;
                    },
                };
            }
            break;
        case 'splice':
            undoStep = {
                verify: () => {
                    for (let i = 0; i < event.addedCount; i++) {
                        if (modifiedObject[event.index + i] !== event.added[i]) {
                            return false;
                        }
                    }
                    return true;
                },
                objectName: event.name,
                propertyName: event.index,
                undo: () => {
                    // First, remove the added items.
                    // Then, add items back one at a time, because passing an array in to 'splice' will insert the array as a single item
                    modifiedObject.splice(event.index, event.addedCount);
                    for (let i = 0; i < event.removedCount; i++) {
                        modifiedObject.splice(event.index + i, 0, event.removed[i]);
                    }
                },
            };
            break;
        case 'add':
            if (typeof modifiedObject.get !== 'undefined') {
                // add (map)
                undoStep = {
                    verify: () => modifiedObject.get(event.key) === event.newValue,
                    objectName: event.name,
                    propertyName: event.key,
                    undo: () => {
                        modifiedObject.delete(event.key);
                    },
                };
            } else {
                // add (object)
                undoStep = {
                    verify: () => modifiedObject[event.key] === event.newValue,
                    objectName: event.name,
                    propertyName: event.key,
                    undo: () => {
                        delete modifiedObject[event.key];
                    },
                };
            }
            break;
        case 'delete':
            undoStep = {
                verify: () => !modifiedObject.has(event.key),
                objectName: event.name,
                propertyName: event.key,
                undo: () => {
                    modifiedObject.set(event.key, event.oldValue);
                },
            };
            break;
        default:
            // Nothing worth tracking
            return;
    }

    undoWindows.forEach(undoWindow => undoWindow.steps.push(undoStep));
}