{"version":3,"file":"track.mjs","sources":["../../../../../src/render/dom/scroll/track.ts"],"sourcesContent":["import { cancelFrame, frame, frameData, resize, Process } from \"motion-dom\"\nimport { noop } from \"motion-utils\"\nimport { createScrollInfo } from \"./info\"\nimport { createOnScrollHandler } from \"./on-scroll-handler\"\nimport { OnScrollHandler, OnScrollInfo, ScrollInfoOptions } from \"./types\"\n\nconst scrollListeners = new WeakMap<Element, VoidFunction>()\nconst resizeListeners = new WeakMap<Element, VoidFunction>()\nconst onScrollHandlers = new WeakMap<Element, Set<OnScrollHandler>>()\nconst scrollSize = new WeakMap<Element, { width: number; height: number }>()\nconst dimensionCheckProcesses = new WeakMap<Element, Process>()\n\nexport type ScrollTargets = Array<HTMLElement>\n\nconst getEventTarget = (element: Element) =>\n    element === document.scrollingElement ? window : element\n\nexport function scrollInfo(\n    onScroll: OnScrollInfo,\n    {\n        container = document.scrollingElement as Element,\n        trackContentSize = false,\n        ...options\n    }: ScrollInfoOptions = {}\n) {\n    if (!container) return noop as VoidFunction\n\n    let containerHandlers = onScrollHandlers.get(container)\n\n    /**\n     * Get the onScroll handlers for this container.\n     * If one isn't found, create a new one.\n     */\n    if (!containerHandlers) {\n        containerHandlers = new Set()\n        onScrollHandlers.set(container, containerHandlers)\n    }\n\n    /**\n     * Create a new onScroll handler for the provided callback.\n     */\n    const info = createScrollInfo()\n    const containerHandler = createOnScrollHandler(\n        container,\n        onScroll,\n        info,\n        options\n    )\n    containerHandlers.add(containerHandler)\n\n    /**\n     * Check if there's a scroll event listener for this container.\n     * If not, create one.\n     */\n    if (!scrollListeners.has(container)) {\n        const measureAll = () => {\n            for (const handler of containerHandlers) {\n                handler.measure(frameData.timestamp)\n            }\n\n            frame.preUpdate(notifyAll)\n        }\n\n        const notifyAll = () => {\n            for (const handler of containerHandlers) {\n                handler.notify()\n            }\n        }\n\n        const listener = () => frame.read(measureAll)\n\n        scrollListeners.set(container, listener)\n\n        const target = getEventTarget(container)\n        window.addEventListener(\"resize\", listener)\n        if (container !== document.documentElement) {\n            resizeListeners.set(container, resize(container, listener))\n        }\n\n        target.addEventListener(\"scroll\", listener)\n\n        listener()\n    }\n\n    /**\n     * Enable content size tracking if requested and not already enabled.\n     */\n    if (trackContentSize && !dimensionCheckProcesses.has(container)) {\n        const listener = scrollListeners.get(container)!\n\n        // Store initial scroll dimensions (object is reused to avoid allocation)\n        const size = {\n            width: container.scrollWidth,\n            height: container.scrollHeight,\n        }\n        scrollSize.set(container, size)\n\n        // Add frame-based scroll dimension checking to detect content changes\n        const checkScrollDimensions: Process = () => {\n            const newWidth = container.scrollWidth\n            const newHeight = container.scrollHeight\n\n            if (size.width !== newWidth || size.height !== newHeight) {\n                listener()\n                size.width = newWidth\n                size.height = newHeight\n            }\n        }\n\n        // Schedule with keepAlive=true to run every frame\n        const dimensionCheckProcess = frame.read(checkScrollDimensions, true)\n        dimensionCheckProcesses.set(container, dimensionCheckProcess)\n    }\n\n    const listener = scrollListeners.get(container)!\n    frame.read(listener, false, true)\n\n    return () => {\n        cancelFrame(listener)\n\n        /**\n         * Check if we even have any handlers for this container.\n         */\n        const currentHandlers = onScrollHandlers.get(container)\n        if (!currentHandlers) return\n\n        currentHandlers.delete(containerHandler)\n\n        if (currentHandlers.size) return\n\n        /**\n         * If no more handlers, remove the scroll listener too.\n         */\n        const scrollListener = scrollListeners.get(container)\n        scrollListeners.delete(container)\n\n        if (scrollListener) {\n            getEventTarget(container).removeEventListener(\n                \"scroll\",\n                scrollListener\n            )\n            resizeListeners.get(container)?.()\n            window.removeEventListener(\"resize\", scrollListener)\n        }\n\n        // Clean up scroll dimension checking\n        const dimensionCheckProcess = dimensionCheckProcesses.get(container)\n        if (dimensionCheckProcess) {\n            cancelFrame(dimensionCheckProcess)\n            dimensionCheckProcesses.delete(container)\n        }\n        scrollSize.delete(container)\n    }\n}\n"],"names":[],"mappings":"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"}