Thành viên:Ryder1992/skin.js
Chú ý: Sau khi lưu thay đổi trang, bạn phải xóa bộ nhớ đệm của trình duyệt để nhìn thấy các thay đổi. Google Chrome, Firefox, Internet Explorer và Safari: Giữ phím ⇧ Shift và nhấn nút Reload/Tải lại trên thanh công cụ của trình duyệt. Để biết chi tiết và hướng dẫn cho các trình duyệt khác, xem Trợ giúp:Xóa bộ nhớ đệm.
/*** Restorer ***/
// Documentation at [[User:BrandonXLF/Restorer]]
// By [[User:BrandonXLF]]
// Dịch sang tiếng Việt bởi [[User: AzusaNyan]]
$(function() {
if (mw.config.get('wgAction') != 'history') return;
window.restorerSummary = window.restorerSummary || 'Lùi sửa về phiên bản $ID bởi [[Special:Contributions/$USER|$USER]] sử dụng [[En:User:BrandonXLF/Restorer|Restorer]]';
function restore(user, revid) {
return new mw.Api().postWithEditToken({
action: 'edit',
pageid: mw.config.get('wgArticleId'),
undo: mw.config.get('wgCurRevisionId'),
undoafter: revid,
summary: window.restorerSummary.replace(/\$ID/g, revid).replace(/\$USER/g, user)
}).then(
function() {
mw.notify('Lùi sửa thành công.');
location.reload();
},
function(_, data) {
mw.notify(new mw.Api().getErrorMessage(data), {type: 'error'});
}
);
}
function addLink(item) {
var revid = item.getAttribute('data-mw-revid'),
user,
links,
el,
parent;
if (revid == mw.config.get('wgCurRevisionId')) return;
user = item.getElementsByClassName('mw-userlink')[0].textContent.replace('User:', '');
links = item.getElementsByClassName('mw-changeslist-links');
links = links[links.length - 1];
parent = document.createElement('span');
el = document.createElement('a');
el.addEventListener('click', function() {
el.className = 'restorer-loading';
restore(user, revid).always(function() {
el.className = '';
});
});
el.innerHTML = 'lùi tự động';
parent.appendChild(el);
links.appendChild(parent);
}
var parents = document.querySelectorAll('li[data-mw-revid]');
for (var i = 0; i < parents.length; i++) {
addLink(parents[i]);
}
mw.loader.addStyleTag(
'@keyframes restorer-loading {' +
'0%, 100% {content: " ⡁"} 16% {content: " ⡈"} 33% {content: " ⠔"} 50% {content: " ⠒"} 66% {content: " ⠢"} 83% {content: " ⢁"}}' +
'.restorer-loading::after {white-space: pre; content: ""; animation: restorer-loading 0.5s infinite}'
);
});
// SectionMover
// Originaly by User:Flooded with them hundreds
// Copied to [[User:DannyS712/SectionMover.js]] after FWTH retired, who took over as maintainer
$.when( mw.loader.using(['mediawiki.util','mediawiki.api']), $.ready).done( function () {
var validSections = {},
fromTos = {},
wikiText = '',
revStamp, startMoveButton, overlay;
if ( mw.config.get( 'wgNamespaceNumber' ) == -1 ) {
// is a special page
return;
}
$( 'head' ).append(
'<style>a.arxylink { font-weight:bold } .arxyhighlight { background-color:#aef9fc }</style>'
);
startMoveButton = mw.util.addPortletLink(
'p-cactions',
'#',
'Move section',
'pt-oeca',
'Enter/exit the process',
null,
null
);
overlay = $( document.createElement( 'button' ) );
$( startMoveButton ).click( function ( e ) {
$( '.arxylink' ).click();
$( '.arxy' ).toggle();
$( '#Movebutton' ).toggle();
} );
overlay.html( 'move' )
.attr( 'id', 'Movebutton' )
.css( 'position', 'fixed' )
.css( 'bottom', '20px' )
.css( 'height', '50px' )
.css( 'width', '100%' )
.css( 'font-size', '200%' );
$( document.body ).append( overlay );
overlay.toggle();
overlay.click( function ( e ) {
var numOfThreads, archiveTarget, sections, archiveThis, cutOffset,
revisedPage;
function cut( s, start, end ) {
return s.substr( 0, start ) + s.substring( end );
}
cutOffset = numOfThreads = 0;
revisedPage = wikiText;
sections = $( 'a.arxylink' ).map( function () {
return $( this ).attr( 'data-section' );
} );
if ( !( numOfThreads = sections.length ) ) {
return alert( 'No sections selected, aborting' );
}
archiveTarget = prompt(
'Moving' + numOfThreads + ' sections: where should we move them to?',
mw.config.get( 'wgPageName' )
);
if ( !archiveTarget || archiveTarget == mw.config.get( 'wgPageName' ) ) {
return alert( 'No target selected, aborting' );
}
sections.each( function ( i, n ) {
revisedPage = cut(
revisedPage,
fromTos[ n ][ 0 ] - cutOffset,
fromTos[ n ][ 1 ] - cutOffset
);
cutOffset += fromTos[ n ][ 1 ] - fromTos[ n ][ 0 ];
} );
archiveThis = sections.map( function () {
return wikiText.substring( fromTos[ this ][ 0 ], fromTos[ this ][ 1 ] );
} ).toArray().join( '' );
console.log( 'archive this:' + archiveThis );
console.log( 'revised page:' + revisedPage );
if ( 1 ) {
new mw.Api().postWithToken(
'csrf',
{
action: 'edit',
title: mw.config.get( 'wgPageName' ),
text: revisedPage,
summary: 'Chuyển phần mục đến [[' + archiveTarget + ']] sử dụng SectionMover',
basetimestamp: revStamp,
starttimestamp: revStamp
}
).done( function ( res1 ) {
alert( 'Successfully moved sections from page' );
console.log( res1 );
new mw.Api().postWithToken(
'csrf',
{
action: 'edit',
title: archiveTarget,
appendtext: '\n' + archiveThis,
summary: 'Chuyển phần mục từ [[' + mw.config.get( 'wgPageName' ) + ']] sử dụng SectionMover'
}
).done( function ( res2 ) {
alert( 'Successfully added sections to page' );
} ).fail( function ( res2 ) {
alert( 'failed to add sections to page. manual inspection needed.' );
} ).always( function ( res2 ) {
console.log( res2 );
window.location.reload();
} );
} ).fail( function ( res1 ) {
alert( 'failed to move sections from page. aborting process.' );
console.log( res1 );
window.location.reload();
} );
}
} );
new mw.Api().get( {
action: 'parse',
page: mw.config.get( 'wgPageName' )
} ).done( function ( dataShit ) {
var i;
new mw.Api().get( {
action: 'query',
pageids: mw.config.get( 'wgArticleId' ),
prop: [ 'revisions' ],
rvprop: [ 'content', 'timestamp' ]
} ).done( function ( shit ) {
var rv;
rv = shit.query.pages[ mw.config.get( 'wgArticleId' ) ].revisions[ 0 ];
wikiText = rv[ '*' ];
revStamp = rv.timestamp;
} );
$( dataShit.parse.sections )
.filter( function ( i, s ) { return s.index == parseInt( s.index ) } )
.each( function ( i, s ) { validSections[ s.index ] = s } );
for ( i in validSections ) {
i = parseInt( i );
fromTos[ i ] = [
validSections[ i ].byteoffset,
validSections.hasOwnProperty( i + 1 ) ? validSections[ i + 1 ].byteoffset : Infinity
];
}
$( '#mw-content-text' )
.find( ':header' )
.find( 'span.mw-headline' )
.each( function ( i, title ) {
var header, editSection, sectionNumber;
header = $( this ).parent();
editSection = header.find( '.mw-editsection' ); // 1st child
sectionNumber = header.find( '.mw-editsection a:first' );
if ( sectionNumber[ 0 ] ) {
sectionNumber = sectionNumber.attr( 'href' ).match( /§ion=(\d+)/ );
if ( sectionNumber ) {
sectionNumber = sectionNumber[ 1 ];
} else {
// eg <h2>not a real section</h2>
sectionNumber = undefined;
}
}
if ( validSections.hasOwnProperty( sectionNumber ) ) {
editSection[ 0 ].innerHTML += ' '
+ '<span class=arxy style=display:none>'
+ '<span class=mw-editsection-bracket>[</span>'
+ '<a data-section=' + sectionNumber + ' '
+ 'onclick=$(this).closest(\':header\').toggleClass(\'arxyhighlight\');$(this).toggleClass(\'arxylink\');>'
+ 'move section</a>'
+ '<span class=mw-editsection-bracket>]</span>'
+ '</span>';
}
} );
} );
} );
(function ($, mw, OO) {
function loadCSS(resources) {
resources.forEach(function (resource) {
mw.loader.load('/w/index.php?title=MediaWiki:Gadget-' + resource + '&action=raw&ctype=text/css', 'text/css');
});
}
function createBasketItems(resources) {
var basketItems = [];
resources.forEach(function (resource) {
basketItems.push({
url: '/w/index.php?title=MediaWiki:Gadget-' + resource + '&action=raw&ctype=text/javascript',
key: resource,
expire: 168 // Cache for 7 days
});
});
return basketItems;
}
function utils() {
// Don't zoom-in when focusing input
$('head').append('<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>');
// CSS for better Twinkle dialog on mobile
mw.loader.load('//vi.wikipedia.org/w/index.php?title=User:P.T.Đ/TwinkleMobile.css&action=raw&ctype=text/css', 'text/css');
}
function main() {
var twinkleDependencies = ['morebits.js', 'select2.min.js', 'Twinkle.js'],
twinkleModules = [
'twinkleconfig.js',
'twinkleprod.js',
'twinkleimage.js',
'twinklewarn.js',
'twinkleblock.js',
'twinklespeedy.js',
'friendlyshared.js',
'twinklediff.js',
'twinkleunlink.js',
'friendlytag.js',
'twinkledeprod.js',
'friendlywelcome.js',
'twinklexfd.js',
'twinklebatchdelete.js',
'twinklebatchundelete.js',
'twinklebatchprotect.js',
'twinkleprotect.js',
'twinklearv.js',
'friendlytalkback.js'
],
twinkleModulePortletLinks = [];
utils();
loadCSS(['morebits.css', 'select2.min.css']);
basket.require.apply(basket, createBasketItems(twinkleDependencies)).then(function () {
// Override Twinkle.addPortletLink function
Twinkle.addPortletLink = function (task, text, id, tooltip) {
twinkleModulePortletLinks.push({
task: task,
text: text,
id: id,
tooltip: tooltip
});
};
// Fix bug on Minerva (it doesn't have this)
mw.config.set('wgCategories', []);
// Fix bug on Special:MobileDiff pages
if (mw.config.get('wgCanonicalSpecialPageName') === 'MobileDiff') {
mw.config.set('wgNamespaceNumber', mw.Title.newFromText(mw.config.get('wgRelevantPageName')).getNamespaceId());
mw.config.set('wgArticleId', mw.config.get('wgRelevantArticleId'));
mw.config.set('wgPageName', mw.config.get('wgRelevantPageName'));
mw.config.set('wgCurRevisionId', mw.config.get('wgDiffNewId'));
Morebits.pageNameNorm = mw.config.get('wgRelevantPageName').replace(/_/g, ' ');
window.history.replaceState(null, null, '?diff=' + mw.config.get('wgDiffNewId'));
}
return basket.require.apply(basket, createBasketItems(twinkleModules));
}).then(function () {
setTimeout(function () {
// Create TwinkleMobile portlet link and dialog
function TwinkleMobileDialog(config) {
TwinkleMobileDialog.super.call(this, config);
}
OO.inheritClass(TwinkleMobileDialog, OO.ui.ProcessDialog);
TwinkleMobileDialog.static.name = 'TwinkleMobileDialog';
TwinkleMobileDialog.static.title = 'TwinkleMobile';
TwinkleMobileDialog.static.actions = [
{
action: 'save',
label: mw.message('ooui-popup-widget-close-button-aria-label').text(),
flags: ['primary', 'progressive']
}
];
TwinkleMobileDialog.prototype.initialize = function () {
var dialog = this;
TwinkleMobileDialog.super.prototype.initialize.apply(this, arguments);
this.panel = new OO.ui.PanelLayout({
padded: true,
expanded: false
});
this.content = new OO.ui.FieldsetLayout();
var fields = [];
twinkleModulePortletLinks.forEach(function (link) {
var button;
if (typeof link.task === 'string') {
button = new OO.ui.ButtonWidget({
href: link.task,
label: link.text,
id: link.id,
title: link.tooltip
});
}
if (typeof link.task === 'function') {
button = new OO.ui.ButtonWidget({
label: link.text,
id: link.id,
title: link.tooltip
});
button.on('click', function (e) {
link.task();
// Only close TwinkleMobile dialog when Twinkle dialog is opened
if ($('.morebits-dialog').length !== 0) {
dialog.close();
}
});
}
fields.push(new OO.ui.FieldLayout(button));
});
if (fields.length === 0) {
fields.push(new OO.ui.LabelWidget({
label: 'Nothing'
}));
}
this.content.addItems(fields);
this.panel.$element.append(this.content.$element);
this.$body.append(this.panel.$element);
};
TwinkleMobileDialog.prototype.getActionProcess = function (action) {
var dialog = this;
if (action) {
return new OO.ui.Process(function () {
dialog.close({
action: action
});
});
}
return TwinkleMobileDialog.super.prototype.getActionProcess.call(this, action);
};
TwinkleMobileDialog.prototype.getBodyHeight = function () {
return this.panel.$element.outerHeight(true);
};
var windowManager = new OO.ui.WindowManager();
$(document.body).append(windowManager.$element);
windowManager.addWindows([new TwinkleMobileDialog({
size: 'small'
})]);
var twmbLink = mw.util.addPortletLink('p-personal', '#', 'TwinkleMobile', 'twmb', 'TwinkleMobile');
$(twmbLink).click(function (e) {
windowManager.openWindow('TwinkleMobileDialog');
e.preventDefault();
});
}, 1000); // Execute this after all Twinkle modules is executed
}).catch(function (e) {
mw.log.error(e.message);
});
}
mw.loader.using([
'mediawiki.user', 'mediawiki.util', 'mediawiki.Title',
'mediawiki.api', 'mediawiki.language', 'jquery.ui',
'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows'
]).then(function () {
if (mw.config.get('wgUserGroups').includes('autoconfirmed')
&& mw.config.get('skin') === 'minerva') {
return new mw.Api().loadMessagesIfMissing([
'ooui-popup-widget-close-button-aria-label'
]);
} else {
throw new Error('TwinkleMobile only works with Minerva skin and autoconfirmed users');
}
}).then(function () {
return mw.loader.getScript('https://tools-static.wmflabs.org/cdnjs/ajax/libs/basket.js/0.5.2/basket.full.min.js');
}).then(main).catch(function (e) {
mw.log.error(e.message);
});
})(jQuery, mediaWiki, OO);