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