User:Irukaza/common.js:修订间差异

H萌娘,万物皆可H的百科全书!
跳到导航 跳到搜索
imported>=海豚=
无编辑摘要
imported>Irukaza
(清空页面)
 
(未显示2个用户的158个中间版本)
第1行: 第1行:
// <nowiki>
/* vim:set noexpandtab ft=javascript ts=4 sw=4: */


( function ( $ ) {
"use strict";
origPageName = mw.config.get('wgPageName'),
scriptPath = mw.config.get('wgScriptPath'),
nsNumber = mw.config.get('wgNamespaceNumber'),
isCategory = nsNumber === 14,
_findRedirectCallbacks = [],
_pageWithRedirectTextSuffix = {},
_redirectExcludes = {},
SUFFIX_APPEND = 0,
SUFFIX_REPLACE = 1,
SUFFIX_SETDEFAULT = 2,
_nsCanonPrefix = origPageName.split( ':' )[0] + ':',
_nsPrefixPattern = $.map(
mw.config.get( 'wgNamespaceIds' ), function( nsid, text ) {
return nsid === nsNumber ? text : null;
} ).join( '|' );
_nsPrefixPattern = new RegExp( '^(' + _nsPrefixPattern + '):', 'i' );
if ( nsNumber === 0 ) { // articles
_nsCanonPrefix = '';
_nsPrefixPattern = /^/;
}
function fixNamespace( title ) {
if ( nsNumber === 0 ) {
// do nothing if it's articles
return title;
}
else if ( _nsPrefixPattern.test( title ) ) {
// canonize the namespace
return title.replace( _nsPrefixPattern, _nsCanonPrefix );
}
else {
// don't have a namespace
return _nsCanonPrefix + title;
}
}
mw.toolsRedirect = {
SUFFIX_APPEND: SUFFIX_APPEND,
SUFFIX_REPLACE: SUFFIX_REPLACE,
SUFFIX_SETDEFAULT: SUFFIX_SETDEFAULT,
findRedirectCallback: function( callback ) {
/* Add new custom callback for finding new
* potential redirect titles.
*
* @param {function} callback( pagename, $content, titles ) -> title list
*/
if ( arguments.length === 1 ) {
_findRedirectCallbacks.push( callback );
}
else {
$.merge( _findRedirectCallbacks, arguments );
}
return this;
},
findRedirectBySelector: function( selector ) {
/* A shortcut to add CSS selectors as rule to find new potential
* redirect titles.
*
* @param {string} selector
*/
_findRedirectCallbacks.push( function( pagename, $content ) {
return $( selector ).map( function() {
var title = $( this ).text();
return title ? title : null;
} );
} );
return this;
},
setRedirectTextSuffix: function( title, suffix, flag ) {
var flag_set = false,
flag_append = false;
flag = flag || SUFFIX_APPEND; // default append
flag_set = flag === SUFFIX_REPLACE;
title = fixNamespace( title );
if ( title in _pageWithRedirectTextSuffix ) {
flag_append = flag === SUFFIX_APPEND;
}
else {
// if not exist, every flag can set
flag_set = true;
}
if ( flag_set ) {
_pageWithRedirectTextSuffix[title] = suffix;
}
else if ( flag_append ) {
_pageWithRedirectTextSuffix[title] =
_pageWithRedirectTextSuffix[title] + suffix;
}
}
};
_TR = {
msg: null,
tabselem: null,
tagselem: null,
variants: [
'zh-hans', 'zh-hant', 'zh-cn', 'zh-hk',
'zh-mo', 'zh-sg', 'zh-tw'],
init: function() {
if(!this.msg) return; // not setup correctly
var self = this,
btn = $(
'<li id="ca-redirect" class="collapsible"><span><a title="' + this.msg.btndesc + '">' +
this.msg.btntitle + '</a></span></li>' );
btn.click( function( evt ) {
evt.preventDefault();
self.dialog();
} );
$( 'li#ca-history' ).after( btn );
},
dialog: function() {
var dlg = $( '<div class="dialog-redirect" title="' + this.msg.dlgtitle + '">' )
.dialog( {
bgiframe: true, resizable: false, modal: true, width: 600 } );
this.tabselem = $( '<div class="tab-redirect">' ).appendTo( dlg );
this.tagselem = $( '<ul>' ).appendTo( this.tabselem );
this.addTabs();
this.tabselem.tabs();
},
addTabs: function() {
for ( var kname in this.tabs ) {
if ( this.tabs[kname] === null ) {
this.tabs[kname] = this['_initTab' + kname[0].charAt(0).toUpperCase() + kname.slice(1)]();
}
var tab = this.tabs[kname];
this.tagselem.append( tab.tag );
this.tabselem.append( tab.cont );
}
// default tab, autoload when dialog initiate
this.loadView();
},
createTab: function( tabname, tabtitle, onClick ) {
var self = this,
tag = $( '<li><a href="#tab-' + tabname + '">' + tabtitle + '</a></li>' ),
cont = $( '<div id="tab-' + tabname + '"/>' );
$( 'a', tag ).click( function() { onClick.call( self ); } );
return { 'tag': tag, 'cont': cont, loaded: false };
},
_initTabView: function() {
return this.createTab( 'view', this.msg.tabviewtitle, this.loadView );
},
_initTabCreate: function() {
return this.createTab( 'create', this.msg.tabcreatetitle, this.loadCreate );
},
tabs: {
view: null,
create: null
},
fix: function( pagenames ) {
var self = this,
desc = $( 'p.desc', this.tabs.view.cont ).text( this.msg.fixloading );
$( 'p[class!=desc]', this.tabs.view.cont ).remove();
this.loading( this.tabs.view.cont );
this
.bulkEdit(
pagenames,
this.msg.fixtext.replace( '$1', origPageName ),
this.msg.fixsummary
)
.done( function() {
// delay load before the asynchronous tasks on server finished
setTimeout( function() {
self.loaded( self.tabs.view.cont );
self.loadView( true );
}, 3000 );
} );
},
create: function( pagenames ) {
var self = this,
desc = $( 'p.desc', this.tabs.create.cont ).text( this.msg.createloading );
$( 'p[class!=desc]', this.tabs.create.cont ).remove();
this.loading( this.tabs.create.cont );
this
.bulkEdit(
pagenames,
this.msg.createtext.replace( '$1', origPageName ),
this.msg.createsummary.replace( '$1', origPageName )
)
.done( function() {
// delay load before the asynchronous tasks on server finished
setTimeout( function() {
self.loaded( self.tabs.create.cont );
self.tabs.view.loaded = false;
self.loadCreate( true );
}, 500 );
} );
},
addRedirectTextSuffix: function( title, text ) {
if ( title in _pageWithRedirectTextSuffix ) {
text = text + _pageWithRedirectTextSuffix[title];
}
return text;
},
bulkEdit: function( titles, text, summary ) {
var self = this;
titles = titles.filter(function(v, i, arr) { return arr.indexOf(v) === i });
titles = titles.join( '|' );
return $.ajax( this.buildQuery(
{ action: 'query', prop: 'info', titles: titles, intoken: 'edit' } ) )
.then( function( data ) {
var deferreds = [];
$.each( data.query.pages, function( idx, page ) {
deferreds.push( $.ajax( self.buildQuery( {
action: 'edit',
title: page.title,
token: page.edittoken,
text: self.addRedirectTextSuffix( page.title, text ),
summary: summary,
tags: 'ToolsRedirect'
} ) ) );
});
return $.when.apply( $, deferreds );
} );
},
loadTabCont: function( tabname, callback, reload ) {
var self = this,
tab = this.tabs[tabname];
if ( reload ) tab.loaded = false;
if ( !tab.loaded ) {
tab.cont.html( '' );
var desc = $( '<p class="desc"><span class="desc-text">' +
this.msg.rediloading + '</span></p>' ).appendTo( tab.cont ),
$text = desc.find( '> .desc-text' );
callback.apply( this )
.done( function() { $text.text( self.msg['tab' + tabname + 'desc'] ); } )
.fail( function() { $text.text( self.msg['tab' + tabname + 'notfound'] ); } )
.always( function() {
self.addMethods( desc, [ {
href: '#refresh',
title: self.msg.refresh,
click: function( evt ) {
evt.preventDefault();
self.loadTabCont( tabname, callback, true );
}
} ] );
} );
tab.loaded = true;
}
},
loading: function( container ) {
if ( container.prop( 'tagName' ).toLowerCase() == 'span' ) {
container.addClass( 'mw-ajax-loader' );
} else if ( $( 'span.mw-ajax-loader', container ).length === 0 ) {
$( '<span class="mw-ajax-loader"></span>' ).appendTo( container );
}
},
loaded: function( container ) {
if ( container.prop( 'tagName' ).toLowerCase() == 'span' ) {
container.removeClass( 'mw-ajax-loader' );
} else {
$( 'span.mw-ajax-loader', container ).remove();
}
},
selectAll: function( cont ) {
$( 'input[type=checkbox]:not(:disabled)', cont )
.prop( 'checked', true );
},
selectInverse: function( cont ) {
$( 'input[type=checkbox]:not(:disabled)', cont )
.each( function() {
var e = $( this );
e.prop( 'checked', !e.prop( 'checked' ) );
} );
},
selectAction: function( cont, cb ) {
var pagenames = [];
$( 'input[type=checkbox]:checked', cont )
.each( function() {
pagenames.push( $( this ).data( 'page-title' ) );
} );
if ( pagenames.length )
cb.call( this, pagenames );
},
clickAction: function( cont, cb ) {
var pagename = $( 'input[type="checkbox"]', cont ).data( 'page-title' );
cb.call( this, [pagename] );
},
buildLink: function( attr ) {
var a = $(
'<a href="' + attr.href + '" title="' + attr.title +
'" target="blank">' + attr.title + '</a>' );
if ( attr.click )
a.click( attr.click );
if ( attr.classname )
a.addClass( attr.classname );
return $( '<span class="tools-redirect_link">' ).append( a );
},
addMethods: function( $parent, methods ) {
var self = this,
$container = $parent.find( '> .tools-redirect_methods' );
function methodExist( method ) {
return $container.find(
'a[href=' + JSON.stringify( method.href ) + ']' ).length > 0;
}
if ( $container.length === 0 ) {
$container = $( '<span class="tools-redirect_methods">' ).appendTo( $parent );
}
$.each( methods, function( idx, method ) {
if ( !methodExist( method ) ) {
self.buildLink( method ).appendTo( $container );
}
} );
},
buildSelection: function( main, metd, mt, dsab ) {
var cont = $( '<span/>' ),
sele = $( '<input type="checkbox"/>' ).appendTo( cont );
this.buildLink( main ).appendTo( cont );
this.addMethods( cont, metd );
sele.data( 'page-title', mt );
if ( dsab ) {
sele.attr( 'disabled', true );
}
return cont;
},
loadView: function( reload ) {
var $container = this.tabs.view.cont;
this.loadTabCont( 'view', function() {
return this.loadRedirect( origPageName, $container, 0 );
}, reload );
},
loadCreate: function( reload ) {
this.loadTabCont( 'create', function() {
return this.findRedirect( origPageName );
}, reload );
},
loadRedirect: function( pagename, container, deep, loaded ) {
this.loading( container );
var self = this,
deferObj = $.Deferred(),
top = deep ? $( '<dl/>' ).appendTo( container ) : container;
if ( !loaded ) {
loaded = {};
loaded[pagename] = true;
}
function onClickFix( evt ) {
/* jshint validthis: true */
var entry = $( this ).parents( 'dd, p' ).first();
evt.preventDefault();
self.clickAction( entry, self.fix );
}
$.ajax( this.buildQuery(
{ action: 'query', prop: 'redirects', titles: pagename, rdlimit: 'max' } ) )
.done( function( data ) {
self.loaded( container );
var has_redirect = false,
desc = $( 'p.desc', self.tabs.view.cont ),
maximumRedirectDepth = mw.config.get('toolsRedirectMaximumRedirectDepth', 10);
$.each( data.query.pages, function( _, page ) {
if ( !( 'redirects' in page ) ) {
return;
}
$.each( page.redirects, function( _, rdpage ) {
var $container,
isCycleRedirect,
rdtitle = rdpage.title,
ultitle = rdtitle.replace( / /g, '_' ),
baseuri = scriptPath + '/index.php?title=' + encodeURIComponent( ultitle ),
entry = ( deep ? $( '<dd/>' ) : $( '<p/>' ) ).appendTo( top ),
methods = [ {href: baseuri + '&action=edit',
title: self.msg.rediedit } ];
isCycleRedirect = rdtitle in loaded;
loaded[rdtitle] = true;
if ( !isCycleRedirect && deep ) {
methods.push({
href: '#fix-redirect',
title: self.msg.tabviewfix,
click: onClickFix
} );
}
$container = self.buildSelection(
{ href: baseuri + '&redirect=no', title: rdtitle },
methods, ultitle, !deep ).appendTo( entry );
if ( isCycleRedirect ) {
$container.append(
'<span class="error">' + self.msg.errcycleredirect + '</span>');
}
else if ( deep < maximumRedirectDepth ) {
deferObj.done( function() {
return self.loadRedirect( rdtitle, entry, deep + 1, loaded );
} );
}
has_redirect = true;
} );
} );
if ( has_redirect && deep === 1 ) {
self.addMethods( desc, [ {
href: '#select-all',
title: self.msg.selectall,
click: function( evt ) {
evt.preventDefault();
self.selectAll( self.tabs.view.cont ); }
}, {
href: '#select-inverse',
title: self.msg.selectinverse,
click: function( evt ) {
evt.preventDefault();
self.selectInverse( self.tabs.view.cont ); }
}, {
href: '#fix-selected',
title: self.msg.tabviewfix,
click: function( evt ) {
evt.preventDefault();
self.selectAction( self.tabs.view.cont, self.fix ); }
} ] );
}
if ( has_redirect ) {
deferObj.resolveWith( self );
}
else {
deferObj.rejectWith( self );
}
} );
return deferObj.promise();
},
findVariants: function( pagename, titles ) {
var self = this,
suffixReg = /^.+?( \(.+?\))$/,
retTitles = [],
deferreds = [],
simpAndTrad = { 'zh-hans': true, 'zh-hant': true };
$.each( this.variants, function( _, variant ) {
var xhr = $.ajax( self.buildQuery( {
action: 'parse',
page: pagename,
prop: 'displaytitle',
variant: variant
} ) )
.then( function( data ) {
var title = fixNamespace( data.parse.displaytitle );
if ( variant in simpAndTrad ) {
mw.toolsRedirect.setRedirectTextSuffix(
title, '\n{{簡繁重定向}}', SUFFIX_APPEND );
}
return title;
} );
if ( isCategory ) {
xhr = xhr.then( function( origTitle ) {
return $.ajax( self.buildQuery( {
action: 'parse',
text: pagename,
prop: 'text',
variant: variant
} ) )
.then( function( data ) {
var tmpTitle = $( data.parse.text['*'] )
.text().replace( /(^\s*|\s*$)/g, '' );
// should not create redirect categories
// if the conversion is already in global table,
// or it will mess up a lot
_redirectExcludes[tmpTitle] = true;
return origTitle;
} );
} );
}
deferreds.push( xhr );
} );
return $.when.apply( $, deferreds )
.then( function() {
var suffixes = [];
$.each( arguments, function() {
var suffix,
title = this;
// find title suffix,
// for example " (济南市)" to "市中区 (济南市)"
suffix = suffixReg.exec( title );
if ( suffix && suffix.length === 2) {
suffix = suffix[1];
}
else {
suffix = '';
}
retTitles.push( title );
suffixes.push( suffix );
} );
// append suffixes
$.each( $.unique( suffixes ), function( _, suffix ) {
$.merge( retTitles, $.map( titles, function( title ) {
title = fixNamespace( title );
return suffixReg.test( title ) ? title : title + suffix;
} ) );
} );
return self.findNotExists( $.unique( retTitles ) );
} );
},
findNotExists: function( titles ) {
var self = this,
deferreds = [],
alltitles = [],
variants = ['zh-hans', 'zh-hant'],
excludes = [ '用字模式' ];
titles = titles.join( '|' );
$.each( [ 'zh-hans', 'zh-hant' ], function( idx, variant ) {
deferreds.push( $.ajax( self.buildQuery(
{ action: 'parse', text: titles, prop: 'text', variant: variant } ) ) );
} );
return $.when.apply( $, deferreds )
.then( function() {
$.each( arguments, function() {
alltitles = alltitles.concat(
$( this[0].parse.text['*'] )
.text().replace( /(^\s*|\s*$)/g, '' ).split( '|' )
);
} );
alltitles = alltitles.filter(function(v, i, arr) { return arr.indexOf(v) === i });
alltitles = alltitles.join( '|' );
return $.ajax( self.buildQuery( {
action: 'query',
prop: 'info',
titles: alltitles
} ) )
.then( function( data ) {
titles = [];
$.each( data.query.pages, function( pageid, page ) {
var title = page.title;
if ( pageid < 0 && excludes.indexOf( title ) === -1 ) {
if ( title in _redirectExcludes ) {
// exclude special titles
return;
}
titles.push( title );
if ( isCategory ) {
var target = origPageName.replace( /^Category:/, '' );
mw.toolsRedirect.setRedirectTextSuffix(
title,
'\n{{分类重定向|$1}}'.replace( '$1', target )
);
}
// only set default suffix
mw.toolsRedirect.setRedirectTextSuffix(
title, '\n{{別名重定向}}', SUFFIX_SETDEFAULT );
}
} );
return titles;
} );
} );
},
findRedirect: function( pagename ) {
var self = this,
titles = [],
frcDeferreds = [],
findBoldsAsTitles = mw.config.get('toolsRedirectFindBoldsAsTitles', false),
container = this.tabs.create.cont,
$content = $( '#mw-content-text' ),
deferObj = $.Deferred();
this.loading( container );
$.each( _findRedirectCallbacks, function( _, callback ) {
var ret = callback( pagename, $content, titles );
if ( typeof ret === 'string' ) {
titles.push( ret );
}
else if ( 'done' in ret ) {
// is Deferred
frcDeferreds.push( ret );
}
else {
$.merge( titles, ret );
}
} );
// remove all empty titles
titles = $.map( titles, function( title ) {
return title ? title : null;
} );
function onClickCreate( evt ) {
/* jshint validthis: true */
var entry = $( this ).parents( 'p:first' );
evt.preventDefault();
self.clickAction( entry, self.create );
}
// handles the deferred callbacks
$.when.apply( $, frcDeferreds )
.then( function() {
$.each( arguments, function( _, ret ) {
if (typeof ret == 'string' ) {
titles.push( ret );
}
else {
$.merge( titles, ret );
}
} );
return self.findVariants( pagename, titles );
} )
.done( function ( titles ) {
// build HTML
self.loaded( container );
$.each( titles, function( _, title ) {
var ultitle = title.replace( ' ', '_' ),
baseuri = scriptPath + '/index.php?title=' + encodeURIComponent( ultitle ),
entry = $( '<p/>' ).appendTo( container );
self.buildSelection(
{ href: baseuri + '&action=edit&redlink=1',
  title: title,
  classname: 'new' },
[ { href: '#create-redirect',
title: self.msg.tabcreatetitle,
click: onClickCreate
} ],
ultitle, false
).appendTo( entry );
} );
var desc = $( 'p.desc', container );
if ( titles.length > 0 ) {
self
.addMethods( desc, [ {
href: '#select-all',
title: self.msg.selectall,
click: function( evt ) {
evt.preventDefault();
self.selectAll( container );
}
}, {
href: '#select-inverse',
title: self.msg.selectinverse,
click: function( evt ) {
evt.preventDefault();
self.selectInverse( container );
}
}, {
href: '#create-selected',
title: self.msg.tabcreatetitle,
click: function( evt ) {
evt.preventDefault();
self.selectAction( container, self.create );
}
} ] );
deferObj.resolveWith( self, [ titles ] );
}
else {
deferObj.rejectWith( self, [ titles ] );
}
} );
return deferObj.promise();
},
buildQuery: function( data ) {
var query = { url: scriptPath + '/api.php', dataType: 'json', type: 'POST' };
query.data = data;
query.data.format = 'json';
return query;
}
};
if ( 'zh-hant|zh-hk|zh-tw|zh-mo'.indexOf( mw.config.get('wgUserVariant') ) > -1 ) {
msglang = 'zh-hant';
}
importScriptCallback( 'MediaWiki:Gadget-ToolsRedirect-msg-' + msglang + '.js', function() {
_TR.msg = window.tools_redirect_msg;
$( function() {
mw.loader.using( ['jquery.ui'], function () {
_TR.init();
} );
} );
} );
} )( jQuery );
// </nowiki>

2022年3月17日 (四) 18:22的最新版本