MediaWiki:Gadget-TabbedLanguages.js

Từ điển mở Wiktionary

Đây là một phiên bản cũ của trang này, do Mxn (thảo luận | đóng góp) sửa đổi vào lúc 04:43, ngày 24 tháng 12 năm 2017 (Thử). Địa chỉ URL hiện tại là một liên kết vĩnh viển đến phiên bản này của trang, có thể khác biệt rất nhiều so với phiên bản hiện tại.

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);
}