User:Polygnotus/Scripts/Signatures.js
// <nowiki>
// Signature normalizer for Wikipedia common.js
// Replaces non-standard signatures with a clean "— Username (talk · contribs) timestamp" format.
// Requires DiscussionTools to be active (default on all Wikimedia wikis since ~2023).
mw.loader.using(['mediawiki.util'], function () {
'use strict';
// Only run on page views, not on edit pages etc.
if (mw.config.get('wgAction') !== 'view') return;
// Namespace check: only run on talk pages and Wikipedia: discussion pages.
// Even-numbered namespaces are content pages; odd-numbered are talk pages.
// Namespace 4 = Wikipedia:, namespace 0 = mainspace (skip that).
var ns = mw.config.get('wgNamespaceNumber');
if (ns === 0) return;
/**
* Extracts a username from a User: or User_talk: href string.
* Returns null if not a user link.
*/
function usernameFromHref(href) {
var m = /\/wiki\/User(?:_talk)?:([^#?&/]+)/.exec(href);
if (!m) return null;
return decodeURIComponent(m[1]).replace(/_/g, ' ');
}
/**
* Checks whether a signature is already "standard" enough to leave alone.
* A standard signature is one whose visible text is basically just the
* username and "(talk)", with no extra styling or unusual text.
*/
function isAlreadyStandard(nodes, username) {
// Collect all text content from the signature nodes
var text = nodes.map(function (n) {
return n.textContent || '';
}).join('').trim();
// Strip common punctuation/whitespace around the username and talk link
var stripped = text.replace(/^\s*[-–—\u2014\u2013]\s*/, '') // leading dash
.replace(/\s*\(talk\)\s*$/i, '') // trailing "(talk)"
.trim();
return stripped === username;
}
// Find all DiscussionTools signature markers in the page
var sigMarkers = document.querySelectorAll('[data-mw-comment-sig]');
sigMarkers.forEach(function (sigMarker) {
// Collect all sibling nodes that belong to the signature.
// The signature runs from the sig marker up to (but not including)
// the timestamp link and the reply button widget.
var sigNodes = [];
var timestampLink = null;
var node = sigMarker.nextSibling;
while (node) {
if (node.nodeType === Node.ELEMENT_NODE) {
// The timestamp link ends the signature
if (node.classList.contains('ext-discussiontools-init-timestamplink')) {
timestampLink = node;
break;
}
// The reply buttons widget also ends the signature
if (node.classList.contains('ext-discussiontools-init-replylink-buttons')) {
break;
}
}
sigNodes.push(node);
node = node.nextSibling;
}
// Nothing to replace if there are no signature nodes
if (sigNodes.length === 0) return;
// Find the username by scanning anchor tags inside the signature nodes.
// We prefer User: links over User_talk: links.
var username = null;
var userHref = null;
for (var i = 0; i < sigNodes.length; i++) {
var n = sigNodes[i];
var anchors = [];
if (n.nodeType === Node.ELEMENT_NODE) {
if (n.tagName === 'A') anchors.push(n);
// Also check descendants
var children = n.querySelectorAll('a');
for (var j = 0; j < children.length; j++) anchors.push(children[j]);
}
for (var k = 0; k < anchors.length; k++) {
var href = anchors[k].getAttribute('href') || '';
// Prefer User: (not User_talk:) for the display link
if (/\/wiki\/User:/.test(href)) {
username = usernameFromHref(href);
userHref = href.split('#')[0]; // strip fragment
break;
}
}
if (username) break;
}
// If we still haven't found one, try User_talk: links as a fallback
if (!username) {
for (var i = 0; i < sigNodes.length; i++) {
var n = sigNodes[i];
if (n.nodeType === Node.ELEMENT_NODE) {
var anchors = n.tagName === 'A' ? [n] : Array.prototype.slice.call(n.querySelectorAll('a'));
for (var k = 0; k < anchors.length; k++) {
var href = anchors[k].getAttribute('href') || '';
if (/\/wiki\/User_talk:/.test(href)) {
username = usernameFromHref(href);
// Derive the User: page href from the User_talk: href
userHref = href.replace('/wiki/User_talk:', '/wiki/User:').split('#')[0];
break;
}
}
}
if (username) break;
}
}
// Can't determine the username — leave this signature alone
if (!username) return;
// If the signature is already standard, leave it alone
if (isAlreadyStandard(sigNodes, username)) return;
// Build the normalized signature fragment:
// — Username (talk · contribs)
var encodedName = encodeURIComponent(username.replace(/ /g, '_'));
var talkHref = '/wiki/User_talk:' + encodedName;
var contribHref = '/wiki/Special:Contributions/' + encodedName;
var frag = document.createDocumentFragment();
frag.appendChild(document.createTextNode('\u00a0\u2014\u00a0')); // non-breaking space + em dash + nbsp
var nameLink = document.createElement('a');
nameLink.href = userHref || ('/wiki/User:' + encodedName);
nameLink.textContent = username;
frag.appendChild(nameLink);
frag.appendChild(document.createTextNode('\u00a0('));
var talkLink = document.createElement('a');
talkLink.href = talkHref;
talkLink.textContent = 'talk';
frag.appendChild(talkLink);
frag.appendChild(document.createTextNode('\u00a0\u00b7\u00a0')); // nbsp · nbsp
var contribLink = document.createElement('a');
contribLink.href = contribHref;
contribLink.textContent = 'contribs';
frag.appendChild(contribLink);
frag.appendChild(document.createTextNode(')\u00a0'));
// Remove the original signature nodes and insert the normalized one
var parent = sigMarker.parentNode;
var insertBefore = timestampLink || sigMarker.nextSibling;
sigNodes.forEach(function (n) {
if (n.parentNode) n.parentNode.removeChild(n);
});
parent.insertBefore(frag, insertBefore);
});
});
// </nowiki>
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.