node.js 2.05 KB

var Type = require('./type');
var Val = require('./val');
var Node = {_: '_'};
Node.soul = function(n, o){ return (n && n._ && n._[o || soul_]) } // convenience function to check to see if there is a soul on a node and return it.
Node.soul.ify = function(n, o){ // put a soul on an object.
	o = (typeof o === 'string')? {soul: o} : o || {};
	n = n || {}; // make sure it exists.
	n._ = n._ || {}; // make sure meta exists.
	n._[soul_] = o.soul || n._[soul_] || text_random(); // put the soul on it.
	return n;
}
Node.soul._ = Val.link._;
;(function(){
	Node.is = function(n, cb, as){ var s; // checks to see if an object is a valid node.
		if(!obj_is(n)){ return false } // must be an object.
		if(s = Node.soul(n)){ // must have a soul on it.
			return !obj_map(n, map, {as:as,cb:cb,s:s,n:n});
		}
		return false; // nope! This was not a valid node.
	}
	function map(v, k){ // we invert this because the way we check for this is via a negation.
		if(k === Node._){ return } // skip over the metadata.
		if(!Val.is(v)){ return true } // it is true that this is an invalid node.
		if(this.cb){ this.cb.call(this.as, v, k, this.n, this.s) } // optionally callback each key/value.
	}
}());
;(function(){
	Node.ify = function(obj, o, as){ // returns a node from a shallow object.
		if(!o){ o = {} }
		else if(typeof o === 'string'){ o = {soul: o} }
		else if('function' == typeof o){ o = {map: o} }
		if(o.map){ o.node = o.map.call(as, obj, u, o.node || {}) }
		if(o.node = Node.soul.ify(o.node || {}, o)){
			obj_map(obj, map, {o:o,as:as});
		}
		return o.node; // This will only be a valid node if the object wasn't already deep!
	}
	function map(v, k){ var o = this.o, tmp, u; // iterate over each key/value.
		if(o.map){
			tmp = o.map.call(this.as, v, ''+k, o.node);
			if(u === tmp){
				obj_del(o.node, k);
			} else
			if(o.node){ o.node[k] = tmp }
			return;
		}
		if(Val.is(v)){
			o.node[k] = v;
		}
	}
}());
var obj = Type.obj, obj_is = obj.is, obj_del = obj.del, obj_map = obj.map;
var text = Type.text, text_random = text.random;
var soul_ = Node.soul._;
var u;
module.exports = Node;