(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
- Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
$.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(); } } );