1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-17 12:41:44 +02:00

fix internal copies that start with a void node

This commit is contained in:
Ian Storm Taylor
2018-04-27 15:28:02 -07:00
parent da89f58c4c
commit f19cde92c7

View File

@@ -16,13 +16,12 @@ import { ZERO_WIDTH_SELECTOR, ZERO_WIDTH_ATTRIBUTE } from './find-point'
function cloneFragment(event, value, fragment = value.fragment) {
const window = getWindow(event.target)
const native = window.getSelection()
const { startKey, endKey, startText, endBlock, endInline } = value
const isVoidBlock = endBlock && endBlock.isVoid
const isVoidInline = endInline && endInline.isVoid
const isVoid = isVoidBlock || isVoidInline
const { startKey, endKey, startText } = value
const startVoid = value.document.getClosestVoid(startKey)
const endVoid = value.document.getClosestVoid(endKey)
// If the selection is collapsed, and it isn't inside a void node, abort.
if (native.isCollapsed && !isVoid) return
if (native.isCollapsed && !startVoid) return
// Create a fake selection so that we can add a Base64-encoded copy of the
// fragment to the HTML, to decode on future pastes.
@@ -31,23 +30,29 @@ function cloneFragment(event, value, fragment = value.fragment) {
let contents = range.cloneContents()
let attach = contents.childNodes[0]
// If the end node is a void node, we need to move the end of the range from
// the void node's spacer span, to the end of the void node's content.
if (isVoid) {
// COMPAT: If the end node is a void node, we need to move the end of the
// range from the void node's spacer span, to the end of the void node's
// content, since the spacer is before void's content in the DOM.
if (endVoid) {
const r = range.cloneRange()
const n = isVoidBlock ? endBlock : endInline
const node = findDOMNode(n, window)
const node = findDOMNode(endVoid, window)
r.setEndAfter(node)
contents = r.cloneContents()
attach = contents.childNodes[contents.childNodes.length - 1].firstChild
}
// COMPAT: in Safari and Chrome when selecting a single marked word,
// marks are not preserved when copying.
// If the attatched is not void, and the startKey and endKey is the same,
// check if there is marks involved. If so, set the range start just before the
// startText node
if ((IS_CHROME || IS_SAFARI) && !isVoid && startKey === endKey) {
// COMPAT: If the start node is a void node, we need to attach the encoded
// fragment to the void node's content node instead of the spacer, because
// attaching it to empty `<div>/<span>` nodes will end up having it erased by
// most browsers. (2018/04/27)
if (startVoid) {
attach = contents.childNodes[0].childNodes[1].firstChild
}
// COMPAT: in Safari and Chrome when selecting a single marked word, marks are
// not preserved when copying. If the attatched is not void, and the start key
// and endKey is the same, check if there is marks involved. If so, set the
// range start just before the start text node.
if ((IS_CHROME || IS_SAFARI) && !endVoid && startKey === endKey) {
const hasMarks =
startText.characters
.slice(value.selection.anchorOffset, value.selection.focusOffset)