MediaWiki:Common.js
Giao diện
Đây là JavaScript ảnh hưởng đến toàn bộ người dùng. Các thay đổi lớn ở đây nên được đề xuất trước hết trong trang thảo luận hoặc Phòng thảo luận.
Xin lưu ý rằng những thay đổi ở đây sẽ có hiệu lực sau vài phút. Những lỗi vô tình ở đây có thể phá hỏng toàn bộ bách khoa toàn thư, vì vậy hãy đảm bảo rằng bạn biết chắc mình đang làm gì. Có thể thử nghiệm trước trong trang common.js hay một trang skin JS tùy chọn khác của cá nhân bạn. |
/**
* Giữ mã nguồn ở MediaWiki:Common.js một cách tối thiểu vì nó sẽ được tải
* vô điều kiện cho mọi thành viên ở tất cả các trang wiki. Nếu có thể hãy tạo
* công cụ (gadget) và để nó kích hoạt mặc định thay vì đặt ở đây (vì công cụ
* là các mô đun ResourceLoader tối ưu hóa tối đa với khả năng ghi các phần phụ
* thuộc).
*
* Vì Common.js không phải là công cụ, không có chỗ để khai báo phần phụ thuộc
* cho nó, do đó ta phải tải chậm với mw.loader.using khi cần và thực hiện toàn
* bộ trong lần gọi lại lần nữa. Trong phần lớn trường hợp các phần phụ thuộc
* này sẽ được tải trước khi tải mã ở đây.
*
* Nhiều nội dung trang này lấy từ các phiêu bản cập nhật năm 2019 của trang
* [[:en:MediaWiki:Common.js]] tại Wikipedia Tiếng Anh. Nội dung còn lại hầu hết
* là mã do các thành viên thêm vào dùng cho Wikipedia tiếng Việt hoặc của
* các phiên bản cũ tại Wikipedia Tiếng Anh đã bị xóa do bảo trì nhưng vì
* Wikipedia Tiếng Việt vẫn còn sử dụng nên được giữ lại và đặt bên dưới phần
* "MÃ DÀNH RIÊNG CHO WIKIPEDIA TIẾNG VIỆT". Xin hãy chú ý trước khi xóa
* hoặc thay đổi những mã này.
*/
/* global mw, $ */
/* jshint strict:false, browser:true */
mw.loader.using( ['mediawiki.util'] ).done( function () {
/* Bắt đầu gọi lại mw.loader.using */
/**
* Sửa bố cục Trang Chính
*
* Miêu tả: Thêm một liên kết bổ sung đến danh sách đầy đủ các phiên bản ngôn ngữ hiện có.
* Bảo trì: [[:en:User:AzaToth]], [[:en:User:R. Koot]], [[:en:User:Alex Smotrov]]
*/
if ( mw.config.get( 'wgPageName' ) === 'Trang_Chính' || mw.config.get( 'wgPageName' ) === 'Thảo_luận:Trang_Chính' ) {
$( function () {
mw.util.addPortletLink( 'p-lang', '//meta.wikimedia.org/w/index.php?title=List_of_Wikipedias&uselang=vi',
'Danh sách đầy đủ', 'interwiki-completelist', 'Danh sách đầy đủ các phiên bản Wikipedia' );
} );
}
/**
* Đổi hướng User:Name/skin.js và skin.css đến các trang giao diện hiện tại
* (trừ khi trang 'skin' thực sự tồn tại)
* @source: http://www.mediawiki.org/wiki/Snippets/Redirect_skin.js
* @rev: 2
*/
if ( mw.config.get( 'wgArticleId' ) === 0 && mw.config.get( 'wgNamespaceNumber' ) === 2 ) {
var titleParts = mw.config.get( 'wgPageName' ).split( '/' );
/* Make sure there was a part before and after the slash
and that the latter is 'skin.js' or 'skin.css' */
if ( titleParts.length == 2 ) {
var userSkinPage = titleParts.shift() + '/' + mw.config.get( 'skin' );
if ( titleParts.slice( -1 ) == 'skin.js' ) {
window.location.href = mw.util.getUrl( userSkinPage + '.js' );
} else if ( titleParts.slice( -1 ) == 'skin.css' ) {
window.location.href = mw.util.getUrl( userSkinPage + '.css' );
}
}
}
/**
* Map addPortletLink sang mw.util
* @deprecated: Dùng mw.util.addPortletLink thay thế.
*/
mw.log.deprecate( window, 'addPortletLink', mw.util.addPortletLink, 'Dùng mw.util.addPortletLink thay thế' );
/**
* Trích xuất một tham số URL từ URL hiện tại
* @deprecated: Dùng mw.util.getParamValue với lối thoát thích hợp
*/
mw.log.deprecate( window, 'getURLParamValue', mw.util.getParamValue, 'Dùng mw.util.getParamValue thay thế' );
/**
* Kiểm tra nếu một phần tử có một lớp nhất định
* @deprecated: Use $(element).hasClass() instead.
*/
mw.log.deprecate( window, 'hasClass', function ( element, className ) {
return $( element ).hasClass( className );
}, 'Dùng jQuery.hasClass() thay thế' );
/**
* @source www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL
* @rev 6
*/
var extraCSS = mw.util.getParamValue( 'withCSS' ),
extraJS = mw.util.getParamValue( 'withJS' );
if ( extraCSS ) {
if ( extraCSS.match( /^MediaWiki:[^&<>=%#]*\.css$/ ) ) {
mw.loader.load( '/w/index.php?title=' + extraCSS + '&action=raw&ctype=text/css', 'text/css' );
} else {
mw.notify( 'Chỉ cho phép các trang từ không gian tên MediaWiki', { title: 'Giá trị withCSS không hợp lệ' } );
}
}
if ( extraJS ) {
if ( extraJS.match( /^MediaWiki:[^&<>=%#]*\.js$/ ) ) {
mw.loader.load( '/w/index.php?title=' + extraJS + '&action=raw&ctype=text/javascript' );
} else {
mw.notify( 'Chỉ cho phép các trang từ không gian tên MediaWiki.', { title: 'Giá trị withJS không hợp lệ' } );
}
}
/**
* WikiMiniAtlas
*
* Miêu tả: WikiMiniAtlas là một cửa sổ bật lên và kéo bản đồ thế giới.
* Kịch bản này khiến tất cả các liên kết tọa độ của chúng tôi hiển thị nút bật lên WikiMiniAtlas.
* Bản thân đoạn mã nằm trên meta vì nó được sử dụng bởi nhiều dự án.
* Xem [[Meta:WikiMiniAtlas]] để biết thêm thông tin.
* Chú ý - nên sử dụng dịch vụ này để thay thế bằng mw:Help:Extension:Kartographer
*/
$( function () {
var require_wikiminiatlas = $( 'a.external.text[href*="geohack"]' ).length || $( 'div.kmldata' ).length;
if ( require_wikiminiatlas ) {
mw.loader.load( '//meta.wikimedia.org/w/index.php?title=MediaWiki:Wikiminiatlas.js&action=raw&ctype=text/javascript' );
}
} );
/**
* Bảng có thể thu gọn; được thực hiện với mw-collapsible
* Kiểu dáng cũng được đặt ra để tránh FOUC
*
* Cho phép các bảng được thu gọn, chỉ hiển thị tiêu đề. Xem [[:en:Help:Collapsing]].
* @version 3.0.0 (2018-05-20)
* @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js
* @author [[:en:User:R. Koot]]
* @author [[:en:User:Krinkle]]
* @author [[:en:User:TheDJ]]
* @deprecated Từ MediaWiki 1.20: Dùng class="mw-collapsible" thay vào đó
* được hỗ trợ trong lõi MediaWiki. Có thể bắt đầu từ MediaWiki 1.32
*/
function makeCollapsibleMwCollapsible( $content ) {
var $tables = $content
.find( 'table.collapsible:not(.mw-collapsible)' )
.addClass( 'mw-collapsible' );
$.each( $tables, function( index, table ) {
// mw.log.warn( 'This page is using the deprecated class collapsible. Please replace it with mw-collapsible.');
if( $( table ).hasClass( 'collapsed') ) {
$( table ).addClass( 'mw-collapsed' );
// mw.log.warn( 'This page is using the deprecated class collapsed. Please replace it with mw-collapsed.');
}
} );
if( $tables.length > 0 ) {
mw.loader.using( 'jquery.makeCollapsible' ).then( function() {
$tables.makeCollapsible();
} );
}
}
mw.hook( 'wikipage.content' ).add( makeCollapsibleMwCollapsible );
/**
* Thêm hỗ trợ cho mw-collapsible cho autocollapse, innercollapse và outercollapse
*
* Bảo trì: TheDJ
*/
function mwCollapsibleSetup( $collapsibleContent ) {
var $element,
$toggle,
autoCollapseThreshold = 2;
$.each( $collapsibleContent, function (index, element) {
$element = $( element );
if ( $element.hasClass( 'collapsible' ) ) {
$element.find('tr:first > th:first').prepend( $element.find('tr:first > * > .mw-collapsible-toggle'));
}
if ( $collapsibleContent.length >= autoCollapseThreshold && $element.hasClass( 'autocollapse' ) ) {
$element.data( 'mw-collapsible' ).collapse();
} else if ( $element.hasClass( 'innercollapse' ) ) {
if ( $element.parents( '.outercollapse' ).length > 0 ) {
$element.data( 'mw-collapsible' ).collapse();
}
}
// because of colored backgrounds, style the link in the text color
// to ensure accessible contrast
$toggle = $element.find( '.mw-collapsible-toggle' );
if ( $toggle.length ) {
// Make the toggle inherit text color
if( $toggle.parent()[0].style.color ) {
$toggle.find( 'a' ).css( 'color', 'inherit' );
}
}
} );
}
mw.hook( 'wikipage.collapsibleContent' ).add( mwCollapsibleSetup );
/**
* Thanh điều hướng động (thử nghiệm)
*
* Miêu tả: Xem [[:en:Wikipedia:NavFrame]].
* Bảo trì: ĐÃ KHÔNG ĐƯỢC BẢO TRÌ
*/
var collapseCaption = 'ẩn';
var expandCaption = 'hiện';
// thiết lập từ trong ngôn ngữ của chúng ta
var navigationBarHide = '[' + collapseCaption + ']';
var navigationBarShow = '[' + expandCaption + ']';
/**
* Hiển thị và ẩn nội dung và hình ảnh (nếu có) của các thanh điều hướng.
*
* @param {number} indexNavigationBar The index of navigation bar to be toggled
* @param {jQuery.Event} event Event object
*/
function toggleNavigationBar( indexNavigationBar, event ) {
var navToggle = document.getElementById( 'NavToggle' + indexNavigationBar );
var navFrame = document.getElementById( 'NavFrame' + indexNavigationBar );
var navChild;
if ( !navFrame || !navToggle ) {
return false;
}
// If shown now
if ( navToggle.firstChild.data === navigationBarHide ) {
for ( navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling ) {
if ( $( navChild ).hasClass( 'NavContent' ) ) {
navChild.style.display = 'none';
}
}
navToggle.firstChild.data = navigationBarShow;
// If hidden now
} else if ( navToggle.firstChild.data === navigationBarShow ) {
for ( navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling ) {
if ( $( navChild ).hasClass( 'NavContent' ) ) {
navChild.style.display = 'block';
}
}
navToggle.firstChild.data = navigationBarHide;
}
event.preventDefault();
}
/**
* Thêm nút hiển/ẩn vào thanh điều hướng.
*
* @param {jQuery} $content
*/
function createNavigationBarToggleButton( $content ) {
var i, j, navChild, navToggle, navToggleText, isCollapsed,
indexNavigationBar = 0;
// Iterate over all < div >-elements
var $divs = $content.find( 'div.NavFrame:not(.mw-collapsible)' );
$divs.each( function ( i, navFrame ) {
indexNavigationBar++;
navToggle = document.createElement( 'a' );
navToggle.className = 'NavToggle';
navToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar );
navToggle.setAttribute( 'href', '#' );
$( navToggle ).on( 'click', $.proxy( toggleNavigationBar, null, indexNavigationBar ) );
isCollapsed = $( navFrame ).hasClass( 'collapsed' );
/**
* Check if any children are already hidden. This loop is here for backwards compatibility:
* the old way of making NavFrames start out collapsed was to manually add style="display:none"
* to all the NavPic/NavContent elements. Since this was bad for accessibility (no way to make
* the content visible without JavaScript support), the new recommended way is to add the class
* "collapsed" to the NavFrame itself, just like with collapsible tables.
*/
for ( navChild = navFrame.firstChild; navChild !== null && !isCollapsed; navChild = navChild.nextSibling ) {
if ( $( navChild ).hasClass( 'NavPic' ) || $( navChild ).hasClass( 'NavContent' ) ) {
if ( navChild.style.display === 'none' ) {
isCollapsed = true;
}
}
}
if ( isCollapsed ) {
for ( navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling ) {
if ( $( navChild ).hasClass( 'NavPic' ) || $( navChild ).hasClass( 'NavContent' ) ) {
navChild.style.display = 'none';
}
}
}
navToggleText = document.createTextNode( isCollapsed ? navigationBarShow : navigationBarHide );
navToggle.appendChild( navToggleText );
// Tìm NavHead và đính kèm liên kết chuyển đổi (Phải phức tạp vì việc xử lý đầu tiên của Moz bị cấm)
for ( j = 0; j < navFrame.childNodes.length; j++ ) {
if ( $( navFrame.childNodes[j] ).hasClass( 'NavHead' ) ) {
navToggle.style.color = navFrame.childNodes[j].style.color;
navFrame.childNodes[j].appendChild( navToggle );
}
}
navFrame.setAttribute( 'id', 'NavFrame' + indexNavigationBar );
} );
}
mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton );
/**
* Thông báo sửa đổi ma thuật ****************************************************
*
* Mô tả: Thêm thông báo sửa đổi cho trang định hướng và TSNDS.
* Bảo trì: [[:en:User:RockMFR]]
*/
function addEditIntro( name ) {
$( '.mw-editsection, #ca-edit, #ca-ve-edit' ).find( 'a' ).each( function ( i, el ) {
el.href = $( this ).attr( 'href' ) + '&editintro=' + name;
} );
}
if ( mw.config.get( 'wgNamespaceNumber' ) === 0 ) {
$( function () {
if ( document.getElementById( 'disambigbox' ) ) {
addEditIntro( 'Bản_mẫu:Disambig_editintro' );
}
} );
$( function () {
var cats = mw.config.get('wgCategories');
if ( !cats ) {
return;
}
if ( $.inArray( 'Nhân vật còn sống', cats ) !== -1 || $.inArray( 'Nhân vật có thể còn sống', cats ) !== -1 ) {
addEditIntro( 'Bản_mẫu:BLP_editintro' );
}
} );
}
/* Các hành động cụ thể cho trang sửa đổi */
if ( mw.config.get( 'wgAction' ) === 'edit' || mw.config.get( 'wgAction' ) === 'submit' ) {
/**
* Sửa lỗi nhắc tóm tắt để hoàn tác
*
* Khắc phục chức năng hoàn tác kết hợp với "nhắc nhở tóm tắt không sửa đổi"
* thực tế phàn nàn về việc sửa đổi bị thiếu, nếu để nguyên bản tóm tắt sửa đổi.
* Thêm bởi [[:en:User:Deskana]], mã bởi [[:en:User:Tra]].
* Xem thêm [[phab:T10912]].
*/
$(function () {
if (document.location.search.indexOf('undo=') !== -1 && document.getElementsByName('wpAutoSummary')[0]) {
document.getElementsByName('wpAutoSummary')[0].value = '1';
}
});
}
/* MÃ DÀNH RIÊNG CHO WIKIPEDIA TIẾNG VIỆT */
/* Dùng để đảm bảo Wikipedia Tiếng Việt hoạt động đúng do một số hệ thống vẫn dùng mã giao diện cũ */
/* Kết các đoạn mã lưu bên ngoài */
if ( mw.config.get( 'wgAction' ) === 'edit' || mw.config.get( 'wgAction' ) === 'submit' || mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Upload' ) {
// Mã chỉ dành riêng cho trang sửa đổi
importScript("MediaWiki:Common.js/edit.js");
} else if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Watchlist' ) {
// Mã chỉ dành riêng cho danh sách theo dõi
importScript( 'MediaWiki:Common.js/watchlist.js' );
}
/* Sửa kết xuất phông chữ Unicode trên Windows XP */
if ( navigator.appVersion.search(/windows nt 5/i) !== -1 ) {
mw.util.addCSS( '.IPA { font-family: "Lucida Sans Unicode", "Arial Unicode MS"; } ' +
'.Unicode { font-family: "Arial Unicode MS", "Lucida Sans Unicode"; } ' );
}
/** Liên kết interwiki đến các bài chọn lọc ***************************************
*
* Chức năng: Chuyển dấu chấm trước các liên kết liên wiki của các bài chọn lọc
* thành dấu sao
* Người bảo trì: [[:en:User:R. Koot]]
*/
function LinkFA() {
if ( document.getElementById( "p-lang" ) ) {
var InterwikiLinks = document.getElementById( "p-lang" ).getElementsByTagName( "li" );
for ( var i = 0; i < InterwikiLinks.length; i++ ) {
var className = InterwikiLinks[i].className.match(/interwiki-[-\w]+/);
if ( document.getElementById( className + "-fa" ) && InterwikiLinks[i].className.indexOf( "badge-featuredarticle" ) === -1 ) {
InterwikiLinks[i].className += " FA";
InterwikiLinks[i].title = "Liên kết này dẫn đến bài chọn lọc.";
} else if ( document.getElementById( className + "-ga" ) && InterwikiLinks[i].className.indexOf( "badge-goodarticle" ) === -1 ) {
InterwikiLinks[i].className += " GA";
InterwikiLinks[i].title = "Liên kết này dẫn đến bài chất lượng tốt.";
}
}
}
}
mw.hook("wikipage.content").add(LinkFA);
/**
* Biểu tượng trên cùng góc phải.
*
* @source: //www.mediawiki.org/wiki/Snippets/Top_icons
* @rev: 2
*/
mw.hook("wikipage.content").add(function () {
$( '.right-uppermost' ).prependTo( '#firstHeading' ).show();
});
/** Viết lại tựa bài và bỏ dòng "Hạn chế kỹ thuật" khi hiển thị một số tựa bài ***************************************
Hàm dước bản mẫu {{tựa sai}} sử dụng
Hàm này tìm
<div id="RealTitleBanner">
<span id="RealTitle">titre</span>
</div>
Nếu có thành phần id="DisableRealTitle" thì tắt hàm
*/
function rewritePageH1() {
var realTitleBanner = document.getElementById('RealTitleBanner');
if (realTitleBanner && mw.config.get("wgNamespaceNumber") === 0) {
if (!document.getElementById('DisableRealTitle')) {
var realTitle = document.getElementById('RealTitle');
var h1 = document.getElementsByTagName('h1')[0];
if (realTitle && h1) {
var titleText = realTitle.innerHTML;
if (titleText === '') h1.style.display = 'none';
else {
h1.innerHTML = titleText;
document.title = document.title.replace(mw.config.get("wgPageName").replace(/_/g, " "),
realTitle.textContent);
}
realTitleBanner.style.display = 'none';
}
}
}
}
mw.hook("wikipage.content").add(rewritePageH1);
/**
* Gắn bảng giới thiệu vào đầu [[Trợ giúp:Chỗ thử]].
*/
mw.hook("wikipage.content").add(function () {
if (mw.config.get("wgPageName") != "Trợ_giúp:Chỗ_thử" ||
mw.config.get("wgAction") != "view" || $("#sandbox-intro").length) {
return;
}
var purgeLink = mw.html.element("a", {
href: mw.util.getUrl("Trợ_giúp:Chỗ_thử", {
action: "edit",
oldid: "15257082",
summary: "Tẩy trống chỗ thử",
minor: "yes"
})
}, "xóa định kỳ");
var editText = mw.html.element("b", {
"style": "white-space: nowrap;"
}, $("#ca-ve-edit").text());
var intro = $(mw.html.element("div", {
"class": "plainlinks toccolours",
id: "sandbox-intro"
}, new mw.html.Raw("Đây là trang bạn có thể thử thoải mái cách soạn bài " +
"trong Wikipedia. Nội dung ở đây sẽ bị " + purgeLink +
". Để bắt đầu sửa đổi trang này, hãy nhấn chuột vào thẻ " +
editText + " ở trên.")));
$("#mw-content-text").wrapInner("<div class='sandbox'></div>").prepend(intro);
});
/**
* Chọn chế độ sửa đổi theo cookie khi bấm liên kết đỏ.
*/
mw.hook("wikipage.content").add(function () {
if (mw.cookie.get("VEE", "") === "wikitext") {
$(".noarticletext, .searchresults h2").find("a").each(function (idx, elt) {
var uri = new mw.Uri(elt.href);
if ("veaction" in uri.query) {
uri.query.action = uri.query.veaction;
elt.href = uri.toString();
}
});
}
});
/**
* Cho phép hiện/ẩn phần tử tùy công cụ Biên dịch nội dung được kích hoạt.
*/
mw.hook("wikipage.content").add(function () {
if (parseInt(mw.user.options.get("cx")) === 1) {
$(document.documentElement).addClass("cx-available");
}
});
/* Cố định liên kết "Tải tập tin lên"
*/
mw.hook("wikipage.content").add(function() {
$("#t-upload a").attr("href", mw.util.getUrl("Wikipedia:Trình tải lên tập tin"));
});
// Kết quả từ Wikidata
// [[:Tập tin:Wdsearch script screenshot.png]]
if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Search' || ( mw.config.get( 'wgArticleId' ) === 0 && mw.config.get( 'wgCanonicalSpecialPageName' ) === false ) ) {
mw.loader.load("//en.wikipedia.org/w/index.php?title=MediaWiki:Wdsearch.js&action=raw&ctype=text/javascript");
}
/**
* Mã ẩn các liên kết đến công cụ Dịch nội dung
*/
function hideContentTranslation() {
if (
mw.config.get('wgUserGroups', []).every(function (userGroup) {
return ['sysop', 'eliminator', 'extendedconfirmed'].indexOf(userGroup) === -1;
})
) {
mw.util.addCSS('#cx-language { display: none; }');
mw.util.addCSS('.cx-campaign-translations { display: none; }');
mw.util.addCSS('.cx-contributions-translation { display: none; }');
if (mw.config.get('wgCanonicalSpecialPageName') === 'ContentTranslation') {
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach(function (node) {
node.remove();
});
}
});
});
observer.observe(document.body, {
childList: true,
});
alert('Không thể sử dụng công cụ này vì bạn không phải là Thành viên được xác nhận mở rộng.');
window.location.href = mw.util.getUrl('Wikipedia:Biên dịch');
}
}
}
mw.hook('wikipage.content').add(hideContentTranslation);
/* Hết mã dành cho Wikipedia Tiếng Việt */
/* Hết gọi mw.loader.using callback */
} );
// https://www.mediawiki.org/wiki/ResourceLoader/Migration_guide_(users)#Legacy_removals
// This can be removed once all clients have been updated for this search https://global-search.toolforge.org/?q=hookEvent®ex=1&namespaces=&title=
window.hookEvent = function ( name, fn ) {
$(window).on(name, fn);
};
/* KHÔNG THÊM MÃ DƯỚI DÒNG NÀY */