UNPKG

bindom

Version:

Tiny, powerful data binding & web application framework

65 lines (56 loc) 2.13 kB
import {updateProperty} from '../bindObject.mjs'; import isLeaf from './isLeaf.mjs'; import parse from '../parse.mjs'; import {moveId, removeId} from './scopeId.mjs'; import selectBound from '../selectBound.mjs'; export default function removeNodes( {forgetScope, scopeId, object, rootNodes, map, mutated}, ) { const bound = selectBound(mutated); const rmMap = parse(rootNodes, bound, {}); findRmPoints(object, map, rmMap); rootNodes.emit('beforeUnbind'); if(forgetScope) bound.forEach(el => removeId(el, scopeId, 'bound')); else bound.forEach(el => moveId(el, scopeId, 'bound', 'bind')); rootNodes.emit('removedBound', {bubbles: true}); } function findRmPoints(object, map, rmMap, path = []) { for(const [key, value] of Object.entries(rmMap)) { if(!map[key]) continue; // rmNotFoundError(key); else if(isLeaf(map[key], value)) { const pth = path.concat(key); rmEntry(object, map, key, value.def, pth); } else removeNestedEntries(object, map, key, value, path); } } function removeNestedEntries(object, map, key, value, path) { findRmPoints(object, map[key].def, value.def, path); if(!Object.keys(map[key].def).length) { delete map[key]; delete object[key]; } } // function rmNotFoundError(key) { // throw new Error(`Could not remove binding to "${key}", not found`); // } function rmEntry(object, map, key, rm, path) { const {def} = map[key]; for(const entry of rm) { const idx = def.indexOf(def.find(({node}) => node[0] === entry.node[0])); def.splice(idx, 1).forEach(removeEventListener); } if(def.length === 1) convertToSimple(object, map, key, path, def); if(!def.length) updateProperty(object, map, path); } function removeEventListener({node, eventListener: {evt, handler} = {}}) { if(handler) node.off(evt, handler); } function convertToSimple(object, map, key, path, def) { removeEventListener(def[0]); if(def[0].to.type === 'event') return updateProperty(object, map, path); const hasPreValue = key in object; const preValue = object[key]; updateProperty(object, map, path); if(hasPreValue) object[key] = preValue; }