UNPKG

auto-cms-server

Version:

Auto turn any webpage into editable CMS without coding.

120 lines (118 loc) 3.99 kB
"use strict"; (() => { // userscript/api.ts async function fetch_json(url, init2) { return fetch(url, init2).then((res) => res.json().catch((err) => ({ error: res.statusText }))).then((json) => { if (json.error) { throw json.error; } return json; }); } async function resolveFilePathname(pathname) { let json = await fetch_json( "/auto-cms/file", { method: "OPTIONS", headers: { "X-Pathname": encodeURIComponent(pathname) } } ); return json; } // userscript/multi-lang.ts var trTemplate = tableBody.querySelector("tr"); async function init() { try { errorMessage.textContent = "Loading langs..."; let { langs } = await fetch_json( "/auto-cms/langs", {} ); for (let lang of langs) { let th = document.createElement("th"); th.textContent = lang.name; tableHeader.appendChild(th); let td = document.createElement("td"); let textarea = document.createElement("textarea"); textarea.dataset.value = lang.code; td.appendChild(textarea); trTemplate.appendChild(td); } errorMessage.textContent = "Resolving pathname..."; const params = new URLSearchParams(window.location.search); const pagePathname = params.get("pathname"); if (!pagePathname) { throw "missing pathname in location.search"; } pathnameNode.textContent = pagePathname; let path = await resolveFilePathname(pagePathname); let jsonPathname = path.pathname + ".json"; pathnameNode.textContent = jsonPathname; errorMessage.textContent = "Loading language translations..."; let dict = await fetch_json(jsonPathname, {}); let keySpanTemplate = trTemplate.querySelector('[data-text="key"]'); trTemplate.hidden = false; for (let [key, word] of Object.entries(dict)) { let tr = trTemplate.cloneNode(true); let keySpan = tr.querySelector('[data-text="key"]'); keySpan.textContent = key; keySpanTemplate.textContent = key; let rect = keySpanTemplate.getBoundingClientRect(); let minHeight = rect.height * 1.25 + "px"; for (let [lang, value] of Object.entries(word)) { let input = tr.querySelector( `[data-value="${lang}"]` ); input.value = value; input.style.minHeight = minHeight; } tableBody.appendChild(tr); } trTemplate.hidden = true; async function save() { saveButton.textContent = "Saving..."; saveButton.disabled = true; saveButton.style.color = "unset"; try { let dict2 = {}; let rows = tableBody.querySelectorAll("tr"); for (let row of rows) { let key = row.querySelector('[data-text="key"]').textContent; let word = {}; let inputs = row.querySelectorAll("textarea"); for (let input of inputs) { let lang = input.dataset.value; let value = input.value; word[lang] = value; } dict2[key] = word; } await fetch_json("/auto-cms/file", { method: "PUT", headers: { "Content-Type": "application/json", "X-Pathname": jsonPathname }, body: JSON.stringify(dict2) }); saveButton.disabled = false; saveButton.textContent = "Saved"; saveButton.style.color = "green"; } catch (error) { saveButton.disabled = false; saveButton.textContent = String(error); saveButton.style.color = "red"; } } saveButton.onclick = save; errorMessage.hidden = true; } catch (error) { console.error(error); errorMessage.textContent = String(error); errorMessage.hidden = false; } } init(); })();