1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-17 20:51:20 +02:00

[WIP] Scoll to selection tweaks, possible fix for #1032 (#1165)

* Scoll to selection tweaks, possible fix for #1032

* Update scroll-to-selection.js

* Update scroll-to-selection.js
This commit is contained in:
Per-Kristian Nordnes
2017-11-01 03:00:02 +01:00
committed by Ian Storm Taylor
parent 40def34e5b
commit 1b4532a9aa

View File

@@ -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
}
}
/**