import { Arr, type Optional } from '@ephox/katamari'; import * as ObjIndex from '../alien/ObjIndex'; import type { AlloyBehaviour } from '../api/behaviour/Behaviour'; import type { BehaviourConfigAndState } from '../behaviour/common/BehaviourBlob'; import type { BehaviourState } from '../behaviour/common/BehaviourState'; import type { DomDefinitionDetail } from '../dom/DomDefinition'; import { type DomModification, nu as NuModification } from '../dom/DomModification'; interface Modification { name: string; modification: T; } type DomModificationAspectRecord = { [K in keyof DomModification]: Array> }; // Based on all the behaviour exhibits, and the original dom modification, identify // the overall combined dom modification that needs to occur const combine = ( info: Record Optional>>, baseMod: Record, behaviours: Array>, base: DomDefinitionDetail ): DomModification => { // Collect all the DOM modifications, indexed by behaviour name (and base for base) type BehaviourName = string; // classes are array of strings, styles and attributes are a record type DomModificationRecord = { [K in keyof DomModification]: DomModification[K] }; // Clone the object so we can change it. const modsByBehaviour: Record = { ...baseMod }; Arr.each(behaviours, (behaviour) => { modsByBehaviour[behaviour.name()] = behaviour.exhibit(info, base); }); // byAspect format: { classes: [ { name: Toggling, modification: [ 'selected' ] } ] } const byAspect = ObjIndex.byInnerKey(modsByBehaviour, (name, modification) => ({ name, modification })) as DomModificationAspectRecord; const combineObjects = >(objects: Array>): T => Arr.foldr(objects, (b, a) => ({ ...a.modification, ...b }), { } as T); const combinedClasses = Arr.foldr(byAspect.classes, (b: string[], a) => a.modification.concat(b), [ ]); const combinedAttributes = combineObjects(byAspect.attributes); const combinedStyles = combineObjects(byAspect.styles); return NuModification({ classes: combinedClasses, attributes: combinedAttributes, styles: combinedStyles }); }; export { combine };