Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
This page was edited 4 days ago on 08/26/2024. What links here
/* Any JavaScript here will be loaded for all users on every page load. */
$(document).ready(function () {
$.get(mw.util.wikiScript('api'), {
action: 'query',
meta: 'userinfo',
format: 'json'
}).done(function (data) {
if (data.query.userinfo.id !== 0) {
var username = data.query.userinfo.name;
var userLink = mw.util.getUrl('User:' + username);
var logoutLink = mw.util.getUrl('Special:Logout');
$('#user-info').html('<a href="' + userLink + '" class="text-white">' + username + '</a>' +
' | <a href="' + logoutLink + '" class="text-white">Logout</a>');
}
});
});
document.getElementById('offcanvas-toggler').addEventListener('click', function() {
var sidebar = document.getElementById('offcanvas-menu');
if (sidebar.classList.contains('show')) {
sidebar.classList.remove('show');
} else {
sidebar.classList.add('show');
}
});
$(document).ready(function() {
$('#offcanvas-close').on('click', function() {
$('#offcanvas-menu').removeClass('show');
});
});
document.addEventListener('DOMContentLoaded', function() {
var form = document.querySelector('.namespace-search-form');
if (form) {
form.addEventListener('submit', function(e) {
var input = form.querySelector('#bs-extendedsearch-input');
if (input) {
var namespace = mw.config.get('wgCanonicalNamespace');
if (namespace && namespace.length > 0) {
input.value = namespace + ": " + input.value;
}
}
});
}
});
(function($) {
'use strict';
var css = [
'#suggestion-container {',
' position: relative;',
' width: 100%;',
'}',
'#suggestion-box {',
' position: absolute;',
' top: 100%;',
' left: 0;',
' width: 100%;',
' margin-top: 5px;',
' background-color: #fff;',
' z-index: 1000;',
'}',
'.suggestion-item {',
' padding: 8px;',
' cursor: pointer;',
'}',
'.suggestion-item:hover {',
' background-color: #e0e0e0;',
'}'
].join('\n');
$('head').append('<style type="text/css">' + css + '</style>');
$('#suggestion-container').append('<div id="suggestion-box"></div>');
function showSuggestions() {
var query = $(this).val();
if (query.length > 0) {
var apiUrl = "https://wiki.mdriven.net/api.php";
var requestData = {
action: "bs-extendedsearch-autocomplete",
format: "json",
q: JSON.stringify({
query: {
bool: {
must: {
match: {
ac_ngram: {
query: query
}
}
}
}
},
size: 8
}),
searchData: JSON.stringify({
namespace: 0,
value: query,
mainpage: ""
})
};
$.ajax({
url: apiUrl,
data: requestData,
dataType: "json",
method: "GET",
success: function(data) {
var suggestions = data.suggestions || [];
$('#suggestion-box').empty();
$.each(suggestions, function(index, suggestion) {
var item = $('<div class="suggestion-item"></div>').text(suggestion.basename);
$('#suggestion-box').append(item);
});
},
error: function(jqxhr, textStatus, error) {
console.error('Error fetching suggestions:', error);
}
});
}
}
function hideSuggestions(event) {
if (!$(event.target).closest('#suggestion-container').length) {
$('#suggestion-box').empty();
}
}
function selectSuggestion(event) {
event.preventDefault(); // Prevent the mousedown event from triggering blur on the search input
var selectedText = $(this).text();
window.location.href = '/index.php?title=' + encodeURIComponent(selectedText);
}
$('.search-input').on('input', showSuggestions);
$(document).on('click', hideSuggestions);
$('#suggestion-box').on('mousedown', '.suggestion-item', selectSuggestion);
})(jQuery);
$(document).ready(function() {
// Function to toggle a section open or closed
function toggleSection(element) {
var submenu = $(element).next('.submenu');
submenu.toggle();
}
// Function to open the submenu containing the current page link and scroll to it
function openCurrentPageSubmenuAndScroll() {
var currentPageLink = $('#navMenu .current-page');
if (currentPageLink.length) {
// Open the parent submenu(s) of the current page link
currentPageLink.parents('.submenu').show();
// Delay the scrolling to allow for any dynamic layout changes
setTimeout(function() {
// Calculate the position of the current page link
var position = currentPageLink.offset().top - $('#navMenu').offset().top + $('#navMenu').scrollTop();
// Scroll the menu to the active item
$('#navMenu').animate({
scrollTop: position
}, 500);
}, 100); // Delay of 100 milliseconds
}
}
// Event delegation for dynamically loaded content
$('#navMenu').on('click', '.menu-header', function() {
toggleSection(this);
});
// Open the submenu containing the current page link and scroll to it
openCurrentPageSubmenuAndScroll();
});
document.getElementById('menu-toggle').addEventListener('click', function() {
var navMenu = document.getElementById('navMenu');
var bodyContent = document.getElementById('bodyContent');
if (navMenu.style.display === 'none' || navMenu.style.display === '') {
navMenu.style.display = 'block';
bodyContent.style.display = 'none'; // Hide body content when nav menu is displayed
} else {
navMenu.style.display = 'none';
bodyContent.style.display = 'block'; // Show body content when nav menu is hidden
}
});
$(document).ready(function() {
$('.video__navigation .navigation-item').click(function() {
var videoID = $(this).data('video');
var startTime = $(this).data('start');
var newSrc = 'https://www.youtube.com/embed/' + videoID + '?start=' + startTime + '&autoplay=1';
$('.video__wrapper iframe').attr('src', newSrc);
});
});
$(document).ready(function() {
$('.bs-extendedsearch-filter-button-button').each(function() {
$(this).append('<span class="fa fa-chevron-down"></span>');
});
});
document.addEventListener("scroll", function() {
var sidebar = document.getElementById("navMenu");
var footerHeight = 100;
var windowHeight = window.innerHeight;
var scrollBottomPosition = window.scrollY + windowHeight;
var footerTopPosition = document.documentElement.offsetHeight - footerHeight;
if (scrollBottomPosition <= footerTopPosition) {
sidebar.style.height = "100vh";
} else {
sidebar.style.height = "calc(100vh - 110px)";
}
});
mw.loader.using('jquery', function() {
$(document).ready(function() {
var $toc = $('#toc').clone();
$('#toc').remove();
$('#tocContainer').html($toc);
$('#tocContainer').css({
position: '-webkit-sticky',
position: 'sticky',
top: '0',
padding: '15px',
margin: '0 auto',
borderRadius: '5px',
maxWidth: '280px',
maxHeight: 'max-content',
overflowY: 'auto',
height: '90vh',
zIndex: 1000
});
$('#tocContainer .toctitle').css({
fontSize: '16px',
fontWeight: '600',
color: '#555',
borderBottom: '1px solid #ccc',
paddingBottom: '10px',
marginBottom: '10px'
});
$('#tocContainer ul').css({
margin: 0,
padding: '0 0 0 20px',
listStyleType: 'none',
fontSize: '14px',
lineHeight: '1.6'
});
$('#tocContainer li').css({
marginBottom: '5px',
});
$('#tocContainer a').css({
color: '#555',
textDecoration: 'none',
}).hover(
function() { $(this).css({textDecoration: 'underline', color: '#000'}); },
function() { $(this).css({textDecoration: 'none', color: '#555'}); }
);
});
});
$(document).ready(function() {
var $inputElement = $('.oo-ui-textInputWidget-type-search .oo-ui-inputWidget-input');
if ($inputElement.length) {
$inputElement.on('keydown', function(event) {
if (event.key === 'Enter') {
event.preventDefault();
$inputElement.addClass('search-input');
}
});
}
});
$(document).ready(function() {
var $inputElement = $('.oo-ui-textInputWidget-type-search .oo-ui-inputWidget-input');
if ($inputElement.length) {
$inputElement.addClass('search-input');
console.log('Class "search-input" added to the input element.');
} else {
console.log('Input element not found.');
}
});
$(document).ready(function() {
function applyChanges() {
console.log('applyChanges function called');
var $searchInput = $('input[type="search"].oo-ui-inputWidget-input');
var $searchWidgetResults = $('.oo-ui-searchWidget-results');
if ($searchInput.length && $searchWidgetResults.length) {
console.log('Input element found:', $searchInput);
$searchInput.addClass('search-input-edit');
console.log('Class "search-input" added to input element');
if ($searchWidgetResults.next('#suggestion-container-edit').length === 0) {
$('<div id="suggestion-container-edit"></div>').insertAfter($searchWidgetResults);
console.log('Suggestion container added after .oo-ui-searchWidget-results element');
}
$searchInput.on('input', showSuggestions);
$('#suggestion-container').css('width', $searchInput.outerWidth());
} else {
console.log('Input element or .oo-ui-searchWidget-results not found, retrying...');
setTimeout(applyChanges, 100);
}
}
function checkVeActiveClass() {
console.log('Checking for ve-active class');
var $htmlTag = $('html');
if ($htmlTag.hasClass('ve-active')) {
console.log('ve-active class detected on HTML tag');
applyChanges();
} else {
console.log('ve-active class not yet detected, retrying...');
setTimeout(checkVeActiveClass, 100);
}
}
function showSuggestions() {
var query = $(this).val();
if (query.length > 0) {
var apiUrl = "https://insider.mdriven.net/api/search";
var requestData = {
q: query
};
$.ajax({
url: apiUrl,
data: requestData,
dataType: "json",
method: "GET",
success: function(data) {
var suggestions = data || [];
$('#suggestion-container-edit').empty();
$.each(suggestions, function(index, suggestion) {
var source = suggestion._source;
var displayText = source.namespace_text + ':' + source.basename;
var item = $('<div class="suggestion-item-edit"></div>').text(displayText);
item.on('click', function() {
$('input[type="search"].oo-ui-inputWidget-input').val(displayText);
$('#suggestion-container-edit').empty();
});
$('#suggestion-container-edit').append(item);
});
},
error: function(jqxhr, textStatus, error) {
console.error('Error fetching suggestions:', error);
}
});
} else {
$('#suggestion-container-edit').empty(); // Clear suggestions if query is empty
}
}
console.log('Starting to check for ve-active class');
checkVeActiveClass();
});
$('<style type="text/css">#suggestion-container-edit { position: static; border: 1px solid #ccc; background: white; z-index: 10000; width: 100%; overflow-y: auto; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .suggestion-item-edit { padding: 8px; cursor: pointer; } .suggestion-item-edit:hover { background: #f0f0f0; }</style>').appendTo('head');
$(document).ready(function() {
var signInLink = $('#user-info a');
var currentUrl = encodeURIComponent(window.location.pathname + window.location.search + window.location.hash);
signInLink.attr('href', signInLink.attr('href').replace('<CURRENT_URL>', currentUrl));
});
document.addEventListener('DOMContentLoaded', function() {
var images = document.querySelectorAll('.thumbimage');
var overlay = document.createElement('div');
overlay.className = 'image-overlay';
document.body.appendChild(overlay);
var overlayImage = document.createElement('img');
overlay.appendChild(overlayImage);
images.forEach(function(image) {
image.addEventListener('click', function(event) {
event.preventDefault();
event.stopPropagation();
overlayImage.src = image.src;
overlay.classList.add('show');
});
});
overlay.addEventListener('click', function() {
overlay.classList.remove('show');
});
});
// ==UserScript==
// @name MediaWiki Clean Delete
// @namespace MediaWikiScripts
// @description Adds a 'Clean Delete' action link to pages for admins to delete pages and clean up incoming links and redirects.
// ==/UserScript==
mw.loader.using(['mediawiki.api', 'mediawiki.util', 'jquery'], function () {
function addCleanDeleteLink() {
if (mw.config.get('wgUserGroups').indexOf('sysop') !== -1) {
if ($('#ca-cleandelete').length === 0) {
var $link = $('<div>').attr('id', 'ca-cleandelete').attr('class', 'mw-list-item').append(
$('<a>').attr('href', '#').attr('class', 'ca-cleandelete').text('Clean Delete').click(function (e) {
e.preventDefault();
gatherAllDecisions(mw.config.get('wgPageName'));
})
);
$('#p-actions .tab-group').append($link);
}
}
}
function gatherAllDecisions(pageTitle) {
var decisions = {};
showModal('Handle Links and Redirects', '<div class="form-group">' +
'<label>Specify how you would like to handle all incoming links and redirects:</label>' +
'<select id="link-handling-select" class="form-control">' +
'<option value="delete">Delete Links and Redirects</option>' +
'<option value="change">Change Target of Links and Redirects</option>' +
'</select>' +
'</div>', function () {
var choice = $('#link-handling-select').val();
if (choice === 'change') {
showModal('Specify New Target', '<div class="form-group">' +
'<label>Enter the new target page name to update all links and redirects:</label>' +
'<input type="text" id="new-target-input" class="form-control" placeholder="Enter new target">' +
'</div>', function () {
decisions.links = $('#new-target-input').val();
confirmDeletion(pageTitle, decisions);
});
} else {
decisions.links = '';
confirmDeletion(pageTitle, decisions);
}
});
}
function confirmDeletion(pageTitle, decisions) {
showModal('Confirm Page Deletion', '<p>Are you sure you want to delete "' + pageTitle + '" after handling all links and redirects?</p>', function () {
decisions.deletion = true;
showLoadingDialog('Performing Cleanup', function (loadingDialog, updateLoadingText, logDetail) {
executeAllActions(pageTitle, decisions, function () {
loadingDialog.close().closed.then(function() {
location.reload();
});
}, updateLoadingText, logDetail);
});
});
}
function showModal(title, body, onConfirm) {
var modal = $(
'<div class="modal fade" tabindex="-1" role="dialog">' +
'<div class="modal-dialog" role="document">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<h5 class="modal-title">' + title + '</h5>' +
'<button type="button" class="close" data-dismiss="modal" aria-label="Close">' +
'<span aria-hidden="true">×</span>' +
'</button>' +
'</div>' +
'<div class="modal-body">' + body + '</div>' +
'<div class="modal-footer">' +
'<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>' +
'<button type="button" class="btn btn-primary">Confirm</button>' +
'</div>' +
'</div>' +
'</div>' +
'</div>'
);
modal.find('.btn-primary').click(function () {
onConfirm();
modal.modal('hide');
});
modal.on('hidden.bs.modal', function () {
modal.remove();
});
$('body').append(modal);
modal.modal('show');
}
function showLoadingDialog(message, callback) {
var modal = $(
'<div class="modal fade" tabindex="-1" role="dialog">' +
'<div class="modal-dialog" role="document">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<h5 class="modal-title">Performing Cleanup</h5>' +
'</div>' +
'<div class="modal-body">' +
'<p id="loading-text">' + message + '</p>' +
'<ul id="loading-log"></ul>' +
'</div>' +
'</div>' +
'</div>' +
'</div>'
);
$('body').append(modal);
modal.modal('show');
callback(modal, function (text) {
$('#loading-text').text(text);
$('#loading-log').append('<li>' + text + '</li>');
}, function (detail) {
$('#loading-log').append('<li>' + detail + '</li>');
});
}
function executeAllActions(pageTitle, decisions, callback, updateLoadingText, logDetail) {
var api = new mw.Api();
function handleLinksAndRedirects(action, newTarget, next) {
updateLoadingText('Fetching backlinks...');
api.get({
action: 'query',
list: 'backlinks',
bltitle: pageTitle,
bllimit: 'max',
blfilterredir: 'all' // Include both redirects and non-redirects
}).done(function (data) {
logDetail('Backlinks fetched.');
if (data.query.backlinks) {
var promises = $.map(data.query.backlinks, function (link) {
return new $.Deferred(function (defer) {
api.get({
action: 'parse',
page: link.title,
prop: 'wikitext'
}).done(function (linkData) {
var isRedirect = linkData.parse.wikitext['*'].trim().startsWith('#REDIRECT');
if (isRedirect) {
if (action === 'update') {
updateRedirectTarget(link.title, newTarget, api, defer.resolve, logDetail);
} else {
logDetail('Backlink ' + link.title + ' is a redirect. Deleting...');
performDeletion(link.title, defer.resolve, logDetail);
}
} else {
if (action === 'update') {
updateLinkInPage(link.title, pageTitle, newTarget, api, defer.resolve, logDetail);
} else {
removeLinkFromPage(link.title, pageTitle, api, defer.resolve, logDetail);
}
}
}).fail(function (error) {
logDetail('Error checking if backlink ' + link.title + ' is a redirect: ' + error);
defer.resolve();
});
}).promise();
});
$.when.apply($, promises).then(function () {
updateLoadingText(action === 'update' ? 'All links updated.' : 'All links removed.');
next();
});
} else {
next();
}
}).fail(function (error) {
updateLoadingText('Error fetching backlinks: ' + error);
next();
});
}
function updateLinkInPage(linkedPageTitle, originalPageTitle, newTarget, api, resolve, logDetail) {
api.get({
action: 'parse',
page: linkedPageTitle,
prop: 'wikitext'
}).then(function (data) {
var wikitext = data.parse.wikitext['*'];
var regex = new RegExp('\\[\\[' + originalPageTitle.replace(/[\[\]]/g, '\\$&') + '(\\|[^\\]]+)?\\]\\]', 'g');
var newWikitext = wikitext.replace(regex, '[[' + newTarget + '$1]]');
if (wikitext !== newWikitext) {
logDetail('Updating link in ' + linkedPageTitle);
} else {
logDetail('No link found in ' + linkedPageTitle);
}
return api.postWithToken('csrf', {
action: 'edit',
title: linkedPageTitle,
text: newWikitext,
summary: 'Updated link to [[' + newTarget + ']]'
}).then(function (response) {
console.log('API response from updating link: ', response);
if (response.edit && response.edit.result === 'Success' && !response.edit.nochange) {
logDetail('Successfully updated link in ' + linkedPageTitle);
} else {
logDetail('No changes made to link in ' + linkedPageTitle);
}
resolve();
}).fail(function (error) {
logDetail('Error updating link in ' + linkedPageTitle + ': ' + error);
resolve();
});
}).fail(function (error) {
logDetail('Error fetching page content for ' + linkedPageTitle + ': ' + error);
resolve();
});
}
function updateRedirectTarget(redirectPageTitle, newTarget, api, resolve, logDetail) {
logDetail('Updating redirect target in ' + redirectPageTitle);
return api.postWithToken('csrf', {
action: 'edit',
title: redirectPageTitle,
text: '#REDIRECT [[' + newTarget + ']]',
summary: 'Updated redirect to [[' + newTarget + ']]'
}).then(function (response) {
console.log('API response from updating redirect: ', response);
if (response.edit && response.edit.result === 'Success' && !response.edit.nochange) {
logDetail('Successfully updated redirect in ' + redirectPageTitle);
} else {
logDetail('No changes made to redirect in ' + redirectPageTitle);
}
resolve();
}).fail(function (error) {
logDetail('Error updating redirect in ' + redirectPageTitle + ': ' + error);
resolve();
});
}
function removeLinkFromPage(linkedPageTitle, originalPageTitle, api, resolve, logDetail) {
api.get({
action: 'parse',
page: linkedPageTitle,
prop: 'wikitext'
}).then(function (data) {
var wikitext = data.parse.wikitext['*'];
var regex = new RegExp('\\[\\[' + originalPageTitle.replace(/[\[\]]/g, '\\$&') + '(\\|[^\\]]+)?\\]\\]', 'g');
var newWikitext = wikitext.replace(regex, function(match, p1) {
return p1 ? p1.substring(1) : originalPageTitle;
});
if (wikitext !== newWikitext) {
logDetail('Removing link from ' + linkedPageTitle);
} else {
logDetail('No link found in ' + linkedPageTitle);
}
return api.postWithToken('csrf', {
action: 'edit',
title: linkedPageTitle,
text: newWikitext,
summary: 'Removed link to [[' + originalPageTitle + ']]'
}).then(function (response) {
console.log('API response from removing link: ', response);
if (response.edit && response.edit.result === 'Success' && !response.edit.nochange) {
logDetail('Successfully removed link from ' + linkedPageTitle);
} else {
logDetail('No changes made to link in ' + linkedPageTitle);
}
resolve();
}).fail(function (error) {
logDetail('Error removing link from ' + linkedPageTitle + ': ' + error);
resolve();
});
}).fail(function (error) {
logDetail('Error fetching page content for ' + linkedPageTitle + ': ' + error);
resolve();
});
}
function handleRedirects(next) {
updateLoadingText('Fetching redirects...');
api.get({
action: 'query',
titles: pageTitle,
redirects: true
}).done(function (data) {
logDetail('Redirects fetched.');
var redirects = data.query.pages[Object.keys(data.query.pages)[0]].redirects;
if (redirects) {
var promises = $.map(redirects, function (redirect) {
return new $.Deferred(function (defer) {
logDetail('Found redirect: ' + redirect.title);
performDeletion(redirect.title, defer.resolve, logDetail);
}).promise();
});
$.when.apply($, promises).then(function () {
next();
});
} else {
next();
}
}).fail(function (error) {
updateLoadingText('Error fetching redirects: ' + error);
next();
});
}
function performDeletion(pageTitle, resolve, logDetail) {
updateLoadingText('Deleting the page: ' + pageTitle);
api.postWithToken('csrf', {
action: 'delete',
title: pageTitle,
reason: 'Automated clean delete by admin'
}).done(function (response) {
console.log('API response from deleting page: ', response);
if (response.delete && response.delete.title) {
logDetail('Successfully deleted page: ' + response.delete.title);
} else {
logDetail('No deletion performed for ' + pageTitle);
}
resolve();
}).fail(function (error) {
logDetail('Error during clean deletion of ' + pageTitle + ': ' + error);
resolve();
});
}
var tasks = [
function (resolve) {
if (decisions.links === '') {
handleLinksAndRedirects('remove', '', resolve);
} else {
handleLinksAndRedirects('update', decisions.links, resolve);
}
},
function (resolve) {
if (decisions.deletion) {
handleRedirects(resolve);
} else {
resolve();
}
},
function (resolve) {
if (decisions.deletion) {
performDeletion(pageTitle, resolve, logDetail);
} else {
resolve();
}
}
];
(function executeTasks(i) {
if (i < tasks.length) {
tasks[i](function () {
executeTasks(i + 1);
});
} else {
callback();
}
})(0);
}
mw.hook('wikipage.content').add(addCleanDeleteLink);
});
This page was edited 4 days ago on 08/26/2024. What links here