Skip to content

Commit

Permalink
Merge pull request #1435 from capricorn86/1397-regression-from-1362-t…
Browse files Browse the repository at this point in the history
…o-1370-clicking-a-checkbox-no-longer-fires-a-change-event

fix: [#1397] HTMLAnchorElement, HTMLButtonElement, HTMLInputElement a…
  • Loading branch information
capricorn86 committed May 13, 2024
2 parents 8ceadb3 + d8732e8 commit 5b527c2
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import NamedNodeMap from '../../named-node-map/NamedNodeMap.js';
import HTMLAnchorElementNamedNodeMap from './HTMLAnchorElementNamedNodeMap.js';
import Event from '../../event/Event.js';
import EventPhaseEnum from '../../event/EventPhaseEnum.js';
import PointerEvent from '../../event/events/PointerEvent.js';
import MouseEvent from '../../event/events/MouseEvent.js';

/**
* HTML Anchor Element.
Expand Down Expand Up @@ -499,7 +499,7 @@ export default class HTMLAnchorElement extends HTMLElement implements IHTMLHyper

if (
event.type === 'click' &&
event instanceof PointerEvent &&
event instanceof MouseEvent &&
(event.eventPhase === EventPhaseEnum.atTarget ||
event.eventPhase === EventPhaseEnum.bubbling) &&
!event.defaultPrevented
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import HTMLLabelElement from '../html-label-element/HTMLLabelElement.js';
import Node from '../node/Node.js';
import NodeList from '../node/NodeList.js';
import HTMLButtonElementNamedNodeMap from './HTMLButtonElementNamedNodeMap.js';
import PointerEvent from '../../event/events/PointerEvent.js';
import { URL } from 'url';
import MouseEvent from '../../event/events/MouseEvent.js';

const BUTTON_TYPES = ['submit', 'reset', 'button', 'menu'];

Expand Down Expand Up @@ -295,7 +295,7 @@ export default class HTMLButtonElement extends HTMLElement {
public override dispatchEvent(event: Event): boolean {
if (
event.type === 'click' &&
event instanceof PointerEvent &&
event instanceof MouseEvent &&
event.eventPhase === EventPhaseEnum.none &&
this.disabled
) {
Expand All @@ -306,7 +306,7 @@ export default class HTMLButtonElement extends HTMLElement {

if (
event.type === 'click' &&
event instanceof PointerEvent &&
event instanceof MouseEvent &&
(event.eventPhase === EventPhaseEnum.atTarget ||
event.eventPhase === EventPhaseEnum.bubbling) &&
this[PropertySymbol.isConnected]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import HTMLInputElementDateUtility from './HTMLInputElementDateUtility.js';
import HTMLLabelElementUtility from '../html-label-element/HTMLLabelElementUtility.js';
import NamedNodeMap from '../../named-node-map/NamedNodeMap.js';
import HTMLInputElementNamedNodeMap from './HTMLInputElementNamedNodeMap.js';
import PointerEvent from '../../event/events/PointerEvent.js';
import { URL } from 'url';
import MouseEvent from '../../event/events/MouseEvent.js';

/**
* HTML Input Element.
Expand Down Expand Up @@ -1305,7 +1305,7 @@ export default class HTMLInputElement extends HTMLElement {
// Do nothing if the input element is disabled and the event is a click event.
if (
event.type === 'click' &&
event instanceof PointerEvent &&
event instanceof MouseEvent &&
event.eventPhase === EventPhaseEnum.none &&
this.disabled
) {
Expand All @@ -1320,7 +1320,7 @@ export default class HTMLInputElement extends HTMLElement {
(event.eventPhase === EventPhaseEnum.atTarget ||
event.eventPhase === EventPhaseEnum.bubbling) &&
event.type === 'click' &&
event instanceof PointerEvent
event instanceof MouseEvent
) {
const inputType = this.type;
if (inputType === 'checkbox' || inputType === 'radio') {
Expand All @@ -1336,7 +1336,7 @@ export default class HTMLInputElement extends HTMLElement {
(event.eventPhase === EventPhaseEnum.atTarget ||
event.eventPhase === EventPhaseEnum.bubbling) &&
event.type === 'click' &&
event instanceof PointerEvent &&
event instanceof MouseEvent &&
this[PropertySymbol.isConnected]
) {
const inputType = this.type;
Expand Down Expand Up @@ -1364,7 +1364,7 @@ export default class HTMLInputElement extends HTMLElement {
(event.eventPhase === EventPhaseEnum.atTarget ||
event.eventPhase === EventPhaseEnum.bubbling) &&
event.type === 'click' &&
event instanceof PointerEvent &&
event instanceof MouseEvent &&
previousCheckedValue !== null
) {
const inputType = this.type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as PropertySymbol from '../../PropertySymbol.js';
import HTMLFormElement from '../html-form-element/HTMLFormElement.js';
import Event from '../../event/Event.js';
import EventPhaseEnum from '../../event/EventPhaseEnum.js';
import PointerEvent from '../../event/events/PointerEvent.js';
import MouseEvent from '../../event/events/MouseEvent.js';

/**
* HTML Label Element.
Expand Down Expand Up @@ -77,12 +77,12 @@ export default class HTMLLabelElement extends HTMLElement {

if (
event.type === 'click' &&
event instanceof PointerEvent &&
event instanceof MouseEvent &&
(event.eventPhase === EventPhaseEnum.atTarget || event.eventPhase === EventPhaseEnum.bubbling)
) {
const control = this.control;
if (control && event.target !== control) {
control.dispatchEvent(new PointerEvent('click', { bubbles: true, cancelable: true }));
control.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Request from '../../../src/fetch/Request.js';
import Response from '../../../src/fetch/Response.js';
import Fetch from '../../../src/fetch/Fetch.js';
import Browser from '../../../src/browser/Browser.js';
import MouseEvent from '../../../src/event/events/MouseEvent.js';

describe('HTMLAnchorElement', () => {
let window: Window;
Expand Down Expand Up @@ -347,7 +348,7 @@ describe('HTMLAnchorElement', () => {
const element = <HTMLAnchorElement>window.document.createElement('a');
element.href = 'https://www.example.com';
window.document.body.appendChild(element);
element.dispatchEvent(new PointerEvent('click'));
element.dispatchEvent(new MouseEvent('click'));

const newWindow = page.mainFrame.window;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import HTMLElement from '../../../src/nodes/html-element/HTMLElement.js';
import HTMLFormElement from '../../../src/nodes/html-form-element/HTMLFormElement.js';
import ValidityState from '../../../src/validity-state/ValidityState.js';
import { beforeEach, afterEach, describe, it, expect } from 'vitest';
import MouseEvent from '../../../src/event/events/MouseEvent.js';
import PointerEvent from '../../../src/event/events/PointerEvent.js';

describe('HTMLButtonElement', () => {
let window: Window;
Expand Down Expand Up @@ -352,7 +354,7 @@ describe('HTMLButtonElement', () => {
submitter = (<SubmitEvent>event).submitter;
});

button.click();
button.dispatchEvent(new MouseEvent('click'));

expect(submitTriggeredCount).toBe(1);
expect(submitter).toBe(button);
Expand All @@ -376,7 +378,7 @@ describe('HTMLButtonElement', () => {
submitter = (<SubmitEvent>event).submitter;
});

button.click();
button.dispatchEvent(new PointerEvent('click'));

expect(submitTriggeredCount).toBe(1);
expect(submitter).toBe(button);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import DOMExceptionNameEnum from '../../../src/exception/DOMExceptionNameEnum.js
import SubmitEvent from '../../../src/event/events/SubmitEvent.js';
import { beforeEach, describe, it, expect } from 'vitest';
import PointerEvent from '../../../src/event/events/PointerEvent.js';
import MouseEvent from '../../../src/event/events/MouseEvent.js';

describe('HTMLInputElement', () => {
let window: Window;
Expand Down Expand Up @@ -1150,22 +1151,22 @@ describe('HTMLInputElement', () => {
element.addEventListener('change', () => (isChangeTriggered = true));

// "input" and "change" events should only be triggered if connected to DOM
element.dispatchEvent(new PointerEvent('click'));
element.dispatchEvent(new MouseEvent('click'));

expect(isInputTriggered).toBe(false);
expect(isChangeTriggered).toBe(false);
expect(element.checked).toBe(true);

document.body.appendChild(element);

element.dispatchEvent(new PointerEvent('click'));
element.dispatchEvent(new MouseEvent('click'));

// "input" and "change" events should now have been triggered as it is connected to DOM
expect(isInputTriggered).toBe(true);
expect(isChangeTriggered).toBe(true);
expect(element.checked).toBe(false);

element.dispatchEvent(new PointerEvent('click'));
element.dispatchEvent(new MouseEvent('click'));

expect(element.checked).toBe(true);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import HTMLLabelElement from '../../../src/nodes/html-label-element/HTMLLabelEle
import HTMLInputElement from '../../../src/nodes/html-input-element/HTMLInputElement.js';
import PointerEvent from '../../../src/event/events/PointerEvent.js';
import { beforeEach, describe, it, expect } from 'vitest';
import MouseEvent from '../../../src/event/events/MouseEvent.js';

describe('HTMLLabelElement', () => {
let window: Window;
Expand Down Expand Up @@ -103,5 +104,29 @@ describe('HTMLLabelElement', () => {
expect(labelClickCount).toBe(2);
expect(inputClickCount).toBe(1);
});

it('Supports MouseEvent.', () => {
const input = <HTMLInputElement>document.createElement('input');
const span = document.createElement('span');

input.type = 'checkbox';

span.appendChild(input);
element.appendChild(span);

let labelClickCount = 0;
let inputClickCount = 0;

element.addEventListener('click', () => labelClickCount++);
input.addEventListener('click', () => inputClickCount++);

expect(input.checked).toBe(false);

element.dispatchEvent(new MouseEvent('click'));

expect(input.checked).toBe(true);
expect(labelClickCount).toBe(2);
expect(inputClickCount).toBe(1);
});
});
});

0 comments on commit 5b527c2

Please sign in to comment.