MediaWiki:Gadget-iw-links-aut.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.
/*
* na podstawie [https://pl.wikisource.org/wiki/MediaWiki:Gadget-iw-links.js]
* @author: [[:pl:User:Beau]]
* modification (slight) [[:pl:User:Zdzislaw]]
*/
/* Translatable strings */
mw.messages.set( {
'iw-whl-not-found': 'Brak.',
'iw-whl-error-unable-to-fetch': 'Nie udało się pobrać linkujących.',
'iw-whl-error-empty-title': 'Podaj nazwę strony.',
'iw-whl-fetching-links': 'Sprawdzanie linkujących...',
'iw-whl-button-label': 'pokazuje także linkujące z siostrzanych projektów',
'iw-whl-sister-project-links': 'Linkujące z projektu $1',
'iw-whl-current-project-links': 'Linkujące z bieżącego projektu',
'iw-whl-project-wikipedia': 'Wikipedia',
'iw-whl-project-wikisource': 'Wikiźródła',
'iw-whl-project-wiktionary': 'Wikisłownik',
'iw-whl-project-wikibooks': 'Wikibooks',
'iw-whl-project-wikinews': 'Wikinews',
'iw-whl-project-wikiquote': 'Wikicytaty',
'iw-whl-project-wikiversity': 'Wikiversity'
} );
window.whatLinksHereAutGadget = {
/** Version of the gadget (based on whatLinksHereGadget v7) */
version: 1,
/** List of families for Polish projects. Should obtain this list using sitematrix api call. */
families: [
{
name: 'wikipedia',
prefix: 'w',
title: mw.msg( 'iw-whl-project-wikipedia' )
},
{
name: 'wikisource',
prefix: 's',
title: mw.msg( 'iw-whl-project-wikisource' )
},
{
name: 'wiktionary',
prefix: 'wikt',
title: mw.msg( 'iw-whl-project-wiktionary' )
},
{
name: 'wikibooks',
prefix: 'b',
title: mw.msg( 'iw-whl-project-wikibooks' )
},
{
name: 'wikinews',
prefix: 'n',
title: mw.msg( 'iw-whl-project-wikinews' )
},
{
name: 'wikiquote',
prefix: 'q',
title: mw.msg( 'iw-whl-project-wikiquote' )
}/*,
{
name: 'wikiversity',
prefix: 'v',
title: mw.msg('iw-whl-project-wikiversity')
}*/
],
/** A family of the wiki the gadget is running on */
family: null,
/** A prefix of the wiki the gadget is running on */
prefix: null,
/** A url template for article links */
articleUrl: null,
/** A url template for api links */
apiUrl: null,
ajax: true,
/** An identifier of last sent request */
lastRequestId: 0,
/** An array requestId => requestCallback */
callbacks: {},
/** Sets up the gadget */
init: function() {
var that = this;
var server = mw.config.get( 'wgServer' );
var m = server.match( /^(?:https?:)?\/\/(.+)\.([^.]+)\.org$/ );
if ( m ) {
this.family = m[2];
this.articleUrl = "//" + m[1] + ".$1.org/wiki/$2";
this.apiUrl = "//" + m[1] + ".$1.org/w/api.php";
this.ajax = false;
}
if ( !this.family ) {
return;
}
for ( var i in this.families ) {
var f = this.families[i];
if ( f.name == this.family ) {
this.prefix = f.prefix;
break;
}
}
if ( !this.prefix ) {
return;
}
if ( mw.config.get( 'wgCanonicalSpecialPageName' ) == "Whatlinkshere" ) {
var $fieldset = jQuery( '#namespace' ).parents( 'fieldset' ).find( '.mw-htmlform-submit-buttons' );
if ( !$fieldset.length ) {
return;
}
var iconIwl = new OO.ui.IconWidget( {
icon: 'share',
} ),
labelIwl = new OO.ui.LabelWidget( {
label: mw.msg( 'iw-whl-button-label' )
} );
$fieldset.append(iconIwl.$element, labelIwl.$element );
this.show();
}
},
/** Executes the callback function for all families except the current one */
forEachFamily: function( callback ) {
for ( var i in this.families ) {
var f = this.families[i];
// Ignore current wiki
if ( f.name == this.family ) {
continue;
}
callback( f );
}
},
/** Shows the list of links */
show: function() {
var target = jQuery.trim( jQuery( '#mw-whatlinkshere-target' ).children('input').val() ).replace( / /g, '_' );
if ( target == '' ) {
alert( mw.msg( 'iw-whl-error-empty-title' ) );
return;
}
if ( !this.uiVisible ) {
this.uiVisible = true;
var $p = jQuery( 'fieldset' ).parent( 'form' ).parent().next('p');
$p.after( jQuery( '<h4/>' ).append( mw.msg( 'iw-whl-current-project-links' ) ) );
var $list = jQuery( '<div />' );
this.forEachFamily( function( family ) {
$list.append(
'<h4 id="header-links-' + family.name + '">' + mw.msg( 'iw-whl-sister-project-links', family.title ) + '</h2>',
'<div id="links-' + family.name + '" />'
);
} );
$p.after( $list );
}
var that = this;
this.forEachFamily( function( family ) {
var $header = jQuery( '#header-links-' + family.name );
var $body = jQuery( '#links-' + family.name );
$header.show();
$body.empty().append( mw.msg( 'iw-whl-fetching-links' ) ).show();
that.fetchLinks( target, family, function( list ) {
if ( list == null ) {
$body.empty().append( '<p>' + mw.msg( 'iw-whl-error-unable-to-fetch' ) + '</p>' );
return;
}
if ( !list.length ) {
$header.hide();
$body.hide();
return;
}
var $ul = jQuery( "<ul/>" );
var url = that.articleUrl.replace( /\$1/, family.name );
for ( var i in list ) {
var title = list[i];
var $link = jQuery( '<a/>' )
.append( document.createTextNode( title.replace( /_/g, ' ' ) ) )
.attr( 'href', url.replace( /\$2/, title ) );
$ul.append( jQuery( '<li/>' ).append( $link ) );
}
$body.empty().append( $ul );
} );
} );
},
/**
* Fetches namespace information for the wiki.
* @param callback A function to be called when information is ready.
*/
fetchNamespaces: function( callback ) {
if ( !this.namespaces ) {
this.namespaces = jQuery.Deferred();
var request = {
action: 'query',
meta: 'siteinfo',
siprop: 'namespaces|namespacealiases',
format: 'json'
};
var that = this;
jQuery.getJSON( mw.util.wikiScript( 'api' ), request, function( data ) {
if ( !data || !data.query || !data.query.namespaces || !data.query.namespacealiases ) {
that.namespaces.reject();
}
var info = data.query.namespaces;
for ( var i in info ) {
var namespace = info[i];
namespace.aliases = [];
if ( namespace['*'] != null ) {
namespace.aliases.push( namespace['*'] );
delete namespace['*'];
}
if ( namespace.canonical != null ) {
namespace.aliases.push( namespace.canonical );
delete namespace.canonical;
}
}
for ( var i in data.query.namespacealiases ) {
var entry = data.query.namespacealiases[i];
var namespace = info[entry.id];
namespace.aliases.push( entry['*'] );
}
that.namespaces.resolve( info );
} );
}
this.namespaces.then( callback );
},
/**
* Returns a string with the first character capitalized.
* @param str A string to be modified.
*/
ucfirst: function( str ) {
if ( !str.length ) {
return "";
}
return str.charAt( 0 ).toUpperCase() + str.substr( 1 );
},
/**
* Returns a string with the first character lowercased.
* @param str A string to be modified.
*/
lcfirst: function( str ) {
if ( !str.length ) {
return "";
}
return str.charAt( 0 ).toLowerCase() + str.substr( 1 );
},
/**
* Fetches links to a page.
* @param title A title of the page to which links refer to.
* @param family A family object representing the wiki to check.
* @param callback A function to be called when information is ready.
*/
fetchLinks: function( title, family, callback ) {
var that = this;
this.fetchNamespaces( function( namespaces ) {
// Split namespace from page name
var parsedTitle = that.parseTitle( title );
// A namespace information of checked page.
var namespace = namespaces[parsedTitle.ns];
// Generate names without a namespace
var names = {};
if ( namespace['case'] == 'first-letter' ) {
names[that.ucfirst( parsedTitle.name )] = 1;
names[that.lcfirst( parsedTitle.name )] = 1;
}
names[parsedTitle.name] = 1;
// Generate titles to check
var titles = {};
for ( var i in namespace.aliases ) {
var alias = namespace.aliases[i];
var prefix = ( alias == "" ) ? "" : alias + ':';
for ( var sufix in names ) {
titles[that.ucfirst( prefix ) + sufix] = 1;
titles[that.lcfirst( prefix ) + sufix] = 1;
}
}
titles[title] = 1;
var requestCallback;
var sendRequest;
var queue = [];
for ( var t in titles ) {
queue.push( t );
}
var results = {};
requestCallback = function( data ) {
if ( data && data.query && data.query.iwbacklinks ) {
for ( var i in data.query.iwbacklinks ) {
results[data.query.iwbacklinks[i].title] = 1;
}
}
if ( queue.length ) {
sendRequest();
} else {
var list = [];
for ( var r in results ) {
list.push( r );
}
callback( list.sort() );
}
};
var url = that.apiUrl.replace( /\$1/, family.name );
sendRequest = function() {
var request = {
action: 'query',
list: 'iwbacklinks',
format: 'json',
iwblprefix: that.prefix,
iwblprop: 'iwtitle',
iwbllimit: 'max',
iwbltitle: queue.shift()
};
if ( that.ajax ) {
jQuery.getJSON( url, request, requestCallback );
} else {
// Fallback for insecure users
that.lastRequestId++;
var id = that.lastRequestId;
request['requestid'] = id;
request['callback'] = 'whatLinksHereAutGadget.processResponse';
that.callbacks[id] = requestCallback;
url += '?' + jQuery.param( request );
mw.loader.load( url );
}
};
sendRequest();
} );
},
/**
* Parses title of a specifed page.
* @param title A title of the page.
*/
parseTitle: function( title ) {
var matches = title.match( /^([^:]+):(.+)$/ );
if ( matches ) {
var key = matches[1].toLowerCase();
var namespaces = mw.config.get( 'wgNamespaceIds' );
var result = namespaces[key];
if ( result != null ) {
return {
'ns': result,
'name': matches[2]
};
}
}
return {
'ns': 0,
'name': title
};
},
/**
* Processes responses from the api by calling a callback function
* assigned to the request.
*/
processResponse: function( data ) {
if ( !data || !data.requestid ) {
return;
}
var callback = this.callbacks[data.requestid];
delete this.callbacks[data.requestid];
callback( data );
}
};
jQuery( document ).ready( function() {
whatLinksHereAutGadget.init();
} );