relu-core
Version:
116 lines (100 loc) • 2.45 kB
JavaScript
var base = require("./base");
module.exports = function rpProperty(obj, name) {
if(obj.properties && obj.properties["$"+name])
return obj.properties["$"+name].temporary();
var p = base();
p.constructor = rpProperty;
p.propertyName = name;
p.parent = obj;
p._info = function() { return "[" + name + "]" };
p._actionsList = function() {
var al = obj._actionsList();
if(!al) return null;
return al.atPath([name]);
};
p._actionsTarget = function() {
var at = obj._actionsTarget();
if(!at) return null;
return at(name);
};
p._get = function() {
p.depend();
return p._getUndependend();
};
p._getUndependend = function() {
var o = obj._getUndependend();
return getValue(o);
};
function getValue(o) {
if(!o) return undefined;
if(Array.isArray(o)) {
return o.map(function(i) {
if(!i || typeof i !== "object") return undefined;
return i[name];
});
}
return o[name];
}
if(!obj.properties)
obj.properties = {};
obj.properties["$"+name] = p;
obj.onUpdated(onUpdated, true);
obj.onAdded(onUpdated, true);
obj.onRemoved(onUpdated, true);
obj.onNested(onNested);
obj.ref(p);
p.onceDisposed(function() {
obj.removeUpdatedListener(onUpdated);
obj.removeAddedListener(onUpdated);
obj.removeRemovedListener(onUpdated);
obj.removeNestedListener(onNested);
if(obj.properties["$"+name] === p)
delete obj.properties["$"+name];
obj.unref(p);
});
p.isConst = function() {
return obj.isConst();
};
p.writable = function() {
return obj.writable();
};
var superElement = p._element;
p._element = function(idx) {
var o = obj._getUndependend();
if(Array.isArray(o)) {
return obj._element(idx)(name);
}
return superElement.call(this, idx);
};
function onUpdated(newValue, oldValue) {
oldValue = getValue(oldValue);
newValue = getValue(newValue);
if(oldValue !== newValue) {
p._updated(newValue, oldValue);
p._changed();
}
}
function onNested(type, path, a, b) {
if(path[0] === name) {
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;
};