refactoring van de cmap structuren bijna compleet
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
"use strict";
|
||||
|
||||
export const debugPrefix = "[racket-wiki:cmap 0.2.122]";
|
||||
|
||||
export function debug(message, details) {
|
||||
if (details === undefined) {
|
||||
console.info(debugPrefix, message);
|
||||
return;
|
||||
}
|
||||
console.info(debugPrefix, message, details);
|
||||
}
|
||||
|
||||
export function elementDescription(element) {
|
||||
if (!(element instanceof Element)) return String(element);
|
||||
return {
|
||||
tag: element.tagName,
|
||||
id: element.id || null,
|
||||
classes: Array.from(element.classList),
|
||||
itemId: element.dataset.rwCmapItemId || null
|
||||
};
|
||||
}
|
||||
|
||||
export function selectionStyle(element) {
|
||||
if (!(element instanceof Element) || typeof window.getComputedStyle !== "function") return null;
|
||||
const style = window.getComputedStyle(element);
|
||||
return {
|
||||
pointerEvents: style.pointerEvents,
|
||||
outline: style.outline,
|
||||
outlineOffset: style.outlineOffset,
|
||||
boxShadow: style.boxShadow,
|
||||
overflow: style.overflow,
|
||||
zIndex: style.zIndex
|
||||
};
|
||||
}
|
||||
|
||||
export function escapeHtml(value) {
|
||||
return String(value || "")
|
||||
.replaceAll("&", "&")
|
||||
.replaceAll("<", "<")
|
||||
.replaceAll(">", ">")
|
||||
.replaceAll('"', """)
|
||||
.replaceAll("'", "'");
|
||||
}
|
||||
|
||||
export function numberOr(value, fallback) {
|
||||
return Number.isFinite(value) ? value : fallback;
|
||||
}
|
||||
|
||||
export function conceptDescriptionReference(label, id) {
|
||||
const slug = String(label || "")
|
||||
.normalize("NFKD")
|
||||
.toLocaleLowerCase()
|
||||
.replace(/[\u0300-\u036f]/g, "")
|
||||
.replace(/[^\p{L}\p{N}]+/gu, "-")
|
||||
.replace(/^-+|-+$/g, "")
|
||||
.slice(0, 120)
|
||||
.replace(/-+$/g, "");
|
||||
return `cmap:${slug || `concept-${id}`}`;
|
||||
}
|
||||
|
||||
export function newConceptId() {
|
||||
if (window.crypto && typeof window.crypto.randomUUID === "function") {
|
||||
try {
|
||||
return window.crypto.randomUUID().toLowerCase();
|
||||
} catch (_error) {
|
||||
// randomUUID can be exposed but forbidden in an insecure/file context.
|
||||
}
|
||||
}
|
||||
const bytes = new Uint8Array(16);
|
||||
if (window.crypto && typeof window.crypto.getRandomValues === "function") {
|
||||
window.crypto.getRandomValues(bytes);
|
||||
} else {
|
||||
for (let index = 0; index < bytes.length; index += 1) {
|
||||
bytes[index] = Math.floor(Math.random() * 256);
|
||||
}
|
||||
}
|
||||
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
||||
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
||||
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0"));
|
||||
return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
|
||||
}
|
||||
|
||||
export function normalizeConceptTags(tags) {
|
||||
if (!Array.isArray(tags)) return [];
|
||||
return tags.map((tag) => {
|
||||
if (typeof tag === "string") return { type: "label", value: tag.trim() };
|
||||
if (!tag || typeof tag !== "object") return null;
|
||||
return {
|
||||
type: String(tag.type || "label").trim() || "label",
|
||||
value: String(tag.value || tag.name || "").trim()
|
||||
};
|
||||
}).filter((tag) => tag && tag.value);
|
||||
}
|
||||
Reference in New Issue
Block a user