diff options
Diffstat (limited to 'popperjs/package/lib/utils/orderModifiers.js.flow')
-rw-r--r-- | popperjs/package/lib/utils/orderModifiers.js.flow | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/popperjs/package/lib/utils/orderModifiers.js.flow b/popperjs/package/lib/utils/orderModifiers.js.flow new file mode 100644 index 0000000..8094d6e --- /dev/null +++ b/popperjs/package/lib/utils/orderModifiers.js.flow @@ -0,0 +1,59 @@ +// @flow +import type { Modifier } from '../types'; +import { modifierPhases } from '../enums'; + +// source: https://stackoverflow.com/questions/49875255 +function order(modifiers) { + const map = new Map(); + const visited = new Set(); + const result = []; + + modifiers.forEach(modifier => { + map.set(modifier.name, modifier); + }); + + // On visiting object, check for its dependencies and visit them recursively + function sort(modifier: Modifier<any, any>) { + visited.add(modifier.name); + + const requires = [ + ...(modifier.requires || []), + ...(modifier.requiresIfExists || []), + ]; + + requires.forEach(dep => { + if (!visited.has(dep)) { + const depModifier = map.get(dep); + + if (depModifier) { + sort(depModifier); + } + } + }); + + result.push(modifier); + } + + modifiers.forEach(modifier => { + if (!visited.has(modifier.name)) { + // check for visited object + sort(modifier); + } + }); + + return result; +} + +export default function orderModifiers( + modifiers: Array<Modifier<any, any>> +): Array<Modifier<any, any>> { + // order based on dependencies + const orderedModifiers = order(modifiers); + + // order based on phase + return modifierPhases.reduce((acc, phase) => { + return acc.concat( + orderedModifiers.filter(modifier => modifier.phase === phase) + ); + }, []); +} |