From 3f2e924f6916e0fc3f9d7b8045646d2f4ba08b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20van=20der=20Sande?= Date: Wed, 2 May 2018 02:44:49 +0200 Subject: [PATCH] [Fix] Copy with empty Block as first-child (#1748) * [Fix] Copy with empty Block as first-child + Added Opera support for only-Mark copy * [Fix] Fixed one missing remove from merge --- packages/slate-dev-environment/src/index.js | 1 + packages/slate-react/src/utils/clone-fragment.js | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/slate-dev-environment/src/index.js b/packages/slate-dev-environment/src/index.js index 27589676a..14eb69f74 100644 --- a/packages/slate-dev-environment/src/index.js +++ b/packages/slate-dev-environment/src/index.js @@ -85,6 +85,7 @@ if (browser) { */ export const IS_CHROME = BROWSER === 'chrome' +export const IS_OPERA = BROWSER === 'opera' export const IS_FIREFOX = BROWSER === 'firefox' export const IS_SAFARI = BROWSER === 'safari' export const IS_IE = BROWSER === 'ie' diff --git a/packages/slate-react/src/utils/clone-fragment.js b/packages/slate-react/src/utils/clone-fragment.js index b37c0b77f..9c8bbaec0 100644 --- a/packages/slate-react/src/utils/clone-fragment.js +++ b/packages/slate-react/src/utils/clone-fragment.js @@ -1,5 +1,5 @@ import Base64 from 'slate-base64-serializer' -import { IS_CHROME, IS_SAFARI } from 'slate-dev-environment' +import { IS_CHROME, IS_SAFARI, IS_OPERA } from 'slate-dev-environment' import getWindow from 'get-window' import findDOMNode from './find-dom-node' @@ -30,6 +30,13 @@ function cloneFragment(event, value, fragment = value.fragment) { let contents = range.cloneContents() let attach = contents.childNodes[0] + // Make sure attach is a non-empty node, since empty nodes will not get copied + contents.childNodes.forEach(node => { + if (node.innerText.trim() !== '') { + attach = node + } + }) + // 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. @@ -52,7 +59,7 @@ function cloneFragment(event, value, fragment = value.fragment) { // 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) { + if ((IS_CHROME || IS_SAFARI || IS_OPERA) && !endVoid && startKey === endKey) { const hasMarks = startText.characters .slice(value.selection.anchorOffset, value.selection.focusOffset) @@ -76,7 +83,7 @@ function cloneFragment(event, value, fragment = value.fragment) { // COMPAT: In Chrome and Safari, if the last element in the selection to // copy has `contenteditable="false"` the copy will fail, and nothing will // be put in the clipboard. So we remove them all. (2017/05/04) - if (IS_CHROME || IS_SAFARI) { + if (IS_CHROME || IS_SAFARI || IS_OPERA) { const els = [].slice.call( contents.querySelectorAll('[contenteditable="false"]') )