From 8e11eb31a307f34c5188b32b8b60f081ae250459 Mon Sep 17 00:00:00 2001 From: "Shypila, Yauheni (EPAM Systems)" Date: Fri, 3 Mar 2023 15:58:23 +0300 Subject: [PATCH 1/2] fix --- src/lib/actions/tooltip/tooltip.ts | 58 +++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/src/lib/actions/tooltip/tooltip.ts b/src/lib/actions/tooltip/tooltip.ts index b920267..b9eaf1e 100644 --- a/src/lib/actions/tooltip/tooltip.ts +++ b/src/lib/actions/tooltip/tooltip.ts @@ -82,13 +82,20 @@ export function tooltip(node: HTMLElement, parameters: TooltipParameters = defau for await (const entry of entries) { if (entry.isIntersecting) { is_intersecting_viewport = true; + addHoverListeners(node); + // const{visibile, keep_visible}= get(tooltip_parameters) + // if() await initializeTooltipPosition(); } else { + removeHoverListeners(node) is_intersecting_viewport = false; } } }); + addIntersectionObserver(node); + + // Create a resize observer for the parent element if it's box size changes const resize_observer = new ResizeObserver(async (entries) => { for await (const entry of entries) { @@ -120,20 +127,47 @@ export function tooltip(node: HTMLElement, parameters: TooltipParameters = defau } /** Add event listeners and observers to the parent element, window, or document */ - async function addEventListeners(node: HTMLElement) { + function addIntersectionObserver(node: HTMLElement) { if (browser && node) { intersection_observer.observe(node); + } + } + + function addScrollResizeListeners(node: HTMLElement) { + if (browser && node) { resize_observer.observe(node); - node.addEventListener('mouseenter', mouseEnter); - node.addEventListener('mouseleave', mouseLeave); - node.addEventListener('mousemove', mouseMove); window.addEventListener('resize', resize); - node.addEventListener('resize', resize); document.addEventListener('scroll', scroll); } } - addEventListeners(node); + function addHoverListeners(node: HTMLElement) { + if (browser && node) { + node.addEventListener('mouseenter', mouseEnter); + node.addEventListener('mouseleave', mouseLeave); + } + } + + function removeIntersectionObserver(node: HTMLElement) { + if (browser && node) { + intersection_observer.observe(node); + } + } + + function removeScrollResizeListeners(node: HTMLElement) { + if (browser && node) { + resize_observer.observe(node); + window.removeEventListener('resize', resize); + document.removeEventListener('scroll', scroll); + } + } + + function removeHoverListeners(node: HTMLElement) { + if (browser && node) { + node.removeEventListener('mouseenter', mouseEnter); + node.removeEventListener('mouseleave', mouseLeave); + } + } // Prune away the unneeded params before passing/setting the tooltip parameters (avoids warning msg in console) let new_tooltip_parameters = getParametersForNewTooltip(); @@ -533,15 +567,6 @@ export function tooltip(node: HTMLElement, parameters: TooltipParameters = defau // Add the event listeners to the new node await addEventListeners(node); } - async function removeEventListeners(node: HTMLElement) { - node.removeEventListener('mouseenter', mouseEnter); - node.removeEventListener('mouseleave', mouseLeave); - node.removeEventListener('mousemove', mouseMove); - window.removeEventListener('resize', resize); - document.removeEventListener('scroll', scroll); - resize_observer.unobserve(node); - intersection_observer.unobserve(node); - } // FIXME: tooltip updates on scroll while not visible! return { @@ -549,8 +574,7 @@ export function tooltip(node: HTMLElement, parameters: TooltipParameters = defau updater(new_parameters); }, async destroy() { - await removeEventListeners(node); - resize_observer.disconnect(); + intersection_observer && removeHoverListeners(node) tooltip.$destroy(); }, async goToNextNode(next_index: number, next_delay = delay) { From 7347854f3b3d0904407caf563c18190e0df0f07c Mon Sep 17 00:00:00 2001 From: "Shypila, Yauheni (EPAM Systems)" Date: Fri, 3 Mar 2023 17:39:49 +0300 Subject: [PATCH 2/2] separate listeners --- src/lib/actions/tooltip/tooltip.ts | 54 +++++++++++++++++++----------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/lib/actions/tooltip/tooltip.ts b/src/lib/actions/tooltip/tooltip.ts index b9eaf1e..1a1c584 100644 --- a/src/lib/actions/tooltip/tooltip.ts +++ b/src/lib/actions/tooltip/tooltip.ts @@ -83,18 +83,20 @@ export function tooltip(node: HTMLElement, parameters: TooltipParameters = defau if (entry.isIntersecting) { is_intersecting_viewport = true; addHoverListeners(node); - // const{visibile, keep_visible}= get(tooltip_parameters) - // if() - await initializeTooltipPosition(); + const { visible, keep_visible } = get(tooltip_parameters); + if (visible || keep_visible) { + await initializeTooltipPosition(); + addScrollResizeListeners(node); + } } else { - removeHoverListeners(node) + removeHoverListeners(node); + removeScrollResizeListeners(node); is_intersecting_viewport = false; } } }); addIntersectionObserver(node); - // Create a resize observer for the parent element if it's box size changes const resize_observer = new ResizeObserver(async (entries) => { @@ -211,24 +213,18 @@ export function tooltip(node: HTMLElement, parameters: TooltipParameters = defau }, delay); } - // If the tooltip is made visibile immediately upon mounting, allow a delay before triggering that visibility. + // If the tooltip is made visible immediately upon mounting, allow a delay before triggering that visibility. if (visible && is_intersecting_viewport) { changeVisiblityAfterDelay({ visibility: true, delay: max_delay }); } async function mouseEnter(event?: MouseEvent) { - // Check if the anchor element has moved since mounting - const { top, left } = node.getBoundingClientRect(); - if (top !== anchor_top || left !== anchor_left) { - anchor_top = top; - anchor_left = left; - initializeTooltipPosition(); - } - const { in_delay, disabled, delay } = get(tooltip_parameters); // If not left-clicking while entering the element's box (i.e. dragging)... if (event?.buttons !== 1 && disabled !== true) { + initializeTooltipPosition(); + addScrollResizeListeners(node); // Remember the existing title attribute and set the title store to it can react to changes await storeTitle(); @@ -322,8 +318,10 @@ export function tooltip(node: HTMLElement, parameters: TooltipParameters = defau async function mouseLeave(event: MouseEvent) { // If the left mouse button isn't being pressed... if (event.buttons !== 1 && tooltip && node) { - const { delay, out_delay } = get(tooltip_parameters); - + const { delay, out_delay, visible, keep_visible } = get(tooltip_parameters); + if (!visible && !keep_visible) { + removeScrollResizeListeners(node); + } await changeVisiblityAfterDelay({ visibility: false, delay: out_delay ?? delay ?? 0 }); // Restore the `title` attribute @@ -556,16 +554,32 @@ export function tooltip(node: HTMLElement, parameters: TooltipParameters = defau await initializeTooltipPosition(); } + const { visible, keep_visible } = get(tooltip_parameters); + if (visible || keep_visible) { + await initializeTooltipPosition(); + addScrollResizeListeners(node); + } else { + removeScrollResizeListeners(node); + } + tooltip.$set({ ...new_parameters }); } } async function reassignNode(new_node: HTMLElement) { // Remove the event listeners from the current node - await removeEventListeners(node); + removeHoverListeners(node); + removeIntersectionObserver(node); + removeScrollResizeListeners(node); // Set the node to the next node in the steps array node = new_node; // Add the event listeners to the new node - await addEventListeners(node); + addIntersectionObserver(node); + is_intersecting_viewport && addHoverListeners(node); + const { visible, keep_visible } = get(tooltip_parameters); + if (visible || keep_visible) { + await initializeTooltipPosition(); + addScrollResizeListeners(node); + } } // FIXME: tooltip updates on scroll while not visible! @@ -574,7 +588,9 @@ export function tooltip(node: HTMLElement, parameters: TooltipParameters = defau updater(new_parameters); }, async destroy() { - intersection_observer && removeHoverListeners(node) + removeHoverListeners(node); + removeIntersectionObserver(node); + removeScrollResizeListeners(node); tooltip.$destroy(); }, async goToNextNode(next_index: number, next_delay = delay) {