From f481007b9a2ddeea19f9b4e7909976d35d29e7f8 Mon Sep 17 00:00:00 2001 From: ajnart Date: Wed, 29 Jul 2026 20:06:59 +0200 Subject: [PATCH] Revert "fix: safely extract notebook summaries" This reverts commit fa3d0375c5197bb5a3b272e207ecf6277f20c93b. --- packages/widgets/src/notebook/component.tsx | 31 ++++++++----------- .../src/notebook/mobile-summary.spec.ts | 20 ------------ .../widgets/src/notebook/mobile-summary.ts | 15 --------- 3 files changed, 13 insertions(+), 53 deletions(-) delete mode 100644 packages/widgets/src/notebook/mobile-summary.spec.ts delete mode 100644 packages/widgets/src/notebook/mobile-summary.ts diff --git a/packages/widgets/src/notebook/component.tsx b/packages/widgets/src/notebook/component.tsx index b8ef2191b..e8dc77498 100644 --- a/packages/widgets/src/notebook/component.tsx +++ b/packages/widgets/src/notebook/component.tsx @@ -1,38 +1,33 @@ "use client"; import dynamic from "next/dynamic"; -import { useEffect, useState } from "react"; import { useScopedI18n } from "@homarr/translation/client"; import { WidgetMobileSummary } from "../common/mobile-summary"; import type { WidgetComponentProps } from "../definition"; -import { extractNotebookExcerpt } from "./mobile-summary"; const Notebook = dynamic(() => import("./notebook").then((module) => module.Notebook), { ssr: false, }); -interface NotebookMobileSummaryProps { - content: string; - label: string; -} - -const NotebookMobileSummary = ({ content, label }: NotebookMobileSummaryProps) => { - const [excerpt, setExcerpt] = useState(""); - - useEffect(() => { - setExcerpt(extractNotebookExcerpt(content)); - }, [content]); - - return ; -}; - export default function NotebookWidget(props: WidgetComponentProps<"notebook">) { const t = useScopedI18n("widget.notebook"); if (props.displayMode === "mobileSummary") { - return ; + const excerpt = props.options.content + .replace(/]*>[\s\S]*?<\/style>/gi, " ") + .replace(/]*>[\s\S]*?<\/script>/gi, " ") + .replace(/<[^>]+>/g, " ") + .replace(/&(?:nbsp|#160);/gi, " ") + .replace(/&(?:amp|#38);/gi, "&") + .replace(/&(?:lt|#60);/gi, "<") + .replace(/&(?:gt|#62);/gi, ">") + .replace(/&(?:quot|#34);/gi, '"') + .replace(/\s+/g, " ") + .trim(); + + return ; } return ; diff --git a/packages/widgets/src/notebook/mobile-summary.spec.ts b/packages/widgets/src/notebook/mobile-summary.spec.ts deleted file mode 100644 index 992867ba6..000000000 --- a/packages/widgets/src/notebook/mobile-summary.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { describe, expect, test } from "vitest"; - -import { extractNotebookExcerpt } from "./mobile-summary"; - -describe("extractNotebookExcerpt", () => { - test("returns decoded plain text from notebook HTML", () => { - expect(extractNotebookExcerpt("

Hello world

Fish & chips

")).toBe("Hello world Fish & chips"); - }); - - test("removes script and style content including whitespace before closing brackets", () => { - const content = - '

Visible

Still visible

'; - - expect(extractNotebookExcerpt(content)).toBe("Visible Still visible"); - }); - - test("returns an empty excerpt when there is no visible content", () => { - expect(extractNotebookExcerpt("")).toBe(""); - }); -}); diff --git a/packages/widgets/src/notebook/mobile-summary.ts b/packages/widgets/src/notebook/mobile-summary.ts deleted file mode 100644 index dc935d3df..000000000 --- a/packages/widgets/src/notebook/mobile-summary.ts +++ /dev/null @@ -1,15 +0,0 @@ -export const extractNotebookExcerpt = (content: string) => { - const parsedDocument = new DOMParser().parseFromString(content, "text/html"); - parsedDocument.querySelectorAll("script, style").forEach((element) => { - element.remove(); - }); - - const textWalker = parsedDocument.createTreeWalker(parsedDocument.body, NodeFilter.SHOW_TEXT); - const textParts: string[] = []; - - while (textWalker.nextNode()) { - textParts.push(textWalker.currentNode.textContent ?? ""); - } - - return textParts.join(" ").replace(/\s+/g, " ").trim(); -};