User:IceWelder/copycat.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
This user script seems to have a documentation page at User:IceWelder/copycat. |
function copycat_copy_page(_oldName, _newName, processContent, copyTalk, isTalk, createParents) {
// Safe-prepend names with space key
var spaceKey = isTalk ? 'Category talk' : 'Category';
var oldName = `${spaceKey}:${_oldName.replace(/Category(?:[_ ]talk):/g, '')}`;
var newName = `${spaceKey}:${_newName.replace(/Category(?:[_ ]talk):/g, '')}`;
// Retrieve the original page to ge its content
var oldPage = new Morebits.wiki.page(oldName, `Reading category ${oldName}`);
oldPage.setCreateOption('nocreate');
oldPage.load(
function () {
if (!oldPage.exists()) {
Morebits.status.warn('Warning', `${oldName} does not exist.`);
return;
}
// Process possible replacements
var oldContent = oldPage.getPageText();
var newContent = processContent(oldContent);
// Create the new page
var newPage = new Morebits.wiki.page(newName, `Creating category ${newName}`);
newPage.setCreateOption('createonly');
newPage.setAppendText(newContent);
newPage.setWatchlist('default');
newPage.setEditSummary(`Copied category from ${oldName} by [[w:User:IceWelder/copycat.js|script]]`);
newPage.load(
function () {
if (newPage.exists()) {
Morebits.status.info('Info', `${newName} already exists.`);
return;
}
newPage.append(
function () {
// Talk page -> Do nothing
if (isTalk) {
return;
}
// Copy talk page
if (copyTalk) {
copycat_copy_page(_oldName, _newName, processContent, copyTalk, true, createParents);
}
// Ignore parents -> Do nothing
if (!createParents) {
return;
}
// Retrieve all listed categories
var categoriesRegex = /(?<=\[\[[_ ]*[Cc]ategory[_ ]*:[_ ]*)[^\]|]+[_ ]*/g;
var match;
do {
match = categoriesRegex.exec(oldContent);
if (match) {
var oldCategory = match[0];
// Category did not contain an ordinal -> do nothing
var newCategory = processContent(oldCategory);
if (newCategory === oldCategory) {
continue;
}
// Recursively create category
copycat_copy_page(oldCategory, newCategory, processContent, copyTalk, false, createParents);
}
} while (match);
},
function () {
Morebits.status.error('Error', `An error occurred while creating ${newName}`);
}
);
},
function () {
Morebits.status.error('Error', `An error occurred while reading ${newName}`);
}
);
},
function () {
Morebits.status.error('Error', `An error occurred while reading ${oldName}`);
}
);
}
function copycat_process_content(changeOrdinals, oldOrdinal, newOrdinal) {
return function (content) {
if (!changeOrdinals) {
return content;
}
return content.replace(new RegExp(oldOrdinal, 'g'), newOrdinal);
};
}
function copycat_submit(event) {
var form = event.target;
// Get parameters
var newName = form['newName'].value;
var copyTalk = form['copyTalk'].checked;
var changeOrdinals = form['changeOrdinals'].checked;
var newOrdinal = changeOrdinals ? form['changeOrdinals.newOrdinal'].value : null;
var createParents = changeOrdinals ? form['createParents'].checked : null;
// Configure actions
Morebits.status.init(form);
Morebits.wiki.actionCompleted.redirect = `Category:${newName}`;
Morebits.wiki.actionCompleted.notice = 'Completed';
Morebits.wiki.api.setApiUserAgent('Copycat ([[w:User:IceWelder/copycat.js]])');
// Set up metadata
var oldName = Morebits.pageNameNorm.replace(/Category:/g, '');
var oldOrdinal = oldName.replace(/\D*(\d+)?\D*/, '$1');
var processContent = copycat_process_content(changeOrdinals, oldOrdinal, newOrdinal);
copycat_copy_page(oldName, newName, processContent, copyTalk, false, createParents);
}
function copycat_show_popup() {
// Define window
var dialog = new Morebits.simpleWindow(600, 450);
dialog.setScriptName('Copycat');
dialog.setTitle('Copy this category');
dialog.addFooterLink('Report bug / request feature', 'w:User talk:IceWelder');
// Define form
var form = new Morebits.quickForm(copycat_submit);
var oldName = Morebits.pageNameNorm.replace(/Category:/g, '');
form.append({
name: 'newName',
type: 'input',
label: 'New name: ',
value: oldName,
});
var oldOrdinal = oldName.replace(/\D*(\d+)?\D*/, '$1');
form.append({
type: 'checkbox',
list: [
{
name: 'copyTalk',
label: 'Also copy talk page',
},
{
name: 'changeOrdinals',
label: 'Change year ordinals',
tooltip: 'Changes all ordinals from the old category to the set value for the new category.',
subgroup: [
{
name: 'newOrdinal',
type: 'input',
label: 'New ordinal: ',
value: oldOrdinal,
},
{
type: 'checkbox',
list: [
{
name: 'createParents',
type: 'input',
label: 'Create missing parent categories',
tooltip: 'Recursively creates new parent categories where required.',
subgroup: [
{
type: 'div',
label: 'Warning: This can create a large number of new categories',
},
],
},
],
},
],
},
],
});
form.append({
type: 'submit',
label: 'Copy',
});
// Display window with form
var render = form.render();
dialog.setContent(render);
dialog.display();
}
// If viewing category
if (mw.config.get('wgNamespaceNumber') === 14 && mw.config.get('wgAction') === 'view') {
// Wait until article is loaded and MediaWiki utils are ready
$.when($.ready, mw.loader.using(['mediawiki.util', 'ext.gadget.morebits'])).then(function () {
// Add portlet link
$(mw.util.addPortletLink('p-tb', '#', 'Copy this category')).click(copycat_show_popup);
});
}