User:Robmoen/fixmeGadget.js

From mediawiki.org

Note: After publishing, 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: Press Ctrl-F5.
// Avoid adding whatlinkshere: <nowiki>
(function( mw, $ ){
    function FIXME() {
		var namespace = mw.config.get('wgCanonicalNamespace');
		var title = this.page = mw.config.get('wgTitle');

		// config
		this.content = null;
		this.template = null;

		if (namespace.length > 0){
			this.page = namespace + ':' + title;
		} else {
			this.page = title;
		}
		
		this.params = {
			'actions': ['delete', 'archive', 'keep'], //radio
			'options': ['expand', 'update', 'rename'] //checkbox
		};
		this.user = {
			groups: mw.config.get( 'wgUserGroups' )
		};
		this.tplLeft = '{{fixme|';
		this.tplRight = '}}';

		// build tools only for sysop
		if ($.inArray('sysop', this.user.groups) !== -1) {
			// create tool
			this.$toolbox = this.buildToolbox();
			$('#contentSub').after( this.$toolbox );

			// load template params
			this.loadTemplate();
		}
		
	}

	FIXME.prototype.buildToolbox = function(){
		var _this = this;
		var $toolbox =
			$('<div />')
				.attr('id', 'FixmeToolbox')
				.css({
					'border': '2px solid #0645AD'
				})
				.append(
					$('<div />')
						.css({
							'background-color': '#0645AD',
							'font-size': '14px',
							'color': '#FFF',
							'padding': '5px'
						})
						.text("SYSOP Review")
				)
				.append(
					$('<div />')
						.attr('id', 'FixmeToolboxActions')
						.css({
							'padding': '5px'
						})
				).append(
					$('<div />')
						.attr('id', 'FixmeToolboxOptions')
						.css({
							'padding': '5px'
						})
						.hide()
				).append(
					$('<div />')
						.css({
							'padding': '5px'
						})
						.attr('id', 'FixmeToolboxControls')
				);

		//build the actions
		$.each(this.params.actions, function(i, action){
			$toolbox
				.find('#FixmeToolboxActions')
				.append(
					$('<input />')
						.attr({
							'id': 'FixmeAction-'+action,
							'type': 'radio',
							'name': 'FixmeActionOpt',
							'value': action
						}).css({
							'margin': '5px'
						}).change(function ( e ){
							if ( $(this).attr('value') === 'keep' ) {
								$('#FixmeToolboxOptions').show();
							} else {
								$('#FixmeToolboxOptions').hide();
							}
						})
				).append(
					$('<label />')
						.attr('for', 'FixmeAction-'+action)
						.text( action )
				);
		});

		//build the options
		$.each(this.params.options, function(i, opt){
			$toolbox
				.find('#FixmeToolboxOptions')
				.append(
					$('<input />')
						.attr({
							'id': 'FixmeOption-'+opt,
							'type': 'checkbox'
						}).css({
							'margin': '5px'
						})
				).append(
					$('<label />')
						.attr('for', 'FixmeOption-'+opt)
						.text( opt )
			);
		});

		// add button

		$toolbox
			.find('#FixmeToolboxControls')
			.append(
				$('<button />')
					.text('Modify')
					.click(function(){
						_this.saveTemplate();
					})
			).append(
				$('<span />')
			);

		return $toolbox;
	};

	FIXME.prototype.getPages = function ( titles, callback ) {
		var pagesQuery = $.isArray(titles) ? titles.join('|') : titles;
		$.ajax({
			url: mw.util.wikiScript( 'api' ),
			data: {
				action: 'query',
				format: 'json',
				titles: pagesQuery,
				prop: 'revisions',
				rvprop: 'content'
			},
			dataType: 'json',
			type: 'GET',
			cache: 'false',
			success: function (data) {
				if ( data && data.query && data.query.pages ) {
					// return pages to callback
					if( typeof callback === 'function') {
						callback( data.query.pages );
					}
				}
			},
			error: function () {
				if( typeof callback === 'function') {
					callback( {} );
				}
			}
		});
	};

	FIXME.prototype.loadTemplate = function () {
		var _this = this;

		var properties = [];
		this.getPages(this.page, function( pages ){
			
			for (var p in pages){
				if ( pages[p].revisions !== undefined ) {
					_this.scrubPage( pages[p], _this.tplLeft, updateToolbox );
				} else {
					//new page, do nothing
					return;
				}
			}
			// look for stuff in the page
			
			// scrub page callback
			function updateToolbox( title, found ) {
				var action;
				if ( found.length > 0 ) {
					//store the template str
					_this.template = found[0];
					//uses first use case of template on page
					properties = _this.getParamsFromTemplate( found[0] );

					for (var p = 0; p < properties.length; p++) {
						if (p === 0) {
							$( '#FixmeAction-' + properties[p] ).click();
							continue;
						} else {
							$( '#FixmeOption-' + properties[p] )
								.prop('checked', true);
						}
				
					}

				}
			}

		});
	};

	FIXME.prototype.getParamsFromTemplate = function( template ){
		return template
			.replace(
				this.tplLeft, ''
			).replace(
				this.tplRight, ''
			).replace(
				'\n', ''
			).split(
				'|'
			);
	};

	FIXME.prototype.saveTemplate = function () {
		var _this = this;
		var action = $('input[name="FixmeActionOpt"]:checked').val();
		//build new template from toolbox
		var newTemplate =
			this.tplLeft +
			action;

		if (action === 'keep') {
			newTemplate += getOptions();
		}
			
		newTemplate += this.tplRight;

		// if content replace old template with new template
		if ( this.content ) {
			if ( this.template ) {
				this.content =
					this.content
						.replace( this.template, newTemplate );
			} else {
				// no template so we just append one to the page
				this.content += newTemplate;
			}
		} else {
			// if the page had no content before, put the template here anyway
			this.content = newTemplate;
		}
		
		//save the page

		this.editPage(function () {
			_this.$toolbox
				.find('#FixmeToolboxControls span')
				.text('Saved!')
				.css('color', 'green');
		});

		function getOptions() {
			var str = '';
			_this.$toolbox
				.find('input[type=checkbox]:checked')
				.each(function(){
					str += '|' + $(this).next().text();
				});
			return str;
		}
		
		// write the page
	};

	FIXME.prototype.scrubPage = function ( page, lookFor, callback ) {
		var lines, i;
		var found = [];
		var content = page.revisions[0]['*'];
		this.content = content;
		var title = page.title;

		if ( content.length > 0 ) {
			lines = content.split(/\n/);
			// Loop through lines
			for ( i = 0; i < lines.length; i++ ) {
				if ( lines[i].indexOf( lookFor ) !== -1 ) {
					found.push(
						lines[i]
					);
				}
			}
			callback ( title, found );
		}
	};


	FIXME.prototype.editPage = function ( callback ) {
		var _this = this,
			summary = 'fixme template modified by SYSOP';

		// Send the wikitext to the parser for rendering
		$.ajax({
			url: mw.util.wikiScript( 'api' ),
			data: {
				action: 'edit',
				// Project page name...
				title: this.page,
				//appendtext: this.wikitext,
				text: this.content,
				format: 'json',
				summary: summary,
				notminor: true,
				token: mw.user.tokens.get( 'editToken' )
			},
			dataType: 'json',
			type: 'POST',
			success: function ( data ) {
				// goto the page for now
				if (data && data.edit && data.edit.result === 'Success') {
					callback ( data.edit.result );
				}
			}
		});
	};

	mw.loader.using(['mediawiki.util'], function () {
		$(document).ready(function () {
			new FIXME();
		});
	});

})( mediaWiki, jQuery );