Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Cmd-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (Cmd-Shift-R on a Mac)
- Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Clear the cache in Tools → Preferences
For details and instructions about other browsers, see Wikipedia:Bypass your cache.
Code that you insert on this page could contain malicious content capable of compromising your account. If you are unsure whether code you are adding to this page is safe, you can ask at the central discussion page, Scriptorium. The code will be executed when previewing this page under some skins, including Monobook. You can in the interim if you wish to refresh the content sooner under another skin. |
Documentation for this script can be added at User:Inductiveload/scan transcludes. |
// ==================================================================
// Scan an Index page's childen for transclusion status
//
// Add a tool to the sidebar on Index pages. When activated, each page in the
// page list is checked for transclusion.
//
// If pages are:
// - transcluded, they are outlined in GREEN
// - expected to be so, but are not, they are outlined in heavy RED
// - not expected to be so, and are not, they are outlined in ORANGE
//
// A page is "expected" to transcluded when it is proofread, validated or
// prolematic,
//
// Multiple transclusions of the same page result in a thicker outline.
// ==================================================================
/* eslint-disable one-var, vars-on-top */
( function ( $, mw ) {
'use strict';
if ( mw.config.get( 'wgCanonicalNamespace' ) !== 'Index' ) {
return;
}
var ST = {
styles: {
ok: 'outline: 1px solid green;',
multiple: 'outline: 2px solid green;',
expNot: 'outline: 1px solid orange;',
warn: 'outline: 2px solid red;'
},
exemptCats: [ 'Category:Not transcluded' ]
};
var ScanTranscludes = function () {
this.pagelinkSelector = '.prp-index-pagelist > a';
};
ScanTranscludes.prototype.init = function () {
// console.log("Init ScanTranscludes");
// only init in the index namespace
if ( mw.config.get( 'wgNamespaceNumber' ) !== 106 ||
mw.config.get( 'wgAction' ) !== 'view' ) {
return;
}
this.installPortlet();
};
ScanTranscludes.prototype.installPortlet = function () {
var self = this,
// var accessKey = "a";
// self.steal_accesskey(accessKey);
portlet = mw.util.addPortletLink(
'p-tb',
'#',
'Check transclusion',
't-check-transcludes',
'Check page transclusion status (shift-click to clear)'
// accessKey
);
$( portlet ).on( 'click', function ( e ) {
e.preventDefault();
if ( e.shiftKey ) {
self.clearMarking();
} else {
self.activate();
}
} );
};
ScanTranscludes.prototype.activate = function () {
// console.log("Checking transclusion");
var self = this,
// inject style rules
$style = $( '<style>' );
for ( var key in ST.styles ) {
$style.append( '._chk_trans_' + key + ' { ' + ST.styles[ key ] + '}\n' );
}
// eslint-disable-next-line no-jquery/no-global-selector
$( 'html > head' ).append( $style );
$( this.pagelinkSelector ).each( function ( index, link ) {
self.processPageLink( $( link ) );
} );
};
/**
* Gets the Page title from a link
*
* @param {jQuery} $link
* @return {string} title
*/
function getTitleFromLink( $link ) {
var title = $link.attr( 'title' );
if ( !title ) {
return null;
}
return title.replace( / \(.*?\)$/, '' );
}
/*
* Consider problematic, proofread and validated as "should be transcluded"
*/
function linkShouldBeTranscluded( link ) {
return link.hasClass( 'quality2' ) ||
link.hasClass( 'quality3' ) ||
link.hasClass( 'quality4' );
}
ScanTranscludes.prototype.processPageLink = function ( link ) {
var self = this,
title = getTitleFromLink( link );
// couldn't get a link target
if ( !title ) {
return;
}
// NOTE: for some reason _every_ page is seen as included on the Index
// page. Only count transcludes from mainspace.
new mw.Api().get( {
action: 'query',
list: 'embeddedin',
titles: title,
prop: 'categories',
einamespace: 0,
eititle: title,
format: 'json',
formatversion: 2
} )
.then( function ( data ) {
var count = data.query.embeddedin.length;
// list of cats in the page
var cats = data.query.pages[ 0 ].categories.map( function ( pcat ) {
return pcat.title;
} );
// any excluded?
var intersection = ST.exemptCats.filter( function ( exemptCat ) {
return cats.indexOf( exemptCat ) !== -1;
} );
self.decorateLink( link, count, intersection.length > 0 );
link.data( 'trans_count', count );
} );
};
ScanTranscludes.prototype.decorateLink = function ( link, count, exempt ) {
var classname = '',
should = !exempt && linkShouldBeTranscluded( link );
if ( should ) {
// red is not, green if yes
if ( count === 0 ) {
classname = 'warn';
} else {
classname = ( count > 1 ) ? 'multiple' : 'ok';
}
} else {
// orange if not, green if yes
classname = ( count > 1 ) ? 'ok' : 'expNot';
}
// eslint-disable-next-line mediawiki/class-doc
link.addClass( '_chk_trans_' + classname );
};
ScanTranscludes.prototype.clearMarking = function () {
for ( var key in ST.styles ) {
// eslint-disable-next-line mediawiki/class-doc
$( this.pagelinkSelector ).removeClass( '._chk_trans_' + key );
}
};
var st = new ScanTranscludes();
st.init();
// eslint-disable-next-line no-undef
}( jQuery, mediaWiki ) );