@kedataindo/docflow-core 0.0.72 → 0.0.73

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 CHANGED
@@ -71,8 +71,8 @@ __export(index_exports, {
71
71
  module.exports = __toCommonJS(index_exports);
72
72
 
73
73
  // src/Editor.ts
74
- var import_core5 = require("@tiptap/core");
75
- var import_state4 = require("@tiptap/pm/state");
74
+ var import_core6 = require("@tiptap/core");
75
+ var import_state5 = require("@tiptap/pm/state");
76
76
  var import_starter_kit = __toESM(require("@tiptap/starter-kit"), 1);
77
77
  var import_extension_text_style = __toESM(require("@tiptap/extension-text-style"), 1);
78
78
 
@@ -1306,6 +1306,94 @@ var PaginationPlus = import_core4.Extension.create({
1306
1306
  }
1307
1307
  });
1308
1308
 
1309
+ // src/pagination/PaginationCaretFix.ts
1310
+ var import_core5 = require("@tiptap/core");
1311
+ var import_state4 = require("@tiptap/pm/state");
1312
+ var PAGINATION_CLASS = "rm-with-pagination";
1313
+ var PAGINATION_DISABLED_ATTR = "rm-pagination-disabled";
1314
+ var dragStates = /* @__PURE__ */ new WeakMap();
1315
+ var isPaginationActive = (view) => {
1316
+ const dom = view.dom;
1317
+ return dom.classList.contains(PAGINATION_CLASS) && dom.getAttribute(PAGINATION_DISABLED_ATTR) === null;
1318
+ };
1319
+ var isEditable = (view) => view.dom.getAttribute("contenteditable") !== "false";
1320
+ var isPlainSingleLeftClick = (event) => event.button === 0 && event.detail === 1 && !event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey;
1321
+ function posFromTextOffset(view, textNode, offset) {
1322
+ if (textNode.nodeType !== Node.TEXT_NODE || !view.dom.contains(textNode)) return null;
1323
+ const text = textNode;
1324
+ const clamped = Math.min(Math.max(0, offset), text.length);
1325
+ const parent = text.parentElement;
1326
+ if (parent?.closest?.('[contenteditable="false"]')) return null;
1327
+ let pos = view.posAtDOM(text, clamped, -1);
1328
+ if (pos < 0) pos = view.posAtDOM(text, clamped, 1);
1329
+ if (pos < 0) return null;
1330
+ return view.state.doc.resolve(pos).parent.isTextblock ? pos : null;
1331
+ }
1332
+ function resolvePosFromNativePoint(view, clientX, clientY) {
1333
+ const doc = view.dom.ownerDocument;
1334
+ if (typeof doc.caretRangeFromPoint !== "function") return null;
1335
+ const range = doc.caretRangeFromPoint(clientX, clientY);
1336
+ if (!range) return null;
1337
+ return posFromTextOffset(view, range.startContainer, range.startOffset);
1338
+ }
1339
+ function stopDrag(view) {
1340
+ const drag = dragStates.get(view);
1341
+ if (!drag) return;
1342
+ dragStates.delete(view);
1343
+ const doc = view.dom.ownerDocument;
1344
+ doc.removeEventListener("mousemove", drag.onMouseMove);
1345
+ doc.removeEventListener("mouseup", drag.onMouseUp);
1346
+ }
1347
+ function beginDrag(view, anchorPos) {
1348
+ stopDrag(view);
1349
+ const doc = view.dom.ownerDocument;
1350
+ const onMouseMove = (event) => {
1351
+ const drag = dragStates.get(view);
1352
+ if (!drag) return;
1353
+ const pos = resolvePosFromNativePoint(view, event.clientX, event.clientY);
1354
+ if (pos === null) return;
1355
+ const from = Math.min(drag.anchorPos, pos);
1356
+ const to = Math.max(drag.anchorPos, pos);
1357
+ view.dispatch(view.state.tr.setSelection(import_state4.TextSelection.create(view.state.doc, from, to)));
1358
+ };
1359
+ const onMouseUp = () => {
1360
+ stopDrag(view);
1361
+ };
1362
+ dragStates.set(view, { anchorPos, onMouseMove, onMouseUp });
1363
+ doc.addEventListener("mousemove", onMouseMove);
1364
+ doc.addEventListener("mouseup", onMouseUp);
1365
+ }
1366
+ function interceptPaginationMouseDown(view, event) {
1367
+ if (!isPaginationActive(view) || !isPlainSingleLeftClick(event) || !isEditable(view)) return false;
1368
+ const pos = resolvePosFromNativePoint(view, event.clientX, event.clientY);
1369
+ if (pos === null) return false;
1370
+ view.focus();
1371
+ view.dispatch(view.state.tr.setSelection(import_state4.TextSelection.create(view.state.doc, pos)));
1372
+ beginDrag(view, pos);
1373
+ return true;
1374
+ }
1375
+ var PaginationCaretFix = import_core5.Extension.create({
1376
+ name: "paginationCaretFix",
1377
+ addProseMirrorPlugins() {
1378
+ return [
1379
+ new import_state4.Plugin({
1380
+ key: new import_state4.PluginKey("paginationCaretFix"),
1381
+ props: {
1382
+ handleDOMEvents: {
1383
+ mousedown: (view, event) => {
1384
+ try {
1385
+ return interceptPaginationMouseDown(view, event);
1386
+ } catch {
1387
+ return false;
1388
+ }
1389
+ }
1390
+ }
1391
+ }
1392
+ })
1393
+ ];
1394
+ }
1395
+ });
1396
+
1309
1397
  // src/PerformanceMonitor.ts
1310
1398
  var TARGET_FRAME_MS = 1e3 / 60;
1311
1399
  var formatMb = (bytes) => `${Math.round(bytes / 1024 / 1024)}MB`;
@@ -1734,11 +1822,11 @@ function createTiptapEditor(options, plugins, collaborationSetup) {
1734
1822
  const pluginExtensions = collectExtensions(plugins);
1735
1823
  const blockAttrs = options.getPageMap ? BlockAttributesExtension.configure({ pageMap: options.getPageMap }) : BlockAttributesExtension;
1736
1824
  const paginationExt = options.paginationOptions ? PaginationPlus.configure(options.paginationOptions) : PaginationPlus;
1737
- const ManualColumnResize = import_core5.Extension.create({
1825
+ const ManualColumnResize = import_core6.Extension.create({
1738
1826
  name: "manualColumnResize",
1739
1827
  addProseMirrorPlugins() {
1740
- const key2 = new import_state4.PluginKey("manualColumnResize");
1741
- return [new import_state4.Plugin({
1828
+ const key2 = new import_state5.PluginKey("manualColumnResize");
1829
+ return [new import_state5.Plugin({
1742
1830
  key: key2,
1743
1831
  view(view) {
1744
1832
  function pauseObserver() {
@@ -2060,6 +2148,10 @@ function createTiptapEditor(options, plugins, collaborationSetup) {
2060
2148
  import_extension_text_style.default,
2061
2149
  blockAttrs,
2062
2150
  paginationExt,
2151
+ // Always present — fixes caret-on-click misplacement caused by the
2152
+ // pagination DOM (header/footer/gap widgets breaking linear coordinates).
2153
+ // No-op (gated at runtime) when pagination is off or disabled.
2154
+ PaginationCaretFix,
2063
2155
  // Always present — carries host-injected ports (onImageUpload, citation, …)
2064
2156
  // in storage so plugin commands can reach them through the editor instance.
2065
2157
  EditorContextExtension.configure({
@@ -2077,7 +2169,7 @@ function createTiptapEditor(options, plugins, collaborationSetup) {
2077
2169
  const seed = seedEmptyFragment(collaborationSetup.ydoc);
2078
2170
  if (seed.seeded) {
2079
2171
  extensions.push(
2080
- import_core5.Extension.create({
2172
+ import_core6.Extension.create({
2081
2173
  name: "provisionalSeedCleanup",
2082
2174
  onDestroy: () => seed.dispose()
2083
2175
  })
@@ -2085,7 +2177,7 @@ function createTiptapEditor(options, plugins, collaborationSetup) {
2085
2177
  }
2086
2178
  extensions = [...extensions, ...collaborationExtensions(collaborationSetup)];
2087
2179
  }
2088
- const tiptapEditor = new import_core5.Editor({
2180
+ const tiptapEditor = new import_core6.Editor({
2089
2181
  element: options.target,
2090
2182
  content,
2091
2183
  extensions,
@@ -2104,7 +2196,7 @@ function createTiptapEditor(options, plugins, collaborationSetup) {
2104
2196
  }
2105
2197
 
2106
2198
  // src/FontSize.ts
2107
- var import_core6 = require("@tiptap/core");
2199
+ var import_core7 = require("@tiptap/core");
2108
2200
  function mergeFontSize(textStyleType, existing, fontSize) {
2109
2201
  if (fontSize === null) {
2110
2202
  const { fontSize: _removed, ...rest } = existing?.attrs ?? {};
@@ -2115,7 +2207,7 @@ function mergeFontSize(textStyleType, existing, fontSize) {
2115
2207
  function hasAttrs(mark) {
2116
2208
  return Object.values(mark.attrs).some((v) => v != null);
2117
2209
  }
2118
- var FontSizeExtension = import_core6.Extension.create({
2210
+ var FontSizeExtension = import_core7.Extension.create({
2119
2211
  name: "fontSize",
2120
2212
  addGlobalAttributes() {
2121
2213
  return [
package/dist/index.js CHANGED
@@ -16,8 +16,8 @@ import {
16
16
  } from "./chunk-XJG72F7M.js";
17
17
 
18
18
  // src/Editor.ts
19
- import { Extension as Extension5, Editor as TiptapEditor } from "@tiptap/core";
20
- import { Plugin as Plugin4, PluginKey as PluginKey4 } from "@tiptap/pm/state";
19
+ import { Extension as Extension6, Editor as TiptapEditor } from "@tiptap/core";
20
+ import { Plugin as Plugin5, PluginKey as PluginKey5 } from "@tiptap/pm/state";
21
21
  import StarterKit from "@tiptap/starter-kit";
22
22
  import TextStyle from "@tiptap/extension-text-style";
23
23
 
@@ -1115,6 +1115,94 @@ var PaginationPlus = Extension4.create({
1115
1115
  }
1116
1116
  });
1117
1117
 
1118
+ // src/pagination/PaginationCaretFix.ts
1119
+ import { Extension as Extension5 } from "@tiptap/core";
1120
+ import { Plugin as Plugin4, PluginKey as PluginKey4, TextSelection as TextSelection2 } from "@tiptap/pm/state";
1121
+ var PAGINATION_CLASS = "rm-with-pagination";
1122
+ var PAGINATION_DISABLED_ATTR = "rm-pagination-disabled";
1123
+ var dragStates = /* @__PURE__ */ new WeakMap();
1124
+ var isPaginationActive = (view) => {
1125
+ const dom = view.dom;
1126
+ return dom.classList.contains(PAGINATION_CLASS) && dom.getAttribute(PAGINATION_DISABLED_ATTR) === null;
1127
+ };
1128
+ var isEditable = (view) => view.dom.getAttribute("contenteditable") !== "false";
1129
+ var isPlainSingleLeftClick = (event) => event.button === 0 && event.detail === 1 && !event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey;
1130
+ function posFromTextOffset(view, textNode, offset) {
1131
+ if (textNode.nodeType !== Node.TEXT_NODE || !view.dom.contains(textNode)) return null;
1132
+ const text = textNode;
1133
+ const clamped = Math.min(Math.max(0, offset), text.length);
1134
+ const parent = text.parentElement;
1135
+ if (parent?.closest?.('[contenteditable="false"]')) return null;
1136
+ let pos = view.posAtDOM(text, clamped, -1);
1137
+ if (pos < 0) pos = view.posAtDOM(text, clamped, 1);
1138
+ if (pos < 0) return null;
1139
+ return view.state.doc.resolve(pos).parent.isTextblock ? pos : null;
1140
+ }
1141
+ function resolvePosFromNativePoint(view, clientX, clientY) {
1142
+ const doc = view.dom.ownerDocument;
1143
+ if (typeof doc.caretRangeFromPoint !== "function") return null;
1144
+ const range = doc.caretRangeFromPoint(clientX, clientY);
1145
+ if (!range) return null;
1146
+ return posFromTextOffset(view, range.startContainer, range.startOffset);
1147
+ }
1148
+ function stopDrag(view) {
1149
+ const drag = dragStates.get(view);
1150
+ if (!drag) return;
1151
+ dragStates.delete(view);
1152
+ const doc = view.dom.ownerDocument;
1153
+ doc.removeEventListener("mousemove", drag.onMouseMove);
1154
+ doc.removeEventListener("mouseup", drag.onMouseUp);
1155
+ }
1156
+ function beginDrag(view, anchorPos) {
1157
+ stopDrag(view);
1158
+ const doc = view.dom.ownerDocument;
1159
+ const onMouseMove = (event) => {
1160
+ const drag = dragStates.get(view);
1161
+ if (!drag) return;
1162
+ const pos = resolvePosFromNativePoint(view, event.clientX, event.clientY);
1163
+ if (pos === null) return;
1164
+ const from = Math.min(drag.anchorPos, pos);
1165
+ const to = Math.max(drag.anchorPos, pos);
1166
+ view.dispatch(view.state.tr.setSelection(TextSelection2.create(view.state.doc, from, to)));
1167
+ };
1168
+ const onMouseUp = () => {
1169
+ stopDrag(view);
1170
+ };
1171
+ dragStates.set(view, { anchorPos, onMouseMove, onMouseUp });
1172
+ doc.addEventListener("mousemove", onMouseMove);
1173
+ doc.addEventListener("mouseup", onMouseUp);
1174
+ }
1175
+ function interceptPaginationMouseDown(view, event) {
1176
+ if (!isPaginationActive(view) || !isPlainSingleLeftClick(event) || !isEditable(view)) return false;
1177
+ const pos = resolvePosFromNativePoint(view, event.clientX, event.clientY);
1178
+ if (pos === null) return false;
1179
+ view.focus();
1180
+ view.dispatch(view.state.tr.setSelection(TextSelection2.create(view.state.doc, pos)));
1181
+ beginDrag(view, pos);
1182
+ return true;
1183
+ }
1184
+ var PaginationCaretFix = Extension5.create({
1185
+ name: "paginationCaretFix",
1186
+ addProseMirrorPlugins() {
1187
+ return [
1188
+ new Plugin4({
1189
+ key: new PluginKey4("paginationCaretFix"),
1190
+ props: {
1191
+ handleDOMEvents: {
1192
+ mousedown: (view, event) => {
1193
+ try {
1194
+ return interceptPaginationMouseDown(view, event);
1195
+ } catch {
1196
+ return false;
1197
+ }
1198
+ }
1199
+ }
1200
+ }
1201
+ })
1202
+ ];
1203
+ }
1204
+ });
1205
+
1118
1206
  // src/PerformanceMonitor.ts
1119
1207
  var TARGET_FRAME_MS = 1e3 / 60;
1120
1208
  var formatMb = (bytes) => `${Math.round(bytes / 1024 / 1024)}MB`;
@@ -1543,11 +1631,11 @@ function createTiptapEditor(options, plugins, collaborationSetup) {
1543
1631
  const pluginExtensions = collectExtensions(plugins);
1544
1632
  const blockAttrs = options.getPageMap ? BlockAttributesExtension.configure({ pageMap: options.getPageMap }) : BlockAttributesExtension;
1545
1633
  const paginationExt = options.paginationOptions ? PaginationPlus.configure(options.paginationOptions) : PaginationPlus;
1546
- const ManualColumnResize = Extension5.create({
1634
+ const ManualColumnResize = Extension6.create({
1547
1635
  name: "manualColumnResize",
1548
1636
  addProseMirrorPlugins() {
1549
- const key2 = new PluginKey4("manualColumnResize");
1550
- return [new Plugin4({
1637
+ const key2 = new PluginKey5("manualColumnResize");
1638
+ return [new Plugin5({
1551
1639
  key: key2,
1552
1640
  view(view) {
1553
1641
  function pauseObserver() {
@@ -1869,6 +1957,10 @@ function createTiptapEditor(options, plugins, collaborationSetup) {
1869
1957
  TextStyle,
1870
1958
  blockAttrs,
1871
1959
  paginationExt,
1960
+ // Always present — fixes caret-on-click misplacement caused by the
1961
+ // pagination DOM (header/footer/gap widgets breaking linear coordinates).
1962
+ // No-op (gated at runtime) when pagination is off or disabled.
1963
+ PaginationCaretFix,
1872
1964
  // Always present — carries host-injected ports (onImageUpload, citation, …)
1873
1965
  // in storage so plugin commands can reach them through the editor instance.
1874
1966
  EditorContextExtension.configure({
@@ -1886,7 +1978,7 @@ function createTiptapEditor(options, plugins, collaborationSetup) {
1886
1978
  const seed = seedEmptyFragment(collaborationSetup.ydoc);
1887
1979
  if (seed.seeded) {
1888
1980
  extensions.push(
1889
- Extension5.create({
1981
+ Extension6.create({
1890
1982
  name: "provisionalSeedCleanup",
1891
1983
  onDestroy: () => seed.dispose()
1892
1984
  })
@@ -1913,7 +2005,7 @@ function createTiptapEditor(options, plugins, collaborationSetup) {
1913
2005
  }
1914
2006
 
1915
2007
  // src/FontSize.ts
1916
- import { Extension as Extension6 } from "@tiptap/core";
2008
+ import { Extension as Extension7 } from "@tiptap/core";
1917
2009
  function mergeFontSize(textStyleType, existing, fontSize) {
1918
2010
  if (fontSize === null) {
1919
2011
  const { fontSize: _removed, ...rest } = existing?.attrs ?? {};
@@ -1924,7 +2016,7 @@ function mergeFontSize(textStyleType, existing, fontSize) {
1924
2016
  function hasAttrs(mark) {
1925
2017
  return Object.values(mark.attrs).some((v) => v != null);
1926
2018
  }
1927
- var FontSizeExtension = Extension6.create({
2019
+ var FontSizeExtension = Extension7.create({
1928
2020
  name: "fontSize",
1929
2021
  addGlobalAttributes() {
1930
2022
  return [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kedataindo/docflow-core",
3
3
  "license": "UNLICENSED",
4
- "version": "0.0.72",
4
+ "version": "0.0.73",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",