46 lines
1.7 KiB
JavaScript
46 lines
1.7 KiB
JavaScript
// Small HTML pieces of the plugin's server-rendered admin pages.
|
|
|
|
const { escapeHtml } = require("./htmlEscape");
|
|
|
|
|
|
// The hidden CSRF input for a form POST (Saltcorn's csurf token).
|
|
const csrfField = (req) => {
|
|
const token = req.csrfToken ? req.csrfToken() : "";
|
|
return `<input type="hidden" name="_csrf" value="${escapeHtml(token)}">`;
|
|
};
|
|
|
|
|
|
// Bootstrap nav-pills (links = [[href, label], ...]) with the current page marked
|
|
// active. The active link is the one whose href is the LONGEST boundary-safe
|
|
// prefix of the request path, so a sub-page still highlights its parent tab.
|
|
const navPills = (req, links) => {
|
|
const cur = String((req && (req.originalUrl || req.path)) || "").split("?")[0].replace(/\/+$/, "");
|
|
let activeHref = "";
|
|
for (const [href] of links) {
|
|
const h = href.replace(/\/+$/, "");
|
|
if ((cur === h || cur.startsWith(h + "/")) && h.length > activeHref.length) {
|
|
activeHref = h;
|
|
}
|
|
}
|
|
const items = links.map(([href, label]) => {
|
|
const on = href.replace(/\/+$/, "") === activeHref;
|
|
return ` <li class="nav-item"><a class="nav-link${on ? " active" : ""}"${on ? ' aria-current="page"' : ""} href="${escapeHtml(href)}">${escapeHtml(label)}</a></li>`;
|
|
}).join("\n");
|
|
return `<ul class="nav nav-pills mb-3">\n${items}\n</ul>`;
|
|
};
|
|
|
|
|
|
// Flash a message and redirect (Post/Redirect/Get). Saltcorn renders flash text
|
|
// as raw HTML and messages can echo admin input, so it is escaped here; nothing
|
|
// is reflected from the query string.
|
|
const flashRedirect = (req, res, url, type, message) => {
|
|
req.flash(type, escapeHtml(message));
|
|
res.redirect(url);
|
|
};
|
|
|
|
|
|
module.exports = {
|
|
csrfField,
|
|
navPills,
|
|
flashRedirect
|
|
};
|