MediaWiki:Gadget-rollback.js

A Wikipédiából, a szabad enciklopédiából

Megjegyzés: közzététel után frissítened kell a böngésződ gyorsítótárát, hogy lásd a változásokat.

  • Firefox / Safari: tartsd lenyomva a Shift gombot és kattints a Frissítés gombra a címsorban, vagy használd a Ctrl–F5 vagy Ctrl–R (Macen ⌘–R) billentyűkombinációt
  • Google Chrome: használd a Ctrl–Shift–R (Macen ⌘–Shift–R) billentyűkombinációt
  • Internet Explorer / Edge: tartsd nyomva a Ctrl-t, és kattints a Frissítés gombra, vagy nyomj Ctrl–F5-öt
  • Opera: Nyomj Ctrl–F5-öt
( function ( $, mw ) {
	/**
	 * Displays success or failure with an icon at the end of each link.
	 * @param {HTMLAnchorElement} link
	 * @param {String} status One of 'working', 'success', 'error'
	 * @param {String} [errorCode] Error code, if status is 'error'
	 * @param {String} [errorMessage] Error message, if status is 'error'
	 */
	function updateLinkStatus( link, status, errorCode, errorMessage ) {
		link.classList.remove( 'api-working', 'api-success', 'api-error' );
		if ( status in { working: 1, success: 1, error: 1 } ) {
			link.classList.add( 'api-' + status );
			if ( status === 'error' ) {
				console.warn( 'gadget-rollback: ' + errorCode );
				var errorElement = document.createElement( 'span' );
				errorElement.innerHTML = errorMessage;
				mw.notify( errorElement, { type: 'error', title: 'Visszaállító-hiba' } );
				link.title = errorElement.innerText;
			}
		} else {
			throw 'gadget-rollback: invalid link status';
		}
	}

	/**
	 * Given a rollback link, sends an API request which does the same thing
	 * the links would have done. Displays success or failure with an icon
	 * at the end of each link.
	 * @param {HTMLAnchorElement} link
	 * @returns {Promise<void>}
	 */
	function submitRollbackLink( link ) {
		return new Promise( function ( resolve, reject ) {
			mw.loader.using( [ 'mediawiki.Uri', 'mediawiki.api' ] ).then( function () {
				var errorMessage,
					api = new mw.Api(),
					uri = new mw.Uri( link.href ),
					title = uri.query.title,
					user = uri.query.from,
					bot = uri.query.bot;
				
				if ( !title || ! user ) { // Rollback info not found in link
					errorMessage = 'Belső hiba: nem sikerült értelmezni a linket';
					updateLinkStatus( link, 'error', 'rollback-info-not-found-in-link', errorMessage );
					reject( errorMessage );
					return;
				}
				
				updateLinkStatus( link, 'working' );

				api.postWithToken( 'rollback', {
					action: 'rollback',
					title: title,
					user: user,
					markbot: bot,
					formatversion: 2,
					errorformat: 'html',
					errorsuselocal: true,
					uselang: mw.config.get( 'wgUserLanguage' )
				} ).done( function ( result, jqXHR ) {
					updateLinkStatus( link, 'success' );
					resolve();
				} ).fail( function ( code, result ) {
					if ( result.errors && result.errors[0] ) {
						errorMessage = result.errors[0].html;
					} else {
						errorMessage = 'API hiba: ' +  code;
					}
					updateLinkStatus( link, 'error', code, errorMessage );
					reject( errorMessage );
				} );
			} );
		} );
	}

	function rollbackAll() {
		/** @type {NodeListOf<HTMLAnchorElement>} */
		var links = document.querySelectorAll( '.mw-rollback-link a.rollback' ),
			/** @type {HTMLButtonElement} */
			button = document.getElementById( 'rollback-all' ),
			oldButtonText = button.innerText;

		if ( !confirm( 'Biztosan vissza akarod vonni a lenti lista összes visszavonható szerkesztését?' ) ) {
			return false;
		}

		button.disabled = true;
		button.innerText = 'Folyamatban…';
		Promise.allSettled( Array.from( links ).map( submitRollbackLink ) ).finally( function () {
			button.disabled = false;
			button.innerText = oldButtonText;
		} );
	}
	
	/**
	 * Remove NavPopups from a link
	 * Copied from en:MediaWiki:Gadget-popups.js
	 * @param {HTMLAnchorElement} a
	 */
	function removeTooltip( a ) {
		a.onmouseover = null;
		a.onmouseout = null;
		if ( a.originalTitle ) {
			a.title = a.originalTitle;
		}
		a.hasPopup = false;
	}
	
	/**
	 * Sets up individual rollback links
	 */
	function installLinks() {
		var isAdmin = ( $.inArray( 'sysop', mw.config.get( 'wgUserGroups' ) ) !== -1 ),
			rollbackSpans = document.querySelectorAll( '.mw-rollback-link' ),
			clickHandler = function( e ) {
				submitRollbackLink( this );
				e.preventDefault();
			};
		
		rollbackSpans.forEach( function ( el ) {
			var link = el.querySelector( 'a' );

			$( el ).off( 'click', 'a[data-mw="interface"]' ); // stop MediaWiki's own rollback.js from interfering @TODO when that script becomes more intelligent, a lot of this code will be unnecessary

			$( link )
				.addClass( 'rollback' )
				.attr( 'nopopup', 1 ) // stop NavPopups from interfering
				.attr( 'data-mw', false ) // stop MW rollback.js even if it's loaded late
				.click( clickHandler );
				
			// if NavPopups was loaded first, the link is already processed and nopopup is ignored, we need to unprocess it
			removeTooltip( link );
			
			if ( isAdmin ) {
				$( '<span>' )
					.append(
						$( '<a>' )
							.attr( {
								title: 'Visszaállítás bot módban',
								href: link.href.replace( '&action=rollback', '&action=rollback&bot=1' ),
								class: 'bot-rollback',
								nopopup: 1
							} )
							.text( 'bot' )
							.click( clickHandler )
					)
					.insertAfter( el.parentElement );
			}
		} );
	}

	/**
	 * Sets up a "rollback all" button
	 */
	function installButton() {
		var $rollbackAllDiv = $( '<div>' ).css( 'float', 'right' );

		$rollbackAllDiv.appendTo( '.firstHeading' ).append(
			$( '<button>' )
				.attr( 'id', 'rollback-all' )
				.text( 'Összes visszaállítása' )
				.click( rollbackAll )
		);
	}
	
	/**
	 * Main setup function
	 */
	function install() {
		if ( mw.config.get( 'wgAction' ) === 'history' || mw.config.get( 'wgCanonicalNamespace' ) === 'Special' ) {
			installLinks();
			if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Contributions' ) {
				installButton();
			}
		}
	}
	
	$( install );
} ) ( jQuery, mediaWiki );