MediaWiki:Common.js: Difference between revisions
Appearance
Dustin Loup (talk | contribs) No edit summary |
No edit summary |
||
(95 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
jQuery. | // Load jQuery UI using mw.loader | ||
('# | mw.loader.using(['jquery.ui'], function() { | ||
console.log("jQuery UI loaded."); | |||
}); | |||
// Load WikiEditor and RefToolbar by default | |||
mw.loader.using(['ext.wikiEditor']).then(function() { | |||
$(function() { | |||
if (mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit') { | |||
$('#wpTextbox1').wikiEditor(); | |||
console.log("WikiEditor auto-initialized."); | |||
mw.loader.load('//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-refToolbar.js&action=raw&ctype=text/javascript'); | |||
console.log("RefToolbar loaded."); | |||
} | |||
}); | |||
}); | |||
// Codex: Open all external links on a new window | |||
mw.loader.using(['mediawiki.util']).then(function () { | |||
function openExternalLinks() { | |||
// General external links | |||
document.querySelectorAll('a.external').forEach(function (link) { | |||
link.setAttribute('target', '_blank'); | |||
link.setAttribute('rel', 'noopener noreferrer'); | |||
}); | |||
// Social media links within templates | |||
document.querySelectorAll('div.external-social a, div.ntldstats a').forEach(function (link) { | |||
link.setAttribute('target', '_blank'); | |||
link.setAttribute('rel', 'noopener noreferrer'); | |||
}); | |||
} | |||
// Run on page load | |||
mw.hook('wikipage.content').add(openExternalLinks); | |||
}); | |||
// Include a registration link in Minerva/mobile's hamburger menu for logged out users | |||
mw.loader.using(['mediawiki.util'], function() { | |||
$(function() { | |||
if (mw.config.get('skin') === 'minerva' && mw.user.isAnon()) { | |||
var waitForPersonalMenu = function(callback) { | |||
var $menu = $('#p-personal'); | |||
if ($menu.length) { | |||
callback($menu); | |||
} else { | |||
setTimeout(function() { | |||
waitForPersonalMenu(callback); | |||
}, 100); | |||
} | |||
}; | |||
waitForPersonalMenu(function($menu) { | |||
var regUrl = mw.util.getUrl('Special:UserLogin', { type: 'signup' }); | |||
// Get the message text and remove any curly braces | |||
var regText = mw.msg('createaccount').replace(/[{}]/g, '').trim(); | |||
var $regItem = $('<li>') | |||
.addClass('toggle-list-item menu__item--register') | |||
.append( | |||
$('<a>') | |||
.addClass('toggle-list-item__anchor') | |||
.attr('href', regUrl) | |||
.append( | |||
$('<span>') | |||
.addClass('minerva-icon minerva-icon--register') | |||
) | |||
.append( | |||
$('<span>') | |||
.addClass('toggle-list-item__label') | |||
.text(regText) | |||
) | |||
); | |||
$menu.append($regItem); | |||
}); | |||
} | |||
}); | |||
}); | |||
// Codex: Shortcut for the "Purge" action for refreshing cache, named "Clear cache" | |||
mw.loader.using(['mediawiki.util']).then(function () { | |||
function addPurgeLink() { | |||
if (!document.getElementById('ca-purge') && mw.config.get('wgIsArticle')) { | |||
mw.util.addPortletLink( | |||
'p-cactions', | |||
mw.util.wikiScript() + '?' + new URLSearchParams({ | |||
title: mw.config.get('wgPageName'), | |||
action: 'purge' | |||
}).toString(), | |||
mw.config.get('skin') === 'monobook' ? '*' : 'Clear cache', | |||
'ca-purge', | |||
'Purge the server cache of this page?', | |||
'*' | |||
); | |||
} | |||
} | |||
mw.hook('wikipage.content').add(addPurgeLink); | |||
}); | |||
// Codex: Modernized "Gadget-predefined-summaries" | |||
// Lists common options below "Summary" to optimize editor experience | |||
mw.loader.using(['mediawiki.util']).then(function () { | |||
'use strict'; | |||
if (window.resumeDeluxe === undefined && | |||
['edit', 'submit'].includes(mw.config.get('wgAction')) && | |||
mw.util.getParamValue('section') !== 'new') { | |||
var resumeDeluxe = { | |||
titles: ["grammar", "normalization", "categorization", "general fixes", "template fixes", "+ internal link(s)", "+ external link(s)"], | |||
inputs: ["grammar", "normalization", "categorization", "general fixes", "template fixes", "+ internal link(s)", "+ external link(s)"], | |||
addToSummary: function (str) { | |||
var summaryField = document.getElementById('wpSummary'); | |||
if (summaryField) { | |||
summaryField.value = summaryField.value ? summaryField.value + '; ' + str : str; | |||
} | |||
return false; | |||
} | |||
}; | |||
window.resumeDeluxe = resumeDeluxe; | |||
var DeluxeSummary = function() { | |||
var summaryLabel = document.getElementById('wpSummaryLabel'); | |||
var summaryField = document.getElementById('wpSummary'); | |||
if (summaryLabel && summaryField) { | |||
// Prevent duplicate bars by checking for an existing one | |||
if (summaryLabel.querySelector('.predefined-summaries-bar')) { | |||
return; | |||
} | |||
// Create container with a unique class name | |||
var container = document.createElement('span'); | |||
container.className = 'predefined-summaries-bar'; | |||
container.innerHTML = '<b>Predefined summaries</b>: '; | |||
resumeDeluxe.titles.forEach((title, index) => { | |||
if (index > 0) { | |||
container.appendChild(document.createTextNode(' / ')); | |||
} | |||
var link = document.createElement('a'); | |||
link.href = '#'; | |||
link.className = 'sumLink'; | |||
link.title = 'Add to edit summary'; | |||
link.textContent = title; | |||
link.addEventListener('click', function (event) { | |||
event.preventDefault(); | |||
resumeDeluxe.addToSummary(resumeDeluxe.inputs[index]); | |||
}); | |||
container.appendChild(link); | |||
}); | |||
container.appendChild(document.createElement('br')); | |||
summaryLabel.prepend(container); | |||
// Adjust width as in original script | |||
summaryField.style.width = '95%'; | |||
} | |||
}; | |||
mw.hook('wikipage.content').add(DeluxeSummary); | |||
} | |||
}); | |||
// Custom script targeting Lingo that performs two separate actions: 1) Disables the rendering of tooltips of a given acronym within the article that defines it (RFC on the Request For Comments article); 2) Disables Lingo entirely in arbitrarily defined Namespaces | |||
$(function() { | |||
// List namespaces where Lingo should be blocked (adjust as needed) | |||
var blockedNamespaces = ['Template', 'Category', 'Module']; | |||
var currentNS = mw.config.get('wgCanonicalNamespace'); | |||
if (blockedNamespaces.indexOf(currentNS) !== -1) { | |||
// Remove any Lingo tooltip markup immediately | |||
$('.mw-lingo-term').each(function() { | |||
$(this).replaceWith($(this).text()); | |||
}); | |||
console.log("Lingo processing is blocked in the '" + currentNS + "' namespace."); | |||
return; // Stop further processing | |||
} | |||
// Decent enough script for Lingo not to render tooltips of an acronym on the page that defines it | |||
var rawTitle = mw.config.get('wgTitle').replace(/_/g, ' ').trim(); | |||
var acronym = null; | |||
// Case 1: Title written as "Long Form (ACRONYM)" | |||
var titleAcronymMatch = rawTitle.match(/^(.+?)\s+\(([A-Z]{2,})\)$/); | |||
if (titleAcronymMatch) { | |||
acronym = titleAcronymMatch[2]; | |||
console.log("Using acronym from title parenthetical: " + acronym); | |||
} | |||
// Case 2: Title is exactly an acronym (all uppercase) | |||
else if (/^[A-Z]+$/.test(rawTitle)) { | |||
acronym = rawTitle; | |||
console.log("Using pure acronym from title: " + acronym); | |||
} | |||
// Otherwise, compute fallback from title’s longform and compare with extracted acronym | |||
else { | |||
// Remove any trailing parenthetical from title, e.g. "Request For Comments (foo)" becomes "Request For Comments" | |||
var longForm = rawTitle.replace(/\s*\(.*\)\s*$/, ''); | |||
var fallback = longForm.split(/\s+/).map(function(word) { | |||
return word.charAt(0).toUpperCase(); | |||
}).join(''); | |||
// Attempt to extract an acronym from the first paragraph | |||
var firstParagraph = $('#mw-content-text p').first().text(); | |||
var parenMatch = firstParagraph.match(/\(([A-Z]{2,})\)/); | |||
if (parenMatch) { | |||
var extracted = parenMatch[1]; | |||
console.log("Extracted acronym from first paragraph: " + extracted); | |||
if (extracted === fallback) { | |||
acronym = extracted; | |||
console.log("Acronym matches fallback computed from title: " + acronym); | |||
} else { | |||
console.log("Extracted acronym (" + extracted + ") does not match computed fallback (" + fallback + "); aborting tooltip removal."); | |||
return; | |||
} | |||
} else { | |||
console.log("No acronym found in first paragraph; aborting tooltip removal."); | |||
return; | |||
} | |||
} | |||
console.log("Assuming definition page for acronym: " + acronym); | |||
// Remove any Lingo tooltip markup for elements whose visible text exactly matches the acronym. | |||
var $matching = $('.mw-lingo-term').filter(function() { | |||
return $(this).text().trim() === acronym; | |||
}); | |||
console.log("Found " + $matching.length + " element(s) with visible text '" + acronym + "'"); | |||
$matching.each(function() { | |||
$(this).replaceWith($(this).text()); | |||
}); | |||
console.log("Finished processing Lingo tooltips for acronym: " + acronym); | |||
}); |
Latest revision as of 18:10, 15 February 2025
// Load jQuery UI using mw.loader
mw.loader.using(['jquery.ui'], function() {
console.log("jQuery UI loaded.");
});
// Load WikiEditor and RefToolbar by default
mw.loader.using(['ext.wikiEditor']).then(function() {
$(function() {
if (mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit') {
$('#wpTextbox1').wikiEditor();
console.log("WikiEditor auto-initialized.");
mw.loader.load('//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-refToolbar.js&action=raw&ctype=text/javascript');
console.log("RefToolbar loaded.");
}
});
});
// Codex: Open all external links on a new window
mw.loader.using(['mediawiki.util']).then(function () {
function openExternalLinks() {
// General external links
document.querySelectorAll('a.external').forEach(function (link) {
link.setAttribute('target', '_blank');
link.setAttribute('rel', 'noopener noreferrer');
});
// Social media links within templates
document.querySelectorAll('div.external-social a, div.ntldstats a').forEach(function (link) {
link.setAttribute('target', '_blank');
link.setAttribute('rel', 'noopener noreferrer');
});
}
// Run on page load
mw.hook('wikipage.content').add(openExternalLinks);
});
// Include a registration link in Minerva/mobile's hamburger menu for logged out users
mw.loader.using(['mediawiki.util'], function() {
$(function() {
if (mw.config.get('skin') === 'minerva' && mw.user.isAnon()) {
var waitForPersonalMenu = function(callback) {
var $menu = $('#p-personal');
if ($menu.length) {
callback($menu);
} else {
setTimeout(function() {
waitForPersonalMenu(callback);
}, 100);
}
};
waitForPersonalMenu(function($menu) {
var regUrl = mw.util.getUrl('Special:UserLogin', { type: 'signup' });
// Get the message text and remove any curly braces
var regText = mw.msg('createaccount').replace(/[{}]/g, '').trim();
var $regItem = $('<li>')
.addClass('toggle-list-item menu__item--register')
.append(
$('<a>')
.addClass('toggle-list-item__anchor')
.attr('href', regUrl)
.append(
$('<span>')
.addClass('minerva-icon minerva-icon--register')
)
.append(
$('<span>')
.addClass('toggle-list-item__label')
.text(regText)
)
);
$menu.append($regItem);
});
}
});
});
// Codex: Shortcut for the "Purge" action for refreshing cache, named "Clear cache"
mw.loader.using(['mediawiki.util']).then(function () {
function addPurgeLink() {
if (!document.getElementById('ca-purge') && mw.config.get('wgIsArticle')) {
mw.util.addPortletLink(
'p-cactions',
mw.util.wikiScript() + '?' + new URLSearchParams({
title: mw.config.get('wgPageName'),
action: 'purge'
}).toString(),
mw.config.get('skin') === 'monobook' ? '*' : 'Clear cache',
'ca-purge',
'Purge the server cache of this page?',
'*'
);
}
}
mw.hook('wikipage.content').add(addPurgeLink);
});
// Codex: Modernized "Gadget-predefined-summaries"
// Lists common options below "Summary" to optimize editor experience
mw.loader.using(['mediawiki.util']).then(function () {
'use strict';
if (window.resumeDeluxe === undefined &&
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.util.getParamValue('section') !== 'new') {
var resumeDeluxe = {
titles: ["grammar", "normalization", "categorization", "general fixes", "template fixes", "+ internal link(s)", "+ external link(s)"],
inputs: ["grammar", "normalization", "categorization", "general fixes", "template fixes", "+ internal link(s)", "+ external link(s)"],
addToSummary: function (str) {
var summaryField = document.getElementById('wpSummary');
if (summaryField) {
summaryField.value = summaryField.value ? summaryField.value + '; ' + str : str;
}
return false;
}
};
window.resumeDeluxe = resumeDeluxe;
var DeluxeSummary = function() {
var summaryLabel = document.getElementById('wpSummaryLabel');
var summaryField = document.getElementById('wpSummary');
if (summaryLabel && summaryField) {
// Prevent duplicate bars by checking for an existing one
if (summaryLabel.querySelector('.predefined-summaries-bar')) {
return;
}
// Create container with a unique class name
var container = document.createElement('span');
container.className = 'predefined-summaries-bar';
container.innerHTML = '<b>Predefined summaries</b>: ';
resumeDeluxe.titles.forEach((title, index) => {
if (index > 0) {
container.appendChild(document.createTextNode(' / '));
}
var link = document.createElement('a');
link.href = '#';
link.className = 'sumLink';
link.title = 'Add to edit summary';
link.textContent = title;
link.addEventListener('click', function (event) {
event.preventDefault();
resumeDeluxe.addToSummary(resumeDeluxe.inputs[index]);
});
container.appendChild(link);
});
container.appendChild(document.createElement('br'));
summaryLabel.prepend(container);
// Adjust width as in original script
summaryField.style.width = '95%';
}
};
mw.hook('wikipage.content').add(DeluxeSummary);
}
});
// Custom script targeting Lingo that performs two separate actions: 1) Disables the rendering of tooltips of a given acronym within the article that defines it (RFC on the Request For Comments article); 2) Disables Lingo entirely in arbitrarily defined Namespaces
$(function() {
// List namespaces where Lingo should be blocked (adjust as needed)
var blockedNamespaces = ['Template', 'Category', 'Module'];
var currentNS = mw.config.get('wgCanonicalNamespace');
if (blockedNamespaces.indexOf(currentNS) !== -1) {
// Remove any Lingo tooltip markup immediately
$('.mw-lingo-term').each(function() {
$(this).replaceWith($(this).text());
});
console.log("Lingo processing is blocked in the '" + currentNS + "' namespace.");
return; // Stop further processing
}
// Decent enough script for Lingo not to render tooltips of an acronym on the page that defines it
var rawTitle = mw.config.get('wgTitle').replace(/_/g, ' ').trim();
var acronym = null;
// Case 1: Title written as "Long Form (ACRONYM)"
var titleAcronymMatch = rawTitle.match(/^(.+?)\s+\(([A-Z]{2,})\)$/);
if (titleAcronymMatch) {
acronym = titleAcronymMatch[2];
console.log("Using acronym from title parenthetical: " + acronym);
}
// Case 2: Title is exactly an acronym (all uppercase)
else if (/^[A-Z]+$/.test(rawTitle)) {
acronym = rawTitle;
console.log("Using pure acronym from title: " + acronym);
}
// Otherwise, compute fallback from title’s longform and compare with extracted acronym
else {
// Remove any trailing parenthetical from title, e.g. "Request For Comments (foo)" becomes "Request For Comments"
var longForm = rawTitle.replace(/\s*\(.*\)\s*$/, '');
var fallback = longForm.split(/\s+/).map(function(word) {
return word.charAt(0).toUpperCase();
}).join('');
// Attempt to extract an acronym from the first paragraph
var firstParagraph = $('#mw-content-text p').first().text();
var parenMatch = firstParagraph.match(/\(([A-Z]{2,})\)/);
if (parenMatch) {
var extracted = parenMatch[1];
console.log("Extracted acronym from first paragraph: " + extracted);
if (extracted === fallback) {
acronym = extracted;
console.log("Acronym matches fallback computed from title: " + acronym);
} else {
console.log("Extracted acronym (" + extracted + ") does not match computed fallback (" + fallback + "); aborting tooltip removal.");
return;
}
} else {
console.log("No acronym found in first paragraph; aborting tooltip removal.");
return;
}
}
console.log("Assuming definition page for acronym: " + acronym);
// Remove any Lingo tooltip markup for elements whose visible text exactly matches the acronym.
var $matching = $('.mw-lingo-term').filter(function() {
return $(this).text().trim() === acronym;
});
console.log("Found " + $matching.length + " element(s) with visible text '" + acronym + "'");
$matching.each(function() {
$(this).replaceWith($(this).text());
});
console.log("Finished processing Lingo tooltips for acronym: " + acronym);
});