@lyra/form-builder
Version:
Lyra form builder
304 lines (272 loc) • 11.9 kB
JavaScript
;
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;
}