Changeset 0.37.10 (#222)

Co-authored-by: gobha <jasafpro@gmail.com>
Co-committed-by: gobha <jasafpro@gmail.com>
This commit is contained in:
2026-03-21 23:39:23 +00:00
committed by xcaliber
parent 37b639c9c8
commit 8d8a118232
52 changed files with 3209 additions and 13811 deletions

View File

@@ -4,6 +4,8 @@
// Wraps window.marked + window.DOMPurify with fallback.
// Independently importable utility.
//
// v0.37.10: Task list rendering, code block language extraction.
//
// Usage:
// import { renderMarkdown } from './markdown.js';
// const html = renderMarkdown('**bold** text');
@@ -17,6 +19,37 @@ function _escapeHtml(text) {
return text.replace(/[&<>"']/g, c => _escMap[c]);
}
/**
* Configure marked with task list support if available.
*/
let _configured = false;
function _ensureConfigured() {
if (_configured) return;
_configured = true;
if (typeof marked === 'undefined') return;
marked.setOptions({
breaks: true,
gfm: true,
});
// Custom renderer for task list items
const renderer = new marked.Renderer();
const origListItem = renderer.listitem?.bind(renderer);
renderer.listitem = function(text, task, checked) {
if (task) {
const checkbox = checked
? '<input type="checkbox" checked disabled class="sw-task-checkbox" />'
: '<input type="checkbox" disabled class="sw-task-checkbox" />';
return '<li class="sw-task-item">' + checkbox + ' ' + text + '</li>\n';
}
if (origListItem) return origListItem(text, task, checked);
return '<li>' + text + '</li>\n';
};
marked.use({ renderer });
}
/**
* Render markdown text to sanitized HTML.
* Falls back to escaped plaintext when marked/DOMPurify unavailable.
@@ -30,6 +63,7 @@ export function renderMarkdown(text) {
let result;
if (typeof marked !== 'undefined' && typeof DOMPurify !== 'undefined') {
_ensureConfigured();
result = DOMPurify.sanitize(marked.parse(text));
} else {
result = _escapeHtml(text);