All files / json-crdt-peritext-ui/events PeritextEventTarget.ts

90.9% Statements 20/22
75% Branches 6/8
77.77% Functions 7/9
90% Lines 18/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 744x                     4x   4x 300x   300x           3942x 3942x 3942x 3942x       3942x 3942x 3942x       210x                   612x 612x       3114x                             6x 6x              
import {TypedEventTarget} from '../../util/events/TypedEventTarget';
import type {PeritextEventDetailMap, CursorDetail, FormatDetail, DeleteDetail, MarkerDetail} from './types';
 
export type PeritextEventMap = {
  [K in keyof PeritextEventDetailMap]: CustomEvent<PeritextEventDetailMap[K]>;
};
 
export type PeritextEventHandlerMap = {
  [K in keyof PeritextEventDetailMap]: (event: CustomEvent<PeritextEventDetailMap[K]>) => void;
};
 
let __id = 0;
 
export class PeritextEventTarget extends TypedEventTarget<PeritextEventMap> {
  public readonly id: number = __id++;
 
  public defaults: Partial<PeritextEventHandlerMap> = {};
 
  public dispatch<K extends keyof Omit<PeritextEventDetailMap, 'change'>>(
    type: K,
    detail: Omit<PeritextEventDetailMap, 'change'>[K],
  ): void {
    const event = new CustomEvent<PeritextEventDetailMap[K]>(type, {detail});
    this.dispatchEvent(event);
    if (!event.defaultPrevented) this.defaults[type]?.(event);
    this.change(event);
  }
 
  public change(ev?: CustomEvent<any>): void {
    const event = new CustomEvent<PeritextEventDetailMap['change']>('change', {detail: {ev}});
    this.dispatchEvent(event);
    if (!event.defaultPrevented) this.defaults.change?.(event);
  }
 
  public insert(text: string): void {
    this.dispatch('insert', {text});
  }
 
  public delete(len: DeleteDetail['len'], unit?: DeleteDetail['unit'], at?: DeleteDetail['at']): void;
  public delete(detail: DeleteDetail): void;
  public delete(
    lenOrDetail: DeleteDetail | DeleteDetail['len'],
    unit?: DeleteDetail['unit'],
    at?: DeleteDetail['at'],
  ): void {
    const detail: DeleteDetail = typeof lenOrDetail === 'object' ? lenOrDetail : {len: lenOrDetail, unit, at};
    this.dispatch('delete', detail);
  }
 
  public cursor(detail: CursorDetail): void {
    this.dispatch('cursor', detail);
  }
 
  public move(len: number, unit?: CursorDetail['unit'], edge?: CursorDetail['edge']): void {
    this.cursor({len, unit, edge});
  }
 
  public format(type: FormatDetail['type'], behavior?: FormatDetail['behavior'], data?: FormatDetail['data']): void;
  public format(detail: FormatDetail): void;
  public format(
    a: FormatDetail | FormatDetail['type'],
    behavior?: FormatDetail['behavior'],
    data?: FormatDetail['data'],
  ): void {
    const detail: FormatDetail =
      typeof a === 'object' && !Array.isArray(a) ? (a as FormatDetail) : ({type: a, behavior, data} as FormatDetail);
    this.dispatch('format', detail);
  }
 
  public marker(detail: MarkerDetail): void {
    this.dispatch('marker', detail);
  }
}