From 3e6207b399d07ecb3302927c1f590f9f536cb0ef Mon Sep 17 00:00:00 2001 From: Miao Wang Date: Sat, 13 Apr 2024 04:45:27 +0800 Subject: [PATCH] introduce polyfill for FormData for helpz and remove DOMContentLoaded event listener --- _src/entrypoints/default.js | 4 +- _src/entrypoints/fancyIndex.js | 10 +- _src/entrypoints/help.js | 160 +++++++++++++-------------- _src/entrypoints/helpz.js | 193 ++++++++++++++++----------------- _src/lib/legacy-polyfill.js | 1 + package.json | 1 + 6 files changed, 180 insertions(+), 189 deletions(-) diff --git a/_src/entrypoints/default.js b/_src/entrypoints/default.js index 75540a9..e19bf12 100644 --- a/_src/entrypoints/default.js +++ b/_src/entrypoints/default.js @@ -8,9 +8,7 @@ if (siteSuffix) { !document.location.hostname.endsWith(siteSuffix + ".") ) { document.title = document.title.replace(/(清华)|(tsinghua)|(tuna)/gi, ""); - document.addEventListener("DOMContentLoaded", () => { - document.body.classList.add("nonthu"); - }); + document.body.classList.add("nonthu"); } } diff --git a/_src/entrypoints/fancyIndex.js b/_src/entrypoints/fancyIndex.js index c54419a..4938755 100644 --- a/_src/entrypoints/fancyIndex.js +++ b/_src/entrypoints/fancyIndex.js @@ -5,10 +5,8 @@ import NowBrowsingMirror from "../components/NowBrowsingMirror.vue"; import { createApp } from "vue"; document.getElementById("list").setAttribute("class", "table"); -document.addEventListener("DOMContentLoaded", function () { - Array.from( - document.querySelectorAll("#list tbody tr td:nth-child(3)"), - ).forEach((el) => { +Array.from(document.querySelectorAll("#list tbody tr td:nth-child(3)")).forEach( + (el) => { const d = new Date(el.innerText); if (!isNaN(d.getTime())) { const date_str = @@ -23,7 +21,7 @@ document.addEventListener("DOMContentLoaded", function () { ("0" + d.getMinutes()).substr(-2)); el.innerText = date_str; } - }); -}); + }, +); createApp(NowBrowsingMirror).mount("#now-browsing-mirror"); diff --git a/_src/entrypoints/help.js b/_src/entrypoints/help.js index a755b68..535eae7 100644 --- a/_src/entrypoints/help.js +++ b/_src/entrypoints/help.js @@ -11,88 +11,84 @@ import { mirrorId } from "../lib/mirrorid"; import "./default"; import "../styles/help.scss"; -document.addEventListener("DOMContentLoaded", () => { - Array.from(document.querySelectorAll("#help-content table")).map((el) => { - el.classList.add("table", "table-bordered", "table-striped"); - }); - - const update_target = (ev) => { - const sel = ev.target; - const target_selectors = sel.attributes["data-target"].value.split(","); - for (const target_selector of target_selectors) { - const target = document.querySelector(target_selector); - const template_selector = target.attributes["data-template"].value; - const select_selectors = - target.attributes["data-select"].value.split(","); - let url = "/" + mirrorId; - if (mirrorId.endsWith(".git")) { - url = "/git/" + mirrorId; - } - const template_data = { - mirror: SiteHostname + url, - }; - for (const select_selector of select_selectors) { - const opt_attrs = document - .querySelector(select_selector) - .querySelector("option:checked").attributes; - for (const attr of opt_attrs) { - if (attr.name.startsWith("data-")) { - template_data[attr.name.slice(5)] = attr.value; - } - } - } - // special hack for case-insensitive - if ("sudoe" in template_data) { - template_data.sudoE = template_data.sudoe; - } - const template = document - .querySelector(template_selector) - .textContent.trim(); - const content = Mark.up(template, template_data); - target.innerHTML = content; - hljs.highlightElement(target); - } - }; - - Array.from(document.querySelectorAll("select.content-select")).map((el) => { - el.addEventListener("change", update_target); - el.dispatchEvent(new Event("change")); - }); - - document.getElementById("help-select").addEventListener("change", (ev) => { - let help_url = - ev.target.querySelector("option:checked").attributes["data-help-url"] - .value; - window.location = `${window.location.protocol}//${window.location.host}${help_url}`; - }); - - fetch(TUNASYNC_JSON_PATH) - .then((resp) => resp.json()) - .then((statusData) => { - // remove help items for disabled/removed mirrors - let availableMirrorIds = new Set(statusData.map((x) => x.name)); - globalOptions.unlisted_mirrors.forEach((elem) => { - availableMirrorIds.add(elem.name); - }); - if (!availableMirrorIds.has(mirrorId)) { - if (HideMirrorZ) { - location.href = "/404-help-hidden.html"; // this will break 404 issue submission - } else { - location.href = MirrorzHelpLink + mirrorId; // TODO: convert this to mirrorz cname - } - } - - Array.from( - document.querySelectorAll('option[id^="toc-"],li[id^="toc-"]'), - ).forEach((elem) => { - if ( - elem.id.startsWith("toc-") && - !availableMirrorIds.has(elem.id.slice(4)) - ) { - elem.remove(); - } - }); - }); +Array.from(document.querySelectorAll("#help-content table")).map((el) => { + el.classList.add("table", "table-bordered", "table-striped"); }); +const update_target = (ev) => { + const sel = ev.target; + const target_selectors = sel.attributes["data-target"].value.split(","); + for (const target_selector of target_selectors) { + const target = document.querySelector(target_selector); + const template_selector = target.attributes["data-template"].value; + const select_selectors = target.attributes["data-select"].value.split(","); + let url = "/" + mirrorId; + if (mirrorId.endsWith(".git")) { + url = "/git/" + mirrorId; + } + const template_data = { + mirror: SiteHostname + url, + }; + for (const select_selector of select_selectors) { + const opt_attrs = document + .querySelector(select_selector) + .querySelector("option:checked").attributes; + for (const attr of opt_attrs) { + if (attr.name.startsWith("data-")) { + template_data[attr.name.slice(5)] = attr.value; + } + } + } + // special hack for case-insensitive + if ("sudoe" in template_data) { + template_data.sudoE = template_data.sudoe; + } + const template = document + .querySelector(template_selector) + .textContent.trim(); + const content = Mark.up(template, template_data); + target.innerHTML = content; + hljs.highlightElement(target); + } +}; + +Array.from(document.querySelectorAll("select.content-select")).map((el) => { + el.addEventListener("change", update_target); + el.dispatchEvent(new Event("change")); +}); + +document.getElementById("help-select").addEventListener("change", (ev) => { + let help_url = + ev.target.querySelector("option:checked").attributes["data-help-url"].value; + window.location = `${window.location.protocol}//${window.location.host}${help_url}`; +}); + +fetch(TUNASYNC_JSON_PATH) + .then((resp) => resp.json()) + .then((statusData) => { + // remove help items for disabled/removed mirrors + let availableMirrorIds = new Set(statusData.map((x) => x.name)); + globalOptions.unlisted_mirrors.forEach((elem) => { + availableMirrorIds.add(elem.name); + }); + if (!availableMirrorIds.has(mirrorId)) { + if (HideMirrorZ) { + location.href = "/404-help-hidden.html"; // this will break 404 issue submission + } else { + location.href = MirrorzHelpLink + mirrorId; // TODO: convert this to mirrorz cname + } + } + + Array.from( + document.querySelectorAll('option[id^="toc-"],li[id^="toc-"]'), + ).forEach((elem) => { + if ( + elem.id.startsWith("toc-") && + !availableMirrorIds.has(elem.id.slice(4)) + ) { + elem.remove(); + } + }); + }); + // vim: ts=2 sts=2 sw=2 noexpandtab diff --git a/_src/entrypoints/helpz.js b/_src/entrypoints/helpz.js index 5618281..b086e05 100644 --- a/_src/entrypoints/helpz.js +++ b/_src/entrypoints/helpz.js @@ -4,110 +4,107 @@ import hljs from "../lib/hljs"; import { mirrorId } from "../lib/mirrorid"; import Mustache from "mustache"; -window.addEventListener("DOMContentLoaded", function () { - function generateFormConfig(form) { - const formData = Object.fromEntries(new FormData(form).entries()); - Array.from( - // FormData ignores unchecked checkboxes, workaround - form.querySelectorAll("input[type=checkbox]:not(:checked)"), - ).forEach((elm) => { - formData[elm.name] = ""; - }); - let conf = {}; - for (const x in formData) { - conf[x] = formData[x]; - const varConf = GLOBAL_CONFIG.input[x]; - if (!varConf) continue; - let optConf = null; - if ("option" in varConf) optConf = varConf.option[formData[x]]; - else if ("true" in varConf || "false" in varConf) { - optConf = formData[x] === "on" ? varConf.true : varConf.false; - } - if (typeof optConf === "object") Object.assign(conf, optConf); - if (typeof optConf === "string") conf[x] = optConf; +function generateFormConfig(form) { + const formData = Object.fromEntries(new FormData(form).entries()); + Array.from( + // FormData ignores unchecked checkboxes, workaround + form.querySelectorAll("input[type=checkbox]:not(:checked)"), + ).forEach((elm) => { + formData[elm.name] = ""; + }); + let conf = {}; + for (const x in formData) { + conf[x] = formData[x]; + const varConf = GLOBAL_CONFIG.input[x]; + if (!varConf) continue; + let optConf = null; + if ("option" in varConf) optConf = varConf.option[formData[x]]; + else if ("true" in varConf || "false" in varConf) { + optConf = formData[x] === "on" ? varConf.true : varConf.false; } - return conf; + if (typeof optConf === "object") Object.assign(conf, optConf); + if (typeof optConf === "string") conf[x] = optConf; } + return conf; +} - function renderCode(tmpl) { - // generate mustache config - let conf = { - path: (mirrorId.endsWith(".git") ? "/git/" : "/") + mirrorId, - }; - Array.from(document.querySelectorAll("form.z-global")).forEach((elm) => { - Object.assign(conf, generateFormConfig(elm)); - }); - conf.scheme = conf._scheme ? "https" : "http"; - conf.host = conf.host.replace(/^https?:\/\//, ""); - conf.sudo = conf._sudo ? "sudo " : ""; - if (conf.filter && GLOBAL_CONFIG.filter.scheme) { - conf.scheme = GLOBAL_CONFIG.filter.scheme; - } - // find div.z-wrap - const div = tmpl.previousElementSibling; - // find form.z-form - const form = div.querySelector("form.z-form"); - // find form.z-code - var code = div.querySelector("pre.z-code"); - if (code === null) { - code = document.createElement("pre"); - code.classList.add("z-code"); - div.appendChild(code); - } - if (form) Object.assign(conf, generateFormConfig(form)); - conf.endpoint = conf.scheme + "://" + conf.host + conf.path; - - // render with mustache - let rendered = Mustache.render( - tmpl.textContent.trim(), - conf, - {}, - { escape: (x) => x }, - ); - try { - const lang = tmpl.attributes.getNamedItem("z-lang"); - if (lang && hljs.getLanguage(lang.value)) { - rendered = hljs.highlight(rendered, { language: lang.value }).value; - } - } catch (err) { - console.error(err); - } - code.innerHTML = rendered; +function renderCode(tmpl) { + // generate mustache config + let conf = { + path: (mirrorId.endsWith(".git") ? "/git/" : "/") + mirrorId, + }; + Array.from(document.querySelectorAll("form.z-global")).forEach((elm) => { + Object.assign(conf, generateFormConfig(elm)); + }); + conf.scheme = conf._scheme ? "https" : "http"; + conf.host = conf.host.replace(/^https?:\/\//, ""); + conf.sudo = conf._sudo ? "sudo " : ""; + if (conf.filter && GLOBAL_CONFIG.filter.scheme) { + conf.scheme = GLOBAL_CONFIG.filter.scheme; } - - function renderForm(event) { - if (!event || event.currentTarget.classList.contains("z-global")) { - Array.from(document.querySelectorAll(".z-help pre.z-tmpl")).forEach( - renderCode, - ); - } else { - renderCode(event.currentTarget.parentElement.nextElementSibling); - } + // find div.z-wrap + const div = tmpl.previousElementSibling; + // find form.z-form + const form = div.querySelector("form.z-form"); + // find form.z-code + var code = div.querySelector("pre.z-code"); + if (code === null) { + code = document.createElement("pre"); + code.classList.add("z-code"); + div.appendChild(code); } + if (form) Object.assign(conf, generateFormConfig(form)); + conf.endpoint = conf.scheme + "://" + conf.host + conf.path; - // Load project config - const GLOBAL_CONFIG = JSON.parse( - atob(document.getElementById("z-config").textContent), + // render with mustache + let rendered = Mustache.render( + tmpl.textContent.trim(), + conf, + {}, + { escape: (x) => x }, ); - - // Hide HTTPS selector if filtered - if (GLOBAL_CONFIG.filter && GLOBAL_CONFIG.filter.scheme) { - document.querySelector( - 'input[name="_scheme"]', - ).parentElement.style.display = "none"; - } - - // Render code - renderForm(null); - - const ignoreEventHandler = (event) => event.preventDefault(); - - for (const form of document.querySelectorAll("form.z-form")) { - form.addEventListener("submit", ignoreEventHandler); - if (form.classList.contains("z-global")) { - form.addEventListener("change", () => renderForm(null)); - } else { - form.addEventListener("change", renderForm); + try { + const lang = tmpl.attributes.getNamedItem("z-lang"); + if (lang && hljs.getLanguage(lang.value)) { + rendered = hljs.highlight(rendered, { language: lang.value }).value; } + } catch (err) { + console.error(err); } -}); + code.innerHTML = rendered; +} + +function renderForm(event) { + if (!event || event.currentTarget.classList.contains("z-global")) { + Array.from(document.querySelectorAll(".z-help pre.z-tmpl")).forEach( + renderCode, + ); + } else { + renderCode(event.currentTarget.parentElement.nextElementSibling); + } +} + +// Load project config +const GLOBAL_CONFIG = JSON.parse( + atob(document.getElementById("z-config").textContent), +); + +// Hide HTTPS selector if filtered +if (GLOBAL_CONFIG.filter && GLOBAL_CONFIG.filter.scheme) { + document.querySelector('input[name="_scheme"]').parentElement.style.display = + "none"; +} + +// Render code +renderForm(null); + +const ignoreEventHandler = (event) => event.preventDefault(); + +for (const form of document.querySelectorAll("form.z-form")) { + form.addEventListener("submit", ignoreEventHandler); + if (form.classList.contains("z-global")) { + form.addEventListener("change", () => renderForm(null)); + } else { + form.addEventListener("change", renderForm); + } +} diff --git a/_src/lib/legacy-polyfill.js b/_src/lib/legacy-polyfill.js index 07b468c..2ef6eb4 100644 --- a/_src/lib/legacy-polyfill.js +++ b/_src/lib/legacy-polyfill.js @@ -3,6 +3,7 @@ import "whatwg-fetch"; import "events-polyfill/src"; import "@webcomponents/template"; import "element-polyfill"; +import "formdata-polyfill"; import Es6ProxyPolyfill from "./es6-proxy-polyfill.js"; const globalObj = diff --git a/package.json b/package.json index 40716d0..d82dfe6 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "core-js": "^3.36.1", "element-polyfill": "^1.1.0", "events-polyfill": "^2.1.2", + "formdata-polyfill": "^4.0.10", "highlight.js": "^11.9.0", "lato-webfont": "^2.15.1", "liquidjs": "^10.10.2",