More actions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
( function ( mw, $ ) { | |||
'use strict'; | |||
( | // ------------------------ Configurable ------------------------- // | ||
// Title (in the page namespace) of the raw JSON data. Change this | |||
// if you decide to store the file elsewhere. | |||
const JSON_PAGE = 'MediaWiki:Vault_altar_ingredients.json'; | |||
// Where in the DOM do we inject the component? Default is the | |||
const | // beginning of the article body. | ||
const TARGET_NODE_SELECTOR = '#vault-altar-component'; | |||
// ---------------------- Helper Functions ----------------------- // | |||
/** | |||
* Given a sorted numeric array of available levels, find the | |||
* greatest level that is <= the user‑selected value. | |||
*/ | |||
function nearestLevel ( levels, val ) { | |||
let chosen = levels[ 0 ]; | |||
for ( const lv of levels ) { | |||
if ( val >= lv ) { | |||
chosen = lv; | |||
} else { | |||
break; | |||
} | |||
} | |||
return chosen; | |||
} | |||
/** | |||
* Render the output tables for a particular vault level. | |||
* | |||
* @param {Object} data – Parsed JSON object (the entire file). | |||
* @param {string} levelKey – The exact level key to show (e.g. "10"). | |||
* @param {jQuery} $out – jQuery node where HTML will be injected. | |||
*/ | |||
function renderLevel ( data, levelKey, $out ) { | |||
$out.empty(); | |||
const levelData = data.LEVELS[ levelKey ]; | |||
if ( !levelData ) { | |||
$out.append( $( '<p>' ).text( 'No data found for level ' + levelKey + '.' ) ); | |||
return; | |||
} | |||
// For each category (resource, mob, farmable, misc) create a | |||
// collapsible <details> section containing a wikitable. | |||
Object.entries( levelData ).forEach( ( [ catName, entries ] ) => { | |||
const $details = $( '<details>' ).addClass( 'vault-altar-cat' ); | |||
$details.append( $( '<summary>' ).text( catName.charAt( 0 ).toUpperCase() + catName.slice( 1 ) ) ); | |||
const $table = $( '<table>' ) | |||
.addClass( 'wikitable sortable' ) | |||
.append( $( '<thead>' ).append( $( '<tr>' ) | |||
.append( $( '<th>' ).text( 'Items' ) ) | |||
.append( $( '<th>' ).text( 'Amount (min‒max)' ) ) | |||
.append( $( '<th>' ).text( 'Scale' ) ) | |||
.append( $( '<th>' ).text( 'Weight' ) ) | |||
) ); | |||
entries.forEach( entry => { | |||
const items = entry.value.items.map( o => o.item.replace( /^minecraft:/, '' ) ).join( ', ' ); | |||
const amt = entry.value.amount.min + '‒' + entry.value.amount.max; | |||
const scale = entry.value.scale; | |||
const weight = entry.weight; | |||
$table.append( $( '<tr>' ) | |||
.append( $( '<td>' ).text( items ) ) | |||
.append( $( '<td>' ).text( amt ) ) | |||
.append( $( '<td>' ).text( scale ) ) | |||
.append( $( '<td>' ).text( weight ) ) | |||
); | |||
} ); | |||
$details.append( $table ); | |||
$out.append( $details ); | |||
} ); | |||
} | |||
} | |||
const | // -------------------------- Main ------------------------------- // | ||
function init () { | |||
// Build the basic UI skeleton first so the page doesn’t feel | |||
// empty if the JSON request is slow. | |||
const $wrapper = $( '<div>' ).addClass( 'vault-altar-wrapper' ); | |||
const $sliderRow = $( '<div>' ).addClass( 'vault-altar-slider' ); | |||
const $label = $( '<label>' ) | |||
.attr( 'for', 'vault-altar-level' ) | |||
.text( 'Vault Level: ' ); | |||
const $valDisplay = $( '<span>' ).attr( 'id', 'vault-altar-level-val' ).text( '0' ); | |||
const $input = $( '<input>' ) | |||
.attr( { | |||
id: 'vault-altar-level', | |||
type: 'range', | |||
min: 0, | |||
max: 100, | |||
step: 1, | |||
value: 0 | |||
} ) | |||
.css( 'width', '100%' ); | |||
$sliderRow.append( $label, $valDisplay, $input ); | |||
$wrapper.append( $sliderRow ); | |||
const $output = $( '<div>' ).attr( 'id', 'vault-altar-output' ); | |||
$wrapper.append( $output ); | |||
// Inject into page. | |||
$( TARGET_NODE_SELECTOR ).first().prepend( $wrapper ); | |||
// Fetch JSON data (raw content). | |||
$.getJSON( mw.util.wikiScript( 'index' ), { | |||
title: JSON_PAGE, | |||
action: 'raw', | |||
ctype: 'application/json' | |||
} ).done( function ( data ) { | |||
// Prepare slider limits based on actual data keys. | |||
const levels = Object.keys( data.LEVELS ).map( Number ).sort( ( a, b ) => a - b ); | |||
$input.attr( { | |||
min: levels[ 0 ], | |||
max: levels[ levels.length - 1 ] | |||
} ); | |||
/** | |||
* Update handler for the slider. | |||
*/ | |||
function update () { | |||
const userVal = parseInt( $input.val(), 10 ); | |||
const lvl = nearestLevel( levels, userVal ); | |||
$valDisplay.text( userVal + ' (showing ' + lvl + ')' ); | |||
renderLevel( data, String( lvl ), $output ); | |||
} | |||
$input.on( 'input change', update ); | |||
update(); // Initial render. | |||
. | } ).fail( function () { | ||
. | $output.text( 'Failed to load Vault Altar data – please check that ' + JSON_PAGE + ' exists and is valid JSON.' ); | ||
} ); | |||
} | } | ||
// Kick‑off when DOM is ready. | |||
$( init ); | |||
})(); | } )( mediaWiki, jQuery ); |
Revision as of 05:39, 7 July 2025
( function ( mw, $ ) {
'use strict';
// ------------------------ Configurable ------------------------- //
// Title (in the page namespace) of the raw JSON data. Change this
// if you decide to store the file elsewhere.
const JSON_PAGE = 'MediaWiki:Vault_altar_ingredients.json';
// Where in the DOM do we inject the component? Default is the
// beginning of the article body.
const TARGET_NODE_SELECTOR = '#vault-altar-component';
// ---------------------- Helper Functions ----------------------- //
/**
* Given a sorted numeric array of available levels, find the
* greatest level that is <= the user‑selected value.
*/
function nearestLevel ( levels, val ) {
let chosen = levels[ 0 ];
for ( const lv of levels ) {
if ( val >= lv ) {
chosen = lv;
} else {
break;
}
}
return chosen;
}
/**
* Render the output tables for a particular vault level.
*
* @param {Object} data – Parsed JSON object (the entire file).
* @param {string} levelKey – The exact level key to show (e.g. "10").
* @param {jQuery} $out – jQuery node where HTML will be injected.
*/
function renderLevel ( data, levelKey, $out ) {
$out.empty();
const levelData = data.LEVELS[ levelKey ];
if ( !levelData ) {
$out.append( $( '<p>' ).text( 'No data found for level ' + levelKey + '.' ) );
return;
}
// For each category (resource, mob, farmable, misc) create a
// collapsible <details> section containing a wikitable.
Object.entries( levelData ).forEach( ( [ catName, entries ] ) => {
const $details = $( '<details>' ).addClass( 'vault-altar-cat' );
$details.append( $( '<summary>' ).text( catName.charAt( 0 ).toUpperCase() + catName.slice( 1 ) ) );
const $table = $( '<table>' )
.addClass( 'wikitable sortable' )
.append( $( '<thead>' ).append( $( '<tr>' )
.append( $( '<th>' ).text( 'Items' ) )
.append( $( '<th>' ).text( 'Amount (min‒max)' ) )
.append( $( '<th>' ).text( 'Scale' ) )
.append( $( '<th>' ).text( 'Weight' ) )
) );
entries.forEach( entry => {
const items = entry.value.items.map( o => o.item.replace( /^minecraft:/, '' ) ).join( ', ' );
const amt = entry.value.amount.min + '‒' + entry.value.amount.max;
const scale = entry.value.scale;
const weight = entry.weight;
$table.append( $( '<tr>' )
.append( $( '<td>' ).text( items ) )
.append( $( '<td>' ).text( amt ) )
.append( $( '<td>' ).text( scale ) )
.append( $( '<td>' ).text( weight ) )
);
} );
$details.append( $table );
$out.append( $details );
} );
}
// -------------------------- Main ------------------------------- //
function init () {
// Build the basic UI skeleton first so the page doesn’t feel
// empty if the JSON request is slow.
const $wrapper = $( '<div>' ).addClass( 'vault-altar-wrapper' );
const $sliderRow = $( '<div>' ).addClass( 'vault-altar-slider' );
const $label = $( '<label>' )
.attr( 'for', 'vault-altar-level' )
.text( 'Vault Level: ' );
const $valDisplay = $( '<span>' ).attr( 'id', 'vault-altar-level-val' ).text( '0' );
const $input = $( '<input>' )
.attr( {
id: 'vault-altar-level',
type: 'range',
min: 0,
max: 100,
step: 1,
value: 0
} )
.css( 'width', '100%' );
$sliderRow.append( $label, $valDisplay, $input );
$wrapper.append( $sliderRow );
const $output = $( '<div>' ).attr( 'id', 'vault-altar-output' );
$wrapper.append( $output );
// Inject into page.
$( TARGET_NODE_SELECTOR ).first().prepend( $wrapper );
// Fetch JSON data (raw content).
$.getJSON( mw.util.wikiScript( 'index' ), {
title: JSON_PAGE,
action: 'raw',
ctype: 'application/json'
} ).done( function ( data ) {
// Prepare slider limits based on actual data keys.
const levels = Object.keys( data.LEVELS ).map( Number ).sort( ( a, b ) => a - b );
$input.attr( {
min: levels[ 0 ],
max: levels[ levels.length - 1 ]
} );
/**
* Update handler for the slider.
*/
function update () {
const userVal = parseInt( $input.val(), 10 );
const lvl = nearestLevel( levels, userVal );
$valDisplay.text( userVal + ' (showing ' + lvl + ')' );
renderLevel( data, String( lvl ), $output );
}
$input.on( 'input change', update );
update(); // Initial render.
} ).fail( function () {
$output.text( 'Failed to load Vault Altar data – please check that ' + JSON_PAGE + ' exists and is valid JSON.' );
} );
}
// Kick‑off when DOM is ready.
$( init );
} )( mediaWiki, jQuery );