/*--------------------------------------------------------- * OpenERP Web Boostrap Code *---------------------------------------------------------*/ /** * @name openerp * @namespace openerp * * Each module can return a deferred. In that case, the module is marked as loaded * only when the deferred is resolved, and its value is equal to the resolved value. * The module can be rejected (unloaded). This will be logged in the console as info. * * logs: * Missing dependencies: * These modules do not appear in the page. It is possible that the * JavaScript file is not in the page or that the module name is wrong * Failed modules: * A javascript error is detected * Rejected modules: * The module returns a rejected deferred. It (and its dependent modules) * is not loaded. * Rejected linked modules: * Modules who depend on a rejected module * Non loaded modules: * Modules who depend on a missing or a failed module * Debug: * Non loaded or failed module informations for debugging */ (function() { "use strict"; var jobs = []; var factories = Object.create(null); var job_names = []; var job_deps = []; var job_deferred = []; var services = Object.create({}); var commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg; var cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g; var debug = ($.deparam($.param.querystring()).debug !== undefined); var flectra = window.flectra = window.flectra || {}; _.extend(flectra, { testing: typeof QUnit === "object", debug: debug, remaining_jobs: jobs, __DEBUG__: { didLogInfo: $.Deferred(), get_dependencies: function (name, transitive) { var deps = name instanceof Array ? name: [name], changed; do { changed = false; _.each(job_deps, function (dep) { if (_.contains(deps, dep.to) && (!_.contains(deps, dep.from))) { deps.push(dep.from); changed = true; } }); } while (changed && transitive); return deps; }, get_dependents: function (name) { return _.pluck(_.where(job_deps, {from: name}), 'to'); }, get_waited_jobs: function () { return _.uniq(_.map(jobs, function(job) {return job.name;})); }, get_missing_jobs: function () { var self = this; var waited = this.get_waited_jobs(); var missing = []; _.each(waited, function(job) { _.each(self.get_dependencies(job), function(job) { if (!(job in self.services)) { missing.push(job); } }); }); return _.filter(_.difference(_.uniq(missing), waited), function (job) {return !job.error;}); }, get_failed_jobs: function () { return _.filter(jobs, function (job) {return !!job.error;}); }, factories: factories, services: services, }, define: function () { var args = Array.prototype.slice.call(arguments); var name = typeof args[0] === 'string' ? args.shift() : _.uniqueId('__job'); var factory = args[args.length - 1]; var deps; if (args[0] instanceof Array) { deps = args[0]; } else { deps = []; factory.toString() .replace(commentRegExp, '') .replace(cjsRequireRegExp, function (match, dep) { deps.push(dep); }); } if (flectra.debug) { if (!(deps instanceof Array)) { throw new Error ('Dependencies should be defined by an array', deps); } if (typeof factory !== 'function') { throw new Error ('Factory should be defined by a function', factory); } if (typeof name !== 'string') { throw new Error("Invalid name definition (should be a string", name); } if (name in factories) { throw new Error("Service " + name + " already defined"); } } factory.deps = deps; factories[name] = factory; jobs.push({ name: name, factory: factory, deps: deps, }); job_names.push(name); _.each(deps, function (dep) { job_deps.push({from:dep, to:name}); }); this.process_jobs(jobs, services); }, log: function () { var missing = []; var failed = []; if (jobs.length) { var debug_jobs = {}; var rejected = []; var rejected_linked = []; var job; var jobdep; for (var k=0; k