MediaWiki:Gadget-PublierBrouillon.js

Une page de Wikipédia, l'encyclopédie libre.
Note : après avoir enregistré la page, vous devrez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

Mozilla / Firefox / Konqueror / Safari : maintenez la touche Majuscule (Shift) en cliquant sur le bouton Actualiser (Reload) ou pressez Maj-Ctrl-R (Cmd-R sur Apple Mac) ;

Chrome / Internet Explorer / Opera : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5.
/*
 * Assistant pour publier des brouillons via le lien présent dans [[Modèle:Brouillon]].
 * Le gadget fournit la même fonctionnalité que Spécial:Renommer_une_page, mais en évitant les confusions liées au
 * choix de l'espace de noms. Pour les utilisateurs non autoconfirmés, le gadget bascule de façon transparente sur une
 * méthode de publication par copier-coller du brouillon.
 *
 * {{Projet:JavaScript/Script|PublierBrouillon}}
 */

( function () {
	'use strict';

	var commonErrorsById = {
		// MediaWiki API.
		'abusefilter-disallowed': { text: 'l’action a été bloquée par le filtre anti-abus.', helpButton: true },
		'articleexists': { text: 'il existe déjà une page portant ce nom.' },
		'invalidtitle': { text: 'titre de page invalide.', helpButton: true },
		'pagecannotexist': { text: 'titre de page invalide.', helpButton: true },
		'selfmove': { text: 'veuillez entrer le nom l’article à créer et non celui de votre brouillon.' },
		'protectedtitle': { text: 'une protection bloque la création d’un article portant ce nom.', helpButton: true },
		// Ce gadget.
		'draftisredirect': { text: 'le brouillon est une redirection. Il a peut-être été publié entre-temps.' },
		'emptydraft': { text: 'le brouillon est vide.' },
		'genericeditfailure': { text: 'la création de la page a échoué.', helpButton: true }
	};

	function moveDraft( draftTitle, articleTitle, captchaResponse ) {
		var api = new mw.Api();
		// Première étape : lecture du contenu du brouillon.
		return api.get( {
			action: 'query',
			prop: 'revisions',
			titles: draftTitle,
			rvprop: 'content',
			rvslots: 'main',
			formatversion: 2
		} ).then( function ( readResponse ) {
			// Deuxième étape : publication.
			// Si l'utilisateur est autoconfirmé, la publication est faite par renommage. Elle est
			// suivie d'une modification pour retirer les modèles d'en-tête (s'il n'y en a pas,
			// cette seconde étape sera simplement un null edit).
			// Si l'utilisation n'est pas autoconfirmé, la publication est faite par copie.
			var draftContent = readResponse.query.pages[ 0 ].revisions[ 0 ].slots.main.content;
			draftContent = draftContent
				.replace( /\{\{(Aide:Comment créer un article\/brouillon|[Bb]rouillon|[Pp]age personnelle)\}\}\n?/g, '' )
				.replace( /<!-- (Ne rien modifier au-|Cliquez sur le bouton)[^-]* -->\n?/g, '' )
				.replace( /^\n+/, '' )
				.replace( /<nowiki>\n?/g, '' )
				.replace( /<\/nowiki>/g, '' );
			// Si le contenu commence par un titre de niveau 1 égal au titre de l'article publié,
			// retire ce titre du contenu.
			var mainTitle = /^= *([^= ].*[^= ]) *=\n+/.exec( draftContent );
			if ( mainTitle && mainTitle[1].toLowerCase() === articleTitle.toLowerCase() ) {
				draftContent = draftContent.substring( mainTitle[0].length );
			}
			if ( draftContent === '' ) {
				return $.Deferred().reject( 'emptydraft' );
			} else if ( /^#redirect/i.test( draftContent ) ) {
				return $.Deferred().reject( 'draftisredirect' );
			}
			var canMovePage = mw.config.get( 'wgUserGroups' ).indexOf( 'autoconfirmed' ) !== -1;
			if ( canMovePage ) {
				return api.postWithEditToken( {
					action: 'move',
					from: draftTitle,
					to: articleTitle,
					reason: 'Publication du brouillon',
					tags: 'PublierBrouillon'
				} ).then( function () {
					return api.postWithEditToken( {
						assert: 'user',
						action: 'edit',
						title: articleTitle,
						summary: 'Retrait de l’en-tête du brouillon',
						text: draftContent,
						tags: 'PublierBrouillon'
					} );
				} );
			} else {
				var editRequest = {
					assert: 'user',
					action: 'edit',
					title: articleTitle,
					summary: 'Publication à partir de [[' + draftTitle + ']]',
					text: draftContent,
					createonly: 1,
					tags: 'PublierBrouillon'
				};
				if ( captchaResponse ) {
					// Injecte la réponse au captcha reçu lors de la précédente tentative.
					editRequest.captchaid = captchaResponse.id;
					editRequest.captchaword = captchaResponse.word;
				}
				return api.postWithEditToken( editRequest ).catch( function ( errorCode ) {
					if ( errorCode === 'abusefilter-warning' ) {
						// Il s'agit d'un transfert de contenu déjà rédigé, donc les avertissements
						// de AbuseFilter sont a priori redondants. Resoumettre la même requête
						// suffit à les ignorer.
						return api.postWithEditToken( editRequest );
					}
					return $.Deferred().reject( errorCode );
				} ).then( function ( editResponse ) {
					if ( editResponse.edit.result === 'Failure' ) {
						if ( editResponse.edit.captcha ) {
							// Associe à l'erreur les données permettant de demander la réponse au
							// captcha.
							return $.Deferred().reject( { captcha: editResponse.edit.captcha } );
						} else {
							return $.Deferred().reject( 'genericeditfailure' );
						}
					}
				} );
			}
		} ).then( function () {
			// Troisième étape : réinitialisation du brouillon.
			var header = '{{Aide:Comment créer un article/brouillon}}\n' +
						'<!-- Ne rien modifier au-dessus de cette ligne -->';
			return api.postWithEditToken( {
				assert: 'user',
				action: 'edit',
				title: draftTitle,
				summary: 'Remise à zéro automatique du brouillon',
				text: header,
				tags: 'PublierBrouillon'
			} );
		} );
	}

	function showPublishDraftDialog() {
		if ( mw.config.get('wgAction') !== 'view' ) {
			OO.ui.alert( 'Veuillez enregistrer la modification en cours avant de publier le brouillon.' );
			return;
		}

		var draftTitle = mw.config.get( 'wgPageName' ).replace( /_/g, ' ' );

		var PublishDraftDialog = function ( config ) {
			PublishDraftDialog.super.call( this, config );
			this.captchaId = null;
		};
		OO.inheritClass( PublishDraftDialog, OO.ui.ProcessDialog );

		PublishDraftDialog.static.name = 'PublishDraftDialog';
		PublishDraftDialog.static.title = 'Publication du brouillon';
		PublishDraftDialog.static.actions = [
			{ action: 'back', label: 'Retour', flags: [ 'safe', 'back' ],
				modes: [ 'step-proofreading', 'step-publish', 'step-captcha' ] },
			{ action: 'cancel', label: 'Annuler', flags: [ 'safe' ],
				modes: [ 'step-proofreading', 'step-publish', 'step-captcha' ] },
			{ action: 'proofreading', label: 'Demander une relecture', flags: 'progressive',
				modes: 'step-proofreading' },
			{ action: 'skipproofreading', label: 'Publier directement', flags: 'progressive',
				modes: 'step-proofreading' },
			{ action: 'publish', label: 'Publier', flags: [ 'progressive', 'primary' ],
				modes: [ 'step-publish', 'step-captcha' ] }
		];

		PublishDraftDialog.prototype.getBodyHeight = function () {
			return 200;
		};
		PublishDraftDialog.prototype.initialize = function () {
			PublishDraftDialog.super.prototype.initialize.call( this );
			var dialog = this;
			this.currentPanel = -1;
			var proofreadingPanel = new OO.ui.PanelLayout( {
				padded: true,
				expanded: false,
				$content: $( '<div><p>Voulez-vous demander une relecture de votre brouillon avant sa publication\u00A0?</p>' +
							'</p>La relecture est conseillée s’il s’agit de votre premier article.</p></div>' )
			} );
			this.articleTitleInput = new OO.ui.TextInputWidget();
			this.errorFrame = $( '<p style="color:#a00;font-weight:bold;"></p>' )[ 0 ];
			this.helpLink = $( '<p></p>' )[ 0 ];
			var publishPanel = new OO.ui.PanelLayout( {
				padded: true,
				expanded: false,
				content: [
					new OO.ui.FieldLayout(
						this.articleTitleInput, {
							align: 'top',
							label: 'Nom du nouvel article\u00A0:'
						}
					),
					this.errorFrame,
					this.helpLink
				]
			} );
			this.captchaImage = $( '<img style="min-width:32px;min-height:32px;">' )[ 0 ];
			this.captchaInput = new OO.ui.TextInputWidget();
			var captchaPanel = new OO.ui.PanelLayout( {
				padded: true,
				expanded: false,
				content: [
					this.captchaImage,
					new OO.ui.FieldLayout(
						this.captchaInput, {
							align: 'top',
							label: 'Saisissez le texte qui apparaît dans l’image\u00A0:'
						}
					)
				]
			} );
			this.steps = [ 'step-proofreading', 'step-publish', 'step-captcha' ];
			this.panels = [ proofreadingPanel, publishPanel, captchaPanel ];
			this.content = new OO.ui.StackLayout( {
				items: this.panels
			} );
			this.articleTitleInput.on( 'change', function () {
				dialog.errorFrame.textContent = '';
				dialog.helpLink.textContent = '';
			} );
			this.$body.append( this.content.$element );
			// Ne propose pas de relecture aux utilisateurs autopatrolled.
			this.firstPanelToShow = mw.config.get( 'wgUserGroups' ).indexOf( 'autopatrolled' ) !== -1 ? 1 : 0;
		};
		PublishDraftDialog.prototype.getSetupProcess = function ( data ) {
			return PublishDraftDialog.super.prototype.getSetupProcess.call( this, data )
				.next( function () { this.switchToPanel( this.firstPanelToShow ); }, this );
		};
		PublishDraftDialog.prototype.switchToPanel = function ( panel ) {
			if ( this.currentPanel === panel ) {
				return;
			}
			this.content.setItem( this.panels[ panel ] );
			this.actions.setMode( this.steps[ panel ] );
			this.currentPanel = panel;
			if ( panel === 1) {
				this.articleTitleInput.focus();
			} else if ( panel === 2 ) {
				this.captchaInput.focus();
			}
		};
		PublishDraftDialog.prototype.getActionProcess = function ( action ) {
			var dialog = this;
			function showError( error ) {
				var commonError = commonErrorsById[ error ];
				dialog.helpLink.textContent = '';
				if ( commonError ) {
					dialog.errorFrame.textContent = 'Erreur\u00A0: ' + commonError.text;
					if ( commonError.helpButton ) {
						$( dialog.helpLink ).html(
							'<a href="https://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Forum_des_nouveaux">' +
							'Demander de l’aide</a>'
						);
					}
				} else {
					dialog.errorFrame.textContent =
						'Erreur\u00A0: ' + ( typeof error === 'string' ? error : JSON.stringify( error ) );
				}
				dialog.switchToPanel( 1 );
			}
			if ( action === 'cancel' ) {
				this.close();
			} else if ( action === 'proofreading' ) {
				window.location = mw.util.getUrl( 'Wikipédia:Forum de relecture' ) +
								'?topiclist_preloadtitle=' +
								encodeURIComponent( 'Demande concernant [[' + draftTitle + ']]' );
			} else if ( action === 'skipproofreading' ) {
				this.switchToPanel( 1 );
			} else if ( action === 'back' ) {
				if ( this.currentPanel > this.firstPanelToShow ) {
					this.switchToPanel( this.currentPanel - 1 );
				} else {
					this.close();
				}
			} else if ( action === 'publish' ) {
				var articleTitle = this.articleTitleInput.getValue();
				if ( articleTitle === '' ) {
					showError( 'veuillez entrer un titre.' );
				} else {
					return new OO.ui.Process( function () {
						var captchaResponse = dialog.captchaId ?
							{ id: dialog.captchaId, word: dialog.captchaInput.getValue() } : null;
						return moveDraft( draftTitle, articleTitle, captchaResponse ).then(
							function () { window.location = mw.util.getUrl( articleTitle ); }
						).catch( function ( error ) {
							if ( error.captcha ) {
								dialog.captchaId = error.captcha.id;
								dialog.captchaImage.src = error.captcha.url;
								dialog.captchaInput.setValue( '' );
								dialog.switchToPanel( 2 );
							} else {
								showError( error );
							}
						} );
					} );
				}
			}
			return PublishDraftDialog.super.prototype.getActionProcess.call( this, action );
		};
		var windowManager = new OO.ui.WindowManager();
		$( document.body ).append( windowManager.$element );
		var publishDraftWindow = new PublishDraftDialog();
		windowManager.addWindows( [ publishDraftWindow ] );
		windowManager.openWindow( publishDraftWindow );
	}

	// Point d'accès pour [[MediaWiki:Gadget-PublierBrouillonInit.js]].
	window.ShowPublishDraftDialog = showPublishDraftDialog;
}() );