From a8a4890484ba6cd0edbd4e77e4e69c2b62ece7f6 Mon Sep 17 00:00:00 2001 From: Michael Wedl Date: Tue, 28 Nov 2023 10:24:04 +0100 Subject: [PATCH] Prevent page jumping when switching MDE mode --- CHANGELOG.md | 1 + frontend/src/components/Markdown/Preview.vue | 4 ++- frontend/src/components/Markdown/Toolbar.vue | 34 +++++++++++++++++--- frontend/src/composables/markdown.ts | 3 ++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb7df22b4..27b027519 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Allow configuring regex patterns for list items * Add scheme to predefined URL regex * Fix list items not updated in design preview data form +* Prevent page offset jumping when switching markdown editor mode ## v2023.142 - 2023-11-21 diff --git a/frontend/src/components/Markdown/Preview.vue b/frontend/src/components/Markdown/Preview.vue index 60c0071d0..2a2be2aef 100644 --- a/frontend/src/components/Markdown/Preview.vue +++ b/frontend/src/components/Markdown/Preview.vue @@ -22,10 +22,12 @@ const props = defineProps<{ value?: string|null; rewriteFileUrl?: (fileSrc: string) => string; rewriteReferenceLink?: (src: string) => {href: string, title: string}|null; + cacheBuster?: string; }>(); const renderedMarkdown = ref(''); -const cacheBuster = uuidv4(); +const cacheBusterFallback = uuidv4(); +const cacheBuster = computed(() => props.cacheBuster || cacheBusterFallback); function rewriteFileSource(imgSrc: string) { // Rewrite image source to handle image fetching from markdown. diff --git a/frontend/src/components/Markdown/Toolbar.vue b/frontend/src/components/Markdown/Toolbar.vue index 83ab1fc99..b5e66fab8 100644 --- a/frontend/src/components/Markdown/Toolbar.vue +++ b/frontend/src/components/Markdown/Toolbar.vue @@ -1,5 +1,5 @@ @@ -63,6 +63,8 @@ import { isTypeInSelection, // @ts-ignore } from 'reportcreator-markdown/editor'; +import type { VToolbar } from 'vuetify/lib/components/index.mjs'; +import { MarkdownEditorMode } from '@/utils/types'; const props = defineProps<{ editorView: EditorView; @@ -119,6 +121,30 @@ function codemirrorAction(actionFn: (view: EditorView) => void) { } } +const toolbarRef = ref(); +function getScrollParent(node?: HTMLElement|null) { + if (!node) { return null; } + if (node.scrollHeight > node.clientHeight) { + return node; + } else { + return getScrollParent(node.parentElement); + } +} +async function setMarkdownEditorMode(mode: MarkdownEditorMode) { + const scrollParent = getScrollParent(toolbarRef.value!.$el); + const { y: prevTop } = toolbarRef.value!.$el.getBoundingClientRect(); + + // Update editor mode => changes view and potentially causes layout jump + localSettings.markdownEditorMode = mode; + await nextTick(); + + // Restore position, such the toolbar is at the same position + const { y: newTop } = toolbarRef.value!.$el.getBoundingClientRect(); + if (scrollParent) { + scrollParent.scrollTop += newTop - prevTop; + } +} +