Benutzer:Nw520/vCaTA.js
(Weitergeleitet von Benutzer:Naseweis520/vCaTA.js)
Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.
- Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
- Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
- Internet Explorer/Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
- Opera: Strg+F5
$.when( mw.loader.using( 'mediawiki.util' ), $.ready ).then( function () {
let dialog = null;
function getTypes() {
return new Promise( function ( resolve, reject ) {
Promise.all( [
getTypesFromWikivoyage(),
getGroupsFromWikivoyage()
] ).then( function ( [ types, groups ] ) {
resolve( Object.keys( types ).sort( function ( a, b ) {
return types[ a ].label.localeCompare( types[ b ].label );
} ).map( function ( typeName ) {
const type = types[ typeName ];
return {
color: groups[ type.group ].color || null,
data: typeName,
group: type.group,
groupLabel: groups[ type.group ].label || null,
label: type.label || typeName
};
} ) );
} ).catch( function ( e ) {
reject( e );
} );
} );
}
function getGroupsFromWikivoyage() {
return new Promise( function ( resolve, reject ) {
$.ajax( {
data: {
title: 'Modul:Marker utilities/Groups',
action: 'raw',
ctype: 'text/plain'
},
method: 'GET',
url: mw.util.wikiScript( '' )
} ).done( function ( e ) {
// FIXME: Use same approach as subtype/type
const lineRegexp = /[ \t]+(([a-zA-Z0-9 _]+?)|'([a-zA-Z0-9 _]+)'|"([a-zA-Z0-9 _]+)"|\['([a-zA-Z0-9 _]+)'\]|\["([a-zA-Z0-9 _]+)"\]) *= *{(.+?)}/g;
let match;
const jsonLines = [];
do {
match = lineRegexp.exec( e );
if ( match ) {
const parameterName = match[ 2 ] || match[ 3 ] || match[ 4 ] || match[ 5 ] || match[ 6 ];
let definition = match[ 7 ];
definition = definition.replace( /(^|,) ([^ ]+) = /g, '$1"$2":' );
jsonLines.push( `"${parameterName.replace( /_/g, ' ' )}": {${definition}}` );
}
} while ( match );
resolve( JSON.parse( `{${jsonLines.join( ',' )}}` ) );
} ).fail( function ( e ) {
reject( e );
} );
} );
}
function getTypesFromWikivoyage() {
return new Promise( function ( resolve, reject ) {
$.ajax( {
data: {
title: 'Modul:Marker utilities/Types',
action: 'raw',
ctype: 'text/plain'
},
method: 'GET',
url: mw.util.wikiScript( '' )
} ).done(
/**
* @param {string} e
*/
function ( e ) {
const lines = e.split( '\n' );
const declarationRegex = /(?:\["(?<nameBracketed>[^"]+)"\]|(?<nameNonBracketed>[\w]+))[\s\t]*=[\s\t]*\{(?<body>[^\n]+)\}/; // Extracts type name and "body" of declaration. We're assuming that there's at most one declaration per line and that each declaration takes up exactly one line
const groupRegex = /group[\s\t]*=[\s\t]*"(?<group>[^"]+)"/; // Extracts group, we're using several regexes to prevent requiring a specific order
const labelRegex = /label[\s\t]*=[\s\t]*"(?<label>[^"]+)"/; // Extracts label
/**
* @type {Object.<string, { group: string, label: string }>}
*/
const groups = {};
lines.forEach( function ( line ) {
const declarationEval = declarationRegex.exec( line );
if ( declarationEval ) {
const name = declarationEval.groups.nameBracketed || declarationEval.groups.nameNonBracketed;
const body = declarationEval.groups.body;
// Group
const groupEval = groupRegex.exec( body );
const group = groupEval ? groupEval.groups.group : null;
const labelEval = labelRegex.exec( body );
const label = labelEval ? labelEval.groups.label : null;
if ( group !== null && label !== null ) {
groups[ name ] = {
group: group,
label: label
};
}
}
} );
resolve( groups );
} ).fail( function ( e ) {
reject( e );
} );
} );
}
function getTypesTable() {
return new Promise( function ( resolve, reject ) {
getTypes().then( function ( types ) {
let out = `<table>
<thead>
<th>Typ</th>
<th>Bezeichnung</th>
<th>Gruppe</th>
<th>Gruppenbezeichnung</th>
</thead>`;
console.log( types );
$( types ).each( function ( _i, type ) {
out += `
<tr class="vcata-item" style="${type.color !== null ? `background-color:${type.color};color:#fff` : ''}">
<td class="vcata-item-type"><input class="vcata-pseudo-input" type="text" value="${type.data.replace( /_/g, ' ' )}" readonly /></td>
<td class="vcata-item-label">${type.label}</td>
<td class="vcata-item-group">${type.group || '—'}</td>
<td class="vcata-item-group-label">${type.groupLabel || '—'}</td>
</tr>`;
} );
out += '</table>';
resolve( out );
} ).catch( function ( e ) {
reject( e );
} );
} );
}
function search( q ) {
q = q.toLowerCase();
if ( q === '' ) {
dialog.getContent().find( '.vcata-item' ).each( function ( i, row ) {
$( row ).show();
} );
} else {
dialog.getContent().find( '.vcata-item' ).each( function ( i, row ) {
const $i = $( row );
if ( $i.find( '.vcata-item-type input' ).val().toLowerCase().includes( q ) || $i.find( '.vcata-item-label' ).text().toLowerCase().includes( q ) || $i.find( '.vcata-item-group' ).text().toLowerCase().includes( q ) || $i.find( '.vcata-item-group-label' ).text().toLowerCase().includes( q ) ) {
$i.show();
} else {
$i.hide();
}
} );
}
}
function setup() {
getTypesTable().then( function ( typesTable ) {
mw.util.addCSS(`.vcata-abbr {
color: #006699;
}
.vcata-pseudo-input {
background: transparent;
border: none;
color: inherit;
font: inherit;
padding: unset;
width: auto;
}
#dialog-vcata table {
border-collapse: collapse;
min-width: 100%;
}
#dialog-vcata td, #dialog-vcata th {
border-left: 1px solid #888;
border-right: 1px solid #888;
padding: .2em .1em;
}
#dialog-vcata th {
border-bottom: 1px solid #888;
}
#dialog-vcata .nw520-dialog-inner {
height: 45vh;
width: 50vw;
}
` );
dialog = new nw520.CornerDialog( 'vcata', `<input placeholder="Suche" type="text" style="width:100%" />
<div style="margin-top:1em">
${typesTable}
</div>`, '<span class="vcata-abbr">vC</span>ard-<span class="vcata-abbr">T</span>ypen-<span class="vcata-abbr">A</span>ssistent', 'se', true );
dialog.getContent().find( 'input[placeholder=Suche][type=text]' ).focus();
dialog.getContent().find( 'input[placeholder=Suche][type=text]' ).keyup( function ( e ) {
e.preventDefault();
search( $( this ).val() );
} );
dialog.getContent().find( '.vcata-pseudo-input' ).click( function ( e ) {
e.preventDefault();
$( this ).trigger( 'select' );
try {
document.execCommand( 'copy' );
mw.notify( $( '<span>Typ in Zwischenablage kopiert. Einfügen mit <kbd>STRG</kbd>+<kbd>V</kbd></span>' ), {
tag: 'vcata'
} );
} catch ( err ) {
mw.notify( $( '<span>Fehler beim Kopieren in die Zwischenablage. Bitte <kbd>STRG</kbd>+<kbd>C</kbd> drücken</span>' ), {
tag: 'vcata'
} );
}
} );
} ).catch( function ( e ) {
console.warn( e );
mw.notify( 'Fehler beim Laden von vCaTA', {
tag: 'vcata',
title: 'vCaTA',
type: 'error'
} );
} );
}
function addPortlet() {
function main() {
if ( dialog === null || !dialog.isAttached() ) {
mw.notify( 'vCaTA wird vorbereitet. Augenblick bitte...', {
tag: 'vcata',
title: 'vCaTA'
} );
setup();
} else {
dialog.kill();
}
}
const portlet = mw.util.addPortletLink( 'p-tb', '#vcata', 'vCard-Typen', 'p-vcata', 'vCard-Typen-Assistenten aufrufen' );
$( portlet ).on( 'click', function ( e ) {
e.preventDefault();
if ( window.nw520?.CornerDialog ?? null === null ) {
mw.loader.getScript( '//de.wikivoyage.org/w/index.php?title=User:Nw520/Util.js&action=raw&ctype=text/javascript' ).then( function () {
main();
}, function ( e ) {
mw.log.error( e.message );
} );
} else {
main();
}
} );
}
if ( mw.config.get( 'wgNamespaceNumber' ) === 0 ) {
addPortlet();
}
} );