@kedataindo/docflow-core 0.0.90 → 0.0.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +201 -17
- package/dist/index.d.cts +45 -2
- package/dist/index.d.ts +45 -2
- package/dist/index.js +192 -15
- package/package.json +10 -10
package/dist/index.cjs
CHANGED
|
@@ -36,6 +36,11 @@ __export(index_exports, {
|
|
|
36
36
|
EditorContextExtension: () => EditorContextExtension,
|
|
37
37
|
FontFamilyExtension: () => FontFamilyExtension,
|
|
38
38
|
FontSizeExtension: () => FontSizeExtension,
|
|
39
|
+
INDENT_MAX_LEVEL: () => INDENT_MAX_LEVEL,
|
|
40
|
+
INDENT_STEP_PX: () => INDENT_STEP_PX,
|
|
41
|
+
INDENT_STEP_VAR: () => INDENT_STEP_VAR,
|
|
42
|
+
INDENT_STYLE_VAR: () => INDENT_STYLE_VAR,
|
|
43
|
+
IndentExtension: () => IndentExtension,
|
|
39
44
|
LOCAL_STORAGE_KEY: () => LOCAL_STORAGE_KEY,
|
|
40
45
|
PAGE_SIZES: () => PAGE_SIZES,
|
|
41
46
|
PaginationPlus: () => PaginationPlus,
|
|
@@ -43,6 +48,7 @@ __export(index_exports, {
|
|
|
43
48
|
SearchAndReplaceExtension: () => SearchAndReplaceExtension,
|
|
44
49
|
SubdocumentProvider: () => SubdocumentProvider,
|
|
45
50
|
buildAIPrompt: () => buildAIPrompt,
|
|
51
|
+
clampIndentLevel: () => clampIndentLevel,
|
|
46
52
|
claudeProvider: () => claudeProvider,
|
|
47
53
|
clearSearch: () => clearSearch,
|
|
48
54
|
collaborationExtensions: () => collaborationExtensions,
|
|
@@ -56,6 +62,7 @@ __export(index_exports, {
|
|
|
56
62
|
findMatches: () => findMatches,
|
|
57
63
|
getSearchState: () => getSearchState,
|
|
58
64
|
httpKeyStorage: () => httpKeyStorage,
|
|
65
|
+
indentLevelOf: () => indentLevelOf,
|
|
59
66
|
localStorageKeyStorage: () => localStorageKeyStorage,
|
|
60
67
|
memoryKeyStorage: () => memoryKeyStorage,
|
|
61
68
|
normalizeClipboardHTML: () => normalizeClipboardHTML,
|
|
@@ -76,7 +83,7 @@ __export(index_exports, {
|
|
|
76
83
|
module.exports = __toCommonJS(index_exports);
|
|
77
84
|
|
|
78
85
|
// src/Editor.ts
|
|
79
|
-
var
|
|
86
|
+
var import_core7 = require("@tiptap/core");
|
|
80
87
|
var import_starter_kit = __toESM(require("@tiptap/starter-kit"), 1);
|
|
81
88
|
var import_extension_text_style = __toESM(require("@tiptap/extension-text-style"), 1);
|
|
82
89
|
|
|
@@ -347,10 +354,173 @@ var EditorContextExtension = import_core2.Extension.create({
|
|
|
347
354
|
}
|
|
348
355
|
});
|
|
349
356
|
|
|
350
|
-
// src/
|
|
357
|
+
// src/Indent.ts
|
|
351
358
|
var import_core3 = require("@tiptap/core");
|
|
359
|
+
var INDENT_STEP_PX = 48;
|
|
360
|
+
var INDENT_MAX_LEVEL = 8;
|
|
361
|
+
var INDENT_ATTR = "indent";
|
|
362
|
+
var INDENT_DATA_ATTR = "data-indent";
|
|
363
|
+
var INDENTABLE_NODES = ["paragraph", "heading"];
|
|
364
|
+
var LIST_ITEM_NODES = ["listItem", "taskItem"];
|
|
365
|
+
var CODE_BLOCK = "codeBlock";
|
|
366
|
+
var ABSOLUTE_UNIT_PX = {
|
|
367
|
+
px: 1,
|
|
368
|
+
in: 96,
|
|
369
|
+
cm: 96 / 2.54,
|
|
370
|
+
mm: 96 / 25.4,
|
|
371
|
+
pt: 96 / 72,
|
|
372
|
+
pc: 16
|
|
373
|
+
};
|
|
374
|
+
function clampIndentLevel(level) {
|
|
375
|
+
if (!Number.isFinite(level)) return 0;
|
|
376
|
+
return Math.min(Math.max(Math.trunc(level), 0), INDENT_MAX_LEVEL);
|
|
377
|
+
}
|
|
378
|
+
function indentLevelOf(node) {
|
|
379
|
+
return clampIndentLevel(Number(node.attrs[INDENT_ATTR] ?? 0));
|
|
380
|
+
}
|
|
381
|
+
function parseIndentLevel(element) {
|
|
382
|
+
const raw = element.getAttribute(INDENT_DATA_ATTR);
|
|
383
|
+
if (raw !== null) return clampIndentLevel(Number.parseInt(raw, 10));
|
|
384
|
+
const px = marginLeftPx(element);
|
|
385
|
+
return Number.isFinite(px) && px > 0 ? clampIndentLevel(Math.round(px / INDENT_STEP_PX)) : 0;
|
|
386
|
+
}
|
|
387
|
+
function marginLeftPx(element) {
|
|
388
|
+
const raw = element.style?.marginLeft?.trim() ?? "";
|
|
389
|
+
if (!raw) return 0;
|
|
390
|
+
const match = /^(-?\d*\.?\d+)\s*([a-z%]*)$/i.exec(raw);
|
|
391
|
+
if (!match) return 0;
|
|
392
|
+
const value = Number.parseFloat(match[1]);
|
|
393
|
+
const unit = (match[2] || "px").toLowerCase();
|
|
394
|
+
const factor = ABSOLUTE_UNIT_PX[unit];
|
|
395
|
+
return factor === void 0 ? 0 : value * factor;
|
|
396
|
+
}
|
|
397
|
+
var INDENT_STYLE_VAR = "--docflow-indent";
|
|
398
|
+
var INDENT_STEP_VAR = "--docflow-indent-step";
|
|
399
|
+
function renderIndentAttributes(level) {
|
|
400
|
+
return {
|
|
401
|
+
[INDENT_DATA_ATTR]: String(level),
|
|
402
|
+
// Three representations on purpose: the custom properties let the
|
|
403
|
+
// stylesheet out-rank its own `!important` block-margin shorthands (see
|
|
404
|
+
// packages/vue/src/styles/index.css) and keep the step size in one place,
|
|
405
|
+
// while the inline `margin-left` still works for hosts that do not ship
|
|
406
|
+
// that stylesheet.
|
|
407
|
+
style: `${INDENT_STYLE_VAR}: ${level}; ${INDENT_STEP_VAR}: ${INDENT_STEP_PX}px; margin-left: ${level * INDENT_STEP_PX}px`
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
function shiftBlockIndent(props, delta) {
|
|
411
|
+
const { state, tr } = props;
|
|
412
|
+
const { from, to } = state.selection;
|
|
413
|
+
let changed = false;
|
|
414
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
415
|
+
if (!INDENTABLE_NODES.includes(node.type.name)) return;
|
|
416
|
+
const current = indentLevelOf(node);
|
|
417
|
+
const next = clampIndentLevel(current + delta);
|
|
418
|
+
if (next === current) return;
|
|
419
|
+
tr.setNodeMarkup(pos, void 0, { ...node.attrs, [INDENT_ATTR]: next });
|
|
420
|
+
changed = true;
|
|
421
|
+
});
|
|
422
|
+
if (changed) props.dispatch?.();
|
|
423
|
+
return changed;
|
|
424
|
+
}
|
|
425
|
+
function coveredCodeLineStarts(state) {
|
|
426
|
+
const { $from, $to } = state.selection;
|
|
427
|
+
if ($from.parent.type.name !== CODE_BLOCK || !$from.sameParent($to)) return null;
|
|
428
|
+
const text = $from.parent.textContent;
|
|
429
|
+
const first = text.lastIndexOf("\n", Math.max($from.parentOffset - 1, 0)) + 1;
|
|
430
|
+
const breakAt = text.indexOf("\n", $to.parentOffset);
|
|
431
|
+
const end = breakAt === -1 ? text.length : breakAt;
|
|
432
|
+
const starts = [];
|
|
433
|
+
for (let at = first; at <= end; at++) {
|
|
434
|
+
if (at === first || text[at - 1] === "\n") starts.push(at);
|
|
435
|
+
}
|
|
436
|
+
return starts;
|
|
437
|
+
}
|
|
438
|
+
var LEADING_INDENT = /^(?:\t| {1,2})/;
|
|
439
|
+
function shiftCodeBlockIndent(props, delta) {
|
|
440
|
+
const starts = coveredCodeLineStarts(props.state);
|
|
441
|
+
if (!starts) return false;
|
|
442
|
+
if (delta > 0 && props.state.selection.empty) {
|
|
443
|
+
props.tr.insertText(" ");
|
|
444
|
+
props.dispatch?.();
|
|
445
|
+
return true;
|
|
446
|
+
}
|
|
447
|
+
const text = props.state.selection.$from.parent.textContent;
|
|
448
|
+
const blockStart = props.state.selection.$from.start();
|
|
449
|
+
const { tr } = props;
|
|
450
|
+
for (let i = starts.length - 1; i >= 0; i--) {
|
|
451
|
+
const at = blockStart + starts[i];
|
|
452
|
+
if (delta > 0) {
|
|
453
|
+
tr.insertText(" ", at, at);
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
const leading = LEADING_INDENT.exec(text.slice(starts[i]))?.[0];
|
|
457
|
+
if (leading) tr.delete(at, at + leading.length);
|
|
458
|
+
}
|
|
459
|
+
const changed = delta > 0 || tr.docChanged;
|
|
460
|
+
if (changed) props.dispatch?.();
|
|
461
|
+
return changed;
|
|
462
|
+
}
|
|
463
|
+
function runIndent(props, delta) {
|
|
464
|
+
if (props.editor.isActive(CODE_BLOCK)) return shiftCodeBlockIndent(props, delta);
|
|
465
|
+
const listItem = LIST_ITEM_NODES.find((name) => props.editor.isActive(name));
|
|
466
|
+
if (listItem) {
|
|
467
|
+
const nested = delta > 0 ? props.commands.sinkListItem(listItem) : props.commands.liftListItem(listItem);
|
|
468
|
+
if (nested) return true;
|
|
469
|
+
}
|
|
470
|
+
return shiftBlockIndent(props, delta);
|
|
471
|
+
}
|
|
472
|
+
var IndentExtension = import_core3.Extension.create({
|
|
473
|
+
name: "indent",
|
|
474
|
+
priority: 50,
|
|
475
|
+
addGlobalAttributes() {
|
|
476
|
+
return [
|
|
477
|
+
{
|
|
478
|
+
types: [...INDENTABLE_NODES],
|
|
479
|
+
attributes: {
|
|
480
|
+
[INDENT_ATTR]: {
|
|
481
|
+
default: 0,
|
|
482
|
+
parseHTML: parseIndentLevel,
|
|
483
|
+
renderHTML: (attributes) => {
|
|
484
|
+
const level = clampIndentLevel(Number(attributes[INDENT_ATTR] ?? 0));
|
|
485
|
+
return level > 0 ? renderIndentAttributes(level) : {};
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
];
|
|
491
|
+
},
|
|
492
|
+
addCommands() {
|
|
493
|
+
return {
|
|
494
|
+
indent: () => (props) => runIndent(props, 1),
|
|
495
|
+
outdent: () => (props) => runIndent(props, -1),
|
|
496
|
+
setIndent: (level) => ({ state, tr, dispatch }) => {
|
|
497
|
+
const target = clampIndentLevel(level);
|
|
498
|
+
const { from, to } = state.selection;
|
|
499
|
+
let changed = false;
|
|
500
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
501
|
+
if (!INDENTABLE_NODES.includes(node.type.name)) return;
|
|
502
|
+
if (indentLevelOf(node) === target) return;
|
|
503
|
+
tr.setNodeMarkup(pos, void 0, { ...node.attrs, [INDENT_ATTR]: target });
|
|
504
|
+
changed = true;
|
|
505
|
+
});
|
|
506
|
+
if (changed) dispatch?.();
|
|
507
|
+
return changed;
|
|
508
|
+
},
|
|
509
|
+
unsetIndent: () => ({ commands }) => commands.setIndent(0)
|
|
510
|
+
};
|
|
511
|
+
},
|
|
512
|
+
addKeyboardShortcuts() {
|
|
513
|
+
return {
|
|
514
|
+
Tab: () => this.editor.commands.indent(),
|
|
515
|
+
"Shift-Tab": () => this.editor.commands.outdent()
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
// src/ManualColumnResize.ts
|
|
521
|
+
var import_core4 = require("@tiptap/core");
|
|
352
522
|
var import_state2 = require("@tiptap/pm/state");
|
|
353
|
-
var ManualColumnResize =
|
|
523
|
+
var ManualColumnResize = import_core4.Extension.create({
|
|
354
524
|
name: "manualColumnResize",
|
|
355
525
|
addProseMirrorPlugins() {
|
|
356
526
|
const key2 = new import_state2.PluginKey("manualColumnResize");
|
|
@@ -673,7 +843,7 @@ var ManualColumnResize = import_core3.Extension.create({
|
|
|
673
843
|
});
|
|
674
844
|
|
|
675
845
|
// src/SearchAndReplace.ts
|
|
676
|
-
var
|
|
846
|
+
var import_core5 = require("@tiptap/core");
|
|
677
847
|
var import_state3 = require("@tiptap/pm/state");
|
|
678
848
|
var import_view2 = require("@tiptap/pm/view");
|
|
679
849
|
var searchAndReplaceKey = new import_state3.PluginKey("searchAndReplace");
|
|
@@ -733,7 +903,7 @@ var searchPlugin = new import_state3.Plugin({
|
|
|
733
903
|
}
|
|
734
904
|
}
|
|
735
905
|
});
|
|
736
|
-
var SearchAndReplaceExtension =
|
|
906
|
+
var SearchAndReplaceExtension = import_core5.Extension.create({
|
|
737
907
|
name: "searchAndReplace",
|
|
738
908
|
addProseMirrorPlugins() {
|
|
739
909
|
return [searchPlugin];
|
|
@@ -790,13 +960,13 @@ function replaceAll(editor, replacement) {
|
|
|
790
960
|
return s.matches.length;
|
|
791
961
|
}
|
|
792
962
|
|
|
793
|
-
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=
|
|
794
|
-
var
|
|
963
|
+
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=00858351959cd6e40e43520c066de1f40e312b64dcfd6be_7def91d83c4dc7f1a0f936fcac6a737a/node_modules/tiptap-pagination-plus/dist/PaginationPlus.js
|
|
964
|
+
var import_core6 = require("@tiptap/core");
|
|
795
965
|
var import_state4 = require("@tiptap/pm/state");
|
|
796
966
|
var import_transform = require("@tiptap/pm/transform");
|
|
797
967
|
var import_view3 = require("@tiptap/pm/view");
|
|
798
968
|
|
|
799
|
-
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=
|
|
969
|
+
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=00858351959cd6e40e43520c066de1f40e312b64dcfd6be_7def91d83c4dc7f1a0f936fcac6a737a/node_modules/tiptap-pagination-plus/dist/utils.js
|
|
800
970
|
var updateCssVariables = (targetNode, config) => {
|
|
801
971
|
const cssVariables = {
|
|
802
972
|
"rm-page-height": `${config.pageHeight}px`,
|
|
@@ -970,7 +1140,7 @@ var footerClickEvent = (pageNumber, onFooterClick) => {
|
|
|
970
1140
|
};
|
|
971
1141
|
};
|
|
972
1142
|
|
|
973
|
-
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=
|
|
1143
|
+
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=00858351959cd6e40e43520c066de1f40e312b64dcfd6be_7def91d83c4dc7f1a0f936fcac6a737a/node_modules/tiptap-pagination-plus/dist/PaginationPlus.js
|
|
974
1144
|
var page_count_meta_key = "PAGE_COUNT_META_KEY";
|
|
975
1145
|
var key = new import_state4.PluginKey("brDecoration");
|
|
976
1146
|
function buildDecorations(doc) {
|
|
@@ -1074,7 +1244,7 @@ var getPageConfigFromOptions = (_currentOptions) => {
|
|
|
1074
1244
|
};
|
|
1075
1245
|
};
|
|
1076
1246
|
var paginationKey = new import_state4.PluginKey("pagination");
|
|
1077
|
-
var PaginationPlus =
|
|
1247
|
+
var PaginationPlus = import_core6.Extension.create({
|
|
1078
1248
|
name: "PaginationPlus",
|
|
1079
1249
|
addOptions() {
|
|
1080
1250
|
return defaultOptions;
|
|
@@ -1627,7 +1797,7 @@ function createDecoration(pageOptions, headerHeightMap, footerHeightMap) {
|
|
|
1627
1797
|
return [pageWidget, firstHeaderWidget];
|
|
1628
1798
|
}
|
|
1629
1799
|
|
|
1630
|
-
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=
|
|
1800
|
+
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=00858351959cd6e40e43520c066de1f40e312b64dcfd6be_7def91d83c4dc7f1a0f936fcac6a737a/node_modules/tiptap-pagination-plus/dist/constants.js
|
|
1631
1801
|
var A4_PAGE_SIZE = getPageSize(1123, 794, 95, 95, 76, 76);
|
|
1632
1802
|
var A3_PAGE_SIZE = getPageSize(1591, 1123, 95, 95, 76, 76);
|
|
1633
1803
|
var A5_PAGE_SIZE = getPageSize(794, 419, 76, 76, 57, 57);
|
|
@@ -1852,7 +2022,10 @@ var KEEP_ATTRS = {
|
|
|
1852
2022
|
td: /* @__PURE__ */ new Set(["colspan", "rowspan", "style"]),
|
|
1853
2023
|
th: /* @__PURE__ */ new Set(["colspan", "rowspan", "style"]),
|
|
1854
2024
|
col: /* @__PURE__ */ new Set(["span"]),
|
|
1855
|
-
|
|
2025
|
+
// `data-indent` carries the block indent (issue #189). Without it, copying an
|
|
2026
|
+
// indented paragraph inside the editor and pasting it back would silently
|
|
2027
|
+
// lose the level, because normalization runs on every paste.
|
|
2028
|
+
"*": /* @__PURE__ */ new Set(["style", "data-indent"])
|
|
1856
2029
|
};
|
|
1857
2030
|
function detectClipboardSource(html) {
|
|
1858
2031
|
if (/id\s*=\s*["']docs-internal/i.test(html)) return "google-docs";
|
|
@@ -2087,13 +2260,17 @@ function createTiptapEditor(options, plugins, collaborationSetup) {
|
|
|
2087
2260
|
}),
|
|
2088
2261
|
// Always present — find & replace decorations + state (core editing infra).
|
|
2089
2262
|
SearchAndReplaceExtension,
|
|
2263
|
+
// Always present — Tab/Shift-Tab block indent (issue #189). Declares
|
|
2264
|
+
// priority 50 so list nesting, table cell navigation and the AI preview
|
|
2265
|
+
// keep their own Tab bindings.
|
|
2266
|
+
IndentExtension,
|
|
2090
2267
|
...pluginExtensions
|
|
2091
2268
|
];
|
|
2092
2269
|
const content = options.collaboration ? void 0 : options.content;
|
|
2093
2270
|
if (options.collaboration && collaborationSetup) {
|
|
2094
2271
|
extensions = [...extensions, ...collaborationExtensions(collaborationSetup)];
|
|
2095
2272
|
}
|
|
2096
|
-
return new
|
|
2273
|
+
return new import_core7.Editor({
|
|
2097
2274
|
element: options.target,
|
|
2098
2275
|
content,
|
|
2099
2276
|
extensions,
|
|
@@ -2191,7 +2368,7 @@ function sanitizeInlineHTML(html) {
|
|
|
2191
2368
|
}
|
|
2192
2369
|
|
|
2193
2370
|
// src/FontSize.ts
|
|
2194
|
-
var
|
|
2371
|
+
var import_core8 = require("@tiptap/core");
|
|
2195
2372
|
function mergeFontSize(textStyleType, existing, fontSize) {
|
|
2196
2373
|
if (fontSize === null) {
|
|
2197
2374
|
const { fontSize: _removed, ...rest } = existing?.attrs ?? {};
|
|
@@ -2202,7 +2379,7 @@ function mergeFontSize(textStyleType, existing, fontSize) {
|
|
|
2202
2379
|
function hasAttrs(mark) {
|
|
2203
2380
|
return Object.values(mark.attrs).some((v) => v != null);
|
|
2204
2381
|
}
|
|
2205
|
-
var FontSizeExtension =
|
|
2382
|
+
var FontSizeExtension = import_core8.Extension.create({
|
|
2206
2383
|
name: "fontSize",
|
|
2207
2384
|
addGlobalAttributes() {
|
|
2208
2385
|
return [
|
|
@@ -2300,7 +2477,7 @@ var FontSizeExtension = import_core7.Extension.create({
|
|
|
2300
2477
|
});
|
|
2301
2478
|
|
|
2302
2479
|
// src/FontFamily.ts
|
|
2303
|
-
var
|
|
2480
|
+
var import_core9 = require("@tiptap/core");
|
|
2304
2481
|
function mergeFontFamily(textStyleType, existing, fontFamily) {
|
|
2305
2482
|
if (fontFamily === null) {
|
|
2306
2483
|
const { fontFamily: _removed, ...rest } = existing?.attrs ?? {};
|
|
@@ -2311,7 +2488,7 @@ function mergeFontFamily(textStyleType, existing, fontFamily) {
|
|
|
2311
2488
|
function hasAttrs2(mark) {
|
|
2312
2489
|
return Object.values(mark.attrs).some((v) => v != null);
|
|
2313
2490
|
}
|
|
2314
|
-
var FontFamilyExtension =
|
|
2491
|
+
var FontFamilyExtension = import_core9.Extension.create({
|
|
2315
2492
|
name: "fontFamily",
|
|
2316
2493
|
addGlobalAttributes() {
|
|
2317
2494
|
return [
|
|
@@ -2928,6 +3105,11 @@ function claudeProvider(config) {
|
|
|
2928
3105
|
EditorContextExtension,
|
|
2929
3106
|
FontFamilyExtension,
|
|
2930
3107
|
FontSizeExtension,
|
|
3108
|
+
INDENT_MAX_LEVEL,
|
|
3109
|
+
INDENT_STEP_PX,
|
|
3110
|
+
INDENT_STEP_VAR,
|
|
3111
|
+
INDENT_STYLE_VAR,
|
|
3112
|
+
IndentExtension,
|
|
2931
3113
|
LOCAL_STORAGE_KEY,
|
|
2932
3114
|
PAGE_SIZES,
|
|
2933
3115
|
PaginationPlus,
|
|
@@ -2935,6 +3117,7 @@ function claudeProvider(config) {
|
|
|
2935
3117
|
SearchAndReplaceExtension,
|
|
2936
3118
|
SubdocumentProvider,
|
|
2937
3119
|
buildAIPrompt,
|
|
3120
|
+
clampIndentLevel,
|
|
2938
3121
|
claudeProvider,
|
|
2939
3122
|
clearSearch,
|
|
2940
3123
|
collaborationExtensions,
|
|
@@ -2948,6 +3131,7 @@ function claudeProvider(config) {
|
|
|
2948
3131
|
findMatches,
|
|
2949
3132
|
getSearchState,
|
|
2950
3133
|
httpKeyStorage,
|
|
3134
|
+
indentLevelOf,
|
|
2951
3135
|
localStorageKeyStorage,
|
|
2952
3136
|
memoryKeyStorage,
|
|
2953
3137
|
normalizeClipboardHTML,
|
package/dist/index.d.cts
CHANGED
|
@@ -8,8 +8,8 @@ import { I as ImageUploadHandler, C as CitationPort, A as AIStreamFn, a as AIDra
|
|
|
8
8
|
export { b as AIAction, c as AIActionRequest, d as AICompleteRequest, e as AIConfig, f as AIDraftCitation, g as AIDraftEvent, h as AIProvider, i as AIProviderFactory, j as Auth, k as CONTEXT_CHAR_CAP, l as ClaudeConfig, m as CslDate, n as CslItemData, o as CslName, H as HttpKeyStorageUrls, p as ImageUploadResult, K as KeyStorage, L as LOCAL_STORAGE_KEY, O as OpenAICompatibleConfig, S as StreamEvent, q as buildAIPrompt, r as claudeProvider, s as httpKeyStorage, t as localStorageKeyStorage, u as memoryKeyStorage, v as openaiCompatibleProvider, w as toAIStreamFn, x as trimContextAfter, y as trimContextBefore } from './index-DtcV-JK5.cjs';
|
|
9
9
|
import { PaginationPlusOptions } from 'tiptap-pagination-plus';
|
|
10
10
|
export { PAGE_SIZES, PageSize, PaginationPlus, PaginationPlusOptions } from 'tiptap-pagination-plus';
|
|
11
|
-
import { PluginKey } from '@tiptap/pm/state';
|
|
12
11
|
import { Node } from '@tiptap/pm/model';
|
|
12
|
+
import { PluginKey } from '@tiptap/pm/state';
|
|
13
13
|
|
|
14
14
|
interface ToolbarItem {
|
|
15
15
|
id: string;
|
|
@@ -260,6 +260,49 @@ interface BlockAttributesOptions {
|
|
|
260
260
|
}
|
|
261
261
|
declare const BlockAttributesExtension: Extension<BlockAttributesOptions, any>;
|
|
262
262
|
|
|
263
|
+
declare module '@tiptap/core' {
|
|
264
|
+
interface Commands<ReturnType> {
|
|
265
|
+
indent: {
|
|
266
|
+
/** Shift the block(s) in the selection one level right (Tab). */
|
|
267
|
+
indent: () => ReturnType;
|
|
268
|
+
/** Shift the block(s) in the selection one level left (Shift-Tab). */
|
|
269
|
+
outdent: () => ReturnType;
|
|
270
|
+
/** Set an absolute block-indent level (clamped to INDENT_MAX_LEVEL). */
|
|
271
|
+
setIndent: (level: number) => ReturnType;
|
|
272
|
+
/** Reset the block indent of every block in the selection. */
|
|
273
|
+
unsetIndent: () => ReturnType;
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/** One indent step — half an inch, matching Google Docs (48px at 96dpi). */
|
|
278
|
+
declare const INDENT_STEP_PX = 48;
|
|
279
|
+
/** Deepest block indent the commands accept (8 × 48px = 384px). */
|
|
280
|
+
declare const INDENT_MAX_LEVEL = 8;
|
|
281
|
+
/** Clamp any input to a valid indent level (0 … INDENT_MAX_LEVEL). */
|
|
282
|
+
declare function clampIndentLevel(level: number): number;
|
|
283
|
+
/** Indent level stored on a block node (`0` when the attribute is absent). */
|
|
284
|
+
declare function indentLevelOf(node: Node): number;
|
|
285
|
+
/** Custom property the editor stylesheet turns into `margin-left`. */
|
|
286
|
+
declare const INDENT_STYLE_VAR = "--docflow-indent";
|
|
287
|
+
/** Custom property carrying the step size, so the stylesheet has no 48px copy. */
|
|
288
|
+
declare const INDENT_STEP_VAR = "--docflow-indent-step";
|
|
289
|
+
/**
|
|
290
|
+
* IndentExtension — keyboard block indentation for the docs editor.
|
|
291
|
+
*
|
|
292
|
+
* Issue #189: Tab used to leave the editor because nothing bound it. The
|
|
293
|
+
* extension stores the level as a node attribute on paragraphs/headings,
|
|
294
|
+
* renders it as `data-indent` + `margin-left`, and exposes
|
|
295
|
+
* `indent` / `outdent` / `setIndent` / `unsetIndent` so the toolbar menu can
|
|
296
|
+
* offer the same commands as the keyboard.
|
|
297
|
+
*
|
|
298
|
+
* Priority is deliberately BELOW the 100 default: Tab is already claimed by
|
|
299
|
+
* richer contexts (`@tiptap/extension-list-item` nesting, table cell
|
|
300
|
+
* navigation, the AI suggestion preview) and those must keep precedence. This
|
|
301
|
+
* extension only runs once they have declined the key — paragraphs/headings,
|
|
302
|
+
* and the first item of a list that cannot nest any deeper.
|
|
303
|
+
*/
|
|
304
|
+
declare const IndentExtension: Extension<any, any>;
|
|
305
|
+
|
|
263
306
|
declare module '@tiptap/core' {
|
|
264
307
|
interface Commands<ReturnType> {
|
|
265
308
|
fontSize: {
|
|
@@ -434,4 +477,4 @@ declare class SubdocumentProvider {
|
|
|
434
477
|
destroy(): void;
|
|
435
478
|
}
|
|
436
479
|
|
|
437
|
-
export { AIDraftFn, AIStreamFn, type AwarenessState, BlockAttributesExtension, CitationPort, type ClipboardSource, type CollaborationOptions, type CollaborationSetup, DOCUMENT_MODES, type DocsEditor, type DocsEditorPlugin, type DocumentMode, EditorContextExtension, type EditorContextOptions, type EditorOptions, FontFamilyExtension, FontSizeExtension, ImageUploadHandler, type MonitorMetric, PerformanceMonitor, type PerformanceMonitorOptions, SearchAndReplaceExtension, type SearchMatch, type SearchState, type SlashCommand, type SubdocState, SubdocumentProvider, type SubdocumentProviderOptions, type ToolbarItem, clearSearch, collaborationExtensions, collectExtensions, createActionMap, createCollaboration, createEditor, createPerformanceMonitor, definePlugin, detectClipboardSource, findMatches, getSearchState, normalizeClipboardHTML, replaceAll, replaceCurrent, resolveAction, sanitizeInlineHTML, sanitizePastedHTML, searchAndReplaceKey, searchNext, searchPrev, setSearchQuery };
|
|
480
|
+
export { AIDraftFn, AIStreamFn, type AwarenessState, BlockAttributesExtension, CitationPort, type ClipboardSource, type CollaborationOptions, type CollaborationSetup, DOCUMENT_MODES, type DocsEditor, type DocsEditorPlugin, type DocumentMode, EditorContextExtension, type EditorContextOptions, type EditorOptions, FontFamilyExtension, FontSizeExtension, INDENT_MAX_LEVEL, INDENT_STEP_PX, INDENT_STEP_VAR, INDENT_STYLE_VAR, ImageUploadHandler, IndentExtension, type MonitorMetric, PerformanceMonitor, type PerformanceMonitorOptions, SearchAndReplaceExtension, type SearchMatch, type SearchState, type SlashCommand, type SubdocState, SubdocumentProvider, type SubdocumentProviderOptions, type ToolbarItem, clampIndentLevel, clearSearch, collaborationExtensions, collectExtensions, createActionMap, createCollaboration, createEditor, createPerformanceMonitor, definePlugin, detectClipboardSource, findMatches, getSearchState, indentLevelOf, normalizeClipboardHTML, replaceAll, replaceCurrent, resolveAction, sanitizeInlineHTML, sanitizePastedHTML, searchAndReplaceKey, searchNext, searchPrev, setSearchQuery };
|
package/dist/index.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ import { I as ImageUploadHandler, C as CitationPort, A as AIStreamFn, a as AIDra
|
|
|
8
8
|
export { b as AIAction, c as AIActionRequest, d as AICompleteRequest, e as AIConfig, f as AIDraftCitation, g as AIDraftEvent, h as AIProvider, i as AIProviderFactory, j as Auth, k as CONTEXT_CHAR_CAP, l as ClaudeConfig, m as CslDate, n as CslItemData, o as CslName, H as HttpKeyStorageUrls, p as ImageUploadResult, K as KeyStorage, L as LOCAL_STORAGE_KEY, O as OpenAICompatibleConfig, S as StreamEvent, q as buildAIPrompt, r as claudeProvider, s as httpKeyStorage, t as localStorageKeyStorage, u as memoryKeyStorage, v as openaiCompatibleProvider, w as toAIStreamFn, x as trimContextAfter, y as trimContextBefore } from './index-DtcV-JK5.js';
|
|
9
9
|
import { PaginationPlusOptions } from 'tiptap-pagination-plus';
|
|
10
10
|
export { PAGE_SIZES, PageSize, PaginationPlus, PaginationPlusOptions } from 'tiptap-pagination-plus';
|
|
11
|
-
import { PluginKey } from '@tiptap/pm/state';
|
|
12
11
|
import { Node } from '@tiptap/pm/model';
|
|
12
|
+
import { PluginKey } from '@tiptap/pm/state';
|
|
13
13
|
|
|
14
14
|
interface ToolbarItem {
|
|
15
15
|
id: string;
|
|
@@ -260,6 +260,49 @@ interface BlockAttributesOptions {
|
|
|
260
260
|
}
|
|
261
261
|
declare const BlockAttributesExtension: Extension<BlockAttributesOptions, any>;
|
|
262
262
|
|
|
263
|
+
declare module '@tiptap/core' {
|
|
264
|
+
interface Commands<ReturnType> {
|
|
265
|
+
indent: {
|
|
266
|
+
/** Shift the block(s) in the selection one level right (Tab). */
|
|
267
|
+
indent: () => ReturnType;
|
|
268
|
+
/** Shift the block(s) in the selection one level left (Shift-Tab). */
|
|
269
|
+
outdent: () => ReturnType;
|
|
270
|
+
/** Set an absolute block-indent level (clamped to INDENT_MAX_LEVEL). */
|
|
271
|
+
setIndent: (level: number) => ReturnType;
|
|
272
|
+
/** Reset the block indent of every block in the selection. */
|
|
273
|
+
unsetIndent: () => ReturnType;
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/** One indent step — half an inch, matching Google Docs (48px at 96dpi). */
|
|
278
|
+
declare const INDENT_STEP_PX = 48;
|
|
279
|
+
/** Deepest block indent the commands accept (8 × 48px = 384px). */
|
|
280
|
+
declare const INDENT_MAX_LEVEL = 8;
|
|
281
|
+
/** Clamp any input to a valid indent level (0 … INDENT_MAX_LEVEL). */
|
|
282
|
+
declare function clampIndentLevel(level: number): number;
|
|
283
|
+
/** Indent level stored on a block node (`0` when the attribute is absent). */
|
|
284
|
+
declare function indentLevelOf(node: Node): number;
|
|
285
|
+
/** Custom property the editor stylesheet turns into `margin-left`. */
|
|
286
|
+
declare const INDENT_STYLE_VAR = "--docflow-indent";
|
|
287
|
+
/** Custom property carrying the step size, so the stylesheet has no 48px copy. */
|
|
288
|
+
declare const INDENT_STEP_VAR = "--docflow-indent-step";
|
|
289
|
+
/**
|
|
290
|
+
* IndentExtension — keyboard block indentation for the docs editor.
|
|
291
|
+
*
|
|
292
|
+
* Issue #189: Tab used to leave the editor because nothing bound it. The
|
|
293
|
+
* extension stores the level as a node attribute on paragraphs/headings,
|
|
294
|
+
* renders it as `data-indent` + `margin-left`, and exposes
|
|
295
|
+
* `indent` / `outdent` / `setIndent` / `unsetIndent` so the toolbar menu can
|
|
296
|
+
* offer the same commands as the keyboard.
|
|
297
|
+
*
|
|
298
|
+
* Priority is deliberately BELOW the 100 default: Tab is already claimed by
|
|
299
|
+
* richer contexts (`@tiptap/extension-list-item` nesting, table cell
|
|
300
|
+
* navigation, the AI suggestion preview) and those must keep precedence. This
|
|
301
|
+
* extension only runs once they have declined the key — paragraphs/headings,
|
|
302
|
+
* and the first item of a list that cannot nest any deeper.
|
|
303
|
+
*/
|
|
304
|
+
declare const IndentExtension: Extension<any, any>;
|
|
305
|
+
|
|
263
306
|
declare module '@tiptap/core' {
|
|
264
307
|
interface Commands<ReturnType> {
|
|
265
308
|
fontSize: {
|
|
@@ -434,4 +477,4 @@ declare class SubdocumentProvider {
|
|
|
434
477
|
destroy(): void;
|
|
435
478
|
}
|
|
436
479
|
|
|
437
|
-
export { AIDraftFn, AIStreamFn, type AwarenessState, BlockAttributesExtension, CitationPort, type ClipboardSource, type CollaborationOptions, type CollaborationSetup, DOCUMENT_MODES, type DocsEditor, type DocsEditorPlugin, type DocumentMode, EditorContextExtension, type EditorContextOptions, type EditorOptions, FontFamilyExtension, FontSizeExtension, ImageUploadHandler, type MonitorMetric, PerformanceMonitor, type PerformanceMonitorOptions, SearchAndReplaceExtension, type SearchMatch, type SearchState, type SlashCommand, type SubdocState, SubdocumentProvider, type SubdocumentProviderOptions, type ToolbarItem, clearSearch, collaborationExtensions, collectExtensions, createActionMap, createCollaboration, createEditor, createPerformanceMonitor, definePlugin, detectClipboardSource, findMatches, getSearchState, normalizeClipboardHTML, replaceAll, replaceCurrent, resolveAction, sanitizeInlineHTML, sanitizePastedHTML, searchAndReplaceKey, searchNext, searchPrev, setSearchQuery };
|
|
480
|
+
export { AIDraftFn, AIStreamFn, type AwarenessState, BlockAttributesExtension, CitationPort, type ClipboardSource, type CollaborationOptions, type CollaborationSetup, DOCUMENT_MODES, type DocsEditor, type DocsEditorPlugin, type DocumentMode, EditorContextExtension, type EditorContextOptions, type EditorOptions, FontFamilyExtension, FontSizeExtension, INDENT_MAX_LEVEL, INDENT_STEP_PX, INDENT_STEP_VAR, INDENT_STYLE_VAR, ImageUploadHandler, IndentExtension, type MonitorMetric, PerformanceMonitor, type PerformanceMonitorOptions, SearchAndReplaceExtension, type SearchMatch, type SearchState, type SlashCommand, type SubdocState, SubdocumentProvider, type SubdocumentProviderOptions, type ToolbarItem, clampIndentLevel, clearSearch, collaborationExtensions, collectExtensions, createActionMap, createCollaboration, createEditor, createPerformanceMonitor, definePlugin, detectClipboardSource, findMatches, getSearchState, indentLevelOf, normalizeClipboardHTML, replaceAll, replaceCurrent, resolveAction, sanitizeInlineHTML, sanitizePastedHTML, searchAndReplaceKey, searchNext, searchPrev, setSearchQuery };
|
package/dist/index.js
CHANGED
|
@@ -284,10 +284,173 @@ var EditorContextExtension = Extension2.create({
|
|
|
284
284
|
}
|
|
285
285
|
});
|
|
286
286
|
|
|
287
|
-
// src/
|
|
287
|
+
// src/Indent.ts
|
|
288
288
|
import { Extension as Extension3 } from "@tiptap/core";
|
|
289
|
+
var INDENT_STEP_PX = 48;
|
|
290
|
+
var INDENT_MAX_LEVEL = 8;
|
|
291
|
+
var INDENT_ATTR = "indent";
|
|
292
|
+
var INDENT_DATA_ATTR = "data-indent";
|
|
293
|
+
var INDENTABLE_NODES = ["paragraph", "heading"];
|
|
294
|
+
var LIST_ITEM_NODES = ["listItem", "taskItem"];
|
|
295
|
+
var CODE_BLOCK = "codeBlock";
|
|
296
|
+
var ABSOLUTE_UNIT_PX = {
|
|
297
|
+
px: 1,
|
|
298
|
+
in: 96,
|
|
299
|
+
cm: 96 / 2.54,
|
|
300
|
+
mm: 96 / 25.4,
|
|
301
|
+
pt: 96 / 72,
|
|
302
|
+
pc: 16
|
|
303
|
+
};
|
|
304
|
+
function clampIndentLevel(level) {
|
|
305
|
+
if (!Number.isFinite(level)) return 0;
|
|
306
|
+
return Math.min(Math.max(Math.trunc(level), 0), INDENT_MAX_LEVEL);
|
|
307
|
+
}
|
|
308
|
+
function indentLevelOf(node) {
|
|
309
|
+
return clampIndentLevel(Number(node.attrs[INDENT_ATTR] ?? 0));
|
|
310
|
+
}
|
|
311
|
+
function parseIndentLevel(element) {
|
|
312
|
+
const raw = element.getAttribute(INDENT_DATA_ATTR);
|
|
313
|
+
if (raw !== null) return clampIndentLevel(Number.parseInt(raw, 10));
|
|
314
|
+
const px = marginLeftPx(element);
|
|
315
|
+
return Number.isFinite(px) && px > 0 ? clampIndentLevel(Math.round(px / INDENT_STEP_PX)) : 0;
|
|
316
|
+
}
|
|
317
|
+
function marginLeftPx(element) {
|
|
318
|
+
const raw = element.style?.marginLeft?.trim() ?? "";
|
|
319
|
+
if (!raw) return 0;
|
|
320
|
+
const match = /^(-?\d*\.?\d+)\s*([a-z%]*)$/i.exec(raw);
|
|
321
|
+
if (!match) return 0;
|
|
322
|
+
const value = Number.parseFloat(match[1]);
|
|
323
|
+
const unit = (match[2] || "px").toLowerCase();
|
|
324
|
+
const factor = ABSOLUTE_UNIT_PX[unit];
|
|
325
|
+
return factor === void 0 ? 0 : value * factor;
|
|
326
|
+
}
|
|
327
|
+
var INDENT_STYLE_VAR = "--docflow-indent";
|
|
328
|
+
var INDENT_STEP_VAR = "--docflow-indent-step";
|
|
329
|
+
function renderIndentAttributes(level) {
|
|
330
|
+
return {
|
|
331
|
+
[INDENT_DATA_ATTR]: String(level),
|
|
332
|
+
// Three representations on purpose: the custom properties let the
|
|
333
|
+
// stylesheet out-rank its own `!important` block-margin shorthands (see
|
|
334
|
+
// packages/vue/src/styles/index.css) and keep the step size in one place,
|
|
335
|
+
// while the inline `margin-left` still works for hosts that do not ship
|
|
336
|
+
// that stylesheet.
|
|
337
|
+
style: `${INDENT_STYLE_VAR}: ${level}; ${INDENT_STEP_VAR}: ${INDENT_STEP_PX}px; margin-left: ${level * INDENT_STEP_PX}px`
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function shiftBlockIndent(props, delta) {
|
|
341
|
+
const { state, tr } = props;
|
|
342
|
+
const { from, to } = state.selection;
|
|
343
|
+
let changed = false;
|
|
344
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
345
|
+
if (!INDENTABLE_NODES.includes(node.type.name)) return;
|
|
346
|
+
const current = indentLevelOf(node);
|
|
347
|
+
const next = clampIndentLevel(current + delta);
|
|
348
|
+
if (next === current) return;
|
|
349
|
+
tr.setNodeMarkup(pos, void 0, { ...node.attrs, [INDENT_ATTR]: next });
|
|
350
|
+
changed = true;
|
|
351
|
+
});
|
|
352
|
+
if (changed) props.dispatch?.();
|
|
353
|
+
return changed;
|
|
354
|
+
}
|
|
355
|
+
function coveredCodeLineStarts(state) {
|
|
356
|
+
const { $from, $to } = state.selection;
|
|
357
|
+
if ($from.parent.type.name !== CODE_BLOCK || !$from.sameParent($to)) return null;
|
|
358
|
+
const text = $from.parent.textContent;
|
|
359
|
+
const first = text.lastIndexOf("\n", Math.max($from.parentOffset - 1, 0)) + 1;
|
|
360
|
+
const breakAt = text.indexOf("\n", $to.parentOffset);
|
|
361
|
+
const end = breakAt === -1 ? text.length : breakAt;
|
|
362
|
+
const starts = [];
|
|
363
|
+
for (let at = first; at <= end; at++) {
|
|
364
|
+
if (at === first || text[at - 1] === "\n") starts.push(at);
|
|
365
|
+
}
|
|
366
|
+
return starts;
|
|
367
|
+
}
|
|
368
|
+
var LEADING_INDENT = /^(?:\t| {1,2})/;
|
|
369
|
+
function shiftCodeBlockIndent(props, delta) {
|
|
370
|
+
const starts = coveredCodeLineStarts(props.state);
|
|
371
|
+
if (!starts) return false;
|
|
372
|
+
if (delta > 0 && props.state.selection.empty) {
|
|
373
|
+
props.tr.insertText(" ");
|
|
374
|
+
props.dispatch?.();
|
|
375
|
+
return true;
|
|
376
|
+
}
|
|
377
|
+
const text = props.state.selection.$from.parent.textContent;
|
|
378
|
+
const blockStart = props.state.selection.$from.start();
|
|
379
|
+
const { tr } = props;
|
|
380
|
+
for (let i = starts.length - 1; i >= 0; i--) {
|
|
381
|
+
const at = blockStart + starts[i];
|
|
382
|
+
if (delta > 0) {
|
|
383
|
+
tr.insertText(" ", at, at);
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
const leading = LEADING_INDENT.exec(text.slice(starts[i]))?.[0];
|
|
387
|
+
if (leading) tr.delete(at, at + leading.length);
|
|
388
|
+
}
|
|
389
|
+
const changed = delta > 0 || tr.docChanged;
|
|
390
|
+
if (changed) props.dispatch?.();
|
|
391
|
+
return changed;
|
|
392
|
+
}
|
|
393
|
+
function runIndent(props, delta) {
|
|
394
|
+
if (props.editor.isActive(CODE_BLOCK)) return shiftCodeBlockIndent(props, delta);
|
|
395
|
+
const listItem = LIST_ITEM_NODES.find((name) => props.editor.isActive(name));
|
|
396
|
+
if (listItem) {
|
|
397
|
+
const nested = delta > 0 ? props.commands.sinkListItem(listItem) : props.commands.liftListItem(listItem);
|
|
398
|
+
if (nested) return true;
|
|
399
|
+
}
|
|
400
|
+
return shiftBlockIndent(props, delta);
|
|
401
|
+
}
|
|
402
|
+
var IndentExtension = Extension3.create({
|
|
403
|
+
name: "indent",
|
|
404
|
+
priority: 50,
|
|
405
|
+
addGlobalAttributes() {
|
|
406
|
+
return [
|
|
407
|
+
{
|
|
408
|
+
types: [...INDENTABLE_NODES],
|
|
409
|
+
attributes: {
|
|
410
|
+
[INDENT_ATTR]: {
|
|
411
|
+
default: 0,
|
|
412
|
+
parseHTML: parseIndentLevel,
|
|
413
|
+
renderHTML: (attributes) => {
|
|
414
|
+
const level = clampIndentLevel(Number(attributes[INDENT_ATTR] ?? 0));
|
|
415
|
+
return level > 0 ? renderIndentAttributes(level) : {};
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
];
|
|
421
|
+
},
|
|
422
|
+
addCommands() {
|
|
423
|
+
return {
|
|
424
|
+
indent: () => (props) => runIndent(props, 1),
|
|
425
|
+
outdent: () => (props) => runIndent(props, -1),
|
|
426
|
+
setIndent: (level) => ({ state, tr, dispatch }) => {
|
|
427
|
+
const target = clampIndentLevel(level);
|
|
428
|
+
const { from, to } = state.selection;
|
|
429
|
+
let changed = false;
|
|
430
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
431
|
+
if (!INDENTABLE_NODES.includes(node.type.name)) return;
|
|
432
|
+
if (indentLevelOf(node) === target) return;
|
|
433
|
+
tr.setNodeMarkup(pos, void 0, { ...node.attrs, [INDENT_ATTR]: target });
|
|
434
|
+
changed = true;
|
|
435
|
+
});
|
|
436
|
+
if (changed) dispatch?.();
|
|
437
|
+
return changed;
|
|
438
|
+
},
|
|
439
|
+
unsetIndent: () => ({ commands }) => commands.setIndent(0)
|
|
440
|
+
};
|
|
441
|
+
},
|
|
442
|
+
addKeyboardShortcuts() {
|
|
443
|
+
return {
|
|
444
|
+
Tab: () => this.editor.commands.indent(),
|
|
445
|
+
"Shift-Tab": () => this.editor.commands.outdent()
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
// src/ManualColumnResize.ts
|
|
451
|
+
import { Extension as Extension4 } from "@tiptap/core";
|
|
289
452
|
import { Plugin as Plugin2, PluginKey as PluginKey2 } from "@tiptap/pm/state";
|
|
290
|
-
var ManualColumnResize =
|
|
453
|
+
var ManualColumnResize = Extension4.create({
|
|
291
454
|
name: "manualColumnResize",
|
|
292
455
|
addProseMirrorPlugins() {
|
|
293
456
|
const key2 = new PluginKey2("manualColumnResize");
|
|
@@ -610,7 +773,7 @@ var ManualColumnResize = Extension3.create({
|
|
|
610
773
|
});
|
|
611
774
|
|
|
612
775
|
// src/SearchAndReplace.ts
|
|
613
|
-
import { Extension as
|
|
776
|
+
import { Extension as Extension5 } from "@tiptap/core";
|
|
614
777
|
import { Plugin as Plugin3, PluginKey as PluginKey3, TextSelection } from "@tiptap/pm/state";
|
|
615
778
|
import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "@tiptap/pm/view";
|
|
616
779
|
var searchAndReplaceKey = new PluginKey3("searchAndReplace");
|
|
@@ -670,7 +833,7 @@ var searchPlugin = new Plugin3({
|
|
|
670
833
|
}
|
|
671
834
|
}
|
|
672
835
|
});
|
|
673
|
-
var SearchAndReplaceExtension =
|
|
836
|
+
var SearchAndReplaceExtension = Extension5.create({
|
|
674
837
|
name: "searchAndReplace",
|
|
675
838
|
addProseMirrorPlugins() {
|
|
676
839
|
return [searchPlugin];
|
|
@@ -727,13 +890,13 @@ function replaceAll(editor, replacement) {
|
|
|
727
890
|
return s.matches.length;
|
|
728
891
|
}
|
|
729
892
|
|
|
730
|
-
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=
|
|
731
|
-
import { Extension as
|
|
893
|
+
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=00858351959cd6e40e43520c066de1f40e312b64dcfd6be_7def91d83c4dc7f1a0f936fcac6a737a/node_modules/tiptap-pagination-plus/dist/PaginationPlus.js
|
|
894
|
+
import { Extension as Extension6 } from "@tiptap/core";
|
|
732
895
|
import { Plugin as Plugin4, PluginKey as PluginKey4 } from "@tiptap/pm/state";
|
|
733
896
|
import { ReplaceStep, ReplaceAroundStep, AddMarkStep, RemoveMarkStep, RemoveNodeMarkStep, AttrStep } from "@tiptap/pm/transform";
|
|
734
897
|
import { Decoration as Decoration3, DecorationSet as DecorationSet3 } from "@tiptap/pm/view";
|
|
735
898
|
|
|
736
|
-
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=
|
|
899
|
+
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=00858351959cd6e40e43520c066de1f40e312b64dcfd6be_7def91d83c4dc7f1a0f936fcac6a737a/node_modules/tiptap-pagination-plus/dist/utils.js
|
|
737
900
|
var updateCssVariables = (targetNode, config) => {
|
|
738
901
|
const cssVariables = {
|
|
739
902
|
"rm-page-height": `${config.pageHeight}px`,
|
|
@@ -907,7 +1070,7 @@ var footerClickEvent = (pageNumber, onFooterClick) => {
|
|
|
907
1070
|
};
|
|
908
1071
|
};
|
|
909
1072
|
|
|
910
|
-
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=
|
|
1073
|
+
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=00858351959cd6e40e43520c066de1f40e312b64dcfd6be_7def91d83c4dc7f1a0f936fcac6a737a/node_modules/tiptap-pagination-plus/dist/PaginationPlus.js
|
|
911
1074
|
var page_count_meta_key = "PAGE_COUNT_META_KEY";
|
|
912
1075
|
var key = new PluginKey4("brDecoration");
|
|
913
1076
|
function buildDecorations(doc) {
|
|
@@ -1011,7 +1174,7 @@ var getPageConfigFromOptions = (_currentOptions) => {
|
|
|
1011
1174
|
};
|
|
1012
1175
|
};
|
|
1013
1176
|
var paginationKey = new PluginKey4("pagination");
|
|
1014
|
-
var PaginationPlus =
|
|
1177
|
+
var PaginationPlus = Extension6.create({
|
|
1015
1178
|
name: "PaginationPlus",
|
|
1016
1179
|
addOptions() {
|
|
1017
1180
|
return defaultOptions;
|
|
@@ -1564,7 +1727,7 @@ function createDecoration(pageOptions, headerHeightMap, footerHeightMap) {
|
|
|
1564
1727
|
return [pageWidget, firstHeaderWidget];
|
|
1565
1728
|
}
|
|
1566
1729
|
|
|
1567
|
-
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=
|
|
1730
|
+
// ../../node_modules/.pnpm/tiptap-pagination-plus@3.1.0_patch_hash=00858351959cd6e40e43520c066de1f40e312b64dcfd6be_7def91d83c4dc7f1a0f936fcac6a737a/node_modules/tiptap-pagination-plus/dist/constants.js
|
|
1568
1731
|
var A4_PAGE_SIZE = getPageSize(1123, 794, 95, 95, 76, 76);
|
|
1569
1732
|
var A3_PAGE_SIZE = getPageSize(1591, 1123, 95, 95, 76, 76);
|
|
1570
1733
|
var A5_PAGE_SIZE = getPageSize(794, 419, 76, 76, 57, 57);
|
|
@@ -1789,7 +1952,10 @@ var KEEP_ATTRS = {
|
|
|
1789
1952
|
td: /* @__PURE__ */ new Set(["colspan", "rowspan", "style"]),
|
|
1790
1953
|
th: /* @__PURE__ */ new Set(["colspan", "rowspan", "style"]),
|
|
1791
1954
|
col: /* @__PURE__ */ new Set(["span"]),
|
|
1792
|
-
|
|
1955
|
+
// `data-indent` carries the block indent (issue #189). Without it, copying an
|
|
1956
|
+
// indented paragraph inside the editor and pasting it back would silently
|
|
1957
|
+
// lose the level, because normalization runs on every paste.
|
|
1958
|
+
"*": /* @__PURE__ */ new Set(["style", "data-indent"])
|
|
1793
1959
|
};
|
|
1794
1960
|
function detectClipboardSource(html) {
|
|
1795
1961
|
if (/id\s*=\s*["']docs-internal/i.test(html)) return "google-docs";
|
|
@@ -2024,6 +2190,10 @@ function createTiptapEditor(options, plugins, collaborationSetup) {
|
|
|
2024
2190
|
}),
|
|
2025
2191
|
// Always present — find & replace decorations + state (core editing infra).
|
|
2026
2192
|
SearchAndReplaceExtension,
|
|
2193
|
+
// Always present — Tab/Shift-Tab block indent (issue #189). Declares
|
|
2194
|
+
// priority 50 so list nesting, table cell navigation and the AI preview
|
|
2195
|
+
// keep their own Tab bindings.
|
|
2196
|
+
IndentExtension,
|
|
2027
2197
|
...pluginExtensions
|
|
2028
2198
|
];
|
|
2029
2199
|
const content = options.collaboration ? void 0 : options.content;
|
|
@@ -2128,7 +2298,7 @@ function sanitizeInlineHTML(html) {
|
|
|
2128
2298
|
}
|
|
2129
2299
|
|
|
2130
2300
|
// src/FontSize.ts
|
|
2131
|
-
import { Extension as
|
|
2301
|
+
import { Extension as Extension7 } from "@tiptap/core";
|
|
2132
2302
|
function mergeFontSize(textStyleType, existing, fontSize) {
|
|
2133
2303
|
if (fontSize === null) {
|
|
2134
2304
|
const { fontSize: _removed, ...rest } = existing?.attrs ?? {};
|
|
@@ -2139,7 +2309,7 @@ function mergeFontSize(textStyleType, existing, fontSize) {
|
|
|
2139
2309
|
function hasAttrs(mark) {
|
|
2140
2310
|
return Object.values(mark.attrs).some((v) => v != null);
|
|
2141
2311
|
}
|
|
2142
|
-
var FontSizeExtension =
|
|
2312
|
+
var FontSizeExtension = Extension7.create({
|
|
2143
2313
|
name: "fontSize",
|
|
2144
2314
|
addGlobalAttributes() {
|
|
2145
2315
|
return [
|
|
@@ -2237,7 +2407,7 @@ var FontSizeExtension = Extension6.create({
|
|
|
2237
2407
|
});
|
|
2238
2408
|
|
|
2239
2409
|
// src/FontFamily.ts
|
|
2240
|
-
import { Extension as
|
|
2410
|
+
import { Extension as Extension8 } from "@tiptap/core";
|
|
2241
2411
|
function mergeFontFamily(textStyleType, existing, fontFamily) {
|
|
2242
2412
|
if (fontFamily === null) {
|
|
2243
2413
|
const { fontFamily: _removed, ...rest } = existing?.attrs ?? {};
|
|
@@ -2248,7 +2418,7 @@ function mergeFontFamily(textStyleType, existing, fontFamily) {
|
|
|
2248
2418
|
function hasAttrs2(mark) {
|
|
2249
2419
|
return Object.values(mark.attrs).some((v) => v != null);
|
|
2250
2420
|
}
|
|
2251
|
-
var FontFamilyExtension =
|
|
2421
|
+
var FontFamilyExtension = Extension8.create({
|
|
2252
2422
|
name: "fontFamily",
|
|
2253
2423
|
addGlobalAttributes() {
|
|
2254
2424
|
return [
|
|
@@ -2457,6 +2627,11 @@ export {
|
|
|
2457
2627
|
EditorContextExtension,
|
|
2458
2628
|
FontFamilyExtension,
|
|
2459
2629
|
FontSizeExtension,
|
|
2630
|
+
INDENT_MAX_LEVEL,
|
|
2631
|
+
INDENT_STEP_PX,
|
|
2632
|
+
INDENT_STEP_VAR,
|
|
2633
|
+
INDENT_STYLE_VAR,
|
|
2634
|
+
IndentExtension,
|
|
2460
2635
|
LOCAL_STORAGE_KEY,
|
|
2461
2636
|
PAGE_SIZES,
|
|
2462
2637
|
PaginationPlus,
|
|
@@ -2464,6 +2639,7 @@ export {
|
|
|
2464
2639
|
SearchAndReplaceExtension,
|
|
2465
2640
|
SubdocumentProvider,
|
|
2466
2641
|
buildAIPrompt,
|
|
2642
|
+
clampIndentLevel,
|
|
2467
2643
|
claudeProvider,
|
|
2468
2644
|
clearSearch,
|
|
2469
2645
|
collaborationExtensions,
|
|
@@ -2477,6 +2653,7 @@ export {
|
|
|
2477
2653
|
findMatches,
|
|
2478
2654
|
getSearchState,
|
|
2479
2655
|
httpKeyStorage,
|
|
2656
|
+
indentLevelOf,
|
|
2480
2657
|
localStorageKeyStorage,
|
|
2481
2658
|
memoryKeyStorage,
|
|
2482
2659
|
normalizeClipboardHTML,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kedataindo/docflow-core",
|
|
3
3
|
"license": "Apache-2.0",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.92",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -27,23 +27,23 @@
|
|
|
27
27
|
],
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@tiptap/core": "^2.
|
|
31
|
-
"@tiptap/extension-collaboration": "^2.27.
|
|
30
|
+
"@tiptap/core": "^2.27.3",
|
|
31
|
+
"@tiptap/extension-collaboration": "^2.27.3",
|
|
32
32
|
"@tiptap/extension-collaboration-cursor": "^2.26.2",
|
|
33
|
-
"@tiptap/extension-text-style": "^2.
|
|
34
|
-
"@tiptap/pm": "^2.
|
|
35
|
-
"@tiptap/starter-kit": "^2.
|
|
33
|
+
"@tiptap/extension-text-style": "^2.27.3",
|
|
34
|
+
"@tiptap/pm": "^2.27.3",
|
|
35
|
+
"@tiptap/starter-kit": "^2.27.3",
|
|
36
36
|
"tiptap-pagination-plus": "3.1.0",
|
|
37
37
|
"y-indexeddb": "^9.0.12",
|
|
38
38
|
"y-protocols": "^1.0.7",
|
|
39
39
|
"yjs": "^13.6.20"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@tiptap/core": "^2.
|
|
43
|
-
"@tiptap/extension-collaboration": "^2.27.
|
|
42
|
+
"@tiptap/core": "^2.27.3",
|
|
43
|
+
"@tiptap/extension-collaboration": "^2.27.3",
|
|
44
44
|
"@tiptap/extension-collaboration-cursor": "^2.26.2",
|
|
45
|
-
"@tiptap/extension-text-style": "^2.
|
|
46
|
-
"@tiptap/starter-kit": "^2.
|
|
45
|
+
"@tiptap/extension-text-style": "^2.27.3",
|
|
46
|
+
"@tiptap/starter-kit": "^2.27.3",
|
|
47
47
|
"tiptap-pagination-plus": "3.1.0",
|
|
48
48
|
"y-webrtc": "^10.3.0",
|
|
49
49
|
"y-websocket": "^2.0.4",
|