Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
//<source lang="javascript">
 
/*
    Support for quick handling of the [[Spam blacklist]] at meta.

    Author: [[:m:User:Erwin]], October - November 2008
    License: Quadruple licensed GFDL, GPL, LGPL and Creative Commons Attribution 3.0 (CC-BY-3.0)


    This tool uses code from DelReqHandler at Commons.
        [[:Commons:MediaWiki:Gadget-DelReqHandler.js]] (oldid=15093612)
        Author: [[:Commons:User:Lupo]], October 2007 - January 2008
        License: Quadruple licensed GFDL, GPL, LGPL and Creative Commons Attribution 3.0 (CC-BY-3.0)

    Tested only in Firefox.
*/
 
/**** Guard against double inclusions */
 
if (typeof (SBHandler) == 'undefined') {
 
    var SBUtils =
    {
        // userIsInGroup (from Commons:MediaWiki:Utilities.js)
        userIsInGroup : function (group)
        {
            if (wgUserGroups) {
                if (!group || group.length == 0) group = '*';
                for (var i=0; i < wgUserGroups.length; i++) {
                    if (wgUserGroups[i] == group) return true;
                }
            }
            return false;
        },
 
        // setEditSummary (from Commons:MediaWiki:Utilities.js)
        setEditSummary : function (text)
        {
            if (document.editform == null || document.editform.wpSummary == null) return;
            var summary = document.editform.wpSummary.value;
            if (summary == null || summary.length == 0) {
                document.editform.wpSummary.value = text;
            } else if (summary.substr(-3) == '*/ ' || summary.substr(-2) == '*/' ) {
                document.editform.wpSummary.value += text
            } else {
                document.editform.wpSummary.value += '; ' + text;
            }
        },
 
        // makeRawLink (from Commons:MediaWiki:Utilities.js)
        makeRawLink : function (name, url, target)
        {
            var link = document.createElement('a');
            link.setAttribute('href', url);
            if (target) link.setAttribute ('target', target);
            link.appendChild(document.createTextNode(name));
            return link;
        },

        // The following function is defined in several places, and unfortunately, it is defined
        // wrongly in some places. (For instance, in [[:en:User:Lupin/popups.js]]: it should use
        // decodeURIComponent, not decodeURI!!!) Make sure we've got the right version here:
        getParamValue : function (paramName)
        {
            var cmdRe = RegExp ('[&?]' + paramName + '=([^&]*)');
            var h = document.location.href;
            var m = cmdRe.exec (document.location.href);
            if (m) {
                try {
                    return decodeURIComponent (m[1]);
                } catch (someError) {}
            }
            return null;
        }
 
    } // End of SBUtils
 
    /**** Enable the whole shebang only for sysops. */
    if (SBUtils.userIsInGroup ('sysop')) {
 
        var SBHandler =
        {
 
            /*------------------------------------------------------------------------------------------
            Spam blacklist requests closing: add "[add]", "[remove]", "[reverted]" and "[decline]" links to
            the left of the section edit links of a request.
            ------------------------------------------------------------------------------------------*/
 
            sb_close_add       : 'close_add',
            sb_close_rem       : 'close_rem',
            sb_close_rev       : 'close_rev',
            sb_close_dec       : 'close_dec',
            close_add_summary  : 'Added',
            close_rem_summary  : 'Removed',
            close_rev_summary  : 'Reverted',
            close_dec_summary  : 'Declined',
            sb_add             : 'add',
            sb_rem             : 'rem',
 
            closeRequestLinks : function ()
            {
                function addRequestLinks (name, href, before, parent)
                {
                    parent.insertBefore (document.createTextNode ('['), before);
                    parent.insertBefore (SBUtils.makeRawLink (name, href, '_blank'), before);
                    parent.insertBefore (document.createTextNode (']'), before);
                }
 
                var param = SBUtils.getParamValue ('fakeaction');
 
                if (param == null) {
                    if (wgPageName == 'Talk:Spam_blacklist') {
                        // We're on [[Talk:Spam blacklist]]
                        var edit_lks = getElementsByClassName(document, 'span', 'editsection');
                        for (i = 0; i < edit_lks.length; i++) {
                            // Set to true if the addition or removal section is found
                            ignore = false;
                            // Find the A within:
                            var anchors = edit_lks[i].getElementsByTagName('a');
                            if (anchors != null && anchors.length > 0) {
                                var anchor = anchors[0];
                                var href = anchor.getAttribute('href');
                                var title = anchor.getAttribute('title');
                                if (title.indexOf('additions') > 0 && title.indexOf('Bot') < 0) {
                                    ignore = true;
                                    lk_name = 'add';
                                    lk_action = SBHandler.sb_close_add;
                                } else if (title.indexOf('additions') > 0 && title.indexOf('Bot') > 0) {
                                    lk_name = null;
                                    lk_action = null;
                                } else if (title.indexOf('removals') > 0 ) {
                                    ignore = true;
                                    lk_name = 'remove';
                                    lk_action = SBHandler.sb_close_rem;
                                } else if (title.indexOf('problems') > 0 ) {
                                    lk_name = null;
                                    lk_action = null;
                                }
                                if (href.indexOf ('Talk:Spam_blacklist') > 0 && href.indexOf ('&section=') > 0 && lk_name != null && !ignore) {
                                    var orig_bracket = edit_lks[i].firstChild;
                                    addRequestLinks(lk_name, href + '&fakeaction=' + lk_action, orig_bracket, edit_lks[i]);
                                    addRequestLinks('decline', href + '&fakeaction=' + SBHandler.sb_close_dec, orig_bracket, edit_lks[i]);
                                }
                            }
                        }
                    } else if (wgPageName.substr(0, 18) == 'User:COIBot/XWiki/') {
                        var edit_lks = getElementsByClassName (document, 'span', 'editsection');
                        i = edit_lks.length - 1;
                        var anchors = edit_lks[i].getElementsByTagName ('a');
                        if (anchors != null && anchors.length > 0) {
                            var anchor = anchors[0];
                            var href   = anchor.getAttribute ('href');
                            if (href.indexOf ('&section=') > 0) {
                                var orig_bracket = edit_lks[i].firstChild;
                                // [reverted]
                                addRequestLinks('reverted', href + '&fakeaction=' + SBHandler.sb_close_rev, orig_bracket, edit_lks[i]);
                                // [add]
                                addRequestLinks('add', href + '&fakeaction=' + SBHandler.sb_close_add, orig_bracket, edit_lks[i]);
                            }
                        }
                    }
 
                } else if (param != null) {
                    // We're on a request page
                    var summary = null;
                    var action = null;
                    var text = document.editform.wpTextbox1;
                    var urls = new Array();
                    // Get URLs
                    if (wgPageName == 'Talk:Spam_blacklist') {
                        var reurl = /\{\{([Ll]ink[Ss]ummary|[Ss]pam[Ll]ink)\|(.*?)\}\}/g;
                        m = text.value.match(reurl)
                        if (m != null) {
                            for (var i=0; i < m.length; i++) {
                                url = m[i].substr(14, m[i].length - 16);
                                urls.push('\\b' + url.replace(/\./g, '\\.') + '\\b');
                            }
                        }
                        request = text.value.match(/^\=\=\=.*?\=\=\=$/m);
                        if (request.length > 0) {
                            request = request[0].substr(3, request[0].length - 6);
                        } else {
                            request = '';
                        }
                    } else if (wgPageName.substr(0, 18) == 'User:COIBot/XWiki/') {
                        url = wgPageName.substr(18);
                        urls.push('\\b' + url.replace(/\./g, '\\.') + '\\b');
                        request = wgPageName;
 
                        // Close report
                        if (param == SBHandler.sb_close_add || param == SBHandler.sb_close_rev) {
                            text.value = text.value.replace("{{LinkStatus|open}}", "{{LinkStatus|closed}}");
                        }
 
                    }
                    if (param == SBHandler.sb_close_add) {
                        summary = SBHandler.close_add_summary;
                        text.value += '\n{{Added}}. --~~~~';
                        action = SBHandler.sb_add;
                    } else if (param == SBHandler.sb_close_del) {
                        summary = SBHandler.close_rem_summary;
                        text.value += '\nRemoved. --~~~~';
                        action = SBHandler.sb_rem;
                    } else if (param == SBHandler.sb_close_rev) {
                        summary = SBHandler.close_rev_summary;
                        text.value += '\nReverted. --~~~~';
                    } else if (param == SBHandler.sb_close_dec) {
                        summary = SBHanderl.close_dec_summary;
                        text.value += '\n{{Declined}}. --~~~~';
                    }
                    if (summary != null) {
                        SBUtils.setEditSummary (summary);
                        if (action != null) {
                            var edithelp = getElementsByClassName(document, 'span', 'editHelp');
                            if (edithelp) {
                                edithelp = edithelp[0];
                                edithelp.innerHTML = '<a href="' + mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php'
                                                     + '?title=Special:SpamBlacklist'
                                                     + '&action=' + action
                                                     + '&urls=' + urls.join('|')
                                                     + '&request=' + request
                                                     + '" title="Special:SpamBlacklist">Edit blacklist</a> | '
                                                     + edithelp.innerHTML;
                            }
                        }
                        // Don't close the window to allow adding a comment.
                        if (text.scrollHeight > text.clientHeight) {
                            text.scrollTop = text.scrollHeight - text.clientHeight;
                        }
                        text.focus ();
                    }
                }
            },
 
            /*------------------------------------------------------------------------------------------
            Add to blacklist.
            ------------------------------------------------------------------------------------------*/
            edittoken : '',
            text : '',
            request : '',
            urls : '',
            action : '',
            timestamp : '',
            oldid : '',
 
            SBWrapper : function ()
            {
                document.title = 'Spam blacklist';
 
                // Add CSS for viewing the differences
                head = document.getElementsByTagName('head')[0];
                head.innerHTML = head.innerHTML + '<link rel=\"stylesheet\" href=\"/skins-1.5/common/diff.css?182\" type=\"text/css\" />';
 
                // Set header
                header = document.getElementsByTagName('h1')[0];
                header.innerHTML = 'Spam blacklist';
 
                // Set content
                content = document.getElementById('bodyContent');
                content.innerHTML = '<h3 id=\"siteSub\">From Meta, a Wikimedia project coordination wiki</h3>'
                                    + '<p>Use this tool to add/remove URLs to the <a href=\"http://meta.wikimedia.org/wiki/Spam blacklist\" title=\"Spam blacklist\">Spam blacklist</a> and log the change. Note that it does not escape URLs. <span style=\"font-weight:bold;\">Do not use this tool unless you have a basic understanding of regex.</span> You still need to confirm the changes. Do not assume that the proposed edit is correct.</p>';

                SBHandler.action = SBUtils.getParamValue ('action');
                SBHandler.urls = SBUtils.getParamValue ('urls');
                SBHandler.request = SBUtils.getParamValue('request');
                
                if ((SBHandler.action == 'add' || SBHandler.action == 'rem') && SBHandler.urls != null && SBHandler.request != null) {
                    content.innerHTML += '<div id=\"SBstatus\" style=\"font-style: italic; border: 1px solid; padding: 5px; float:right;\">'
                                        + '<span id=\"Sthrobber\" style=\"text-align:center; font-weight:bold; float:right;\">'
                                        + '<img src=\"http://upload.wikimedia.org/wikipedia/commons/d/d2/Spinning_wheel_throbber.gif\" alt=\"Loading\">'
                                        + 'Loading…</span>'
                                        + '<br clear=\"all\" />'
                                        + '<table><tr style=\"vertical-align:top;\"><td>'
                                        + '<h5>Blacklist</h5>'
                                        + '<ul><li id=\"SgetBL\" style=\"color:grey;\">Get blacklist text</li>'
                                        + '<li id=\"SaddBL\" style=\"color:grey;\">Add/remove URLs</li>'
                                        + '<li id=\"SgetC\" style=\"color:grey;\">Get changes from server</li>'
                                        + '<li id=\"SparseBL\" style=\"color:grey;\">Parse and show changes</li>'
                                        + '<li id=\"SconfirmBL\" style=\"color:grey;\">Confirm changes</li>'
                                        + '<li id=\"SsaveBL\" style=\"color:grey;\">Save changes</li></ul></td><td>'
                                        + '<h5>Log</h5>'
                                        + '<ul><li id=\"SgetL\" style=\"color:grey;\">Get log text</li>'
                                        + '<li id=\"SaddL\" style=\"color:grey;\">Add/remove URLs</li>'
                                        + '<li id=\"SsaveL\" style=\"color:grey;\">Save changes</li>'
                                        + '</ul></tr></table></div><br clear=\"all\" />'
                                        + '<h3>Blacklist</h3><div id=\"SBlist\"></div>'
                                         + '<h3>Log</h3><div id=\"SBlog\"></div>';
                    SBlist = document.getElementById("SBlist");
                    SBlog = document.getElementById("SBlog");
                    SBHandler.getRequest('action=query&prop=info&intoken=edit&titles=Spam blacklist', SBHandler.getBL, true);
                } else {
                    content.innerHTML += '<p style=\"font-style:italic\">This tool can only be used in conjunction with <a href=\"http://meta.wikimedia.org/wiki/Talk:Spam_blacklist\" title=\"Talk:Spam blacklist\">Talk:Spam blacklist</a> or <a href=\"http://meta.wikimedia.org/wiki/User:COIBot/XWiki\" title=\"User:COIBOt/XWiki\">COIBot\'s spam reports</a> to add or remove URLs.</p>'
                }
            },
 
            // Get the current text and oldid of [[Spam blacklist]]
            getBL : function(request)
            {
                var xml = request.responseXML;
                if ( xml != null ) {
                    pages = xml.getElementsByTagName('page');
                    SBHandler.edittoken = pages[0].getAttribute('edittoken');
                    SBHandler.getRequest('action=query&prop=revisions&titles=Spam blacklist&rvprop=ids|timestamp|user|comment|content', SBHandler.parseBL, true);
                }
            },
 
            // Add/remove URLs from the text
            parseBL : function(request)
            {
                var xml = request.responseXML;
                if ( xml != null ) {
                    revs = xml.getElementsByTagName('rev') ;
                    user = revs[0].getAttribute('user');
                    revid = revs[0].getAttribute('revid');
                    SBHandler.timestamp = revs[0].getAttribute('timestamp');
                    SBHandler.text = revs[0].textContent;
                    oldlength = SBHandler.text.length;
                    document.getElementById('SgetBL').style.color = 'black';
                } else {
                    SBlist.innerHTML += '<div style=\"font-weight:bold;\">ERROR: ' + request.status + '<br />Aborting.</div>';
                    return;
                }
 
                if (SBHandler.action == SBHandler.sb_add) {
                    urls = SBHandler.urls.replace(/\|/g,'\n');
                    if (SBHandler.text.length > 1000 ) {
                        lastchars = SBHandler.text.substr(-1000);
                        SBHandler.text = SBHandler.text.substr(0, SBHandler.text.length - 1000);
                        if (lastchars.indexOf('## sbhandler_end') > 0) {
                            lastchars = lastchars.replace('## sbhandler_end', urls + '\n## sbhandler_end');
                        } else {
                            SBlist.innerHTML += '<div style=\"font-weight:bold;\">ERROR: Could not find marker. Aborting.</div>';
                            return;
                        }    
                        SBHandler.text += lastchars;
                    } else {
                        if (SBHandler.text.indexOf('## sbhandler_end') > 0) {
                            SBHandler.text = SBHandler.text.replace('## sbhandler_end', urls + '\n## sbhandler_end');
                        } else {
                            SBlist.innerHTML += '<div style=\"font-weight:bold;\">ERROR: Could not find marker. Aborting.</div>';
                            return;
                        }
                    }
                } else if (SBHandler.action == SBHandler.sb_rem) {
                    urls = SBHandler.urls.split('|');
                    for (var i=0; i < urls.length; i++) {
                        SBHandler.text = SBHandler.text.replace(urls[i] + '\n', '');
                    }
                }
                //Check if the length changed, if not assume nothing changed.
                if (oldlength == SBHandler.text.length) {
                    SBlist.innerHTML += '<div style=\"font-weight:bold;\">ERROR: The length of the old and new text are the same. This shouldn\'t happen. Aborting.</div>';
                    return;
                }
                document.getElementById('SaddBL').style.color = 'black';
                params = 'wpEdittime=' + SBHandler.timestamp + '&wpTextbox1=' + encodeURIComponent(SBHandler.text) + '&wpDiff=1&wpEditToken=' + encodeURIComponent(SBHandler.edittoken);
                SBHandler.postRequest('title=Spam blacklist&action=submit', SBHandler.parseDiff, params, false)                     
            },
 
            // Parse and show the proposed edit
            parseDiff : function(request)
            {
                text = request.responseText;
                if ( text != null ) {
                    document.getElementById('SgetC').style.color = 'black';
                    m1 = text.indexOf('<div id="wikiDiff">');
                    m2 = text.indexOf('<!-- diff generator');
                    if (m1 > 0 && m2 > 0) {
                        diffdiv = text.substr(m1, m2 - m1) + '</tbody></table></div>';
                        urls = SBHandler.urls.split('|');
 
                        if (SBHandler.action == 'add') {
                            summary = 'Adding ';
                        } else {
                            summary = 'Removing ';
                        }
 
                        if (urls.length > 1 ) {
                            summary += urls.length + ' URLs ';
                        } else {
                            summary += urls[0] + ' ';
                        }
 
                        if (SBHandler.request.substr(0, 18) == 'User:COIBot/XWiki/') {
                            summary += 'per [[' + SBHandler.request + ']].';
                        } else {
                            summary += 'per [[Talk:Spam blacklist]].';
                        }
 
                        SBlist.innerHTML += diffdiv
                                        + '<br /><div>'
                                        + '<input type=\"text\" value=\"' + summary + '\" id=\"summary\" maxlength=\"200\" size=\"60\" >&nbsp;&nbsp;&nbsp;<button onclick=\"SBHandler.submitBL()\">Confirm changes</button></div>';
                        document.getElementById('SparseBL').style.color = 'black';
                    } else {
                        SBlist.innerHTML += '<div style=\"font-weight:bold;\">ERROR: Could not show diff.<br />Aborting.</div>';
                        return;
                    }
                } else {
                    SBlist.innerHTML += '<div style=\"font-weight:bold;\">ERROR: ' + request.status + '<br />Aborting.</div>';
                    return;
                }
            },
 
            // Submit the edit to [[Spam blacklist]]
            submitBL : function()
            {
                document.getElementById('SconfirmBL').style.color = 'black';
                summary = document.getElementById('summary').value;
                summary += ' Using SBHandler.';
                query = 'format=xml';
                params = 'action=edit&title=Spam blacklist&summary=' + encodeURIComponent(summary) + '&text=' + encodeURIComponent(SBHandler.text) + '&basetimestamp=' + SBHandler.timestamp  +  '&token=' + encodeURIComponent(SBHandler.edittoken);
                SBHandler.postRequest(query, SBHandler.LWrapper, params, true);
            },
 
            // Start logging procedure
            LWrapper : function(request)
            {
                var xml = request.responseXML;
                if (xml != null ) {
                    edits = xml.getElementsByTagName('edit');
                    if (edits.length == 0 ) {
                        SBlist.innerHTML = '<div style=\"font-weight:bold;\">Saving might have failed. Please check if it succeeded and log the edit yourself if necessary.</div>';
                        return;
                    }    
                    result = edits[0].getAttribute('result');
                    SBHandler.oldid = edits[0].getAttribute('newrevid');
                    if (result != 'Success') {
                        SBlist.innerHTML = '<div style=\"font-weight:bold;\">Saving failed. Please blacklist URLs yourself.</div>';
                        return;
                    } else {
                        document.getElementById('SsaveBL').style.color = 'black';
                        SBlist.innerHTML = '<div>Blacklist has been updated, <a href=\"' + mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?oldid=' + SBHandler.oldid + '&diff=prev\" title=\"diff\">diff</a>.</div>';
                    }
 
                } else {
                    SBlist.innerHTML += '<div style=\"font-weight:bold;\">ERROR: ' + request.status + '<br />Aborting.</div>';
                    return;
                }
 
                d = new Date();
                m = d.getMonth() + 1;
                if (m < 10 ) {
                    m = '0' + m;
                }
                y = d.getFullYear();
                logtitle = 'Spam blacklist/Log/' + y + '/' + m;
 
                if (SBHandler.request.substr(0, 18) != 'User:COIBot/XWiki/') {
                    SBHandler.getRequest('action=query&prop=revisions&titles=Talk:Spam blacklist&rvprop=ids|timestamp|user|comment|content', SBHandler.parseTBL, true);
                } else {  
                    SBHandler.getRequest('action=query&prop=revisions&titles=' + logtitle + '&rvprop=ids|timestamp|user|comment|content', SBHandler.parseL, true);
                }
            },
 
            // Get current oldid of [[Talk:Spam blacklist]], because that's the location of the request.
            parseTBL : function(request)
            {
                var xml = request.responseXML;
                if ( xml != null ) {
                    revs = xml.getElementsByTagName('rev') ;
                    tprevid = revs[0].getAttribute('revid');
                } else {
                    SBlog.innerHTML += '<div style=\"font-weight:bold;\">ERROR: ' + request.status + '<br />. Please log the edit yourself.</div>';
                    return;
                }
 
                SBHandler.getRequest('action=query&prop=revisions&titles=' + logtitle + '&rvprop=ids|timestamp|user|comment|content', SBHandler.parseL, true);    
            },
 
            // Add/remove URLs to log
            parseL : function(request)
            {
                var xml = request.responseXML;
                if ( xml != null ) {
                    document.getElementById('SgetL').style.color = 'black';
                    revs = xml.getElementsByTagName('rev') ;
                    SBHandler.timestamp = revs[0].getAttribute('timestamp');
                    SBHandler.text = revs[0].textContent;
                } else {
                    SBlog.innerHTML += '<div style=\"font-weight:bold;\">ERROR: ' + request.status + '<br /> Please log the edit yourself.</div>';
                    return;
                }
 
                if (SBHandler.action == SBHandler.sb_add) {
                    action = 'addition';
                } else if (SBHandler.action == SBHandler.sb_rem) {
                    action = 'removal';
                }
 
                urls = SBHandler.urls.split('|');
                r = SBHandler.request
                if (r.substr(0, 18) == 'User:COIBot/XWiki/')
                {
                    r = '[[' + r + ']]';
                } else {
                    r = '{{sbl-log|' + tprevid + '#{{subst:anchorencode:' + r + '}}}}';
                }
 
                spaces = '                                        ';
 
                if (urls.length == 1) {
                    SBHandler.text = SBHandler.text + '\n ' + urls[0] + spaces.substr(0, 39 - urls[0].length) + '# '
                                     + wgUserName + ' # {{sbl-diff|' + SBHandler.oldid + '|' + action + '}}; see '
                                     + r
                } else {
                    SBHandler.text = SBHandler.text + '\n #:                                     ';
                                     + wgUserName + ' # {{sbl-diff|'
                                     + SBHandler.oldid + '|'
                                     + action + '}}; see '
                                     + r
                    for (var i=0; i < urls.length; i++) {
                        SBHandler.text = SBHandler.text + '\n   ' + urls[i];
                    }
                }
                
                document.getElementById('SaddL').style.color = 'black';
                text = SBHandler.text;
                query = 'format=xml';
                params = 'action=edit&title=' + logtitle + '&summary=' + summary + '&text=' + text + '&basetimestamp=' + SBHandler.timestamp  +  '&token=' + encodeURIComponent(SBHandler.edittoken);
                SBHandler.postRequest(query, SBHandler.LEnd, params, true);                 
            },
 
            // Confirm results
            LEnd : function(request)
            {
                var xml = request.responseXML;
 
                if (xml != null ) {
                    edits = xml.getElementsByTagName('edit');
                    result = edits[0].getAttribute('result');
                    oldid = edits[0].getAttribute('newrevid');
                    if (result != 'Success') {
                        SBlog.innerHTML = '<div>Saving failed. Please log the edit yourself.</div>';
                        return;
                    } else {
                        document.getElementById('SsaveL').style.color = 'black';
                        document.getElementById('Sthrobber').innerHTML = '';
                        SBlog.innerHTML = '<div>Log has been updated, <a href=\"' + mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?oldid=' + oldid + '&diff=prev\" title=\"diff\">diff</a>.<p style=\"font-style:italic\">Thanks for helping with the Spam blacklist!</p></div>';
                    }
                }
            },
 
            getRequest : function(query, callback, api)
            {
                if (api) {
                    var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?format=xml&' + query;
                } else {
                    var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + query;
                }
                var request = sajax_init_object() ;
                if (request == null) {
                    return null;
                }    
                request.open('GET', url, true);
                request.onreadystatechange = function () {
                    if(request.readyState==4) {
                        callback(request)
                    }
                };
                request.setRequestHeader('Pragma', 'cache=yes');
                request.setRequestHeader('Cache-Control', 'no-transform');
                request.send(null);
            },
 
            postRequest : function(query, callback, params, api)
            {
                if (api) {
                    var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?' + query;
                } else {
                    var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + query;
                }
 
                var request = sajax_init_object() ;
                if (request == null) {
                    return null;
                }    
                request.open('POST', url, true);
                request.onreadystatechange = function () {
                    if(request.readyState==4) {
                        callback(request)
                    }
                };

                request.setRequestHeader('Content-type','application/x-www-form-urlencoded');
                request.setRequestHeader('Content-length', params.length);
                request.setRequestHeader("Pragma", "cache=yes");
                request.setRequestHeader("Cache-Control", "no-transform");

                request.send(params);
            },
 
            setupHandler : function ()
            {
                if (wgPageName == 'Special:SpamBlacklist') {
                    SBHandler.SBWrapper();
                } else {
                    SBHandler.closeRequestLinks();
                }
            }
 
        } // End of SBHandler
 
        addOnloadHook (SBHandler.setupHandler);
 
    } // End of sysop check
 
} // End of idempotency check
 
//</source>