mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-04-21 22:02:05 +02:00
Merge pull request #443 from tyler-johnson/nested-editable
add support for nested content-editables
This commit is contained in:
commit
6f7bbbfca8
@ -143,6 +143,30 @@ class Content extends React.Component {
|
||||
return point
|
||||
}
|
||||
|
||||
/**
|
||||
* The React ref method to set the root content element locally.
|
||||
*
|
||||
* @param {Element} n
|
||||
*/
|
||||
|
||||
ref = (element) => {
|
||||
this.element = element
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an `event` is being fired from within the contenteditable element.
|
||||
* This will return false for edits happening in non-contenteditable children,
|
||||
* such as void nodes and other nested Slate editors.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
isInContentEditable = (event) => {
|
||||
const { target } = event
|
||||
return target.isContentEditable && target === this.element
|
||||
}
|
||||
|
||||
/**
|
||||
* On before input, bubble up.
|
||||
*
|
||||
@ -151,7 +175,7 @@ class Content extends React.Component {
|
||||
|
||||
onBeforeInput = (e) => {
|
||||
if (this.props.readOnly) return
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
|
||||
const data = {}
|
||||
|
||||
@ -168,7 +192,7 @@ class Content extends React.Component {
|
||||
onBlur = (e) => {
|
||||
if (this.props.readOnly) return
|
||||
if (this.tmp.isCopying) return
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
|
||||
const data = {}
|
||||
|
||||
@ -194,7 +218,7 @@ class Content extends React.Component {
|
||||
*/
|
||||
|
||||
onCompositionStart = (e) => {
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
|
||||
this.tmp.isComposing = true
|
||||
this.tmp.compositions++
|
||||
@ -211,7 +235,7 @@ class Content extends React.Component {
|
||||
*/
|
||||
|
||||
onCompositionEnd = (e) => {
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
|
||||
this.forces++
|
||||
const count = this.tmp.compositions
|
||||
@ -234,7 +258,7 @@ class Content extends React.Component {
|
||||
*/
|
||||
|
||||
onCopy = (e) => {
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
const window = getWindow(e.target)
|
||||
|
||||
this.tmp.isCopying = true
|
||||
@ -259,7 +283,7 @@ class Content extends React.Component {
|
||||
|
||||
onCut = (e) => {
|
||||
if (this.props.readOnly) return
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
const window = getWindow(e.target)
|
||||
|
||||
this.tmp.isCopying = true
|
||||
@ -283,7 +307,7 @@ class Content extends React.Component {
|
||||
*/
|
||||
|
||||
onDragEnd = (e) => {
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
|
||||
this.tmp.isDragging = false
|
||||
this.tmp.isInternalDrag = null
|
||||
@ -298,7 +322,7 @@ class Content extends React.Component {
|
||||
*/
|
||||
|
||||
onDragOver = (e) => {
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
|
||||
const { dataTransfer } = e.nativeEvent
|
||||
const transfer = new Transfer(dataTransfer)
|
||||
@ -322,7 +346,7 @@ class Content extends React.Component {
|
||||
*/
|
||||
|
||||
onDragStart = (e) => {
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
|
||||
this.tmp.isDragging = true
|
||||
this.tmp.isInternalDrag = true
|
||||
@ -348,7 +372,7 @@ class Content extends React.Component {
|
||||
|
||||
onDrop = (e) => {
|
||||
if (this.props.readOnly) return
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
|
||||
e.preventDefault()
|
||||
|
||||
@ -405,7 +429,7 @@ class Content extends React.Component {
|
||||
onInput = (e) => {
|
||||
if (this.tmp.isComposing) return
|
||||
if (this.props.state.isBlurred) return
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
debug('onInput')
|
||||
|
||||
const window = getWindow(e.target)
|
||||
@ -475,7 +499,7 @@ class Content extends React.Component {
|
||||
|
||||
onKeyDown = (e) => {
|
||||
if (this.props.readOnly) return
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
|
||||
const key = keycode(e.which)
|
||||
const data = {}
|
||||
@ -530,7 +554,7 @@ class Content extends React.Component {
|
||||
|
||||
onPaste = (e) => {
|
||||
if (this.props.readOnly) return
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
|
||||
e.preventDefault()
|
||||
const transfer = new Transfer(e.clipboardData)
|
||||
@ -550,7 +574,7 @@ class Content extends React.Component {
|
||||
if (this.props.readOnly) return
|
||||
if (this.tmp.isCopying) return
|
||||
if (this.tmp.isComposing) return
|
||||
if (isNonEditable(e)) return
|
||||
if (!this.isInContentEditable(e)) return
|
||||
|
||||
const window = getWindow(e.target)
|
||||
const { state } = this.props
|
||||
@ -640,6 +664,7 @@ class Content extends React.Component {
|
||||
return (
|
||||
<div
|
||||
key={this.forces}
|
||||
ref={this.ref}
|
||||
contentEditable={!readOnly}
|
||||
suppressContentEditableWarning
|
||||
className={className}
|
||||
@ -690,19 +715,6 @@ class Content extends React.Component {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an `event` is being fired from inside a non-contentediable child
|
||||
* element, in which case we'll want to ignore it.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
function isNonEditable(event) {
|
||||
const { target } = event
|
||||
return !target.isContentEditable
|
||||
}
|
||||
|
||||
/**
|
||||
* Export.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user