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*

  • .+(<\/li>)?\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])(

  • )/mgi, "$1\n$2");

    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 = $('

    ').css('display', 'inline').submit(liedit.save);

    var input = $('').attr('id', 'liedit_input').attr('size', liedit.inputsize).val(liedit.li_wikitext);

    var button1 = $('