fix(search): empty mindmap note breaking search (closes #1107)

pull/1125/head v0.91.6
Elian Doran 2025-02-03 18:59:56 +07:00
parent 438f28b5b0
commit 79e830b6ea
No known key found for this signature in database
2 changed files with 73 additions and 46 deletions

@ -0,0 +1,13 @@
import { describe, it, expect } from "vitest";
import { processMindmapContent } from "./note_content_fulltext.js";
describe("processMindmapContent", () => {
it("supports empty JSON", () => {
expect(processMindmapContent("{}")).toEqual("");
});
it("supports blank text / invalid JSON", () => {
expect(processMindmapContent("")).toEqual("");
expect(processMindmapContent(`{ "node": " }`)).toEqual("");
});
});

@ -131,7 +131,53 @@ class NoteContentFulltextExp extends Expression {
content = content.replace(/ /g, " ");
} else if (type === "mindMap" && mime === "application/json") {
let mindMapcontent = JSON.parse(content);
content = processMindmapContent(content);
} else if (type === "canvas" && mime === "application/json") {
interface Element {
type: string;
text?: string; // Optional since not all objects have a `text` property
id: string;
[key: string]: any; // Other properties that may exist
}
let canvasContent = JSON.parse(content);
const elements: Element[] = canvasContent.elements;
const texts = elements
.filter((element: Element) => element.type === "text" && element.text) // Filter for 'text' type elements with a 'text' property
.map((element: Element) => element.text!); // Use `!` to assert `text` is defined after filtering
content = normalize(texts.toString());
}
return content.trim();
}
stripTags(content: string) {
// we want to allow link to preserve URLs: https://github.com/zadam/trilium/issues/2412
// we want to insert space in place of block tags (because they imply text separation)
// but we don't want to insert text for typical formatting inline tags which can occur within one word
const linkTag = "a";
const inlineFormattingTags = ["b", "strong", "em", "i", "span", "big", "small", "font", "sub", "sup"];
// replace tags which imply text separation with a space
content = striptags(content, [linkTag, ...inlineFormattingTags], " ");
// replace the inline formatting tags (but not links) without a space
content = striptags(content, [linkTag], "");
// at least the closing link tag can be easily stripped
return content.replace(/<\/a>/gi, "");
}
}
export function processMindmapContent(content: string) {
let mindMapcontent;
try {
mindMapcontent = JSON.parse(content);
} catch (e) {
return "";
}
// Define interfaces for the JSON structure
interface MindmapNode {
@ -156,7 +202,11 @@ class NoteContentFulltextExp extends Expression {
}
// Recursive function to collect all topics
function collectTopics(node: MindmapNode): string[] {
function collectTopics(node?: MindmapNode): string[] {
if (!node) {
return [];
}
// Collect the current node's topic
let topics = [node.topic];
@ -176,43 +226,7 @@ class NoteContentFulltextExp extends Expression {
// Combine topics into a single string
const topicsString = topicsArray.join(", ");
content = normalize(topicsString.toString());
} else if (type === "canvas" && mime === "application/json") {
interface Element {
type: string;
text?: string; // Optional since not all objects have a `text` property
id: string;
[key: string]: any; // Other properties that may exist
}
let canvasContent = JSON.parse(content);
const elements: Element[] = canvasContent.elements;
const texts = elements
.filter((element: Element) => element.type === "text" && element.text) // Filter for 'text' type elements with a 'text' property
.map((element: Element) => element.text!); // Use `!` to assert `text` is defined after filtering
content = normalize(texts.toString());
}
return content.trim();
}
stripTags(content: string) {
// we want to allow link to preserve URLs: https://github.com/zadam/trilium/issues/2412
// we want to insert space in place of block tags (because they imply text separation)
// but we don't want to insert text for typical formatting inline tags which can occur within one word
const linkTag = "a";
const inlineFormattingTags = ["b", "strong", "em", "i", "span", "big", "small", "font", "sub", "sup"];
// replace tags which imply text separation with a space
content = striptags(content, [linkTag, ...inlineFormattingTags], " ");
// replace the inline formatting tags (but not links) without a space
content = striptags(content, [linkTag], "");
// at least the closing link tag can be easily stripped
return content.replace(/<\/a>/gi, "");
}
return normalize(topicsString.toString());
}
export default NoteContentFulltextExp;