Skip to content

Commit

Permalink
capricorn86#475@minor: Adds support for HTMLMediaElement.
Browse files Browse the repository at this point in the history
  • Loading branch information
rudywaltz committed May 31, 2022
1 parent cede8a4 commit 1c68654
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 4 deletions.
5 changes: 3 additions & 2 deletions packages/happy-dom/src/config/ElementTag.ts
Expand Up @@ -13,6 +13,7 @@ import HTMLLabelElement from '../nodes/html-label-element/HTMLLabelElement';
import HTMLSlotElement from '../nodes/html-slot-element/HTMLSlotElement';
import HTMLMetaElement from '../nodes/html-meta-element/HTMLMetaElement';
import HTMLBaseElement from '../nodes/html-base-element/HTMLBaseElement';
import HTMLMediaElement from '../nodes/html-media-element/HTMLMediaElement';

export default {
A: HTMLElement,
Expand All @@ -21,7 +22,7 @@ export default {
AREA: HTMLElement,
ARTICLE: HTMLElement,
ASIDE: HTMLElement,
AUDIO: HTMLElement,
AUDIO: HTMLMediaElement,
B: HTMLElement,
BASE: HTMLBaseElement,
BDI: HTMLElement,
Expand Down Expand Up @@ -140,6 +141,6 @@ export default {
U: HTMLElement,
UL: HTMLElement,
VAR: HTMLElement,
VIDEO: HTMLElement,
VIDEO: HTMLMediaElement,
WBR: HTMLElement
};
Expand Up @@ -54,7 +54,5 @@ export default [
'HTMLEmbedElement',
'HTMLObjectElement',
'HTMLParamElement',
'HTMLVideoElement',
'HTMLAudioElement',
'HTMLTrackElement'
];
137 changes: 137 additions & 0 deletions packages/happy-dom/src/nodes/html-media-element/HTMLMediaElement.ts
@@ -0,0 +1,137 @@
import HTMLElement from '../html-element/HTMLElement';
import IHTMLMediaElement from './IHTMLMediaElement';

/**
* HTML Base Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base.
*/
export default class HTMLMediaElement extends HTMLElement implements IHTMLMediaElement {
/**
* Returns autoplay.
*
* @returns Autoplay.
*/
public get autoplay(): boolean {
return this.getAttributeNS(null, 'autoplay') !== null;
}

/**
* Sets autoplay.
*
* @param autoplay Autoplay.
*/
public set autoplay(autoplay: boolean) {
if (!autoplay) {
this.removeAttributeNS(null, 'autoplay');
} else {
this.setAttributeNS(null, 'autoplay', '');
}
}

/**
* Returns controls.
*
* @returns Controls.
*/
public get controls(): boolean {
return this.getAttributeNS(null, 'controls') !== null;
}

/**
* Sets controls.
*
* @param controls Controls.
*/
public set controls(controls: boolean) {
if (!controls) {
this.removeAttributeNS(null, 'controls');
} else {
this.setAttributeNS(null, 'controls', '');
}
}

/**
* Returns paused.
*
* @returns Paused.
*/
public get paused(): boolean {
return this.getAttributeNS(null, 'paused') !== null;
}

/**
* Sets paused.
*
* @param paused Paused.
*/
public set paused(paused: boolean) {
if (!paused) {
this.removeAttributeNS(null, 'paused');
} else {
this.setAttributeNS(null, 'paused', '');
}
}

/**
* Returns loop.
*
* @returns Loop.
*/
public get loop(): boolean {
return this.getAttributeNS(null, 'loop') !== null;
}

/**
* Sets loop.
*
* @param loop Loop.
*/
public set loop(loop: boolean) {
if (!loop) {
this.removeAttributeNS(null, 'loop');
} else {
this.setAttributeNS(null, 'loop', '');
}
}
/**
* Returns muted.
*
* @returns muted.
*/
public get muted(): boolean {
return this.getAttributeNS(null, 'muted') !== null;
}

/**
* Sets muted.
*
* @param muted muted.
*/
public set muted(muted: boolean) {
if (!muted) {
this.removeAttributeNS(null, 'muted');
} else {
this.setAttributeNS(null, 'muted', '');
}
}

/**
*
*/
public pause(): void {
this.paused = true;
}

/**
* Clones a node.
*
* @override
* @param [deep=false] "true" to clone deep.
* @returns Cloned node.
*/
public cloneNode(deep = false): IHTMLMediaElement {
return <IHTMLMediaElement>super.cloneNode(deep);
}
}
@@ -0,0 +1,52 @@
import IHTMLElement from '../html-element/IHTMLElement';

/**
* HTML Media Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement.
*/
export default interface IHTMLMediaElement extends IHTMLElement {
// AddTextTrack;
autoplay: boolean;
// Buffered; // TODO
// CaptureStream; // TODO
controls: boolean;
// ControlsList: string; // TODO
// CrossOrigin: string; // TODO: enum?
// CurrentSrc: string; // TODO
// CurrentTime; // TODO
// DefaultMuted: boolean; // TODO
// DefaultPlaybackRate; // TODO
// DisableRemotePlayback: boolean; // TODO
// Duration: number; // TODO
// Ended: boolean; // TODO
// Error; // TODO object
loop: boolean;
// MediaKeys; // TODO
muted: boolean;
// NetworkState; // TODO
paused: boolean;
// Played: boolean; // TODO
// PlaybackRate: number; // TODO

/**
* The HTMLMediaElement.pause() method will pause playback of the media, if the media is already in a paused state this method will have no effect.
*/

pause(): void;

/**
* The HTMLMediaElement play() method attempts to begin playback of the media. It returns a Promise which is resolved when playback has been successfully started.
*/
// play(): Promise<void>; // TODO function

/**
* Clones a node.
*
* @override
* @param [deep=false] "true" to clone deep.
* @returns Cloned node.
*/
cloneNode(deep: boolean): IHTMLMediaElement;
}
@@ -0,0 +1,44 @@
import Window from '../../../src/window/Window';
import IWindow from '../../../src/window/IWindow';
import IDocument from '../../../src/nodes/document/IDocument';
import IHTMLMediaElement from '../../../src/nodes/html-media-element/IHTMLMediaElement';

describe('HTMLMediaElement', () => {
let window: IWindow;
let document: IDocument;
let element: IHTMLMediaElement;

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

afterEach(() => {
jest.restoreAllMocks();
});

for (const property of ['autoplay', 'controls', 'paused', 'loop', 'muted']) {
describe(`get ${property}()`, () => {
it('Returns attribute value.', () => {
expect(element[property]).toBe(false);
element.setAttribute(property, '');
expect(element[property]).toBe(true);
});
});

describe(`set ${property}()`, () => {
it('Sets attribute value.', () => {
element[property] = true;
expect(element.getAttribute(property)).toBe('');
});
});
}

describe('paused', () => {
it('Set paused attribute as well', () => {
element.pause();
expect(element.getAttribute('paused')).toBe('');
});
});
});

0 comments on commit 1c68654

Please sign in to comment.