proper recursive proxy initialization

pull/1/head
ansuz 9 years ago
parent 68cec2348a
commit e44446f71e

@ -35,8 +35,7 @@ define([
throw new Error("'on' is a reserved attribute name for realtime lists and maps"); throw new Error("'on' is a reserved attribute name for realtime lists and maps");
} }
var t_value = type(value); if (isProxyable(value)) {
if (isProxyable(t_value)) {
var proxy = obj[prop] = deepProxy.create(value, cb); var proxy = obj[prop] = deepProxy.create(value, cb);
} else { } else {
obj[prop] = value; obj[prop] = value;
@ -82,7 +81,7 @@ define([
events.change.sort(lengthDescending); events.change.sort(lengthDescending);
break; break;
case 'delete': case 'remove':
pattern = type(pattern) === 'array'? pattern: [pattern]; pattern = type(pattern) === 'array'? pattern: [pattern];
events.remove.push({ events.remove.push({
@ -119,6 +118,7 @@ define([
pattern(info); pattern(info);
} }
}); });
break;
default: default:
break; break;
} }
@ -198,7 +198,7 @@ define([
}, map)) || undefined; }, map)) || undefined;
}; };
var onRemove = function (path, key, root) { var onRemove = function (path, key, root, old, top) {
var newpath = path.concat(key); var newpath = path.concat(key);
var X = find(root, newpath); var X = find(root, newpath);
@ -209,24 +209,32 @@ define([
switch (t_X) { switch (t_X) {
case 'array': case 'array':
if (top) {
// the top of an onremove should emit an onchange instead
onChange(path, key, root, old, undefined);// no newval since it's a deletion
} else {
root._events.remove.forEach(function (handler, i) {
return handler.cb(X, newpath, root);
});
}
// remove all of the array's children // remove all of the array's children
X.forEach(function (x, i) { X.forEach(function (x, i) {
onRemove(newpath, i, root); onRemove(newpath, i, root);
}); });
root._events.remove.forEach(function (handler, i) {
return handler.cb(X, newpath, root);
});
break; break;
case 'object': case 'object':
if (top) {
onChange(path, key, root, old, undefined);// no newval since it's a deletion
} else {
root._events.remove.forEach(function (handler, i) {
return handler.cb(X, newpath, root, old, false);
});
}
// remove all of the object's children // remove all of the object's children
Object.keys(X).forEach(function (key, i) { Object.keys(X).forEach(function (key, i) {
onRemove(newpath, key, root); onRemove(newpath, key, root, X[key], false);
});
root._events.remove.forEach(function (handler, i) {
return handler.cb(X, newpath, root);
}); });
break; break;
@ -300,13 +308,7 @@ define([
console.log("type changed from [%s] to [%s]", t_a, t_b); console.log("type changed from [%s] to [%s]", t_a, t_b);
switch (t_b) { switch (t_b) {
case 'undefined': case 'undefined':
// deletions are a removal
//delete A[b];
onRemove(path, b, root);
// this should never happen?
throw new Error("first pass should never reveal undefined keys"); throw new Error("first pass should never reveal undefined keys");
//break;
case 'array': case 'array':
A[b] = f(B[b]); A[b] = f(B[b]);
// make a new proxy // make a new proxy
@ -353,7 +355,7 @@ define([
// the key was deleted // the key was deleted
if (Bkeys.indexOf(a) === -1 || type(B[a]) === 'undefined') { if (Bkeys.indexOf(a) === -1 || type(B[a]) === 'undefined') {
onRemove(path, a, root); onRemove(path, a, root, old, true);
delete A[a]; delete A[a];
} }
}); });
@ -384,6 +386,8 @@ define([
// type changes are always destructive // type changes are always destructive
// that's good news because destructive is easy // that's good news because destructive is easy
switch (t_b) { switch (t_b) {
case 'undefined':
throw new Error('this should never happen');
case 'object': case 'object':
A[i] = f(b); A[i] = f(b);
break; break;
@ -424,10 +428,13 @@ define([
// A was longer than B, so there have been deletions // A was longer than B, so there have been deletions
var i = l_B; var i = l_B;
var t_a; var t_a;
var old;
for (; i <= l_B; i++) { for (; i <= l_B; i++) {
// recursively delete // recursively delete
onRemove(path, i, root); old = A[i];
onRemove(path, i, root, old, true);
} }
// cool // cool
} }
@ -447,7 +454,7 @@ define([
if (t_a !== t_b) { if (t_a !== t_b) {
switch (t_b) { switch (t_b) {
case 'undefined': case 'undefined':
onRemove(path, i, root); onRemove(path, i, root, old, true);
break; break;
// watch out for fallthrough behaviour // watch out for fallthrough behaviour

Loading…
Cancel
Save