introduce polyfill for FormData for helpz

and remove DOMContentLoaded event listener
This commit is contained in:
Miao Wang 2024-04-13 04:45:27 +08:00
parent 6b9c11995d
commit 3e6207b399
6 changed files with 180 additions and 189 deletions

View File

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

View File

@ -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");

View File

@ -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

View File

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

View File

@ -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 =

View File

@ -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",