Skip to content

Instantly share code, notes, and snippets.

@r37r0m0d3l
Forked from bolshchikov/gist:8069009
Created January 6, 2014 23:35
Show Gist options
  • Save r37r0m0d3l/8292004 to your computer and use it in GitHub Desktop.
Save r37r0m0d3l/8292004 to your computer and use it in GitHub Desktop.
// lo-dash lib is the dependency
function readOnly(target){
var _readOnly = function (target, acc) {
// acc is passed into the function to be used for observer
var _defineProperty = function (propName, target, acc) {
var i, len;
// operation to be performed when add occurred
var addOp = function (cArg) {
// have to define the added item
_defineProperty(cArg.name, cArg.object, acc[propName]);
};
// operation to be performed when add delete
var delOp = function (cArg) {
if (_.isPlainObject(cArg.object)) {
delete acc[propName][cArg.name];
}
if (_.isArray(cArg.object)) {
// this fixes the array
acc[propName].unshift(acc[propName].shift());
// when splice occures, there's no
// clear indication what has been removed
// so, we need to find the diff, and clear acc
var args = _.difference(acc[propName], cArg.object);
args.unshift(acc[propName]);
_.pull.apply(null, args);
}
};
// function that is called when any change in the property happens
var observeFn = function (changes) {
console.log(changes);
for (i = 0, len = changes.length; i < len; i += 1) {
switch(changes[i].type) {
case 'new':
addOp(changes[i]);
break;
case 'deleted':
delOp(changes[i]);
break;
default:
continue;
}
}
};
if (_.isArray(target[propName])) {
Object.defineProperty(acc, propName, {
enumerable: true,
value: []
});
Object.observe(target[propName], observeFn);
_readOnly(target[propName], acc[propName]);
}
else if (_.isPlainObject(target[propName])) {
Object.defineProperty(acc, propName, {
enumerable: true,
value: {}
});
Object.observe(target[propName], observeFn);
_readOnly(target[propName], acc[propName]);
}
// value is the primitive one
else {
Object.defineProperty(acc, propName, {
enumerable: true,
get: function () {
return target[propName];
}
});
}
};
// target is an array
_.forEach(target, function (val, key) {
_defineProperty(key, target, acc);
});
return acc;
};
return _readOnly(target, {});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment