24 lines
1.1 KiB
JavaScript
24 lines
1.1 KiB
JavaScript
export function esc(str) {
|
|
if (!str) return '';
|
|
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
}
|
|
|
|
export function sanitizeHtml(html) {
|
|
// DOMPurify is loaded globally from index.html. If it is unavailable, render
|
|
// as plain text rather than attempting partial sanitization.
|
|
if (!window.DOMPurify || typeof window.DOMPurify.sanitize !== 'function') {
|
|
console.warn('[learningHub] DOMPurify unavailable - rendering as plain text.');
|
|
var d = document.createElement('div');
|
|
d.textContent = String(html == null ? '' : html);
|
|
return d.innerHTML;
|
|
}
|
|
return window.DOMPurify.sanitize(html, {
|
|
ALLOWED_TAGS: ['p','br','b','strong','i','em','u','s','h1','h2','h3','h4','h5','h6',
|
|
'ul','ol','li','a','blockquote','code','pre','table','thead','tbody','tr','th','td',
|
|
'hr','div','span','sub','sup','dl','dt','dd'],
|
|
ALLOWED_ATTR: ['href','colspan','rowspan','class','target','rel'],
|
|
ADD_ATTR: ['target'],
|
|
FORBID_ATTR: ['style','onerror','onload','onclick','onmouseover'],
|
|
ALLOW_DATA_ATTR: false
|
|
});
|
|
}
|