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);
});
}