Skip to content

Commit

Permalink
cleanup memory leakes
Browse files Browse the repository at this point in the history
  • Loading branch information
huntabyte committed Apr 20, 2024
1 parent 6a23442 commit 649edb8
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { onDestroy, onMount, untrack } from "svelte";
import { untrack } from "svelte";
import type {
DismissableLayerProps,
InteractOutsideBehaviorType,
Expand Down Expand Up @@ -65,10 +65,6 @@ export class DismissableLayerState {
this.#interactOutsideProp = props.onInteractOutside;
this.#present = props.present;

$effect(() => {
console.log("present", this.#present.value);
});

$effect(() => {
this.#documentObj = getOwnerDocument(this.node.value);
});
Expand Down Expand Up @@ -107,7 +103,6 @@ export class DismissableLayerState {
}

#addEventListeners() {
console.log("adding event listeners");
return executeCallbacks(
/**
* CAPTURE INTERACTION START
Expand Down Expand Up @@ -160,7 +155,6 @@ export class DismissableLayerState {
}

#onInteractOutsideStart = debounce((e: InteractOutsideEvent) => {
console.log("onInteractOutsideStart");
if (!this.node.value) return;
if (
!this.#isResponsibleLayer ||
Expand All @@ -174,7 +168,6 @@ export class DismissableLayerState {
}, 10);

#onInteractOutside = debounce((e: InteractOutsideEvent) => {
console.log("onInteractOutside");
if (!this.node.value) return;

const behaviorType = this.#behaviorType.value;
Expand All @@ -191,23 +184,19 @@ export class DismissableLayerState {
}, 10);

#markInterceptedEvent = (e: HTMLElementEventMap[InteractOutsideInterceptEventType]) => {
console.log("markInterceptedEvent", e.type);
this.#interceptedEvents[e.type as InteractOutsideInterceptEventType] = true;
};

#markNonInterceptedEvent = (e: HTMLElementEventMap[InteractOutsideInterceptEventType]) => {
console.log("markNonInterceptedEvent", e.type);
this.#interceptedEvents[e.type as InteractOutsideInterceptEventType] = false;
};

#markResponsibleLayer = () => {
console.log("markResponsibleLayer");
if (!this.node.value) return;
this.#isResponsibleLayer = isResponsibleLayer(this.node.value);
};

#resetState = debounce(() => {
console.log("resetState");
for (const eventType in this.#interceptedEvents) {
this.#interceptedEvents[eventType as InteractOutsideInterceptEventType] = false;
}
Expand All @@ -216,7 +205,6 @@ export class DismissableLayerState {
}, 20);

#isAnyEventIntercepted() {
console.log("isAnyEventIntercepted");
return Object.values(this.#interceptedEvents).some(Boolean);
}
}
Expand All @@ -226,7 +214,6 @@ export function useDismissableLayer(props: DismissableLayerStateProps) {
}

function isResponsibleLayer(node: HTMLElement): boolean {
console.log("isResponsibleLayer");
const layersArr = [...layers];
/**
* We first check if we can find a top layer with `close` or `ignore`.
Expand All @@ -243,7 +230,6 @@ function isResponsibleLayer(node: HTMLElement): boolean {
}

function isValidEvent(e: InteractOutsideEvent, node: HTMLElement): boolean {
console.log("isValidEvent");
if ("button" in e && e.button > 0) return false;
const target = e.target;
if (!isElement(target)) return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { onDestroy } from "svelte";
import { untrack } from "svelte";
import type { EscapeBehaviorType, EscapeLayerProps } from "./types.js";
import type { ReadonlyBox, ReadonlyBoxedValues } from "$lib/internal/box.svelte.js";
import { type EventCallback, addEventListener } from "$lib/internal/events.js";
import { kbd } from "$lib/internal/kbd.js";
import { noop } from "$lib/internal/callbacks.js";

const layers = new Map<EscapeLayerState, ReadonlyBox<EscapeBehaviorType>>();

Expand All @@ -11,14 +12,23 @@ type EscapeLayerStateProps = ReadonlyBoxedValues<Required<Omit<EscapeLayerProps,
export class EscapeLayerState {
#onEscapeProp: ReadonlyBox<EventCallback<KeyboardEvent>>;
#behaviorType: ReadonlyBox<EscapeBehaviorType>;
#present: ReadonlyBox<boolean>;

constructor(props: EscapeLayerStateProps) {
this.#behaviorType = props.behaviorType;
this.#onEscapeProp = props.onEscape;
layers.set(this, this.#behaviorType);
this.#present = props.present;

$effect.root(() => {
const unsubEvents = this.#addEventListener();
let unsubEvents = noop;

$effect(() => {
if (this.#present.value) {
layers.set(
this,
untrack(() => this.#behaviorType)
);
unsubEvents = this.#addEventListener();
}

return () => {
unsubEvents();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { VirtualElement } from "@floating-ui/core";
import { getContext, setContext, untrack } from "svelte";
import {
type Middleware,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { onDestroy } from "svelte";
import { untrack } from "svelte";
import type { PreventTextSelectionOverflowLayerProps } from "./types.js";
import {
type Box,
Expand Down Expand Up @@ -26,18 +26,25 @@ export class PreventTextSelectionOverflowLayerState {
#enabled: ReadonlyBox<boolean>;
#unsubSelectionLock = noop;
#node: Box<HTMLElement | null>;
#present: ReadonlyBox<boolean>;

constructor(props: StateProps) {
this.#node = useNodeById(props.id);
this.#enabled = props.enabled;
this.#onPointerDownProp = props.onPointerDown;
this.#onPointerUpProp = props.onPointerUp;
this.#present = props.present;

layers.set(this, this.#enabled);

$effect.root(() => {
const unsubEvents = this.#addEventListeners();
let unsubEvents = noop;

$effect(() => {
if (this.#present.value) {
layers.set(
this,
untrack(() => this.#enabled)
);
unsubEvents = this.#addEventListeners();
}
return () => {
unsubEvents();
this.#resetSelectionLock();
Expand Down Expand Up @@ -102,6 +109,9 @@ function setUserSelect(node: HTMLElement, value: string) {
}

function isHighestLayer(instance: PreventTextSelectionOverflowLayerState) {
const [topLayer] = [...layers].at(-1)!;
return topLayer === instance;
const layersArr = [...layers];
if (!layersArr.length) return false;
const highestLayer = layersArr.at(-1);
if (!highestLayer) return false;
return highestLayer[0] === instance;
}

0 comments on commit 649edb8

Please sign in to comment.