UNPKG

html-to-json-rs

Version:

Package for converting HTML to JSON and JSON to HTML using Rust and WebAssembly.

95 lines (82 loc) 3.17 kB
// Чистая JS-реализация: принимает JSON-строку или объект/массив объектов и возвращает HTML-строку export const JsonToHtmlJs = (input) => { // Экранирование текста const escapeHtml = (str) => String(str) .replace(/&(?!(?:[a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+);)/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;') .replace(/'/g, '&#39;'); // Экранирование для значений атрибутов (совпадает с escapeHtml) const escapeAttr = (str) => escapeHtml(str); // Рендер атрибутов: id, class, затем пары из attrs const renderAttrs = (node) => { const parts = []; if (node && typeof node.id === 'string' && node.id.length > 0) { parts.push(`id="${escapeAttr(node.id)}"`); } if (node && typeof node.class === 'string' && node.class.length > 0) { parts.push(`class="${escapeAttr(node.class)}"`); } if (Array.isArray(node?.attrs)) { for (const pair of node.attrs) { if (!Array.isArray(pair) || pair.length < 2) continue; const [k, v] = pair; if (typeof k !== 'string') continue; parts.push(`${k}="${escapeAttr(v)}"`); } } return parts.length ? ' ' + parts.join(' ') : ''; }; // Рендер одного узла const renderNode = (node) => { if (!node || typeof node !== 'object') { throw new Error('Invalid node: expected object'); } const t = node.obj_type; switch (t) { case 'Element': { const tag = node.name || ''; if (!tag) throw new Error('Element node must have a non-empty name'); const attrs = renderAttrs(node); const children = Array.isArray(node.children) ? node.children.map(renderNode).join('') : ''; return `<${tag}${attrs}>${children}</${tag}>`; } case 'Text': { const text = node.text != null ? node.text : ''; return escapeHtml(text); } case 'Comment': { const text = node.text != null ? String(node.text) : ''; return `<!-- ${text} -->`; } case 'Doctype': { const name = node.name || ''; if (!name) throw new Error('Doctype node must have a non-empty name'); return `<!DOCTYPE ${name}>`; } default: throw new Error(`Unknown obj_type: ${t}`); } }; // Преобразуем вход к массиву узлов const toArray = (value) => Array.isArray(value) ? value : [value]; if (typeof input === 'string') { if (input.trim() === '') { throw new Error('JSON must be a non-empty string'); } let parsed; try { parsed = JSON.parse(input); } catch (_e) { throw new Error('JSON string is not valid!'); } const nodes = toArray(parsed); return nodes.map(renderNode).join(''); } if (input && typeof input === 'object') { const nodes = toArray(input); return nodes.map(renderNode).join(''); } throw new Error('Input must be a non-empty JSON string or a non-null object/array'); };