User:Perhelion/justReplace.js
Jump to navigation
Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
Documentation for this user script can be added at User:Perhelion/justReplace. |
/**
* @description: Support for just replace a file global (without move).
* @usage / configuration:
// Sets a prefilled custom reason (e.g. duplicate)
window.GlobalReplaceDefaultReason = "duplicate";
// Sets the checkboxes for namespace exclusion default off
window.aqdUserNsOptOut = 1;
window.aqdProjectNsOptOut = 1;
window.aqdTalkNsOptOut = 1;
* @revision: 17:32, 16 October 2019 (UTC)
* @author: User:Perhelion - 2017 (Commons lib, jsHint ready, regex support)
* @author: Adapted from [[MediaWiki:Gadget-libGlobalReplace.js]] and [[User:Sreejithk2000/JustReplace.js]]
* @required modules: mediawiki.util, mediawiki.user, jquery.ui, ext.gadget.libCommons, ext.gadget.libJQuery,
ext.gadget.libUtil, mediawiki.util, ext.gadget.libGlobalReplace, ext.gadget.AjaxQuickDelete,
'mediawiki.api', 'mediawiki.jqueryMsg'
<nowiki>
**/
(function () {
'use strict';
// Guard against multiple inclusions
if (mw.libs.JustReplace) return;
var AQD = window.AjaxQuickDelete,
pageName,
file;
mw.libs.JustReplace = function (page) {
file = page;
// Parameter for external usage and also from non file namespace
if (typeof file === 'string') {
pageName = file;
} else {
// if (typeof file === 'boolean')
AQD.initialize();
file = false;
}
AQD.pageName = pageName;
AQD.possibleReason = (window.GlobalReplaceDefaultReason || AQD.possibleReason || '').replace(/"/, '"');
if (!file) {
AQD.addTask('loadWMmessages');
if (!mw.config.get('wgIsRedirect') && document.getElementById('file'))
AQD.addTask('getMoveToken'); // only works if source file exists
AQD.addTask('promptForReplaceTarget');
AQD.addTask('getFileExtension');
AQD.fileNameExistsCB = 'fileExists';
AQD.addTask('doesFileExist'); // AQD.destination get's now file-namspace
AQD.addTask('declineReplace');
}
AQD.addTask('replaceUsage');
if (!file) {
AQD.addTask('queryRedirects');
AQD.addTask('replaceRedirects');
AQD.addTask('reloadPage');
}
AQD.nextTask();
AQD.replaceUsage = function (reasonShort) {
var notOnNs = [];
AQD.showProgress(AQD.i18n.replacingUsage);
reasonShort = (typeof reasonShort === 'string') ? reasonShort : ''; // TODO '[[COM:Duplicate|Duplicate]]:';
if (AQD.notUserNS) notOnNs.push(2);
if (AQD.notProjectNS) notOnNs.push(4);
if (AQD.notTalkNS) notOnNs = notOnNs.concat([1, 3, 5, 7, 9, 11, 13, 15]);
if (!notOnNs.length) notOnNs = '';
mw.loader.using(['ext.gadget.libGlobalReplace']).always(function () {
if (AQD.replaceUsingCORS) {
mw.libs.globalReplace(pageName, AQD.destination, reasonShort,
AQD.reason, AQD.replaceUsingCORS, notOnNs
).progress(function (r) {
console.log(r);
AQD.showProgress(r);
}).done(function (/* r*/) {
// console.log(r);
if (!AQD.tasks.length) {
// mw.log("Redirect replaced");
AQD.addTask('reloadPage');
}
AQD.nextTask();
}).fail(function (r) {
if (console.warn) console.warn('GlobalReplace fail, try again.', r);
AQD.disableReport = true;
mw.notify(r, {
title: 'replaceUsingCORS', type: 'warn'
});
AQD.fail(r);
// AQD.showProgress();
AQD.nextTask();
// throw new Error(r);
});
} else {
mw.libs.globalReplaceDelinker(pageName, AQD.destination, reasonShort ' ' AQD.reason, function () {
AQD.nextTask();
}, function (r) {
mw.notify(r, {
title: 'Global CommonsDelinker', type: 'warn'
});
console.log(r);
});
}
});
};
/** TODO: replace with updateRedirects from AQD, getFileExtension is added **/
AQD.replaceRedirectsCB = function (result) {
this.redirectsToUpdate = 0;
if ((result = result.query) && (result = result.pages)) {
this.tasks.pop(); // remove last task, 'reloadPage'
AQD.showProgress('Replacing redirects');
for (var r in result) {
var pg = result[r],
rv = pg.revisions[0];
if (!rv || !rv['*']) continue;
// Replace only redirects with different mimetype
if (!AQD.checkFileExt(pg.title, AQD.destination, true)) {
mw.log('Redirect replace skipped, same mimetype', pg.title);
continue;
}
AQD.addTask('updateRedirectsCB'); // go in race condition but buffer for next
AQD.redirectsToUpdate ;
console.log('Update redirects', pg, AQD.redirectsToUpdate, AQD.tasks);
mw.libs.JustReplace(pg.title);
}
// AQD.addTask('reloadPage'); // add last task again!? but it comes to late
}
if (!AQD.redirectsToUpdate) {
AQD.destination = undefined; // Reset?
if (AQD.tasks.length)
AQD.nextTask();
}
};
/**
** Replace also the redirects to the current page
** when moving or processing dupes immediately
**/
AQD.replaceRedirects = function () {
AQD.queryRedirectsCB = 'replaceRedirectsCB';
AQD.queryRedirects(); // now in replace mode
};
};
mw.libs.JustReplace.init = function (/* e*/) {
AQD.loadWMmessages = function () {
$.when(mw.loader.using(['mediawiki.api', 'mediawiki.jqueryMsg']), $.ready)
.always(function () {
return new mw.Api().loadMessagesIfMissing([
'Translate-import-err-invalid-title',
'Wikilove-err-gallery-again',
// 'Whatlinkshere',
'Createacct-reason'
]);
}).always(function () {
AQD.nextTask();
});
};
AQD.promptForReplaceTarget = function () {
this.showProgress();
this.prompt([{
message: this.i18n.moveDestination,
prefill: this.possibleDestination || this.destination || pageName,
returnvalue: 'destination',
cleanUp: false,
noEmpty: true
}, {
message: mw.msg('Createacct-reason'), // i18n
prefill: ((this.reason || this.possibleReason || '').replace(/'{2,}/g, '').replace(/\s{2,}/g, ' ')).trim(),
returnvalue: 'reason',
cleanUp: true,
noEmpty: false
}, {
message: 'Ignore file check (be sure):',
prefill: false,
returnvalue: 'noFileCheck',
type: 'checkbox'
}, {
message: 'Ignore User namespace:',
prefill: !window.aqdUserNsOptOut,
returnvalue: 'notUserNS',
type: 'checkbox'
}, {
message: 'Ignore Project namespace:',
prefill: !window.aqdProjectNsOptOut,
returnvalue: 'notProjectNS',
type: 'checkbox'
}, {
message: 'Ignore Talk namespace:',
prefill: !window.aqdTalkNsOptOut,
returnvalue: 'notTalkNS',
type: 'checkbox'
}, {
message: this.i18n.useCORSForReplace,
prefill: !window.aqdCORSOptOut,
returnvalue: 'replaceUsingCORS',
type: 'checkbox'
}
], 'JustReplace');
setTimeout(function () {
mw.hook('script-loaded.justreplace-prompt').fire();
}, 200);
};
AQD.getFileExtension = function (fn) {
// Hack: Overwrite mimetype from MoveToken
// Needed for .doesFileExist (.cleanFileName) check
if (this.noFileCheck) {
this.tasks.shift(); // remove nextTask
return this.fileExists();
}
var ext = (fn || this.destination || '').replace(/.*?\.(\w{2,5})$/, '$1').toLowerCase();
if (ext) {
if (fn)
return ext;
if (this.destination)
this.mimeFileExtension = ext;
else
this.fail('No destination found!');
} else {
this.fail('Can’t get file extension!');
}
this.nextTask();
};
AQD.fileExists = function () {
/* Only works if destination file has lowercase filename extension,
but there is already a fileExists check in JustReplace */
this.tasks.shift(); // remove declineReplace
// if (!file) this.addTask('reloadPage');
this.replaceUsage();
};
AQD.declineReplace = function () {
this.possibleDestination = this.destination; // save for retry
// i18ns
this.i18n.moveDestination = mw.msg('Wikilove-err-gallery-again'); // Please again
this.showProgress(mw.msg('Translate-import-err-invalid-title', this.destination)); // "Checking file: name is not valid!"
mw.libs.JustReplace(file); // try again
};
mw.libs.JustReplace(file);
};
$(function () {
if ([6, 14].indexOf(mw.config.get('wgNamespaceNumber')) !== -1) {
mw.loader.using(['mediawiki.util', 'ext.gadget.AjaxQuickDelete'], function () {
var a = document.getElementById('ca-justreplace'),
wgUserGroups = mw.config.get('wgUserGroups'),
userGroups = ['sysop', 'filemover'];
AQD = window.AjaxQuickDelete;
pageName = AQD.pageName || window.pn || mw.config.get('wgPageName');
if (!AQD.userRights) { // Check user group
userGroups.some(function (v) {
if (wgUserGroups.indexOf(v) !== -1) {
AQD.userRights = v;
return true;
}
});
}
if (AQD.userRights) {
if (!a && mw.libs.JustReplace) {
a = $(mw.util.addPortletLink('p-cactions', '#', 'Global replace', 'ca-justreplace', 'Replace stuff'))
.find('a').on('click', mw.libs.JustReplace.init);
}
mw.hook('script-loaded.justreplace').fire(a);
}
});
}
});
}());
// </nowiki> EOF