Saltar para o conteúdo

MediaWiki:Gadget-wikibugs.js/Core.js

Origem: Wikipédia, a enciclopédia livre.

Nota: Depois de publicar, poderá ter de contornar a cache do seu navegador para ver as alterações.

  • Firefox / Safari: Pressione Shift enquanto clica Recarregar, ou pressione Ctrl-F5 ou Ctrl-R (⌘-R no Mac)
  • Google Chrome: Pressione Ctrl-Shift-R (⌘-Shift-R no Mac)
  • Edge: Pressione Ctrl enquanto clica Recarregar, ou pressione Ctrl-F5.
/*
 * Source: [[:pl:MediaWiki:Gadget-wikibugs.js]]
 * @author: [[:pl:User:Dodek]] (idea and text)
 * @author: [[:pl:User:Adziura]] (idea and text)
 * @author: [[:pl:User:Nux]] (implementation)
 * @author: [[:pl:User:Saper]] (implementation)
 * @author: [[:pl:User:Beau]] (implementation)
 * @author: Helder (https://github.com/he7d3r) (implementation)
 */

/*jslint browser: true, white: true, regexp: true, devel: true, todo: true, sloppy: true*/
/*global mediaWiki, jQuery*/
( function ( mw, $ ) {
// 'use strict';

/* Translatable strings */
mw.messages.set( {
	'wikibugs-dialog-title': 'Informar um erro',
	'wikibugs-open-form-button': 'Informar',
	'wikibugs-edit-page-button': 'Editar a página e corrigir o erro',
	'wikibugs-cancel-button': 'Cancelar',
	'wikibugs-submit-report-button': 'Enviar',
	'wikibugs-ip-address-notice': '<b>Observação:</b> seu endereço de IP' +
		' ficará armazenado no histórico de notificações.',
	'wikibugs-page-name-label': 'Nome da página:<br/><small>(juntamente com' +
		' o prefixo "Imagem:" se estiver informando um erro em uma imagem ou' +
		' outro tipo de ficheiro/arquivo</small>',
	'wikibugs-report-content-label': 'Detalhes sobre o erro:<br><small>' +
		'<u>Não</u> deixe seu número de telefone, e-mail ou qualquer outro dado pessoal</small>',
	'wikibugs-report-content-placeholder': 'Explique aqui o problema detalhadamente e,' +
		' se possível, indique uma referência onde se possa confirmar a informação',
	'wikibugs-signature-label': 'Assinatura:',
	'wikibugs-try-again': 'Por favor, tente novamente. Se o problema persistir, informe-o no café dos programadores, com uma cópia dessa mensagem.',
	'wikibugs-captcha-desc': 'Por favor, introduza na caixa abaixo as palavras apresentadas:',
	'wikibugs-error-inexistent': 'A API informou que a página $1 não existe.',
	'wikibugs-error-reading-content': 'Houve um erro ao usar AJAX para acessar a página. ',
	'wikibugs-error-editing': 'Houve um erro ao usar AJAX para editar a página. ',
	'wikibugs-error-using-api': 'Erro ao usar a API: $1. $2. ',
	'wikibugs-error-unexpected-editing': 'Houve um erro inesperado ao usar a API para editar a página. ',
	'wikibugs-current-page': 'Houve um erro ao tentar usar a API para acessar a página atual.',
	'wikibugs-incomplete-information': 'Descreva detalhadamente qual é o erro. Não coloque informações incompletas.',
	'wikibugs-invalid-page': 'Informe um nome válido para a página.',
	'wikibugs-reported-by': ' Enviado por: $1',
	'wikibugs-file-section-line': '<!-- Erros nas imagens a partir desta linha. Itens mais recentes no topo. -->',
	'wikibugs-page-section-line': '<!-- Erros nos artigos a partir desta linha. Itens mais recentes no topo. -->',
	'wikibugs-bad-reports-text': '<p>Neste formulário <b>não são aceitos</b> pedidos' +
		' para expandir ou criar artigos. Isso deve ser feito na página:</p>' +
		'<ul><li><a href="' + mw.util.getUrl('Wikipédia:Artigos pedidos') +
		'">Artigos pedidos</a></li></ul><p><b>Não informe</b> erros em outros sites' +
		' (como <b>Facebook</b> ou <b>Twitter</b>), pois não serão atendidos.' +
		'<p>A Wikipédia não dá conselhos. Se precisa de aconselhamento,' +
		' <b>não peça aqui</b>.</p><p>Para informações sobre como contactar a Wikipédia,' +
		' consulte:</p><ul><li><a href="' + mw.util.getUrl('Wikipédia:Contato') +
		'">Contato</a></li></ul>',
	'wikibugs-article-intro': '<p style="margin-top:0px;">É possível avisar' +
		' sobre erros encontrados nos artigos da Wikipédia, mas lembre-se de' +
		' que ela é uma <a href="' + mw.util.getUrl('Wiki') +
		'">wíki</a> e por isso até mesmo o leitor pode <a href="' +
		mw.util.getUrl('Wikipédia:Seja audaz') +
		'">ser audaz e corrigir um erro</a> encontrado durante a leitura.' +
		' No entanto, reconhecemos o fato de que alguns leitores da Wikipédia' +
		' têm motivos para não quererem editar e aprimorar os artigos diretamente.</p>' +
		'<p><b>Falta de informação não é considerado erro. Se puder corrigir o problema, não o informe aqui.</b></p>',
	'wikibugs-image-intro': '<p style="margin-top:0px;">Aqui é possível informar' +
		' sobre imagens que violam os termos da licença, que possuem versões' +
		' melhores no Wikimedia Commons, que estão descritas incorretamente etc. </p>' +
		'<p><b>Se puder corrigir o problema, não o informe aqui.</b></p>',
	'wikibugs-already-reported-notice': '<p><b>Observação:</b> se informou um problema' +
		' e agora ele já não existe, então provavelmente algum editor já o corrigiu.' +
		' Consulte:<ul><li><a href="' + mw.util.getUrl('Ajuda:Informe um erro') +
		'">a lista atual de problemas informados</a> e</li><li><a href="' +
		mw.util.getUrl('Ajuda:Informe um erro') +
		'?action=history">o histórico de modificações da página.</a></li></ul></p>',
	'wikibugs-footer': '<p>Leia os <a href="https://foundation.wikimedia.org/wiki/' +
		'Condições_de_Uso" target="_blank">termos de uso</a> e a <a href="' +
		'https://foundation.wikimedia.org/wiki/Política_de_privacidade"' +
		' target="_blank">política de privacidade</a> da Wikipédia.</p>',
	'wikibugs-new-report': 'Nova notificação: $1'
});

$.extend( mw.Api.prototype, {
	/**
	* Convinience method to get the text of the current revision of a page.
	*
	* @param title {String}
	* @param success {Function} callback to which to pass success wikitext
	* @param err {Function} callback if error (optional)
	* @return {jqXHR}
	*/
	getPageText: function( title, success, err ) {
		// TODO Allow passing a "data" object to be merged with default settings
		var params = {
				action: 'query',
				titles: title,
				prop: 'revisions',
				rvprop: 'content',
				indexpageids: ''
			},
			ok = function( data ) {
				var	query = data.query,
					pages = query && query.pages,
					pageid = query && query.pageids && query.pageids[0];
				// Based on https://github.com/Krinkle/mw-gadgets-jsUpdater/commit/b3d96a1a13d72f5022110b05de1a857c9ed64ab5
				// pageid may be -1, in that case 'text' and 'revisions' will be undefined
				if (pageid && Number(pageid) > 0 && pages[pageid]) {
					success( pages[pageid].revisions && pages[pageid].revisions[0] && pages[pageid].revisions[0]['*'] );
				} else {
					err( 'inexistent', mw.msg( 'wikibugs-error-inexistent', title ) );
				}
			};
		return this.get( params ).done( ok ).fail( err );
	},

	/**
	* Convinience method to edit a page.
	*
	* @param title {String}
	* @param ok {Function} callback to which to pass success data
	* @param err {Function} callback if error (optional)
	* @return {jqXHR}
	*/
	editPage: function( data, ok, err ) {
		var	defaultData = {
				action: 'edit',
				minor: false,
				token: mw.user.tokens.get( 'csrfToken' )
			},
			params;
		if ( data === undefined ) {
			data = {};
		}
		params = $.extend( {}, defaultData, data );
		return this.post( params ).done( ok ).fail( err );
	}
} );

var wb = {
	/**
	 * Version number of this gadget.
	 */
	version: 11,
	/**
	 * A name of a page where reports are saved.
	 */
	reportPage: 'Ajuda:Informe um erro',
	/**
	 * Black list of pages which reports should not refer to.
	 */
	badPages: [
		'Ajuda:Informe um erro'
	],
	/**
	 * Message shown on pages in the main namespace.
	 */
	articleIntro: '<div id="wbBadReports">' +
		mw.msg( 'wikibugs-bad-reports-text' ) + '</div>' +
		mw.msg( 'wikibugs-article-intro' ) +
		mw.msg( 'wikibugs-already-reported-notice' ) +
		mw.msg( 'wikibugs-footer' ),
	/**
	 * Message shown on pages in the file namespace.
	 */
	imageIntro: '<div id="wbBadReports">' +
		mw.msg( 'wikibugs-bad-reports-text' ) + '</div>' +
		mw.msg( 'wikibugs-image-intro' ) +
		mw.msg( 'wikibugs-already-reported-notice' ) +
		mw.msg( 'wikibugs-footer' ),

	/**
	 * Checks if a title of the page is valid for a report.
	 * @param title A title of the page.
	 */
	isValidPageName: function( title ) {
		// Empty title is not valid
		if ( title === '' ) {
			return false;
		}
		// Special pages are not valid too
		if ( this.getPageNamespaceNumber( title ) === -1 ) {
			return false;
		}
		// Check black list
		title = this.getRefinedPageName( title );
		return $.inArray( title, this.badPages ) === -1;
	},

	/**
	 * Returns a namespace number of a specifed page.
	 * @param title A title of the page.
	 */
	getPageNamespaceNumber: function( title ) {
		var	matches = title.match( /^([^:]+)/ ),
			key, namespaces, result;
		if ( matches ) {
			key = matches[1].replace( / /g, '_' ).toLowerCase();
			namespaces = mw.config.get( 'wgNamespaceIds' );
			result = namespaces[key];
			if ( result !== null ) {
				return result;
			}
		}
		return 0;
	},

	/**
	 * Redirects to the edit page.
	 */
	goToEditPage: function() {
		var $editLink = $( '#ca-edit' ).find( 'a' );
		window.location = $editLink.attr( 'href' ) || mw.util.getUrl( this.reportPage );
	},

	/**
	 * Shows the dialog window.
	 * @param infoHtml The message content.
	 */
	open: function( infoHtml ) {
		var	that = this,
			buttons = {},
			can_edit = document.getElementById( 'ca-edit' ) ? true : false,
			$dialog = $( '<div id="dialogContent"></div>' ).append( infoHtml );

		if ( mw.user.isAnon() ) {
			$dialog.append( '<p>' + mw.msg( 'wikibugs-ip-address-notice' ) + '</p>' );
		}

		buttons[mw.msg( 'wikibugs-cancel-button' )] = function() {
			$( this ).dialog( 'close' );
		};
		buttons[mw.msg( 'wikibugs-open-form-button' )] = function() {
			that.openForm( this );
		};
		if ( can_edit ) {
			buttons[mw.msg( 'wikibugs-edit-page-button' )] = function() {
				that.goToEditPage();
			};
		}

		$dialog.dialog( {
			width: 700,
			height: 500,
			modal: true,
			resizable: false,
			draggable: true,
			closeOnEscape: true,
			dialogClass: 'reportBugDialog',
			title: mw.msg( 'wikibugs-dialog-title' ),
			close: function() {
				$( this ).dialog( 'destroy' ).remove();
			},
			buttons: buttons
		} );
		$( 'div.reportBugDialog button:last' ).focus();
	},
	/**
	 * Shows the form in the dialog window.
	 */
	openForm: function( dialog ) {
		var	that = this,
			buttons = {},
			author;
		$( '#dialogContent' ).empty().append(
			'<form name="WikibugForm" enctype="multipart/form-data">' +
			'<fieldset>' +
			'<label for="wbPageTitle">' + mw.msg( 'wikibugs-page-name-label' ) + '</label>' +
			'<input id="wbPageTitle" type="text" name="wbPageTitle" class="text ui-widget-content ui-corner-all" />' +
			'<label for="wbText">' + mw.msg( 'wikibugs-report-content-label' ) + '</label>' +
			'<textarea id="wbText" name="wbText" rows="6" class="text ui-widget-content ui-corner-all">' +
			mw.msg( 'wikibugs-report-content-placeholder' ) + '</textarea>' +
			'<label for="wbAuthor">' + mw.msg( 'wikibugs-signature-label' ) + '</label>' +
			'<input id="wbAuthor" type="text" class="text ui-widget-content ui-corner-all"/>' +
			'</fieldset>' +
			'<img id="wikibugs-loading-icon" src="//upload.wikimedia.org/wikipedia/commons/4/49/Linux_Ubuntu_Loader.gif" style="display:none;"/>' +
			'</form>'
		);

		buttons[mw.msg( 'wikibugs-cancel-button' )] = function() {
			$( this ).dialog( 'close' );
		};
		buttons[mw.msg( 'wikibugs-submit-report-button' )] = function() {
			that.submitForm();
		};

		$( dialog ).dialog( 'option', 'buttons', buttons );

		$( '#wbText' ).focus( function() {
			if ( this.value === mw.msg( 'wikibugs-report-content-placeholder' ) ) {
				this.value = '';
			}
		} );

		if ( this.isValidPageName( mw.config.get( 'wgPageName' ) ) ) {
			$( '#wbPageTitle' ).val( this.getRefinedPageName() );
		}

		if ( !mw.user.isAnon() ) {
			author = document.getElementById( 'wbAuthor' );
			author.value = '~~' + '~~';
			author.disabled = 'disabled';
		}
	},

	/**
	 * Indicates wheter submit should be ignored.
	 */
	suppressSubmit: false,
	newText: null,
	reportedPage: null,

	/**
	 * Show an error message to the user
	 */
	informError: function( code, result, tryAgain ){
		var msg = mw.msg( 'wikibugs-error-' + code ) + ' (' + result + ')';
		if ( tryAgain !== undefined && !tryAgain ) {
			alert( msg );
		} else {
			alert( msg + '. ' + mw.msg( 'wikibugs-try-again' ) );
		}
		this.suppressSubmit = false;
		$('#wikibugs-loading-icon').hide();
	},

	/**
	 * Sends the contents of the form.
	 */
	submitForm: function() {
		var	that = this,
			form = document.forms.WikibugForm,
			content = form.wbText.value,
			$captcha = $('#wpCaptchaWord'),
			api = new mw.Api( { ajax: { error: that.informError } } ),
			toInsert, isFile,
			refinedPageName, $loadingIcon;

		function editCallback( res ) {
			var	result = res && res.edit && res.edit.result && res.edit.result,
				$captchaForm;
			if ( res.error !== undefined ) {
				that.informError( 'using-api', res.error.code + ': ' + res.error.info );
			} else if ( result === 'Success' ){
				//saved successfully - go to the report page
				window.location = mw.util.getUrl(that.reportPage) + '#' +
					encodeURIComponent(
						encodeURI(that.reportedPage).replace(/%/g, '.')
					).replace(/%/g, '.').replace(/\.3A/g, ':').
					replace(/\.20/g, '_').
					replace(/\(/g, '.28').replace(/\)/g, '.29');

				if (mw.config.get('wgPageName') === that.reportPage.replace( / /g, '_' )) {
					//we're already there
					window.location.reload();
				}
			} else if ( result === 'Failure' && res.edit.captcha !== undefined ){
				$captchaForm = $('<div id="wikibus-captcha"></div>')
					.append( mw.msg( 'wikibugs-captcha-desc' ) )
					.append('<br /><img src="' + res.edit.captcha.url + '" id="captcha-' + res.edit.captcha.id + '" width="255" height="76" alt="">')
					.append('<input name="wpCaptchaWord" id="wpCaptchaWord" autocorrect="off" autocapitalize="off" tabindex="1">');
					//.append('<input type="submit">');
				$captchaForm.submit(function() {
					return false;
				}).keyup(function(e) {
					if (e.keyCode === $.ui.keyCode.ENTER) {
						that.submitForm();
					}
				});
				$('#wikibugs-loading-icon').after( $captchaForm );
			} else {
				that.informError( 'unexpected-editing' );
			}
		}

		function doEditPage( data ){
			var params = {
				title: that.reportPage,
				text: that.newText,
				summary: mw.msg(
					'wikibugs-new-report',
					'[[:' + that.reportedPage + ']]'
				)
			};
			api.editPage(
				$.extend( {}, params, data ),
				editCallback,
				function( code, result){
					that.informError( 'editing', code + ': ' + result );
				}
			);
		}

		if( $captcha.length ){
			doEditPage( {
				captchaid: $captcha.prev().attr('id').replace( /^captcha-/g, ''),
				captchaword: $captcha.val()
			} );
			return;
		}
		if ( this.suppressSubmit ) {
			return;
		}

		if ( content === mw.msg( 'wikibugs-report-content-placeholder' ) ||
			content.length < 20 ||
			!content.match( ' ' )
		) {
			// Description too short or unchanged
			alert( mw.msg( 'wikibugs-incomplete-information' ) );

			form.wbText.focus();
			return;
		}
		content = content.trim();

		// Append a signature to the report
		if ( !mw.user.isAnon() ) {
			content += mw.msg( 'wikibugs-reported-by', '~~' + '~~' );
		} else {
			content += mw.msg( 'wikibugs-reported-by', form.wbAuthor.value + ' ~~' + '~~' );
		}

		that.reportedPage = this.getRefinedPageName( form.wbPageTitle.value.replace( /[\[\]]/g, '' ) );
		isFile = this.getPageNamespaceNumber( that.reportedPage ) === 6;

		if ( !this.isValidPageName( that.reportedPage ) ) {
			alert( mw.msg( 'wikibugs-invalid-page' ) );

			refinedPageName = this.getRefinedPageName();
			if ( this.isValidPageName( refinedPageName ) ) {
				form.wbPageTitle.value = refinedPageName;
			} else {
				form.wbPageTitle.value = '';
				form.wbPageTitle.focus();
			}
			return;
		}

		this.suppressSubmit = true;
		$loadingIcon = $( '#wikibugs-loading-icon' );
		$loadingIcon.show();

		toInsert = '== [[:' + that.reportedPage + ']] ==\n' + content;

		function processContentOfPage( text ){
			var sectionLine;

			// Process the wikitext of the page
			sectionLine = mw.msg( 'wikibugs-page-section-line' );
			that.newText = text.replace(sectionLine, sectionLine + '\n\n' + toInsert);
			if (text === that.newText) {
				// Could not find the section line - simply append;
				that.newText = text + '\n\n' + toInsert;
			}
			doEditPage();
		}

		// EDIT THE "REPORT AN ERROR" PAGE
		api.getPageText(
			this.reportPage,
			processContentOfPage,
			function( code, result ){
				that.informError( 'reading-content', code + ': ' + result );
			}
		);
	}
};

$.extend(window.wikiBugsGadget, wb);

}( mediaWiki, jQuery ) );