@kedataindo/docflow-core 0.0.2 → 0.0.4
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/LICENSE +44 -0
- package/dist/index.cjs +1519 -28
- package/dist/index.d.cts +337 -1
- package/dist/index.d.ts +337 -1
- package/dist/index.js +1499 -21
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -11,9 +11,9 @@ var __export = (target, all) => {
|
|
|
11
11
|
};
|
|
12
12
|
var __copyProps = (to, from, except, desc) => {
|
|
13
13
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let
|
|
15
|
-
if (!__hasOwnProp.call(to,
|
|
16
|
-
__defProp(to,
|
|
14
|
+
for (let key2 of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key2) && key2 !== except)
|
|
16
|
+
__defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
|
|
17
17
|
}
|
|
18
18
|
return to;
|
|
19
19
|
};
|
|
@@ -31,24 +31,37 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
BlockAttributesExtension: () => BlockAttributesExtension,
|
|
34
|
+
EditorContextExtension: () => EditorContextExtension,
|
|
34
35
|
FontSizeExtension: () => FontSizeExtension,
|
|
35
|
-
PAGE_SIZES: () =>
|
|
36
|
-
PaginationPlus: () =>
|
|
36
|
+
PAGE_SIZES: () => PAGE_SIZES,
|
|
37
|
+
PaginationPlus: () => PaginationPlus,
|
|
38
|
+
SearchAndReplaceExtension: () => SearchAndReplaceExtension,
|
|
39
|
+
SubdocumentProvider: () => SubdocumentProvider,
|
|
40
|
+
clearSearch: () => clearSearch,
|
|
37
41
|
collaborationExtensions: () => collaborationExtensions,
|
|
38
42
|
collectExtensions: () => collectExtensions,
|
|
39
43
|
createActionMap: () => createActionMap,
|
|
40
44
|
createCollaboration: () => createCollaboration,
|
|
41
45
|
createEditor: () => createEditor,
|
|
42
46
|
definePlugin: () => definePlugin,
|
|
43
|
-
|
|
47
|
+
findMatches: () => findMatches,
|
|
48
|
+
getSearchState: () => getSearchState,
|
|
49
|
+
replaceAll: () => replaceAll,
|
|
50
|
+
replaceCurrent: () => replaceCurrent,
|
|
51
|
+
resolveAction: () => resolveAction,
|
|
52
|
+
sanitizePastedHTML: () => sanitizePastedHTML,
|
|
53
|
+
searchAndReplaceKey: () => searchAndReplaceKey,
|
|
54
|
+
searchNext: () => searchNext,
|
|
55
|
+
searchPrev: () => searchPrev,
|
|
56
|
+
setSearchQuery: () => setSearchQuery
|
|
44
57
|
});
|
|
45
58
|
module.exports = __toCommonJS(index_exports);
|
|
46
59
|
|
|
47
60
|
// src/Editor.ts
|
|
48
|
-
var
|
|
61
|
+
var import_core5 = require("@tiptap/core");
|
|
62
|
+
var import_state4 = require("@tiptap/pm/state");
|
|
49
63
|
var import_starter_kit = __toESM(require("@tiptap/starter-kit"), 1);
|
|
50
64
|
var import_extension_text_style = __toESM(require("@tiptap/extension-text-style"), 1);
|
|
51
|
-
var import_y_prosemirror = require("y-prosemirror");
|
|
52
65
|
|
|
53
66
|
// src/PluginSystem.ts
|
|
54
67
|
function definePlugin(plugin) {
|
|
@@ -101,9 +114,23 @@ function createActionMap(editor, plugins) {
|
|
|
101
114
|
var import_extension_collaboration = require("@tiptap/extension-collaboration");
|
|
102
115
|
var import_extension_collaboration_cursor = require("@tiptap/extension-collaboration-cursor");
|
|
103
116
|
var import_awareness = require("y-protocols/awareness");
|
|
117
|
+
var import_y_indexeddb = require("y-indexeddb");
|
|
104
118
|
var import_y_webrtc = require("y-webrtc");
|
|
105
119
|
var import_y_websocket = require("y-websocket");
|
|
106
120
|
var Y = __toESM(require("yjs"), 1);
|
|
121
|
+
var LOCAL_SIGNALING = ["ws://localhost:4444"];
|
|
122
|
+
var warnedLocalSignaling = false;
|
|
123
|
+
function resolveSignalingUrls(signaling) {
|
|
124
|
+
if (signaling && signaling.length > 0) return signaling;
|
|
125
|
+
if (!warnedLocalSignaling) {
|
|
126
|
+
warnedLocalSignaling = true;
|
|
127
|
+
console.warn(
|
|
128
|
+
'[docflow] webrtc provider has no `signaling` configured \u2014 falling back to localhost-only sync (ws://localhost:4444 + same-browser tabs). For production self-host, run your own signaling server and pass `signaling`, or use `provider: "websocket"` with your own websocketUrl.'
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
return LOCAL_SIGNALING;
|
|
132
|
+
}
|
|
133
|
+
var LOCAL_PRESENT_DEFAULT = true;
|
|
107
134
|
function createAwarenessStates(awareness) {
|
|
108
135
|
const states = [];
|
|
109
136
|
awareness.getStates().forEach((state, clientId) => {
|
|
@@ -111,7 +138,11 @@ function createAwarenessStates(awareness) {
|
|
|
111
138
|
states.push({
|
|
112
139
|
clientId,
|
|
113
140
|
user: raw.user ?? { name: "", color: "" },
|
|
114
|
-
cursor: raw.cursor ?? null
|
|
141
|
+
cursor: raw.cursor ?? null,
|
|
142
|
+
// `present` defaults to true for backwards compat (legacy states
|
|
143
|
+
// don't set it) and for the local user (always considered present
|
|
144
|
+
// until PR2 toggles it off).
|
|
145
|
+
present: raw.present ?? LOCAL_PRESENT_DEFAULT
|
|
115
146
|
});
|
|
116
147
|
});
|
|
117
148
|
return states;
|
|
@@ -121,14 +152,14 @@ function createCollaboration(options) {
|
|
|
121
152
|
if (options.initialStorageState) {
|
|
122
153
|
Y.applyUpdate(ydoc, options.initialStorageState);
|
|
123
154
|
}
|
|
155
|
+
let persistence;
|
|
156
|
+
if (options.offline) {
|
|
157
|
+
persistence = new import_y_indexeddb.IndexeddbPersistence(`docflow-${options.room}`, ydoc);
|
|
158
|
+
}
|
|
124
159
|
let provider = null;
|
|
125
160
|
if (options.provider === "webrtc") {
|
|
126
161
|
provider = new import_y_webrtc.WebrtcProvider(options.room, ydoc, {
|
|
127
|
-
signaling: options.signaling
|
|
128
|
-
"ws://localhost:4444",
|
|
129
|
-
"wss://signaling.yjs.dev",
|
|
130
|
-
"wss://y-webrtc-eu.fly.dev"
|
|
131
|
-
]
|
|
162
|
+
signaling: resolveSignalingUrls(options.signaling)
|
|
132
163
|
});
|
|
133
164
|
} else if (options.provider === "websocket") {
|
|
134
165
|
if (!options.websocketUrl) {
|
|
@@ -138,6 +169,16 @@ function createCollaboration(options) {
|
|
|
138
169
|
}
|
|
139
170
|
const awareness = provider?.awareness ?? new import_awareness.Awareness(ydoc);
|
|
140
171
|
awareness.setLocalStateField("user", options.user);
|
|
172
|
+
let emitCursor = options.emitCursor ?? true;
|
|
173
|
+
const setLocalCursorEnabled = (enabled) => {
|
|
174
|
+
if (emitCursor === enabled) return;
|
|
175
|
+
emitCursor = enabled;
|
|
176
|
+
if (!enabled) {
|
|
177
|
+
awareness.setLocalStateField("cursor", null);
|
|
178
|
+
}
|
|
179
|
+
awareness.setLocalStateField("present", enabled);
|
|
180
|
+
};
|
|
181
|
+
awareness.setLocalStateField("present", emitCursor);
|
|
141
182
|
let awarenessHandler;
|
|
142
183
|
if (options.onAwarenessChange) {
|
|
143
184
|
const notify = () => {
|
|
@@ -154,9 +195,10 @@ function createCollaboration(options) {
|
|
|
154
195
|
awareness.setLocalState(null);
|
|
155
196
|
provider?.destroy?.();
|
|
156
197
|
awareness.destroy?.();
|
|
198
|
+
void persistence?.destroy();
|
|
157
199
|
ydoc.destroy();
|
|
158
200
|
};
|
|
159
|
-
return { ydoc, provider, awareness, destroy };
|
|
201
|
+
return { ydoc, provider, awareness, persistence, destroy, setLocalCursorEnabled };
|
|
160
202
|
}
|
|
161
203
|
function collaborationExtensions(options) {
|
|
162
204
|
const setup = "ydoc" in options ? options : createCollaboration(options);
|
|
@@ -235,8 +277,1016 @@ var BlockAttributesExtension = import_core.Extension.create({
|
|
|
235
277
|
}
|
|
236
278
|
});
|
|
237
279
|
|
|
280
|
+
// src/EditorContext.ts
|
|
281
|
+
var import_core2 = require("@tiptap/core");
|
|
282
|
+
var EditorContextExtension = import_core2.Extension.create({
|
|
283
|
+
name: "editorContext",
|
|
284
|
+
addOptions() {
|
|
285
|
+
return {
|
|
286
|
+
onImageUpload: void 0,
|
|
287
|
+
citation: void 0,
|
|
288
|
+
aiStream: void 0,
|
|
289
|
+
aiDraft: void 0
|
|
290
|
+
};
|
|
291
|
+
},
|
|
292
|
+
addStorage() {
|
|
293
|
+
return {
|
|
294
|
+
onImageUpload: this.options.onImageUpload,
|
|
295
|
+
citation: this.options.citation,
|
|
296
|
+
aiStream: this.options.aiStream,
|
|
297
|
+
aiDraft: this.options.aiDraft
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// src/SearchAndReplace.ts
|
|
303
|
+
var import_core3 = require("@tiptap/core");
|
|
304
|
+
var import_state2 = require("@tiptap/pm/state");
|
|
305
|
+
var import_view2 = require("@tiptap/pm/view");
|
|
306
|
+
var searchAndReplaceKey = new import_state2.PluginKey("searchAndReplace");
|
|
307
|
+
var EMPTY_STATE = { query: "", matches: [], activeIndex: 0 };
|
|
308
|
+
function findMatches(doc, query) {
|
|
309
|
+
const matches = [];
|
|
310
|
+
if (!query) return matches;
|
|
311
|
+
const needle = query.toLowerCase();
|
|
312
|
+
doc.descendants((node, pos) => {
|
|
313
|
+
if (!node.isText || !node.text) return;
|
|
314
|
+
const hay = node.text.toLowerCase();
|
|
315
|
+
let idx = hay.indexOf(needle);
|
|
316
|
+
while (idx !== -1) {
|
|
317
|
+
matches.push({ from: pos + idx, to: pos + idx + needle.length });
|
|
318
|
+
idx = hay.indexOf(needle, idx + needle.length);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
return matches;
|
|
322
|
+
}
|
|
323
|
+
function clampIndex(index, matches) {
|
|
324
|
+
if (matches.length === 0) return 0;
|
|
325
|
+
return Math.min(Math.max(index, 0), matches.length - 1);
|
|
326
|
+
}
|
|
327
|
+
function computeState(doc, query, activeIndex = 0) {
|
|
328
|
+
const matches = findMatches(doc, query);
|
|
329
|
+
return { query, matches, activeIndex: clampIndex(activeIndex, matches) };
|
|
330
|
+
}
|
|
331
|
+
var searchPlugin = new import_state2.Plugin({
|
|
332
|
+
key: searchAndReplaceKey,
|
|
333
|
+
state: {
|
|
334
|
+
init: () => EMPTY_STATE,
|
|
335
|
+
apply: (tr, prev) => {
|
|
336
|
+
const meta = tr.getMeta(searchAndReplaceKey);
|
|
337
|
+
if (meta) {
|
|
338
|
+
if (meta.type === "clear") return EMPTY_STATE;
|
|
339
|
+
if (meta.type === "set") return computeState(tr.doc, meta.query);
|
|
340
|
+
return { ...prev, activeIndex: clampIndex(meta.index, prev.matches) };
|
|
341
|
+
}
|
|
342
|
+
if (tr.docChanged && prev.query) {
|
|
343
|
+
return computeState(tr.doc, prev.query, prev.activeIndex);
|
|
344
|
+
}
|
|
345
|
+
return prev;
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
props: {
|
|
349
|
+
decorations: (state) => {
|
|
350
|
+
const s = searchAndReplaceKey.getState(state);
|
|
351
|
+
if (!s || s.matches.length === 0) return null;
|
|
352
|
+
return import_view2.DecorationSet.create(
|
|
353
|
+
state.doc,
|
|
354
|
+
s.matches.map(
|
|
355
|
+
(m, i) => import_view2.Decoration.inline(m.from, m.to, {
|
|
356
|
+
class: i === s.activeIndex ? "find-match find-match-active" : "find-match"
|
|
357
|
+
})
|
|
358
|
+
)
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
var SearchAndReplaceExtension = import_core3.Extension.create({
|
|
364
|
+
name: "searchAndReplace",
|
|
365
|
+
addProseMirrorPlugins() {
|
|
366
|
+
return [searchPlugin];
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
function getSearchState(editor) {
|
|
370
|
+
return searchAndReplaceKey.getState(editor.state) ?? EMPTY_STATE;
|
|
371
|
+
}
|
|
372
|
+
function setSearchQuery(editor, query) {
|
|
373
|
+
editor.view.dispatch(editor.state.tr.setMeta(searchAndReplaceKey, { type: "set", query }));
|
|
374
|
+
}
|
|
375
|
+
function clearSearch(editor) {
|
|
376
|
+
editor.view.dispatch(editor.state.tr.setMeta(searchAndReplaceKey, { type: "clear" }));
|
|
377
|
+
}
|
|
378
|
+
function activateMatch(editor, index) {
|
|
379
|
+
const s = getSearchState(editor);
|
|
380
|
+
const match = s.matches[index];
|
|
381
|
+
const tr = editor.state.tr.setMeta(searchAndReplaceKey, { type: "setActive", index });
|
|
382
|
+
if (match) {
|
|
383
|
+
tr.setSelection(import_state2.TextSelection.create(editor.state.doc, match.from, match.to));
|
|
384
|
+
tr.scrollIntoView();
|
|
385
|
+
}
|
|
386
|
+
editor.view.dispatch(tr);
|
|
387
|
+
}
|
|
388
|
+
function searchNext(editor) {
|
|
389
|
+
const s = getSearchState(editor);
|
|
390
|
+
if (s.matches.length === 0) return null;
|
|
391
|
+
const next = (s.activeIndex + 1) % s.matches.length;
|
|
392
|
+
activateMatch(editor, next);
|
|
393
|
+
return s.matches[next];
|
|
394
|
+
}
|
|
395
|
+
function searchPrev(editor) {
|
|
396
|
+
const s = getSearchState(editor);
|
|
397
|
+
if (s.matches.length === 0) return null;
|
|
398
|
+
const prev = (s.activeIndex - 1 + s.matches.length) % s.matches.length;
|
|
399
|
+
activateMatch(editor, prev);
|
|
400
|
+
return s.matches[prev];
|
|
401
|
+
}
|
|
402
|
+
function replaceCurrent(editor, replacement) {
|
|
403
|
+
const s = getSearchState(editor);
|
|
404
|
+
const match = s.matches[s.activeIndex];
|
|
405
|
+
if (!match) return false;
|
|
406
|
+
editor.view.dispatch(editor.state.tr.insertText(replacement, match.from, match.to));
|
|
407
|
+
return true;
|
|
408
|
+
}
|
|
409
|
+
function replaceAll(editor, replacement) {
|
|
410
|
+
const s = getSearchState(editor);
|
|
411
|
+
if (s.matches.length === 0) return 0;
|
|
412
|
+
const tr = editor.state.tr;
|
|
413
|
+
for (let i = s.matches.length - 1; i >= 0; i--) {
|
|
414
|
+
tr.insertText(replacement, s.matches[i].from, s.matches[i].to);
|
|
415
|
+
}
|
|
416
|
+
editor.view.dispatch(tr);
|
|
417
|
+
return s.matches.length;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_@tiptap+core@2.27.2_@tiptap+pm@2.27.2__@tiptap+pm@2.27.2/node_modules/tiptap-pagination-plus/dist/PaginationPlus.js
|
|
421
|
+
var import_core4 = require("@tiptap/core");
|
|
422
|
+
var import_state3 = require("@tiptap/pm/state");
|
|
423
|
+
var import_transform = require("@tiptap/pm/transform");
|
|
424
|
+
var import_view3 = require("@tiptap/pm/view");
|
|
425
|
+
|
|
426
|
+
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_@tiptap+core@2.27.2_@tiptap+pm@2.27.2__@tiptap+pm@2.27.2/node_modules/tiptap-pagination-plus/dist/utils.js
|
|
427
|
+
var updateCssVariables = (targetNode, config) => {
|
|
428
|
+
const cssVariables = {
|
|
429
|
+
"rm-page-height": `${config.pageHeight}px`,
|
|
430
|
+
"rm-margin-top": `${config.marginTop}px`,
|
|
431
|
+
"rm-margin-bottom": `${config.marginBottom}px`,
|
|
432
|
+
"rm-margin-left": `${config.marginLeft}px`,
|
|
433
|
+
"rm-margin-right": `${config.marginRight}px`,
|
|
434
|
+
"rm-content-margin-top": `${config.contentMarginTop}px`,
|
|
435
|
+
"rm-content-margin-bottom": `${config.contentMarginBottom}px`,
|
|
436
|
+
"rm-page-gap-border-color": `${config.pageGapBorderColor}`,
|
|
437
|
+
"rm-page-width": `${config.pageWidth}px`
|
|
438
|
+
};
|
|
439
|
+
Object.entries(cssVariables).forEach(([key2, value]) => {
|
|
440
|
+
targetNode.style.setProperty(`--${key2}`, value);
|
|
441
|
+
});
|
|
442
|
+
};
|
|
443
|
+
var getPageSize = (height, width, marginTop, marginBottom, marginLeft, marginRight) => {
|
|
444
|
+
return {
|
|
445
|
+
pageHeight: height,
|
|
446
|
+
pageWidth: width,
|
|
447
|
+
marginTop,
|
|
448
|
+
marginBottom,
|
|
449
|
+
marginLeft,
|
|
450
|
+
marginRight
|
|
451
|
+
};
|
|
452
|
+
};
|
|
453
|
+
var getHeaderHeight = (targetNode, pageNumbers, type) => {
|
|
454
|
+
const headerHeightMap = /* @__PURE__ */ new Map();
|
|
455
|
+
const clientHeader = targetNode.querySelector(getHeaderHeightSelector(0, type));
|
|
456
|
+
headerHeightMap.set(0, clientHeader ? clientHeader.clientHeight : 0);
|
|
457
|
+
pageNumbers.forEach((pageNumber) => {
|
|
458
|
+
const clientHeader2 = targetNode.querySelector(getHeaderHeightSelector(pageNumber, type));
|
|
459
|
+
const headerHeight = clientHeader2 ? clientHeader2.clientHeight : 0;
|
|
460
|
+
headerHeightMap.set(pageNumber, headerHeight);
|
|
461
|
+
});
|
|
462
|
+
return headerHeightMap;
|
|
463
|
+
};
|
|
464
|
+
var getHeaderHeightSelector = (pageNumber, type) => {
|
|
465
|
+
return type === "actual" ? `.rm-page-header-${pageNumber}` : `.rm-page-header-${pageNumber} .rm-page-header-content`;
|
|
466
|
+
};
|
|
467
|
+
var getFooterHeight = (targetNode, pageNumbers, type) => {
|
|
468
|
+
const footerHeightMap = /* @__PURE__ */ new Map();
|
|
469
|
+
const clientFooter = targetNode.querySelector(getFooterHeightSelector(0, type));
|
|
470
|
+
footerHeightMap.set(0, clientFooter ? clientFooter.clientHeight : 0);
|
|
471
|
+
pageNumbers.forEach((pageNumber) => {
|
|
472
|
+
const clientFooter2 = targetNode.querySelector(getFooterHeightSelector(pageNumber, type));
|
|
473
|
+
const footerHeight = clientFooter2 ? clientFooter2.clientHeight : 0;
|
|
474
|
+
footerHeightMap.set(pageNumber, footerHeight);
|
|
475
|
+
});
|
|
476
|
+
return footerHeightMap;
|
|
477
|
+
};
|
|
478
|
+
var getFooterHeightSelector = (pageNumber, type) => {
|
|
479
|
+
return type === "actual" ? `.rm-page-footer-${pageNumber}` : `.rm-page-footer-${pageNumber} .rm-page-footer-content`;
|
|
480
|
+
};
|
|
481
|
+
function deepEqualIterative(a, b) {
|
|
482
|
+
if (a === b)
|
|
483
|
+
return true;
|
|
484
|
+
if (typeof a !== "object" || typeof b !== "object" || a == null || b == null) {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
const stack = [{ x: a, y: b }];
|
|
488
|
+
while (stack.length) {
|
|
489
|
+
const _stackItem = stack.pop();
|
|
490
|
+
if (!_stackItem)
|
|
491
|
+
continue;
|
|
492
|
+
const { x, y } = _stackItem;
|
|
493
|
+
if (x === y)
|
|
494
|
+
continue;
|
|
495
|
+
if (typeof x !== typeof y)
|
|
496
|
+
return false;
|
|
497
|
+
if (typeof x !== "object")
|
|
498
|
+
return false;
|
|
499
|
+
if (x == null || y == null)
|
|
500
|
+
return false;
|
|
501
|
+
const xKeys = Object.keys(x);
|
|
502
|
+
const yKeys = Object.keys(y);
|
|
503
|
+
if (xKeys.length !== yKeys.length)
|
|
504
|
+
return false;
|
|
505
|
+
for (const key2 of xKeys) {
|
|
506
|
+
if (!(key2 in y))
|
|
507
|
+
return false;
|
|
508
|
+
const xVal = x[key2];
|
|
509
|
+
const yVal = y[key2];
|
|
510
|
+
if (xVal === yVal)
|
|
511
|
+
continue;
|
|
512
|
+
if (typeof xVal === "object" && typeof yVal === "object") {
|
|
513
|
+
stack.push({ x: xVal, y: yVal });
|
|
514
|
+
} else {
|
|
515
|
+
if (xVal !== yVal)
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
return true;
|
|
521
|
+
}
|
|
522
|
+
function getCustomPages(customHeader, customFooter) {
|
|
523
|
+
return [...Object.keys(customHeader), ...Object.keys(customFooter)].map(Number);
|
|
524
|
+
}
|
|
525
|
+
function getFooter(footerRightContent, footerLeftContent, onFooterClick, pageNumber) {
|
|
526
|
+
const pageFooter = document.createElement("div");
|
|
527
|
+
pageFooter.classList.add("rm-page-footer");
|
|
528
|
+
pageFooter.classList.add(`rm-page-footer-${pageNumber ? pageNumber : 0}`);
|
|
529
|
+
pageFooter.style.overflow = "visible";
|
|
530
|
+
pageFooter.style.position = "relative";
|
|
531
|
+
pageFooter.style.cursor = "pointer";
|
|
532
|
+
const pageFooterContent = document.createElement("div");
|
|
533
|
+
pageFooterContent.classList.add("rm-page-footer-content");
|
|
534
|
+
pageFooterContent.style.width = "100%";
|
|
535
|
+
pageFooterContent.style.overflow = "hidden";
|
|
536
|
+
const footerRight = footerRightContent.replace("{page}", `<span class="rm-page-number"></span>`);
|
|
537
|
+
const footerLeft = footerLeftContent.replace("{page}", `<span class="rm-page-number"></span>`);
|
|
538
|
+
const pageFooterLeft = document.createElement("div");
|
|
539
|
+
pageFooterLeft.classList.add("rm-page-footer-left");
|
|
540
|
+
pageFooterLeft.innerHTML = footerLeft;
|
|
541
|
+
const pageFooterRight = document.createElement("div");
|
|
542
|
+
pageFooterRight.classList.add("rm-page-footer-right");
|
|
543
|
+
pageFooterRight.innerHTML = footerRight;
|
|
544
|
+
pageFooterContent.append(pageFooterLeft, pageFooterRight);
|
|
545
|
+
pageFooter.append(pageFooterContent);
|
|
546
|
+
pageFooter.addEventListener("click", onFooterClick);
|
|
547
|
+
return pageFooter;
|
|
548
|
+
}
|
|
549
|
+
function getHeader(headerRightContent, headerLeftContent, onHeaderClick, pageNumber) {
|
|
550
|
+
const pageHeader = document.createElement("div");
|
|
551
|
+
pageHeader.classList.add("rm-page-header");
|
|
552
|
+
pageHeader.classList.add(`rm-page-header-${pageNumber ? pageNumber : 0}`);
|
|
553
|
+
pageHeader.style.overflow = "hidden";
|
|
554
|
+
pageHeader.style.cursor = "pointer";
|
|
555
|
+
pageHeader.style.position = "relative";
|
|
556
|
+
const pageHeaderContent = document.createElement("div");
|
|
557
|
+
pageHeaderContent.classList.add("rm-page-header-content");
|
|
558
|
+
pageHeaderContent.style.width = "100%";
|
|
559
|
+
pageHeaderContent.style.overflow = "hidden";
|
|
560
|
+
const headerLeft = headerLeftContent.replace("{page}", `<span class="rm-page-number-plus"></span>`);
|
|
561
|
+
const headerRight = headerRightContent.replace("{page}", `<span class="rm-page-number-plus"></span>`);
|
|
562
|
+
const pageHeaderLeft = document.createElement("div");
|
|
563
|
+
pageHeaderLeft.classList.add("rm-page-header-left");
|
|
564
|
+
pageHeaderLeft.innerHTML = headerLeft;
|
|
565
|
+
const pageHeaderRight = document.createElement("div");
|
|
566
|
+
pageHeaderRight.classList.add("rm-page-header-right");
|
|
567
|
+
pageHeaderRight.innerHTML = headerRight;
|
|
568
|
+
pageHeaderContent.append(pageHeaderLeft, pageHeaderRight);
|
|
569
|
+
pageHeader.append(pageHeaderContent);
|
|
570
|
+
pageHeader.addEventListener("click", onHeaderClick);
|
|
571
|
+
return pageHeader;
|
|
572
|
+
}
|
|
573
|
+
var getHeight = (pageOptions, _headerHeight, _footerHeight) => {
|
|
574
|
+
const _pageHeaderHeight = pageOptions.contentMarginTop + pageOptions.marginTop + _headerHeight;
|
|
575
|
+
const _pageFooterHeight = pageOptions.contentMarginBottom + pageOptions.marginBottom + _footerHeight;
|
|
576
|
+
const _pageHeight = pageOptions.pageHeight - _pageHeaderHeight - _pageFooterHeight;
|
|
577
|
+
return {
|
|
578
|
+
_pageHeaderHeight,
|
|
579
|
+
_pageFooterHeight,
|
|
580
|
+
_pageHeight
|
|
581
|
+
};
|
|
582
|
+
};
|
|
583
|
+
var headerClickEvent = (pageNumber, onHeaderClick) => {
|
|
584
|
+
return (event) => {
|
|
585
|
+
onHeaderClick === null || onHeaderClick === void 0 ? void 0 : onHeaderClick({
|
|
586
|
+
event,
|
|
587
|
+
pageNumber
|
|
588
|
+
});
|
|
589
|
+
};
|
|
590
|
+
};
|
|
591
|
+
var footerClickEvent = (pageNumber, onFooterClick) => {
|
|
592
|
+
return (event) => {
|
|
593
|
+
onFooterClick === null || onFooterClick === void 0 ? void 0 : onFooterClick({
|
|
594
|
+
event,
|
|
595
|
+
pageNumber
|
|
596
|
+
});
|
|
597
|
+
};
|
|
598
|
+
};
|
|
599
|
+
|
|
600
|
+
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_@tiptap+core@2.27.2_@tiptap+pm@2.27.2__@tiptap+pm@2.27.2/node_modules/tiptap-pagination-plus/dist/PaginationPlus.js
|
|
601
|
+
var page_count_meta_key = "PAGE_COUNT_META_KEY";
|
|
602
|
+
var key = new import_state3.PluginKey("brDecoration");
|
|
603
|
+
function buildDecorations(doc) {
|
|
604
|
+
const decorations = [];
|
|
605
|
+
doc.descendants((node, pos) => {
|
|
606
|
+
if (node.type.name === "hardBreak") {
|
|
607
|
+
const afterPos = pos + 1;
|
|
608
|
+
const widget = import_view3.Decoration.widget(afterPos, () => {
|
|
609
|
+
const el = document.createElement("span");
|
|
610
|
+
el.classList.add("rm-br-decoration");
|
|
611
|
+
return el;
|
|
612
|
+
});
|
|
613
|
+
decorations.push(widget);
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
return import_view3.DecorationSet.create(doc, decorations);
|
|
617
|
+
}
|
|
618
|
+
var defaultPageConfig = {
|
|
619
|
+
enabled: true,
|
|
620
|
+
pageBreakBackground: "#ffffff",
|
|
621
|
+
pageHeight: 800,
|
|
622
|
+
pageWidth: 789,
|
|
623
|
+
marginTop: 20,
|
|
624
|
+
marginBottom: 20,
|
|
625
|
+
marginLeft: 50,
|
|
626
|
+
marginRight: 50,
|
|
627
|
+
pageGap: 50,
|
|
628
|
+
contentMarginTop: 10,
|
|
629
|
+
contentMarginBottom: 10,
|
|
630
|
+
footerRight: "{page}",
|
|
631
|
+
footerLeft: "",
|
|
632
|
+
headerRight: "",
|
|
633
|
+
headerLeft: "",
|
|
634
|
+
customHeader: {},
|
|
635
|
+
customFooter: {}
|
|
636
|
+
};
|
|
637
|
+
var defaultOptions = Object.assign({ pageGapBorderSize: 1, pageGapBorderColor: "#e5e5e5" }, defaultPageConfig);
|
|
638
|
+
var refreshPage = (targetNode, paginationEnabled = true) => {
|
|
639
|
+
var _a;
|
|
640
|
+
const paginationElement = targetNode.querySelector("[data-rm-pagination]");
|
|
641
|
+
if (paginationEnabled) {
|
|
642
|
+
targetNode.removeAttribute("rm-pagination-disabled");
|
|
643
|
+
if (paginationElement) {
|
|
644
|
+
const lastPageBreak = (_a = paginationElement.lastElementChild) === null || _a === void 0 ? void 0 : _a.querySelector(".breaker");
|
|
645
|
+
if (lastPageBreak) {
|
|
646
|
+
const minHeight = lastPageBreak.offsetTop + lastPageBreak.offsetHeight;
|
|
647
|
+
targetNode.style.minHeight = `calc(${minHeight}px + 2px)`;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
} else {
|
|
651
|
+
targetNode.setAttribute("rm-pagination-disabled", "");
|
|
652
|
+
targetNode.style.minHeight = `auto`;
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
var getPageConfig = (_storage, _currentOptions) => {
|
|
656
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
657
|
+
const pageConfig = {
|
|
658
|
+
enabled: (_a = _storage.enabled) !== null && _a !== void 0 ? _a : defaultOptions.enabled,
|
|
659
|
+
pageBreakBackground: (_b = _storage.pageBreakBackground) !== null && _b !== void 0 ? _b : defaultOptions.pageBreakBackground,
|
|
660
|
+
pageHeight: (_c = _storage.pageHeight) !== null && _c !== void 0 ? _c : defaultOptions.pageHeight,
|
|
661
|
+
pageWidth: (_d = _storage.pageWidth) !== null && _d !== void 0 ? _d : defaultPageConfig.pageWidth,
|
|
662
|
+
marginTop: (_e = _storage.marginTop) !== null && _e !== void 0 ? _e : defaultPageConfig.marginTop,
|
|
663
|
+
marginBottom: (_f = _storage.marginBottom) !== null && _f !== void 0 ? _f : defaultPageConfig.marginBottom,
|
|
664
|
+
marginLeft: (_g = _storage.marginLeft) !== null && _g !== void 0 ? _g : defaultPageConfig.marginLeft,
|
|
665
|
+
marginRight: (_h = _storage.marginRight) !== null && _h !== void 0 ? _h : defaultPageConfig.marginRight,
|
|
666
|
+
pageGap: (_j = _storage.pageGap) !== null && _j !== void 0 ? _j : defaultPageConfig.pageGap,
|
|
667
|
+
contentMarginTop: (_k = _storage.contentMarginTop) !== null && _k !== void 0 ? _k : defaultPageConfig.contentMarginTop,
|
|
668
|
+
contentMarginBottom: (_l = _storage.contentMarginBottom) !== null && _l !== void 0 ? _l : defaultPageConfig.contentMarginBottom,
|
|
669
|
+
footerRight: (_m = _storage.footerRight) !== null && _m !== void 0 ? _m : defaultPageConfig.footerRight,
|
|
670
|
+
footerLeft: (_o = _storage.footerLeft) !== null && _o !== void 0 ? _o : defaultPageConfig.footerLeft,
|
|
671
|
+
headerRight: (_p = _storage.headerRight) !== null && _p !== void 0 ? _p : defaultPageConfig.headerRight,
|
|
672
|
+
headerLeft: (_q = _storage.headerLeft) !== null && _q !== void 0 ? _q : defaultPageConfig.headerLeft,
|
|
673
|
+
customHeader: (_r = _storage.customHeader) !== null && _r !== void 0 ? _r : defaultPageConfig.customHeader,
|
|
674
|
+
customFooter: (_s = _storage.customFooter) !== null && _s !== void 0 ? _s : defaultPageConfig.customFooter
|
|
675
|
+
};
|
|
676
|
+
return {
|
|
677
|
+
config: pageConfig,
|
|
678
|
+
options: Object.assign(Object.assign({}, _currentOptions), pageConfig)
|
|
679
|
+
};
|
|
680
|
+
};
|
|
681
|
+
var getPageConfigFromOptions = (_currentOptions) => {
|
|
682
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
683
|
+
return {
|
|
684
|
+
enabled: (_a = _currentOptions.enabled) !== null && _a !== void 0 ? _a : defaultOptions.enabled,
|
|
685
|
+
pageBreakBackground: (_b = _currentOptions.pageBreakBackground) !== null && _b !== void 0 ? _b : defaultOptions.pageBreakBackground,
|
|
686
|
+
pageHeight: (_c = _currentOptions.pageHeight) !== null && _c !== void 0 ? _c : defaultOptions.pageHeight,
|
|
687
|
+
pageWidth: (_d = _currentOptions.pageWidth) !== null && _d !== void 0 ? _d : defaultPageConfig.pageWidth,
|
|
688
|
+
marginTop: (_e = _currentOptions.marginTop) !== null && _e !== void 0 ? _e : defaultPageConfig.marginTop,
|
|
689
|
+
marginBottom: (_f = _currentOptions.marginBottom) !== null && _f !== void 0 ? _f : defaultPageConfig.marginBottom,
|
|
690
|
+
marginLeft: (_g = _currentOptions.marginLeft) !== null && _g !== void 0 ? _g : defaultPageConfig.marginLeft,
|
|
691
|
+
marginRight: (_h = _currentOptions.marginRight) !== null && _h !== void 0 ? _h : defaultPageConfig.marginRight,
|
|
692
|
+
pageGap: (_j = _currentOptions.pageGap) !== null && _j !== void 0 ? _j : defaultPageConfig.pageGap,
|
|
693
|
+
contentMarginTop: (_k = _currentOptions.contentMarginTop) !== null && _k !== void 0 ? _k : defaultPageConfig.contentMarginTop,
|
|
694
|
+
contentMarginBottom: (_l = _currentOptions.contentMarginBottom) !== null && _l !== void 0 ? _l : defaultPageConfig.contentMarginBottom,
|
|
695
|
+
footerRight: (_m = _currentOptions.footerRight) !== null && _m !== void 0 ? _m : defaultPageConfig.footerRight,
|
|
696
|
+
footerLeft: (_o = _currentOptions.footerLeft) !== null && _o !== void 0 ? _o : defaultPageConfig.footerLeft,
|
|
697
|
+
headerRight: (_p = _currentOptions.headerRight) !== null && _p !== void 0 ? _p : defaultPageConfig.headerRight,
|
|
698
|
+
headerLeft: (_q = _currentOptions.headerLeft) !== null && _q !== void 0 ? _q : defaultPageConfig.headerLeft,
|
|
699
|
+
customHeader: (_r = _currentOptions.customHeader) !== null && _r !== void 0 ? _r : defaultPageConfig.customHeader,
|
|
700
|
+
customFooter: (_s = _currentOptions.customFooter) !== null && _s !== void 0 ? _s : defaultPageConfig.customFooter
|
|
701
|
+
};
|
|
702
|
+
};
|
|
703
|
+
var paginationKey = new import_state3.PluginKey("pagination");
|
|
704
|
+
var PaginationPlus = import_core4.Extension.create({
|
|
705
|
+
name: "PaginationPlus",
|
|
706
|
+
addOptions() {
|
|
707
|
+
return defaultOptions;
|
|
708
|
+
},
|
|
709
|
+
addStorage() {
|
|
710
|
+
return Object.assign(Object.assign({}, defaultOptions), { headerHeight: /* @__PURE__ */ new Map(), footerHeight: /* @__PURE__ */ new Map(), appliedConfig: defaultPageConfig });
|
|
711
|
+
},
|
|
712
|
+
onCreate() {
|
|
713
|
+
const { options: _currentOptions } = getPageConfig(this.storage, this.options);
|
|
714
|
+
const pageConfig = getPageConfigFromOptions(this.options);
|
|
715
|
+
const targetNode = this.editor.view.dom;
|
|
716
|
+
targetNode.classList.add("rm-with-pagination");
|
|
717
|
+
targetNode.style.border = `1px solid var(--rm-page-gap-border-color)`;
|
|
718
|
+
targetNode.style.paddingLeft = `var(--rm-margin-left)`;
|
|
719
|
+
targetNode.style.paddingRight = `var(--rm-margin-right)`;
|
|
720
|
+
targetNode.style.width = `var(--rm-page-width)`;
|
|
721
|
+
updateCssVariables(targetNode, Object.assign(Object.assign({}, _currentOptions), pageConfig));
|
|
722
|
+
const style = document.createElement("style");
|
|
723
|
+
style.dataset.rmPaginationStyle = "";
|
|
724
|
+
style.textContent = `
|
|
725
|
+
.rm-pagination-gap{
|
|
726
|
+
border-top: 1px solid;
|
|
727
|
+
border-bottom: 1px solid;
|
|
728
|
+
border-color: var(--rm-page-gap-border-color);
|
|
729
|
+
}
|
|
730
|
+
.rm-with-pagination,
|
|
731
|
+
.rm-with-pagination .rm-first-page-header {
|
|
732
|
+
counter-reset: page-number page-number-plus 1;
|
|
733
|
+
}
|
|
734
|
+
.rm-with-pagination .image-plus-wrapper,
|
|
735
|
+
.rm-with-pagination .table-plus td,
|
|
736
|
+
.rm-with-pagination .table-plus th {
|
|
737
|
+
max-height: var(--rm-max-content-child-height);
|
|
738
|
+
overflow-y: auto;
|
|
739
|
+
}
|
|
740
|
+
.rm-with-pagination .image-plus-wrapper {
|
|
741
|
+
overflow-y: visible;
|
|
742
|
+
}
|
|
743
|
+
.rm-with-pagination .rm-page-break {
|
|
744
|
+
counter-increment: page-number page-number-plus;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
.rm-with-pagination .rm-page-break:last-child .rm-pagination-gap {
|
|
748
|
+
display: none;
|
|
749
|
+
}
|
|
750
|
+
.rm-with-pagination .rm-page-break:last-child .rm-page-header {
|
|
751
|
+
display: none;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
.rm-with-pagination table tr td,
|
|
755
|
+
.rm-with-pagination table tr th {
|
|
756
|
+
word-break: break-all;
|
|
757
|
+
}
|
|
758
|
+
.rm-with-pagination table > tr {
|
|
759
|
+
display: grid;
|
|
760
|
+
min-width: 100%;
|
|
761
|
+
}
|
|
762
|
+
.rm-with-pagination table {
|
|
763
|
+
border-collapse: collapse;
|
|
764
|
+
width: 100%;
|
|
765
|
+
display: contents;
|
|
766
|
+
}
|
|
767
|
+
.rm-with-pagination table tbody{
|
|
768
|
+
display: table;
|
|
769
|
+
max-height: 300px;
|
|
770
|
+
overflow-y: auto;
|
|
771
|
+
}
|
|
772
|
+
.rm-with-pagination table tbody > tr{
|
|
773
|
+
display: table-row !important;
|
|
774
|
+
}
|
|
775
|
+
.rm-with-pagination *:has(>br.ProseMirror-trailingBreak:only-child) {
|
|
776
|
+
display: table;
|
|
777
|
+
width: 100%;
|
|
778
|
+
}
|
|
779
|
+
.rm-with-pagination .rm-br-decoration {
|
|
780
|
+
display: table;
|
|
781
|
+
width: 100%;
|
|
782
|
+
}
|
|
783
|
+
.rm-with-pagination .table-row-group {
|
|
784
|
+
max-height: var(--rm-max-content-child-height);
|
|
785
|
+
overflow-y: auto;
|
|
786
|
+
width: 100%;
|
|
787
|
+
}
|
|
788
|
+
.rm-with-pagination .rm-page-footer-left,
|
|
789
|
+
.rm-with-pagination .rm-page-footer-right,
|
|
790
|
+
.rm-with-pagination .rm-page-header-left,
|
|
791
|
+
.rm-with-pagination .rm-page-header-right {
|
|
792
|
+
display: inline-block;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
.rm-with-pagination .rm-page-header-left,
|
|
796
|
+
.rm-with-pagination .rm-page-footer-left{
|
|
797
|
+
float: left;
|
|
798
|
+
margin-left: var(--rm-margin-left);
|
|
799
|
+
}
|
|
800
|
+
.rm-with-pagination .rm-page-header-right,
|
|
801
|
+
.rm-with-pagination .rm-page-footer-right{
|
|
802
|
+
float: right;
|
|
803
|
+
margin-right: var(--rm-margin-right);
|
|
804
|
+
}
|
|
805
|
+
.rm-with-pagination .rm-first-page-header .rm-page-header-right{
|
|
806
|
+
margin-right: 0px !important;
|
|
807
|
+
}
|
|
808
|
+
.rm-with-pagination .rm-first-page-header .rm-page-header-left{
|
|
809
|
+
margin-left: 0px !important;
|
|
810
|
+
}
|
|
811
|
+
.rm-with-pagination .rm-page-number::before {
|
|
812
|
+
content: counter(page-number);
|
|
813
|
+
}
|
|
814
|
+
.rm-with-pagination .rm-page-number-plus::before {
|
|
815
|
+
content: counter(page-number-plus);
|
|
816
|
+
}
|
|
817
|
+
.rm-with-pagination .rm-page-header,
|
|
818
|
+
.rm-with-pagination .rm-page-footer{
|
|
819
|
+
width: 100%;
|
|
820
|
+
}
|
|
821
|
+
.rm-with-pagination .rm-page-header{
|
|
822
|
+
padding-bottom: var(--rm-content-margin-top) !important;
|
|
823
|
+
padding-top: var(--rm-margin-top) !important;
|
|
824
|
+
display: inline-flex;
|
|
825
|
+
justify-content: space-between;
|
|
826
|
+
max-height: calc(calc(var(--rm-page-height) * 0.45) - var(--rm-margin-top) - var(--rm-content-margin-top));
|
|
827
|
+
overflow-y: hidden;
|
|
828
|
+
}
|
|
829
|
+
.rm-with-pagination .rm-page-footer{
|
|
830
|
+
padding-top: var(--rm-content-margin-bottom) !important;
|
|
831
|
+
padding-bottom: var(--rm-margin-bottom) !important;
|
|
832
|
+
display: inline-flex;
|
|
833
|
+
justify-content: space-between;
|
|
834
|
+
max-height: calc(calc(var(--rm-page-height) * 0.45) - var(--rm-content-margin-bottom) - var(--rm-margin-bottom));
|
|
835
|
+
overflow-y: hidden;
|
|
836
|
+
}
|
|
837
|
+
.rm-with-pagination[rm-pagination-disabled] {
|
|
838
|
+
padding-top: var(--rm-margin-top) !important;
|
|
839
|
+
padding-bottom: var(--rm-margin-bottom) !important;
|
|
840
|
+
}
|
|
841
|
+
`;
|
|
842
|
+
document.head.appendChild(style);
|
|
843
|
+
refreshPage(targetNode, _currentOptions.enabled);
|
|
844
|
+
},
|
|
845
|
+
addProseMirrorPlugins() {
|
|
846
|
+
const editor = this.editor;
|
|
847
|
+
const storage = this.storage;
|
|
848
|
+
return [
|
|
849
|
+
new import_state3.Plugin({
|
|
850
|
+
key: paginationKey,
|
|
851
|
+
state: {
|
|
852
|
+
init: (_, state) => {
|
|
853
|
+
const _currentOptions = getPageConfigFromOptions(this.options);
|
|
854
|
+
const pageConfig = getPageConfigFromOptions(this.options);
|
|
855
|
+
const widgetList = createDecoration(Object.assign(Object.assign({}, this.options), _currentOptions), /* @__PURE__ */ new Map(), /* @__PURE__ */ new Map());
|
|
856
|
+
storage.pageBreakBackground = _currentOptions.pageBreakBackground;
|
|
857
|
+
storage.pageHeight = _currentOptions.pageHeight;
|
|
858
|
+
storage.pageWidth = _currentOptions.pageWidth;
|
|
859
|
+
storage.marginTop = _currentOptions.marginTop;
|
|
860
|
+
storage.marginBottom = _currentOptions.marginBottom;
|
|
861
|
+
storage.marginLeft = _currentOptions.marginLeft;
|
|
862
|
+
storage.marginRight = _currentOptions.marginRight;
|
|
863
|
+
storage.pageGap = _currentOptions.pageGap;
|
|
864
|
+
storage.contentMarginTop = _currentOptions.contentMarginTop;
|
|
865
|
+
storage.contentMarginBottom = _currentOptions.contentMarginBottom;
|
|
866
|
+
storage.footerRight = _currentOptions.footerRight;
|
|
867
|
+
storage.footerLeft = _currentOptions.footerLeft;
|
|
868
|
+
storage.headerRight = _currentOptions.headerRight;
|
|
869
|
+
storage.headerLeft = _currentOptions.headerLeft;
|
|
870
|
+
storage.customHeader = _currentOptions.customHeader;
|
|
871
|
+
storage.customFooter = _currentOptions.customFooter;
|
|
872
|
+
storage.headerHeight = /* @__PURE__ */ new Map();
|
|
873
|
+
storage.footerHeight = /* @__PURE__ */ new Map();
|
|
874
|
+
storage.appliedConfig = pageConfig;
|
|
875
|
+
return {
|
|
876
|
+
decorations: import_view3.DecorationSet.create(state.doc, widgetList)
|
|
877
|
+
};
|
|
878
|
+
},
|
|
879
|
+
apply: (tr, oldDeco, oldState, newState) => {
|
|
880
|
+
const { options: _currentOptions, config: pageConfig } = getPageConfig(storage, this.options);
|
|
881
|
+
if (storage.enabled === storage.appliedConfig.enabled && storage.enabled === false && storage.appliedConfig.enabled === false) {
|
|
882
|
+
return oldDeco;
|
|
883
|
+
}
|
|
884
|
+
const pageCount = getNewPageCount(editor.view, Object.assign(Object.assign({}, _currentOptions), pageConfig));
|
|
885
|
+
const currentPageCount = getExistingPageCount(editor.view);
|
|
886
|
+
const getNewDecoration = () => {
|
|
887
|
+
const { options: _currentOptions2, config: pageConfig2 } = getPageConfig(storage, this.options);
|
|
888
|
+
updateCssVariables(editor.view.dom, _currentOptions2);
|
|
889
|
+
let headerHeight = "headerHeight" in this.storage ? this.storage.headerHeight : /* @__PURE__ */ new Map();
|
|
890
|
+
let footerHeight = "footerHeight" in this.storage ? this.storage.footerHeight : /* @__PURE__ */ new Map();
|
|
891
|
+
const widgetList = createDecoration(Object.assign(Object.assign({}, _currentOptions2), pageConfig2), headerHeight, footerHeight);
|
|
892
|
+
storage.appliedConfig = pageConfig2;
|
|
893
|
+
storage.headerHeight = headerHeight;
|
|
894
|
+
storage.footerHeight = footerHeight;
|
|
895
|
+
return {
|
|
896
|
+
decorations: import_view3.DecorationSet.create(newState.doc, [...widgetList]),
|
|
897
|
+
footerHeight
|
|
898
|
+
};
|
|
899
|
+
};
|
|
900
|
+
if (
|
|
901
|
+
// If pagination is enabled only then check for other changes
|
|
902
|
+
(pageCount > 1 ? pageCount : 1) !== currentPageCount || storage.enabled !== storage.appliedConfig.enabled || storage.pageBreakBackground !== storage.appliedConfig.pageBreakBackground || storage.pageHeight !== storage.appliedConfig.pageHeight || storage.pageWidth !== storage.appliedConfig.pageWidth || storage.marginTop !== storage.appliedConfig.marginTop || storage.marginBottom !== storage.appliedConfig.marginBottom || storage.marginLeft !== storage.appliedConfig.marginLeft || storage.marginRight !== storage.appliedConfig.marginRight || storage.pageGap !== storage.appliedConfig.pageGap || storage.contentMarginTop !== storage.appliedConfig.contentMarginTop || storage.contentMarginBottom !== storage.appliedConfig.contentMarginBottom || storage.headerLeft !== storage.appliedConfig.headerLeft || storage.headerRight !== storage.appliedConfig.headerRight || storage.footerLeft !== storage.appliedConfig.footerLeft || storage.footerRight !== storage.appliedConfig.footerRight || !deepEqualIterative(storage.appliedConfig.customHeader, storage.customHeader) || !deepEqualIterative(storage.appliedConfig.customFooter, storage.customFooter)
|
|
903
|
+
) {
|
|
904
|
+
return getNewDecoration();
|
|
905
|
+
}
|
|
906
|
+
return oldDeco;
|
|
907
|
+
}
|
|
908
|
+
},
|
|
909
|
+
props: {
|
|
910
|
+
decorations(state) {
|
|
911
|
+
var _a;
|
|
912
|
+
return (_a = this.getState(state)) === null || _a === void 0 ? void 0 : _a.decorations;
|
|
913
|
+
}
|
|
914
|
+
},
|
|
915
|
+
view: (editorView) => {
|
|
916
|
+
return {
|
|
917
|
+
update: (view) => {
|
|
918
|
+
const { options: _currentOptions, config: pageConfig } = getPageConfig(storage, this.options);
|
|
919
|
+
if (!pageConfig.enabled && !view.dom.hasAttribute("rm-pagination-disabled")) {
|
|
920
|
+
refreshPage(view.dom, false);
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
const pageCount = getNewPageCount(view, Object.assign(Object.assign({}, _currentOptions), pageConfig));
|
|
924
|
+
const currentPageCount = getExistingPageCount(view);
|
|
925
|
+
const triggerUpdate = (_footerHeight) => {
|
|
926
|
+
requestAnimationFrame(() => {
|
|
927
|
+
const tr = view.state.tr.setMeta(page_count_meta_key, { footerHeight: _footerHeight });
|
|
928
|
+
view.dispatch(tr);
|
|
929
|
+
});
|
|
930
|
+
};
|
|
931
|
+
if (currentPageCount !== pageCount) {
|
|
932
|
+
triggerUpdate();
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
const headerHeight = getHeaderHeight(view.dom, getCustomPages(_currentOptions.customHeader, {}), "content");
|
|
936
|
+
const footerHeight = getFooterHeight(view.dom, getCustomPages({}, _currentOptions.customFooter), "content");
|
|
937
|
+
const footerHeightForCurrentPages = /* @__PURE__ */ new Map();
|
|
938
|
+
for (let i = 0; i <= pageCount; i++) {
|
|
939
|
+
if (footerHeight.has(i)) {
|
|
940
|
+
footerHeightForCurrentPages.set(i, footerHeight.get(i) || 0);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
const headerHeightForCurrentPages = /* @__PURE__ */ new Map();
|
|
944
|
+
for (let i = 0; i <= pageCount; i++) {
|
|
945
|
+
if (headerHeight.has(i)) {
|
|
946
|
+
headerHeightForCurrentPages.set(i, headerHeight.get(i) || 0);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
const pagesSetToCheck = /* @__PURE__ */ new Set([1, ...footerHeightForCurrentPages.keys(), ...headerHeightForCurrentPages.keys()]);
|
|
950
|
+
let missingPageNumber = void 0;
|
|
951
|
+
for (let i = 1; i <= pageCount; i++) {
|
|
952
|
+
if (!pagesSetToCheck.has(i)) {
|
|
953
|
+
missingPageNumber = i;
|
|
954
|
+
break;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
if (missingPageNumber) {
|
|
958
|
+
pagesSetToCheck.add(missingPageNumber);
|
|
959
|
+
}
|
|
960
|
+
pagesSetToCheck.delete(0);
|
|
961
|
+
let pageContentHeightVariable = {};
|
|
962
|
+
let maxContentHeight = void 0;
|
|
963
|
+
for (const page of pagesSetToCheck) {
|
|
964
|
+
const headerHeight2 = headerHeightForCurrentPages.has(page) ? headerHeightForCurrentPages.get(page) || 0 : headerHeightForCurrentPages.get(0) || 0;
|
|
965
|
+
const footerHeight2 = footerHeightForCurrentPages.has(page) ? footerHeightForCurrentPages.get(page) || 0 : footerHeightForCurrentPages.get(0) || 0;
|
|
966
|
+
const { _pageHeaderHeight, _pageHeight } = getHeight(_currentOptions, headerHeight2, footerHeight2);
|
|
967
|
+
const contentHeight = page === 1 ? _pageHeight + _pageHeaderHeight : _pageHeight;
|
|
968
|
+
if (page === 1) {
|
|
969
|
+
pageContentHeightVariable[`rm-page-content-first`] = `${contentHeight}px`;
|
|
970
|
+
}
|
|
971
|
+
if (page === missingPageNumber) {
|
|
972
|
+
pageContentHeightVariable[`rm-page-content-general`] = `${contentHeight}px`;
|
|
973
|
+
} else {
|
|
974
|
+
pageContentHeightVariable[`rm-page-content-${page}`] = `${contentHeight}px`;
|
|
975
|
+
}
|
|
976
|
+
if (maxContentHeight === void 0 || contentHeight < maxContentHeight) {
|
|
977
|
+
maxContentHeight = contentHeight;
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
if (maxContentHeight) {
|
|
981
|
+
view.dom.style.setProperty(`--rm-max-content-child-height`, `${maxContentHeight - 10}px`);
|
|
982
|
+
}
|
|
983
|
+
Object.entries(pageContentHeightVariable).forEach(([key2, value]) => {
|
|
984
|
+
view.dom.style.setProperty(`--${key2}`, value);
|
|
985
|
+
});
|
|
986
|
+
refreshPage(view.dom, _currentOptions.enabled);
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
};
|
|
990
|
+
}
|
|
991
|
+
}),
|
|
992
|
+
new import_state3.Plugin({
|
|
993
|
+
key,
|
|
994
|
+
state: {
|
|
995
|
+
init(_, state) {
|
|
996
|
+
return buildDecorations(state.doc);
|
|
997
|
+
},
|
|
998
|
+
apply(tr, old) {
|
|
999
|
+
if (tr.docChanged || tr.steps.some((step) => step instanceof import_transform.ReplaceStep) || tr.steps.some((step) => step instanceof import_transform.ReplaceAroundStep) || tr.steps.some((step) => step instanceof import_transform.AddMarkStep) || tr.steps.some((step) => step instanceof import_transform.RemoveMarkStep) || tr.steps.some((step) => step instanceof import_transform.RemoveNodeMarkStep) || tr.steps.some((step) => step instanceof import_transform.AttrStep)) {
|
|
1000
|
+
return buildDecorations(tr.doc);
|
|
1001
|
+
}
|
|
1002
|
+
return old;
|
|
1003
|
+
}
|
|
1004
|
+
},
|
|
1005
|
+
props: {
|
|
1006
|
+
decorations(state) {
|
|
1007
|
+
var _a;
|
|
1008
|
+
return (_a = key.getState(state)) !== null && _a !== void 0 ? _a : import_view3.DecorationSet.empty;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
})
|
|
1012
|
+
];
|
|
1013
|
+
},
|
|
1014
|
+
addCommands() {
|
|
1015
|
+
return {
|
|
1016
|
+
updatePageBreakBackground: (color) => () => {
|
|
1017
|
+
this.storage.pageBreakBackground = color;
|
|
1018
|
+
return true;
|
|
1019
|
+
},
|
|
1020
|
+
updatePageSize: (size) => () => {
|
|
1021
|
+
this.storage.pageHeight = size.pageHeight;
|
|
1022
|
+
this.storage.pageWidth = size.pageWidth;
|
|
1023
|
+
this.storage.marginTop = size.marginTop;
|
|
1024
|
+
this.storage.marginBottom = size.marginBottom;
|
|
1025
|
+
this.storage.marginLeft = size.marginLeft;
|
|
1026
|
+
this.storage.marginRight = size.marginRight;
|
|
1027
|
+
return true;
|
|
1028
|
+
},
|
|
1029
|
+
updatePageWidth: (width) => () => {
|
|
1030
|
+
this.storage.pageWidth = width;
|
|
1031
|
+
return true;
|
|
1032
|
+
},
|
|
1033
|
+
updatePageHeight: (height) => () => {
|
|
1034
|
+
this.storage.pageHeight = height;
|
|
1035
|
+
return true;
|
|
1036
|
+
},
|
|
1037
|
+
updatePageGap: (gap) => () => {
|
|
1038
|
+
this.storage.pageGap = gap;
|
|
1039
|
+
return true;
|
|
1040
|
+
},
|
|
1041
|
+
updateMargins: (margins) => () => {
|
|
1042
|
+
this.storage.marginTop = margins.top;
|
|
1043
|
+
this.storage.marginBottom = margins.bottom;
|
|
1044
|
+
this.storage.marginLeft = margins.left;
|
|
1045
|
+
this.storage.marginRight = margins.right;
|
|
1046
|
+
return true;
|
|
1047
|
+
},
|
|
1048
|
+
updateContentMargins: (margins) => () => {
|
|
1049
|
+
this.storage.contentMarginTop = margins.top;
|
|
1050
|
+
this.storage.contentMarginBottom = margins.bottom;
|
|
1051
|
+
return true;
|
|
1052
|
+
},
|
|
1053
|
+
updateHeaderContent: (left, right, pageNumber) => () => {
|
|
1054
|
+
if (pageNumber) {
|
|
1055
|
+
this.storage.customHeader = Object.assign(Object.assign({}, this.storage.customHeader), { [pageNumber]: { headerLeft: left, headerRight: right } });
|
|
1056
|
+
} else {
|
|
1057
|
+
this.storage.headerLeft = left;
|
|
1058
|
+
this.storage.headerRight = right;
|
|
1059
|
+
}
|
|
1060
|
+
return true;
|
|
1061
|
+
},
|
|
1062
|
+
updateFooterContent: (left, right, pageNumber) => () => {
|
|
1063
|
+
if (pageNumber) {
|
|
1064
|
+
this.storage.customFooter = Object.assign(Object.assign({}, this.storage.customFooter), { [pageNumber]: { footerLeft: left, footerRight: right } });
|
|
1065
|
+
} else {
|
|
1066
|
+
this.storage.footerLeft = left;
|
|
1067
|
+
this.storage.footerRight = right;
|
|
1068
|
+
}
|
|
1069
|
+
return true;
|
|
1070
|
+
},
|
|
1071
|
+
togglePagination: () => () => {
|
|
1072
|
+
this.storage.enabled = !this.storage.enabled;
|
|
1073
|
+
return true;
|
|
1074
|
+
},
|
|
1075
|
+
enablePagination: () => () => {
|
|
1076
|
+
this.storage.enabled = true;
|
|
1077
|
+
return true;
|
|
1078
|
+
},
|
|
1079
|
+
disablePagination: () => () => {
|
|
1080
|
+
this.storage.enabled = false;
|
|
1081
|
+
return true;
|
|
1082
|
+
}
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
});
|
|
1086
|
+
var getExistingPageCount = (view) => {
|
|
1087
|
+
const editorDom = view.dom;
|
|
1088
|
+
const paginationElement = editorDom.querySelector("[data-rm-pagination]");
|
|
1089
|
+
if (paginationElement) {
|
|
1090
|
+
return paginationElement.children.length;
|
|
1091
|
+
}
|
|
1092
|
+
return 0;
|
|
1093
|
+
};
|
|
1094
|
+
var calculatePageCount = (view, pageOptions, headerHeight = 0, footerHeight = 0) => {
|
|
1095
|
+
var _a;
|
|
1096
|
+
const editorDom = view.dom;
|
|
1097
|
+
const _pageHeaderHeight = pageOptions.contentMarginTop + pageOptions.marginTop + headerHeight;
|
|
1098
|
+
const _pageFooterHeight = pageOptions.contentMarginBottom + pageOptions.marginBottom + footerHeight;
|
|
1099
|
+
const pageContentAreaHeight = pageOptions.pageHeight - _pageHeaderHeight - _pageFooterHeight;
|
|
1100
|
+
const paginationElement = editorDom.querySelector("[data-rm-pagination]");
|
|
1101
|
+
const currentPageCount = getExistingPageCount(view);
|
|
1102
|
+
if (paginationElement) {
|
|
1103
|
+
const lastElementOfEditor = editorDom.lastElementChild;
|
|
1104
|
+
const lastPageBreak = (_a = paginationElement.lastElementChild) === null || _a === void 0 ? void 0 : _a.querySelector(".breaker");
|
|
1105
|
+
if (lastElementOfEditor && lastPageBreak) {
|
|
1106
|
+
const lastElementRect = lastElementOfEditor.getBoundingClientRect();
|
|
1107
|
+
const lastPageBreakRect = lastPageBreak.getBoundingClientRect();
|
|
1108
|
+
const lastPageGap = lastElementRect.bottom - lastPageBreakRect.bottom;
|
|
1109
|
+
if (lastPageGap > 0) {
|
|
1110
|
+
const addPage = Math.ceil(lastPageGap / pageContentAreaHeight);
|
|
1111
|
+
return currentPageCount + addPage;
|
|
1112
|
+
} else {
|
|
1113
|
+
const allBreaksAfterLastElement = Array.from(paginationElement.querySelectorAll(".breaker"));
|
|
1114
|
+
const allBreaksAfterLastElementRect = allBreaksAfterLastElement.filter((element) => element.getBoundingClientRect().top > lastElementRect.bottom);
|
|
1115
|
+
const removePage = allBreaksAfterLastElementRect.length;
|
|
1116
|
+
if (removePage > 1) {
|
|
1117
|
+
return currentPageCount - removePage;
|
|
1118
|
+
} else {
|
|
1119
|
+
return currentPageCount;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
return 1;
|
|
1124
|
+
} else {
|
|
1125
|
+
const editorHeight = editorDom.scrollHeight;
|
|
1126
|
+
let pageCount = Math.ceil(editorHeight / pageContentAreaHeight);
|
|
1127
|
+
pageCount = pageCount <= 0 ? 1 : pageCount;
|
|
1128
|
+
return pageCount;
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
var getNewPageCount = (view, pageOptions) => {
|
|
1132
|
+
if (pageOptions.enabled) {
|
|
1133
|
+
const pageCount = calculatePageCount(view, pageOptions);
|
|
1134
|
+
return pageCount <= 1 ? 1 : pageCount;
|
|
1135
|
+
} else {
|
|
1136
|
+
return 0;
|
|
1137
|
+
}
|
|
1138
|
+
};
|
|
1139
|
+
function createDecoration(pageOptions, headerHeightMap, footerHeightMap) {
|
|
1140
|
+
if (!pageOptions.enabled) {
|
|
1141
|
+
return [];
|
|
1142
|
+
}
|
|
1143
|
+
const commonHeaderOptions = { headerLeft: pageOptions.headerLeft, headerRight: pageOptions.headerRight };
|
|
1144
|
+
const commonFooterOptions = { footerLeft: pageOptions.footerLeft, footerRight: pageOptions.footerRight };
|
|
1145
|
+
const pageWidget = import_view3.Decoration.widget(0, (view) => {
|
|
1146
|
+
const _pageGap = pageOptions.pageGap;
|
|
1147
|
+
const _pageBreakBackground = pageOptions.pageBreakBackground;
|
|
1148
|
+
const el = document.createElement("div");
|
|
1149
|
+
el.dataset.rmPagination = "true";
|
|
1150
|
+
const pageBreakDefinition = (firstPage, pageHeader, pageFooter, headerHeight, footerHeight, pageNumber) => {
|
|
1151
|
+
const { _pageHeaderHeight, _pageHeight } = getHeight(pageOptions, headerHeight, footerHeight);
|
|
1152
|
+
const pageContainer = document.createElement("div");
|
|
1153
|
+
pageContainer.classList.add("rm-page-break");
|
|
1154
|
+
const page = document.createElement("div");
|
|
1155
|
+
page.classList.add("page");
|
|
1156
|
+
page.style.position = "relative";
|
|
1157
|
+
page.style.float = "left";
|
|
1158
|
+
page.style.clear = "both";
|
|
1159
|
+
const marginTop = firstPage ? `calc(${_pageHeaderHeight}px + ${_pageHeight}px)` : _pageHeight + "px";
|
|
1160
|
+
if (pageNumber) {
|
|
1161
|
+
page.style.marginTop = `var(--rm-page-content-${pageNumber}, ${marginTop})`;
|
|
1162
|
+
} else {
|
|
1163
|
+
page.style.marginTop = firstPage ? `var(--rm-page-content-first, ${marginTop})` : `var(--rm-page-content-general, ${marginTop})`;
|
|
1164
|
+
}
|
|
1165
|
+
const pageBreak = document.createElement("div");
|
|
1166
|
+
pageBreak.classList.add("breaker");
|
|
1167
|
+
pageBreak.style.width = `calc(100% + var(--rm-margin-left) + var(--rm-margin-right))`;
|
|
1168
|
+
pageBreak.style.marginLeft = `calc(-1 * var(--rm-margin-left))`;
|
|
1169
|
+
pageBreak.style.marginRight = `calc(-1 * var(--rm-margin-right))`;
|
|
1170
|
+
pageBreak.style.position = "relative";
|
|
1171
|
+
pageBreak.style.float = "left";
|
|
1172
|
+
pageBreak.style.clear = "both";
|
|
1173
|
+
pageBreak.style.left = `0px`;
|
|
1174
|
+
pageBreak.style.right = `0px`;
|
|
1175
|
+
pageBreak.style.zIndex = "2";
|
|
1176
|
+
const pageSpace = document.createElement("div");
|
|
1177
|
+
pageSpace.classList.add("rm-pagination-gap");
|
|
1178
|
+
pageSpace.style.height = _pageGap + "px";
|
|
1179
|
+
pageSpace.style.borderLeft = "1px solid";
|
|
1180
|
+
pageSpace.style.borderRight = "1px solid";
|
|
1181
|
+
pageSpace.style.position = "relative";
|
|
1182
|
+
pageSpace.style.setProperty("width", "calc(100% + 2px)", "important");
|
|
1183
|
+
pageSpace.style.left = "-1px";
|
|
1184
|
+
pageSpace.style.backgroundColor = _pageBreakBackground;
|
|
1185
|
+
pageSpace.style.borderLeftColor = _pageBreakBackground;
|
|
1186
|
+
pageSpace.style.borderRightColor = _pageBreakBackground;
|
|
1187
|
+
pageBreak.append(pageFooter, pageSpace, pageHeader);
|
|
1188
|
+
pageContainer.append(page, pageBreak);
|
|
1189
|
+
return pageContainer;
|
|
1190
|
+
};
|
|
1191
|
+
const _headerHeight = headerHeightMap.get(0) || 0;
|
|
1192
|
+
const _footerHeight = footerHeightMap.get(0) || 0;
|
|
1193
|
+
const fragment = document.createDocumentFragment();
|
|
1194
|
+
const pageCount = getNewPageCount(view, pageOptions);
|
|
1195
|
+
for (let i = 0; i < pageCount; i++) {
|
|
1196
|
+
const pageNumber = i + 1;
|
|
1197
|
+
const headerPageNumber = i + 2;
|
|
1198
|
+
if (headerPageNumber in pageOptions.customHeader || pageNumber in pageOptions.customFooter || pageNumber in pageOptions.customHeader) {
|
|
1199
|
+
let _headerOptions = commonHeaderOptions;
|
|
1200
|
+
let _footerOptions = commonFooterOptions;
|
|
1201
|
+
let _pageHeaderHeight = _headerHeight;
|
|
1202
|
+
let _pageFooterHeight = _footerHeight;
|
|
1203
|
+
if (headerPageNumber in pageOptions.customHeader) {
|
|
1204
|
+
_headerOptions = pageOptions.customHeader[headerPageNumber] || commonHeaderOptions;
|
|
1205
|
+
_pageHeaderHeight = headerHeightMap.get(headerPageNumber) || 0;
|
|
1206
|
+
}
|
|
1207
|
+
if (pageNumber in pageOptions.customFooter) {
|
|
1208
|
+
_footerOptions = pageOptions.customFooter[pageNumber] || commonFooterOptions;
|
|
1209
|
+
_pageFooterHeight = footerHeightMap.get(pageNumber) || 0;
|
|
1210
|
+
}
|
|
1211
|
+
let _pageHeader = getHeader(_headerOptions.headerRight, _headerOptions.headerLeft, headerClickEvent(headerPageNumber, pageOptions.onHeaderClick), headerPageNumber);
|
|
1212
|
+
let _pageFooter = getFooter(_footerOptions.footerRight, _footerOptions.footerLeft, footerClickEvent(pageNumber, pageOptions.onFooterClick), pageNumber);
|
|
1213
|
+
let pageBreak = pageBreakDefinition(i === 0, _pageHeader, _pageFooter, _pageHeaderHeight, _pageFooterHeight, pageNumber);
|
|
1214
|
+
fragment.appendChild(pageBreak);
|
|
1215
|
+
} else {
|
|
1216
|
+
const __pageHeader = getHeader(commonHeaderOptions.headerRight, commonHeaderOptions.headerLeft, headerClickEvent(headerPageNumber, pageOptions.onHeaderClick));
|
|
1217
|
+
const __pageFooter = getFooter(commonFooterOptions.footerRight, commonFooterOptions.footerLeft, footerClickEvent(pageNumber, pageOptions.onFooterClick));
|
|
1218
|
+
fragment.appendChild(pageBreakDefinition(i === 0, __pageHeader, __pageFooter, _headerHeight, _footerHeight));
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
el.append(fragment);
|
|
1222
|
+
el.id = "pages";
|
|
1223
|
+
el.classList.add("rm-pages-wrapper");
|
|
1224
|
+
return el;
|
|
1225
|
+
}, { side: -1 });
|
|
1226
|
+
const firstHeaderWidget = import_view3.Decoration.widget(0, () => {
|
|
1227
|
+
const pageNumber = 1;
|
|
1228
|
+
let _headerOptions = commonHeaderOptions;
|
|
1229
|
+
if (pageNumber in pageOptions.customHeader) {
|
|
1230
|
+
_headerOptions = pageOptions.customHeader[pageNumber];
|
|
1231
|
+
}
|
|
1232
|
+
const el = getHeader(_headerOptions.headerRight, _headerOptions.headerLeft, headerClickEvent(pageNumber, pageOptions.onHeaderClick));
|
|
1233
|
+
el.classList.add("rm-first-page-header");
|
|
1234
|
+
return el;
|
|
1235
|
+
}, { side: -1 });
|
|
1236
|
+
return [pageWidget, firstHeaderWidget];
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_@tiptap+core@2.27.2_@tiptap+pm@2.27.2__@tiptap+pm@2.27.2/node_modules/tiptap-pagination-plus/dist/constants.js
|
|
1240
|
+
var A4_PAGE_SIZE = getPageSize(1123, 794, 95, 95, 76, 76);
|
|
1241
|
+
var A3_PAGE_SIZE = getPageSize(1591, 1123, 95, 95, 76, 76);
|
|
1242
|
+
var A5_PAGE_SIZE = getPageSize(794, 419, 76, 76, 57, 57);
|
|
1243
|
+
var LETTER_PAGE_SIZE = getPageSize(1060, 818, 96, 96, 96, 96);
|
|
1244
|
+
var LEGAL_PAGE_SIZE = getPageSize(1404, 818, 96, 96, 96, 96);
|
|
1245
|
+
var TABLOID_PAGE_SIZE = getPageSize(1635, 1060, 96, 96, 96, 96);
|
|
1246
|
+
var PAGE_SIZES = {
|
|
1247
|
+
A4: A4_PAGE_SIZE,
|
|
1248
|
+
A3: A3_PAGE_SIZE,
|
|
1249
|
+
A5: A5_PAGE_SIZE,
|
|
1250
|
+
LETTER: LETTER_PAGE_SIZE,
|
|
1251
|
+
LEGAL: LEGAL_PAGE_SIZE,
|
|
1252
|
+
TABLOID: TABLOID_PAGE_SIZE
|
|
1253
|
+
};
|
|
1254
|
+
|
|
238
1255
|
// src/Editor.ts
|
|
239
|
-
|
|
1256
|
+
function sanitizePastedHTML(html) {
|
|
1257
|
+
let cleaned = html.replace(/<meta[^>]*>/gi, "");
|
|
1258
|
+
cleaned = cleaned.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "");
|
|
1259
|
+
cleaned = cleaned.replace(/<!--[\s\S]*?-->/g, "");
|
|
1260
|
+
cleaned = cleaned.replace(/<link[^>]*>/gi, "");
|
|
1261
|
+
cleaned = cleaned.replace(/<base[^>]*>/gi, "");
|
|
1262
|
+
cleaned = cleaned.replace(/<title[^>]*>[\s\S]*?<\/title>/gi, "");
|
|
1263
|
+
{
|
|
1264
|
+
for (let pass = 0; pass < 10; pass++) {
|
|
1265
|
+
const before = cleaned;
|
|
1266
|
+
cleaned = cleaned.replace(
|
|
1267
|
+
/<span\s([^>]*style\s*=\s*["'][^"']*(?:background-color|background)[^"']*["'][^>]*)>([^<]*(?:<(?!\/?span)[^>]*>[^<]*)*)<\/span>/gi,
|
|
1268
|
+
(_full, attrs, content) => {
|
|
1269
|
+
if (!/background(?:-color)?\s*:/.test(attrs)) return _full;
|
|
1270
|
+
const colorMatch = attrs.match(/(?<!background-)color\s*:\s*([^;"]+)/i);
|
|
1271
|
+
const colorVal = colorMatch ? colorMatch[1].trim() : null;
|
|
1272
|
+
const markAttrs = colorVal ? attrs.replace(/(?<!background-)color\s*:\s*[^;"]+;?\s*/gi, "").trim() : attrs;
|
|
1273
|
+
if (colorVal) {
|
|
1274
|
+
return `<mark ${markAttrs}><span style="color: ${colorVal};">${content}</span></mark>`;
|
|
1275
|
+
}
|
|
1276
|
+
return `<mark ${markAttrs}>${content}</mark>`;
|
|
1277
|
+
}
|
|
1278
|
+
);
|
|
1279
|
+
if (cleaned === before) break;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
cleaned = cleaned.replace(
|
|
1283
|
+
/<b\s[^>]*style\s*=\s*["'][^"']*font-weight:\s*normal[^"']*["'][^>]*>/gi,
|
|
1284
|
+
""
|
|
1285
|
+
);
|
|
1286
|
+
cleaned = cleaned.replace(/<\/b>/gi, "");
|
|
1287
|
+
cleaned = cleaned.replace(/\sid\s*=\s*["']docs-internal[^"']*["']/gi, "");
|
|
1288
|
+
return cleaned;
|
|
1289
|
+
}
|
|
240
1290
|
function migrateContent(content) {
|
|
241
1291
|
if (!content) return content;
|
|
242
1292
|
if (typeof content === "string") {
|
|
@@ -335,36 +1385,360 @@ function createTiptapEditor(options, plugins, collaborationSetup) {
|
|
|
335
1385
|
const baseStarterKit = options.collaboration ? import_starter_kit.default.configure({ history: false }) : import_starter_kit.default;
|
|
336
1386
|
const pluginExtensions = collectExtensions(plugins);
|
|
337
1387
|
const blockAttrs = options.getPageMap ? BlockAttributesExtension.configure({ pageMap: options.getPageMap }) : BlockAttributesExtension;
|
|
338
|
-
const paginationExt = options.paginationOptions ?
|
|
1388
|
+
const paginationExt = options.paginationOptions ? PaginationPlus.configure(options.paginationOptions) : PaginationPlus;
|
|
1389
|
+
const ManualColumnResize = import_core5.Extension.create({
|
|
1390
|
+
name: "manualColumnResize",
|
|
1391
|
+
addProseMirrorPlugins() {
|
|
1392
|
+
const key2 = new import_state4.PluginKey("manualColumnResize");
|
|
1393
|
+
return [new import_state4.Plugin({
|
|
1394
|
+
key: key2,
|
|
1395
|
+
view(view) {
|
|
1396
|
+
function pauseObserver() {
|
|
1397
|
+
try {
|
|
1398
|
+
view.domObserver?.stop?.();
|
|
1399
|
+
} catch (_) {
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
function resumeObserver() {
|
|
1403
|
+
try {
|
|
1404
|
+
view.domObserver?.start?.();
|
|
1405
|
+
} catch (_) {
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
function getMaxContainerWidth(tableEl) {
|
|
1409
|
+
let curr = tableEl.parentElement;
|
|
1410
|
+
while (curr) {
|
|
1411
|
+
const style = window.getComputedStyle(curr);
|
|
1412
|
+
const paddingLeft = parseFloat(style.paddingLeft) || 0;
|
|
1413
|
+
const paddingRight = parseFloat(style.paddingRight) || 0;
|
|
1414
|
+
const availWidth = curr.clientWidth - paddingLeft - paddingRight;
|
|
1415
|
+
if (availWidth > 100 && (curr.classList.contains("docs-editor__paper") || curr.classList.contains("docs-editor-page") || curr.classList.contains("ProseMirror") || curr.classList.contains("rm-with-pagination"))) {
|
|
1416
|
+
return availWidth;
|
|
1417
|
+
}
|
|
1418
|
+
curr = curr.parentElement;
|
|
1419
|
+
}
|
|
1420
|
+
return tableEl.parentElement?.clientWidth || 614;
|
|
1421
|
+
}
|
|
1422
|
+
const onMouseDown = function(event) {
|
|
1423
|
+
if (event.button !== 0) return;
|
|
1424
|
+
const td = event.target.closest("td, th");
|
|
1425
|
+
if (!td) return;
|
|
1426
|
+
const r = td.getBoundingClientRect();
|
|
1427
|
+
const parent = td.parentElement;
|
|
1428
|
+
if (!parent) return;
|
|
1429
|
+
const colIdx = Array.from(parent.children).indexOf(td);
|
|
1430
|
+
if (colIdx === -1) return;
|
|
1431
|
+
const table = td.closest("table");
|
|
1432
|
+
if (!table) return;
|
|
1433
|
+
const distRight = Math.abs(event.clientX - r.right);
|
|
1434
|
+
const distLeft = Math.abs(event.clientX - r.left);
|
|
1435
|
+
let targetColIdx = -1;
|
|
1436
|
+
if (distRight <= 16) {
|
|
1437
|
+
targetColIdx = colIdx;
|
|
1438
|
+
} else if (distLeft <= 16 && colIdx > 0) {
|
|
1439
|
+
targetColIdx = colIdx - 1;
|
|
1440
|
+
} else {
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
const colsList = table.querySelectorAll("colgroup col");
|
|
1444
|
+
const totalCols = colsList.length || table.querySelector("tr")?.children.length || 0;
|
|
1445
|
+
const allColWidths = [];
|
|
1446
|
+
for (let c = 0; c < totalCols; c++) {
|
|
1447
|
+
const colEl = colsList[c];
|
|
1448
|
+
const w = colEl ? parseFloat(colEl.style.width) : 0;
|
|
1449
|
+
allColWidths[c] = w || initialWidth(table, c);
|
|
1450
|
+
}
|
|
1451
|
+
const isLastCol = targetColIdx === totalCols - 1;
|
|
1452
|
+
const startX = event.clientX;
|
|
1453
|
+
const startW = allColWidths[targetColIdx] || initialWidth(table, targetColIdx);
|
|
1454
|
+
const maxContainerW = getMaxContainerWidth(table);
|
|
1455
|
+
let otherColsW = 0;
|
|
1456
|
+
allColWidths.forEach((w, idx) => {
|
|
1457
|
+
if (idx !== targetColIdx) {
|
|
1458
|
+
otherColsW += w;
|
|
1459
|
+
}
|
|
1460
|
+
});
|
|
1461
|
+
const maxNw = Math.max(20, maxContainerW - otherColsW);
|
|
1462
|
+
function updateDOMWidths(targetIdx, targetW) {
|
|
1463
|
+
let totalWidth = 0;
|
|
1464
|
+
allColWidths.forEach((_, idx) => {
|
|
1465
|
+
const w = idx === targetIdx ? targetW : allColWidths[idx];
|
|
1466
|
+
const col = table.querySelector(`colgroup col:nth-child(${idx + 1})`);
|
|
1467
|
+
if (col) col.style.setProperty("width", w + "px", "important");
|
|
1468
|
+
table.querySelectorAll("tr").forEach(function(row) {
|
|
1469
|
+
const cell = row.children[idx];
|
|
1470
|
+
if (cell) {
|
|
1471
|
+
cell.style.setProperty("width", w + "px", "important");
|
|
1472
|
+
cell.setAttribute("width", String(w));
|
|
1473
|
+
}
|
|
1474
|
+
});
|
|
1475
|
+
totalWidth += w;
|
|
1476
|
+
});
|
|
1477
|
+
if (totalWidth > 0) {
|
|
1478
|
+
table.style.setProperty("width", Math.min(totalWidth, maxContainerW) + "px", "important");
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
event.stopPropagation();
|
|
1482
|
+
let lastNw = startW;
|
|
1483
|
+
let moveCount = 0;
|
|
1484
|
+
const onMove = function(e) {
|
|
1485
|
+
moveCount++;
|
|
1486
|
+
if (!e.buttons) {
|
|
1487
|
+
onUp(e);
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
const diff = e.clientX - startX;
|
|
1491
|
+
const nw = Math.min(maxNw, Math.max(20, startW + diff));
|
|
1492
|
+
lastNw = nw;
|
|
1493
|
+
let borderPos = table.getBoundingClientRect().left;
|
|
1494
|
+
for (let i = 0; i <= targetColIdx; i++) {
|
|
1495
|
+
borderPos += i === targetColIdx ? nw : allColWidths[i];
|
|
1496
|
+
}
|
|
1497
|
+
showLine(table, borderPos);
|
|
1498
|
+
pauseObserver();
|
|
1499
|
+
updateDOMWidths(targetColIdx, nw);
|
|
1500
|
+
resumeObserver();
|
|
1501
|
+
};
|
|
1502
|
+
const onUp = function(upEvent) {
|
|
1503
|
+
document.removeEventListener("mousemove", onMove);
|
|
1504
|
+
document.removeEventListener("mouseup", onUp, true);
|
|
1505
|
+
upEvent.stopPropagation();
|
|
1506
|
+
hideLine();
|
|
1507
|
+
if (lastNw === startW) return;
|
|
1508
|
+
allColWidths[targetColIdx] = lastNw;
|
|
1509
|
+
console.log("[Resize] onUp:", { lastNw, startW, isLastCol, targetColIdx, allColWidths });
|
|
1510
|
+
try {
|
|
1511
|
+
const { state } = view;
|
|
1512
|
+
const { doc } = state;
|
|
1513
|
+
let tablePos = -1;
|
|
1514
|
+
doc.descendants((node, pos) => {
|
|
1515
|
+
if (tablePos >= 0) return false;
|
|
1516
|
+
if (node.type.name === "table") {
|
|
1517
|
+
try {
|
|
1518
|
+
const dom = view.nodeDOM(pos);
|
|
1519
|
+
if (dom === table || dom instanceof HTMLElement && dom.contains(table) || table.contains(dom)) {
|
|
1520
|
+
tablePos = pos;
|
|
1521
|
+
return false;
|
|
1522
|
+
}
|
|
1523
|
+
} catch (_) {
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
return true;
|
|
1527
|
+
});
|
|
1528
|
+
if (tablePos >= 0) {
|
|
1529
|
+
const tableNode = doc.nodeAt(tablePos);
|
|
1530
|
+
if (tableNode) {
|
|
1531
|
+
const tr = state.tr;
|
|
1532
|
+
let cellsUpdated = 0;
|
|
1533
|
+
tableNode.forEach((row, rowOffset) => {
|
|
1534
|
+
let cellColIdx = 0;
|
|
1535
|
+
row.forEach((cell, cellOffset) => {
|
|
1536
|
+
const colspan = cell.attrs.colspan || 1;
|
|
1537
|
+
const cellPos = tablePos + 1 + rowOffset + 1 + cellOffset;
|
|
1538
|
+
const cw = new Array(colspan);
|
|
1539
|
+
for (let k = 0; k < colspan; k++) {
|
|
1540
|
+
cw[k] = allColWidths[cellColIdx + k] || 100;
|
|
1541
|
+
}
|
|
1542
|
+
tr.setNodeMarkup(cellPos, null, { ...cell.attrs, colwidth: cw });
|
|
1543
|
+
cellsUpdated++;
|
|
1544
|
+
cellColIdx += colspan;
|
|
1545
|
+
});
|
|
1546
|
+
});
|
|
1547
|
+
view.dispatch(tr);
|
|
1548
|
+
pauseObserver();
|
|
1549
|
+
updateDOMWidths(targetColIdx, lastNw);
|
|
1550
|
+
resumeObserver();
|
|
1551
|
+
}
|
|
1552
|
+
} else {
|
|
1553
|
+
console.warn("[Resize] could not find table position in doc");
|
|
1554
|
+
}
|
|
1555
|
+
} catch (err) {
|
|
1556
|
+
console.warn("[Resize] transaction failed, falling back to DOM:", err);
|
|
1557
|
+
pauseObserver();
|
|
1558
|
+
updateDOMWidths(targetColIdx, lastNw);
|
|
1559
|
+
resumeObserver();
|
|
1560
|
+
}
|
|
1561
|
+
};
|
|
1562
|
+
document.addEventListener("mousemove", onMove);
|
|
1563
|
+
document.addEventListener("mouseup", onUp, true);
|
|
1564
|
+
};
|
|
1565
|
+
function initialWidth(table, colIdx) {
|
|
1566
|
+
const firstRow = table.querySelector("tr");
|
|
1567
|
+
if (!firstRow) return 100;
|
|
1568
|
+
const cell = firstRow.children[colIdx];
|
|
1569
|
+
if (!cell) return 100;
|
|
1570
|
+
return Math.round(cell.getBoundingClientRect().width) || cell.offsetWidth || 100;
|
|
1571
|
+
}
|
|
1572
|
+
let lineEl = null;
|
|
1573
|
+
let isDragging = false;
|
|
1574
|
+
function getOrCreateLine() {
|
|
1575
|
+
if (!lineEl) {
|
|
1576
|
+
lineEl = document.createElement("div");
|
|
1577
|
+
lineEl.className = "docflow-active-border-line";
|
|
1578
|
+
Object.assign(lineEl.style, {
|
|
1579
|
+
position: "fixed",
|
|
1580
|
+
width: "3px",
|
|
1581
|
+
background: "#06b6d4",
|
|
1582
|
+
boxShadow: "0 0 8px rgba(6, 182, 212, 0.9)",
|
|
1583
|
+
pointerEvents: "none",
|
|
1584
|
+
zIndex: "999999",
|
|
1585
|
+
display: "none",
|
|
1586
|
+
borderRadius: "1.5px"
|
|
1587
|
+
});
|
|
1588
|
+
const dotTop = document.createElement("div");
|
|
1589
|
+
Object.assign(dotTop.style, {
|
|
1590
|
+
position: "absolute",
|
|
1591
|
+
top: "-4px",
|
|
1592
|
+
left: "-3.5px",
|
|
1593
|
+
width: "10px",
|
|
1594
|
+
height: "10px",
|
|
1595
|
+
borderRadius: "50%",
|
|
1596
|
+
background: "#ffffff",
|
|
1597
|
+
border: "2px solid #06b6d4"
|
|
1598
|
+
});
|
|
1599
|
+
const dotBottom = document.createElement("div");
|
|
1600
|
+
Object.assign(dotBottom.style, {
|
|
1601
|
+
position: "absolute",
|
|
1602
|
+
bottom: "-4px",
|
|
1603
|
+
left: "-3.5px",
|
|
1604
|
+
width: "10px",
|
|
1605
|
+
height: "10px",
|
|
1606
|
+
borderRadius: "50%",
|
|
1607
|
+
background: "#ffffff",
|
|
1608
|
+
border: "2px solid #06b6d4"
|
|
1609
|
+
});
|
|
1610
|
+
lineEl.appendChild(dotTop);
|
|
1611
|
+
lineEl.appendChild(dotBottom);
|
|
1612
|
+
document.body.appendChild(lineEl);
|
|
1613
|
+
}
|
|
1614
|
+
return lineEl;
|
|
1615
|
+
}
|
|
1616
|
+
function showLine(table, borderX) {
|
|
1617
|
+
const line = getOrCreateLine();
|
|
1618
|
+
const tableRect = table.getBoundingClientRect();
|
|
1619
|
+
line.style.left = `${borderX - 1.5}px`;
|
|
1620
|
+
line.style.top = `${tableRect.top}px`;
|
|
1621
|
+
line.style.height = `${tableRect.height}px`;
|
|
1622
|
+
line.style.display = "block";
|
|
1623
|
+
document.body.style.cursor = "col-resize";
|
|
1624
|
+
view.dom.style.cursor = "col-resize";
|
|
1625
|
+
}
|
|
1626
|
+
function hideLine() {
|
|
1627
|
+
if (lineEl) {
|
|
1628
|
+
lineEl.style.display = "none";
|
|
1629
|
+
}
|
|
1630
|
+
document.body.style.cursor = "";
|
|
1631
|
+
view.dom.style.cursor = "";
|
|
1632
|
+
}
|
|
1633
|
+
const onMouseMoveHover = function(event) {
|
|
1634
|
+
if (isDragging) return;
|
|
1635
|
+
const target = event.target;
|
|
1636
|
+
const td = target.closest("td, th");
|
|
1637
|
+
if (!td) {
|
|
1638
|
+
hideLine();
|
|
1639
|
+
return;
|
|
1640
|
+
}
|
|
1641
|
+
const r = td.getBoundingClientRect();
|
|
1642
|
+
const distRight = Math.abs(event.clientX - r.right);
|
|
1643
|
+
const distLeft = Math.abs(event.clientX - r.left);
|
|
1644
|
+
const parent = td.parentElement;
|
|
1645
|
+
if (!parent) {
|
|
1646
|
+
hideLine();
|
|
1647
|
+
return;
|
|
1648
|
+
}
|
|
1649
|
+
const colIdx = Array.from(parent.children).indexOf(td);
|
|
1650
|
+
let borderX = -1;
|
|
1651
|
+
if (distRight <= 16) {
|
|
1652
|
+
borderX = r.right;
|
|
1653
|
+
} else if (distLeft <= 16 && colIdx > 0) {
|
|
1654
|
+
borderX = r.left;
|
|
1655
|
+
}
|
|
1656
|
+
if (borderX >= 0) {
|
|
1657
|
+
const table = td.closest("table");
|
|
1658
|
+
if (table) {
|
|
1659
|
+
showLine(table, borderX);
|
|
1660
|
+
}
|
|
1661
|
+
} else {
|
|
1662
|
+
hideLine();
|
|
1663
|
+
}
|
|
1664
|
+
};
|
|
1665
|
+
document.addEventListener("mousemove", onMouseMoveHover, true);
|
|
1666
|
+
view.dom.addEventListener("mousedown", function handleMouseDown(event) {
|
|
1667
|
+
onMouseDown(event);
|
|
1668
|
+
const td = event.target.closest("td, th");
|
|
1669
|
+
if (!td) return;
|
|
1670
|
+
const r = td.getBoundingClientRect();
|
|
1671
|
+
const distRight = Math.abs(event.clientX - r.right);
|
|
1672
|
+
const distLeft = Math.abs(event.clientX - r.left);
|
|
1673
|
+
const parent = td.parentElement;
|
|
1674
|
+
if (!parent) return;
|
|
1675
|
+
const colIdx = Array.from(parent.children).indexOf(td);
|
|
1676
|
+
if (distRight <= 16 || distLeft <= 16 && colIdx > 0) {
|
|
1677
|
+
isDragging = true;
|
|
1678
|
+
hideLine();
|
|
1679
|
+
const onDragEnd = function() {
|
|
1680
|
+
isDragging = false;
|
|
1681
|
+
hideLine();
|
|
1682
|
+
document.removeEventListener("mouseup", onDragEnd, true);
|
|
1683
|
+
};
|
|
1684
|
+
document.addEventListener("mouseup", onDragEnd, true);
|
|
1685
|
+
}
|
|
1686
|
+
}, true);
|
|
1687
|
+
return {
|
|
1688
|
+
destroy: function() {
|
|
1689
|
+
document.removeEventListener("mousemove", onMouseMoveHover, true);
|
|
1690
|
+
if (lineEl && lineEl.parentElement) {
|
|
1691
|
+
lineEl.parentElement.removeChild(lineEl);
|
|
1692
|
+
}
|
|
1693
|
+
lineEl = null;
|
|
1694
|
+
hideLine();
|
|
1695
|
+
}
|
|
1696
|
+
};
|
|
1697
|
+
}
|
|
1698
|
+
})];
|
|
1699
|
+
}
|
|
1700
|
+
});
|
|
339
1701
|
let extensions = [
|
|
1702
|
+
ManualColumnResize,
|
|
340
1703
|
baseStarterKit,
|
|
341
1704
|
import_extension_text_style.default,
|
|
342
1705
|
blockAttrs,
|
|
343
1706
|
paginationExt,
|
|
1707
|
+
// Always present — carries host-injected ports (onImageUpload, citation, …)
|
|
1708
|
+
// in storage so plugin commands can reach them through the editor instance.
|
|
1709
|
+
EditorContextExtension.configure({
|
|
1710
|
+
onImageUpload: options.onImageUpload,
|
|
1711
|
+
citation: options.citation,
|
|
1712
|
+
aiStream: options.aiStream,
|
|
1713
|
+
aiDraft: options.aiDraft
|
|
1714
|
+
}),
|
|
1715
|
+
// Always present — find & replace decorations + state (core editing infra).
|
|
1716
|
+
SearchAndReplaceExtension,
|
|
344
1717
|
...pluginExtensions
|
|
345
1718
|
];
|
|
346
1719
|
const content = options.collaboration ? void 0 : options.content;
|
|
347
1720
|
if (options.collaboration && collaborationSetup) {
|
|
348
|
-
const fragment = collaborationSetup.ydoc.getXmlFragment("default");
|
|
349
|
-
if (fragment.length === 0 && options.content && typeof options.content === "object") {
|
|
350
|
-
const schema = (0, import_core2.getSchema)([baseStarterKit, import_extension_text_style.default, blockAttrs, paginationExt, ...pluginExtensions]);
|
|
351
|
-
(0, import_y_prosemirror.prosemirrorJSONToYXmlFragment)(schema, options.content, fragment);
|
|
352
|
-
}
|
|
353
1721
|
extensions = [...extensions, ...collaborationExtensions(collaborationSetup)];
|
|
354
1722
|
}
|
|
355
|
-
return new
|
|
1723
|
+
return new import_core5.Editor({
|
|
356
1724
|
element: options.target,
|
|
357
1725
|
content,
|
|
358
1726
|
extensions,
|
|
359
1727
|
editable: options.editable ?? true,
|
|
360
1728
|
onUpdate: ({ editor }) => {
|
|
361
1729
|
options.onUpdate?.(editor.getJSON());
|
|
1730
|
+
},
|
|
1731
|
+
editorProps: {
|
|
1732
|
+
// Sanitize pasted HTML (strips <meta>, <style>, comments, etc.)
|
|
1733
|
+
// before ProseMirror parsing. Prevents crashes from non-content
|
|
1734
|
+
// tags commonly produced by Google Docs clipboard data.
|
|
1735
|
+
transformPastedHTML: sanitizePastedHTML
|
|
362
1736
|
}
|
|
363
1737
|
});
|
|
364
1738
|
}
|
|
365
1739
|
|
|
366
1740
|
// src/FontSize.ts
|
|
367
|
-
var
|
|
1741
|
+
var import_core6 = require("@tiptap/core");
|
|
368
1742
|
function mergeFontSize(textStyleType, existing, fontSize) {
|
|
369
1743
|
if (fontSize === null) {
|
|
370
1744
|
const { fontSize: _removed, ...rest } = existing?.attrs ?? {};
|
|
@@ -375,7 +1749,7 @@ function mergeFontSize(textStyleType, existing, fontSize) {
|
|
|
375
1749
|
function hasAttrs(mark) {
|
|
376
1750
|
return Object.values(mark.attrs).some((v) => v != null);
|
|
377
1751
|
}
|
|
378
|
-
var FontSizeExtension =
|
|
1752
|
+
var FontSizeExtension = import_core6.Extension.create({
|
|
379
1753
|
name: "fontSize",
|
|
380
1754
|
addGlobalAttributes() {
|
|
381
1755
|
return [
|
|
@@ -473,19 +1847,136 @@ var FontSizeExtension = import_core3.Extension.create({
|
|
|
473
1847
|
}
|
|
474
1848
|
});
|
|
475
1849
|
|
|
476
|
-
// src/
|
|
477
|
-
var
|
|
1850
|
+
// src/SubdocumentProvider.ts
|
|
1851
|
+
var import_awareness2 = require("y-protocols/awareness");
|
|
1852
|
+
var import_y_websocket2 = require("y-websocket");
|
|
1853
|
+
var Y2 = __toESM(require("yjs"), 1);
|
|
1854
|
+
var SubdocumentProvider = class {
|
|
1855
|
+
parentDoc;
|
|
1856
|
+
subdocs;
|
|
1857
|
+
awareness;
|
|
1858
|
+
options;
|
|
1859
|
+
states = /* @__PURE__ */ new Map();
|
|
1860
|
+
activeQueue = [];
|
|
1861
|
+
parentProvider = null;
|
|
1862
|
+
constructor(options) {
|
|
1863
|
+
this.options = {
|
|
1864
|
+
maxActive: options.maxActive ?? 5,
|
|
1865
|
+
onStateChange: options.onStateChange ?? (() => {
|
|
1866
|
+
}),
|
|
1867
|
+
...options
|
|
1868
|
+
};
|
|
1869
|
+
this.parentDoc = new Y2.Doc();
|
|
1870
|
+
this.subdocs = this.parentDoc.getMap("subdocs");
|
|
1871
|
+
this.awareness = new import_awareness2.Awareness(this.parentDoc);
|
|
1872
|
+
this.awareness.setLocalStateField("user", this.options.user);
|
|
1873
|
+
this.parentProvider = new import_y_websocket2.WebsocketProvider(
|
|
1874
|
+
this.options.websocketUrl,
|
|
1875
|
+
`${this.options.roomPrefix}/_parent`,
|
|
1876
|
+
this.parentDoc
|
|
1877
|
+
);
|
|
1878
|
+
}
|
|
1879
|
+
/** Create a new subdocument. Does NOT activate it. */
|
|
1880
|
+
createSubdoc(id, initialState) {
|
|
1881
|
+
if (this.states.has(id)) return this.states.get(id).doc;
|
|
1882
|
+
const doc = new Y2.Doc();
|
|
1883
|
+
if (initialState) Y2.applyUpdate(doc, initialState);
|
|
1884
|
+
doc.getXmlFragment("default");
|
|
1885
|
+
this.subdocs.set(id, doc);
|
|
1886
|
+
this.states.set(id, {
|
|
1887
|
+
id,
|
|
1888
|
+
doc,
|
|
1889
|
+
provider: null,
|
|
1890
|
+
active: false
|
|
1891
|
+
});
|
|
1892
|
+
this.options.onStateChange(this.getAllStates());
|
|
1893
|
+
return doc;
|
|
1894
|
+
}
|
|
1895
|
+
/** Activate a subdocument — connects it to the network for live sync. */
|
|
1896
|
+
activate(id) {
|
|
1897
|
+
const state = this.states.get(id);
|
|
1898
|
+
if (!state || state.active) return;
|
|
1899
|
+
if (this.activeQueue.length >= this.options.maxActive) {
|
|
1900
|
+
const oldest = this.activeQueue.shift();
|
|
1901
|
+
if (oldest) this.deactivate(oldest);
|
|
1902
|
+
}
|
|
1903
|
+
const doc = state.doc;
|
|
1904
|
+
const roomName = `${this.options.roomPrefix}/${id}`;
|
|
1905
|
+
const provider = new import_y_websocket2.WebsocketProvider(
|
|
1906
|
+
this.options.websocketUrl,
|
|
1907
|
+
roomName,
|
|
1908
|
+
doc
|
|
1909
|
+
);
|
|
1910
|
+
provider.awareness.setLocalStateField("user", this.options.user);
|
|
1911
|
+
state.provider = provider;
|
|
1912
|
+
state.active = true;
|
|
1913
|
+
this.activeQueue.push(id);
|
|
1914
|
+
this.options.onStateChange(this.getAllStates());
|
|
1915
|
+
}
|
|
1916
|
+
/** Deactivate a subdocument — disconnects it from the network. */
|
|
1917
|
+
deactivate(id) {
|
|
1918
|
+
const state = this.states.get(id);
|
|
1919
|
+
if (!state || !state.active) return;
|
|
1920
|
+
state.provider?.destroy();
|
|
1921
|
+
state.provider = null;
|
|
1922
|
+
state.active = false;
|
|
1923
|
+
const idx = this.activeQueue.indexOf(id);
|
|
1924
|
+
if (idx >= 0) this.activeQueue.splice(idx, 1);
|
|
1925
|
+
this.options.onStateChange(this.getAllStates());
|
|
1926
|
+
}
|
|
1927
|
+
/** Get the Y.XmlFragment for a subdocument. */
|
|
1928
|
+
getFragment(id) {
|
|
1929
|
+
const doc = this.states.get(id)?.doc ?? this.subdocs.get(id);
|
|
1930
|
+
if (!doc) return null;
|
|
1931
|
+
return doc.getXmlFragment("default");
|
|
1932
|
+
}
|
|
1933
|
+
/** Check if a subdocument is currently active (syncing). */
|
|
1934
|
+
isActive(id) {
|
|
1935
|
+
return this.states.get(id)?.active ?? false;
|
|
1936
|
+
}
|
|
1937
|
+
/** Get all subdocument states. */
|
|
1938
|
+
getAllStates() {
|
|
1939
|
+
return Array.from(this.states.values());
|
|
1940
|
+
}
|
|
1941
|
+
/** Get IDs of all active subdocuments. */
|
|
1942
|
+
getActiveIds() {
|
|
1943
|
+
return [...this.activeQueue];
|
|
1944
|
+
}
|
|
1945
|
+
/** Destroy all subdocuments and providers. */
|
|
1946
|
+
destroy() {
|
|
1947
|
+
for (const [id] of this.states) {
|
|
1948
|
+
this.deactivate(id);
|
|
1949
|
+
}
|
|
1950
|
+
this.parentProvider?.destroy();
|
|
1951
|
+
this.parentDoc.destroy();
|
|
1952
|
+
this.states.clear();
|
|
1953
|
+
this.activeQueue.length = 0;
|
|
1954
|
+
}
|
|
1955
|
+
};
|
|
478
1956
|
// Annotate the CommonJS export names for ESM import in node:
|
|
479
1957
|
0 && (module.exports = {
|
|
480
1958
|
BlockAttributesExtension,
|
|
1959
|
+
EditorContextExtension,
|
|
481
1960
|
FontSizeExtension,
|
|
482
1961
|
PAGE_SIZES,
|
|
483
1962
|
PaginationPlus,
|
|
1963
|
+
SearchAndReplaceExtension,
|
|
1964
|
+
SubdocumentProvider,
|
|
1965
|
+
clearSearch,
|
|
484
1966
|
collaborationExtensions,
|
|
485
1967
|
collectExtensions,
|
|
486
1968
|
createActionMap,
|
|
487
1969
|
createCollaboration,
|
|
488
1970
|
createEditor,
|
|
489
1971
|
definePlugin,
|
|
490
|
-
|
|
1972
|
+
findMatches,
|
|
1973
|
+
getSearchState,
|
|
1974
|
+
replaceAll,
|
|
1975
|
+
replaceCurrent,
|
|
1976
|
+
resolveAction,
|
|
1977
|
+
sanitizePastedHTML,
|
|
1978
|
+
searchAndReplaceKey,
|
|
1979
|
+
searchNext,
|
|
1980
|
+
searchPrev,
|
|
1981
|
+
setSearchQuery
|
|
491
1982
|
});
|