Jump to content

User:Kephir/gadgets/table-editor.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*jshint undef:true*/
/*globals mw, jQuery */
if (mw.config.get('wgPageContentModel') === 'wikitext' &&
	(mw.config.get('wgAction') === "edit" || mw.config.get('wgAction') === 'submit'))
mw.loader.using(['mediawiki.action.edit', 'ext.wikiEditor'], function () {

var apiEntry = jQuery('#wpTextbox1');

apiEntry.wikiEditor('addToToolbar', { // so fucking intuitive. [[mw:Extension:WikiEditor/Toolbar customization#Add a toolbar section]]
	sections: {
		'tables': {
			type: 'toolbar',
			label: 'Tables'
		}
	}
});

apiEntry.wikiEditor('addToToolbar', {
	section: 'tables',
	groups: {
		'tables': {
			label: 'Tables'
		}
	}
});

function addButton(text, handler, icon) { // ugly, i no.
	apiEntry.wikiEditor('addToToolbar', {
		section: 'tables',
		group: 'tables',
		tools: {
			ident: {
				label: text,
				type: 'button',
				icon: icon || '/upwiki/wikipedia/commons/thumb/a/a4/Gnome-face-smile.svg/22px-Gnome-face-smile.svg.png',
				action: {
					type: 'callback',
					execute: handler
				}
			}
		}
	});
}

function getSelection(textarea) {
	return textarea.value.substr(
		textarea.selectionStart,
		textarea.selectionEnd - textarea.selectionStart
	);
}

function putSelection(textarea, text) {
	var before = textarea.value.substr(0, textarea.selectionStart);
	var after = textarea.value.substr(textarea.selectionEnd);
	var pss = textarea.selectionStart;
	
	textarea.value = before + text + after;
	textarea.selectionStart = pss;
	textarea.selectionEnd = pss + text.length;
}

var editBox = document.getElementsByTagName('textarea')[0];

String.prototype.rep = function (times) {
	var result = '';
	for (var i = 0; i < times; ++i)
		result += this;
	return result;
};

String.prototype.pad = function (target) {
	return this + ' '.rep(target - this.length);
};

function parseTable(table) {
	var result = [];
	var r = -1, c = 0;
	var lines = table.split('\n');
	for (var i = 0; i < lines.length; ++i) {
		lines[i] = lines[i].trim();
		var lst = lines[i].split(/\s+/)[0];
		switch (lst) {
		case '{|':
			result.meta = lines[i];
			/* fall through */
		case '|-':
			result[++r] = [];
			result[r].meta = lines[i];
			c = 0;
			break;
		case '!':
		case '|':
			result[r].push(lines[i]);
			break;
		default:
			console.info(lines[i], lst);
		}
	}
	if (result[r] && !result[r].length) {
		delete result[r];
		result.length--;
	}
	
	return result;
}

function tableProcessor(f) {
	return function () {
		var table = getSelection(editBox).replace(/(^[ \t\n]+|[ \t\n]+$)/g, '');
		
		if (!table && (editBox.selectionStart == editBox.selectionEnd)) {
			var start = editBox.value.substr(0, editBox.selectionStart);
			var end = editBox.value.substr(editBox.selectionStart);
			var si = -2;
			while (start.indexOf('{|', si + 2) != -1)
				si = start.indexOf('{|', si + 2);
			end = end.indexOf('|}');
			if ((si > 0) && (end != -1)) {
				end = end + editBox.selectionStart + 2;
				editBox.selectionStart = si;
				editBox.selectionEnd = end;
				table = getSelection(editBox);
			}
		}
		var sb = [editBox.selectionStart, editBox.selectionEnd];
		
		if (!table || (table.substr(0, 2) != '{|') || (table.substr(-2) != '|}')) {
			alert('Select a whole table first');
			return;
		}

		var rows = parseTable(table);
		var colSizes = {};
			
		rows = f(rows);
		if (!rows) {
			editBox.focus();
			return;
		}

		table = rows.meta + '\n';
		for (var i = 0; i < rows.length; ++i) {
			table += ' ' + rows[i].meta + '\n';
			for (var j = 0; j < rows[i].length; ++j) {
				table += ' ' + rows[i][j] + '\n';
			}
		}
		table += ' |}\n';
		editBox.selectionStart = sb[0];
		editBox.selectionEnd = sb[1];
		putSelection(editBox, table);
		editBox.focus();
	};
}

addButton('Add column', tableProcessor(function (rows) {
	var init = prompt('Initial content', '{{dunno}}');
	
	if (init === null) {
		return null;
	}

	for (var i = 0; i < rows.length; ++i) {
		rows[i].push("| " + init);
	}
	
	return rows;
}), '/upwiki/wikipedia/commons/thumb/d/dc/Gnome-insert-object.svg/22px-Gnome-insert-object.svg.png');

addButton('Delete/shuffle columns', tableProcessor(function (rows) {
	var ids = [];
	for (var i = 0; i < rows[0].length; ++i)
		ids.push(i);

	ids = JSON.parse(prompt('New order', '[' + ids.join(', ') + ']'));
	
	if (!ids) {
		return null;
	}

	for (var i = 0; i < rows.length; ++i) {
		var newrows = [];
		for (var j = 0; j < ids.length; ++j) {
			newrows.push(rows[i][ids[j]]);
		}
		newrows.meta = rows[i].meta;
		rows[i] = newrows;
	}
	
	return rows;
}), '/upwiki/wikipedia/commons/thumb/f/f3/Red_arrows.svg/22px-Red_arrows.svg.png');

addButton('Transpose rows and columns', tableProcessor(function (rows) {
	var cols = [];

	cols.meta = rows.meta;
	for (var i = 0; i < rows.length; ++i) {
		for (var j = 0; j < rows[i].length; ++j) {
			if (!cols[j]) {
				cols[j] = [];
				cols[j].meta = '|-';
			}
			cols[j][i] = rows[i][j];
		}
	}
	
	return cols;
}), '/upwiki/wikipedia/commons/thumb/0/08/RomanT-01.svg/22px-RomanT-01.svg.png');

});