Khác biệt giữa bản sửa đổi của “MediaWiki:Gadget-start.js”
Giao diện
Nội dung được xóa Nội dung được thêm vào
Maintenance: mw:RL/MGU - Updated deprecated module name |
Sửa vấn đề hộp chọn ngôn ngữ không được cập nhật trong giao diện sau khi MediaWiki:Gadget-headers.js tải các đầu đề, trong khi các giá trị được cập nhật một cách lén lút; xem Thảo luận Thành viên:Mxn#Lỗi bản mẫu |
||
Dòng 410: | Dòng 410: | ||
"class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); |
"class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); |
||
input.attr("data-placeholder", "Chọn một " + step.keyName); |
input.attr("data-placeholder", "Chọn một " + step.keyName); |
||
input.on(" |
input.on("chosen:showing_dropdown", function (evt, context) { |
||
$(this).data("wiktvi-defaultValue", $(this).val()); |
$(this).data("wiktvi-defaultValue", $(this).val()); |
||
}); |
}); |
||
Dòng 419: | Dòng 419: | ||
inputs.find("option[value='" + oldValue + "']").prop('disabled', false); |
inputs.find("option[value='" + oldValue + "']").prop('disabled', false); |
||
inputs.find("option[value='" + newValue + "']").prop('disabled', true); |
inputs.find("option[value='" + newValue + "']").prop('disabled', true); |
||
inputs.trigger(" |
inputs.trigger("chosen:updated"); |
||
}); |
}); |
||
populateMenus(input, step.keys, getDisabledKeys(step)); |
populateMenus(input, step.keys, getDisabledKeys(step)); |
||
Dòng 655: | Dòng 655: | ||
var langMenu = $("#wiktvi-start-lang-field"); |
var langMenu = $("#wiktvi-start-lang-field"); |
||
populateMenus(langMenu, steps.lang.choices); |
populateMenus(langMenu, steps.lang.choices); |
||
langMenu.trigger(" |
langMenu.trigger("chosen:updated"); |
||
var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); |
var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); |
||
populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); |
populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); |
||
transMenus.trigger(" |
transMenus.trigger("chosen:updated"); |
||
}); |
}); |
||
} |
} |
Phiên bản lúc 22:26, ngày 3 tháng 1 năm 2021
$(function () {
var ns = mw.config.get("wgNamespaceNumber");
if (ns &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/sandbox$|\/thử$/))) {
return;
}
var action = mw.config.get("wgAction");
if (!(action === "edit" || action === "submit") ||
!$(".mw-newarticletext, .mw-newarticletextanon").length) {
return;
}
String.prototype.wiktviCapitalize = function () {
return this[0].toUpperCase() + this.substr(1);
};
var pageName = mw.config.get("wgPageName").replace(/_/g, " ");
if (ns) pageName = pageName.replace(/.*\//, "");
var userLang = mw.config.get("wgUserLanguage");
var chosenOptions = {
width: "20em",
disable_search_threshold: 20,
placeholder_text_single: "Chọn một",
placeholder_text_multiple: "Chọn nhiều",
no_results_text: "Không tìm thấy",
enable_split_word_search: false,
search_contains: true };
var langsByCode = {};
var steps = {
lang: {
id: "lang",
required: true,
name: "ngôn ngữ",
question_fmt: "“{{PAGENAME}}” là tiếng gì?",
choices: [
// Languages with 100 or more entries are loaded immediately.
// The rest come in through ext.gadget.headers.
["vie", "tiếng Việt"],
["eng", "tiếng Anh"],
["nld", "tiếng Hà Lan"],
["ido", "tiếng Ido"],
["lit", "tiếng Litva"],
["nor", "tiếng Na Uy"],
["rus", "tiếng Nga"],
["fra", "tiếng Pháp"],
["spa", "tiếng Tây Ban Nha"],
["zho", "tiếng Trung Quốc"] ],
output: function (values) {
return "{{-" + values.lang + "-}}\n";
} },
pron: {
id: "pron",
name: "cách phát âm",
question_fmt: "“{{PAGENAME}}” đọc như thế nào?",
visible: function (values) {
return false;
},
output: function (values) {
if (values.lang === "vie") {
return "{{-pron-}}\n{{vie-pron}}\n\n";
}
return "";
} },
pos: {
id: "pos",
required: true,
name: "từ loại",
question_fmt: "“{{PAGENAME}}” là loại từ nào?",
visible: function (values) {
return values.lang;
},
choices: [
["noun", "danh từ"],
["verb", "động từ"],
["adj", "tính từ"],
["adv", "phó từ"],
["prep", "giới từ"],
["pronoun", "đại từ"],
["interj", "thán từ"],
["conj", "liên từ"],
["prefix", "tiền tố"],
["suffix", "hậu tố"],
["place", "địa danh"],
["phrase", "thành ngữ"],
["proverb", "tục ngữ"] ],
output: function (values) {
return "{{-" + values.pos + "-}}\n";
} },
infl: {
id: "infl",
name: "biến cách",
multiple: true,
visible: function (values) {
return (values.lang === "eng" && ["noun", "adj", "adv"].indexOf(values.pos) >= 0) ||
(values.lang === "spa" && ["noun", "adj"].indexOf(values.pos) >= 0);
},
build: function (stepDiv, values) {
if (!values) return;
var forms;
// TODO: Spanish and other languages with inflection templates.
var forms = {
eng: {
noun: [
{name: "Số nhiều", "default": pageName + "s"}
],
adj: [
{name: "Cấp hơn", "default": "more " + pageName},
{name: "Cấp nhất", "default": "most " + pageName} ] },
spa: {
noun: [
{
name: "Giống",
"default": pageName.match(/(?:as?|ción|ciones)$/) ? "f" : "m",
choices: [
["m", "đực"],
["f", "cái"],
["mf", "tùy"] ] } ] } };
if (pageName.match(/(?:c|sh?|zh?)$/)) {
forms.eng.noun[0].firstSuggestion = pageName + "es";
}
else if (pageName.match(/y$/)) {
forms.eng.noun[0].firstSuggestion = pageName.substr(0, pageName.length - 1) + "ies";
}
forms.eng.adv = forms.eng.adj;
forms.spa.adj = forms.spa.noun;
forms = forms[values.lang];
if (forms) forms = forms[values.pos];
if (!forms) return;
var firstInput;
var stepId = this.id;
$("#wiktvi-start-" + stepId + " .wiktvi-start-custom").detach();
var list = $("<ul class='wiktvi-start-custom'></ul>");
var fieldId = "wiktvi-start-" + stepId + "-field";
$.each(forms, function (i, form) {
var item = $("<li></li>");
item.append($(mw.html.element("label", {
"for": "wiktvi-start-" + stepId + "-field" }, form.name + ":")));
var value = form.firstSuggestion || form["default"];
if (values && this.oldLang === values.lang &&
this.oldPos === values.pos && values.infl[i]) {
value = values.infl[i];
}
var input;
if (form.choices) {
input = $(mw.html.element("select", {
"class": "wiktvi-start-step-field" }));
$.each(form.choices, function (j, choice) {
input.append($(mw.html.element("option", {
value: choice[0],
selected: choice[0] === (form.firstSuggestion || form["default"]) },
choice[1].wiktviCapitalize())));
});
}
else {
input = $(mw.html.element("input", {
type: "text",
"class": "wiktvi-start-step-field wiktvi-start-narrow",
placeholder: form["default"],
value: value }));
}
if (!i) {
input.attr("id", fieldId);
firstInput = input;
}
item.append(input);
list.append(item);
});
stepDiv.append(list);
list.find("select").chosen(chosenOptions);
this["default"] = $.map(forms, function (form, i) {
return form["default"];
});
this.oldLang = values.lang;
this.oldPos = values.pos;
return firstInput;
},
output: function (values) {
var output = "'''" + pageName + "'''";
switch (values.lang) {
case "eng": {
// TODO: Fetch the English Wiktionary’s inflection template parameters.
if (["noun", "adj", "adv"].indexOf(values.pos) >= 0) {
output = "{{eng-" + values.pos;
var defaults = this["default"];
var modified = false;
$.each(values.infl, function (i, value) {
if (value && value !== defaults[i]) {
modified = true;
return false;
}
});
if (modified) {
$.each(values.infl, function (i, value) {
output += "|" + value;
});
}
return output + "}}\n";
}
break;
}
case "spa": {
if (values.infl[0] && ["noun", "adj"].indexOf(values.pos) >= 0) {
output += " {{" + values.infl[0] + "}}"
}
break;
}
}
return output + "\n";
} },
dfn: {
id: "dfn",
required: true,
name: "ngữ nghĩa",
multiple: true,
ordered: true,
visible: function (values) {
return values.lang && values.pos;
},
example: function (values) {
var examples = {
noun: "Bản vẽ hình thể của một khu vực.",
verb: "Đùa vui một cách tinh nghịch.",
adj: "Rất hoạt bát, nhẹ nhàng và mau chóng.",
adv: "Luôn luôn đều đặn, không gián đoạn.",
prep: "Thuộc vị trí, địa điểm nào.",
pronoun: "Ngôi thứ hai khi mình nói với anh ruột hay anh họ.",
interj: "Tiếng thốt lên để than thở hoặc ngạc nhiên.",
place: "Thủ đô Vương quốc Anh.",
proverb: "Thế hệ con phải chịu hậu quả của các hành động của thế hệ cha." };
var transExamples = {
noun: "Cá thật mập.",
verb: "Lè lưỡi.",
adj: "To lớn.",
adv: "Thường xuyên.",
prep: "Ở, tại.",
pronoun: "Bà ấy, cô ấy, chị ấy.",
interj: "Ôi trời ơi!",
prefix: "Trước về thời gian.",
suffix: "Chỉ đến môn học.",
place: "Luân Đôn.",
proverb: "Đời cha ăn mặn đời con khát nước." };
var pos = values.pos;
return values.lang === "vie" ? examples[pos] : transExamples[pos];
},
getOutput: function (values, callback) {
var text = $.map(values.dfn, function (dfn, i) {
dfn = $.trim(dfn);
if (!dfn) return undefined;
// Capitalize the first word.
if (dfn[0] !== dfn[0].toUpperCase()) {
dfn = dfn.wiktviCapitalize();
}
// Punctuate the definition.
if (!dfn.match(/[.…?!)\]]$/)) dfn += ".";
return "# " + dfn;
}).join("\n") + "\n\n";
var didTryToLoad = function () {
$.wiktviLinkify(text, callback);
};
mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad);
} },
syn: {
id: "syn",
name: "từ đồng nghĩa",
multiple: true,
narrow: true,
visible: function (values) {
return values.lang && values.pos;
},
output: function (values) {
if (!values.syn.join("").length) return "";
return "{{-syn-}}\n" + $.map(values.syn, function (syn, i) {
return syn ? "* [[" + syn + "]]" : undefined;
}).join("\n") + "\n\n";
} },
trans: {
id: "trans",
name: "bản dịch",
multiple: true,
narrow: true,
keyName: "ngôn ngữ",
visible: function (values) {
return values.lang === "vie" && values.pos;
},
disabledKeys: {
"mul": true,
"vie": true },
output: function (values) {
var rows = [];
$.each(values.trans, function (lang, words) {
if (words) rows.push([lang, words]);
});
if (!rows.length) return "";
rows.sort(function (a, b) {
var aLang = langsByCode[a[0]] || [];
var bLang = langsByCode[b[0]] || [];
return (aLang[2] || "").localeCompare(bLang[2] || "", "vi");
});
return "{{-trans-}}\n{{đầu}}\n" + $.map(rows, function (row, i) {
var words = row[1].replace(/(\s*[,;()]+\s*)/g, "]]$1[[");
return "* {{" + row[0] + "}}: [[" + words + "]]";
}).join("\n") + "\n{{cuối}}\n\n";
} } };
steps.trans.keys = steps.lang.choices;
var ordered_steps = [
steps.lang, steps.pron, steps.pos, steps.infl, steps.dfn, steps.syn,
steps.trans ];
var continueBtn;
function getValuesForStep(stepId) {
var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field");
var step = steps[stepId];
if (step.keys) {
var values = {};
fields.each(function (i, field) {
var key = $(field).prevAll(".wiktvi-start-step-keyfield").val();
if (key) values[key] = $(field).val();
});
return values;
}
else if (step.multiple) {
return fields.map(function (i) {
return $(this).val();
}).get();
}
return fields.val();
};
function getValues() {
var values = {};
$.each(steps, function (stepId) {
values[stepId] = getValuesForStep(stepId);
});
return values;
}
function getWikitext(callback) {
var values = getValues();
var entry = steps.lang.output(values);
entry += steps.pron.output(values);
entry += steps.pos.output(values);
entry += steps.infl.output(values);
steps.dfn.getOutput(values, function (output) {
entry += output;
entry += steps.syn.output(values);
entry += steps.trans.output(values);
// Tag the entry as having come from this tool.
entry += "{{mẫu}}\n"
// Add categories.
var langChoice = $.grep(steps.lang.choices, function (choice, i) {
return choice[0] === values.lang;
})[0];
var posChoice = $.grep(steps.pos.choices, function (choice, i) {
return choice[0] === values.pos;
})[0];
if (langChoice && posChoice) {
entry += "[[Thể loại:" + posChoice[1].wiktviCapitalize() + " " + langChoice[1] + "]]\n";
}
callback(entry);
});
}
function populateMenus(inputs, choices, disabledValues) {
if (!disabledValues) disabledValues = {};
var vals = inputs.map(function (i, input) {
return $(input).val();
});
inputs.empty();
inputs.append($("<option></option>"));
$.each(choices, function (j, choice) {
var option = $(mw.html.element("option", {
value: choice[0] }, choice[1].wiktviCapitalize()));
if (disabledValues[choice[0]]) option.prop("disabled", true);
inputs.append(option);
});
inputs.val(function (i) {
return vals[i];
});
}
/**
* Returns a bitmap containing the keys that should be disabled for a key
* menu in the given step because they are disabled or already taken by
* another key menu.
*/
function getDisabledKeys(step) {
var occupiedKeys = {};
$("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) {
occupiedKeys[$(this).val()] = true;
});
if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys);
return occupiedKeys;
}
function buildKeyInput(step) {
if (!step.keys) return undefined;
var input = $(mw.html.element("select", {
"class": "wiktvi-start-step-keyfield wiktvi-start-narrow" }));
input.attr("data-placeholder", "Chọn một " + step.keyName);
input.on("chosen:showing_dropdown", function (evt, context) {
$(this).data("wiktvi-defaultValue", $(this).val());
});
input.change(function (evt, context) {
var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this);
var oldValue = $(this).data("wiktvi-defaultValue");
var newValue = context.selected;
inputs.find("option[value='" + oldValue + "']").prop('disabled', false);
inputs.find("option[value='" + newValue + "']").prop('disabled', true);
inputs.trigger("chosen:updated");
});
populateMenus(input, step.keys, getDisabledKeys(step));
return input;
}
/**
* If the current text field has text and there are no more text fields after
* the current text field in the list, add another text field to the list.
*/
function refreshForTextField(currentInput, step) {
currentInput = $(currentInput);
var value = currentInput.val();
var item = currentInput.parent();
if (value && !item.next("li").length) {
var nextInput = $(mw.html.element("input", {
type: "text",
"class": currentInput.attr("class") }));
nextInput.on("input", function (evt) {
refreshForTextField(evt.target, step);
});
var nextKeyInput = buildKeyInput(step);
var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput);
item.parent().append(nextItem);
if (nextKeyInput) nextKeyInput.chosen(chosenOptions);
}
var canContinue = !continueBtn.prop("disabled");
if ((value && !canContinue) || (!value && canContinue)) {
refresh(step);
}
}
function prepareInput(input, step) {
if (!input) return;
if (step.required) input.prop('required', true);
input.change(step, refresh);
}
/**
* Shows and hides all the steps based on whether their prerequisites are met,
* and updates placeholders where applicable.
*/
function refresh(evt) {
var values = getValues();
var changedStep = evt && evt.data;
var didFocus = false;
var canContinue = true;
$.each(steps, function (stepId, step) {
if (typeof(step.visible) === "function" && !step.visible(values)) {
$("#wiktvi-start-" + stepId).slideUp();
// $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val("");
}
else {
var stepDiv = $("#wiktvi-start-" + stepId);
if (changedStep !== step && typeof(step.build) === "function") {
prepareInput(step.build(stepDiv, values), step);
}
var input = stepDiv.find(".wiktvi-start-step-field");
if (typeof(step.example) === "function") {
input.attr("placeholder", step.example(values) || "");
}
var didSlideDown;
if (!didFocus && stepDiv.css("display") === "none" && step.required) {
didSlideDown = function (evt) {
input.focus();
};
didFocus = true;
}
stepDiv.slideDown(didSlideDown);
}
if (step.required &&
(values[stepId] === "" ||
(step.multiple && values[stepId].join("") === ""))) {
canContinue = false;
}
});
continueBtn.button(canContinue ? "enable" : "disable");
}
function destroy() {
$("#wiktvi-start-form, .noafterwizard").slideUp(function () {
$(this).remove();
});
$(".noarticletext .nowizard, #editform").slideDown();
$("#ca-edit").removeClass("selected");
$("#ca-wiktvi-nowizard").addClass("selected");
}
function build() {
$(".nowizard, .nowizard .noafterwizard").hide();
var callToAction = $("#wiktvi-calltoaction");
var origCallToActionText = callToAction.text();
$(mw.util.addPortletLink("p-views", "#", "Tạo mã nguồn",
"ca-wiktvi-nowizard", "Tạo mục từ dùng hộp sửa đổi văn bản thuần",
undefined, "#ca-watch")).click(function (evt) {
evt.preventDefault();
callToAction.text(origCallToActionText);
destroy();
});
callToAction.text(origCallToActionText +
" Điền biểu mẫu ở dưới để viết mục từ mới.");
var startForm = $("<form id='wiktvi-start-form'></form>");
var spinner;
startForm.submit(function (evt) {
evt.preventDefault();
continueBtn.button("disable");
spinner.show();
getWikitext(function (wikitext) {
$("#wpTextbox1").val(wikitext);
$("html, body").animate({scrollTop: 0});
callToAction.text("Gần xong!");
destroy();
});
});
$.each(ordered_steps, function (i, step) {
var stepDiv = $(mw.html.element("div", {
"class": "wiktvi-start-step",
id: "wiktvi-start-" + step.id }));
var name = step.name.wiktviCapitalize();
stepDiv.append($(mw.html.element("h3", {
"class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", {
"for": "wiktvi-start-" + step.id + "-field" }, name)))));
if (step.question_fmt) {
var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName);
stepDiv.append($(mw.html.element("label", {
"class": "wiktvi-start-step-question",
"for": "wiktvi-start-" + step.id + "-field" }, question)));
}
var input;
// Menu
if (step.choices) {
input = $(mw.html.element("select", {
"class": "wiktvi-start-step-field",
id: "wiktvi-start-" + step.id + "-field" }));
input.attr("data-placeholder",
(step.multiple ? "Chọn các " : "Chọn một ") + step.name);
populateMenus(input, step.choices);
if (step.multiple) input.attr("multiple", true);
stepDiv.append(input);
}
// Custom
else if (typeof(step.build) === "function") {
input = step.build(stepDiv);
}
// Text field(s)
else {
input = $(mw.html.element("input", {
type: "text",
"class": "wiktvi-start-step-field",
id: "wiktvi-start-" + step.id + "-field" }));
if (step.narrow) input.addClass("wiktvi-start-narrow");
if (step.multiple) {
input.on("input", function (evt) {
refreshForTextField(evt.target, step);
});
var keyInput = buildKeyInput(step);
var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>")
.append($("<li></li>").append(keyInput).append(input));
stepDiv.append(list);
}
else stepDiv.append(input);
}
prepareInput(input, step);
stepDiv.hide();
startForm.append(stepDiv);
});
var footer = $("<div id='wiktvi-start-footer'></div>");
spinner = $(mw.html.element("img", {
id: "wiktvi-start-spinner",
src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif",
alt: "Đang tải…",
title: "Đang tải…" }));
footer.append(spinner.hide());
continueBtn = $(mw.html.element("button", {
id: "wiktvi-unhide-editform",
type: "submit" }, "Tiếp"));
footer.append(continueBtn);
startForm.append(footer);
$("#editform").hide().before(startForm);
startForm.find("select").chosen(chosenOptions);
continueBtn.button();
refresh();
$.wiktviHeaders.get(function (allHeaders) {
// Replace the initial language list with the complete list.
var headers = $.extend({}, allHeaders);
delete headers.vie;
if (headers.mul) headers.mul.name = "đa ngữ";
steps.lang.choices = steps.trans.keys = [];
$.each(headers, function (code, header) {
var match;
if (header.level === 1 && (match = header.name.match(/^tiếng (.+)| ngữ$/i))) {
var name = header.name;
if (!name.indexOf("Tiếng ")) name = "tiếng " + match[1];
var choice = [code, name, (match[1] || name)];
steps.lang.choices.push(choice);
langsByCode[code] = choice;
}
});
// Alphabetize the language list by sort key.
steps.lang.choices.sort(function (a, b) {
return a[2].localeCompare(b[2], userLang);
});
// Vietnamese goes first in language lists but is disabled in the
// translation section.
var choice = ["vie", "tiếng Việt", "Việt"];
steps.lang.choices.unshift(choice);
langsByCode.vie = choice;
var langMenu = $("#wiktvi-start-lang-field");
populateMenus(langMenu, steps.lang.choices);
langMenu.trigger("chosen:updated");
var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield");
populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans));
transMenus.trigger("chosen:updated");
});
}
mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api", "ext.gadget.headers"],
build);
});