(function() { if (typeof(console) === "undefined") { // Even IE9 only exposes console object if debug window opened window.console = {}; ('log error debug info warn assert clear dir dirxml trace group' + ' groupCollapsed groupEnd time timeEnd profile profileEnd count' + ' exception').split(/\s+/).forEach(function(property) { console[property] = _.identity; }); } var instance = openerp; openerp.web.core = {}; var ControllerMixin = { /** * Informs the action manager to do an action. This supposes that * the action manager can be found amongst the ancestors of the current widget. * If that's not the case this method will simply return `false`. */ do_action: function() { var parent = this.getParent(); if (parent) { return parent.do_action.apply(parent, arguments); } return false; }, do_notify: function() { if (this.getParent()) { return this.getParent().do_notify.apply(this,arguments); } return false; }, do_warn: function() { if (this.getParent()) { return this.getParent().do_warn.apply(this,arguments); } return false; }, rpc: function(url, data, options) { return this.alive(openerp.session.rpc(url, data, options)); } }; /** A class containing common utility methods useful when working with OpenERP as well as the PropertiesMixin. */ openerp.web.Controller = openerp.web.Class.extend(openerp.web.PropertiesMixin, ControllerMixin, { /** * Constructs the object and sets its parent if a parent is given. * * @param {openerp.web.Controller} parent Binds the current instance to the given Controller instance. * When that controller is destroyed by calling destroy(), the current instance will be * destroyed too. Can be null. */ init: function(parent) { openerp.web.PropertiesMixin.init.call(this); this.setParent(parent); this.session = openerp.session; }, }); openerp.web.Widget.include(_.extend({}, ControllerMixin, { init: function() { this._super.apply(this, arguments); this.session = openerp.session; }, })); instance.web.Registry = instance.web.Class.extend({ /** * Stores a mapping of arbitrary key (strings) to object paths (as strings * as well). * * Resolves those paths at query time in order to always fetch the correct * object, even if those objects have been overloaded/replaced after the * registry was created. * * An object path is simply a dotted name from the instance root to the * object pointed to (e.g. ``"instance.web.Session"`` for an OpenERP * session object). * * @constructs instance.web.Registry * @param {Object} mapping a mapping of keys to object-paths */ init: function (mapping) { this.parent = null; this.map = mapping || {}; }, /** * Retrieves the object matching the provided key string. * * @param {String} key the key to fetch the object for * @param {Boolean} [silent_error=false] returns undefined if the key or object is not found, rather than throwing an exception * @returns {Class} the stored class, to initialize or null if not found */ get_object: function (key, silent_error) { var path_string = this.map[key]; if (path_string === undefined) { if (this.parent) { return this.parent.get_object(key, silent_error); } if (silent_error) { return void 'nooo'; } return null; } var object_match = instance; var path = path_string.split('.'); // ignore first section for(var i=1; i', { 'href': self.url(file, null), 'rel': 'stylesheet', 'type': 'text/css' })); }); }, load_js: function(files) { var self = this; var d = $.Deferred(); if(files.length !== 0) { var file = files.shift(); var tag = document.createElement('script'); tag.type = 'text/javascript'; tag.src = self.url(file, null); tag.onload = tag.onreadystatechange = function() { if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done ) return; tag.onload_done = true; self.load_js(files).done(function () { d.resolve(); }); }; var head = document.head || document.getElementsByTagName('head')[0]; head.appendChild(tag); } else { d.resolve(); } return d; }, load_qweb: function(files) { var self = this; _.each(files, function(file) { self.qweb_mutex.exec(function() { return self.rpc('/web/proxy/load', {path: file}).then(function(xml) { if (!xml) { return; } instance.web.qweb.add_template(_.str.trim(xml)); }); }); }); return self.qweb_mutex.def; }, on_modules_loaded: function() { for(var j=0; j'); var complete = function () { if (options.complete) { options.complete(); } clearTimeout(timer); $form_data.remove(); $target.remove(); if (remove_form && $form) { $form.remove(); } }; var $target = $('