<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 */

import { BackSide, FrontSide } from '../../constants.js';
import { BoxBufferGeometry } from '../../geometries/BoxGeometry.js';
import { PlaneBufferGeometry } from '../../geometries/PlaneGeometry.js';
import { ShaderMaterial } from '../../materials/ShaderMaterial.js';
import { Color } from '../../math/Color.js';
import { Mesh } from '../../objects/Mesh.js';
import { ShaderLib } from '../shaders/ShaderLib.js';
import { cloneUniforms } from '../shaders/UniformsUtils.js';

function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {

	var clearColor = new Color( 0x000000 );
	var clearAlpha = 0;

	var planeMesh;
	var boxMesh;
	// Store the current background texture and its `version`
	// so we can recompile the material accordingly.
	var currentBackground = null;
	var currentBackgroundVersion = 0;

	function render( renderList, scene, camera, forceClear ) {

		var background = scene.background;

		if ( background === null ) {

			setClear( clearColor, clearAlpha );
			currentBackground = null;
			currentBackgroundVersion = 0;

		} else if ( background && background.isColor ) {

			setClear( background, 1 );
			forceClear = true;
			currentBackground = null;
			currentBackgroundVersion = 0;

		}

		if ( renderer.autoClear || forceClear ) {

			renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );

		}

		if ( background && ( background.isCubeTexture || background.isWebGLRenderTargetCube ) ) {

			if ( boxMesh === undefined ) {

				boxMesh = new Mesh(
					new BoxBufferGeometry( 1, 1, 1 ),
					new ShaderMaterial( {
						type: 'BackgroundCubeMaterial',
						uniforms: cloneUniforms( ShaderLib.cube.uniforms ),
						vertexShader: ShaderLib.cube.vertexShader,
						fragmentShader: ShaderLib.cube.fragmentShader,
						side: BackSide,
						depthTest: true,
						depthWrite: false,
						fog: false
					} )
				);

				boxMesh.geometry.removeAttribute( 'normal' );
				boxMesh.geometry.removeAttribute( 'uv' );

				boxMesh.onBeforeRender = function ( renderer, scene, camera ) {

					this.matrixWorld.copyPosition( camera.matrixWorld );

				};

				// enable code injection for non-built-in material
				Object.defineProperty( boxMesh.material, 'map', {

					get: function () {

						return this.uniforms.tCube.value;

					}

				} );

				objects.update( boxMesh );

			}

			var texture = background.isWebGLRenderTargetCube ? background.texture : background;
			boxMesh.material.uniforms.tCube.value = texture;
			boxMesh.material.uniforms.tFlip.value = ( background.isWebGLRenderTargetCube ) ? 1 : - 1;

			if ( currentBackground !== background ||
			     currentBackgroundVersion !== texture.version ) {

				boxMesh.material.needsUpdate = true;

				currentBackground = background;
				currentBackgroundVersion = texture.version;

			}

			// push to the pre-sorted opaque render list
			renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null );

		} else if ( background && background.isTexture ) {

			if ( planeMesh === undefined ) {

				planeMesh = new Mesh(
					new PlaneBufferGeometry( 2, 2 ),
					new ShaderMaterial( {
						type: 'BackgroundMaterial',
						uniforms: cloneUniforms( ShaderLib.background.uniforms ),
						vertexShader: ShaderLib.background.vertexShader,
						fragmentShader: ShaderLib.background.fragmentShader,
						side: FrontSide,
						depthTest: false,
						depthWrite: false,
						fog: false
					} )
				);

				planeMesh.geometry.removeAttribute( 'normal' );

				// enable code injection for non-built-in material
				Object.defineProperty( planeMesh.material, 'map', {

					get: function () {

						return this.uniforms.t2D.value;

					}

				} );

				objects.update( planeMesh );

			}

			planeMesh.material.uniforms.t2D.value = background;

			if ( background.matrixAutoUpdate === true ) {

				background.updateMatrix();

			}

			planeMesh.material.uniforms.uvTransform.value.copy( background.matrix );

			if ( currentBackground !== background ||
				   currentBackgroundVersion !== background.version ) {

				planeMesh.material.needsUpdate = true;

				currentBackground = background;
				currentBackgroundVersion = background.version;

			}

			// push to the pre-sorted opaque render list
			renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null );

		}

	}

	function setClear( color, alpha ) {

		state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha );

	}

	return {

		getClearColor: function () {

			return clearColor;

		},
		setClearColor: function ( color, alpha ) {

			clearColor.set( color );
			clearAlpha = alpha !== undefined ? alpha : 1;
			setClear( clearColor, clearAlpha );

		},
		getClearAlpha: function () {

			return clearAlpha;

		},
		setClearAlpha: function ( alpha ) {

			clearAlpha = alpha;
			setClear( clearColor, clearAlpha );

		},
		render: render

	};

}

export { WebGLBackground };
<commit_msg>WebGLBackgrounds from cube textures should no longer check depth buffer; follow up fix from #15239<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 */

import { BackSide, FrontSide } from '../../constants.js';
import { BoxBufferGeometry } from '../../geometries/BoxGeometry.js';
import { PlaneBufferGeometry } from '../../geometries/PlaneGeometry.js';
import { ShaderMaterial } from '../../materials/ShaderMaterial.js';
import { Color } from '../../math/Color.js';
import { Mesh } from '../../objects/Mesh.js';
import { ShaderLib } from '../shaders/ShaderLib.js';
import { cloneUniforms } from '../shaders/UniformsUtils.js';

function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {

	var clearColor = new Color( 0x000000 );
	var clearAlpha = 0;

	var planeMesh;
	var boxMesh;
	// Store the current background texture and its `version`
	// so we can recompile the material accordingly.
	var currentBackground = null;
	var currentBackgroundVersion = 0;

	function render( renderList, scene, camera, forceClear ) {

		var background = scene.background;

		if ( background === null ) {

			setClear( clearColor, clearAlpha );
			currentBackground = null;
			currentBackgroundVersion = 0;

		} else if ( background && background.isColor ) {

			setClear( background, 1 );
			forceClear = true;
			currentBackground = null;
			currentBackgroundVersion = 0;

		}

		if ( renderer.autoClear || forceClear ) {

			renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );

		}

		if ( background && ( background.isCubeTexture || background.isWebGLRenderTargetCube ) ) {

			if ( boxMesh === undefined ) {

				boxMesh = new Mesh(
					new BoxBufferGeometry( 1, 1, 1 ),
					new ShaderMaterial( {
						type: 'BackgroundCubeMaterial',
						uniforms: cloneUniforms( ShaderLib.cube.uniforms ),
						vertexShader: ShaderLib.cube.vertexShader,
						fragmentShader: ShaderLib.cube.fragmentShader,
						side: BackSide,
						depthTest: false,
						depthWrite: false,
						fog: false
					} )
				);

				boxMesh.geometry.removeAttribute( 'normal' );
				boxMesh.geometry.removeAttribute( 'uv' );

				boxMesh.onBeforeRender = function ( renderer, scene, camera ) {

					this.matrixWorld.copyPosition( camera.matrixWorld );

				};

				// enable code injection for non-built-in material
				Object.defineProperty( boxMesh.material, 'map', {

					get: function () {

						return this.uniforms.tCube.value;

					}

				} );

				objects.update( boxMesh );

			}

			var texture = background.isWebGLRenderTargetCube ? background.texture : background;
			boxMesh.material.uniforms.tCube.value = texture;
			boxMesh.material.uniforms.tFlip.value = ( background.isWebGLRenderTargetCube ) ? 1 : - 1;

			if ( currentBackground !== background ||
			     currentBackgroundVersion !== texture.version ) {

				boxMesh.material.needsUpdate = true;

				currentBackground = background;
				currentBackgroundVersion = texture.version;

			}

			// push to the pre-sorted opaque render list
			renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null );

		} else if ( background && background.isTexture ) {

			if ( planeMesh === undefined ) {

				planeMesh = new Mesh(
					new PlaneBufferGeometry( 2, 2 ),
					new ShaderMaterial( {
						type: 'BackgroundMaterial',
						uniforms: cloneUniforms( ShaderLib.background.uniforms ),
						vertexShader: ShaderLib.background.vertexShader,
						fragmentShader: ShaderLib.background.fragmentShader,
						side: FrontSide,
						depthTest: false,
						depthWrite: false,
						fog: false
					} )
				);

				planeMesh.geometry.removeAttribute( 'normal' );

				// enable code injection for non-built-in material
				Object.defineProperty( planeMesh.material, 'map', {

					get: function () {

						return this.uniforms.t2D.value;

					}

				} );

				objects.update( planeMesh );

			}

			planeMesh.material.uniforms.t2D.value = background;

			if ( background.matrixAutoUpdate === true ) {

				background.updateMatrix();

			}

			planeMesh.material.uniforms.uvTransform.value.copy( background.matrix );

			if ( currentBackground !== background ||
				   currentBackgroundVersion !== background.version ) {

				planeMesh.material.needsUpdate = true;

				currentBackground = background;
				currentBackgroundVersion = background.version;

			}

			// push to the pre-sorted opaque render list
			renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null );

		}

	}

	function setClear( color, alpha ) {

		state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha );

	}

	return {

		getClearColor: function () {

			return clearColor;

		},
		setClearColor: function ( color, alpha ) {

			clearColor.set( color );
			clearAlpha = alpha !== undefined ? alpha : 1;
			setClear( clearColor, clearAlpha );

		},
		getClearAlpha: function () {

			return clearAlpha;

		},
		setClearAlpha: function ( alpha ) {

			clearAlpha = alpha;
			setClear( clearColor, clearAlpha );

		},
		render: render

	};

}

export { WebGLBackground };
<|endoftext|>


<commit_before>kWidget.addReadyCallback( function( playerId ){
	/**
	 * The main omnitureOnPage object:
	 */
	var omnitureOnPage = function( player ){
		return this.init( player );
	}
	omnitureOnPage.prototype = {
		instanceName: 'omnitureOnPage',
		sCodeLoaded: false,
		init: function( player ){
			var _this = this;
			this.kdp = player;
			// unbind any existing bindings:
			this.kdp.kUnbind( '.' + this.instanceName );
			this.bind('entryReady', function() {
				// Check for on-page s-code that already exists
				_this.sCodeCheck(function(){
					_this.setupMonitor();
					_this.bindPlayer();
					_this.bindCustomEvents();
				});
			});
		},
		getSCodeName: function(){
			return this.getConfig('s_codeVarName') || 's';
		},
		sCodeCheck: function( callback ){
			var _this = this;

			// Run sCode check once
			if( this.sCodeLoaded ) {
				return ;
			}

			var doneCallback = function() {
				// Override s_code object with local configuration
				var configFuncName = _this.getConfig('s_codeConfigFunc');
				if( configFuncName && typeof window[ configFuncName ] == 'function' ) {
					var localConfig = window[ configFuncName ]();
					for( var k in localConfig ) {
						window[ _this.getSCodeName() ][ k ] = localConfig[ k ];
					}
				}

				_this.sCodeLoaded = true;

				if(callback) {
					callback();
				}
			}
			// check if already on the page:
			if( window[ this.getSCodeName() ] && window[ this.getSCodeName() ]['Media'] ){
				doneCallback();
				return ;
			}

			// check if we have scode
			if( !_this.getConfig('s_codeUrl') ){
				kWidget.log( "Error: s_codeUrl must be set for Omniture onPage plugin");
				return ;
			}
			kWidget.appendScriptUrl( _this.getConfig('s_codeUrl'), doneCallback );
		},
		/** Getters **/
		getMediaPlayerName: function(){
			return 'Kaltura Omniture OnPage v' + mw.getConfig('version');
		},
		getMediaName: function(){
	 		var _this = this;
	 		// shortcut to custom data
	 		var g = function( key ){
	 			return _this.getAttr( 'mediaProxy.entryMetadata.' + key ) || '_';
	 		}
 			switch( _this.getConfig( 'concatMediaName' ) ){
 				case 'doluk':
 					var refId = _this.kdp.evaluate( '{mediaProxy.entry.referenceId}' )
 					if( !refId )
 						refId = _this.kdp.evaluate( '{mediaProxy.entry.id}' )
 					return [ g('SiteSection'), g('PropertyCode'),
 						g('ContentType'),  g('ShortTitle').substr(0,30),
 						_this.getDuration(),  refId
 						].join(':').replace(/\s/g, "_");
 				break;
 			}
			return this.getAttr('mediaProxy.entry.name');
		},
		getDuration: function(){
			return this.getAttr('mediaProxy.entry.duration').toString();
		},
		getCurrentTime: function(){
			return Math.floor( parseInt(this.getAttr('video.player.currentTime')) );
		},
		bindPlayer: function(){
			var _this = this;
			var firstPlay = true;
			// setup shortcuts:
			var stop = function(){
				_this.runMediaCommand( "stop", _this.getMediaName(), _this.getCurrentTime() );
			}
			var play = function(){
				_this.runMediaCommand( "play", _this.getMediaName(), _this.getCurrentTime() );
			}
			// Run open on first play:
			this.bind( 'doPlay', function(){
				if( firstPlay ){
					_this.runMediaCommand( "open",
						_this.getMediaName(),
						_this.getDuration(),
						_this.getMediaPlayerName()
					)
				}
				firstPlay = false;
				play();
			});
			this.bind( 'playerSeekStart', function() {
				// Ignore HTML5 seek to 0 on PlayerPlayEnd
				if(firstPlay) return;
				stop();
			});
			this.bind( 'playerSeekEnd', function() {
				// Ignore HTML5 seek to 0 on PlayerPlayEnd
				if(firstPlay) return;
				play();
			});
			this.bind( 'doPause', stop );
			this.bind( 'playerPlayEnd', function(){
				stop();
				_this.runMediaCommand( "close", _this.getMediaName() );
				firstPlay = true;
			});
		},

		bindCustomEvents: function() {
			var _this = this;
			var customEvents = _this.getConfig( 'customEvents' );
			if( !customEvents ) {
				return ;
			}
			customEvents = customEvents.split( ',' );

			// Get all the plugin config for all the omniture events
			for( var i = 0; i < customEvents.length; i++ ) {
				(function(eventName) {
					var eventId = _this.getConfig( eventName + 'Event' );
					if( ! eventId ){
						return true; // next
					}
					// Add the binding:
					_this.bind( eventName, function(){
						_this.sendNotification( eventId, eventName );
					});
				}(customEvents[i]));
			}
		},

		getPropsAndEvars: function( eventName ){
	 		var _this = this;
	 		var propsAndEvars = {};
	 		// Look for up-to 10 associated eVars
			for( var i = 1 ; i < 10; i++ ){
				var eVarId = _this.getConfig( eventName + 'Evar' + i );
				var eVarVal = _this.getConfig( eventName + 'Evar' + i + 'Value' );

				// Stop looking for more eVars if we did not find one:
				if( ! eVarId ){
					break;
				}
				propsAndEvars[ eVarId ] = eVarVal;
			}
			// Special Case a few base eVar mappings
			if( this.getConfig( 'contentType') ){
				propsAndEvars[  this.getConfig( 'contentType') ] = this.getCType();
			}
			// Look for up-to 10 associated Props
			for( var i = 1 ; i < 10; i++ ){
				var ePropId = _this.getConfig( eventName + 'Prop' + i );
				var ePropVal = _this.getConfig( eventName + 'Prop' + i + 'Value' );
				if( !ePropId )
					break;
				propsAndEvars[ ePropId ] = ePropVal;
			}
			return propsAndEvars;
	 	},

		getCType: function(){
	 		if( this.embedPlayer.mediaElement.selectedSource ){
				var ctype = this.embedPlayer.mediaElement.selectedSource.mimeType;
				if( ctype.indexOf('/') != -1 ){
					return ctype.split('/')[0];
				}
	 		}
			// default to video if we can't detect content type from mime
			return 'video';
	 	},

		runMediaCommand: function(){
			// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments#Description
	 		var args = Array.prototype.slice.call( arguments );
	 		var cmd = args[0];
	 		var argSet = args.slice( 1 );

	 		var s = window[ this.getSCodeName() ];
	 		try {
	 			// When using argSet.join we turn all arguments to string, we need to send them with the same type
	 			//eval( this.getSCodeName() + '.Media.' + cmd + '("' + argSet.join('","') + '");');
	 			// not working :(
	 			//s.Media[cmd].apply( this, args );
		 		switch( cmd ) {
		 			case 'open':
		 				s.Media.open(argSet[0], argSet[1], args[2]);
		 			break;
		 			case 'play':
		 				s.Media.play(argSet[0], argSet[1]);
		 			break;
		 			case 'stop':
		 				s.Media.stop(argSet[0], argSet[1]);
		 			break;
		 			case 'close':
		 				s.Media.close(argSet[0]);
		 			break;
		 		}
		 	} catch( e ) {
	 			kWidget.log( "Error: Omniture, trying to run media command:" + cmd + ' does not exist' );
	 		}
	 		// audit if trackEventMonitor is set:
	 		if( this.getConfig( 'trackEventMonitor') ){
		 		try{
		 			if( window[ this.getConfig( 'trackEventMonitor') ] ){
		 				window[ this.getConfig( 'trackEventMonitor') ]( this.getSCodeName() +
		 					'.Media.' + cmd + '( "' + argSet.join('", "') + '" )' );
		 			}
		 		} catch ( e ){}
	 		}
	 	},

		/**
	 	 * Dispatches an event to omniture via the s.track(); call
	 	 *
	 	 * @param {String} eventId The omniture event id
	 	 * @param {=String} eventName Optional eventName for logging ( not used in the omniture beacon )
	 	 * @return
	 	 */
	 	sendNotification: function( eventId, eventName ){
	 		var _this = this;
	 		// mark everything we updated for logging and audit
	 		var oDebugDispatch = {};
	 		// Get the proprs and evars:
	 		var propsAndEvars = _this.getPropsAndEvars( eventName );
	 		// dispatch the "s" event:

	 		oDebugDispatch['trackEvents'] = s.Media.trackEvents;
	 		// check if we have associated eVars:
	 		if( ! kWidget.isEmptyObject( propsAndEvars ) ){
	 			s.Media.trackEvents += ',eVars';
	 			// Build props and evars
				for ( var key in propsAndEvars ){
					s[ key ] = propsAndEvars[ key ];
					oDebugDispatch[key] = propsAndEvars[ key ];
				}
	 		}
	 		if( eventId ){
	 			s.events = eventId;
	 			oDebugDispatch['events'] = s.events;
	 		}

	 		try {
	 			var logMethod = this.getConfig( 'trackEventMonitor' );
	 			var logEvent = eventName || '';
	 			window[ logMethod ](
	 				logEvent,
					oDebugDispatch
				);
	 			kWidget.log( "Omniture: s.track(), state:" +  logEvent, oDebugDispatch)
	 		} catch ( e ){ }

	 		// dispatch the event
	 		if( !s.track ){
	 			// sometimes s.track is not defined? s.t seems to be the replacement :(
	 			s.tl();
	 		} else {
	 			s.track();
	 		}
	 	},
		normalizeAttrValue: function( attrValue ){
			// normalize flash kdp string values
			switch( attrValue ){
				case "null":
					return null;
				break;
				case "true":
					return true;
				break;
				case "false":
					return false;
				break;
			}
			return attrValue;
		},
		bind: function( eventName, callback ){
			// postfix the instanceName to namespace all the bindings
			this.kdp.kBind( eventName + '.' + this.instanceName, callback );
		},
		getAttr: function( attr ){
			return this.normalizeAttrValue(
				this.kdp.evaluate( '{' + attr + '}' )
			);
		},
		getConfig : function( attr ){
			return this.normalizeAttrValue(
				this.kdp.evaluate( '{' + this.instanceName + '.' + attr + '}' )
			);
		}
	}

	/**********************************
	 * Initialization of omnitureOnpage:
	 **********************************/
	new omnitureOnPage( document.getElementById( playerId ) );
});
<commit_msg>Added monitor event to omniture (comented out)<commit_after>kWidget.addReadyCallback( function( playerId ){
	/**
	 * The main omnitureOnPage object:
	 */
	var omnitureOnPage = function( player ){
		return this.init( player );
	}
	omnitureOnPage.prototype = {
		instanceName: 'omnitureOnPage',
		sCodeLoaded: false,
		init: function( player ){
			var _this = this;
			this.kdp = player;
			// unbind any existing bindings:
			this.kdp.kUnbind( '.' + this.instanceName );
			this.bind('entryReady', function() {
				// Check for on-page s-code that already exists
				_this.sCodeCheck(function(){
					_this.setupMonitor();
					_this.bindPlayer();
					_this.bindCustomEvents();
				});
			});
		},
		getSCodeName: function(){
			return this.getConfig('s_codeVarName') || 's';
		},
		sCodeCheck: function( callback ){
			var _this = this;

			// Run sCode check once
			if( this.sCodeLoaded ) {
				return ;
			}

			var doneCallback = function() {
				// Override s_code object with local configuration
				var configFuncName = _this.getConfig('s_codeConfigFunc');
				if( configFuncName && typeof window[ configFuncName ] == 'function' ) {
					var localConfig = window[ configFuncName ]();
					for( var k in localConfig ) {
						window[ _this.getSCodeName() ][ k ] = localConfig[ k ];
					}
				}

				_this.sCodeLoaded = true;

				if(callback) {
					callback();
				}
			}
			// check if already on the page:
			if( window[ this.getSCodeName() ] && window[ this.getSCodeName() ]['Media'] ){
				doneCallback();
				return ;
			}

			// check if we have scode
			if( !_this.getConfig('s_codeUrl') ){
				kWidget.log( "Error: s_codeUrl must be set for Omniture onPage plugin");
				return ;
			}
			kWidget.appendScriptUrl( _this.getConfig('s_codeUrl'), doneCallback );
		},
		/** Getters **/
		getMediaPlayerName: function(){
			return 'Kaltura Omniture OnPage v' + mw.getConfig('version');
		},
		getMediaName: function(){
	 		var _this = this;
	 		// shortcut to custom data
	 		var g = function( key ){
	 			return _this.getAttr( 'mediaProxy.entryMetadata.' + key ) || '_';
	 		}
 			switch( _this.getConfig( 'concatMediaName' ) ){
 				case 'doluk':
 					var refId = _this.kdp.evaluate( '{mediaProxy.entry.referenceId}' )
 					if( !refId )
 						refId = _this.kdp.evaluate( '{mediaProxy.entry.id}' )
 					return [ g('SiteSection'), g('PropertyCode'),
 						g('ContentType'),  g('ShortTitle').substr(0,30),
 						_this.getDuration(),  refId
 						].join(':').replace(/\s/g, "_");
 				break;
 			}
			return this.getAttr('mediaProxy.entry.name');
		},
		getDuration: function(){
			return this.getAttr('mediaProxy.entry.duration').toString();
		},
		getCurrentTime: function(){
			return Math.floor( parseInt(this.getAttr('video.player.currentTime')) );
		},
		/*
		Support passing global evars to all events
		additionalEvarsAndProps="eVar51,eVar52,eVar53,eVar54,prop44"
		additionalEvarsAndPropsValues="{mediaProxy.entry.creatorId},
			{mediaProxy.entry.createdAt},{configProxy.flashvars.referer},
			{mediaProxy.entry.duration},{configProxy.flashvars.streamerType}"
		*/
		setupMonitor: function() {

			// Check for addtional eVars and eVars values
			var additionalEvarsAndProps = this.getConfig('additionalEvarsAndProps');
			var additionalEvarsAndPropsValues = this.getConfig('additionalEvarsAndPropsValues');
			if( !additionalEvarsAndProps || !additionalEvarsAndPropsValues ) {
				kWidget.log('omnitureOnPage:: No addtional eVars and Values');
				return ;
			}

			var extraEvars = additionalEvarsAndProps.split(",");
			var extraEvarsValues = additionalEvarsAndPropsValues.split(",");
			// Compare length between eVars and eVars values
			if( extraEvars.length == 0 || extraEvarsValues.length == 0
				|| (extraEvars.length !== extraEvarsValues.length) ) {
				kWidget.log('omnitureOnPage:: Addtional eVars and Values length does not match');
				return ;
			}

			var s = window[ this.getSCodeName() ];
			var trackMediaWithExtraEvars = function() {
				for(var i=0; i<extraEvars.length; i++) {
					(function(key, val) {
						console.log('eVar: ' + key + ' - eValue: ' + val);
						// Set extra eVars and eVars values on s object
						s[ key ] = val;

					})(extraEvars[i], extraEvarsValues[i]);
				}
				// Call s.track method
				s.Media.track( this.getMediaName() );
			};

			// Check if we have monitor function
			var originalMediaFunc = s.Media.monitor;

			// List of events we want to track
			var trackEvents = ['OPEN', 'CLOSE', 'PLAY', 'STOP', 'SECONDS', 'MILESTONE'];

			/*
			 * Commented out due to some errors
			 *
			s.Media.monitor = function ( s, media ) {
				if( trackEvents.indexOf(media.event) !== -1 ) {
					trackMediaWithExtraEvars();
				}
				if( typeof originalMediaFunc == 'function' ) {
					originalMediaFunc( s, media );
				}
			};
			**/

		},
		bindPlayer: function(){
			var _this = this;
			var firstPlay = true;
			// setup shortcuts:
			var stop = function(){
				_this.runMediaCommand( "stop", _this.getMediaName(), _this.getCurrentTime() );
			}
			var play = function(){
				_this.runMediaCommand( "play", _this.getMediaName(), _this.getCurrentTime() );
			}
			// Run open on first play:
			this.bind( 'doPlay', function(){
				if( firstPlay ){
					_this.runMediaCommand( "open",
						_this.getMediaName(),
						_this.getDuration(),
						_this.getMediaPlayerName()
					)
				}
				firstPlay = false;
				play();
			});
			this.bind( 'playerSeekStart', function() {
				// Ignore HTML5 seek to 0 on PlayerPlayEnd
				if(firstPlay) return;
				stop();
			});
			this.bind( 'playerSeekEnd', function() {
				// Ignore HTML5 seek to 0 on PlayerPlayEnd
				if(firstPlay) return;
				play();
			});
			this.bind( 'doPause', stop );
			this.bind( 'playerPlayEnd', function(){
				stop();
				_this.runMediaCommand( "close", _this.getMediaName() );
				firstPlay = true;
			});
		},

		bindCustomEvents: function() {
			var _this = this;
			var customEvents = _this.getConfig( 'customEvents' );
			if( !customEvents ) {
				return ;
			}
			customEvents = customEvents.split( ',' );

			// Get all the plugin config for all the omniture events
			for( var i = 0; i < customEvents.length; i++ ) {
				(function(eventName) {
					var eventId = _this.getConfig( eventName + 'Event' );
					if( ! eventId ){
						return true; // next
					}
					// Add the binding:
					_this.bind( eventName, function(){
						_this.sendNotification( eventId, eventName );
					});
				}(customEvents[i]));
			}
		},

		getPropsAndEvars: function( eventName ){
	 		var _this = this;
	 		var propsAndEvars = {};
	 		// Look for up-to 10 associated eVars
			for( var i = 1 ; i < 10; i++ ){
				var eVarId = _this.getConfig( eventName + 'Evar' + i );
				var eVarVal = _this.getConfig( eventName + 'Evar' + i + 'Value' );

				// Stop looking for more eVars if we did not find one:
				if( ! eVarId ){
					break;
				}
				propsAndEvars[ eVarId ] = eVarVal;
			}
			// Special Case a few base eVar mappings
			if( this.getConfig( 'contentType') ){
				propsAndEvars[  this.getConfig( 'contentType') ] = this.getCType();
			}
			// Look for up-to 10 associated Props
			for( var i = 1 ; i < 10; i++ ){
				var ePropId = _this.getConfig( eventName + 'Prop' + i );
				var ePropVal = _this.getConfig( eventName + 'Prop' + i + 'Value' );
				if( !ePropId )
					break;
				propsAndEvars[ ePropId ] = ePropVal;
			}
			return propsAndEvars;
	 	},

		getCType: function(){
	 		if( this.embedPlayer.mediaElement.selectedSource ){
				var ctype = this.embedPlayer.mediaElement.selectedSource.mimeType;
				if( ctype.indexOf('/') != -1 ){
					return ctype.split('/')[0];
				}
	 		}
			// default to video if we can't detect content type from mime
			return 'video';
	 	},

		runMediaCommand: function(){
			// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments#Description
	 		var args = Array.prototype.slice.call( arguments );
	 		var cmd = args[0];
	 		var argSet = args.slice( 1 );

	 		var s = window[ this.getSCodeName() ];
	 		try {
	 			// When using argSet.join we turn all arguments to string, we need to send them with the same type
	 			//eval( this.getSCodeName() + '.Media.' + cmd + '("' + argSet.join('","') + '");');
	 			// not working :(
	 			//s.Media[cmd].apply( this, args );
		 		switch( cmd ) {
		 			case 'open':
		 				s.Media.open(argSet[0], argSet[1], args[2]);
		 			break;
		 			case 'play':
		 				s.Media.play(argSet[0], argSet[1]);
		 			break;
		 			case 'stop':
		 				s.Media.stop(argSet[0], argSet[1]);
		 			break;
		 			case 'close':
		 				s.Media.close(argSet[0]);
		 			break;
		 		}
		 	} catch( e ) {
	 			kWidget.log( "Error: Omniture, trying to run media command:" + cmd + ' does not exist' );
	 		}
	 		// audit if trackEventMonitor is set:
	 		if( this.getConfig( 'trackEventMonitor') ){
		 		try{
		 			if( window[ this.getConfig( 'trackEventMonitor') ] ){
		 				window[ this.getConfig( 'trackEventMonitor') ]( this.getSCodeName() +
		 					'.Media.' + cmd + '( "' + argSet.join('", "') + '" )' );
		 			}
		 		} catch ( e ){}
	 		}
	 	},

		/**
	 	 * Dispatches an event to omniture via the s.track(); call
	 	 *
	 	 * @param {String} eventId The omniture event id
	 	 * @param {=String} eventName Optional eventName for logging ( not used in the omniture beacon )
	 	 * @return
	 	 */
	 	sendNotification: function( eventId, eventName ){
	 		var _this = this;
	 		// mark everything we updated for logging and audit
	 		var oDebugDispatch = {};
	 		// Get the proprs and evars:
	 		var propsAndEvars = _this.getPropsAndEvars( eventName );
	 		// dispatch the "s" event:

	 		oDebugDispatch['trackEvents'] = s.Media.trackEvents;
	 		// check if we have associated eVars:
	 		if( ! kWidget.isEmptyObject( propsAndEvars ) ){
	 			s.Media.trackEvents += ',eVars';
	 			// Build props and evars
				for ( var key in propsAndEvars ){
					s[ key ] = propsAndEvars[ key ];
					oDebugDispatch[key] = propsAndEvars[ key ];
				}
	 		}
	 		if( eventId ){
	 			s.events = eventId;
	 			oDebugDispatch['events'] = s.events;
	 		}

	 		try {
	 			var logMethod = this.getConfig( 'trackEventMonitor' );
	 			var logEvent = eventName || '';
	 			window[ logMethod ](
	 				logEvent,
					oDebugDispatch
				);
	 			kWidget.log( "Omniture: s.track(), state:" +  logEvent, oDebugDispatch)
	 		} catch ( e ){ }

	 		// dispatch the event
	 		if( !s.track ){
	 			// sometimes s.track is not defined? s.t seems to be the replacement :(
	 			s.tl();
	 		} else {
	 			s.track();
	 		}
	 	},
		normalizeAttrValue: function( attrValue ){
			// normalize flash kdp string values
			switch( attrValue ){
				case "null":
					return null;
				break;
				case "true":
					return true;
				break;
				case "false":
					return false;
				break;
			}
			return attrValue;
		},
		bind: function( eventName, callback ){
			// postfix the instanceName to namespace all the bindings
			this.kdp.kBind( eventName + '.' + this.instanceName, callback );
		},
		getAttr: function( attr ){
			return this.normalizeAttrValue(
				this.kdp.evaluate( '{' + attr + '}' )
			);
		},
		getConfig : function( attr ){
			return this.normalizeAttrValue(
				this.kdp.evaluate( '{' + this.instanceName + '.' + attr + '}' )
			);
		}
	}

	/**********************************
	 * Initialization of omnitureOnpage:
	 **********************************/
	new omnitureOnPage( document.getElementById( playerId ) );
});
<|endoftext|>


<commit_before>import React from 'react';
import SPELLS from 'common/SPELLS';
import { formatPercentage, formatThousands } from 'common/format';
import TalentStatisticBox from 'interface/others/TalentStatisticBox';
import Analyzer from 'parser/core/Analyzer';
import Events from 'parser/core/Events';
import { SELECTED_PLAYER } from 'parser/core/EventFilter';

const REDUCTION_BONUS = 0.1;

class Warpaint extends Analyzer {

  damageMitigated = 0;
  damageTaken = 0;

  constructor(...args) {
    super(...args);

    this.active = this.selectedCombatant.hasTalent(SPELLS.WARPAINT_TALENT.id);

    if(!this.active){
      return;
    }

    this.addEventListener(Events.damage.to(SELECTED_PLAYER), this.onPlayerDamageTaken);
  }

  onPlayerDamageTaken(event) {
    if (this.selectedCombatant.hasBuff(SPELLS.ENRAGE.id)) {
      const preMitigatedDefensiveStance = (event.amount + event.absorbed) / (1 - REDUCTION_BONUS);
      this.damageMitigated += preMitigatedDefensiveStance * REDUCTION_BONUS;
    }

    this.damageTaken += event.amount + event.absorbed;
  }

  get damageMitigatedPercent() {
    if(this.damageTaken === 0) {
      return 0;
    }

    return this.damageMitigated / this.damageTaken;
  }

  statistic() {
    return (
      <TalentStatisticBox
        talent={SPELLS.WARPAINT_TALENT.id}
        value={`${formatPercentage(this.damageMitigatedPercent)}% damage mitigated`}
        label="Warpaint"
        tooltip={`Warpaint mitigated a total of <b>${formatThousands(this.damageMitigated)}</b> damage.`}
      />
    );
  }
}

export default Warpaint;<commit_msg>Renamed variable<commit_after>import React from 'react';
import SPELLS from 'common/SPELLS';
import { formatPercentage, formatThousands } from 'common/format';
import TalentStatisticBox from 'interface/others/TalentStatisticBox';
import Analyzer from 'parser/core/Analyzer';
import Events from 'parser/core/Events';
import { SELECTED_PLAYER } from 'parser/core/EventFilter';

const REDUCTION_BONUS = 0.1;

class Warpaint extends Analyzer {

  damageMitigated = 0;
  damageTaken = 0;

  constructor(...args) {
    super(...args);

    this.active = this.selectedCombatant.hasTalent(SPELLS.WARPAINT_TALENT.id);

    if(!this.active){
      return;
    }

    this.addEventListener(Events.damage.to(SELECTED_PLAYER), this.onPlayerDamageTaken);
  }

  onPlayerDamageTaken(event) {
    if (this.selectedCombatant.hasBuff(SPELLS.ENRAGE.id)) {
      const preMitigatedDamage = (event.amount + event.absorbed) / (1 - REDUCTION_BONUS);
      this.damageMitigated += preMitigatedDamage * REDUCTION_BONUS;
    }

    this.damageTaken += event.amount + event.absorbed;
  }

  get damageMitigatedPercent() {
    if(this.damageTaken === 0) {
      return 0;
    }

    return this.damageMitigated / this.damageTaken;
  }

  statistic() {
    return (
      <TalentStatisticBox
        talent={SPELLS.WARPAINT_TALENT.id}
        value={`${formatPercentage(this.damageMitigatedPercent)}% damage mitigated`}
        label="Warpaint"
        tooltip={`Warpaint mitigated a total of <b>${formatThousands(this.damageMitigated)}</b> damage.`}
      />
    );
  }
}

export default Warpaint;<|endoftext|>


<commit_before>/**
   # QuickCheck

   QuickCheck is a form of *automated specification testing*. Instead
   of manually writing tests cases like so:

       assert(0 + 1 == 1);
       assert(1 + 1 == 2);
       assert(3 + 3 == 6);

   We can just write the assertion algebraicly and tell QuickCheck to
   automaticaly generate lots of inputs:

       bilby.forAll(
           function(n) {
               return n + n == 2 * n;
           },
           [Number]
       ).fold(
           function(fail) {
               return "Failed after " + fail.tries + " tries: " + fail.inputs.toString();
           },
           "All tests passed!"
       )
**/

function generateInputs(env, args, size) {
    return env.map(args, function(arg) {
        return env.arb(arg, size);
    });
}

/**
   ### failureReporter

   * inputs - the arguments to the property that failed
   * tries - number of times inputs were tested before failure
**/
function failureReporter(inputs, tries) {
    var self = getInstance(this, failureReporter);
    self.inputs = inputs;
    self.tries = tries;
    return self;
}

function findSmallest(env, property, inputs) {
    var shrunken = env.map(inputs, env.shrink),
        smallest = [].concat(inputs),
        args,
        i,
        j;

    for(i = 0; i < shrunken.length; i++) {
        args = [].concat(smallest);
        for(j = 0; j < shrunken[i].length; j++) {
            args[i] = shrunken[i][j];
            if(property.apply(this, args))
                break;
            smallest[i] = shrunken[i][j];
        }
    }

    return smallest;
}

/**
   ## forAll(property, args)

   Generates values for each type in `args` using `bilby.arb` and
   then passes them to `property`, a function returning a
   `Boolean`. Tries `goal` number of times or until failure.

   Returns an `Option` of a `failureReporter`:

       var reporter = bilby.forAll(
           function(s) {
               return isPalindrome(s + s.split('').reverse().join(''));
           },
           [String]
       );
**/
function forAll(property, args) {
    var inputs,
        i;

    for(i = 0; i < this.goal; i++) {
        inputs = generateInputs(this, args, i);
        if(!property.apply(this, inputs))
            return Option.some(failureReporter(
                findSmallest(this, property, inputs),
                i
            ));
    }

    return Option.none;
}

/**
   ## goal

   The number of successful inputs necessary to declare the whole
   property a success:

       var _ = bilby.property('goal', 1000);

   Default is `100`.
**/
var goal = 100;

bilby = bilby
    .property('failureReporter', failureReporter)
    .property('forAll', forAll)
    .property('goal', goal);
<commit_msg>It reports that it fails after 0 tries, even through it tried the test, either change the language of tries or up the counter to say that it had tried.<commit_after>/**
   # QuickCheck

   QuickCheck is a form of *automated specification testing*. Instead
   of manually writing tests cases like so:

       assert(0 + 1 == 1);
       assert(1 + 1 == 2);
       assert(3 + 3 == 6);

   We can just write the assertion algebraicly and tell QuickCheck to
   automaticaly generate lots of inputs:

       bilby.forAll(
           function(n) {
               return n + n == 2 * n;
           },
           [Number]
       ).fold(
           function(fail) {
               return "Failed after " + fail.tries + " tries: " + fail.inputs.toString();
           },
           "All tests passed!"
       )
**/

function generateInputs(env, args, size) {
    return env.map(args, function(arg) {
        return env.arb(arg, size);
    });
}

/**
   ### failureReporter

   * inputs - the arguments to the property that failed
   * tries - number of times inputs were tested before failure
**/
function failureReporter(inputs, tries) {
    var self = getInstance(this, failureReporter);
    self.inputs = inputs;
    self.tries = tries;
    return self;
}

function findSmallest(env, property, inputs) {
    var shrunken = env.map(inputs, env.shrink),
        smallest = [].concat(inputs),
        args,
        i,
        j;

    for(i = 0; i < shrunken.length; i++) {
        args = [].concat(smallest);
        for(j = 0; j < shrunken[i].length; j++) {
            args[i] = shrunken[i][j];
            if(property.apply(this, args))
                break;
            smallest[i] = shrunken[i][j];
        }
    }

    return smallest;
}

/**
   ## forAll(property, args)

   Generates values for each type in `args` using `bilby.arb` and
   then passes them to `property`, a function returning a
   `Boolean`. Tries `goal` number of times or until failure.

   Returns an `Option` of a `failureReporter`:

       var reporter = bilby.forAll(
           function(s) {
               return isPalindrome(s + s.split('').reverse().join(''));
           },
           [String]
       );
**/
function forAll(property, args) {
    var inputs,
        i;

    for(i = 0; i < this.goal; i++) {
        inputs = generateInputs(this, args, i);
        if(!property.apply(this, inputs))
            return Option.some(failureReporter(
                findSmallest(this, property, inputs),
                i + 1
            ));
    }

    return Option.none;
}

/**
   ## goal

   The number of successful inputs necessary to declare the whole
   property a success:

       var _ = bilby.property('goal', 1000);

   Default is `100`.
**/
var goal = 100;

bilby = bilby
    .property('failureReporter', failureReporter)
    .property('forAll', forAll)
    .property('goal', goal);
<|endoftext|>


<commit_before>/**
 * virtual list default component
 */

import Vue from 'vue'
import Virtual from './virtual'
import { Item, Slot } from './item'
import { VirtualProps } from './props'

const EVENT_TYPE = {
  ITEM: 'item_resize',
  SLOT: 'slot_resize'
}
const SLOT_TYPE = {
  HEADER: 'header', // string value also use for aria role attribute
  FOOTER: 'footer'
}

const NAME = 'virtual-list'

const VirtualList = Vue.component(NAME, {
  props: VirtualProps,

  data () {
    return {
      range: null
    }
  },

  watch: {
    dataSources (newValue, oldValue) {
      if (newValue.length !== oldValue.length) {
        this.virtual.updateParam('uniqueIds', this.getUniqueIdFromDataSources())
        this.virtual.handleDataSourcesChange()
      }
    }
  },

  created () {
    this.isHorizontal = this.direction === 'horizontal'
    this.directionKey = this.isHorizontal ? 'scrollLeft' : 'scrollTop'

    this.virtual = new Virtual({
      size: this.size, // also could be a estimate value
      slotHeaderSize: 0,
      slotFooterSize: 0,
      keeps: this.keeps,
      buffer: Math.round(this.keeps / 3), // recommend for a third of keeps
      uniqueIds: this.getUniqueIdFromDataSources()
    }, this.onRangeChanged)

    // also need sync initial range first
    this.range = this.virtual.getRange()

    // listen item size changing
    this.$on(EVENT_TYPE.ITEM, this.onItemResized)

    // listen slot size changing
    if (this.$slots.header || this.$slots.footer) {
      this.$on(EVENT_TYPE.SLOT, this.onSlotResized)
    }
  },

  beforeDestroy () {
    this.virtual.destroy()
  },

  mounted () {
    // set position
    if (this.start) {
      this.scrollToIndex(this.start)
    } else if (this.offset) {
      this.scrollToOffset(this.offset)
    }

    window.virtual = this.virtual
  },

  methods: {
    // set current scroll position to a expectant offset
    scrollToOffset (offset) {
      const { root } = this.$refs
      if (root) {
        root[this.directionKey] = offset || 0
      }
    },

    // set current scroll position to a expectant index
    scrollToIndex (index) {
      const offset = this.virtual.getOffset(index)
      this.scrollToOffset(offset)
    },

    // ----------- public method end -----------

    getUniqueIdFromDataSources () {
      return this.dataSources.map((dataSource) => dataSource[this.dataKey])
    },

    // event called when each item mounted or size changed
    onItemResized (id, size) {
      this.virtual.saveSize(id, size)
    },

    // event called when slot mounted or size changed
    onSlotResized (type, size, hasInit) {
      if (type === SLOT_TYPE.HEADER) {
        this.virtual.updateParam('slotHeaderSize', size)
      } else if (type === SLOT_TYPE.FOOTER) {
        this.virtual.updateParam('slotFooterSize', size)
      }

      if (hasInit) {
        this.virtual.handleSlotSizeChange()
      }
    },

    // here is the rerendering entry
    onRangeChanged (range) {
      this.range = range
    },

    onScroll (evt) {
      const { root } = this.$refs
      if (!root) {
        return
      }

      const offset = root[this.directionKey]
      const offsetShape = root[this.isHorizontal ? 'clientWidth' : 'clientHeight']
      const scrollShape = root[this.isHorizontal ? 'scrollWidth' : 'scrollHeight']

      // iOS scroll-spring-back behavior will make direction mistake
      if (offset + offsetShape > scrollShape) {
        return
      }

      this.virtual.handleScroll(offset)
      this.emitEvent(offset, offsetShape, scrollShape, evt)
    },

    // emit event in special position
    emitEvent (offset, offsetShape, scrollShape, evt) {
      const range = this.virtual.getRange()
      if (this.virtual.isFront() && !!this.dataSources.length && offset - this.topThreshold <= 0) {
        this.$emit('totop', evt, range)
      } else if (this.virtual.isBehind() && offset + offsetShape + this.bottomThreshold >= scrollShape) {
        this.$emit('tobottom', evt, range)
      } else {
        this.$emit('scroll', evt, range)
      }
    },

    // get the real render slots based on range data
    getRenderSlots (h) {
      const slots = []
      const start = this.disabled ? 0 : this.range.start
      const end = this.disabled ? this.dataSources.length - 1 : this.range.end
      for (let index = start; index <= end; index++) {
        const dataSource = this.dataSources[index]
        if (dataSource) {
          slots.push(h(Item, {
            class: this.itemClass,
            props: {
              tag: this.itemTag,
              event: EVENT_TYPE.ITEM,
              horizontal: this.isHorizontal,
              uniqueKey: dataSource[this.dataKey],
              source: dataSource,
              extraProps: this.extraProps,
              component: this.dataComponent
            }
          }))
        } else {
          console.warn(`[${NAME}]: cannot get the index ${index} from data-sources.`)
        }
      }
      return slots
    }
  },

  // render function, a closer-to-the-compiler alternative to templates
  // https://vuejs.org/v2/guide/render-function.html#The-Data-Object-In-Depth
  render (h) {
    const { header, footer } = this.$slots
    const padding = this.disabled ? 0 : this.isHorizontal
      ? `0px ${this.range.padBehind}px 0px ${this.range.padFront}px`
      : `${this.range.padFront}px 0px ${this.range.padBehind}px`

    return h(this.rootTag, {
      ref: 'root',
      on: {
        '&scroll': this.onScroll
      }
    }, [
      // header slot
      header ? h(Slot, {
        class: this.headerClass,
        props: {
          tag: this.headerTag,
          event: EVENT_TYPE.SLOT,
          uniqueKey: SLOT_TYPE.HEADER
        }
      }, header) : null,

      // main list
      h(this.wrapTag, {
        class: this.wrapClass,
        attrs: {
          role: 'group'
        },
        style: {
          padding: padding
        }
      }, this.getRenderSlots(h)),

      // footer slot
      footer ? h(Slot, {
        class: this.footerClass,
        props: {
          tag: this.footerTag,
          event: EVENT_TYPE.SLOT,
          uniqueKey: SLOT_TYPE.FOOTER
        }
      }, footer) : null
    ])
  }
})

export default VirtualList
<commit_msg>Add scroll to top / bottom<commit_after>/**
 * virtual list default component
 */

import Vue from 'vue'
import Virtual from './virtual'
import { Item, Slot } from './item'
import { VirtualProps } from './props'

const EVENT_TYPE = {
  ITEM: 'item_resize',
  SLOT: 'slot_resize'
}
const SLOT_TYPE = {
  HEADER: 'header', // string value also use for aria role attribute
  FOOTER: 'footer'
}

const NAME = 'virtual-list'

const VirtualList = Vue.component(NAME, {
  props: VirtualProps,

  data () {
    return {
      range: null
    }
  },

  watch: {
    dataSources (newValue, oldValue) {
      if (newValue.length !== oldValue.length) {
        this.virtual.updateParam('uniqueIds', this.getUniqueIdFromDataSources())
        this.virtual.handleDataSourcesChange()
      }
    }
  },

  created () {
    this.isHorizontal = this.direction === 'horizontal'
    this.directionKey = this.isHorizontal ? 'scrollLeft' : 'scrollTop'

    this.virtual = new Virtual({
      size: this.size, // also could be a estimate value
      slotHeaderSize: 0,
      slotFooterSize: 0,
      keeps: this.keeps,
      buffer: Math.round(this.keeps / 3), // recommend for a third of keeps
      uniqueIds: this.getUniqueIdFromDataSources()
    }, this.onRangeChanged)

    // sync initial range
    this.range = this.virtual.getRange()

    // listen item size changing
    this.$on(EVENT_TYPE.ITEM, this.onItemResized)

    // listen slot size changing
    if (this.$slots.header || this.$slots.footer) {
      this.$on(EVENT_TYPE.SLOT, this.onSlotResized)
    }
  },

  beforeDestroy () {
    this.virtual.destroy()
  },

  mounted () {
    // set position
    if (this.start) {
      this.scrollToIndex(this.start)
    } else if (this.offset) {
      this.scrollToOffset(this.offset)
    }

    window.virtual = this.virtual
  },

  methods: {
    // set current scroll position to a expectant offset
    scrollToOffset (offset) {
      const { root } = this.$refs
      if (root) {
        root[this.directionKey] = offset || 0
      }
    },

    // set current scroll position to a expectant index
    scrollToIndex (index) {
      // scroll to top
      if (index === 0) {
        this.scrollToOffset(0)
      } else if (index >= this.dataSources.length - 1) {
        // scroll to bottom
        this.scrollToOffset(this.getScrollSize())
      } else {
        const offset = this.virtual.getOffset(index)
        this.scrollToOffset(offset)
      }
    },

    // ----------- public method end -----------

    getUniqueIdFromDataSources () {
      return this.dataSources.map((dataSource) => dataSource[this.dataKey])
    },

    // get client viewport size (width or height)
    getClientSize () {
      const { root } = this.$refs
      if (root) {
        return root[this.isHorizontal ? 'clientWidth' : 'clientHeight']
      } else {
        return 0
      }
    },

    // get all scroll size (width or height)
    getScrollSize () {
      const { root } = this.$refs
      if (root) {
        return root[this.isHorizontal ? 'scrollWidth' : 'scrollHeight']
      } else {
        return 0
      }
    },

    // event called when each item mounted or size changed
    onItemResized (id, size) {
      this.virtual.saveSize(id, size)
    },

    // event called when slot mounted or size changed
    onSlotResized (type, size, hasInit) {
      if (type === SLOT_TYPE.HEADER) {
        this.virtual.updateParam('slotHeaderSize', size)
      } else if (type === SLOT_TYPE.FOOTER) {
        this.virtual.updateParam('slotFooterSize', size)
      }

      if (hasInit) {
        this.virtual.handleSlotSizeChange()
      }
    },

    // here is the rerendering entry
    onRangeChanged (range) {
      this.range = range
    },

    onScroll (evt) {
      const { root } = this.$refs
      if (!root) {
        return
      }

      const offset = root[this.directionKey]
      const clientSize = this.getClientSize()
      const scrollSize = this.getScrollSize()

      // iOS scroll-spring-back behavior will make direction mistake
      if (offset + clientSize > scrollSize) {
        return
      }

      this.virtual.handleScroll(offset)
      this.emitEvent(offset, clientSize, scrollSize, evt)
    },

    // emit event in special position
    emitEvent (offset, clientSize, scrollSize, evt) {
      const range = this.virtual.getRange()
      if (this.virtual.isFront() && !!this.dataSources.length && offset - this.topThreshold <= 0) {
        this.$emit('totop', evt, range)
      } else if (this.virtual.isBehind() && offset + clientSize + this.bottomThreshold >= scrollSize) {
        this.$emit('tobottom', evt, range)
      } else {
        this.$emit('scroll', evt, range)
      }
    },

    // get the real render slots based on range data
    getRenderSlots (h) {
      const slots = []
      const start = this.disabled ? 0 : this.range.start
      const end = this.disabled ? this.dataSources.length - 1 : this.range.end
      for (let index = start; index <= end; index++) {
        const dataSource = this.dataSources[index]
        if (dataSource) {
          slots.push(h(Item, {
            class: this.itemClass,
            props: {
              tag: this.itemTag,
              event: EVENT_TYPE.ITEM,
              horizontal: this.isHorizontal,
              uniqueKey: dataSource[this.dataKey],
              source: dataSource,
              extraProps: this.extraProps,
              component: this.dataComponent
            }
          }))
        } else {
          console.warn(`[${NAME}]: cannot get the index ${index} from data-sources.`)
        }
      }
      return slots
    }
  },

  // render function, a closer-to-the-compiler alternative to templates
  // https://vuejs.org/v2/guide/render-function.html#The-Data-Object-In-Depth
  render (h) {
    const { header, footer } = this.$slots
    const padding = this.disabled ? 0 : this.isHorizontal
      ? `0px ${this.range.padBehind}px 0px ${this.range.padFront}px`
      : `${this.range.padFront}px 0px ${this.range.padBehind}px`

    return h(this.rootTag, {
      ref: 'root',
      on: {
        '&scroll': this.onScroll
      }
    }, [
      // header slot
      header ? h(Slot, {
        class: this.headerClass,
        props: {
          tag: this.headerTag,
          event: EVENT_TYPE.SLOT,
          uniqueKey: SLOT_TYPE.HEADER
        }
      }, header) : null,

      // main list
      h(this.wrapTag, {
        class: this.wrapClass,
        attrs: {
          role: 'group'
        },
        style: {
          padding: padding
        }
      }, this.getRenderSlots(h)),

      // footer slot
      footer ? h(Slot, {
        class: this.footerClass,
        props: {
          tag: this.footerTag,
          event: EVENT_TYPE.SLOT,
          uniqueKey: SLOT_TYPE.FOOTER
        }
      }, footer) : null
    ])
  }
})

export default VirtualList
<|endoftext|>


<commit_before>(function() {
    CQ.wcm.EditBase.EDITSHARED = "EDITSHARED";
    CQ.wcm.EditBase.EDITGLOBAL = "EDITGLOBAL";

    var addSharedConfigActions = function(xtype) {
        var origType = CQ.Ext.ComponentMgr.types[xtype];
        var newType = CQ.Ext.extend(origType, {
            applyConfigDefaults: function(config, defaults) {
                if (config.actions) {
                    var pageInfo = CQ.utils.WCM.getPageInfo(config.path);
                    var enabled = pageInfo.sharedComponentProperties && pageInfo.sharedComponentProperties.enabled;
                    var canModify = pageInfo.permissions && pageInfo.permissions.modify;

                    if (!!enabled && !!canModify) {
                        if (config.actions.indexOf(CQ.wcm.EditBase.EDITSHARED) < 0) {
                            var actionsCount = config.actions.length;
                            var editActionIdx = null;
                            for (var i = 0; i < actionsCount; i++) {
                                if (config.actions[i] == CQ.wcm.EditBase.EDIT) {
                                    editActionIdx = i;
                                    break;
                                }
                            }
                            if (editActionIdx != null) {
                                config.actions.splice(editActionIdx + 1, 0, CQ.wcm.EditBase.EDITGLOBAL);
                                config.actions.splice(editActionIdx + 1, 0, CQ.wcm.EditBase.EDITSHARED);
                            }
                        }
                    }
                }
                CQ.wcm.EditBase.applyConfigDefaults.call(this, config, defaults);
            }
        });
        CQ.Ext.reg(xtype, newType);
    };

    // Define the handlers for CQ.wcm.EditBase.EDITGLOBAL and CQ.wcm.EditBase.EDITSHARED
    var editSharedHandler = function(type, editBaseType) {
        var origDialog = this.dialog;
        var origDialogCached = this.dialogs[CQ.wcm.EditBase.EDIT];
        var origPath = this.path;

        var pageInfo = CQ.utils.WCM.getPageInfo(this.path);
        var newPath = pageInfo.sharedComponentProperties.root + "/jcr:content/" + type + "-component-properties";
        if (type == "shared") {
            newPath += "/" + this.getResourceType();
        }

        try {
            this.dialog = this.dialog + type;
            this.dialogs[CQ.wcm.EditBase.EDIT] = this.dialogs[editBaseType];
            this.path = newPath;

            // For global props, need to unregister any previous fetch since it
            // always has the same data path.
            if (type == "global") {
                CQ.WCM.unregisterDialog("editdialog-" + this.path);
            }

            CQ.wcm.EditBase.showDialog(this, editBaseType);
        } catch (e) {
            if (window.console && console.error) {
                console.error(e);
            }
        } finally {
            this.dialog = origDialog;

            // Don't allow the global props dialog to be cached, as it causes
            // problems due to always having the same data path.
            if (type != "global") {
                this.dialogs[editBaseType] = this.dialogs[CQ.wcm.EditBase.EDIT];
            }

            this.dialogs[CQ.wcm.EditBase.EDIT] = origDialogCached;
            this.path = origPath;
        }
    };

    function addSharedConfigActionHandlers(clazz) {
        clazz.ActionsConvertor[CQ.wcm.EditBase.EDITSHARED] = {
            text: CQ.I18n.getMessage("Edit Shared"),
            handler: function (evt) {
                // Using 'evt.ownerCt.defaults.scope' instead of 'this' because
                // 'this' has a permanent reference to the first component for
                // which the menu is launched.
                editSharedHandler.call(evt.ownerCt.defaults.scope, "shared", CQ.wcm.EditBase.EDITSHARED);
            }
        };

        clazz.ActionsConvertor[CQ.wcm.EditBase.EDITGLOBAL] = {
            text: CQ.I18n.getMessage("Edit Global"),
            handler: function (evt) {
                // Using 'evt.ownerCt.defaults.scope' instead of 'this' because
                // 'this' has a permanent reference to the first component for
                // which the menu is launched.
                editSharedHandler.call(evt.ownerCt.defaults.scope, "global", CQ.wcm.EditBase.EDITGLOBAL);
            }
        };
    }

    addSharedConfigActions("editrollover");
    addSharedConfigActionHandlers(CQ.wcm.EditRollover);

})();<commit_msg>Fixed a jshint error.<commit_after>(function() {
    CQ.wcm.EditBase.EDITSHARED = "EDITSHARED";
    CQ.wcm.EditBase.EDITGLOBAL = "EDITGLOBAL";

    var addSharedConfigActions = function(xtype) {
        var origType = CQ.Ext.ComponentMgr.types[xtype];
        var newType = CQ.Ext.extend(origType, {
            applyConfigDefaults: function(config, defaults) {
                if (config.actions) {
                    var pageInfo = CQ.utils.WCM.getPageInfo(config.path);
                    var enabled = pageInfo.sharedComponentProperties && pageInfo.sharedComponentProperties.enabled;
                    var canModify = pageInfo.permissions && pageInfo.permissions.modify;

                    if (!!enabled && !!canModify) {
                        if (config.actions.indexOf(CQ.wcm.EditBase.EDITSHARED) < 0) {
                            var actionsCount = config.actions.length;
                            var editActionIdx = null;
                            for (var i = 0; i < actionsCount; i++) {
                                if (config.actions[i] == CQ.wcm.EditBase.EDIT) {
                                    editActionIdx = i;
                                    break;
                                }
                            }
                            if (editActionIdx !== null) {
                                config.actions.splice(editActionIdx + 1, 0, CQ.wcm.EditBase.EDITGLOBAL);
                                config.actions.splice(editActionIdx + 1, 0, CQ.wcm.EditBase.EDITSHARED);
                            }
                        }
                    }
                }
                CQ.wcm.EditBase.applyConfigDefaults.call(this, config, defaults);
            }
        });
        CQ.Ext.reg(xtype, newType);
    };

    // Define the handlers for CQ.wcm.EditBase.EDITGLOBAL and CQ.wcm.EditBase.EDITSHARED
    var editSharedHandler = function(type, editBaseType) {
        var origDialog = this.dialog;
        var origDialogCached = this.dialogs[CQ.wcm.EditBase.EDIT];
        var origPath = this.path;

        var pageInfo = CQ.utils.WCM.getPageInfo(this.path);
        var newPath = pageInfo.sharedComponentProperties.root + "/jcr:content/" + type + "-component-properties";
        if (type == "shared") {
            newPath += "/" + this.getResourceType();
        }

        try {
            this.dialog = this.dialog + type;
            this.dialogs[CQ.wcm.EditBase.EDIT] = this.dialogs[editBaseType];
            this.path = newPath;

            // For global props, need to unregister any previous fetch since it
            // always has the same data path.
            if (type == "global") {
                CQ.WCM.unregisterDialog("editdialog-" + this.path);
            }

            CQ.wcm.EditBase.showDialog(this, editBaseType);
        } catch (e) {
            if (window.console && console.error) {
                console.error(e);
            }
        } finally {
            this.dialog = origDialog;

            // Don't allow the global props dialog to be cached, as it causes
            // problems due to always having the same data path.
            if (type != "global") {
                this.dialogs[editBaseType] = this.dialogs[CQ.wcm.EditBase.EDIT];
            }

            this.dialogs[CQ.wcm.EditBase.EDIT] = origDialogCached;
            this.path = origPath;
        }
    };

    function addSharedConfigActionHandlers(clazz) {
        clazz.ActionsConvertor[CQ.wcm.EditBase.EDITSHARED] = {
            text: CQ.I18n.getMessage("Edit Shared"),
            handler: function (evt) {
                // Using 'evt.ownerCt.defaults.scope' instead of 'this' because
                // 'this' has a permanent reference to the first component for
                // which the menu is launched.
                editSharedHandler.call(evt.ownerCt.defaults.scope, "shared", CQ.wcm.EditBase.EDITSHARED);
            }
        };

        clazz.ActionsConvertor[CQ.wcm.EditBase.EDITGLOBAL] = {
            text: CQ.I18n.getMessage("Edit Global"),
            handler: function (evt) {
                // Using 'evt.ownerCt.defaults.scope' instead of 'this' because
                // 'this' has a permanent reference to the first component for
                // which the menu is launched.
                editSharedHandler.call(evt.ownerCt.defaults.scope, "global", CQ.wcm.EditBase.EDITGLOBAL);
            }
        };
    }

    addSharedConfigActions("editrollover");
    addSharedConfigActionHandlers(CQ.wcm.EditRollover);

})();<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 */

import { Uint16BufferAttribute, Uint32BufferAttribute } from '../../core/BufferAttribute.js';
import { BufferGeometry } from '../../core/BufferGeometry.js';
import { arrayMax } from '../../utils.js';

function WebGLGeometries( gl, attributes, info ) {

	var geometries = {};
	var wireframeAttributes = {};

	function onGeometryDispose( event ) {

		var geometry = event.target;
		var buffergeometry = geometries[ geometry.id ];

		if ( buffergeometry.index !== null ) {

			attributes.remove( buffergeometry.index );

		}

		for ( var name in buffergeometry.attributes ) {

			attributes.remove( buffergeometry.attributes[ name ] );

		}

		geometry.removeEventListener( 'dispose', onGeometryDispose );

		delete geometries[ geometry.id ];

		var attribute = wireframeAttributes[ buffergeometry.id ];

		if ( attribute ) {

			attributes.remove( attribute );
			delete wireframeAttributes[ buffergeometry.id ];

		}

		//

		info.memory.geometries --;

	}

	function get( object, geometry ) {

		var buffergeometry = geometries[ geometry.id ];

		if ( buffergeometry ) return buffergeometry;

		geometry.addEventListener( 'dispose', onGeometryDispose );

		if ( geometry.isBufferGeometry ) {

			buffergeometry = geometry;

		} else if ( geometry.isGeometry ) {

			if ( geometry._bufferGeometry === undefined ) {

				geometry._bufferGeometry = new BufferGeometry().setFromObject( object );

			}

			buffergeometry = geometry._bufferGeometry;

		}

		geometries[ geometry.id ] = buffergeometry;

		info.memory.geometries ++;

		return buffergeometry;

	}

	function update( geometry ) {

		var index = geometry.index;
		var geometryAttributes = geometry.attributes;

		if ( index !== null ) {

			attributes.update( index, gl.ELEMENT_ARRAY_BUFFER );

		}

		for ( var name in geometryAttributes ) {

			attributes.update( geometryAttributes[ name ], gl.ARRAY_BUFFER );

		}

		// morph targets

		var morphAttributes = geometry.morphAttributes;

		for ( var name in morphAttributes ) {

			var array = morphAttributes[ name ];

			for ( var i = 0, l = array.length; i < l; i ++ ) {

				attributes.update( array[ i ], gl.ARRAY_BUFFER );

			}

		}

	}

	function getWireframeAttribute( geometry ) {

		var attribute = wireframeAttributes[ geometry.id ];

		if ( attribute ) return attribute;

		var indices = [];

		var geometryIndex = geometry.index;
		var geometryAttributes = geometry.attributes;

		// console.time( 'wireframe' );

		if ( geometryIndex !== null ) {

			var array = geometryIndex.array;

			for ( var i = 0, l = array.length; i < l; i += 3 ) {

				var a = array[ i + 0 ];
				var b = array[ i + 1 ];
				var c = array[ i + 2 ];

				indices.push( a, b, b, c, c, a );

			}

		} else {

			var array = geometryAttributes.position.array;

			for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {

				var a = i + 0;
				var b = i + 1;
				var c = i + 2;

				indices.push( a, b, b, c, c, a );

			}

		}

		// console.timeEnd( 'wireframe' );

		attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );

		attributes.update( attribute, gl.ELEMENT_ARRAY_BUFFER );

		wireframeAttributes[ geometry.id ] = attribute;

		return attribute;

	}

	return {

		get: get,
		update: update,

		getWireframeAttribute: getWireframeAttribute

	};

}

export { WebGLGeometries };
<commit_msg>WebGLGeometries: Ensure wireframes reflect the current geometry data<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 */

import { Uint16BufferAttribute, Uint32BufferAttribute } from '../../core/BufferAttribute.js';
import { BufferGeometry } from '../../core/BufferGeometry.js';
import { arrayMax } from '../../utils.js';

function WebGLGeometries( gl, attributes, info ) {

	var geometries = {};
	var wireframeAttributes = {};

	function onGeometryDispose( event ) {

		var geometry = event.target;
		var buffergeometry = geometries[ geometry.id ];

		if ( buffergeometry.index !== null ) {

			attributes.remove( buffergeometry.index );

		}

		for ( var name in buffergeometry.attributes ) {

			attributes.remove( buffergeometry.attributes[ name ] );

		}

		geometry.removeEventListener( 'dispose', onGeometryDispose );

		delete geometries[ geometry.id ];

		var attribute = wireframeAttributes[ buffergeometry.id ];

		if ( attribute ) {

			attributes.remove( attribute );
			delete wireframeAttributes[ buffergeometry.id ];

		}

		//

		info.memory.geometries --;

	}

	function get( object, geometry ) {

		var buffergeometry = geometries[ geometry.id ];

		if ( buffergeometry ) return buffergeometry;

		geometry.addEventListener( 'dispose', onGeometryDispose );

		if ( geometry.isBufferGeometry ) {

			buffergeometry = geometry;

		} else if ( geometry.isGeometry ) {

			if ( geometry._bufferGeometry === undefined ) {

				geometry._bufferGeometry = new BufferGeometry().setFromObject( object );

			}

			buffergeometry = geometry._bufferGeometry;

		}

		geometries[ geometry.id ] = buffergeometry;

		info.memory.geometries ++;

		return buffergeometry;

	}

	function update( geometry ) {

		var index = geometry.index;
		var geometryAttributes = geometry.attributes;

		if ( index !== null ) {

			attributes.update( index, gl.ELEMENT_ARRAY_BUFFER );

		}

		for ( var name in geometryAttributes ) {

			attributes.update( geometryAttributes[ name ], gl.ARRAY_BUFFER );

		}

		// morph targets

		var morphAttributes = geometry.morphAttributes;

		for ( var name in morphAttributes ) {

			var array = morphAttributes[ name ];

			for ( var i = 0, l = array.length; i < l; i ++ ) {

				attributes.update( array[ i ], gl.ARRAY_BUFFER );

			}

		}

	}

	function updateWireframeAttribute( geometry ) {

		var indices = [];

		var geometryIndex = geometry.index;
		var geometryPosition = geometry.attributes.position;
		var version = 0;

		if ( geometryIndex !== null ) {

			var array = geometryIndex.array;
			version = geometryIndex.version;

			for ( var i = 0, l = array.length; i < l; i += 3 ) {

				var a = array[ i + 0 ];
				var b = array[ i + 1 ];
				var c = array[ i + 2 ];

				indices.push( a, b, b, c, c, a );

			}

		} else {

			var array = geometryPosition.array;
			version = geometryPosition.version;

			for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {

				var a = i + 0;
				var b = i + 1;
				var c = i + 2;

				indices.push( a, b, b, c, c, a );

			}

		}

		var attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
		attribute.version = version;

		attributes.update( attribute, gl.ELEMENT_ARRAY_BUFFER );

		wireframeAttributes[ geometry.id ] = attribute;

	}

	function getWireframeAttribute( geometry ) {

		var geometryIndex = geometry.index;
		var geometryPosition = geometry.attributes.position;

		var currentAttribute = wireframeAttributes[ geometry.id ];

		if ( currentAttribute ) {

			if ( geometryIndex !== null ) {

				// if the attribute is obsolete, create a new one

				if ( currentAttribute.version < geometryIndex.version ) {

					updateWireframeAttribute( geometry );

				}

			} else {

				// if the attribute is obsolete, create a new one

				if ( currentAttribute.version < geometryPosition.version ) {

					updateWireframeAttribute( geometry );

				}

			}

		} else {

			updateWireframeAttribute( geometry );

		}

		return wireframeAttributes[ geometry.id ];

	}

	return {

		get: get,
		update: update,

		getWireframeAttribute: getWireframeAttribute

	};

}

export { WebGLGeometries };
<|endoftext|>


<commit_before>'use strict';

const { readFile } = require('fs').promises;
const path = require('path');

const postcss = require('postcss');
const timsort = require('timsort').sort;

const builtInOrders = [
  'alphabetical',
  'concentric-css',
  'smacss',
];

module.exports = postcss.plugin(
  'css-declaration-sorter',
  ({ order = 'alphabetical', keepOverrides = false } = {}) => css => {
    let withKeepOverrides = comparator => comparator;
    if (keepOverrides) {
      const shorthandData = require('./shorthand-data.js');
      withKeepOverrides = withOverridesComparator(shorthandData);
    }

    if (typeof order === 'function') {
      return processCss({ css, comparator: withKeepOverrides(order) });
    }

    if (!builtInOrders.includes(order))
      return Promise.reject(
        Error([
          `Invalid built-in order '${order}' provided.`,
          `Available built-in orders are: ${builtInOrders}`,
        ].join('\n'))
      );

    // Load in the array containing the order from a JSON file
    return readFile(path.join(__dirname, '..', 'orders', order) + '.json')
      .then(data => processCss({
        css,
        comparator: withKeepOverrides(orderComparator(JSON.parse(data))),
      }));
  }
);

function processCss ({ css, comparator }) {
  const comments = [];
  const rulesCache = [];

  css.walk(node => {
    const nodes = node.nodes;
    const type = node.type;

    if (type === 'comment') {
      // Don't do anything to root comments or the last newline comment
      const isNewlineNode = node.raws.before && ~node.raws.before.indexOf('\n');
      const lastNewlineNode = isNewlineNode && !node.next();
      const onlyNode = !node.prev() && !node.next();

      if (lastNewlineNode || onlyNode || node.parent.type === 'root') {
        return;
      }

      if (isNewlineNode) {
        const pairedNode = node.next() ? node.next() : node.prev().prev();
        if (pairedNode) {
          comments.unshift({
            'comment': node,
            'pairedNode': pairedNode,
            'insertPosition': node.next() ? 'Before' : 'After',
          });
          node.remove();
        }
      } else {
        const pairedNode = node.prev() ? node.prev() : node.next().next();
        if (pairedNode) {
          comments.push({
            'comment': node,
            'pairedNode': pairedNode,
            'insertPosition': 'After',
          });
          node.remove();
        }
      }
      return;
    }

    // Add rule-like nodes to a cache so that we can remove all
    // comment nodes before we start sorting.
    const isRule = type === 'rule' || type === 'atrule';
    if (isRule && nodes && nodes.length > 1) {
      rulesCache.push(nodes);
    }
  });

  // Perform a sort once all comment nodes are removed
  rulesCache.forEach(nodes => {
    sortCssDeclarations({ nodes, comparator });
  });

  // Add comments back to the nodes they are paired with
  comments.forEach(node => {
    const pairedNode = node.pairedNode;
    node.comment.remove();
    pairedNode.parent['insert' + node.insertPosition](pairedNode, node.comment);
  });
}

function sortCssDeclarations ({ nodes, comparator }) {
  timsort(nodes, (a, b) => {
    if (a.type === 'decl' && b.type === 'decl') {
      return comparator(a.prop, b.prop);
    } else {
      return compareDifferentType(a, b);
    }
  });
}

function withOverridesComparator (shorthandData) {
  return function (comparator) {
    return function (a, b) {
      a = postcss.vendor.unprefixed(a);
      b = postcss.vendor.unprefixed(b);

      if (shorthandData[a] && shorthandData[a].includes(b)) return 0;
      if (shorthandData[b] && shorthandData[b].includes(a)) return 0;

      return comparator(a, b);
    };
  };
}

function orderComparator (order) {
  return function (a, b) {
    const aIndex = order.indexOf(a);
    const bIndex = order.indexOf(b);

    return defaultComparator(aIndex, bIndex);
  };
}

function defaultComparator (a, b) {
  return a === b ? 0 : a < b ? -1 : 1;
}

function compareDifferentType (a, b) {
  if (b.type === 'atrule') {
    return 0;
  }

  return a.type === 'decl' ? -1 : b.type === 'decl' ? 1 : 0;
}
<commit_msg>Simplify default comparator function<commit_after>'use strict';

const { readFile } = require('fs').promises;
const path = require('path');

const postcss = require('postcss');
const timsort = require('timsort').sort;

const builtInOrders = [
  'alphabetical',
  'concentric-css',
  'smacss',
];

module.exports = postcss.plugin(
  'css-declaration-sorter',
  ({ order = 'alphabetical', keepOverrides = false } = {}) => css => {
    let withKeepOverrides = comparator => comparator;
    if (keepOverrides) {
      const shorthandData = require('./shorthand-data.js');
      withKeepOverrides = withOverridesComparator(shorthandData);
    }

    if (typeof order === 'function') {
      return processCss({ css, comparator: withKeepOverrides(order) });
    }

    if (!builtInOrders.includes(order))
      return Promise.reject(
        Error([
          `Invalid built-in order '${order}' provided.`,
          `Available built-in orders are: ${builtInOrders}`,
        ].join('\n'))
      );

    // Load in the array containing the order from a JSON file
    return readFile(path.join(__dirname, '..', 'orders', order) + '.json')
      .then(data => processCss({
        css,
        comparator: withKeepOverrides(orderComparator(JSON.parse(data))),
      }));
  }
);

function processCss ({ css, comparator }) {
  const comments = [];
  const rulesCache = [];

  css.walk(node => {
    const nodes = node.nodes;
    const type = node.type;

    if (type === 'comment') {
      // Don't do anything to root comments or the last newline comment
      const isNewlineNode = node.raws.before && ~node.raws.before.indexOf('\n');
      const lastNewlineNode = isNewlineNode && !node.next();
      const onlyNode = !node.prev() && !node.next();

      if (lastNewlineNode || onlyNode || node.parent.type === 'root') {
        return;
      }

      if (isNewlineNode) {
        const pairedNode = node.next() ? node.next() : node.prev().prev();
        if (pairedNode) {
          comments.unshift({
            'comment': node,
            'pairedNode': pairedNode,
            'insertPosition': node.next() ? 'Before' : 'After',
          });
          node.remove();
        }
      } else {
        const pairedNode = node.prev() ? node.prev() : node.next().next();
        if (pairedNode) {
          comments.push({
            'comment': node,
            'pairedNode': pairedNode,
            'insertPosition': 'After',
          });
          node.remove();
        }
      }
      return;
    }

    // Add rule-like nodes to a cache so that we can remove all
    // comment nodes before we start sorting.
    const isRule = type === 'rule' || type === 'atrule';
    if (isRule && nodes && nodes.length > 1) {
      rulesCache.push(nodes);
    }
  });

  // Perform a sort once all comment nodes are removed
  rulesCache.forEach(nodes => {
    sortCssDeclarations({ nodes, comparator });
  });

  // Add comments back to the nodes they are paired with
  comments.forEach(node => {
    const pairedNode = node.pairedNode;
    node.comment.remove();
    pairedNode.parent['insert' + node.insertPosition](pairedNode, node.comment);
  });
}

function sortCssDeclarations ({ nodes, comparator }) {
  timsort(nodes, (a, b) => {
    if (a.type === 'decl' && b.type === 'decl') {
      return comparator(a.prop, b.prop);
    } else {
      return compareDifferentType(a, b);
    }
  });
}

function withOverridesComparator (shorthandData) {
  return function (comparator) {
    return function (a, b) {
      a = postcss.vendor.unprefixed(a);
      b = postcss.vendor.unprefixed(b);

      if (shorthandData[a] && shorthandData[a].includes(b)) return 0;
      if (shorthandData[b] && shorthandData[b].includes(a)) return 0;

      return comparator(a, b);
    };
  };
}

function orderComparator (order) {
  return function (a, b) {
    return order.indexOf(a) - order.indexOf(b);
  };
}

function compareDifferentType (a, b) {
  if (b.type === 'atrule') {
    return 0;
  }

  return a.type === 'decl' ? -1 : b.type === 'decl' ? 1 : 0;
}
<|endoftext|>


<commit_before>export function configure(aurelia) {
  aurelia.globalizeResources(
    './dialog',
    './dialog-header',
    './dialog-body',
    './dialog-footer',
    './attach-focus',
    './examples/prompt'
  );
}
export * from './dialog-service';
export * from './dialog-controller';
export * from './examples/prompt';
<commit_msg>fix(index): update to latest configuration api<commit_after>export function configure(config) {
  config.globalResources(
    './dialog',
    './dialog-header',
    './dialog-body',
    './dialog-footer',
    './attach-focus',
    './examples/prompt'
  );
}
export * from './dialog-service';
export * from './dialog-controller';
export * from './examples/prompt';
<|endoftext|>


<commit_before>import React, { useState } from 'react';
import PropTypes from 'prop-types';

// Components
import Icon from 'components/ui/icon';
import LoginRequired from 'components/ui/login-required';
import Modal from 'components/modal/modal-component';
import ShareModal from 'components/modal/share-modal';

// Tooltip
import { Tooltip } from 'vizzuality-components';
import CollectionsPanel from 'components/collections-panel';
import { getTooltipContainer } from 'utils/tooltip';

// utils
import { logEvent } from 'utils/analytics';

// Styles
import './styles.scss';

function ExploreDetailHeaderComponent(props) {
  const { dataset, setSelectedDataset } = props;
  const [showShareModal, setShowShareModal] = useState(false);

  return (

      <button
        className="c-btn -primary -compressed"
        onClick={() => setSelectedDataset(null)}
      >
        {'< ALL DATASETS'}
      </button>

        {/* Collections tooltip */}
        <LoginRequired>
          <Tooltip
            overlay={
              <CollectionsPanel
                resource={dataset}
                resourceType="dataset"
              />
            }
            overlayClassName="c-rc-tooltip"
            placement="bottomRight"
            trigger="click"
            getTooltipContainer={getTooltipContainer}
            monitorWindowResize
          >
            <button className="c-btn -secondary -compressed" >
              <Icon className="-small" name="icon-star-full" />
              SAVE
            </button>
          </Tooltip>
        </LoginRequired>

        <button
          className="c-btn -secondary -compressed"
          onClick={() => setShowShareModal(true)}
        >
          <Icon className="-small" name="icon-arrow-up-2" />
          SHARE
          <Modal
            isOpen={showShareModal}
            className="-medium"
            onRequestClose={() => setShowShareModal(false)}
          >
            <ShareModal
              links={{
                  link: location && location.href,
                  embed: location && `${location.origin}/embed${location.pathname}${location.search}`
                }}
              analytics={{
                  facebook: () => logEvent('Share', 'Share explore', 'Facebook'),
                  twitter: () => logEvent('Share', 'Share explore', 'Twitter'),
                  email: () => logEvent('Share', 'Share explore', 'Email'),
                  copy: type => logEvent('Share', 'Share explore', `Copy ${type}`)
                }}
            />
          </Modal>
        </button>

  );
}

ExploreDetailHeaderComponent.propTypes = {
  dataset: PropTypes.object.isRequired,
  // Store
  setSelectedDataset: PropTypes.func.isRequired
};

export default ExploreDetailHeaderComponent;
<commit_msg>bug hotfix<commit_after>import React, { useState } from 'react';
import PropTypes from 'prop-types';

// Components
import Icon from 'components/ui/icon';
import LoginRequired from 'components/ui/login-required';
import Modal from 'components/modal/modal-component';
import ShareModal from 'components/modal/share-modal';

// Tooltip
import { Tooltip } from 'vizzuality-components';
import CollectionsPanel from 'components/collections-panel';
import { getTooltipContainer } from 'utils/tooltip';

// utils
import { logEvent } from 'utils/analytics';

// Styles
import './styles.scss';

function ExploreDetailHeaderComponent(props) {
  const { dataset, setSelectedDataset } = props;
  const [showShareModal, setShowShareModal] = useState(false);
  const location = typeof window !== 'undefined' && window.location;

  return (

      <button
        className="c-btn -primary -compressed"
        onClick={() => setSelectedDataset(null)}
      >
        {'< ALL DATASETS'}
      </button>

        {/* Collections tooltip */}
        <LoginRequired>
          <Tooltip
            overlay={
              <CollectionsPanel
                resource={dataset}
                resourceType="dataset"
              />
            }
            overlayClassName="c-rc-tooltip"
            placement="bottomRight"
            trigger="click"
            getTooltipContainer={getTooltipContainer}
            monitorWindowResize
          >
            <button className="c-btn -secondary -compressed" >
              <Icon className="-small" name="icon-star-full" />
              SAVE
            </button>
          </Tooltip>
        </LoginRequired>

        <button
          className="c-btn -secondary -compressed"
          onClick={() => setShowShareModal(true)}
        >
          <Icon className="-small" name="icon-arrow-up-2" />
          SHARE
          <Modal
            isOpen={showShareModal}
            className="-medium"
            onRequestClose={() => setShowShareModal(false)}
          >
            <ShareModal
              links={{
                  link: location && location.href,
                  embed: location && `${location.origin}/embed${location.pathname}${location.search}`
                }}
              analytics={{
                  facebook: () => logEvent('Share', 'Share explore', 'Facebook'),
                  twitter: () => logEvent('Share', 'Share explore', 'Twitter'),
                  email: () => logEvent('Share', 'Share explore', 'Email'),
                  copy: type => logEvent('Share', 'Share explore', `Copy ${type}`)
                }}
            />
          </Modal>
        </button>

  );
}

ExploreDetailHeaderComponent.propTypes = {
  dataset: PropTypes.object.isRequired,
  // Store
  setSelectedDataset: PropTypes.func.isRequired
};

export default ExploreDetailHeaderComponent;
<|endoftext|>


<commit_before>// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©2006-2009 Apple, Inc. and contributors.
// License:   Licened under MIT license (see license.js)
// ==========================================================================
/*globals module ok equals same test MyApp */

// NOTE: The test below are based on the Data Hashes state chart.  This models
// the "commit" event in the NestedStore portion of the diagram.

var parent, store, child, storeKey, json, args;
module("SC.NestedStore#commitChanges", {
  setup: function() {
    parent = SC.Store.create();

    json = {
      string: "string",
      number: 23,
      bool:   YES
    };
    args = null;

    storeKey = SC.Store.generateStoreKey();

    store = parent.chain(); // create nested store
    child = store.chain();  // test multiple levels deep

    // override commitChangesFromNestedStore() so we can ensure it is called
    // save call history for later evaluation
    parent.commitChangesFromNestedStore =
    child.commitChangesFromNestedStore =
    store.commitChangesFromNestedStore = function(store, changes, force) {
      if (!args) args = [];
      args.push({
        target: this,
        store: store,
        changes: changes,
        force: force
      });
    };

  }
});

// ..........................................................
// BASIC STATE TRANSITIONS
//

function testStateTransition(shouldIncludeStoreKey) {

  // attempt to commit
  equals(store.commitChanges(), store, 'should return receiver');

  // verify result
  equals(store.storeKeyEditState(storeKey), SC.Store.INHERITED, 'data edit state');
  equals(args.length, 1, 'should have called commitChangesFromNestedStore');
  equals(args[0].target, parent, 'should have called on parent store');

  // verify if changes passed to callback included storeKey
  var changes = args[0].changes;
  var didInclude = changes && changes.contains(storeKey);
  if (shouldIncludeStoreKey) {
    ok(didInclude, 'passed set of changes should include storeKey');
  } else {
    ok(!didInclude, 'passed set of changes should NOT include storeKey');
  }

  equals(store.get('hasChanges'), NO, 'hasChanges should be cleared');
  ok(!store.chainedChanges || store.chainedChanges.length===0, 'should have empty chainedChanges set');
}

test("state = INHERITED", function() {

  // write in some data to parent
  parent.writeDataHash(storeKey, json);

  // check preconditions
  equals(store.storeKeyEditState(storeKey), SC.Store.INHERITED, 'precond - data edit state');

  testStateTransition(NO);
});

test("state = LOCKED", function() {

  // write in some data to parent
  parent.writeDataHash(storeKey, json);
  parent.editables = null ; // manually force to lock state
  store.readDataHash(storeKey);

  // check preconditions
  equals(store.storeKeyEditState(storeKey), SC.Store.LOCKED, 'precond - data edit state');
  ok(!store.chainedChanges || !store.chainedChanges.contains(storeKey), 'locked record should not be in chainedChanges set');

  testStateTransition(NO);
});

test("state = EDITABLE", function() {

  // write in some data to parent
  store.writeDataHash(storeKey, json);
  store.dataHashDidChange(storeKey);

  // check preconditions
  equals(store.storeKeyEditState(storeKey), SC.Store.EDITABLE, 'precond - data edit state');
  ok(store.chainedChanges  && store.chainedChanges.contains(storeKey), 'editable record should be in chainedChanges set');

  testStateTransition(YES);
});

// ..........................................................
// SPECIAL CASES
//

// TODO: Add more special cases for SC.NestedStore#commitChanges
<commit_msg>Eliminate exception in tests (they still fail)<commit_after>// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©2006-2009 Apple, Inc. and contributors.
// License:   Licened under MIT license (see license.js)
// ==========================================================================
/*globals module ok equals same test MyApp */

// NOTE: The test below are based on the Data Hashes state chart.  This models
// the "commit" event in the NestedStore portion of the diagram.

var parent, store, child, storeKey, json, args;
module("SC.NestedStore#commitChanges", {
  setup: function() {
    parent = SC.Store.create();

    json = {
      string: "string",
      number: 23,
      bool:   YES
    };
    args = [];

    storeKey = SC.Store.generateStoreKey();

    store = parent.chain(); // create nested store
    child = store.chain();  // test multiple levels deep

    // override commitChangesFromNestedStore() so we can ensure it is called
    // save call history for later evaluation
    parent.commitChangesFromNestedStore =
    child.commitChangesFromNestedStore =
    store.commitChangesFromNestedStore = function(store, changes, force) {
      args.push({
        target: this,
        store: store,
        changes: changes,
        force: force
      });
    };

  }
});

// ..........................................................
// BASIC STATE TRANSITIONS
//

function testStateTransition(shouldIncludeStoreKey) {

  // attempt to commit
  equals(store.commitChanges(), store, 'should return receiver');

  // verify result
  equals(store.storeKeyEditState(storeKey), SC.Store.INHERITED, 'data edit state');
  equals(args.length, 1, 'should have called commitChangesFromNestedStore');

  var opts = args[0] || {}; // avoid exceptions
  equals(opts.target, parent, 'should have called on parent store');

  // verify if changes passed to callback included storeKey
  var changes = opts.changes;
  var didInclude = changes && changes.contains(storeKey);
  if (shouldIncludeStoreKey) {
    ok(didInclude, 'passed set of changes should include storeKey');
  } else {
    ok(!didInclude, 'passed set of changes should NOT include storeKey');
  }

  equals(store.get('hasChanges'), NO, 'hasChanges should be cleared');
  ok(!store.chainedChanges || store.chainedChanges.length===0, 'should have empty chainedChanges set');
}

test("state = INHERITED", function() {

  // write in some data to parent
  parent.writeDataHash(storeKey, json);

  // check preconditions
  equals(store.storeKeyEditState(storeKey), SC.Store.INHERITED, 'precond - data edit state');

  testStateTransition(NO);
});

test("state = LOCKED", function() {

  // write in some data to parent
  parent.writeDataHash(storeKey, json);
  parent.editables = null ; // manually force to lock state
  store.readDataHash(storeKey);

  // check preconditions
  equals(store.storeKeyEditState(storeKey), SC.Store.LOCKED, 'precond - data edit state');
  ok(!store.chainedChanges || !store.chainedChanges.contains(storeKey), 'locked record should not be in chainedChanges set');

  testStateTransition(NO);
});

test("state = EDITABLE", function() {

  // write in some data to parent
  store.writeDataHash(storeKey, json);
  store.dataHashDidChange(storeKey);

  // check preconditions
  equals(store.storeKeyEditState(storeKey), SC.Store.EDITABLE, 'precond - data edit state');
  ok(store.chainedChanges  && store.chainedChanges.contains(storeKey), 'editable record should be in chainedChanges set');

  testStateTransition(YES);
});

// ..........................................................
// SPECIAL CASES
//

// TODO: Add more special cases for SC.NestedStore#commitChanges
<|endoftext|>