User:Rillke/gallery-sort.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>

$(document).ready(function () {

var imagesByHeading = {};
var headingByImage = {};
var $sortInput = $('<select>');
var toPrepare = [];
var toMove = {};
var sectionsByHeading = {};
var queueLength = 0;

$sortInput.change(function() {
	var $this = $(this),
		f = $this.closest('.gallerytext').data('reFile');

	if ( !(f in toMove) ) {
		queueLength++;
		$('#queueCounter').text(queueLength);
	}
	toMove[f] = {
		to: $this.val()
	};
	sectionsByHeading[$this.val()].append($this.closest('li.gallerybox'));
	if ( queueLength > 15 ) commit();
});

$('.mw-heading2').each(function(l, h) {
	var $h = $(h),
		ht = $.trim($h.find('.mw-headline').text()),
		$gallery = $h.next('ul');

	if (!$gallery.length) return;
	imagesByHeading[ht] = {};
	sectionsByHeading[ht] = $gallery;

	$gallery.find('.gallerybox').each(function(i, e) {
		try {
			$e = $(e);
			var file = mw.Title.newFromImg(
					$e.find('.thumb').find('img') || $('<img>')
				).toText(),
				$gt = $e.find('.gallerytext').data('reFile', file);

			if (!file) return;
			imagesByHeading[ht][file] = {
				name: file,
				$galleryText: $gt
			};
			toPrepare.push($gt);
			headingByImage[file] = ht;
		} catch (ex) {}
	});
});

$.each(imagesByHeading, function( h, file ) {
	$('<option>').text(h).appendTo( $sortInput );
});
$.each(toPrepare, function( i, $gt ) {
	$gt.append( $sortInput.clone( true ).val(
		headingByImage[ $gt.data('reFile') ]
	) );
});

var processing = false;
var sendingRequest = false;
var lastListPageContent = '';
var commit = function() {
	if (processing) return;
	processing = true;
	var doMove = function(pageText) {
		sendingRequest = true;
		toMoveCopy = $.extend( true, {}, toMove );

		if (lastListPageContent && $.trim(lastListPageContent) !== $.trim(pageText)) {
			reQueueNode.append('<br/>Warning! Someone else is working on the list.');
		}
		reQueueNode.find('#queueCounter').text("Processing..");

		var pageTextWithoutMovedFiles = pageText;
		$.each( toMove, function( fileName, info ) {
			fileName = fileName.replace('File:', '');
			var reFile = new RegExp(
				'\n((?:[Ff]ile\\:\\s*)?' +
				mw.util.escapeRegExp( fileName ).replace( /_/g, ' ' ).replace( / /g, '[_ ]' )
				+ '(?:\\|.+)?)'
			);
			var m = pageTextWithoutMovedFiles.match( reFile );
			if ( !m ) return console.warn( 'Could not (re)move ' + fileName + ' from page.' );
			info.fileItem = m[1];
			pageTextWithoutMovedFiles = pageTextWithoutMovedFiles.replace( reFile, '' );
		} );

		var dom = mw.libs.wikiDOM.parser.text2Obj( pageTextWithoutMovedFiles );
		var galleriesByHeading = {};

		$.each( dom.nodesByType.h, function( i, node ) {
			try {
				if ( !node.parts[0][1] ) return;
				var h = node.parts[0][1].parts[1][0];
				var nextNodeIsGallery = false;

				$.each( node.parent.parts[0], function( l, pnode ) {
					if ( nextNodeIsGallery && pnode.type === 'ext' && pnode.extname === 'gallery' ) {
						galleriesByHeading[h] = pnode;
						return false;
					}
					if ( pnode === node ) {
						nextNodeIsGallery = true;
					}
				} );
			} catch(ex){}
		} );

		$.each( toMove, function( fileName, info ) {
			var g = galleriesByHeading[info.to];
			if ( !g || !info.fileItem ) {
				return console.warn( "Gallery belonging to heading " + info.to + " not found!" );
			}
			g.parts[1][0] = '\n' + $.trim( g.parts[1][0] ) + '\n' + info.fileItem + '\n';
			info.processed = true;
		} );
		reQueueNode.find('#queueCounter').text("Processing...");

		var params = {
			action: 'edit',
			title: mw.config.get('wgPageName'),
			nocreate: 1,
			summary: 'Sorting ' + queueLength + ' files using [[User:Rillke/gallery-sort.js]]',
			text: mw.libs.wikiDOM.parser.obj2Text( dom ),
			token: (mw.user.tokens.get('csrfToken')),
			format: 'json'
		};
		
		movalDone = function(editStat) {
			processing = false;
			sendingRequest = false;
			lastListPageContent = mw.libs.wikiDOM.parser.obj2Text( dom );
			if (!editStat) return;
			if (editStat.error) {
				alert('Unable to move files in list. Maybe reloading the page helps.\n' + result.error.code + '\n' + result.error.info);
			}
			$.each( toMoveCopy, function( fileName ) {
				if ( toMove[ fileName ].processed ) {
					delete toMove[ fileName ];
					queueLength--;
				}
			} );
			$('#queueCounter').text(queueLength);
		};
		$.post(mw.util.wikiScript('api'), params, movalDone);
		$('#queueCounter').text("Processing...");
	};
	$.get(mw.config.get('wgScript'), { 'action': 'raw', title: mw.config.get('wgPageName') , dummy: Math.round(Math.random()*4294967296), maxage: 0 }, function(text) {
		mw.loader.using(['ext.gadget.libWikiDOM'], doMove.bind( this, text ) );
	});
	reQueueNode.find('#queueCounter').text("Processing.");
};

var reQueueNode = $('<div>', { style: 'position:fixed; background: #efe; top: 30px; left: 30px; border:solid 2px #000; z-index:1005;' }).append(
	$('<span>', { id: 'queueCounter', text: '0' }), ' items in commit queue. ', $('<a>', { href: '#', text: 'commit edits' }).click(function(e) {
		e.preventDefault();
		commit();
	})
);

$('body').prepend(reQueueNode);

});

// </nowiki>