User:Chlod/Scripts/LinkGrab.js

Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// LinkGrab
// Author: Chlod
// Version: 1.0.0

// Copies all links in a page to the clipboard.

var portlet = mw.util.addPortletLink(
    'p-cactions',
    "javascript:void(0)",
    'Grab links', 'pc-linkgrab', 'Copy external links to clipboard'
);

function testString(regexMode, matchers, string, matches = null) {
	for (var matcher of matchers) {
		if (regexMode && (matcher instanceof RegExp ? matcher : new RegExp(matcher, "gi")).test(string)) {
			if (matches) {
				if (matches[matcher] == null)
					matches[matcher] = 1;
				else
					matches[matcher] += 1;
			}
			return true;
		} else if (string.indexOf(matcher) !== -1) {
			if (matches) {
				if (matches[matcher] == null)
					matches[matcher] = 1;
				else
					matches[matcher] += 1;
			}
			return true;
		}
	}
	return false;
}

function oldCopy(text) {
    var textarea = document.createElement("textarea");
    textarea.value = text;
    textarea.style.position = "fixed";
    textarea.style.left = "-100vw";
    textarea.style.top = "-100vh";
    document.body.appendChild(textarea);
    textarea.select();
    document.execCommand("copy");
    document.body.removeChild(textarea);
}

portlet.addEventListener("click", function () {
	// Find all links that match settings.
	var linksToFind = window.lgLinksToFind || [
		"youtube.com",
		"youtu.be",
		"facebook.com",
		"twitter.com"
	];
	var regexMode = window.lgRegexMode || false;
	var parseMode = window.lgParseMode || "hostname";
	
	var matches = {};
	
	// Find all links.
	var links = Array.from(document.querySelectorAll(".mw-parser-output a"))
		.filter(function (el) {
			var href = el.getAttribute("href");
			if (href) {
				var url = new URL(href, window.location.href);
				switch (parseMode) {
					case "href":
						return testString(regexMode, linksToFind, url.href, matches);
					case "origin":
						return testString(regexMode, linksToFind, url.origin, matches);
					case "protocol":
						return testString(regexMode, linksToFind, url.protocol, matches);
					case "pathname":
						return testString(regexMode, linksToFind, url.pathname, matches);
					case "search":
						return testString(regexMode, linksToFind, url.search, matches);
					case "host":
						return testString(regexMode, linksToFind, url.host, matches);
					case "hostname": /* fall through */
					default:
						return testString(regexMode, linksToFind, url.hostname, matches);
				}
			}
		})
		.map((el) => new URL(el.getAttribute("href"), window.location.href).href);
	
	var notification = document.createElement("div");
	notification.innerText = "Links copied to clipboard.";
	var linkList = document.createElement("ul");
	for (var [k, v] of Object.entries(matches)) {
		var linkItem = document.createElement("li");
		linkItem.innerText = k + ": " + v;
		linkList.appendChild(linkItem);
	}
	notification.appendChild(linkList);
	
	if (links.length > 0) {
		try {
			navigator.clipboard.writeText(links.join("\n")).then(() => {
				mw.notify(notification);
			}).catch((e) => {
				console.warn("Falling back to old copy method.");
				oldCopy(text);
			});
		} catch (e) {
			oldCopy(text);
		}
	} else {
		mw.notify("No links to be copied.");
	}
});