UNPKG

@lyra/form-builder

Version:
241 lines (215 loc) 8.24 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); 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 = patchesToChange; var _blockTools = require('@lyra/block-tools'); var _slate = require('slate'); var _simplePatch = require('../../../simplePatch'); var _findInlineByAnnotationKey = require('./findInlineByAnnotationKey'); var _findInlineByAnnotationKey2 = _interopRequireDefault(_findInlineByAnnotationKey); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /*:: import type {Type, Block} from '../typeDefs'*/ // const VALUE_TO_JSON_OPTS = { // preserveData: true, // preserveKeys: true, // preserveSelection: false, // preserveHistory: false // } /*:: type Path = string | {_key: string}*/ /*:: type Patch = { type: string, path: Path[] }*/ function findLastKey(path /*: Path[]*/) { let key = null; path.forEach(part => { if (part._key) { key = part._key; } }); return key; } function setPatch(patch /*: Patch*/, change /*: () => void*/, type /*: Type*/) { if (Array.isArray(patch.value)) { if (patch.path.length === 0) { return replaceValue(patch.value, change, type); } throw new Error(`Invalid patch, looks like it should be an insert: ${JSON.stringify(patch)}`); } const editorBlock = (0, _blockTools.blocksToEditorValue)([patch.value], type).document.nodes[0]; const key = findLastKey(patch.path); return change.replaceNodeByKey(key, editorBlock); } function setIfMissingPatch(patch /*: Patch*/, change /*: () => void*/, type /*: Type*/) { if (patch.path.length === 0) { return replaceValue(patch.value, change, type); } const doc = change.value.document; const blockKey = patch.path[0]._key; const block = doc.nodes.find(node => node.key === blockKey); if (block.isVoid) { const data = block.data.toObject(); if (!data.value) { const newData = _extends({}, data, { value: patch.value }); change.setNodeByKey(blockKey, { data: newData }); } } else { throw new Error(`Invalid patch, looks like it should be an insert: ${JSON.stringify(patch)}`); } return change; } function insertPatch(patch /*: Patch*/, change /*: () => void*/, type /*: Type*/) { const items = patch.items, position = patch.position; const fragment = (0, _blockTools.blocksToEditorValue)(items, type); const posKey = findLastKey(patch.path); let path = change.value.document.nodes.findIndex(node => { return node.key === posKey; }); if (position === 'before') { path = path > 0 ? path-- : path; } if (position === 'after') { path++; } const operations = fragment.document.nodes.map(block => { return _slate.Operation.create({ type: 'insert_node', path: [path], node: block }); }); change.applyOperations(operations); return change; } function unsetPatch(patch /*: Patch*/, change /*: () => void*/) { const lastKey = findLastKey(patch.path); change.removeNodeByKey(lastKey); return change; } function replaceValue(snapshot /*: ?(Blocks[])*/, change /*: () => void*/, type /*: Type*/) { if (snapshot) { const fragment = (0, _blockTools.blocksToEditorValue)(snapshot, type); if (change.value.document.nodes.size) { change.selectAll().delete(); } change.applyOperations(fragment.document.nodes.reverse().map(node => { return { type: 'insert_node', path: [0], node: node }; })); return change; } throw new Error('No snapshot given!'); } function patchAnnotationData(patch /*: Patch*/, change /*: () => void*/, type /*: Type*/, snapshot /*: Block[]*/) { const doc = change.value.document; const blockKey = patch.path[0]._key; const markDefKey = patch.path[2]._key; const node = (0, _findInlineByAnnotationKey2.default)(markDefKey, doc); const data = node.data.toObject(); data.annotations = data.annotations || {}; const annotationKey = Object.keys(data.annotations).find(key => data.annotations[key]._key === markDefKey); if (!annotationKey) { throw new Error('Annotation not found in data'); } // If this is a unset patch, remove the annotation if (patch.type === 'unset' && patch.path.length === 3) { delete data.annotations[annotationKey]; // If no more annotations, unwrap the inline if (Object.keys(data.annotations).length === 0) { return change.unwrapInlineByKey(node.key); } return change.setNodeByKey(node.key, { data }); } // Annotation is changed, update it's data if (snapshot) { data.annotations[annotationKey] = snapshot.find(blk => blk._key === blockKey).markDefs.find(def => def._key === markDefKey); } else { const _patch = _extends({}, patch); _patch.path = patch.path.slice(2); const annotation = data.annotations[annotationKey]; data.annotations[annotationKey] = (0, _simplePatch.applyAll)([annotation], [_patch])[0]; } return change.setNodeByKey(node.key, { data }); } function patchBlockData(patch /*: Patch*/, change /*: () => void*/, type /*: Type*/, snapshot /*: Block[]*/) { const doc = change.value.document; const blockKey = patch.path[0]._key; const block = doc.nodes.find(node => node.key === blockKey); // Only act on formbuilder blocks if (block.isVoid) { const data = block.data.toObject(); // A Saga patch because snapshot, set value from there if (snapshot) { data.value = snapshot.find(blk => blk._key === blockKey); } else { // Do a simple formbuilderPatch const _patch = _extends({}, patch); _patch.path = _patch.path.slice(1); const newValue = (0, _simplePatch.applyAll)(data.value, [_patch]); data.value = newValue; } change.setNodeByKey(block.key, { data }); } return change; } function patchInlineData(patch /*: Patch*/, change /*: () => void*/, type /*: Type*/, snapshot /*: Block[]*/) { const doc = change.value.document; const blockKey = patch.path[0]._key; const inlineKey = patch.path[2]._key; const block = doc.nodes.find(node => node.key === blockKey); const inline = block.nodes.find(node => node.data && node.data.get('value') && node.data.get('value')._key === inlineKey); const data = inline.data.toObject(); // A Saga patch because snapshot, set value from there if (snapshot) { data.value = snapshot.find(blk => blk._key === blockKey).children.find(child => child._key === inlineKey); } else { // Do a simple formbuilderPatch const _patch = _extends({}, patch); _patch.path = _patch.path.slice(3); const newValue = (0, _simplePatch.applyAll)(data.value, [_patch]); data.value = newValue; } change.setNodeByKey(inline.key, { data }); return change; } function patchesToChange(patches /*: Patch[]*/, editorValue /*: Value*/, snapshot /*: ?(Block[])*/, type /*: Type*/) { const change = editorValue.change({ normalize: false }); // console.log('EDITORVALUE', JSON.stringify(editorValue.document.toJSON(VALUE_TO_JSON_OPTS), null, 2)) // console.log('BLOCKS', JSON.stringify(blocks, null, 2)) patches.forEach((patch /*: Patch*/) => { // console.log('INCOMING PATCH', JSON.stringify(patch, null, 2)) if (patch.path.length > 1) { if (patch.path[1] === 'markDefs') { patchAnnotationData(patch, change, type, snapshot); } else if (patch.path[1] === 'children' && patch.path.length > 3) { patchInlineData(patch, change, type, snapshot); } else { patchBlockData(patch, change, type, snapshot); } } else { switch (patch.type) { case 'set': setPatch(patch, change, type); break; case 'setIfMissing': setIfMissingPatch(patch, change, type); break; case 'insert': insertPatch(patch, change, type); break; case 'unset': unsetPatch(patch, change); break; default: replaceValue(snapshot, change, type); } } }); return change; }