Skip to content

Commit d79ead6

Browse files
authored
Fix Obsidian listener accumulation (#141)
1 parent a665eff commit d79ead6

2 files changed

Lines changed: 61 additions & 33 deletions

File tree

src/ui/obsidian/Slider.svelte

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { SliderComponent } from "obsidian";
33
import type { CSSObject } from "src/types/CSSObject";
44
import extractStylesFromObj from "src/utility/extractStylesFromObj";
5-
import { afterUpdate, createEventDispatcher, onMount } from "svelte";
5+
import { createEventDispatcher, onDestroy, onMount } from "svelte";
66
77
export let value: number;
88
export let limits: [min: number, max: number] | [min: number, max: number, step: number];
@@ -13,36 +13,49 @@
1313
const dispatch = createEventDispatcher();
1414
1515
let slider: SliderComponent;
16-
let styles: CSSObject;
16+
let styles: CSSObject = {};
17+
let changeHandler: ((event: Event) => void) | null = null;
1718
1819
// This is not a complete implementation. I implemented what I needed.
1920
2021
onMount(() => {
2122
slider = new SliderComponent(sliderRef);
2223
23-
updateSliderAttributes(slider);
24+
changeHandler = (event: Event) => {
25+
const newValue = Number((event.target as HTMLInputElement).value);
26+
dispatch("change", { value: newValue });
27+
};
28+
29+
slider.sliderEl.addEventListener("input", changeHandler);
2430
});
2531
26-
afterUpdate(() => {
27-
updateSliderAttributes(slider);
32+
onDestroy(() => {
33+
if (slider?.sliderEl && changeHandler) {
34+
slider.sliderEl.removeEventListener("input", changeHandler);
35+
}
2836
});
2937
30-
function updateSliderAttributes(sldr: SliderComponent) {
31-
if (value !== undefined) sldr.setValue(value);
32-
if (limits) {
33-
if (limits.length === 2) {
34-
sldr.setLimits(limits[0], limits[1], 1);
38+
$: if (slider) {
39+
updateSliderAttributes(slider, value, limits, styles);
40+
}
41+
42+
function updateSliderAttributes(
43+
sldr: SliderComponent,
44+
currentValue: number,
45+
currentLimits: [min: number, max: number] | [min: number, max: number, step: number],
46+
currentStyles: CSSObject
47+
) {
48+
if (currentValue !== undefined) sldr.setValue(currentValue);
49+
if (currentLimits) {
50+
if (currentLimits.length === 2) {
51+
sldr.setLimits(currentLimits[0], currentLimits[1], 1);
3552
} else {
36-
sldr.setLimits(limits[0], limits[1], limits[2]);
53+
sldr.setLimits(currentLimits[0], currentLimits[1], currentLimits[2]);
3754
}
3855
}
39-
if (styles) {
40-
sldr.sliderEl.setAttr("style", extractStylesFromObj(styles));
56+
if (currentStyles) {
57+
sldr.sliderEl.setAttr("style", extractStylesFromObj(currentStyles));
4158
}
42-
43-
sldr.onChange((value: number) => {
44-
dispatch("change", { value });
45-
});
4659
}
4760
</script>
4861

src/ui/obsidian/Text.svelte

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { TextComponent } from "obsidian";
33
import type { CSSObject } from "src/types/CSSObject";
44
import extractStylesFromObj from "src/utility/extractStylesFromObj";
5-
import { afterUpdate, createEventDispatcher, onMount } from "svelte";
5+
import { createEventDispatcher, onDestroy, onMount } from "svelte";
66
77
export let value: string = "";
88
export let disabled: boolean = false;
@@ -17,33 +17,48 @@
1717
1818
let text: TextComponent;
1919
let styles: CSSObject = {};
20+
let textChangeHandler: ((event: Event) => void) | null = null;
2021
2122
onMount(() => {
2223
text = new TextComponent(textRef);
2324
24-
updateTextComponentAttributes(text);
25+
textChangeHandler = (event: Event) => {
26+
const newValue = (event.target as HTMLInputElement).value;
27+
value = newValue;
28+
dispatch("change", { value: newValue });
29+
};
30+
31+
text.inputEl.addEventListener("input", textChangeHandler);
2532
});
2633
27-
afterUpdate(() => {
28-
updateTextComponentAttributes(text);
34+
onDestroy(() => {
35+
if (text?.inputEl && textChangeHandler) {
36+
text.inputEl.removeEventListener("input", textChangeHandler);
37+
}
2938
});
3039
31-
function updateTextComponentAttributes(component: TextComponent) {
32-
if (value !== undefined) component.setValue(value);
33-
if (disabled) component.setDisabled(disabled);
34-
if (placeholder) component.setPlaceholder(placeholder);
35-
if (type) component.inputEl.type = type;
36-
if (styles) {
37-
text.inputEl.setAttr("style", extractStylesFromObj(styles));
40+
$: if (text) {
41+
updateTextComponentAttributes(text, value, disabled, placeholder, type, styles);
42+
}
43+
44+
function updateTextComponentAttributes(
45+
component: TextComponent,
46+
currentValue: string,
47+
isDisabled: boolean,
48+
currentPlaceholder: string,
49+
currentType: "text" | "password" | "email" | "number" | "tel" | "url",
50+
currentStyles: CSSObject
51+
) {
52+
if (currentValue !== undefined) component.setValue(currentValue);
53+
if (isDisabled) component.setDisabled(isDisabled);
54+
if (currentPlaceholder) component.setPlaceholder(currentPlaceholder);
55+
if (currentType) component.inputEl.type = currentType;
56+
if (currentStyles) {
57+
component.inputEl.setAttr("style", extractStylesFromObj(currentStyles));
3858
}
3959
if (component?.inputEl) {
4060
el = component.inputEl;
4161
}
42-
43-
component.onChange((newValue: string) => {
44-
value = newValue;
45-
dispatch("change", { value: newValue });
46-
});
4762
}
4863
</script>
4964

0 commit comments

Comments
 (0)