User:Fred Gandt/chessDemo.js

( function( DOM_w, DOM_d ) {	if ( ~mw.config.get( 'wgCategories' ).indexOf( 'Pages using Template chessDemo' ) ) {		var init = function( demo ) {				var printable = DOM_w.location.search && DOM_w.location.search.indexOf( '&printable=yes' ),					data = JSON.parse( demo.getAttribute( 'data-data' ) ),					notes = demo.querySelector( '.cd-notation' ),					ui = demo.querySelector( '.cd-controls' ),					board = demo.querySelector( '.cd-board' ),					speed = data.speed * 1000,					controls = data.controls,					BF = data.blackfirst,					setup = data.setup,					moves = data.moves,					numberofmoves = data.moves.length,					parsed = [],					frame = 0,					glue = function( a ) {						return 'cd-file-' + a.join( ' cd-rank-' );					},					pick = function( s ) {						return board.querySelector( '[class*="' + s + '"]:not([class*="cd-captured"])' );					},					note = function( r ) {						if ( notes ) {							var ln = notes.querySelector( '.cd-movenote' ), mn = notes.querySelectorAll( 'b span' )[ frame ]; if ( ln ) { ln.removeAttribute( 'class' ); }							if ( !r ) { mn.classList.add( 'cd-movenote' ); }						}					},					move = function( dir ) { var pf = parsed[ frame ], i = 0, m, m0, m00, m1, m10, lm, alm = board.querySelectorAll( 'div[class*="cd-moving"]' ); while ( lm = alm[ i++ ] ) { lm.classList.remove( 'cd-moving' ); }						i = 0; while ( m = pf[ i++ ] ) { m0 = m[ 0 ]; m00 = m0[ 0 ]; m00.setAttribute( 'class', m0[ dir ] ); m00.classList.add( 'cd-moving' ); if ( m1 = m[ 1 ] ) { m10 = m1[ 0 ]; m10.setAttribute( 'class', m1[ dir ] ); m10.classList.add( 'cd-moving' ); }						}						note; },					next = function( a ) { if ( a ) { data.timeout = DOM_w.setTimeout( function {								actions.play( a );							}, speed ); }					},					actions = { reset: function { var i = 0, p;							actions.pause; note( true ); frame = 0; while ( p = board.querySelectorAll( 'div:not(.cd-fallback)' )[ i ] ) { p.setAttribute( 'class', setup[ i++ ] ); }						},						auto: function { actions.pause; actions.play( true ); },						pause: function { DOM_w.clearTimeout( data.timeout ); },						back: function { var lf = frame - 1; actions.pause; if ( lf >= 0 && parsed[ lf ] ) { --frame; move( 1 ); } else { skipTo( numberofmoves ); }						},						play: function( a ) { actions.pause; if ( frame < data.moves.length ) { move( 2 ); ++frame; next( a ); } else { if ( a ) { data.timeout = DOM_w.setTimeout( function {										actions.reset;										next( a );									}, speed ); } else { actions.reset; }							}						}					},					skipTo = function( pos ) { actions.reset; while ( pos-- ) { actions.play; }					},					calculate = function( initial ) { while ( frame < numberofmoves ) { var m = data.moves[ frame ], from = m[ 0 ].split( '' ), bits = ( /(^(0\-0(?:\-0)?)|([KQBNR]{1})?(?:[a-h]{0,1}[1-8]{0,1})?(x{1})?([a-h]{1}[1-8]{1})(e\.p\.)?(?:(?:\=)?([KQBNR]{1}))?(?:\+|#)?(?:[.]*)?$)/ ).exec( m[ 1 ] ), castle = bits[ 2 ], piece = bits[ 3 ] ? 'cd-piece-' + bits[ 3 ] + ' ' : '', to = bits[ 5 ] ? bits[ 5 ].split(  ) : , promote = bits[ 7 ] ? 'cd-piece-' + bits[ 7 ] + ' ' : '', turn = frame % 2, color = 'cd-piece-' + [ 'white', 'black' ][ +( BF ? !turn : turn ) ], pass = [], arr = []; if ( castle ) { var rank = ' cd-rank-' + from[ 1 ], kingside = castle === '0-0', ck = color + ' cd-piece-K cd-file-e' + rank, cr = color + ' cd-piece-R cd-file-' + ( kingside ? 'h' : 'a' ) + rank; pass.push( [									[ pick( ck ), ck, color + ' cd-piece-K cd-file-' + ( kingside ? 'g' : 'c' ) + rank ],									[ pick( cr ), cr, color + ' cd-piece-R cd-file-' + ( kingside ? 'f' : 'd' ) + rank ]								] ); } else { var f = color + ' ' + piece + glue( from ); if ( bits[ 4 ] ) { var captured = pick( glue( bits[ 6 ] ? [ to[ 0 ], from[ 1 ] ] : to ) ), cc = captured.getAttribute( 'class' ); arr.push( [ captured, cc, cc + ' cd-captured' ] ); }								arr.push( [ pick( f ), f, color + ' ' + ( promote || piece ) + glue( to ) ] ); pass.push( arr ); }							parsed.push( pass ); move( 2 ); ++frame; }						if ( initial !== undefined ) { skipTo( initial ); }					},					controlSpeed = function( evt ) { speed = 5000 - evt.target.value; },					controlDemo = function( evt ) { var trg = evt.target; if ( trg.tagName.toLowerCase === "button" ) { actions[ trg.getAttribute( 'data-action' ) ]; }					};				if ( controls || printable ) { var min = '&#9664; &#9654; ', med = ' Reset ' + min + 'Auto &#9654; '; if ( printable || controls === 'min' ) { ui.classList.add( 'cd-mini' ); ui.innerHTML = ' ' + min + ' '; } else if ( controls === 'med' ) { ui.innerHTML = med; } else { ui.innerHTML = med + ' Speed: ' + '&#8214; &#9632; '; ui.querySelector( 'input' ).addEventListener( 'input', controlSpeed, false ); }					ui.addEventListener( 'click', controlDemo, false ); }				calculate( data.initial ); if ( printable ) { if ( notes ) { var cc = notes.querySelector( '.mw-collapsible-content' ); if ( cc ) { cc.style.display = 'block'; }					}				} else if ( data.autostart ) { actions.play( true ); }			};		$( DOM_d ).ready( function {			var demos = DOM_d.querySelectorAll( '.chessDemo' ),				link = DOM_d.createElement( 'link' ),				i = 0, demo;			link.href = '/w/index.php?title=User:Fred_Gandt/chessDemo.css&action=raw&ctype=text/css';			link.setAttribute( 'rel', 'stylesheet' );			link.addEventListener( 'load', function { while ( demo = demos[ i++ ] ) { init( demo ); }			}, false );			DOM_d.querySelector( 'head' ).appendChild( link );		} ); } } ( window, document ) );