mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 21:19:01 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			107 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import ws from "./ws.js";
 | 
						|
import froca from "./froca.js";
 | 
						|
import type FAttribute from "../entities/fattribute.js";
 | 
						|
import type FNote from "../entities/fnote.js";
 | 
						|
 | 
						|
async function renderAttribute(attribute: FAttribute, renderIsInheritable: boolean) {
 | 
						|
    const isInheritable = renderIsInheritable && attribute.isInheritable ? `(inheritable)` : "";
 | 
						|
    const $attr = $("<span>");
 | 
						|
 | 
						|
    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 $("<a>", {
 | 
						|
        href: `#root/${noteId}`,
 | 
						|
        class: "reference-link"
 | 
						|
    }).text(note.title);
 | 
						|
}
 | 
						|
 | 
						|
async function renderAttributes(attributes: FAttribute[], renderIsInheritable: boolean) {
 | 
						|
    const $container = $('<span class="rendered-note-attributes">');
 | 
						|
 | 
						|
    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", "geolocation", "docName"];
 | 
						|
 | 
						|
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
 | 
						|
};
 |