mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-08-23 06:42:15 +10:00
* feat(editor): add multicolor highlight with auto-contrast text Enable the Tiptap Highlight extension in multicolor mode, replacing the single-color yellow toggle with a full color picker (16 presets + custom). When the chosen highlight color is perceptually dark, text inside the mark automatically renders white for readability. Changes span the full pipeline: - Editor: ColorPicker UI, extended renderHTML for contrast detection - PDF: normalizeMarkElements preserves data-color as inline style - DOCX: mergeStyle reads actual background-color from <mark> - Utils: new isDarkColor() luminance helper Backward-compatible: legacy <mark> without data-color still renders yellow. Resolves #3109 * fix: handle multicolor highlight edge cases --------- Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
72 lines
2.6 KiB
TypeScript
72 lines
2.6 KiB
TypeScript
// @vitest-environment happy-dom
|
|
|
|
import { describe, expect, it } from "vitest";
|
|
import { htmlToParagraphs } from "./html-to-docx";
|
|
|
|
describe("htmlToParagraphs", () => {
|
|
it("returns [] for empty / whitespace-only input", () => {
|
|
expect(htmlToParagraphs("")).toEqual([]);
|
|
expect(htmlToParagraphs(" \n ")).toEqual([]);
|
|
});
|
|
|
|
it("returns at least one paragraph for a simple <p> element", () => {
|
|
const result = htmlToParagraphs("<p>Hello world</p>");
|
|
expect(result.length).toBeGreaterThanOrEqual(1);
|
|
});
|
|
|
|
it("converts plain text nodes at the body root into a paragraph", () => {
|
|
const result = htmlToParagraphs("Just some plain text");
|
|
expect(result.length).toBe(1);
|
|
});
|
|
|
|
it("emits separate paragraphs for multiple top-level blocks", () => {
|
|
const result = htmlToParagraphs("<p>One</p><p>Two</p><p>Three</p>");
|
|
expect(result.length).toBeGreaterThanOrEqual(3);
|
|
});
|
|
|
|
it("treats <h1>..<h6> as block-level paragraphs (one per heading)", () => {
|
|
const result = htmlToParagraphs("<h1>A</h1><h2>B</h2><h3>C</h3>");
|
|
expect(result.length).toBe(3);
|
|
});
|
|
|
|
it("renders nested <strong>, <em>, <u>, <s> inline styling without throwing", () => {
|
|
const result = htmlToParagraphs("<p><strong>Bold</strong> <em>italic</em> <u>under</u> <s>strike</s></p>");
|
|
expect(result.length).toBe(1);
|
|
});
|
|
|
|
it("renders links and lists without throwing", () => {
|
|
const html = '<p><a href="https://example.com">link</a></p><ul><li>One</li><li>Two</li></ul>';
|
|
const result = htmlToParagraphs(html);
|
|
expect(result.length).toBeGreaterThanOrEqual(2);
|
|
});
|
|
|
|
it("accepts custom font + size config without throwing", () => {
|
|
const result = htmlToParagraphs("<p>Hello</p>", {
|
|
font: "Roboto",
|
|
size: 22,
|
|
color: "111111",
|
|
linkColor: "0563C1",
|
|
});
|
|
expect(result.length).toBe(1);
|
|
});
|
|
|
|
it("ignores HTML comments and script/style tags at the root", () => {
|
|
// Comments at root and script tags don't add paragraph output.
|
|
const result = htmlToParagraphs("<!--c--><script>x</script><p>Hello</p>");
|
|
expect(result.length).toBeGreaterThanOrEqual(1);
|
|
});
|
|
|
|
it("applies default yellow shading for <mark> without background-color", () => {
|
|
const result = htmlToParagraphs("<p><mark>highlighted</mark></p>");
|
|
const json = JSON.stringify(result[0]);
|
|
// TextRun with shading should contain "FFFF00" in serialized output
|
|
expect(json).toContain("FFFF00");
|
|
});
|
|
|
|
it("reads custom background-color from <mark> style for shading fill", () => {
|
|
const result = htmlToParagraphs('<p><mark style="background-color: rgba(204, 255, 204, 1)">green</mark></p>');
|
|
const json = JSON.stringify(result[0]);
|
|
expect(json).toContain("CCFFCC");
|
|
});
|
|
});
|