@prosekit/extensions 0.14.2 → 0.16.0-beta.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.
Files changed (151) hide show
  1. package/dist/commit/style.css +1 -3
  2. package/dist/{drop-indicator-DJq8pF92.js → drop-indicator.js} +2 -4
  3. package/dist/drop-indicator.js.map +1 -0
  4. package/dist/{file-upload-I9m1EJAM.js → file.js} +2 -6
  5. package/dist/file.js.map +1 -0
  6. package/dist/gap-cursor/style.css +5 -8
  7. package/dist/{file-upload-dr3IXUty.d.ts → index.d.ts} +1 -1
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/list/style.css +79 -110
  10. package/dist/loro/style.css +18 -21
  11. package/dist/{mark-rule-Bqdm49Eq.js → mark-rule.js} +2 -5
  12. package/dist/mark-rule.js.map +1 -0
  13. package/dist/page/style.css +43 -0
  14. package/dist/{mark-paste-rule--F1QPUcU.js → paste-rule.js} +2 -6
  15. package/dist/paste-rule.js.map +1 -0
  16. package/dist/placeholder/style.css +4 -7
  17. package/dist/prosekit-extensions-autocomplete.js +1 -5
  18. package/dist/prosekit-extensions-autocomplete.js.map +1 -1
  19. package/dist/prosekit-extensions-background-color.js +1 -4
  20. package/dist/prosekit-extensions-background-color.js.map +1 -1
  21. package/dist/prosekit-extensions-blockquote.js +1 -6
  22. package/dist/prosekit-extensions-blockquote.js.map +1 -1
  23. package/dist/prosekit-extensions-bold.js +1 -6
  24. package/dist/prosekit-extensions-bold.js.map +1 -1
  25. package/dist/prosekit-extensions-code-block.d.ts +4 -2
  26. package/dist/prosekit-extensions-code-block.d.ts.map +1 -1
  27. package/dist/prosekit-extensions-code-block.js +1 -10
  28. package/dist/prosekit-extensions-code-block.js.map +1 -1
  29. package/dist/prosekit-extensions-code.js +1 -6
  30. package/dist/prosekit-extensions-code.js.map +1 -1
  31. package/dist/prosekit-extensions-commit.js +1 -2
  32. package/dist/prosekit-extensions-commit.js.map +1 -1
  33. package/dist/prosekit-extensions-doc.js +1 -2
  34. package/dist/prosekit-extensions-doc.js.map +1 -1
  35. package/dist/prosekit-extensions-drop-cursor.js +1 -2
  36. package/dist/prosekit-extensions-drop-cursor.js.map +1 -1
  37. package/dist/prosekit-extensions-drop-indicator.js +2 -3
  38. package/dist/prosekit-extensions-enter-rule.js +1 -2
  39. package/dist/prosekit-extensions-enter-rule.js.map +1 -1
  40. package/dist/prosekit-extensions-file.d.ts +2 -2
  41. package/dist/prosekit-extensions-file.js +2 -3
  42. package/dist/prosekit-extensions-gap-cursor.js +1 -2
  43. package/dist/prosekit-extensions-gap-cursor.js.map +1 -1
  44. package/dist/prosekit-extensions-hard-break.js +1 -5
  45. package/dist/prosekit-extensions-hard-break.js.map +1 -1
  46. package/dist/prosekit-extensions-heading.js +1 -6
  47. package/dist/prosekit-extensions-heading.js.map +1 -1
  48. package/dist/prosekit-extensions-horizontal-rule.d.ts.map +1 -1
  49. package/dist/prosekit-extensions-horizontal-rule.js +3 -6
  50. package/dist/prosekit-extensions-horizontal-rule.js.map +1 -1
  51. package/dist/prosekit-extensions-image.d.ts +1 -2
  52. package/dist/prosekit-extensions-image.d.ts.map +1 -1
  53. package/dist/prosekit-extensions-image.js +2 -8
  54. package/dist/prosekit-extensions-image.js.map +1 -1
  55. package/dist/prosekit-extensions-input-rule.js +1 -2
  56. package/dist/prosekit-extensions-input-rule.js.map +1 -1
  57. package/dist/prosekit-extensions-italic.js +1 -6
  58. package/dist/prosekit-extensions-italic.js.map +1 -1
  59. package/dist/prosekit-extensions-link.js +3 -6
  60. package/dist/prosekit-extensions-link.js.map +1 -1
  61. package/dist/prosekit-extensions-list.js +2 -10
  62. package/dist/prosekit-extensions-list.js.map +1 -1
  63. package/dist/prosekit-extensions-loro.d.ts.map +1 -1
  64. package/dist/prosekit-extensions-loro.js +3 -9
  65. package/dist/prosekit-extensions-loro.js.map +1 -1
  66. package/dist/prosekit-extensions-mark-rule.js +2 -3
  67. package/dist/prosekit-extensions-math.js +1 -5
  68. package/dist/prosekit-extensions-math.js.map +1 -1
  69. package/dist/prosekit-extensions-mention.js +1 -2
  70. package/dist/prosekit-extensions-mention.js.map +1 -1
  71. package/dist/prosekit-extensions-mod-click-prevention.js +1 -2
  72. package/dist/prosekit-extensions-mod-click-prevention.js.map +1 -1
  73. package/dist/prosekit-extensions-page.d.ts +114 -0
  74. package/dist/prosekit-extensions-page.d.ts.map +1 -0
  75. package/dist/prosekit-extensions-page.js +324 -0
  76. package/dist/prosekit-extensions-page.js.map +1 -0
  77. package/dist/prosekit-extensions-paragraph.d.ts.map +1 -1
  78. package/dist/prosekit-extensions-paragraph.js +3 -7
  79. package/dist/prosekit-extensions-paragraph.js.map +1 -1
  80. package/dist/prosekit-extensions-paste-rule.js +2 -3
  81. package/dist/prosekit-extensions-placeholder.js +2 -3
  82. package/dist/prosekit-extensions-placeholder.js.map +1 -1
  83. package/dist/prosekit-extensions-readonly.js +1 -2
  84. package/dist/prosekit-extensions-readonly.js.map +1 -1
  85. package/dist/prosekit-extensions-search.js +1 -2
  86. package/dist/prosekit-extensions-search.js.map +1 -1
  87. package/dist/prosekit-extensions-strike.js +1 -2
  88. package/dist/prosekit-extensions-strike.js.map +1 -1
  89. package/dist/prosekit-extensions-table.js +2 -3
  90. package/dist/prosekit-extensions-text-align.js +1 -2
  91. package/dist/prosekit-extensions-text-align.js.map +1 -1
  92. package/dist/prosekit-extensions-text-color.js +1 -4
  93. package/dist/prosekit-extensions-text-color.js.map +1 -1
  94. package/dist/prosekit-extensions-text.js +1 -2
  95. package/dist/prosekit-extensions-text.js.map +1 -1
  96. package/dist/prosekit-extensions-underline.js +1 -2
  97. package/dist/prosekit-extensions-underline.js.map +1 -1
  98. package/dist/prosekit-extensions-virtual-selection.js +1 -2
  99. package/dist/prosekit-extensions-virtual-selection.js.map +1 -1
  100. package/dist/prosekit-extensions-yjs.d.ts.map +1 -1
  101. package/dist/prosekit-extensions-yjs.js +3 -9
  102. package/dist/prosekit-extensions-yjs.js.map +1 -1
  103. package/dist/prosekit-extensions.js +1 -1
  104. package/dist/search/style.css +4 -8
  105. package/dist/shiki-highlighter-chunk.js +1 -2
  106. package/dist/shiki-highlighter-chunk.js.map +1 -1
  107. package/dist/table/style.css +16 -16
  108. package/dist/{table-B81i9oH9.js → table.js} +3 -15
  109. package/dist/table.js.map +1 -0
  110. package/dist/virtual-selection/style.css +1 -4
  111. package/dist/yjs/style.css +14 -20
  112. package/package.json +27 -14
  113. package/src/horizontal-rule/horizontal-rule-commands.ts +2 -1
  114. package/src/loro/loro.ts +3 -2
  115. package/src/page/index.ts +5 -0
  116. package/src/page/page-break-commands.spec.ts +61 -0
  117. package/src/page/page-break-commands.ts +41 -0
  118. package/src/page/page-break-keymap.ts +17 -0
  119. package/src/page/page-break-spec.ts +33 -0
  120. package/src/page/page-break.ts +23 -0
  121. package/src/page/page-element.ts +246 -0
  122. package/src/page/page-rendering.ts +164 -0
  123. package/src/page/style.css +43 -0
  124. package/src/paragraph/paragraph.ts +3 -2
  125. package/src/yjs/yjs.ts +3 -2
  126. package/dist/commit/style.css.map +0 -1
  127. package/dist/commit/style.js +0 -1
  128. package/dist/drop-indicator-DJq8pF92.js.map +0 -1
  129. package/dist/file-upload-I9m1EJAM.js.map +0 -1
  130. package/dist/file-upload-dr3IXUty.d.ts.map +0 -1
  131. package/dist/gap-cursor/style.css.map +0 -1
  132. package/dist/gap-cursor/style.js +0 -1
  133. package/dist/list/style.css.map +0 -1
  134. package/dist/list/style.js +0 -1
  135. package/dist/loro/style.css.map +0 -1
  136. package/dist/loro/style.js +0 -1
  137. package/dist/mark-paste-rule--F1QPUcU.js.map +0 -1
  138. package/dist/mark-rule-Bqdm49Eq.js.map +0 -1
  139. package/dist/placeholder/style.css.map +0 -1
  140. package/dist/placeholder/style.js +0 -1
  141. package/dist/search/style.css.map +0 -1
  142. package/dist/search/style.js +0 -1
  143. package/dist/shiki-highlighter-chunk.d.ts +0 -19
  144. package/dist/shiki-highlighter-chunk.d.ts.map +0 -1
  145. package/dist/table/style.css.map +0 -1
  146. package/dist/table/style.js +0 -1
  147. package/dist/table-B81i9oH9.js.map +0 -1
  148. package/dist/virtual-selection/style.css.map +0 -1
  149. package/dist/virtual-selection/style.js +0 -1
  150. package/dist/yjs/style.css.map +0 -1
  151. package/dist/yjs/style.js +0 -1
@@ -0,0 +1,114 @@
1
+ import { Command } from "@prosekit/pm/state";
2
+ import { Extension, PlainExtension, Union } from "@prosekit/core";
3
+ import { Attrs } from "@prosekit/pm/model";
4
+
5
+ //#region src/page/page-break-commands.d.ts
6
+ /**
7
+ * @internal
8
+ */
9
+ type PageBreakCommandsExtension = Extension<{
10
+ Commands: {
11
+ insertPageBreak: [];
12
+ };
13
+ }>;
14
+ /**
15
+ * @internal
16
+ */
17
+ declare function insertPageBreak(): Command;
18
+ /**
19
+ * @internal
20
+ */
21
+ declare function definePageBreakCommands(): PageBreakCommandsExtension;
22
+ //#endregion
23
+ //#region src/page/page-break-keymap.d.ts
24
+ /**
25
+ * @internal
26
+ */
27
+ type PageBreakKeymapExtension = PlainExtension;
28
+ /**
29
+ * @internal
30
+ */
31
+ declare function definePageBreakKeymap(): PageBreakKeymapExtension;
32
+ //#endregion
33
+ //#region src/page/page-break-spec.d.ts
34
+ /**
35
+ * @internal
36
+ */
37
+ type PageBreakSpecExtension = Extension<{
38
+ Nodes: {
39
+ pageBreak: Attrs;
40
+ };
41
+ }>;
42
+ /**
43
+ * @internal
44
+ */
45
+ declare function definePageBreakSpec(): PageBreakSpecExtension;
46
+ declare module '@prosekit/pm/model' {
47
+ interface NodeSpec {
48
+ pageBreak?: boolean | undefined;
49
+ }
50
+ } //# sourceMappingURL=page-break-spec.d.ts.map
51
+ //#endregion
52
+ //#region src/page/page-break.d.ts
53
+ /**
54
+ * @internal
55
+ */
56
+ type PageBreakExtension = Union<[PageBreakSpecExtension, PageBreakCommandsExtension, PageBreakKeymapExtension]>;
57
+ /**
58
+ * @public
59
+ */
60
+ declare function definePageBreak(): PageBreakExtension;
61
+ //#endregion
62
+ //#region src/page/page-rendering.d.ts
63
+ /**
64
+ * @public
65
+ */
66
+ interface PageRenderingOptions {
67
+ /**
68
+ * The width of the page in px.
69
+ *
70
+ * @default 794 (Portrait A4 paper size in 96 DPI)
71
+ */
72
+ pageWidth?: number;
73
+ /**
74
+ * The height of the page in px.
75
+ *
76
+ * @default 1123 (Portrait A4 paper size in 96 DPI)
77
+ */
78
+ pageHeight?: number;
79
+ /**
80
+ * The top margin of the page in px.
81
+ *
82
+ * @default 70
83
+ */
84
+ marginTop?: number;
85
+ /**
86
+ * The right margin of the page in px.
87
+ *
88
+ * @default 70
89
+ */
90
+ marginRight?: number;
91
+ /**
92
+ * The bottom margin of the page in px.
93
+ *
94
+ * @default 70
95
+ */
96
+ marginBottom?: number;
97
+ /**
98
+ * The left margin of the page in px.
99
+ *
100
+ * @default 70
101
+ */
102
+ marginLeft?: number;
103
+ }
104
+ /**
105
+ * @public
106
+ */
107
+ declare function definePageRendering(options?: PageRenderingOptions): PageRenderingExtension;
108
+ /**
109
+ * @internal
110
+ */
111
+ type PageRenderingExtension = Extension;
112
+ //#endregion
113
+ export { type PageBreakCommandsExtension, type PageBreakExtension, type PageBreakKeymapExtension, type PageBreakSpecExtension, type PageRenderingExtension, type PageRenderingOptions, definePageBreak, definePageBreakCommands, definePageBreakKeymap, definePageBreakSpec, definePageRendering, insertPageBreak };
114
+ //# sourceMappingURL=prosekit-extensions-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prosekit-extensions-page.d.ts","names":[],"sources":["../src/page/page-break-commands.ts","../src/page/page-break-keymap.ts","../src/page/page-break-spec.ts","../src/page/page-break.ts","../src/page/page-rendering.ts"],"mappings":";;;;;;;;KAOY,0BAAA,GAA6B,SAAA;EACvC,QAAA;IACE,eAAA;EAAA;AAAA;;;;iBAoBY,eAAA,CAAA,GAAmB,OAAA;AAAnC;;;AAAA,iBAOgB,uBAAA,CAAA,GAA2B,0BAAA;;;;;;KC7B/B,wBAAA,GAA2B,cAAA;ADAvC;;;AAAA,iBCKgB,qBAAA,CAAA,GAAyB,wBAAA;;;;;;KCN7B,sBAAA,GAAyB,SAAA;EACnC,KAAA;IACE,SAAA,EAAW,KAAA;EAAA;AAAA;;;;iBAOC,mBAAA,CAAA,GAAuB,sBAAA;AAAA;EAAA,UAc3B,QAAA;IACR,SAAA;EAAA;AAAA;;;;AFvBJ;;KGEY,kBAAA,GAAqB,KAAA,EAC9B,sBAAA,EAAwB,0BAAA,EAA4B,wBAAA;;;AHmBvD;iBGbgB,eAAA,CAAA,GAAmB,kBAAA;;;;;;UCLlB,oBAAA;EJJL;;;;;EIUV,SAAA;EJRE;;;AAoBJ;;EILE,UAAA;EJKiC;;AAOnC;;;EILE,SAAA;EJKmE;;;;AC7BrE;EG+BE,WAAA;;;;AH1BF;;EGiCE,YAAA;EHjCuC;;;;;EGwCvC,UAAA;AAAA;;;;iBAMc,mBAAA,CAAoB,OAAA,GAAS,oBAAA,GAA4B,sBAAA;;;;KAS7D,sBAAA,GAAyB,SAAA"}
@@ -0,0 +1,324 @@
1
+ import { Plugin, PluginKey } from "@prosekit/pm/state";
2
+ import { defineCommands, defineKeymap, defineNodeSpec, definePlugin, getNodeType, union } from "@prosekit/core";
3
+ import { Decoration, DecorationSet } from "@prosekit/pm/view";
4
+ import { Fragment, Slice } from "@prosekit/pm/model";
5
+ import { getId, once } from "@ocavue/utils";
6
+ import { HTMLElement, customElements } from "server-dom-shim";
7
+ //#region src/page/page-break-commands.ts
8
+ const insertPageBreakCommand = (state, dispatch) => {
9
+ if (!dispatch) return true;
10
+ const { schema, tr } = state;
11
+ const node = getNodeType(schema, "pageBreak").createChecked();
12
+ const pos = tr.selection.anchor;
13
+ const slice = new Slice(Fragment.from(node), 0, 0);
14
+ tr.replaceRange(pos, pos, slice).scrollIntoView();
15
+ dispatch(tr);
16
+ return true;
17
+ };
18
+ /**
19
+ * @internal
20
+ */
21
+ function insertPageBreak() {
22
+ return insertPageBreakCommand;
23
+ }
24
+ /**
25
+ * @internal
26
+ */
27
+ function definePageBreakCommands() {
28
+ return defineCommands({ insertPageBreak });
29
+ }
30
+ //#endregion
31
+ //#region src/page/page-break-keymap.ts
32
+ /**
33
+ * @internal
34
+ */
35
+ function definePageBreakKeymap() {
36
+ return defineKeymap({ "Mod-Enter": insertPageBreak() });
37
+ }
38
+ //#endregion
39
+ //#region src/page/page-break-spec.ts
40
+ /**
41
+ * @internal
42
+ */
43
+ function definePageBreakSpec() {
44
+ return defineNodeSpec({
45
+ name: "pageBreak",
46
+ group: "block",
47
+ selectable: true,
48
+ parseDOM: [{ tag: "div.prosekit-page-break" }],
49
+ toDOM() {
50
+ return [
51
+ "div",
52
+ { class: "prosekit-horizontal-rule prosekit-page-break" },
53
+ ["hr"]
54
+ ];
55
+ },
56
+ pageBreak: true
57
+ });
58
+ }
59
+ //#endregion
60
+ //#region src/page/page-break.ts
61
+ /**
62
+ * @public
63
+ */
64
+ function definePageBreak() {
65
+ return union(definePageBreakSpec(), definePageBreakCommands(), definePageBreakKeymap());
66
+ }
67
+ //#endregion
68
+ //#region src/page/page-element.ts
69
+ /**
70
+ * @internal
71
+ */
72
+ const PAGE_CHUNK_TAG_NAME = "pm-page-chunk";
73
+ /**
74
+ * @internal
75
+ */
76
+ const registerPageChunkElement = /* @__PURE__ */ once(() => {
77
+ if (typeof window === "undefined" || customElements.get("pm-page-chunk")) return;
78
+ customElements.define(PAGE_CHUNK_TAG_NAME, PageChunkElement);
79
+ });
80
+ var PageChunkElement = class extends HTMLElement {
81
+ static {
82
+ this.observedAttributes = [
83
+ "data-group",
84
+ "data-break",
85
+ "data-h",
86
+ "data-mt",
87
+ "data-mb",
88
+ "data-size"
89
+ ];
90
+ }
91
+ #group = "";
92
+ #forceNextBreak = false;
93
+ #pageHeight = 0;
94
+ #pageMarginTop = 0;
95
+ #pageMarginBottom = 0;
96
+ #size = void 0;
97
+ #updateRequested = false;
98
+ #contentBoxHeight = 0;
99
+ #isHead = false;
100
+ #isTail = false;
101
+ #paddingTop = 0;
102
+ #paddingBottom = 0;
103
+ #isHeadPending = false;
104
+ #isTailPending = false;
105
+ #paddingTopPending = 0;
106
+ #paddingBottomPending = 0;
107
+ connectedCallback() {
108
+ this.#parseDataAttributes();
109
+ if (this.#isLeader()) this.#isHeadPending = true;
110
+ this.#render();
111
+ this.#contentBoxHeight = this.clientHeight - this.#paddingTop - this.#paddingBottom;
112
+ observeElement(this);
113
+ this.#requestUpdate();
114
+ }
115
+ disconnectedCallback() {
116
+ unobserveElement(this);
117
+ }
118
+ attributeChangedCallback(_, oldValue, newValue) {
119
+ if (oldValue === newValue) return;
120
+ this.#parseDataAttributes();
121
+ this.#requestUpdate();
122
+ }
123
+ #parseDataAttributes() {
124
+ this.#group = this.getAttribute("data-group") || "";
125
+ this.#forceNextBreak = this.hasAttribute("data-break");
126
+ this.#pageHeight = this.#parseFloatAttribute("data-h");
127
+ this.#pageMarginTop = this.#parseFloatAttribute("data-mt");
128
+ this.#pageMarginBottom = this.#parseFloatAttribute("data-mb");
129
+ const sizeAttr = this.getAttribute("data-size");
130
+ this.#size = sizeAttr ? Number.parseInt(sizeAttr, 10) : void 0;
131
+ }
132
+ #parseFloatAttribute(name) {
133
+ const value = this.getAttribute(name);
134
+ return value != null ? Number.parseFloat(value) : 0;
135
+ }
136
+ #isLeader() {
137
+ return this.#size != null;
138
+ }
139
+ #render() {
140
+ if (this.#paddingTop !== this.#paddingTopPending || this.#paddingBottom !== this.#paddingBottomPending) Object.assign(this.style, {
141
+ paddingTop: `${this.#paddingTop = this.#paddingTopPending}px`,
142
+ paddingBottom: `${this.#paddingBottom = this.#paddingBottomPending}px`
143
+ });
144
+ if (this.#isHead !== this.#isHeadPending) this.toggleAttribute("data-page-head", this.#isHead = this.#isHeadPending);
145
+ if (this.#isTail !== this.#isTailPending) this.toggleAttribute("data-page-tail", this.#isTail = this.#isTailPending);
146
+ }
147
+ setHeight(height) {
148
+ if (Math.abs(this.#contentBoxHeight - height) < .1) return;
149
+ this.#contentBoxHeight = height;
150
+ this.#requestUpdate();
151
+ }
152
+ /**
153
+ * Schedules a batched page layout recalculation.
154
+ *
155
+ * Any chunk can call this method, but the actual layout work (#updateAll)
156
+ * always runs on the leader chunk, because it needs to iterate over every
157
+ * chunk in order to compute page breaks.
158
+ *
159
+ * Two nested microtasks are used to batch updates:
160
+ *
161
+ * Microtask 1 – Delegation: non-leader chunks forward the request to the
162
+ * leader chunk, so multiple chunks changing in the same tick only trigger
163
+ * one layout pass.
164
+ *
165
+ * Microtask 2 – Execution: the leader chunk defers #updateAll to a second
166
+ * microtask so that any other attribute / resize changes that were queued
167
+ * in the same tick (and forwarded during microtask 1) are already reflected
168
+ * before the layout is recalculated.
169
+ *
170
+ * The #updateRequested flag acts as a deduplication guard so that rapid
171
+ * successive calls (e.g. multiple attributes changing at once) result in at
172
+ * most one scheduled pass per chunk.
173
+ */
174
+ #requestUpdate() {
175
+ if (this.#updateRequested) return;
176
+ this.#updateRequested = true;
177
+ queueMicrotask(() => {
178
+ if (!this.#isLeader()) {
179
+ this.#updateRequested = false;
180
+ const leader = findLeaderChunk(this, this.#group);
181
+ if (!leader) return;
182
+ leader.#requestUpdate();
183
+ return;
184
+ }
185
+ queueMicrotask(() => {
186
+ this.#updateRequested = false;
187
+ this.#updateAll();
188
+ });
189
+ });
190
+ }
191
+ #updateAll() {
192
+ if (!this.isConnected) return;
193
+ const elements = findAllChunks(this, this.#group);
194
+ const count = elements.length;
195
+ if (count === 0) return;
196
+ const pageHeight = this.#pageHeight;
197
+ const pageMarginTop = this.#pageMarginTop;
198
+ const maxContentHeight = pageHeight - pageMarginTop - this.#pageMarginBottom;
199
+ let currentContentHeight = 0;
200
+ let forceNextBreak = false;
201
+ for (let i = 0; i < count; i++) {
202
+ const element = elements[i];
203
+ const h = element.#contentBoxHeight;
204
+ const isHead = forceNextBreak || i === 0 || currentContentHeight + h > maxContentHeight;
205
+ forceNextBreak = element.#forceNextBreak;
206
+ if (isHead && i > 0) {
207
+ const prev = elements[i - 1];
208
+ prev.#paddingBottomPending = Math.max(0, pageHeight - pageMarginTop - currentContentHeight);
209
+ prev.#isTailPending = true;
210
+ currentContentHeight = h;
211
+ } else currentContentHeight += h;
212
+ element.#paddingTopPending = isHead ? pageMarginTop : 0;
213
+ element.#paddingBottomPending = 0;
214
+ element.#isTailPending = false;
215
+ element.#isHeadPending = isHead;
216
+ }
217
+ const last = elements[count - 1];
218
+ last.#paddingBottomPending = Math.max(0, pageHeight - pageMarginTop - currentContentHeight);
219
+ last.#isTailPending = true;
220
+ for (const element of elements) element.#render();
221
+ }
222
+ };
223
+ function handleResize(entries) {
224
+ for (const entry of entries) {
225
+ const contentBoxHeight = entry.contentBoxSize?.[0]?.blockSize ?? entry.contentRect.height;
226
+ entry.target.setHeight(contentBoxHeight);
227
+ }
228
+ }
229
+ const getResizeObserver = /* @__PURE__ */ once(() => {
230
+ return new ResizeObserver(handleResize);
231
+ });
232
+ function observeElement(element) {
233
+ getResizeObserver().observe(element);
234
+ }
235
+ function unobserveElement(element) {
236
+ getResizeObserver().unobserve(element);
237
+ }
238
+ function findLeaderChunk(element, group) {
239
+ return element.closest(".ProseMirror")?.querySelector(`${PAGE_CHUNK_TAG_NAME}[data-group="${group}"][data-size]`);
240
+ }
241
+ function findAllChunks(element, group) {
242
+ const elements = element.closest(".ProseMirror")?.querySelectorAll(`${PAGE_CHUNK_TAG_NAME}[data-group="${group}"]`);
243
+ return Array.from(elements || []);
244
+ }
245
+ //#endregion
246
+ //#region src/page/page-rendering.ts
247
+ /**
248
+ * @public
249
+ */
250
+ function definePageRendering(options = {}) {
251
+ return definePlugin(createPageRenderingPlugin(options));
252
+ }
253
+ function createPageRenderingPlugin(options) {
254
+ const { pageWidth = 794, pageHeight = 1123, marginTop = 70, marginRight = 70, marginBottom = 70, marginLeft = 70 } = options;
255
+ const key = new PluginKey("prosekit-page-render");
256
+ function createDecorationSet(doc, group) {
257
+ const decorations = [];
258
+ const totalCount = doc.childCount;
259
+ doc.forEach((node, pos, index) => {
260
+ const isPageBreak = node.type.spec.pageBreak;
261
+ decorations.push(Decoration.node(pos, pos + node.nodeSize, {
262
+ "nodeName": PAGE_CHUNK_TAG_NAME,
263
+ "data-group": group,
264
+ "data-break": isPageBreak ? "true" : void 0,
265
+ "data-h": String(pageHeight),
266
+ "data-mt": String(marginTop),
267
+ "data-mb": String(marginBottom),
268
+ "data-size": index === 0 ? String(totalCount) : void 0
269
+ }));
270
+ });
271
+ return DecorationSet.create(doc, decorations);
272
+ }
273
+ return new Plugin({
274
+ key,
275
+ view: () => {
276
+ registerPageChunkElement();
277
+ return {};
278
+ },
279
+ state: {
280
+ init: (_config, state) => {
281
+ const group = `page-group-${getId()}`;
282
+ return [group, createDecorationSet(state.doc, group)];
283
+ },
284
+ apply: (tr, value, oldState, newState) => {
285
+ if (!tr.docChanged) return value;
286
+ const [group, decoration] = value;
287
+ let needRecreate = oldState.doc.childCount !== newState.doc.childCount;
288
+ if (!needRecreate) {
289
+ const count = oldState.doc.childCount;
290
+ for (let i = 0; i < count; i++) {
291
+ const oldNode = oldState.doc.child(i);
292
+ const newNode = newState.doc.child(i);
293
+ if (oldNode.type !== newNode.type) {
294
+ needRecreate = true;
295
+ break;
296
+ }
297
+ }
298
+ }
299
+ if (!needRecreate) {
300
+ const mapped = decoration.map(tr.mapping, tr.doc, { onRemove: () => {
301
+ needRecreate = true;
302
+ } });
303
+ if (!needRecreate) return [group, mapped];
304
+ }
305
+ return [group, createDecorationSet(newState.doc, group)];
306
+ }
307
+ },
308
+ props: {
309
+ decorations: (state) => {
310
+ return key.getState(state)?.[1];
311
+ },
312
+ attributes: { style: [
313
+ `--page-margin-right:${marginRight}px;`,
314
+ `--page-margin-left:${marginLeft}px;`,
315
+ `--page-width:${pageWidth}px;`,
316
+ `--page-height:${pageHeight}px;`
317
+ ].join("") }
318
+ }
319
+ });
320
+ }
321
+ //#endregion
322
+ export { definePageBreak, definePageBreakCommands, definePageBreakKeymap, definePageBreakSpec, definePageRendering, insertPageBreak };
323
+
324
+ //# sourceMappingURL=prosekit-extensions-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prosekit-extensions-page.js","names":["#parseDataAttributes","#isLeader","#isHeadPending","#render","#contentBoxHeight","#paddingTop","#paddingBottom","#requestUpdate","#group","#forceNextBreak","#pageHeight","#parseFloatAttribute","#pageMarginTop","#pageMarginBottom","#size","#paddingTopPending","#paddingBottomPending","#isHead","#isTail","#isTailPending","#updateRequested","#updateAll"],"sources":["../src/page/page-break-commands.ts","../src/page/page-break-keymap.ts","../src/page/page-break-spec.ts","../src/page/page-break.ts","../src/page/page-element.ts","../src/page/page-rendering.ts"],"sourcesContent":["import { defineCommands, getNodeType, type Extension } from '@prosekit/core'\nimport { Fragment, Slice } from '@prosekit/pm/model'\nimport type { Command } from '@prosekit/pm/state'\n\n/**\n * @internal\n */\nexport type PageBreakCommandsExtension = Extension<{\n Commands: {\n insertPageBreak: []\n }\n}>\n\nconst insertPageBreakCommand: Command = (state, dispatch): boolean => {\n if (!dispatch) return true\n\n const { schema, tr } = state\n const type = getNodeType(schema, 'pageBreak')\n const node = type.createChecked()\n const pos = tr.selection.anchor\n const slice = new Slice(Fragment.from(node), 0, 0)\n tr.replaceRange(pos, pos, slice).scrollIntoView()\n dispatch(tr)\n return true\n}\n\n/**\n * @internal\n */\nexport function insertPageBreak(): Command {\n return insertPageBreakCommand\n}\n\n/**\n * @internal\n */\nexport function definePageBreakCommands(): PageBreakCommandsExtension {\n return defineCommands({\n insertPageBreak: insertPageBreak,\n })\n}\n","import { defineKeymap, type PlainExtension } from '@prosekit/core'\n\nimport { insertPageBreak } from './page-break-commands.ts'\n\n/**\n * @internal\n */\nexport type PageBreakKeymapExtension = PlainExtension\n\n/**\n * @internal\n */\nexport function definePageBreakKeymap(): PageBreakKeymapExtension {\n return defineKeymap({\n 'Mod-Enter': insertPageBreak(),\n })\n}\n","import { defineNodeSpec, type Extension } from '@prosekit/core'\nimport type { Attrs } from '@prosekit/pm/model'\n\n/**\n * @internal\n */\nexport type PageBreakSpecExtension = Extension<{\n Nodes: {\n pageBreak: Attrs\n }\n}>\n\n/**\n * @internal\n */\nexport function definePageBreakSpec(): PageBreakSpecExtension {\n return defineNodeSpec({\n name: 'pageBreak',\n group: 'block',\n selectable: true,\n parseDOM: [{ tag: 'div.prosekit-page-break' }],\n toDOM() {\n return ['div', { class: 'prosekit-horizontal-rule prosekit-page-break' }, ['hr']]\n },\n pageBreak: true,\n })\n}\n\ndeclare module '@prosekit/pm/model' {\n interface NodeSpec {\n pageBreak?: boolean | undefined\n }\n}\n","import { union, type Union } from '@prosekit/core'\n\nimport { definePageBreakCommands, type PageBreakCommandsExtension } from './page-break-commands.ts'\nimport { definePageBreakKeymap, type PageBreakKeymapExtension } from './page-break-keymap.ts'\nimport { definePageBreakSpec, type PageBreakSpecExtension } from './page-break-spec.ts'\n\n/**\n * @internal\n */\nexport type PageBreakExtension = Union<\n [PageBreakSpecExtension, PageBreakCommandsExtension, PageBreakKeymapExtension]\n>\n\n/**\n * @public\n */\nexport function definePageBreak(): PageBreakExtension {\n return union(\n definePageBreakSpec(),\n definePageBreakCommands(),\n definePageBreakKeymap(),\n )\n}\n","import { once } from '@ocavue/utils'\nimport { customElements, HTMLElement } from 'server-dom-shim'\n\n/**\n * @internal\n */\nexport const PAGE_CHUNK_TAG_NAME = 'pm-page-chunk'\n\n/**\n * @internal\n */\nexport const registerPageChunkElement: VoidFunction = /* @__PURE__ */ once(() => {\n if (typeof window === 'undefined' || customElements.get(PAGE_CHUNK_TAG_NAME)) return\n customElements.define(PAGE_CHUNK_TAG_NAME, PageChunkElement)\n})\n\nclass PageChunkElement extends HTMLElement {\n static observedAttributes = [\n 'data-group',\n 'data-break',\n 'data-h',\n 'data-mt',\n 'data-mb',\n\n // Only the first chunk of the whole document has this attribute.\n 'data-size',\n ]\n\n // Data attributes set by external code\n #group: string = ''\n #forceNextBreak: boolean = false\n #pageHeight: number = 0\n #pageMarginTop: number = 0\n #pageMarginBottom: number = 0\n #size: number | undefined = undefined\n\n // Internal states\n #updateRequested: boolean = false\n #contentBoxHeight: number = 0\n\n // Rendering states\n #isHead: boolean = false\n #isTail: boolean = false\n #paddingTop: number = 0\n #paddingBottom: number = 0\n\n // Pending rendering states\n #isHeadPending: boolean = false\n #isTailPending: boolean = false\n #paddingTopPending: number = 0\n #paddingBottomPending: number = 0\n\n connectedCallback() {\n this.#parseDataAttributes()\n\n if (this.#isLeader()) {\n this.#isHeadPending = true\n }\n\n this.#render()\n\n // Get the initial content box height when the resize observer is not started yet. Notice that\n // `this.clientHeight` is an integer while the content box height can be a float, so this is not\n // accurate but should be good enough for the first render.\n this.#contentBoxHeight = this.clientHeight - this.#paddingTop - this.#paddingBottom\n\n observeElement(this)\n\n this.#requestUpdate()\n }\n\n disconnectedCallback() {\n unobserveElement(this)\n }\n\n attributeChangedCallback(_: string, oldValue: string | null, newValue: string | null) {\n if (oldValue === newValue) return\n this.#parseDataAttributes()\n this.#requestUpdate()\n }\n\n #parseDataAttributes() {\n this.#group = this.getAttribute('data-group') || ''\n this.#forceNextBreak = this.hasAttribute('data-break')\n this.#pageHeight = this.#parseFloatAttribute('data-h')\n this.#pageMarginTop = this.#parseFloatAttribute('data-mt')\n this.#pageMarginBottom = this.#parseFloatAttribute('data-mb')\n\n const sizeAttr = this.getAttribute('data-size')\n this.#size = sizeAttr ? Number.parseInt(sizeAttr, 10) : undefined\n }\n\n #parseFloatAttribute(name: string): number {\n const value = this.getAttribute(name)\n return value != null ? Number.parseFloat(value) : 0\n }\n\n #isLeader() {\n return this.#size != null\n }\n\n #render() {\n if (this.#paddingTop !== this.#paddingTopPending || this.#paddingBottom !== this.#paddingBottomPending) {\n Object.assign(this.style, {\n paddingTop: `${this.#paddingTop = this.#paddingTopPending}px`,\n paddingBottom: `${this.#paddingBottom = this.#paddingBottomPending}px`,\n })\n }\n if (this.#isHead !== this.#isHeadPending) {\n this.toggleAttribute('data-page-head', this.#isHead = this.#isHeadPending)\n }\n if (this.#isTail !== this.#isTailPending) {\n this.toggleAttribute('data-page-tail', this.#isTail = this.#isTailPending)\n }\n }\n\n setHeight(height: number) {\n // Avoid potential float number precision issues\n if (Math.abs(this.#contentBoxHeight - height) < 0.1) {\n return\n }\n this.#contentBoxHeight = height\n this.#requestUpdate()\n }\n\n /**\n * Schedules a batched page layout recalculation.\n *\n * Any chunk can call this method, but the actual layout work (#updateAll)\n * always runs on the leader chunk, because it needs to iterate over every\n * chunk in order to compute page breaks.\n *\n * Two nested microtasks are used to batch updates:\n *\n * Microtask 1 – Delegation: non-leader chunks forward the request to the\n * leader chunk, so multiple chunks changing in the same tick only trigger\n * one layout pass.\n *\n * Microtask 2 – Execution: the leader chunk defers #updateAll to a second\n * microtask so that any other attribute / resize changes that were queued\n * in the same tick (and forwarded during microtask 1) are already reflected\n * before the layout is recalculated.\n *\n * The #updateRequested flag acts as a deduplication guard so that rapid\n * successive calls (e.g. multiple attributes changing at once) result in at\n * most one scheduled pass per chunk.\n */\n #requestUpdate() {\n if (this.#updateRequested) {\n return\n }\n\n this.#updateRequested = true\n queueMicrotask(() => {\n if (!this.#isLeader()) {\n this.#updateRequested = false\n const leader = findLeaderChunk(this, this.#group)\n if (!leader) return\n leader.#requestUpdate()\n return\n }\n queueMicrotask(() => {\n this.#updateRequested = false\n this.#updateAll()\n })\n })\n }\n\n #updateAll() {\n if (!this.isConnected) {\n return\n }\n\n const elements = findAllChunks(this, this.#group)\n const count = elements.length\n if (count === 0) return\n\n const pageHeight = this.#pageHeight\n const pageMarginTop = this.#pageMarginTop\n const maxContentHeight = pageHeight - pageMarginTop - this.#pageMarginBottom\n\n let currentContentHeight = 0\n let forceNextBreak = false\n\n for (let i = 0; i < count; i++) {\n const element = elements[i]\n const h = element.#contentBoxHeight\n const isHead = forceNextBreak || i === 0 || (currentContentHeight + h > maxContentHeight)\n\n forceNextBreak = element.#forceNextBreak\n\n if (isHead && i > 0) {\n const prev = elements[i - 1]\n prev.#paddingBottomPending = Math.max(0, pageHeight - pageMarginTop - currentContentHeight)\n prev.#isTailPending = true\n currentContentHeight = h\n } else {\n currentContentHeight += h\n }\n\n element.#paddingTopPending = isHead ? pageMarginTop : 0\n element.#paddingBottomPending = 0\n element.#isTailPending = false\n element.#isHeadPending = isHead\n }\n\n const last = elements[count - 1]\n last.#paddingBottomPending = Math.max(0, pageHeight - pageMarginTop - currentContentHeight)\n last.#isTailPending = true\n\n for (const element of elements) {\n element.#render()\n }\n }\n}\n\nfunction handleResize(entries: ResizeObserverEntry[]) {\n for (const entry of entries) {\n const contentBoxHeight = entry.contentBoxSize?.[0]?.blockSize ?? entry.contentRect.height\n const element = entry.target as PageChunkElement\n element.setHeight(contentBoxHeight)\n }\n}\n\nconst getResizeObserver = /* @__PURE__ */ once(() => {\n return new ResizeObserver(handleResize)\n})\n\nfunction observeElement(element: PageChunkElement) {\n getResizeObserver().observe(element)\n}\n\nfunction unobserveElement(element: PageChunkElement) {\n getResizeObserver().unobserve(element)\n}\n\nfunction findLeaderChunk(element: HTMLElement, group: string): PageChunkElement | null | undefined {\n const root = element.closest('.ProseMirror')\n return root?.querySelector<PageChunkElement>(`${PAGE_CHUNK_TAG_NAME}[data-group=\"${group}\"][data-size]`)\n}\n\nfunction findAllChunks(element: HTMLElement, group: string): PageChunkElement[] {\n const root = element.closest('.ProseMirror')\n const elements = root?.querySelectorAll<PageChunkElement>(`${PAGE_CHUNK_TAG_NAME}[data-group=\"${group}\"]`)\n return Array.from(elements || [])\n}\n","import { getId } from '@ocavue/utils'\nimport { definePlugin, type Extension } from '@prosekit/core'\nimport type { Node } from '@prosekit/pm/model'\nimport { Plugin, PluginKey } from '@prosekit/pm/state'\nimport { Decoration, DecorationSet } from '@prosekit/pm/view'\n\nimport { PAGE_CHUNK_TAG_NAME, registerPageChunkElement } from './page-element.ts'\n\n/**\n * @public\n */\nexport interface PageRenderingOptions {\n /**\n * The width of the page in px.\n *\n * @default 794 (Portrait A4 paper size in 96 DPI)\n */\n pageWidth?: number\n\n /**\n * The height of the page in px.\n *\n * @default 1123 (Portrait A4 paper size in 96 DPI)\n */\n pageHeight?: number\n\n /**\n * The top margin of the page in px.\n *\n * @default 70\n */\n marginTop?: number\n\n /**\n * The right margin of the page in px.\n *\n * @default 70\n */\n marginRight?: number\n\n /**\n * The bottom margin of the page in px.\n *\n * @default 70\n */\n marginBottom?: number\n\n /**\n * The left margin of the page in px.\n *\n * @default 70\n */\n marginLeft?: number\n}\n\n/**\n * @public\n */\nexport function definePageRendering(options: PageRenderingOptions = {}): PageRenderingExtension {\n return definePlugin(\n createPageRenderingPlugin(options),\n )\n}\n\n/**\n * @internal\n */\nexport type PageRenderingExtension = Extension\n\nfunction createPageRenderingPlugin(options: PageRenderingOptions): Plugin {\n const {\n pageWidth = 794,\n pageHeight = 1123,\n marginTop = 70,\n marginRight = 70,\n marginBottom = 70,\n marginLeft = 70,\n } = options\n\n type PluginState = [group: string, decoration: DecorationSet]\n\n const key = new PluginKey<PluginState>('prosekit-page-render')\n\n function createDecorationSet(doc: Node, group: string): DecorationSet {\n const decorations: Decoration[] = []\n const totalCount = doc.childCount\n\n doc.forEach((node, pos, index) => {\n const isPageBreak: boolean | undefined = node.type.spec.pageBreak\n\n decorations.push(Decoration.node(pos, pos + node.nodeSize, {\n 'nodeName': PAGE_CHUNK_TAG_NAME,\n 'data-group': group,\n 'data-break': isPageBreak ? 'true' : undefined,\n 'data-h': String(pageHeight),\n 'data-mt': String(marginTop),\n 'data-mb': String(marginBottom),\n 'data-size': index === 0 ? String(totalCount) : undefined,\n }))\n })\n\n return DecorationSet.create(doc, decorations)\n }\n\n return new Plugin<PluginState>({\n key,\n view: () => {\n registerPageChunkElement()\n return {}\n },\n state: {\n init: (_config, state): PluginState => {\n const group = `page-group-${getId()}`\n const decoration = createDecorationSet(state.doc, group)\n return [group, decoration]\n },\n apply: (tr, value, oldState, newState): PluginState => {\n if (!tr.docChanged) return value\n\n const [group, decoration] = value\n\n let needRecreate = oldState.doc.childCount !== newState.doc.childCount\n\n if (!needRecreate) {\n const count = oldState.doc.childCount\n for (let i = 0; i < count; i++) {\n const oldNode = oldState.doc.child(i)\n const newNode = newState.doc.child(i)\n if (oldNode.type !== newNode.type) {\n needRecreate = true\n break\n }\n }\n }\n\n if (!needRecreate) {\n const mapped = decoration.map(tr.mapping, tr.doc, {\n onRemove: () => {\n needRecreate = true\n },\n })\n if (!needRecreate) {\n return [group, mapped]\n }\n }\n\n return [group, createDecorationSet(newState.doc, group)]\n },\n },\n props: {\n decorations: (state) => {\n return key.getState(state)?.[1]\n },\n attributes: {\n style: [\n `--page-margin-right:${marginRight}px;`,\n `--page-margin-left:${marginLeft}px;`,\n `--page-width:${pageWidth}px;`,\n `--page-height:${pageHeight}px;`,\n ].join(''),\n },\n },\n })\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-paragraph.d.ts","names":[],"sources":["../src/paragraph/paragraph-commands.ts","../src/paragraph/paragraph-keymap.ts","../src/paragraph/paragraph-spec.ts","../src/paragraph/paragraph.ts"],"mappings":";;;;;;;;KAMY,0BAAA,GAA6B,SAAA;EACvC,QAAA;IACE,YAAA;EAAA;AAAA;AAcJ;;;AAAA,iBAAgB,uBAAA,CAAA,GAA2B,0BAAA;;;;;;iBCf3B,qBAAA,CAAA,GAAyB,cAAA;;;;;;KCD7B,sBAAA,GAAyB,SAAA;EACnC,KAAA;IACE,SAAA,EAAW,KAAA;EAAA;AAAA;;;;;AFcf;iBELgB,mBAAA,CAAA,GAAuB,sBAAA;;;;;AFXvC;KGGY,kBAAA,GAAqB,KAAA,EAAO,sBAAA,EAAwB,0BAAA;;;;;;;;AHahE;iBGHgB,eAAA,CAAA,GAAmB,kBAAA"}
1
+ {"version":3,"file":"prosekit-extensions-paragraph.d.ts","names":[],"sources":["../src/paragraph/paragraph-commands.ts","../src/paragraph/paragraph-keymap.ts","../src/paragraph/paragraph-spec.ts","../src/paragraph/paragraph.ts"],"mappings":";;;;;;;;KAMY,0BAAA,GAA6B,SAAA;EACvC,QAAA;IACE,YAAA;EAAA;AAAA;AAcJ;;;AAAA,iBAAgB,uBAAA,CAAA,GAA2B,0BAAA;;;;;;iBCf3B,qBAAA,CAAA,GAAyB,cAAA;;;;;;KCD7B,sBAAA,GAAyB,SAAA;EACnC,KAAA;IACE,SAAA,EAAW,KAAA;EAAA;AAAA;;;;;AFcf;iBELgB,mBAAA,CAAA,GAAuB,sBAAA;;;;;AFXvC;KGIY,kBAAA,GAAqB,KAAA,EAAO,sBAAA,EAAwB,0BAAA;;;;;;;;AHYhE;iBGFgB,eAAA,CAAA,GAAmB,kBAAA"}
@@ -1,5 +1,4 @@
1
- import { Priority, defineCommands, defineKeymap, defineNodeSpec, setBlockType, union, withPriority } from "@prosekit/core";
2
-
1
+ import { defineCommands, defineKeymap, defineNodeSpec, setBlockType, union, withPriority } from "@prosekit/core";
3
2
  //#region src/paragraph/paragraph-commands.ts
4
3
  /**
5
4
  * @internal
@@ -13,7 +12,6 @@ function setParagraph() {
13
12
  function defineParagraphCommands() {
14
13
  return defineCommands({ setParagraph });
15
14
  }
16
-
17
15
  //#endregion
18
16
  //#region src/paragraph/paragraph-keymap.ts
19
17
  /**
@@ -22,7 +20,6 @@ function defineParagraphCommands() {
22
20
  function defineParagraphKeymap() {
23
21
  return defineKeymap({ "Mod-Alt-0": setParagraph() });
24
22
  }
25
-
26
23
  //#endregion
27
24
  //#region src/paragraph/paragraph-spec.ts
28
25
  /**
@@ -41,7 +38,6 @@ function defineParagraphSpec() {
41
38
  }
42
39
  });
43
40
  }
44
-
45
41
  //#endregion
46
42
  //#region src/paragraph/paragraph.ts
47
43
  /**
@@ -53,9 +49,9 @@ function defineParagraphSpec() {
53
49
  * default block node for most cases.
54
50
  */
55
51
  function defineParagraph() {
56
- return union(withPriority(defineParagraphSpec(), Priority.highest), defineParagraphCommands(), defineParagraphKeymap());
52
+ return union(withPriority(defineParagraphSpec(), 4), defineParagraphCommands(), defineParagraphKeymap());
57
53
  }
58
-
59
54
  //#endregion
60
55
  export { defineParagraph, defineParagraphCommands, defineParagraphKeymap, defineParagraphSpec };
56
+
61
57
  //# sourceMappingURL=prosekit-extensions-paragraph.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-paragraph.js","names":[],"sources":["../src/paragraph/paragraph-commands.ts","../src/paragraph/paragraph-keymap.ts","../src/paragraph/paragraph-spec.ts","../src/paragraph/paragraph.ts"],"sourcesContent":["import { defineCommands, setBlockType, type Extension } from '@prosekit/core'\nimport type { Command } from '@prosekit/pm/state'\n\n/**\n * @internal\n */\nexport type ParagraphCommandsExtension = Extension<{\n Commands: {\n setParagraph: []\n }\n}>\n\n/**\n * @internal\n */\nexport function setParagraph(): Command {\n return setBlockType({ type: 'paragraph' })\n}\n\n/**\n * @internal\n */\nexport function defineParagraphCommands(): ParagraphCommandsExtension {\n return defineCommands({ setParagraph })\n}\n","import { defineKeymap, type PlainExtension } from '@prosekit/core'\n\nimport { setParagraph } from './paragraph-commands.ts'\n\n/**\n * @internal\n */\nexport function defineParagraphKeymap(): PlainExtension {\n return defineKeymap({\n 'Mod-Alt-0': setParagraph(),\n })\n}\n","import { defineNodeSpec, type Extension } from '@prosekit/core'\nimport type { Attrs } from '@prosekit/pm/model'\n\n/**\n * @internal\n */\nexport type ParagraphSpecExtension = Extension<{\n Nodes: {\n paragraph: Attrs\n }\n}>\n\n/**\n * @internal\n *\n * Defines a paragraph node spec.\n */\nexport function defineParagraphSpec(): ParagraphSpecExtension {\n return defineNodeSpec({\n name: 'paragraph',\n content: 'inline*',\n group: 'block',\n parseDOM: [{ tag: 'p' }],\n toDOM() {\n return ['p', 0]\n },\n })\n}\n","import { Priority, union, withPriority, type Union } from '@prosekit/core'\n\nimport { defineParagraphCommands, type ParagraphCommandsExtension } from './paragraph-commands.ts'\nimport { defineParagraphKeymap } from './paragraph-keymap.ts'\nimport { defineParagraphSpec, type ParagraphSpecExtension } from './paragraph-spec.ts'\n\n/**\n * @internal\n */\nexport type ParagraphExtension = Union<[ParagraphSpecExtension, ParagraphCommandsExtension]>\n\n/**\n * @public\n *\n * Defines a paragraph node.\n *\n * The paragraph node spec has the highest priority, because it should be the\n * default block node for most cases.\n */\nexport function defineParagraph(): ParagraphExtension {\n return union(\n withPriority(defineParagraphSpec(), Priority.highest),\n defineParagraphCommands(),\n defineParagraphKeymap(),\n )\n}\n"],"mappings":";;;;;;AAeA,SAAgB,eAAwB;AACtC,QAAO,aAAa,EAAE,MAAM,aAAa,CAAC;;;;;AAM5C,SAAgB,0BAAsD;AACpE,QAAO,eAAe,EAAE,cAAc,CAAC;;;;;;;;AChBzC,SAAgB,wBAAwC;AACtD,QAAO,aAAa,EAClB,aAAa,cAAc,EAC5B,CAAC;;;;;;;;;;ACOJ,SAAgB,sBAA8C;AAC5D,QAAO,eAAe;EACpB,MAAM;EACN,SAAS;EACT,OAAO;EACP,UAAU,CAAC,EAAE,KAAK,KAAK,CAAC;EACxB,QAAQ;AACN,UAAO,CAAC,KAAK,EAAE;;EAElB,CAAC;;;;;;;;;;;;;ACPJ,SAAgB,kBAAsC;AACpD,QAAO,MACL,aAAa,qBAAqB,EAAE,SAAS,QAAQ,EACrD,yBAAyB,EACzB,uBAAuB,CACxB"}
1
+ {"version":3,"file":"prosekit-extensions-paragraph.js","names":[],"sources":["../src/paragraph/paragraph-commands.ts","../src/paragraph/paragraph-keymap.ts","../src/paragraph/paragraph-spec.ts","../src/paragraph/paragraph.ts"],"sourcesContent":["import { defineCommands, setBlockType, type Extension } from '@prosekit/core'\nimport type { Command } from '@prosekit/pm/state'\n\n/**\n * @internal\n */\nexport type ParagraphCommandsExtension = Extension<{\n Commands: {\n setParagraph: []\n }\n}>\n\n/**\n * @internal\n */\nexport function setParagraph(): Command {\n return setBlockType({ type: 'paragraph' })\n}\n\n/**\n * @internal\n */\nexport function defineParagraphCommands(): ParagraphCommandsExtension {\n return defineCommands({ setParagraph })\n}\n","import { defineKeymap, type PlainExtension } from '@prosekit/core'\n\nimport { setParagraph } from './paragraph-commands.ts'\n\n/**\n * @internal\n */\nexport function defineParagraphKeymap(): PlainExtension {\n return defineKeymap({\n 'Mod-Alt-0': setParagraph(),\n })\n}\n","import { defineNodeSpec, type Extension } from '@prosekit/core'\nimport type { Attrs } from '@prosekit/pm/model'\n\n/**\n * @internal\n */\nexport type ParagraphSpecExtension = Extension<{\n Nodes: {\n paragraph: Attrs\n }\n}>\n\n/**\n * @internal\n *\n * Defines a paragraph node spec.\n */\nexport function defineParagraphSpec(): ParagraphSpecExtension {\n return defineNodeSpec({\n name: 'paragraph',\n content: 'inline*',\n group: 'block',\n parseDOM: [{ tag: 'p' }],\n toDOM() {\n return ['p', 0]\n },\n })\n}\n","import type { Priority } from '@prosekit/core'\nimport { union, withPriority, type Union } from '@prosekit/core'\n\nimport { defineParagraphCommands, type ParagraphCommandsExtension } from './paragraph-commands.ts'\nimport { defineParagraphKeymap } from './paragraph-keymap.ts'\nimport { defineParagraphSpec, type ParagraphSpecExtension } from './paragraph-spec.ts'\n\n/**\n * @internal\n */\nexport type ParagraphExtension = Union<[ParagraphSpecExtension, ParagraphCommandsExtension]>\n\n/**\n * @public\n *\n * Defines a paragraph node.\n *\n * The paragraph node spec has the highest priority, because it should be the\n * default block node for most cases.\n */\nexport function defineParagraph(): ParagraphExtension {\n return union(\n withPriority(defineParagraphSpec(), 4 satisfies typeof Priority.highest),\n defineParagraphCommands(),\n defineParagraphKeymap(),\n )\n}\n"],"mappings":";;;;;AAeA,SAAgB,eAAwB;AACtC,QAAO,aAAa,EAAE,MAAM,aAAa,CAAC;;;;;AAM5C,SAAgB,0BAAsD;AACpE,QAAO,eAAe,EAAE,cAAc,CAAC;;;;;;;AChBzC,SAAgB,wBAAwC;AACtD,QAAO,aAAa,EAClB,aAAa,cAAc,EAC5B,CAAC;;;;;;;;;ACOJ,SAAgB,sBAA8C;AAC5D,QAAO,eAAe;EACpB,MAAM;EACN,SAAS;EACT,OAAO;EACP,UAAU,CAAC,EAAE,KAAK,KAAK,CAAC;EACxB,QAAQ;AACN,UAAO,CAAC,KAAK,EAAE;;EAElB,CAAC;;;;;;;;;;;;ACNJ,SAAgB,kBAAsC;AACpD,QAAO,MACL,aAAa,qBAAqB,EAAE,EAAoC,EACxE,yBAAyB,EACzB,uBAAuB,CACxB"}
@@ -1,3 +1,2 @@
1
- import { n as definePasteRule, t as defineMarkPasteRule } from "./mark-paste-rule--F1QPUcU.js";
2
-
3
- export { defineMarkPasteRule, definePasteRule };
1
+ import { n as definePasteRule, t as defineMarkPasteRule } from "./paste-rule.js";
2
+ export { defineMarkPasteRule, definePasteRule };
@@ -1,8 +1,7 @@
1
- import { p as findTable } from "./table-B81i9oH9.js";
1
+ import { p as findTable } from "./table.js";
2
2
  import { Plugin, PluginKey } from "@prosekit/pm/state";
3
3
  import { definePlugin, isInCodeBlock, isTextSelection, maybeRun } from "@prosekit/core";
4
4
  import { Decoration, DecorationSet } from "@prosekit/pm/view";
5
-
6
5
  //#region src/placeholder/index.ts
7
6
  /**
8
7
  * Add a placeholder text to the editor when the current block or document is
@@ -44,7 +43,7 @@ function createPlaceholderDecoration(state, placeholderText) {
44
43
  "data-placeholder": placeholderText
45
44
  });
46
45
  }
47
-
48
46
  //#endregion
49
47
  export { definePlaceholder };
48
+
50
49
  //# sourceMappingURL=prosekit-extensions-placeholder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-placeholder.js","names":[],"sources":["../src/placeholder/index.ts"],"sourcesContent":["import { definePlugin, isInCodeBlock, isTextSelection, maybeRun, type PlainExtension } from '@prosekit/core'\nimport type { ProseMirrorNode } from '@prosekit/pm/model'\nimport { Plugin, PluginKey, type EditorState } from '@prosekit/pm/state'\nimport { Decoration, DecorationSet } from '@prosekit/pm/view'\n\nimport { findTable } from '../table/index.ts'\n\nexport interface PlaceholderOptions {\n /**\n * The placeholder to use. It can be a static string or a function that\n * receives the current editor state and returns a string.\n */\n placeholder: string | ((state: EditorState) => string)\n\n /**\n * By default, the placeholder text will be shown whenever the current text\n * cursor is in an empty text node and it's not inside a code block or a\n * table node.\n *\n * If you only want to show the placeholder when the whole doc is empty, you\n * can set this option to 'doc'.\n *\n * You can also pass a function that receives the current editor state and\n * returns a boolean value to determine whether the placeholder should be\n * shown.\n *\n * @default 'block'\n */\n strategy?: 'doc' | 'block' | ((state: EditorState) => boolean)\n}\n\n/**\n * Add a placeholder text to the editor when the current block or document is\n * empty.\n */\nexport function definePlaceholder(options: PlaceholderOptions): PlainExtension {\n return definePlugin(createPlaceholderPlugin(options))\n}\n\nfunction createPlaceholderPlugin({\n placeholder,\n strategy = 'block',\n}: PlaceholderOptions): Plugin {\n return new Plugin({\n key: new PluginKey('prosekit-placeholder'),\n props: {\n decorations: (state) => {\n const strategyFn = typeof strategy === 'function'\n ? strategy\n : strategy === 'doc'\n ? docStrategy\n : defaultStrategy\n\n if (!strategyFn(state)) {\n return null\n }\n\n const placeholderText: string = maybeRun(placeholder, state)\n const deco = createPlaceholderDecoration(state, placeholderText)\n if (!deco) {\n return null\n }\n\n return DecorationSet.create(state.doc, [deco])\n },\n },\n })\n}\n\nfunction defaultStrategy(state: EditorState): boolean {\n return !isInCodeBlock(state.selection) && !findTable(state.selection.$from)\n}\n\nfunction docStrategy(state: EditorState): boolean {\n return isDocEmpty(state.doc) && defaultStrategy(state)\n}\n\nfunction isDocEmpty(doc: ProseMirrorNode) {\n return doc.childCount <= 1 && !doc.firstChild?.content.size\n}\n\nfunction createPlaceholderDecoration(\n state: EditorState,\n placeholderText: string,\n): Decoration | null {\n if (!placeholderText) return null\n\n const { selection } = state\n if (!selection.empty || !isTextSelection(selection)) return null\n\n const $pos = selection.$anchor\n const node = $pos.parent\n if (node.content.size > 0) return null\n\n const before = $pos.before()\n\n return Decoration.node(before, before + node.nodeSize, {\n 'class': 'prosekit-placeholder',\n 'data-placeholder': placeholderText,\n })\n}\n"],"mappings":";;;;;;;;;;AAmCA,SAAgB,kBAAkB,SAA6C;AAC7E,QAAO,aAAa,wBAAwB,QAAQ,CAAC;;AAGvD,SAAS,wBAAwB,EAC/B,aACA,WAAW,WACkB;AAC7B,QAAO,IAAI,OAAO;EAChB,KAAK,IAAI,UAAU,uBAAuB;EAC1C,OAAO,EACL,cAAc,UAAU;AAOtB,OAAI,EANe,OAAO,aAAa,aACnC,WACA,aAAa,QACb,cACA,iBAEY,MAAM,CACpB,QAAO;GAIT,MAAM,OAAO,4BAA4B,OADT,SAAS,aAAa,MAAM,CACI;AAChE,OAAI,CAAC,KACH,QAAO;AAGT,UAAO,cAAc,OAAO,MAAM,KAAK,CAAC,KAAK,CAAC;KAEjD;EACF,CAAC;;AAGJ,SAAS,gBAAgB,OAA6B;AACpD,QAAO,CAAC,cAAc,MAAM,UAAU,IAAI,CAAC,UAAU,MAAM,UAAU,MAAM;;AAG7E,SAAS,YAAY,OAA6B;AAChD,QAAO,WAAW,MAAM,IAAI,IAAI,gBAAgB,MAAM;;AAGxD,SAAS,WAAW,KAAsB;AACxC,QAAO,IAAI,cAAc,KAAK,CAAC,IAAI,YAAY,QAAQ;;AAGzD,SAAS,4BACP,OACA,iBACmB;AACnB,KAAI,CAAC,gBAAiB,QAAO;CAE7B,MAAM,EAAE,cAAc;AACtB,KAAI,CAAC,UAAU,SAAS,CAAC,gBAAgB,UAAU,CAAE,QAAO;CAE5D,MAAM,OAAO,UAAU;CACvB,MAAM,OAAO,KAAK;AAClB,KAAI,KAAK,QAAQ,OAAO,EAAG,QAAO;CAElC,MAAM,SAAS,KAAK,QAAQ;AAE5B,QAAO,WAAW,KAAK,QAAQ,SAAS,KAAK,UAAU;EACrD,SAAS;EACT,oBAAoB;EACrB,CAAC"}
1
+ {"version":3,"file":"prosekit-extensions-placeholder.js","names":[],"sources":["../src/placeholder/index.ts"],"sourcesContent":["import { definePlugin, isInCodeBlock, isTextSelection, maybeRun, type PlainExtension } from '@prosekit/core'\nimport type { ProseMirrorNode } from '@prosekit/pm/model'\nimport { Plugin, PluginKey, type EditorState } from '@prosekit/pm/state'\nimport { Decoration, DecorationSet } from '@prosekit/pm/view'\n\nimport { findTable } from '../table/index.ts'\n\nexport interface PlaceholderOptions {\n /**\n * The placeholder to use. It can be a static string or a function that\n * receives the current editor state and returns a string.\n */\n placeholder: string | ((state: EditorState) => string)\n\n /**\n * By default, the placeholder text will be shown whenever the current text\n * cursor is in an empty text node and it's not inside a code block or a\n * table node.\n *\n * If you only want to show the placeholder when the whole doc is empty, you\n * can set this option to 'doc'.\n *\n * You can also pass a function that receives the current editor state and\n * returns a boolean value to determine whether the placeholder should be\n * shown.\n *\n * @default 'block'\n */\n strategy?: 'doc' | 'block' | ((state: EditorState) => boolean)\n}\n\n/**\n * Add a placeholder text to the editor when the current block or document is\n * empty.\n */\nexport function definePlaceholder(options: PlaceholderOptions): PlainExtension {\n return definePlugin(createPlaceholderPlugin(options))\n}\n\nfunction createPlaceholderPlugin({\n placeholder,\n strategy = 'block',\n}: PlaceholderOptions): Plugin {\n return new Plugin({\n key: new PluginKey('prosekit-placeholder'),\n props: {\n decorations: (state) => {\n const strategyFn = typeof strategy === 'function'\n ? strategy\n : strategy === 'doc'\n ? docStrategy\n : defaultStrategy\n\n if (!strategyFn(state)) {\n return null\n }\n\n const placeholderText: string = maybeRun(placeholder, state)\n const deco = createPlaceholderDecoration(state, placeholderText)\n if (!deco) {\n return null\n }\n\n return DecorationSet.create(state.doc, [deco])\n },\n },\n })\n}\n\nfunction defaultStrategy(state: EditorState): boolean {\n return !isInCodeBlock(state.selection) && !findTable(state.selection.$from)\n}\n\nfunction docStrategy(state: EditorState): boolean {\n return isDocEmpty(state.doc) && defaultStrategy(state)\n}\n\nfunction isDocEmpty(doc: ProseMirrorNode) {\n return doc.childCount <= 1 && !doc.firstChild?.content.size\n}\n\nfunction createPlaceholderDecoration(\n state: EditorState,\n placeholderText: string,\n): Decoration | null {\n if (!placeholderText) return null\n\n const { selection } = state\n if (!selection.empty || !isTextSelection(selection)) return null\n\n const $pos = selection.$anchor\n const node = $pos.parent\n if (node.content.size > 0) return null\n\n const before = $pos.before()\n\n return Decoration.node(before, before + node.nodeSize, {\n 'class': 'prosekit-placeholder',\n 'data-placeholder': placeholderText,\n })\n}\n"],"mappings":";;;;;;;;;AAmCA,SAAgB,kBAAkB,SAA6C;AAC7E,QAAO,aAAa,wBAAwB,QAAQ,CAAC;;AAGvD,SAAS,wBAAwB,EAC/B,aACA,WAAW,WACkB;AAC7B,QAAO,IAAI,OAAO;EAChB,KAAK,IAAI,UAAU,uBAAuB;EAC1C,OAAO,EACL,cAAc,UAAU;AAOtB,OAAI,EANe,OAAO,aAAa,aACnC,WACA,aAAa,QACb,cACA,iBAEY,MAAM,CACpB,QAAO;GAIT,MAAM,OAAO,4BAA4B,OADT,SAAS,aAAa,MAAM,CACI;AAChE,OAAI,CAAC,KACH,QAAO;AAGT,UAAO,cAAc,OAAO,MAAM,KAAK,CAAC,KAAK,CAAC;KAEjD;EACF,CAAC;;AAGJ,SAAS,gBAAgB,OAA6B;AACpD,QAAO,CAAC,cAAc,MAAM,UAAU,IAAI,CAAC,UAAU,MAAM,UAAU,MAAM;;AAG7E,SAAS,YAAY,OAA6B;AAChD,QAAO,WAAW,MAAM,IAAI,IAAI,gBAAgB,MAAM;;AAGxD,SAAS,WAAW,KAAsB;AACxC,QAAO,IAAI,cAAc,KAAK,CAAC,IAAI,YAAY,QAAQ;;AAGzD,SAAS,4BACP,OACA,iBACmB;AACnB,KAAI,CAAC,gBAAiB,QAAO;CAE7B,MAAM,EAAE,cAAc;AACtB,KAAI,CAAC,UAAU,SAAS,CAAC,gBAAgB,UAAU,CAAE,QAAO;CAE5D,MAAM,OAAO,UAAU;CACvB,MAAM,OAAO,KAAK;AAClB,KAAI,KAAK,QAAQ,OAAO,EAAG,QAAO;CAElC,MAAM,SAAS,KAAK,QAAQ;AAE5B,QAAO,WAAW,KAAK,QAAQ,SAAS,KAAK,UAAU;EACrD,SAAS;EACT,oBAAoB;EACrB,CAAC"}
@@ -1,6 +1,5 @@
1
1
  import { PluginKey, ProseMirrorPlugin } from "@prosekit/pm/state";
2
2
  import { definePlugin } from "@prosekit/core";
3
-
4
3
  //#region src/readonly/index.ts
5
4
  /**
6
5
  * Make the editor read-only.
@@ -12,7 +11,7 @@ const plugin = new ProseMirrorPlugin({
12
11
  key: new PluginKey("prosekey-readonly"),
13
12
  props: { editable: () => false }
14
13
  });
15
-
16
14
  //#endregion
17
15
  export { defineReadonly };
16
+
18
17
  //# sourceMappingURL=prosekit-extensions-readonly.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-readonly.js","names":[],"sources":["../src/readonly/index.ts"],"sourcesContent":["import { definePlugin, type PlainExtension } from '@prosekit/core'\nimport { PluginKey, ProseMirrorPlugin } from '@prosekit/pm/state'\n\n/**\n * Make the editor read-only.\n */\nexport function defineReadonly(): PlainExtension {\n return definePlugin(plugin)\n}\n\nconst plugin = new ProseMirrorPlugin({\n key: new PluginKey('prosekey-readonly'),\n props: {\n editable: () => false,\n },\n})\n"],"mappings":";;;;;;;AAMA,SAAgB,iBAAiC;AAC/C,QAAO,aAAa,OAAO;;AAG7B,MAAM,SAAS,IAAI,kBAAkB;CACnC,KAAK,IAAI,UAAU,oBAAoB;CACvC,OAAO,EACL,gBAAgB,OACjB;CACF,CAAC"}
1
+ {"version":3,"file":"prosekit-extensions-readonly.js","names":[],"sources":["../src/readonly/index.ts"],"sourcesContent":["import { definePlugin, type PlainExtension } from '@prosekit/core'\nimport { PluginKey, ProseMirrorPlugin } from '@prosekit/pm/state'\n\n/**\n * Make the editor read-only.\n */\nexport function defineReadonly(): PlainExtension {\n return definePlugin(plugin)\n}\n\nconst plugin = new ProseMirrorPlugin({\n key: new PluginKey('prosekey-readonly'),\n props: {\n editable: () => false,\n },\n})\n"],"mappings":";;;;;;AAMA,SAAgB,iBAAiC;AAC/C,QAAO,aAAa,OAAO;;AAG7B,MAAM,SAAS,IAAI,kBAAkB;CACnC,KAAK,IAAI,UAAU,oBAAoB;CACvC,OAAO,EACL,gBAAgB,OACjB;CACF,CAAC"}
@@ -1,6 +1,5 @@
1
1
  import { defineCommands, definePlugin } from "@prosekit/core";
2
2
  import { SearchQuery, findNext, findNextNoWrap, findPrev, findPrevNoWrap, replaceAll, replaceCurrent, replaceNext, replaceNextNoWrap, search } from "prosemirror-search";
3
-
4
3
  //#region src/search/index.ts
5
4
  /**
6
5
  * Defines an extension that stores a current search query and replace string.
@@ -49,7 +48,7 @@ function defineSearchCommands() {
49
48
  replaceAll: () => withScrollActiveIntoView(replaceAll)
50
49
  });
51
50
  }
52
-
53
51
  //#endregion
54
52
  export { defineSearchCommands, defineSearchQuery };
53
+
55
54
  //# sourceMappingURL=prosekit-extensions-search.js.map