MediaWiki

Difference between revisions of "Gadget-ExternalTools.js"

m

Revision as of 18:14, 16 December 2018

'use strict';

if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'RecordWizard' ) {
	mw.loader.using( 'ext.recordWizard.generator', function() {
		var PETSCAN_URL = 'petscan.wmflabs.org/',
			rw = mw.recordWizard;

		rw.generator.PetScan = function ( config ) {
			rw.generator.Generator.call( this, config );
		};

		OO.inheritClass( rw.generator.PetScan, rw.generator.Generator );

		// This line defines an internal name for the generator
		rw.generator.PetScan.static.name = 'petscan';

		// And this one defines the name for the generator which will be displayed in the UI
		rw.generator.PetScan.static.title = 'PetScan';

		rw.generator.PetScan.prototype.initialize = function () {
			// The two text fields
			this.urlField = new OO.ui.TextInputWidget();
			this.limitField = new OO.ui.NumberInputWidget( { min: 1, max: 2000, value: 500, step: 10, pageStep: 100, isInteger: true } );

			// The custom layout
			this.layout = new OO.ui.Widget( {
				content: [
					new OO.ui.FieldLayout( this.urlField, {
						align: 'top',
						label: 'PetScan URL:'
					} ),
					new OO.ui.FieldLayout(
						this.limitField, {
							align: 'top',
							label: mw.message( 'mwe-recwiz-nearby-limit' ).text()
						}
					)
				]
			} );

			// To be displayed, all the fields/widgets/... should be appended to "this.content.$element"
			this.content.$element.append( this.layout.$element );

			// Do not remove this line, it will initialize the popup itself
			rw.generator.Generator.prototype.initialize.call( this );
		};

		rw.generator.PetScan.prototype.fetch = function () {
			// Get the values of our text fields
			var generator = this,
				url = this.urlField.getValue(),
				limit = parseInt( this.limitField.getValue() );

			/*
			 * TODO:
			 * - list of turnkey urls
			 */

			// Initialize a new promise
			this.deferred = $.Deferred();

			// Initialize our word list
			this.list = [];

			// Check if the given URL refers to petscan
			if ( url.lastIndexOf( 'http://' + PETSCAN_URL, 0 ) !== 0 && url.lastIndexOf( 'https://' + PETSCAN_URL, 0 ) !== 0 ) {
				this.deferred.reject( new OO.ui.Error( 'This is not a petscan URL...' ) );
				return this.deferred.promise();
			}

			this.lockUI();

			// We will do an AJAX request to petscan's API
			$.get( url + '&output_compatability=quick-intersection&format=json&doit=' ).then( function ( data ) {
				var i, page, ns, element, property,
					prefix = '',
					project = mw.util.getParamValue( 'project', data.query ),
					language = mw.util.getParamValue( 'language', data.query );

				// Check whether the response looks fine or not
				if ( data.status !== 'OK' ) {
					generator.deferred.reject( new OO.ui.Error( 'Petscan outputs something weird with this URL, check it and come back afterwards.' ) );
				}

				// For projects that have a custom property, select it
				switch ( project ) {
					case 'wikipedia':
						property = 'P19';
						prefix = language + ':';
						break;
					case 'wiktionary':
						property = 'P20';
						prefix = language + ':';
						break;
				}

				// Parse the complete response (or at least until the limit is reached)
				for ( i = 0; i < data.pages.length && i < limit; i++ ) {
					page = data.pages[ i ];

					element = { text: page.page_title.replace( /_/g, ' ' ) };
					if ( property !== undefined ) {
						ns = ( page.page_namespace !== 0 ? data.namespaces[ page.page_namespace ] : '' );
						element[ property ] = prefix + ns + page.page_title;
					}

					generator.list.push( element );
				}

				generator.deferred.resolve();
			} ).fail( function ( error ) {
				// If something goes wrong, we reject our promise
				// So the process stops and our popup shows the error message
				generator.deferred.reject( new OO.ui.Error( error ) );
			} );

			// At this point we're not done yet, make the dialog closing process
			// to wait the promise to be resolved or rejected
			this.deferred.then( this.unlockUI.bind( this ), this.unlockUI.bind( this ) );
			return this.deferred.promise();
		};

		rw.generator.PetScan.prototype.lockUI = function () {
			this.urlField.setDisabled( true );
			this.limitField.setDisabled( true );
		};

		rw.generator.PetScan.prototype.unlockUI = function () {
			this.urlField.setDisabled( false );
			this.limitField.setDisabled( false );

			this.getActions().get( { actions: 'save' } )[ 0 ].setDisabled( false );
		};

	} );
}