User:Ingenuity/MergeDuplicateRefs.js

//

(function() {

if ([0, 2, 118].includes(mw.config.get("wgNamespaceNumber"))) {

var link = mw.util.addPortletLink("p-cactions", "#", "Remove dup refs", "ca-duprefs", null, null, "#ca-duprefs");

if ( link ) link.addEventListener("click", removeDups);

}

function getRefName(content) {

let count = 1;

while (content.includes(`auto${count}`)) {

count++;

}

return `auto${count}`;

}

async function removeDups() {

const treatAsSame = prompt("Should URLs with different query strings be treated as the same? (y/n)", "y") === "y";

const api = new mw.Api();

const data = await api.get({

action: "query",

prop: "revisions",

rvprop: "content",

titles: mw.config.get("wgPageName"),

rvslots: "*"

});

const page = data.query.pages[Object.keys(data.query.pages)[0]];

const content = page.revisions[0].slots.main["*"];

let newContent = content;

const fullMatches = [...content.matchAll(/]+?)?>([^<]+?)<\/ref>/gmi)];

const shortMatches = [...content.matchAll(/]+)\"?(?:\s+)?\/ ?>/gmi)];

const fullRefDict = {}, shortRefDict = {};

fullMatches.forEach((ref) => {

const match = ref[1].match(/(https?:\/\/[^ }<>]+)/i);

if (!match) {

return;

}

const url = treatAsSame ? match[0].split("?")[0].split("#")[0] : match[0];

if (!fullRefDict[url]) {

fullRefDict[url] = [];

}

const name = ref[0].match(//i);

fullRefDict[url].push({

text: ref[0],

content: ref[1],

name: name ? name[1] : null

});

});

shortMatches.forEach((ref) => {

if (!shortRefDict[ref[1]]) {

shortRefDict[ref[1]] = [];

}

shortRefDict[ref[1]].push(ref[0]);

});

for (let url in fullRefDict) {

if (fullRefDict[url].length === 1) {

continue;

}

const item = fullRefDict[url];

const firstRefName = item[0].name ? item[0].name : getRefName(newContent);

newContent = newContent.replace(item[0].text, `${item[0].content}`);

for (let i = 1; i < item.length; i++) {

newContent = newContent.replaceAll(item[i].text, ``);

const ref = item[i];

if (!ref.name || (ref.name && !shortRefDict[ref.name])) {

continue;

}

for (const shortRef of shortRefDict[ref.name]) {

newContent = newContent.replaceAll(shortRef, ``);

}

}

}

await api.postWithToken("csrf", {

action: "edit",

title: mw.config.get("wgPageName"),

text: newContent,

summary: "Merging duplicate references"

});

location.reload();

}

})();

//