Khác biệt giữa bản sửa đổi của “MediaWiki:Gadget-TabbedLanguages.js”

Từ điển mở Wiktionary
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 để tương thích với jQuery UI Tabs.
* Mã hóa chuỗi được cho vào theo kiểu tên neo 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 mục từ được cho vào để chỉ đến một neo ngôn ngữ
* 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(entry) {
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 = anchorDecode(entry.prop("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;
if ((tabIdx = entry.index(".lang-entry")) === -1) {
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").tabs("destroy");
$("#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 articleLinks = [];
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 = anchor.prop("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": $(langSpan).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 một mục lục mới chỉ có liên kết đến các <article>.
// 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);
$("#tab-links li").on("click", function (evt) {
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);
}

});