查看“Widget:TextToggleDisplay”的源代码
←
Widget:TextToggleDisplay
跳转至:
导航
、
搜索
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您没有权限编辑
Widget
名字空间内的页面。
您可以查看与复制此页面的源代码。
<noinclude>only for {{tl|切换显示按钮}}</noinclude><includeonly><!--{if !isset($wgTextToggleDisplay) || !$wgTextToggleDisplay}--><!--{assign var="wgTextToggleDisplay" value=true scope="global"}--><script> "use strict"; window.RLQ = window.RLQ || []; window.RLQ.push(() => $(() => { const cssSanitizer = (cssStr) => (typeof cssStr === "string" ? cssStr : "").replace(RegExp(decodeURIComponent("%3C!--"), "g"), "").replace(RegExp(decodeURIComponent("-%3E"), "g"), "").replace(/\/\//g, "").replace(/url/g, "").replace(/&/g, "").replace(/pointer-event/g, ";").replace(/display\s*:\s*none\s*!\s*important/g, "display: none"); const uuidv4 = () => { let result = ""; while (result === "" || $(`#${result}, [name="${result}"]`).length > 0) { result = ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16), ); } return result; }; const datasetParser = (ele) => { const result = { config: {}, data: {}, }; Object.entries(ele.dataset).filter(([n, m]) => n.startsWith("key-") && !/['"<>\\/]/.test(m)).forEach(([__key, _key]) => { const value = ele.dataset[`value-${__key.substring(4)}`]; if (_key.length > 0 && value.length > 0) { const isConfig = _key.startsWith("@"); const key = isConfig ? _key.substring(1) : _key; const base = result[isConfig ? "config" : "data"]; base[key] = value; if (/@o(?:n|ff)$/.test(_key)) { const id = _key.replace(/@o(?:n|ff)$/, ""); if (!(id in base)) { base[id] = value; } } else if (_key.endsWith("@input")) { base[_key] = value; const id = _key.replace(/@input$/, ""); if (!(id in base)) { base[id] = ""; } } else { if (!(`${key}@on` in base)) { base[`${key}@on`] = value; } if (!(`${key}@off` in base)) { base[`${key}@off`] = value; } if (!(`${key}@input` in base)) { base[`${key}@input`] = ""; } } } }); return result; }; const getEntries = (obj) => Object.entries(obj).filter(([k, n]) => !/@(?:on|off|input)$/.test(k) && !/['"<>\\/]/.test(n)); const textToggleDisplayStyle = {}; $(".textToggleDisplayStyle").each((_, ele) => { const dataset = datasetParser(ele).data; getEntries(dataset).forEach(([id, style]) => { textToggleDisplayStyle[id] = style; }); }); $(".textToggleDisplay").each((_, ele) => { if (ele.dataset.id in textToggleDisplayStyle) { $(ele).attr("style", cssSanitizer(textToggleDisplayStyle[ele.dataset.id])); } }).addClass("hidden"); const defaultInputs = []; $(".textToggleDisplayButtons").each((_, ele) => { const self = $(ele); const parsedDataset = datasetParser(ele); const ifRadio = "radio" in parsedDataset.config && parsedDataset.config.radio.length > 0; const ifForceNoCancel = "forceNoCancel" in parsedDataset.config && parsedDataset.config.forceNoCancel.length > 0; const ifReverse = "reverse" in parsedDataset.config && parsedDataset.config.reverse.length > 0; const name = uuidv4(); let hasDefault = false; self.children("span[data-key]").each((_, e) => { if (/['"<>\\/]/.test(e.dataset.key)) { e.remove(); return; } const $e = $(e); const input = $("<input/>"); input.attr({ "data-id": e.dataset.key, type: ifRadio ? "radio" : "checkbox", }).addClass(ifReverse ? "textToggleDisplayButtonInputReverse" : "textToggleDisplayButtonInput"); if (ifRadio) { input.attr("name", name); } const label = $("<label/>"); $e.children().appendTo(label); label.prepend(input).appendTo(e).attr("data-id", e.dataset.key).addClass("textToggleDisplayButtonLabel"); $e.find("*").each((_, e) => { e.addEventListener("click", (evt) => { evt.stopImmediatePropagation(); evt.stopPropagation(); if (!$(evt.target).is(input)) { evt.preventDefault(); if (ifRadio ? !input.prop("checked") : true) { input.prop("checked", !input.prop("checked")).trigger("change"); } } }, { capture: true, }); }); if (e.dataset.key === parsedDataset.config.default) { defaultInputs.push(input[0]); hasDefault = true; } }); if (ifRadio && (!hasDefault || !ifForceNoCancel)) { const input = $("<input/>"); const inputId = uuidv4(); input.attr({ "data-id": "", "data-radio-cancel": "true", id: inputId, name, type: "radio", }).addClass(ifReverse ? "textToggleDisplayButtonInputReverse" : "textToggleDisplayButtonInput").css({ "margin-left": "0", "margin-right": "0", width: "0", }); const label = $("<label/>"); const span = $("<span/>"); span.text("取消选择"); label.attr({ "data-id": "", "for": inputId, }).addClass("textToggleDisplayButtonLabel cancelButton"); self.append(label.append(input).append(span)); if (!hasDefault) { defaultInputs.push(input[0]); } } }); $(".textToggleDisplayButtonsStyle").each((_, ele) => { const parsedDataset = datasetParser(ele); $(".textToggleDisplayButtonLabel.cancelButton").attr({ "data-style-off": parsedDataset.config["cancel@off"] || "", "data-style-on": parsedDataset.config["cancel@on"] || "", }); $(".textToggleDisplayButtonLabel.cancelButton > input").attr("style", cssSanitizer(parsedDataset.config["cancel@input"])); getEntries(parsedDataset.data).forEach(([id]) => { $(`.textToggleDisplayButtonLabel[data-id="${id}"]`).attr({ "data-style-off": parsedDataset.data[`${id}@off`] || "", "data-style-on": parsedDataset.data[`${id}@on`] || "", }).children("input").attr("style", cssSanitizer(parsedDataset.data[`${id}@input`])); }); }); const setInputStatus = (input, checked) => { const label = $(input).closest(".textToggleDisplayButtonLabel"); const span = label.children(".on"); label[checked ? "addClass" : "removeClass"]("on").attr("style", cssSanitizer(label.attr(checked ? "data-style-on" : "data-style-off"))); if (checked) { span.attr("style", cssSanitizer(textToggleDisplayStyle[input.dataset.id])); } else { span.removeAttr("style"); } const labelContainer = label.closest("span[data-order][data-key]"); labelContainer.prev("span[data-order][data-key]").children(".textToggleDisplayButtonLabel").last()[checked ? "addClass" : "removeClass"]("before-on"); labelContainer.next("span[data-order][data-key]").children(".textToggleDisplayButtonLabel").first()[checked ? "addClass" : "removeClass"]("after-on"); }; const setLabelStatus = () => { const map = Object.fromEntries($(".textToggleDisplay").toArray().map(({ dataset: { id, }, classList, }) => [id, !classList.contains("textToggleDisplay-off")])); for (const input of $(".textToggleDisplayButtonInput:not(.textToggleDisplayButtonLabel.cancelButton > input)")) { const { dataset: { id, }, } = input; const cancelInput = $(input).closest(".textToggleDisplayButtons").find(".textToggleDisplayButtonLabel.cancelButton > input:checked"); const checked = cancelInput.length > 0 ? false : id.split("$").filter((i) => !map[i]).length === 0; input.checked = checked; setInputStatus(input, checked); } for (const input of $(".textToggleDisplayButtonInputReverse:not(.textToggleDisplayButtonLabel.cancelButton > input)")) { const { dataset: { id, }, } = input; const cancelInput = $(input).closest(".textToggleDisplayButtons").find(".textToggleDisplayButtonLabel.cancelButton > input:checked"); const checked = cancelInput.length > 0 ? false : id.split("$").filter((i) => map[i]).length === 0; input.checked = checked; setInputStatus(input, !checked); } for (const input of $(".textToggleDisplayButtonLabel.cancelButton > input")) { const checked = $(input).closest(".textToggleDisplayButtons").find("input").not(input).toArray().filter(({ checked }) => checked).length === 0; input.checked = checked; setInputStatus(input, checked); } }; const updateSilbing = () => { $("textToggleDisplay-before-on").each((_, ele) => { const $ele = $(ele); if ($ele.next(".textToggleDisplay").is(":not(.textToggleDisplay-on)")) { $ele.removeClass("textToggleDisplay-before-on"); } }); $(".textToggleDisplay:not(.textToggleDisplay-on) + .textToggleDisplay-after-on").removeClass("textToggleDisplay-after-on"); $(".textToggleDisplay-on").prev(".textToggleDisplay").addClass("textToggleDisplay-before-on").end().next(".textToggleDisplay").addClass("textToggleDisplay-after-on"); }; $(".textToggleDisplayButtonInput").on("change", ({ target, }) => { const { dataset: { id, radioCancel, }, checked, } = target; const ids = id.split("$"); const self = $(target); const label = self.closest(".textToggleDisplayButtonLabel"); const textToggleDisplayTarget = $(ids.map((i) => `.textToggleDisplay[data-id="${i}"]`).join(", ")); const textToggleDisplayButtons = self.closest(".textToggleDisplayButtons"); const { config: { toggleClass, radio } } = datasetParser(textToggleDisplayButtons[0]); let toggleClassName = typeof toggleClass === "string" && toggleClass.length > 0 ? toggleClass : "hidden"; if (toggleClassName !== "hidden") { textToggleDisplayTarget.removeClass("hidden"); } toggleClassName += " textToggleDisplay-off"; if (radioCancel?.length > 0) { label[checked ? "addClass" : "removeClass"]("on").attr("style", cssSanitizer(label.attr(checked ? "data-style-on" : "data-style-off"))); $(textToggleDisplayButtons.find(".textToggleDisplayButtonLabel > input").toArray().flatMap(({ dataset: { id } }) => id.split("$")).map((i) => `.textToggleDisplay[data-id="${i}"]`).join(", ")).addClass(toggleClassName).removeClass("textToggleDisplay-on"); } else { textToggleDisplayTarget[checked ? "removeClass" : "addClass"](toggleClassName)[checked ? "addClass" : "removeClass"]("textToggleDisplay-on"); if (radio?.length > 0 && checked) { const siblings = $(textToggleDisplayButtons.find(".textToggleDisplayButtonLabel > input").not(target).toArray().flatMap(({ dataset: { id } }) => id.split("$")).map((i) => `.textToggleDisplay[data-id="${i}"]`).join(", ")); siblings.addClass(toggleClassName).removeClass("textToggleDisplay-on"); } } setLabelStatus(); updateSilbing(); }); $(".textToggleDisplayButtonInputReverse").on("change", ({ target, }) => { const { dataset: { id, radioCancel, }, checked, } = target; const ids = id.split("$"); const self = $(target); const label = self.closest(".textToggleDisplayButtonLabel"); const textToggleDisplayTarget = $(ids.map((i) => `.textToggleDisplay[data-id="${i}"]`).join(", ")); const textToggleDisplayButtons = self.closest(".textToggleDisplayButtons"); const { config: { toggleClass, radio } } = datasetParser(textToggleDisplayButtons[0]); let toggleClassName = typeof toggleClass === "string" && toggleClass.length > 0 ? toggleClass : "hidden"; if (toggleClassName !== "hidden") { textToggleDisplayTarget.removeClass("hidden"); } toggleClassName += " textToggleDisplay-off"; if (radioCancel?.length > 0) { label[checked ? "addClass" : "removeClass"]("on").attr("style", cssSanitizer(label.attr(checked ? "data-style-on" : "data-style-off"))); $(textToggleDisplayButtons.find(".textToggleDisplayButtonLabel > input").toArray().flatMap(({ dataset: { id } }) => id.split("$")).map((i) => `.textToggleDisplay[data-id="${i}"]`).join(", ")).addClass(toggleClassName).removeClass("textToggleDisplay-on"); } else { textToggleDisplayTarget[checked ? "addClass" : "removeClass"](toggleClassName)[checked ? "removeClass" : "addClass"]("textToggleDisplay-on"); if (radio?.length > 0 && checked) { const siblings = $(textToggleDisplayButtons.find(".textToggleDisplayButtonLabel > input").not(target).toArray().flatMap(({ dataset: { id } }) => id.split("$")).map((i) => `.textToggleDisplay[data-id="${i}"]`).join(", ")); siblings.removeClass(toggleClassName).addClass("textToggleDisplay-on"); } } setLabelStatus(); updateSilbing(); }); for (const ele of defaultInputs) { $(ele).prop("checked", true).trigger("change"); } $(window).on("beforeunload", () => { $(".textToggleDisplayButtons input[type=checkbox]").prop("checked", false); }); })); </script><style> .textToggleDisplayButtons { display: inline-flex; flex-wrap: wrap; align-items: baseline; align-content: flex-start; user-select: none; } .textToggleDisplayButtonLabel { border: 1px solid rgba(0, 0, 0, .3); border-left-width: 4px; border-radius: 2px; flex: 1 0 auto; margin: 4px; padding: 0 8px; box-shadow: 1px 1px 2px black; color: rgba(0, 0, 0, .7); transition: .13s ease-in-out all; background-color: white; } .textToggleDisplayButtonLabel.cancelButton { line-height: normal; } .textToggleDisplayButtonLabel.on { border-color: rgba(0, 0, 0, 1); color: rgba(0, 0, 0, 1); } .textToggleDisplay.hidden, .textToggleDisplayButtonsStyle, .textToggleDisplayStyle, .textToggleDisplayButtonLabel:not(.on) .textToggleDisplayButtonLabelText.on, .textToggleDisplayButtonLabel.on .textToggleDisplayButtonLabelText.off, .textToggleDisplayButtonLabel.cancelButton > input { display: none !important; } </style><!--{/if}--></includeonly>
该页面使用的模板:
模板:Tl
(
查看源代码
)
返回至
Widget:TextToggleDisplay
。
导航菜单
个人工具
登录
名字空间
Widget
讨论
变种
视图
阅读
查看源代码
查看历史
更多
搜索
导航
首页
随机页面
最近更改
最新文件
常用
上传多个文件
工具
链入页面
相关更改
特殊页面
页面信息