User:IceWelder/copycat.js

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