MediaWiki:Gadget-frequency-ranking.js

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.
// Opis: wyszukiwanie hasła na listach frekwencyjnych Wikisłownika
// Autor: Peter Bowman @ plwikt

var gadget = mw.libs.frequencyRanking = {};

var pageTitle, $headers, listCount, api, regexps, scrolled;
var r_striplang = /(.*?)\s\(.*/;

gadget.init = function () {
	pageTitle = mw.config.get( 'wgPageName' );
	$headers = $( 'h2' );
	listCount = 0;
	api = new mw.Api();

	regexps = [
		{
			title: /^Indeks:Angielski - Najpopularniejsze słowa \d+-\d+$/,
			patt:  /\[\[([^\]]+)\]\][^:]+:\[\[:en:.*?\]\]=\d+/g
		},
		{
			title: /^Indeks:(Angielski|Arabski|Węgierski) - Najpopularniejsze słowa.*/,
			patt:  /#\s?\[\[([^\]]+)\]\]/g
		},
		{
			title: /^Indeks:(Hiszpański|Niemiecki|Włoski) - Najpopularniejsze słowa.*/,
			rank:  new RegExp( '\\|-\\n\\|(\\d+)\\.\\n\\|(\\[\\[)?' + pageTitle + '(\\]\\])?\\n' )
		},
		{
			title: 'Indeks:Czeski - 1000 najpopularniejszych słów',
			patt:  /\[\[([^\]]+)\]\]/g,
			check: /.*:.*/
		},
		{
			title: 'Indeks:(Fiński|Łaciński|Starogrecki) - Najpopularniejsze słowa',
			rank:  new RegExp( '\\| \\[\\[' + pageTitle + '(?:\\|[^\\]]*?)?\\]\\] \\|\\| (\\d+)' )
		},
		{
			title: /Indeks:(Francuski|Kataloński) - Najpopularniejsze słowa.*/,
			rank:  new RegExp( '\\* (\\d+)\\. \\[\\[' + pageTitle + '\\]\\]' )
		},
		{
			title: 'Indeks:Koreański - Najpopularniejsze słowa 1–5890',
			patt:  /:\s\[\[([^\]]+)\]\]/g
		},
		{
			title: 'Indeks:Norweski - Najpopularniejsze słowa',
			pattf: function ( lang ) {
				var iso = '';
				switch ( lang ) {
					case 'norweski (bokmål)':
						iso = 'nb';
						break;
					case 'norweski (nynorsk)':
						iso = 'nn';
						break;
				}
				return new RegExp( '\\{\\{język linków\\|id=' + iso + '\\}\\}\\[\\[([^\\]]+)\\]\\]', 'g' );
			}
		},
		{
			title: /^Indeks:Polski.*/,
			patt:  /\[\[([^\]]+)\]\]=\d+/g
		},
		{
			title: 'Indeks:Szwedzki - Najpopularniejsze słowa',
			patt:  /\[\[([^\]]+)\]\],/g
		}
	];
	
	scrolled = false;
	
	$( window ).on( 'mousedown wheel DOMMouseScroll mousewheel keyup', function () {
		scrolled = true;
	} );

	this.langs = {};
	this.lists = {};
	this.list_names = [];
	this.multilang = {
		'norweski': 0
	};

	if ( $headers.length !== 0 ) {
		query_lists( function () {
			if ( listCount !== 0 ) {
				get_langs();
			}
		} );
	}
};

function query_lists( callback ) {
	api.get( {
		formatversion: 2,
		prop:         'links',
		pllimit:      'max',
		pltitles:     pageTitle,
		generator:    'categorymembers',
		gcmtitle:     'Kategoria:Listy frekwencyjne',
		gcmnamespace: 102, // Indeks
		gcmlimit:     'max'
	} )
	.done( function ( data ) {
		$.each( data.query.pages, function () {
			if ( this.links ) {
				gadget.lists[ this.title ] = null;
				listCount++;
			}
		} );
	} )
	.done( callback );
}

function query_contents( callback ) {
	api.get( {
		formatversion: 2,
		prop:    'revisions',
		rvprop:  'content',
		rvslots: 'main',
		titles:  gadget.list_names,
		maxage:  43200,
		smaxage: 600
	} )
	.done( function ( data ) {
		$.each( data.query.pages, function () {
			analyze_regexps(
				this.title,
				gadget.lists[ this.title ],
				this.revisions[ 0 ].slots.main.content
			);
		} );
	} )
	.done( callback );
}

function analyze_regexps( list, obj, content ) {
	var pos;
	
	if ( Array.isArray( obj ) ) {
		$.each( obj, function ( i ) {
			analyze_regexps( list, obj[ i ], content );
		} );
		
		return;
	}

	$.each( regexps, function ( _, regexp ) {
		var posmatch, r, matcher, found;
		
		if ( !list.match( regexp.title ) ) {
			return true;
		}
		
		if ( regexp.rank ) {
			posmatch = content.match( regexp.rank );
			pos = posmatch ? posmatch[ 1 ] : undefined;
		} else {
			posmatch = list.match( regexp.initpos || /(\d+)-\d+/ );
			pos = posmatch ? parseInt( posmatch[ 1 ] || 1 ) : 1;

			if ( regexp.patt || regexp.pattf ) {
				r = regexp.patt || regexp.pattf( obj.lang );
				found = false;

				while ( matcher = r.exec( content ) ) {
					if ( regexp.check && regexp.check.test( matcher[ 1 ] ) ) {
						continue;
					}
					
					if ( matcher[ 1 ] == pageTitle ) {
						found = true;
						break;
					}
					
					pos++;
				}
				
				if ( !found ) {
					obj.omit = true;
				}
				
				if ( regexp.patt ) {
					regexp.patt.lastIndex = 0;
				}
			}
		}
		
		return false;
	} );

	obj.rank = pos;
}

function get_langs() {
	$headers.each( function ( i ) {
		var strippedLang;
		var $this = $( this );
		var lang = $this
			.find( 'span.lang-code a' )
			.text();

		if ( lang ) {
			lang = lang.replace( 'język ', '' );
			strippedLang = lang.replace( r_striplang, '$1' );
			gadget.langs[ lang ] =  {
				$header:      $this,
				strippedLang: strippedLang
			};
			
			if ( gadget.multilang[ strippedLang ] > -1 ) {
				gadget.multilang[ strippedLang ]++;
			}
		}
	} );

	$.each( gadget.lists, function ( list ) {
		var found = false, obj;

		$.each( gadget.langs, function ( lang, gadgetLang ) {
			if ( list.toLowerCase().indexOf( gadgetLang.strippedLang ) !== -1 ) {
				found = true;
				obj = {
					lang:    lang,
					$header: gadgetLang.$header,
					$link:   $( '<a>' )
						.attr( 'href', '/wiki/' + list )
						.text( list )
				};
				
				if ( gadget.multilang[ gadgetLang.strippedLang ] > 1 ) {
					if ( Array.isArray( gadget.lists[ list ] ) ) {
						gadget.lists[ list ].push( obj );
						gadget.list_names.push( list );
					} else {
						gadget.lists[ list ] = [ obj ];
					}
				} else {
					gadget.lists[ list ] = obj;
					gadget.list_names.push( list );
					return false;
				}
			}
		} );

		if ( !found ) {
			delete gadget.lists[ list ];
		}
	} );

	if ( gadget.list_names.length !== 0 ) {
		query_contents( function () {
			$.each( gadget.lists, function ( list, obj ) {
				if ( Array.isArray( obj ) ) {
					$.each( obj, function () {
						print_rankings( this );
					} );
				} else {
					print_rankings( obj );
				}
			} );
			
			if ( !scrolled && location.hash ) {
				location.hash = location.hash;
			}
		} );
	}
}

function print_rankings( obj ) {
	if ( obj.omit ) {
		return true;
	}
	
	// [[Specjalna:Niezmienny link/4318644#Typografia nazw stron (półpauza)]]
	obj.$link.text(
		obj.$link.text()
			.replace( ' - ', ' – ' )
			.replace( /(\d+)-(\d+)/, '$1–$2' )
	);
	
	obj.$header
		.css( 'margin-bottom', '5px' )
		.after( $( '<div>' )
			.addClass( 'freq-ranking' )
			.css( {
				'display':   'block',
				'font-size': '0.8em'
			} )
			.append( obj.$link )
		);
	
	obj.$link
		.before( obj.rank
			? 'Ranking: ' + obj.rank + '. pozycja na liście '
			: 'Ranking: hasło znajduje się na liście '
		);
}

$( function () {
	gadget.init();
} );