155 lines
4.7 KiB
JavaScript
155 lines
4.7 KiB
JavaScript
odoo.define('web.Class', function () {
|
|
"use strict";
|
|
/**
|
|
* Improved John Resig's inheritance, based on:
|
|
*
|
|
* Simple JavaScript Inheritance
|
|
* By John Resig http://ejohn.org/
|
|
* MIT Licensed.
|
|
*
|
|
* Adds "include()"
|
|
*
|
|
* Defines The Class object. That object can be used to define and inherit classes using
|
|
* the extend() method.
|
|
*
|
|
* Example:
|
|
*
|
|
* var Person = Class.extend({
|
|
* init: function(isDancing){
|
|
* this.dancing = isDancing;
|
|
* },
|
|
* dance: function(){
|
|
* return this.dancing;
|
|
* }
|
|
* });
|
|
*
|
|
* The init() method act as a constructor. This class can be instancied this way:
|
|
*
|
|
* var person = new Person(true);
|
|
* person.dance();
|
|
*
|
|
* The Person class can also be extended again:
|
|
*
|
|
* var Ninja = Person.extend({
|
|
* init: function(){
|
|
* this._super( false );
|
|
* },
|
|
* dance: function(){
|
|
* // Call the inherited version of dance()
|
|
* return this._super();
|
|
* },
|
|
* swingSword: function(){
|
|
* return true;
|
|
* }
|
|
* });
|
|
*
|
|
* When extending a class, each re-defined method can use this._super() to call the previous
|
|
* implementation of that method.
|
|
*/
|
|
var initializing = false;
|
|
var fnTest = /xyz/.test(function(){xyz();}) ? /\b_super\b/ : /.*/;
|
|
|
|
// The web Class implementation (does nothing)
|
|
function OdooClass(){};
|
|
|
|
/**
|
|
* Subclass an existing class
|
|
*
|
|
* @param {Object} prop class-level properties (class attributes and instance methods) to set on the new class
|
|
*/
|
|
OdooClass.extend = function() {
|
|
var _super = this.prototype;
|
|
// Support mixins arguments
|
|
var args = _.toArray(arguments);
|
|
args.unshift({});
|
|
var prop = _.extend.apply(_,args);
|
|
|
|
// Instantiate a web class (but only create the instance,
|
|
// don't run the init constructor)
|
|
initializing = true;
|
|
var This = this;
|
|
var prototype = new This();
|
|
initializing = false;
|
|
|
|
// Copy the properties over onto the new prototype
|
|
_.each(prop, function(val, name) {
|
|
// Check if we're overwriting an existing function
|
|
prototype[name] = typeof prop[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() {
|
|
if(this.constructor !== OdooClass){
|
|
throw new Error("You can only instanciate objects with the 'new' operator");
|
|
}
|
|
// All construction is actually done in the init method
|
|
this._super = null;
|
|
if (!initializing && this.init) {
|
|
var ret = this.init.apply(this, arguments);
|
|
if (ret) { return ret; }
|
|
}
|
|
return this;
|
|
}
|
|
Class.include = function (properties) {
|
|
_.each(properties, function(val, name) {
|
|
if (typeof properties[name] !== 'function'
|
|
|| !fnTest.test(properties[name])) {
|
|
prototype[name] = properties[name];
|
|
} else if (typeof prototype[name] === 'function'
|
|
&& prototype.hasOwnProperty(name)) {
|
|
prototype[name] = (function (name, fn, previous) {
|
|
return function () {
|
|
var tmp = this._super;
|
|
this._super = previous;
|
|
var ret = fn.apply(this, arguments);
|
|
this._super = tmp;
|
|
return ret;
|
|
};
|
|
})(name, properties[name], prototype[name]);
|
|
} else if (typeof _super[name] === 'function') {
|
|
prototype[name] = (function (name, fn) {
|
|
return function () {
|
|
var tmp = this._super;
|
|
this._super = _super[name];
|
|
var ret = fn.apply(this, arguments);
|
|
this._super = tmp;
|
|
return ret;
|
|
};
|
|
})(name, properties[name]);
|
|
}
|
|
});
|
|
};
|
|
|
|
// 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 = this.extend;
|
|
|
|
return Class;
|
|
};
|
|
|
|
return OdooClass;
|
|
});
|