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:
@@ -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)
|
||||
|
Reference in New Issue
Block a user