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');
});