readonly #cache: SharedCache;
#container: HTMLElement | undefined = undefined;
#enabled = true;
+ readonly #element: HTMLElement;
readonly #identifier: string;
- #pendingObjectId: number | undefined = undefined;
- #timerStart: RepeatingTimer | undefined = undefined;
+ #timerShouldShow: RepeatingTimer | undefined = undefined;
#timerHide: RepeatingTimer | undefined = undefined;
- constructor(cache: SharedCache, selector: string, identifier: string) {
+ constructor(cache: SharedCache, element: HTMLElement, identifier: string) {
this.#cache = cache;
+ this.#element = element;
this.#identifier = identifier;
- wheneverFirstSeen(selector, (element) => {
- element.addEventListener("mouseenter", () => {
- this.#showPopover(element);
- });
- element.addEventListener("mouseleave", () => {
- this.#hidePopover();
- });
+ element.addEventListener("mouseenter", () => {
+ this.#showPopover();
+ });
+ element.addEventListener("mouseleave", () => {
+ this.#hidePopover();
});
const mq = window.matchMedia("(hover:hover)");
window.addEventListener("beforeunload", () => {
this.#setEnabled(false);
});
+
+ this.#showPopover();
}
- #showPopover(element: HTMLElement): void {
- const objectId = this.#getObjectId(element);
+ #showPopover(): void {
+ this.#timerHide?.stop();
- this.#pendingObjectId = objectId;
- if (this.#timerStart === undefined) {
- this.#timerStart = new RepeatingTimer((timer) => {
+ if (this.#timerShouldShow === undefined) {
+ this.#timerShouldShow = new RepeatingTimer((timer) => {
timer.stop();
- const objectId = this.#pendingObjectId!;
+ const objectId = this.#getObjectId();
void this.#cache.get(objectId).then((content) => {
- if (objectId !== this.#pendingObjectId) {
- return;
- }
-
const container = this.#getContainer();
DomUtil.setInnerHtml(container, content);
- UiAlignment.set(container, element, { vertical: "top" });
+ UiAlignment.set(container, this.#element, { vertical: "top" });
container.setAttribute("aria-hidden", "false");
});
}, Delay.Show);
} else {
- this.#timerStart.restart();
+ this.#timerShouldShow.restart();
}
}
#hidePopover(): void {
+ this.#timerShouldShow?.stop();
+
if (this.#timerHide === undefined) {
this.#timerHide = new RepeatingTimer((timer) => {
timer.stop();
- this.#timerStart?.stop();
this.#container?.setAttribute("aria-hidden", "true");
}, Delay.Hide);
} else {
this.#enabled = enabled;
}
- #getObjectId(element: HTMLElement): number {
- return parseInt(element.dataset.objectId!);
+ #getObjectId(): number {
+ return parseInt(this.#element.dataset.objectId!);
}
#getContainer(): HTMLElement {
this.#container.classList.add("popoverContainer");
this.#container.dataset.identifier = this.#identifier;
this.#container.setAttribute("aria-hidden", "true");
+
+ this.#container.addEventListener("transitionend", () => {
+ if (this.#container!.getAttribute("aria-hidden") === "true") {
+ this.#container!.remove();
+ }
+ });
}
- this.#container.remove();
- getPageOverlayContainer().append(this.#container);
+ if (this.#container.parentNode === null) {
+ getPageOverlayContainer().append(this.#container);
+ }
return this.#container;
}
const cache = new SharedCache(endpoint);
- new Popover(cache, selector, identifier);
+ wheneverFirstSeen(selector, (element) => {
+ element.addEventListener(
+ "mouseenter",
+ () => {
+ new Popover(cache, element, identifier);
+ },
+ { once: true },
+ );
+ });
}
#cache;
#container = undefined;
#enabled = true;
+ #element;
#identifier;
- #pendingObjectId = undefined;
- #timerStart = undefined;
+ #timerShouldShow = undefined;
#timerHide = undefined;
- constructor(cache, selector, identifier) {
+ constructor(cache, element, identifier) {
this.#cache = cache;
+ this.#element = element;
this.#identifier = identifier;
- (0, Selector_1.wheneverFirstSeen)(selector, (element) => {
- element.addEventListener("mouseenter", () => {
- this.#showPopover(element);
- });
- element.addEventListener("mouseleave", () => {
- this.#hidePopover();
- });
+ element.addEventListener("mouseenter", () => {
+ this.#showPopover();
+ });
+ element.addEventListener("mouseleave", () => {
+ this.#hidePopover();
});
const mq = window.matchMedia("(hover:hover)");
this.#setEnabled(mq.matches);
window.addEventListener("beforeunload", () => {
this.#setEnabled(false);
});
+ this.#showPopover();
}
- #showPopover(element) {
- const objectId = this.#getObjectId(element);
- this.#pendingObjectId = objectId;
- if (this.#timerStart === undefined) {
- this.#timerStart = new Repeating_1.default((timer) => {
+ #showPopover() {
+ this.#timerHide?.stop();
+ if (this.#timerShouldShow === undefined) {
+ this.#timerShouldShow = new Repeating_1.default((timer) => {
timer.stop();
- const objectId = this.#pendingObjectId;
+ const objectId = this.#getObjectId();
void this.#cache.get(objectId).then((content) => {
- if (objectId !== this.#pendingObjectId) {
- return;
- }
const container = this.#getContainer();
Util_1.default.setInnerHtml(container, content);
- UiAlignment.set(container, element, { vertical: "top" });
+ UiAlignment.set(container, this.#element, { vertical: "top" });
container.setAttribute("aria-hidden", "false");
});
}, 800 /* Delay.Show */);
}
else {
- this.#timerStart.restart();
+ this.#timerShouldShow.restart();
}
}
#hidePopover() {
+ this.#timerShouldShow?.stop();
if (this.#timerHide === undefined) {
this.#timerHide = new Repeating_1.default((timer) => {
timer.stop();
- this.#timerStart?.stop();
this.#container?.setAttribute("aria-hidden", "true");
}, 500 /* Delay.Hide */);
}
#setEnabled(enabled) {
this.#enabled = enabled;
}
- #getObjectId(element) {
- return parseInt(element.dataset.objectId);
+ #getObjectId() {
+ return parseInt(this.#element.dataset.objectId);
}
#getContainer() {
if (this.#container === undefined) {
this.#container.classList.add("popoverContainer");
this.#container.dataset.identifier = this.#identifier;
this.#container.setAttribute("aria-hidden", "true");
+ this.#container.addEventListener("transitionend", () => {
+ if (this.#container.getAttribute("aria-hidden") === "true") {
+ this.#container.remove();
+ }
+ });
+ }
+ if (this.#container.parentNode === null) {
+ (0, PageOverlay_1.getPageOverlayContainer)().append(this.#container);
}
- this.#container.remove();
- (0, PageOverlay_1.getPageOverlayContainer)().append(this.#container);
return this.#container;
}
}
function setupFor(configuration) {
const { identifier, endpoint, selector } = configuration;
const cache = new SharedCache_1.default(endpoint);
- new Popover(cache, selector, identifier);
+ (0, Selector_1.wheneverFirstSeen)(selector, (element) => {
+ element.addEventListener("mouseenter", () => {
+ new Popover(cache, element, identifier);
+ }, { once: true });
+ });
}
exports.setupFor = setupFor;
});