From 7ccede67bf92e0f168fd48eab248020426e12798 Mon Sep 17 00:00:00 2001 From: Vildan Softic Date: Fri, 7 Feb 2025 15:27:22 +0100 Subject: [PATCH] fix: add an explicit check to bound element to work around monkey patching issues (#1839) #1835 --- .../src/__tests__/bindingEvent.service.spec.ts | 15 +++++++++++++++ packages/binding/src/bindingEvent.service.ts | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/binding/src/__tests__/bindingEvent.service.spec.ts b/packages/binding/src/__tests__/bindingEvent.service.spec.ts index ba617f3ea..aa6da1346 100644 --- a/packages/binding/src/__tests__/bindingEvent.service.spec.ts +++ b/packages/binding/src/__tests__/bindingEvent.service.spec.ts @@ -32,6 +32,21 @@ describe('BindingEvent Service', () => { expect(addEventSpy).toHaveBeenCalledWith('click', mockCallback, undefined); }); + it('should not use forEach if the element is a single HTMLElement but with a monkey patched forEach', () => { + const elm = document.createElement('input'); + div.appendChild(elm); + const forEachSpy = vi.fn(); + (elm as any).forEach = forEachSpy; + const mockCallback = vi.fn(); + const addEventSpy = vi.spyOn(elm, 'addEventListener'); + + service.bind(elm, 'click', mockCallback); + + expect(service.boundedEvents.length).toBe(1); + expect(addEventSpy).toHaveBeenCalledWith('click', mockCallback, undefined); + expect(forEachSpy).not.toHaveBeenCalled(); + }); + it('should be able to bind and unbindByEventName an event', () => { const mockElm = { addEventListener: vi.fn() } as unknown as HTMLElement; const mockCallback = vi.fn(); diff --git a/packages/binding/src/bindingEvent.service.ts b/packages/binding/src/bindingEvent.service.ts index 0ddcdc69e..73f387702 100644 --- a/packages/binding/src/bindingEvent.service.ts +++ b/packages/binding/src/bindingEvent.service.ts @@ -28,7 +28,10 @@ export class BindingEventService { // convert to array for looping in next task const eventNames = Array.isArray(eventNameOrNames) ? eventNameOrNames : [eventNameOrNames]; - if ((elementOrElements as NodeListOf)?.forEach) { + if ( + !(elementOrElements instanceof HTMLElement || elementOrElements instanceof DocumentFragment) && + (elementOrElements as NodeListOf)?.forEach + ) { // multiple elements to bind to (elementOrElements as NodeListOf).forEach((element) => { for (const eventName of eventNames) {