User:Colin M/scripts/JWB annotated.js

// Copied from User:Joeytje50/JWB.js

/**

* Install this script by pasting the following in your personal JavaScript file:

mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/load.js&action=raw&ctype=text/javascript');

* Or for users on en.wikipedia.org:

importScript( 'User:Joeytje50/JWB.js/load.js' ); // Backlink: User:Joeytje50/JWB.js/load.js

* Note that this script will only run on the 'Project:AutoWikiBrowser/Script' page.

* This script is based on the downloadable AutoWikiBrowser.

*

* @licence

* This program is free software; you can redistribute it and/or modify

* it under the terms of the GNU General Public License as published by

* the Free Software Foundation; either version 2 of the License, or

* (at your option) any later version.

*

* This program is distributed in the hope that it will be useful,

* but WITHOUT ANY WARRANTY; without even the implied warranty of

* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

* GNU General Public License for more details.

*

* You should have received a copy of the GNU General Public License along

* with this program; if not, write to the Free Software Foundation, Inc.,

* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

* http://www.gnu.org/copyleft/gpl.html

* @version 3.1.0

* @author Joeytje50

*/

//TODO: Re-enable summary box (possibly more) when not busy submitting.

//TODO: more advanced pagelist-generating options

//TODO: generate page list based on images on a page

//TODO: Split up i18n to separate files per language (in the same way MediaWiki does it)

//TODO: Add feature to perform general cleanup (

to {|, fullurl-links to wikilinks, removing underscores from wikilinks)

window.JWB = {}; //The main global object for the script.

/***** User verification *****/

(function() {

if (mw.config.get('wgCanonicalNamespace')+':'+mw.config.get('wgTitle') !== 'Project:AutoWikiBrowser/Script Beta' || JWB.allowed === false || mw.config.get('wgUserName') === null) {

JWB.allowed = false;

return;

}

mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.css&action=raw&ctype=text/css', 'text/css');

mw.loader.load('mediawiki.diff.styles');

$.getScript('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/i18n.js&action=raw&ctype=text/javascript', function() {

if (JWB.allowed === true) {

JWB.init(); //init if verification has already returned true

} else if (JWB.allowed === false) {

alert(JWB.msg('not-on-list'));

}

});

//RegEx Typo Fixing

$.getScript('//en.wikipedia.org/w/index.php?title=User:Joeytje50/RETF.js&action=raw&ctype=text/javascript', function() {

$('#refreshRETF').click(RETF.load);

});

(new mw.Api()).get({

action: 'query',

titles: 'Project:AutoWikiBrowser/CheckPage',

prop: 'revisions',

meta: 'userinfo|siteinfo',

rvprop: 'content',

rvlimit: 1,

uiprop: 'groups',

siprop: 'namespaces',

indexpageids: true,

format: 'json',

}).done(function(response) {

if (response.error) {

alert('API error: ' + response.error.info);

JWB = false; //preventing further access. No verification => no access.

return;

}

JWB.ns = response.query.namespaces; //saving for later

JWB.username = response.query.userinfo.name; //preventing any "hacks" that change wgUserName or mw.config.wgUserName

var groups = response.query.userinfo.groups;

var page = response.query.pages[response.query.pageids[0]];

var users, bots;

if (response.query.pageids[0] !== '-1' && //.test(page.revisions[0]['*'])) {

var cont = page.revisions[0]['*'];

users = cont.substring(

cont.search(//),

cont.search(//)

).split('\n');

if (//.test(cont)) {

bots = cont.substring(

cont.search(//),

cont.search(//)

).split('\n');

} else bots = [];

var i=0;

while (i

if (users[i].charAt(0) !== '*') {

users.splice(i,1);

} else {

users[i] = $.trim(users[i].substr(1));

i++;

}

}

i=0;

while (i

if (bots[i].charAt(0) !== '*') {

bots.splice(i,1);

} else {

bots[i] = $.trim(bots[i].substr(1));

i++;

}

}

} else {

users = false; //fallback when page doesn't exist

}

// Temporary global debugging variables

JWB.debug = [groups.indexOf('bot'), users === false, bots && bots.indexOf(JWB.username)];

JWB.bot = groups.indexOf('bot') !== -1 && (users === false || bots.indexOf(JWB.username) !== -1);

JWB.sysop = groups.indexOf('sysop') !== -1;

if (JWB.username === "Joeytje50" && response.query.userinfo.id === 13299994) {//TEMP: Dev full access to entire interface.

JWB.bot = true;

users.push("Joeytje50");

}

if (JWB.sysop || response.query.pageids[0] === '-1' || users.indexOf(JWB.username) !== -1 || users === false) {

JWB.allowed = true;

if (JWB.messages.en) JWB.init(); //init if messages have already loaded

} else {

if (JWB.messages.en) {

//run this after messages have loaded, so the message that shows is in the user's language

alert(JWB.msg('not-on-list'));

}

JWB = false; //prevent further access

}

}).fail(function(xhr, error) {

alert(JWB.msg('verify-error') + '\n' + error);

JWB = false; //preventing further access. No verification => no access.

});

})();

/***** Global object/variables *****/

var objs = ['page', 'api', 'fn', 'pl', 'messages', 'setup', 'settings', 'ns'];

for (var i=0;i

JWB[objs[i]] = {};

}

JWB.summarySuffix = ' (via JWB)';

if (document.location.hostname == 'en.wikipedia.org') JWB.summarySuffix = ' (via WP:JWB)'

JWB.lang = mw.config.get('wgUserLanguage');

JWB.index_php = mw.config.get('wgScript');

JWB.isStopped = true;

JWB.tooltip = window.tooltipAccessKeyPrefix || '';

JWB.configext = 'js';

if (document.location.hostname.split('.').slice(-2).join('.') == 'wikia.com' || document.location.hostname.split('.').slice(-2).join('.') == 'fandom.com') {

//it makes no sense, but Wikia does not allow users to create .js subpages of their userpage.

//Because the settings should REALLY be protected from vandalism automatically, the backup is .css

//even though this has nothing to do with CSS.

JWB.configext = 'css';

}

JWB.settingspage = 'JWB';

if (window.hasOwnProperty('JWBSETTINGS')) {

JWB.settingspage = JWBSETTINGS;

delete window.JWBSETTINGS; //clean up the global variable

}

/***** Google Analytics *****/

JWB.loadAnalytics = function() {

$.getScript('https://www.googletagmanager.com/gtag/js?id=UA-149754182-1', function() {

window.dataLayer = window.dataLayer || [];

function gtag(){

dataLayer.push(arguments);

}

gtag('js', new Date());

gtag('config', 'UA-149754182-1', { 'anonymize_ip': true }); // anonymize_ip to comply with GDPR

});

}

/***** API functions *****/

//Main template for API calls

JWB.api.call = function(data, callback, onerror) {

data.format = 'json';

if (data.action !== 'query') data.bot = true;

$.ajax({

data: data,

dataType: 'json',

url: mw.config.get('wgScriptPath') + '/api.php',

type: 'POST',

success: function(response) {

if (response.error) {

alert('API error: ' + response.error.info);

JWB.stop();

} else {

callback(response);

}

},

error: function(xhr, error) {

alert('AJAX error: ' + error);

JWB.stop();

if (onerror) onerror();

}

});

};

//Get page diff, and process it for more interactivity

JWB.api.diff = function(callback) {

JWB.status('diff');

var editBoxInput = $('#editBoxArea').val();

var redirects = $('input.redirects:checked').val()==='follow'?'1':'0';

var data = {

'action': 'query',

'prop': 'info|revisions',

'indexpageids': true,

'titles': JWB.page.name,

'rvlimit': '1',

'rvdifftotext': editBoxInput,

'redirects': redirects

};

JWB.api.call(data, function(response) {

var pageExists = response.query.pageids[0] !== '-1';

var diff;

if (pageExists) {

var diffpage = response.query.pages[response.query.pageids[0]];

diff = diffpage.revisions[0].diff['*'];

if (diff === '') {

diff = '

'+JWB.msg('no-changes-made')+'

';

} else {

diff = '

'+

'

'+

'

'+

'

'+

'

'+

'

'+

''+

'

'+diff+'
';

}

} else {

diff = ''+JWB.msg('page-not-exists')+'';

}

$('#resultWindow').html(diff);

$('.diff-lineno').each(function() {

$(this).parent().attr('data-line',parseInt($(this).html().match(/\d+/)[0])-1).addClass('lineheader');

});

$('table.diff tr').each(function() { //add data-line attribute to every line, relative to the previous one. Used for click event.

if (!$(this).next().is('[data-line]') && !$(this).next().has('td.diff-deletedline + td.diff-empty')) {

$(this).next().attr('data-line',parseInt($(this).data('line'))+1);

} else if ($(this).next().has('td.diff-deletedline + td.diff-empty')) {

$(this).next().attr('data-line',$(this).data('line')); //copy over current data-line for deleted lines to prevent them from messing up counting.

}

});

JWB.status('done', true);

if (typeof(callback) === 'function') {

callback();

}

});

};

//Retrieve page contents/info, process them, and store information in JWB.page object.

JWB.api.get = function(pagename) {

JWB.pageCount();

if (!JWB.list[0] || JWB.isStopped) {

return JWB.stop();

}

if (pagename === '#PRE-PARSE-STOP') {

var curval = $('#articleList').val();

$('#articleList').val(curval.substr(curval.indexOf('\n') + 1));

$('#preparse').prop('checked', false);

JWB.stop();

return;

}

var redirect = $('input.redirects:checked').val();

var data = {

'action': 'query',

'prop': 'info|revisions',

'inprop': 'watched',

'intoken': 'edit|delete|protect|move|watch',

'titles': pagename,

'rvprop': 'content|timestamp|ids',

'rvlimit': '1',

'indexpageids': true,

'meta': 'userinfo',

'uiprop': 'hasmsg'

};

if (redirect=='follow'||redirect=='skip') data.redirects = true;

if (JWB.sysop) {

data.list = 'deletedrevs';

data.drprop = 'token';

}

JWB.status('load-page');

JWB.api.call(data, function(response) {

if (response.query.userinfo.hasOwnProperty('messages')) {

var view = mw.config.get('wgScriptPath') + '?title=Special:MyTalk';

var viewNew = view + '&diff=cur';

JWB.status(

''+

JWB.msg('status-newmsg',

''+JWB.msg('status-talklink')+'',

''+JWB.msg('status-difflink')+'')+

'', true);

alert(JWB.msg('new-message'));

JWB.stop();

return;

}

JWB.page = response.query.pages[response.query.pageids[0]];

JWB.page.name = JWB.list[0].split('|')[0];

var varOffset = JWB.list[0].indexOf('|') !== -1 ? JWB.list[0].indexOf('|') + 1 : 0;

JWB.page.pagevar = JWB.list[0].substr(varOffset);

JWB.page.content = JWB.page.revisions ? JWB.page.revisions[0]['*'] : '';

JWB.page.exists = !response.query.pages["-1"];

JWB.page.deletedrevs = response.query.deletedrevs;

JWB.page.watched = JWB.page.hasOwnProperty('watched');

if (response.query.redirects) {

JWB.page.name = response.query.redirects[0].to;

}

var newContent = JWB.replace(JWB.page.content);

if (JWB.stopped === true) return;

JWB.status('done', true);

var containRegex = $('#containRegex').prop('checked'), containFlags = $('#containFlags').val();

var skipContains = containRegex ? new RegExp($('#skipContains').val(), containFlags) : $('#skipContains').val();

var skipNotContains = containRegex ? new RegExp($('#skipNotContains').val(), containFlags) : $('#skipContains').val();

if (

($('#skipNoChange').prop('checked') && JWB.page.content === newContent) || //skip if no changes are made

($('#skipContains').val() && JWB.page.content.match(skipContains)) ||

($('#skipNotContains').val() && !JWB.page.content.match(skipNotContains)) ||

($('#exists-no').prop('checked') && !JWB.page.exists) ||

($('#exists-yes').prop('checked') && JWB.page.exists) ||

(redirect==='skip' && response.query.redirects) // variable redirect is defined outside this callback function.

) {

JWB.log('skip', JWB.page.name);

return JWB.next();

} else {

$('#editBoxArea').val(newContent);

$('#currentpage').html(JWB.msg('editbox-currentpage', JWB.page.name, encodeURIComponent(JWB.page.name)));

if ($('#preparse').prop('checked')) {

$('#articleList').val($.trim($('#articleList').val()) + '\n' + JWB.list[0]); //move current page to the bottom

JWB.next();

return;

} else if (JWB.bot && $('#autosave').prop('checked')) {

JWB.api.diff(function() {

//timeout will take #throttle's value * 1000, if it's a number above 0. Currently defaults to 0.

setTimeout(JWB.api.submit, Math.max(+$('#throttle').val() || 0, 0) * 1000, JWB.page.name);

});

} else {

JWB.api.diff();

}

}

JWB.updateButtons();

});

};

//Some functions with self-explanatory names:

JWB.api.submit = function(page) {

JWB.status('submit');

var summary = $('#summary').val();

if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix;

if ((typeof page === 'text' && page !== JWB.page.name) || $('#currentpage a').html().replace(/&/g, '&') !== JWB.page.name) {

console.log(page, JWB.page.name, $('#currentpage a').html())

JWB.stop();

alert(JWB.msg('autosave-error', JWB.msg('tab-log')));

$('#currentpage').html(JWB.msg('editbox-currentpage', ' ', ' '));

return;

}

var data = {

'title': JWB.page.name,

'summary': summary,

'action': 'edit',

'basetimestamp': JWB.page.revisions ? JWB.page.revisions[0].timestamp : '',

'token': JWB.page.edittoken,

'text': $('#editBoxArea').val(),

'watchlist': $('#watchPage').val()

};

if ($('#minorEdit').prop('checked')) data.minor = true;

JWB.api.call(data, function(response) {

JWB.log('edit', response.edit.title, response.edit.newrevid);

JWB.status('done', true);

JWB.next();

});

};

JWB.api.preview = function() {

JWB.status('preview');

JWB.api.call({

'title': JWB.page.name,

'action': 'parse',

'text': $('#editBoxArea').val()

}, function(response) {

$('#resultWindow').html(response.parse.text['*']);

$('#resultWindow div.previewnote').remove();

JWB.status('done', true);

});

};

JWB.api.move = function() {

JWB.status('move');

var topage = $('#moveTo').val().replace(/\$x/gi, JWB.page.pagevar);

var summary = $('#summary').val();

if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix;

var data = {

'action':'move',

'from': JWB.page.name,

'to': topage,

'token': JWB.page.movetoken,

'reason': summary,

'ignorewarnings': 'yes'

};

if ($('#moveTalk').prop('checked')) data.movetalk = true;

if ($('#moveSubpage').prop('checked')) data.movesubpages = true;

if ($('#suppressRedir').prop('checked')) data.noredirect = true;

JWB.api.call(data, function(response) {

JWB.log('move', response.move.from, reponse.move.to);

JWB.status('done', true);

if (!$('#moveTo').val().match(/\$x/i)) $('#moveTo').val('')[0].focus(); //clear entered move-to pagename if it's not based on the pagevar

JWB.next(topage);

});

};

JWB.api.delete = function() {

JWB.status(($('#deletePage').is('.undelete') ? 'un' : '') + 'delete');

var summary = $('#summary').val();

if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix;

var undeltoken = JWB.page.deletedrevs && JWB.page.deletedrevs[0] ? JWB.page.deletedrevs[0].token : '';

JWB.api.call({

'action': (!JWB.page.exists ? 'un' : '') + 'delete',

'title': JWB.page.name,

'token': JWB.page.exists ? JWB.page.deletetoken : undeltoken,

'reason': summary

}, function(response) {

JWB.log((!JWB.page.exists ? 'un' : '') + 'delete', (response.delete||response.undelete).title);

JWB.status('done', true);

JWB.next(response.undelete && response.undelete.title);

});

};

JWB.api.protect = function() {

JWB.status('protect');

var summary = $('#summary').val();

if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix;

var editprot = $('#editProt').val();

var moveprot = $('#moveProt').val();

JWB.api.call({

'action':'protect',

'title': JWB.page.name,

'token': JWB.page.protecttoken,

'reason': summary,

'expiry': $('#protectExpiry').val()!==''?$('#protectExpiry').val():'infinite',

'protections': (JWB.page.exists?'edit='+editprot+'|move='+moveprot:'create='+editprot)

}, function(response) {

var protactions = '';

var prots = response.protect.protections;

for (var i=0;i

if (typeof prots[i].edit == 'string') {

protactions += ' edit: '+(prots[i].edit?prots[i].edit:'all');

} else if (typeof prots[i].move == 'string') {

protactions += ' move: '+(prots[i].move?prots[i].move:'all');

} else if (typeof prots[i].create == 'string') {

protactions += ' create: '+(prots[i].create?prots[i].create:'all');

}

}

protactions += ' expires: '+prots[0].expiry;

JWB.log('protect', response.protect.title, protactions);

JWB.status('done', false);

JWB.next(response.protect.title);

});

};

JWB.api.watch = function() {

JWB.status('watch');

var data = {

'action':'watch',

'title':JWB.page.name,

'token':JWB.page.watchtoken

};

if (JWB.page.watched) data.unwatch = true;

JWB.api.call(data, function(response) {

JWB.status(''+

JWB.msg('status-watch-'+(JWB.page.watched ? 'removed' : 'added'), "'"+JWB.page.name+"'")+

'', true);

JWB.page.watched = !JWB.page.watched;

$('#watchNow').html( JWB.msg('watch-' + (JWB.page.watched ? 'remove' : 'add')) );

});

};

/***** Pagelist functions *****/

JWB.pl.list = [];

JWB.pl.iterations = 0;

JWB.pl.stop = function() {

JWB.pl.iterations = 0;

$('#pagelistPopup [disabled]:not(fieldset [disabled]), #pagelistPopup legend input').prop('disabled', false);

$('#pagelistPopup legend input').trigger('change');

$('#pagelistPopup button img').remove();

}

JWB.pl.getNSpaces = function() {

var list = $('#pagelistPopup [name="namespace"]')[0];

if (list.selectedOptions.length == list.options.length) {

return ''; //return empty string if every namespace is selected; this will make the request default to having no filter

} else {

return $('#pagelistPopup [name="namespace"]').val().join('|'); //.val() returns an array of selected options.

}

};

/**

* abbrs: array of abbreviations for each page generator enabled.

* ps = prefix search, pl = links on page, etc.

* note that the "Links to page" section may generate multiple generators (each

* of wikilinks, transclusions, and file usage are done separately)

* lists: as above, but full names. Possible elements include:

* prefixsearch, links, watchlistraw

* These correspond to possible "list" values for https://www.mediawiki.org/wiki/API:Query

* Er, except when they don't. "links" is not a valid list value (but this just causes a benign warning)

* data: object with keys for each value in lists, plus "continue". For each generator,

* the corresponding value will be the user input related to that generator

* (e.g. the category name, the title prefix). If there are multiple values for

* a generator, they'll be pipe-delimited within the string.

* More keys will be added to this obj during this function's execution.

* (This is ultimately used as POST data for API calls)

  • /

JWB.pl.getList = function(abbrs, lists, data) {

$('#pagelistPopup button, #pagelistPopup input, #pagelistPopup select').prop('disabled', true);

JWB.pl.iterations++;

// cf. https://www.mediawiki.org/wiki/API:Query

data.action = 'query';

var nspaces = JWB.pl.getNSpaces();

for (var i=0;i

if (nspaces) data[abbrs[i]+'namespace'] = nspaces;

data[abbrs[i]+'limit'] = 'max';

}

if (lists.indexOf('links') !== -1) {

// If using the "Links on page" feature, then ask the API to give us the links

// on each returned page

data.prop = 'links';

}

data.list = lists.join('|');

JWB.api.call(data, function(response) {

var maxiterate = 100; //allow up to 100 consecutive requests at a time to avoid overloading the server.

if (!response.query) response.query = {};

if (response.watchlistraw) response.query.watchlistraw = response.watchlistraw; //adding some consistency

var plist = [];

if (response.query.pages) {

var links;

for (var id in response.query.pages) {

links = response.query.pages[id].links;

for (var i=0;i

plist.push(links[i].title);

}

}

}

for (var l in response.query) {

if (l === 'pages') continue;

for (var i=0;i

plist.push(response.query[l][i].title);

}

}

//add the result to the pagelist immediately, as opposed to saving it all up and adding in 1 go like AWB does

$('#articleList').val($.trim($('#articleList').val()) + '\n' + plist.join('\n'));

JWB.pageCount();

var cont = response.continue;

console.log("Continue",JWB.pl.iterations, cont);

if (cont && JWB.pl.iterations <= maxiterate) {

var lists = [];

if (response.query) { //compatibility with the code I wrote for the old query-continue. TODO: make this unnecessary?

for (var list in response.query) {

lists.push(list); //add to the new array of &list= values

}

}

var abbrs = [];

for (var abbr in cont) {

data[abbr] = cont[abbr]; //add the &xxcontinue= value to the data

if (abbr != 'continue') {

abbrs.push(abbr.replace('continue','')); //find out what xx is and add it to the list of abbrs

}

}

JWB.pl.getList(abbrs, lists, data); //recursive function to get every page of a list

} else {

if (JWB.pl.iterations > maxiterate) {

JWB.status('pl-over-lim', true);

} else {

JWB.status('done', true);

}

JWB.pl.stop();

}

}, function() { //on error, simply reset and let the user work with what he has

JWB.status('done', true);

JWB.pl.stop();

});

};

//JWB.pl.getList(['wr'], ['watchlistraw'], {}) for watchlists

JWB.pl.generate = function() {

var $fields = $('#pagelistPopup fieldset').not('[disabled]');

var spinner = ''+JWB.msg('status-alt')+'';

$('#pagelistPopup').find('button[type="submit"]').append(spinner);

var abbrs = [], lists = [], data = {'continue': ''};

$fields.each(function() {

var list = $(this).find('legend input').attr('name');

var abbr;

if (list === 'linksto') { //Special case since this fieldset features 3 merged lists in 1 fieldset

if (!$('[name="title"]').val()) return;

$('[name="backlinks"], [name="embeddedin"], [name="imageusage"]').filter(':checked').each(function() {

var val = this.value;

abbrs.push(val);

lists.push(this.name);

data[val+'title'] = $('[name="title"]').val();

data[val+'filterredir'] = $('[name="filterredir"]:checked').val();

if ($('[name="redirect"]').prop('checked')) data[val+'redirect'] = true;

});

} else { //default input system

abbr = $(this).find('legend input').val();

lists.push(list);

abbrs.push(abbr);

// For each input in this fieldset other than the checkbox enabling it,

// add a key-value pair to data, where the key is the input's name and

// the value is the value (or pipe-separated string of values, if multiple)

// (These will correspond to params of the API query)

$(this).find('input').not('legend input').each(function() {

if ((this.type === 'checkbox' || this.type === 'radio') && this.checked === false) return;

if ($(this).is('[name="cmtitle"]')) {

//making sure every page has a Category: prefix, in case the user left it out

var newval = $(this).val().replace(new RegExp(JWB.ns[14]['*']+':', 'gi'), '').split('|')[0];

$(this).val(JWB.ns[14]['*']+':'+newval);

}

var name = this.name;

var val = this.value;

if (data.hasOwnProperty(name)) {

data[name] += '|'+val;

} else {

data[name] = val;

}

});

console.log("abbrs, lists, data:", abbrs, lists, data);

}

});

if (abbrs.length) JWB.pl.getList(abbrs, lists, data);

};

/***** Setup functions *****/

JWB.setup.save = function(name) {

name = name || prompt(JWB.msg('setup-prompt', JWB.msg('setup-prompt-store')), $('#loadSettings').val());

if (name === null) return;

var self = JWB.settings[name] = {

string: {},

bool: {},

replaces: []

};

//inputs with a text value

$('textarea, input[type="text"], input[type="number"], select').not('.replaces input, #editBoxArea, #settings *, #google-analytics').each(function() {

if (typeof $(this).val() == 'string') {

self.string[this.id] = this.value.replace(/\n{2,}/g,'\n');

} else {

self.string[this.id] = $(this).val();

}

});

self.replaces = [];

$('.replaces').each(function() {

if ($(this).find('.replaceText').val() || $(this).find('.replaceWith').val()) {

self.replaces.push({

replaceText: $(this).find('.replaceText').val(),

replaceWith: $(this).find('.replaceWith').val(),

useRegex: $(this).find('.useRegex').prop('checked'),

regexFlags: $(this).find('.regexFlags').val(),

ignoreNowiki: $(this).find('.ignoreNowiki').prop('checked')

});

}

});

$('input[type="radio"], input[type="checkbox"]').not('.replaces input').each(function() {

self.bool[this.id] = this.checked;

});

if (!$('#loadSettings option[value="'+name+'"]').length) {

$('#loadSettings').append('');

}

$('#loadSettings').val(name);

console.log(self);

};

JWB.setup.apply = function(name) {

name = name && JWB.settings[name] ? name : 'default';

var self = JWB.settings[name];

$('#loadSettings').val(name);

$('.replaces + .replaces').remove(); //reset find&replace inputs

$('.replaces input[type="text"]').val('');

$('.useRegex').each(function() {this.checked = false;});

$('#pagelistPopup legend input').trigger('change'); //fix checked state of pagelist generating inputs

for (var a in self.string) {

$('#'+a).val(self.string[a]);

}

for (var b in self.bool) {

$('#'+b).prop('checked', self.bool[b]);

}

var cur;

for (var c=0;c

if ($('.replaces').length <= c) $('#moreReplaces')[0].click();

cur = self.replaces[c];

for (var d in cur) {

if (cur[d] === true || cur[d] === false) {

$('.replaces').eq(c).find('.'+d).prop('checked', cur[d]);

} else {

$('.replaces').eq(c).find('.'+d).val(cur[d]);

}

}

}

$('.useRegex, #containRegex,'+

'#pagelistPopup legend input,'+

'#viaJWB').trigger('change'); //reset disabled inputs

};

JWB.setup.getObj = function() {

// google analytics preferences do not depend on which settings profile, so should be stored outside that.

JWB.settings['_google_analytics'] = $('#allow-analytics').prop('checked');

var settings = [];

for (var i in JWB.settings) {

if (i != '_blank') {

settings.push('"' + i + '": ' + JSON.stringify(JWB.settings[i]));

}

}

return '{\n\t' + settings.join(',\n\t') + '\n}';

};

JWB.setup.submit = function() {

var name = prompt(JWB.msg('setup-prompt', JWB.msg('setup-prompt-save')), $('#loadSettings').val());

if (name === null) return;

if ($.trim(name) === '') name = 'default';

JWB.setup.save(name);

JWB.status('setup-submit');

JWB.api.call({

'title': 'User:'+JWB.username+'/'+JWB.settingspage+'-settings.'+JWB.configext,

'summary': JWB.msg(['setup-summary', mw.config.get('wgContentLanguage')]),

'action': 'edit',

'token': JWB.setup.edittoken,

'text': JWB.setup.getObj(),

'minor': true

}, function(response) {

JWB.status('done', true);

});

};

//TODO: use blob uri

JWB.setup.download = function() {

var name = prompt(JWB.msg('setup-prompt', JWB.msg('setup-prompt-save')), $('#loadSettings').val());

if (name === null) return;

if ($.trim(name) === '') name = 'default';

JWB.setup.save(name);

JWB.status('setup-dload');

var url = 'data:application/json;base64,' + btoa(JWB.setup.getObj());

var elem = $('#download-anchor')[0];

if (elem.hasOwnProperty('download')) { //use download attribute when possible, for its ability to specify a filename

elem.href = url;

elem.click();

setTimeout(function() {elem.removeAttribute('href');}, 2000);

} else { //fallback to iframes for browsers with no support for download="" attributes

elem = $('#download-iframe')[0];

elem.src = url.replace('application/json', 'application/octet-stream');

setTimeout(function() {elem.removeAttribute('src');}, 2000);

}

JWB.status('done', true);

};

JWB.setup.import = function(e) {

e.preventDefault();

file = (e.dataTransfer||this).files[0];

if ($(this).is('#import')) { //reset input

this.outerHTML = this.outerHTML;

$('#import').change(JWB.setup.import);

}

if (!window.hasOwnProperty('FileReader')) {

alert(JWB.msg('old-browser'));

JWB.status('old-browser', '/'+JWB.settingspage+'-settings.'+JWB.configext+'');

return;

}

if (file.name.split('.').pop().toLowerCase() !== 'json') {

alert(JWB.msg('not-json'));

return;

}

JWB.status('Processing file');

var reader = new FileReader();

reader.readAsText(file);

reader.onload = function(e) {

JWB.status('done', true);

try {

//Exclusion regex based on http://stackoverflow.com/a/23589204/1256925

//Removes all JS comments from the file, except when they're between quotes.

var data = JSON.parse(reader.result.replace(/("[^"]*")|(\/\*[\w\W]*\*\/|\/\/[^\n]*)/g, function(match, g1, g2) {

if (g1) return g1;

}));

} catch(e) {

alert(JWB.msg('json-err', e.message, JWB.msg('json-err-upload')));

console.log(e); //also log the error for further info

return;

}

JWB.setup.extend(data);

};

JWB.status('Processing file');

};

JWB.setup.load = function() {

JWB.status('setup-load');

JWB.api.call({

'action': 'query',

'titles': 'User:' + (JWB.username||mw.config.get('wgUserName')) + '/'+JWB.settingspage+'-settings.'+JWB.configext,

'prop': 'info|revisions',

'intoken': 'edit',

'rvprop': 'content',

'indexpageids': true

}, function(response) {

JWB.status('done', true);

if (JWB === false) return; //user is not allowed to use JWB

var firstrun = JWB.setup.edittoken ? false : true;

var page = response.query.pages[response.query.pageids[0]];

JWB.setup.edittoken = page.edittoken;

if (response.query.pageids[0] === '-1') {

if (JWB.allowed && firstrun) JWB.setup.save('default'); //this runs when this callback returns after the init has loaded.

JWB.loadAnalytics(); // load Analytics, because user did not opt-out (no settings page)

return;

}

var data = page.revisions[0]['*'];

if (!data) {

if (JWB.allowed && firstrun) JWB.setup.save('default'); //this runs when this callback returns after the init has loaded.

JWB.loadAnalytics(); // load Analytics, because user did not opt-out (empty settings page)

return;

}

try {

data = JSON.parse(data);

} catch(e) {

alert(JWB.msg('json-err', e.message, JWB.msg('json-err-page', JWB.settingspage)) || 'JSON error:\n'+e.message);

JWB.setup.save('default');

JWB.loadAnalytics(); // load Analytics, because user did not opt-out (no valid settings page)

return;

}

if (data["_google_analytics"] === false) {

$('#allow-analytics').prop('checked', false); // user opts out of analytics

} else {

JWB.loadAnalytics(); // if user's settings exist, and the google analytics preference is not false, load GA.

delete data["_google_analytics"]; // prevent "_google_analytics" from appearing as a profile

}

JWB.setup.extend(data);

});

};

JWB.setup.extend = function(obj) {

$.extend(JWB.settings, obj);

if (!JWB.settings.hasOwnProperty('default')) {

JWB.setup.save('default');

}

for (var i in JWB.settings) {

if ($('#loadSettings').find('option[value="'+i+'"]').length) continue;

$('#loadSettings').append('');

}

JWB.setup.apply($('#loadSettings').val());

};

JWB.setup.delete = function() {

var name = $('#loadSettings').val();

if (name === '_blank') return alert(JWB.msg('setup-delete-blank'));

var temp = {};

temp[name] = JWB.settings[name];

JWB.setup.temp = $.extend({}, temp);

delete JWB.settings[name];

$('#loadSettings').val('default');

if (name === 'default') {

JWB.setup.apply('_blank');

JWB.setup.save('default');

JWB.status(JWB.msg('status-del-default', ''+JWB.msg('status-del-undo')+''), true);

} else {

$('#loadSettings').find('[value="'+name+'"]').remove();

JWB.setup.apply();

JWB.status(JWB.msg('status-del-setup', name, ''+JWB.msg('status-del-undo')+''), true);

}

};

JWB.setup.undelete = function() {

JWB.setup.extend(JWB.setup.temp);

JWB.status('done', true);

};

/***** Main other functions *****/

//Show status message

JWB.status = function(action, done) {

$('#summary, .editbutton').prop('disabled', !done); //Disable box when not done (so busy loading). re-enable when done loading.

var status = JWB.msg('status-'+action);

if (status === false) return;

var spinImg = ''+JWB.msg('status-alt')+'';

if (status) {

if (!done) { //spinner if not done

status += ' ' + spinImg;

}

} else {

status = action;

}

$('#status').html(status);

JWB.pageCount();

return action=='done';

};

JWB.pageCount = function() {

if (JWB.allowed === false||!$('#articleList').length) return;

$('#articleList').val(($('#articleList').val()||).replace(/(^[ \t]*$\n)*/gm, ));

JWB.list = $('#articleList').val().split('\n');

var count = JWB.list.length;

if (count === 1 && JWB.list[0] === '') count = 0;

$('#totPages').html(count);

};

//Perform all specified find&replace actions

JWB.replace = function(input) {

JWB.pageCount();

var varOffset = JWB.list[0].indexOf('|') !== -1 ? JWB.list[0].indexOf('|') + 1 : 0;

JWB.page.pagevar = JWB.list[0].substr(varOffset);

$('.replaces').each(function() {

var $this = $(this);

var regexFlags = $this.find('.regexFlags').val();

var replace = $this.find('.replaceText').val().replace(/\$x/gi, JWB.page.pagevar).replace(/\\{2}/g, '\\').replace(/\\n/g,'\n') || '$';

var useRegex = replace === '$' || $this.find('.useRegex').prop('checked');

if (useRegex && regexFlags.indexOf('_') !== -1) {

replace = replace.replace(/[ _]/g, '[ _]'); //replaces any of [Space OR underscore] with a match for spaces or underscores.

replace = replace.replace(/(\^\*)\[ _\]/g, '$1 _'); //in case a [ _] was placed inside another [] match, remove the [].

regexFlags = regexFlags.replace('_', '');

}

//apply replaces where \n and \\ work in both regular text and regex mode.

var rWith = $this.find('.replaceWith').val().replace(/\$x/gi, JWB.page.pagevar).replace(/\\{2}/g, '\\').replace(/\\n/g,'\n');

try {

if ($this.find('.ignoreNowiki').prop('checked')) {

if (!useRegex) {

replace = replace.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');

regexFlags = 'g';

}

input = JWB.replaceParsed(input, replace, regexFlags, rWith);

} else if (useRegex) {

replace = new RegExp(replace, regexFlags);

input = input.replace(replace, rWith);

} else {

input = input.split(replace).join(rWith); //global replacement without having to escape all special chars.

}

} catch(e) {

JWB.stop();

return JWB.status('regex-err', false);

}

});

if ($('#enableRETF').prop('checked')) {

input = RETF.replace(input);

}

return input;

};

//function to *only* replace the parsed wikitext

//It excludes comments (), and nowiki, math, source, syntaxhighlight, pre, code, gallery and timeline tags)

//Based on http://stackoverflow.com/a/23589204/1256925

JWB.replaceParsed = function(str, replace, flags, rwith) {

var exclude = '(|<(nowiki|math|source|syntaxhighlight|pre|gallery|timeline)[^>]*?>[\\s\\S]*?<\\/\\2>)';

//add /i flag, to exclude the correct tags regardless of casing.

//This won't matter for the actual replacing, as the specified flags are used there.

var re = new RegExp(exclude + '|(' + replace + ')', flags.replace(/i|$/, 'i'));

return str.replace(re, function(match, g1, g2, g3) {

if (g3 !== undefined) { //continue to perform replacement if the match is the group that's supposed to be the match

return match.replace(new RegExp(replace, flags), rwith);

} else { //do nothing if the match is one of the excluded groups

return match;

}

});

};

//Adds a line to the logs tab.

JWB.log = function(action, page, info) {

var d = new Date();

var pagee = encodeURIComponent(page);

var extraInfo = , actionStat = ;

switch (action) {

case 'edit':

if (typeof info === 'undefined') {

action = 'null-edit';

actionStat = 'nullEdits';

extraInfo = '';

} else {

extraInfo = ' (diff)';

actionStat = 'pagesSaved';

}

break;

case 'skip':

actionStat = 'pagesSkipped';

break;

case 'move':

extraInfo = ' to '+info+'';

break;

case 'protect':

extraInfo = info;

break;

}

actionStat = '#' + (actionStat || 'otherActions');

$(actionStat).html(+$(actionStat).html() + 1);

$('#actionlog tbody')

.append(''+

''+(JWB.fn.pad0(d.getHours())+':'+JWB.fn.pad0(d.getMinutes())+':'+JWB.fn.pad0(d.getSeconds()))+''+

''+action+''+

''+page+''+ extraInfo +''+

'')

.parents('.JWBtabc').scrollTop($('#actionlog tbody').parents('.JWBtabc')[0].scrollHeight);

};

//Move to the next page in the list

JWB.next = function(nextPage) {

if ($.trim(nextPage) && !$('#skipAfterAction').prop('checked')) {

nextPage = $.trim(nextPage) + '\n';

} else {

nextPage = '';

}

$('#articleList').val($('#articleList').val().replace(/^.*\n?/, nextPage));

JWB.list.splice(0,1);

JWB.pageCount();

JWB.api.get(JWB.list[0].split('|')[0]);

};

//Stop everything, reset inputs and editor

JWB.stop = function() {

$('#stopbutton,'+

'.editbutton,'+

'#watchNow,'+

'.JWBtabc[data-tab="2"] .editbutton,'+

'#watchNow'+

'.JWBtabc[data-tab="4"] button').prop('disabled', true);

$('#startbutton, #articleList,'+

'.JWBtabc[data-tab="1"] button,'+

'#replacesPopup button,'+

'#replacesPopup input,'+

'.JWBtabc input, select').prop('disabled', false);

$('#resultWindow').html('');

$('#editBoxArea').val('');

$('#currentpage').html(JWB.msg('editbox-currentpage', ' ', ' '));

JWB.pl.stop();

JWB.status('done', true);

JWB.isStopped = true;

};

//Start AutoWikiBrowsing

JWB.start = function() {

JWB.pageCount();

if (JWB.list.length === 0 || (JWB.list.length === 1 && !JWB.list[0])) {

alert(JWB.msg('no-pages-listed'));

} else if ($('#skipNoChange').prop('checked') && !$('.replaceText').val() && !$('.replaceWith').val() && !$('#enableRETF').prop('checked')) {

alert(JWB.msg('infinite-skip-notice'));

} else {

JWB.isStopped = false;

if ($('#preparse').prop('checked') && !$('#articleList').val().match('#PRE-PARSE-STOP')) {

$('#articleList').val($.trim($('#articleList').val()) + '\n#PRE-PARSE-STOP'); //mark where to stop pre-parsing

} else {

$('#preparse-reset').click();

}

$('#stopbutton, .editbutton, #watchNow, .JWBtabc[data-tab="2"] button, .JWBtabc[data-tab="4"] button').prop('disabled', false);

$('#startbutton, #articleList, .JWBtabc[data-tab="1"] button, #replacesPopup button, #replacesPopup input, .JWBtabc input, select').prop('disabled', true);

JWB.api.get(JWB.list[0].split('|')[0]);

}

};

JWB.updateButtons = function() {

if (!JWB.page.exists && $('#deletePage').is('.delete')) {

$('#deletePage').removeClass('delete').addClass('undelete').html('Undelete');

JWB.fn.blink('#deletePage'); //Indicate the button has changed

} else if (JWB.page.exists && $('#deletePage').is('.undelete')) {

$('#deletePage').removeClass('undelete').addClass('delete').html('Delete');

JWB.fn.blink('#deletePage'); //Indicate the button has changed

}

if (!JWB.page.exists) {

$('#movePage').prop('disabled', true);

} else {

$('#movePage').prop('disabled', false);

}

$('#watchNow').html( JWB.msg('watch-' + (JWB.page.watched ? 'remove' : 'add')) );

};

/***** General functions *****/

//Clear all existing timers to prevent them from getting errors

JWB.fn.clearAllTimeouts = function() {

var i = setTimeout(function() {

return void(0);

}, 1000);

for (var n=0;n<=i;n++) {

clearTimeout(n);

clearInterval(i);

}

console.log('Cleared all running intervals up to index',i);

};

//Filter an array to only contain unique values.

JWB.fn.uniques = function(arr) {

var a = [];

for (var i=0, l=arr.length; i

if (a.indexOf(arr[i]) === -1 && arr[i] !== '') {

a.push(arr[i]);

}

}

return a;

};

//Prepends zeroes until the number has the desired length of len (default 2)

JWB.fn.pad0 = function(n, len) {

n = n.toString();

len = len||2;

return n.length < len ? Array(len-n.length).join('0')+n : n;

};

JWB.fn.blink = function(el,t) {

t=t?t:500;

$(el).prop('disabled', true)

.children().animate({opacity:'0.1'},t-100)

.animate({opacity:'1'},t)

.animate({opacity:'0.1'},t-100)

.animate({opacity:'1'},t);

setTimeout("$('"+el+"').prop('disabled', false)",t*4-400);

};

JWB.fn.setSelection = function(el, start, end, dir) {

dir = dir||'none'; //Default value

end = end||start; //If no end is specified, assume the caret is placed without creating text selection.

if (el.setSelectionRange) {

el.focus();

el.setSelectionRange(start, end, dir);

} else if (el.createTextRange) {

var rng = el.createTextRange();

rng.collapse(true);

rng.moveStart('character', start);

rng.moveEnd('character', end);

rng.select();

}

};

JWB.fn.scrollSelection = function(el, index) { //function to fix scrolling to selection - doesn't do that automatically.

var newEl = document.createElement('textarea'); //create a new textarea to simulate the same conditions

var elStyle = getComputedStyle(el);

newEl.style.height = elStyle.height; //copy over size-influencing styles

newEl.style.width = elStyle.width;

newEl.style.lineHeight = elStyle.lineHeight;

newEl.style.fontSize = elStyle.fontSize;

newEl.value = el.value.substr(0,index);

document.body.appendChild(newEl); //needs to be added to the HTML for the scrollHeight and clientHeight to work.

if (newEl.scrollHeight != newEl.clientHeight) {

el.scrollTop = newEl.scrollHeight - 2;

} else {

el.scrollTop = 0;

}

newEl.remove(); //clean up the mess I've made

};

//i18n function

JWB.msg = function(message) {

var args = arguments;

var lang = JWB.lang;

if (typeof message === 'object') {

lang = message[1];

message = message[0];

}

if (lang == 'qqx') return message;

if (!JWB.messages || !JWB.messages.en) return message;

var msg;

if (JWB.messages.hasOwnProperty(lang) && JWB.messages[lang].hasOwnProperty(message)) {

msg = JWB.messages[lang][message];

} else {

msg = (JWB.messages.en.hasOwnProperty(message)) ? JWB.messages.en[message] : '';

}

msg = msg.replace(/\$(\d+)/g, function(match, num) {

return args[+num] || match;

});

return msg;

};

/***** Init *****/

JWB.init = function() {

console.log(JWB.messages.en, !!JWB.messages.en);

JWB.setup.load();

JWB.fn.clearAllTimeouts();

if (!JWB.messages[JWB.lang] && JWB.lang != 'qqx') JWB.lang = 'en';

var findreplace = '

'+

''+

''+

'

'+

''+

'?'+

'

JWB.msg('label-regex-flags')+' '+ //default: global replacement

''+

'
'+

'

'+

'

' '+JWB.msg('label-ignore-comment')+

''+

'

';

var NSList = '';

/***** Interface *****/

document.title = 'AWB+search Script'+(document.title.split('-')[1] ? ' -'+document.title.split('-')[1] : '');

$('body').html(

'

'+

'

'+

'

'+

'

'+

'

'+

'

'+

'

'+

'

'+

'

'+

(JWB.sysop?'

':'')+

'

'+

'

done
'+

'

'+

'

'+

'

'+

'

'+

'

'+

JWB.msg('stat-pages')+' 0; '+

JWB.msg('stat-save')+' 0; '+

JWB.msg('stat-null')+' 0; '+

JWB.msg('stat-skip')+' 0; '+

JWB.msg('stat-other')+' 0; '+

'

'+

'

'+

'

'+

'

'

);

$('.JWBtabc[data-tab="1"]').html(

'

'+

''+JWB.msg('label-pagelist')+''+

' '+

''+

'
'+

'

' '+JWB.msg('preparse')+

''+

''+

''+

'
'+

''+

'

'+

'

'+

''+JWB.msg('label-settings')+''+

''+

'
'+

'

JWB.msg('load-settings') + ' '+

''+

''+

''+

''+

'


'+

''+

''+

''+

'


'+

'

''+

JWB.msg('import-setup')+

''+

''+

''+

'

'+

''+

''+

'

'+

'

'+

'

'+

''+JWB.msg('label-analytics')+''+

'

' '+

JWB.msg('allow-analytics')+

''+

''+

''+

JWB.msg('analytics-link')+

''+

'

'

);

$('.JWBtabc[data-tab="2"]').html(

''+

''+

' '+

''+

''+

''+

'
'+

(JWB.bot?

''+

'

JWB.msg('save-interval', '')+

''+

'
'

:'')+

''+

''+

'
'+

' '+

''+

''+

''+

'
'+

''+

''+

''+

findreplace+

'


'+

'

JWB.msg('label-enable-RETF',

''+

JWB.msg('label-RETF')+

'')+

''+

'

'id="refreshRETF" title="'+JWB.msg('tip-refresh-RETF')+'">'

);

$('.JWBtabc[data-tab="3"]').html(

'

'+

''+JWB.msg('label-redirects')+''+

'

' '+JWB.msg('redirects-follow')+' '+

''+

'

' '+JWB.msg('redirects-skip')+' '+

''+

'

' '+JWB.msg('redirects-edit')+''+

''+

'

'+

'

'+

''+JWB.msg('label-skip-when')+''+

''+

'
'+

''+

''+

''+

'
'+

(JWB.sysop?'':'')+

'

'+

''+

''+

'

'+

''+

'?'+

'

JWB.msg('label-regex-flags')+' '+

''+

'

'

);

if (JWB.sysop) $('.JWBtabc[data-tab="4"]').html(

'

'+

''+JWB.msg('move-header')+''+

''+

'
'+

JWB.msg('move-also')+' '+

' '+

''+

'
'+

''+

'

'+

'

'+

''+JWB.msg('protect-header')+''+

JWB.msg('protect-edit')+

' '+

'
'+

JWB.msg('protect-move')+

' '+

'
'+

''+

'

'+

' '+

' '+

' '+

''

);

$('.JWBtabc[data-tab="5"]').html('

');

$('#pagelistPopup form').html(

'

' + JWB.msg('label-ns-select') + NSList + '
'+

'

'+

''+

''+

'

'+JWB.msg('cm-include')+' '+

''+

''+

''+

'

'+

'

'+

'

'+

''+

''+

'

'+JWB.msg('links-include')+' '+

''+

''+

''+

'

'+

'

'+JWB.msg('links-redir')+' '+

''+

''+

''+

'

'+

'

' '+JWB.msg('label-link-redir')+

''+

'

'+

'

'+

''+

''+

'

'+

'

'+

''+

JWB.msg('label-wr')+

'

'+

'

'+

''+

''+

'

'+

'

'+

''+

''+

'

'+

''

);

$('body').addClass('AutoWikiBrowser'); //allow easier custom styling of JWB.

/***** Setup *****/

JWB.setup.save('_blank'); //default setup

if (JWB.settings.hasOwnProperty('default')) {

JWB.setup.apply();

} else if (JWB.setup.hasOwnProperty('edittoken')) {

JWB.setup.save('default');

}

JWB.setup.extend({});

/***** Event handlers *****/

//Alert user when leaving the tab, to prevent accidental closing.

onbeforeunload = function() {

return "Closing this tab will cause you to lose all progress.";

};

ondragover = function(e) {

e.preventDefault();

};

$('.JWBtab').click(function() {

$('.active').removeClass('active');

$(this).addClass('active');

$('.JWBtabc[data-tab="'+$(this).attr('data-tab')+'"]').addClass('active');

});

function showRegexFlags() {

// >>this<< is the element that's triggered

$(this).parent().nextAll('label').toggle(this.checked);

}

$('body').on('change', '#useRegex, #containRegex, .useRegex', showRegexFlags);

$('#preparse-reset').click(function() {

$('#articleList').val($('#articleList').val().replace(/#PRE-PARSE-STOP/g,'').replace(/\n\n/g, '\n'));

});

$('#saveAs').click(function() {

JWB.setup.save();

});

$('#loadSettings').change(function() {

JWB.setup.apply(this.value);

});

$('#download').click(JWB.setup.download);

$('#saveToWiki').click(JWB.setup.submit);

$('#import').change(JWB.setup.import);

ondrop = JWB.setup.import;

$('#updateSetups').click(JWB.setup.load);

$('#deleteSetup').click(JWB.setup.delete);

if (window.RETF) $('#refreshRETF').click(RETF.load);

$('#replacesButton, #pagelistButton').click(function() {

var popup = this.id.slice(0, -6); //omits the 'Button' in the id by cutting off the last 6 characters

$('#'+popup+'Popup, #overlay').show();

});

$('#overlay').click(function() {

$('#replacesPopup, #pagelistPopup, #overlay').hide();

});

$('#moreReplaces').click(function() {

$('#replacesPopup').append(findreplace);

});

$('#replacesPopup').on('keydown', '.replaces:last', function(e) {

if (e.which === 9) $('#moreReplaces')[0].click();

});

$('#pagelistPopup legend input').change(function() {

//remove disabled attr when checked, add when not.

$(this).parents('fieldset').find('input').not('legend input').prop('disabled', !this.checked);

$(this).parents('fieldset').prop('disabled', !this.checked);

}).trigger('change');

$('#resultWindow').on('click', 'tr[data-line]:not(.lineheader) *', function(e) {

var line = +$(e.target).closest('tr[data-line]').data('line');

var index = $('#editBoxArea').val().split('\n').slice(0, line-1).join('\n').length;

$('#editBoxArea')[0].focus();

JWB.fn.setSelection($('#editBoxArea')[0], index+1);

JWB.fn.scrollSelection($('#editBoxArea')[0], index);

});

$('#removeDupes').click(function() {

$('#articleList').val(JWB.fn.uniques($('#articleList').val().split('\n')).join('\n'));

JWB.pageCount();

});

$('#sortArticles').click(function() {

$('#articleList').val($('#articleList').val().split('\n').sort().join('\n'));

JWB.pageCount();

});

$('#watchNow').click(JWB.api.watch);

$('#autosave').change(function() {

$('#throttle').prop('disabled', !this.checked);

});

$('#viaJWB').change(function() {

$('#summary').parent('label')

.toggleClass('viaJWB', this.checked)

.attr('maxlength', 250 - this.checked*JWB.summarySuffix.length); // Change the max size of the allowed summary according to having a suffix or not.

});

$('#startbutton').click(JWB.start);

$('#stopbutton').click(JWB.stop);

$('#submitButton').click(JWB.api.submit);

$('#previewButton').click(JWB.api.preview);

$('#diffButton').click(JWB.api.diff);

$('#skipButton, #skipPage').click(function() {

JWB.log('skip', JWB.list[0].split('|')[0]);

JWB.next();

});

if (JWB.sysop) {

$('#movePage').click(function() {

if ($('#moveTo').val().length === 0) {

return alert(JWB.msg('alert-no-move'));

}

JWB.api.move();

});

$('#protectPage').click(JWB.api.protect);

$('#deletePage').click(JWB.api.delete);

}

};

//Disable JWB altogether when it's loaded on a page other than Project:AutoWikiBrowser/Script. This script shouldn't be loaded on any other page in the first place.

if (JWB.allowed === false) JWB = false;