import ws from "./ws.js"; import froca from "./froca.js"; import FAttribute from "../entities/fattribute.js"; import FNote from "../entities/fnote.js"; async function renderAttribute(attribute: FAttribute, renderIsInheritable: boolean) { const isInheritable = renderIsInheritable && attribute.isInheritable ? `(inheritable)` : ''; const $attr = $(""); if (attribute.type === 'label') { $attr.append(document.createTextNode(`#${attribute.name}${isInheritable}`)); if (attribute.value) { $attr.append('='); $attr.append(document.createTextNode(formatValue(attribute.value))); } } else if (attribute.type === 'relation') { if (attribute.isAutoLink) { return $attr; } // when the relation has just been created, then it might not have a value if (attribute.value) { $attr.append(document.createTextNode(`~${attribute.name}${isInheritable}=`)); const link = await createLink(attribute.value); if (link) { $attr.append(link); } } } else { ws.logError(`Unknown attr type: ${attribute.type}`); } return $attr; } function formatValue(val: string) { if (/^[\p{L}\p{N}\-_,.]+$/u.test(val)) { return val; } else if (!val.includes('"')) { return `"${val}"`; } else if (!val.includes("'")) { return `'${val}'`; } else if (!val.includes("`")) { return `\`${val}\``; } else { return `"${val.replace(/"/g, '\\"')}"`; } } async function createLink(noteId: string) { const note = await froca.getNote(noteId); if (!note) { return; } return $("", { href: `#root/${noteId}`, class: 'reference-link' }) .text(note.title); } async function renderAttributes(attributes: FAttribute[], renderIsInheritable: boolean) { const $container = $(''); for (let i = 0; i < attributes.length; i++) { const attribute = attributes[i]; const $attr = await renderAttribute(attribute, renderIsInheritable); $container.append($attr.html()); // .html() to get only inner HTML, we don't want any spans if (i < attributes.length - 1) { $container.append(" "); } } return $container; } const HIDDEN_ATTRIBUTES = [ 'originalFileName', 'fileSize', 'template', 'inherit', 'cssClass', 'iconClass', 'pageSize', 'viewType' ]; async function renderNormalAttributes(note: FNote) { const promotedDefinitionAttributes = note.getPromotedDefinitionAttributes(); let attrs = note.getAttributes(); if (promotedDefinitionAttributes.length > 0) { attrs = attrs.filter(attr => !!promotedDefinitionAttributes.find(promAttr => promAttr.isDefinitionFor(attr))); } else { attrs = attrs.filter( attr => !attr.isDefinition() && !attr.isAutoLink && !HIDDEN_ATTRIBUTES.includes(attr.name) && attr.noteId === note.noteId ); } const $renderedAttributes = await renderAttributes(attrs, false); return { count: attrs.length, $renderedAttributes } } export default { renderAttribute, renderAttributes, renderNormalAttributes }