UNPKG

happy-dom

Version:

Happy DOM is a JavaScript implementation of a web browser without its graphical user interface. It includes many web standards from WHATWG DOM and HTML.

94 lines (88 loc) 2.89 kB
import Element from '../nodes/element/Element.js'; import * as PropertySymbol from '../PropertySymbol.js'; import DOMStringMapUtility from './DOMStringMapUtility.js'; /** * Dataset factory. * * Reference: * https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset */ export default class DOMStringMap { [key: string]: string; /** * Constructor. * * @param illegalConstructorSymbol Illegal constructor symbol. * @param element Element. */ constructor(illegalConstructorSymbol: symbol, element: Element) { if (illegalConstructorSymbol !== PropertySymbol.illegalConstructor) { throw new TypeError('Illegal constructor'); } // Documentation for Proxy: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy return new Proxy(this, { get(_target, property: string): string | void { const attribute = element.getAttribute( 'data-' + DOMStringMapUtility.camelCaseToKebab(property) ); if (attribute !== null) { return attribute; } }, set(_target, property: string, value: string): boolean { element.setAttribute('data-' + DOMStringMapUtility.camelCaseToKebab(property), value); return true; }, deleteProperty(_target, property: string): boolean { element.removeAttribute('data-' + DOMStringMapUtility.camelCaseToKebab(property)); return true; }, ownKeys(_target): string[] { // According to Mozilla we have to update the dataset object (target) to contain the same keys as what we return: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/ownKeys // "The result List must contain the keys of all non-configurable own properties of the target object." const keys = []; for (const items of element[PropertySymbol.attributes][ PropertySymbol.itemsByName ].values()) { if (items[0][PropertySymbol.name].startsWith('data-')) { keys.push( DOMStringMapUtility.kebabToCamelCase( items[0][PropertySymbol.name].replace('data-', '') ) ); } } return keys; }, has(_target, property: string): boolean { return element.hasAttribute('data-' + DOMStringMapUtility.camelCaseToKebab(property)); }, defineProperty(_target, property: string, descriptor): boolean { if (descriptor.value === undefined) { return false; } element.setAttribute( 'data-' + DOMStringMapUtility.camelCaseToKebab(property), descriptor.value ); return true; }, getOwnPropertyDescriptor(_target, property: string): PropertyDescriptor { const attribute = element.getAttribute( 'data-' + DOMStringMapUtility.camelCaseToKebab(property) ); if (!attribute) { return; } return { value: attribute, writable: true, enumerable: true, configurable: true }; } }); } }