All checks were successful
Deploy Development / deploy (push) Successful in 36s
Test Suite / pytest-backend (push) Successful in 25s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 7s
Test Suite / playwright-tests (push) Successful in 23s
Test Suite / pytest-backend (pull_request) Successful in 23s
Test Suite / lint-backend (pull_request) Successful in 0s
Test Suite / build-frontend (pull_request) Successful in 7s
Test Suite / playwright-tests (pull_request) Successful in 23s
- Incremented application version to 0.8.64 and updated changelog with new features. - Improved media handling in the Rich Text Editor with auto-scrolling during drag-and-drop. - Added new CSS styles for video thumbnails and enhanced layout for media items. - Removed deprecated `ExerciseAttachmentMediaStrip` from the ExerciseFullContent component. - Updated ExerciseFormPage to manage form dirty state and prevent data loss on navigation.
67 lines
2.1 KiB
JavaScript
67 lines
2.1 KiB
JavaScript
/**
|
|
* Während eines Drags automatischen Bildlauf auslösen (Viewport + scrollbare Bereiche unter dem Cursor).
|
|
* @param {DragEvent} e
|
|
* @param {{ edgePx?: number, scrollStep?: number }} [opts]
|
|
*/
|
|
export function autoScrollForDragNearEdges(e, opts = {}) {
|
|
const edge = opts.edgePx ?? 80
|
|
const step = opts.scrollStep ?? Math.max(24, Math.round(window.innerHeight * 0.05))
|
|
const { clientX, clientY } = e
|
|
|
|
const vh = window.innerHeight || 0
|
|
const vw = window.innerWidth || 0
|
|
|
|
let sy =
|
|
clientY < edge ? -step : vh > 0 && clientY > vh - edge ? step : 0
|
|
let sx =
|
|
clientX < edge ? -step : vw > 0 && clientX > vw - edge ? step : 0
|
|
|
|
if (sy !== 0) window.scrollBy(0, sy)
|
|
if (sx !== 0) window.scrollBy(sx, 0)
|
|
|
|
/** @type {HTMLElement|null} */
|
|
let top = /** @type {HTMLElement|null} */ (document.elementFromPoint(clientX, clientY))
|
|
|
|
/** @type {Set<HTMLElement>} */
|
|
const done = new Set()
|
|
|
|
/** @type {HTMLElement|null} */
|
|
let walk = top
|
|
const innerEdge = Math.min(edge, 40)
|
|
|
|
while (walk && walk !== document.body) {
|
|
if (!(walk instanceof HTMLElement)) break
|
|
|
|
const cs = window.getComputedStyle(walk)
|
|
const canY =
|
|
walk.scrollHeight - walk.clientHeight > 6 &&
|
|
(cs.overflowY === 'auto' || cs.overflowY === 'scroll')
|
|
const canX =
|
|
walk.scrollWidth - walk.clientWidth > 6 &&
|
|
(cs.overflowX === 'auto' || cs.overflowX === 'scroll')
|
|
|
|
if ((canY || canX) && !done.has(walk)) {
|
|
done.add(walk)
|
|
const rect = walk.getBoundingClientRect()
|
|
|
|
const relY = clientY - rect.top
|
|
const relX = clientX - rect.left
|
|
|
|
if (canY) {
|
|
if (relY < innerEdge && walk.scrollTop > 0) walk.scrollTop -= step
|
|
else if (rect.height - relY < innerEdge && walk.scrollTop < walk.scrollHeight - walk.clientHeight) {
|
|
walk.scrollTop += step
|
|
}
|
|
}
|
|
if (canX) {
|
|
if (relX < innerEdge && walk.scrollLeft > 0) walk.scrollLeft -= step
|
|
else if (rect.width - relX < innerEdge && walk.scrollLeft < walk.scrollWidth - walk.clientWidth) {
|
|
walk.scrollLeft += step
|
|
}
|
|
}
|
|
}
|
|
|
|
walk = walk.parentElement
|
|
}
|
|
}
|