flectra/addons/web/static/src/js/boot.js
flectra-admin 769eafb483 [INIT] Inception of Flectra from Odoo
Flectra is Forked from Odoo v11 commit : (6135e82d73)
2018-01-16 11:45:59 +05:30

292 lines
11 KiB
JavaScript

/*---------------------------------------------------------
* 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 odoo = window.odoo = window.odoo || {};
_.extend(odoo, {
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 (odoo.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<jobs.length; k++) {
debug_jobs[jobs[k].name] = job = {
dependencies: jobs[k].deps,
dependents: odoo.__DEBUG__.get_dependents(jobs[k].name),
name: jobs[k].name
};
if (jobs[k].error) {
job.error = jobs[k].error;
}
if (jobs[k].rejected) {
job.rejected = jobs[k].rejected;
rejected.push(job.name);
}
var deps = odoo.__DEBUG__.get_dependencies( job.name );
for (var i=0; i<deps.length; i++) {
if (job.name !== deps[i] && !(deps[i] in services)) {
jobdep = debug_jobs[deps[i]] || (deps[i] in factories && _.find(jobs, function (job) { return job.name === deps[i];}));
if (jobdep && jobdep.rejected) {
if (!job.rejected) {
job.rejected = [];
rejected_linked.push(job.name);
}
job.rejected.push(deps[i]);
} else {
if (!job.missing) {
job.missing = [];
}
job.missing.push(deps[i]);
}
}
}
}
missing = odoo.__DEBUG__.get_missing_jobs();
failed = odoo.__DEBUG__.get_failed_jobs();
var unloaded = _.filter(debug_jobs, function (job) { return job.missing; });
if (odoo.debug || !_.isEmpty(failed) || !_.isEmpty(unloaded)) {
var log = console[_.isEmpty(failed) || _.isEmpty(unloaded) ? 'info' : 'error'].bind(console);
log((_.isEmpty(failed) ? (_.isEmpty(unloaded) ? 'info' : 'warning') : 'error') + ': Some modules could not be started');
if (missing.length) {
log('Missing dependencies: ', missing);
}
if (!_.isEmpty(failed)) {
log('Failed modules: ', _.pluck(failed, 'name'));
}
if (!_.isEmpty(rejected)) {
log('Rejected modules: ', rejected);
}
if (!_.isEmpty(rejected_linked)) {
log('Rejected linked modules: ', rejected_linked);
}
if (!_.isEmpty(unloaded)) {
log('Non loaded modules: ', _.pluck(unloaded, 'name'));
}
if (odoo.debug && !_.isEmpty(debug_jobs)) {
log('Debug: ', debug_jobs);
}
}
}
odoo.__DEBUG__.js_modules = {
missing: missing,
failed: _.pluck(failed, 'name'),
};
odoo.__DEBUG__.didLogInfo.resolve();
},
process_jobs: function (jobs, services) {
var job;
function process_job (job) {
var require = make_require(job);
var job_exec;
var def = $.Deferred();
try {
job_exec = job.factory.call(null, require);
jobs.splice(jobs.indexOf(job), 1);
job_deferred.push(def);
} catch (e) {
job.error = e;
}
if (!job.error) {
$.when(job_exec).then(
function (data) {
services[job.name] = data;
def.resolve();
odoo.process_jobs(jobs, services);
}, function (e) {
job.rejected = e || true;
jobs.push(job);
def.resolve();
}
);
}
}
function is_ready (job) {
return !job.error && !job.rejected && _.every(job.factory.deps, function (name) { return name in services; });
}
function make_require (job) {
var deps = _.pick(services, job.deps);
function require (name) {
if (!(name in deps)) {
console.error('Undefined dependency: ', name);
} else {
require.__require_calls++;
}
return deps[name];
}
require.__require_calls = 0;
return require;
}
while (jobs.length && (job = _.find(jobs, is_ready))) {
process_job(job);
}
return services;
}
});
// automatically log errors detected when loading modules
var log_when_loaded = function () {
_.delay(function () {
var len = job_deferred.length;
$.when.apply($, job_deferred).then(function () {
if (len === job_deferred.length) {
odoo.log();
} else {
log_when_loaded();
}
});
}, 4000);
};
$(log_when_loaded);
})();