github.com/nicgrayson/terraform@v0.4.3-0.20150415203910-c4de50829380/website/source/assets/javascripts/lib/Base.js (about)

     1  /*
     2    Based on Base.js 1.1a (c) 2006-2010, Dean Edwards
     3    Updated to pass JSHint and converted into a module by Kenneth Powers
     4    License: http://www.opensource.org/licenses/mit-license.php
     5  */
     6  /*global define:true module:true*/
     7  /*jshint eqeqeq:true*/
     8  (function (name, global, definition) {
     9    if (typeof module !== 'undefined') {
    10      module.exports = definition();
    11    } else if (typeof define !== 'undefined' && typeof define.amd === 'object') {
    12      define(definition);
    13    } else {
    14      global[name] = definition();
    15    }
    16  })('Base', this, function () {
    17    // Base Object
    18    var Base = function () {};
    19  
    20    // Implementation
    21    Base.extend = function (_instance, _static) { // subclass
    22      var extend = Base.prototype.extend;
    23      // build the prototype
    24      Base._prototyping = true;
    25      var proto = new this();
    26      extend.call(proto, _instance);
    27      proto.base = function () {
    28        // call this method from any other method to invoke that method's ancestor
    29      };
    30      delete Base._prototyping;
    31      // create the wrapper for the constructor function
    32      //var constructor = proto.constructor.valueOf(); //-dean
    33      var constructor = proto.constructor;
    34      var klass = proto.constructor = function () {
    35          if (!Base._prototyping) {
    36            if (this._constructing || this.constructor === klass) { // instantiation
    37              this._constructing = true;
    38              constructor.apply(this, arguments);
    39              delete this._constructing;
    40            } else if (arguments[0] !== null) { // casting
    41              return (arguments[0].extend || extend).call(arguments[0], proto);
    42            }
    43          }
    44        };
    45      // build the class interface
    46      klass.ancestor = this;
    47      klass.extend = this.extend;
    48      klass.forEach = this.forEach;
    49      klass.implement = this.implement;
    50      klass.prototype = proto;
    51      klass.toString = this.toString;
    52      klass.valueOf = function (type) {
    53        return (type === 'object') ? klass : constructor.valueOf();
    54      };
    55      extend.call(klass, _static);
    56      // class initialization
    57      if (typeof klass.init === 'function') klass.init();
    58      return klass;
    59    };
    60  
    61    Base.prototype = {
    62      extend: function (source, value) {
    63        if (arguments.length > 1) { // extending with a name/value pair
    64          var ancestor = this[source];
    65          if (ancestor && (typeof value === 'function') && // overriding a method?
    66          // the valueOf() comparison is to avoid circular references
    67          (!ancestor.valueOf || ancestor.valueOf() !== value.valueOf()) && /\bbase\b/.test(value)) {
    68            // get the underlying method
    69            var method = value.valueOf();
    70            // override
    71            value = function () {
    72              var previous = this.base || Base.prototype.base;
    73              this.base = ancestor;
    74              var returnValue = method.apply(this, arguments);
    75              this.base = previous;
    76              return returnValue;
    77            };
    78            // point to the underlying method
    79            value.valueOf = function (type) {
    80              return (type === 'object') ? value : method;
    81            };
    82            value.toString = Base.toString;
    83          }
    84          this[source] = value;
    85        } else if (source) { // extending with an object literal
    86          var extend = Base.prototype.extend;
    87          // if this object has a customized extend method then use it
    88          if (!Base._prototyping && typeof this !== 'function') {
    89            extend = this.extend || extend;
    90          }
    91          var proto = {
    92            toSource: null
    93          };
    94          // do the "toString" and other methods manually
    95          var hidden = ['constructor', 'toString', 'valueOf'];
    96          // if we are prototyping then include the constructor
    97          for (var i = Base._prototyping ? 0 : 1; i < hidden.length; i++) {
    98            var h = hidden[i];
    99            if (source[h] !== proto[h])
   100              extend.call(this, h, source[h]);
   101          }
   102          // copy each of the source object's properties to this object
   103          for (var key in source) {
   104            if (!proto[key]) extend.call(this, key, source[key]);
   105          }
   106        }
   107        return this;
   108      }
   109    };
   110  
   111    // initialize
   112    Base = Base.extend({
   113      constructor: function () {
   114        this.extend(arguments[0]);
   115      }
   116    }, {
   117      ancestor: Object,
   118      version: '1.1',
   119      forEach: function (object, block, context) {
   120        for (var key in object) {
   121          if (this.prototype[key] === undefined) {
   122            block.call(context, object[key], key, object);
   123          }
   124        }
   125      },
   126      implement: function () {
   127        for (var i = 0; i < arguments.length; i++) {
   128          if (typeof arguments[i] === 'function') {
   129            // if it's a function, call it
   130            arguments[i](this.prototype);
   131          } else {
   132            // add the interface using the extend method
   133            this.prototype.extend(arguments[i]);
   134          }
   135        }
   136        return this;
   137      },
   138      toString: function () {
   139        return String(this.valueOf());
   140      }
   141    });
   142  
   143    // Return Base implementation
   144    return Base;
   145  });