MediaWiki:Gadget-CacheCheck.js
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.
/* CacheCheck.js
* Crosses out resolved entries on the cached special pages to save time checking them.
* Note: these pages have a much shorter cache here, but the script also helps at-a-glance on SpecialPages.
* Therefore, the script will only run on a report page if ten or fewer items are listed.
* Use window.cacheCheckAlways = true; to disable this.
* Originally by Bobogoobo, edited by KockaAdmiralac and others, then ported off Wikia by Bobogoobo.
* For full documentation and contribution history (other than changes before publishing), please see:
* https://dev.fandom.com/wiki/CacheCheck
*/
window.topLevelCat = 'Category:Contents';
mw.loader.using('mediawiki.util').done(function() {
if (window.cacheCheckLoaded || mw.config.get('wgCanonicalNamespace') !== 'Special') {
return;
}
window.cacheCheckLoaded = true;
var removeIfFalse = false,
skips = window.cacheSkip || [],
skipLimit = Number(window.cacheSkipLimit) || 1000,
throttle = !window.cacheCheckAlways;
$list = $('ol.special').length ? $('ol.special > li') : $('ul.gallery > li'),
isgallery = $('ol.special').length ? false : true,
pending = $list.length,
qstr = mw.util.wikiScript('api') + '?action=query&format=json&',
structure = ['query'],
page = mw.config.get('wgCanonicalSpecialPageName'),
pages = [
'Specialpages',
'Deadendpages',
'Lonelypages',
'Uncategorizedcategories',
'Uncategorizedpages',
'Uncategorizedimages',
'Uncategorizedtemplates',
'Unusedcategories',
'Unusedimages',
'Unusedtemplates',
'Wantedcategories',
'Wantedpages',
'Wantedfiles',
'Wantedtemplates'
];
// Only on "Wanted" reports, entries are resolved if the query result is empty.
if (page.substring(0, 6) === 'Wanted') {
removeIfFalse = true;
}
// Skip execution if not on a relevant page, page is skipped by user,
// or list on page is empty. Else, check for empty listings on SpecialPages.
if (
pages.indexOf(page) === -1 ||
skips.indexOf(page) !== -1 ||
($list.length === 0 && page !== 'Specialpages') ||
(throttle && $list.length > 10 && page !== 'Specialpages') ||
skipLimit < (Number(mw.util.getParamValue('limit')) || 0)
) {
return;
} else if (page === 'Specialpages') {
pages.push('BrokenRedirects', 'DoubleRedirects');
$('#mw-specialpagesgroup-maintenance + .mw-specialpages-list li').each(function() {
var $this = $(this),
exceptions = {
'Uncategorizedfiles': 'Uncategorizedimages',
'Unusedfiles': 'Unusedimages',
'Brokenredirects': 'BrokenRedirects',
'Doubleredirects': 'DoubleRedirects'
},
link = $this.children('a').attr('title').substring(8);
link = link.charAt(0) + link.slice(1).toLowerCase();
if (link in exceptions) {
link = exceptions[link];
}
if (pages.indexOf(link) === -1) {
return;
}
$.getJSON(qstr + 'list=querypage&qppage=' + link, function(data) {
var results = data.query.querypage.results;
if (results.length === 0) {
takeAction($this);
}
if (
link === 'Uncategorizedcategories' &&
results.length === 1 &&
results[0].title === window.topLevelCat
) {
takeAction($this);
}
});
});
return;
}
// Handles marking the given element as resolved.
function takeAction($el) {
if (window.cacheCheckRemove) {
$el.remove();
} else {
var $gallery = $el.find('.gallerytext a:first');
if ($gallery.length) {
if ($gallery.find('img')) {
// The link is actually on the image
$el.remove();
} else {
$gallery.wrap('<s></s>');
}
} else {
$el.wrapInner('<s></s>');
}
}
}
// Takes list element, returns generated API query string.
// Foo is 0 or 1 for lonelypages section.
function getQS($this, foo) {
var qs = qstr,
select = isgallery ? '.gallerytext a:first' : 'a:first',
url = $this.find(select).attr('href');
if (page === 'Lonelypages') {
qs += foo ? 'list=embeddedin&eititle=' : 'list=backlinks&bltitle=';
}
qs += encodeURIComponent(mw.util.getParamValue('title', url));
return qs;
}
// Takes a JSON request result, returns array relevant to current page.
function getData(data) {
for (var i = 0; i < structure.length; i++) {
if (structure[i] === 'placeholder') {
//shortcut/hack thanks to StackOverflow
for (var first in data) break;
data = data[first];
} else {
data = data[structure[i]];
}
if (data === undefined) {
return [];
}
}
return data;
}
// Takes element in list, marks script as complete if it is the last list element.
function checkComplete() {
pending -= 1;
if (pending <= 0) {
$('#CacheCheck').text('CacheCheck completed!');
} else {
$('#CacheCheck').text('CacheCheck is running... (' + pending + ' remaining)');
}
}
// Note: all desired data is in the format of an array,
// which in the case of "prop=" queries is missing when there is no data,
// and otherwise is empty.
switch (page) {
case 'Unusedtemplates':
case 'Wantedtemplates':
qstr += 'list=embeddedin&eititle=';
structure.push('embeddedin');
break;
case 'Uncategorizedcategories':
case 'Uncategorizedpages':
case 'Uncategorizedtemplates':
case 'Uncategorizedimages':
qstr += 'prop=categories&titles=';
structure.push('pages', 'placeholder', 'categories');
break;
case 'Unusedimages':
case 'Wantedfiles':
qstr += 'list=imageusage&iutitle=';
structure.push('imageusage');
break;
case 'Unusedcategories':
case 'Wantedcategories':
qstr += 'list=categorymembers&cmtitle=';
structure.push('categorymembers');
break;
case 'Wantedpages':
qstr += 'list=backlinks&bltitle=';
structure.push('backlinks');
break;
case 'Deadendpages':
qstr += 'prop=links&titles=';
structure.push('pages', 'placeholder', 'links');
break;
default:
break;
}
function init() {
$('.mw-spcontent').append(
$('<p>', {
id: 'CacheCheck',
text: 'CacheCheck is running... (' + pending + ' remaining)'
})
);
$list.each(function() {
var $this = $(this);
if (isgallery) {
// Uncategorizedimages, Unusedimages
if ($this.find('img').length) {
$.getJSON(getQS($this), function(data) {
data = getData(data);
if (data.length !== 0) {
takeAction($this);
}
checkComplete();
});
} else {
takeAction($this);
checkComplete();
}
} else if (page === 'Lonelypages') {
// The only one that needs two queries
$.getJSON(getQS($this, 0), function(data) {
data = data.query.backlinks;
if (data.length && !($this.children('s').length)) {
takeAction($this);
}
checkComplete();
});
$.getJSON(getQS($this, 1), function(data) {
data = data.query.embeddedin;
if (data.length && !($this.children('s').length)) {
takeAction($this);
}
checkComplete();
});
} else {
$.getJSON(getQS($this), function(data) {
data = getData(data);
if (removeIfFalse === (data.length === 0)) {
takeAction($this);
}
checkComplete();
});
}
});
}
init();
});