Last active
February 13, 2019 13:44
-
-
Save bebbi/9ba49f2eff018508e57119c3b9c6e582 to your computer and use it in GitHub Desktop.
slatejs fragment manipulation for custom onPaste behaviour
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Block, Document } from 'slate' | |
import { getEventTransfer } from 'slate-react' | |
import isContainerNode from '../utils/node/isContainerNode' | |
/* | |
* What generalizes about this example is that thanks to slatejs #2589 paste | |
* behaviour is controlled by the fragment's trunk. | |
*/ | |
const deepestSingleContainer = doc => { | |
// result holds the found container. | |
let result = null | |
// candidate iterates through fragment. | |
let candidate = doc | |
while ( | |
candidate.nodes.size === 1 && | |
candidate.nodes.first().object === 'block' | |
) { | |
candidate = candidate.nodes.first() | |
if (isContainerNode(candidate)) { | |
result = candidate | |
} | |
} | |
return result | |
} | |
/* | |
* Additional benefit, apply custom operations on the pasted fragment such as | |
* removing id. | |
* TODO: Simplify? New controller just for this? | |
*/ | |
const removeUuids = node => { | |
if (node.object === 'document') { | |
return Document.create(node.nodes.map(removeUuids)) | |
} | |
if (node.object !== 'block') { | |
return node | |
} | |
return Block.fromJSON({ | |
...node.toJSON(), | |
nodes: node.nodes.map(removeUuids), | |
data: isContainerNode(node) ? node.data.remove('id') : node.data | |
}) | |
} | |
/* | |
* Shorten (or prolong) the fragment's trunk to get a different paste depth. | |
*/ | |
const truncateFragment = fragment => { | |
const startBlock = deepestSingleContainer(fragment) | |
return startBlock ? Document.create([startBlock]) : fragment | |
} | |
const onFragment = (event, editor, next) => { | |
const transfer = getEventTransfer(event) | |
const { type, fragment } = transfer | |
if (type !== 'fragment') { | |
return next() | |
} | |
const newFragment = removeUuids(truncateFragment(fragment)) | |
editor.insertFragment(newFragment) | |
} | |
export default options => ({ | |
onPaste: onFragment | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment