MediaWiki

Gadget-LinguaImporter.js

Revision as of 21:46, 6 January 2022 by Yug (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Note: After saving, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
/* ************************************************************************** */
// Description: Adds to the "Actions" menu (top right) a gadget to import a new language. Administrators only.
// Usage: open Special:Preferences#mw-prefsection-gadgets > select "LanguageImporter"
// See also : [[Help:Add_a_new_language]]

mw.loader.using( [ 'oojs-ui', 'ext.recordWizard.wikibase', 'ext.recordWizard.widgets', 'wikibase.api.RepoApi', 'mediawiki.ForeignApi', 'mediawiki.widgets' ], function() {
	'use strict';

	// Messages
	const messages = {
		'fr': {
			'linguaimporter': 'LinguaImporter',
			'linguaimporter-action-import': 'Importer',
			'linguaimporter-action-cancel': 'Annuler',
			'linguaimporter-field-wd': 'Élément Wikidata',
			'linguaimporter-portlet-title': 'Importer une langue',
			'linguaimporter-notify-success': 'Langue importée avec succès - [[$1]]',
		},
		'en': {
			'linguaimporter': 'LinguaImporter',
			'linguaimporter-action-import': 'Import',
			'linguaimporter-action-cancel': 'Cancel',
			'linguaimporter-field-wd': 'Wikidata item',
			'linguaimporter-portlet-title': 'Import a language',
			'linguaimporter-notify-success': 'Language successfuly imported - [[$1]]',
		}
	};
	mw.messages.set( messages.en );
	var lang = mw.config.get( 'wgUserLanguage' );
	if ( lang !== 'en' && lang in messages ) {
		mw.messages.set( messages[ lang ] );
	}


	// Instanciate LinguaImporter and add it to MediaWiki's UI
	$( function ( $ ) {
	    var instanceLinguaImporter,
			instanceWindowManager = new OO.ui.WindowManager(),
		$portlet = $( '<a href="#">' + mw.msg( 'linguaimporter-portlet-title' ) + '</a>' );
		$( '#actions' ).append( $( '<li>' ).append( $portlet ) );
	    $( 'body' ).append( instanceWindowManager.$element );

		$portlet.on( 'click', function ( e ) {
			e.preventDefault();
			if ( instanceLinguaImporter === undefined ) {
			    instanceLinguaImporter = new LinguaImporter();
			    instanceWindowManager.addWindows( [ instanceLinguaImporter ] );
			}
	        instanceLinguaImporter.open();
		} );
	} );

	var LinguaImporter = function() {
		// Initialize config
		var config = { size: 'large' };

		// Parent constructor
		LinguaImporter.parent.call( this, config );

		// Properties
		this.api = new mw.Api( { timeout: 7000 } );
		this.wikidataApi = new mw.ForeignApi( 'https://www.wikidata.org/w/api.php', {
			    anonymous: true,
			    parameters: { origin: '*' },
			    ajax: { timeout: 10000 }
		    } );
		this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
	    this.layout;
	    this.$body;
	};


	/* Setup */

	OO.inheritClass( LinguaImporter, OO.ui.ProcessDialog );

	/* Static Properties */

	LinguaImporter.static.name = 'linguaimporter';
	LinguaImporter.static.title = mw.msg( 'linguaimporter' );
	LinguaImporter.static.actions = [
		{ action: 'import', label: mw.msg( 'linguaimporter-action-import' ), flags: [ 'primary', 'progressive' ] },
		{ action: 'cancel', label: mw.msg( 'linguaimporter-action-cancel' ), flags: [ 'safe', 'back' ] }
	];




	/* ProcessDialog-related Methods */

	/**
	 * Build the interface displayed inside the ProcessDialog box.
	 */
	LinguaImporter.prototype.initialize = function () {
		LinguaImporter.parent.prototype.initialize.apply( this, arguments );

		this.wdInput = new mw.recordWizard.widgets.WikidataSearchWidget( {
			$overlay: $( 'body' )
		} );

		this.layout = new OO.ui.Widget( {
			content: [
				new OO.ui.FieldLayout(
					this.wdInput, {
						align: 'top',
						label: mw.msg( 'linguaimporter-field-wd' ),
					}
				)
			],
		} );

		this.content.$element.append( this.layout.$element );
		this.$body.append( this.content.$element );

		this.updateSize();
	};


	/**
	 * Get a process for taking action.
	 *
	 * This method is called within the ProcessDialog when the user clicks
	 * on an action button (the one defined in LinguaImporter.static.actions).
	 * Here is defined in which order each method of the category moving
	 * process is called.
	 * @param {string} action Name of the action button clicked.
	 * @return {OO.ui.Process} Action process.
	 */
	LinguaImporter.prototype.getActionProcess = function ( action ) {
		var process = new OO.ui.Process(),
		    WID, wikidataItem;

		if ( action === 'import' ) {
		    WID = this.wdInput.getData();
		    wikidataItem = new mw.recordWizard.wikibase.Item( WID );

	        process.next( wikidataItem.getFromApi.bind( wikidataItem, this.wikidataApi ) );
	        process.next( this.createLang.bind( this, wikidataItem ) );
	        process.next( this.success.bind( this ) );
		}
		process.next( this.closeDialog, this );

		return process;
	};

	/**
	 * Close the window.
	 *
	 * @return {jQuery.Promise} Promise resolved when window is closed
	 */
	LinguaImporter.prototype.closeDialog = function () {
		var dialog = this;

		var lifecycle = dialog.close();

		return lifecycle.closed;
	};

	/**
	 * Get the height of the window body.
	 * Used by the ProcessDialog to set an accurate height to the dialog.
	 *
	 * @return {number} Height in px the dialog should be.
	 */
	LinguaImporter.prototype.getBodyHeight = function () {
		return this.content.$element.outerHeight( true );
	};



	LinguaImporter.prototype.createLang = function ( wikidataItem ) {
		var isoStatement, wmlangStatement, wmInstanceOfStatement, newMediaTypeStatement,
			newItem = new mw.recordWizard.wikibase.Item(),
			dialog = this;

		newItem.labels = wikidataItem.getLabels();
		newItem.descriptions = wikidataItem.getDescriptions();
		newItem.aliases = wikidataItem.getAliases();

		// instance of = language
		newItem.addStatement( new mw.recordWizard.wikibase.Statement( 'P2' ).setType( 'wikibase-item' ).setValue( 'Q4' ) );

		// wikidata id
		newItem.addStatement( new mw.recordWizard.wikibase.Statement( 'P12' ).setType( 'external-id' ).setValue( wikidataItem.getId() ) );

		// ISO 639-3
		isoStatement = wikidataItem.getStatements( 'P220' );
		if ( isoStatement !== null ) {
			newItem.addStatement( new mw.recordWizard.wikibase.Statement( 'P13' ).setType( 'external-id' ).setValue( isoStatement[ 0 ].getValue() ) );
		}
				
		//Commons category containing all recordings of the language
		if ( isoStatement !== null ) {
			newItem.addStatement( new mw.recordWizard.wikibase.Statement( 'P26' ).setType( 'external-id' ).setValue( isoStatement[ 0 ].getValue() ) );
		}

		// Wikimedia language code
		wmlangStatement = wikidataItem.getStatements( 'P424' );
		if ( wmlangStatement !== null ) {
			newItem.addStatement( new mw.recordWizard.wikibase.Statement( 'P17' ).setType( 'external-id' ).setValue( wmlangStatement[ 0 ].getValue() ) );
		}

		// Media type (depending on whether it is a sign language or not)
		wmInstanceOfStatement = wikidataItem.getStatements( 'P31' );
		newMediaTypeStatement = new mw.recordWizard.wikibase.Statement( 'P24' ).setType( 'wikibase-item' ).setValue( 'Q88889' ); // audio
		if ( wmInstanceOfStatement !== null ) {
			if ( wmInstanceOfStatement[ 0 ].getValue() === 'Q33302' ) {
				newMediaTypeStatement = new mw.recordWizard.wikibase.Statement( 'P24' ).setType( 'wikibase-item' ).setValue( 'Q88890' ); // video
			}
		}
		newItem.addStatement( newMediaTypeStatement );

		return newItem.createOrUpdate( this.api ).then( function( data ) {
			console.log( 'https://lingualibre.org/wiki/' + data.entity.id );
			dialog.newEntityId = data.entity.id;
		} );
	};

	LinguaImporter.prototype.success = function () {
		mw.notify( mw.message( 'linguaimporter-notify-success', this.newEntityId ).text() );
	};
} );