mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-17 20:51:20 +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 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.
|
||||
*
|
||||
@@ -12,22 +51,47 @@ function scrollToSelection(selection) {
|
||||
if (!selection.anchorNode) return
|
||||
|
||||
const window = getWindow(selection.anchorNode)
|
||||
const scroller = findScrollContainer(selection.anchorNode)
|
||||
const isWindow = scroller == window
|
||||
const backward = isBackward(selection)
|
||||
const range = selection.getRangeAt(0)
|
||||
const rect = range.getBoundingClientRect()
|
||||
const { innerWidth, innerHeight, pageYOffset, pageXOffset } = window
|
||||
const top = (backward ? rect.top : rect.bottom) + pageYOffset
|
||||
const left = (backward ? rect.left : rect.right) + pageXOffset
|
||||
let width
|
||||
let height
|
||||
let yOffset
|
||||
let xOffset
|
||||
|
||||
const x = left < pageXOffset || innerWidth + pageXOffset < left
|
||||
? left - innerWidth / 2
|
||||
: pageXOffset
|
||||
if (isWindow) {
|
||||
const { innerWidth, innerHeight, pageYOffset, pageXOffset } = scroller
|
||||
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
|
||||
? top - innerHeight / 2
|
||||
: pageYOffset
|
||||
const top = (backward ? rect.top : rect.bottom) + yOffset
|
||||
const left = (backward ? rect.left : rect.right) + xOffset
|
||||
|
||||
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