Viel neues
This commit is contained in:
96
qa-tool/htdocs/js/utils.js
Normal file
96
qa-tool/htdocs/js/utils.js
Normal file
@@ -0,0 +1,96 @@
|
||||
// auto-split module
|
||||
|
||||
const DOCBEE_UI_BASE = DOCBEE_BASEURL; // feste Instanzbasis für UI-Links
|
||||
const SEP = '────────────────────────────────────────────────────────────────────────';
|
||||
const SMAP = {
|
||||
pass: '✅',
|
||||
fail: '❌',
|
||||
skip: '⏭️',
|
||||
blocked: '⛔'
|
||||
};
|
||||
|
||||
// auto-split module
|
||||
|
||||
|
||||
const escAttr = (s) => String(s ?? '').replaceAll('"', '"');
|
||||
|
||||
|
||||
const escHTML = (s) => String(s ?? '').replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>');
|
||||
|
||||
|
||||
const safeName = (s) => String(s || '').replace(/\s+/g, '-').toLowerCase().replace(/[^\w.-]/g, '');
|
||||
|
||||
|
||||
const linkify = (s) => /^https?:\/\//i.test(String(s || '')) ? `<a href="${escHTML(s)}" target="_blank" rel="noopener">${escHTML(s)}</a>` : escHTML(s);
|
||||
|
||||
|
||||
const hasToken = () => typeof DOCBEE_TOKEN === 'string' && DOCBEE_TOKEN.trim().length > 0;
|
||||
|
||||
// auto-split module
|
||||
|
||||
|
||||
function download(content, filename, type) {
|
||||
const blob = new Blob([content], {
|
||||
type
|
||||
});
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
setTimeout(() => URL.revokeObjectURL(url), 1500);
|
||||
}
|
||||
|
||||
|
||||
function loadScript(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const s = document.createElement('script');
|
||||
s.src = url;
|
||||
s.onload = resolve;
|
||||
s.onerror = reject;
|
||||
document.head.appendChild(s);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function extractTicketId(u) {
|
||||
const m = String(u || "").match(/(?:\/ticket\/show\/|\/tickets\/)(\d+)/i);
|
||||
return m ? m[1] : null;
|
||||
}
|
||||
|
||||
|
||||
function rowIndexOf(target) {
|
||||
const tr = target.closest('tr');
|
||||
if (!tr) return -1;
|
||||
return [...els.stepsTableBody.children].indexOf(tr);
|
||||
}
|
||||
|
||||
|
||||
function replaceSymbols(s) {
|
||||
return String(s)
|
||||
// right arrows (→ ⇒ ⟶ ➔ ➜ …) → "->"
|
||||
.replace(/[\u2192\u21A6\u21E8\u27A1\u2794\u27F6\u27F7\u27F9\u279D\u279E\u279F\u27A0]/g, '->')
|
||||
// left arrows (← ⇐ ⟵ …) → "<-"
|
||||
.replace(/[\u2190\u21A4\u21E6\u2B05\u27F5]/g, '<-')
|
||||
// both directions (↔ ⇔ ⟷ …) → "<->"
|
||||
.replace(/[\u2194\u21D4\u27F7\u27F8\u2B04]/g, '<->')
|
||||
// normalize dashes
|
||||
.replace(/[–—‑]/g, '-')
|
||||
// ellipsis/multiply
|
||||
.replace(/…/g, '...')
|
||||
.replace(/×/g, 'x');
|
||||
}
|
||||
|
||||
|
||||
|
||||
function sanitizeText(s) {
|
||||
// Inline text normalization for labels/titles/comments
|
||||
const out = String(s ?? '')
|
||||
.replace(/\u00A0/g, ' ') // NBSP -> space
|
||||
.replace(/[“”]/g, '"') // smart quotes -> ASCII
|
||||
.replace(/[’‘]/g, "'")
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
// Map arrows/dashes and limit to PDF-safe charset
|
||||
return toPdfSafe(replaceSymbols(out));
|
||||
}
|
||||
Reference in New Issue
Block a user