UNPKG

@lyra/form-builder

Version:
304 lines (272 loc) 11.9 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.VALUE_TO_JSON_OPTS = undefined; var _isEqual2 = require('lodash/isEqual'); var _isEqual3 = _interopRequireDefault(_isEqual2); var _flatten2 = require('lodash/flatten'); var _flatten3 = _interopRequireDefault(_flatten2); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; exports.default = changeToPatches; var _slate = require('slate'); var _blockTools = require('@lyra/block-tools'); var _PatchEvent = require('../../../PatchEvent'); var _simplePatch = require('../../../simplePatch'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /*:: import type {Block, Type} from '../typeDefs'*/ const VALUE_TO_JSON_OPTS = exports.VALUE_TO_JSON_OPTS = { preserveData: true, preserveKeys: true, preserveSelection: false, preserveHistory: false }; function setKey(key /*: string*/, block /*: Block*/) { block._key = key; if (block._type === 'block') { block.children.forEach((child, index) => { child._key = `${block._key}${index}`; }); } return block; } function setNodePatchSimple(change /*: Change*/, operation /*: Operation*/, blocks /*: Block[]*/, blockContentType) { const appliedBlocks = (0, _blockTools.editorValueToBlocks)({ document: { nodes: [change.applyOperations([operation]).value.document.nodes.get(operation.path[0]).toJSON(VALUE_TO_JSON_OPTS)] } }, blockContentType); // Value is undefined if (!blocks && appliedBlocks) { return (0, _PatchEvent.setIfMissing)(appliedBlocks); } // Value is empty if (blocks && blocks.length === 0) { return (0, _PatchEvent.set)(appliedBlocks, []); } const changedBlock = appliedBlocks[0]; setKey(changedBlock._key, (0, _blockTools.normalizeBlock)(changedBlock)); return (0, _PatchEvent.set)(changedBlock, [{ _key: changedBlock._key }]); } function setNodePatch(change /*: Change*/, operation /*: Operation*/, blocks /*: Block[]*/, blockContentType) { const appliedBlocks = (0, _blockTools.editorValueToBlocks)(change.applyOperations([operation]).value.toJSON(VALUE_TO_JSON_OPTS), blockContentType); // Value is undefined if (!blocks && appliedBlocks) { return (0, _PatchEvent.setIfMissing)(appliedBlocks); } // Value is empty if (blocks && blocks.length === 0) { return (0, _PatchEvent.set)(appliedBlocks, []); } const changedBlock = appliedBlocks[operation.path[0]]; // Don't do anything if nothing is changed if ((0, _isEqual3.default)(changedBlock, blocks[operation.path[0]])) { return []; } setKey(changedBlock._key, changedBlock); return (0, _PatchEvent.set)((0, _blockTools.normalizeBlock)(changedBlock), [{ _key: blocks[operation.path[0]]._key }]); } function insertNodePatch(change /*: Change*/, operation /*: Operation*/, blocks /*: Block[]*/, blockContentType) { const patches = []; const appliedBlocks = (0, _blockTools.editorValueToBlocks)(change.applyOperations([operation]).value.toJSON(VALUE_TO_JSON_OPTS), blockContentType); if (operation.path.length === 1) { if (!blocks.length) { return (0, _PatchEvent.set)(appliedBlocks.map((block, index) => { return setKey(change.value.document.nodes.get(index).key, block); })); } let position = 'after'; let afterKey; if (operation.path[0] === 0) { afterKey = blocks[0]._key; position = 'before'; } else { afterKey = blocks[operation.path[0] - 1]._key; } const newBlock = appliedBlocks[operation.path[0]]; const newKey = change.value.document.nodes.get(operation.path[0]).key; setKey(newKey, newBlock); const oldData = change.value.document.nodes.get(operation.path[0]).data.toObject(); if (oldData.value && oldData.value._key) { oldData.value._key = newKey; } change.setNodeByKey(newKey, { data: _extends({}, oldData, { _key: newKey }) }, { normalize: false }); patches.push((0, _PatchEvent.insert)([newBlock], position, [{ _key: afterKey }])); } if (operation.path.length > 1) { const block = appliedBlocks[operation.path[0]]; setKey(block._key, block); if (block._type === 'block') { patches.push((0, _PatchEvent.set)((0, _blockTools.normalizeBlock)(block), [{ _key: block._key }])); } } return patches; } function splitNodePatch(change /*: Change*/, operation /*: Operation*/, blocks /*: Block[]*/, blockContentType) { const patches = []; const appliedBlocks = (0, _blockTools.editorValueToBlocks)(change.applyOperations([operation]).value.toJSON(VALUE_TO_JSON_OPTS), blockContentType); const splitBlock = appliedBlocks[operation.path[0]]; setKey(splitBlock._key, splitBlock); if (operation.path.length === 1) { patches.push((0, _PatchEvent.set)(splitBlock, [{ _key: splitBlock._key }])); const newBlock = appliedBlocks[operation.path[0] + 1]; const newKey = change.value.document.nodes.get(operation.path[0] + 1).key; setKey(newKey, newBlock); // Update the change value data with new key const oldData = change.value.document.nodes.get(operation.path[0] + 1).data.toObject(); if (oldData.value && oldData.value._key) { oldData.value._key = newKey; } change.setNodeByKey(newKey, { data: _extends({}, oldData, { _key: newKey }) }, { normalize: false }); patches.push((0, _PatchEvent.insert)([newBlock], 'after', [{ _key: splitBlock._key }])); } if (operation.path.length > 1) { patches.push((0, _PatchEvent.set)(splitBlock, [{ _key: splitBlock._key }])); } return patches; } function mergeNodePatch(change /*: Change*/, operation /*: Operation*/, blocks /*: Block[]*/, blockContentType) { const patches = []; const appliedBlocks = (0, _blockTools.editorValueToBlocks)(change.applyOperations([operation]).value.toJSON(VALUE_TO_JSON_OPTS), blockContentType); if (operation.path.length === 1) { const mergedBlock = blocks[operation.path[0]]; const targetBlock = appliedBlocks[operation.path[0] - 1]; patches.push((0, _PatchEvent.unset)([{ _key: mergedBlock._key }])); patches.push((0, _PatchEvent.set)(targetBlock, [{ _key: blocks[operation.path[0] - 1]._key }])); } if (operation.path.length > 1) { const targetBlock = appliedBlocks[operation.path[0]]; setKey(targetBlock._key, targetBlock); patches.push((0, _PatchEvent.set)(targetBlock, [{ _key: targetBlock._key }])); } return patches; } function moveNodePatch(change /*: Change*/, operation /*: Operation*/, blocks /*: Block[]*/, blockContentType) { change.applyOperations([operation]); const patches = []; if (operation.path.length === 1) { if (operation.path[0] === operation.newPath[0]) { return []; } const block = blocks[operation.path[0]]; patches.push((0, _PatchEvent.unset)([{ _key: block._key }])); let position = 'after'; let posKey; if (operation.newPath[0] === 0) { posKey = blocks[0]._key; position = 'before'; } else { posKey = blocks[operation.newPath[0] - 1]._key; } setKey(block._key, block); patches.push((0, _PatchEvent.insert)([block], position, [{ _key: posKey }])); } else { const appliedBlocks = (0, _blockTools.editorValueToBlocks)(change.value.toJSON(VALUE_TO_JSON_OPTS), blockContentType); const changedBlockFrom = appliedBlocks[operation.path[0]]; const changedBlockTo = appliedBlocks[operation.newPath[0]]; setKey(changedBlockFrom._key, changedBlockFrom); setKey(changedBlockTo._key, changedBlockTo); patches.push((0, _PatchEvent.set)(changedBlockFrom, [{ _key: changedBlockFrom._key }])); patches.push((0, _PatchEvent.set)(changedBlockTo, [{ _key: changedBlockTo._key }])); } return patches; } function removeNodePatch(change /*: SlateChange*/, operation /*: Operation*/, blocks /*: Block[]*/, blockContentType /*: Type*/) { change.applyOperations([operation]); const patches = []; const block = blocks[operation.path[0]]; if (operation.path.length === 1) { // Unset block patches.push((0, _PatchEvent.unset)([{ _key: block._key }])); } if (operation.path.length > 1) { // Only relevant for 'block' type blocks if (block._type !== 'block') { return patches; } const appliedBlocks = (0, _blockTools.editorValueToBlocks)(change.value.toJSON(VALUE_TO_JSON_OPTS), blockContentType); const changedBlock = appliedBlocks[operation.path[0]]; setKey(changedBlock._key, changedBlock); patches.push((0, _PatchEvent.set)(changedBlock, [{ _key: changedBlock._key }])); } if (patches.length === 0) { throw new Error(`Don't know how to unset ${JSON.stringify(operation.toJSON(VALUE_TO_JSON_OPTS))}`); } return patches; } function noOpPatch(change /*: SlateChange*/, operation /*: Operation*/) { change.applyOperations([operation]); return []; } function setValuePatch(change /*: SlateChange*/, operation /*: Operation*/, blocks /*: Block[]*/, blockContentType /*: Type*/) { change.applyOperations([operation]); const appliedBlocks = (0, _blockTools.editorValueToBlocks)(change.value.toJSON(VALUE_TO_JSON_OPTS), blockContentType); console.log('setValuePatch', appliedBlocks); return [(0, _PatchEvent.set)(appliedBlocks, [])]; } function applyPatchesOnValue(patches, value) { let _patches = patches; if (!patches || Array.isArray(patches) && !patches.length) { return value; } if (!Array.isArray(patches)) { _patches = [patches]; } return (0, _simplePatch.applyAll)(value, _patches); } function changeToPatches(unchangedEditorValue /*: Value*/, change /*: Change*/, value /*: Block[]*/, blockContentType /*: Type*/) { const operations = change.operations; let blocks = value ? [...value] : []; const _change = unchangedEditorValue.change(); const patches = (0, _flatten3.default)(operations.map((operation /*: Operation*/, index /*: number*/) => { // console.log('OPERATION:', JSON.stringify(operation, null, 2)) let _patches; switch (operation.type) { case 'insert_text': _patches = setNodePatchSimple(_change, operation, blocks, blockContentType); break; case 'remove_text': _patches = setNodePatchSimple(_change, operation, blocks, blockContentType); break; case 'add_mark': _patches = setNodePatchSimple(_change, operation, blocks, blockContentType); break; case 'remove_mark': _patches = setNodePatchSimple(_change, operation, blocks, blockContentType); break; case 'set_node': _patches = setNodePatch(_change, operation, blocks, blockContentType); break; case 'insert_node': _patches = insertNodePatch(_change, operation, blocks, blockContentType); break; case 'remove_node': _patches = removeNodePatch(_change, operation, blocks, blockContentType); break; case 'split_node': _patches = splitNodePatch(_change, operation, blocks, blockContentType); break; case 'merge_node': _patches = mergeNodePatch(_change, operation, blocks, blockContentType); break; case 'move_node': _patches = moveNodePatch(_change, operation, blocks, blockContentType); break; default: _patches = noOpPatch(_change, operation); } // console.log('BLOCKS BEFORE:', JSON.stringify(blocks, null, 2)) // console.log('PATCHES:', JSON.stringify(_patches, null, 2)) blocks = applyPatchesOnValue(_patches, blocks); // console.log('BLOCKS AFTER:', JSON.stringify(blocks, null, 2)) return _patches; }).toArray()).filter(Boolean); if (change.__isUndoRedo) { patches.push((0, _PatchEvent.set)({}, [{ _key: 'undoRedoVoidPatch' }])); } return patches; }