@harbour-enterprises/superdoc 0.23.0-next.1 → 0.23.0-next.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/chunks/{PdfViewer-C9SGNZr6.cjs → PdfViewer-CxsRHFKK.cjs} +2 -2
  2. package/dist/chunks/{PdfViewer-D9atA783.es.js → PdfViewer-itEb8CY_.es.js} +2 -2
  3. package/dist/chunks/{eventemitter3-CZv6vEhA.es.js → eventemitter3-CR2eBWft.es.js} +1 -1
  4. package/dist/chunks/{eventemitter3-B_kO1Pxm.cjs → eventemitter3-DSRogsNq.cjs} +1 -1
  5. package/dist/chunks/{index-C8q6lenv.es.js → index-CTFsQkQh.es.js} +75 -28
  6. package/dist/chunks/{index-CIbe1VMu.cjs → index-DO0hDjEd.cjs} +75 -28
  7. package/dist/chunks/{jszip-b7l8QkfH.cjs → jszip-B4LDL19y.cjs} +1 -1
  8. package/dist/chunks/{jszip-B8KIZSNe.es.js → jszip-DAXEPCUv.es.js} +1 -1
  9. package/dist/chunks/{super-editor.es-DxScE0ep.cjs → super-editor.es-Ck_zDasU.cjs} +259 -86
  10. package/dist/chunks/{super-editor.es-Dj6Sxtr7.es.js → super-editor.es-D2K5zQwY.es.js} +259 -86
  11. package/dist/chunks/{vue-DWle4Cai.cjs → vue-DKMj1I9B.cjs} +39 -42
  12. package/dist/chunks/{vue-CXxsqYcP.es.js → vue-ZWZLQtoU.es.js} +39 -42
  13. package/dist/chunks/xml-js-Bbc0NeKa.es.js +2 -0
  14. package/dist/chunks/xml-js-CWV8R-ek.cjs +3 -0
  15. package/dist/core/SuperDoc.d.ts +5 -18
  16. package/dist/core/SuperDoc.d.ts.map +1 -1
  17. package/dist/core/types/index.d.ts +29 -1
  18. package/dist/core/types/index.d.ts.map +1 -1
  19. package/dist/stores/comments-store.d.ts +3 -3
  20. package/dist/stores/comments-store.d.ts.map +1 -1
  21. package/dist/stores/superdoc-store.d.ts.map +1 -1
  22. package/dist/style.css +73 -54
  23. package/dist/super-editor/ai-writer.es.js +2 -2
  24. package/dist/super-editor/chunks/{converter-C08GQjNi.js → converter-ClnqoStR.js} +18 -19
  25. package/dist/super-editor/chunks/{docx-zipper-C3-uf2tI.js → docx-zipper-DC28ucAi.js} +1 -1
  26. package/dist/super-editor/chunks/{editor-C2IwVkIp.js → editor-C3VH8Ia2.js} +240 -66
  27. package/dist/super-editor/chunks/{toolbar-De8G_9NV.js → toolbar-BG1F_1RK.js} +4 -4
  28. package/dist/super-editor/converter.es.js +1 -1
  29. package/dist/super-editor/docx-zipper.es.js +2 -2
  30. package/dist/super-editor/editor.es.js +3 -3
  31. package/dist/super-editor/file-zipper.es.js +1 -1
  32. package/dist/super-editor/src/core/Attribute.d.ts +2 -2
  33. package/dist/super-editor/src/core/Schema.d.ts +2 -2
  34. package/dist/super-editor/src/extensions/comment/comments-plugin.d.ts +60 -0
  35. package/dist/super-editor/src/extensions/comment/helpers/index.d.ts +2 -0
  36. package/dist/super-editor/src/extensions/comment/helpers/normalize-comment-event-payload.d.ts +1 -0
  37. package/dist/super-editor/src/extensions/comment/helpers/update-position.d.ts +7 -0
  38. package/dist/super-editor/src/extensions/image/imageHelpers/handleBase64.d.ts +4 -0
  39. package/dist/super-editor/src/extensions/image/imageHelpers/imageRegistrationPlugin.d.ts +1 -0
  40. package/dist/super-editor/src/extensions/image/imageHelpers/startImageUpload.d.ts +5 -0
  41. package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentTagsByAlias.d.ts +8 -0
  42. package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/index.d.ts +1 -0
  43. package/dist/super-editor/style.css +46 -27
  44. package/dist/super-editor/super-editor.es.js +6 -6
  45. package/dist/super-editor/toolbar.es.js +2 -2
  46. package/dist/super-editor.cjs +2 -2
  47. package/dist/super-editor.es.js +2 -2
  48. package/dist/superdoc.cjs +4 -4
  49. package/dist/superdoc.es.js +4 -4
  50. package/dist/superdoc.umd.js +362 -142
  51. package/dist/superdoc.umd.js.map +1 -1
  52. package/package.json +1 -1
  53. package/dist/chunks/xml-js-CX8FH0He.cjs +0 -3
  54. package/dist/chunks/xml-js-D0tLGmKu.es.js +0 -2
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const vue = require("./vue-DWle4Cai.cjs");
2
+ const vue = require("./vue-DKMj1I9B.cjs");
3
3
  const Y = require("yjs");
4
4
  function _interopNamespaceDefault(e) {
5
5
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -5111,6 +5111,19 @@ function requireSafeRegexTest() {
5111
5111
  };
5112
5112
  return safeRegexTest;
5113
5113
  }
5114
+ var generatorFunction;
5115
+ var hasRequiredGeneratorFunction;
5116
+ function requireGeneratorFunction() {
5117
+ if (hasRequiredGeneratorFunction) return generatorFunction;
5118
+ hasRequiredGeneratorFunction = 1;
5119
+ const cached = (
5120
+ /** @type {GeneratorFunctionConstructor} */
5121
+ function* () {
5122
+ }.constructor
5123
+ );
5124
+ generatorFunction = () => cached;
5125
+ return generatorFunction;
5126
+ }
5114
5127
  var isGeneratorFunction;
5115
5128
  var hasRequiredIsGeneratorFunction;
5116
5129
  function requireIsGeneratorFunction() {
@@ -5123,16 +5136,7 @@ function requireIsGeneratorFunction() {
5123
5136
  var getProto2 = requireGetProto();
5124
5137
  var toStr = callBound2("Object.prototype.toString");
5125
5138
  var fnToStr = callBound2("Function.prototype.toString");
5126
- var getGeneratorFunc = function() {
5127
- if (!hasToStringTag) {
5128
- return false;
5129
- }
5130
- try {
5131
- return Function("return function*() {}")();
5132
- } catch (e) {
5133
- }
5134
- };
5135
- var GeneratorFunction;
5139
+ var getGeneratorFunction = /* @__PURE__ */ requireGeneratorFunction();
5136
5140
  isGeneratorFunction = function isGeneratorFunction2(fn2) {
5137
5141
  if (typeof fn2 !== "function") {
5138
5142
  return false;
@@ -5147,14 +5151,8 @@ function requireIsGeneratorFunction() {
5147
5151
  if (!getProto2) {
5148
5152
  return false;
5149
5153
  }
5150
- if (typeof GeneratorFunction === "undefined") {
5151
- var generatorFunc = getGeneratorFunc();
5152
- GeneratorFunction = generatorFunc ? (
5153
- /** @type {GeneratorFunctionConstructor} */
5154
- getProto2(generatorFunc)
5155
- ) : false;
5156
- }
5157
- return getProto2(fn2) === GeneratorFunction;
5154
+ var GeneratorFunction = getGeneratorFunction();
5155
+ return GeneratorFunction && getProto2(fn2) === GeneratorFunction.prototype;
5158
5156
  };
5159
5157
  return isGeneratorFunction;
5160
5158
  }
@@ -31895,7 +31893,8 @@ generateXml_fn = function(node) {
31895
31893
  }
31896
31894
  if (elements) {
31897
31895
  if (name === "w:instrText") {
31898
- tags.push(elements[0].text);
31896
+ const textContent2 = (elements || []).map((child) => typeof child?.text === "string" ? child.text : "").join("");
31897
+ tags.push(__privateMethod$2(this, _DocxExporter_instances, replaceSpecialCharacters_fn).call(this, textContent2));
31899
31898
  } else if (name === "w:t" || name === "w:delText" || name === "wp:posOffset") {
31900
31899
  try {
31901
31900
  let text = String(elements[0].text);
@@ -42091,8 +42090,7 @@ function readDOMChange(view, from2, to, typeOver, addedNodes) {
42091
42090
  let $to = parse.doc.resolveNoCache(change.endB - parse.from);
42092
42091
  let $fromA = doc2.resolve(change.start);
42093
42092
  let inlineChange = $from.sameParent($to) && $from.parent.inlineContent && $fromA.end() >= change.endA;
42094
- let nextSel;
42095
- if ((ios && view.input.lastIOSEnter > Date.now() - 225 && (!inlineChange || addedNodes.some((n) => n.nodeName == "DIV" || n.nodeName == "P")) || !inlineChange && $from.pos < parse.doc.content.size && (!$from.sameParent($to) || !$from.parent.inlineContent) && !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", "")) && (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && nextSel.head > $from.pos) && view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter")))) {
42093
+ if ((ios && view.input.lastIOSEnter > Date.now() - 225 && (!inlineChange || addedNodes.some((n) => n.nodeName == "DIV" || n.nodeName == "P")) || !inlineChange && $from.pos < parse.doc.content.size && (!$from.sameParent($to) || !$from.parent.inlineContent) && $from.pos < $to.pos && !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", ""))) && view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter")))) {
42096
42094
  view.input.lastIOSEnter = 0;
42097
42095
  return;
42098
42096
  }
@@ -48746,26 +48744,100 @@ const onHeaderFooterDataUpdate = async ({ editor, transaction }, mainEditor, sec
48746
48744
  const setEditorToolbar = ({ editor }, mainEditor) => {
48747
48745
  editor.setToolbar(mainEditor.toolbar);
48748
48746
  };
48747
+ const normalizeCommentEventPayload = ({ conversation, editorOptions, fallbackCommentId, fallbackInternal }) => {
48748
+ const { user, documentId } = editorOptions || {};
48749
+ const normalized = {
48750
+ ...conversation,
48751
+ commentId: conversation?.commentId ?? fallbackCommentId,
48752
+ isInternal: conversation?.isInternal ?? fallbackInternal
48753
+ };
48754
+ if (!normalized.commentText && normalized.text) {
48755
+ normalized.commentText = normalized.text;
48756
+ delete normalized.text;
48757
+ }
48758
+ if ("skipEmit" in normalized) delete normalized.skipEmit;
48759
+ if (!normalized.creatorName && user?.name) {
48760
+ normalized.creatorName = user.name;
48761
+ }
48762
+ if (!normalized.creatorEmail && user?.email) {
48763
+ normalized.creatorEmail = user.email;
48764
+ }
48765
+ if (!normalized.createdTime) {
48766
+ normalized.createdTime = Date.now();
48767
+ }
48768
+ if (!normalized.fileId && documentId) {
48769
+ normalized.fileId = documentId;
48770
+ }
48771
+ if (!normalized.documentId && documentId) {
48772
+ normalized.documentId = documentId;
48773
+ }
48774
+ return normalized;
48775
+ };
48776
+ const updatePosition = ({ allCommentPositions, threadId, pos, currentBounds, node }) => {
48777
+ let bounds = {};
48778
+ if (currentBounds instanceof DOMRect) {
48779
+ bounds = {
48780
+ top: currentBounds.top,
48781
+ bottom: currentBounds.bottom,
48782
+ left: currentBounds.left,
48783
+ right: currentBounds.right
48784
+ };
48785
+ } else {
48786
+ bounds = { ...currentBounds };
48787
+ }
48788
+ if (!allCommentPositions[threadId]) {
48789
+ allCommentPositions[threadId] = {
48790
+ threadId,
48791
+ start: pos,
48792
+ end: pos + node.nodeSize,
48793
+ bounds
48794
+ };
48795
+ } else {
48796
+ const existing = allCommentPositions[threadId];
48797
+ existing.start = Math.min(existing.start, pos);
48798
+ existing.end = Math.max(existing.end, pos + node.nodeSize);
48799
+ existing.bounds.top = Math.min(existing.bounds.top, currentBounds.top);
48800
+ existing.bounds.bottom = Math.max(existing.bounds.bottom, currentBounds.bottom);
48801
+ }
48802
+ };
48749
48803
  const TRACK_CHANGE_MARKS = [TrackInsertMarkName, TrackDeleteMarkName, TrackFormatMarkName];
48750
48804
  const CommentsPluginKey = new PluginKey("comments");
48751
48805
  const CommentsPlugin = Extension.create({
48752
48806
  name: "comments",
48753
48807
  addCommands() {
48754
48808
  return {
48755
- insertComment: (conversation) => ({ tr, dispatch }) => {
48809
+ insertComment: (conversation = {}) => ({ tr, dispatch }) => {
48756
48810
  const { selection } = tr;
48757
48811
  const { $from, $to } = selection;
48758
- const { commentId, isInternal } = conversation;
48812
+ const skipEmit = conversation?.skipEmit;
48813
+ const resolvedCommentId = conversation?.commentId ?? v4();
48814
+ const resolvedInternal = conversation?.isInternal ?? false;
48759
48815
  tr.setMeta(CommentsPluginKey, { event: "add" });
48760
48816
  tr.addMark(
48761
48817
  $from.pos,
48762
48818
  $to.pos,
48763
48819
  this.editor.schema.marks[CommentMarkName].create({
48764
- commentId,
48765
- internal: isInternal
48820
+ commentId: resolvedCommentId,
48821
+ internal: resolvedInternal
48766
48822
  })
48767
48823
  );
48768
- dispatch(tr);
48824
+ if (dispatch) dispatch(tr);
48825
+ const shouldEmit = !skipEmit && resolvedCommentId !== "pending";
48826
+ if (shouldEmit) {
48827
+ const commentPayload = normalizeCommentEventPayload({
48828
+ conversation,
48829
+ editorOptions: this.editor.options,
48830
+ fallbackCommentId: resolvedCommentId,
48831
+ fallbackInternal: resolvedInternal
48832
+ });
48833
+ const activeCommentId = commentPayload.commentId || commentPayload.importedId || null;
48834
+ const event = {
48835
+ type: comments_module_events.ADD,
48836
+ comment: commentPayload,
48837
+ ...activeCommentId && { activeCommentId }
48838
+ };
48839
+ this.editor.emit("commentsUpdate", event);
48840
+ }
48769
48841
  return true;
48770
48842
  },
48771
48843
  removeComment: ({ commentId, importedId }) => ({ tr, dispatch, state: state2 }) => {
@@ -49001,33 +49073,6 @@ const CommentsPlugin = Extension.create({
49001
49073
  return [commentsPlugin];
49002
49074
  }
49003
49075
  });
49004
- const updatePosition = ({ allCommentPositions, threadId, pos, currentBounds, node }) => {
49005
- let bounds = {};
49006
- if (currentBounds instanceof DOMRect) {
49007
- bounds = {
49008
- top: currentBounds.top,
49009
- bottom: currentBounds.bottom,
49010
- left: currentBounds.left,
49011
- right: currentBounds.right
49012
- };
49013
- } else {
49014
- bounds = { ...currentBounds };
49015
- }
49016
- if (!allCommentPositions[threadId]) {
49017
- allCommentPositions[threadId] = {
49018
- threadId,
49019
- start: pos,
49020
- end: pos + node.nodeSize,
49021
- bounds
49022
- };
49023
- } else {
49024
- const existing = allCommentPositions[threadId];
49025
- existing.start = Math.min(existing.start, pos);
49026
- existing.end = Math.max(existing.end, pos + node.nodeSize);
49027
- existing.bounds.top = Math.min(existing.bounds.top, currentBounds.top);
49028
- existing.bounds.bottom = Math.max(existing.bounds.bottom, currentBounds.bottom);
49029
- }
49030
- };
49031
49076
  const getActiveCommentId = (doc2, selection) => {
49032
49077
  if (!selection) return;
49033
49078
  const { $from, $to } = selection;
@@ -54236,6 +54281,17 @@ function getStructuredContentTagsById(idOrIds, state2) {
54236
54281
  });
54237
54282
  return result;
54238
54283
  }
54284
+ function getStructuredContentTagsByAlias(aliasOrAliases, state2) {
54285
+ const result = findChildren$5(state2.doc, (node) => {
54286
+ const isStructuredContent = ["structuredContent", "structuredContentBlock"].includes(node.type.name);
54287
+ if (Array.isArray(aliasOrAliases)) {
54288
+ return isStructuredContent && aliasOrAliases.includes(node.attrs.alias);
54289
+ } else {
54290
+ return isStructuredContent && node.attrs.alias === aliasOrAliases;
54291
+ }
54292
+ });
54293
+ return result;
54294
+ }
54239
54295
  function getStructuredContentTags(state2) {
54240
54296
  const result = findChildren$5(state2.doc, (node) => {
54241
54297
  return node.type.name === "structuredContent" || node.type.name === "structuredContentBlock";
@@ -54255,6 +54311,7 @@ const structuredContentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ O
54255
54311
  getStructuredContentBlockTags,
54256
54312
  getStructuredContentInlineTags,
54257
54313
  getStructuredContentTags,
54314
+ getStructuredContentTagsByAlias,
54258
54315
  getStructuredContentTagsById
54259
54316
  }, Symbol.toStringTag, { value: "Module" }));
54260
54317
  const STRUCTURED_CONTENT_NAMES = ["structuredContent", "structuredContentBlock"];
@@ -54343,10 +54400,11 @@ const StructuredContentCommands = Extension.create({
54343
54400
  return true;
54344
54401
  },
54345
54402
  /**
54346
- * Updates a structured content attributes or content.
54403
+ * Updates a single structured content field by its unique ID.
54404
+ * IDs are unique identifiers, so this will update at most one field.
54347
54405
  * If the updated node does not match the schema, it will not be updated.
54348
54406
  * @category Command
54349
- * @param {string} id
54407
+ * @param {string} id - Unique identifier of the field
54350
54408
  * @param {StructuredContentUpdate} options
54351
54409
  */
54352
54410
  updateStructuredContentById: (id, options = {}) => ({ editor, dispatch, state: state2, tr }) => {
@@ -54386,6 +54444,58 @@ const StructuredContentCommands = Extension.create({
54386
54444
  }
54387
54445
  return true;
54388
54446
  },
54447
+ /**
54448
+ * Updates all structured content fields with the same alias.
54449
+ * Unlike IDs (which are unique), aliases can be shared across multiple fields.
54450
+ * This will update every field that matches the given alias.
54451
+ * If any updated node does not match the schema, no updates will be applied.
54452
+ * @category Command
54453
+ * @param {string | string[]} alias - Shared identifier for fields (e.g., "customer_name")
54454
+ * @param {StructuredContentUpdate} options
54455
+ */
54456
+ updateStructuredContentByAlias: (alias, options = {}) => ({ editor, dispatch, state: state2, tr }) => {
54457
+ const structuredContentTags = getStructuredContentTagsByAlias(alias, state2);
54458
+ if (!structuredContentTags.length) {
54459
+ return true;
54460
+ }
54461
+ const { schema } = editor;
54462
+ const createContent = (node) => {
54463
+ if (options.text) {
54464
+ return schema.text(options.text);
54465
+ }
54466
+ if (options.html) {
54467
+ const html = htmlHandler(options.html, editor);
54468
+ const doc2 = DOMParser$1.fromSchema(schema).parse(html);
54469
+ return doc2.content;
54470
+ }
54471
+ if (options.json) {
54472
+ return schema.nodeFromJSON(options.json);
54473
+ }
54474
+ return node.content;
54475
+ };
54476
+ for (const { node } of structuredContentTags) {
54477
+ const content = createContent(node);
54478
+ const updatedNode = node.type.create({ ...node.attrs, ...options.attrs }, content, node.marks);
54479
+ try {
54480
+ updatedNode.check();
54481
+ } catch {
54482
+ console.error("Updated node does not conform to the schema");
54483
+ return false;
54484
+ }
54485
+ }
54486
+ if (dispatch) {
54487
+ structuredContentTags.forEach(({ pos, node }) => {
54488
+ const mappedPos = tr.mapping.map(pos);
54489
+ const currentNode = tr.doc.nodeAt(mappedPos);
54490
+ if (currentNode && node.eq(currentNode)) {
54491
+ const content = createContent(node);
54492
+ const updatedNode = node.type.create({ ...node.attrs, ...options.attrs }, content, node.marks);
54493
+ tr.replaceWith(mappedPos, mappedPos + node.nodeSize, updatedNode);
54494
+ }
54495
+ });
54496
+ }
54497
+ return true;
54498
+ },
54389
54499
  /**
54390
54500
  * Removes a structured content.
54391
54501
  * @category Command
@@ -62527,6 +62637,7 @@ function getFormatAttrsFromMarks(marks) {
62527
62637
  }
62528
62638
  return formatAttrs;
62529
62639
  }
62640
+ const DEFAULT_MIME_TYPE = "application/octet-stream";
62530
62641
  const simpleHash = (str) => {
62531
62642
  let hash2 = 0;
62532
62643
  for (let i = 0; i < str.length; i++) {
@@ -62536,21 +62647,40 @@ const simpleHash = (str) => {
62536
62647
  }
62537
62648
  return Math.abs(hash2).toString();
62538
62649
  };
62539
- const base64ToFile = (base64String) => {
62540
- const arr = base64String.split(",");
62541
- const mimeMatch = arr[0].match(/:(.*?);/);
62542
- const mimeType = mimeMatch ? mimeMatch[1] : "";
62543
- const data = arr[1];
62544
- const binaryString = atob(data);
62650
+ const decodeBase64ToBinaryString = (data) => {
62651
+ if (!data) return "";
62652
+ if (typeof atob === "function") {
62653
+ return atob(data);
62654
+ }
62655
+ if (typeof Buffer2 !== "undefined" && typeof Buffer2.from === "function") {
62656
+ return Buffer2.from(data, "base64").toString("binary");
62657
+ }
62658
+ throw new Error("Unable to decode base64 payload in the current environment.");
62659
+ };
62660
+ const extractBase64Meta = (base64String) => {
62661
+ const [meta = "", payload = ""] = base64String.split(",");
62662
+ const mimeMatch = meta.match(/:(.*?);/);
62663
+ const rawMimeType = mimeMatch ? mimeMatch[1] : "";
62664
+ const mimeType = rawMimeType || DEFAULT_MIME_TYPE;
62665
+ const binaryString = decodeBase64ToBinaryString(payload);
62545
62666
  const hash2 = simpleHash(binaryString);
62546
62667
  const extension = mimeType.split("/")[1] || "bin";
62547
62668
  const filename = `image-${hash2}.${extension}`;
62669
+ return { mimeType, binaryString, filename };
62670
+ };
62671
+ const getBase64FileMeta = (base64String) => {
62672
+ const { mimeType, filename } = extractBase64Meta(base64String);
62673
+ return { mimeType, filename };
62674
+ };
62675
+ const base64ToFile = (base64String) => {
62676
+ const { mimeType, binaryString, filename } = extractBase64Meta(base64String);
62677
+ const fileType = mimeType || DEFAULT_MIME_TYPE;
62548
62678
  const bytes = new Uint8Array(binaryString.length);
62549
62679
  for (let i = 0; i < binaryString.length; i++) {
62550
62680
  bytes[i] = binaryString.charCodeAt(i);
62551
62681
  }
62552
- const blob = new Blob([bytes], { type: mimeType });
62553
- return new File([blob], filename, { type: mimeType });
62682
+ const blob = new Blob([bytes], { type: fileType });
62683
+ return new File([blob], filename, { type: fileType });
62554
62684
  };
62555
62685
  const urlToFile = async (url, filename, mimeType) => {
62556
62686
  try {
@@ -62926,6 +63056,7 @@ function addImageRelationship({ editor, path }) {
62926
63056
  }
62927
63057
  }
62928
63058
  const key = new PluginKey("ImageRegistration");
63059
+ const WORD_MEDIA_PREFIX = "word/";
62929
63060
  const ImageRegistrationPlugin = ({ editor }) => {
62930
63061
  const { view } = editor;
62931
63062
  return new Plugin({
@@ -62946,16 +63077,16 @@ const ImageRegistrationPlugin = ({ editor }) => {
62946
63077
  },
62947
63078
  appendTransaction: (trs, _oldState, state2) => {
62948
63079
  let foundImages = [];
62949
- trs.forEach((tr2) => {
62950
- if (tr2.docChanged) {
62951
- tr2.steps.forEach((step, index2) => {
63080
+ trs.forEach((tr) => {
63081
+ if (tr.docChanged) {
63082
+ tr.steps.forEach((step, index2) => {
62952
63083
  const stepMap = step.getMap();
62953
63084
  foundImages = foundImages.map(({ node, pos, id }) => {
62954
63085
  const mappedPos = stepMap.map(pos, -1);
62955
63086
  return { node, pos: mappedPos, id };
62956
63087
  });
62957
63088
  if (step instanceof ReplaceStep || step instanceof ReplaceAroundStep$1) {
62958
- (tr2.docs[index2 + 1] || tr2.doc).nodesBetween(
63089
+ (tr.docs[index2 + 1] || tr.doc).nodesBetween(
62959
63090
  stepMap.map(step.from, -1),
62960
63091
  stepMap.map(step.to, 1),
62961
63092
  (node, pos) => {
@@ -62974,22 +63105,10 @@ const ImageRegistrationPlugin = ({ editor }) => {
62974
63105
  if (!foundImages || foundImages.length === 0) {
62975
63106
  return null;
62976
63107
  }
62977
- registerImages(foundImages, editor, view);
62978
- const tr = state2.tr;
62979
- let { set } = key.getState(state2);
62980
- foundImages.slice().sort((a, b2) => a.pos - b2.pos).forEach(({ pos, id }) => {
62981
- let deco = Decoration.widget(pos, () => document.createElement("placeholder"), {
62982
- side: -1,
62983
- id
62984
- });
62985
- set = set.add(tr.doc, [deco]);
62986
- });
62987
- foundImages.slice().sort((a, b2) => b2.pos - a.pos).forEach(({ node, pos }) => {
62988
- tr.delete(pos, pos + node.nodeSize);
62989
- });
62990
- set = set.map(tr.mapping, tr.doc);
62991
- tr.setMeta(key, { set });
62992
- return tr;
63108
+ if (editor.options.isHeadless) {
63109
+ return handleNodePath(foundImages, editor, state2);
63110
+ }
63111
+ return handleBrowserPath(foundImages, editor, view, state2);
62993
63112
  },
62994
63113
  props: {
62995
63114
  decorations(state2) {
@@ -62999,6 +63118,59 @@ const ImageRegistrationPlugin = ({ editor }) => {
62999
63118
  }
63000
63119
  });
63001
63120
  };
63121
+ const derivePreferredFileName = (src) => {
63122
+ if (typeof src !== "string" || src.length === 0) {
63123
+ return "image.bin";
63124
+ }
63125
+ if (src.startsWith("data:")) {
63126
+ return getBase64FileMeta(src).filename;
63127
+ }
63128
+ const lastSegment = src.split("/").pop() ?? "";
63129
+ const trimmed = lastSegment.split(/[?#]/)[0];
63130
+ return trimmed || "image.bin";
63131
+ };
63132
+ const handleNodePath = (foundImages, editor, state2) => {
63133
+ const { tr } = state2;
63134
+ const mediaStore = editor.storage.image.media ?? {};
63135
+ if (!editor.storage.image.media) {
63136
+ editor.storage.image.media = mediaStore;
63137
+ }
63138
+ const existingFileNames = new Set(Object.keys(mediaStore).map((key2) => key2.split("/").pop()));
63139
+ foundImages.forEach(({ node, pos }) => {
63140
+ const { src } = node.attrs;
63141
+ const preferredFileName = derivePreferredFileName(src);
63142
+ const uniqueFileName = ensureUniqueFileName(preferredFileName, existingFileNames);
63143
+ existingFileNames.add(uniqueFileName);
63144
+ const mediaPath = buildMediaPath(uniqueFileName);
63145
+ mediaStore[mediaPath] = src;
63146
+ const path = mediaPath.startsWith(WORD_MEDIA_PREFIX) ? mediaPath.slice(WORD_MEDIA_PREFIX.length) : mediaPath;
63147
+ const rId = addImageRelationship({ editor, path });
63148
+ tr.setNodeMarkup(pos, void 0, {
63149
+ ...node.attrs,
63150
+ src: mediaPath,
63151
+ rId
63152
+ });
63153
+ });
63154
+ return tr;
63155
+ };
63156
+ const handleBrowserPath = (foundImages, editor, view, state2) => {
63157
+ registerImages(foundImages, editor, view);
63158
+ const tr = state2.tr;
63159
+ let { set } = key.getState(state2);
63160
+ foundImages.slice().sort((a, b2) => a.pos - b2.pos).forEach(({ pos, id }) => {
63161
+ let deco = Decoration.widget(pos, () => document.createElement("placeholder"), {
63162
+ side: -1,
63163
+ id
63164
+ });
63165
+ set = set.add(tr.doc, [deco]);
63166
+ });
63167
+ foundImages.slice().sort((a, b2) => b2.pos - a.pos).forEach(({ node, pos }) => {
63168
+ tr.delete(pos, pos + node.nodeSize);
63169
+ });
63170
+ set = set.map(tr.mapping, tr.doc);
63171
+ tr.setMeta(key, { set });
63172
+ return tr;
63173
+ };
63002
63174
  const findPlaceholder = (state2, id) => {
63003
63175
  let { set } = key.getState(state2);
63004
63176
  let found2 = set?.find(null, null, (spec) => spec.id === id);
@@ -70116,6 +70288,7 @@ function getActualBreakCoords(view, pos, calculatedThreshold) {
70116
70288
  return actualBreak;
70117
70289
  }
70118
70290
  const onImageLoad = (editor) => {
70291
+ if (typeof requestAnimationFrame !== "function") return;
70119
70292
  requestAnimationFrame(() => {
70120
70293
  const newTr = editor.view.state.tr;
70121
70294
  newTr.setMeta("forceUpdatePagination", true);
@@ -71327,7 +71500,7 @@ const _sfc_main$4$1 = {
71327
71500
  };
71328
71501
  const handleInputSubmit = () => {
71329
71502
  const value = inlineTextInput.value;
71330
- const cleanValue = value.replace(/[^0-9]/g, "");
71503
+ const cleanValue = value.match(/^\d+(\.5)?$/) ? value : Math.floor(parseFloat(value)).toString();
71331
71504
  emit("textSubmit", cleanValue);
71332
71505
  inlineTextInput.value = cleanValue;
71333
71506
  };
@@ -71409,7 +71582,7 @@ const _sfc_main$4$1 = {
71409
71582
  };
71410
71583
  }
71411
71584
  };
71412
- const ToolbarButton = /* @__PURE__ */ _export_sfc(_sfc_main$4$1, [["__scopeId", "data-v-303b3245"]]);
71585
+ const ToolbarButton = /* @__PURE__ */ _export_sfc(_sfc_main$4$1, [["__scopeId", "data-v-cea02a58"]]);
71413
71586
  const _hoisted_1$2$1 = {
71414
71587
  class: "toolbar-separator",
71415
71588
  role: "separator",