@tiptap/static-renderer 3.23.5 → 3.24.0
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/README.md +33 -0
- package/dist/index.cjs +59 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +57 -7
- package/dist/index.d.ts +57 -7
- package/dist/index.js +62 -18
- package/dist/index.js.map +1 -1
- package/dist/json/html-string/index.cjs +1 -1
- package/dist/json/html-string/index.cjs.map +1 -1
- package/dist/json/html-string/index.js +1 -1
- package/dist/json/html-string/index.js.map +1 -1
- package/dist/json/react/index.cjs +11 -8
- package/dist/json/react/index.cjs.map +1 -1
- package/dist/json/react/index.js +11 -8
- package/dist/json/react/index.js.map +1 -1
- package/dist/json/renderer.cjs.map +1 -1
- package/dist/json/renderer.js.map +1 -1
- package/dist/pm/html-string/index.cjs +42 -6
- package/dist/pm/html-string/index.cjs.map +1 -1
- package/dist/pm/html-string/index.d.cts +42 -4
- package/dist/pm/html-string/index.d.ts +42 -4
- package/dist/pm/html-string/index.js +45 -7
- package/dist/pm/html-string/index.js.map +1 -1
- package/dist/pm/markdown/index.cjs +46 -8
- package/dist/pm/markdown/index.cjs.map +1 -1
- package/dist/pm/markdown/index.d.cts +37 -3
- package/dist/pm/markdown/index.d.ts +37 -3
- package/dist/pm/markdown/index.js +49 -9
- package/dist/pm/markdown/index.js.map +1 -1
- package/dist/pm/react/index.cjs +41 -12
- package/dist/pm/react/index.cjs.map +1 -1
- package/dist/pm/react/index.d.cts +38 -4
- package/dist/pm/react/index.d.ts +38 -4
- package/dist/pm/react/index.js +44 -13
- package/dist/pm/react/index.js.map +1 -1
- package/package.json +21 -22
- package/src/helpers.ts +22 -6
- package/src/json/html-string/string.ts +4 -1
- package/src/json/react/react.ts +12 -9
- package/src/json/renderer.ts +7 -3
- package/src/pm/extensionRenderer.ts +62 -5
- package/src/pm/html-string/html-string.ts +40 -10
- package/src/pm/markdown/markdown.ts +11 -2
- package/src/pm/react/react.ts +27 -10
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* oslint-disableno-explicit-any */
|
|
2
2
|
import type { DOMOutputSpecArray, Extensions, JSONContent } from '@tiptap/core'
|
|
3
3
|
import type { DOMOutputSpec, Mark, Node } from '@tiptap/pm/model'
|
|
4
4
|
|
|
@@ -9,22 +9,38 @@ import {
|
|
|
9
9
|
serializeChildrenToHTMLString,
|
|
10
10
|
} from '../../json/html-string/string.js'
|
|
11
11
|
import type { TiptapStaticRendererOptions } from '../../json/renderer.js'
|
|
12
|
-
import {
|
|
12
|
+
import type { StaticEditorOptions } from '../extensionRenderer.js'
|
|
13
|
+
import { applyStaticEditorOptionsToExtensions, renderToElement } from '../extensionRenderer.js'
|
|
13
14
|
|
|
14
|
-
export {
|
|
15
|
+
export {
|
|
16
|
+
serializeAttrsToHTMLString,
|
|
17
|
+
serializeChildrenToHTMLString,
|
|
18
|
+
} from '../../json/html-string/string.js'
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* HTML elements that cannot be self-closing and must always have a closing tag.
|
|
18
22
|
* These elements must be rendered as <tag></tag> even when empty, not <tag />.
|
|
19
23
|
*/
|
|
20
|
-
const NON_SELF_CLOSING_TAGS = new Set([
|
|
24
|
+
const NON_SELF_CLOSING_TAGS = new Set([
|
|
25
|
+
'iframe',
|
|
26
|
+
'script',
|
|
27
|
+
'style',
|
|
28
|
+
'title',
|
|
29
|
+
'textarea',
|
|
30
|
+
'div',
|
|
31
|
+
'span',
|
|
32
|
+
'a',
|
|
33
|
+
'button',
|
|
34
|
+
])
|
|
21
35
|
|
|
22
36
|
/**
|
|
23
37
|
* Take a DOMOutputSpec and return a function that can render it to a string
|
|
24
38
|
* @param content The DOMOutputSpec to convert to a string
|
|
25
39
|
* @returns A function that can render the DOMOutputSpec to a string
|
|
26
40
|
*/
|
|
27
|
-
export function domOutputSpecToHTMLString(
|
|
41
|
+
export function domOutputSpecToHTMLString(
|
|
42
|
+
content: DOMOutputSpec,
|
|
43
|
+
): (children?: string | string[]) => string {
|
|
28
44
|
if (typeof content === 'string') {
|
|
29
45
|
return () => escapeHTML(content)
|
|
30
46
|
}
|
|
@@ -46,10 +62,12 @@ export function domOutputSpecToHTMLString(content: DOMOutputSpec): (children?: s
|
|
|
46
62
|
if (typeof attrs === 'object') {
|
|
47
63
|
if (Array.isArray(attrs)) {
|
|
48
64
|
if (children === undefined) {
|
|
49
|
-
return child =>
|
|
65
|
+
return child =>
|
|
66
|
+
`<${tag}>${domOutputSpecToHTMLString(attrs as DOMOutputSpecArray)(child)}</${tag}>`
|
|
50
67
|
}
|
|
51
68
|
if (children === 0) {
|
|
52
|
-
return child =>
|
|
69
|
+
return child =>
|
|
70
|
+
`<${tag}>${domOutputSpecToHTMLString(attrs as DOMOutputSpecArray)(child)}</${tag}>`
|
|
53
71
|
}
|
|
54
72
|
return child =>
|
|
55
73
|
`<${tag}>${domOutputSpecToHTMLString(attrs as DOMOutputSpecArray)(child)}${[children]
|
|
@@ -63,7 +81,8 @@ export function domOutputSpecToHTMLString(content: DOMOutputSpec): (children?: s
|
|
|
63
81
|
return () => `<${tag}${serializeAttrsToHTMLString(attrs)}/>`
|
|
64
82
|
}
|
|
65
83
|
if (children === 0) {
|
|
66
|
-
return child =>
|
|
84
|
+
return child =>
|
|
85
|
+
`<${tag}${serializeAttrsToHTMLString(attrs)}>${serializeChildrenToHTMLString(child)}</${tag}>`
|
|
67
86
|
}
|
|
68
87
|
|
|
69
88
|
return child =>
|
|
@@ -84,19 +103,30 @@ export function domOutputSpecToHTMLString(content: DOMOutputSpec): (children?: s
|
|
|
84
103
|
}
|
|
85
104
|
|
|
86
105
|
/**
|
|
87
|
-
* This function will statically render a Prosemirror Node to HTML using the provided extensions and options
|
|
106
|
+
* This function will statically render a Prosemirror Node to HTML using the provided extensions and options.
|
|
107
|
+
*
|
|
108
|
+
* Limitations: this function builds the schema and runs each extension's
|
|
109
|
+
* `renderHTML`, but does not instantiate an `Editor`. Extensions that mutate
|
|
110
|
+
* the document inside `addProseMirrorPlugins`, `onCreate`, or transaction
|
|
111
|
+
* hooks will not run. For UniqueID, pre-process the JSON with
|
|
112
|
+
* `generateUniqueIds` from `@tiptap/extension-unique-id`; for TableOfContents,
|
|
113
|
+
* pre-process with `generateTocIds` from `@tiptap/extension-table-of-contents`.
|
|
114
|
+
*
|
|
88
115
|
* @param content The content to render to HTML
|
|
89
116
|
* @param extensions The extensions to use for rendering
|
|
117
|
+
* @param staticEditorOptions Optional editor-level options that affect rendered output, currently `{ textDirection }`. Mirrors a subset of `EditorOptions`.
|
|
90
118
|
* @param options The options to use for rendering
|
|
91
119
|
* @returns The rendered HTML string
|
|
92
120
|
*/
|
|
93
121
|
export function renderToHTMLString({
|
|
94
122
|
content,
|
|
95
123
|
extensions,
|
|
124
|
+
staticEditorOptions,
|
|
96
125
|
options,
|
|
97
126
|
}: {
|
|
98
127
|
content: Node | JSONContent
|
|
99
128
|
extensions: Extensions
|
|
129
|
+
staticEditorOptions?: StaticEditorOptions
|
|
100
130
|
options?: Partial<TiptapStaticRendererOptions<string, Mark, Node>>
|
|
101
131
|
}): string {
|
|
102
132
|
return renderToElement<string>({
|
|
@@ -109,7 +139,7 @@ export function renderToHTMLString({
|
|
|
109
139
|
text: ({ node }) => escapeHTML(node.text ?? ''),
|
|
110
140
|
},
|
|
111
141
|
content,
|
|
112
|
-
extensions,
|
|
142
|
+
extensions: applyStaticEditorOptionsToExtensions(extensions, staticEditorOptions),
|
|
113
143
|
options,
|
|
114
144
|
})
|
|
115
145
|
}
|
|
@@ -2,24 +2,33 @@ import type { Extensions, JSONContent } from '@tiptap/core'
|
|
|
2
2
|
import type { Mark, Node } from '@tiptap/pm/model'
|
|
3
3
|
|
|
4
4
|
import type { TiptapStaticRendererOptions } from '../../json/renderer.js'
|
|
5
|
+
import type { StaticEditorOptions } from '../extensionRenderer.js'
|
|
5
6
|
import { renderToHTMLString, serializeChildrenToHTMLString } from '../html-string/html-string.js'
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* This code is just to show the flexibility of this renderer. We can potentially render content to any format we want.
|
|
9
10
|
* This is a simple example of how we can render content to markdown. This is not a full implementation of a markdown renderer.
|
|
11
|
+
*
|
|
12
|
+
* Limitations: see `renderToHTMLString` — extensions that mutate the document
|
|
13
|
+
* via plugins/onCreate (UniqueID, TableOfContents) need to be pre-processed.
|
|
14
|
+
*
|
|
15
|
+
* @param staticEditorOptions Optional editor-level options that affect rendered output — mirrors a subset of `EditorOptions`.
|
|
10
16
|
*/
|
|
11
17
|
export function renderToMarkdown({
|
|
12
18
|
content,
|
|
13
19
|
extensions,
|
|
20
|
+
staticEditorOptions,
|
|
14
21
|
options,
|
|
15
22
|
}: {
|
|
16
23
|
content: Node | JSONContent
|
|
17
24
|
extensions: Extensions
|
|
25
|
+
staticEditorOptions?: StaticEditorOptions
|
|
18
26
|
options?: Partial<TiptapStaticRendererOptions<string, Mark, Node>>
|
|
19
27
|
}) {
|
|
20
28
|
return renderToHTMLString({
|
|
21
29
|
content,
|
|
22
30
|
extensions,
|
|
31
|
+
staticEditorOptions,
|
|
23
32
|
options: {
|
|
24
33
|
...options,
|
|
25
34
|
nodeMapping: {
|
|
@@ -53,7 +62,7 @@ export function renderToMarkdown({
|
|
|
53
62
|
heading({ node, children }) {
|
|
54
63
|
const level = node.attrs.level as number
|
|
55
64
|
|
|
56
|
-
return `${
|
|
65
|
+
return `${Array.from<string>({ length: level }).fill('#').join('')} ${children}\n`
|
|
57
66
|
},
|
|
58
67
|
codeBlock({ node, children }) {
|
|
59
68
|
return `\n\`\`\`${node.attrs.language}\n${serializeChildrenToHTMLString(children)}\n\`\`\`\n`
|
|
@@ -80,7 +89,7 @@ export function renderToMarkdown({
|
|
|
80
89
|
}
|
|
81
90
|
|
|
82
91
|
const columnCount = node.children[0].childCount
|
|
83
|
-
return `\n${serializeChildrenToHTMLString(children[0])}| ${
|
|
92
|
+
return `\n${serializeChildrenToHTMLString(children[0])}| ${Array.from<string>({ length: columnCount }).fill('---').join(' | ')} |\n${serializeChildrenToHTMLString(children.slice(1))}\n`
|
|
84
93
|
},
|
|
85
94
|
tableRow({ children }) {
|
|
86
95
|
if (Array.isArray(children)) {
|
package/src/pm/react/react.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* oslint-disable no-plusplus,no-explicit-any */
|
|
2
2
|
import type { DOMOutputSpecArray, Extensions, JSONContent } from '@tiptap/core'
|
|
3
3
|
import type { DOMOutputSpec, Mark, Node } from '@tiptap/pm/model'
|
|
4
4
|
import React from 'react'
|
|
5
5
|
|
|
6
6
|
import { renderJSONContentToReactElement } from '../../json/react/react.js'
|
|
7
7
|
import type { TiptapStaticRendererOptions } from '../../json/renderer.js'
|
|
8
|
-
import {
|
|
8
|
+
import type { StaticEditorOptions } from '../extensionRenderer.js'
|
|
9
|
+
import { applyStaticEditorOptionsToExtensions, renderToElement } from '../extensionRenderer.js'
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* This function maps the attributes of a node or mark to HTML attributes
|
|
@@ -13,7 +14,10 @@ import { renderToElement } from '../extensionRenderer.js'
|
|
|
13
14
|
* @param key The key to use for the React element
|
|
14
15
|
* @returns The mapped HTML attributes as an object
|
|
15
16
|
*/
|
|
16
|
-
export function mapAttrsToHTMLAttributes(
|
|
17
|
+
export function mapAttrsToHTMLAttributes(
|
|
18
|
+
attrs?: Record<string, any>,
|
|
19
|
+
key?: string,
|
|
20
|
+
): Record<string, any> {
|
|
17
21
|
if (!attrs) {
|
|
18
22
|
return { key }
|
|
19
23
|
}
|
|
@@ -58,7 +62,7 @@ export function domOutputSpecToReactElement(
|
|
|
58
62
|
return () => content
|
|
59
63
|
}
|
|
60
64
|
if (typeof content === 'object' && 'length' in content) {
|
|
61
|
-
//
|
|
65
|
+
// oxlint-disable-next-line prefer-const
|
|
62
66
|
let [tag, attrs, children, ...rest] = content as DOMOutputSpecArray
|
|
63
67
|
const parts = tag.split(' ')
|
|
64
68
|
|
|
@@ -84,7 +88,8 @@ export function domOutputSpecToReactElement(
|
|
|
84
88
|
return () => React.createElement(tag, mapAttrsToHTMLAttributes(undefined, key.toString()))
|
|
85
89
|
}
|
|
86
90
|
if (attrs === 0) {
|
|
87
|
-
return child =>
|
|
91
|
+
return child =>
|
|
92
|
+
React.createElement(tag, mapAttrsToHTMLAttributes(undefined, key.toString()), child)
|
|
88
93
|
}
|
|
89
94
|
if (typeof attrs === 'object') {
|
|
90
95
|
if (Array.isArray(attrs)) {
|
|
@@ -109,21 +114,26 @@ export function domOutputSpecToReactElement(
|
|
|
109
114
|
tag,
|
|
110
115
|
mapAttrsToHTMLAttributes(undefined, key.toString()),
|
|
111
116
|
domOutputSpecToReactElement(attrs as DOMOutputSpecArray)(child),
|
|
112
|
-
[children]
|
|
117
|
+
[children]
|
|
118
|
+
.concat(rest)
|
|
119
|
+
.map(outputSpec => domOutputSpecToReactElement(outputSpec, key++)(child)),
|
|
113
120
|
)
|
|
114
121
|
}
|
|
115
122
|
if (children === undefined) {
|
|
116
123
|
return () => React.createElement(tag, mapAttrsToHTMLAttributes(attrs, key.toString()))
|
|
117
124
|
}
|
|
118
125
|
if (children === 0) {
|
|
119
|
-
return child =>
|
|
126
|
+
return child =>
|
|
127
|
+
React.createElement(tag, mapAttrsToHTMLAttributes(attrs, key.toString()), child)
|
|
120
128
|
}
|
|
121
129
|
|
|
122
130
|
return child =>
|
|
123
131
|
React.createElement(
|
|
124
132
|
tag,
|
|
125
133
|
mapAttrsToHTMLAttributes(attrs, key.toString()),
|
|
126
|
-
[children]
|
|
134
|
+
[children]
|
|
135
|
+
.concat(rest)
|
|
136
|
+
.map(outputSpec => domOutputSpecToReactElement(outputSpec, key++)(child)),
|
|
127
137
|
)
|
|
128
138
|
}
|
|
129
139
|
}
|
|
@@ -138,19 +148,26 @@ export function domOutputSpecToReactElement(
|
|
|
138
148
|
}
|
|
139
149
|
|
|
140
150
|
/**
|
|
141
|
-
* This function will statically render a Prosemirror Node to a React component using the given extensions
|
|
151
|
+
* This function will statically render a Prosemirror Node to a React component using the given extensions.
|
|
152
|
+
*
|
|
153
|
+
* Limitations: see `renderToHTMLString` — extensions that mutate the document
|
|
154
|
+
* via plugins/onCreate (UniqueID, TableOfContents) need to be pre-processed.
|
|
155
|
+
*
|
|
142
156
|
* @param content The content to render to a React component
|
|
143
157
|
* @param extensions The extensions to use for rendering
|
|
158
|
+
* @param staticEditorOptions Optional editor-level options that affect rendered output — mirrors a subset of `EditorOptions`.
|
|
144
159
|
* @param options The options to use for rendering
|
|
145
160
|
* @returns The React element that represents the rendered content
|
|
146
161
|
*/
|
|
147
162
|
export function renderToReactElement({
|
|
148
163
|
content,
|
|
149
164
|
extensions,
|
|
165
|
+
staticEditorOptions,
|
|
150
166
|
options,
|
|
151
167
|
}: {
|
|
152
168
|
content: Node | JSONContent
|
|
153
169
|
extensions: Extensions
|
|
170
|
+
staticEditorOptions?: StaticEditorOptions
|
|
154
171
|
options?: Partial<TiptapStaticRendererOptions<React.ReactNode, Mark, Node>>
|
|
155
172
|
}): React.ReactNode {
|
|
156
173
|
return renderToElement<React.ReactNode>({
|
|
@@ -163,7 +180,7 @@ export function renderToReactElement({
|
|
|
163
180
|
text: ({ node }) => node.text ?? '',
|
|
164
181
|
},
|
|
165
182
|
content,
|
|
166
|
-
extensions,
|
|
183
|
+
extensions: applyStaticEditorOptionsToExtensions(extensions, staticEditorOptions),
|
|
167
184
|
options,
|
|
168
185
|
})
|
|
169
186
|
}
|