User:AramilFeraxa/FileDelinker.js
Appearance
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)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
mw.loader.using(['oojs-ui', 'mediawiki.api', 'mediawiki.util']).then(function () {
$(function () {
if (mw.config.get('wgNamespaceNumber') !== 6) {
return;
}
function getLocalFileUsage(fileName) {
return new mw.Api().get({
action: 'query',
prop: 'fileusage',
titles: fileName,
fulimit: 'max',
format: 'json'
}).then(function (data) {
var pages = [];
Object.values(data.query.pages).forEach(function (page) {
if (page.fileusage) {
pages = pages.concat(page.fileusage.map(function (usage) {
return usage.title;
}));
}
});
return pages;
});
}
function removeFileReferences(content, fileName) {
const fileRegex = new RegExp('^.*\[\[.*?[:/]?' + fileName.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') + '(\|.*?)?\]\].*$', 'gim');
const gallerySectionRegex = /<gallery>([\s\S]*?)<\/gallery>/gi;
const infoboxRegex = new RegExp('(\|.*?=\s*)' + fileName.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') + '(\s*)$', 'gim');
let updatedContent = content;
updatedContent = updatedContent.replace(gallerySectionRegex, (match, galleryContent) => {
const updatedGallery = galleryContent
.split('\n')
.filter(line => !line.includes(fileName))
.join('\n');
return `<gallery>${updatedGallery}</gallery>`;
});
updatedContent = updatedContent.replace(infoboxRegex, (match, beforeEquals, afterEquals) => {
return beforeEquals + '' + afterEquals;
});
updatedContent = updatedContent
.split('\n')
.filter(line => !line.match(fileRegex))
.join('\n');
return updatedContent;
}
function openPageForEditing(page, fileName) {
new mw.Api().get({
action: 'query',
prop: 'revisions',
titles: page,
rvslots: 'main',
rvprop: 'content',
format: 'json'
}).then(function (data) {
const pageContent = Object.values(data.query.pages)[0].revisions[0].slots.main['*'];
const updatedContent = removeFileReferences(pageContent, fileName);
const editUrl = new mw.Uri(mw.util.getUrl(page));
editUrl.extend({ action: 'edit' });
const win = window.open(editUrl.toString(), '_blank');
if (win) {
win.onload = function () {
const textarea = win.document.querySelector('#wpTextbox1');
const summary = win.document.querySelector('#wpSummary');
if (textarea) {
textarea.value = updatedContent;
}
if (summary) {
summary.value = 'Removing references to [[File:' + fileName + ']]';
}
const previewButton = win.document.querySelector('#wpDiff');
if (previewButton) {
previewButton.click();
}
};
}
}).catch(function (error) {
console.error('Error fetching page content:', page, error);
});
}
function removeLinksFromPageAndSave(page, fileName) {
new mw.Api().get({
action: 'query',
prop: 'revisions',
titles: page,
rvslots: 'main',
rvprop: 'content',
format: 'json'
}).then(function (data) {
const pageContent = Object.values(data.query.pages)[0].revisions[0].slots.main['*'];
const updatedContent = removeFileReferences(pageContent, fileName);
if (updatedContent === pageContent) {
console.warn('No changes detected for page:', page);
return;
}
new mw.Api().postWithEditToken({
action: 'edit',
title: page,
text: updatedContent,
summary: 'Removing references to [[File:' + fileName + ']]'
}).then(function () {
console.log('Updated page:', page);
}).catch(function (error) {
console.error('Error updating page:', page, error);
});
}).catch(function (error) {
console.error('Error fetching page content:', page, error);
});
}
function showDialog(pages, fileName) {
const dialog = new OO.ui.MessageDialog();
const windowManager = new OO.ui.WindowManager();
$(document.body).append(windowManager.$element);
windowManager.addWindows([dialog]);
const pageLinks = pages.map(page => {
return $('<a>')
.attr('href', '#')
.text(page)
.on('click', function (event) {
event.preventDefault();
openPageForEditing(page, fileName);
});
});
const content = $('<div>').append(
$('<p>').text('Select a page to edit or review:'),
$('<ul>').append(pageLinks.map(link => $('<li>').append(link)))
);
windowManager.openWindow(dialog, {
title: 'Pages linking to file',
message: content,
actions: [
{ action: 'close', label: 'Close', flags: 'safe' }
]
});
}
var autoSave = false;
var button = new OO.ui.ButtonWidget({
label: 'Delink file',
icon: 'unlink',
flags: ['progressive']
});
var pageCountLabel = new OO.ui.LabelWidget({
label: ' (0 pages)',
classes: ['page-count-label']
});
var autoSaveToggle = new OO.ui.ToggleSwitchWidget({
value: autoSave
});
autoSaveToggle.on('change', function (value) {
autoSave = value;
});
$('#mw-content-text').prepend(
$('<div>').css('margin-bottom', '10px').append(
$('<div>').append(button.$element, pageCountLabel.$element),
$('<div>').css('margin-top', '5px').text('Auto-save: ').append(autoSaveToggle.$element)
)
);
button.on('click', function () {
var fileName = mw.config.get('wgTitle');
button.setDisabled(true);
getLocalFileUsage('File:' + fileName).then(function (pages) {
pageCountLabel.setLabel(' (' + pages.length + ' pages)');
if (pages.length === 0) {
alert('No pages link to this file.');
} else if (!autoSave) {
showDialog(pages, fileName);
} else {
pages.forEach(page => removeLinksFromPageAndSave(page, fileName));
alert('Links removed from all pages.');
}
}).catch(function (error) {
console.error('Error fetching file usage:', error);
alert('An error occurred while fetching file usage.');
}).always(function () {
button.setDisabled(false);
});
});
var fileName = mw.config.get('wgTitle');
getLocalFileUsage('File:' + fileName).then(function (pages) {
pageCountLabel.setLabel(' (' + pages.length + ' pages)');
});
});
});