Tip of the day
Want to find something particular about the game and don't mind spoilers? Check the Wiki!
MediaWiki:Gadget-WSWBHighlightTable.js
From Walkscape Walkthrough
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.
/* Gadget: WSWB Highlight Table
*
* Highlights rows in tables with class "wswb-highlight-table". A row's state
* follows its data-wswb-object-id across every participating table and page.
* Tables may set data-wswb-tracker when the same object needs an independent
* checklist (for example, "obtained" versus "discovered").
*/
mw.loader.using( [ 'jquery', 'mediawiki.storage' ] ).then( function () {
'use strict';
var STORAGE_KEY = 'wswb:highlight-table:v1';
var TABLE_SELECTOR = 'table.wswb-highlight-table';
var FOOTER_CLASS = 'wswb-highlight-table-footer';
var OBJECT_ID_ATTRIBUTE = 'data-wswb-object-id';
var TRACKER_ATTRIBUTE = 'data-wswb-tracker';
var DEFAULT_TRACKER = 'default';
function canUseLocalStorage() {
var testKey;
try {
testKey = STORAGE_KEY + ':test';
localStorage.setItem( testKey, '1' );
localStorage.removeItem( testKey );
return true;
} catch ( error ) {
return false;
}
}
var usesLocalStorage = canUseLocalStorage();
var storage = usesLocalStorage ? {
get: function ( key ) {
return localStorage.getItem( key );
},
set: function ( key, value ) {
localStorage.setItem( key, value );
}
} : {
get: function ( key ) {
return mw.storage.get( key );
},
set: function ( key, value ) {
mw.storage.set( key, value );
}
};
function readSelections() {
var raw = storage.get( STORAGE_KEY );
if ( !raw ) {
return {};
}
try {
var parsed = JSON.parse( raw );
return parsed && typeof parsed === 'object' && !Array.isArray( parsed ) ? parsed : {};
} catch ( error ) {
return {};
}
}
function writeSelections( selections ) {
try {
storage.set( STORAGE_KEY, JSON.stringify( selections ) );
} catch ( error ) {
mw.log.error( 'WSWB Highlight Table could not save its state:', error );
}
}
function getTracker( $table ) {
return $table.attr( TRACKER_ATTRIBUTE ) || DEFAULT_TRACKER;
}
function getObjectId( $row ) {
return $row.attr( OBJECT_ID_ATTRIBUTE ) || '';
}
function getSelectionId( $table, $row ) {
var objectId = getObjectId( $row );
return objectId ? getTracker( $table ) + '/' + objectId : '';
}
function tableColumnCount( $table ) {
var maximum = 1;
$table.children( 'thead, tbody' ).children( 'tr' ).each( function () {
var count = 0;
$( this ).children( 'th, td' ).each( function () {
var span = parseInt( $( this ).attr( 'colspan' ) || '1', 10 );
count += isNaN( span ) ? 1 : span;
} );
maximum = Math.max( maximum, count );
} );
return maximum;
}
function selectableRows( $table ) {
return $table.find( 'tbody tr[' + OBJECT_ID_ATTRIBUTE + ']' );
}
function updateFooter( $table ) {
var $rows;
var selectedIds = {};
var allIds = {};
var selectedCount;
var totalCount;
var $footer;
var $cell;
var $counter;
if ( !$table.hasClass( FOOTER_CLASS ) ) {
return;
}
$rows = selectableRows( $table );
$rows.each( function () {
var $row = $( this );
var selectionId = getSelectionId( $table, $row );
if ( selectionId ) {
allIds[ selectionId ] = true;
if ( $row.hasClass( 'wswb-highlight-on' ) ) {
selectedIds[ selectionId ] = true;
}
}
} );
selectedCount = Object.keys( selectedIds ).length;
totalCount = Object.keys( allIds ).length;
$footer = $table.children( 'tfoot' );
if ( !$footer.length ) {
$footer = $( '<tfoot>' ).appendTo( $table );
}
$cell = $footer.find( 'tr.wswb-highlight-table-footer-row > th' );
if ( !$cell.length ) {
$cell = $( '<th>' )
.addClass( 'wswb-highlight-table-footer-cell' )
.appendTo(
$( '<tr>' )
.addClass( 'wswb-highlight-table-footer-row' )
.appendTo( $footer )
);
}
$cell.attr( 'colspan', tableColumnCount( $table ) );
$counter = $cell.find( '.wswb-highlight-table-counter' );
if ( !$counter.length ) {
$counter = $( '<span>' )
.addClass( 'wswb-highlight-table-counter' )
.appendTo( $cell );
$( '<button>' )
.attr( 'type', 'button' )
.addClass( 'wswb-highlight-table-clear-button' )
.text( 'Clear All' )
.appendTo( $cell );
}
$counter.text( 'Entries Completed: (' + selectedCount + ' / ' + totalCount + ')' );
}
function applySelections() {
var selections = readSelections();
$( TABLE_SELECTOR ).each( function () {
var $table = $( this );
selectableRows( $table ).each( function () {
var $row = $( this );
var selectionId = getSelectionId( $table, $row );
var selected = selections[ selectionId ] === 1;
$row
.toggleClass( 'wswb-highlight-on', selected )
.attr( 'aria-selected', selected ? 'true' : 'false' );
if ( !$row.attr( 'tabindex' ) ) {
$row.attr( 'tabindex', '0' );
}
} );
updateFooter( $table );
} );
}
function toggleRow( $table, $row ) {
var selectionId = getSelectionId( $table, $row );
var selections;
if ( !selectionId ) {
return;
}
selections = readSelections();
if ( selections[ selectionId ] === 1 ) {
delete selections[ selectionId ];
} else {
selections[ selectionId ] = 1;
}
writeSelections( selections );
applySelections();
}
function clearTable( $table ) {
var selections = readSelections();
selectableRows( $table ).each( function () {
delete selections[ getSelectionId( $table, $( this ) ) ];
} );
writeSelections( selections );
applySelections();
}
function bindTables( $root ) {
$root.find( TABLE_SELECTOR ).addBack( TABLE_SELECTOR ).each( function () {
var $table = $( this );
$table.off( '.wswbHighlightTable' );
$table.on( 'click.wswbHighlightTable', 'tbody tr[' + OBJECT_ID_ATTRIBUTE + ']', function ( event ) {
if ( $( event.target ).closest( 'a, button, input, label, select, textarea' ).length ) {
return;
}
toggleRow( $table, $( this ) );
} );
$table.on( 'keydown.wswbHighlightTable', 'tbody tr[' + OBJECT_ID_ATTRIBUTE + ']', function ( event ) {
if ( event.key === ' ' || event.key === 'Enter' ) {
event.preventDefault();
toggleRow( $table, $( this ) );
}
} );
$table.on( 'click.wswbHighlightTable', '.wswb-highlight-table-clear-button', function () {
clearTable( $table );
} );
} );
}
function initialize( $content ) {
bindTables( $content );
applySelections();
}
$( function () {
initialize( $( document ) );
} );
mw.hook( 'wikipage.content' ).add( initialize );
if ( usesLocalStorage ) {
window.addEventListener( 'storage', function ( event ) {
if ( event.key === STORAGE_KEY ) {
applySelections();
}
} );
}
} );
