Skip to content

Commit

Permalink
pushed walk() out of map
Browse files Browse the repository at this point in the history
  • Loading branch information
James Halliday committed Sep 4, 2010
1 parent 5662b6f commit e7ec7de
Showing 1 changed file with 93 additions and 80 deletions.
173 changes: 93 additions & 80 deletions lib/traverse.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,95 +44,22 @@ function Traverse (refObj) {
this.get = function () { return this.value };

this.map = function (cb) {
var self = this;

var path = [];
var parents = [];
walk(this.value);
walk({
node : this.value,
root : this.value,
callback : cb
})
return this;

function walk (node) {
var before = null;
var after = null;
var between = null;

var state = {
node : node,
path : [].concat(path),
parent : parents.slice(-1)[0],
key : path.slice(-1)[0],
isRoot : node === self.value,
level : path.length,
circular : null,
update : function (x) {
if (state.isRoot) {
self.value = x;
}
else {
state.parent.node[state.key] = x;
}
state.node = x;
},
before : function (f) { before = f },
after : function (f) { after = f },
between : function (f, acc) {
between = f;
between._acc = acc;
}
};

if (typeof node == 'object' && node !== null) {
state.isLeaf = Object.keys(node).length == 0
var circs = parents.filter(function (p) {
return node == p.node
});
if (circs.length) state.circular = circs[0];
}
else {
state.isLeaf = true;
}

state.notLeaf = !state.isLeaf;
state.notRoot = !state.isRoot;

if (before) before.call(state, node);

// use return values to update if defined
var ret = cb.call(state, node);
if (ret !== undefined && state.update) state.update(ret);

if (typeof state.node == 'object'
&& state.node !== null && !state.circular) {
parents.push(state);
Object.keys(state.node).forEach(function (key, i) {
path.push(key);
walk(state.node[key]);

if (i == 0 && between && between._acc === undefined) {
between._acc = state.node[key]
}
else if (between) {
between._acc = between.call(
state, between._acc, state.node[key]
);
}

path.pop();
});
parents.pop();
}

if (after) after.call(state, node);
}
};

this.modify = this.map; // deprecated .modify()

this.forEach = function (f) {
this.map(function (node) {
delete this.update;
f.call(this,node);
},null);
f.call(this, node);
});
return this;
};

Expand Down Expand Up @@ -172,3 +99,89 @@ Traverse.paths = function (obj) {
Traverse.nodes = function (obj) {
return Traverse(obj).nodes();
};

function walk (params) {
var node = params.node;
var root = params.root;
var path = params.path || [];
var parents = params.parents || [];
var cb = params.callback;

var before = null;
var after = null;
var between = null;

var state = {
node : node,
path : [].concat(path),
parent : parents.slice(-1)[0],
key : path.slice(-1)[0],
isRoot : node === root,
level : path.length,
circular : null,
update : function (x) {
if (state.isRoot) {
root = x;
}
else {
state.parent.node[state.key] = x;
}
state.node = x;
},
before : function (f) { before = f },
after : function (f) { after = f },
between : function (f, acc) {
between = f;
between._acc = acc;
}
};

if (typeof node == 'object' && node !== null) {
state.isLeaf = Object.keys(node).length == 0
var circs = parents.filter(function (p) {
return node == p.node
});
if (circs.length) state.circular = circs[0];
}
else {
state.isLeaf = true;
}

state.notLeaf = !state.isLeaf;
state.notRoot = !state.isRoot;

if (before) before.call(state, node);

// use return values to update if defined
var ret = cb.call(state, node);
if (ret !== undefined && state.update) state.update(ret);

if (typeof state.node == 'object'
&& state.node !== null && !state.circular) {
parents.push(state);
Object.keys(state.node).forEach(function (key, i) {
path.push(key);
walk({
node : state.node[key],
root : root,
path : path,
parents : parents,
callback : cb
});

if (i == 0 && between && between._acc === undefined) {
between._acc = state.node[key]
}
else if (between) {
between._acc = between.call(
state, between._acc, state.node[key]
);
}

path.pop();
});
parents.pop();
}

if (after) after.call(state, node);
}

0 comments on commit e7ec7de

Please sign in to comment.