import Scope from '../scope.js'; export interface AttributorOptions { scope?: Scope; whitelist?: string[]; } export default class Attributor { public static keys(node: HTMLElement): string[] { return Array.from(node.attributes).map((item: Attr) => item.name); } public scope: Scope; public whitelist: string[] | undefined; constructor( public readonly attrName: string, public readonly keyName: string, options: AttributorOptions = {}, ) { const attributeBit = Scope.TYPE & Scope.ATTRIBUTE; this.scope = options.scope != null ? // Ignore type bits, force attribute bit (options.scope & Scope.LEVEL) | attributeBit : Scope.ATTRIBUTE; if (options.whitelist != null) { this.whitelist = options.whitelist; } } public add(node: HTMLElement, value: any): boolean { if (!this.canAdd(node, value)) { return false; } node.setAttribute(this.keyName, value); return true; } public canAdd(_node: HTMLElement, value: any): boolean { if (this.whitelist == null) { return true; } if (typeof value === 'string') { return this.whitelist.indexOf(value.replace(/["']/g, '')) > -1; } else { return this.whitelist.indexOf(value) > -1; } } public remove(node: HTMLElement): void { node.removeAttribute(this.keyName); } public value(node: HTMLElement): any { const value = node.getAttribute(this.keyName); if (this.canAdd(node, value) && value) { return value; } return ''; } }