Skip to content

Commit

Permalink
feat: [#1184] Adds support for form method 'dialog' (#1754)
Browse files Browse the repository at this point in the history
  • Loading branch information
karpiuMG authored Mar 7, 2025
1 parent a5424a8 commit e8b77d0
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default class HTMLDialogElement extends HTMLElement {
* @param value Return value.
*/
public set returnValue(value: string) {
this[PropertySymbol.returnValue] = value;
this[PropertySymbol.returnValue] = String(value);
}

/**
Expand Down Expand Up @@ -79,10 +79,10 @@ export default class HTMLDialogElement extends HTMLElement {
*
* @param [returnValue] ReturnValue.
*/
public close(returnValue = ''): void {
public close(returnValue?: string): void {
const wasOpen = this.open;
this.removeAttribute('open');
this.returnValue = returnValue;
this.returnValue = returnValue !== undefined ? String(returnValue) : '';
if (wasOpen) {
this.dispatchEvent(new Event('close'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import ClassMethodBinder from '../../utilities/ClassMethodBinder.js';
import Node from '../node/Node.js';
import Element from '../element/Element.js';
import EventTarget from '../../event/EventTarget.js';
import HTMLDialogElement from '../html-dialog-element/HTMLDialogElement.js';
import ElementEventAttributeUtility from '../element/ElementEventAttributeUtility.js';

/**
Expand Down Expand Up @@ -573,6 +574,26 @@ export default class HTMLFormElement extends HTMLElement {
* @param [submitter] Submitter.
*/
#submit(submitter?: HTMLInputElement | HTMLButtonElement): void {
const method = submitter?.formMethod || this.method;

if (method === 'dialog') {
let dialog: HTMLDialogElement | null = null;
let parent: Element = this;

while (parent) {
if (parent[PropertySymbol.tagName] === 'DIALOG') {
dialog = <HTMLDialogElement>parent;
break;
}
parent = parent.parentElement;
}

if (dialog) {
dialog.close(submitter?.value);
return;
}
}

const action = submitter?.hasAttribute('formaction')
? submitter?.formAction || this.action
: this.action;
Expand All @@ -589,7 +610,6 @@ export default class HTMLFormElement extends HTMLElement {
return;
}

const method = submitter?.formMethod || this.method;
const formData = new this[PropertySymbol.window].FormData(this);
let targetFrame: IBrowserFrame;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import HTMLDialogElement from '../../../src/nodes/html-dialog-element/HTMLDialog
import Window from '../../../src/window/Window.js';
import Document from '../../../src/nodes/document/Document.js';
import { beforeEach, describe, it, expect } from 'vitest';
import KeyboardEvent from '../../../src/event/events/KeyboardEvent.js';

describe('HTMLDialogElement', () => {
let window: Window;
Expand Down Expand Up @@ -83,6 +84,8 @@ describe('HTMLDialogElement', () => {
it('Should be possible to set manually', () => {
element.returnValue = 'foo';
expect(element.returnValue).toBe('foo');
element.returnValue = <string>(<unknown>undefined);
expect(element.returnValue).toBe('undefined');
});
});

Expand All @@ -105,6 +108,12 @@ describe('HTMLDialogElement', () => {
element.show();
element.close('foo');
expect(element.returnValue).toBe('foo');
element.show();
element.close(undefined);
expect(element.returnValue).toBe('');
element.show();
element.close(<string>(<unknown>null));
expect(element.returnValue).toBe('null');
});

it('Should be possible to close the modal dialog with a return value', () => {
Expand All @@ -122,7 +131,7 @@ describe('HTMLDialogElement', () => {
expect((<Event>(<unknown>dispatched)).bubbles).toBe(false);
});

it('Should only dispatch a close event when dialog wasnt already closed', () => {
it("Should only dispatch a close event when dialog wasn't already closed", () => {
let dispatched: Event | null = null;
element.addEventListener('close', (event: Event) => (dispatched = event));
element.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,46 @@ describe('HTMLFormElement', () => {

expect(page.mainFrame.url).toBe('about:blank#blocked');
});

it('Supports form method "dialog"', () => {
const container = document.body;
container.innerHTML = `<dialog>
<form method="dialog">
<input name="test123" value="">
<button value="buttonValue">Close</button>
</form>
</dialog>`;
const dialog = container.querySelector('dialog')!;
const form = dialog.querySelector('form')!;
const button = dialog.querySelector('button')!;
const input = dialog.querySelector('input')!;

input.value = 'test';

expect(dialog.returnValue).toBe('');
expect(dialog.open).toBe(false);

dialog.showModal();

expect(dialog.open).toBe(true);

let submitEvent: SubmitEvent | null = null;
dialog.addEventListener('submit', (event) => (submitEvent = <SubmitEvent>event));
button.click();
expect(dialog.open).toBe(false);
expect((<SubmitEvent>(<unknown>submitEvent)).submitter).toBe(button);
expect((<SubmitEvent>(<unknown>submitEvent)).target).toBe(form);
expect(dialog.returnValue).toBe('buttonValue');

dialog.showModal();
expect(dialog.open).toBe(true);

form.submit();
expect(dialog.open).toBe(false);
expect(dialog.returnValue).toBe('');

expect(input.value).toBe('test');
});
});

describe('requestSubmit()', () => {
Expand Down

0 comments on commit e8b77d0

Please sign in to comment.