vendor/components/indefinido-observable/lib/observable.js in ende-0.4.5 vs vendor/components/indefinido-observable/lib/observable.js in ende-0.4.6
- old
+ new
@@ -5,15 +5,16 @@
if (!Object.create ) require('../vendor/shims/object.create');
if (!Array.prototype.indexOf) require('../vendor/shims/array.indexOf');
// Object.defineProperty (for ie5+)
if (typeof require != 'undefined') {
- require('../vendor/shims/accessors.js');
-
// __lookup*__ and __define*__ for browsers with defineProperty support
// TODO Figure out why gives an infinity loop
require('../vendor/shims/accessors-legacy.js');
+
+ // Creates Object.defineProperty
+ require('../vendor/shims/accessors.js');
}
// Require Dependencies
if (!window['jQuery']) jQuery = $ = require('jquery');
@@ -86,13 +87,14 @@
if (requiresDomElement) {
observable = function (object) {
+ var fix;
// observable() or observable(object)
- if (this.document && this.location) {
+ if (this.document && this.location) {
if (!object) {
object = {};
}
// observable.call(...)
} else {
@@ -103,19 +105,32 @@
} else {
object = this;
}
}
+ // TODO better documentation
if (!jQuery.isReady) throw new Error('observable.call: For compatibility reasons, observable can only be called when dom is loaded.');
- var fix = document.createElement('fix');
- if (!jQuery.isReady) $(function () {document.body.appendChild(fix);});
- else document.body.appendChild(fix);
+ // Create dom element if object isn't one
+ if (!(typeof object.nodeName === 'string')) {
+ fix = document.createElement('fix');
- if (!object.observed) generator.observable_for(fix);
+ if (!jQuery.isReady) $(function () {document.body.appendChild(fix);});
+ else document.body.appendChild(fix);
- return $.extend(fix, object, mixin);
+ // Replace object with dom node
+ object = fix;
+ }
+
+ // Observe element if it is not observed
+ // TODO remove jquery dependency
+ if (!object.observed) {
+ generator.observable_for(object);
+ object = $.extend(object, mixin);
+ }
+
+ return object;
};
var ignores = document.createElement('fix'), fix_ignores = [], property;
for (property in ignores) {
@@ -149,13 +164,12 @@
};
observable.ignores = [];
}
-
observable.unobserve = function (object) {
- var name, value, subname;
+ var name, value, subname, unobserved = {};
// TODO remove root setter and root getter and callbacks from
// callback thread
// Remove mixed in properties
@@ -164,10 +178,11 @@
}
// Remove array properties overrides
for (name in object) {
value = object[name];
+
if ($.type(value) == 'array') {
delete value.thread;
delete value.object;
delete value.key;
@@ -175,12 +190,20 @@
delete value[subname];
}
}
}
+ for (name in object) {
+ // TODO put Array.indexOf as a dependency
+ if (observable.ignores && observable.ignores.indexOf(name) == -1) {
+ unobserved[name] = object[name];
+ }
+ }
+
delete object.observed;
- return true;
+
+ return unobserved;
};
check = function (keypath, value) {
this.observed[keypath] = value;
@@ -188,22 +211,33 @@
(this.dirty === false && keypath != 'dirty') && (this.dirty = true);
return true;
};
generator = {
- observe: function(keypath, callback) {
+ // TODO pass object as parameter
+ observe: function (keypath, callback) {
return Object.defineProperty(this, keypath, {
get: generator.getter.call(this, keypath),
set: generator.setter.call(this, keypath, callback),
enumerable: true
});
},
observable_for: function (object) {
- return Object.defineProperty(object, 'observed', {
+ Object.defineProperty(object, 'observed', {
configurable: true,
enumerable: false,
value: {}
+ });
+
+ // TODO call the current object.toJSON after this method
+ return Object.defineProperty(object, 'toJSON', {
+ enumerable: false,
+ value: function () {
+ // TODO remove underscore dependency
+ return observable.unobserve(_.omit(this, observable.ignores));
+ // old_to_json()
+ }
});
},
// TODO improve readability
// TODO implement linked list