User:Kephir/gadgets/table-editor.js

/*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 || '//upload.wikimedia.org/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;

}), '//upload.wikimedia.org/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;

}), '//upload.wikimedia.org/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;

}), '//upload.wikimedia.org/wikipedia/commons/thumb/0/08/RomanT-01.svg/22px-RomanT-01.svg.png');

});