testomatio-editor-blocks 0.4.30 → 0.4.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package/editor/customMarkdownConverter.js +2 -3
- package/package/editor/fileDisplayUrl.d.ts +3 -0
- package/package/editor/fileDisplayUrl.js +15 -0
- package/package/index.d.ts +1 -0
- package/package/index.js +1 -0
- package/package.json +1 -1
- package/src/editor/customMarkdownConverter.test.ts +20 -7
- package/src/editor/customMarkdownConverter.ts +2 -3
- package/src/editor/fileDisplayUrl.ts +18 -0
- package/src/index.ts +6 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isLinkInlineContent, isStyledTextInlineContent, } from "@blocknote/core";
|
|
2
|
+
import { resolveFileDisplayUrl } from "./fileDisplayUrl";
|
|
2
3
|
import { isStepsHeading } from "./blocks/step";
|
|
3
4
|
const BASE_BLOCK_PROPS = {
|
|
4
5
|
textAlignment: "left",
|
|
@@ -269,9 +270,8 @@ function serializeBlock(block, ctx, orderedIndex, stepIndex) {
|
|
|
269
270
|
case "file": {
|
|
270
271
|
const url = block.props.url || "";
|
|
271
272
|
const name = block.props.name || "";
|
|
272
|
-
const caption = block.props.caption || "";
|
|
273
273
|
if (url) {
|
|
274
|
-
const displayUrl =
|
|
274
|
+
const displayUrl = resolveFileDisplayUrl(name, url);
|
|
275
275
|
lines.push(`[](${url})`);
|
|
276
276
|
}
|
|
277
277
|
return flattenWithBlankLine(lines, true);
|
|
@@ -1230,7 +1230,6 @@ export function markdownToBlocks(markdown) {
|
|
|
1230
1230
|
type: "file",
|
|
1231
1231
|
props: {
|
|
1232
1232
|
name: fileMatch[1] || "",
|
|
1233
|
-
caption: fileMatch[2] || "",
|
|
1234
1233
|
url: fileMatch[3],
|
|
1235
1234
|
},
|
|
1236
1235
|
children: [],
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
let resolver = null;
|
|
2
|
+
export function setFileDisplayUrlResolver(fn) {
|
|
3
|
+
resolver = fn;
|
|
4
|
+
}
|
|
5
|
+
export function resolveFileDisplayUrl(fileName, fallbackUrl) {
|
|
6
|
+
var _a;
|
|
7
|
+
if (resolver) {
|
|
8
|
+
return resolver(fileName);
|
|
9
|
+
}
|
|
10
|
+
const ext = ((_a = fileName.split(".").pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || "";
|
|
11
|
+
if (ext) {
|
|
12
|
+
return `/images/file-type-icons/${ext}.svg`;
|
|
13
|
+
}
|
|
14
|
+
return fallbackUrl;
|
|
15
|
+
}
|
package/package/index.d.ts
CHANGED
|
@@ -5,5 +5,6 @@ export { markdownToHtml, htmlToMarkdown } from "./editor/blocks/markdown";
|
|
|
5
5
|
export { blocksToMarkdown, markdownToBlocks, type CustomEditorBlock, type CustomPartialBlock, } from "./editor/customMarkdownConverter";
|
|
6
6
|
export { useStepAutocomplete, parseStepsFromJsonApi, setStepsFetcher, type StepSuggestion, type StepJsonApiDocument, type StepJsonApiResource, } from "./editor/stepAutocomplete";
|
|
7
7
|
export { useStepImageUpload, setImageUploadHandler, type StepImageUploadHandler, } from "./editor/stepImageUpload";
|
|
8
|
+
export { setFileDisplayUrlResolver, resolveFileDisplayUrl, type FileDisplayUrlResolver, } from "./editor/fileDisplayUrl";
|
|
8
9
|
export { createMarkdownPasteHandler } from "./editor/createMarkdownPasteHandler";
|
|
9
10
|
export declare const testomatioEditorClassName = "markdown testomatio-editor";
|
package/package/index.js
CHANGED
|
@@ -5,5 +5,6 @@ export { markdownToHtml, htmlToMarkdown } from "./editor/blocks/markdown";
|
|
|
5
5
|
export { blocksToMarkdown, markdownToBlocks, } from "./editor/customMarkdownConverter";
|
|
6
6
|
export { useStepAutocomplete, parseStepsFromJsonApi, setStepsFetcher, } from "./editor/stepAutocomplete";
|
|
7
7
|
export { useStepImageUpload, setImageUploadHandler, } from "./editor/stepImageUpload";
|
|
8
|
+
export { setFileDisplayUrlResolver, resolveFileDisplayUrl, } from "./editor/fileDisplayUrl";
|
|
8
9
|
export { createMarkdownPasteHandler } from "./editor/createMarkdownPasteHandler";
|
|
9
10
|
export const testomatioEditorClassName = "markdown testomatio-editor";
|
package/package.json
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type CustomEditorBlock,
|
|
7
7
|
type CustomPartialBlock,
|
|
8
8
|
} from "./customMarkdownConverter";
|
|
9
|
+
import { setFileDisplayUrlResolver } from "./fileDisplayUrl";
|
|
9
10
|
|
|
10
11
|
const baseProps = {
|
|
11
12
|
textAlignment: "left" as const,
|
|
@@ -1515,7 +1516,12 @@ describe("markdownToBlocks", () => {
|
|
|
1515
1516
|
});
|
|
1516
1517
|
|
|
1517
1518
|
describe("file block serialization", () => {
|
|
1518
|
-
it("serializes a file block
|
|
1519
|
+
it("serializes a file block using display url resolver", () => {
|
|
1520
|
+
setFileDisplayUrlResolver((name: string) => {
|
|
1521
|
+
const ext = name.split(".").pop()?.toLowerCase() || "";
|
|
1522
|
+
return `/images/file-type-icons/${ext}.svg`;
|
|
1523
|
+
});
|
|
1524
|
+
|
|
1519
1525
|
const blocks: CustomEditorBlock[] = [
|
|
1520
1526
|
{
|
|
1521
1527
|
id: "1",
|
|
@@ -1524,7 +1530,7 @@ describe("file block serialization", () => {
|
|
|
1524
1530
|
...baseProps,
|
|
1525
1531
|
url: "https://example.com/file.pdf",
|
|
1526
1532
|
name: "report.pdf",
|
|
1527
|
-
caption: "
|
|
1533
|
+
caption: "",
|
|
1528
1534
|
},
|
|
1529
1535
|
content: undefined as any,
|
|
1530
1536
|
children: [],
|
|
@@ -1532,9 +1538,11 @@ describe("file block serialization", () => {
|
|
|
1532
1538
|
];
|
|
1533
1539
|
const md = blocksToMarkdown(blocks);
|
|
1534
1540
|
expect(md).toBe("[](https://example.com/file.pdf)");
|
|
1541
|
+
|
|
1542
|
+
setFileDisplayUrlResolver(null);
|
|
1535
1543
|
});
|
|
1536
1544
|
|
|
1537
|
-
it("falls back to url when
|
|
1545
|
+
it("falls back to url when no resolver is set", () => {
|
|
1538
1546
|
const blocks: CustomEditorBlock[] = [
|
|
1539
1547
|
{
|
|
1540
1548
|
id: "1",
|
|
@@ -1550,7 +1558,7 @@ describe("file block serialization", () => {
|
|
|
1550
1558
|
},
|
|
1551
1559
|
];
|
|
1552
1560
|
const md = blocksToMarkdown(blocks);
|
|
1553
|
-
expect(md).toBe("[.toBe("[](https://example.com/file.pdf)");
|
|
1554
1562
|
});
|
|
1555
1563
|
|
|
1556
1564
|
it("outputs nothing when url is empty", () => {
|
|
@@ -1580,7 +1588,6 @@ describe("file block parsing", () => {
|
|
|
1580
1588
|
expect(blocks).toHaveLength(1);
|
|
1581
1589
|
expect(blocks[0].type).toBe("file");
|
|
1582
1590
|
expect((blocks[0].props as any).name).toBe("report.pdf");
|
|
1583
|
-
expect((blocks[0].props as any).caption).toBe("/images/file-type-icons/pdf.svg");
|
|
1584
1591
|
expect((blocks[0].props as any).url).toBe("https://example.com/file.pdf");
|
|
1585
1592
|
});
|
|
1586
1593
|
|
|
@@ -1601,6 +1608,11 @@ describe("file block parsing", () => {
|
|
|
1601
1608
|
});
|
|
1602
1609
|
|
|
1603
1610
|
it("round-trips file blocks through serialize and parse", () => {
|
|
1611
|
+
setFileDisplayUrlResolver((name: string) => {
|
|
1612
|
+
const ext = name.split(".").pop()?.toLowerCase() || "";
|
|
1613
|
+
return `/images/file-type-icons/${ext}.svg`;
|
|
1614
|
+
});
|
|
1615
|
+
|
|
1604
1616
|
const blocks: CustomEditorBlock[] = [
|
|
1605
1617
|
{
|
|
1606
1618
|
id: "1",
|
|
@@ -1609,7 +1621,7 @@ describe("file block parsing", () => {
|
|
|
1609
1621
|
...baseProps,
|
|
1610
1622
|
url: "https://example.com/doc.xlsx",
|
|
1611
1623
|
name: "doc.xlsx",
|
|
1612
|
-
caption: "
|
|
1624
|
+
caption: "",
|
|
1613
1625
|
},
|
|
1614
1626
|
content: undefined as any,
|
|
1615
1627
|
children: [],
|
|
@@ -1621,6 +1633,7 @@ describe("file block parsing", () => {
|
|
|
1621
1633
|
expect(parsed[0].type).toBe("file");
|
|
1622
1634
|
expect((parsed[0].props as any).url).toBe("https://example.com/doc.xlsx");
|
|
1623
1635
|
expect((parsed[0].props as any).name).toBe("doc.xlsx");
|
|
1624
|
-
|
|
1636
|
+
|
|
1637
|
+
setFileDisplayUrlResolver(null);
|
|
1625
1638
|
});
|
|
1626
1639
|
});
|
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
PartialBlock,
|
|
9
9
|
Styles,
|
|
10
10
|
} from "@blocknote/core";
|
|
11
|
+
import { resolveFileDisplayUrl } from "./fileDisplayUrl";
|
|
11
12
|
import type { customSchema } from "./customSchema";
|
|
12
13
|
import { isStepsHeading } from "./blocks/step";
|
|
13
14
|
|
|
@@ -347,9 +348,8 @@ function serializeBlock(
|
|
|
347
348
|
case "file": {
|
|
348
349
|
const url = (block.props as any).url || "";
|
|
349
350
|
const name = (block.props as any).name || "";
|
|
350
|
-
const caption = (block.props as any).caption || "";
|
|
351
351
|
if (url) {
|
|
352
|
-
const displayUrl =
|
|
352
|
+
const displayUrl = resolveFileDisplayUrl(name, url);
|
|
353
353
|
lines.push(`[](${url})`);
|
|
354
354
|
}
|
|
355
355
|
return flattenWithBlankLine(lines, true);
|
|
@@ -1472,7 +1472,6 @@ export function markdownToBlocks(markdown: string): CustomPartialBlock[] {
|
|
|
1472
1472
|
type: "file",
|
|
1473
1473
|
props: {
|
|
1474
1474
|
name: fileMatch[1] || "",
|
|
1475
|
-
caption: fileMatch[2] || "",
|
|
1476
1475
|
url: fileMatch[3],
|
|
1477
1476
|
},
|
|
1478
1477
|
children: [],
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type FileDisplayUrlResolver = (fileName: string) => string;
|
|
2
|
+
|
|
3
|
+
let resolver: FileDisplayUrlResolver | null = null;
|
|
4
|
+
|
|
5
|
+
export function setFileDisplayUrlResolver(fn: FileDisplayUrlResolver | null) {
|
|
6
|
+
resolver = fn;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function resolveFileDisplayUrl(fileName: string, fallbackUrl: string): string {
|
|
10
|
+
if (resolver) {
|
|
11
|
+
return resolver(fileName);
|
|
12
|
+
}
|
|
13
|
+
const ext = fileName.split(".").pop()?.toLowerCase() || "";
|
|
14
|
+
if (ext) {
|
|
15
|
+
return `/images/file-type-icons/${ext}.svg`;
|
|
16
|
+
}
|
|
17
|
+
return fallbackUrl;
|
|
18
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -30,6 +30,12 @@ export {
|
|
|
30
30
|
type StepImageUploadHandler,
|
|
31
31
|
} from "./editor/stepImageUpload";
|
|
32
32
|
|
|
33
|
+
export {
|
|
34
|
+
setFileDisplayUrlResolver,
|
|
35
|
+
resolveFileDisplayUrl,
|
|
36
|
+
type FileDisplayUrlResolver,
|
|
37
|
+
} from "./editor/fileDisplayUrl";
|
|
38
|
+
|
|
33
39
|
export { createMarkdownPasteHandler } from "./editor/createMarkdownPasteHandler";
|
|
34
40
|
|
|
35
41
|
export const testomatioEditorClassName = "markdown testomatio-editor";
|