/** * Страница /documentation: загрузка README через API и рендер Markdown. * Зависимости из репозитория: /static/js/vendor/marked.min.js, purify.min.js * * Автор: Сергей Антропов * Сайт: https://devops.org.ru */ (function () { "use strict"; const body = document.body; const API = (body.dataset.apiBase || "/api/v1").replace(/\/$/, ""); function showErr(el, msg) { if (!el) return; el.textContent = msg; el.classList.remove("hidden"); } async function run() { const article = document.getElementById("readme-doc-article"); const errEl = document.getElementById("readme-error"); const loadEl = document.getElementById("readme-loading"); if (!article || !loadEl) return; if (typeof marked === "undefined" || typeof DOMPurify === "undefined") { showErr(errEl, "Не загружены скрипты marked или DOMPurify из /static/js/vendor/."); loadEl.classList.add("hidden"); return; } try { const r = await fetch(API + "/docs/readme", { headers: { Accept: "text/markdown, text/plain, */*" }, }); const text = await r.text(); if (!r.ok) { var detail = text; try { var j = JSON.parse(text); if (j.detail) detail = typeof j.detail === "string" ? j.detail : JSON.stringify(j.detail); } catch (e) { /* сырой текст */ } showErr(errEl, "Не удалось загрузить README: " + (detail || r.statusText)); loadEl.classList.add("hidden"); return; } /* marked v15: переносы строк в параграфах (breaks). */ try { if (marked.defaults && typeof marked.defaults === "object") { marked.defaults.breaks = true; marked.defaults.gfm = true; } } catch (e) { /* игнорируем, если defaults защищены от записи */ } var rawHtml = typeof marked.parse === "function" ? marked.parse(text, { async: false }) : marked(text); article.innerHTML = DOMPurify.sanitize(rawHtml); article.removeAttribute("hidden"); loadEl.classList.add("hidden"); } catch (e) { showErr(errEl, "Ошибка: " + (e.message || String(e))); loadEl.classList.add("hidden"); } } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", run); } else { run(); } })();