diff --git a/packages/slate-react/src/components/content.js b/packages/slate-react/src/components/content.js index ebc4cb6da..a15680ec9 100644 --- a/packages/slate-react/src/components/content.js +++ b/packages/slate-react/src/components/content.js @@ -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 diff --git a/packages/slate-react/src/components/node.js b/packages/slate-react/src/components/node.js index bd33eb4d6..a9b94f275 100644 --- a/packages/slate-react/src/components/node.js +++ b/packages/slate-react/src/components/node.js @@ -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. *