UNPKG

relu-core

Version:
147 lines (128 loc) 3.32 kB
var base = require("./base"); module.exports = function rpElement(array, index) { if(array.elements && array.elements[index]) return array.elements[index].temporary(); var p = base(); p.constructor = rpElement; p.index = index; p.parent = array; p._info = function() { return "[" + index + "]" }; p._actionsList = function() { if(index < 0) return null; var al = array._actionsList(); if(!al) return null; return al.atPath([index]); }; p._actionsTarget = function() { if(index < 0) return null; var at = array._actionsTarget(); if(!at) return null; return at(index); }; p._get = function() { p.depend(); return p._getUndependend(); }; p._getUndependend = function() { var a = array._getUndependend(); return getValue(a); }; function getValue(a) { if(index < 0) return undefined; if(!Array.isArray(a)) return undefined; if(a.length <= index) return undefined; return a[index]; } if(!array.elements) array.elements = {}; array.elements[index] = p; array.onUpdated(onUpdated, true); array.onAdded(onAdded, true); array.onRemoved(onRemoved, true); array.onNested(onNested); array.ref(p); p.onceDisposed(function() { if(index >= 0) disconnect(); p.index = index = -1; }); p.isConst = function() { return array.isConst(); }; p.writable = function() { return array.writable(); }; function disconnect() { array.removeUpdatedListener(onUpdated); array.removeAddedListener(onAdded); array.removeRemovedListener(onRemoved); array.removeNestedListener(onNested); if(array.elements[index] === p) delete array.elements[index]; array.unref(p); }; p.remove = function() { if(index < 0) throw new Error("Item is already removed"); if(!Array.isArray(p.parent._getUndependend())) throw new Error("Parent is not an array"); if(index >= p.parent._getUndependend().length) throw new Error("Item is out of range (weird)"); array.spliceBefore(index, 1); }; function onUpdated(newValue, oldValue) { if(index < 0) return; disconnect(); p.index = index = -1; var old = getValue(oldValue); if(old !== undefined) { p._updated(undefined, old); p._changed() } } function onAdded(idx) { if(index < 0) return; if(idx <= index) { if(array.elements[index] === p) delete array.elements[index]; p.index = ++index; array.elements[index] = p; } } function onRemoved(idx, oldValue) { if(index < 0) return; if(idx < index) { if(array.elements[index] === p) delete array.elements[index]; p.index = --index; array.elements[index] = p; } else if(idx === index) { disconnect(); p.index = index = -1; var value = getValue(oldValue); if(value !== undefined) { p._updated(undefined, value); p._changed(); } } } function onNested(type, path, a, b) { if(path[0] === index) { if(path.length > 1) p._nested(type, path.slice(1), a, b); else { switch(type) { case "updated": p._updated(a, b); break; case "added": p._added(a, b); break; case "removed": p._removed(a, b); break; case "changed": p._changed(); break; } } } } return p; };