MediaWiki:Gadget-TabbedLanguages.js
Giao diện
Chú ý: Sau khi lưu trang này, phải xóa bộ nhớ đệm (cache) của trình duyệt để những thay đổi hiện ra
- Firefox / Safari: Nhấn giữ phím Shift trong khi nhấn Tải lại (Reload), hoặc nhấn tổ hợp Ctrl-F5 hay Ctrl-R (⌘R trên Mac)
- Google Chrome: Nhấn tổ hợp Ctrl-Shift-R (⇧⌘R trên Mac)
- Internet Explorer / Edge: Nhấn giữ phím Ctrl trong khi nhấn Làm tươi (Refresh), hoặc nhấn tổ hợp Ctrl-F5
- Opera: Nhấn tổ hợp Ctrl-F5.
/**
* Bố trí lại các mục từ để phân chia theo ngôn ngữ.
*
* Phỏng theo [[:en:MediaWiki:Gadget-TabbedLanguages.js]].
*/
/**
* Thoát các ký tự đặc biệt trong ID để tương thích với bộ lựa chọn jQuery.
*/
function queryEscapeId(str) {
return str.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" );
}
/**
* Mã hóa chuỗi được cho vào để tương thích với jQuery UI Tabs.
*/
function anchorEncode(str) {
return encodeURIComponent(str.replace(/ /g, "_")).replace(/%/g, ".");
}
/**
* Giải mã chuỗi được cho vào để tương thích với phần neo của URL.
*/
function anchorDecode(str) {
return decodeURIComponent(str.replace(/\./g, "%")).replace(/ /g, "_");
}
var tabsOptions = {
beforeActivate: function (event, ui) {
location.assign("#" + anchorDecode(ui.newPanel.prop("id")));
}
};
/**
* Viết lại các liên kết trong mục từ được cho vào để chỉ đến một neo ngôn ngữ
* trong mục từ.
*/
function prefillAnchors(entry) {
if (entry.data("anchors-prefilled") === true) return;
entry.data("anchors-prefilled", true);
var id = anchorDecode(entry.prop("id"));
var articlePrefix = location.protocol + mw.config.get("wgServer") +
mw.config.get("wgArticlePath").replace("$1", "");
// TODO: Quốc tế hóa danh sách đề mục để cho những người dùng giao diện
// trong ngôn ngữ khác cũng được có tính năng này.
var linkListHeaderTexts = [
"Từ đồng âm", "Từ tương tự", "Đồng nghĩa", "Trái nghĩa", "Từ dẫn xuất",
"Từ liên hệ",
];
var linkListHeaders = entry.find(":header").filter(function (idx, header) {
return linkListHeaderTexts.indexOf($(header).find(".mw-headline").text()) !== -1;
});
linkListHeaders.nextUntil(":header", "ul, ol, dl, .NavFrame")
.find("a:not(.new)").prop("href", function (idx, old) {
if (old.indexOf(articlePrefix) !== 0 || old.indexOf("#") !== -1) return old;
return old + "#" + id;
});
}
/**
* Chuyển qua thẻ tại vị trí được cho vào.
*
* @returns đối tượng jQuery chứa mục từ của thẻ
*/
function showTabAt(idx) {
if (idx === -1) return null;
$("#entry-tabs").tabs("option", "active", idx);
var entry = $("#entry-tabs .lang-entry").eq(idx);
var id = anchorDecode(entry.prop("id"));
if (location.hash.substr(1) !== id) location.replace("#" + id);
prefillAnchors(entry);
return entry;
}
/**
* Chuyển qua thẻ ứng với ID được cho vào.
*
* @param {string} id mã ngôn ngữ ISO hoặc tên ngôn ngữ
* @returns đối tượng jQuery chứa mục từ của thẻ
*/
function showTabNamed(id) {
if (!id) return;
if (id.indexOf("%") !== -1) id = anchorDecode(id);
id = anchorEncode(id);
var entry = $("#" + queryEscapeId(id));
var tabIdx;
if ((tabIdx = entry.index(".lang-entry")) === -1) {
// Thử kiếm theo mã ngôn ngữ.
entry = $('.lang-entry[data-iso="' + id + '"]');
}
return showTabAt((tabIdx = entry.index(".lang-entry")));
}
/**
* Chuyển qua thẻ ứng với neo trong URL.
*/
function updateTabFromHash() {
showTabNamed(location.hash.substr(1));
}
/**
* Ghi nhớ thẻ trong cookie.
*/
function rememberRequest(iso) {
var tabIdx = $("#entry-tabs").tabs("option", "active");
var entry = $(".lang-entry").eq(tabIdx);
$.cookie("lastRequestedTabId", entry.data("iso"));
}
/**
* Tạm tắt các thẻ để phù hợp với giấy in.
*/
function beforePrint() {
$("#entry-tabs").tabs("destroy");
$("#tab-links").hide();
$(".mw-headline .lang").closest("h2").show();
$("#toc").show();
}
/**
* Khôi phục các thẻ sau khi in.
*/
function afterPrint() {
$("#toc").hide();
$(".mw-headline .lang").closest("h2").hide();
$("#tab-links").show();
$("#entry-tabs").tabs(tabsOptions);
}
/**
* Bố trí lại mục từ.
*/
function tabbify() {
if ($(".mw-headline .lang").length === 0) return;
// Ẩn mục lục.
$("#toc").hide();
// Cho mỗi đề mục ngôn ngữ…
var articleLinks = [];
$(".mw-headline .lang").each(function (headingIdx, langSpan) {
var heading = $(langSpan).closest("h2");
var headline = $(langSpan).parent();
var anchor = $(headline).prev();
// Bọc đề mục và cả phần vào một thẻ <article>. Chuyển id từ đầu đề tới
// <article>.
var id = anchor.prop("id");
anchor.prop("id", "");
var entry = $(mw.html.element("article", {
id: anchorEncode(id),
"class": "lang-entry",
"data-iso": $(langSpan).data("iso"),
}));
heading.nextUntil("h2").addBack().wrapAll(entry);
entry = $("#" + queryEscapeId(id));
var name = headline.text().replace(/^Tiếng |^Ngôn ngữ /, "");
// Thêm một liên kết đến <article> này vào mục lục sắp xây.
articleLinks.push(mw.html.element("li", {}, new mw.html.Raw(mw.html.element("a", {
href: "#" + id,
}, mw.html.escape(name)))));
heading.hide();
// Đưa những thể loại thuộc về ngôn ngữ này vào phần này.
var catItems = [];
$("#mw-normal-catlinks li").each(function (catIdx, catItem) {
var catName = $(catItem).text();
if (catName.toLowerCase().indexOf(headline.text().toLowerCase()) !== -1) {
catItems.push(catItem);
}
});
if (catItems.length) {
var catBox = $(mw.html.element("div", {
"class": "catlinks",
}));
entry.append(catBox);
catBox.append(mw.html.element("div", {
"class": "mw-normal-catlinks",
}));
catBox = catBox.find(".mw-normal-catlinks");
catBox.append($("#mw-normal-catlinks > a").text() + ":");
catBox.append($("<ul>").append(catItems));
}
});
$(".lang-entry").wrapAll(mw.html.element("div", {
id: "entry-tabs",
}));
// Xây dựng một mục lục mới chỉ có liên kết đến các <article>.
$("#entry-tabs").prepend(mw.html.element("ul", {
id: "tab-links",
}));
$("#tab-links").append(articleLinks);
// Xây dựng các thẻ.
// http://jqueryui.com/tabs/#vertical
$("#entry-tabs").tabs(tabsOptions)
.addClass("ui-tabs-vertical ui-helper-clearfix");
$("#tab-links").removeClass("ui-corner-all");
$("#tab-links li").removeClass("ui-corner-top").addClass("ui-corner-left");
$(window).on("hashchange", updateTabFromHash);
$("#tab-links li").on("click", function (evt) {
var id = $(this).attr("aria-controls");
var entry = $("#" + queryEscapeId(id));
var iso = entry.data("iso");
if (iso) rememberRequest(iso);
});
$(window).on("beforeprint", beforePrint).on("afterprint", afterPrint);
// Chọn thẻ đầu tiên.
if (location.hash.length) updateTabFromHash();
else showTabNamed($.cookie("lastRequestedTabId")) || showTabAt(0);
if (window.scrollY) window.scroll(0, 0);
}
if ((mw.config.get("wgNamespaceNumber") === 0 ||
mw.config.get("wgPageName") === "Wiktionary:Chỗ_thử") &&
["view", "submit"].indexOf(mw.config.get("wgAction")) !== -1 &&
$.cookie("disable-tabbed-languages") === null &&
mw.util.getParamValue("tabbedlanguages") !== "off" &&
mw.util.getParamValue("printable") !== "yes") {
mw.hook("wikipage.content").add(tabbify);
}