mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-18 21:21:21 +02:00
Set clipboard data programmitcally on copy when supported (#1815)
This commit is contained in:
committed by
Ian Storm Taylor
parent
0cfd54fc19
commit
62d87b23c0
@@ -1,10 +1,13 @@
|
|||||||
import Base64 from 'slate-base64-serializer'
|
import Base64 from 'slate-base64-serializer'
|
||||||
import { IS_CHROME, IS_SAFARI, IS_OPERA } from 'slate-dev-environment'
|
import { IS_CHROME, IS_SAFARI, IS_OPERA } from 'slate-dev-environment'
|
||||||
|
|
||||||
|
import TRANSFER_TYPES from '../constants/transfer-types'
|
||||||
import getWindow from 'get-window'
|
import getWindow from 'get-window'
|
||||||
import findDOMNode from './find-dom-node'
|
import findDOMNode from './find-dom-node'
|
||||||
import { ZERO_WIDTH_SELECTOR, ZERO_WIDTH_ATTRIBUTE } from './find-point'
|
|
||||||
import removeAllRanges from './remove-all-ranges'
|
import removeAllRanges from './remove-all-ranges'
|
||||||
|
import { ZERO_WIDTH_SELECTOR, ZERO_WIDTH_ATTRIBUTE } from './find-point'
|
||||||
|
|
||||||
|
const { FRAGMENT, HTML, TEXT } = TRANSFER_TYPES
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares a Slate document fragment to be copied to the clipboard.
|
* Prepares a Slate document fragment to be copied to the clipboard.
|
||||||
@@ -33,7 +36,7 @@ function cloneFragment(event, value, fragment = value.fragment) {
|
|||||||
|
|
||||||
// Make sure attach is a non-empty node, since empty nodes will not get copied
|
// Make sure attach is a non-empty node, since empty nodes will not get copied
|
||||||
contents.childNodes.forEach(node => {
|
contents.childNodes.forEach(node => {
|
||||||
if (node.innerText.trim() !== '') {
|
if (node.innerText && node.innerText.trim() !== '') {
|
||||||
attach = node
|
attach = node
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -108,31 +111,30 @@ function cloneFragment(event, value, fragment = value.fragment) {
|
|||||||
|
|
||||||
attach.setAttribute('data-slate-fragment', encoded)
|
attach.setAttribute('data-slate-fragment', encoded)
|
||||||
|
|
||||||
// Add the phony content to the DOM, and select it, so it will be copied.
|
// Add the phony content to a div element. This is needed to copy the
|
||||||
const editor = event.target.closest('[data-slate-editor]')
|
// contents into the html clipboard register.
|
||||||
const div = window.document.createElement('div')
|
const div = window.document.createElement('div')
|
||||||
|
div.appendChild(contents)
|
||||||
|
|
||||||
|
// For browsers supporting it, we set the clipboard registers manually,
|
||||||
|
// since the result is more predictable.
|
||||||
|
if (event.clipboardData && event.clipboardData.setData) {
|
||||||
|
event.preventDefault()
|
||||||
|
event.clipboardData.setData(TEXT, native.toString())
|
||||||
|
event.clipboardData.setData(FRAGMENT, encoded)
|
||||||
|
event.clipboardData.setData(HTML, div.innerHTML)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// COMPAT: For browser that don't support the Clipboard API's setData method,
|
||||||
|
// we must rely on the browser to natively copy what's selected.
|
||||||
|
// So we add the div (containing our content) to the DOM, and select it.
|
||||||
|
const editor = event.target.closest('[data-slate-editor]')
|
||||||
div.setAttribute('contenteditable', true)
|
div.setAttribute('contenteditable', true)
|
||||||
div.style.position = 'absolute'
|
div.style.position = 'absolute'
|
||||||
div.style.left = '-9999px'
|
div.style.left = '-9999px'
|
||||||
|
|
||||||
// COMPAT: In Firefox, the viewport jumps to find the phony div, so it
|
|
||||||
// should be created at the current scroll offset with `style.top`.
|
|
||||||
// The box model attributes which can interact with 'top' are also reset.
|
|
||||||
div.style.border = '0px'
|
|
||||||
div.style.padding = '0px'
|
|
||||||
div.style.margin = '0px'
|
|
||||||
div.style.top = `${window.pageYOffset ||
|
|
||||||
window.document.documentElement.scrollTop}px`
|
|
||||||
|
|
||||||
div.appendChild(contents)
|
|
||||||
editor.appendChild(div)
|
editor.appendChild(div)
|
||||||
|
native.selectAllChildren(div)
|
||||||
// COMPAT: In Firefox, trying to use the terser `native.selectAllChildren`
|
|
||||||
// throws an error, so we use the older `range` equivalent. (2016/06/21)
|
|
||||||
const r = window.document.createRange()
|
|
||||||
r.selectNodeContents(div)
|
|
||||||
removeAllRanges(native)
|
|
||||||
native.addRange(r)
|
|
||||||
|
|
||||||
// Revert to the previous selection right after copying.
|
// Revert to the previous selection right after copying.
|
||||||
window.requestAnimationFrame(() => {
|
window.requestAnimationFrame(() => {
|
||||||
|
Reference in New Issue
Block a user