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.
// [[User:Quarl/autoedit.js]] - tab menu & framework for automatically editing
// wiki pages

// depends: wikipage.js, wikiedit.js, util.js, wikitabs.js

// SYNOPSIS:
//    var myeditor = new autoedit('myeditor', 'MyEdit', 'ca-myedit', 'Do my edits', 'Edit summary prefix');
//    myeditor.initData = function() { this.foo=5; } /* optional */
//    myeditor.splitText = function(s) { return s.split('\n'); } /* optional */
//    myeditor.buildRegExp = function() { return /foo/ }
//    myeditor.replaceRegExp = function(s) { return + "("+s+")" }
//    addOnloadHook(function(){myeditor.qAutoEdit();myeditor.addTab();});

// Note: can't add "myeditor.addTab" directly as addOnloadHook because
// runOnloadHook doesn't pass "this"

// quarl 2006-02-08 initial version, refactoring *_canonicalize.js scripts

// <pre><nowiki>

var autoedit = function(varname, name, id, title, summaryPrefix) {
    this.varname = varname;
    this.name = name;
    this.id = id;
    this.title = title;
    this.summaryPrefix = summaryPrefix;
}

autoedit.submitButton = 'wpDiff';

autoedit.prototype.addTab = function() {
    if (wikiPage.nsSpecialP) return;
    if (wikiDoc.protectedP) return;

    if (!document.menuAutoEdit) {
        document.menuAutoEdit = wikitabs.addTabMenu('AutoEdit', 'mn-autoedit');
    }

    var url = 'javascript:' + this.varname + '.run()';
    this.tab = wikitabs.addLiLink(document.menuAutoEdit, url, this.name, this.id, this.title);
}

autoedit.prototype.run = function() {
    this.initData();
    buttonShowStatus(this.tab);
    wikiPage.getEditorAsync(this._edit0, this);
}

autoedit.prototype._edit0 = function(editor, this_) {
    this_._edit1(editor);
}

autoedit.prototype._edit1 = function(editor) {
    var result = '';
    var input = editor.wpTextbox1;
    var changes = [];

    var inputs = this.splitText(input);

    var result = this.editStrings(inputs, changes);

    buttonRestoreStatus(this.tab);
    if (changes.length) {
        editor.wpTextbox1 = result;
        editor.wpSummary = this.summaryPrefix + ': ' + changes.join('; ');
        editor.wpMinoredit = true;
        editor.submit(autoedit.submitButton);
    } else {
        alert("No changes to make!");
    }
}

autoedit.prototype.initData = function() {
    /* TO BE OVERRIDDEN */
    // default: nothing to initialize
}

autoedit.prototype.splitText = function(s) {
    /* TO BE OVERRIDDEN */
    // default: don't split at all
    return [s];
}

autoedit.prototype.editStrings = function(inputs, changes) {
    for (var i in inputs) {
        inputs[i] = this.editString(inputs[i], changes);
    }
    return inputs.join('');
}

autoedit.prototype.editString = function(input, changes) {
    /* TO BE OVERRIDDEN */
    return this.regexpEditString(input, changes);
}

autoedit.prototype.regexpEditString = function(input, changes) {
    var result = '';

    var regexp = this.buildRegExp();
    var m;
    while ((m=input.match(regexp))) {
        result += RegExp.leftContext;
        var remainder = RegExp.rightContext;

        // This descriptor is passed in for input as well as taken as output.
        //
        // LEFT is the text on the left of the match; TEXT is the text itself;
        // RIGHT is the text on the right of the match.  All 3 can be modified.
        //
        // Return value of regexpReplacement overrides d.text if non-null --
        // it's simply a convenience feature.

        var d = { left: result, text: m[0], right: RegExp.rightContext };

        var dresult = this.replaceRegExp(d, m);
        if (dresult != null) {
            d.text = dresult;
        }

        if (d.text != m[0]) {
            changes.push('"'+m[0]+'"' + ' → ' +'"'+d.text+'"');
        }
        result = d.left + d.text;
        input = d.right;
    }
    result += input;
    return result;
}

autoedit.prototype.buildRegExp = function() {
    alert("## autoedit.buildRegExp() not overridden! (38c826f0-9f24-4ce2-9708-567d8e55a7c5)");
}

autoedit.prototype.regexpReplacement = function(d, match) {
    // d.left
    // d.text
    // d.right
    alert("## autoedit.regexpReplacement() not overridden! (1a791fee-8020-453f-adb1-df3c69dc6828)");
}

autoedit.prototype.makeAuthToken = function(wp) {
    return makeAuthToken('autoedit', wp.page);
}

autoedit.prototype.makeEditUrl = function(wp) {
    return (wp.qurl + '&action=edit&autoedit=' + this.varname + '&auth=' +
            this.makeAuthToken(wp));
}

// auto edit if query string asks us to
autoedit.prototype.qAutoEdit = function() {
    if (WikiPage.queryVars['autoedit'] == this.varname) {
        if (WikiPage.queryVars['auth'] != this.makeAuthToken(wikiPage)) {
            alert(this.varname+".autoedit: invalid auth token! (error a1908c50-620b-4104-bcfa-881ecf094442)");
            return;
        }
        var t = this;
        setTimeout(function(){t.run();}, 50);
    }
}

// autoedit._findCategoryContentTable = function() {
//     var tables = document.getElementsByTagName('table');
//     for (var i = 0; i < tables.length; ++i) {
//         var table = tables[i];
//         if (table.previousSibling.textContent.match(/^There are/)) {
//             return table;
//         }
//     }
//     return false;
// }


// prefix [varname] buttons before all wikilinks.  Good for category pages.
autoedit.prototype.addAutoEditButtons = function() {
    // if (!wikiPage.nsCategoryP) return;

    // var table = autoedit._findCategoryContentTable();
    // if (!table) return;

    var d = document.getElementById('bodyContent');

    var links = copyArray(d.getElementsByTagName('a'));
    for (var i = 0; i < links.length; ++i) {
        var link = links[i];
        if (!link.href || !link.href.match(/\/wiki\//)) continue;
        if (link.href.match(/#/)) continue;
        if (link.className.match(/external/)) continue;
        var wp = new WikiPage(link);
        var url = this.makeEditUrl(wp);

        var span = document.createElement('span');
        span.innerHTML = '[<a href="'+url+'">'+this.varname+'</a>] ';
        add_before(link, span);
    }
}

// </nowiki></pre>