mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-21 06:31:28 +02:00
fix void leaf selection handling
This commit is contained in:
@@ -17,7 +17,9 @@ Transform methods can either operate on the [`Document`](./document.md), the [`S
|
|||||||
- [`deleteBackward`](#deletebackward)
|
- [`deleteBackward`](#deletebackward)
|
||||||
- [`deleteForward`](#deleteforward)
|
- [`deleteForward`](#deleteforward)
|
||||||
- [`delete`](#delete)
|
- [`delete`](#delete)
|
||||||
|
- [`insertBlock`](#insertblock)
|
||||||
- [`insertFragment`](#insertfragment)
|
- [`insertFragment`](#insertfragment)
|
||||||
|
- [`insertInline`](#insertinline)
|
||||||
- [`insertText`](#inserttext)
|
- [`insertText`](#inserttext)
|
||||||
- [`addMark`](#addmark)
|
- [`addMark`](#addmark)
|
||||||
- [`setBlock`](#setblock)
|
- [`setBlock`](#setblock)
|
||||||
@@ -50,7 +52,9 @@ Transform methods can either operate on the [`Document`](./document.md), the [`S
|
|||||||
- [`deleteAtRange`](#deleteatrange)
|
- [`deleteAtRange`](#deleteatrange)
|
||||||
- [`deleteBackwardAtRange`](#deletebackwardatrange)
|
- [`deleteBackwardAtRange`](#deletebackwardatrange)
|
||||||
- [`deleteForwardAtRange`](#deleteforwardatrange)
|
- [`deleteForwardAtRange`](#deleteforwardatrange)
|
||||||
|
- [`insertBlockAtRange`](#insertblockatrange)
|
||||||
- [`insertFragmentAtRange`](#insertfragmentatrange)
|
- [`insertFragmentAtRange`](#insertfragmentatrange)
|
||||||
|
- [`insertInlineAtRange`](#insertinlineatrange)
|
||||||
- [`insertTextAtRange`](#inserttextatrange)
|
- [`insertTextAtRange`](#inserttextatrange)
|
||||||
- [`addMarkAtRange`](#addmarkatrange)
|
- [`addMarkAtRange`](#addmarkatrange)
|
||||||
- [`setBlockAtRange`](#setblockatrange)
|
- [`setBlockAtRange`](#setblockatrange)
|
||||||
|
@@ -202,41 +202,9 @@ class Images extends React.Component {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
insertImage = (state, src) => {
|
insertImage = (state, src) => {
|
||||||
if (state.isExpanded) {
|
return state
|
||||||
state = state
|
|
||||||
.transform()
|
.transform()
|
||||||
.delete()
|
.insertBlock({
|
||||||
.apply()
|
|
||||||
}
|
|
||||||
|
|
||||||
const { anchorBlock, selection } = state
|
|
||||||
let transform = state.transform()
|
|
||||||
|
|
||||||
if (anchorBlock.type == 'image') {
|
|
||||||
transform = transform.splitBlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (anchorBlock.text != '') {
|
|
||||||
if (selection.isAtEndOf(anchorBlock)) {
|
|
||||||
transform = transform.splitBlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (selection.isAtStartOf(anchorBlock)) {
|
|
||||||
transform = transform
|
|
||||||
.splitBlock()
|
|
||||||
.collapseToStartOfPreviousBlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
transform = transform
|
|
||||||
.splitBlock()
|
|
||||||
.splitBlock()
|
|
||||||
.collapseToStartOfPreviousBlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return transform
|
|
||||||
.setBlock({
|
|
||||||
type: 'image',
|
type: 'image',
|
||||||
isVoid: true,
|
isVoid: true,
|
||||||
data: { src }
|
data: { src }
|
||||||
|
@@ -28,6 +28,7 @@ class Leaf extends React.Component {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
index: React.PropTypes.number.isRequired,
|
index: React.PropTypes.number.isRequired,
|
||||||
|
isVoid: React.PropTypes.bool,
|
||||||
marks: React.PropTypes.object.isRequired,
|
marks: React.PropTypes.object.isRequired,
|
||||||
node: React.PropTypes.object.isRequired,
|
node: React.PropTypes.object.isRequired,
|
||||||
ranges: React.PropTypes.object.isRequired,
|
ranges: React.PropTypes.object.isRequired,
|
||||||
@@ -36,6 +37,16 @@ class Leaf extends React.Component {
|
|||||||
text: React.PropTypes.string.isRequired
|
text: React.PropTypes.string.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default properties.
|
||||||
|
*
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
isVoid: false
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
@@ -85,6 +96,10 @@ class Leaf extends React.Component {
|
|||||||
return state.selection.hasEdgeBetween(node, start, end)
|
return state.selection.hasEdgeBetween(node, start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the DOM updates, try updating the selection.
|
||||||
|
*/
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.updateSelection()
|
this.updateSelection()
|
||||||
}
|
}
|
||||||
@@ -93,14 +108,18 @@ class Leaf extends React.Component {
|
|||||||
this.updateSelection()
|
this.updateSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the DOM selection if it's inside the leaf.
|
||||||
|
*/
|
||||||
|
|
||||||
updateSelection() {
|
updateSelection() {
|
||||||
const { state, ranges } = this.props
|
const { state, ranges, isVoid } = this.props
|
||||||
const { selection } = state
|
const { selection } = state
|
||||||
|
|
||||||
// If the selection is blurred we have nothing to do.
|
// If the selection is blurred we have nothing to do.
|
||||||
if (selection.isBlurred) return
|
if (selection.isBlurred) return
|
||||||
|
|
||||||
const { anchorOffset, focusOffset } = selection
|
let { anchorOffset, focusOffset } = selection
|
||||||
const { node, index } = this.props
|
const { node, index } = this.props
|
||||||
const { start, end } = OffsetKey.findBounds(index, ranges)
|
const { start, end } = OffsetKey.findBounds(index, ranges)
|
||||||
|
|
||||||
@@ -109,6 +128,13 @@ class Leaf extends React.Component {
|
|||||||
const hasFocus = selection.hasFocusBetween(node, start, end)
|
const hasFocus = selection.hasFocusBetween(node, start, end)
|
||||||
if (!hasAnchor && !hasFocus) return
|
if (!hasAnchor && !hasFocus) return
|
||||||
|
|
||||||
|
// If the leaf is a void leaf, ensure that it has no width. This is due to
|
||||||
|
// void nodes always rendering an empty leaf, for browser compatibility.
|
||||||
|
if (isVoid) {
|
||||||
|
anchorOffset = 0
|
||||||
|
focusOffset = 0
|
||||||
|
}
|
||||||
|
|
||||||
// We have a selection to render, so prepare a few things...
|
// We have a selection to render, so prepare a few things...
|
||||||
const native = window.getSelection()
|
const native = window.getSelection()
|
||||||
const el = findDeepestNode(ReactDOM.findDOMNode(this))
|
const el = findDeepestNode(ReactDOM.findDOMNode(this))
|
||||||
|
@@ -164,6 +164,7 @@ class Void extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Leaf
|
<Leaf
|
||||||
|
isVoid
|
||||||
renderMark={noop}
|
renderMark={noop}
|
||||||
key={offsetKey}
|
key={offsetKey}
|
||||||
state={state}
|
state={state}
|
||||||
|
Reference in New Issue
Block a user