mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-18 05:01:17 +02:00
Call scrollToSelection
on selection update. (#1134)
This commit is contained in:
committed by
Ian Storm Taylor
parent
ee2c4e6bc7
commit
fd7981782c
@@ -17,6 +17,7 @@ import getHtmlFromNativePaste from '../utils/get-html-from-native-paste'
|
|||||||
import getPoint from '../utils/get-point'
|
import getPoint from '../utils/get-point'
|
||||||
import getTransferData from '../utils/get-transfer-data'
|
import getTransferData from '../utils/get-transfer-data'
|
||||||
import setTransferData from '../utils/set-transfer-data'
|
import setTransferData from '../utils/set-transfer-data'
|
||||||
|
import scrollToSelection from '../utils/scroll-to-selection'
|
||||||
import { IS_FIREFOX, IS_MAC, IS_IE } from '../constants/environment'
|
import { IS_FIREFOX, IS_MAC, IS_IE } from '../constants/environment'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -165,6 +166,8 @@ class Content extends React.Component {
|
|||||||
native.addRange(range)
|
native.addRange(range)
|
||||||
if (!isCollapsed) extendSelection(native, focus.node, focus.offset)
|
if (!isCollapsed) extendSelection(native, focus.node, focus.offset)
|
||||||
|
|
||||||
|
scrollToSelection(native)
|
||||||
|
|
||||||
// Then unset the `isSelecting` flag after a delay.
|
// Then unset the `isSelecting` flag after a delay.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// COMPAT: In Firefox, it's not enough to create a range, you also need to
|
// COMPAT: In Firefox, it's not enough to create a range, you also need to
|
||||||
|
@@ -2,15 +2,12 @@
|
|||||||
import Base64 from 'slate-base64-serializer'
|
import Base64 from 'slate-base64-serializer'
|
||||||
import Debug from 'debug'
|
import Debug from 'debug'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
|
||||||
import SlateTypes from 'slate-prop-types'
|
import SlateTypes from 'slate-prop-types'
|
||||||
import Types from 'prop-types'
|
import Types from 'prop-types'
|
||||||
import getWindow from 'get-window'
|
|
||||||
|
|
||||||
import TRANSFER_TYPES from '../constants/transfer-types'
|
import TRANSFER_TYPES from '../constants/transfer-types'
|
||||||
import Leaf from './leaf'
|
import Leaf from './leaf'
|
||||||
import Void from './void'
|
import Void from './void'
|
||||||
import scrollToSelection from '../utils/scroll-to-selection'
|
|
||||||
import setTransferData from '../utils/set-transfer-data'
|
import setTransferData from '../utils/set-transfer-data'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -143,67 +140,6 @@ class Node extends React.Component {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* On mount, update the scroll position.
|
|
||||||
*/
|
|
||||||
|
|
||||||
componentDidMount = () => {
|
|
||||||
this.updateScroll()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* After update, update the scroll position if the node's content changed.
|
|
||||||
*
|
|
||||||
* @param {Object} prevProps
|
|
||||||
* @param {Object} prevState
|
|
||||||
*/
|
|
||||||
|
|
||||||
componentDidUpdate = (prevProps, prevState) => {
|
|
||||||
if (this.props.node != prevProps.node) this.updateScroll()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* There is a corner case, that some nodes are unmounted right after they update
|
|
||||||
* Then, when the timer execute, it will throw the error
|
|
||||||
* `findDOMNode was called on an unmounted component`
|
|
||||||
* We should clear the timer from updateScroll here
|
|
||||||
*/
|
|
||||||
|
|
||||||
componentWillUnmount = () => {
|
|
||||||
clearTimeout(this.scrollTimer)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the scroll position after a change as occured if this is a leaf
|
|
||||||
* block and it has the selection's ending edge. This ensures that scrolling
|
|
||||||
* matches native `contenteditable` behavior even for cases where the edit is
|
|
||||||
* not applied natively, like when enter is pressed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
updateScroll = () => {
|
|
||||||
const { node, state } = this.props
|
|
||||||
const { selection } = state
|
|
||||||
|
|
||||||
// If this isn't a block, or it's a wrapping block, abort.
|
|
||||||
if (node.kind != 'block') return
|
|
||||||
if (node.nodes.first().kind == 'block') return
|
|
||||||
|
|
||||||
// If the selection is blurred, or this block doesn't contain it, abort.
|
|
||||||
if (selection.isBlurred) return
|
|
||||||
if (!selection.hasEndIn(node)) return
|
|
||||||
|
|
||||||
// The native selection will be updated after componentDidMount or componentDidUpdate.
|
|
||||||
// Use setTimeout to queue scrolling to the last when the native selection has been updated to the correct value.
|
|
||||||
this.scrollTimer = setTimeout(() => {
|
|
||||||
const el = ReactDOM.findDOMNode(this)
|
|
||||||
const window = getWindow(el)
|
|
||||||
const native = window.getSelection()
|
|
||||||
scrollToSelection(native)
|
|
||||||
|
|
||||||
this.debug('updateScroll', el)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On drag start, add a serialized representation of the node to the data.
|
* On drag start, add a serialized representation of the node to the data.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user