User:The Evil IP address/liedit.js
/**
- Allows for one click modification of list items when viewing a page
- add importScript('User:The Evil IP address/liedit.js'); to your .js file to use it
- @author Janko Hoener (The Evil IP address)
- @version 0.9.9 (beta)
- /
mw.loader.load('mediawiki.api');
window.liedit = {
REGEX_WIKI: /^\s*(\*+)[^\*]*/,
REGEX_HTML: /^\s*
SIBLING: -1,
PARENT: 1,
EDIT_SUM_LIMIT: 170,
arraysEqual: function(a, b) {
// stolen from StackOverflow
if (a === b) return true;
if (a === null || b === null) return false;
if (a.length != b.length) return false;
// If you don't care about the order of the elements inside
// the array, you should sort both arrays here.
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
},
onclick: function (event, $e) {
if ($e.is('table.infobox li')) {
liedit.set_error_msg('Sorry, cannot edit list items in infoboxes using this script.');
return;
}
if ($e.is('#toc li') || $e.has('form').length) {
return;
}
if (liedit.$e) {
liedit.cancel(event);
}
liedit.pagename = mw.config.get('wgPageName');
liedit.api = new mw.Api();
liedit.$e = $e;
liedit.api.get( {
action: 'parse',
page: liedit.pagename,
prop: 'sections',
format: 'json'
}).done( function (data) {
liedit.sections = {};
$.each(data.parse.sections, function (i, v) {
if (v.byteoffset) {
liedit.sections[v.anchor] = v.index;
}
}
);
cur_elem = liedit.$e[0];
liedit.index = 0;
abort = false;
last_move = liedit.SIBLING;
liedit.position = [0, 0];
for (i = 0; i < 10000 && !abort; i++) {
$cur_elem = $(cur_elem);
switch (cur_elem.localName) {
case 'li':
if (last_move == liedit.SIBLING) {
liedit.position[1]++;
}
if (last_move == liedit.PARENT) {
liedit.position.unshift(0);
}
break;
case 'ul':
liedit.position[0]++;
break;
case 'dl':
case 'dd':
if (last_move == liedit.PARENT) {
liedit.set_error_msg('Cannot edit this list item using this script.');
return;
}
break;
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
case 'h6':
if ($cur_elem.attr('class') == 'firstHeading') {
liedit.index = 0;
abort = true;
break;
}
liedit.anchor = $cur_elem.find('span.mw-headline').first().attr('id');
if (liedit.anchor in liedit.sections) {
liedit.index = liedit.sections[liedit.anchor];
abort = true;
}
break;
}
if (cur_elem.previousElementSibling) {
cur_elem = cur_elem.previousElementSibling;
last_move = liedit.SIBLING;
}
else {
cur_elem = cur_elem.parentNode;
last_move = liedit.PARENT;
}
}
liedit.api.get( {
action: 'parse',
page: liedit.pagename,
section: liedit.index,
prop: 'wikitext',
format: 'json'
}).done( function (obj) {
liedit.wikitext = obj.parse.wikitext['*'];
liedit.wikitext = liedit.wikitext.replace(/([^\n])(
liedit.lines = liedit.wikitext.split('\n');
currently_in_list = false;
current_list_wiki = false;
current_list_html = false;
cur_pos = [];
depth = liedit.position.length-1;
for (i = 0; i < liedit.position.length; i++) {
cur_pos.push(0);
}
for (i = 0; i < liedit.lines.length; i++) {
line = liedit.lines[i];
line_match_wiki = line.match(liedit.REGEX_WIKI);
line_match_html = line.match(liedit.REGEX_HTML);
if (line_match_html || line_match_wiki) {
if (!currently_in_list) {
currently_in_list = true;
if (line_match_wiki) {
current_list_wiki = true;
current_list_html = false;
}
else if (line_match_html) {
current_list_wiki = false;
current_list_html = true;
}
cur_pos[0]++;
cur_pos[1] = 1;
for (j = 2; j < cur_pos.length; j++) {
cur_pos[j] = 0;
}
}
else if (line_match_wiki && currently_in_list && current_list_html) {
cur_pos[0]++;
cur_pos[1] = 1;
for (j = 2; j < cur_pos.length; j++) {
cur_pos[j] = 0;
}
current_list_wiki = true;
current_list_html = false;
}
else if (line_match_html && currently_in_list && current_list_wiki) {
cur_pos[0]++;
cur_pos[1] = 1;
for (j = 2; j < cur_pos.length; j++) {
cur_pos[j] = 0;
}
current_list_wiki = false;
current_list_html = true;
}
else if (currently_in_list && current_list_wiki && line_match_wiki) {
line_depth = line.replace(liedit.REGEX_WIKI, '$1').length;
if (line_depth > depth) {
continue;
}
for (j = 1; j < line_depth; j++) {
if (cur_pos[j] === 0) {
cur_pos[j] = 1;
}
}
cur_pos[line_depth]++;
for (j = line_depth + 1; j < cur_pos.length; j++) {
cur_pos[j] = 0;
}
}
else if (currently_in_list && current_list_html && line_match_html) {
cur_pos[1]++;
}
liedit.li_index = i;
if (liedit.arraysEqual(liedit.position, cur_pos)) {
liedit.li_wikitext = line;
liedit.inputsize = liedit.li_wikitext.length*1.5;
var form = $('