1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-21 14:41:23 +02:00

feat: Add extendSelection utility (#730)

* feat: Add extendSelection util

* Shims the native `Selection.extend` method if not available with a simplistic shim by @tyler-johnson
* Fixes IE10+ as they don't support the native method

* Linting fixes

* Linting fix
This commit is contained in:
Craig Michael Thompson
2017-04-19 17:14:08 +01:00
committed by Ian Storm Taylor
parent c36537c6e8
commit 1e2bd62d38
2 changed files with 47 additions and 1 deletions

View File

@@ -3,6 +3,7 @@ import Base64 from '../serializers/base-64'
import Debug from 'debug' import Debug from 'debug'
import Node from './node' import Node from './node'
import getPoint from '../utils/get-point' import getPoint from '../utils/get-point'
import extendSelection from '../utils/extend-selection'
import findClosestNode from '../utils/find-closest-node' import findClosestNode from '../utils/find-closest-node'
import React from 'react' import React from 'react'
import Selection from '../models/selection' import Selection from '../models/selection'
@@ -207,7 +208,7 @@ class Content extends React.Component {
const range = window.document.createRange() const range = window.document.createRange()
range.setStart(anchorEl, anchorOff) range.setStart(anchorEl, anchorOff)
native.addRange(range) native.addRange(range)
native.extend(focusEl, focusOff) extendSelection(native, focusEl, focusOff)
// Then unset the `isSelecting` flag after a delay. // Then unset the `isSelecting` flag after a delay.
setTimeout(() => { setTimeout(() => {

View File

@@ -0,0 +1,45 @@
/**
* Extends the given selection to a given node and offset
*
* @param {Selection} selection Selection instance
* @param {Element} el Node to extend to
* @param {Number} offset Text offset to extend to
* @returns {Selection} Mutated Selection instance
*/
function extendSelection(selection, el, offset) {
// Use native method when possible
if (typeof selection.extend === 'function') return selection.extend(el, offset)
// See https://gist.github.com/tyler-johnson/0a3e8818de3f115b2a2dc47468ac0099
const range = document.createRange()
const anchor = document.createRange()
anchor.setStart(selection.anchorNode, selection.anchorOffset)
const focus = document.createRange()
focus.setStart(el, offset)
const v = focus.compareBoundaryPoints(Range.START_TO_START, anchor)
if (v >= 0) { // Focus is after anchor
range.setStart(selection.anchorNode, selection.anchorOffset)
range.setEnd(el, offset)
} else { // Anchor is after focus
range.setStart(el, offset)
range.setEnd(selection.anchorNode, selection.anchorOffset)
}
selection.removeAllRanges()
selection.addRange(range)
return selection
}
/**
* Export.
*
* @type {Function}
*/
export default extendSelection