Skip to content

Commit 73a3672

Browse files
authored
fix: [#1614] Fixes issue where change event wasn't triggered for an input inside of a label (#1743)
* fix: [#1605] Fixes issue when using filtering in TreeWalker, which caused it not to work according to spec * fix: [#1605] Fixes issue when using filtering in TreeWalker, which caused it not to work according to spec * chore: [#1614] Fixes issue where input change event wasnt triggered when clicking on an element inside of a label * chore: [#1614] Fixes issue where input change event wasnt triggered when clicking on an element inside of a label
1 parent baaeeb9 commit 73a3672

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

packages/happy-dom/src/nodes/html-label-element/HTMLLabelElement.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ export default class HTMLLabelElement extends HTMLElement {
113113
if (
114114
!event[PropertySymbol.defaultPrevented] &&
115115
event.type === 'click' &&
116-
event.eventPhase === EventPhaseEnum.none &&
116+
(event.eventPhase === EventPhaseEnum.atTarget ||
117+
event.eventPhase === EventPhaseEnum.bubbling) &&
117118
event instanceof MouseEvent
118119
) {
119120
const control = this.control;

packages/happy-dom/test/nodes/html-label-element/HTMLLabelElement.test.ts

+39-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import Window from '../../../src/window/Window.js';
22
import Document from '../../../src/nodes/document/Document.js';
33
import HTMLLabelElement from '../../../src/nodes/html-label-element/HTMLLabelElement.js';
44
import HTMLInputElement from '../../../src/nodes/html-input-element/HTMLInputElement.js';
5-
import PointerEvent from '../../../src/event/events/PointerEvent.js';
65
import { beforeEach, describe, it, expect } from 'vitest';
76
import MouseEvent from '../../../src/event/events/MouseEvent.js';
87

@@ -171,5 +170,44 @@ describe('HTMLLabelElement', () => {
171170
expect(input.checked).toBe(false);
172171
expect(inputClickCount).toBe(0);
173172
});
173+
174+
it('It triggers "change" event on the control element when clicking on a span inside the label.', () => {
175+
const div = document.createElement('div');
176+
div.innerHTML = `
177+
<label>
178+
<input type="checkbox">
179+
<span>Description</span>
180+
</label>
181+
`;
182+
let isChangeFired = false;
183+
184+
document.body.appendChild(div);
185+
186+
div.querySelector('input')?.addEventListener('change', () => (isChangeFired = true));
187+
188+
div.querySelector('span')?.click();
189+
190+
expect(isChangeFired).toBe(true);
191+
});
192+
193+
it('Doesn\'t trigger "change" event a second time when clicking on control element inside of a label.', () => {
194+
const div = document.createElement('div');
195+
div.innerHTML = `
196+
<label>
197+
<input type="checkbox">
198+
<span>Description</span>
199+
</label>
200+
`;
201+
let changeFiredCount = 0;
202+
203+
document.body.appendChild(div);
204+
205+
div.querySelector('input')?.addEventListener('change', () => changeFiredCount++);
206+
207+
div.querySelector('input')?.click();
208+
209+
expect(changeFiredCount).toBe(1);
210+
expect(div.querySelector('input')?.checked).toBe(true);
211+
});
174212
});
175213
});

0 commit comments

Comments
 (0)