MediaWiki:Group-sysop.js
From cppreference.com
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)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
//<nowiki>
/* Any JavaScript here will be loaded for sysops only */
$(function ($) {
// Opt-out
if ( window.disableSysopJS ) {
return;
}
// Animum's mass-deletion tool
// from https://en.wikipedia.org/wiki/User:Animum/massdelete.js
mw.loader.using(['mediawiki.api.edit', 'mediawiki.Title'], function () {
"use strict";
var config = mw.config.get(['wgNamespaceNumber', 'wgTitle', 'wgUserGroups', 'skin']);
function removeBlanks(arr) {
var ret = [];
var i, len;
for (i = 0, len = arr.length; i < len; i++) {
var s = arr[i];
s = s.trim();
if (s) {
ret.push(s);
}
}
return ret;
}
function doMassDelete() {
document.getElementById("wpMassDeleteSubmit").disabled = true;
var articles = document.getElementById("wpMassDeletePages").value.split("\n");
articles = removeBlanks(articles);
if (!articles.length) {
return;
}
var
api = new mw.Api(),
wpMassDeleteReasons = document.getElementById("wpMassDeleteReasons").value,
wpMassDeleteReason = document.getElementById("wpMassDeleteReason").value,
deleted = 0,
failed = [],
error = [],
deferreds = [],
reason = wpMassDeleteReasons == "other" ?
wpMassDeleteReason :
wpMassDeleteReasons + (wpMassDeleteReason ? " (" + wpMassDeleteReason + ")" : ""),
onSuccess = function () {
deleted++;
document.getElementById("wpMassDeleteSubmit").value = "(" + deleted + ")";
};
function makeDeleteFunc(article) {
return function () {
return $.Deferred(function (deferred) {
var promise = api.post({
format: 'json',
action: 'delete',
title: article,
reason: reason,
token: mw.user.tokens.get('editToken')
});
promise.done(onSuccess);
promise.fail(function (code, obj) {
failed.push(article);
error.push(obj.error.info);
});
promise.always(function () {
deferred.resolve();
});
});
};
}
// Make a chain of deferred objects. We chain them rather than execute them in
// parallel so that we don't make 1000 simultaneous delete requests and bring the
// site down. We use deferred objects rather than the promise objects returned
// from the API request so that the chain continues even if some articles gave
// errors.
var deferred = makeDeleteFunc(articles[0])();
for (var i = 1, len = articles.length; i < len; i++) {
deferred = deferred.then(makeDeleteFunc(articles[i]));
}
// Show the output and do cleanup once all the requests are done.
$.when(deferred).then(function () {
document.getElementById("wpMassDeleteSubmit").value = "Done (" + deleted + ")";
if (failed.length) {
var $failedList = $('<ul>');
for(var x = 0; x < failed.length; x++) {
// Link the titles in the "failed" array
var $failedItem = $('<li>');
$failedItem.text(failed[x]);
$failedItem.append(document.createTextNode(': ' + error[x]));
$failedList.append($failedItem);
}
$('#wpMassDeleteFailedContainer')
.append($('<br />'))
.append($('<b>')
.text('Failed deletions:')
)
.append($failedList);
}
});
}
function massdeleteform() {
var bodyContent = (config.skin == "cologneblue" ? "article" : "bodyContent");
document.getElementsByTagName("h1")[0].textContent = "Animum's mass-deletion tool";
document.title = "Animum's mass-deletion tool - Wikipedia, the free encyclopedia";
document.getElementById(bodyContent).innerHTML = '<h3 id="siteSub">From Wikipedia, the free encyclopedia</h3><br /><br />' +
'<form id="wpMassDelete" name="wpMassDelete">' +
'<b>If you abuse this tool, it\'s <i>your</i> fault, not mine.</b>' +
'<div id="wpMassDeleteFailedContainer"></div>' +
'<br /><br />' +
'Pages to delete (one on each line, please):<br />' +
'<textarea tabindex="1" accesskey="," name="wpMassDeletePages" id="wpMassDeletePages" rows="10" cols="80"></textarea>' +
'<br /><br /><table style="background-color:transparent">' +
'<tr><td>Common reasons:</td>' +
'<td><select id="wpMassDeleteReasons">' +
'<optgroup label="Other reason">' +
'<option value="other">Other reason</option>' +
'</optgroup>' +
'<optgroup label="General reasons">' +
'<option value="Vandalism">Vandalism</option>' +
'<option value="Cleanup">Cleanup</option>' +
'</optgroup>' +
'</select></td></tr>' +
'<tr><td>Other/additional reason:</td>' +
'<td><input type="text" id="wpMassDeleteReason" name="wpMassDeleteReason" maxlength="255" /></td></tr>' +
'<tr><td><input type="button" id="wpMassDeleteSubmit" name="wpMassDeleteSubmit" value="Delete" /></td>' +
'</form>';
document.getElementById("wpMassDeleteReasons").onchange = function() {
var maxlength = (document.getElementById("wpMassDeleteReasons").value == "other" ? 255 : 252-document.getElementById("wpMassDeleteReasons").value.length); //It's 252 because of the three characters (" ()") in addition to the selected summary.
document.getElementById("wpMassDeleteReason").setAttribute("maxlength", maxlength);
};
document.getElementById("wpMassDeleteSubmit").addEventListener("click", function (e) {
doMassDelete();
});
}
if (config.wgNamespaceNumber == -1 &&
config.wgTitle.toLowerCase() == "massdelete" &&
/sysop/.test(config.wgUserGroups)
) {
massdeleteform();
}
});
});
// Rollback summary: from https://en.wikipedia.org/wiki/User:Gracenotes/rollback.js
/**
* This script lets you use a custom summary with the rollback feature
* by adding a "sum" link wherever a rollback link appears. When you
* click "sum" you are prompted for a custom summary, and the script
* adds an additional summary parameter to the rollback URL submitting it.
*
* For usage and extra options, see the talk page.
*/
function addSumLink() {
var rbnode = [], diffnode, index = {}, gebcn = document.getElementsByClassName
? function(a, b, c) { return a.getElementsByClassName(c) }
: getElementsByClassName;
if (typeof rollbackLinksDisable == 'object' && rollbackLinksDisable instanceof Array)
for (var i = 0; i < rollbackLinksDisable.length; i++)
index[rollbackLinksDisable[i]] = true;
if (!('user' in index) && mw.config.get("wgCanonicalSpecialPageName") == "Contributions" ||
!('recent' in index) && mw.config.get("wgCanonicalSpecialPageName") == "Recentchanges" ||
!('watchlist' in index) && mw.config.get("wgCanonicalSpecialPageName") == "Watchlist")
rbnode = gebcn(document.getElementById("bodyContent"), "span", "mw-rollback-link");
else if (!('history' in index) && mw.config.get("wgAction") == "history")
rbnode = gebcn(document.getElementById("pagehistory"), "span", "mw-rollback-link");
else if (!('diff' in index) && (diffnode = document.getElementById("mw-diff-ntitle2")))
rbnode = gebcn(diffnode, "span", "mw-rollback-link");
for (var i = 0, len = rbnode.length; i < len; i++)
addRollbackSummaryLink(rbnode[i]);
}
function confirmRollback() {
var url = this.href;
var user = url.match(/[?&]from=([^&]*)/);
if (!user) return;
user = decodeURIComponent(user[1].replace(/\+/g, " "));
var summary = prompt("Enter a summary to use for rollback.\n\nLeave blank to use the default. $user will be replaced with \"" + user + "\".",
rollbackSummaryDefault);
if (summary == undefined)
return false;
else if (summary == "")
return true;
this.href += "&summary=" + encodeURIComponent(summary.replace(/\$user/g, user));
return true;
}
function addRollbackSummaryLink(rbnode) {
var rblink = rbnode.getElementsByTagName("a")[0];
var alink = rblink.cloneNode(true);
alink.className = ""; //don't confuse other scripts
alink.firstChild.nodeValue = "sum";
alink.onclick = confirmRollback;
rbnode.insertBefore(alink, rblink.nextSibling);
rbnode.insertBefore(document.createTextNode(" | "), alink);
}
if (typeof rollbackLinksDisable == 'undefined')
rollbackLinksDisable = [];
if (typeof rollbackSummaryDefault == 'undefined')
rollbackSummaryDefault = "";
$(addSumLink);
// TC's mass-blocking script
function doMassBlock() {
document.getElementById("wpMassBlockSubmit").disabled = true;
var users = document.getElementById("wpMassBlockUsers").value.split("\n");
if(users.length == 0) return;
var wpMassBlockReasons = document.getElementById("wpMassBlockReasons").value, wpMassBlockReason = document.getElementById("wpMassBlockReason").value, blocked = 0, talkpageedited = 0, userpageedited = 0, failed = new Array(), error = new Array();
var wpMassBlockAnononly = document.getElementById("wpMassBlockAnononly").checked, wpMassBlockNocreate = document.getElementById("wpMassBlockNocreate").checked, wpMassBlockAutoblock = document.getElementById("wpMassBlockAutoblock").checked, wpMassBlockReblock = document.getElementById("wpMassBlockReblock").checked;
var wpMassBlockMessage = document.getElementById("wpMassBlockMessage").value, wpMassBlockTag = document.getElementById("wpMassBlockTag").value, wpMassBlockExpiry = document.getElementById("wpMassBlockExpiry").value;
var wpMassBlockSummaryTalk = document.getElementById("wpMassBlockSummaryTalk").value, wpMassBlockSummaryUser = document.getElementById("wpMassBlockSummaryUser").value, wpMassBlockExpiry = document.getElementById("wpMassBlockExpiry").value;
var blocksettingstring = "&expiry=" + encodeURIComponent(wpMassBlockExpiry == ""? "indefinite" : wpMassBlockExpiry) + (wpMassBlockAnononly ? "&anononly=1" : "") + (wpMassBlockNocreate ? "&nocreate=1" : "") + (wpMassBlockAutoblock ? "&autoblock=1" : "") + (wpMassBlockReblock ? "&reblock=1" : "");
for(i=0;i<users.length;i++) {
var user = users[i];
if(user.length > 0) {
var req = new XMLHttpRequest();
req.open("GET", wgScriptPath + "/api.php?format=json&action=query&prop=info&intoken=block&titles=User:" + encodeURIComponent(user), false);
req.send(null);
var response = eval("(" + req.responseText + ")").query.pages;
for(var index in response) {
var info = response[index];
var blocktoken = info.blocktoken;
var postdata = "format=json"
+ "&action=block"
+ "&user=" + encodeURIComponent(user)
+ "&reason=" + encodeURIComponent(wpMassBlockReasons == "other" ? wpMassBlockReason : wpMassBlockReasons + (wpMassBlockReason ? ": " + wpMassBlockReason : ""))
+ blocksettingstring
+ "&token=" + encodeURIComponent(blocktoken);
var req = new XMLHttpRequest();
req.open("POST", wgScriptPath + "/api.php", false);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", postdata.length);
req.send(postdata);
if(eval("(" + req.responseText + ")")['block']) { //If blockd, update the blockd count and the button.
blocked++;
// now edit user and user talk.
if(wpMassBlockMessage != "") {
var postdata = "format=json&action=edit&watchlist=nochange&title=User%20talk:" + encodeURIComponent(user) + "&summary=" + encodeURIComponent(wpMassBlockSummaryTalk)
+ "&appendtext=" + encodeURIComponent(wpMassBlockMessage)
+ "&token=" + encodeURIComponent(blocktoken);
var req = new XMLHttpRequest();
req.open("POST", wgScriptPath + "/api.php", false);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", postdata.length);
req.send(postdata);
if(eval("(" + req.responseText + ")")['edit']) { talkpageedited ++; }
else { //If not edited, add the title to the "failed" array and a description of the error to the "error" array.
failed.push("User talk:" + user);
error.push(eval("(" + req.responseText + ")").error.info);
}
}
if(wpMassBlockTag != "") {
var postdata = "format=json&action=edit&watchlist=nochange&title=User:" + encodeURIComponent(user) + "&summary=" + encodeURIComponent(wpMassBlockSummaryUser)
+ "&text=" + encodeURIComponent(wpMassBlockTag)
+ "&token=" + encodeURIComponent(blocktoken);
var req = new XMLHttpRequest();
req.open("POST", wgScriptPath + "/api.php", false);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", postdata.length);
req.send(postdata);
if(eval("(" + req.responseText + ")")['edit']) { userpageedited ++; }
else { //If not edited, add the title to the "failed" array and a description of the error to the "error" array.
failed.push("User talk:" + user);
error.push(eval("(" + req.responseText + ")").error.info);
}
}
document.getElementById("wpMassBlockSubmit").value = "(" + blocked + "/" + talkpageedited + "/" + userpageedited + ")";
} else { //If not blocked, add the title to the "failed" array and a description of the error to the "error" array.
failed.push("Special:Block/" + user);
error.push(eval("(" + req.responseText + ")").error.info);
}
}
}
if(!users[i+1]) {
document.getElementById("wpMassBlockSubmit").value = "(" + blocked + "/" + talkpageedited + "/" + userpageedited + ")";
if(failed.length > 0) {
var linkedList = "";
for(x=0; x<failed.length; x++) {
linkedList += "<li><a href=\"" + wgScript + "?title=" + encodeURIComponent(failed[x]) + "\">" + failed[x] + "</a>: " + error[x] + "</li>"; //Links the titles in the "failed" array
}
document.getElementById("wpMassBlockFailedContainer").innerHTML += '<br /><b>Failed actions:</b><ul>' + linkedList + '</ul>';
}
}
}
}
function massblockform() {
var bodyContent = (skin == "cologneblue" ? "article" : "bodyContent");
document.getElementsByTagName("h1")[0].textContent = "Tim's mass-blocking tool";
document.title = "Tim's mass-blocking tool";
document.getElementById(bodyContent).innerHTML = '<br /><br />'
+ '<form id="wpMassBlock" name="wpMassBlock">'
+ '<b>If you abuse this tool, it\'s <i>your</i> fault, not mine.</b>'
+ '<div id="wpMassBlockFailedContainer"></div>'
+ '<br /><br />'
+ 'Users to block (one on each line, please):<br />'
+ '<textarea tabindex="1" accesskey="," name="wpMassBlockUsers" id="wpMassBlockUsers" rows="10" cols="80"></textarea>'
+ 'Talk page message, if any (leave blank to leave no message):<br />'
+ '<textarea tabindex="2" accesskey="," name="wpMassBlockMessage" id="wpMassBlockMessage" rows="10" cols="80"></textarea>'
+ 'Replace user page text with (leave blank for no change):<br />'
+ '<textarea tabindex="3" accesskey="," name="wpMassBlockTag" id="wpMassBlockTag" rows="10" cols="80"></textarea>'
+ '<br /><br /><table style="background-color:transparent">'
+ '<tr><td>Common reasons:</td>'
+ '<td><select id="wpMassBlockReasons">'
+ '<optgroup label="Other reason">'
+ '<option value="other">Other reason</option>'
+ '</optgroup>'
+ '<optgroup label="Common reasons">'
+ '<option value="Vandalism">Vandalism</option>'
+ '<option value="Vandalism-only account">Vandalism-only account </option>'
+ '<option value="Spam or advertising">Spam or advertising</option>'
+ '</optgroup>'
+ '</select></td></tr>'
+ '<tr><td>Other/additional reason:</td>'
+ '<td><input type="text" id="wpMassBlockReason" name="wpMassBlockReason" maxlength="255" /></td></tr>'
+ '<tr><td>Expiration time (blank for indefinite):</td>'
+ '<td><input type="text" id="wpMassBlockExpiry" name="wpMassBlockExpiry" maxlength="255" /></td></tr>'
+ '<tr><td>Edit summary for talk page edit:</td>'
+ '<td><input type="text" id="wpMassBlockSummaryTalk" name="wpMassBlockSummaryTalk" maxlength="255" /></td></tr>'
+ '<tr><td>Edit summary for user page edit:</td>'
+ '<td><input type="text" id="wpMassBlockSummaryUser" name="wpMassBlockSummaryUser" maxlength="255" /></td></tr>'
+ '<tr><td>Block anonymous users only (IPs only):</td><td><input type="checkbox" id="wpMassBlockAnononly" name="wpMassBlockAnononly" /></td></tr>'
+ '<tr><td>Enable autoblock (accounts only):</td><td><input type="checkbox" id="wpMassBlockAutoblock" name="wpMassBlockAutoblock" checked="checked" /></td></tr>'
+ '<tr><td>Block account creation:</td><td><input type="checkbox" id="wpMassBlockNocreate" name="wpMassBlockNocreate" checked="checked" /></td></tr>'
+ '<tr><td>Override existing blocks:</td><td><input type="checkbox" id="wpMassBlockReblock" name="wpMassBlockReblock" checked="checked" /></td></tr>'
+ '<tr><td><input type="button" id="wpMassBlockSubmit" name="wpMassBlockSubmit" value="Block" /></td></tr>'
+ '</form>';
document.getElementById("wpMassBlockReasons").onchange = function() {
var maxlength = (document.getElementById("wpMassBlockReasons").value == "other" ? 255 : 253-document.getElementById("wpMassBlockReasons").value.length); //It's 25e because of the two characters (": ") in addition to the selected summary.
document.getElementById("wpMassBlockReason").setAttribute("maxlength", maxlength);
}
document.getElementById("wpMassBlockSubmit").addEventListener("click", function (e) {
doMassBlock();
});
}
if(mw.config.get("wgNamespaceNumber") == -1 && (mw.config.get("wgPageName") == "Special:Massblock" || mw.config.get("wgPageName") == "Special:MassBlock") && /sysop/.test(mw.config.get("wgUserGroups"))) $(massblockform);
//</nowiki>
// One click archiver
// Adapted from https://en.wikipedia.org/wiki/User:Technical_13/Scripts/OneClickArchiver.js
mw.loader.using( 'mediawiki.api.edit', function () { $(document).ready( function() {
if ( $( '#ca-addsection' ).length > 0 &&
mw.config.get( 'wgAction' ) === 'view' ) {
var pageid = mw.config.get( 'wgArticleId' );
var errorLog = { errorCount: 0 };
new mw.Api().post( {
action: 'query',
prop: 'revisions|info',
rvsection: 0,
rvprop: 'content',
pageids: pageid,
indexpageids: 1
} ).done( function ( response0 ) {
var content0 = response0.query.pages[ pageid ].revisions[ 0 ][ '*' ];
/* counter */// Get the counter value
var counterRegEx = new RegExp( '\\| *counter *= *(\\d+)' );
var counter = counterRegEx.exec( content0 );
if ( counter === null || counter === undefined ) {
counter = 1;
errorLog.errorCount++;
errorLog.counter = counter;
} else {
counter = counter[ 1 ];
var archiveNum = counter;
}
/* archiveName */// Get the archiveName value
var archiveNameRegEx = /\| *archive *= *(.*\%\(counter\)d.*) *(-->)?/;
var archiveName = archiveNameRegEx.exec( content0 );
var rootBase = mw.config.get( 'wgPageName' )
.replace( /\/.*/g, '' )// Chop off the subpages
.replace( /_/g, ' ' );// Replace underscores with spaces
if ( archiveName === null || archiveName === undefined ) {
archiveName = rootBase + '/Archive ' + counter;
errorLog.errorCount++;
errorLog.archiveName = archiveName;
} else {
var archiveName = archiveName[ 1 ]
.replace( /\| *archive *= */, '' )
.replace( /\%\(counter\)d/g, archiveNum );
var archiveBase = archiveName
.replace( /\/.*/, '' )// Chop off the subpages
.replace( /_/g, ' ' );// Replace underscores with spaces
var archiveSub = archiveName
.replace( /_/g, ' ' )// Replace underscores with spaces
.replace( archiveBase, '' );// Chop off the base pagename
if ( archiveBase != rootBase ) {
errorLog.errorCount++;
errorLog.archiveName = 'Archive name mismatch:<br /><br />Found: ' + archiveName;
errorLog.archiveName += '<br />Expected: ' + rootBase.replace( '_', ' ' ) + archiveSub + '<br /><br />';
}
}
/* archivepagesize */// Get the size of the destination archive from the API
new mw.Api().post( {
action: 'query',
prop: 'revisions',rvlimit: 1,
rvprop: 'size|content',
titles: archiveName,
list: 'usercontribs',
uclimit: 1,
ucprop: 'timestamp',
ucuser: ( mw.config.get( 'wgRelevantUserName' ) ?
mw.config.get( 'wgRelevantUserName' ) : 'Example' ),
} ).done( function ( archivePageData ) {
var archivePageSize = 0;
if ( archivePageData.query.pages[ -1 ] === undefined ) {
for ( var a in archivePageData.query.pages ) {
archivePageSize = parseInt( archivePageData.query.pages[ a ].revisions[ 0 ].size, 10 );
archiveName = archivePageData.query.pages[ a ].title;
}
} else {
archivePageSize = -1;
archiveName = archivePageData.query.pages[ archivePageSize ].title;
errorLog.errorCount++;
errorLog.archivePageSize = -1;
errorLog.archiveName = archiveName;
}
/* maxarchivesize */// Get the defined max archive size from template
var maxArchiveSizeRegEx = new RegExp( '\\| *maxarchivesize *= *(\\d+K?)' );
var maxArchiveSize = maxArchiveSizeRegEx.exec( content0 );
if ( maxArchiveSize === null || maxArchiveSize[ 1 ] === undefined ) {
maxArchiveSize = parseInt( 153600, 10 );
errorLog.errorCount++;
errorLog.maxArchiveSize = maxArchiveSize;
} else if ( maxArchiveSize[ 1 ].slice( -1 ) === "K" && $.isNumeric( maxArchiveSize[ 1 ].slice( 0, maxArchiveSize[ 1 ].length-1 ) ) ) {
maxArchiveSize = parseInt( maxArchiveSize[ 1 ].slice( 0, maxArchiveSize[ 1 ].length - 1 ), 10 ) * 1024;
} else if ( $.isNumeric( maxArchiveSize[ 1 ].slice() ) ) {
maxArchiveSize = parseInt( maxArchiveSize[ 1 ].slice(), 10 );
}
/* pslimit */// If maxArchiveSize is defined, and archivePageSize >= maxArchiveSize increment counter and redfine page name.
if ( !errorLog.maxArchiveSize && archivePageSize >= maxArchiveSize ) {
counter++;
archiveName = archiveNameRegEx.exec( content0 );
var archiveName = archiveName[ 1 ]
.replace( /\| *archive *= */, '' )
.replace( /\%\(counter\)d/g, counter );
var oldCounter = counterRegEx.exec( content0 );
var newCounter = '|counter=1';
if ( oldCounter !== null && oldCounter !== undefined ) {
newCounter = oldCounter[ 0 ].replace( oldCounter[ 1 ], counter );
oldCounter = oldCounter[ 0 ];
} else {
errorLog.errorCount++;
errorLog.newCounter = newCounter;
}
}
/* archiveheader */// Get the defined archive header to place on archive page if it doesn't exist
var archiveHeaderRegEx = new RegExp( '\\| *archiveheader *= *(\{\{[^\r\n]*\}\})' );
var archiveHeader = archiveHeaderRegEx.exec( content0 );
if ( archiveHeader === null || archiveHeader === undefined ) {
archiveHeader = "{{Aan}}";
errorLog.errorCount++;
errorLog.archiveHeader = archiveHeader;
} else {
archiveHeader = archiveHeader[ 1 ];
}
/* headerlevel */// Get the headerlevel value or default to '2'
var headerLevelRegEx = new RegExp( '\\| *headerlevel *= *(\\d+)' );
var headerLevel = headerLevelRegEx.exec( content0 );
if ( headerLevel === null || headerLevel === undefined ) {
headerLevel = 2;
errorLog.errorCount++;
errorLog.headerLevel = headerLevel;
} else {
headerLevel = parseInt( headerLevel[ 1 ] );
}
/* debug */// Table to report the values found.
if ( mw.config.get( 'debug' ) === true ) {
var OCAreport = '<table style="width: 100%;" border="1"><tr><th style="font-variant: small-caps; font-size: 20px;">config</th><th style="font-variant: small-caps; font-size: 20px;">value</th></tr>';
OCAreport += '<tr><td>Counter</td><td style="text-align: center;';
if ( errorLog.counter ) { OCAreport += ' background-color: #FFEEEE;">' + errorLog.counter; }
else { OCAreport += '">' + counter; }
OCAreport += '</td></tr><tr><td colspan="2" style="text-align: center;">Archive name</td></tr><tr><td colspan="2" style="text-align: center;';
if ( errorLog.archiveName ) { OCAreport += ' background-color: #FFEEEE;">' + errorLog.archiveName; }
else { OCAreport += '">' + archiveName; }
OCAreport += '</td></tr><tr><td>Header Level</td><td style="text-align: center;';
if ( errorLog.headerLevel ) { OCAreport += ' background-color: #FFEEEE;">' + errorLog.headerLevel; }
else { OCAreport += '">' + headerLevel }
OCAreport += '</td></tr><tr><td>Archive header</td><td style="text-align: center;';
if ( errorLog.archiveHeader ) { OCAreport += ' background-color: #FFEEEE;">' + errorLog.archiveHeader; }
else { OCAreport += '">' + archiveHeader }
OCAreport += '</td></tr><tr><td>Max<br />archive size</td><td style="text-align: center;';
if ( errorLog.maxArchiveSize ) { OCAreport += ' background-color: #FFEEEE;">' + errorLog.maxArchiveSize; }
else { OCAreport += '">' + maxArchiveSize }
OCAreport += '</td></tr><tr><td>Current<br />archive size</td><td style="text-align: center;';
if ( errorLog.archivePageSize ) { OCAreport += ' background-color: #FFEEEE;">' + archivePageSize; }
else if ( archivePageSize >= maxArchiveSize ) { OCAreport += ' background-color: #FFEEEE;">' + archivePageSize; }
else { OCAreport += '">' + archivePageSize }
OCAreport += '</td></tr><tr><td colspan="2" style="font-size: larger; text-align: center;"><a href="/wiki/User:Technical_13/Scripts/OneClickArchiver" title="User:Technical 13/Scripts/OneClickArchiver">Documentation</a></td></tr></table>';
mw.notify( $( OCAreport ), { title: 'OneClickArchiver report!', tag: 'OCA', autoHide: false } );
}
var OCAerror = '<p>The following errors detected:<br />';
if ( errorLog.counter ) { OCAerror += '<b style="font-size: larger; color: #FF0000;">•</b> Unable to find <b>|counter=</b><br /> Default value: <b>1</b><br />'; }
if ( errorLog.archiveName && errorLog.archiveName.search( 'defaulted to' ) !== -1 ) { OCAerror += '<b style="font-size: larger; color: #FF0000;">•</b> Unable to find <b>|archive=</b><br /> Default value: <b>' + archiveName + '</b><br />'; }
if ( errorLog.archiveName && errorLog.archiveName.search( 'mismatch' ) !== -1 ) { OCAerror += '<b style="font-size: larger; color: #FF0000;">•</b> Archive name mismatch detected.<br />'; }
if ( errorLog.headerLevel ) { OCAerror += ' Unable to find <b>|headerlevel=</b><br /> Default value: <b>2</b><br />'; }
if ( errorLog.archiveHeader ) { OCAerror += ' Unable to find <b>|archiveheader=</b><br /> Default value: <b>"{{Aan}}"</b><br />'; }
if ( errorLog.maxArchiveSize ) { OCAerror += ' Unable to find <b>|maxarchivesize=</b><br /> Default value: <b>153600</b><br />'; }
if ( errorLog.counter || errorLog.archiveName ) { OCAerror += '<br /><b style="font-size: larger; color: #FF0000;">•</b> Causing the script to abort.<br />'; }
OCAerror += '<br /><span style="font-size: larger;">Please, see <a href="/wiki/User:Technical_13/Scripts/OneClickArchiver" title="User:Technical 13/Scripts/OneClickArchiver">the documentation</a> for details.</span></p>';
var archiverReport = mw.util.addPortletLink(
'p-cactions',
'#archiverNoLink',
'|Archive',
'pt-OCA-report',
'Report for why there are no |Archive links on this page',
null,
null
);
$( archiverReport ).click( function ( e ) {
e.preventDefault();
mw.notify( $( OCAerror ), { title: 'OneClickArchiver errors!', tag: 'OCAerr', autoHide: false } );
} );
$( 'h' + headerLevel + ' span.mw-headline' ).each( function( i, val ) {
var sectionName = $( this ).text();
var editSectionUrl = $( this ).parent().find( '.editsection a:first' ).attr( 'href' );
var sectionReg = /§ion=(.*)/;
var sectionRaw = sectionReg.exec( editSectionUrl );
if ( sectionRaw != null && sectionRaw[ 1 ].indexOf( 'T' ) < 0 ) {
var sectionNumber = parseInt( sectionRaw[ 1 ] );
if ( $( this ).parent().prop( 'tagName' ) === 'H' + headerLevel ) {
$( this ).parent( 'h' + headerLevel ).append( ' <div style="font-size: 0.6em; font-weight: bold; float: right;"> | <a id="' + sectionNumber +
'" href="#archiverLink" class="archiverLink">' + 'Archive' + '</a></div>' );
$( this ).parent( 'h' + headerLevel ).find( 'a.archiverLink' ).click( function() {
var mHeaders = '<span style="color: #444444;">Retrieving headers...</span>';
var mSection = 'retrieving section content...';
var mPosting = '<span style="color: #004400">Content retrieved,</span> performing edits...';
var mPosted = '<span style="color: #008800">Archive appended...</span>';
var mCleared = '<span style="color: #008800">Section cleared...</span>';
var mReloading = '<span style="color: #000088">All done! </span><a href="#archiverLink" onClick="javascript:location.reload();" title="Reload page">Reloading</a>...';
$( 'body' ).append( '<div class="overlay" style="background-color: #000000; opacity: 0.4; position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; z-index: 500;"></div>' );
$( 'body' ).prepend( '<div class="arcProg" style="font-weight: bold; box-shadow: 7px 7px 5px #000000; font-size: 0.9em; line-height: 1.5em; z-index: 501; opacity: 1; position: fixed; width: 50%; left: 25%; top: 30%; background: #F7F7F7; border: #222222 ridge 1px; padding: 20px;"></div>' );
$( '.arcProg' ).append( '<div>' + mHeaders + '</div>' );
$( '.arcProg' ).append( '<div>' + 'Archive name <span style="font-weight: normal; color: #003366;">' + archiveName + '</span> <span style="color: darkgreen;">found</span>, ' + mSection + ' (' + archivePageSize + 'b)</div>' );
new mw.Api().post( {
action: 'query',
pageids: pageid,
rvsection: sectionNumber,
prop: 'revisions|info',
rvprop: 'content',
indexpageids: 1,
} ).done( function ( responseSection ) {
var sectionContent = responseSection.query.pages[ pageid ].revisions[ 0 ][ '*' ];
$( '.arcProg' ).append( '<div>' + mPosting + '</div>' );
var dnau = sectionContent.match( /<!-- \[\[User:DoNotArchiveUntil\]\] ([\d]{2}):([\d]{2}), ([\d]{1,2}) (January|February|March|April|May|June|July|August|September|October|November|December) ([\d]{4}) \(UTC\) -->/ );
if ( dnau === null || dnau === undefined ) {
var dnauDate = Date.now();
dnau = null;
} else {
dnau = dnau[ 1 ] + ':' + dnau[ 2 ] + ' ' + dnau[ 3 ] + ' ' + dnau[ 4 ] + ' ' + dnau[ 5 ];
var dnauDate = new Date( dnau );
dnauDate = dnauDate.valueOf();
}
if ( dnauDate > Date.now() ) {
$( '.arcProg' ).remove();
$( '.overlay' ).remove();
var dnauAbortMsg = '<p>This section has been marked \"Do Not Archive Until\" ' + dnau + ', so archiving was aborted.<br /><br /><span style="font-size: larger;">Please, see <a href="/wiki/User:Technical_13/Scripts/OneClickArchiver" title="User:Technical 13/Scripts/OneClickArchiver">the documentation</a> for details.</span></p>';
mw.notify( $( dnauAbortMsg ), { title: 'OneClickArchiver aborted!', tag: 'OCAdnau', autoHide: false } );
} else {
var archiveAction = 'adding';
if ( archivePageSize <= 0 || ( archivePageSize >= maxArchiveSize && !errorLog.maxArchiveSize ) ) {
sectionContent = archiveHeader + '\n\n' + sectionContent;
archiveAction = 'creating'
mPosted = '<span style="color: #008800">Archive created...</span>';
} else {
sectionContent = '\n\n{{Clear}}\n' + sectionContent;
}
if ( dnau != null ) {
sectionContent = sectionContent.replace( /<!-- \[\[User:DoNotArchiveUntil\]\] ([\d]{2}):([\d]{2}), ([\d]{1,2}) (January|February|March|April|May|June|July|August|September|October|November|December) ([\d]{4}) \(UTC\) -->/g, '' );
}
new mw.Api().postWithEditToken({
action: 'edit',
title: archiveName,
appendtext: sectionContent,
summary: 'OneClickArchiver ' + archiveAction + ' [[' + archiveName + '#' + sectionName + '|' + sectionName + ']]'
} ).done( function ( archived ) {
$( '.arcProg' ).append( '<div class="archiverPosted">' + mPosted + '</div>' );
new mw.Api().postWithEditToken({
action: 'edit',
section: sectionNumber,
pageid: pageid,
text: '',
summary: 'OneClickArchiver archived \'' + sectionName + '\' to [[' + archiveName + '#' + sectionName + '|' + archiveName + ']]'
} ).done( function () {
$( '.arcProg' ).append( '<div class="archiverCleared">' + mCleared + '</div>' );
if ( archivePageSize >= maxArchiveSize && !errorLog.maxArchiveSize ) {
var mUpdated = '<span style="color: #008800">Counter updated...</span>';
new mw.Api().postWithEditToken({
action: 'edit',
section: 0,
pageid: pageid,
text: content0.replace( oldCounter, newCounter ),
summary: 'OneClickArchiver updating counter.'
} ).done( function () {
$( '.arcProg' ).append( '<div class="archiverPosted">' + mUpdated + '</div>' );
$( '.arcProg' ).append( '<div>' + mReloading + '</div>' );
location.reload();
} );
} else {
$( '.arcProg' ).append( '<div>' + mReloading + '</div>' );
location.reload();
}
} );
} );
}
} );
} );
}
}
} );
} );
} );
}
} );
} );