diff options
| author | niv-openerp <nicolas.vanhoren@openerp.com> | 2011-07-18 17:29:54 +0200 |
|---|---|---|
| committer | niv-openerp <nicolas.vanhoren@openerp.com> | 2011-07-18 17:29:54 +0200 |
| commit | da5f320a0a72c0fa4bcf2a415556f469104402da (patch) | |
| tree | 1a9debd7b7c2d204fa0c17774a7a6152fd9405de /addons/base/static/src/js/controller.js | |
| parent | 193fc86c38fb2a3241e16b6afcc79627f4c1886a (diff) | |
| parent | 711b22f52cb4876509abbdc029dd6a1303b474f9 (diff) | |
[merge]
bzr revid: nicolas.vanhoren@openerp.com-20110718152954-1osrwsxmyij4wkun
Diffstat (limited to 'addons/base/static/src/js/controller.js')
| -rw-r--r-- | addons/base/static/src/js/controller.js | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/addons/base/static/src/js/controller.js b/addons/base/static/src/js/controller.js new file mode 100644 index 00000000000..a5c7bca4b53 --- /dev/null +++ b/addons/base/static/src/js/controller.js @@ -0,0 +1,216 @@ +/*--------------------------------------------------------- + * OpenERP controller framework + *--------------------------------------------------------*/ + +openerp.base.controller = function(instance) { +/** + * John Resig Class with factory improvement + */ +(function() { + var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; + // The base Class implementation (does nothing) + this.Class = function(){}; + + // Create a new Class that inherits from this class + Class.extend = function(prop) { + var _super = this.prototype; + + // Instantiate a base class (but only create the instance, + // don't run the init constructor) + initializing = true; + var prototype = new this(); + initializing = false; + + // Copy the properties over onto the new prototype + for (var name in prop) { + // Check if we're overwriting an existing function + prototype[name] = typeof prop[name] == "function" && + typeof _super[name] == "function" && fnTest.test(prop[name]) ? + (function(name, fn){ + return function() { + var tmp = this._super; + + // Add a new ._super() method that is the same method + // but on the super-class + this._super = _super[name]; + + // The method only need to be bound temporarily, so we + // remove it when we're done executing + var ret = fn.apply(this, arguments); + this._super = tmp; + + return ret; + }; + })(name, prop[name]) : + prop[name]; + } + + // The dummy class constructor + function Class() { + // All construction is actually done in the init method + if ( !initializing && this.init ) { + var ret = this.init.apply(this, arguments); + if (ret) { return ret; } + } + return this; + } + + // Populate our constructed prototype object + Class.prototype = prototype; + + // Enforce the constructor to be what we expect + Class.constructor = Class; + + // And make this class extendable + Class.extend = arguments.callee; + + return Class; + }; +})(instance.base); + +// todo change john resig class to keep window clean +instance.base.Class = window.Class + +instance.base.callback = function(obj, method) { + var callback = function() { + var args = Array.prototype.slice.call(arguments); + var r; + for(var i = 0; i < callback.callback_chain.length; i++) { + var c = callback.callback_chain[i]; + if(c.unique) { + callback.callback_chain.splice(i, 1); + i -= 1; + } + r = c.callback.apply(c.self, c.args.concat(args)); + // TODO special value to stop the chain + // openerp.base.callback_stop + } + return r; + }; + callback.callback_chain = []; + callback.add = function(f) { + if(typeof(f) == 'function') { + f = { callback: f, args: Array.prototype.slice.call(arguments, 1) }; + } + f.self = f.self || null; + f.args = f.args || []; + f.unique = !!f.unique; + if(f.position == 'last') { + callback.callback_chain.push(f); + } else { + callback.callback_chain.unshift(f); + } + return callback; + }; + callback.add_first = function(f) { + return callback.add.apply(null,arguments); + }; + callback.add_last = function(f) { + return callback.add({ + callback: f, + args: Array.prototype.slice.call(arguments, 1), + position: "last" + }); + }; + + return callback.add({ + callback: method, + self:obj, + args:Array.prototype.slice.call(arguments, 2) + }); +}; + +/** + * OpenERP Controller + */ +instance.base.BasicController = instance.base.Class.extend( /** @lends instance.base.BasicController# */{ + /** + * rpc operations, event binding and callback calling should be done in + * start() instead of init so that event can be hooked in between. + * + * @constructs + */ + init: function(parent, element_id) { + this.element_id = element_id; + this.$element = $('#' + element_id); + if (element_id) { + instance.screen[element_id] = this; + } + // save the parent children relationship + this.controller_parent = null; + this.controller_children = []; + this.parent = parent; + if(this.parent && this.parent.children) { + this.parent.children.push(this); + } + + // Transform on_* method into openerp.base.callbacks + for (var name in this) { + if(typeof(this[name]) == "function") { + this[name].debug_name = name; + // bind ALL function to this not only on_and _do ? + if((/^on_|^do_/).test(name)) { + this[name] = instance.base.callback(this, this[name]); + } + } + } + }, + /** + * Controller start + * event binding, rpc and callback calling required to initialize the + * object can happen here + * + * Returns a promise object letting callers (subclasses and direct callers) + * know when this component is done starting + * + * @returns {jQuery.Deferred} + */ + start: function() { + // returns an already fulfilled promise. Maybe we could return nothing? + // $.when can take non-deferred and in that case it simply considers + // them all as fulfilled promises. + // But in thise case we *have* to ensure callers use $.when and don't + // try to call deferred methods on this return value. + return $.Deferred().done().promise(); + }, + stop: function() { + }, + log: function() { + var args = Array.prototype.slice.call(arguments); + var caller = arguments.callee.caller; + // TODO add support for line number using + // https://github.com/emwendelin/javascript-stacktrace/blob/master/stacktrace.js + // args.unshift("" + caller.debug_name); + this.on_log.apply(this,args); + }, + on_log: function() { + if(window.openerp.debug || (window.location.search.indexOf('?debug') !== -1)) { + var notify = false; + var body = false; + if(window.console) { + console.log(arguments); + } else { + body = true; + } + var a = Array.prototype.slice.call(arguments, 0); + for(var i = 0; i < a.length; i++) { + var v = a[i]==null ? "null" : a[i].toString(); + if(i==0) { + notify = v.match(/^not/); + body = v.match(/^bod/); + } + if(body) { + $('<pre></pre>').text(v).appendTo($('body')); + } + if(notify && this.notification) { + this.notification.notify("Logging:",v); + } + } + } + + } +}); + +}; + +// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: |
