MediaWiki:Gadget-chessDemo.js
Appearance
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
( 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 = '<button title="Step back one move" data-action="back">◀</button><button title="Step forward one move" data-action="play">▶</button>',
med = '<span><button title="Reset the board" data-action="reset">Reset</button>' + min +
'<button title="Play automatic animation" data-action="auto">Auto ▶</button></span>';
if ( printable || controls === 'min' ) {
ui.classList.add( 'cd-mini' );
ui.innerHTML = '<span>' + min + '</span>';
} else if ( controls === 'med' ) {
ui.innerHTML = med;
} else {
ui.innerHTML = med + '<br><span><label>Speed:<input type="range" value="' + ( 5000 - speed ) + '" min="0" max="4500" step="500"></label>' +
'<button title="Pause automatic animation" data-action="pause">‖</button><button title="Stop automatic animation" data-action="reset">■</button></span>';
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 ) );