feat(extra-sheet) : add inline cell editing

This commit is contained in:
2026-09-25 16:08:40 +07:00 Unverified
parent 6127682d5d
commit 37b7cb39f6
6 changed files with 119 additions and 140 deletions
+9
View File
@@ -1,6 +1,7 @@
import { describe, expect, it } from "vitest";
import {
extraRichTextToPlainText,
applyRichTextStylePatch,
normalizeExtraRichText,
richTextContentSignature,
@@ -34,6 +35,14 @@ describe("rich text sanitization", () => {
});
describe("legacy Extra rich text conversion", () => {
it("converts stored markup into safe multiline text for cell editing", () => {
expect(extraRichTextToPlainText(
"<p><strong>First</strong><br>line</p><p>Second &amp; safe<script>bad()</script></p>",
)).toBe("First\nline\nSecond & safe");
expect(normalizeExtraRichText(extraRichTextToPlainText("<p>A<br>B</p>")))
.toBe("<p>A<br>B</p>");
});
it("escapes plain text, preserves newlines, and converts phrase colors", () => {
expect(normalizeExtraRichText("<unsafe>\nMASSIVE damage", [
{ text: "MASSIVE", color: "#ff0000" },
+18
View File
@@ -1,4 +1,5 @@
import sanitizeHtml from "sanitize-html";
import { decodeHTML } from "entities";
import { highlightTextSegments, type TextHighlight } from "@/lib/guides/highlights";
@@ -112,6 +113,23 @@ export function normalizeExtraRichText(
return content ? `<p>${content}</p>` : "";
}
/** Converts stored Extra Sheet rich text into editable plain text. */
export function extraRichTextToPlainText(value: string): string {
const withLineBreaks = normalizeExtraRichText(value)
.replace(/<br\s*\/?>/gi, "\n")
.replace(/<\/(?:blockquote|li|ol|p|pre|ul)>/gi, "\n");
let text = "";
sanitizeHtml(withLineBreaks, {
allowedTags: [],
allowedAttributes: {},
textFilter: (chunk) => {
text += chunk;
return "";
},
});
return decodeHTML(text).replace(/\n$/, "");
}
const RICH_TEXT_MARK_TAGS = {
bold: "strong",
italic: "em",