JSFiddle - React, Tailwind, and code Playground

by gschutz

HTML

<script src="https://cdn.rawgit.com/lodash/lodash/3.10.1/lodash.js"></script>

JavaScript

!function(exports){
  'use strict';
    
  var extension = [];

  function $extend(source) {
    this.$extend = function(name, ctr, singleton) {
        
        // add the extension to a list
        extension.push({parent: source.name, name: name, extension: ctr, singleton: singleton, thisArgs: this});
        
        // add to the object as well
        source.prototype[name] = ctr;
        
        return this;
    }
  }
    
  function $applyExtension(source, n) {
      
      _.each(_.filter(extension, {parent: source}), function(ext) {
        if (_.isPlainObject(ext.extension)) {
            ext.extension.$parent = n;
        	n[ext.name] = ext.extension;
            
            $applyExtension(ext.name, ext.extension);
        } else if (typeof ext.extension == "function" && ext.singleton === false) {
            n[ext.name] = function() {
                var ne = ext.extension.apply({$parent: n}, arguments);
                
                $applyExtension(ext.name, ne);
                
                return ne;
            };
        } else if (typeof ext.extension == "function" && ext.singleton === true) {
            ext.extension.prototype.$parent = this;
            
			n[ext.name] = (function() {
                var instance;
                
                return function() {
                    if (!instance) {
                        instance = new (Function.prototype.bind.apply(ext.extension, [ext.extension].concat(_.toArray(arguments))));
                        
                        $applyExtension(ext.name, instance);
                    }
                    
                    return instance;
                };
            }());
        } else if (typeof ext.extension == "function") {
            
            n[ext.name] = function() {
                var ne = new (Function.prototype.bind.apply(ext.extension, [ext.extension].concat(_.toArray(arguments))));
                
                ne.$parent = n;
                
       ...