/**
* Extend a sub class from base class
* @param {object|Function} makeDefaultOpt default option of this sub class, method of the sub can use this.xxx to access this option
* @param {Function} [initialize] Initialize after the sub class is instantiated
* @param {Object} [proto] Prototype methods/properties of the sub class
* @memberOf clay.core.mixin.extend
* @return {Function}
*/
function derive(makeDefaultOpt, initialize/*optional*/, proto/*optional*/) {
if (typeof initialize == 'object') {
proto = initialize;
initialize = null;
}
var _super = this;
var propList;
if (!(makeDefaultOpt instanceof Function)) {
// Optimize the property iterate if it have been fixed
propList = [];
for (var propName in makeDefaultOpt) {
if (makeDefaultOpt.hasOwnProperty(propName)) {
propList.push(propName);
}
}
}
var sub = function(options) {
// call super constructor
_super.apply(this, arguments);
if (makeDefaultOpt instanceof Function) {
// Invoke makeDefaultOpt each time if it is a function, So we can make sure each
// property in the object will not be shared by mutiple instances
extend(this, makeDefaultOpt.call(this, options));
}
else {
extendWithPropList(this, makeDefaultOpt, propList);
}
if (this.constructor === sub) {
// Initialize function will be called in the order of inherit
var initializers = sub.__initializers__;
for (var i = 0; i < initializers.length; i++) {
initializers[i].apply(this, arguments);
}
}
};
// save super constructor
sub.__super__ = _super;
// Initialize function will be called after all the super constructor is called
if (!_super.__initializers__) {
sub.__initializers__ = [];
} else {
sub.__initializers__ = _super.__initializers__.slice();
}
if (initialize) {
sub.__initializers__.push(initialize);
}
var Ctor = function() {};
Ctor.prototype = _super.prototype;
sub.prototype = new Ctor();
sub.prototype.constructor = sub;
extend(sub.prototype, proto);
// extend the derive method as a static method;
sub.extend = _super.extend;
// DEPCRATED
sub.derive = _super.extend;
return sub;
}
function extend(target, source) {
if (!source) {
return;
}
for (var name in source) {
if (source.hasOwnProperty(name)) {
target[name] = source[name];
}
}
}
function extendWithPropList(target, source, propList) {
for (var i = 0; i < propList.length; i++) {
var propName = propList[i];
target[propName] = source[propName];
}
}
/**
* @alias clay.core.mixin.extend
* @mixin
*/
export default {
extend: derive,
// DEPCRATED
derive: derive
};