@prosekit/extensions 0.14.1 → 0.15.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/dist/commit/style.css +1 -3
- package/dist/{drop-indicator-DJq8pF92.js → drop-indicator.js} +2 -4
- package/dist/drop-indicator.js.map +1 -0
- package/dist/{file-upload-I9m1EJAM.js → file.js} +2 -6
- package/dist/file.js.map +1 -0
- package/dist/gap-cursor/style.css +5 -8
- package/dist/{file-upload-dr3IXUty.d.ts → index.d.ts} +1 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/list/style.css +79 -110
- package/dist/loro/style.css +18 -21
- package/dist/{mark-rule-CUnXwBuy.js → mark-rule.js} +3 -6
- package/dist/mark-rule.js.map +1 -0
- package/dist/page/style.css +43 -0
- package/dist/{mark-paste-rule-n_2Ehmb5.js → paste-rule.js} +3 -7
- package/dist/paste-rule.js.map +1 -0
- package/dist/placeholder/style.css +4 -7
- package/dist/prosekit-extensions-autocomplete.d.ts +1 -1
- package/dist/prosekit-extensions-autocomplete.js +17 -21
- package/dist/prosekit-extensions-autocomplete.js.map +1 -1
- package/dist/prosekit-extensions-background-color.d.ts +1 -1
- package/dist/prosekit-extensions-background-color.js +1 -4
- package/dist/prosekit-extensions-background-color.js.map +1 -1
- package/dist/prosekit-extensions-blockquote.d.ts +13 -13
- package/dist/prosekit-extensions-blockquote.d.ts.map +1 -1
- package/dist/prosekit-extensions-blockquote.js +6 -10
- package/dist/prosekit-extensions-blockquote.js.map +1 -1
- package/dist/prosekit-extensions-bold.d.ts +12 -12
- package/dist/prosekit-extensions-bold.d.ts.map +1 -1
- package/dist/prosekit-extensions-bold.js +1 -6
- package/dist/prosekit-extensions-bold.js.map +1 -1
- package/dist/prosekit-extensions-code-block.d.ts +56 -37
- package/dist/prosekit-extensions-code-block.d.ts.map +1 -1
- package/dist/prosekit-extensions-code-block.js +73 -76
- package/dist/prosekit-extensions-code-block.js.map +1 -1
- package/dist/prosekit-extensions-code.d.ts +12 -12
- package/dist/prosekit-extensions-code.d.ts.map +1 -1
- package/dist/prosekit-extensions-code.js +1 -6
- package/dist/prosekit-extensions-code.js.map +1 -1
- package/dist/prosekit-extensions-commit.d.ts +1 -1
- package/dist/prosekit-extensions-commit.js +2 -3
- package/dist/prosekit-extensions-commit.js.map +1 -1
- package/dist/prosekit-extensions-doc.js +1 -2
- package/dist/prosekit-extensions-doc.js.map +1 -1
- package/dist/prosekit-extensions-drop-cursor.js +1 -2
- package/dist/prosekit-extensions-drop-cursor.js.map +1 -1
- package/dist/prosekit-extensions-drop-indicator.js +2 -3
- package/dist/prosekit-extensions-enter-rule.d.ts +2 -2
- package/dist/prosekit-extensions-enter-rule.d.ts.map +1 -1
- package/dist/prosekit-extensions-enter-rule.js +1 -2
- package/dist/prosekit-extensions-enter-rule.js.map +1 -1
- package/dist/prosekit-extensions-file.d.ts +2 -2
- package/dist/prosekit-extensions-file.js +2 -3
- package/dist/prosekit-extensions-gap-cursor.js +1 -2
- package/dist/prosekit-extensions-gap-cursor.js.map +1 -1
- package/dist/prosekit-extensions-hard-break.d.ts +7 -7
- package/dist/prosekit-extensions-hard-break.d.ts.map +1 -1
- package/dist/prosekit-extensions-hard-break.js +1 -5
- package/dist/prosekit-extensions-hard-break.js.map +1 -1
- package/dist/prosekit-extensions-heading.d.ts +15 -15
- package/dist/prosekit-extensions-heading.d.ts.map +1 -1
- package/dist/prosekit-extensions-heading.js +1 -6
- package/dist/prosekit-extensions-heading.js.map +1 -1
- package/dist/prosekit-extensions-horizontal-rule.d.ts +7 -7
- package/dist/prosekit-extensions-horizontal-rule.d.ts.map +1 -1
- package/dist/prosekit-extensions-horizontal-rule.js +12 -14
- package/dist/prosekit-extensions-horizontal-rule.js.map +1 -1
- package/dist/prosekit-extensions-image.d.ts +12 -13
- package/dist/prosekit-extensions-image.d.ts.map +1 -1
- package/dist/prosekit-extensions-image.js +10 -16
- package/dist/prosekit-extensions-image.js.map +1 -1
- package/dist/prosekit-extensions-input-rule.js +1 -2
- package/dist/prosekit-extensions-input-rule.js.map +1 -1
- package/dist/prosekit-extensions-italic.d.ts +12 -12
- package/dist/prosekit-extensions-italic.d.ts.map +1 -1
- package/dist/prosekit-extensions-italic.js +1 -6
- package/dist/prosekit-extensions-italic.js.map +1 -1
- package/dist/prosekit-extensions-link.js +3 -6
- package/dist/prosekit-extensions-link.js.map +1 -1
- package/dist/prosekit-extensions-list.d.ts +26 -26
- package/dist/prosekit-extensions-list.d.ts.map +1 -1
- package/dist/prosekit-extensions-list.js +26 -34
- package/dist/prosekit-extensions-list.js.map +1 -1
- package/dist/prosekit-extensions-loro.d.ts +16 -16
- package/dist/prosekit-extensions-loro.d.ts.map +1 -1
- package/dist/prosekit-extensions-loro.js +3 -9
- package/dist/prosekit-extensions-loro.js.map +1 -1
- package/dist/prosekit-extensions-mark-rule.js +2 -3
- package/dist/prosekit-extensions-math.d.ts +3 -3
- package/dist/prosekit-extensions-math.d.ts.map +1 -1
- package/dist/prosekit-extensions-math.js +5 -5
- package/dist/prosekit-extensions-math.js.map +1 -1
- package/dist/prosekit-extensions-mention.js +1 -2
- package/dist/prosekit-extensions-mention.js.map +1 -1
- package/dist/prosekit-extensions-mod-click-prevention.js +2 -3
- package/dist/prosekit-extensions-mod-click-prevention.js.map +1 -1
- package/dist/prosekit-extensions-page.d.ts +114 -0
- package/dist/prosekit-extensions-page.d.ts.map +1 -0
- package/dist/prosekit-extensions-page.js +324 -0
- package/dist/prosekit-extensions-page.js.map +1 -0
- package/dist/prosekit-extensions-paragraph.d.ts +7 -7
- package/dist/prosekit-extensions-paragraph.d.ts.map +1 -1
- package/dist/prosekit-extensions-paragraph.js +3 -7
- package/dist/prosekit-extensions-paragraph.js.map +1 -1
- package/dist/prosekit-extensions-paste-rule.js +2 -3
- package/dist/prosekit-extensions-placeholder.d.ts +1 -1
- package/dist/prosekit-extensions-placeholder.js +3 -4
- package/dist/prosekit-extensions-placeholder.js.map +1 -1
- package/dist/prosekit-extensions-readonly.js +2 -3
- package/dist/prosekit-extensions-readonly.js.map +1 -1
- package/dist/prosekit-extensions-search.js +1 -2
- package/dist/prosekit-extensions-search.js.map +1 -1
- package/dist/prosekit-extensions-strike.js +1 -2
- package/dist/prosekit-extensions-strike.js.map +1 -1
- package/dist/prosekit-extensions-table.d.ts +47 -47
- package/dist/prosekit-extensions-table.d.ts.map +1 -1
- package/dist/prosekit-extensions-table.js +2 -3
- package/dist/prosekit-extensions-text-align.d.ts +1 -1
- package/dist/prosekit-extensions-text-align.js +1 -2
- package/dist/prosekit-extensions-text-align.js.map +1 -1
- package/dist/prosekit-extensions-text-color.d.ts +1 -1
- package/dist/prosekit-extensions-text-color.js +1 -4
- package/dist/prosekit-extensions-text-color.js.map +1 -1
- package/dist/prosekit-extensions-text.js +1 -2
- package/dist/prosekit-extensions-text.js.map +1 -1
- package/dist/prosekit-extensions-underline.js +1 -2
- package/dist/prosekit-extensions-underline.js.map +1 -1
- package/dist/prosekit-extensions-virtual-selection.js +2 -3
- package/dist/prosekit-extensions-virtual-selection.js.map +1 -1
- package/dist/prosekit-extensions-yjs.d.ts +3 -3
- package/dist/prosekit-extensions-yjs.d.ts.map +1 -1
- package/dist/prosekit-extensions-yjs.js +3 -9
- package/dist/prosekit-extensions-yjs.js.map +1 -1
- package/dist/prosekit-extensions.js +1 -1
- package/dist/search/style.css +4 -8
- package/dist/shiki-highlighter-chunk.js +1 -2
- package/dist/shiki-highlighter-chunk.js.map +1 -1
- package/dist/table/style.css +16 -16
- package/dist/{table-UJVYsrB7.js → table.js} +29 -41
- package/dist/table.js.map +1 -0
- package/dist/virtual-selection/style.css +1 -4
- package/dist/yjs/style.css +14 -20
- package/package.json +30 -16
- package/src/autocomplete/autocomplete-helpers.ts +1 -1
- package/src/autocomplete/autocomplete-plugin.ts +2 -2
- package/src/autocomplete/autocomplete-rule.ts +1 -1
- package/src/autocomplete/autocomplete.spec.ts +4 -4
- package/src/autocomplete/autocomplete.ts +2 -2
- package/src/autocomplete/index.ts +2 -2
- package/src/background-color/background-color-commands.spec.ts +1 -1
- package/src/background-color/background-color-commands.ts +1 -1
- package/src/background-color/background-color-spec.spec.ts +1 -1
- package/src/background-color/background-color.ts +2 -2
- package/src/background-color/index.ts +3 -3
- package/src/blockquote/blockquote-input-rule.ts +1 -1
- package/src/blockquote/blockquote-keymap.spec.ts +1 -1
- package/src/blockquote/blockquote-keymap.ts +9 -7
- package/src/blockquote/blockquote.ts +4 -4
- package/src/blockquote/index.ts +5 -5
- package/src/bold/bold-input-rule.spec.ts +2 -2
- package/src/bold/bold-input-rule.ts +1 -1
- package/src/bold/bold.ts +4 -4
- package/src/bold/index.ts +5 -5
- package/src/code/code-input-rule.ts +1 -1
- package/src/code/code.ts +4 -4
- package/src/code/index.ts +5 -5
- package/src/code-block/code-block-commands.ts +1 -1
- package/src/code-block/code-block-highlight.ts +11 -1
- package/src/code-block/code-block-input-rule.ts +3 -3
- package/src/code-block/code-block-shiki.ts +13 -5
- package/src/code-block/code-block-spec.spec.ts +2 -2
- package/src/code-block/code-block-spec.ts +1 -1
- package/src/code-block/code-block.ts +4 -4
- package/src/code-block/index.ts +9 -9
- package/src/code-block/shiki-highlighter.ts +2 -2
- package/src/code-block/shiki-parser.ts +2 -2
- package/src/drop-cursor/index.ts +1 -1
- package/src/drop-indicator/drop-indicator.ts +1 -1
- package/src/drop-indicator/index.ts +1 -1
- package/src/enter-rule/index.ts +3 -3
- package/src/file/file-drop-handler.ts +1 -1
- package/src/file/file-paste-handler.spec.ts +3 -3
- package/src/file/file-paste-handler.ts +1 -1
- package/src/file/index.ts +3 -3
- package/src/gap-cursor/index.ts +1 -1
- package/src/hard-break/hard-break-keymap.spec.ts +2 -2
- package/src/hard-break/hard-break-keymap.ts +1 -1
- package/src/hard-break/hard-break.ts +3 -3
- package/src/hard-break/index.ts +4 -4
- package/src/heading/heading-commands.ts +1 -1
- package/src/heading/heading-input-rule.ts +2 -2
- package/src/heading/heading-keymap.spec.ts +1 -1
- package/src/heading/heading-spec.ts +1 -1
- package/src/heading/heading.ts +4 -4
- package/src/heading/index.ts +6 -6
- package/src/horizontal-rule/horizontal-rule-commands.spec.ts +1 -1
- package/src/horizontal-rule/horizontal-rule-commands.ts +14 -11
- package/src/horizontal-rule/horizontal-rule-input-rule.spec.ts +2 -2
- package/src/horizontal-rule/horizontal-rule-input-rule.ts +1 -1
- package/src/horizontal-rule/horizontal-rule.ts +3 -3
- package/src/horizontal-rule/index.ts +4 -4
- package/src/image/image-commands/insert-image.ts +1 -1
- package/src/image/image-commands/upload-image.spec.ts +4 -4
- package/src/image/image-commands/upload-image.ts +2 -2
- package/src/image/image-commands.ts +3 -3
- package/src/image/image-upload-handler.ts +2 -2
- package/src/image/image.ts +2 -2
- package/src/image/index.ts +6 -6
- package/src/italic/index.ts +5 -5
- package/src/italic/italic-commands.spec.ts +4 -4
- package/src/italic/italic-input-rule.spec.ts +2 -2
- package/src/italic/italic-input-rule.ts +1 -1
- package/src/italic/italic.ts +4 -4
- package/src/link/index.spec.ts +2 -2
- package/src/link/index.ts +6 -6
- package/src/link/link-paste-rule.spec.ts +2 -2
- package/src/link/link-paste-rule.ts +3 -3
- package/src/link/link-regex.spec.ts +1 -1
- package/src/list/index.ts +8 -8
- package/src/list/list-drop-indicator.ts +2 -2
- package/src/list/list-input-rules.ts +1 -1
- package/src/list/list-keymap.spec.ts +1 -1
- package/src/list/list-spec.ts +1 -1
- package/src/list/list-types.spec.ts +2 -2
- package/src/list/list.spec.ts +6 -6
- package/src/list/list.ts +7 -7
- package/src/loro/index.ts +6 -6
- package/src/loro/loro.ts +8 -7
- package/src/mark-rule/apply.ts +2 -2
- package/src/mark-rule/index.ts +2 -2
- package/src/mark-rule/mark-rule.spec.ts +4 -4
- package/src/mark-rule/mark-rule.ts +2 -2
- package/src/math/index.ts +4 -4
- package/src/math/math-block.ts +8 -1
- package/src/math/math-inline.ts +1 -1
- package/src/math/math.ts +3 -3
- package/src/page/index.ts +5 -0
- package/src/page/page-break-commands.spec.ts +61 -0
- package/src/page/page-break-commands.ts +41 -0
- package/src/page/page-break-keymap.ts +17 -0
- package/src/page/page-break-spec.ts +33 -0
- package/src/page/page-break.ts +23 -0
- package/src/page/page-element.ts +246 -0
- package/src/page/page-rendering.ts +164 -0
- package/src/page/style.css +43 -0
- package/src/paragraph/index.ts +7 -7
- package/src/paragraph/paragraph-keymap.ts +1 -1
- package/src/paragraph/paragraph.ts +6 -5
- package/src/paste-rule/index.ts +2 -2
- package/src/paste-rule/mark-paste-rule.spec.ts +8 -8
- package/src/paste-rule/mark-paste-rule.ts +2 -2
- package/src/paste-rule/paste-rule.spec.ts +2 -2
- package/src/paste-rule/paste-rule.ts +1 -1
- package/src/paste-rule/split-text-by-regex.spec.ts +1 -1
- package/src/placeholder/index.ts +1 -1
- package/src/strike/index.ts +1 -1
- package/src/table/index.ts +14 -14
- package/src/table/table-commands/delete-cell-selection.spec.ts +3 -3
- package/src/table/table-commands/exit-table.spec.ts +2 -2
- package/src/table/table-commands/insert-table.spec.ts +1 -1
- package/src/table/table-commands/move-table-column.spec.ts +2 -2
- package/src/table/table-commands/move-table-row.spec.ts +2 -2
- package/src/table/table-commands/select-table-cell.spec.ts +3 -3
- package/src/table/table-commands/select-table-cell.ts +1 -1
- package/src/table/table-commands/select-table-column.spec.ts +2 -2
- package/src/table/table-commands/select-table-column.ts +1 -1
- package/src/table/table-commands/select-table-row.spec.ts +2 -2
- package/src/table/table-commands/select-table-row.ts +1 -1
- package/src/table/table-commands/select-table.spec.ts +2 -2
- package/src/table/table-commands/select-table.ts +1 -1
- package/src/table/table-commands.ts +9 -9
- package/src/table/table-drop-indicator.ts +2 -2
- package/src/table/table-spec.spec.ts +4 -4
- package/src/table/table.ts +4 -4
- package/src/table/test-utils.ts +1 -1
- package/src/testing/index.ts +24 -24
- package/src/text-color/index.ts +3 -3
- package/src/text-color/text-color-commands.spec.ts +1 -1
- package/src/text-color/text-color-commands.ts +1 -1
- package/src/text-color/text-color-spec.spec.ts +1 -1
- package/src/text-color/text-color.ts +2 -2
- package/src/yjs/index.ts +7 -7
- package/src/yjs/yjs-cursor-plugin.ts +1 -1
- package/src/yjs/yjs-undo-plugin.ts +3 -2
- package/src/yjs/yjs.ts +9 -8
- package/dist/commit/style.css.map +0 -1
- package/dist/commit/style.js +0 -1
- package/dist/drop-indicator-DJq8pF92.js.map +0 -1
- package/dist/file-upload-I9m1EJAM.js.map +0 -1
- package/dist/file-upload-dr3IXUty.d.ts.map +0 -1
- package/dist/gap-cursor/style.css.map +0 -1
- package/dist/gap-cursor/style.js +0 -1
- package/dist/list/style.css.map +0 -1
- package/dist/list/style.js +0 -1
- package/dist/loro/style.css.map +0 -1
- package/dist/loro/style.js +0 -1
- package/dist/mark-paste-rule-n_2Ehmb5.js.map +0 -1
- package/dist/mark-rule-CUnXwBuy.js.map +0 -1
- package/dist/placeholder/style.css.map +0 -1
- package/dist/placeholder/style.js +0 -1
- package/dist/search/style.css.map +0 -1
- package/dist/search/style.js +0 -1
- package/dist/shiki-highlighter-chunk.d.ts +0 -19
- package/dist/shiki-highlighter-chunk.d.ts.map +0 -1
- package/dist/table/style.css.map +0 -1
- package/dist/table/style.js +0 -1
- package/dist/table-UJVYsrB7.js.map +0 -1
- package/dist/virtual-selection/style.css.map +0 -1
- package/dist/virtual-selection/style.js +0 -1
- package/dist/yjs/style.css.map +0 -1
- package/dist/yjs/style.js +0 -1
package/src/math/math.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { union, type Union } from '@prosekit/core'
|
|
2
2
|
import type { RenderMathBlock, RenderMathInline } from 'prosemirror-math'
|
|
3
3
|
|
|
4
|
-
import { defineMathBlock, type MathBlockExtension } from './math-block'
|
|
5
|
-
import { defineMathInline, type MathInlineExtension } from './math-inline'
|
|
6
|
-
import { defineMathPlugin } from './math-plugin'
|
|
4
|
+
import { defineMathBlock, type MathBlockExtension } from './math-block.ts'
|
|
5
|
+
import { defineMathInline, type MathInlineExtension } from './math-inline.ts'
|
|
6
|
+
import { defineMathPlugin } from './math-plugin.ts'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @public
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { definePageBreakCommands, insertPageBreak, type PageBreakCommandsExtension } from './page-break-commands.ts'
|
|
2
|
+
export { definePageBreakKeymap, type PageBreakKeymapExtension } from './page-break-keymap.ts'
|
|
3
|
+
export { definePageBreakSpec, type PageBreakSpecExtension } from './page-break-spec.ts'
|
|
4
|
+
export { definePageBreak, type PageBreakExtension } from './page-break.ts'
|
|
5
|
+
export { definePageRendering, type PageRenderingExtension, type PageRenderingOptions } from './page-rendering.ts'
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { union } from '@prosekit/core'
|
|
2
|
+
import { describe, expect, it } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import { defineDoc } from '../doc/index.ts'
|
|
5
|
+
import { defineHardBreak } from '../hard-break/index.ts'
|
|
6
|
+
import { defineHorizontalRule } from '../horizontal-rule/index.ts'
|
|
7
|
+
import { defineParagraph } from '../paragraph/index.ts'
|
|
8
|
+
import { setupTestFromExtension } from '../testing/index.ts'
|
|
9
|
+
import { defineText } from '../text/index.ts'
|
|
10
|
+
|
|
11
|
+
import { definePageBreak } from './page-break.ts'
|
|
12
|
+
|
|
13
|
+
function setup() {
|
|
14
|
+
const extension = union(
|
|
15
|
+
defineDoc(),
|
|
16
|
+
defineText(),
|
|
17
|
+
defineParagraph(),
|
|
18
|
+
defineHorizontalRule(),
|
|
19
|
+
defineHardBreak(),
|
|
20
|
+
definePageBreak(),
|
|
21
|
+
)
|
|
22
|
+
return setupTestFromExtension(extension)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe('insertPageBreak', () => {
|
|
26
|
+
it('should insert a page break in an empty paragraph', () => {
|
|
27
|
+
const { editor, n } = setup()
|
|
28
|
+
editor.set(n.doc(n.paragraph('<a>')))
|
|
29
|
+
editor.commands.insertPageBreak()
|
|
30
|
+
expect(editor.view.state.doc.toJSON()).toEqual(
|
|
31
|
+
n.doc(n.pageBreak()).toJSON(),
|
|
32
|
+
)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('should insert a page break after text', () => {
|
|
36
|
+
const { editor, n } = setup()
|
|
37
|
+
editor.set(n.doc(n.paragraph('hello<a>')))
|
|
38
|
+
editor.commands.insertPageBreak()
|
|
39
|
+
expect(editor.view.state.doc.toJSON()).toEqual(
|
|
40
|
+
n.doc(n.paragraph('hello'), n.pageBreak()).toJSON(),
|
|
41
|
+
)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('should insert a page break before text', () => {
|
|
45
|
+
const { editor, n } = setup()
|
|
46
|
+
editor.set(n.doc(n.paragraph('<a>hello')))
|
|
47
|
+
editor.commands.insertPageBreak()
|
|
48
|
+
expect(editor.view.state.doc.toJSON()).toEqual(
|
|
49
|
+
n.doc(n.pageBreak(), n.paragraph('hello')).toJSON(),
|
|
50
|
+
)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('should insert a page break between text', () => {
|
|
54
|
+
const { editor, n } = setup()
|
|
55
|
+
editor.set(n.doc(n.paragraph('hel<a>lo')))
|
|
56
|
+
editor.commands.insertPageBreak()
|
|
57
|
+
expect(editor.view.state.doc.toJSON()).toEqual(
|
|
58
|
+
n.doc(n.paragraph('hel'), n.pageBreak(), n.paragraph('lo')).toJSON(),
|
|
59
|
+
)
|
|
60
|
+
})
|
|
61
|
+
})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { defineCommands, getNodeType, type Extension } from '@prosekit/core'
|
|
2
|
+
import { Fragment, Slice } from '@prosekit/pm/model'
|
|
3
|
+
import type { Command } from '@prosekit/pm/state'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export type PageBreakCommandsExtension = Extension<{
|
|
9
|
+
Commands: {
|
|
10
|
+
insertPageBreak: []
|
|
11
|
+
}
|
|
12
|
+
}>
|
|
13
|
+
|
|
14
|
+
const insertPageBreakCommand: Command = (state, dispatch): boolean => {
|
|
15
|
+
if (!dispatch) return true
|
|
16
|
+
|
|
17
|
+
const { schema, tr } = state
|
|
18
|
+
const type = getNodeType(schema, 'pageBreak')
|
|
19
|
+
const node = type.createChecked()
|
|
20
|
+
const pos = tr.selection.anchor
|
|
21
|
+
const slice = new Slice(Fragment.from(node), 0, 0)
|
|
22
|
+
tr.replaceRange(pos, pos, slice).scrollIntoView()
|
|
23
|
+
dispatch(tr)
|
|
24
|
+
return true
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export function insertPageBreak(): Command {
|
|
31
|
+
return insertPageBreakCommand
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
export function definePageBreakCommands(): PageBreakCommandsExtension {
|
|
38
|
+
return defineCommands({
|
|
39
|
+
insertPageBreak: insertPageBreak,
|
|
40
|
+
})
|
|
41
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineKeymap, type PlainExtension } from '@prosekit/core'
|
|
2
|
+
|
|
3
|
+
import { insertPageBreak } from './page-break-commands.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export type PageBreakKeymapExtension = PlainExtension
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export function definePageBreakKeymap(): PageBreakKeymapExtension {
|
|
14
|
+
return defineKeymap({
|
|
15
|
+
'Mod-Enter': insertPageBreak(),
|
|
16
|
+
})
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { defineNodeSpec, type Extension } from '@prosekit/core'
|
|
2
|
+
import type { Attrs } from '@prosekit/pm/model'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export type PageBreakSpecExtension = Extension<{
|
|
8
|
+
Nodes: {
|
|
9
|
+
pageBreak: Attrs
|
|
10
|
+
}
|
|
11
|
+
}>
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export function definePageBreakSpec(): PageBreakSpecExtension {
|
|
17
|
+
return defineNodeSpec({
|
|
18
|
+
name: 'pageBreak',
|
|
19
|
+
group: 'block',
|
|
20
|
+
selectable: true,
|
|
21
|
+
parseDOM: [{ tag: 'div.prosekit-page-break' }],
|
|
22
|
+
toDOM() {
|
|
23
|
+
return ['div', { class: 'prosekit-horizontal-rule prosekit-page-break' }, ['hr']]
|
|
24
|
+
},
|
|
25
|
+
pageBreak: true,
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare module '@prosekit/pm/model' {
|
|
30
|
+
interface NodeSpec {
|
|
31
|
+
pageBreak?: boolean | undefined
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { union, type Union } from '@prosekit/core'
|
|
2
|
+
|
|
3
|
+
import { definePageBreakCommands, type PageBreakCommandsExtension } from './page-break-commands.ts'
|
|
4
|
+
import { definePageBreakKeymap, type PageBreakKeymapExtension } from './page-break-keymap.ts'
|
|
5
|
+
import { definePageBreakSpec, type PageBreakSpecExtension } from './page-break-spec.ts'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export type PageBreakExtension = Union<
|
|
11
|
+
[PageBreakSpecExtension, PageBreakCommandsExtension, PageBreakKeymapExtension]
|
|
12
|
+
>
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export function definePageBreak(): PageBreakExtension {
|
|
18
|
+
return union(
|
|
19
|
+
definePageBreakSpec(),
|
|
20
|
+
definePageBreakCommands(),
|
|
21
|
+
definePageBreakKeymap(),
|
|
22
|
+
)
|
|
23
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { once } from '@ocavue/utils'
|
|
2
|
+
import { customElements, HTMLElement } from 'server-dom-shim'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export const PAGE_CHUNK_TAG_NAME = 'pm-page-chunk'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export const registerPageChunkElement: VoidFunction = /* @__PURE__ */ once(() => {
|
|
13
|
+
if (typeof window === 'undefined' || customElements.get(PAGE_CHUNK_TAG_NAME)) return
|
|
14
|
+
customElements.define(PAGE_CHUNK_TAG_NAME, PageChunkElement)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
class PageChunkElement extends HTMLElement {
|
|
18
|
+
static observedAttributes = [
|
|
19
|
+
'data-group',
|
|
20
|
+
'data-break',
|
|
21
|
+
'data-h',
|
|
22
|
+
'data-mt',
|
|
23
|
+
'data-mb',
|
|
24
|
+
|
|
25
|
+
// Only the first chunk of the whole document has this attribute.
|
|
26
|
+
'data-size',
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
// Data attributes set by external code
|
|
30
|
+
#group: string = ''
|
|
31
|
+
#forceNextBreak: boolean = false
|
|
32
|
+
#pageHeight: number = 0
|
|
33
|
+
#pageMarginTop: number = 0
|
|
34
|
+
#pageMarginBottom: number = 0
|
|
35
|
+
#size: number | undefined = undefined
|
|
36
|
+
|
|
37
|
+
// Internal states
|
|
38
|
+
#updateRequested: boolean = false
|
|
39
|
+
#contentBoxHeight: number = 0
|
|
40
|
+
|
|
41
|
+
// Rendering states
|
|
42
|
+
#isHead: boolean = false
|
|
43
|
+
#isTail: boolean = false
|
|
44
|
+
#paddingTop: number = 0
|
|
45
|
+
#paddingBottom: number = 0
|
|
46
|
+
|
|
47
|
+
// Pending rendering states
|
|
48
|
+
#isHeadPending: boolean = false
|
|
49
|
+
#isTailPending: boolean = false
|
|
50
|
+
#paddingTopPending: number = 0
|
|
51
|
+
#paddingBottomPending: number = 0
|
|
52
|
+
|
|
53
|
+
connectedCallback() {
|
|
54
|
+
this.#parseDataAttributes()
|
|
55
|
+
|
|
56
|
+
if (this.#isLeader()) {
|
|
57
|
+
this.#isHeadPending = true
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
this.#render()
|
|
61
|
+
|
|
62
|
+
// Get the initial content box height when the resize observer is not started yet. Notice that
|
|
63
|
+
// `this.clientHeight` is an integer while the content box height can be a float, so this is not
|
|
64
|
+
// accurate but should be good enough for the first render.
|
|
65
|
+
this.#contentBoxHeight = this.clientHeight - this.#paddingTop - this.#paddingBottom
|
|
66
|
+
|
|
67
|
+
observeElement(this)
|
|
68
|
+
|
|
69
|
+
this.#requestUpdate()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
disconnectedCallback() {
|
|
73
|
+
unobserveElement(this)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
attributeChangedCallback(_: string, oldValue: string | null, newValue: string | null) {
|
|
77
|
+
if (oldValue === newValue) return
|
|
78
|
+
this.#parseDataAttributes()
|
|
79
|
+
this.#requestUpdate()
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#parseDataAttributes() {
|
|
83
|
+
this.#group = this.getAttribute('data-group') || ''
|
|
84
|
+
this.#forceNextBreak = this.hasAttribute('data-break')
|
|
85
|
+
this.#pageHeight = this.#parseFloatAttribute('data-h')
|
|
86
|
+
this.#pageMarginTop = this.#parseFloatAttribute('data-mt')
|
|
87
|
+
this.#pageMarginBottom = this.#parseFloatAttribute('data-mb')
|
|
88
|
+
|
|
89
|
+
const sizeAttr = this.getAttribute('data-size')
|
|
90
|
+
this.#size = sizeAttr ? Number.parseInt(sizeAttr, 10) : undefined
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
#parseFloatAttribute(name: string): number {
|
|
94
|
+
const value = this.getAttribute(name)
|
|
95
|
+
return value != null ? Number.parseFloat(value) : 0
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
#isLeader() {
|
|
99
|
+
return this.#size != null
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
#render() {
|
|
103
|
+
if (this.#paddingTop !== this.#paddingTopPending || this.#paddingBottom !== this.#paddingBottomPending) {
|
|
104
|
+
Object.assign(this.style, {
|
|
105
|
+
paddingTop: `${this.#paddingTop = this.#paddingTopPending}px`,
|
|
106
|
+
paddingBottom: `${this.#paddingBottom = this.#paddingBottomPending}px`,
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
if (this.#isHead !== this.#isHeadPending) {
|
|
110
|
+
this.toggleAttribute('data-page-head', this.#isHead = this.#isHeadPending)
|
|
111
|
+
}
|
|
112
|
+
if (this.#isTail !== this.#isTailPending) {
|
|
113
|
+
this.toggleAttribute('data-page-tail', this.#isTail = this.#isTailPending)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
setHeight(height: number) {
|
|
118
|
+
// Avoid potential float number precision issues
|
|
119
|
+
if (Math.abs(this.#contentBoxHeight - height) < 0.1) {
|
|
120
|
+
return
|
|
121
|
+
}
|
|
122
|
+
this.#contentBoxHeight = height
|
|
123
|
+
this.#requestUpdate()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Schedules a batched page layout recalculation.
|
|
128
|
+
*
|
|
129
|
+
* Any chunk can call this method, but the actual layout work (#updateAll)
|
|
130
|
+
* always runs on the leader chunk, because it needs to iterate over every
|
|
131
|
+
* chunk in order to compute page breaks.
|
|
132
|
+
*
|
|
133
|
+
* Two nested microtasks are used to batch updates:
|
|
134
|
+
*
|
|
135
|
+
* Microtask 1 – Delegation: non-leader chunks forward the request to the
|
|
136
|
+
* leader chunk, so multiple chunks changing in the same tick only trigger
|
|
137
|
+
* one layout pass.
|
|
138
|
+
*
|
|
139
|
+
* Microtask 2 – Execution: the leader chunk defers #updateAll to a second
|
|
140
|
+
* microtask so that any other attribute / resize changes that were queued
|
|
141
|
+
* in the same tick (and forwarded during microtask 1) are already reflected
|
|
142
|
+
* before the layout is recalculated.
|
|
143
|
+
*
|
|
144
|
+
* The #updateRequested flag acts as a deduplication guard so that rapid
|
|
145
|
+
* successive calls (e.g. multiple attributes changing at once) result in at
|
|
146
|
+
* most one scheduled pass per chunk.
|
|
147
|
+
*/
|
|
148
|
+
#requestUpdate() {
|
|
149
|
+
if (this.#updateRequested) {
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
this.#updateRequested = true
|
|
154
|
+
queueMicrotask(() => {
|
|
155
|
+
if (!this.#isLeader()) {
|
|
156
|
+
this.#updateRequested = false
|
|
157
|
+
const leader = findLeaderChunk(this, this.#group)
|
|
158
|
+
if (!leader) return
|
|
159
|
+
leader.#requestUpdate()
|
|
160
|
+
return
|
|
161
|
+
}
|
|
162
|
+
queueMicrotask(() => {
|
|
163
|
+
this.#updateRequested = false
|
|
164
|
+
this.#updateAll()
|
|
165
|
+
})
|
|
166
|
+
})
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
#updateAll() {
|
|
170
|
+
if (!this.isConnected) {
|
|
171
|
+
return
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const elements = findAllChunks(this, this.#group)
|
|
175
|
+
const count = elements.length
|
|
176
|
+
if (count === 0) return
|
|
177
|
+
|
|
178
|
+
const pageHeight = this.#pageHeight
|
|
179
|
+
const pageMarginTop = this.#pageMarginTop
|
|
180
|
+
const maxContentHeight = pageHeight - pageMarginTop - this.#pageMarginBottom
|
|
181
|
+
|
|
182
|
+
let currentContentHeight = 0
|
|
183
|
+
let forceNextBreak = false
|
|
184
|
+
|
|
185
|
+
for (let i = 0; i < count; i++) {
|
|
186
|
+
const element = elements[i]
|
|
187
|
+
const h = element.#contentBoxHeight
|
|
188
|
+
const isHead = forceNextBreak || i === 0 || (currentContentHeight + h > maxContentHeight)
|
|
189
|
+
|
|
190
|
+
forceNextBreak = element.#forceNextBreak
|
|
191
|
+
|
|
192
|
+
if (isHead && i > 0) {
|
|
193
|
+
const prev = elements[i - 1]
|
|
194
|
+
prev.#paddingBottomPending = Math.max(0, pageHeight - pageMarginTop - currentContentHeight)
|
|
195
|
+
prev.#isTailPending = true
|
|
196
|
+
currentContentHeight = h
|
|
197
|
+
} else {
|
|
198
|
+
currentContentHeight += h
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
element.#paddingTopPending = isHead ? pageMarginTop : 0
|
|
202
|
+
element.#paddingBottomPending = 0
|
|
203
|
+
element.#isTailPending = false
|
|
204
|
+
element.#isHeadPending = isHead
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const last = elements[count - 1]
|
|
208
|
+
last.#paddingBottomPending = Math.max(0, pageHeight - pageMarginTop - currentContentHeight)
|
|
209
|
+
last.#isTailPending = true
|
|
210
|
+
|
|
211
|
+
for (const element of elements) {
|
|
212
|
+
element.#render()
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function handleResize(entries: ResizeObserverEntry[]) {
|
|
218
|
+
for (const entry of entries) {
|
|
219
|
+
const contentBoxHeight = entry.contentBoxSize?.[0]?.blockSize ?? entry.contentRect.height
|
|
220
|
+
const element = entry.target as PageChunkElement
|
|
221
|
+
element.setHeight(contentBoxHeight)
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const getResizeObserver = /* @__PURE__ */ once(() => {
|
|
226
|
+
return new ResizeObserver(handleResize)
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
function observeElement(element: PageChunkElement) {
|
|
230
|
+
getResizeObserver().observe(element)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function unobserveElement(element: PageChunkElement) {
|
|
234
|
+
getResizeObserver().unobserve(element)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function findLeaderChunk(element: HTMLElement, group: string): PageChunkElement | null | undefined {
|
|
238
|
+
const root = element.closest('.ProseMirror')
|
|
239
|
+
return root?.querySelector<PageChunkElement>(`${PAGE_CHUNK_TAG_NAME}[data-group="${group}"][data-size]`)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function findAllChunks(element: HTMLElement, group: string): PageChunkElement[] {
|
|
243
|
+
const root = element.closest('.ProseMirror')
|
|
244
|
+
const elements = root?.querySelectorAll<PageChunkElement>(`${PAGE_CHUNK_TAG_NAME}[data-group="${group}"]`)
|
|
245
|
+
return Array.from(elements || [])
|
|
246
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { getId } from '@ocavue/utils'
|
|
2
|
+
import { definePlugin, type Extension } from '@prosekit/core'
|
|
3
|
+
import type { Node } from '@prosekit/pm/model'
|
|
4
|
+
import { Plugin, PluginKey } from '@prosekit/pm/state'
|
|
5
|
+
import { Decoration, DecorationSet } from '@prosekit/pm/view'
|
|
6
|
+
|
|
7
|
+
import { PAGE_CHUNK_TAG_NAME, registerPageChunkElement } from './page-element.ts'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export interface PageRenderingOptions {
|
|
13
|
+
/**
|
|
14
|
+
* The width of the page in px.
|
|
15
|
+
*
|
|
16
|
+
* @default 794 (Portrait A4 paper size in 96 DPI)
|
|
17
|
+
*/
|
|
18
|
+
pageWidth?: number
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The height of the page in px.
|
|
22
|
+
*
|
|
23
|
+
* @default 1123 (Portrait A4 paper size in 96 DPI)
|
|
24
|
+
*/
|
|
25
|
+
pageHeight?: number
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The top margin of the page in px.
|
|
29
|
+
*
|
|
30
|
+
* @default 70
|
|
31
|
+
*/
|
|
32
|
+
marginTop?: number
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The right margin of the page in px.
|
|
36
|
+
*
|
|
37
|
+
* @default 70
|
|
38
|
+
*/
|
|
39
|
+
marginRight?: number
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The bottom margin of the page in px.
|
|
43
|
+
*
|
|
44
|
+
* @default 70
|
|
45
|
+
*/
|
|
46
|
+
marginBottom?: number
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The left margin of the page in px.
|
|
50
|
+
*
|
|
51
|
+
* @default 70
|
|
52
|
+
*/
|
|
53
|
+
marginLeft?: number
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
export function definePageRendering(options: PageRenderingOptions = {}): PageRenderingExtension {
|
|
60
|
+
return definePlugin(
|
|
61
|
+
createPageRenderingPlugin(options),
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
export type PageRenderingExtension = Extension
|
|
69
|
+
|
|
70
|
+
function createPageRenderingPlugin(options: PageRenderingOptions): Plugin {
|
|
71
|
+
const {
|
|
72
|
+
pageWidth = 794,
|
|
73
|
+
pageHeight = 1123,
|
|
74
|
+
marginTop = 70,
|
|
75
|
+
marginRight = 70,
|
|
76
|
+
marginBottom = 70,
|
|
77
|
+
marginLeft = 70,
|
|
78
|
+
} = options
|
|
79
|
+
|
|
80
|
+
type PluginState = [group: string, decoration: DecorationSet]
|
|
81
|
+
|
|
82
|
+
const key = new PluginKey<PluginState>('prosekit-page-render')
|
|
83
|
+
|
|
84
|
+
function createDecorationSet(doc: Node, group: string): DecorationSet {
|
|
85
|
+
const decorations: Decoration[] = []
|
|
86
|
+
const totalCount = doc.childCount
|
|
87
|
+
|
|
88
|
+
doc.forEach((node, pos, index) => {
|
|
89
|
+
const isPageBreak: boolean | undefined = node.type.spec.pageBreak
|
|
90
|
+
|
|
91
|
+
decorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
92
|
+
'nodeName': PAGE_CHUNK_TAG_NAME,
|
|
93
|
+
'data-group': group,
|
|
94
|
+
'data-break': isPageBreak ? 'true' : undefined,
|
|
95
|
+
'data-h': String(pageHeight),
|
|
96
|
+
'data-mt': String(marginTop),
|
|
97
|
+
'data-mb': String(marginBottom),
|
|
98
|
+
'data-size': index === 0 ? String(totalCount) : undefined,
|
|
99
|
+
}))
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
return DecorationSet.create(doc, decorations)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return new Plugin<PluginState>({
|
|
106
|
+
key,
|
|
107
|
+
view: () => {
|
|
108
|
+
registerPageChunkElement()
|
|
109
|
+
return {}
|
|
110
|
+
},
|
|
111
|
+
state: {
|
|
112
|
+
init: (_config, state): PluginState => {
|
|
113
|
+
const group = `page-group-${getId()}`
|
|
114
|
+
const decoration = createDecorationSet(state.doc, group)
|
|
115
|
+
return [group, decoration]
|
|
116
|
+
},
|
|
117
|
+
apply: (tr, value, oldState, newState): PluginState => {
|
|
118
|
+
if (!tr.docChanged) return value
|
|
119
|
+
|
|
120
|
+
const [group, decoration] = value
|
|
121
|
+
|
|
122
|
+
let needRecreate = oldState.doc.childCount !== newState.doc.childCount
|
|
123
|
+
|
|
124
|
+
if (!needRecreate) {
|
|
125
|
+
const count = oldState.doc.childCount
|
|
126
|
+
for (let i = 0; i < count; i++) {
|
|
127
|
+
const oldNode = oldState.doc.child(i)
|
|
128
|
+
const newNode = newState.doc.child(i)
|
|
129
|
+
if (oldNode.type !== newNode.type) {
|
|
130
|
+
needRecreate = true
|
|
131
|
+
break
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!needRecreate) {
|
|
137
|
+
const mapped = decoration.map(tr.mapping, tr.doc, {
|
|
138
|
+
onRemove: () => {
|
|
139
|
+
needRecreate = true
|
|
140
|
+
},
|
|
141
|
+
})
|
|
142
|
+
if (!needRecreate) {
|
|
143
|
+
return [group, mapped]
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return [group, createDecorationSet(newState.doc, group)]
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
props: {
|
|
151
|
+
decorations: (state) => {
|
|
152
|
+
return key.getState(state)?.[1]
|
|
153
|
+
},
|
|
154
|
+
attributes: {
|
|
155
|
+
style: [
|
|
156
|
+
`--page-margin-right:${marginRight}px;`,
|
|
157
|
+
`--page-margin-left:${marginLeft}px;`,
|
|
158
|
+
`--page-width:${pageWidth}px;`,
|
|
159
|
+
`--page-height:${pageHeight}px;`,
|
|
160
|
+
].join(''),
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
})
|
|
164
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
.ProseMirror pm-page-chunk {
|
|
2
|
+
box-sizing: border-box;
|
|
3
|
+
display: flow-root;
|
|
4
|
+
position: relative;
|
|
5
|
+
width: var(--page-width, 100%);
|
|
6
|
+
margin: 0;
|
|
7
|
+
padding-top: 0;
|
|
8
|
+
padding-right: var(--page-margin-right, 0);
|
|
9
|
+
padding-bottom: 0;
|
|
10
|
+
padding-left: var(--page-margin-left, 0);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.ProseMirror pm-page-chunk ~ pm-page-chunk[data-page-head] {
|
|
14
|
+
margin-top: 50px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@media print {
|
|
18
|
+
.ProseMirror pm-page-chunk ~ pm-page-chunk[data-page-head] {
|
|
19
|
+
margin-top: 0;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.ProseMirror pm-page-chunk[data-page-head]::before {
|
|
24
|
+
box-sizing: border-box;
|
|
25
|
+
position: absolute;
|
|
26
|
+
top: 0;
|
|
27
|
+
left: 0;
|
|
28
|
+
width: 100%;
|
|
29
|
+
height: var(--page-height);
|
|
30
|
+
outline: 1px solid CanvasText;
|
|
31
|
+
content: "";
|
|
32
|
+
pointer-events: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@media print {
|
|
36
|
+
.ProseMirror pm-page-chunk[data-page-head]::before {
|
|
37
|
+
outline-color: transparent;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.ProseMirror pm-page-chunk[data-page-tail] {
|
|
42
|
+
break-after: page;
|
|
43
|
+
}
|
package/src/paragraph/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type {
|
|
3
|
-
export {
|
|
4
|
-
export
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export type {
|
|
1
|
+
export { defineParagraphCommands } from './paragraph-commands.ts'
|
|
2
|
+
export type { ParagraphCommandsExtension } from './paragraph-commands.ts'
|
|
3
|
+
export { defineParagraphKeymap } from './paragraph-keymap.ts'
|
|
4
|
+
export { defineParagraphSpec } from './paragraph-spec.ts'
|
|
5
|
+
export type { ParagraphSpecExtension } from './paragraph-spec.ts'
|
|
6
|
+
export { defineParagraph } from './paragraph.ts'
|
|
7
|
+
export type { ParagraphExtension } from './paragraph.ts'
|