MediaWiki:Gadget-false-blue-links.js

Z Wikisłownika – wolnego słownika wielojęzycznego

Uwaga: aby zobaczyć zmiany po opublikowaniu, może zajść potrzeba wyczyszczenia pamięci podręcznej przeglądarki.

  • Firefox / Safari: Przytrzymaj Shift podczas klikania Odśwież bieżącą stronę, lub naciśnij klawisze Ctrl+F5, lub Ctrl+R (⌘-R na komputerze Mac)
  • Google Chrome: Naciśnij Ctrl-Shift-R (⌘-Shift-R na komputerze Mac)
  • Internet Explorer / Edge: Przytrzymaj Ctrl, jednocześnie klikając Odśwież, lub naciśnij klawisze Ctrl+F5
  • Opera: Naciśnij klawisze Ctrl+F5.
/**
 * Zaznacza innym kolorem linki do nieistniejących sekcji językowych istniejących haseł.
 * Przeróbka autorstwa [[User:Olaf]] skryptu [[User:Beau]] do zabarwiania disambigów:
 *  https://pl.wikipedia.org/wiki/MediaWiki:Gadget-mark-disambigs.js
 * Dalsze modyfikacje: [[User:Peter Bowman]]
 */

var config = mw.config.get( [
		'wgPageName',
		'wgArticlePath',
		'wgNamespaceNumber',
		'wgNamespaceIds',
		'wgFormattedNamespaces'
	] ),
	ignoredClasses = [
		'.new',
		'.extiw',
		'.external',
		'.internal',
		'.image',
		'.mw-redirect',
		'.cancelLink'
	],
	categoryRegex = /^(.+?) \((?:indeks|formy fleksyjne)\)$/,
	pathPrefix = mw.format( config.wgArticlePath, '' ),
	formattedNs = config.wgFormattedNamespaces[ config.wgNamespaceIds.category ],
	standardQuery = {
		formatversion: 2,
		titles:        config.wgPageName,
		prop:         'categories',
		cllimit:      'max',
		clshow:       '!hidden',
		generator:    'links',
		gpllimit:     'max',
		gplnamespace:  0,
		redirects:     true
	},
	api = new mw.Api(),
	worklist = {},
	langSections = {};

mw.libs.langData = require( 'ext.gadget.langdata' );

function makeRequest( query, cont ) {
	var apiPromise = api.get( $.extend( query, cont ) );
	
	return apiPromise.then( function ( data ) {
		$.each( data.query && data.query.pages || [], extractQueryData );
		
		if ( data[ 'continue' ] ) {
			return makeRequest( query, data[ 'continue' ] );
		} else {
			return undefined;
		}
	} ).promise( {
		abort: apiPromise.abort
	} );
}

function extractQueryData( i, obj ) {
	var arr;
	
	if ( !obj.categories ) {
		return true;
	}
	
	// Zabezpieczenie przed metodami Object.prototype.(un)watch pod FF
	if ( worklist.hasOwnProperty( obj.title ) ) {
		arr = worklist[ obj.title ];
	} else {
		arr = worklist[ obj.title ] = [];
	}
	
	$.each( obj.categories, function ( i, obj ) {
		var title = obj.title.slice( formattedNs.length + 1 );
		arr.push( title );
	} );
}

function extractLangSections() {
	$.each( worklist, function ( title, categories ) {
		$.each( categories, function ( i, cat ) {
			var iso,
				m = cat.match( categoryRegex );
			
			if ( !m || !m[ 1 ] ) {
				return true;
			}
			
			iso = mw.libs.langData.lang2code[ m[ 1 ] ];
			
			if ( iso ) {
				iso = iso.replace( '-foreign', '' );
				
				if ( !langSections.hasOwnProperty( title ) ) {
					langSections[ title ] = [];
				}
				
				langSections[ title ].push( iso );
			}
		} );
	} );
	
	worklist = {};
}

function extractSelfSections( pageName, $content ) {
	$content.find( '.primary-lang-code' ).each( function () {
		if ( !langSections.hasOwnProperty( pageName ) ) {
			langSections[ pageName ] = [];
		}
		
		langSections[ pageName ].push( this.id.replace( '-foreign', '' ) );
	} );
}

function decodeFragment( s ) {
	return decodeURIComponent(
		s.replace( /\./g, '%' ).replace( /_/g, ' ' )
	);
}

function extractArticleName( s ) {
	return decodeURI(
		s.replace( pathPrefix, '' ).replace( /_/g, ' ' )
	);
}

function filterLinks( i, link ) {
	var title, fragment, m, iso,
		uri = new mw.Uri( link.getAttribute( 'href' ) );
	
	if (
		!uri.fragment ||
		!$.isEmptyObject( uri.query ) ||
		uri.path.indexOf( ':' ) !== -1
	) {
		return false;
	}
	
	title = extractArticleName( uri.path );
	fragment = decodeFragment( uri.fragment );
	m = fragment.match( new RegExp( '^' + title + ' \\((?:język )?(.+)\\)$' ) );
	iso = m && m[ 1 ] ? mw.libs.langData.lang2code[ m[ 1 ] ] : fragment;
	
	if ( !mw.libs.langData.code2lang.hasOwnProperty( iso ) ) {
		return true;
	}
	
	return (
		langSections.hasOwnProperty( title ) &&
		langSections[ title ].indexOf( iso ) === -1 &&
		langSections[ title ].indexOf( 'inter' ) === -1 &&
		!(
			( iso === 'zh' || iso === 'ja' ) &&
			langSections[ title ].indexOf( 'zh-char' ) === -1
		)
	);
}

function inspectPageLinks( page ) {
	return makeRequest( $.extend( {}, standardQuery, {
		titles: page
	} ) ).done( extractLangSections );
}

function inspectTitles( titles ) {
	if ( typeof titles === 'string' ) {
		titles = [ titles ];
	}
	
	titles = titles.filter( function ( title ) {
		return !langSections.hasOwnProperty( title );
	} );
	
	if ( !titles.length ) {
		return $().promise( { abort: $.noop } );
	}
	
	// TODO: ograniczone do 50 stron
	return makeRequest( {
		formatversion: 2,
		titles:        titles,
		prop:         'categories',
		cllimit:      'max',
		clshow:       '!hidden',
		redirects:     true
	} ).done( extractLangSections );
}

function processElements( $container ) {
	if ( $.isEmptyObject( langSections ) ) {
		return;
	}
	
	$container
		.find( mw.format( 'a[href^="$1"]:not($2)',
			pathPrefix,
			ignoredClasses.join( ', ' )
		) )
		.filter( filterLinks )
		.addClass( 'mw-false-blue' );
}

if (
	config.wgNamespaceNumber >= 0 &&
	config.wgNamespaceNumber !== config.wgNamespaceIds.category
) {
	$.when(
		makeRequest( standardQuery ).done( extractLangSections ),
		$.ready
	).done( function () {
		var pageName = config.wgPageName.replace( /_/g, ' ' ),
			$content = $( '#mw-content-text' );
		
		if (
			!langSections.hasOwnProperty( pageName ) &&
			$content.find( '.mw-selflink, .mw-selflink-fragment' ).length
		) {
			extractSelfSections( pageName, $content );
		}
		
		processElements( $content );
	} );
}

module.exports = {
	inspectPageLinks: inspectPageLinks,
	inspectTitles: inspectTitles,
	processElements: processElements,
	langSections: langSections
};