User:Shizhao/tools-redirect.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
var TR = {
msg: tools_redirect_msg,
tabselem: null,
tagselem: null,
variants: ['zh-cn', 'zh-hk', 'zh-sg', 'zh-tw'],
button: function( click ) {
var btn = zh$j( '<li id="ca-redirect">' + '<a title="' + TR.msg.btndesc +
'"><span>' + TR.msg.btntitle + '</span></a></li>' );
btn.click( click );
zh$j( 'li#ca-history' ).after( btn );
},
dialog: function() {
var dlg = zh$j( '<div class="dialog-redirect" title="' + TR.msg.dlgtitle + '"></div>' ).dialog( {
bgiframe: true, resizable: false, modal: true, width: 600 } );
TR.tabselem = zh$j( '<div class="tab-redirect"></div>' ).appendTo( dlg );
TR.tagselem = zh$j( '<ul/>' ).appendTo( TR.tabselem );
TR.addTabs();
TR.tabselem.tabs();
},
addTabs: function() {
for ( var kname in TR.tabs ) {
if ( typeof TR.tabs[kname] === 'function' ) {
TR.tabs[kname] = TR.tabs[kname]();
}
var tab = TR.tabs[kname];
TR.tagselem.append( tab.tag );
TR.tabselem.append( tab.cont );
}
// default tab, autoload when dialog initiate
TR.loadView();
},
createTab: function( tabname, tabtitle, callback ) {
var tag = zh$j( '<li><a href="#tab-' + tabname + '">' + tabtitle + '</a></li>' );
var cont = zh$j( '<div id="tab-' + tabname + '"/>' );
zh$j( 'a', tag ).click(
function() {
TR.tabselem.tabs( 'select', '#tab-' + tabname );
callback();
return false;
}
);
return { 'tag': tag, 'cont': cont, loaded: false };
},
tabs: {
view: function() {
return TR.createTab( 'view', TR.msg.tabviewtitle, TR.loadView );
},
create: function() {
return TR.createTab( 'create', TR.msg.tabcreatetitle, TR.loadCreate );
}
},
fix: function( pagenames ) {
var desc = zh$j( 'p.desc', TR.tabs.view.cont ).text( TR.msg.fixloading );
zh$j( 'p[class!=desc]', TR.tabs.view.cont ).remove();
TR.loading( TR.tabs.view.cont );
TR.bulkEdit( pagenames, TR.msg.fixtext.replace( '$1', wgPageName ),
TR.msg.fixsummary, function() {
TR.loaded( TR.tabs.view.cont );
TR.loadView( true );
}
);
},
create: function( pagenames ) {
var desc = zh$j( 'p.desc', TR.tabs.create.cont ).text( TR.msg.createloading );
zh$j( 'p[class!=desc]', TR.tabs.create.cont ).remove();
TR.loading( TR.tabs.create.cont );
TR.bulkEdit( pagenames, TR.msg.createtext.replace( '$1', wgPageName ),
TR.msg.createsummary, function() {
TR.loaded( TR.tabs.create.cont );
TR.tabs.view.loaded = false;
TR.loadCreate( true );
}
);
},
bulkEdit: function( titles, text, summary, callback ) {
titles = titles.join( '|' );
zh$j.ajax( TR.buildQuery(
{ action: 'query', prop: 'info', 'titles': titles, intoken: 'edit' },
null,
function( data ) {
var pages = data.query.pages;
var l = 0; var f = 0;
for( var pageid in pages ) {
l ++;
}
for( var pageid in pages ) {
page = pages[pageid];
zh$j.ajax( TR.buildQuery(
{ action: 'edit', title: page.title, token: page.edittoken,
'text': text, 'summary': summary }, null,
function() {
f ++;
if ( l == f ) {
callback();
}
}
) );
}
}
) );
},
reloadTabCont: function( tabname, callback ) {
var tab = TR.tabs[tabname];
tab.loaded = false;
TR.loadTabCont( tabname, callback );
},
loadTabCont: function( tabname, callback, reload ) {
var tab = TR.tabs[tabname];
if ( reload ) tab.loaded = false;
if ( !tab.loaded ) {
tab.cont.html( '' );
var desc = zh$j( '<p class="desc">' +
TR.msg.rediloading + '</p>' ).appendTo( tab.cont );
callback( function( success ) {
if ( success ) desc.text( TR.msg['tab' + tabname + 'desc'] );
else desc.text( TR.msg['tab' + tabname + 'notfound'] );
} );
tab.loaded = true;
}
},
loading: function( container ) {
if ( container.attr( 'tagName' ).toLowerCase() == 'span' ) {
container.addClass( 'loading' );
} else if ( zh$j( 'span.loading', container ).length == 0 ) {
zh$j( '<span class="loading"> </span>' ).appendTo( container );
}
},
loaded: function( container ) {
if ( container.attr( 'tagName' ).toLowerCase() == 'span' ) {
container.removeClass( 'loading' );
} else {
zh$j( 'span.loading', container ).remove();
}
},
selectAll: function( cont ) {
zh$j( 'input[type=checkbox][disabled!=true]', cont )
.prop('checked', true );
},
selectInverse: function( cont ) {
zh$j( 'input[type=checkbox][disabled!=true]', cont )
.each( function() {
var e = zh$j( this );
e.attr( 'checked', !e.attr( 'checked' ) );
} );
},
selectAction: function( cont, cb ) {
var pagenames = [];
zh$j( 'input[type=checkbox][checked=true]', cont )
.each( function() {
pagenames.push( zh$j( '.meta-title', zh$j( this ).parent() ).text() );
} );
if ( pagenames.length )
cb( pagenames );
},
clickAction: function( cont, cb ) {
var pagename = zh$j( '.meta-title', cont ).text();
cb( [pagename] );
},
buildLink: function( attr ) {
var a = zh$j( '<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 a;
},
buildMethods: function( metd ) {
var cont = zh$j( '<span/>' );
var l = metd ? metd.length : 0;
cont.append( l ? ' (' : '' );
for ( var i = 0; i < l; i ++ ) {
TR.buildLink( metd[i] ).appendTo( cont );
if ( i + 1 < l )
cont.append( '<span class="gap">|</span>' );
}
cont.append( l ? ')' : '' );
return cont;
},
buildSelection: function( main, metd, mt, dsab ) {
var cont = zh$j( '<span/>' );
var sele = zh$j( '<input type="checkbox"/>' ).appendTo( cont );
TR.buildLink( main).appendTo( cont );
TR.buildMethods( metd ).appendTo( cont );
cont.append( '<span class="meta-title">' + mt + '</span>' );
if ( dsab )
sele.prop('disabled', true );
return cont;
},
loadView: function( reload ) {
TR.loadTabCont( 'view', function( after ) {
TR.loadRedirect( wgPageName, TR.tabs.view.cont, 0, after );
}, reload );
},
loadCreate: function( reload ) {
TR.loadTabCont( 'create', function( after ) {
TR.findRedirect( wgPageName, after );
}, reload );
},
loadRedirect: function( pagename, container, deep, after ) {
TR.loading( container );
var top = deep ? zh$j( '<dl/>' ).appendTo( container ) : container;
zh$j.ajax( TR.buildQuery(
{ action: 'query', list: 'backlinks', bltitle: pagename, blfilterredir: 'redirects' },
null, function( data ) {
TR.loaded( container );
var l = data.query.backlinks.length;
var desc = zh$j( 'p.desc', TR.tabs.view.cont );
for ( var i = 0; i < l; i ++ ) {
var link = data.query.backlinks[i];
if ( link.title ) {
var ultitle = link.title.replace( ' ', '_' );
var baseuri = encodeURI( wgScriptPath + '/index.php?title=' + ultitle );
var entry = ( deep ? zh$j( '<dd/>' ) : zh$j( '<p/>' ) ).appendTo( top );
var methods = [ {href: baseuri + '&action=edit',
title: TR.msg.rediedit } ];
if ( deep ) {
methods.push(
{ href: '#',
title: TR.msg.tabviewfix,
click: function() {
TR.clickAction( entry, TR.fix );
return false; }
} );
}
TR.buildSelection( { href: baseuri + '&redirect=no', title: link.title },
methods, ultitle, !deep ).appendTo( entry );
TR.loadRedirect( link.title, entry, deep + 1 );
}
}
if ( after ) {
after( l );
} else if ( l && zh$j( 'a', desc ).length == 0 ) {
TR.buildMethods(
[ { href: '#',
title: TR.msg.selectall,
click: function() {
TR.selectAll( TR.tabs.view.cont );
return false; }
},
{ href: '#',
title: TR.msg.selectinverse,
click: function() {
TR.selectInverse( TR.tabs.view.cont );
return false; }
},
{ href: '#',
title: TR.msg.tabviewfix,
click: function() {
TR.selectAction( TR.tabs.view.cont, TR.fix );
return false; }
} ] ).appendTo( desc );
}
} ) );
},
findVariants: function( pagename, titles, callback ) {
var pc = 0;
var l = TR.variants.length;
for ( var i = 0; i < l; i ++ ) {
zh$j.ajax( TR.buildQuery( {action: 'parse', page: pagename, prop: 'displaytitle', variant: TR.variants[i] },
null, function( data ) {
titles.push( data.parse.displaytitle );
pc ++;
if ( pc == l ) {
callback( titles );
}
} ) );
}
},
findNotExists: function( titles, callback ) {
var titles = titles.join('|');
var alltitles = [];
var v = ['zh-hans', 'zh-hant'];
var t = 0;
var excludes = [ '用字模式' ];
for( var i = 0; i < 2; i ++ ) {
zh$j.ajax( TR.buildQuery( { action: 'parse', text: titles, prop: 'text', variant: v[i] },
null, function( data ) {
alltitles = alltitles.concat( zh$j( data.parse.text['*'] ).text().split( '|' ) );
t ++;
if ( t == 2 ) {
alltitles = alltitles.join( '|' );
zh$j.ajax( TR.buildQuery( {action: 'query', prop: 'info', 'titles': alltitles }, null,
function( data ) {
titles = [];
var pages = data.query.pages;
for ( var pageid in pages ) {
var title = pages[pageid].title;
if ( pageid < 0 && zh$j.inArray( title, excludes ) == -1 ) {
titles.push( title );
}
}
callback( titles );
}
) );
}
} ) );
}
},
findRedirect: function( pagename, after ) {
var container = TR.tabs.create.cont;
TR.loading( container );
var titles = Array();
zh$j( 'div#bodyContent p i' ).each( function() {
titles.push( zh$j( this ).text() ); } );
TR.findVariants( pagename, titles, function( tt ) {
TR.findNotExists( tt, function( t ) {
TR.loaded( container );
l = t.length;
for ( var i = 0; i < l; i ++ ) {
var title = t[i];
var ultitle = title.replace( ' ', '_' );
var baseuri = encodeURI( wgScriptPath + '/index.php?title=' + ultitle );
var entry = zh$j( '<p/>' ).appendTo( container );
TR.buildSelection(
{ href: baseuri + '&action=edit&redlink=1',
'title': title,
classname: 'new' },
[ { href: '#',
title: TR.msg.tabcreatetitle,
click: function() {
TR.clickAction( entry, TR.create );
return false; }
} ],
ultitle, false ).appendTo( entry );
}
var desc = zh$j( 'p.desc', container );
if ( after )
after( l );
if ( l ) {
TR.buildMethods(
[ { href: '#',
title: TR.msg.selectall,
click: function() {
TR.selectAll( container );
return false; }
},
{ href: '#',
title: TR.msg.selectinverse,
click: function() {
TR.selectInverse( container );
return false; }
},
{ href: '#',
title: TR.msg.tabcreatetitle,
click: function() {
TR.selectAction( container, TR.create );
return false; }
}
] ).appendTo( desc );
}
} );
} );
},
buildQuery: function( data, before, after ) {
var query = { url: wgScriptPath + '/api.php', dataType: 'json', type: 'POST' };
query.data = data;
query.data.format = 'json';
if ( before ) query.beforeSend = before;
if ( after ) query.success = after;
return query;
}
}
$( function() {
TR.button( TR.dialog );
});