mirror of
https://github.com/tuna/mirror-web.git
synced 2025-12-25 20:32:46 +00:00
introduce polyfill for FormData for helpz
and remove DOMContentLoaded event listener
This commit is contained in:
parent
6b9c11995d
commit
3e6207b399
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in New Issue