MediaWiki:Gadget-toolbar.js
Vai alla navigazione
Vai alla ricerca
Nota: Dopo aver salvato le preferenze, perché i cambi abbiano effetto, devi bypassare la cache del tuo browser. Mozilla / Firefox / Safari: tieni premuto Shift mentre clicchi Reload, o premi Ctrl-Shift-R (Cmd-Shift-R per Apple Mac); Google Chrome: premi Ctrl o Shift mentre clicchi F5; IE: premi Ctrl mentre clicchi Refresh, o premi Ctrl-F5; Konqueror:: clicca semplicemente il pulsante di Reload, o premi F5; se usi Opera devi cancellare completamente la chache nel menu Tools→Preferences.
/** * Gadget-toolbar.js * Permette di aggiungere ulteriori pulsanti alla toolbar di modifica * e di selezionarli tramite una finestra di opzioni. * * @author [[it:User:Rotpunkt]] */ /*jshint evil: true */ /*global mediaWiki, jQuery, gadgetToolbarButtons */ /* <nowiki> */ ( function ( mw, $ ) { 'use strict'; var sign = ' --~~~~', configVersion = 1, optionname = 'userjs-gadget-toolbar', iconOptions = '//upload.wikimedia.org/wikipedia/commons/1/1e/Button_ns-basics.png', hotkeys, userConfig, groups = { formattazione: { label: 'Formattazione' }, avvisivoci: { label: 'Avvisi voci' }, messaggiutente: { label: 'Messaggi utente' }, altro: { label: 'Altro' } }; // =========================== // Funzioni di utilità // =========================== function padleft0( num ) { return ( num < 10 ? '0' : '' ) + num; } function makeTimestamp( date ) { return date.getUTCFullYear() + '-' + padleft0( date.getUTCMonth() + 1 ) + '-' + padleft0( date.getUTCDate() ) + 'T' + padleft0( date.getUTCHours() ) + ':' + padleft0( date.getUTCMinutes() ) + ':00Z'; } function endsWith( str, suffix ) { return str.length >= suffix.length && str.indexOf( suffix, str.length - suffix.length ) !== -1; } function readUserConfig() { var config, ret = { buttons: [], version: configVersion }; if ( mw.user.options.exists( optionname ) ) { config = JSON.parse( mw.user.options.get( optionname ) ); if ( config.version === configVersion ) { ret = config; } } return ret; } function writeUserConfig( config ) { new mw.Api().postWithToken( 'csrf', { action: 'options', optionname: optionname, optionvalue: config, } ) .done( function ( data ) { var msg; if ( data && data.options === 'success' ) { mw.notify( 'La configurazione dei pulsanti è stata aggiornata.' ); } else { msg = data && data.error ? ': ' + data.error.code + ' ' + data.error.info : ''; mw.notify( 'Errore nell\'aggiornare la configurazione dei pulsanti ' + msg ); } } ); } function readUserButtons( readHandler ) { var title = 'User:' + mw.config.get( 'wgUserName' ) + '/toolbarbuttons.js'; $.ajax( { url: mw.config.get( 'wgScript' ), data: { title: title, action: 'raw' }, dataType: 'text' } ) .done( function ( data ) { var buttons = []; try { // non si può usare JSON perché i pulsanti contengono anche funzioni eval( data ); if ( window.gadgetToolbarUserButtons !== undefined && $.isPlainObject( window.gadgetToolbarUserButtons ) ) { buttons = window.gadgetToolbarUserButtons; } } catch ( e ) { mw.notify( 'La pagina di configurazione ' + title + ' contiene errori.' ); } finally { readHandler( buttons ); } } ) .fail( function ( jqXHR, textStatus, errorThrown ) { readHandler( [] ); } ); } function buildDescr( button ) { var ret = ''; if ( button.text ) { ret = $( '<div>' ).text( 'Inserisce il testo ' + ( button.text.pre || '' ) + ' ' + ( button.text.post || '' ) + ' nella pagina.' ).html(); } else if ( button.template ) { var $a = $( '<a>' ) .attr( 'href', '/wiki/Template:' + button.template.name ) .attr( 'target', '_blank' ) .attr( 'tabindex', '-1' ) .css( 'color', '#2e45ad' ) .text( button.template.name ); ret = [ 'Inserisce il template {{', $a, '}} nella pagina.']; } return ret; } /** * Aggiunge l'autocompletamento con gli ultimi contributi, non più vecchi di un'ora. */ function addAutocompleteContribs( inputEl ) { var dateEnd = new Date(); dateEnd.setHours( dateEnd.getHours() - 1 ); new mw.Api().get( { action: 'query', list: 'usercontribs', ucuser: mw.config.get( 'wgUserName' ), uclimit: '10', ucend: makeTimestamp( dateEnd ), ucdir: 'older', ucprop: 'title', } ) .done( function ( data ) { var contribs = []; $.each( data.query.usercontribs, function( i, usercontrib ) { if ( $.inArray( usercontrib.title, contribs ) === -1 ) { contribs.push( usercontrib.title ); } }); inputEl.autocomplete( { source: contribs } ); } ); } /** * Aggiunge l'autocompletamento per i nomi utente. */ function addAutocompleteUsers( inputEl ) { inputEl.autocomplete( { source: function( request, response ) { new mw.Api().get( { action: 'query', list: 'allusers', aulimit: '10', auprefix: request.term, } ) .done( function ( data ) { var users = []; $.each( data.query.allusers, function( i, user ) { users.push( user.name ); }); response( users ); } ); } } ); } // ======================= // Finestra opzioni // ======================= function buildRow( id, button ) { var $tr = $( '<tr>' ); $( '<td>' ).html( '<img src="' + button.icon + '"/> ' + id ).appendTo( $tr ); $( '<td>' ).append( button.descr || buildDescr( button ) ).appendTo( $tr ); $( '<td>' ).append( $( '<input>' ).data( 'id', id ) .attr( 'type', 'checkbox' ).attr( 'checked', $.inArray( id, userConfig.buttons ) > -1 ) ).appendTo( $tr ); return $tr; } function buildTable() { var $table, $thead, $tr; $table = $( '<table>' ) .attr( 'border', '0' ) .attr( 'cellpadding', '0' ) .attr( 'cellspacing', '0' ) .attr( 'width', '100%' ); $thead = $( '<thead>' ).appendTo( $table ); $tr = $( '<tr>' ).appendTo( $thead ); $( '<th>' ).text( 'Pulsante' ).appendTo( $tr ); $( '<th>' ).text( 'Descrizione' ).appendTo( $tr ); $( '<th>' ).text( '' ).appendTo( $tr ); $( '<tbody>' ).appendTo( $table ); return $table; } /** * Visualizza la finestra delle opzioni per selezionare i pulsanti. */ function showConfigDialog() { var $div, $ul; if ( $( '#gtb-dialog-options' ).hasClass( 'ui-dialog-content' ) ) { $( '#gtb-dialog-options' ).dialog( 'open' ); return; } $div = $( '<div>' ).attr( 'id', 'tabs' ); $ul = $( '<ul>' ).appendTo( $div ); $.each( groups, function ( key, group ) { var $a = $( '<a>' ).attr( 'href', '#tabs-' + key ).text( group.label ); $( '<li/>' ).append( $a ).appendTo( $ul ); group.table = buildTable(); } ); $.each( gadgetToolbarButtons, function ( id, button ) { groups[button.group].table.find( 'tbody' ).append( buildRow( id, button ) ); } ); $.each( groups, function ( key, group ) { $( '<div>' ).addClass( 'gtb-tablecontainer' ).attr( 'id', 'tabs-' + key ) .append( group.table ) .appendTo( $ul ); } ); $( '#gtb-dialog-options' ).html( $div ).tabs(); // visualizza il dialog $( '#gtb-dialog-options' ).dialog( { title: '<img src="' + iconOptions + '"/> Configurazione pulsanti toolbar', width: 700, resizable: false, modal: true, open: function( event, ui ) { $( '#gtb-dialog-options' ).tabs( 'option', 'active', 0 ); }, buttons: { 'Salva': function () { var newConfig, newConfigJSON; // genera la nuova configurazione newConfig = $( '#gtb-dialog-options' ).find( 'tr:has( td )' ).map( function () { var $input = $( this ).find( 'input' ).eq( 0 ); return $input.prop( 'checked' ) ? [ $input.data( 'id' ) ] : null; } ).get(); newConfig = { buttons: newConfig, version: configVersion }; newConfigJSON = JSON.stringify( newConfig ); // se necessario scrive la configurazione if ( newConfigJSON === JSON.stringify( userConfig ) ) { mw.notify( 'I pulsanti non sono stati modificati.' ); } else { writeUserConfig( newConfigJSON ); userConfig = newConfig; addButtons(); } $( this ).dialog( 'close' ); }, 'Annulla': function () { $( this ).dialog( 'close' ); } } } ); } // ===================================== // Finestra parametri per template // ===================================== function buildInputEl( id, val ) { var inputEl; switch ( val.type ) { case 'textbox': inputEl = $( '<input/>' ).attr( 'id', id ).attr( 'type', 'text' ).attr( 'size', 50 ); if ( val.autocomplete ) { mw.loader.using( 'jquery.ui' ) .done( function () { switch ( val.autocomplete ) { case 'contribs': addAutocompleteContribs( inputEl ); break; case 'users': addAutocompleteUsers( inputEl ); break; // supporto per eventuali altri tipi di autocompletamento default: break; } } ) .fail( function () { console.error( 'Impossibile avviare l\'accessorio "toolbar".' ); } ); } break; case 'combobox': inputEl = $( '<select>' ).attr( 'id', id ).css( 'width', '200px' ); $.each( val.value, function ( i, option ) { $( '<option>' ).html( option ).appendTo( inputEl ); } ); break; case 'checkbox': inputEl = $( '<input/>' ).attr( 'id', id ).attr( 'type', 'checkbox' ).attr( 'checked', val.value ); break; default: break; } return inputEl; } /** * Visualizza la finestra di dialogo per richiedere i parametri dei template. */ function showTemplateDialog( button ) { var $dialog, $fieldset, template = button.template; // crea l'html del dialog $dialog = $( '#gtb-dialog-template' ).html( buildDescr( button ) ); $fieldset = $( '<fieldset>' ).css( 'border-color', 'gray' ).appendTo( $dialog ); $( '<legend>' ).text( 'Parametri' ).appendTo( $fieldset ); $.each( template.params, function ( id, val ) { var inputEl = buildInputEl( id, val ); $( '<label>' ).attr( 'for', id ).text( val.label + ':' ).appendTo( $fieldset ); $fieldset.append( '<br/>', inputEl, '<br/>' ); } ); // visualizza il dialog $dialog.dialog( { title: '<img src="' + button.icon + '"/> ' + button.label, width: 500, resizable: false, modal: false, buttons: { 'Inserisci': function () { var params = {}; $dialog.find( 'input:text,select' ).each( function () { params[$( this ).attr( 'id' )] = $.trim( $( this ).val() ); } ); $dialog.find( 'input:checkbox' ).each( function () { params[$( this ).attr( 'id' )] = $( this ).prop( 'checked' ); } ); dumpTemplate( template, params ); setSummary( button ); $( this ).dialog( 'close' ); }, 'Annulla': function () { $( this ).dialog( 'close' ); } } } ); } // ===================================== // Inserimento e gestione pulsanti // ===================================== /** * Inserisce il template nell'area di testo. */ function dumpTemplate( template, params ) { var text, templateParams; if ( template.format ) { templateParams = template.format( params || {} ); } text = ( template.noinclude ? '<noinclude>' : '' ) + '{{' + ( template.subst ? 'subst:' : '' ) + template.name + ( templateParams || '' ) + '}}' + ( template.sign ? sign : '' ) + ( template.noinclude ? '</noinclude>' : '' ) + ( template.extratext ? template.extratext : '' ); if ( template.position === 'top' ) { $( '#wpTextbox1' ).textSelection( 'setSelection', { start: 0, end: 0 } ); $( '#wpTextbox1' ).textSelection( 'encapsulateSelection', { post: text + '\n' } ); } else if ( template.position === 'bottom' ) { $( '#wpTextbox1' ).select().val( $( '#wpTextbox1' ).val() + '\n' + text ); } else { $( '#wpTextbox1' ).textSelection( 'encapsulateSelection', { pre: text } ); } } /** * Valorizza il campo oggetto della modifica. */ function setSummary( button ) { var text, replace = false; if ( button.summary !== undefined ) { text = button.summary; } else if ( button.template ) { if ( $( '#wpMinoredit' ).length ) { text = '+' + button.template.name; } else if ( button.group === 'messaggiutente' ) { text = 'Avviso'; replace = true; } } if ( text ) { $( '#wpSummary' ).val( function ( i, prevText ) { return replace ? text : prevText + ( prevText.length > 0 ? ' ' : '' ) + text; } ); } } /** * Gestore del click sui pulsanti della toolbar (avanzata e classica). */ function clickHandler( button ) { var dialog = false; if ( button.text ) { $( '#wpTextbox1' ).textSelection( 'encapsulateSelection', button.text ); } else if ( button.execute ) { button.execute(); } else if ( button.template ) { if ( button.template.params ) { dialog = true; showTemplateDialog( button ); // setSummary avviene alla conferma del dialog } else { dumpTemplate( button.template ); } } if ( !dialog ) { setSummary( button ); } } /** * Ritorna true se il namespace è corretto per il pulsante. */ function rightNs( button ) { var ret = true; if ( button.ns !== undefined ) { if ( typeof button.ns === 'function' ) { ret = button.ns(); } else if ( $.isArray( button.ns ) ) { ret = $.inArray( mw.config.get( 'wgNamespaceNumber' ), button.ns ) !== -1; } } return ret; } /** * Inizializza il pulsante per l'utilizzo nella toolbar. */ function initButton( id, button ) { button.label = button.tooltip = id; if ( button.hotkey ) { button.hotkey = button.hotkey.toUpperCase(); button.tooltip += ' [Alt+' + button.hotkey + ']'; hotkeys[button.hotkey] = button; } } /** * Aggiunge i pulsanti alla toolbar avanzata (wikiEditor). */ function addButtonsAdvancedToolbar() { $.each( groups, function ( key, buttons ) { groups[key].tools = {}; } ); $.each( userConfig.buttons, function( i, id ) { var button = gadgetToolbarButtons[id]; if ( button && rightNs( button ) ) { initButton( id, button ); groups[button.group].tools[id] = { label: button.tooltip, type: 'button', icon: button.icon, action: { type: 'callback', execute: function ( context ) { clickHandler( button ); } } }; } } ); var tb = { sections: { altro: { type: 'toolbar', label: 'Altri pulsanti', groups: { opzioni: { label: 'Opzioni', tools: { opzioni: { type: 'button', label: 'Opzioni', icon: iconOptions, action: { type: 'callback', execute: function ( context ) { showConfigDialog(); } } } } } } } } }; $.each( groups, function ( key, group ) { tb.sections.altro.groups[key] = { label: group.label, tools: group.tools }; } ); $( '#wpTextbox1' ).wikiEditor( 'addToToolbar', tb ); } /** * Aggiunge i pulsanti alla toolbar "classica". */ function addButtonsClassicToolbar() { $.each( userConfig.buttons, function( i, id ) { var button = gadgetToolbarButtons[id]; if ( button && rightNs( button ) ) { initButton( id, button ); $( '<img/>' ) .attr( 'src', button.icon ) .attr( 'title', button.tooltip ) .css( 'cursor', 'pointer' ) .addClass( 'gtb-button' ) .click( function () { clickHandler( button ); } ) .appendTo( '#toolbar' ); } } ); } function addButtons( userButtons ) { hotkeys = {}; // unisce userButtons a gadgetToolbarButtons if ( userButtons ) { $.extend( gadgetToolbarButtons, userButtons ); } // aggiunge i pulsanti alla toolbar if ( mw.user.options.get( 'usebetatoolbar' ) ) { mw.loader.using( [ 'ext.wikiEditor' ], function () { // rimozione pulsanti precedenti if ( !userButtons ) { $( '#wpTextbox1' ).wikiEditor( 'removeFromToolbar', { 'section': 'altro' } ); } addButtonsAdvancedToolbar(); // secondo tentativo per [[phab:T30563]] $( '#wpTextbox1' ).on( 'wikiEditor-toolbar-doneInitialSections', function () { if ( !$( '#wikiEditor-ui-toolbar .tab-altro' ).length ) { addButtonsAdvancedToolbar(); } } ); } ); } else if ( mw.user.options.get( 'gadget-ClassicToolbar' ) ) { mw.loader.using( 'ext.gadget.ClassicToolbar', function () { if ( userButtons ) { mw.toolbar.addButton( { imageFile: iconOptions, speedTip: 'Opzioni', onClick: showConfigDialog } ); } else { // rimozione pulsanti precedenti $( '.gtb-button' ).remove(); } addButtonsClassicToolbar(); }); } } /** * Installa il gestore per gli hotkeys */ function installHotkeyHandler() { $( '#wpTextbox1' ).keypress( function ( event ) { var button, help = ''; if ( event.altKey && !event.shiftKey && !event.ctrlKey && !event.metaKey ) { if ( event.which === 72 || event.which === 104 ) { event.preventDefault(); $.each( hotkeys, function ( hotkey, button ) { help += button.label + ' = Alt+' + hotkey + '\n'; } ); alert( 'Hotkey attivi:\n' + help ); } else { button = hotkeys[String.fromCharCode( event.which ).toUpperCase()]; if ( button ) { event.preventDefault(); clickHandler( button ); } } } } ); } /** * Verifica se la pagina userà codeEditor */ function needCodeEditor() { var title = mw.config.get( 'wgTitle' ), ns = mw.config.get( 'wgNamespaceNumber' ); return endsWith( title, '.js' ) || ( ns == 828 && !endsWith( title, '/man' ) ); } $( function () { if ( !needCodeEditor() ) { mw.loader.using( [ 'jquery.ui'], function () { // lettura configurazione userConfig = readUserConfig(); // setup dialog $( '<div>' ).attr( 'id', 'gtb-dialog-options' ).appendTo( 'body' ); $( '<div>' ).attr( 'id', 'gtb-dialog-template' ).appendTo( 'body' ); // installa handler hotkeys installHotkeyHandler(); // aggiunge i pulsanti readUserButtons( function( userButtons ) { addButtons( userButtons ); } ); } ); } } ); }( mediaWiki, jQuery ) ); /* </nowiki> */