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.
/* eslint-disable max-lines */
/* eslint-disable max-statements */
/* eslint-disable complexity */
/* eslint-disable no-alert */
/**
* Name: FileUsageAuto-update
* Description: Updates file links in use on the wiki when image is renamed.
* Version: v2.0
* Authors: Foodbandlt
* Jr Mime
* KockaAdmiralac
* Used files: [[File:Circle throbber.gif]]
*/
(function() {
'use strict';
if (window.LIR) {
return;
}
var LIR = {
options: window.LIRoptions || {},
wg: mw.config.get([
'wgAction',
'wgCanonicalNamespace',
'wgCanonicalSpecialPageName',
'wgContentLanguage',
'wgFileExtensions',
'wgFormattedNamespaces',
'wgPageName',
'wgScriptPath',
'wgTitle',
'wgUserLanguage',
'wgUserName'
]),
ERRORS: [],
updateStatus: function(gifDisplay, message) {
var $queueStatusButton = $('#queueStatus');
var $liveLoaderButton = $('#liveLoader');
if ($queueStatusButton.length === 0 && $liveLoaderButton.length === 0) {
return false;
}
var buttonMessage = message;
if (typeof gifDisplay === 'string') {
buttonMessage = gifDisplay;
} else if (typeof gifDisplay === 'boolean') {
$liveLoaderButton.css('display', gifDisplay ? 'inline-block' : 'none');
} else {
return false;
}
if (typeof buttonMessage === 'string' && $queueStatusButton.length > 0) {
$queueStatusButton.html(' ' + buttonMessage);
}
return true;
},
start: function(type, oldName, newName, reason, callback) {
// Checks if function has already started
if ((LIR.started || LIR.started) && typeof LIR.queuePosition === 'undefined') {
return false;
}
// Treat manual additions like multi
var normalizedType = type;
if (normalizedType === 'manual') {
normalizedType = 'multi';
LIR.method = 'manual';
LIR.updateStatus(true, LIR.i18n.msg.processing);
}
// Checks whether renaming single image or adding to queue
if (typeof normalizedType === 'undefined') {
LIR.started = true;
LIR.updateStatus(true, LIR.i18n.msg('processing').escape());
LIR.type = 'single';
} else if (normalizedType === 'single') {
LIR.started = true;
LIR.updateStatus(true, LIR.i18n.msg('processing').escape());
LIR.type = 'single';
} else if (normalizedType === 'multi') {
LIR.started = true;
if (typeof LIR.queuePosition === 'undefined') {
LIR.queuePosition = ++localStorage.LIRQueuedUpdates;
LIR.updateStatus(true);
}
if (LIR.queuePosition !== Number(localStorage.LIRQueuedUpdatesPos)) {
var position = LIR.queuePosition - Number(localStorage.LIRQueuedUpdatesPos);
LIR.updateStatus(LIR.i18n.msg('waitList', position).escape());
setTimeout(function() {
LIR.start(normalizedType, oldName, newName, reason, callback);
}, 500);
return false;
}
LIR.updateStatus(LIR.i18n.msg('processing').escape());
LIR.type = 'multi';
} else {
if (console) {
console.log('Incorrect type specified');
}
return false;
}
// Retrieves queue, or resets variables if doesn't exist
if (typeof localStorage[LIR.wg.wgUserName + '_LIRQueueData'] === 'undefined') {
LIR.queueData = [];
} else {
LIR.queueData = JSON.parse(localStorage[LIR.wg.wgUserName + '_LIRQueueData']);
}
// Sets variables used by the function
var newReason;
var oldImageName;
var newImageName;
if (typeof oldName !== 'undefined' && typeof newName !== 'undefined') {
if (oldName === '' || newName === '') {
LIR.updateStatus(false, LIR.i18n.msg('fileNameBlank').escape());
LIR.started = false;
localStorage.LIRQueuedUpdatesPos++;
delete LIR.queuePosition;
return false;
}
oldImageName = oldName;
newImageName = newName;
if (typeof reason === 'undefined') {
newReason = '';
}
} else {
oldImageName = $('input[name="wpOldTitle"]').val().slice(LIR.wg.wgFormattedNamespaces[6].length + 1);
newImageName = $('input[name="wpNewTitleMain"]').val();
newReason = $('input[name="wpReason"]').val();
}
var leaveRedirect = $('input[name="wpLeaveRedirect"]').is(':checked');
LIR.pageKey = [];
// Checks if old or new file name is currently part of the queue
var alreadyIn = LIR.queueData.find(function(data) {
return data.newImage === oldImageName ||
data.newImage === newImageName ||
data.oldImage === oldImageName ||
data.oldImage === newImageName;
});
if (alreadyIn) {
LIR.started = false;
if (typeof LIR.queuePosition !== 'undefined') {
localStorage.LIRQueuedUpdatesPos++;
delete LIR.queuePosition;
}
var errorMessage;
if (alreadyIn.oldImage === oldImageName || alreadyIn.newImage === oldImageName) {
errorMessage = 'alreadyInQueue';
} else {
errorMessage = 'nameInUse';
}
LIR.updateStatus(false, LIR.i18n.msg(errorMessage).escape());
if (typeof callback === 'function') {
callback(false, errorMessage);
}
return false;
}
var isVideo = true;
for (var ext in LIR.wg.wgFileExtensions) {
if (oldImageName.indexOf('.' + LIR.wg.wgFileExtensions[ext]) !== -1) {
isVideo = false;
break;
}
}
// Checks if destination file name is the same as file being renamed
var oldExt = oldImageName.slice(oldImageName.lastIndexOf('.')).toLowerCase();
var newExt = newImageName.slice(newImageName.lastIndexOf('.')).toLowerCase();
if (
oldExt !== newExt &&
// Same MIME type bugfix
!(
(oldExt === '.jpeg' || oldExt === '.jpg') &&
(newExt === '.jpeg' || newExt === '.jpg')
) &&
LIR.method !== 'manual' &&
!isVideo
) {
LIR.started = false;
if (typeof LIR.queuePosition !== 'undefined') {
localStorage.LIRQueuedUpdatesPos++;
delete LIR.queuePosition;
}
LIR.updateStatus(false, LIR.i18n.msg('invalidExtension').escape());
if (typeof callback === 'function') {
callback(false, 'invalidExtension');
}
return false;
}
// Check if destination file name is in use
LIR.api.get({
action: 'query',
prop: 'revisions',
rvprop: 'content',
titles: 'File:' + newImageName,
v: Date.now()
}).then(function(result) {
if (typeof result.query.pages[-1] !== 'undefined' || LIR.method === 'manual') {
return LIR.backlinksUsagePromise(oldImageName);
}
LIR.started = false;
if (typeof LIR.queuePosition !== 'undefined') {
localStorage.LIRQueuedUpdatesPos++;
delete LIR.queuePosition;
}
LIR.updateStatus(false, LIR.i18n.msg('destInUse').escape());
if (typeof callback === 'function') {
callback(false, 'destInUse');
}
}).then(function(result) {
if (!result) {
// An error occurred during the previous stage.
return;
}
var imageUsage = result.query.imageusage;
var imageLinks = result.query.backlinks;
var totalImageUsage = imageUsage.concat(imageLinks);
console.log('Image usage successfully retrieved');
if (totalImageUsage.length === 0) {
// Else, prompt to use normal renaming, since this is kind of pointless otherwise
LIR.started = false;
if (typeof LIR.queuePosition !== 'undefined') {
localStorage.LIRQueuedUpdatesPos++;
delete LIR.queuePosition;
}
LIR.updateStatus(false, LIR.i18n.msg('fileNotUsed').escape());
if (typeof callback === 'function') {
callback(false, 'fileNotUsed');
}
return;
}
// Resets queue-related variables if only renaming and replacing a single image
if (LIR.type === 'single') {
LIR.queueData = [];
LIR.queueDataList = [];
LIR.pageKey = [];
LIR.queueDataList.push({
oldImage: oldImageName,
newImage: newImageName,
reason: newReason,
move: true,
noRedirect: !leaveRedirect
});
} else {
LIR.queueData.push({
oldImage: oldImageName,
newImage: newImageName,
reason: newReason,
move: LIR.method !== 'manual',
noRedirect: !leaveRedirect
});
}
// Stores queue if renaming multiple images, or updates file usage if only renaming one
if (LIR.type === 'multi') {
LIR.storeQueue();
LIR.started = false;
localStorage.LIRQueuedUpdatesPos++;
LIR.updateStatus(false, LIR.i18n.msg('successful').escape());
var enFileNamespace = 'File:';
var langFileNamespace = LIR.wg.wgFormattedNamespaces[6] + ':';
var pageName = LIR.wg.wgPageName;
if (
LIR.wg.wgCanonicalSpecialPageName === 'Movepage' &&
(
pageName.indexOf(langFileNamespace) !== -1 ||
pageName.indexOf(enFileNamespace) !== -1
)
) {
// We're on Special:MovePage for a file.
window.location = mw.util.getUrl('File:' + oldImageName);
} else if (typeof callback === 'function') {
callback(true);
}
} else {
/**
* This may seem odd, but because LIR.processQueue() is used for both single and multiple image
* updating, it requires LIR.started to be false to start
*/
LIR.started = false;
LIR.processQueue(function() {
window.location.href = mw.util.getUrl('File:' + newImageName);
});
}
});
},
/**
* Standalone function to store the queue in window.localStorage
* uses wgUserName as a variable key so multi-user computers on the same wiki don't get each other's queue
*/
storeQueue: function() {
localStorage[LIR.wg.wgUserName + '_LIRQueueData'] = JSON.stringify(LIR.queueData);
},
backlinksUsagePromise: function(file) {
var options = {
action: 'query',
list: 'backlinks|imageusage',
bltitle: 'File:' + file,
bllimit: 'max',
iutitle: 'File:' + file,
iulimit: 'max',
v: Date.now()
};
if (!localStorage[LIR.wg.wgUserName + '_LIRNamespaceSelection']) {
options.blnamespace = 0;
}
return LIR.api.get(options);
},
started: false,
delay: 1000,
updateProgress: function(show, progress) {
var newProgress = progress;
if (typeof newProgress === 'undefined' && typeof show === 'boolean') {
newProgress = 0;
}
if (typeof show === 'boolean') {
if (LIR.type === 'multi') {
if (show) {
var ui = window.dev.dorui;
$('.modalToolbar').prepend(ui.div({
attrs: {
id: 'LIRQueueProgress'
},
child: ui.div({
attrs: {
id: 'LIRProgressInd'
}
})
}));
} else {
$('#LIRQueueProgress').remove();
}
}
}
if (typeof newProgress === 'number') {
$('#LIRProgressInd').css('width', newProgress * 100 + '%');
return;
}
if (typeof show === 'number') {
$('#LIRProgressInd').css('width', show * 100 + '%');
}
},
compareQueueDataEntries: function(currentData, currentTitle, entry) {
return entry.title === currentTitle &&
entry.oldImage === currentData.oldImage &&
entry.newImage === currentData.newImage;
},
getUsage: function(index) {
var data = LIR.queueDataList[index];
return LIR.backlinksUsagePromise(data.oldImage).then(function(result) {
var imageUsage = result.query.imageusage;
var imageLinks = result.query.backlinks;
var totalImageUsage = imageUsage.concat(imageLinks);
console.log('Image usage successfully retrieved');
// Adds pages image is used on to LIR.pageKey to help keep track of pages in LIR.pageData later on
totalImageUsage.forEach(function(usageData) {
var title = usageData.title;
if (LIR.pageKey.indexOf(title) === -1) {
LIR.pageKey.push(title);
}
if (!LIR.queueData.some(LIR.compareQueueDataEntries.bind(this, data, title))) {
LIR.queueData.push({
oldImage: data.oldImage,
newImage: data.newImage,
title: title,
move: data.move
});
}
});
});
},
processQueue: function(callback) {
if (
Number(localStorage.LIRQueuedUpdates) < Number(localStorage.LIRQueuedUpdatesPos) &&
Number(localStorage.LIRQueuedUpdates) !== 0
) {
localStorage.LIRQueuedUpdates = 0;
localStorage.LIRQueuedUpdatesPos = 1;
}
// Check if operation already started
if (LIR.started) {
return false;
}
// LIR.type is already set if processing single update
if (typeof LIR.type === 'undefined') {
LIR.type = 'multi';
}
// Variable redeclaration
LIR.started = true;
LIR.requestCompleted = [];
LIR.pageData = [];
// Queue retrieval, returns false if no queue
var queueDataLS = localStorage[LIR.wg.wgUserName + '_LIRQueueData'];
if (LIR.type === 'multi' && Number(localStorage.LIRQueuedUpdates) === 0 || LIR.type === 'single') {
if (typeof queueDataLS === 'undefined' && LIR.type !== 'single') {
console.log('Queue does not exist or was unable to be retrieved.');
LIR.started = false;
return false;
}
if (LIR.type === 'multi') {
LIR.queueDataList = JSON.parse(queueDataLS);
LIR.updateProgress(true);
console.log('Queue retrieved successfully.');
}
LIR.usageRequested = 0;
LIR.usageProgress = 0;
LIR.moveRequested = LIR.queueDataList.length;
LIR.moveProgress = 0;
LIR.queueData = [];
LIR.pageKey = [];
LIR.timer = 0;
LIR.queueDataList.forEach(function(queueData, index) {
if (queueData.move) {
LIR.moveFile(
index,
function() {
LIR.updateProgress(++LIR.moveProgress / LIR.moveRequested / 2);
LIR.usageRequested++;
LIR.getUsage(index).then(function() {
LIR.usageProgress++;
if (
LIR.moveProgress === LIR.moveRequested &&
LIR.usageProgress === LIR.usageRequested
) {
LIR.processPageContent(callback);
}
});
},
function() {
LIR.updateProgress(++LIR.moveProgress / LIR.moveRequested / 2);
if (
LIR.moveProgress === LIR.moveRequested &&
LIR.usageProgress === LIR.usageRequested
) {
LIR.processPageContent(callback);
}
}
);
} else {
LIR.updateProgress(++LIR.moveProgress / LIR.moveRequested / 2);
LIR.usageRequested++;
LIR.getUsage(index).then(function() {
LIR.usageProgress++;
if (
LIR.moveProgress === LIR.moveRequested &&
LIR.usageProgress === LIR.usageRequested
) {
LIR.processPageContent(callback);
}
});
}
});
} else if (LIR.type === 'multi') {
console.log('Pages are still being added to the queue.');
alert(LIR.i18n.msg('pagesWaiting').plain());
LIR.started = false;
return false;
}
},
lowerUpperReg: function(input) {
return '[' + input.substr(0, 1).toUpperCase() + input.substr(0, 1).toLowerCase() + ']' + input.substr(1);
},
processPageContent: function(callback) {
console.log('Begin queue execution');
// Sets progress checking variables
for (var i = 0; i < LIR.pageKey.length; i++) {
LIR.requestCompleted[i] = false;
}
var promises = [];
console.log('Getting page contents');
for (var j = 0; j < Math.floor(LIR.pageKey.length / 500) + 1; j++) {
var tempArray = [];
for (var k = j * 500; k < j * 500 + 500 && k < LIR.pageKey.length; k++) {
tempArray.push(LIR.pageKey[k]);
}
// Calls API for page contents
promises.push(LIR.api.post({
action: 'query',
prop: 'revisions',
rvprop: 'content',
titles: tempArray.join('|'),
format: 'json'
}).then(LIR.processPageCallback));
}
$.when.apply(this, promises).then(function() {
// TODO: Now we're no longer sure we collected all pages
console.log('Page contents retrieved and saved');
LIR.log(LIR.i18n.msg('contentsRetrieved').escape());
console.log('Begin processing page content.');
// Replacing image name on each page
var escapeRegExp = mw.util.escapeRegExp;
LIR.queueData.forEach(function(data) {
var pageKey = LIR.pageKey.indexOf(data.title);
var pageData = LIR.pageData[pageKey];
var escapedName = escapeRegExp(data.oldImage).replace(/( |_)/g, '[ _]');
if (escapedName.substr(0, 1).match(/[A-Za-z]/i)) {
escapedName = LIR.lowerUpperReg(escapedName);
}
var pageReplacement = new RegExp(
'(\\n[ ]*?|\\[?:?([Ff]ile|[Ii]mage|' +
LIR.lowerUpperReg(LIR.wg.wgFormattedNamespaces[6]) +
'|' +
LIR.lowerUpperReg(LIR.i18n.msg('imageNamespace').plain()) +
'):[ ]*?|=[ ]*?|\\|)' +
escapedName +
'([ ]*?\\n|[ ]*?\\||[ ]*?\\]|[ ]*?\\}|[ ]*?;)',
'g'
);
if (pageData.content.search(pageReplacement) !== -1) {
var replacementReg = new RegExp(escapedName, 'g');
var regExec;
pageData.changed = true;
console.log(data.oldImage, 'replaced on page', data.title);
while ((regExec = pageReplacement.exec(pageData.content)) !== null) {
if (!data.newImage && !data.move) {
// Removing links/usages
var replaceWith;
if (regExec[1].search(/\n/g) !== -1 || regExec[3].search(/\n/g) !== -1 || regExec[1].search(/[=]/g) !== -1) {
// If surrounded by newlines or equals, keep them to prevent things from breaking
replaceWith = regExec[0].replace(
replacementReg,
'<nowiki>' + data.oldImage + '</nowiki>'
);
} else {
replaceWith = '<nowiki>' + regExec[0] + '</nowiki>';
}
pageData.content = pageData.content.replace(regExec[0], replaceWith);
pageReplacement.lastIndex += '<nowiki></nowiki>'.length;
} else {
// Everything else
var replaced = regExec[0].replace(replacementReg, data.newImage);
pageData.content = pageData.content.replace(regExec[0], replaced);
pageReplacement.lastIndex += replaced.length - regExec[0].length - regExec[3].length;
}
}
} else if (LIR.type === 'multi') {
LIR.failedLog(data.oldImage, data.newImage, data.title);
} else {
alert(LIR.i18n.msg('unableToFind', data.oldImage, data.title).plain());
}
});
LIR.log(LIR.i18n.msg('submittingContent').escape());
console.log('Begin submitting pages');
var l = 0;
if (LIR.type === 'multi') {
LIR.queueProgress = 0;
}
var throttle = setInterval(function() {
if (LIR.pageData[l].changed) {
LIR.submitChangedPages(l, callback);
} else {
LIR.requestCompleted[l] = true;
}
l++;
if (l === LIR.pageData.length) {
clearInterval(throttle);
}
}, LIR.options.delay || LIR.delay);
});
},
processPageCallback: function(result) {
// Saves page contents for each page in LIR.pageData
for (var i in result.query.pages) {
var keyNum = LIR.pageKey.indexOf(result.query.pages[i].title);
LIR.pageData[keyNum] = {
title: LIR.pageKey[keyNum],
content: result.query.pages[i].revisions[0]['*'],
changed: false
};
}
},
submitChangedPages: function(pageKey, callback) {
LIR.api.post({
action: 'edit',
title: LIR.pageData[pageKey].title,
summary: LIR.options.editSummary || LIR.i18n.inContentLang().msg('editSummary').plain(),
text: LIR.pageData[pageKey].content,
minor: true,
nocreate: true,
redirect: false,
bot: true,
watchlist: 'nochange',
token: mw.user.tokens.get('csrfToken')
}).then(function() {
LIR.requestCompleted[pageKey] = true;
console.log('Posted page', LIR.pageKey[pageKey]);
if (LIR.type === 'multi') {
LIR.updateProgress(++LIR.queueProgress / LIR.pageKey.length / 2 + 0.5);
}
if (LIR.requestCompleted.indexOf(false) === -1) {
if (LIR.type === 'multi') {
// Cleans up localStorage variables
delete localStorage[LIR.wg.wgUserName + '_LIRQueueData'];
LIR.started = false;
LIR.updateProgress(false);
}
// Call callback if exists
if (typeof callback === 'function') {
callback();
}
}
}).fail(function(code) {
var message = LIR.i18n.msg('unableToSubmit', LIR.pageData[pageKey].title, code);
if (LIR.type === 'multi') {
LIR.failedLogCustom(message.escape());
LIR.queueData.forEach(function(data) {
if (data.title === LIR.pageData[pageKey].title) {
LIR.failedLog(data.oldImage, data.newImage, data.title);
}
});
} else {
alert(message.plain());
}
});
},
moveFile: function(index, callback, failure) {
var data = LIR.queueDataList[index];
var fileNS = LIR.wg.wgFormattedNamespaces[6];
var options = {
action: 'move',
from: fileNS + ':' + data.oldImage,
to: fileNS + ':' + data.newImage,
reason: data.reason,
movetalk: true,
ignorewarnings: true,
token: mw.user.tokens.get('csrfToken')
};
if (data.noRedirect) {
options.noredirect = true;
}
setTimeout(function() {
LIR.api.post(options).then(function(result) {
if (typeof result.error === 'undefined' || !data.move) {
console.log('Moved file', data.oldImage);
if (typeof callback === 'function') {
callback();
}
}
}).fail(function(code) {
var errorMsg = LIR.i18n.msg('unableToMove', data.oldImage, data.newImage, code);
if (!data.move) {
console.log('Error while moving file, but we weren\'t supposed to move it anyways?');
if (typeof callback === 'function') {
callback();
}
} else if (code === 'articleexists' || code === 'invalidtitle') {
var promptResponse = prompt(
errorMsg.plain() + '\n' + LIR.i18n.msg('unableToMoveChoose').plain()
);
if (promptResponse) {
data.newImage = promptResponse;
LIR.moveFile(index, callback, failure);
} else if (LIR.type === 'multi') {
LIR.failedLogCustom(LIR.i18n.msg('unableToMoveFail', data.oldImage).escape());
if (LIR.queueDataList.length === 1) {
delete localStorage[LIR.wg.wgUserName + '_LIRQueueData'];
LIR.started = false;
LIR.log(LIR.i18n.msg('queueComplete').escape());
LIR.updateQueueListing();
} else {
delete LIR.queueDataList[index];
failure();
}
} else {
LIR.started = false;
LIR.updateStatus(false, errorMsg.escape());
}
} else {
LIR.failedLogCustom(
errorMsg.escape() + ' ' +
LIR.i18n.msg('unableToMoveFail', data.oldImage).escape()
);
LIR.ERRORS.push(code);
if (LIR.queueDataList.length === 1) {
delete localStorage[LIR.wg.wgUserName + '_LIRQueueData'];
LIR.started = false;
LIR.log(LIR.i18n.msg('queueComplete').escape());
LIR.updateQueueListing();
} else {
delete LIR.queueDataList[index];
failure();
}
}
});
}, LIR.timer++ * (LIR.options.delay || LIR.delay));
},
removeFromQueue: function(queueOldName) {
LIR.queueData = JSON.parse(localStorage[LIR.wg.wgUserName + '_LIRQueueData']);
var escapeRegExp = mw.util.escapeRegExp;
var index = LIR.queueData.findIndex(function(data) {
return queueOldName.match(new RegExp(escapeRegExp(data.oldImage), 'gi'));
});
if (index !== -1) {
LIR.queueData.splice(index, 1);
}
if (LIR.queueData.length > 0) {
LIR.storeQueue();
} else {
delete localStorage[LIR.wg.wgUserName + '_LIRQueueData'];
}
},
log: function(text) {
var options = {
classes: ['LIRLogEntry']
};
if (typeof text === 'object') {
options.child = text;
} else {
options.html = text;
}
$('#LIRLog')
.append(window.dev.dorui.div(options))
.scrollTop(100000000);
},
failedLog: function(oldImage, newImage, page) {
var ui = window.dev.dorui;
LIR.failedLogCustom(ui.frag([
ui.a({
attrs: {
href: mw.util.getUrl('File:' + oldImage),
target: '_blank'
},
text: oldImage
}),
' → ',
ui.a({
attrs: {
href: mw.util.getUrl(newImage),
target: '_blank'
},
text: newImage
}),
' on ',
ui.a({
attrs: {
href: mw.util.getUrl(page),
target: '_blank'
},
text: page
})
]));
},
failedLogCustom: function(text) {
var options = {};
if (typeof text === 'object') {
options.child = text;
} else {
options.html = text;
}
$('#LIRFailedLog').append(window.dev.dorui.div(options));
},
updateQueueListing: function() {
var queueDataLS = localStorage[LIR.wg.wgUserName + '_LIRQueueData'];
var ui = window.dev.dorui;
if (!queueDataLS) {
$('#LIRQueue').html(ui.div({
text: LIR.i18n.msg('nothingInQueue').plain()
}));
$('#LIRQueueLengthBox').text('0');
LIR.log(LIR.i18n.msg('queueUpdate').escape());
return false;
}
LIR.queueData = JSON.parse(queueDataLS);
$('#LIRQueue').html(LIR.queueData.map(function(data) {
var removing = !data.move && !data.newImage;
return ui.div({
classes: {
FUAuQueueEntry: true,
FUAuQueueEntryStyle1: !data.move && data.newImage,
FUAuQueueEntryRemoving: removing
},
children: [
ui.div({
attrs: {
title: LIR.i18n.msg('removeFromQueue').plain()
},
classes: ['LIRDeleteButton'],
children: [
ui.img({
attrs: {
height: 15,
width: 15,
src: 'https://upload.wikimedia.org/wikipedia/commons/b/ba/Red_x.svg'
}
})
],
events: {
click: function() {
LIR.removeFromQueue(data.oldImage);
LIR.log(LIR.i18n.msg('itemRemoved').escape());
LIR.updateQueueListing();
}
}
}),
ui.a({
attrs: {
href: mw.util.getUrl('File:' + data.oldImage),
target: '_blank'
},
classes: ['LIROldName'],
text: data.oldImage
}),
' → ',
removing ?
LIR.i18n.msg('removing').plain() :
ui.a({
attrs: {
href: mw.util.getUrl('File:' + data.newImage),
target: '_blank'
},
classes: ['LIRNewName'],
text: data.newImage
})
]
});
}));
$('#LIRQueueLengthBox').text(LIR.queueData.length);
LIR.log(LIR.i18n.msg('queueUpdate').escape());
},
updateNamespaceSelection: function() {
var $element = $('#LIRNamespaceToggleCheck input');
if ($element.length === 0) {
// OOUI is dumb
$element = $('#LIRNamespaceToggleCheck');
}
if ($element.is(':checked')) {
localStorage[LIR.wg.wgUserName + '_LIRNamespaceSelection'] = 'checked';
} else {
localStorage[LIR.wg.wgUserName + '_LIRNamespaceSelection'] = '';
}
},
showQueueModal: function() {
var ui = window.dev.dorui;
window.dev.showCustomModal(LIR.i18n.msg('queueModalTitle').escape(), {
content: ui.div({
attrs: {
id: 'LIRContainer'
},
children: [
ui.div({
attrs: {
id: 'LIRQueue'
}
}),
ui.div({
attrs: {
id: 'LIRLog'
}
}),
ui.div({
attrs: {
id: 'LIRQueueLength'
},
children: [
LIR.i18n.msg('filesInQueue').plain(),
ui.span({
attrs: {
id: 'LIRQueueLengthBox'
}
})
]
}),
ui.div({
attrs: {
id: 'LIRNamespaceToggle'
},
children: [
ui.input({
attrs: {
id: 'LIRNamespaceToggleCheck',
type: 'checkbox'
},
events: {
change: LIR.updateNamespaceSelection
}
// TODO: Initial checked based on localStorage
}),
ui.label({
attrs: {
'for': 'LIRNamespaceToggleCheck'
},
text: LIR.i18n.msg('namespaceCheckbox').plain()
}),
LIR.createLiveLoader(ui),
ui.div({
attrs: {
id: 'LIRFailedLog'
},
text: LIR.i18n.msg('failedDescription').plain()
})
]
})
]
}),
id: 'queueModal',
width: 800,
buttons: [
{
id: 'openManualModal',
message: LIR.i18n.msg('queueModalManual').escape(),
handler: function() {
if (LIR.started) {
return false;
}
LIR.showManualModal();
}
},
{
id: 'openBatchModal',
message: LIR.i18n.msg('queueModalBatch').escape(),
handler: function() {
if (LIR.started) {
return false;
}
LIR.showBatchModal();
}
},
{
id: 'resetCounter',
message: LIR.i18n.msg('queueModalReset').escape(),
handler: function() {
if (LIR.started) {
return false;
}
var diff = Number(localStorage.LIRQueuedUpdates) -
Number(localStorage.LIRQueuedUpdatesPos) +
1;
if (confirm(LIR.i18n.msg('queueModalWaitConfirm', diff).plain())) {
localStorage.LIRQueuedUpdates = 0;
localStorage.LIRQueuedUpdatesPos = 1;
LIR.log(LIR.i18n.msg('waitCleared').escape());
}
}
},
{
id: 'updateButton',
message: LIR.i18n.msg('queueModalUpdate').escape(),
handler: function() {
LIR.updateQueueListing();
}
},
{
id: 'executeButton',
message: LIR.i18n.msg('queueModalExecute').escape(),
defaultButton: true,
handler: function() {
if (typeof localStorage[LIR.wg.wgUserName + '_LIRQueueData'] === 'undefined') {
LIR.log(LIR.i18n.msg('noQueueExists').escape());
} else {
LIR.log(LIR.i18n.msg('queueStarted').escape());
LIR.updateStatus(true);
LIR.processQueue(function() {
LIR.log(LIR.i18n.msg('queueComplete').escape());
LIR.updateStatus(false);
LIR.updateQueueListing();
});
}
}
}
],
callback: function() {
$('.blackout, #queueModal .close').off('click').click(function() {
if (LIR.started === false || typeof LIR.started === 'undefined') {
delete LIR.queueData;
$('#queueModal').remove();
$('.blackout').fadeOut(function() {
$(this).remove();
});
}
});
LIR.updateQueueListing();
}
});
},
createLiveLoader: function(ui) {
return ui.span({
attrs: {
id: 'liveLoader'
},
child: ui.img({
attrs: {
src: 'https://static.wikia.nocookie.net/dev/images/c/c5/Circle_throbber.gif'
}
}),
style: {
display: 'none'
}
});
},
createQueueStatus: function(ui) {
return ui.span({
attrs: {
id: 'queueStatus'
}
});
},
showManualModal: function() {
var ui = window.dev.dorui;
var filePrefix = LIR.wg.wgFormattedNamespaces[6] + ':';
window.dev.showCustomModal(LIR.i18n.msg('queueAddition').escape(), {
content: ui.fieldset({
children: [
ui.p({
child: ui.span({
html: LIR.i18n.msg('manualModalDescription').parse()
})
}),
ui.p({
children: [
ui.strong({
text: LIR.i18n.msg('oldFileName').plain()
}),
ui.br(),
filePrefix,
ui.input({
attrs: {
id: 'modalOldName',
type: 'text'
}
}),
ui.br(),
ui.strong({
// TODO: Separate i18n message?
html: LIR.i18n.msg('newFileName', '').parse()
}),
ui.br(),
filePrefix,
ui.input({
attrs: {
id: 'modalNewName',
type: 'text'
}
})
]
}),
ui.p({
children: [
LIR.createLiveLoader(ui),
LIR.createQueueStatus(ui)
]
})
]
}),
id: 'manualModal',
width: 650,
buttons: [
{
id: 'submit',
defaultButton: true,
message: LIR.i18n.msg('addToQueue').escape(),
handler: function() {
if (LIR.started) {
return false;
}
var $oldName = $('#modalOldName');
var $newName = $('#modalNewName');
LIR.start('manual', $oldName.val(), $newName.val(), '', function(res) {
if (res) {
delete LIR.queuePosition;
$oldName.val('').focus();
$newName.val('');
LIR.updateQueueListing();
}
});
}
}
],
callback: function() {
$('.blackout, #manualModal .close').off('click').click(function() {
if (LIR.started) {
return false;
}
$('#manualModal').remove();
$('.blackout').fadeOut(function() {
$(this).remove();
});
});
$('#modalOldName, #modalNewName').on('keypress', function(e) {
if (e.which === 13) {
$('#manualModal #submit').click();
}
});
}
});
},
multipleManualAdd: function(files) {
var pair = files.shift();
if (!pair) {
return;
}
LIR.start('manual', pair[0], pair[1], '', function(res) {
if (res) {
delete LIR.queuePosition;
LIR.updateQueueListing();
}
$('#batchModalInput').val(files.map(function(filePair) {
return filePair[0] + ' ' + filePair[1];
}).join('\n'));
LIR.multipleManualAdd(files);
});
},
showBatchModal: function() {
var ui = window.dev.dorui;
window.dev.showCustomModal(LIR.i18n.msg('queueAddition').escape(), {
content: ui.fieldset({
children: [
ui.p({
text: LIR.i18n.msg('batchModalDescription').plain()
}),
ui.textarea({
attrs: {
id: 'batchModalInput',
rows: 20
}
})
]
}),
id: 'batchModal',
width: 650,
buttons: [
{
id: 'submit',
defaultButton: true,
message: LIR.i18n.msg('addToQueue').escape(),
handler: function() {
if (LIR.started) {
return false;
}
LIR.multipleManualAdd(
$('#batchModalInput')
.val()
.split('\n')
.map(function(line) {
return line.trim().split(' ');
})
);
}
}
]
});
},
initialize: function(i18n) {
LIR.api = new mw.Api();
LIR.i18n = i18n;
var ui = window.dev.dorui;
if (typeof localStorage.LIRQueuedUpdates === 'undefined') {
localStorage.LIRQueuedUpdates = 0;
localStorage.LIRQueuedUpdatesPos = 1;
}
if (typeof localStorage[LIR.wg.wgUserName + '_LIRNamespaceSelection'] === 'undefined') {
localStorage[LIR.wg.wgUserName + '_LIRNamespaceSelection'] = '';
}
var enFileNamespace = 'File:';
var langFileNamespace = LIR.wg.wgFormattedNamespaces[6] + ':';
var pageName = LIR.wg.wgPageName;
if (
LIR.wg.wgCanonicalSpecialPageName === 'Movepage' &&
(
pageName.indexOf(langFileNamespace) !== -1 ||
pageName.indexOf(enFileNamespace) !== -1
)
) {
var $anchor = $('.oo-ui-buttonInputWidget').parent();
// Buttons
$anchor.append(
ui.a({
attrs: {
id: 'FUAuStartSingle'
},
classes: ['wds-button'],
events: {
click: LIR.start.bind(this, 'single')
},
text: LIR.options.singleButtonText || LIR.i18n.msg('singleButtonText').plain()
}),
ui.a({
attrs: {
'class': 'wds-button',
'id': 'FUAuStartMulti'
},
events: {
click: LIR.start.bind(this, 'multi')
},
text: LIR.options.queueButtonText || LIR.i18n.msg('queueButtonText').plain()
}),
LIR.createLiveLoader(ui),
LIR.createQueueStatus(ui),
ui.br(),
ui.span({
attrs: {
id: 'FUAuMovePageDescription'
},
html: LIR.i18n.msg(
'movePageDescription',
LIR.options.singleButtonText || LIR.i18n.msg('singleButtonText').plain(),
LIR.options.queueButtonText || LIR.i18n.msg('queueButtonText').plain()
).parse()
}),
ui.br(),
LIR.options.bottomMessage ?
ui.div({
attrs: {
id: 'FUAuBottomMessage'
},
html: LIR.options.bottomMessage
}) :
null,
ui.br(),
ui.span({
attrs: {
id: 'FUAuFooter'
},
html: LIR.i18n.msg('movePageInfo').parse()
})
);
var checkbox = new OO.ui.CheckboxInputWidget({
id: 'LIRNamespaceToggleCheck'
});
$('#mw-movepage-table .oo-ui-fieldLayout-align-inline').last().after(
new OO.ui.FieldLayout(checkbox, {
align: 'inline',
label: LIR.i18n.msg('namespaceCheckbox').plain(),
selected: Boolean(localStorage[LIR.wg.wgUserName + '_LIRNamespaceSelection'])
}).$element,
ui.div({
classes: ['FUAuNote'],
text: LIR.i18n.msg(
'movePageNamespaceSelect',
LIR.options.singleButtonText || LIR.i18n.msg('singleButtonText').plain()
).plain()
})
);
checkbox.$element
.find('input')
.on('change', LIR.updateNamespaceSelection);
} else if (LIR.wg.wgCanonicalNamespace === 'File') {
// File page
$('.page-header__contribution-buttons .wds-list, .page-header__actions .wds-list').append(
$('<li>').append(
$('<a>', {
click: LIR.showQueueModal,
text: LIR.i18n.msg('queue').plain()
})
)
);
if (typeof localStorage[LIR.wg.wgUserName + '_LIRQueueData'] !== 'undefined') {
LIR.queueData = JSON.parse(localStorage[LIR.wg.wgUserName + '_LIRQueueData']);
var escapeRegExp = mw.util.escapeRegExp;
var matchedData = LIR.queueData.find(function(data) {
return LIR.wg.wgTitle.match(new RegExp(escapeRegExp(data.oldImage), 'gi'));
});
$('#content').prepend(ui.table({
attrs: {
id: 'LIRNotification'
},
classes: ['metadata', 'plainlinks', 'ambox', 'ambox-notice'],
child: ui.tbody({
children: [
ui.tr({
children: [
ui.td({
classes: ['mbox-image'],
child: ui.div({
child: ui.img({
attrs: {
height: 40,
// eslint-disable-next-line max-len
src: 'https://upload.wikimedia.org/wikipedia/commons/b/bd/Checkmark_green.svg',
width: 46
}
})
})
}),
ui.td({
classes: ['mbox-text'],
children: [
LIR.i18n.msg('alreadyInQueue').plain(),
ui.br(),
ui.span({
html: LIR.i18n.msg('newFileName', matchedData.newImage).parse()
})
]
})
]
}),
ui.tr({
child: ui.td({
attrs: {
colspan: 2,
id: 'LIRNotificationBottom'
},
children: [
ui.a({
attrs: {
href: '#'
},
events: {
click: LIR.showQueueModal
},
text: LIR.i18n.msg('queue').plain()
}),
' • ',
ui.a({
attrs: {
href: '#'
},
events: {
click: function() {
LIR.removeFromQueue(matchedData.oldImage);
$('#LIRNotification').slideUp('fast', function() {
this.remove();
});
}
},
text: LIR.i18n.msg('removeFromQueue').plain()
})
]
})
})
]
})
}));
}
}
},
preload: function() {
$.when(
window.dev.i18n.loadMessages('FileUsageAuto-update', {
cacheVersion: 2
}),
mw.loader.using([
'mediawiki.api',
'mediawiki.user',
'mediawiki.util'
])
).then(LIR.initialize);
}
};
importArticles({
type: 'script',
articles: [
'u:dev:MediaWiki:I18n-js/code.js',
'u:dev:MediaWiki:Dorui.js',
'u:dev:MediaWiki:ShowCustomModal.js'
]
}).then(LIR.preload);
importArticle({
type: 'style',
article: 'u:dev:MediaWiki:FileUsageAuto-update.css'
});
window.LIR = LIR;
})();