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.
/* jshint esversion: 6 */
/**
 * @name DPH.js
 *
 * Ajoute un lien à l'interface qui permet
 * de faire une demande de purge d'historique
 *
 * @param {boolean} window.DPHDebugMode
 *
 * {{Catégorisation JS}}
 */
// <nowiki>
if ( mw.config.get( 'wgNamespaceNumber' ) !== -1 ) {
	mw.loader.using( [ 'mediawiki.util' ], () => {
		const link = mw.util.addPortletLink(
			'p-cactions',
			'#',
			'Masquage',
			'ca-dph',
			'Demander la purge de certaines versions de l\'historique'
		);

		if ( link !== null ) {
			link.addEventListener( 'click', ( e ) => {
				e.preventDefault();
				/**
				 * notifyScriptStop
				 *
				 * @param {string} [textNotif] - Le texte de la notification
				 * @param {string} [typeNotif] - Le type de notification
				 * @param {string} [titleNotif] - Le titre de la notification
				 */
				function notifyScriptStop(
					textNotif = `${mw.config.get( 'wgUserName' )} a demandé l'arrêt du script`,
					typeNotif = 'warn',
					titleNotif = 'Arrêt'
				) {
					mw.notify( textNotif,
						{ type: typeNotif, title: titleNotif, autoHide: false, tag: 'dph-info' }
					);
				}

				/**
				 * editDPHPage
				 *
				 * Modifie la page des demandes de purge d'historique
				 *
				 * @param {string} type - Le type de demande de purge d'historique
				 * @param {string} firstRev - La révision qui ajoute le contenu à masquer
				 * @param {string} secondRev - La révision qui retire le contenu à masquer
				 * @param {string} url - L'URL du site copié
				 */
				function editDPHPage( type, firstRev, secondRev, url ) {
					let internalDPHPageName;
					const api = new mw.Api();

					if ( window.DPHDebugMode === true ) {
						internalDPHPageName = `Utilisateur:${mw.config.get( 'wgUserName' )}/Brouillon`;
					} else {
						internalDPHPageName = 'Wikipédia:Demande de purge d\'historique';
					}
					$( document.getElementById( 'drz-dphSelectRev' ) ).remove();
					$( document.getElementById( 'drz-dphSelectType' ) ).remove();
					if ( type === 'copyvio' ) {
						const reqText =
`{{DPH début|traitée=|date=<!--~~~~~-->}}

'''Motif :''' [[Wikipédia:Droit d'auteur|Violation de copyright]]

'''Site web copié :''' ${url}

'''Historique :'''
* ${secondRev}
* ${firstRev}

Merci, ~~~~
{{DPH fin}}`;
						api.newSection(
							internalDPHPageName,
							'{{a-court|' + mw.config.get( 'wgPageName' ) + '}}',
							reqText,
							{ nocreate: true }
						).then( () => {
							notifyScriptStop( $( '<p>' ).html( 'Demande déposée sur <a href="/wiki/Wikipédia:Demande de purge d\'historique">Wikipédia:Demande de purge d\'historique</a>' ), 'success', 'Requête effectuée' );
						}, () => {
							notifyScriptStop( $( '<p>' ).html( 'La demande n\'a pas été traitée en raison d\'une erreur inconnue' ), 'error', 'Erreur' );
						} );
					} else if ( type === 'illegal' ) {
						firstRev = firstRev.replace( /<span class="dph-comment">[^</]*<\/span>$/, '' );
						const reqText =
`{{DPH début|traitée=|date=<!--~~~~~-->}}

'''Motif :''' Contenu illégal

'''Historique :'''
* ${secondRev}
* ${firstRev}
Merci, ~~~~
{{DPH fin}}`;
						api.newSection(
							internalDPHPageName,
							'{{a-court|' + mw.config.get( 'wgPageName' ) + '}}',
							reqText,
							{ nocreate: true }
						).then( () => {
							notifyScriptStop( $( '<p>' ).html( 'Demande déposée sur <a href="/wiki/Wikipédia:Demande de purge d\'historique">Wikipédia:Demande de purge d\'historique</a>' ), 'success', 'Requête effectuée' );
						}, () => {
							notifyScriptStop( $( '<p>' ).html( 'La demande n\'a pas été traitée en raison d\'une erreur inconnue' ), 'error', 'Erreur' );
						} );
					}
				}

				function selectRevisions( query ) {
					const array1 = [],
						array2 = [],
						windowManager = new OO.ui.WindowManager();

					/**
					 * SelectRevisions
					 *
					 * @class
					 * @extends OO.ui.ProcessDialog
					 * @param {Object} config - Configuration du dialogue
					 */
					function SelectRevisions( config ) {
						SelectRevisions.super.call( this, config );
					}
					if ( query.query.pages[ 0 ].missing === true ) {
						return;
					} else {
						const revisions = query.query.pages[ 0 ].revisions;
						revisions.forEach( ( rev, i ) => {
							let username, comment;
							if ( rev.commenthidden === true ) {
								rev.comment = '——————';
							}
							username = rev.user;
							comment = rev.comment;
							if ( username.length >= 20 ) {
								username = `${username.slice( '0', '15' )}…`;
							}
							comment = comment.replace( /^\s*\/\*[^*/]*\*\/\s*/, '' );
							if ( comment.length >= 10 ) {
								comment = `${comment.slice( '0', '10' )}…`;
							}
							array1.push( new OO.ui.RadioOptionWidget( {
								data: `''Premier ajout'' : ([[Spécial:Diff/${rev.revid}/cur|actu]] | [[Spécial:Diff/${rev.revid}|diff]]) ${new Date( rev.timestamp ).toLocaleString()} [[Utilisateur:${rev.user}|]] ([[Discussion utilisateur:${rev.user}|discuter]] | [[Spécial:Contributions/${rev.user}|contributions]]) <small>(${rev.size} octets)</small> <span class="dph-comment">(${rev.comment})</span>`,
								id: `${i}-radioSelect1`
							} ) );
							array2.push( new OO.ui.RadioOptionWidget( {
								data: `''Retrait'' : ([[Spécial:Diff/${rev.revid}/cur|actu]] | [[Spécial:Diff/${rev.revid}|diff]]) ${new Date( rev.timestamp ).toLocaleString()} [[Utilisateur:${rev.user}|]] ([[Discussion utilisateur:${rev.user}|discuter]] | [[Spécial:Contributions/${rev.user}|contributions]]) <small>(${rev.size} octets)</small> (${rev.comment})`,
								id: `${i}-radioSelect2`,
								label: $( `<div>(<a href="/wiki/Spécial:Diff/${rev.revid}/cur">actu</a> | <a href="/wiki/Spécial:Diff/${rev.revid}">diff</a>) ${new Date( rev.timestamp ).toLocaleString()} <a href="/wiki/Utilisateur:${rev.user}" title="${rev.user}">${username}</a> (<a href="/wiki/Discussion utilisateur:${rev.user}">discuter</a> | <a href="/wiki/Spécial:Contributions/${rev.user}">contributions</a>) <span title="Commentaire : ${mw.html.escape( rev.comment )}">(${comment})</span></div>` )// .append( popupButton.$element )
							} ) );
						} );
						const radioSelect1 = new OO.ui.RadioSelectWidget( { items: array1 } ),
							radioSelect2 = new OO.ui.RadioSelectWidget( { items: array2 } ),
							layout = new OO.ui.HorizontalLayout( {
								items: [ radioSelect1, radioSelect2 ]
							} );

						radioSelect1.on( 'select', () => {
							const selectedId = parseInt(
								radioSelect1.findSelectedItem().elementId
							);
							for ( const element of radioSelect2.items ) {
								if ( parseInt( element.elementId ) >= selectedId ) {
									element.setDisabled( true );
								} else if ( parseInt( element.elementId ) < selectedId ) {
									element.setDisabled( false );
								}
							}
						} );

						radioSelect2.on( 'select', () => {
							const selectedId = parseInt(
								radioSelect2.findSelectedItem().elementId
							);
							for ( const element of radioSelect1.items ) {
								if ( parseInt( element.elementId ) <= selectedId ) {
									element.setDisabled( true );
								} else if ( parseInt( element.elementId ) > selectedId ) {
									element.setDisabled( false );
								}
							}
						} );

						OO.inheritClass( SelectRevisions, OO.ui.ProcessDialog );
						SelectRevisions.static.name = 'longProcess';
						SelectRevisions.static.title = 'Révisions';
						SelectRevisions.static.actions = [
							{
								action: 'save', label: 'Continuer',
								icon: 'arrowNext', flags: [ 'primary', 'progressive' ],
								modes: [ 'disabled' ], disabled: true
							},
							{
								action: 'save', label: 'Continuer',
								icon: 'arrowNext', flags: [ 'primary', 'progressive' ],
								modes: [ 'enabled' ], disabled: false
							},
							{
								action: 'close', label: 'Fermer la fenêtre',
								flags: [ 'safe', 'close' ], modes: [ 'disabled', 'enabled' ]
							}
						];
						SelectRevisions.prototype.initialize = function () {
							SelectRevisions.super.prototype.initialize.apply( this, arguments );
							this.content = layout;
							this.$body.append( '<br>' );
							this.$body.append( this.content.$element );
							radioSelect2.on( 'select', () => {
								if ( radioSelect1.findSelectedItem() !== null ) {
									this.actions.setMode( 'enabled' );
								}
							} );
							radioSelect1.on( 'select', () => {
								if ( radioSelect2.findSelectedItem() !== null ) {
									this.actions.setMode( 'enabled' );
								}
							} );
						};
						SelectRevisions.prototype.getSetupProcess = function ( data ) {
							return SelectRevisions.super.prototype
								.getSetupProcess.call( this, data )
								.next( function () {
									this.actions.setMode( 'disabled' );
								}, this );
						};
						SelectRevisions.prototype.getActionProcess = function ( action ) {
							return SelectRevisions
								.super
								.prototype
								.getActionProcess
								.call( this, action )
								.next( function () {
									const dialogAction = this;
									if ( action === 'close' ) {
										dialogAction.close();
										windowManager.destroy();
										notifyScriptStop();
									} else if ( action === 'save' ) {
										dialogAction.close();
										selectType(
											radioSelect1.findSelectedItem().data,
											radioSelect2.findSelectedItem().data,
											windowManager
										);
									}
									return SelectRevisions
										.super
										.prototype
										.getActionProcess
										.call( this, action );
								}, this );
						};
						SelectRevisions.prototype.getBodyHeight = function () {
							return this.content.$element.outerHeight( true );
						};

						const dialogLiveAbuseLog = new SelectRevisions( {
							size: 'large',
							id: 'drz-dphSelectRev'
						} );
						$( document.body ).append( windowManager.$element );
						windowManager.addWindows( [ dialogLiveAbuseLog ] );
						windowManager.openWindow( dialogLiveAbuseLog );

					}
				}
				function selectType( firstRev, secondRev, windowManager ) {
					const option1 = new OO.ui.RadioOptionWidget( {
							data: 'illegal',
							label: 'Contenu illégal'
						} ), option2 = new OO.ui.RadioOptionWidget( {
							data: 'copyvio',
							label: 'Violation de copyright'
						} ), radioSelect = new OO.ui.RadioSelectWidget( {
							items: [ option1, option2 ],
							id: 'selectDPHType'
						} ), textInput = new OO.ui.TextInputWidget( {
							type: 'url',
							icon: 'linkExternal',
							label: 'Site copié',
							indicator: 'required',
							placeholder: 'https://example.org'
						} );
					/**
					 * DisplayOptions
					 *
					 * @class
					 * @extends OO.ui.ProcessDialog
					 * @param {Object} config - Configuration du dialogue
					 */
					function DisplayOptions( config ) {
						DisplayOptions.super.call( this, config );
					}
					OO.inheritClass( DisplayOptions, OO.ui.ProcessDialog );

					DisplayOptions.prototype.getBodyHeight = function () {
						return 250;
					};
					DisplayOptions.static.name = 'DisplayOptions';
					DisplayOptions.static.title = 'Motif de la demande de purge d\'historique';
					DisplayOptions.static.actions = [
						{
							action: 'save', label: 'Envoyer',
							icon: 'last', flags: [ 'primary', 'progressive' ],
							modes: [ 'disabled' ], disabled: true
						},
						{
							action: 'save', label: 'Envoyer',
							icon: 'last', flags: [ 'primary', 'progressive' ],
							modes: [ 'enabled' ], disabled: false
						},
						{
							action: 'close', label: 'Fermer la fenêtre',
							flags: [ 'safe', 'close' ], modes: [ 'disabled', 'enabled' ]
						},
						{
							action: 'other', label: 'Retour',
							icon: 'arrowPrevious', modes: [ 'disabled', 'enabled' ]
						}
					];

					DisplayOptions.prototype.initialize = function () {
						DisplayOptions.super.prototype.initialize.apply( this, arguments );
						this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
						this.content.$element.append( radioSelect.$element );
						this.$body.append( this.content.$element );
						$( radioSelect.$element ).after( textInput.$element );
						$( textInput.$element ).hide();
						radioSelect.on( 'select', () => {
							if ( radioSelect.findSelectedItem().data === 'copyvio' ) {
								$( textInput.$element ).show();
								if ( Boolean( textInput.getValue() ) === true ) {
									textInput.getValidity().then(
										() => {
											this.actions.setMode( 'enabled' );
										},
										() => {
											this.actions.setMode( 'disabled' );
										}
									);
								} else {
									this.actions.setMode( 'disabled' );
								}
							} else {
								this.actions.setMode( 'enabled' );
								$( textInput.$element ).hide();
							}
						} );
						textInput.on( 'change', () => {
							if ( Boolean( textInput.getValue() ) === true ) {
								textInput.getValidity().then(
									() => {
										this.actions.setMode( 'enabled' );
									},
									() => {
										this.actions.setMode( 'disabled' );
									}
								);
							} else {
								this.actions.setMode( 'disabled' );
							}
						} );
					};
					DisplayOptions.prototype.getSetupProcess = function ( data ) {
						return DisplayOptions.super.prototype
							.getSetupProcess.call( this, data )
							.next( function () {
								this.actions.setMode( 'disabled' );
							}, this );
					};
					DisplayOptions.prototype.getActionProcess = function ( action ) {
						return DisplayOptions.super.prototype.getActionProcess.call( this, action )
							.next( function () {
								const dialogAction = this;
								if ( action === 'close' ) {
									dialogAction.close();
									windowManager.destroy();
									notifyScriptStop();
								} else if ( action === 'save' ) {
									if ( radioSelect.findSelectedItem().data === 'illegal' ) {
										dialogAction.close();
										windowManager.destroy();
										editDPHPage( 'illegal', firstRev, secondRev );
									} else if ( radioSelect.findSelectedItem().data === 'copyvio' ) {
										dialogAction.close();
										windowManager.destroy();
										editDPHPage( 'copyvio', firstRev, secondRev, textInput.getValue() );
									}
								} else if ( action === 'other' ) {
									dialogAction.close();
									windowManager.openWindow( 'longProcess' );
								}
								return DisplayOptions
									.super
									.prototype
									.getActionProcess
									.call( this, action );
							}, this );
					};
					if ( document.getElementById( 'drz-dphSelectType' ) === null ) {
						const dialog = new DisplayOptions( {
							id: 'drz-dphSelectType'
						} );
						windowManager.addWindows( [ dialog ] );
					}
					windowManager.openWindow( 'DisplayOptions' );
				}
				/**
				 * createData
				 *
				 * Génère les données à insérer dans la demande de purge d'historique
				 */
				function createData() {
					new mw.Api().get( {
						action: 'query',
						format: 'json',
						prop: 'revisions',
						titles: mw.config.get( 'wgPageName' ),
						formatversion: '2',
						rvprop: 'ids|timestamp|comment|user|size',
						rvlimit: '500'
					} ).then( selectRevisions );
				}
				mw.loader.using( [
					'mediawiki.api', 'mediawiki.notification', 'oojs-ui-windows',
					'oojs-ui.styles.icons-editing-core', 'oojs-ui.styles.icons-movement'
				], () => {
					OO.ui.confirm(
						'Souhaitez-vous demander une purge d\'historique ?'
					).then( ( response ) => {
						if ( response === true ) {
							createData();
						} else {
							notifyScriptStop();
						}
					} );
				} );
			} );
		}
	} );
}
// </nowiki>