MediaWiki:Gadget-VariantAllyDialog.js
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
/**!
* _________________________________________________________________________________
* | |
* | === WARNING: GLOBAL GADGET FILE === |
* | Changes to this page affect many users. |
* | Please discuss changes on the talk page, [[WP:VPT]] or GitHub before editing. |
* |_________________________________________________________________________________|
*
* Built from GitHub repository (https://github.com/wikimedia-gadgets/VariantAlly), you should not make
* changes directly here.
*
* See https://github.com/wikimedia-gadgets/VariantAlly/blob/main/CONTRIBUTING.md for build instructions.
*/
// <nowiki>
"use strict";
var _a;
const vue = require("vue");
const ext_gadget_VariantAlly = require("ext.gadget.VariantAlly");
const _hoisted_1$3 = ["width", "height"];
const _hoisted_2$2 = { key: 0 };
const _hoisted_3$2 = { key: 1 };
const _hoisted_4$2 = { key: 2 };
const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
__name: "VAIcon",
props: {
icon: {},
size: { default: 20 }
},
setup(__props) {
return (_ctx, _cache) => {
return vue.openBlock(), vue.createElementBlock("svg", {
class: "va-icon",
xmlns: "http://www.w3.org/2000/svg",
"xmlns:xlink": "http://www.w3.org/1999/xlink",
width: _ctx.size,
height: _ctx.size,
viewBox: "0 0 20 20",
"aria-hidden": "true"
}, [
_ctx.icon === "lang" ? (vue.openBlock(), vue.createElementBlock("g", _hoisted_2$2, _cache[0] || (_cache[0] = [
vue.createElementVNode("path", { d: "M20 18h-1.44a.61.61 0 01-.4-.12.81.81 0 01-.23-.31L17 15h-5l-1 2.54a.77.77 0 01-.22.3.59.59 0 01-.4.14H9l4.55-11.47h1.89zm-3.53-4.31L14.89 9.5a11.62 11.62 0 01-.39-1.24q-.09.37-.19.69l-.19.56-1.58 4.19zm-6.3-1.58a13.43 13.43 0 01-2.91-1.41 11.46 11.46 0 002.81-5.37H12V4H7.31a4 4 0 00-.2-.56C6.87 2.79 6.6 2 6.6 2l-1.47.5s.4.89.6 1.5H0v1.33h2.15A11.23 11.23 0 005 10.7a17.19 17.19 0 01-5 2.1q.56.82.87 1.38a23.28 23.28 0 005.22-2.51 15.64 15.64 0 003.56 1.77zM3.63 5.33h4.91a8.11 8.11 0 01-2.45 4.45 9.11 9.11 0 01-2.46-4.45z" }, null, -1)
]))) : _ctx.icon === "close" ? (vue.openBlock(), vue.createElementBlock("g", _hoisted_3$2, _cache[1] || (_cache[1] = [
vue.createElementVNode("path", { d: "m4.34 2.93 12.73 12.73-1.41 1.41L2.93 4.35z" }, null, -1),
vue.createElementVNode("path", { d: "M17.07 4.34 4.34 17.07l-1.41-1.41L15.66 2.93z" }, null, -1)
]))) : (vue.openBlock(), vue.createElementBlock("g", _hoisted_4$2, _cache[2] || (_cache[2] = [
vue.createElementVNode("path", { d: "M8.59 3.42 14.17 9H2v2h12.17l-5.58 5.59L10 18l8-8-8-8z" }, null, -1)
])))
], 8, _hoisted_1$3);
};
}
});
const _hoisted_1$2 = {
key: 1,
class: "va-button__text"
};
const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
__name: "VAButton",
props: {
icon: {},
indicator: {},
action: {},
weight: {}
},
emits: ["click"],
setup(__props) {
return (_ctx, _cache) => {
return vue.openBlock(), vue.createElementBlock("button", {
class: vue.normalizeClass(["va-button", {
"va-button--action-progressive": _ctx.action === "progressive",
"va-button--weight-quiet": _ctx.weight === "quiet"
}]),
onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("click"))
}, [
_ctx.icon !== void 0 ? (vue.openBlock(), vue.createBlock(_sfc_main$6, {
key: 0,
class: "va-button__icon",
icon: _ctx.icon
}, null, 8, ["icon"])) : vue.createCommentVNode("", true),
_ctx.$slots.default ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_1$2, [
vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
])) : vue.createCommentVNode("", true),
_ctx.indicator !== void 0 ? (vue.openBlock(), vue.createBlock(_sfc_main$6, {
key: 2,
class: "va-button__indicator",
icon: _ctx.indicator,
size: 16
}, null, 8, ["icon"])) : vue.createCommentVNode("", true)
], 2);
};
}
});
const _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props) {
target[key] = val;
}
return target;
};
const VAButton = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-e9c2c849"]]);
const _sfc_main$4 = {};
function _sfc_render(_ctx, _cache) {
return vue.openBlock(), vue.createBlock(vue.Transition, {
name: "va-fade",
mode: "out-in"
}, {
default: vue.withCtx(() => [
vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
]),
_: 3
});
}
const VAFadeTransition = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render], ["__scopeId", "data-v-c22b77e6"]]);
const variants = { "zh-cn": "中国大陆简体", "zh-sg": "新加坡简体", "zh-my": "马来西亚简体", "zh-hk": "香港繁體", "zh-mo": "澳門繁體", "zh-tw": "臺灣正體" };
const hans = { "space": "", "close": "关闭", "vp.header": "我们支持", "vp.header.alt": "记住此变体?", "vp.main": "选取内容的语言变体", "vp.main.alt": "以后都使用此变体呈现内容", "vp.main.ext": "保存您偏好的中文语言变体,以避免显示简繁混杂的内容,提供最佳的阅读体验。", "vp.button.ok": "确定", "vp.button.other": "其他" };
const hant = { "space": "", "close": "關閉", "vp.header": "我們支援", "vp.header.alt": "記住此變體?", "vp.main": "選取內容的語言變體", "vp.main.alt": "以後都使用此變體呈現內容", "vp.main.ext": "儲存您偏好的中文語言變體,以避免顯示簡繁混雜的內容,提供最佳的閱讀體驗。", "vp.button.ok": "確定", "vp.button.other": "其他" };
const messages = {
variants,
hans,
hant
};
const VALID_VARIANTS = [
"zh-cn",
"zh-sg",
"zh-my",
"zh-tw",
"zh-hk",
"zh-mo"
];
const wgUserVariant = vue.ref((_a = mw.config.get("wgUserVariant")) != null ? _a : "");
function isMobileDevice() {
return matchMedia("(hover: none), (pointer: coarse)").matches;
}
function getMountPoint() {
var _a2, _b;
switch (mw.config.get("skin")) {
case "vector-2022":
return (_a2 = document.getElementsByClassName("mw-page-container")[0]) != null ? _a2 : document.body;
case "timeless":
return (_b = document.getElementById("mw-content-block")) != null ? _b : document.body;
case "vector":
case "minerva":
case "monobook":
default:
return document.body;
}
}
const inferredVariant = vue.computed(() => {
if (VALID_VARIANTS.includes(wgUserVariant.value)) {
return wgUserVariant.value;
}
return null;
});
function shuffleVariant(last) {
const targetArray = [...VALID_VARIANTS].filter((i) => i !== last);
const randomIndex = Math.floor(Math.random() * targetArray.length);
return targetArray[randomIndex];
}
const i18nVariant = vue.computed(() => {
if (wgUserVariant.value === "zh") {
return Math.random() > 0.5 ? "hans" : "hant";
}
if (["zh-hant", "zh-tw", "zh-hk", "zh-mo"].includes(wgUserVariant.value)) {
return "hant";
}
return "hans";
});
function useI18n(key) {
var _a2;
const currentMsgsGroup = messages[i18nVariant.value];
return (_a2 = currentMsgsGroup[key]) != null ? _a2 : key;
}
let counter = 0;
function useUniqueId() {
return `va-${counter++}`;
}
const INTERVAL = 3 * 1e3;
function useShuffledVariant(isFreezed) {
const result = vue.ref(shuffleVariant());
let id;
vue.watch(isFreezed, (newValue) => {
var _a2;
if (!newValue) {
id = window.setInterval(() => {
result.value = shuffleVariant(result.value);
}, INTERVAL);
} else {
clearInterval(id);
result.value = (_a2 = inferredVariant.value) != null ? _a2 : shuffleVariant();
}
}, { immediate: true });
return result;
}
function useModelWrapper(props, emit, name = "modelValue") {
return vue.computed({
get() {
return props[name];
},
set(value) {
emit(`update:${name}`, value);
}
});
}
function useDefault(defaultValue) {
const realRef = vue.shallowRef(typeof defaultValue === "function" ? defaultValue() : defaultValue.value);
vue.watch(defaultValue, (newValue) => {
realRef.value = newValue;
}, { deep: true });
return vue.computed({
get() {
return realRef.value;
},
set(newValue) {
realRef.value = newValue;
}
});
}
const _hoisted_1$1 = ["lang", "aria-labelledby", "aria-describedby"];
const _hoisted_2$1 = ["id"];
const _hoisted_3$1 = ["lang"];
const _hoisted_4$1 = ["id"];
const _hoisted_5$1 = { class: "va-variant-prompt__options" };
const _hoisted_6$1 = { class: "va-variant-prompt__footer" };
const _hoisted_7$1 = { class: "va-para va-para--subtle" };
const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
__name: "VAVariantPrompt",
props: {
open: { type: Boolean },
disabled: { type: Boolean, default: false },
autoClose: { type: Boolean, default: false }
},
emits: ["update:open", "update:disabled", "select", "optout"],
setup(__props, { emit: __emit }) {
const props = __props;
const emit = __emit;
const prompt = vue.ref(null);
const titleId = useUniqueId();
const descId = useUniqueId();
const isOpen = useModelWrapper(props, emit, "open");
const isDisabled = useModelWrapper(props, emit, "disabled");
const isVariantNarrowed = useDefault(() => inferredVariant.value !== null);
const shuffledVariant = useShuffledVariant(isVariantNarrowed);
function optOutAndClose() {
emit("optout");
isOpen.value = false;
}
function select(variant) {
isDisabled.value = true;
emit("select", variant);
}
vue.watch(prompt, () => {
const element = prompt.value;
if (element !== null) {
element.addEventListener("mouseleave", (ev) => {
if (ev.buttons === 0 && props.autoClose && !props.disabled) {
isOpen.value = false;
}
});
}
});
return (_ctx, _cache) => {
return vue.openBlock(), vue.createBlock(vue.Transition, {
name: "va-variant-prompt",
appear: ""
}, {
default: vue.withCtx(() => [
_ctx.open ? (vue.openBlock(), vue.createElementBlock("div", {
key: 0,
ref_key: "prompt",
ref: prompt,
lang: `zh-${vue.unref(i18nVariant)}`,
class: "va-variant-prompt",
role: "dialog",
"aria-modal": "false",
"aria-labelledby": vue.unref(titleId),
"aria-describedby": vue.unref(descId)
}, [
vue.createVNode(VAButton, {
class: "va-variant-prompt__close",
weight: "quiet",
icon: "close",
title: vue.unref(useI18n)("close"),
"aria-label": vue.unref(useI18n)("close"),
disabled: _ctx.disabled,
onClick: optOutAndClose
}, null, 8, ["title", "aria-label", "disabled"]),
vue.createElementVNode("h2", {
id: vue.unref(titleId),
class: "va-variant-prompt__title va-title"
}, [
vue.createTextVNode(vue.toDisplayString(vue.unref(useI18n)(vue.unref(isVariantNarrowed) ? "vp.header.alt" : "vp.header")), 1),
_cache[1] || (_cache[1] = vue.createElementVNode("br", null, null, -1)),
vue.createVNode(VAFadeTransition, null, {
default: vue.withCtx(() => [
!vue.unref(isVariantNarrowed) ? (vue.openBlock(), vue.createElementBlock("span", {
key: vue.unref(shuffledVariant),
lang: `zh-${vue.unref(shuffledVariant)}`,
class: "va-variant-prompt__title__variant"
}, vue.toDisplayString(vue.unref(messages).variants[vue.unref(shuffledVariant)]), 9, _hoisted_3$1)) : vue.createCommentVNode("", true)
]),
_: 1
})
], 8, _hoisted_2$1),
vue.createElementVNode("p", {
id: vue.unref(descId),
class: "va-variant-prompt__desc va-para"
}, vue.toDisplayString(vue.unref(useI18n)(vue.unref(isVariantNarrowed) ? "vp.main.alt" : "vp.main")), 9, _hoisted_4$1),
vue.createElementVNode("div", _hoisted_5$1, [
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(isVariantNarrowed) && vue.unref(inferredVariant) !== null ? [vue.unref(inferredVariant)] : vue.unref(VALID_VARIANTS), (variant) => {
return vue.openBlock(), vue.createBlock(VAButton, {
key: variant,
class: vue.normalizeClass(["va-variant-prompt__options__button", { "va-variant-prompt__options__button--primary": vue.unref(isVariantNarrowed) }]),
indicator: "arrowNext",
weight: "quiet",
action: "progressive",
lang: variant,
disabled: _ctx.disabled,
onClick: ($event) => select(variant)
}, {
default: vue.withCtx(() => [
vue.createTextVNode(vue.toDisplayString(vue.unref(messages).variants[variant]), 1)
]),
_: 2
}, 1032, ["class", "lang", "disabled", "onClick"]);
}), 128)),
vue.unref(isVariantNarrowed) ? (vue.openBlock(), vue.createBlock(VAButton, {
key: 0,
class: "va-variant-prompt__options__button",
indicator: "arrowNext",
weight: "quiet",
action: "progressive",
disabled: _ctx.disabled,
onClick: _cache[0] || (_cache[0] = ($event) => isVariantNarrowed.value = false)
}, {
default: vue.withCtx(() => [
vue.createTextVNode(vue.toDisplayString(vue.unref(useI18n)("vp.button.other")), 1)
]),
_: 1
}, 8, ["disabled"])) : vue.createCommentVNode("", true)
]),
vue.createElementVNode("footer", _hoisted_6$1, [
vue.createElementVNode("p", _hoisted_7$1, vue.toDisplayString(vue.unref(useI18n)("vp.main.ext")), 1)
])
], 8, _hoisted_1$1)) : vue.createCommentVNode("", true)
]),
_: 1
});
};
}
});
const VAVariantPrompt = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-1582c41c"]]);
const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
__name: "VASelect",
props: {
modelValue: {}
},
emits: ["update:modelValue"],
setup(__props, { emit: __emit }) {
const props = __props;
const emit = __emit;
const modelValue = useModelWrapper(props, emit);
return (_ctx, _cache) => {
return vue.withDirectives((vue.openBlock(), vue.createElementBlock("select", {
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.isRef(modelValue) ? modelValue.value = $event : null),
class: "va-select"
}, [
vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
], 512)), [
[vue.vModelSelect, vue.unref(modelValue)]
]);
};
}
});
const VASelect = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-c9623b25"]]);
const _hoisted_1 = ["lang", "aria-labelledby"];
const _hoisted_2 = { class: "va-variant-prompt-mobile__header" };
const _hoisted_3 = ["id"];
const _hoisted_4 = { class: "va-variant-prompt-mobile__main" };
const _hoisted_5 = ["value", "lang"];
const _hoisted_6 = { class: "va-variant-prompt-mobile__footer" };
const _hoisted_7 = { class: "va-para va-para--subtle" };
const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
__name: "VAVariantPromptMobile",
props: {
open: { type: Boolean },
disabled: { type: Boolean, default: false }
},
emits: ["update:open", "update:disabled", "select", "optout"],
setup(__props, { emit: __emit }) {
const props = __props;
const emit = __emit;
const prompt = vue.ref(null);
const titleId = useUniqueId();
const selectedVariant = useDefault(() => {
var _a2;
return (_a2 = inferredVariant.value) != null ? _a2 : shuffleVariant();
});
const isOpen = useModelWrapper(props, emit, "open");
const isDisabled = useModelWrapper(props, emit, "disabled");
function optOutAndClose() {
emit("optout");
isOpen.value = false;
}
function select(variant) {
isDisabled.value = true;
emit("select", variant);
}
return (_ctx, _cache) => {
return vue.openBlock(), vue.createBlock(vue.Transition, {
name: "va-variant-prompt-mobile",
appear: ""
}, {
default: vue.withCtx(() => [
_ctx.open ? (vue.openBlock(), vue.createElementBlock("div", {
key: 0,
ref_key: "prompt",
ref: prompt,
lang: `zh-${vue.unref(i18nVariant)}`,
class: "va-variant-prompt-mobile",
role: "dialog",
"aria-modal": "false",
"aria-labelledby": vue.unref(titleId)
}, [
vue.createElementVNode("div", _hoisted_2, [
vue.createElementVNode("h2", {
id: vue.unref(titleId),
class: "va-variant-prompt-mobile__header__title va-title"
}, vue.toDisplayString(vue.unref(useI18n)("vp.main")), 9, _hoisted_3),
vue.createVNode(VAButton, {
class: "va-variant-prompt-mobile__header__close",
weight: "quiet",
icon: "close",
title: vue.unref(useI18n)("close"),
"aria-label": vue.unref(useI18n)("close"),
disabled: _ctx.disabled,
onClick: optOutAndClose
}, null, 8, ["title", "aria-label", "disabled"])
]),
vue.createElementVNode("div", _hoisted_4, [
vue.createVNode(VASelect, {
modelValue: vue.unref(selectedVariant),
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.isRef(selectedVariant) ? selectedVariant.value = $event : null),
class: "va-variant-prompt-mobile__main__select",
lang: vue.unref(selectedVariant),
disabled: _ctx.disabled,
"aria-labelledby": vue.unref(titleId)
}, {
default: vue.withCtx(() => [
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(VALID_VARIANTS), (variant) => {
return vue.openBlock(), vue.createElementBlock("option", {
key: variant,
value: variant,
lang: variant
}, vue.toDisplayString(vue.unref(messages).variants[variant]), 9, _hoisted_5);
}), 128))
]),
_: 1
}, 8, ["modelValue", "lang", "disabled", "aria-labelledby"]),
vue.createVNode(VAButton, {
class: "va-variant-prompt-mobile__main__action",
action: "progressive",
icon: "arrowNext",
disabled: _ctx.disabled,
onClick: _cache[1] || (_cache[1] = ($event) => select(vue.unref(selectedVariant)))
}, {
default: vue.withCtx(() => [
vue.createTextVNode(vue.toDisplayString(vue.unref(useI18n)("vp.button.ok")), 1)
]),
_: 1
}, 8, ["disabled"])
]),
vue.createElementVNode("footer", _hoisted_6, [
vue.createElementVNode("p", _hoisted_7, vue.toDisplayString(vue.unref(useI18n)("vp.main.ext")), 1)
])
], 8, _hoisted_1)) : vue.createCommentVNode("", true)
]),
_: 1
});
};
}
});
const VAVariantPromptMobile = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-2ca12e49"]]);
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
__name: "App",
setup(__props) {
const isOpen = vue.ref(true);
const isDisabled = vue.ref(false);
const isMobile = isMobileDevice();
const desktopMountPoint = getMountPoint();
ext_gadget_VariantAlly.stat(isMobile ? "variant-prompt-mobile-show" : "variant-prompt-show");
function setVariant(variant) {
ext_gadget_VariantAlly.stat(isMobile ? "variant-prompt-mobile-select" : "variant-prompt-select");
ext_gadget_VariantAlly.setLocalVariant(variant);
ext_gadget_VariantAlly.redirect(variant, { forced: true });
}
addEventListener(isMobile ? "touchmove" : "scroll", () => {
if (!isDisabled.value) {
isOpen.value = false;
}
});
function onOptOut() {
ext_gadget_VariantAlly.stat(isMobile ? "variant-prompt-mobile-optout" : "variant-prompt-optout");
ext_gadget_VariantAlly.setOptOut();
}
vue.watch(isOpen, (newValue) => {
if (!newValue) {
ext_gadget_VariantAlly.stat(isMobile ? "variant-prompt-mobile-dismiss" : "variant-prompt-dismiss");
}
});
return (_ctx, _cache) => {
return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
(vue.openBlock(), vue.createBlock(vue.Teleport, { to: vue.unref(desktopMountPoint) }, [
!vue.unref(isMobile) ? (vue.openBlock(), vue.createBlock(VAVariantPrompt, {
key: 0,
open: isOpen.value,
"onUpdate:open": _cache[0] || (_cache[0] = ($event) => isOpen.value = $event),
disabled: isDisabled.value,
"onUpdate:disabled": _cache[1] || (_cache[1] = ($event) => isDisabled.value = $event),
"auto-close": false,
onOptout: onOptOut,
onSelect: setVariant
}, null, 8, ["open", "disabled"])) : vue.createCommentVNode("", true)
], 8, ["to"])),
(vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
vue.unref(isMobile) ? (vue.openBlock(), vue.createBlock(VAVariantPromptMobile, {
key: 0,
open: isOpen.value,
"onUpdate:open": _cache[2] || (_cache[2] = ($event) => isOpen.value = $event),
disabled: isDisabled.value,
"onUpdate:disabled": _cache[3] || (_cache[3] = ($event) => isDisabled.value = $event),
onOptout: onOptOut,
onSelect: setVariant
}, null, 8, ["open", "disabled"])) : vue.createCommentVNode("", true)
]))
], 64);
};
}
});
const root = document.createElement("div");
document.body.appendChild(root);
vue.createMwApp(_sfc_main).mount(root);
// </nowiki>