User:Monster Domosed/common.js: Difference between revisions

No edit summary
No edit summary
Line 1: Line 1:
/* Patch Formatter */
/* Patch Formatter */
( function () {
( function () {
'use strict';
'use strict';
Line 20: Line 20:
// ---- API ------------------------------------------------------------
// ---- API ------------------------------------------------------------
function getWikiData( templateName ) {
function getWikiData( templateName ) {
console.log('[PatchFormatter] getWikiData called:', templateName);
console.log('[PatchFormatter] getWikiData:', templateName);


var api = new mw.Api();
var api = new mw.Api();
Line 33: Line 33:
} ).then( function ( data ) {
} ).then( function ( data ) {


console.log('[PatchFormatter] API response:', templateName, data);
console.log('[PatchFormatter] API response:', templateName);


var wikitext = ( data.expandtemplates && data.expandtemplates.wikitext ) || '';
var wikitext = ( data.expandtemplates && data.expandtemplates.wikitext ) || '';


var result = wikitext.split( ',' )
return wikitext.split( ',' )
.map( function ( item ) {
.map( function ( item ) {
return item.trim().replace( /^'+|'+$/g, '' );
return item.trim().replace( /^'+|'+$/g, '' );
Line 44: Line 44:
return item.length > 0;
return item.length > 0;
} );
} );
console.log('[PatchFormatter] parsed list:', templateName, result.length);
return result;
} );
} );
}
}
Line 53: Line 49:
// ---- PARSING --------------------------------------------------------
// ---- PARSING --------------------------------------------------------
function parseEntries( rawText ) {
function parseEntries( rawText ) {
console.log('[PatchFormatter] parseEntries input size:', rawText.length);
console.log('[PatchFormatter] parseEntries');


var entries = [];
var entries = [];
Line 62: Line 58:


if ( stripped.indexOf( '-' ) === 0 ) {
if ( stripped.indexOf( '-' ) === 0 ) {
if ( current !== null ) {
if ( current !== null ) entries.push( current );
entries.push( current );
}
current = stripped.slice( 1 ).trim();
current = stripped.slice( 1 ).trim();
} else if ( current !== null ) {
} else if ( current !== null ) {
Line 71: Line 65:
} );
} );


if ( current !== null ) {
if ( current !== null ) entries.push( current );
entries.push( current );
}


var cleaned = entries
return entries
.map( function ( e ) {
.map( function ( e ) {
return e.replace( /\s+/g, ' ' ).trim();
return e.replace( /\s+/g, ' ' ).trim();
} )
} )
.filter( function ( e ) {
.filter( Boolean );
return e.length > 0;
} );
 
console.log('[PatchFormatter] parsed entries:', cleaned.length);
 
return cleaned;
}
}


Line 96: Line 82:
var rest = entry.slice( idx + 1 ).trim();
var rest = entry.slice( idx + 1 ).trim();


if ( gameModes.indexOf( prefix ) !== -1 ) {
if ( gameModes.indexOf( prefix ) !== -1 ) return [ 'mode', prefix, rest ];
return [ 'mode', prefix, rest ];
if ( heroes.indexOf( prefix ) !== -1 ) return [ 'hero', prefix, rest ];
}
if ( items.indexOf( prefix ) !== -1 ) return [ 'item', prefix, rest ];
if ( heroes.indexOf( prefix ) !== -1 ) {
return [ 'hero', prefix, rest ];
}
if ( items.indexOf( prefix ) !== -1 ) {
return [ 'item', prefix, rest ];
}
}
}


Line 125: Line 105:


function wrap( terms, template ) {
function wrap( terms, template ) {
terms.slice().sort( function ( a, b ) {
terms.slice()
return b.length - a.length;
.sort( function ( a, b ) { return b.length - a.length; } )
} ).forEach( function ( term ) {
.forEach( function ( term ) {


var pattern = new RegExp( '(?<!\\w)' + escapeRegExp( term ) + '(?!\\w)', 'g' );
var pattern = new RegExp( '(?<!\\w)' + escapeRegExp( term ) + '(?!\\w)', 'g' );


text = text.replace( pattern, function () {
text = text.replace( pattern, function () {
return protect( template.replace( '%s', function () {
return protect(
return term;
template.replace( '%s', function () {
} ) );
return term;
} )
);
} );
} );
} );
} );
}
}


Line 158: Line 140:
// ---- OUTPUT ---------------------------------------------------------
// ---- OUTPUT ---------------------------------------------------------
function buildOutput( entries, heroes, abilities, items, gameModes ) {
function buildOutput( entries, heroes, abilities, items, gameModes ) {
console.log('[PatchFormatter] buildOutput start');
console.log('[PatchFormatter] buildOutput');


var general = [];
var general = [];
var modes = {}, modeOrder = [];
var itemSections = {}, itemOrder = [];
var heroSections = {}, heroOrder = [];


entries.forEach( function ( entry ) {
entries.forEach( function ( entry ) {
var c = classify( entry, heroes, items, gameModes );
var c = classify( entry, heroes, items, gameModes );
var kind = c[ 0 ];
var name = c[ 1 ];
var body = formatBody( c[ 2 ], heroes, abilities, items );
var body = formatBody( c[ 2 ], heroes, abilities, items );


if ( kind === 'general' ) {
if ( c[ 0 ] === 'general' ) {
general.push( body );
general.push( body );
} else if ( kind === 'mode' ) {
if ( !modes[ name ] ) {
modes[ name ] = [];
modeOrder.push( name );
}
modes[ name ].push( body );
} else if ( kind === 'item' ) {
if ( !itemSections[ name ] ) {
itemSections[ name ] = [];
itemOrder.push( name );
}
itemSections[ name ].push( body );
} else if ( kind === 'hero' ) {
if ( !heroSections[ name ] ) {
heroSections[ name ] = [];
heroOrder.push( name );
}
heroSections[ name ].push( body );
}
}
} );
} );


var out = [];
var out = general.map( function ( e ) {
 
return '* ' + e;
general.forEach( function ( entry ) {
out.push( '* ' + entry );
} );
} );


console.log('[PatchFormatter] sections ready');
return out.join( '\n' ) + '\n';
 
return out.join( '\n' ).trim() + '\n';
}
}


// ---- UI -------------------------------------------------------------
// ---- INIT -----------------------------------------------------------
function init() {
function init() {
console.log('[PatchFormatter] init started');
console.log('[PatchFormatter] init START');


var app = document.getElementById( 'patchformatter' );
var app = document.getElementById( 'patchformatter' );


if ( !app ) {
if ( !app ) {
console.error('[PatchFormatter] #patchformatter not found');
console.error('[PatchFormatter] container not found');
return;
return;
}
}


console.log('[PatchFormatter] container found');
console.log('[PatchFormatter] container OK');


console.log('[PatchFormatter] OO check:', OO, OO && OO.ui);
if ( !window.OO || !OO.ui ) {
console.error('[PatchFormatter] OOUI NOT AVAILABLE');
return;
}


try {
console.log('[PatchFormatter] OOUI OK');
var inputWidget = new OO.ui.MultilineTextInputWidget( {
rows: 14,
placeholder: 'Raw patch notes',
autofocus: true
} );


var outputWidget = new OO.ui.MultilineTextInputWidget( {
var inputWidget = new OO.ui.MultilineTextInputWidget( {
rows: 20,
rows: 14,
readOnly: true
placeholder: 'Raw patch notes'
} );
} );


var formatButton = new OO.ui.ButtonWidget( {
var outputWidget = new OO.ui.MultilineTextInputWidget( {
label: 'Format',
rows: 20,
flags: [ 'primary', 'progressive' ]
readOnly: true
} );
} );


var copyButton = new OO.ui.ButtonWidget( {
var formatButton = new OO.ui.ButtonWidget( {
label: 'Copy output',
label: 'Format',
flags: [ 'progressive' ]
flags: [ 'primary', 'progressive' ]
} );
} );


var statusLabel = new OO.ui.LabelWidget( {
var copyButton = new OO.ui.ButtonWidget( {
label: ''
label: 'Copy'
} );
} );
 
console.log('[PatchFormatter] widgets created');


var buttonRow = new OO.ui.HorizontalLayout( {
var status = new OO.ui.LabelWidget();
items: [ formatButton, copyButton, statusLabel ]
} );


var fieldset = new OO.ui.FieldsetLayout();
var layout = new OO.ui.FieldsetLayout();
fieldset.$element.append( buttonRow.$element );


app.appendChild( fieldset.$element[ 0 ] );
layout.$element.append(
inputWidget.$element,
formatButton.$element,
copyButton.$element,
status.$element,
outputWidget.$element
);


console.log('[PatchFormatter] UI mounted');
app.appendChild( layout.$element[ 0 ] );


formatButton.on( 'click', function () {
console.log('[PatchFormatter] UI READY');
console.log('[PatchFormatter] format clicked');


formatButton.setDisabled( true );
formatButton.on( 'click', function () {
statusLabel.setLabel( 'Loading wiki data...' );
console.log('[PatchFormatter] FORMAT CLICK');


Promise.all( [
status.setLabel( 'Loading...' );
getWikiData( 'get_released_heroes_list' ),
getWikiData( 'get_all_released_item_names' ),
getWikiData( 'get_all_released_abilities_list' )
] ).then( function ( lists ) {


console.log('[PatchFormatter] lists loaded');
Promise.all( [
getWikiData( 'get_released_heroes_list' ),
getWikiData( 'get_all_released_item_names' ),
getWikiData( 'get_all_released_abilities_list' )
] ).then( function ( lists ) {


var heroes = lists[ 0 ];
console.log('[PatchFormatter] DATA READY');
var items = lists[ 1 ];
var abilities = lists[ 2 ];


var entries = parseEntries( inputWidget.getValue() );
var heroes = lists[ 0 ];
var items = lists[ 1 ];
var abilities = lists[ 2 ];


var result = buildOutput( entries, heroes, abilities, items, GAME_MODE_SECTIONS );
var entries = parseEntries( inputWidget.getValue() );


outputWidget.setValue( result );
var result = buildOutput( entries, heroes, abilities, items, GAME_MODE_SECTIONS );


statusLabel.setLabel( 'Done' );
outputWidget.setValue( result );


} ).catch( function ( err ) {
status.setLabel( 'Done: ' + entries.length );
console.error('[PatchFormatter] ERROR:', err);
} ).catch( function ( e ) {
statusLabel.setLabel( 'Error: ' + err );
console.error('[PatchFormatter] ERROR', e);
} ).then( function () {
status.setLabel( 'Error' );
formatButton.setDisabled( false );
} );
} );
} );
} );


copyButton.on( 'click', function () {
copyButton.on( 'click', function () {
console.log('[PatchFormatter] copy clicked');
console.log('[PatchFormatter] COPY CLICK');


navigator.clipboard.writeText(
navigator.clipboard.writeText(
outputWidget.getValue()
outputWidget.getValue()
).then( function () {
);
statusLabel.setLabel( 'Copied' );
} );
} );


} catch ( e ) {
status.setLabel( 'Copied' );
console.error('[PatchFormatter] INIT CRASH:', e);
} );
}
}
}
// ---- BOOT -----------------------------------------------------------
console.log('[PatchFormatter] loader start');


mw.loader.using( [
mw.loader.using( [
Line 316: Line 266:
'mediawiki.util'
'mediawiki.util'
] ).then( function () {
] ).then( function () {
console.log('[PatchFormatter] loader ready');
 
$( init );
console.log('[PatchFormatter] loader OK');
 
init();
 
} ).catch( function ( e ) {
console.error('[PatchFormatter] LOADER FAILED', e);
} );
} );