mirror of
https://github.com/nextcloud/richdocuments.git
synced 2025-12-17 21:12:14 +01:00
When resizing the frame on mobile we correctly resize the outer <div>
element. We used to also resize the frame, but in ba45233bf (chore:
refactor iframes to load collabora directly, 2023-06-11) the ID of the
iframe was changed without things that depended on it also changing.
In Chrome, this causes the issue that the iframe isn't resized all the
way down, leading to it being possible to scroll the iframe inside the
viewport. This is bad as it means some elements of Collabora Online that
are meant to be stuck to different parts of the screen can go off the
screen edge.
There are some bits of CSS which also refer to this ID. To aid in easy
partial reverting (and as I don't currently have a need for them) I have
not fixed them in this commit
Signed-off-by: Skyler Grey <skyler.grey@collabora.com>
71 lines
1.9 KiB
JavaScript
71 lines
1.9 KiB
JavaScript
/**
|
|
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
let scrollLock = false
|
|
let intervalHandler
|
|
|
|
// Workaround for browsers automatically scrolling the body when the hidden input is focussed
|
|
const handleScrollReset = () => {
|
|
document.documentElement.scrollTop = 0
|
|
document.scrollingElement.scrollTop = 0
|
|
}
|
|
|
|
// Workaround for mobile browsers to resize the iframe to the visual viewport height
|
|
// as visual viewport area - which includes OSK, say - is not propagated to iframes
|
|
// see https://developer.mozilla.org/en-US/docs/Web/API/VisualViewport
|
|
const handleResize = () => {
|
|
const expectedHeight = window.visualViewport.height ?? document.documentElement.clientHeight
|
|
const frames = document.getElementsByClassName('office-viewer__iframe')
|
|
for (const frame of frames) {
|
|
frame.style.maxHeight = expectedHeight + 'px'
|
|
}
|
|
const viewer = document.querySelector('.office-viewer')
|
|
if (viewer) {
|
|
viewer.style.height = expectedHeight + 'px'
|
|
}
|
|
}
|
|
|
|
const fixThemAll = () => {
|
|
if (!scrollLock) {
|
|
return
|
|
}
|
|
|
|
handleScrollReset()
|
|
handleResize()
|
|
}
|
|
|
|
const preventDefault = (e) => e.preventDefault()
|
|
|
|
export const enableScrollLock = () => {
|
|
if (scrollLock) {
|
|
return
|
|
}
|
|
|
|
scrollLock = true
|
|
|
|
window?.visualViewport?.addEventListener('resize', fixThemAll)
|
|
|| window.addEventListener('resize', fixThemAll)
|
|
|
|
document.addEventListener('touchstart', preventDefault, false)
|
|
document.addEventListener('touchmove', preventDefault, false)
|
|
|
|
intervalHandler = setInterval(fixThemAll, 200)
|
|
}
|
|
|
|
export const disableScrollLock = () => {
|
|
if (!scrollLock) {
|
|
return
|
|
}
|
|
|
|
scrollLock = false
|
|
|
|
window?.visualViewport?.removeEventListener('resize', fixThemAll)
|
|
|| window.removeEventListener('resize', fixThemAll)
|
|
|
|
document.removeEventListener('touchstart', preventDefault, false)
|
|
document.removeEventListener('touchmove', preventDefault, false)
|
|
|
|
clearInterval(intervalHandler)
|
|
}
|