mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-16 12:14:14 +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 getTransferData from '../utils/get-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'
|
||||
|
||||
/**
|
||||
@@ -165,6 +166,8 @@ class Content extends React.Component {
|
||||
native.addRange(range)
|
||||
if (!isCollapsed) extendSelection(native, focus.node, focus.offset)
|
||||
|
||||
scrollToSelection(native)
|
||||
|
||||
// Then unset the `isSelecting` flag after a delay.
|
||||
setTimeout(() => {
|
||||
// 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 Debug from 'debug'
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import SlateTypes from 'slate-prop-types'
|
||||
import Types from 'prop-types'
|
||||
import getWindow from 'get-window'
|
||||
|
||||
import TRANSFER_TYPES from '../constants/transfer-types'
|
||||
import Leaf from './leaf'
|
||||
import Void from './void'
|
||||
import scrollToSelection from '../utils/scroll-to-selection'
|
||||
import setTransferData from '../utils/set-transfer-data'
|
||||
|
||||
/**
|
||||
@@ -143,67 +140,6 @@ class Node extends React.Component {
|
||||
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.
|
||||
*
|
||||
|
Reference in New Issue
Block a user