Created
November 16, 2012 09:06
-
-
Save Saneyan/4085688 to your computer and use it in GitHub Desktop.
Module Manager (Prototype)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var wic = wic || {}; | |
| wic.Module = function(){ | |
| var _id | |
| , _detail | |
| , _children = {}; | |
| /* | |
| * @param object destination | |
| * @param object source | |
| * @return object | |
| */ | |
| var _extend = function( destination, source ){ | |
| for( var key in source ) | |
| destination[ key ] = source[ key ]; | |
| return destination; | |
| }; | |
| /* | |
| * @param string key | |
| * @param object obj (Must be wic.Module instance) | |
| */ | |
| var _addChild = function( key, obj ){ | |
| var child = { | |
| object: obj | |
| , configuration: { | |
| modifiable: true | |
| , deletable: true | |
| , overwritable: true | |
| , attachable: true | |
| , detachable: true | |
| , freezable: true | |
| , setter: null | |
| , getter: null | |
| } | |
| , listeners: { | |
| set: [] | |
| , get: [] | |
| , del: [] | |
| , has: [] | |
| , modify: [] | |
| , trigger: [] | |
| , number: 0 | |
| } | |
| , statuses: { | |
| modified: false | |
| , overwritten: false | |
| , attached: false | |
| , detached: false | |
| , frozen: false | |
| } | |
| }; | |
| _children[ key ] = child; | |
| }; | |
| var _getChild = function( target, preventException ){ | |
| var child = _children[ target ]; | |
| if( child ){ | |
| if( child.statuses.frozen === false ) | |
| return child; | |
| else if( preventException !== true ) | |
| throw "'" + target + "' is frozen"; | |
| } | |
| else{ | |
| throw "'" + target + "' does not exist in this module"; | |
| } | |
| }; | |
| /* | |
| * @param string target | |
| * @param object obj | |
| */ | |
| var _overwriteChild = function( target, obj ){ | |
| var child = _getChild( target ) | |
| , conf = child.configuration; | |
| if( conf.overwritable === true ){ | |
| if( conf.setter ) | |
| conf.setter.apply( child.object, [ obj ] ); | |
| else | |
| child.object = obj; | |
| child.statuses.overwritten = true; | |
| } | |
| else | |
| throw "'" + target + "' cannot be overwritten because of permission"; | |
| }; | |
| /* | |
| * @param string target | |
| * @return true || false (If specific child exists, | |
| * it'll return true; otherwise return false) | |
| */ | |
| var _hasChild = function( target ){ | |
| return !!_children[ target ]; | |
| }; | |
| var _callListeners = function( type, target ){ | |
| var child = _children[ target ] | |
| , listeners = child.listeners[ type ]; | |
| for( var i = 0; listeners[ i ]; i++ ) | |
| listeners[ i ](); | |
| }; | |
| _extend( this, { | |
| set: function(){ | |
| if( arguments.length > 0 ){ | |
| var obj; | |
| if( arguments.length === 1 ){ | |
| obj = arguments[ 0 ]; | |
| } | |
| else if( arguments.length === 2 ){ | |
| obj = {}; | |
| obj[ arguments[ 0 ] ] = arguments[ 1 ]; | |
| } | |
| for( var key in obj ){ | |
| if( _hasChild( key ) === true ){ | |
| _overwriteChild( key, obj[ key ] ); | |
| _callListeners( 'set', key ); | |
| } | |
| else{ | |
| _addChild( key, obj[ key ] ); | |
| } | |
| } | |
| } | |
| else{ | |
| throw "No arguments assigned"; | |
| } | |
| } | |
| , get: function( target ){ | |
| var res, child, conf; | |
| if( target == '*' ){ | |
| res = {} | |
| for( var key in _children ){ | |
| child = _getChild( key, true ); | |
| if( !child ) | |
| continue; | |
| conf = child.configuration; | |
| if( conf.getter ) | |
| res[ key ] = conf.getter.apply( child.object, [] ); | |
| else | |
| res[ key ] = child.object; | |
| } | |
| } | |
| else{ | |
| child = _getChild( target ); | |
| conf = child.configuration; | |
| if( conf.getter ) | |
| res = conf.getter.apply( child.object, [] ); | |
| else | |
| res = child.object; | |
| _callListeners( 'get', target ); | |
| } | |
| return res; | |
| } | |
| , isModifiable: function( target ){ | |
| return _getChild( target ).configuration.modifiable; | |
| } | |
| , isDeletable: function( target ){ | |
| return _getChild( target ).configuration.deletable; | |
| } | |
| , isOverwritable: function( target ){ | |
| return _getChild( target ).configuration.overwritable; | |
| } | |
| , isAttachable: function( target ){ | |
| return _getChild( target ).configuration.attachable; | |
| } | |
| , isDetachable: function( target ){ | |
| return _getChild( target ).configuration.detachable; | |
| } | |
| , isFreezable: function( target ){ | |
| return _getChild( target ).configuration.freezable; | |
| } | |
| , isModified: function( target ){ | |
| return _getChild( target ).statuses.modified; | |
| } | |
| , isOverwritten: function( target ){ | |
| return _getChild( target ).statuses.overwritten; | |
| } | |
| , isAttached: function( target ){ | |
| return _getChild( target ).statuses.attached; | |
| } | |
| , isDetached: function( target ){ | |
| return _getChild( target ).statuses.detached; | |
| } | |
| , isFrozen: function( target ){ | |
| return _getChild( target ).statuses.frozen; | |
| } | |
| , isset: function( target ){ | |
| var res = _hasChild( target ); | |
| if( res === true ) | |
| _callListeners( 'has', target ); | |
| return res; | |
| } | |
| , hasSetter: function( target ){ | |
| return !!_getChild( target ).setter; | |
| } | |
| , hasGetter: function( target ){ | |
| return !!_getChild( target ).getter; | |
| } | |
| , del: function(){ | |
| var child, target; | |
| for( var i = 0; arguments[ i ]; i++ ){ | |
| target = arguments[ i ]; | |
| child = _getChild( target ); | |
| if( child.configuration.deletable === true ){ | |
| _callListeners( 'del', target ); | |
| delete _children[ target ]; | |
| } | |
| else{ | |
| throw "'" + target + "' cannot be deleted because of permission"; | |
| } | |
| } | |
| } | |
| , modify: function( target, configuration ){ | |
| var child = _getChild( target ) | |
| , conf = child.configuration; | |
| if( conf.modifiable === true ){ | |
| for( var key in configuration ){ | |
| if(( | |
| key.match( /modifiable|deletable|overwritable|attachable|detachable|freezable/ ) | |
| && typeof configuration[ key ] == 'boolean' | |
| ) || ( | |
| key.match( /setter|getter/ ) | |
| && typeof configuration[ key ] == 'function' || configuration[ key ] === null | |
| )) | |
| conf[ key ] = configuration[ key ]; | |
| } | |
| child.statuses.modified = true; | |
| _callListeners( 'modify', target ); | |
| } | |
| else{ | |
| throw "'" + target + "' cannot be modified because of permission"; | |
| } | |
| } | |
| , lock: function(){ | |
| var target, conf; | |
| for( var i = 0; arguments[ i ]; i++ ){ | |
| target = arguments[ i ]; | |
| conf = _getChild( target ).configuration; | |
| if( conf.modifiable === true ){ | |
| for( var key in conf ){ | |
| if( !key.match( /setter|getter/ ) ) | |
| conf[ key ] = false; | |
| } | |
| } | |
| else{ | |
| throw "'" + target + "' cannot be modified because of permission"; | |
| } | |
| } | |
| } | |
| , trigger: function( target, arg ){ | |
| var obj = _getChild( target ).object; | |
| if( typeof obj == 'function' ){ | |
| obj.apply( null, arg ); | |
| _callListeners( 'trigger', target ); | |
| } | |
| else{ | |
| throw "'" + target + "' is not function"; | |
| } | |
| } | |
| , attach: function( type, target, listener ){ | |
| var child = _getChild( target ); | |
| if( child.listeners[ type ] ){ | |
| if( child.configuration.attachable === true ){ | |
| child.listeners[ type ].push( listener ); | |
| child.listeners.number++; | |
| child.statuses.attached = true; | |
| } | |
| else{ | |
| throw "'" + target + "' cannot be attached a listener because of permission"; | |
| } | |
| } | |
| } | |
| , detach: function( type, target, targetListener ){ | |
| var listener | |
| , listeners | |
| , child = getChild( target ); | |
| if( child.listeners[ type ] ){ | |
| if( child.detachable === true ){ | |
| listeners = child.listeners[ type ]; | |
| for( var i = 0; listeners[ i ]; i++ ){ | |
| listener = listeners[ i ]; | |
| if( listener === targetListener ){ | |
| listeners.splice( i, 1 ); | |
| child.listeners.number--; | |
| if( child.listeners.number <= 0 ) | |
| child.statuses.detached = true; | |
| } | |
| } | |
| } | |
| else{ | |
| throw "'" + target + "' cannot be detached a listener because of permission"; | |
| } | |
| } | |
| } | |
| , freeze: function(){ | |
| var child, target; | |
| for( var i = 0; arguments[ i ]; i++ ){ | |
| target = arguments[ i ]; | |
| child = _getChild( target ); | |
| if( child.configuration.freezable === true ) | |
| child.statuses.frozen = true; | |
| else | |
| throw "'" + target + "' cannot be frozen because of permission"; | |
| } | |
| } | |
| }); | |
| _extend( this.set, { | |
| detail: function( detail ){ | |
| if( _detail === undefined ) | |
| _detail = detail; | |
| } | |
| , id: function( id ){ | |
| if( _id === undefined ) | |
| _id = id; | |
| } | |
| }); | |
| _extend( this.get, { | |
| detail: function(){ | |
| return _detail; | |
| } | |
| , id: function(){ | |
| return _id; | |
| } | |
| }); | |
| }; | |
| wic.modules = function( Module ){ | |
| var _modules = {} | |
| , _paths = {}; | |
| var _addModule = function( id, module ){ | |
| _modules[ id ] = module; | |
| }; | |
| var _require = function( src, success, error ){ | |
| var script = document.createElement( 'script' ); | |
| script.type = 'text/javascript'; | |
| script.src = src; | |
| script.onload = success; | |
| script.onerror = error; | |
| document.getElementsByTagName( 'head' ).item( 0 ).appendChild( script ); | |
| }; | |
| return { | |
| require: function( target, success, error ){ | |
| if( _modules[ target ] ){ | |
| return _modules[ target ]; | |
| } | |
| else{ | |
| var i = 0; | |
| var srcs = typeof target == 'string' ? [ target ] : target; | |
| for( var src, j = 0; srcs[ j ]; j++ ){ | |
| src = srcs[ j ]; | |
| if( _paths[ src ] ) | |
| srcs[ j ] = _paths[ src ]; | |
| } | |
| var repeat = function(){ | |
| i++; | |
| if( srcs.length > i ){ | |
| _require( srcs[ i ], repeat, error ); | |
| } | |
| else{ | |
| success( wic.modules.require, wic.modules.demand ); | |
| } | |
| }; | |
| _require( srcs[ i ], repeat, error ); | |
| } | |
| } | |
| , demand: function( target ){ | |
| if( _modules[ target ] ) | |
| return _modules[ target ].get( '*' ); | |
| } | |
| , add: function(){ | |
| if( arguments[ 0 ] instanceof Module ){ | |
| var module = arguments[ 0 ]; | |
| _addModule( module.get.id(), module ); | |
| } | |
| else{ | |
| var id = arguments[ 0 ] | |
| , define = arguments[ 1 ] | |
| , module = new Module(); | |
| module.set.id( id ); | |
| define.apply( module, [ this.require, this.demand ] ); | |
| _addModule( id, module ); | |
| } | |
| } | |
| , has: function( target ){ | |
| return _modules.hasOwnProperty( target ); | |
| } | |
| , configure: function( configuration ){ | |
| if( configuration.paths ){ | |
| for( var key in configuration.paths ) | |
| _paths[ key ] = configuration.paths[ key ]; | |
| } | |
| } | |
| }; | |
| }( wic.Module ); | |
| if( Object.seal ){ | |
| Object.seal( wic.modules ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment