Always correctly update MathjaxHandle position

This commit is contained in:
Henrik Giesel 2021-09-15 17:05:43 +02:00
parent ce9674f824
commit 9b7ea75399
5 changed files with 51 additions and 36 deletions

View File

@ -24,10 +24,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
$: { $: {
encoded = encodeURIComponent(converted); encoded = encodeURIComponent(converted);
setTimeout(() => (imageHeight = image.getBoundingClientRect().height));
setTimeout(() => {
imageHeight = image.getBoundingClientRect().height;
});
} }
let image: HTMLImageElement; let image: HTMLImageElement;

View File

@ -5,7 +5,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<script lang="ts"> <script lang="ts">
import { onMount, createEventDispatcher } from "svelte"; import { onMount, createEventDispatcher } from "svelte";
export let title: string | undefined = undefined; export let tooltip: string | undefined = undefined;
let background: HTMLDivElement; let background: HTMLDivElement;
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
@ -15,7 +15,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<div <div
bind:this={background} bind:this={background}
{title} title={tooltip}
on:mousedown|preventDefault on:mousedown|preventDefault
on:click|stopPropagation on:click|stopPropagation
on:dblclick on:dblclick

View File

@ -15,7 +15,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let width: number; let width: number;
let height: number; let height: number;
export function updateSelection(_div: HTMLDivElement): void { function setSelection(_selection?: HTMLDivElement): void {
const containerRect = container.getBoundingClientRect(); const containerRect = container.getBoundingClientRect();
const imageRect = image!.getBoundingClientRect(); const imageRect = image!.getBoundingClientRect();
@ -28,6 +28,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
height = image!.clientHeight; height = image!.clientHeight;
} }
export function updateSelection(): Promise<void> {
let updateResolve: () => void;
const afterUpdate: Promise<void> = new Promise((resolve) => {
updateResolve = resolve;
});
setSelection();
setTimeout(() => updateResolve());
return afterUpdate;
}
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
let selection: HTMLDivElement; let selection: HTMLDivElement;
@ -36,7 +48,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<div <div
bind:this={selection} bind:this={selection}
use:updateSelection use:setSelection
on:click={(event) => on:click={(event) =>
/* prevent triggering Bootstrap dropdown */ event.stopImmediatePropagation()} /* prevent triggering Bootstrap dropdown */ event.stopImmediatePropagation()}
style="--left: {left}px; --top: {top}px; --width: {width}px; --height: {height}px; --offsetX: {offsetX}px; --offsetY: {offsetY}px;" style="--left: {left}px; --top: {top}px; --width: {width}px; --height: {height}px; --offsetX: {offsetX}px; --offsetY: {offsetY}px;"

View File

@ -53,10 +53,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} }
} }
let updateSelection: () => void; let updateSelection: () => Promise<void>;
async function updateSizesWithDimensions() { async function updateSizesWithDimensions() {
updateSelection(); await updateSelection();
updateDimensions(); updateDimensions();
} }

View File

@ -20,51 +20,57 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let container: HTMLElement; export let container: HTMLElement;
export let isRtl: boolean; export let isRtl: boolean;
const resizeObserver = new ResizeObserver(() => { let dropdownApi: any;
const resizeObserver = new ResizeObserver(async () => {
if (activeImage) { if (activeImage) {
updateSelection(); await updateSelection();
dropdownApi.update();
} }
}); });
resizeObserver.observe(container); resizeObserver.observe(container);
let updateSelection: () => void; let updateSelection: () => Promise<void>;
let dropdownApi: any; let errorMessage: string;
let title: string;
function getComponent(image: HTMLImageElement): HTMLElement { function getComponent(image: HTMLImageElement): HTMLElement {
return image.closest("anki-mathjax")! as HTMLElement; return image.closest("anki-mathjax")! as HTMLElement;
} }
function scheduleDropdownUpdate() { function onEditorUpdate(event: CustomEvent) {
setTimeout(async () => {
await tick();
dropdownApi.update();
});
}
async function onEditorUpdate(event: CustomEvent) {
getComponent(activeImage!).dataset.mathjax = event.detail.mathjax; getComponent(activeImage!).dataset.mathjax = event.detail.mathjax;
setTimeout(() => { let selectionResolve: (value: void) => void;
updateSelection(); const afterSelectionUpdate = new Promise((resolve) => {
title = activeImage!.title; selectionResolve = resolve;
scheduleDropdownUpdate();
}); });
setTimeout(async () => {
errorMessage = activeImage!.title;
await updateSelection();
selectionResolve();
});
return afterSelectionUpdate;
} }
</script> </script>
<WithDropdown drop="down" autoOpen={true} autoClose={false} let:createDropdown> <WithDropdown
drop="down"
autoOpen={true}
autoClose={false}
let:createDropdown
let:dropdownObject
>
{#if activeImage} {#if activeImage}
<HandleSelection <HandleSelection
image={activeImage} image={activeImage}
{container} {container}
offsetX={2}
offsetY={2}
bind:updateSelection bind:updateSelection
on:mount={(event) => (dropdownApi = createDropdown(event.detail.selection))} on:mount={(event) => (dropdownApi = createDropdown(event.detail.selection))}
> >
<HandleBackground {title} /> <HandleBackground tooltip={errorMessage} />
<HandleControl offsetX={1} offsetY={1} /> <HandleControl offsetX={1} offsetY={1} />
</HandleSelection> </HandleSelection>
@ -72,7 +78,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<DropdownMenu> <DropdownMenu>
<MathjaxHandleEditor <MathjaxHandleEditor
initialValue={getComponent(activeImage).dataset.mathjax ?? ""} initialValue={getComponent(activeImage).dataset.mathjax ?? ""}
on:update={onEditorUpdate} on:update={async (event) => {
await onEditorUpdate(event);
dropdownObject.update();
}}
/> />
<div class="margin-x"> <div class="margin-x">
<ButtonToolbar> <ButtonToolbar>
@ -80,10 +89,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<MathjaxHandleInlineBlock <MathjaxHandleInlineBlock
{activeImage} {activeImage}
{isRtl} {isRtl}
on:click={() => { on:click={updateSelection}
updateSelection();
scheduleDropdownUpdate();
}}
/> />
</Item> </Item>
</ButtonToolbar> </ButtonToolbar>