Забыл саму либу)
this.$jin = {}
$jin.value = function $jin_value( value ){
var func = function $jin_value_instance( ){
return func.$jin_value
}
func.$jin_value = value
return func
}
$jin.root = $jin.value( this )
$jin.glob = function $jin_glob( name, value ){
var keyList = name.split( '_' )
var current = $jin.root()
var currentName = ''
while( keyList.length > 1 ){
var key = keyList.shift() || 'prototype'
currentName += ( currentName ? '_' : '' ) + ( key === 'prototype' ? '' : key )
if(!( key in current )){
current[ key ] = $jin.trait.make( currentName )
}
current = current[ key ]
}
var key = keyList.shift() || 'prototype'
if( arguments.length > 1 ){
current[ key ] = value
} else {
value = current[ key ]
}
return value
}
$jin.lazy = function $jin_lazy( generator ){
if( typeof generator === 'string' ){
generator = $jin.lazy.glob( generator )
}
var lazy = function $jin_lazy_instance( ){
return lazy.$jin_lazy_func.apply( this, arguments )
}
lazy.$jin_lazy_gen = generator
lazy.$jin_lazy_func = function $jin_lazy_generate( ){
var func = lazy.$jin_lazy_func = lazy.$jin_lazy_gen()
return func.apply( this, arguments )
}
return lazy
}
$jin.lazy.glob = function $jin_lazy_glob( name ){
var lazy = function $jin_lazy_glob( ){
return $jin.glob( lazy.$jin_lazy_name )
}
lazy.$jin_lazy_name = name
return lazy
}
$jin.trait = function $jin_trait( name ){
var trait = $jin.glob( name )
if( trait ) return trait
trait = $jin.trait.make( name )
return $jin.glob( name, trait )
}
$jin.trait.make = function $jin_trait_make( name ){
eval( 'var trait= function ' + name + '( ){ \
return ( this instanceof trait ) ? this : trait.apply( trait, arguments ) \
}' )
trait.name = name
trait.apply = void 0
trait.prototype = {}
return trait
}
$jin.method = function $jin_method( ){ // arguments: resolveName*, func
var resolveList = [].slice.call( arguments )
var func = resolveList.pop()
var name = func.name = func.name || func.toString().match( /^\s*function\s*([$\w]*)\s*\(/ )[ 1 ]
if( !name ) throw new Error( 'Can not register anonymous function' )
func.$jin_method_name = func.$jin_method_name || name
func.$jin_method_resolveList = resolveList.concat( func.$jin_method_resolveList || [] )
$jin.method.define( name, func )
}
$jin.method.define = function $jin_method_define( name, func ){
var funcName = func.$jin_method_name
if( !funcName ) throw new Error( '$jin_method_name is not defined in [' + func + ']' )
var nameList = name.split( '_' )
var methodName = nameList.pop()
var ownerPath = nameList.join( '_' )
var owner = $jin.trait( ownerPath )
owner[ funcName ]= func
var existFunc = owner[ methodName ]
checkConflict: {
if( existFunc === void 0 ) break checkConflict
if( typeof existFunc !== 'function' ){
throw new Error( 'Can not redefine [' + existFunc + '] by [' + funcName + ']' )
}
if( func === existFunc ) return existFunc
if( !existFunc.$jin_method_name ) break checkConflict
func = $jin.method.merge( existFunc, func, name )
}
owner[ methodName ]= func
var slaveList = owner.$jin_mixin_slaveList
if( slaveList ) slaveList.forEach( function( slavePath ){
$jin.method.define( slavePath + '_' + methodName, func )
})
return func
}
$jin.method.merge = function $jin_method_merge( left, right, name ){
var leftConflicts = left.$jin_method_conflictList || [ left ]
var rightConflicts = right.$jin_method_conflictList || [ right ]
var conflictList = leftConflicts.concat( rightConflicts )
var leftResolves = left.$jin_method_resolveList || []
var rightResolves = right.$jin_method_resolveList || []
var resolveList = leftResolves.concat( rightResolves )
conflictList = conflictList.filter( function( conflict ){
return !~resolveList.indexOf( conflict.$jin_method_name )
})
if( conflictList.length === 0 ){
throw new Error( 'Can not resolve conflict ' + name + ' because cyrcullar resolving' )
} else if( conflictList.length === 1 ){
var func = conflictList[0]
} else if( conflictList.length > 1 ){
eval( 'var func= function ' + name + '( ){ \
throw new Error( "Conflict in [" + func.$jin_method_name + "] by [" + func.$jin_method_conflictList + "]" )\
}' )
func.$jin_method_name = name
func.$jin_method_conflictList = conflictList
}
func.$jin_method_resolveList = resolveList
return func
}
$jin.method.naming = function $jin_method_naming( name, owner ){
if( arguments.length < 2 ){
owner = $jin.glob( name )
}
for( var key in owner ){
if( !owner.hasOwnProperty( key ) ) continue
var value = owner[ key ]
if( Object( value ) !== value ) continue
$jin.method.naming( name + '_' + key, value )
}
if( typeof owner === 'function' && !owner.$jin_method_name ){
$jin.method.naming( name + '_', owner.prototype )
owner.$jin_method_name = name
owner.$jin_method_resolveList = [ '$jin_klass__constructor' ]
}
}
$jin.mixin = function( ){ // arguments: sourceName+, targetName
var trait = $jin.mixin.object.apply( this, arguments )
for( var index = 0; index < arguments.length; ++index ){
arguments[ index ] += '_'
}
$jin.mixin.object.apply( this, arguments )
return trait
}
$jin.mixin.object = function( ){ // arguments: sourceName+, targetName
var sourcePathList = [].slice.call( arguments )
var targetPath = sourcePathList.pop()
var target = $jin.trait( targetPath )
sourcePathList.forEach( function( sourcePath ){
var source = $jin.trait( sourcePath )
source.$jin_mixin_slaveList = source.$jin_mixin_slaveList || []
if( ~source.$jin_mixin_slaveList.indexOf( targetPath ) ) return
source.$jin_mixin_slaveList.push( targetPath )
for( var key in source ){
var func = source[ key ]
if( typeof func !== 'function' ) continue
if( !func.$jin_method_name ) continue
$jin.method.define( targetPath + '_' + key, func )
}
if( source.constructor && source.constructor.$jin_method_name ){
$jin.method.define( targetPath + '_constructor', source.constructor )
}
})
return target
}
$jin.property = function $jin_property( ){ // arguments: resolveName*, name, type
var resolveList = [].slice.call( arguments )
var type = resolveList.pop()
var name = resolveList.pop()
var fieldName = '_' + name
eval( 'var property = function ' + name + '( ){ \
return property.apply( this, arguments ) \
}' )
property.name = name
property.apply = function $jin_property_apply( obj, args ){
if( args.length ){
obj[ fieldName ] = property.$jin_property_ensureType( args[ 0 ] )
return obj
} else {
if( obj.hasOwnProperty( fieldName ) ){
return obj[ fieldName ]
} else {
return obj[ fieldName ] = property.$jin_property_ensureType()
}
}
}
if( typeof type === 'string' ) type = $jin.lazy.glob( type )
property.$jin_property_ensureType = type || function( value ){ return nvalue }
property.$jin_method_resolveList = resolveList
return $jin.method( property )
}
$jin.klass = function $jin_klass( ){ // arguments: sourceName*, targetName
$jin.mixin.apply( this, arguments )
var name = arguments[ arguments.length - 1 ]
return $jin.mixin( '$jin_klass', name )
}
$jin.method( function $jin_klass_apply( klass, args ){
var obj = new klass
obj.constructor.apply( obj, args )
return obj
} )
$jin.method( function $jin_klass_toString( ){
return this.name
} )
$jin.method( function $jin_klass__constructor( config ){
if( !config ) return this
for( var key in config ){
this[ key ]( config[ key ] )
}
return this
} )