UNPKG

radi

Version:

**Radi** is a tiny javascript framework.

237 lines (219 loc) 6.72 kB
/* eslint-disable no-param-reassign */ /* eslint-disable no-shadow */ /* eslint-disable guard-for-in */ /* eslint-disable no-restricted-syntax */ // import fuseDom from '../r/utils/fuseDom'; export default class Listener { /** * @param {Component} component * @param {...string} path */ constructor(component, ...path) { this.component = component; [this.key] = path; this.path = path.slice(1, path.length); this.depth = 0; this.attached = true; this.processValue = value => value; this.changeListener = () => {}; this.addedListeners = []; } /** * Applies values and events to listener */ init() { this.value = this.getValue(this.component.state[this.key]); this.component.addListener(this.key, this, this.depth); this.handleUpdate(this.component.state[this.key]); return this; } /** * Removes last active value with destroying listeners and * @param {*} value */ unlink() { if (this.value instanceof Node) { // Destroy this Node // fuseDom.destroy(this.value); } else if (this.value instanceof Listener) { // Deattach this Listener this.value.deattach(); } } clone(target, source) { const out = {}; for (const i in target) { out[i] = target[i]; } for (const i in source) { out[i] = source[i]; } return out; } setPartialState(path, value, source) { const target = {}; if (path.length) { target[path[0]] = path.length > 1 ? this.setPartialState(path.slice(1), value, source[path[0]]) : value; return this.clone(source, target); } return value; } /** * Updates state value * @param {*} value */ updateValue(value) { const source = this.component.state[this.key]; return this.component.setState({ [this.key]: this.setPartialState(this.path, value, source), }); } extractListeners(value) { // if (this.value instanceof Listener && value instanceof Listener) { // console.log('middle') // } else if (value instanceof Listener) { // if (this.value instanceof Listener) { // this.value.processValue = value.processValue; // // this.value = value; // this.handleUpdate(value.getValue(value.component.state[value.key])); // console.log(value, value.getValue(value.component.state[value.key])); // value.deattach(); // } // value.component.addListener(value.key, value, value.depth); // value.handleUpdate = () => { // console.log('inner handler') // } const tempListener = { depth: value.depth, attached: true, processValue: value => value, handleUpdate: () => { if (this.component) { this.handleUpdate(this.getValue(this.component.state[this.key])); } tempListener.attached = false; }, changeListener: () => {}, }; this.addedListeners.push(tempListener); value.component.addListener(value.key, tempListener, value.depth); // value.init() // value.handleUpdate = () => { // console.log('inner handler') // } // value.onValueChange((v) => { // this.handleUpdate(this.getValue(this.component.state[this.key])); // console.log('me got changed', v) // }); const newValue = value.processValue( value.getValue(value.component.state[value.key]) ); value.deattach(); return this.extractListeners(newValue); } return value; // return this.processValue(this.getValue(value)); } /** * @param {*} value */ handleUpdate(value) { const newValue = this.processValue(this.getValue(value)); // if (this.value instanceof Listener && newValue instanceof Listener) { // this.value.processValue = newValue.processValue; // // this.value = newValue; // this.value.handleUpdate(newValue.component.state[newValue.key]); // console.log(newValue, newValue.getValue(newValue.component.state[newValue.key])); // newValue.deattach(); // } else if (newValue instanceof Listener) { // if (this.value instanceof Listener) { // this.value.processValue = newValue.processValue; // // this.value = newValue; // this.value.handleUpdate(newValue.component.state[newValue.key]); // console.log(newValue, newValue.getValue(newValue.component.state[newValue.key])); // newValue.deattach(); // } else { for (let i = 0; i < this.addedListeners.length; i++) { this.addedListeners[i].attached = false; } this.addedListeners = []; this.value = this.extractListeners(newValue); this.changeListener(this.value); // } // // console.log(this.value.processValue('P'), newValue.processValue('A')); // // console.log(this.extractListeners(newValue)); // // newValue.handleUpdate(newValue.component.state[newValue.key]); // // this.value = newValue; // // this.value.processValue = newValue.processValue; // this.value = this.extractListeners(newValue); // this.changeListener(this.value); // // this.value.processValue = newValue.processValue; // // // this.value = newValue; // // this.value.handleUpdate(newValue.component.state[newValue.key]); // // console.log(newValue, newValue.getValue(newValue.component.state[newValue.key])); // // newValue.deattach(); } else { this.unlink(); this.value = newValue; this.changeListener(this.value); } } /** * @param {*} source * @returns {*} */ getValue(source) { let i = 0; while (i < this.path.length) { if (source === null || (!source[this.path[i]] && typeof source[this.path[i]] !== 'number')) { source = null; } else { source = source[this.path[i]]; } i += 1; } return source; } /** * @param {number} depth * @returns {Listener} */ applyDepth(depth) { this.depth = depth; return this; } /** * @param {function(*)} changeListener */ onValueChange(changeListener) { this.changeListener = changeListener; this.changeListener(this.value); } /** * @param {function(*): *} processValue * @returns {function(*): *} */ process(processValue) { this.processValue = processValue; return this; } deattach() { this.component = null; this.attached = false; this.key = null; this.childPath = null; this.path = null; this.unlink(); this.value = null; this.changeListener = () => {}; this.processValue = () => {}; } }