mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-18 13:11:17 +02:00
* Scoll to selection tweaks, possible fix for #1032 * Update scroll-to-selection.js * Update scroll-to-selection.js
This commit is contained in:
committed by
Ian Storm Taylor
parent
40def34e5b
commit
1b4532a9aa
@@ -2,6 +2,45 @@
|
|||||||
import getWindow from 'get-window'
|
import getWindow from 'get-window'
|
||||||
import isBackward from 'selection-is-backward'
|
import isBackward from 'selection-is-backward'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CSS overflow values that would cause scrolling.
|
||||||
|
*
|
||||||
|
* @type {Array}
|
||||||
|
*/
|
||||||
|
|
||||||
|
const OVERFLOWS = [
|
||||||
|
'auto',
|
||||||
|
'overlay',
|
||||||
|
'scroll',
|
||||||
|
]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the nearest parent with scrolling, or window.
|
||||||
|
*
|
||||||
|
* @param {el} Element
|
||||||
|
*/
|
||||||
|
|
||||||
|
function findScrollContainer(el) {
|
||||||
|
const window = getWindow(el)
|
||||||
|
let parent = el.parentNode
|
||||||
|
let scroller = window
|
||||||
|
|
||||||
|
while (!scroller) {
|
||||||
|
if (!parent.parentNode) break
|
||||||
|
const style = window.getComputedStyle(parent)
|
||||||
|
const { overflowY } = style
|
||||||
|
|
||||||
|
if (OVERFLOWS.includes(overflowY)) {
|
||||||
|
scroller = parent
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
parent = parent.parentNode
|
||||||
|
}
|
||||||
|
|
||||||
|
return scroller
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scroll the current selection's focus point into view if needed.
|
* Scroll the current selection's focus point into view if needed.
|
||||||
*
|
*
|
||||||
@@ -12,22 +51,47 @@ function scrollToSelection(selection) {
|
|||||||
if (!selection.anchorNode) return
|
if (!selection.anchorNode) return
|
||||||
|
|
||||||
const window = getWindow(selection.anchorNode)
|
const window = getWindow(selection.anchorNode)
|
||||||
|
const scroller = findScrollContainer(selection.anchorNode)
|
||||||
|
const isWindow = scroller == window
|
||||||
const backward = isBackward(selection)
|
const backward = isBackward(selection)
|
||||||
const range = selection.getRangeAt(0)
|
const range = selection.getRangeAt(0)
|
||||||
const rect = range.getBoundingClientRect()
|
const rect = range.getBoundingClientRect()
|
||||||
const { innerWidth, innerHeight, pageYOffset, pageXOffset } = window
|
let width
|
||||||
const top = (backward ? rect.top : rect.bottom) + pageYOffset
|
let height
|
||||||
const left = (backward ? rect.left : rect.right) + pageXOffset
|
let yOffset
|
||||||
|
let xOffset
|
||||||
|
|
||||||
const x = left < pageXOffset || innerWidth + pageXOffset < left
|
if (isWindow) {
|
||||||
? left - innerWidth / 2
|
const { innerWidth, innerHeight, pageYOffset, pageXOffset } = scroller
|
||||||
: pageXOffset
|
width = innerWidth
|
||||||
|
height = innerHeight
|
||||||
|
yOffset = pageYOffset
|
||||||
|
xOffset = pageXOffset
|
||||||
|
} else {
|
||||||
|
const { offsetWidth, offsetHeight, scrollTop, scrollLeft } = scroller
|
||||||
|
width = offsetWidth
|
||||||
|
height = offsetHeight
|
||||||
|
yOffset = scrollTop
|
||||||
|
xOffset = scrollLeft
|
||||||
|
}
|
||||||
|
|
||||||
const y = top < pageYOffset || innerHeight + pageYOffset < top
|
const top = (backward ? rect.top : rect.bottom) + yOffset
|
||||||
? top - innerHeight / 2
|
const left = (backward ? rect.left : rect.right) + xOffset
|
||||||
: pageYOffset
|
|
||||||
|
|
||||||
window.scrollTo(x, y)
|
const x = left < yOffset || innerWidth + xOffset < left
|
||||||
|
? left - width / 2
|
||||||
|
: xOffset
|
||||||
|
|
||||||
|
const y = top < yOffset || height + yOffset < top
|
||||||
|
? top - height / 2
|
||||||
|
: yOffset
|
||||||
|
|
||||||
|
if (isWindow) {
|
||||||
|
window.scrollTo(x, y)
|
||||||
|
} else {
|
||||||
|
scroller.scrollTop = scroller.scrollTop + y
|
||||||
|
scroller.scrollLeft = scroller.scrollLeft + x
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user