all files / src/core/mixin/ extend.js

97.56% Statements 40/41
83.33% Branches 15/18
100% Functions 5/5
97.56% Lines 40/41
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107                    61× 26× 26×     61×     61×   32× 32× 160× 160×         61×     1131×   1131×     503×     628×     1131×   593× 593× 1586×         61×   61×     61×   61× 33×     61× 61× 61× 61× 61×     61×     61×   61×       564×   562× 4066× 4066×           628× 3860× 3860×                            
/**
 * 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) {
            Eif (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
    Iif (!_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) {
        Eif (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
};