2f752e0f71bb5cccb3495d23ec19698a71a0f4b890b1040a5268f35397bb4265d7b3884659364d197d454ca46ecf6d367f1ca6ad93e40be1af25246d21eb11 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import Scope from '../scope.js';
  2. export interface AttributorOptions {
  3. scope?: Scope;
  4. whitelist?: string[];
  5. }
  6. export default class Attributor {
  7. public static keys(node: HTMLElement): string[] {
  8. return Array.from(node.attributes).map((item: Attr) => item.name);
  9. }
  10. public scope: Scope;
  11. public whitelist: string[] | undefined;
  12. constructor(
  13. public readonly attrName: string,
  14. public readonly keyName: string,
  15. options: AttributorOptions = {},
  16. ) {
  17. const attributeBit = Scope.TYPE & Scope.ATTRIBUTE;
  18. this.scope =
  19. options.scope != null
  20. ? // Ignore type bits, force attribute bit
  21. (options.scope & Scope.LEVEL) | attributeBit
  22. : Scope.ATTRIBUTE;
  23. if (options.whitelist != null) {
  24. this.whitelist = options.whitelist;
  25. }
  26. }
  27. public add(node: HTMLElement, value: any): boolean {
  28. if (!this.canAdd(node, value)) {
  29. return false;
  30. }
  31. node.setAttribute(this.keyName, value);
  32. return true;
  33. }
  34. public canAdd(_node: HTMLElement, value: any): boolean {
  35. if (this.whitelist == null) {
  36. return true;
  37. }
  38. if (typeof value === 'string') {
  39. return this.whitelist.indexOf(value.replace(/["']/g, '')) > -1;
  40. } else {
  41. return this.whitelist.indexOf(value) > -1;
  42. }
  43. }
  44. public remove(node: HTMLElement): void {
  45. node.removeAttribute(this.keyName);
  46. }
  47. public value(node: HTMLElement): any {
  48. const value = node.getAttribute(this.keyName);
  49. if (this.canAdd(node, value) && value) {
  50. return value;
  51. }
  52. return '';
  53. }
  54. }