User:Antoine WMFr/scripts/AutotranslateHelper.js

Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
/*
* AutotranslateHelper
*
* Creates an {{autotranslate}} template very quickly, by automating the creation
* of all required subpages.
* To launch the process, go on [[User:Antoine WMFr/AutotranslateHelper]]
*
* Author : [[User:0x010C]]
* Creation : 31 March 2017
* Last edit : 3 April 2017
*/
//<nowiki>

mw.loader.using( [ 'mediawiki.util', 'oojs-ui' ], function () {
	const baseTemplate = '{{autotranslate|base=$(title)}}<includeonly>$(categories)</includeonly><noinclude>\n{{documentation}}\n</noinclude>';
	const categoryTemplate = '\n[[Category:$(category)|{{PAGENAME}}]]';
	const layoutTemplate = '$(layout)<noinclude>\n[[Category:Layout templates|{{PAGENAME}}]]\n</noinclude>';
	const langSubpageTemplate = '{{$(title)/layout|lang={{subst:SUBPAGENAME}}\n$(params)\n}}<noinclude>\n{{translated tag|source}}\n</noinclude>';
	const langTemplate = '{{subst:lle}}';
	const docTemplate = '{{TemplateBox\n|name=$(title)\n|desc=$(description)\n|namespace=$(namespace)\n|usergroup=$(usergroup)\n|placement=$(placement)\n|usage-notes=\n|type=\n|example=\n|i18n-method=autotranslate\n|i18n-desc=\n|seealso=$(seealso)\n|setscats=$(setscats)\n|lines=\n|shorthand=\n|relieson=\n}}';
	const setcatsTemplate = '\n*{{cl|$(category)}}';

	const messages = {
		'en': {
			'athelper-save': 'Generate!',
			'athelper-notif-progress': 'Template $1 out of $2 created.',
			'athelper-notif-title': 'Generation in progress...',
			'athelper-pageexists': 'There is already a template with this title on Commons...',
			'athelper-error-message': 'Oops... Something wrong happend.',
			'athelper-error-title': 'Error',
			'athelper-error-log': 'Unable to create the page named $1',
			'athelper-success-message': 'The process is over. You will be redirected to the main template page.',
			'athelper-success-title': 'End of the process!',
			'athelper-base-title': 'General settings',
			'athelper-name-label': 'Template title',
			'athelper-name-help': '',
			'athelper-layout-label': 'Layout',
			'athelper-layout-help': '',
			'athelper-parameters-label': 'Layout parameters',
			'athelper-parameters-help': '',
			'athelper-categories-label': 'Categories',
			'athelper-categories-help': '',
			'athelper-langs-label': 'Languages',
			'athelper-langs-help': '',
			'athelper-lang-title': 'Layout`s parameters in language: $1',
			'athelper-doc-title': 'Documentation',
			'athelper-description-label': 'Description',
			'athelper-description-help': '',
			'athelper-namespace-label': 'Namespace',
			'athelper-namespace-help': '',
			'athelper-doc-categories-label': 'Categories',
			'athelper-doc-categories-help': '',
			'athelper-usergroup-label': 'Authorised user group',
			'athelper-usergroup-help': '',
			'athelper-placement-label': 'Placement',
			'athelper-placement-help': '',
			'athelper-seealso-label': 'See also',
			'athelper-seealso-help': '',
		},
		'fr': {
			'athelper-save': 'Générer !',
			'athelper-notif-progress': 'Modèle $1 sur $2 créé.',
			'athelper-notif-title': 'Génération en cours...',
			'athelper-pageexists': 'Une page existe déjà avec ce titre sur Commons...',
			'athelper-error-message': 'Oups... Une erreur innatendu est survenu.',
			'athelper-error-title': 'Erreur',
			'athelper-error-log': 'Impossible de créer la page $1',
			'athelper-success-message': 'Vous allez être redirigé sur la page du modèle principal.',
			'athelper-success-title': 'Génération terminé !',
			'athelper-base-title': 'Configuration général',
			'athelper-name-label': 'Nom',
			'athelper-name-help': 'Titre à donner au modèle principal, SANS le prefix Template:',
			'athelper-layout-label': 'Layout de base',
			'athelper-layout-help': 'Code Wikitext/HTML servant de structure au bandeau. Si vous ne savez pas quoi mettre, songez à utilisez un modèle pré-rempli.',
			'athelper-parameters-label': 'Paramètres dans le layout',
			'athelper-parameters-help': 'Paramètres présents dans le layout, servant à la traduction.',
			'athelper-categories-label': 'Catégories',
			'athelper-categories-help': 'Catégories qui contiendront les pages sur les-quels le modèle sera transclu.',
			'athelper-langs-label': 'Langues à générer',
			'athelper-langs-help': 'Code ISO 639 des langues à traduire dès maintenant.',
			'athelper-lang-title': 'Paramètres du modèle dans la langue : $1',
			'athelper-doc-title': 'Documentation',
			'athelper-description-label': 'Description',
			'athelper-description-help': 'Décrivez le modèle, son but,...',
			'athelper-namespace-label': 'Espace de nom',
			'athelper-namespace-help': 'L\'espace de nom où s\'applique le modèle.',
			'athelper-doc-categories-label': 'Catégories',
			'athelper-doc-categories-help': 'Catégories dans lesquels catégoriser le modèle lui-même (et non les pages transcluant le modèle).',
			'athelper-usergroup-label': 'Groupe d\'utilisateurs autorisé',
			'athelper-usergroup-help': 'Le groupe d\'utilisateurs qui est autorisé à déposer le modèle.',
			'athelper-placement-label': 'Positionnement du modèle',
			'athelper-placement-help': 'Position dans la page où le modèle doit être apposé.',
			'athelper-seealso-label': 'Voir aussi',
			'athelper-seealso-help': 'Lien vers des pages et/ou modèles ayant un lien avec celui-ci.',
		}
	};
	
	mw.messages.set( messages[ 'en' ] );
	var lang = mw.config.get( 'wgUserLanguage' );
	if ( lang && lang != 'en' && lang in messages ) {
		mw.messages.set( messages[ lang ] );
	}
	
	var AutotranslateHelper = function () {
		this.booklet = undefined;
		this.basePage = undefined;
		this.docPage = undefined;
		this.langPages = {};
		this.langCodes = [];
		this.params = [];
		
		this.generateInterface();
		this.fetchPreload();
	};

	AutotranslateHelper.prototype.generateInterface = function () {
		var self = this;
		var saveButton = new OO.ui.ButtonWidget( {
			label: mw.msg( 'athelper-save' ),
			icon: 'next',
			iconTitle: 'Save',
			flags: [ 'primary', 'progressive' ]
		} );
		saveButton.on( 'click', function() {
			mw.loader.using( [ 'mediawiki.api.edit' ], function() {
				self.generateTemplates();
			} );
		} );
		this.booklet = new OO.ui.BookletLayout( { 
			outlined: true
		} );
		$( '#bodyContent' ).empty();
		var buttonsContainer = $( '<div>' ).css( 'text-align', 'right' ).append( saveButton.$element[ 0 ] );
		var mainContainer = $( '<div>' ).css('height', '500px').css( 'border', '1px solid #a2a9b1' ).css( 'border-radius', '2px' ).css( 'position', 'relative' ).append( this.booklet.$element );
		$( '#bodyContent' ).append( buttonsContainer ).append( mainContainer );
		
		this.basePage = new BasePageLayout( this, 'base' );
		this.docPage = new DocPageLayout( this, 'doc' );
		this.booklet.addPages ( [ this.basePage, this.docPage ] );
	};
	AutotranslateHelper.prototype.fetchPreload = function () {
		if ( mw.util.getParamValue( 'preload' ) !== null ) {
			var self = this;
			var preloadPage = mw.util.getParamValue( 'preload' );
			if ( preloadPage[ 0 ] === "/" ) {
				preloadPage = mw.config.get( 'wgPageName' ) + preloadPage;
			}
			var api = new mw.Api();
			api.get( {
				action: 'query',
				prop: 'revisions',
				rvprop: [ 'content' ],
				titles: String( preloadPage ),
				formatversion: '2',
			} ).then( function( data ) {
				preload = JSON.parse( data.query.pages[ 0 ].revisions[ 0 ].content );
				
				self.basePage.nameInput.setValue( preload.title );
				self.basePage.layoutInput.setValue( preload.layout );
				self.basePage.paramsInput.setItemsFromData( preload.parameters );
				self.basePage.categoriesInput.setItemsFromData( preload.categories );
				
				self.docPage.descriptionInput.setValue( preload.doc.description );
				self.docPage.namespaceInput.setValue( preload.doc.namespace );
				self.docPage.usergroupInput.setValue( preload.doc.usergroup );
				self.docPage.placementInput.setValue( preload.doc.placement );
				self.docPage.categoriesInput.setItemsFromData( preload.doc.categories );
				self.docPage.seealsoInput.setValue( preload.doc.seealso );
			} );
		}
	};
	AutotranslateHelper.prototype.updateLangPages= function ( langCodes ) {
		var self = this;
		
		var newCodes = langCodes.filter( function( i ) { return self.langCodes.indexOf( i ) < 0; } );
		$.each( newCodes, function( key, code ) {
			self.addLangPage( code );
		} );
		
		var oldCodes = self.langCodes.filter( function( i ) { return langCodes.indexOf( i ) < 0; } );
		$.each( oldCodes, function( key, code ) {
			self.removeLangPage( code );
		} );
		
		this.langCodes = langCodes;
	};
	AutotranslateHelper.prototype.addLangPage= function ( langCode ) {
		if( this.langPages[ langCode ] === undefined ) {
			langPage = new LangPageLayout( langCode, this.params, { label: langCode } );
			this.langPages[ langCode ] = langPage;
		}
		this.booklet.addPages ( [ this.langPages[ langCode ] ] );
	};
	AutotranslateHelper.prototype.removeLangPage= function ( langCode ) {
		this.booklet.removePages ( [ this.langPages[ langCode ] ] );
	};
	AutotranslateHelper.prototype.updateParams= function ( params ) {
		var self = this;
		
		var newParams = params.filter( function( i ) { return self.params.indexOf( i ) < 0; } );
		$.each( newParams, function( key, param ) {
			$.each( self.langPages, function( key, langPage ) {
				langPage.addParam( param );
			} );
		} );
		
		var oldParams = self.params.filter( function( i ) { return params.indexOf( i ) < 0; } );
		$.each( oldParams, function( key, param ) {
			$.each( self.langPages, function( key, langPage ) {
				langPage.removeParam( param );
			} );
		} );
		
		this.params = params;
	};
	AutotranslateHelper.prototype.generateTemplates = function () {
		var api = new mw.Api();
		var self = this;
		this.nbTemplates = this.langCodes.length + 4;
		this.createdTemplates = 0;
		
		var baseTitle = this.basePage.nameInput.getValue();
		var layout = this.basePage.layoutInput.getValue();
		var categories = this.basePage.categoriesInput.getItemsData();
		
		var description = this.docPage.descriptionInput.getValue();
		var namespace = this.docPage.namespaceInput.getValue();
		var usergroup = this.docPage.usergroupInput.getValue();
		var placement = this.docPage.placementInput.getValue();
		var docCategories = this.docPage.categoriesInput.getItemsData();
		var seealso = this.docPage.seealsoInput.getValue();
		
		var categoriesContent = '';
		var setscats = '';
		var docCategoriesContent = '';
		
		$.each( categories, function( key, category ) {
			categoriesContent += categoryTemplate.replace( '$(category)', category );
			setscats += setcatsTemplate.replace( '$(category)', category );
		} );
		$.each( docCategories, function( key, category ) {
			docCategoriesContent += categoryTemplate.replace( '$(category)', category );
		} );
		
		api.create( 'Template:' + baseTitle, {
			summary: 'Template created using [[User:Antoine_WMFr/AutotranslateHelper|AutotranslateHelper]]',
		}, baseTemplate.replace( '$(title)', baseTitle ).replace( '$(categories)', categoriesContent ) )
		.fail( function( data ) {
			self.error( 'Template:' + baseTitle, data );
		} )
		.then( function() {
			self.log();

			api.create( 'Template:' + baseTitle + '/layout', {
				summary: 'Template created using [[User:Antoine_WMFr/AutotranslateHelper|AutotranslateHelper]]',
			}, layoutTemplate.replace( '$(layout)', layout ) )
			.fail( function( data ) {
				self.error( 'Template:' + baseTitle + '/layout', data );
			} )
			.then( function() {
				self.log();
			} );

			api.create( 'Template:' + baseTitle + '/doc', {
				summary: 'Template created using [[User:Antoine_WMFr/AutotranslateHelper|AutotranslateHelper]]',
			}, docTemplate.replace( '$(title)', baseTitle ).replace( '$(description)', description ).replace( '$(namespace)', namespace ).replace( '$(usergroup)', usergroup ).replace( '$(placement)', placement ).replace( '$(setscats)', setscats ).replace( '$(seealso)', seealso ) )
			.fail( function( data ) {
				self.error( 'Template:' + baseTitle + '/doc', data );
			} )
			.then( function() {
				self.log();
			} );
			
			$.each( self.langCodes, function( key, langCode ) {
				var paramsContent = '';
				$.each( self.params, function(key, param) {
					paramsContent += '\n|' + param + '=' + self.langPages[langCode].paramInputs[param].getValue();
				} );
				
				api.create( 'Template:' + baseTitle + '/' + langCode, {
					summary: 'Template created using [[User:Antoine_WMFr/AutotranslateHelper|AutotranslateHelper]]',
				}, langSubpageTemplate.replace( '$(title)', baseTitle ).replace( '$(params)', paramsContent ) )
				.fail( function( data ) {
					self.error('Template:' + baseTitle + '/' + langCode, data );
				} )
				.then( function() {
					self.log();
				} );
			} );
		} );
	};
	AutotranslateHelper.prototype.log = function() {
		this.createdTemplates++;
		mw.notify( mw.msg( 'athelper-notif-progress', this.createdTemplates, this.nbTemplates ), { title: mw.msg( 'athelper-notif-title' ) } );
		if ( this.createdTemplates +1 === this.nbTemplates ) {
			this.GenerateLastTemplate();
		}
	};
	AutotranslateHelper.prototype.error = function( title, data ) {
		if ( data === 'articleexists' ) {
			OO.ui.alert( mw.msg( 'athelper-pageexists' ), {
				title: mw.msg( 'athelper-error-title' )
			} );
		}
		else {
			OO.ui.alert( mw.msg( 'athelper-error-message' ), {
				title: mw.msg( 'athelper-error-title' )
			} );
		}
		console.log( mw.msg( 'athelper-error-log', title ) );
		console.log( data );
	};
	AutotranslateHelper.prototype.GenerateLastTemplate = function() {
		var api = new mw.Api();
		var self = this;
		
		var baseTitle = this.basePage.nameInput.getValue();
		
		api.create( 'Template:' + baseTitle + '/lang', {
			summary: 'Template created using [[User:Antoine_WMFr/AutotranslateHelper|AutotranslateHelper]]',
		}, langTemplate )
		.fail( function(data) {
			self.error( 'Template:' + baseTitle + '/lang', data );
		} )
		.then( function() {
			mw.notify( mw.msg( 'athelper-success-message' ), { title: mw.msg( 'athelper-success-title' ) } );
			setTimeout( function() {
				window.location.href = mw.util.getUrl( 'Template:' + baseTitle );
			}, 700 );
		} );
	};

	var BasePageLayout = function( autotranslateHelper, name, config ) {
		BasePageLayout.super.call( this, name, config );
		
		this.nameInput = new OO.ui.TextInputWidget( {} );

		this.layoutInput = new OO.ui.TextInputWidget( {
			multiline: true,
			value: '',
			autosize: true,
			rows: 5,
			maxRows: 12,
		} );

		this.paramsInput = new OO.ui.CapsuleMultiselectWidget( {
			label: 'CapsuleMultiselectWidget',
			menu: {
				items: []
			},
			allowArbitrary: true,
			allowDuplicates: false,
		} );
		this.paramsInput.on( 'change', function( data ) {
			if ( data.length === 0 ) {
				autotranslateHelper.updateParams( [] );
			}
			else if ( typeof( data[ 0 ] ) === 'string' ) {
				autotranslateHelper.updateParams( data );
			}
		} );

		this.categoriesInput = new OO.ui.CapsuleMultiselectWidget( {
			label: 'CapsuleMultiselectWidget',
			menu: {
				items: []
			},
			allowArbitrary: true,
			allowDuplicates: false,
		} );
		//TODO: Category search

		this.langsInput = new OO.ui.CapsuleMultiselectWidget( {
			label: 'CapsuleMultiselectWidget',
			menu: {
				items: [
					new OO.ui.MenuOptionWidget( {
						data: 'fr',
						label: 'fr'
					} ),
					new OO.ui.MenuOptionWidget( {
						data: 'en',
						label: 'en'
					} ),
				]
			},
			allowArbitrary: true,
			allowDuplicates: false,
		} );
		this.langsInput.on( 'change', function( data ) {
			if ( data.length === 0 ) {
				autotranslateHelper.updateLangPages( [] );
			}
			else if ( typeof( data[ 0 ] ) === 'string' ) {
				autotranslateHelper.updateLangPages( data );
			}
		} );
		
		// Create a Fieldset layout.
		var fieldset = new OO.ui.FieldsetLayout( { 
			label: mw.msg( 'athelper-base-title' ),
		} );
		
		fieldset.addItems( [ 
			new OO.ui.FieldLayout( this.nameInput, {
				label: mw.msg( 'athelper-name-label' ),
				align: 'left',
				help: mw.msg( 'athelper-name-help' ),
			} ),
			new OO.ui.FieldLayout( this.layoutInput, { 
				label: mw.msg( 'athelper-layout-label' ),
				align: 'left',
				help: mw.msg( 'athelper-layout-help' ),
			} ),
			new OO.ui.FieldLayout( this.paramsInput, { 
				label: mw.msg( 'athelper-parameters-label' ),
				align: 'left',
				help: mw.msg( 'athelper-parameters-help' ),
			} ),
			new OO.ui.FieldLayout( this.categoriesInput, { 
				label: mw.msg( 'athelper-categories-label' ), 
				align: 'left',
				help: mw.msg( 'athelper-categories-help' ),
			} ),
			new OO.ui.FieldLayout( this.langsInput, { 
				label: mw.msg( 'athelper-langs-label' ), 
				align: 'left',
				help: mw.msg( 'athelper-langs-help' ),
			} )
		] );
		
		this.$element.append( fieldset.$element );
	};
	OO.inheritClass( BasePageLayout, OO.ui.PageLayout );
	BasePageLayout.prototype.setupOutlineItem = function () {
		this.outlineItem.setLabel( mw.msg( 'athelper-base-title' ) );
	};

	var DocPageLayout = function( autotranslateHelper, name, config ) {
		DocPageLayout.super.call( this, name, config );
		
		this.descriptionInput = new OO.ui.TextInputWidget( {
			multiline: true,
			autosize: true,
			rows: 4,
		} );

		this.namespaceInput = new OO.ui.DropdownInputWidget( {
			options:[
				{ data: 'all', label: 'all' },
				{ data: 'talks', label: 'talks' },
				{ data: 'contents', label: 'contents' },
				{ data: 'Main', label: 'Main' },
				{ data: 'Talk', label: 'Talk' },
				{ data: 'User', label: 'User' },
				{ data: 'User talk', label: 'User talk' },
				{ data: 'Commons', label: 'Commons' },
				{ data: 'Commons talk', label: 'Commons talk' },
				{ data: 'File', label: 'File' },
				{ data: 'File talk', label: 'File talk' },
				{ data: 'MediaWiki', label: 'MediaWiki' },
				{ data: 'MediaWiki talk', label: 'MediaWiki talk' },
				{ data: 'Template', label: 'Template' },
				{ data: 'Template talk', label: 'Template talk' },
				{ data: 'Help', label: 'Help' },
				{ data: 'Help talk', label: 'Help talk' },
				{ data: 'Category', label: 'Category' },
				{ data: 'Category talk', label: 'Category talk' },
				{ data: 'Creator', label: 'Creator' },
				{ data: 'Creator talk', label: 'Creator talk' },
				{ data: 'Special', label: 'Special' },
			],
		} );

		this.usergroupInput = new OO.ui.DropdownInputWidget( {
			options:[
				{ data: 'all', label: 'all' },
				{ data: 'bot', label: 'bot' },
				{ data: 'sysop', label: 'sysop' },
				{ data: 'bureaucrat', label: 'bureaucrat' },
				{ data: 'checkuser', label: 'checkuser' },
				{ data: 'licensereviewer', label: 'licensereviewer' },
				{ data: 'otrs', label: 'otrs' },
				{ data: 'autoconfirmed', label: 'autoconfirmed' },
				{ data: 'autopatrolled', label: 'autopatrolled' },
				{ data: 'filemover', label: 'filemover' },
				{ data: 'oversight', label: 'oversight' },
				{ data: 'patroller', label: 'patroller' },
				{ data: 'rollbacker', label: 'rollbacker' },
				{ data: 'steward', label: 'steward' },
			],
		} );

		this.placementInput = new OO.ui.DropdownInputWidget( {
			options:[
				{ data: 'top', label: 'top' },
				{ data: 'bottom', label: 'bottom' },
				{ data: 'licence', label: 'licence' },
				{ data: 'source', label: 'source' },
			],
		} );

		this.categoriesInput = new OO.ui.CapsuleMultiselectWidget( {
			label: 'CapsuleMultiselectWidget',
			menu: {
				items: []
			},
			allowArbitrary: true,
			allowDuplicates: false,
		} );
		//TODO: Category search
		
		this.seealsoInput = new OO.ui.TextInputWidget( {
			multiline: true,
			autosize: true,
			rows: 2,
		} );
		
		// Create a Fieldset layout.
		var fieldset = new OO.ui.FieldsetLayout( { 
			label: mw.msg( 'athelper-base-title' ),
		} );
		
		fieldset.addItems( [ 
			new OO.ui.FieldLayout( this.descriptionInput, {
				label: mw.msg( 'athelper-description-label' ),
				align: 'left',
				help: mw.msg( 'athelper-description-help' ),
			} ),
			new OO.ui.FieldLayout( this.namespaceInput, { 
				label: mw.msg( 'athelper-namespace-label' ),
				align: 'left',
				help: mw.msg( 'athelper-namespace-help' ),
			} ),
			new OO.ui.FieldLayout( this.usergroupInput, { 
				label: mw.msg( 'athelper-usergroup-label' ),
				align: 'left',
				help: mw.msg( 'athelper-usergroup-help' ),
			} ),
			new OO.ui.FieldLayout( this.placementInput, { 
				label: mw.msg( 'athelper-placement-label' ),
				align: 'left',
				help: mw.msg( 'athelper-placement-help' ),
			} ),
			new OO.ui.FieldLayout( this.categoriesInput, { 
				label: mw.msg( 'athelper-doc-categories-label' ), 
				align: 'left',
				help: mw.msg( 'athelper-doc-categories-help' ),
			} ),
			new OO.ui.FieldLayout( this.seealsoInput, { 
				label: mw.msg( 'athelper-seealso-label' ), 
				align: 'left',
				help: mw.msg( 'athelper-seealso-help' ),
			} ),
		] );
		
		this.$element.append( fieldset.$element );
	};
	OO.inheritClass( DocPageLayout, OO.ui.PageLayout );
	DocPageLayout.prototype.setupOutlineItem = function () {
		this.outlineItem.setLabel( mw.msg( 'athelper-doc-title' ) );
	};

	var LangPageLayout = function( name, params, config ) {
		LangPageLayout.super.call( this, name, config );
		this.label = config.label;
		this.paramInputs = {};
		this.params = [];

		this.fieldset = new OO.ui.FieldsetLayout( { 
			label: mw.msg( 'athelper-lang-title', config.label ),
		} );

		this.$element.append( this.fieldset.$element );

		var self = this;
		$.each( params, function( key, value ) {
			self.addParam( value );
		} );
	};
	OO.inheritClass( LangPageLayout, OO.ui.PageLayout );
	LangPageLayout.prototype.setupOutlineItem = function () {
		this.outlineItem.setLabel( this.label );
		this.outlineItem.setLevel( 1 );
	};
	LangPageLayout.prototype.addParam = function ( param ) {
		this.params.push( param );
		if ( this.paramInputs[param] === undefined ) {
			this.paramInputs[param] = new OO.ui.TextInputWidget( {} );
		}

		this.fieldset.addItems( [ 
			new OO.ui.FieldLayout( this.paramInputs[ param ], {
				label: '{{{' + param + '}}}',
				align: 'left',
			} ),
		] );
	};
	LangPageLayout.prototype.removeParam = function ( param ) {
		var index = this.params.indexOf( param );
		if (index > -1) {
			this.params.splice(index, 1);
			
			this.fieldset.clearItems();
			var self = this;
			$.each( this.params, function(key, param) {
				self.fieldset.addItems( [ 
					new OO.ui.FieldLayout( self.paramInputs[ param ], {
						label: '{{{' + param + '}}}',
						align: 'left',
					} ),
				] );
			} );
		}
	};

	if ( mw.config.get( 'wgPageName' ) === 'User:Antoine_WMFr/AutotranslateHelper' && mw.config.get( 'wgAction' ) === 'view' ) {
		ah = new AutotranslateHelper();
		window.ah = ah;
	}
});

//</nowiki>