import { AlloyComponent, AlloyEvents, EventFormat } from '@ephox/alloy'; import { Cell, Type } from '@ephox/katamari'; export interface GetApiType { readonly getApi: (comp: AlloyComponent) => T; } export type OnDestroy = (controlApi: T) => void; export interface OnControlAttachedType extends GetApiType { readonly onSetup: (controlApi: T) => OnDestroy | void; } const runWithApi = (info: GetApiType, comp: AlloyComponent): (f: OnDestroy) => void => { const api = info.getApi(comp); return (f: OnDestroy) => { f(api); }; }; // These handlers are used for providing common onAttached and onDetached handlers. // Essentially, the `editorOffCell` is used store the onDestroy function returned // by onSetup. The reason onControlAttached doesn't create the cell itself, is because // it also has to be passed into onControlDetached. We could make this function return // the cell and the onAttachedHandler, but that would provide too much complexity. const onControlAttached = (info: OnControlAttachedType, editorOffCell: Cell>): AlloyEvents.AlloyEventKeyAndHandler => AlloyEvents.runOnAttached((comp) => { const run = runWithApi(info, comp); run((api) => { const onDestroy = info.onSetup(api); if (Type.isFunction(onDestroy)) { editorOffCell.set(onDestroy); } }); }); const onControlDetached = (getApi: GetApiType, editorOffCell: Cell>): AlloyEvents.AlloyEventKeyAndHandler => AlloyEvents.runOnDetached((comp) => runWithApi(getApi, comp)(editorOffCell.get())); export { runWithApi, onControlAttached, onControlDetached };