Skip to content

Commit

Permalink
#517@minor: Implement dialog element.
Browse files Browse the repository at this point in the history
  • Loading branch information
markgaze committed Jun 24, 2022
1 parent f9d55eb commit 925ddad
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packages/happy-dom/src/config/ElementTag.ts
Expand Up @@ -16,6 +16,7 @@ import HTMLBaseElement from '../nodes/html-base-element/HTMLBaseElement';
import HTMLSelectElement from '../nodes/html-select-element/HTMLSelectElement';
import HTMLOptionElement from '../nodes/html-option-element/HTMLOptionElement';
import HTMLOptGroupElement from '../nodes/html-opt-group-element/HTMLOptGroupElement';
import HTMLDialogElement from '../nodes/html-dialog-element/HTMLDialogElement';

export default {
A: HTMLElement,
Expand Down Expand Up @@ -67,7 +68,7 @@ export default {
DEL: HTMLElement,
DETAILS: HTMLElement,
DFN: HTMLElement,
DIALOG: HTMLElement,
DIALOG: HTMLDialogElement,
DIV: HTMLElement,
DL: HTMLElement,
DT: HTMLElement,
Expand Down
@@ -0,0 +1,52 @@
import Event from '../../event/Event';
import HTMLElement from '../html-element/HTMLElement';
import IHTMLDialogElement from './IHTMLDialogElement';

/**
* HTML Dialog Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement.
*/
export default class HTMLDialogElement extends HTMLElement implements IHTMLDialogElement {
/**
* Returns returnValue.
*
* @returns ReturnValue.
*/
public returnValue: string;

/**
* Returns open.
*
* @returns Open.
*/
public get open(): boolean {
return this.hasAttributeNS(null, 'open');
}

/**
* Closes the dialog.
*
* @param returnValue ReturnValue.
*/
public close(returnValue?: string): void {
this.removeAttributeNS(null, 'open');
this.returnValue = returnValue;
this.dispatchEvent(new Event('close', { bubbles: false, cancelable: false }));
}

/**
* Shows the modal.
*/
public showModal(): void {
this.setAttributeNS(null, 'open', '');
}

/**
* Shows the dialog.
*/
public show(): void {
this.setAttributeNS(null, 'open', '');
}
}
@@ -0,0 +1,15 @@
import IHTMLElement from '../html-element/IHTMLElement';

/**
* HTML Dialog Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement.
*/
export default interface IHTMLDialogElement extends IHTMLElement {
open: boolean;
returnValue: string;
close(returnValue?: string): void;
showModal(): void;
show(): void;
}
@@ -0,0 +1,110 @@
import { Event } from 'src';
import Document from '../../../src/nodes/document/Document';
import HTMLDialogElement from '../../../src/nodes/html-dialog-element/HTMLDialogElement';
import Window from '../../../src/window/Window';

describe('HTMLDialogElement', () => {
let window: Window;
let document: Document;
let element: HTMLDialogElement;

beforeEach(() => {
window = new Window();
document = window.document;
element = <HTMLDialogElement>document.createElement('dialog');
});

describe('open', () => {
it('Should be closed by default', () => {
expect(element.open).toBe(false);
});

it('Should be open when show has been called', () => {
element.show();
expect(element.open).toBe(true);
});

it('Should be open when showModal has been called', () => {
element.showModal();
expect(element.open).toBe(true);
});
});

describe('returnValue', () => {
it('Should be undefined by default', () => {
expect(element.returnValue).toBe(undefined);
});

it('Should be set when close has been called with a return value', () => {
element.close('foo');
expect(element.returnValue).toBe('foo');
});

it('Should be possible to set manually', () => {
element.returnValue = 'foo';
expect(element.returnValue).toBe('foo');
});
});

describe('close', () => {
it('Should be possible to close an open dialog', () => {
element.show();
element.close();
expect(element.open).toBe(false);
expect(element.getAttributeNS(null, 'open')).toBe(null);
});

it('Should be possible to close an open modal dialog', () => {
element.showModal();
element.close();
expect(element.open).toBe(false);
expect(element.getAttributeNS(null, 'open')).toBe(null);
});

it('Should be possible to close the dialog with a return value', () => {
element.show();
element.close('foo');
expect(element.returnValue).toBe('foo');
});

it('Should be possible to close the modal dialog with a return value', () => {
element.showModal();
element.close('foo');
expect(element.returnValue).toBe('foo');
});

it('Should dispatch a close event', () => {
let dispatched: Event = null;
element.addEventListener('close', (event: Event) => (dispatched = event));
element.show();
element.close();
expect(dispatched.cancelable).toBe(false);
expect(dispatched.bubbles).toBe(false);
});

it('Should dispatch a close event when closing a modal', () => {
let dispatched: Event = null;
element.addEventListener('close', (event: Event) => (dispatched = event));
element.showModal();
element.close();
expect(dispatched.cancelable).toBe(false);
expect(dispatched.bubbles).toBe(false);
});
});

describe('showModal', () => {
it('Should be possible to show a modal dialog', () => {
element.showModal();
expect(element.open).toBe(true);
expect(element.getAttributeNS(null, 'open')).toBe('');
});
});

describe('show', () => {
it('Should be possible to show a dialog', () => {
element.show();
expect(element.open).toBe(true);
expect(element.getAttributeNS(null, 'open')).toBe('');
});
});
});

0 comments on commit 925ddad

Please sign in to comment.