User:Andrybak/Scripts/Unsigned generator.js

(function {	'use strict';

const USERSCRIPT_NAME = 'Unsigned generator'; const VERSION = 2; const locale = { portletText: "Unsigned gen", // short to keep the "Tools" menu narrow portletTooltip: "Generate template for unsigned discussion messages", template: "subst:Unsigned", // see Template:Unsigned templateIp: "subst:Unsigned IP", // see Template:Unsigned IP prefixText: "Unsigned wikitext: ", copyButtonText: "Copy", errorTimestamp: "Cannot find the timestamp of the edit. Aborting.", errorAuthor: "Cannot find the author of the edit. Aborting.", }	// 	const LOG_PREFIX = `[${USERSCRIPT_NAME} v${VERSION}]:`; const mw = window.mw; // a hack to trick my JS editor into believing that `mw` exists const USERSCRIPT_OUTPUT_ID = 'userscript-unsigned-generator';

function error(...toLog) { console.error(LOG_PREFIX, ...toLog); }

function warn(...toLog) { console.warn(LOG_PREFIX, ...toLog); }

function info(...toLog) { console.info(LOG_PREFIX, ...toLog); }

function debug(...toLog) { console.debug(LOG_PREFIX, ...toLog); }

function notify(notificationMessage) { mw.notify(notificationMessage, {			title: USERSCRIPT_NAME		}); }

function errorAndNotify(errorMessage, exception) { error(errorMessage, exception); notify(errorMessage); }

function createTimestampWikitext(timestamp) { // https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions##time_format_like_in_signatures return '`; }

function createWikitext(template, user, timestamp) { const timestampWikitext = createTimestampWikitext(timestamp); return ``; }

/*	 * Adapted from User:Enterprisey/diff-permalink.js * https://en.wikipedia.org/wiki/User:Enterprisey/diff-permalink.js	 */ function showWikitextAboveDiff(wikitext) { const wikitextInput = document.createElement('input'); wikitextInput.id = USERSCRIPT_OUTPUT_ID; wikitextInput.value = wikitext; wikitextInput.style.fontFamily = 'monospace'; wikitextInput.setAttribute('size', wikitext.length);

const copyButton = document.createElement('button'); copyButton.textContent = locale.copyButtonText; copyButton.style.padding = '0.5em'; copyButton.style.cursor = 'pointer'; copyButton.style.marginLeft = '0.5em'; copyButton.onclick = => { document.getElementById(USERSCRIPT_OUTPUT_ID).select; document.execCommand('copy'); };

const container = document.createElement('div'); container.appendChild(document.createTextNode(locale.prefixText)); container.appendChild(wikitextInput); container.appendChild(copyButton); document.getElementById('bodyContent').prepend(container); }

/*	 * The main function of the script. */	function runPortlet { /*		 * Reference documentation about keys and values in mw.config: * https://www.mediawiki.org/wiki/Manual:Interface/JavaScript#mw.config */		const diffTimestampElement = document.querySelector('#mw-diff-ntitle1 .mw-diff-timestamp'); if (!diffTimestampElement) { errorAndNotify(locale.errorTimestamp); return; }		const mwUserlink = document.querySelector('#mw-diff-ntitle2 .mw-userlink'); if (!mwUserlink) { errorAndNotify(locale.errorAuthor); return; }		const template = mwUserlink.classList.contains('mw-anonuserlink') ? locale.templateIp : locale.template; const usernameOrIp = mwUserlink.innerText; const isoTimestamp = diffTimestampElement.getAttribute('data-timestamp'); const wikitext = createWikitext(template, usernameOrIp, isoTimestamp); info(wikitext); showWikitextAboveDiff(wikitext); }

function wait(message) { info(message); setTimeout(lazyLoadUnsignedGenerator, 200); }

/*	 * Infrastructure to ensure the script can run. */	function lazyLoadUnsignedGenerator { if (mw.config.get('wgDiffNewId') == null && mw.config.get('wgDiffOldId') == null) { /*			 * TODO: Not supported is the use case of the talk page being *      created with an unsigned message. *      It's harder in such cases to get to the diff view via the GUI. */			info('Not a diff view. Aborting.'); return; }		const namespaceId = mw.config.get("wgNamespaceNumber"); if (namespaceId % 2 == 0 && namespaceId != 4) { // not a talk page and not project namespace info('Not a discussion namespace. Aborting.'); return; }		if (!mw.loader.using) { wait('Function mw.loader.using is no loaded yet. Waiting...'); return; }		debug('Loading...'); mw.loader.using(			['mediawiki.util'],			 => {				const link = mw.util.addPortletLink('p-cactions', '#', locale.portletText, 'ca-unsigned-generator', locale.portletTooltip);				if (!link) {					info('Cannot create portlet link (mw.util.addPortletLink). Assuming unsupported skin. Aborting.');					return;				}				link.onclick = event => {					mw.loader.using('mediawiki.api', runPortlet);				};			},			(e) => {				error('Cannot add portlet link', e);			}		); }

if (document.readyState !== 'loading') { lazyLoadUnsignedGenerator; } else { warn('Cannot load yet. Setting up a listener...'); document.addEventListener('DOMContentLoaded', lazyLoadUnsignedGenerator); }	// });