<commit_before>/**
 * @author Camille Reynders
 * @namespace
 */
var dijon = {
	/**
	 * framework version number
	 * @constant
	 * @type String
	 */
	VERSION : '0.5.0'
};//dijon

  //======================================//
 // dijon.System
//======================================//

/**
 * @class dijon.System
 * @constructor
*/
dijon.System = function(){
	/** @private */
	this._mappings = {};

	/** @private */
	this._outlets = {};

    /** @private */
    this._handlers = {};

    /**
     * When true injections are made only if an object has a property with the mapped outlet name.

     * Set to false at own risk, may have quite undesired side effects.
     * @example
     * system.strictInjections = true
     * var o = {};
     * system.mapSingleton( 'userModel', UserModel );
     * system.mapOutlet( 'userModel' );
     * system.injectInto( o );
     *
     * //o is unchanged
     *
     * system.strictInjections = false;
     * system.injectInto( o );
     *
     * //o now has a member 'userModel' which holds a reference to the singleton instance
     * //of UserModel
     * @property
     * @type Boolean
     * @default true
     */
    this.strictInjections = true;

    /**
     * Enables the automatic mapping of outlets for mapped values, singletons and classes
     * When this is true any value, singleton or class that is mapped will automatically be mapped as a global outlet
     * using the value of key as outlet name
     *
     * @example
     * var o = {
     *     userModel : undefined; //inject
     * }
     * system.mapSingleton( 'userModel', UserModel );
     * system.injectInto( o ):
     * //o.userModel now holds a reference to the singleton instance of UserModel
     * @property
     * @type Boolean
     * @default false
     */
    this.autoMapOutlets = false;
};//dijon.System

dijon.System.prototype = {

	/**
	 * @private
	 * @param {Class} clazz
	 */
	_createAndSetupInstance : function( key, clazz ){
		var instance = new clazz();
		this.injectInto( instance, key );
		if( "setup" in instance ) instance.setup.call( instance );
		return instance;
	},

	/**
	 * @private
	 * @param {String} key
	 * @param {Boolean} overrideRules
	 * @return {Object}
	 */
	_retrieveFromCacheOrCreate : function( key, overrideRules ){
        if( overrideRules == undefined ) overrideRules = false;
        if( this._mappings.hasOwnProperty( key ) ){
            var config = this._mappings[ key ];
            var output = null;
            if( !overrideRules && config.isSingleton ){
                if( config.object == null  ){
                    config.object = this._createAndSetupInstance( key, config.clazz );
                }
                output = config.object;
            }else{
                if( config.clazz ) output = this._createAndSetupInstance( key, config.clazz );
                else{

                }
            }
        }else{
            throw new Error( 1020 );
        }
		return output
	},

	/**
	 * defines outletName as an injection point in targetKeyfor the object mapped to sourceKey
     * @example
     * var o = {
     *     user : undefined //inject
     * }
     * system.mapValue( 'o', o );
     * system.mapSingleton( 'userModel', UserModel );
     * system.mapOutlet( 'userModel', 'o', 'user' );
     *
     * var obj = system.getInstance( 'o' );
     * //obj.user holds a reference to the singleton instance of UserModel
     *
     * @example
     * var o = {
     *      userModel : undefined //inject
     * }
     * system.mapValue( 'o', o );
     * system.mapSingleton( 'userModel', UserModel );
     * system.mapOutlet( 'userModel', 'o' );
     *
     * var obj = system.getInstance( 'o' );
     * //obj.userModel holds a reference to the singleton instance of UserModel
     *
     * @example
     *
     * var o = {
     *      userModel : undefined
     * }
     *
     * system.mapSingleton( 'userModel', UserModel );
     * system.mapOutlet( 'userModel' );
     *
     * system.injectInto( o );
     *
     * //o.userModel holds a reference to the singleton instance of userModel
     *
     * @param {String} sourceKey the key mapped to the object that will be injected
     * @param {String} [targetKey='global'] the key the outlet is assigned to.
	 * @param {String} [outletName=sourceKey] the name of the property used as an outlet.

     * @see dijon.System#unmapOutlet
	 */
	mapOutlet : function( sourceKey, targetKey, outletName ){
	    if( sourceKey == undefined ) throw new Error( 1010 );
        if( targetKey == undefined ) targetKey = "global";
        if( outletName == undefined ) outletName = sourceKey;
        if( ! this._outlets.hasOwnProperty( targetKey ) ) this._outlets[ targetKey ] = {};
		this._outlets[ targetKey ][ outletName ] = sourceKey
	},

	/**
	 * Retrieve (or create) the object mapped to key
     * @example
     * system.mapValue( 'foo', 'bar' );
     * var b = system.getObject( 'foo' ); //now contains 'bar'
	 * @param {Object} key
	 * @return {Object}
	 */
	getObject : function( key ){
	    if( key == undefined ) throw new Error( 1010 )
		return this._retrieveFromCacheOrCreate( key );
	},

	/**
	 * Maps useValue to key
     * @example
     * system.mapValue( 'foo', 'bar' );
     * var b = system.getObject( 'foo' ); //now contains 'bar'
	 * @param {String} key
	 * @param {Object} useValue
	 */
	mapValue : function( key, useValue ){
	    if( key == undefined ) throw new Error( 1010 );
		this._mappings[ key ]= {
            clazz : null,
            object : useValue,
            isSingleton : true
		}
        if( this.autoMapOutlets ) this.mapOutlet( key );
	},

	/**
	 * Returns whether the key is mapped to an object
     * @example
     * system.mapValue( 'foo', 'bar' );
     * var isMapped = system.hasMapping( 'foo' );
	 * @param {String} key
	 * @return {Boolean}
	 */
	hasMapping : function( key ){
	    if( key == undefined ) throw new Error( 1010 );
		return this._mappings.hasOwnProperty( key );
	},

	/**
     * Maps clazz as a factory to key
     * @example
     * var SomeClass = function(){
     * }
     * system.mapClass( 'o', SomeClass );
     *
     * var s1 = system.getInstance( 'o' );
     * var s2 = system.getInstance( 'o' );
     *
     * //s1 and s2 reference two different instances of SomeClass
     *
	 * @param {String} key
	 * @param {Function} clazz
	 */
	mapClass : function( key, clazz ){
	    if( key == undefined ) throw new Error( 1010 );
	    if( key == undefined ) throw new Error( 1010 );
		this._mappings[ key ]= {
				clazz : clazz,
				object : null,
				isSingleton : false
        }
        if( this.autoMapOutlets ) this.mapOutlet( key );
	},

    /**
     * Maps clazz as a singleton factory to key
     * @example
     * var SomeClass = function(){
     * }
     * system.mapSingleton( 'o', SomeClass );
     *
     * var s1 = system.getInstance( 'o' );
     * var s2 = system.getInstance( 'o' );
     *
     * //s1 and s2 reference the same instance of SomeClass
     *
     * @param {String} key
     * @param {Function} clazz
     */
    mapSingleton : function( key, clazz ){
        if( key == undefined ) throw new Error( 1010 );
        if( clazz == undefined ) throw new Error( 1010 );
        this._mappings[ key ] = {
            clazz : clazz,
            object : null,
            isSingleton : true
        }
        if( this.autoMapOutlets ) this.mapOutlet( key );
    },

	/**
     * Force instantiation of the object mapped to key, whether it was mapped as a singleton or not.
	 * @param {Class} keyOrClass
	 * @return {Object}
	 */
	instantiate : function( key ){
        if( key == undefined ) throw new Error( 1010 );
		return this._retrieveFromCacheOrCreate( key, true );
	},

	/**
	 * Perform an injection into an object, satisfying all it's dependencies
	 * @param {Object} instance
     * @param {String} [key]
	 */
	injectInto : function( instance, key ){
        if( key == undefined ) throw new Error( 1010 );
        if( instance == undefined ) throw new Error( 1010 );
        var o = [];
        if( this._outlets.hasOwnProperty( 'global' ) ) o.push( this._outlets[ 'global' ] );
        if( key != undefined && this._outlets.hasOwnProperty( key ) ) o.push( this._outlets[ key ] );
        for( var i in o ){
            var l = o [ i ];
            for( var outlet in l ){
                var source = l[ outlet ];
                //must be "in" [!]
                if( ! this.strictInjections || outlet in instance ) instance[ outlet ] = this.getObject( source );
            }
        }

        return instance;
	},

	/**
	 * Remove a rule from the System
	 * @param {String} key
	 */
	unmap : function( key ){
        if( key == undefined ) throw new Error( 1010 );
		delete this._mappings[ key ];
	},

	/**
	 * removes an injection point mapping for a given class mapped to key
	 * @param {String} target
	 * @param {String} outlet
	 * @see dijon.System#addOutlet
	 */
	unmapOutlet : function( target, outlet ){
        if( target == undefined ) throw new Error( 1010 );
        if( outlet == undefined ) throw new Error( 1010 );
		delete this._outlets[ target ][ outlet ];
	},

    /**
     *
     * @param {String} eventName
     * @param {String} [key=undefined]
     * @param {String|Function} [handler=eventName]
     * @param {Boolean} [oneShot=false]
     * @param {Boolean} [passEvent=false]
     */
    mapHandler : function( eventName, key, handler, oneShot, passEvent ){
        if( eventName == undefined ) throw new Error( 1010 );
        if( key == undefined ) key = 'global';
        if( handler == undefined ) handler = eventName;
        if( oneShot == undefined ) oneShot = false;
        if( passEvent == undefined ) passEvent = false;
        if( ! this._handlers.hasOwnProperty( eventName ) ){
            this._handlers[ eventName ] = {};
        }
        if( ! this._handlers[eventName].hasOwnProperty( key ) ){
            this._handlers[eventName][key] = [];
        }
        this._handlers[ eventName ][ key ].push( {
            handler : handler,
            oneShot: oneShot,
            passEvent: passEvent
        } );
    },

    /**
     *
     * @param {String} eventName
     * @param {String} [key=undefined]
     * @param {String | Function} [handler=eventName]
     */
    unmapHandler : function( eventName, key, handler  ){
        if( eventName == undefined ) throw new Error( 1010 );
        if( key == undefined ) key = 'global';
        if( handler == undefined ) handler = eventName;
        if( this._handlers.hasOwnProperty( eventName ) && this._handlers[ eventName ].hasOwnProperty( key ) ){
            var handlers = this._handlers[ eventName ][ key ];
            for( var i in handlers ){
                var config = handlers[ i ];
                if( config.handler == handler ){
                    handlers.splice( i, 1 );
                    return;
                }
            }
        }
    },

    /**
     *
     * @param {String} eventName
     */
    notify : function( eventName ){
        var argsWithEvent = Array.prototype.slice.call( arguments );
        var argsClean = argsWithEvent.slice(1);
        if( this._handlers.hasOwnProperty( eventName ) ){
            var handlers = this._handlers[ eventName ];
            for( var key in handlers ){
                var configs = handlers[ key ];
                var instance;
                if( key != 'global' ) instance = this.getObject( key );
                var toBeDeleted = [];
                for( var i = 0, n = configs.length; i < n; i++ ){
                    var handler;
                    var config = configs[ i ];
                    if( instance && typeof config.handler == "string" ){
                        handler = instance[ config.handler ];
                    }else{
                        handler = config.handler;
                    }

                    //see deletion below
                    if( config.oneShot ) toBeDeleted.unshift( i );

                    if( config.passEvent ) handler.apply( instance, argsWithEvent );
                    else handler.apply( instance, argsClean );
                }

                //items should be deleted in reverse order
                //either use push above and decrement here
                //or use unshift above and increment here
                for( var i = 0, n = toBeDeleted.length; i < n; i++ ){
                    configs.splice( toBeDeleted[ i ], 1 );
                }
            }
        }
    }

};//dijon.System.prototype
<commit_msg>minor fixes<commit_after>/**
 * @author Camille Reynders
 * @namespace
 */
var dijon = {
	/**
	 * framework version number
	 * @constant
	 * @type String
	 */
	VERSION : '0.5.0'
};//dijon

  //======================================//
 // dijon.System
//======================================//

/**
 * @class dijon.System
 * @constructor
*/
dijon.System = function(){
	/** @private */
	this._mappings = {};

	/** @private */
	this._outlets = {};

    /** @private */
    this._handlers = {};

    /**
     * When true injections are made only if an object has a property with the mapped outlet name.

     * Set to false at own risk, may have quite undesired side effects.
     * @example
     * system.strictInjections = true
     * var o = {};
     * system.mapSingleton( 'userModel', UserModel );
     * system.mapOutlet( 'userModel' );
     * system.injectInto( o );
     *
     * //o is unchanged
     *
     * system.strictInjections = false;
     * system.injectInto( o );
     *
     * //o now has a member 'userModel' which holds a reference to the singleton instance
     * //of UserModel
     * @property
     * @type Boolean
     * @default true
     */
    this.strictInjections = true;

    /**
     * Enables the automatic mapping of outlets for mapped values, singletons and classes
     * When this is true any value, singleton or class that is mapped will automatically be mapped as a global outlet
     * using the value of key as outlet name
     *
     * @example
     * var o = {
     *     userModel : undefined; //inject
     * }
     * system.mapSingleton( 'userModel', UserModel );
     * system.injectInto( o ):
     * //o.userModel now holds a reference to the singleton instance of UserModel
     * @property
     * @type Boolean
     * @default false
     */
    this.autoMapOutlets = false;
};//dijon.System

dijon.System.prototype = {

	/**
	 * @private
	 * @param {Class} clazz
	 */
	_createAndSetupInstance : function( key, clazz ){
		var instance = new clazz();
		this.injectInto( instance, key );
		if( "setup" in instance ) instance.setup.call( instance );
		return instance;
	},

	/**
	 * @private
	 * @param {String} key
	 * @param {Boolean} overrideRules
	 * @return {Object}
	 */
	_retrieveFromCacheOrCreate : function( key, overrideRules ){
        if( overrideRules == undefined ) overrideRules = false;
        if( this._mappings.hasOwnProperty( key ) ){
            var config = this._mappings[ key ];
            var output = null;
            if( !overrideRules && config.isSingleton ){
                if( config.object == null  ){
                    config.object = this._createAndSetupInstance( key, config.clazz );
                }
                output = config.object;
            }else{
                if( config.clazz ) output = this._createAndSetupInstance( key, config.clazz );
                else{

                }
            }
        }else{
            throw new Error( 1020 );
        }
		return output
	},

	/**
	 * defines outletName as an injection point in targetKeyfor the object mapped to sourceKey
     * @example
     * var o = {
     *     user : undefined //inject
     * }
     * system.mapValue( 'o', o );
     * system.mapSingleton( 'userModel', UserModel );
     * system.mapOutlet( 'userModel', 'o', 'user' );
     *
     * var obj = system.getInstance( 'o' );
     * //obj.user holds a reference to the singleton instance of UserModel
     *
     * @example
     * var o = {
     *      userModel : undefined //inject
     * }
     * system.mapValue( 'o', o );
     * system.mapSingleton( 'userModel', UserModel );
     * system.mapOutlet( 'userModel', 'o' );
     *
     * var obj = system.getInstance( 'o' );
     * //obj.userModel holds a reference to the singleton instance of UserModel
     *
     * @example
     *
     * var o = {
     *      userModel : undefined
     * }
     *
     * system.mapSingleton( 'userModel', UserModel );
     * system.mapOutlet( 'userModel' );
     *
     * system.injectInto( o );
     *
     * //o.userModel holds a reference to the singleton instance of userModel
     *
     * @param {String} sourceKey the key mapped to the object that will be injected
     * @param {String} [targetKey='global'] the key the outlet is assigned to.
	 * @param {String} [outletName=sourceKey] the name of the property used as an outlet.

     * @see dijon.System#unmapOutlet
	 */
	mapOutlet : function( sourceKey, targetKey, outletName ){
	    if( sourceKey == undefined ) throw new Error( 1010 );
        if( targetKey == undefined ) targetKey = "global";
        if( outletName == undefined ) outletName = sourceKey;
        if( ! this._outlets.hasOwnProperty( targetKey ) ) this._outlets[ targetKey ] = {};
		this._outlets[ targetKey ][ outletName ] = sourceKey
	},

	/**
	 * Retrieve (or create) the object mapped to key
     * @example
     * system.mapValue( 'foo', 'bar' );
     * var b = system.getObject( 'foo' ); //now contains 'bar'
	 * @param {Object} key
	 * @return {Object}
	 */
	getObject : function( key ){
	    if( key == undefined ) throw new Error( 1010 )
		return this._retrieveFromCacheOrCreate( key );
	},

	/**
	 * Maps useValue to key
     * @example
     * system.mapValue( 'foo', 'bar' );
     * var b = system.getObject( 'foo' ); //now contains 'bar'
	 * @param {String} key
	 * @param {Object} useValue
	 */
	mapValue : function( key, useValue ){
	    if( key == undefined ) throw new Error( 1010 );
		this._mappings[ key ]= {
            clazz : null,
            object : useValue,
            isSingleton : true
		}
        if( this.autoMapOutlets ) this.mapOutlet( key );
	},

	/**
	 * Returns whether the key is mapped to an object
     * @example
     * system.mapValue( 'foo', 'bar' );
     * var isMapped = system.hasMapping( 'foo' );
	 * @param {String} key
	 * @return {Boolean}
	 */
	hasMapping : function( key ){
	    if( key == undefined ) throw new Error( 1010 );
		return this._mappings.hasOwnProperty( key );
	},

	/**
     * Maps clazz as a factory to key
     * @example
     * var SomeClass = function(){
     * }
     * system.mapClass( 'o', SomeClass );
     *
     * var s1 = system.getInstance( 'o' );
     * var s2 = system.getInstance( 'o' );
     *
     * //s1 and s2 reference two different instances of SomeClass
     *
	 * @param {String} key
	 * @param {Function} clazz
	 */
	mapClass : function( key, clazz ){
	    if( key == undefined ) throw new Error( 1010 );
	    if( key == undefined ) throw new Error( 1010 );
		this._mappings[ key ]= {
				clazz : clazz,
				object : null,
				isSingleton : false
        }
        if( this.autoMapOutlets ) this.mapOutlet( key );
	},

    /**
     * Maps clazz as a singleton factory to key
     * @example
     * var SomeClass = function(){
     * }
     * system.mapSingleton( 'o', SomeClass );
     *
     * var s1 = system.getInstance( 'o' );
     * var s2 = system.getInstance( 'o' );
     *
     * //s1 and s2 reference the same instance of SomeClass
     *
     * @param {String} key
     * @param {Function} clazz
     */
    mapSingleton : function( key, clazz ){
        if( key == undefined ) throw new Error( 1010 );
        if( clazz == undefined ) throw new Error( 1010 );
        this._mappings[ key ] = {
            clazz : clazz,
            object : null,
            isSingleton : true
        }
        if( this.autoMapOutlets ) this.mapOutlet( key );
    },

	/**
     * Force instantiation of the object mapped to key, whether it was mapped as a singleton or not.
	 * @param {Class} keyOrClass
	 * @return {Object}
	 */
	instantiate : function( key ){
        if( key == undefined ) throw new Error( 1010 );
		return this._retrieveFromCacheOrCreate( key, true );
	},

	/**
	 * Perform an injection into an object, satisfying all it's dependencies
	 * @param {Object} instance
     * @param {String} [key]
	 */
	injectInto : function( instance, key ){
        if( instance == undefined ) throw new Error( 1010 );
        var o = [];
        if( this._outlets.hasOwnProperty( 'global' ) ) o.push( this._outlets[ 'global' ] );
        if( key != undefined && this._outlets.hasOwnProperty( key ) ) o.push( this._outlets[ key ] );
        for( var i in o ){
            var l = o [ i ];
            for( var outlet in l ){
                var source = l[ outlet ];
                //must be "in" [!]
                if( ! this.strictInjections || outlet in instance ) instance[ outlet ] = this.getObject( source );
            }
        }

        return instance;
	},

	/**
	 * Remove a rule from the System
	 * @param {String} key
	 */
	unmap : function( key ){
        if( key == undefined ) throw new Error( 1010 );
		delete this._mappings[ key ];
	},

	/**
	 * removes an injection point mapping for a given class mapped to key
	 * @param {String} target
	 * @param {String} outlet
	 * @see dijon.System#addOutlet
	 */
	unmapOutlet : function( target, outlet ){
        if( target == undefined ) throw new Error( 1010 );
        if( outlet == undefined ) throw new Error( 1010 );
		delete this._outlets[ target ][ outlet ];
	},

    /**
     *
     * @param {String} eventName
     * @param {String} [key=undefined]
     * @param {String|Function} [handler=eventName]
     * @param {Boolean} [oneShot=false]
     * @param {Boolean} [passEvent=false]
     */
    mapHandler : function( eventName, key, handler, oneShot, passEvent ){
        if( eventName == undefined ) throw new Error( 1010 );
        if( key == undefined ) key = 'global';
        if( handler == undefined ) handler = eventName;
        if( oneShot == undefined ) oneShot = false;
        if( passEvent == undefined ) passEvent = false;
        if( ! this._handlers.hasOwnProperty( eventName ) ){
            this._handlers[ eventName ] = {};
        }
        if( ! this._handlers[eventName].hasOwnProperty( key ) ){
            this._handlers[eventName][key] = [];
        }
        this._handlers[ eventName ][ key ].push( {
            handler : handler,
            oneShot: oneShot,
            passEvent: passEvent
        } );
    },

    /**
     *
     * @param {String} eventName
     * @param {String} [key=undefined]
     * @param {String | Function} [handler=eventName]
     */
    unmapHandler : function( eventName, key, handler  ){
        if( eventName == undefined ) throw new Error( 1010 );
        if( key == undefined ) key = 'global';
        if( handler == undefined ) handler = eventName;
        if( this._handlers.hasOwnProperty( eventName ) && this._handlers[ eventName ].hasOwnProperty( key ) ){
            var handlers = this._handlers[ eventName ][ key ];
            for( var i in handlers ){
                var config = handlers[ i ];
                if( config.handler == handler ){
                    handlers.splice( i, 1 );
                    return;
                }
            }
        }
    },

    /**
     *
     * @param {String} eventName
     */
    notify : function( eventName ){
        var argsWithEvent = Array.prototype.slice.call( arguments );
        var argsClean = argsWithEvent.slice(1);
        if( this._handlers.hasOwnProperty( eventName ) ){
            var handlers = this._handlers[ eventName ];
            for( var key in handlers ){
                var configs = handlers[ key ];
                var instance;
                if( key != 'global' ) instance = this.getObject( key );
                var toBeDeleted = [];
                for( var i = 0, n = configs.length; i < n; i++ ){
                    var handler;
                    var config = configs[ i ];
                    if( instance && typeof config.handler == "string" ){
                        handler = instance[ config.handler ];
                    }else{
                        handler = config.handler;
                    }

                    //see deletion below
                    if( config.oneShot ) toBeDeleted.unshift( i );

                    if( config.passEvent ) handler.apply( instance, argsWithEvent );
                    else handler.apply( instance, argsClean );
                }

                //items should be deleted in reverse order
                //either use push above and decrement here
                //or use unshift above and increment here
                for( var i = 0, n = toBeDeleted.length; i < n; i++ ){
                    configs.splice( toBeDeleted[ i ], 1 );
                }
            }
        }
    }

};//dijon.System.prototype
<|endoftext|>


<commit_before>/* global QUnit */
require(['plugins/webida.editor.test-editor/plugin'], function (plugin) {
    'use strict';
    QUnit.test('TestEditor API Test', function (assert) {
        assert.ok(typeof plugin.create === 'function', 'create method exists');
    });
});<commit_msg>[TASK] Sample Test Case for TestEditor plug-in [DESC.] (See ODP-405) Support for Unit Test Environment<commit_after>/* global QUnit */
require(['plugins/webida.editor.test-editor/plugin'], function (plugin) {
    'use strict';
    QUnit.test('TestEditor API Validation', function (assert) {
        assert.ok(typeof plugin.create === 'function', 'create() method exists');
		assert.ok(typeof plugin.show === 'function', 'show() method exists');
		assert.ok(typeof plugin.destroy === 'function', 'destroy() method exists');
		assert.ok(typeof plugin.getValue === 'function', 'getValue() method exists');
		assert.ok(typeof plugin.addChangeListener === 'function', 'addChangeListener() method exists');
		assert.ok(typeof plugin.focus === 'function', 'focus() method exists');
		assert.ok(typeof plugin.pushCursorLocation === 'function', 'pushCursorLocation() method exists');
		assert.ok(typeof plugin.moveBack === 'function', 'moveBack() method exists');
		assert.ok(typeof plugin.moveForth === 'function', 'moveForth() method exists');
		assert.ok(typeof plugin.moveTo === 'function', 'moveTo() method exists');
		assert.ok(typeof plugin.getLastSavedFoldingStatus === 'function', 'getLastSavedFoldingStatus() method exists');
		assert.ok(typeof plugin.markClean === 'function', 'markClean() method exists');
		assert.ok(typeof plugin.isClean === 'function', 'isClean() method exists');
		assert.ok(typeof plugin.setMode === 'function', 'setMode() method exists');
    });
});<|endoftext|>


<commit_before>(function () {
    var resources = glinamespace("gli.resources");

    var Texture = function (gl, frameNumber, stack, target) {
        glisubclass(gli.host.Resource, this, [gl, frameNumber, stack, target]);
        this.creationOrder = 1;

        this.defaultName = "Texture " + this.id;

        this.type = gl.TEXTURE_2D; // TEXTURE_2D, TEXTURE_CUBE_MAP

        this.parameters = {};
        this.parameters[gl.TEXTURE_MAG_FILTER] = gl.LINEAR;
        this.parameters[gl.TEXTURE_MIN_FILTER] = gl.NEAREST_MIPMAP_LINEAR;
        this.parameters[gl.TEXTURE_WRAP_S] = gl.REPEAT;
        this.parameters[gl.TEXTURE_WRAP_T] = gl.REPEAT;

        this.currentVersion.target = this.type;
        this.currentVersion.setParameters(this.parameters);

        this.estimatedSize = 0;
    };

    Texture.prototype.guessSize = function (gl, version, face) {
        version = version || this.currentVersion;
        for (var n = version.calls.length - 1; n >= 0; n--) {
            var call = version.calls[n];
            if (call.name == "texImage2D") {
                // Ignore all but level 0
                if (call.args[1]) {
                    continue;
                }
                if (face) {
                    if (call.args[0] != face) {
                        continue;
                    }
                }
                if (call.args.length == 9) {
                    return [call.args[3], call.args[4]];
                } else {
                    var sourceObj = call.args[5];
                    if (sourceObj) {
                        return [sourceObj.width, sourceObj.height];
                    } else {
                        return null;
                    }
                }
            } else if (call.name == "compressedTexImage2D") {
                // Ignore all but level 0
                if (call.args[1]) {
                    continue;
                }
                if (face) {
                    if (call.args[0] != face) {
                        continue;
                    }
                }
                return [call.args[3], call.args[4]];
            }
        }
        return null;
    };

    Texture.prototype.refresh = function (gl) {
        var paramEnums = [gl.TEXTURE_MAG_FILTER, gl.TEXTURE_MIN_FILTER, gl.TEXTURE_WRAP_S, gl.TEXTURE_WRAP_T];
        for (var n = 0; n < paramEnums.length; n++) {
            this.parameters[paramEnums[n]] = gl.getTexParameter(this.type, paramEnums[n]);
        }
    };

    Texture.getTracked = function (gl, args) {
        var bindingEnum;
        switch (args[0]) {
            case gl.TEXTURE_2D:
                bindingEnum = gl.TEXTURE_BINDING_2D;
                break;
            case gl.TEXTURE_CUBE_MAP:
            case gl.TEXTURE_CUBE_MAP_POSITIVE_X:
            case gl.TEXTURE_CUBE_MAP_NEGATIVE_X:
            case gl.TEXTURE_CUBE_MAP_POSITIVE_Y:
            case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y:
            case gl.TEXTURE_CUBE_MAP_POSITIVE_Z:
            case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z:
                bindingEnum = gl.TEXTURE_BINDING_CUBE_MAP;
                break;
        }
        var gltexture = gl.rawgl.getParameter(bindingEnum);
        if (gltexture == null) {
            // Going to fail
            return null;
        }
        return gltexture.trackedObject;
    };

    Texture.setCaptures = function (gl) {
        // TODO: copyTexImage2D
        // TODO: copyTexSubImage2D

        var original_texParameterf = gl.texParameterf;
        gl.texParameterf = function () {
            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;
                tracked.parameters[arguments[1]] = arguments[2];
                tracked.markDirty(false);
                tracked.currentVersion.target = tracked.type;
                tracked.currentVersion.setParameters(tracked.parameters);
            }

            return original_texParameterf.apply(gl, arguments);
        };
        var original_texParameteri = gl.texParameteri;
        gl.texParameteri = function () {
            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;
                tracked.parameters[arguments[1]] = arguments[2];
                tracked.markDirty(false);
                tracked.currentVersion.target = tracked.type;
                tracked.currentVersion.setParameters(tracked.parameters);
            }

            return original_texParameteri.apply(gl, arguments);
        };

        function pushPixelStoreState(gl, version) {
            var pixelStoreEnums = [gl.PACK_ALIGNMENT, gl.UNPACK_ALIGNMENT, gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.UNPACK_FLIP_Y_WEBGL, gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL];
            for (var n = 0; n < pixelStoreEnums.length; n++) {
                var pixelStoreEnum = pixelStoreEnums[n];
                if (pixelStoreEnum === undefined) {
                    continue;
                }
                var value = gl.getParameter(pixelStoreEnums[n]);
                version.pushCall("pixelStorei", [pixelStoreEnum, value]);
            }
        };

        function calculateBpp(gl, format, type) {
            switch (type) {
                default:
                case gl.UNSIGNED_BYTE:
                    switch (format) {
                        case gl.ALPHA:
                        case gl.LUMINANCE:
                            return 1;
                        case gl.LUMINANCE_ALPHA:
                            return 2;
                        case gl.RGB:
                            return 3;
                        default:
                        case gl.RGBA:
                            return 4;
                    }
                    return 4;
                case gl.UNSIGNED_SHORT_5_6_5:
                    return 2;
                case gl.UNSIGNED_SHORT_4_4_4_4:
                    return 2;
                case gl.UNSIGNED_SHORT_5_5_5_1:
                    return 2;
                case 0x83F0: // COMPRESSED_RGB_S3TC_DXT1_EXT
                    return 3;
                case 0x83F1: // COMPRESSED_RGBA_S3TC_DXT1_EXT
                case 0x83F2: // COMPRESSED_RGBA_S3TC_DXT3_EXT
                case 0x83F3: // COMPRESSED_RGBA_S3TC_DXT5_EXT
                    return 4;
            }
        };

        var original_texImage2D = gl.texImage2D;
        gl.texImage2D = function () {
            // Track texture writes
            var totalBytes = 0;
            if (arguments.length == 9) {
                totalBytes = arguments[3] * arguments[4] * calculateBpp(gl, arguments[6], arguments[7]);
            } else {
                var sourceArg = arguments[5];
                var width = sourceArg.width;
                var height = sourceArg.height;
                totalBytes = width * height * calculateBpp(gl, arguments[3], arguments[4]);
            }
            gl.statistics.textureWrites.value += totalBytes;

            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;

                // Track total texture bytes consumed
                gl.statistics.textureBytes.value -= tracked.estimatedSize;
                gl.statistics.textureBytes.value += totalBytes;
                tracked.estimatedSize = totalBytes;

                // If a 2D texture this is always a reset, otherwise it may be a single face of the cube
                if (arguments[0] == gl.TEXTURE_2D) {
                    tracked.markDirty(true);
                    tracked.currentVersion.setParameters(tracked.parameters);
                } else {
                    // Cube face - always partial
                    tracked.markDirty(false);
                }
                tracked.currentVersion.target = tracked.type;

                pushPixelStoreState(gl.rawgl, tracked.currentVersion);
                tracked.currentVersion.pushCall("texImage2D", arguments);

                // If this is an upload from something with a URL and we haven't been named yet, auto name us
                if (arguments.length == 6) {
                    var sourceArg = arguments[5];
                    if (sourceArg && sourceArg.src) {
                        if (!tracked.target.displayName) {
                            var filename = sourceArg.src;
                            var lastSlash = filename.lastIndexOf("/");
                            if (lastSlash >= 0) {
                                filename = filename.substr(lastSlash + 1);
                            }
                            var lastDot = filename.lastIndexOf(".");
                            if (lastDot >= 0) {
                                filename = filename.substr(0, lastDot);
                            }
                            tracked.setName(filename, true);
                        }
                    }
                }
            }

            return original_texImage2D.apply(gl, arguments);
        };

        var original_texSubImage2D = gl.texSubImage2D;
        gl.texSubImage2D = function () {
            // Track texture writes
            var totalBytes = 0;
            if (arguments.length == 9) {
                totalBytes = arguments[4] * arguments[5] * calculateBpp(gl, arguments[6], arguments[7]);
            } else {
                var sourceArg = arguments[6];
                var width = sourceArg.width;
                var height = sourceArg.height;
                totalBytes = width * height * calculateBpp(gl, arguments[4], arguments[5]);
            }
            gl.statistics.textureWrites.value += totalBytes;

            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;
                tracked.markDirty(false);
                tracked.currentVersion.target = tracked.type;
                pushPixelStoreState(gl.rawgl, tracked.currentVersion);
                tracked.currentVersion.pushCall("texSubImage2D", arguments);
            }

            return original_texSubImage2D.apply(gl, arguments);
        };

        var original_compressedTexImage2D = gl.compressedTexImage2D;
        gl.compressedTexImage2D = function () {
            // Track texture writes
            var totalBytes = 0;
            switch (arguments[2]) {
                case 0x83F0: // COMPRESSED_RGB_S3TC_DXT1_EXT
                case 0x83F1: // COMPRESSED_RGBA_S3TC_DXT1_EXT
                    totalBytes = Math.floor((arguments[3] + 3) / 4) * Math.floor((arguments[4] + 3) / 4) * 8;
                    break;
                case 0x83F2: // COMPRESSED_RGBA_S3TC_DXT3_EXT
                case 0x83F3: // COMPRESSED_RGBA_S3TC_DXT5_EXT
                    totalBytes = Math.floor((arguments[3] + 3) / 4) * Math.floor((arguments[4] + 3) / 4) * 16;
                    break;
            }
            gl.statistics.textureWrites.value += totalBytes;

            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;

                // Track total texture bytes consumed
                gl.statistics.textureBytes.value -= tracked.estimatedSize;
                gl.statistics.textureBytes.value += totalBytes;
                tracked.estimatedSize = totalBytes;

                // If a 2D texture this is always a reset, otherwise it may be a single face of the cube
                // Note that we don't reset if we are adding extra levels.
                if (arguments[1] == 0 && arguments[0] == gl.TEXTURE_2D) {
                    tracked.markDirty(true);
                    tracked.currentVersion.setParameters(tracked.parameters);
                } else {
                    // Cube face - always partial
                    tracked.markDirty(false);
                }
                tracked.currentVersion.target = tracked.type;

                pushPixelStoreState(gl.rawgl, tracked.currentVersion);
                tracked.currentVersion.pushCall("compressedTexImage2D", arguments);
            }

            return original_compressedTexImage2D.apply(gl, arguments);
        };

        var original_compressedTexSubImage2D = gl.compressedTexSubImage2D;
        gl.compressedTexSubImage2D = function () {
            // Track texture writes
            var totalBytes = 0;
            switch (arguments[2]) {
                case 0x83F0: // COMPRESSED_RGB_S3TC_DXT1_EXT
                case 0x83F1: // COMPRESSED_RGBA_S3TC_DXT1_EXT
                    totalBytes = Math.floor((arguments[4] + 3) / 4) * Math.floor((arguments[5] + 3) / 4) * 8;
                    break;
                case 0x83F2: // COMPRESSED_RGBA_S3TC_DXT3_EXT
                case 0x83F3: // COMPRESSED_RGBA_S3TC_DXT5_EXT
                    totalBytes = Math.floor((arguments[4] + 3) / 4) * Math.floor((arguments[5] + 3) / 4) * 16;
                    break;
            }
            gl.statistics.textureWrites.value += totalBytes;

            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;
                tracked.markDirty(false);
                tracked.currentVersion.target = tracked.type;
                pushPixelStoreState(gl.rawgl, tracked.currentVersion);
                tracked.currentVersion.pushCall("compressedTexSubImage2D", arguments);
            }

            return original_compressedTexSubImage2D.apply(gl, arguments);
        };

        var original_generateMipmap = gl.generateMipmap;
        gl.generateMipmap = function () {
            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;
                // TODO: figure out what to do with mipmaps
                pushPixelStoreState(gl.rawgl, tracked.currentVersion);
                tracked.currentVersion.pushCall("generateMipmap", arguments);
            }

            return original_generateMipmap.apply(gl, arguments);
        };

        var original_readPixels = gl.readPixels;
        gl.readPixels = function () {
            var result = original_readPixels.apply(gl, arguments);
            if (result) {
                // Track texture reads
                // NOTE: only RGBA is supported for reads
                var totalBytes = arguments[2] * arguments[3] * 4;
                gl.statistics.textureReads.value += totalBytes;
            }
            return result;
        };
    };

    // If a face is supplied the texture created will be a 2D texture containing only the given face
    Texture.prototype.createTarget = function (gl, version, options, face) {
        options = options || {};
        var target = version.target;
        if (face) {
            target = gl.TEXTURE_2D;
        }

        var texture = gl.createTexture();
        gl.bindTexture(target, texture);

        for (var n in version.parameters) {
            gl.texParameteri(target, parseInt(n), version.parameters[n]);
        }

        this.replayCalls(gl, version, texture, function (call, args) {
            // Filter uploads if requested
            if (options.ignoreTextureUploads) {
                if ((call.name == "texImage2D") || (call.name == "texSubImage2D") ||
                    (call.name == "compressedTexImage2D") || (call.name == "compressedTexSubImage2D")) {
                    return false;
                }
            }

            // Filter non-face calls and rewrite the target if this is a face-specific call
            if ((call.name == "texImage2D") || (call.name == "texSubImage2D") ||
                (call.name == "compressedTexImage2D") || (call.name == "compressedTexSubImage2D")) {
                if (face && (args.length > 0)) {
                    if (args[0] != face) {
                        return false;
                    }
                    args[0] = gl.TEXTURE_2D;
                }
            } else if (call.name == "generateMipmap") {
                args[0] = target;
            }
            return true;
        });

        return texture;
    };

    Texture.prototype.deleteTarget = function (gl, target) {
        gl.deleteTexture(target);
    };

    resources.Texture = Texture;

})();
<commit_msg>fix generateMipmap error issue<commit_after>(function () {
    var resources = glinamespace("gli.resources");

    var Texture = function (gl, frameNumber, stack, target) {
        glisubclass(gli.host.Resource, this, [gl, frameNumber, stack, target]);
        this.creationOrder = 1;

        this.defaultName = "Texture " + this.id;

        this.type = gl.TEXTURE_2D; // TEXTURE_2D, TEXTURE_CUBE_MAP

        this.parameters = {};
        this.parameters[gl.TEXTURE_MAG_FILTER] = gl.LINEAR;
        this.parameters[gl.TEXTURE_MIN_FILTER] = gl.NEAREST_MIPMAP_LINEAR;
        this.parameters[gl.TEXTURE_WRAP_S] = gl.REPEAT;
        this.parameters[gl.TEXTURE_WRAP_T] = gl.REPEAT;

        this.currentVersion.target = this.type;
        this.currentVersion.setParameters(this.parameters);

        this.estimatedSize = 0;
    };

    Texture.prototype.guessSize = function (gl, version, face) {
        version = version || this.currentVersion;
        for (var n = version.calls.length - 1; n >= 0; n--) {
            var call = version.calls[n];
            if (call.name == "texImage2D") {
                // Ignore all but level 0
                if (call.args[1]) {
                    continue;
                }
                if (face) {
                    if (call.args[0] != face) {
                        continue;
                    }
                }
                if (call.args.length == 9) {
                    return [call.args[3], call.args[4]];
                } else {
                    var sourceObj = call.args[5];
                    if (sourceObj) {
                        return [sourceObj.width, sourceObj.height];
                    } else {
                        return null;
                    }
                }
            } else if (call.name == "compressedTexImage2D") {
                // Ignore all but level 0
                if (call.args[1]) {
                    continue;
                }
                if (face) {
                    if (call.args[0] != face) {
                        continue;
                    }
                }
                return [call.args[3], call.args[4]];
            }
        }
        return null;
    };

    Texture.prototype.refresh = function (gl) {
        var paramEnums = [gl.TEXTURE_MAG_FILTER, gl.TEXTURE_MIN_FILTER, gl.TEXTURE_WRAP_S, gl.TEXTURE_WRAP_T];
        for (var n = 0; n < paramEnums.length; n++) {
            this.parameters[paramEnums[n]] = gl.getTexParameter(this.type, paramEnums[n]);
        }
    };

    Texture.getTracked = function (gl, args) {
        var bindingEnum;
        switch (args[0]) {
            case gl.TEXTURE_2D:
                bindingEnum = gl.TEXTURE_BINDING_2D;
                break;
            case gl.TEXTURE_CUBE_MAP:
            case gl.TEXTURE_CUBE_MAP_POSITIVE_X:
            case gl.TEXTURE_CUBE_MAP_NEGATIVE_X:
            case gl.TEXTURE_CUBE_MAP_POSITIVE_Y:
            case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y:
            case gl.TEXTURE_CUBE_MAP_POSITIVE_Z:
            case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z:
                bindingEnum = gl.TEXTURE_BINDING_CUBE_MAP;
                break;
        }
        var gltexture = gl.rawgl.getParameter(bindingEnum);
        if (gltexture == null) {
            // Going to fail
            return null;
        }
        return gltexture.trackedObject;
    };

    Texture.setCaptures = function (gl) {
        // TODO: copyTexImage2D
        // TODO: copyTexSubImage2D

        var original_texParameterf = gl.texParameterf;
        gl.texParameterf = function () {
            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;
                tracked.parameters[arguments[1]] = arguments[2];
                tracked.markDirty(false);
                tracked.currentVersion.target = tracked.type;
                tracked.currentVersion.setParameters(tracked.parameters);
            }

            return original_texParameterf.apply(gl, arguments);
        };
        var original_texParameteri = gl.texParameteri;
        gl.texParameteri = function () {
            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;
                tracked.parameters[arguments[1]] = arguments[2];
                tracked.markDirty(false);
                tracked.currentVersion.target = tracked.type;
                tracked.currentVersion.setParameters(tracked.parameters);
            }

            return original_texParameteri.apply(gl, arguments);
        };

        function pushPixelStoreState(gl, version) {
            var pixelStoreEnums = [gl.PACK_ALIGNMENT, gl.UNPACK_ALIGNMENT, gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.UNPACK_FLIP_Y_WEBGL, gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL];
            for (var n = 0; n < pixelStoreEnums.length; n++) {
                var pixelStoreEnum = pixelStoreEnums[n];
                if (pixelStoreEnum === undefined) {
                    continue;
                }
                var value = gl.getParameter(pixelStoreEnums[n]);
                version.pushCall("pixelStorei", [pixelStoreEnum, value]);
            }
        };

        function calculateBpp(gl, format, type) {
            switch (type) {
                default:
                case gl.UNSIGNED_BYTE:
                    switch (format) {
                        case gl.ALPHA:
                        case gl.LUMINANCE:
                            return 1;
                        case gl.LUMINANCE_ALPHA:
                            return 2;
                        case gl.RGB:
                            return 3;
                        default:
                        case gl.RGBA:
                            return 4;
                    }
                    return 4;
                case gl.UNSIGNED_SHORT_5_6_5:
                    return 2;
                case gl.UNSIGNED_SHORT_4_4_4_4:
                    return 2;
                case gl.UNSIGNED_SHORT_5_5_5_1:
                    return 2;
                case 0x83F0: // COMPRESSED_RGB_S3TC_DXT1_EXT
                    return 3;
                case 0x83F1: // COMPRESSED_RGBA_S3TC_DXT1_EXT
                case 0x83F2: // COMPRESSED_RGBA_S3TC_DXT3_EXT
                case 0x83F3: // COMPRESSED_RGBA_S3TC_DXT5_EXT
                    return 4;
            }
        };

        var original_texImage2D = gl.texImage2D;
        gl.texImage2D = function () {
            // Track texture writes
            var totalBytes = 0;
            if (arguments.length == 9) {
                totalBytes = arguments[3] * arguments[4] * calculateBpp(gl, arguments[6], arguments[7]);
            } else {
                var sourceArg = arguments[5];
                var width = sourceArg.width;
                var height = sourceArg.height;
                totalBytes = width * height * calculateBpp(gl, arguments[3], arguments[4]);
            }
            gl.statistics.textureWrites.value += totalBytes;

            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;

                // Track total texture bytes consumed
                gl.statistics.textureBytes.value -= tracked.estimatedSize;
                gl.statistics.textureBytes.value += totalBytes;
                tracked.estimatedSize = totalBytes;

                // If a 2D texture this is always a reset, otherwise it may be a single face of the cube
                if (arguments[0] == gl.TEXTURE_2D) {
                    tracked.markDirty(true);
                    tracked.currentVersion.setParameters(tracked.parameters);
                } else {
                    // Cube face - always partial
                    tracked.markDirty(false);
                }
                tracked.currentVersion.target = tracked.type;

                pushPixelStoreState(gl.rawgl, tracked.currentVersion);
                tracked.currentVersion.pushCall("texImage2D", arguments);

                // If this is an upload from something with a URL and we haven't been named yet, auto name us
                if (arguments.length == 6) {
                    var sourceArg = arguments[5];
                    if (sourceArg && sourceArg.src) {
                        if (!tracked.target.displayName) {
                            var filename = sourceArg.src;
                            var lastSlash = filename.lastIndexOf("/");
                            if (lastSlash >= 0) {
                                filename = filename.substr(lastSlash + 1);
                            }
                            var lastDot = filename.lastIndexOf(".");
                            if (lastDot >= 0) {
                                filename = filename.substr(0, lastDot);
                            }
                            tracked.setName(filename, true);
                        }
                    }
                }
            }

            return original_texImage2D.apply(gl, arguments);
        };

        var original_texSubImage2D = gl.texSubImage2D;
        gl.texSubImage2D = function () {
            // Track texture writes
            var totalBytes = 0;
            if (arguments.length == 9) {
                totalBytes = arguments[4] * arguments[5] * calculateBpp(gl, arguments[6], arguments[7]);
            } else {
                var sourceArg = arguments[6];
                var width = sourceArg.width;
                var height = sourceArg.height;
                totalBytes = width * height * calculateBpp(gl, arguments[4], arguments[5]);
            }
            gl.statistics.textureWrites.value += totalBytes;

            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;
                tracked.markDirty(false);
                tracked.currentVersion.target = tracked.type;
                pushPixelStoreState(gl.rawgl, tracked.currentVersion);
                tracked.currentVersion.pushCall("texSubImage2D", arguments);
            }

            return original_texSubImage2D.apply(gl, arguments);
        };

        var original_compressedTexImage2D = gl.compressedTexImage2D;
        gl.compressedTexImage2D = function () {
            // Track texture writes
            var totalBytes = 0;
            switch (arguments[2]) {
                case 0x83F0: // COMPRESSED_RGB_S3TC_DXT1_EXT
                case 0x83F1: // COMPRESSED_RGBA_S3TC_DXT1_EXT
                    totalBytes = Math.floor((arguments[3] + 3) / 4) * Math.floor((arguments[4] + 3) / 4) * 8;
                    break;
                case 0x83F2: // COMPRESSED_RGBA_S3TC_DXT3_EXT
                case 0x83F3: // COMPRESSED_RGBA_S3TC_DXT5_EXT
                    totalBytes = Math.floor((arguments[3] + 3) / 4) * Math.floor((arguments[4] + 3) / 4) * 16;
                    break;
            }
            gl.statistics.textureWrites.value += totalBytes;

            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;

                // Track total texture bytes consumed
                gl.statistics.textureBytes.value -= tracked.estimatedSize;
                gl.statistics.textureBytes.value += totalBytes;
                tracked.estimatedSize = totalBytes;

                // If a 2D texture this is always a reset, otherwise it may be a single face of the cube
                // Note that we don't reset if we are adding extra levels.
                if (arguments[1] == 0 && arguments[0] == gl.TEXTURE_2D) {
                    tracked.markDirty(true);
                    tracked.currentVersion.setParameters(tracked.parameters);
                } else {
                    // Cube face - always partial
                    tracked.markDirty(false);
                }
                tracked.currentVersion.target = tracked.type;

                pushPixelStoreState(gl.rawgl, tracked.currentVersion);
                tracked.currentVersion.pushCall("compressedTexImage2D", arguments);
            }

            return original_compressedTexImage2D.apply(gl, arguments);
        };

        var original_compressedTexSubImage2D = gl.compressedTexSubImage2D;
        gl.compressedTexSubImage2D = function () {
            // Track texture writes
            var totalBytes = 0;
            switch (arguments[2]) {
                case 0x83F0: // COMPRESSED_RGB_S3TC_DXT1_EXT
                case 0x83F1: // COMPRESSED_RGBA_S3TC_DXT1_EXT
                    totalBytes = Math.floor((arguments[4] + 3) / 4) * Math.floor((arguments[5] + 3) / 4) * 8;
                    break;
                case 0x83F2: // COMPRESSED_RGBA_S3TC_DXT3_EXT
                case 0x83F3: // COMPRESSED_RGBA_S3TC_DXT5_EXT
                    totalBytes = Math.floor((arguments[4] + 3) / 4) * Math.floor((arguments[5] + 3) / 4) * 16;
                    break;
            }
            gl.statistics.textureWrites.value += totalBytes;

            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;
                tracked.markDirty(false);
                tracked.currentVersion.target = tracked.type;
                pushPixelStoreState(gl.rawgl, tracked.currentVersion);
                tracked.currentVersion.pushCall("compressedTexSubImage2D", arguments);
            }

            return original_compressedTexSubImage2D.apply(gl, arguments);
        };

        var original_generateMipmap = gl.generateMipmap;
        gl.generateMipmap = function () {
            var tracked = Texture.getTracked(gl, arguments);
            if (tracked) {
                tracked.type = arguments[0] == gl.TEXTURE_2D ?
                    gl.TEXTURE_2D : gl.TEXTURE_CUBE_MAP;
                // TODO: figure out what to do with mipmaps
                pushPixelStoreState(gl.rawgl, tracked.currentVersion);
                tracked.currentVersion.pushCall("generateMipmap", arguments);
            }

            return original_generateMipmap.apply(gl, arguments);
        };

        var original_readPixels = gl.readPixels;
        gl.readPixels = function () {
            var result = original_readPixels.apply(gl, arguments);
            if (result) {
                // Track texture reads
                // NOTE: only RGBA is supported for reads
                var totalBytes = arguments[2] * arguments[3] * 4;
                gl.statistics.textureReads.value += totalBytes;
            }
            return result;
        };
    };

    // If a face is supplied the texture created will be a 2D texture containing only the given face
    Texture.prototype.createTarget = function (gl, version, options, face) {
        options = options || {};
        var target = version.target;
        if (face) {
            target = gl.TEXTURE_2D;
        }

        var texture = gl.createTexture();
        gl.bindTexture(target, texture);

        for (var n in version.parameters) {
            gl.texParameteri(target, parseInt(n), version.parameters[n]);
        }

        this.replayCalls(gl, version, texture, function (call, args) {
            // Filter uploads if requested
            if (options.ignoreTextureUploads) {
                if ((call.name === "texImage2D") ||
                    (call.name === "texSubImage2D") ||
                    (call.name === "compressedTexImage2D") ||
                    (call.name === "compressedTexSubImage2D") ||
                    (call.name === "generateMipmap")) {
                    return false;
                }
            }

            // Filter non-face calls and rewrite the target if this is a face-specific call
            if ((call.name == "texImage2D") || (call.name == "texSubImage2D") ||
                (call.name == "compressedTexImage2D") || (call.name == "compressedTexSubImage2D")) {
                if (face && (args.length > 0)) {
                    if (args[0] != face) {
                        return false;
                    }
                    args[0] = gl.TEXTURE_2D;
                }
            } else if (call.name == "generateMipmap") {
                args[0] = target;
            }
            return true;
        });

        return texture;
    };

    Texture.prototype.deleteTarget = function (gl, target) {
        gl.deleteTexture(target);
    };

    resources.Texture = Texture;

})();
<|endoftext|>


<commit_before>const Errors = use("core/errors");

class PropertyPrototype {

    constructor() {
        this._validators = new Set();
        this._outputModifications = new Set();
    }

    _addValidator(validateFunction) {
        this._validators.add(validateFunction);
    }

    _addOutputModification(outputSetter) {
        this._outputModifications.add(outputSetter);
    }

    _inputModification(value) {
        return value;
    }

    _validate(value, propertyName, modelName) {
        try {
            this._validators.forEach(validator => validator.call(this, value, propertyName, modelName));
        }
        catch (error) {
            if (error instanceof Errors.Validation) {
                throw new Errors.Validation(`In model ${modelName} ` + error.message);
            } else {
                throw error;
            }
        }
    }

    _output(outputObject, propertyName) {
        this._outputModifications.forEach(outputSetter => outputSetter(outputObject, propertyName));
    }
}

class DefaultProperty extends PropertyPrototype {
    required() {
        this._addValidator((value, propertyName) => {
            if (typeof value === 'undefined' || value === null) {
                throw new Errors.Validation(`property ${propertyName} is required, but does not exists`);
            }
        });
        return this;
    }

    private() {
        this._addOutputModification((outputObject, propertyName) => {
            delete outputObject[propertyName];
        });
        return this;
    }
}

module.exports = DefaultProperty;<commit_msg>Change error message in Property.<commit_after>const Errors = use("core/errors");

class PropertyPrototype {

    constructor() {
        this._validators = new Set();
        this._outputModifications = new Set();
    }

    _addValidator(validateFunction) {
        this._validators.add(validateFunction);
    }

    _addOutputModification(outputSetter) {
        this._outputModifications.add(outputSetter);
    }

    _inputModification(value) {
        return value;
    }

    _validate(value, propertyName, modelName) {
        try {
            this._validators.forEach(validator => validator.call(this, value, propertyName, modelName));
        }
        catch (error) {
            if (error instanceof Errors.Validation) {
                throw new Errors.Validation(`In ${modelName} model ` + error.message);
            } else {
                throw error;
            }
        }
    }

    _output(outputObject, propertyName) {
        this._outputModifications.forEach(outputSetter => outputSetter(outputObject, propertyName));
    }
}

class DefaultProperty extends PropertyPrototype {
    required() {
        this._addValidator((value, propertyName) => {
            if (typeof value === 'undefined' || value === null) {
                throw new Errors.Validation(`property ${propertyName} is required, but does not exists`);
            }
        });
        return this;
    }

    private() {
        this._addOutputModification((outputObject, propertyName) => {
            delete outputObject[propertyName];
        });
        return this;
    }
}

module.exports = DefaultProperty;<|endoftext|>


<commit_before>/*
Copyright 2018 New Vector Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

const assert = require('assert');
const acceptInvite = require("./accept-invite")
module.exports = async function acceptServerNoticesInviteAndConsent(session) {
    await acceptInvite(session, "Server Notices");
    session.log.step(`accepts terms & conditions`);
    const consentLink = await session.waitAndQuery(".mx_EventTile_body a", 10000);
    const termsPagePromise = session.waitForNewPage();
    await consentLink.click();
    const termsPage = await termsPagePromise;
    const acceptButton = await termsPage.$('input[type=submit]');
    await acceptButton.click();
    await session.delay(1000); //TODO yuck, timers
    await termsPage.close();
    session.log.done();
}
<commit_msg>Revert "increase timeout for server notices room"<commit_after>/*
Copyright 2018 New Vector Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

const assert = require('assert');
const acceptInvite = require("./accept-invite")
module.exports = async function acceptServerNoticesInviteAndConsent(session) {
    await acceptInvite(session, "Server Notices");
    session.log.step(`accepts terms & conditions`);
    const consentLink = await session.waitAndQuery(".mx_EventTile_body a");
    const termsPagePromise = session.waitForNewPage();
    await consentLink.click();
    const termsPage = await termsPagePromise;
    const acceptButton = await termsPage.$('input[type=submit]');
    await acceptButton.click();
    await session.delay(1000); //TODO yuck, timers
    await termsPage.close();
    session.log.done();
}
<|endoftext|>


<commit_before>/*
 Copyright (C) Lan 2017
 Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
 */
import Affix from './components/affix';
import BackTop from './components/backtop';
import Badge from './components/badge';
import Checkbox from './components/checkbox';
import Circle from './components/circle';
import Category from './components/category';
import Datetime from './components/datetime';
import Dropdown from './plugins/dropdown';
import DropdownCustom from './components/dropdowncustom';
import DropdownMenu from './components/dropdownmenu';
import Form from './components/form';
import Menu from './components/menu';
import modal from './components/modal';
import Pagination from './components/pagination';
import Poptip from './components/poptip';
import Progress from './components/progress';
import Radio from './components/radio';
import Rate from './components/rate';
import Slider from './components/slider';
import Loading from './components/Loading';
import Steps from './components/steps';
import Search from './components/search';
import Select from './components/select';
import Switch from './components/switch';
import SwitchList from './components/switchlist';
import { Table, TableItem } from './components/table';
import Tabs from './components/tabs';
import Tag from './components/tag';
import TagInput from './components/taginput';
import Tree from './components/tree';
import TreePicker from './components/treepicker';
import NumberInput from './components/numberinput';
import Tooltip from './components/tooltip';
import Uploader from './components/uploader';
import AutoComplete from './components/autocomplete';
import {
  Row,
  Col
} from './components/layout';
import Timeline from './components/timeline';
import { Button, ButtonGroup } from './components/button';

import style from './directives/style';
import tooltip from './directives/tooltip';
import autosize from './directives/autosize';
import $Modal from './plugins/modal';
import $Confirm from './plugins/confirm';
import $Message from './plugins/message';
import $Notice from './plugins/notice';
import $Loading from './plugins/loading';
import $LoadingBar from './plugins/loadingBar';

import filters from './filters';
import config from './utils/config';
// import locale from './locale';

const components = {
  Affix,
  AutoComplete,
  BackTop,
  Badge,
  Button,
  hButton: Button,
  ButtonGroup,
  Checkbox,
  Category,
  hCircle: Circle,
  DropdownCustom,
  DropdownMenu,
  DatePicker: Datetime.DatePicker,
  DateRangePicker: Datetime.DateRangePicker,
  DateFullRangePicker: Datetime.DateFullRangePicker,
  hForm: Form,
  Form,
  FormItem: Form.Item,
  FormItemList: Form.ItemList,
  Menu,
  Modal: modal.Modal,
  ModalComponent: modal.ModalComponent,
  NumberInput,
  Pagination,
  Poptip,
  Progress,
  Radio,
  Rate,
  Row,
  hCol: Col,
  Col,
  Timeline,
  TimelineItem: Timeline.Item,
  hSelect: Select,
  Select,
  Search,
  Slider,
  Loading,
  Steps,
  hSwitch: Switch,
  SwitchList,
  TagInput,
  Table,
  TableItem,
  hTable: Table,
  Tabs,
  Tag,
  Tooltip,
  Tree,
  TreePicker,
  Uploader
};

const directives = {
  width: style.width,
  color: style.color,
  "bg-color": style.bgColor,
  height: style.height,
  padding: style.padding,
  margin: style.margin,
  font: style.font,
  autosize,
  tooltip
}

let prototypes = {
  $Message,
  // $Modal,
  $Confirm,
  $Loading,
  $LoadingBar
}

const install = function (Vue) {
  // locale.use(opts.locale);
  // locale.i18n(opts.i18n);

  if (install.installed) return;
  // if (opts) {

  // }

  Object.keys(components).forEach((key) => {
    Vue.component(key, components[key]);
  });

  Object.keys(filters).forEach((key) => {
    Vue.filter(key, filters[key]);
  });

  Object.keys(directives).forEach((key) => {
    Vue.directive(key, directives[key]);
  });

  Object.keys(prototypes).forEach((key) => {
    Vue.prototype[key] = prototypes[key];
  });

  this.$Modal = Vue.prototype.$Modal = $Modal(Vue);
  this.$Notice = Vue.prototype.$Notice = $Notice(Vue);
};

if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue);
}

const HeyUI = Object.assign(components, {
  install
}, { $Modal, $Notice }, prototypes, config, { Dropdown }, filters);

module.exports = HeyUI;
<commit_msg>fix: modal,notice 返回执行的对象<commit_after>/*
 Copyright (C) Lan 2017
 Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
 */
import Affix from './components/affix';
import BackTop from './components/backtop';
import Badge from './components/badge';
import Checkbox from './components/checkbox';
import Circle from './components/circle';
import Category from './components/category';
import Datetime from './components/datetime';
import Dropdown from './plugins/dropdown';
import DropdownCustom from './components/dropdowncustom';
import DropdownMenu from './components/dropdownmenu';
import Form from './components/form';
import Menu from './components/menu';
import modal from './components/modal';
import Pagination from './components/pagination';
import Poptip from './components/poptip';
import Progress from './components/progress';
import Radio from './components/radio';
import Rate from './components/rate';
import Slider from './components/slider';
import Loading from './components/Loading';
import Steps from './components/steps';
import Search from './components/search';
import Select from './components/select';
import Switch from './components/switch';
import SwitchList from './components/switchlist';
import { Table, TableItem } from './components/table';
import Tabs from './components/tabs';
import Tag from './components/tag';
import TagInput from './components/taginput';
import Tree from './components/tree';
import TreePicker from './components/treepicker';
import NumberInput from './components/numberinput';
import Tooltip from './components/tooltip';
import Uploader from './components/uploader';
import AutoComplete from './components/autocomplete';
import {
  Row,
  Col
} from './components/layout';
import Timeline from './components/timeline';
import { Button, ButtonGroup } from './components/button';

import style from './directives/style';
import tooltip from './directives/tooltip';
import autosize from './directives/autosize';
import $Modal from './plugins/modal';
import $Confirm from './plugins/confirm';
import $Message from './plugins/message';
import $Notice from './plugins/notice';
import $Loading from './plugins/loading';
import $LoadingBar from './plugins/loadingBar';

import filters from './filters';
import config from './utils/config';
// import locale from './locale';

const components = {
  Affix,
  AutoComplete,
  BackTop,
  Badge,
  Button,
  hButton: Button,
  ButtonGroup,
  Checkbox,
  Category,
  hCircle: Circle,
  DropdownCustom,
  DropdownMenu,
  DatePicker: Datetime.DatePicker,
  DateRangePicker: Datetime.DateRangePicker,
  DateFullRangePicker: Datetime.DateFullRangePicker,
  hForm: Form,
  Form,
  FormItem: Form.Item,
  FormItemList: Form.ItemList,
  Menu,
  Modal: modal.Modal,
  ModalComponent: modal.ModalComponent,
  NumberInput,
  Pagination,
  Poptip,
  Progress,
  Radio,
  Rate,
  Row,
  hCol: Col,
  Col,
  Timeline,
  TimelineItem: Timeline.Item,
  hSelect: Select,
  Select,
  Search,
  Slider,
  Loading,
  Steps,
  hSwitch: Switch,
  SwitchList,
  TagInput,
  Table,
  TableItem,
  hTable: Table,
  Tabs,
  Tag,
  Tooltip,
  Tree,
  TreePicker,
  Uploader
};

const directives = {
  width: style.width,
  color: style.color,
  "bg-color": style.bgColor,
  height: style.height,
  padding: style.padding,
  margin: style.margin,
  font: style.font,
  autosize,
  tooltip
}

let prototypes = {
  $Message,
  // $Modal,
  $Confirm,
  $Loading,
  $LoadingBar
}

const install = function (Vue) {
  // locale.use(opts.locale);
  // locale.i18n(opts.i18n);

  if (install.installed) return;
  // if (opts) {

  // }

  Object.keys(components).forEach((key) => {
    Vue.component(key, components[key]);
  });

  Object.keys(filters).forEach((key) => {
    Vue.filter(key, filters[key]);
  });

  Object.keys(directives).forEach((key) => {
    Vue.directive(key, directives[key]);
  });

  Object.keys(prototypes).forEach((key) => {
    Vue.prototype[key] = prototypes[key];
  });

  this.$Modal = Vue.prototype.$Modal = $Modal(Vue);
  this.$Notice = Vue.prototype.$Notice = $Notice(Vue);
};

if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue);
}

const HeyUI = Object.assign(components, {
  install
}, { $Modal: $Modal(), $Notice: $Notice() }, prototypes, config, { Dropdown }, filters);

module.exports = HeyUI;
<|endoftext|>


<commit_before>/*
---

script: Expression.js

description: Adds layout capabilities to widget (parse and render widget trees from objects)

license: Public domain (http://unlicense.org).

authors: Yaroslaff Fedin

requires:
  - LSD.Module
  - LSD.Module.Events
  - LSD.Layout
  - LSD.Layout.Branch
  - LSD.Layout.Microdata
  - LSD.Layout.Promise

provides:
  - LSD.Module.Layout

...
*/

LSD.Module.Layout = new Class({
  /*
  options: {
    traverse: true,
    extract: true
  },
  */

  constructors: {
    layout: function(options) {
      if (!options.document && !this.document && LSD.document)
        this.properties.set('document', LSD.document);
      this.layouts = {};
    }
  },

  addLayout: function(name, layout, parent, memo) {
    if (!memo) memo = {};
    var old = this.layouts[name];
    if (old) {
      this.document.layout.add(old, parent, memo)
    } else {
      var first = layout.push && layout.length && layout[0];
      var method = (first && first.nodeType && ((first.nodeType != 1) || (!first.lsd))) ? 'children' : 'render';
      old = this.layouts[name] = this.document.layout[method](layout, parent, memo);
    }
    if (memo.promised) {
      memo.promised = false;
      this.addEvent('DOMChildNodesRendered:once', function() {
        this.document.layout.realize(old)
      });
    }
    return this.layouts[name];
  },

  removeLayout: function(name, layout, parent, memo) {
    return this.document.layout.remove(this.layouts[name] || layout, parent, memo);
  },

  buildLayout: function(layout, parent, memo) {
    return this.document.layout[layout.charAt ? 'selector' : 'render'](layout, (!parent && parent !== false) ? this : parent, memo)
  }
});

LSD.Module.Layout.events = {
  /*
    Builds children after element is built
  */
  build: function() {
    if (this.properties.layout) {
      this.addLayout('options', this.properties.layout, [this, this.getWrapper()], {lazy: true});
    }
    if (this.origin && !this.options.clone && this.origin.parentNode && this.origin != this.element)
      this.element.replaces(this.origin);
    if ((!this.options.lazy && this.options.traverse !== false) || (this.origin && this.origin != this.element)) {
      var nodes = LSD.slice((this.origin || this.element).childNodes);
      var opts = {};
      if (this.options.context) opts.context = this.options.context;
      if (this.options.clone) opts.clone = this.options.clone;
      if (nodes.length) this.addLayout('children', nodes, [this, this.getWrapper()], opts);
      this.fireEvent('DOMChildNodesRendered');
    }
  },
  /*
    Destroys the built layout with the widget
  */
  destroy: function() {
    if (this.layouts.children) this.removeLayout('children');
    if (this.layouts.options) this.removeLayout('options');
  },
  /*
    Augments all parsed HTML that goes through standart .write() interface
  */
  write: function(node) {
    this.addLayout('written', node, [this, this.getWrapper()]);
  },
  /*
    Augments all inserted nodes that come from partial html updates
  */
  DOMNodeInserted: function(node) {
    this.buildLayout(node, [this, this.getWrapper()]);
  },
  DOMNodeInsertedBefore: function(node, target) {
    this.buildLayout(node, [this, this.getWrapper()], null, {before: target});
  }
};

LSD.Module.Events.addEvents.call(LSD.Module.Layout.prototype, LSD.Module.Layout.events);

Object.append(LSD.Options, {
  layout: {
    add: function(value) {
      this.properties.set('layout', value);
    },
    remove: function(value) {
      this.properties.unset('layout', value);
    }
  }
});<commit_msg>Simplify layout api: build/add/removeLayout methods will set parents automatically if its given as null<commit_after>/*
---

script: Expression.js

description: Adds layout capabilities to widget (parse and render widget trees from objects)

license: Public domain (http://unlicense.org).

authors: Yaroslaff Fedin

requires:
  - LSD.Module
  - LSD.Module.Events
  - LSD.Layout
  - LSD.Layout.Branch
  - LSD.Layout.Microdata
  - LSD.Layout.Promise

provides:
  - LSD.Module.Layout

...
*/

LSD.Module.Layout = new Class({
  /*
  options: {
    traverse: true,
    extract: true
  },
  */

  constructors: {
    layout: function(options) {
      if (!options.document && !this.document && LSD.document)
        this.properties.set('document', LSD.document);
      this.layouts = {};
    }
  },

  addLayout: function(name, layout, parent, memo) {
    if (parent == null) parent = [this, this.getWrapper()];
    if (!memo) memo = {};
    var old = this.layouts[name];
    if (old) {
      this.document.layout.add(old, parent, memo)
    } else {
      var first = layout.push && layout.length && layout[0];
      var method = (first && first.nodeType && ((first.nodeType != 1) || (!first.lsd))) ? 'children' : 'render';
      old = this.layouts[name] = this.document.layout[method](layout, parent, memo);
    }
    if (memo.promised) {
      memo.promised = false;
      this.addEvent('DOMChildNodesRendered:once', function() {
        this.document.layout.realize(old)
      });
    }
    return this.layouts[name];
  },

  removeLayout: function(name, layout, parent, memo) {
    if (parent == null) parent = [this, this.getWrapper()];
    if (this.layouts[name])
      return this.document.layout.remove(this.layouts[name], parent, memo);
  },

  buildLayout: function(layout, parent, memo) {
    if (parent == null) parent = [this, this.getWrapper()];
    return this.document.layout[layout.charAt ? 'selector' : 'render'](layout, parent, memo)
  }
});

LSD.Module.Layout.events = {
  /*
    Builds children after element is built
  */
  build: function() {
    if (this.properties.layout) {
      this.addLayout('options', this.properties.layout, null, {lazy: true});
    }
    if (this.origin && !this.options.clone && this.origin.parentNode && this.origin != this.element)
      this.element.replaces(this.origin);
    if ((!this.options.lazy && this.options.traverse !== false) || (this.origin && this.origin != this.element)) {
      var nodes = LSD.slice((this.origin || this.element).childNodes);
      var opts = {};
      if (this.options.context) opts.context = this.options.context;
      if (this.options.clone) opts.clone = this.options.clone;
      if (nodes.length) this.addLayout('children', nodes, null, opts);
      this.fireEvent('DOMChildNodesRendered');
    }
  },
  /*
    Destroys the built layout with the widget
  */
  destroy: function() {
    if (this.layouts.children) this.removeLayout('children');
    if (this.layouts.options) this.removeLayout('options');
  },
  /*
    Augments all parsed HTML that goes through standart .write() interface
  */
  write: function(node) {
    this.addLayout('written', node, null);
  },
  /*
    Augments all inserted nodes that come from partial html updates
  */
  DOMNodeInserted: function(node) {
    this.buildLayout(node, null);
  },
  DOMNodeInsertedBefore: function(node, target) {
    this.buildLayout(node, null, null, {before: target});
  }
};

LSD.Module.Events.addEvents.call(LSD.Module.Layout.prototype, LSD.Module.Layout.events);

Object.append(LSD.Options, {
  layout: {
    add: function(value) {
      this.properties.set('layout', value);
    },
    remove: function(value) {
      this.properties.unset('layout', value);
    }
  }
});<|endoftext|>


<commit_before>let hasPM2;

try {
    require.resolve("pm2");
    hasPM2 = "PM2 is installed, hopefully I will reboot!";
} catch (e) {
    hasPM2 = "I cannot find PM2, you must restart manually.";
}

exports.run = async (client, message, cmd, args, level) => { // eslint-disable-line no-unused-vars
    await message.channel.send(`${message.author}, ${client.user.username} is shutting down. ${hasPM2}
*<RRRRDDTT!!!! Wewewedt! Veeeeedt!>*`);
    process.exit(1);
};

exports.conf = {
    enabled: true,
    guildOnly: false,
    aliases: ["restart", "shutdown"],
    permLevel: "Bot Admin"
};

exports.help = {
    name: "reboot",
    category: "System",
    description: "Shuts down the bot, if running under PM2, will restart automatically",
    usage: "reboot"
};
<commit_msg>Updated restart message<commit_after>let hasPM2;

try {
    require.resolve("pm2");
    hasPM2 = "PM2 is installed, hopefully I will reboot!";
} catch (e) {
    hasPM2 = "I cannot find PM2, you must restart manually.";
}

exports.run = async (client, message, cmd, args, level) => { // eslint-disable-line no-unused-vars
    await message.channel.send(`${message.author}, ${client.user.username} is shutting down and might restart if you're lucky!
*<RRRRDDTT!!!! Wewewedt! Veeeeedt!>*`);
    process.exit(1);
};

exports.conf = {
    enabled: true,
    guildOnly: false,
    aliases: ["restart", "shutdown"],
    permLevel: "Bot Admin"
};

exports.help = {
    name: "reboot",
    category: "System",
    description: "Shuts down the bot, if running under PM2, will restart automatically",
    usage: "reboot"
};
<|endoftext|>