diff --git a/package.json b/package.json index 20de183..78aa4bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-atom-trigger", - "version": "2.0.6", + "version": "2.0.7", "description": "Geometry-based scroll trigger for React with precise enter/leave control. A modern alternative to react-waypoint.", "keywords": [ "intersection", diff --git a/src/AtomTrigger.observation.ts b/src/AtomTrigger.observation.ts index 13e0642..9154211 100644 --- a/src/AtomTrigger.observation.ts +++ b/src/AtomTrigger.observation.ts @@ -44,18 +44,6 @@ function createRegistration( }; } -function applyObservationConfig( - registration: SentinelRegistration, - config: ObservationConfig, -): void { - registration.node = config.node; - registration.rootMargin = config.rootMargin; - registration.threshold = config.threshold; - registration.once = config.once; - registration.oncePerDirection = config.oncePerDirection; - registration.fireOnInitialVisible = config.fireOnInitialVisible; -} - function applyObservationCallbacks( registration: SentinelRegistration, callbacks: ObservationCallbacks, @@ -71,40 +59,6 @@ function clearObservationBinding(controller: ObservationController): void { controller.binding = null; } -function createObservationConfig(input: { - node: Element; - rootMargin: string; - threshold: number; - once: boolean; - oncePerDirection: boolean; - fireOnInitialVisible: boolean; -}): ObservationConfig { - return { - node: input.node, - rootMargin: input.rootMargin, - threshold: input.threshold, - once: input.once, - oncePerDirection: input.oncePerDirection, - fireOnInitialVisible: input.fireOnInitialVisible, - }; -} - -function bindingsMatch( - previousBinding: ObservationBinding | null, - nextBinding: ObservationBinding, -): boolean { - return Boolean( - previousBinding && - previousBinding.node === nextBinding.node && - previousBinding.target === nextBinding.target && - previousBinding.rootMargin === nextBinding.rootMargin && - previousBinding.threshold === nextBinding.threshold && - previousBinding.once === nextBinding.once && - previousBinding.oncePerDirection === nextBinding.oncePerDirection && - previousBinding.fireOnInitialVisible === nextBinding.fireOnInitialVisible, - ); -} - export function createObservationController( config: ObservationConfig, callbacks: ObservationCallbacks, @@ -144,18 +98,18 @@ export function reconcileObservationBinding( return; } - const nextConfig = createObservationConfig({ + const nextConfig: ObservationConfig = { node: input.node, rootMargin: input.rootMargin, threshold: input.threshold, once: input.once, oncePerDirection: input.oncePerDirection, fireOnInitialVisible: input.fireOnInitialVisible, - }); + }; if (input.disabled || !input.target) { clearObservationBinding(controller); - applyObservationConfig(registration, nextConfig); + Object.assign(registration, nextConfig); resetObservationState(registration); return; } @@ -165,14 +119,24 @@ export function reconcileObservationBinding( target: input.target, }; - if (bindingsMatch(controller.binding, nextBinding)) { - applyObservationConfig(registration, nextConfig); + const bindingUnchanged = + controller.binding !== null && + controller.binding.node === nextBinding.node && + controller.binding.target === nextBinding.target && + controller.binding.rootMargin === nextBinding.rootMargin && + controller.binding.threshold === nextBinding.threshold && + controller.binding.once === nextBinding.once && + controller.binding.oncePerDirection === nextBinding.oncePerDirection && + controller.binding.fireOnInitialVisible === nextBinding.fireOnInitialVisible; + + if (bindingUnchanged) { + Object.assign(registration, nextConfig); return; } resetObservationState(registration); clearObservationBinding(controller); - applyObservationConfig(registration, nextConfig); + Object.assign(registration, nextConfig); controller.dispose = registerSentinel(input.target, registration); controller.binding = nextBinding; } diff --git a/src/AtomTrigger.scheduler.ts b/src/AtomTrigger.scheduler.ts index aa57b4b..1ca6568 100644 --- a/src/AtomTrigger.scheduler.ts +++ b/src/AtomTrigger.scheduler.ts @@ -99,15 +99,10 @@ function createRootScheduler(target: SchedulerTarget): RootScheduler { return; } - scheduler.rafId = -1; - const nextFrameId = window.requestAnimationFrame(() => { + scheduler.rafId = window.requestAnimationFrame(() => { scheduler.rafId = 0; flushSamples(); }); - - if (scheduler.rafId === -1) { - scheduler.rafId = nextFrameId; - } }; const handleScroll = () => { diff --git a/src/testUtils/domEnvironment.ts b/src/testUtils/domEnvironment.ts index 7260840..cd6715e 100644 --- a/src/testUtils/domEnvironment.ts +++ b/src/testUtils/domEnvironment.ts @@ -2,7 +2,6 @@ import { cleanup, fireEvent } from '@testing-library/react'; import { vi } from 'vitest'; import { __resetWarningsForTests } from '../AtomTrigger.warnings'; -let animationFrameId = 0; let activeScrollTop = 0; let activeScrollLeft = 0; const initialNodeEnv = process.env.NODE_ENV; @@ -96,14 +95,12 @@ export function setWindowSize(width: number, height: number): void { export function prepareDomTestRun(): void { setActiveScrollPosition(0, 0); - animationFrameId = 0; setWindowScroll(0, 0); setWindowSize(1024, 768); vi.stubGlobal('requestAnimationFrame', (callback: FrameRequestCallback) => { callback(performance.now()); - animationFrameId += 1; - return animationFrameId; + return 0; }); vi.stubGlobal('cancelAnimationFrame', vi.fn()); }