Khác biệt giữa bản sửa đổi của “MediaWiki:Gadget-TabbedLanguages.js”
Nội dung được xóa Nội dung được thêm vào
n Thử |
nKhông có tóm lược sửa đổi |
||
(không hiển thị 2 phiên bản ở giữa của cùng người dùng) | |||
Dòng 4: | Dòng 4: | ||
* Phỏng theo [[:en:MediaWiki:Gadget-TabbedLanguages.js]]. |
* Phỏng theo [[:en:MediaWiki:Gadget-TabbedLanguages.js]]. |
||
*/ |
*/ |
||
mw.loader.using(["mediawiki.util", "oojs-ui-core", "oojs-ui-widgets"], function () { |
|||
/** |
/** |
||
Dòng 13: | Dòng 15: | ||
/** |
/** |
||
* Mã hóa chuỗi được cho vào |
* Mã hóa chuỗi được cho vào theo kiểu tên neo cũ của MediaWiki. |
||
*/ |
*/ |
||
function anchorEncode(str) { |
function anchorEncode(str) { |
||
Dòng 26: | Dòng 28: | ||
} |
} |
||
/** |
|||
var tabsOptions = { |
|||
* Bố trí chỉ mục. |
|||
beforeActivate: function (event, ui) { |
|||
*/ |
|||
location.assign("#" + anchorDecode(ui.newPanel.prop("id"))); |
|||
var index; |
|||
} |
|||
}; |
|||
/** |
/** |
||
* Viết lại các liên kết trong |
* Viết lại các liên kết trong thẻ được cho vào để chỉ đến một neo ngôn ngữ |
||
* trong mục từ. |
* trong mục từ. |
||
*/ |
*/ |
||
function prefillAnchors( |
function prefillAnchors(panel) { |
||
var entry = panel.$element.find(".lang-entry"); |
|||
if (entry.data("anchors-prefilled") === true) return; |
if (entry.data("anchors-prefilled") === true) return; |
||
entry.data("anchors-prefilled", true); |
entry.data("anchors-prefilled", true); |
||
var id = |
var id = entry.data("title"); |
||
var articlePrefix = location.protocol + mw.config.get("wgServer") + |
var articlePrefix = location.protocol + mw.config.get("wgServer") + |
||
mw.config.get("wgArticlePath").replace("$1", ""); |
mw.config.get("wgArticlePath").replace("$1", ""); |
||
Dòng 57: | Dòng 59: | ||
return old + "#" + id; |
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; |
|||
} |
} |
||
Dòng 84: | Dòng 71: | ||
if (id.indexOf("%") !== -1) id = anchorDecode(id); |
if (id.indexOf("%") !== -1) id = anchorDecode(id); |
||
var panel = index.getTabPanel("lang-entry-" + id); |
|||
id = anchorEncode(id); |
|||
if (!panel) { |
|||
var entry = $("#" + queryEscapeId(id)); |
|||
var entry = $("#" + queryEscapeId(id)).parents(".lang-entry"); |
|||
var tabIdx; |
|||
id = entry && entry.data("iso"); |
|||
panel = id && index.getTabPanel("lang-entry-" + id); |
|||
// Thử kiếm theo mã ngôn ngữ. |
|||
entry = $('.lang-entry[data-iso="' + id + '"]'); |
|||
} |
} |
||
if (!panel) return; |
|||
return showTabAt((tabIdx = entry.index(".lang-entry"))); |
|||
index.setTabPanel("lang-entry-" + id); |
|||
updateHashFromTab(); |
|||
prefillAnchors(panel); |
|||
return panel; |
|||
} |
} |
||
Dòng 99: | Dòng 90: | ||
function updateTabFromHash() { |
function updateTabFromHash() { |
||
showTabNamed(location.hash.substr(1)); |
showTabNamed(location.hash.substr(1)); |
||
} |
|||
/** |
|||
* Cập nhật tên neo trong URL theo thẻ hiện tại. |
|||
*/ |
|||
function updateHashFromTab() { |
|||
var panel = index.getCurrentTabPanel(); |
|||
var title = panel.$element.find(".lang-entry").data("title"); |
|||
if (title && location.hash.substr(1) !== title) { |
|||
location.replace("#" + title); |
|||
} |
|||
} |
} |
||
Dòng 105: | Dòng 107: | ||
*/ |
*/ |
||
function rememberRequest(iso) { |
function rememberRequest(iso) { |
||
$.cookie("lastRequestedTabId", iso); |
|||
var tabIdx = $("#entry-tabs").tabs("option", "active"); |
|||
var entry = $(".lang-entry").eq(tabIdx); |
|||
$.cookie("lastRequestedTabId", entry.data("iso")); |
|||
} |
} |
||
Dòng 114: | Dòng 114: | ||
*/ |
*/ |
||
function beforePrint() { |
function beforePrint() { |
||
$("#entry-tabs |
$("#entry-tabs .oo-ui-panelLayout.oo-ui-element-hidden") |
||
.addClass("oo-ui-element-unhidden-while-printing") |
|||
$("#tab-links").hide(); |
|||
.removeClass("oo-ui-element-hidden"); |
|||
$(".mw-headline .lang").closest("h2").show(); |
$(".mw-headline .lang").closest("h2").show(); |
||
$("#toc").show(); |
$("#toc").show(); |
||
Dòng 126: | Dòng 127: | ||
$("#toc").hide(); |
$("#toc").hide(); |
||
$(".mw-headline .lang").closest("h2").hide(); |
$(".mw-headline .lang").closest("h2").hide(); |
||
$("#entry-tabs .oo-ui-panelLayout.oo-ui-element-unhidden-while-printing") |
|||
$("#tab-links").show(); |
|||
.addClass("oo-ui-element-hidden") |
|||
$("#entry-tabs").tabs(tabsOptions); |
|||
.removeClass("oo-ui-element-unhidden-while-printing"); |
|||
} |
} |
||
Dòng 140: | Dòng 142: | ||
// Cho mỗi đề mục ngôn ngữ… |
// Cho mỗi đề mục ngôn ngữ… |
||
var |
var panels = []; |
||
$(".mw-headline .lang").each(function (headingIdx, langSpan) { |
$(".mw-headline .lang").each(function (headingIdx, langSpan) { |
||
var heading = $(langSpan).closest("h2"); |
var heading = $(langSpan).closest("h2"); |
||
Dòng 148: | Dòng 150: | ||
// Bọc đề mục và cả phần vào một thẻ <article>. Chuyển id từ đầu đề tới |
// Bọc đề mục và cả phần vào một thẻ <article>. Chuyển id từ đầu đề tới |
||
// <article>. |
// <article>. |
||
var id = |
var id = $(langSpan).data("iso"); |
||
anchor.prop("id", ""); |
|||
var entry = $(mw.html.element("article", { |
var entry = $(mw.html.element("article", { |
||
id: anchorEncode(id), |
|||
"class": "lang-entry", |
"class": "lang-entry", |
||
"data-iso": |
"data-iso": id, |
||
"data-title": anchorDecode(anchor.prop("id")) |
|||
})); |
})); |
||
heading.nextUntil("h2").addBack().wrapAll(entry); |
entry = heading.nextUntil("h2").addBack().wrapAll(entry).parent(); |
||
entry = $("#" + queryEscapeId(id)); |
|||
var name = headline.text().replace(/^Tiếng |^Ngôn ngữ /, ""); |
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(); |
heading.hide(); |
||
Dòng 187: | Dòng 182: | ||
catBox.append($("<ul>").append(catItems)); |
catBox.append($("<ul>").append(catItems)); |
||
} |
} |
||
panels.push({ |
|||
id: id, |
|||
label: name, |
|||
expanded: false, |
|||
framed: true, |
|||
scrollable: true, |
|||
$content: entry |
|||
}); |
|||
}); |
}); |
||
$(".lang-entry").wrapAll(mw.html.element("div", { |
$(".lang-entry").wrapAll(mw.html.element("div", { |
||
Dòng 192: | Dòng 196: | ||
})); |
})); |
||
// Xây dựng |
// Xây dựng các thẻ. |
||
index = new OO.ui.IndexLayout({ |
|||
$("#entry-tabs").prepend(mw.html.element("ul", { |
|||
expanded: false |
|||
id: "tab-links", |
|||
}); |
|||
index.addTabPanels(panels.map(function (panel) { |
|||
$("#tab-links").append(articleLinks); |
|||
return new OO.ui.TabPanelLayout("lang-entry-" + panel.id, panel); |
|||
})); |
|||
// Xây dựng các thẻ. |
|||
$("#entry-tabs").append(index.$element); |
|||
// 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"); |
|||
// Đồng bộ hóa phần neo của URL với thẻ hiện tại. |
|||
$(window).on("hashchange", updateTabFromHash); |
$(window).on("hashchange", updateTabFromHash); |
||
index.on("set", function (panel) { |
|||
rememberRequest(panel.$element.find(".lang-entry").data("iso")); |
|||
var id = $(this).attr("aria-controls"); |
|||
updateHashFromTab(); |
|||
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. |
// Chọn thẻ đầu tiên. |
||
if (location.hash.length) updateTabFromHash(); |
if (location.hash.length) updateTabFromHash(); |
||
else { |
|||
else showTabNamed($.cookie("lastRequestedTabId")) || showTabAt(0); |
|||
showTabNamed($.cookie("lastRequestedTabId")) || showTabNamed(panels[0].id); |
|||
if (window.scrollY) window.scroll(0, 0); |
|||
if (window.scrollY) window.scroll(0, 0); |
|||
} |
|||
// Hiển thị nội dung của mọi thẻ trước khi in. |
|||
$(window).on("beforeprint", beforePrint).on("afterprint", afterPrint); |
|||
} |
} |
||
Dòng 228: | Dòng 231: | ||
mw.hook("wikipage.content").add(tabbify); |
mw.hook("wikipage.content").add(tabbify); |
||
} |
} |
||
}); |
Phiên bản lúc 07:45, ngày 20 tháng 12 năm 2021
/**
* Bố trí lại các mục từ để phân chia theo ngôn ngữ.
*
* Phỏng theo [[:en:MediaWiki:Gadget-TabbedLanguages.js]].
*/
mw.loader.using(["mediawiki.util", "oojs-ui-core", "oojs-ui-widgets"], function () {
/**
* 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 theo kiểu tên neo cũ của MediaWiki.
*/
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, "_");
}
/**
* Bố trí chỉ mục.
*/
var index;
/**
* Viết lại các liên kết trong thẻ được cho vào để chỉ đến một neo ngôn ngữ
* trong mục từ.
*/
function prefillAnchors(panel) {
var entry = panel.$element.find(".lang-entry");
if (entry.data("anchors-prefilled") === true) return;
entry.data("anchors-prefilled", true);
var id = entry.data("title");
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ẻ ứ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);
var panel = index.getTabPanel("lang-entry-" + id);
if (!panel) {
var entry = $("#" + queryEscapeId(id)).parents(".lang-entry");
id = entry && entry.data("iso");
panel = id && index.getTabPanel("lang-entry-" + id);
}
if (!panel) return;
index.setTabPanel("lang-entry-" + id);
updateHashFromTab();
prefillAnchors(panel);
return panel;
}
/**
* Chuyển qua thẻ ứng với neo trong URL.
*/
function updateTabFromHash() {
showTabNamed(location.hash.substr(1));
}
/**
* Cập nhật tên neo trong URL theo thẻ hiện tại.
*/
function updateHashFromTab() {
var panel = index.getCurrentTabPanel();
var title = panel.$element.find(".lang-entry").data("title");
if (title && location.hash.substr(1) !== title) {
location.replace("#" + title);
}
}
/**
* Ghi nhớ thẻ trong cookie.
*/
function rememberRequest(iso) {
$.cookie("lastRequestedTabId", iso);
}
/**
* Tạm tắt các thẻ để phù hợp với giấy in.
*/
function beforePrint() {
$("#entry-tabs .oo-ui-panelLayout.oo-ui-element-hidden")
.addClass("oo-ui-element-unhidden-while-printing")
.removeClass("oo-ui-element-hidden");
$(".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();
$("#entry-tabs .oo-ui-panelLayout.oo-ui-element-unhidden-while-printing")
.addClass("oo-ui-element-hidden")
.removeClass("oo-ui-element-unhidden-while-printing");
}
/**
* 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 panels = [];
$(".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 = $(langSpan).data("iso");
var entry = $(mw.html.element("article", {
"class": "lang-entry",
"data-iso": id,
"data-title": anchorDecode(anchor.prop("id"))
}));
entry = heading.nextUntil("h2").addBack().wrapAll(entry).parent();
var name = headline.text().replace(/^Tiếng |^Ngôn ngữ /, "");
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));
}
panels.push({
id: id,
label: name,
expanded: false,
framed: true,
scrollable: true,
$content: entry
});
});
$(".lang-entry").wrapAll(mw.html.element("div", {
id: "entry-tabs",
}));
// Xây dựng các thẻ.
index = new OO.ui.IndexLayout({
expanded: false
});
index.addTabPanels(panels.map(function (panel) {
return new OO.ui.TabPanelLayout("lang-entry-" + panel.id, panel);
}));
$("#entry-tabs").append(index.$element);
// Đồng bộ hóa phần neo của URL với thẻ hiện tại.
$(window).on("hashchange", updateTabFromHash);
index.on("set", function (panel) {
rememberRequest(panel.$element.find(".lang-entry").data("iso"));
updateHashFromTab();
});
// Chọn thẻ đầu tiên.
if (location.hash.length) updateTabFromHash();
else {
showTabNamed($.cookie("lastRequestedTabId")) || showTabNamed(panels[0].id);
if (window.scrollY) window.scroll(0, 0);
}
// Hiển thị nội dung của mọi thẻ trước khi in.
$(window).on("beforeprint", beforePrint).on("afterprint", afterPrint);
}
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);
}
});