import type { SugarElement } from '@ephox/sugar'; import type { EventFormat, SimulatedEvent } from '../../events/SimulatedEvent'; import type { AlloyComponent } from '../component/ComponentApi'; import * as SystemEvents from './SystemEvents'; const emit = (component: AlloyComponent, event: string): void => { dispatchWith(component, component.element, event, { }); }; const emitWith = (component: AlloyComponent, event: string, properties: Record): void => { dispatchWith(component, component.element, event, properties); }; const emitExecute = (component: AlloyComponent): void => { emit(component, SystemEvents.execute()); }; const dispatch = (component: AlloyComponent, target: SugarElement, event: string): void => { dispatchWith(component, target, event, { }); }; const dispatchWith = (component: AlloyComponent, target: SugarElement, event: string, properties: Record): void => { // NOTE: The order of spreading here means that it will maintain any target that // exists in the current properties. Because this function has been used for situations where // properties is either an emulated SugarEvent with no target (see TouchEvent) or // for emitting custom events that have no target, this likely hasn't been a problem. // But until we verify that nothing is relying on this ordering, there is an alternate // function below called retargetAndDispatchWith, which spreads in the other direction. const data = { target, ...properties }; component.getSystem().triggerEvent(event, target, data); }; const retargetAndDispatchWith = (component: AlloyComponent, target: SugarElement, eventName: string, properties: T): void => { // This is essentially the same as dispatchWith, except the spreading order // means that it clobbers anything in the nativeEvent with "target". It also // expects what is being passed in to be a real sugar event, not just a data // blob const data = { ...properties, target }; component.getSystem().triggerEvent(eventName, target, data); }; const dispatchEvent = (component: AlloyComponent, target: SugarElement, event: string, simulatedEvent: SimulatedEvent): void => { component.getSystem().triggerEvent(event, target, simulatedEvent.event); }; const dispatchFocus = (component: AlloyComponent, target: SugarElement): void => { component.getSystem().triggerFocus(target, component.element); }; export { emit, emitWith, emitExecute, dispatch, dispatchWith, dispatchEvent, retargetAndDispatchWith, dispatchFocus };