mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-23 15:32:59 +02:00
fix: account for container padding in scrollToSelection (#1462)
This commit is contained in:
committed by
Ian Storm Taylor
parent
fafa607e54
commit
a3d91b6daa
@@ -65,8 +65,9 @@ function scrollToSelection(selection) {
|
|||||||
const isWindow = scroller == window.document.body || scroller == window.document.documentElement
|
const isWindow = scroller == window.document.body || scroller == window.document.documentElement
|
||||||
const backward = isBackward(selection)
|
const backward = isBackward(selection)
|
||||||
|
|
||||||
const range = selection.getRangeAt(0)
|
const range = selection.getRangeAt(0).cloneRange()
|
||||||
let selectionRect = range.getBoundingClientRect()
|
range.collapse(backward)
|
||||||
|
let cursorRect = range.getBoundingClientRect()
|
||||||
|
|
||||||
// COMPAT: range.getBoundingClientRect() returns 0s in Safari when range is
|
// COMPAT: range.getBoundingClientRect() returns 0s in Safari when range is
|
||||||
// collapsed. Expanding the range by 1 is a relatively effective workaround
|
// collapsed. Expanding the range by 1 is a relatively effective workaround
|
||||||
@@ -74,18 +75,18 @@ function scrollToSelection(selection) {
|
|||||||
// https://bugs.webkit.org/show_bug.cgi?id=138949
|
// https://bugs.webkit.org/show_bug.cgi?id=138949
|
||||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=435438
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=435438
|
||||||
if (IS_SAFARI) {
|
if (IS_SAFARI) {
|
||||||
if (range.collapsed && selectionRect.top == 0 && selectionRect.height == 0) {
|
if (range.collapsed && cursorRect.top == 0 && cursorRect.height == 0) {
|
||||||
if (range.startOffset == 0) {
|
if (range.startOffset == 0) {
|
||||||
range.setEnd(range.endContainer, 1)
|
range.setEnd(range.endContainer, 1)
|
||||||
} else {
|
} else {
|
||||||
range.setStart(range.startContainer, range.startOffset - 1)
|
range.setStart(range.startContainer, range.startOffset - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
selectionRect = range.getBoundingClientRect()
|
cursorRect = range.getBoundingClientRect()
|
||||||
|
|
||||||
if (selectionRect.top == 0 && selectionRect.height == 0) {
|
if (cursorRect.top == 0 && cursorRect.height == 0) {
|
||||||
if (range.getClientRects().length) {
|
if (range.getClientRects().length) {
|
||||||
selectionRect = range.getClientRects()[0]
|
cursorRect = range.getClientRects()[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,6 +100,10 @@ function scrollToSelection(selection) {
|
|||||||
let scrollerLeft = 0
|
let scrollerLeft = 0
|
||||||
let scrollerBordersY = 0
|
let scrollerBordersY = 0
|
||||||
let scrollerBordersX = 0
|
let scrollerBordersX = 0
|
||||||
|
let scrollerPaddingTop = 0
|
||||||
|
let scrollerPaddingBottom = 0
|
||||||
|
let scrollerPaddingLeft = 0
|
||||||
|
let scrollerPaddingRight = 0
|
||||||
|
|
||||||
if (isWindow) {
|
if (isWindow) {
|
||||||
const { innerWidth, innerHeight, pageYOffset, pageXOffset } = window
|
const { innerWidth, innerHeight, pageYOffset, pageXOffset } = window
|
||||||
@@ -113,6 +118,10 @@ function scrollToSelection(selection) {
|
|||||||
borderBottomWidth,
|
borderBottomWidth,
|
||||||
borderLeftWidth,
|
borderLeftWidth,
|
||||||
borderRightWidth,
|
borderRightWidth,
|
||||||
|
paddingTop,
|
||||||
|
paddingBottom,
|
||||||
|
paddingLeft,
|
||||||
|
paddingRight,
|
||||||
} = window.getComputedStyle(scroller)
|
} = window.getComputedStyle(scroller)
|
||||||
|
|
||||||
const scrollerRect = scroller.getBoundingClientRect()
|
const scrollerRect = scroller.getBoundingClientRect()
|
||||||
@@ -122,33 +131,34 @@ function scrollToSelection(selection) {
|
|||||||
scrollerLeft = scrollerRect.left + parseInt(borderLeftWidth, 10)
|
scrollerLeft = scrollerRect.left + parseInt(borderLeftWidth, 10)
|
||||||
scrollerBordersY = parseInt(borderTopWidth, 10) + parseInt(borderBottomWidth, 10)
|
scrollerBordersY = parseInt(borderTopWidth, 10) + parseInt(borderBottomWidth, 10)
|
||||||
scrollerBordersX = parseInt(borderLeftWidth, 10) + parseInt(borderRightWidth, 10)
|
scrollerBordersX = parseInt(borderLeftWidth, 10) + parseInt(borderRightWidth, 10)
|
||||||
|
scrollerPaddingTop = parseInt(paddingTop, 10)
|
||||||
|
scrollerPaddingBottom = parseInt(paddingBottom, 10)
|
||||||
|
scrollerPaddingLeft = parseInt(paddingLeft, 10)
|
||||||
|
scrollerPaddingRight = parseInt(paddingRight, 10)
|
||||||
yOffset = scrollTop
|
yOffset = scrollTop
|
||||||
xOffset = scrollLeft
|
xOffset = scrollLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectionFocusTop = backward ? selectionRect.top : selectionRect.bottom
|
const cursorTop = cursorRect.top + yOffset - scrollerTop
|
||||||
const selectionTop = selectionFocusTop + yOffset - scrollerTop
|
const cursorLeft = cursorRect.left + xOffset - scrollerLeft
|
||||||
|
|
||||||
const selectionFocusLeft = backward ? selectionRect.left : selectionRect.right
|
|
||||||
const selectionLeft = selectionFocusLeft + xOffset - scrollerLeft
|
|
||||||
|
|
||||||
let x = xOffset
|
let x = xOffset
|
||||||
let y = yOffset
|
let y = yOffset
|
||||||
|
|
||||||
if (selectionLeft < xOffset) {
|
if (cursorLeft < xOffset) {
|
||||||
// selection to the left of viewport
|
// selection to the left of viewport
|
||||||
x = selectionLeft
|
x = cursorLeft - scrollerPaddingLeft
|
||||||
} else if (selectionLeft + selectionRect.width + scrollerBordersX > xOffset + width) {
|
} else if (cursorLeft + cursorRect.width + scrollerBordersX > xOffset + width) {
|
||||||
// selection to the right of viewport
|
// selection to the right of viewport
|
||||||
x = selectionLeft + scrollerBordersX - width
|
x = cursorLeft + scrollerBordersX + scrollerPaddingRight - width
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectionTop < yOffset) {
|
if (cursorTop < yOffset) {
|
||||||
// selection above viewport
|
// selection above viewport
|
||||||
y = selectionTop
|
y = cursorTop - scrollerPaddingTop
|
||||||
} else if (selectionTop + selectionRect.height + scrollerBordersY > yOffset + height) {
|
} else if (cursorTop + cursorRect.height + scrollerBordersY > yOffset + height) {
|
||||||
// selection below viewport
|
// selection below viewport
|
||||||
y = selectionTop + scrollerBordersY + selectionRect.height - height
|
y = cursorTop + scrollerBordersY + scrollerPaddingBottom + cursorRect.height - height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user