Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

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 () {
	function initFilter( filter ) {
		if ( filter.dataset.initialized ) {
			return;
		}
		filter.dataset.initialized = '1';

		var targetSelector = filter.getAttribute( 'data-target' );
		var table = targetSelector ? document.querySelector( targetSelector ) : null;
		if ( !table ) {
			return;
		}

		var rows = Array.prototype.slice.call( table.querySelectorAll( 'tr.item-list__row, tr.spell-list__row' ) );
		var count = document.createElement( 'span' );
		var reset = document.createElement( 'button' );
		var fields = parseFields( filter.getAttribute( 'data-filter-fields' ) );
		var selects = fields.map( function ( field ) {
			return buildSelect( rows, field.key, field.label, field.all );
		} );

		filter.textContent = '';
		selects.forEach( function ( select ) {
			filter.appendChild( select.label );
		} );

		reset.type = 'button';
		reset.textContent = 'Reset';
		filter.appendChild( reset );

		count.className = filter.classList.contains( 'spell-list-filter' ) ?
			'spell-list-filter__count' :
			'item-list-filter__count';
		filter.appendChild( count );

		function parseFields( value ) {
			if ( !value ) {
				return [
					{ key: 'slot', label: 'Slot', all: 'All slots' },
					{ key: 'construction', label: 'Construction', all: 'All levels' }
				];
			}
			return value.split( '|' ).map( function ( spec ) {
				var parts = spec.split( ':' );
				return {
					key: parts[ 0 ],
					label: parts[ 1 ] || parts[ 0 ],
					all: parts[ 2 ] || 'All'
				};
			} );
		}

		function buildSelect( sourceRows, key, labelText, allText ) {
			var label = document.createElement( 'label' );
			var select = document.createElement( 'select' );
			var values = [];
			var seen = {};

			sourceRows.forEach( function ( row ) {
				var value = row.dataset[ key ];
				if ( value && !seen[ value ] ) {
					seen[ value ] = true;
					values.push( value );
				}
			} );

			values.sort( function ( a, b ) {
				if ( key === 'construction' || key === 'research' ) {
					return Number( a ) - Number( b );
				}
				return a.localeCompare( b );
			} );

			select.dataset.filter = key;
			select.appendChild( new Option( allText, '' ) );
			values.forEach( function ( value ) {
				select.appendChild( new Option( value, value ) );
			} );

			label.appendChild( document.createTextNode( labelText + ' ' ) );
			label.appendChild( select );
			select.label = label;
			return select;
		}

		function applyFilters() {
			var visible = 0;
			rows.forEach( function ( row ) {
				var keep = selects.every( function ( select ) {
					var value = select.value;
					var key = select.getAttribute( 'data-filter' );
					return !value || row.dataset[ key ] === value;
				} );
				row.hidden = !keep;
				if ( keep ) {
					visible += 1;
				}
			} );
			if ( count ) {
				count.textContent = visible + ' items';
			}
		}

		selects.forEach( function ( select ) {
			select.addEventListener( 'change', applyFilters );
		} );

		reset.addEventListener( 'click', function () {
			selects.forEach( function ( select ) {
				select.value = '';
			} );
			applyFilters();
		} );

		applyFilters();
	}

	mw.hook( 'wikipage.content' ).add( function ( $content ) {
		var content = $content && $content[ 0 ] ? $content[ 0 ] : document;
		Array.prototype.forEach.call( content.querySelectorAll( '.domwiki-filter' ), initFilter );
	} );
}() );