Skip to content

Commit

Permalink
before, after, and between callbacks to fancier traversing
Browse files Browse the repository at this point in the history
  • Loading branch information
James Halliday committed Sep 4, 2010
1 parent f22580a commit 5662b6f
Showing 1 changed file with 29 additions and 5 deletions.
34 changes: 29 additions & 5 deletions lib/traverse.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function Traverse (refObj) {
// get() is deprecated, use .value
this.get = function () { return this.value };

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

var path = [];
Expand All @@ -52,12 +52,18 @@ function Traverse (refObj) {
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;
Expand All @@ -67,8 +73,12 @@ function Traverse (refObj) {
}
state.node = x;
},
level : path.length,
circular : null
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) {
Expand All @@ -85,20 +95,34 @@ function Traverse (refObj) {
state.notLeaf = !state.isLeaf;
state.notRoot = !state.isRoot;

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

// use return values to update if defined
var ret = f.call(state, node);
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) {
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);
}
};

Expand Down

0 comments on commit 5662b6f

Please sign in to comment.