MediaWiki:Gadget-move-to-sandbox.js
Z Wiki.Pnikuczanie
Uwaga: aby zobaczyć zmiany po zapisaniu, może zajść potrzeba wyczyszczenia pamięci podręcznej przeglądarki.
- Firefox / Safari: Przytrzymaj Shift podczas klikania Odśwież bieżącą stronę, lub naciśnij klawisze Ctrl+F5 lub Ctrl+R (⌘-R na komputerze Mac)
- Google Chrome: Naciśnij Ctrl-Shift-R (⌘-Shift-R na komputerze Mac)
- Internet Explorer: Przytrzymaj Ctrl jednocześnie klikając Odśwież lub naciśnij klawisze Ctrl+F5
- Opera: Wyczyść pamięć podręczną w Narzędzia → Preferencje
/* Translatable strings */ mw.messages.set( { 'mtsg-move-link': 'Przenieś do brudnopisu', 'mtsg-user-talk-link': 'dyskusja', 'mtsg-user-contribs-link': 'wkład', 'mtsg-dialog-title': 'Przenieś do brudnopisu', 'mtsg-author-label': 'Autor artykułu:', 'mtsg-author-pending': 'sprawdzanie', 'mtsg-destination-label': 'Docelowa nazwa artykułu:', 'mtsg-reason-label': 'Uzasadnienie:', 'mtsg-default-reason': 'artykuł należy dopracować', 'mtsg-message-label': 'Wiadomość dla użytkownika:', 'mtsg-error-label': 'Błąd:', 'mtsg-jobs-label': 'Wykonywane zadania:', 'mtsg-link-placeholder': '$link', 'mtsg-default-message': 'Witaj. Twój artykuł nie nadaje się jeszcze do publikacji w Wikipedii, dlatego został przeniesiony do twojego brudnopisu [[$link]], gdzie możesz nad nim popracować. Należy w nim poprawić:\n* ...\n* ...\n* ...\nPo skończeniu użyj [[Pomoc:Zmiana nazwy strony|zakładki przenieś]], aby opublikować go ponownie. Jeżeli nie możesz przenieść samodzielnie (należy mieć konto zarejestrowane od co najmniej 4 dni oraz 10 edycji), zwróć się do dowolnego bardziej zaawansowanego wikipedysty lub do [[WP:PdA|administratorów]]. Pozdrawiam, ~~' + '~~', 'mtsg-confirm-button': 'Przenieś', 'mtsg-cancel-button': 'Anuluj', 'mtsg-move-page-job': 'Przenoszenie strony', 'mtsg-insert-speedy-job': 'Wstawianie szablonu ek do przekierowania', 'mtsg-send-message-job': 'Wysyłanie wiadomości autorowi', 'mtsg-redirect-job': 'Przejście na stronę po przenosinach', 'mtsg-speedy-template': '{' + '{ek|1=strona została przeniesiona do [[$1|brudnopisu autora]]}}\n', 'mtsg-speedy-summary': 'Oznaczenie przekierowania po przenosinach do skasowania', 'mtsg-error-nonexistent-page': 'Artykuł nie istnieje.', 'mtsg-error-unknown-author': 'Nie można określić autora artykułu.', 'mtsg-error-anonymous-author': 'Anonimowy użytkownik nie posiada brudnopisu.', 'mtsg-error-no-move-permission': 'Nie masz uprawnień do przenoszenia stron.', 'mtsg-error-empty-destination-name': 'Nazwa strony docelowej nie może być pusta.', 'mtsg-error-move-message-not-changed': 'Uzupełnij wiadomość do użytkownika.', 'mtsg-error-caught-exception': 'Wystąpił błąd podczas działania gadżetu. Przekaż następujące informacje autorowi:', 'mtsg-error-api-error': 'Operacja się nie powiodła' // FIXME } ); window.moveToSandboxGadget = { /** Version of the gadget */ version: 7, /* Gadget variables */ canSuppressRedirect: false, moveToken: null, moveSource: mw.config.get( 'wgPageName' ).replace( /_/g, ' ' ), moveDestination: null, moveReason: null, author: null, jobQueue: [], currentJob: null, debug: false, /** Gadget entry point */ init: function() { if ( mw.config.get( 'wgNamespaceNumber' ) != 0 || mw.config.get( 'wgArticleId' ) == 0 ) { return; } var that = this; jQuery( document ).ready( function() { that.addMenu(); } ); }, /** Adds menu for triggering dialog box */ addMenu: function() { var that = this; mw.util.addPortletLink( 'p-tb', '', mw.msg( 'mtsg-move-link' ), 'move-to-sandbox' ); jQuery( '#move-to-sandbox a' ).click( function( event ) { that.open(); event.preventDefault(); } ).attr( 'href', '#' ); }, /** Shows dialog box */ open: function() { var dialog = jQuery('<div></div>').append( '<form>' + '<fieldset id="mtsg-fieldset">' + '<label for="mtsg-author">' + mw.msg( 'mtsg-author-label' ) + '</label>' + '<span id="mtsg-author" class="text ui-widget-content ui-corner-all">' + mw.msg( 'mtsg-author-pending' ) + '</span>' + '<label for="mtsg-destination">' + mw.msg( 'mtsg-destination-label' ) + '</label>' + '<input type="text" name="mtsg-destination" id="mtsg-destination" class="text ui-widget-content ui-corner-all" disabled="disabled"/>' + '<label for="mtsg-reason">' + mw.msg( 'mtsg-reason-label' ) + '</label>' + '<input type="text" name="mtsg-reason" id="mtsg-reason" class="text ui-widget-content ui-corner-all" value="' + mw.msg( 'mtsg-default-reason' ) + '"/>' + '<label for="mtsg-message">' + mw.msg( 'mtsg-message-label' ) + '</label>' + '<textarea rows="3" name="mtsg-message" id="mtsg-message" class="text ui-widget-content ui-corner-all mtsg-message-full">' + mw.message( 'mtsg-default-message' ).plain() + '</textarea>' + '</fieldset>' + '</form>' ); var buttons = {}; buttons[mw.msg( 'mtsg-cancel-button' )] = function() { jQuery( this ).dialog( 'close' ); }; jQuery( dialog ).dialog( { width: 600, height: 600, modal: true, resizable: false, draggable: true, closeOnEscape: true, dialogClass: 'moveToSandboxDialog', title: mw.msg( 'mtsg-dialog-title' ), close: function() { jQuery( this ).dialog( 'destroy' ); jQuery( this ).remove(); }, buttons: buttons } ); var that = this; var request = { action: 'query', prop: 'revisions|info', rvprop: 'user|userid', rvdir: 'newer', meta: 'userinfo', uiprop: 'rights', titles: mw.config.get( 'wgPageName' ), rvlimit: 1, intoken: 'move' }; this.callApi( request, function( data ) { var page = data.query.pages[mw.config.get( 'wgArticleId' )]; if ( !page ) { that.showError( mw.msg( 'mtsg-error-nonexistent-page' ) ); return; } var revision = page.revisions[0]; if ( !revision || !revision.user ) { that.showError( mw.msg( 'mtsg-error-unknown-author' ) ); return; } jQuery('#mtsg-author').empty().append( jQuery('<a></a>').attr('href', mw.util.wikiGetlink('User:' + revision.user)).append(document.createTextNode(revision.user)), ' (', jQuery('<a>' + mw.msg( 'mtsg-user-talk-link' ) + '</a>').attr('href', mw.util.wikiGetlink('User_talk:' + revision.user)), ', ', jQuery('<a>' + mw.msg( 'mtsg-user-contribs-link' ) + '</a>').attr('href', mw.util.wikiGetlink('Special:Contributions/' + revision.user)), ')' ); if ( !revision.userid ) { that.showError( mw.msg( 'mtsg-error-anonymous-author' ) ); return; } jQuery( '#mtsg-destination' ).attr( 'disabled', false ).val( mw.config.get( 'wgFormattedNamespaces' )[2] + ':' + revision.user + '/' + that.moveSource ); var userRights = data.query.userinfo.rights; if ( jQuery.inArray( 'move', userRights ) == -1 ) { that.showError( mw.msg( 'mtsg-error-no-move-permission' ) ); return; } that.canSuppressRedirect = jQuery.inArray( 'suppressredirect', userRights ) > -1; that.moveToken = page.movetoken; that.author = revision.user; // Add confirm button buttons[mw.msg( 'mtsg-confirm-button' )] = function() { that.confirm( dialog ) }; jQuery( dialog ).dialog( "option", "buttons", buttons ); } ); }, /** Shows error on the dialog */ showError: function( message ) { // Shrink the message field jQuery( '#mtsg-message' ).removeClass( 'mtsg-message-full' ); jQuery( '#mtsg-fieldset' ).append( '<label for="mtsg-error">' + mw.msg( 'mtsg-error-label' ) + '</label>' ); jQuery( '#mtsg-fieldset' ).append( '<p id="mtsg-error">' + message + '</p>' ); this.updateCurrentStatus( 'error' ); }, updateCurrentStatus: function( status ) { if ( !this.currentJob ) { return; } if ( status == 'done' ) { this.currentJob.image.src = '//upload.wikimedia.org/wikipedia/commons/thumb/3/34/Crystal_Clear_app_clean.png/16px-Crystal_Clear_app_clean.png'; } else if ( status == 'running' ) { this.currentJob.image.src = '//upload.wikimedia.org/wikipedia/commons/3/32/Loader3.gif'; } else { this.currentJob.image.src = '//upload.wikimedia.org/wikipedia/commons/thumb/9/99/Crystal_128_error.svg/16px-Crystal_128_error.svg.png'; } }, /** Exception handler */ handleException: function( e ) { var message = errorCaughtException + '\n' + e.name + ':' + e.message; if ( e.stack ) { message += '\n' + e.stack; } showError( message ); }, /** Creates list of jobs, and starts executing them */ processQueue: function() { jQuery( '#mtsg-fieldset' ).append( '<label for="mtsg-jobs">' + mw.msg( 'mtsg-jobs-label' ) + '</label>' ); jQuery( '#mtsg-fieldset' ).append( '<div id="mtsg-jobs"></div>' ); // Shrink the message field jQuery( '#mtsg-message' ).removeClass( 'mtsg-message-full' ); for ( var index in this.jobQueue ) { var job = this.jobQueue[index]; var image = jQuery( '<img src="//upload.wikimedia.org/wikipedia/commons/1/11/Hourglass.png" width="16" height="16">' ); jQuery( '#mtsg-jobs' ).append( jQuery( '<div id="job-' + job.name + '"></div>' ).append( image, job.description ) ); job.image = image[0]; } this.executeNextJob(); }, /** Executes next enqueued job */ executeNextJob: function() { if ( this.currentJob ) { this.updateCurrentStatus( 'done' ); } if ( !this.jobQueue.length ) { if ( this.debug ) { console.log( 'There are no jobs left' ); } return; } var that = this; var job = this.jobQueue.shift(); if ( this.debug ) { console.log( 'Executing job: ' + job.name ); console.log( job ); } job.callback = function( success ) { that.executeNextJob(); }; job.owner = this; this.currentJob = job; this.updateCurrentStatus( 'running' ); try { job.execute(); } catch ( e ) { this.handleException( e ); } }, /** Performs move */ confirm: function( dialog ) { var gadget = this; this.moveDestination = jQuery( '#mtsg-destination' ).val().trim(); if ( this.moveDestination == '' ) { alert( mw.msg( 'mtsg-error-empty-destination-name' ) ); return; } this.moveReason = jQuery( '#mtsg-reason' ).val().trim(); this.moveMessage = jQuery( '#mtsg-message' ).val().trim(); if ( this.moveMessage == jQuery.trim( mw.msg( 'mtsg-default-message' ) ) ) { alert( mw.msg( 'mtsg-error-move-message-not-changed' ) ); return; } var buttons = jQuery( dialog ).dialog( 'option', 'buttons' ); delete buttons[mw.msg( 'mtsg-confirm-button' )]; jQuery( dialog ).dialog( 'option', 'buttons', buttons ); this.jobQueue = []; this.jobQueue.push( { name: 'move', description: mw.msg( 'mtsg-move-page-job' ), execute: function() { var job = this; var request = { action: 'move', fromid: mw.config.get( 'wgArticleId' ), to: gadget.moveDestination, token: gadget.moveToken, reason: gadget.moveReason, movetalk: 1 } if ( gadget.canSuppressRedirect ) { request['noredirect'] = 1; } gadget.callApi( request, function( data ) { if ( data.error && data.error.code ) { gadget.showError( data.error.code ); } else { job.callback(); } } ); } } ); if ( !gadget.canSuppressRedirect ) { this.jobQueue.push( { name: 'speedy', description: mw.msg( 'mtsg-insert-speedy-job' ), execute: function() { var job = this; var request = { action: 'edit', title: gadget.moveSource, prependtext: mw.message( 'mtsg-speedy-template', gadget.moveDestination ).plain(), nocreate: 1, summary: mw.msg( 'mtsg-speedy-summary' ) } gadget.editPage( request, function( data ) { if ( !data.edit || data.edit.result != 'Success' ) { gadget.showError( mw.msg( 'mtsg-error-api-error' ) ); } else { job.callback(); } } ); } } ); } if ( this.moveMessage != '' ) { this.jobQueue.push( { name: 'message', description: mw.msg( 'mtsg-send-message-job' ), messageTitle: '[[:' + this.moveSource + '|' + this.moveSource + ']]', messageText: this.moveMessage.replace( /\$link/g, this.moveDestination ), execute: function() { var job = this; var request = { action: 'edit', title: 'User talk:' + gadget.author, text: this.messageText, section: 'new', summary: this.messageTitle } gadget.editPage( request, function( data ) { if ( !data.edit || data.edit.result != 'Success' ) { gadget.showError( mw.msg( 'mtsg-error-api-error' ) ); } else { job.callback(); } } ); } } ); } this.jobQueue.push( { name: 'redirect', description: mw.msg( 'mtsg-redirect-job' ), execute: function() { setTimeout( function() { window.location = mw.util.wikiGetlink( gadget.moveDestination ); }, 1000 ); } } ); gadget.processQueue(); }, /** * Performs MediaWiki call using post method. * @param request * Api request. * @param callback * Function to be called when request is completed. */ callApi: function( request, callback ) { var gadget = this; if ( gadget.debug ) { console.log( 'Sending api request: ', request ); } request.format = 'json'; jQuery.post( mw.util.wikiScript( 'api' ), request, function( data ) { if ( gadget.debug ) { console.log( 'Response: ', data ); } try { callback( data ); } catch ( e ) { gadget.handleException( e ); } }, 'json' ); }, /** * Performs edit, fetches edit token if not provided. * @param request * Api request. * @param callback * Function to be called when request is completed. */ editPage: function( request, callback ) { var gadget = this; if ( request.title == null ) { throw new Error( 'Page title is missing' ); } if ( callback == null ) { throw new Error( 'Callback is missing' ); } if ( request.token == null ) { var tokenRequest = { action: 'query', prop: 'info', format: 'json', titles: request.title, intoken: 'edit' } gadget.callApi( tokenRequest, function( data ) { if ( data.error ) { callback( data ); return; } var page; for ( var pageId in data.query.pages ) { page = data.query.pages[pageId]; } if ( !page || page.edittoken == null ) { callback( data ); return; } request.title = page.title; request.token = page.edittoken; gadget.editPage( request, callback ); } ); } else { gadget.callApi( request, callback ); } } }; moveToSandboxGadget.init();