MediaWiki:Gadget-searchsuggest-inflected.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.
/**
 * Opis: wyodrębnianie form fleksyjnych w liście propozycji wyników wyszukiwania (opensearch)
 * Adaptacja kodu [mediawiki/core.git]/resources/src/mediawiki/mediawiki.searchSuggest.js
 * Autor: Peter Bowman @ plwiktionary
 */

var api, resultRenderCache,
	CANON_LIMIT = 10,
	FORMS_LIMIT = 5,
	cache = {
		_suggestions: {}
	};

mw.messages.set( {
	'search-suggest-label-forms': ( mw.config.get( 'wgUserLanguage' ) === 'pl' )
		? 'formy fleksyjne'
		: 'inflected forms'
} );

function computeResultRenderCache( context ) {
	var $form, baseHref, linkParams;
	
	$form = context.config.$region.closest( 'form' );
	
	baseHref  = $form.attr( 'action' );
	baseHref += baseHref.indexOf( '?' ) > -1 ? '&' : '?';
	
	linkParams = {};
	
	$.each( $form.serializeArray(), function ( idx, obj ) {
		linkParams[ obj.name ] = obj.value;
	} );
	
	return {
		textParam:  context.data.$textbox.attr( 'name' ),
		linkParams: linkParams,
		baseHref:   baseHref
	};
}

function renderFunction( suggestion, context ) {
	var query = context.data.prevText;
	
	if (
		!cache[ query ] &&
		context.config.suggestions.indexOf( suggestion ) >= CANON_LIMIT
	) {
		this.remove();
		return;
	}
	
	if ( !resultRenderCache ) {
		resultRenderCache = computeResultRenderCache( context );
	}
	
	resultRenderCache.linkParams[ resultRenderCache.textParam ] = suggestion;
	
	this
		.text( suggestion )
		.wrap(
			$( '<a>' )
				.attr( {
					href:  resultRenderCache.baseHref + $.param( resultRenderCache.linkParams ),
					title: suggestion
				} )
				.addClass( 'mw-searchSuggest-link' )
		);
	
	if (
		cache[ query ] &&
		cache[ query ].hasForms &&
		context.config.suggestions.indexOf( suggestion ) === cache[ query ].delimiter
	) {
		this.before(
			$( '<div>' )
				.addClass( 'special-label suggestions-forms-label' )
				.text( mw.msg( 'search-suggest-label-forms' ) )
		);
	}
}

function checkCategories( categories ) {
	var i;
	
	if ( !categories || !categories.length ) {
		return true; // dla przekierowań
	}
	
	for ( i = 0; i < categories.length; i++ ) {
		var title = categories[ i ].title;
		
		if ( title.indexOf( ' (indeks)', title.length - 9 ) !== -1 ) {
			return true;
		}
	}
	
	return false;
}

function analyzeResults( query, data, response ) {
	var canon = [],
		forms = [],
		delimiter = 0;
	
	$.each( data, function () {
		var hasCanonical = cache._suggestions[ this ];
		
		if ( typeof hasCanonical === 'undefined' ) {
			return true;
		} else if (
			hasCanonical &&
			canon.length < CANON_LIMIT
		) {
			canon.push( this );
			delimiter++;
		} else if (
			!hasCanonical &&
			forms.length < FORMS_LIMIT
		) {
			forms.push( this );
		} else if (
			canon.length >= CANON_LIMIT &&
			forms.length >= FORMS_LIMIT
		) {
			return false;
		}
	} );
	
	cache[ query ] = {
		hasForms:  ( forms.length !== 0 ),
		delimiter: delimiter
	};
	
	response( [].concat( canon, forms ), {
		type: null,
		query: query
	} );
}

function getCategories( query, data, response ) {
	var titles = [];
	
	$.each( data, function () {
		if ( typeof cache._suggestions[ this ] === 'undefined' ) {
			titles.push( this );
		}
	} );
	
	if ( !titles.length ) {
		analyzeResults( query, data, response );
		return false;
	}
	
	return api.get( {
		formatversion: 2,
		prop: 'categories',
		clshow: '!hidden',
		cllimit: 'max',
		titles: titles
	} )
	.done( function ( res, jqXHR ) {
		if ( !res || !res.query ) {
			response( data, {
				type: jqXHR.getResponseHeader( 'X-OpenSearch-Type' ),
				query: query
			} );
			
			return;
		}
		
		$.each( res.query.pages, function () {
			cache._suggestions[ this.title ] = checkCategories( this.categories );
		} );
		
		analyzeResults( query, data, response );
	} );
}

$( function () {
	$( '#searchInput' ).suggestions( {
		fetch: function ( query, response ) {
			var node = this[ 0 ];

			api = api || new mw.Api();
			
			$.data( node, 'request', api.get( {
				formatversion: 2,
				action: 'opensearch',
				search: query,
				namespace: 0,
				suggest: true,
				limit: 50
			} ).done( function ( data, jqXHR ) {
				if ( query.indexOf( ':' ) !== -1 ) {
					response( data[ 1 ], {
						type: jqXHR.getResponseHeader( 'X-OpenSearch-Type' ),
						query: query
					} );
				} else {
					$.data( node, 'request2', getCategories( query, data[ 1 ], response ) );
				}
			} ) );
		},
		cancel: function () {
			var request2,
				node = this[ 0 ],
				request = $.data( node, 'request' );
			
			if ( request ) {
				request.abort();
				$.removeData( node, 'request' );
				
				request2 = $.data( node, 'request2' );
				
				if ( request2 ) {
					request2.abort();
					$.removeData( node, 'request2' );
				}
			}
		},
		result: {
			render: renderFunction,
			select: function () {
				return true;
			}
		}
	} );
} );