User:Ricordisamoa/ShouldBeSVG.js

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
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.
/* <nowiki>
 * ShouldBeSVG.js
 * allows to quickly add the {{Convert to SVG}} template to file description pages
 * @author [[User:Ricordisamoa]]
*/
/* global $, mw, OO */
$( function () {
	'use strict';

	if ( mw.config.get( 'wgNamespaceNumber' ) !== 6 || !/^(png|jpe?g|tiff?|gif)/i.test( mw.config.get( 'wgPageName' ).split( '.' ).slice( -1 )[ 0 ] ) ) {
		return;
	}
	mw.loader.using( [ 'mediawiki.util', 'jquery.ui', 'oojs-ui-windows' ], function () {
		var cat = {
			alphabet: {
				desc: 'character images, font examples, etc.',
				example: '2D5A.png'
			},
			architecture: {
				desc: 'architecture blueprints',
				example: 'BourgesDB362.jpg'
			},
			art: {
				desc: 'simple images based on artwork, or otherwise related to culture and art',
				example: 'Jimbo vector trace.png'
			},
			biology: {
				desc: 'animal/plant diagrams, human anatomy, anything biological in nature',
				example: 'Brain limbicsystem.jpg'
			},
			chemical: {
				desc: 'only for structural formulae, especially skeletal formulae',
				example: '2-Pyridone-NMR.png'
			},
			chemistry: {
				desc: 'for all other chemistry related images',
				example: 'AtomicOrbital n5 l1.png'
			},
			circuit: {
				desc: 'electronic circuit diagrams, etc.',
				example: 'Biased stacked TL squaring.png'
			},
			'coat of arms': {
				desc: 'coats of arms',
				example: '200px-Aldeaseca de la Frontera (Salamanca) - Escudo.png'
			},
			diagram: {
				desc: 'diagrams that do not fit any other subcategory',
				example: 'ALSEP Solar Wind Spectrometer.gif'
			},
			flag: {
				desc: 'flags',
				example: 'Banderamotilla.gif'
			},
			graph: {
				desc: 'visual plots of data',
				example: 'Accionariat.GIF'
			},
			icon: {
				desc: 'icons, generally ones you could see being used as computer desktop icons, otherwise \'symbol\' may be better',
				example: 'Crystal 128 forward green.png'
			},
			logo: {
				desc: 'logos, or images intended to be logos',
				example: 'Airwatch logo.png'
			},
			map: {
				desc: 'maps',
				example: '1908 Summer Olympic games countries.png'
			},
			math: {
				desc: 'mathematical content (s.a. \'should use TeX\')',
				example: 'Clairaut1.png'
			},
			'military insignia': {
				desc: 'military insignia',
				example: '2-8MARINES.png'
			},
			'musical notation': {
				desc: 'musical scales, notes, etc. equivalent to {{ConvertToSVG-MN}}',
				example: 'Alternate augmented ninth chord on C.png'
			},
			physical: {
				desc: 'supposedly for "realistic images of physical objects, people, etc." but has been used more for physical science diagrams',
				example: '--'
			},
			text: {
				desc: 'character images, font examples, etc.',
				example: 'Drop initial example.jpg'
			}
		},
		getLatestRevision = function ( title ) {
			return new mw.Api().get( {
				action: 'query',
				formatversion: 2,
				titles: title,
				prop: 'revisions',
				rvprop: 'content|timestamp',
				rvlimit: 1
			} )
			.then( function ( data ) {
				if (
					data &&
					data.query &&
					data.query.pages &&
					data.query.pages.length === 1 &&
					data.query.pages[ 0 ].revisions &&
					data.query.pages[ 0 ].revisions.length === 1
				) {
					return data.query.pages[ 0 ].revisions[ 0 ];
				}
				return $.Deferred().reject();
			} );
		},
		insertTemplate = function ( type ) {
			var typeExt;
			if ( typeof type === 'undefined' ) {
				type = '';
			}
			typeExt = '';
			if ( type !== '' ) {
				typeExt = '|[[Category:' + type + ' images that should use vector graphics|' + type + ']]';
				type = '|' + type;
			}
			getLatestRevision( mw.config.get( 'wgPageName' ) )
			.done( function ( rev ) {
				var newText = '{{Convert to SVG' + type + '}}\n' + rev.content.replace( /(^|\n)([^\n]*)\{\{\s*([Ss]houldBeSVG|[Ss]hould be SVG|[Cc]onvert to SVG|[Cc]onvertToSVG|[Vv]ectorize|[Ss]vg|[Ss]VG|[Tt]oSVG)\s*(\|[\S\s]*?)?\}\}(\n|$)/g, function ( m, p1, p2, p3, p4, p5 ) {
					return ( p2 === '' && p5 === '\n' ) ? p1 : ( p2 + p5 );
				} );
				new mw.Api().postWithToken( 'csrf', {
					action: 'edit',
					formatversion: 2,
					text: newText,
					basetimestamp: rev.timestamp,
					title: mw.config.get( 'wgPageName' ),
					summary: '[[User:Ricordisamoa/ShouldBeSVG|added]] template {{[[Template:Convert to SVG|Convert to SVG]]' + typeExt + '}}'
				} )
				.done( function () {
					mw.notify( 'Template added!' );
					setTimeout( function () {
						document.location.reload();
					}, 2500 );
				} )
				.fail( function () {
					mw.notify( 'The ajax request failed.' );
				} );
			} )
			.fail( function () {
				mw.notify( 'The ajax request failed.' );
			} );
		},
		ShouldBeSvgDialog = function ( config ) {
			ShouldBeSvgDialog.parent.call( this, config );
		};
		OO.inheritClass( ShouldBeSvgDialog, OO.ui.ProcessDialog );

		ShouldBeSvgDialog.static.title = 'ShouldBeSVG';
		ShouldBeSvgDialog.static.size = 'full';
		ShouldBeSvgDialog.static.actions = [
			{
				action: 'insert',
				label: 'Insert template',
				flags: [ 'primary', 'constructive' ]
			},
			{
				action: 'cancel',
				label: 'Cancel',
				flags: 'safe'
			}
		];

		ShouldBeSvgDialog.prototype.initialize = function () {
			var $body;

			ShouldBeSvgDialog.parent.prototype.initialize.apply( this, arguments );

			$body = this.$body;

			$body
			.append(
				$( '<table>' )
				.attr( 'id', 'convert-to-svg' )
				.append(
					$( '<tbody>' )
					.append( '<tr>' )
					.append( '<tr>' )
					.append( '<tr>' )
				)
			)
			.append(
				$( '<p>' )
				.hide()
				.append( '<p>You haven\'t specified any value for the template parameter.<br/>' +
				'It is recommended to use it, to ease automatical categorization of images.<br/>' +
				'Do you really want to insert the template?</p>' )
			);
			$.each( cat, function ( k, v ) {
				$( new Image() )
				.data( 'type', k )
				.attr( {
					src: mw.util.getUrl( 'Special:Filepath/' + v.example ),
					width: 120,
					title: k + ': ' + v.desc
				} )
				.appendTo( $body.find( 'tr' ).get( Math.floor( Object.keys( cat ).indexOf( k ) / 7 ) ) );
			} );
			$body.selectable( {
				filter: 'img',
				selected: function () {
					$body.parents( '.ui-dialog' ).find( '.ui-dialog-buttonset button' ).last().button( 'enable' );
				}
			} );
			mw.util.addCSS( 'table#convert-to-svg img{border:2px transparent solid}\ntable#convert-to-svg img.ui-selected{border-color:orange}' );
			this.alreadyAsked = false;
		};

		ShouldBeSvgDialog.prototype.insert = function () {
			var type = this.$body.find( 'tr img.ui-selected' ).data( 'type' );
			if ( type === undefined && this.alreadyAsked === false ) {
				this.$body.find( 'table#convert-to-svg' ).hide().next( 'p' ).show();
				this.alreadyAsked = true;
			} else {
				this.close();
				insertTemplate( type );
			}
		};

		ShouldBeSvgDialog.prototype.getActionProcess = function ( action ) {
			if ( action === 'insert' ) {
				return new OO.ui.Process( this.insert, this );
			}
			if ( action === 'cancel' ) {
				return new OO.ui.Process( this.close() );
			}

			return ShouldBeSvgDialog.parent.prototype.getActionProcess.call( this, action );
		};

		$( mw.util.addPortletLink( 'p-cactions', '#', 'ShouldBeSVG', 'ShouldBeSVG', 'Add [[Template:Convert to SVG]]' ) )
		.click( function ( event ) {
			var windowManager, dialog;
			event.preventDefault();
			windowManager = new OO.ui.WindowManager();
			$( 'body' ).append( windowManager.$element );
			dialog = new ShouldBeSvgDialog( {} );
			windowManager.addWindows( [ dialog ] );
			windowManager.openWindow( dialog );
		} );
	} );
} );
// </nowiki>