@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,4 +1,4 @@
1
- import { g as global$2, c as createElementBlock, o as openBlock, a as createBaseVNode, r as ref$1, b as createApp, d as computed, F as Fragment$1, e as renderList, n as normalizeClass, w as withModifiers, f as createCommentVNode, t as toDisplayString, i as inject, h as onBeforeMount, j as onMounted, k as onBeforeUnmount, l as watch, m as defineComponent, p as getCurrentInstance, q as onDeactivated, s as nextTick, u as createBlock, v as createVNode, x as unref, y as withCtx, z as createTextVNode, A as normalizeStyle, B as h$1, C as toRef, D as provide, E as mergeProps, G as cloneVNode, T as Text$2, H as withDirectives, I as watchEffect, J as shallowRef, K as vModelText, L as withKeys, M as reactive, N as readonly, O as Transition, P as vShow, Q as Comment, R as renderSlot, S as onActivated, U as Teleport, V as isVNode, W as onUnmounted, X as resolveDynamicComponent, Y as normalizeProps, Z as guardReactiveProps, _ as markRaw } from "./vue-CXxsqYcP.es.js";
1
+ import { g as global$2, c as createElementBlock, o as openBlock, a as createBaseVNode, r as ref$1, b as createApp, d as computed, F as Fragment$1, e as renderList, n as normalizeClass, w as withModifiers, f as createCommentVNode, t as toDisplayString, i as inject, h as onBeforeMount, j as onMounted, k as onBeforeUnmount, l as watch, m as defineComponent, p as getCurrentInstance, q as onDeactivated, s as nextTick, u as createBlock, v as createVNode, x as unref, y as withCtx, z as createTextVNode, A as normalizeStyle, B as h$1, C as toRef, D as provide, E as mergeProps, G as cloneVNode, T as Text$2, H as withDirectives, I as watchEffect, J as shallowRef, K as vModelText, L as withKeys, M as reactive, N as readonly, O as Transition, P as vShow, Q as Comment, R as renderSlot, S as onActivated, U as Teleport, V as isVNode, W as onUnmounted, X as resolveDynamicComponent, Y as normalizeProps, Z as guardReactiveProps, _ as markRaw } from "./vue-ZWZLQtoU.es.js";
2
2
  import * as Y from "yjs";
3
3
  import { UndoManager, Item as Item$2, ContentType, Text as Text$1, XmlElement, encodeStateAsUpdate } from "yjs";
4
4
  var __defProp$2 = Object.defineProperty;
@@ -5094,6 +5094,19 @@ function requireSafeRegexTest() {
5094
5094
  };
5095
5095
  return safeRegexTest;
5096
5096
  }
5097
+ var generatorFunction;
5098
+ var hasRequiredGeneratorFunction;
5099
+ function requireGeneratorFunction() {
5100
+ if (hasRequiredGeneratorFunction) return generatorFunction;
5101
+ hasRequiredGeneratorFunction = 1;
5102
+ const cached = (
5103
+ /** @type {GeneratorFunctionConstructor} */
5104
+ function* () {
5105
+ }.constructor
5106
+ );
5107
+ generatorFunction = () => cached;
5108
+ return generatorFunction;
5109
+ }
5097
5110
  var isGeneratorFunction;
5098
5111
  var hasRequiredIsGeneratorFunction;
5099
5112
  function requireIsGeneratorFunction() {
@@ -5106,16 +5119,7 @@ function requireIsGeneratorFunction() {
5106
5119
  var getProto2 = requireGetProto();
5107
5120
  var toStr = callBound2("Object.prototype.toString");
5108
5121
  var fnToStr = callBound2("Function.prototype.toString");
5109
- var getGeneratorFunc = function() {
5110
- if (!hasToStringTag) {
5111
- return false;
5112
- }
5113
- try {
5114
- return Function("return function*() {}")();
5115
- } catch (e) {
5116
- }
5117
- };
5118
- var GeneratorFunction;
5122
+ var getGeneratorFunction = /* @__PURE__ */ requireGeneratorFunction();
5119
5123
  isGeneratorFunction = function isGeneratorFunction2(fn2) {
5120
5124
  if (typeof fn2 !== "function") {
5121
5125
  return false;
@@ -5130,14 +5134,8 @@ function requireIsGeneratorFunction() {
5130
5134
  if (!getProto2) {
5131
5135
  return false;
5132
5136
  }
5133
- if (typeof GeneratorFunction === "undefined") {
5134
- var generatorFunc = getGeneratorFunc();
5135
- GeneratorFunction = generatorFunc ? (
5136
- /** @type {GeneratorFunctionConstructor} */
5137
- getProto2(generatorFunc)
5138
- ) : false;
5139
- }
5140
- return getProto2(fn2) === GeneratorFunction;
5137
+ var GeneratorFunction = getGeneratorFunction();
5138
+ return GeneratorFunction && getProto2(fn2) === GeneratorFunction.prototype;
5141
5139
  };
5142
5140
  return isGeneratorFunction;
5143
5141
  }
@@ -31878,7 +31876,8 @@ generateXml_fn = function(node) {
31878
31876
  }
31879
31877
  if (elements) {
31880
31878
  if (name === "w:instrText") {
31881
- tags.push(elements[0].text);
31879
+ const textContent2 = (elements || []).map((child) => typeof child?.text === "string" ? child.text : "").join("");
31880
+ tags.push(__privateMethod$2(this, _DocxExporter_instances, replaceSpecialCharacters_fn).call(this, textContent2));
31882
31881
  } else if (name === "w:t" || name === "w:delText" || name === "wp:posOffset") {
31883
31882
  try {
31884
31883
  let text = String(elements[0].text);
@@ -42074,8 +42073,7 @@ function readDOMChange(view, from2, to, typeOver, addedNodes) {
42074
42073
  let $to = parse.doc.resolveNoCache(change.endB - parse.from);
42075
42074
  let $fromA = doc2.resolve(change.start);
42076
42075
  let inlineChange = $from.sameParent($to) && $from.parent.inlineContent && $fromA.end() >= change.endA;
42077
- let nextSel;
42078
- 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")))) {
42076
+ 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")))) {
42079
42077
  view.input.lastIOSEnter = 0;
42080
42078
  return;
42081
42079
  }
@@ -48729,26 +48727,100 @@ const onHeaderFooterDataUpdate = async ({ editor, transaction }, mainEditor, sec
48729
48727
  const setEditorToolbar = ({ editor }, mainEditor) => {
48730
48728
  editor.setToolbar(mainEditor.toolbar);
48731
48729
  };
48730
+ const normalizeCommentEventPayload = ({ conversation, editorOptions, fallbackCommentId, fallbackInternal }) => {
48731
+ const { user, documentId } = editorOptions || {};
48732
+ const normalized = {
48733
+ ...conversation,
48734
+ commentId: conversation?.commentId ?? fallbackCommentId,
48735
+ isInternal: conversation?.isInternal ?? fallbackInternal
48736
+ };
48737
+ if (!normalized.commentText && normalized.text) {
48738
+ normalized.commentText = normalized.text;
48739
+ delete normalized.text;
48740
+ }
48741
+ if ("skipEmit" in normalized) delete normalized.skipEmit;
48742
+ if (!normalized.creatorName && user?.name) {
48743
+ normalized.creatorName = user.name;
48744
+ }
48745
+ if (!normalized.creatorEmail && user?.email) {
48746
+ normalized.creatorEmail = user.email;
48747
+ }
48748
+ if (!normalized.createdTime) {
48749
+ normalized.createdTime = Date.now();
48750
+ }
48751
+ if (!normalized.fileId && documentId) {
48752
+ normalized.fileId = documentId;
48753
+ }
48754
+ if (!normalized.documentId && documentId) {
48755
+ normalized.documentId = documentId;
48756
+ }
48757
+ return normalized;
48758
+ };
48759
+ const updatePosition = ({ allCommentPositions, threadId, pos, currentBounds, node }) => {
48760
+ let bounds = {};
48761
+ if (currentBounds instanceof DOMRect) {
48762
+ bounds = {
48763
+ top: currentBounds.top,
48764
+ bottom: currentBounds.bottom,
48765
+ left: currentBounds.left,
48766
+ right: currentBounds.right
48767
+ };
48768
+ } else {
48769
+ bounds = { ...currentBounds };
48770
+ }
48771
+ if (!allCommentPositions[threadId]) {
48772
+ allCommentPositions[threadId] = {
48773
+ threadId,
48774
+ start: pos,
48775
+ end: pos + node.nodeSize,
48776
+ bounds
48777
+ };
48778
+ } else {
48779
+ const existing = allCommentPositions[threadId];
48780
+ existing.start = Math.min(existing.start, pos);
48781
+ existing.end = Math.max(existing.end, pos + node.nodeSize);
48782
+ existing.bounds.top = Math.min(existing.bounds.top, currentBounds.top);
48783
+ existing.bounds.bottom = Math.max(existing.bounds.bottom, currentBounds.bottom);
48784
+ }
48785
+ };
48732
48786
  const TRACK_CHANGE_MARKS = [TrackInsertMarkName, TrackDeleteMarkName, TrackFormatMarkName];
48733
48787
  const CommentsPluginKey = new PluginKey("comments");
48734
48788
  const CommentsPlugin = Extension.create({
48735
48789
  name: "comments",
48736
48790
  addCommands() {
48737
48791
  return {
48738
- insertComment: (conversation) => ({ tr, dispatch }) => {
48792
+ insertComment: (conversation = {}) => ({ tr, dispatch }) => {
48739
48793
  const { selection } = tr;
48740
48794
  const { $from, $to } = selection;
48741
- const { commentId, isInternal } = conversation;
48795
+ const skipEmit = conversation?.skipEmit;
48796
+ const resolvedCommentId = conversation?.commentId ?? v4();
48797
+ const resolvedInternal = conversation?.isInternal ?? false;
48742
48798
  tr.setMeta(CommentsPluginKey, { event: "add" });
48743
48799
  tr.addMark(
48744
48800
  $from.pos,
48745
48801
  $to.pos,
48746
48802
  this.editor.schema.marks[CommentMarkName].create({
48747
- commentId,
48748
- internal: isInternal
48803
+ commentId: resolvedCommentId,
48804
+ internal: resolvedInternal
48749
48805
  })
48750
48806
  );
48751
- dispatch(tr);
48807
+ if (dispatch) dispatch(tr);
48808
+ const shouldEmit = !skipEmit && resolvedCommentId !== "pending";
48809
+ if (shouldEmit) {
48810
+ const commentPayload = normalizeCommentEventPayload({
48811
+ conversation,
48812
+ editorOptions: this.editor.options,
48813
+ fallbackCommentId: resolvedCommentId,
48814
+ fallbackInternal: resolvedInternal
48815
+ });
48816
+ const activeCommentId = commentPayload.commentId || commentPayload.importedId || null;
48817
+ const event = {
48818
+ type: comments_module_events.ADD,
48819
+ comment: commentPayload,
48820
+ ...activeCommentId && { activeCommentId }
48821
+ };
48822
+ this.editor.emit("commentsUpdate", event);
48823
+ }
48752
48824
  return true;
48753
48825
  },
48754
48826
  removeComment: ({ commentId, importedId }) => ({ tr, dispatch, state: state2 }) => {
@@ -48984,33 +49056,6 @@ const CommentsPlugin = Extension.create({
48984
49056
  return [commentsPlugin];
48985
49057
  }
48986
49058
  });
48987
- const updatePosition = ({ allCommentPositions, threadId, pos, currentBounds, node }) => {
48988
- let bounds = {};
48989
- if (currentBounds instanceof DOMRect) {
48990
- bounds = {
48991
- top: currentBounds.top,
48992
- bottom: currentBounds.bottom,
48993
- left: currentBounds.left,
48994
- right: currentBounds.right
48995
- };
48996
- } else {
48997
- bounds = { ...currentBounds };
48998
- }
48999
- if (!allCommentPositions[threadId]) {
49000
- allCommentPositions[threadId] = {
49001
- threadId,
49002
- start: pos,
49003
- end: pos + node.nodeSize,
49004
- bounds
49005
- };
49006
- } else {
49007
- const existing = allCommentPositions[threadId];
49008
- existing.start = Math.min(existing.start, pos);
49009
- existing.end = Math.max(existing.end, pos + node.nodeSize);
49010
- existing.bounds.top = Math.min(existing.bounds.top, currentBounds.top);
49011
- existing.bounds.bottom = Math.max(existing.bounds.bottom, currentBounds.bottom);
49012
- }
49013
- };
49014
49059
  const getActiveCommentId = (doc2, selection) => {
49015
49060
  if (!selection) return;
49016
49061
  const { $from, $to } = selection;
@@ -54219,6 +54264,17 @@ function getStructuredContentTagsById(idOrIds, state2) {
54219
54264
  });
54220
54265
  return result;
54221
54266
  }
54267
+ function getStructuredContentTagsByAlias(aliasOrAliases, state2) {
54268
+ const result = findChildren$5(state2.doc, (node) => {
54269
+ const isStructuredContent = ["structuredContent", "structuredContentBlock"].includes(node.type.name);
54270
+ if (Array.isArray(aliasOrAliases)) {
54271
+ return isStructuredContent && aliasOrAliases.includes(node.attrs.alias);
54272
+ } else {
54273
+ return isStructuredContent && node.attrs.alias === aliasOrAliases;
54274
+ }
54275
+ });
54276
+ return result;
54277
+ }
54222
54278
  function getStructuredContentTags(state2) {
54223
54279
  const result = findChildren$5(state2.doc, (node) => {
54224
54280
  return node.type.name === "structuredContent" || node.type.name === "structuredContentBlock";
@@ -54238,6 +54294,7 @@ const structuredContentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ O
54238
54294
  getStructuredContentBlockTags,
54239
54295
  getStructuredContentInlineTags,
54240
54296
  getStructuredContentTags,
54297
+ getStructuredContentTagsByAlias,
54241
54298
  getStructuredContentTagsById
54242
54299
  }, Symbol.toStringTag, { value: "Module" }));
54243
54300
  const STRUCTURED_CONTENT_NAMES = ["structuredContent", "structuredContentBlock"];
@@ -54326,10 +54383,11 @@ const StructuredContentCommands = Extension.create({
54326
54383
  return true;
54327
54384
  },
54328
54385
  /**
54329
- * Updates a structured content attributes or content.
54386
+ * Updates a single structured content field by its unique ID.
54387
+ * IDs are unique identifiers, so this will update at most one field.
54330
54388
  * If the updated node does not match the schema, it will not be updated.
54331
54389
  * @category Command
54332
- * @param {string} id
54390
+ * @param {string} id - Unique identifier of the field
54333
54391
  * @param {StructuredContentUpdate} options
54334
54392
  */
54335
54393
  updateStructuredContentById: (id, options = {}) => ({ editor, dispatch, state: state2, tr }) => {
@@ -54369,6 +54427,58 @@ const StructuredContentCommands = Extension.create({
54369
54427
  }
54370
54428
  return true;
54371
54429
  },
54430
+ /**
54431
+ * Updates all structured content fields with the same alias.
54432
+ * Unlike IDs (which are unique), aliases can be shared across multiple fields.
54433
+ * This will update every field that matches the given alias.
54434
+ * If any updated node does not match the schema, no updates will be applied.
54435
+ * @category Command
54436
+ * @param {string | string[]} alias - Shared identifier for fields (e.g., "customer_name")
54437
+ * @param {StructuredContentUpdate} options
54438
+ */
54439
+ updateStructuredContentByAlias: (alias, options = {}) => ({ editor, dispatch, state: state2, tr }) => {
54440
+ const structuredContentTags = getStructuredContentTagsByAlias(alias, state2);
54441
+ if (!structuredContentTags.length) {
54442
+ return true;
54443
+ }
54444
+ const { schema } = editor;
54445
+ const createContent = (node) => {
54446
+ if (options.text) {
54447
+ return schema.text(options.text);
54448
+ }
54449
+ if (options.html) {
54450
+ const html = htmlHandler(options.html, editor);
54451
+ const doc2 = DOMParser$1.fromSchema(schema).parse(html);
54452
+ return doc2.content;
54453
+ }
54454
+ if (options.json) {
54455
+ return schema.nodeFromJSON(options.json);
54456
+ }
54457
+ return node.content;
54458
+ };
54459
+ for (const { node } of structuredContentTags) {
54460
+ const content = createContent(node);
54461
+ const updatedNode = node.type.create({ ...node.attrs, ...options.attrs }, content, node.marks);
54462
+ try {
54463
+ updatedNode.check();
54464
+ } catch {
54465
+ console.error("Updated node does not conform to the schema");
54466
+ return false;
54467
+ }
54468
+ }
54469
+ if (dispatch) {
54470
+ structuredContentTags.forEach(({ pos, node }) => {
54471
+ const mappedPos = tr.mapping.map(pos);
54472
+ const currentNode = tr.doc.nodeAt(mappedPos);
54473
+ if (currentNode && node.eq(currentNode)) {
54474
+ const content = createContent(node);
54475
+ const updatedNode = node.type.create({ ...node.attrs, ...options.attrs }, content, node.marks);
54476
+ tr.replaceWith(mappedPos, mappedPos + node.nodeSize, updatedNode);
54477
+ }
54478
+ });
54479
+ }
54480
+ return true;
54481
+ },
54372
54482
  /**
54373
54483
  * Removes a structured content.
54374
54484
  * @category Command
@@ -62510,6 +62620,7 @@ function getFormatAttrsFromMarks(marks) {
62510
62620
  }
62511
62621
  return formatAttrs;
62512
62622
  }
62623
+ const DEFAULT_MIME_TYPE = "application/octet-stream";
62513
62624
  const simpleHash = (str) => {
62514
62625
  let hash2 = 0;
62515
62626
  for (let i = 0; i < str.length; i++) {
@@ -62519,21 +62630,40 @@ const simpleHash = (str) => {
62519
62630
  }
62520
62631
  return Math.abs(hash2).toString();
62521
62632
  };
62522
- const base64ToFile = (base64String) => {
62523
- const arr = base64String.split(",");
62524
- const mimeMatch = arr[0].match(/:(.*?);/);
62525
- const mimeType = mimeMatch ? mimeMatch[1] : "";
62526
- const data = arr[1];
62527
- const binaryString = atob(data);
62633
+ const decodeBase64ToBinaryString = (data) => {
62634
+ if (!data) return "";
62635
+ if (typeof atob === "function") {
62636
+ return atob(data);
62637
+ }
62638
+ if (typeof Buffer2 !== "undefined" && typeof Buffer2.from === "function") {
62639
+ return Buffer2.from(data, "base64").toString("binary");
62640
+ }
62641
+ throw new Error("Unable to decode base64 payload in the current environment.");
62642
+ };
62643
+ const extractBase64Meta = (base64String) => {
62644
+ const [meta = "", payload = ""] = base64String.split(",");
62645
+ const mimeMatch = meta.match(/:(.*?);/);
62646
+ const rawMimeType = mimeMatch ? mimeMatch[1] : "";
62647
+ const mimeType = rawMimeType || DEFAULT_MIME_TYPE;
62648
+ const binaryString = decodeBase64ToBinaryString(payload);
62528
62649
  const hash2 = simpleHash(binaryString);
62529
62650
  const extension = mimeType.split("/")[1] || "bin";
62530
62651
  const filename = `image-${hash2}.${extension}`;
62652
+ return { mimeType, binaryString, filename };
62653
+ };
62654
+ const getBase64FileMeta = (base64String) => {
62655
+ const { mimeType, filename } = extractBase64Meta(base64String);
62656
+ return { mimeType, filename };
62657
+ };
62658
+ const base64ToFile = (base64String) => {
62659
+ const { mimeType, binaryString, filename } = extractBase64Meta(base64String);
62660
+ const fileType = mimeType || DEFAULT_MIME_TYPE;
62531
62661
  const bytes = new Uint8Array(binaryString.length);
62532
62662
  for (let i = 0; i < binaryString.length; i++) {
62533
62663
  bytes[i] = binaryString.charCodeAt(i);
62534
62664
  }
62535
- const blob = new Blob([bytes], { type: mimeType });
62536
- return new File([blob], filename, { type: mimeType });
62665
+ const blob = new Blob([bytes], { type: fileType });
62666
+ return new File([blob], filename, { type: fileType });
62537
62667
  };
62538
62668
  const urlToFile = async (url, filename, mimeType) => {
62539
62669
  try {
@@ -62909,6 +63039,7 @@ function addImageRelationship({ editor, path }) {
62909
63039
  }
62910
63040
  }
62911
63041
  const key = new PluginKey("ImageRegistration");
63042
+ const WORD_MEDIA_PREFIX = "word/";
62912
63043
  const ImageRegistrationPlugin = ({ editor }) => {
62913
63044
  const { view } = editor;
62914
63045
  return new Plugin({
@@ -62929,16 +63060,16 @@ const ImageRegistrationPlugin = ({ editor }) => {
62929
63060
  },
62930
63061
  appendTransaction: (trs, _oldState, state2) => {
62931
63062
  let foundImages = [];
62932
- trs.forEach((tr2) => {
62933
- if (tr2.docChanged) {
62934
- tr2.steps.forEach((step, index2) => {
63063
+ trs.forEach((tr) => {
63064
+ if (tr.docChanged) {
63065
+ tr.steps.forEach((step, index2) => {
62935
63066
  const stepMap = step.getMap();
62936
63067
  foundImages = foundImages.map(({ node, pos, id }) => {
62937
63068
  const mappedPos = stepMap.map(pos, -1);
62938
63069
  return { node, pos: mappedPos, id };
62939
63070
  });
62940
63071
  if (step instanceof ReplaceStep || step instanceof ReplaceAroundStep$1) {
62941
- (tr2.docs[index2 + 1] || tr2.doc).nodesBetween(
63072
+ (tr.docs[index2 + 1] || tr.doc).nodesBetween(
62942
63073
  stepMap.map(step.from, -1),
62943
63074
  stepMap.map(step.to, 1),
62944
63075
  (node, pos) => {
@@ -62957,22 +63088,10 @@ const ImageRegistrationPlugin = ({ editor }) => {
62957
63088
  if (!foundImages || foundImages.length === 0) {
62958
63089
  return null;
62959
63090
  }
62960
- registerImages(foundImages, editor, view);
62961
- const tr = state2.tr;
62962
- let { set } = key.getState(state2);
62963
- foundImages.slice().sort((a, b2) => a.pos - b2.pos).forEach(({ pos, id }) => {
62964
- let deco = Decoration.widget(pos, () => document.createElement("placeholder"), {
62965
- side: -1,
62966
- id
62967
- });
62968
- set = set.add(tr.doc, [deco]);
62969
- });
62970
- foundImages.slice().sort((a, b2) => b2.pos - a.pos).forEach(({ node, pos }) => {
62971
- tr.delete(pos, pos + node.nodeSize);
62972
- });
62973
- set = set.map(tr.mapping, tr.doc);
62974
- tr.setMeta(key, { set });
62975
- return tr;
63091
+ if (editor.options.isHeadless) {
63092
+ return handleNodePath(foundImages, editor, state2);
63093
+ }
63094
+ return handleBrowserPath(foundImages, editor, view, state2);
62976
63095
  },
62977
63096
  props: {
62978
63097
  decorations(state2) {
@@ -62982,6 +63101,59 @@ const ImageRegistrationPlugin = ({ editor }) => {
62982
63101
  }
62983
63102
  });
62984
63103
  };
63104
+ const derivePreferredFileName = (src) => {
63105
+ if (typeof src !== "string" || src.length === 0) {
63106
+ return "image.bin";
63107
+ }
63108
+ if (src.startsWith("data:")) {
63109
+ return getBase64FileMeta(src).filename;
63110
+ }
63111
+ const lastSegment = src.split("/").pop() ?? "";
63112
+ const trimmed = lastSegment.split(/[?#]/)[0];
63113
+ return trimmed || "image.bin";
63114
+ };
63115
+ const handleNodePath = (foundImages, editor, state2) => {
63116
+ const { tr } = state2;
63117
+ const mediaStore = editor.storage.image.media ?? {};
63118
+ if (!editor.storage.image.media) {
63119
+ editor.storage.image.media = mediaStore;
63120
+ }
63121
+ const existingFileNames = new Set(Object.keys(mediaStore).map((key2) => key2.split("/").pop()));
63122
+ foundImages.forEach(({ node, pos }) => {
63123
+ const { src } = node.attrs;
63124
+ const preferredFileName = derivePreferredFileName(src);
63125
+ const uniqueFileName = ensureUniqueFileName(preferredFileName, existingFileNames);
63126
+ existingFileNames.add(uniqueFileName);
63127
+ const mediaPath = buildMediaPath(uniqueFileName);
63128
+ mediaStore[mediaPath] = src;
63129
+ const path = mediaPath.startsWith(WORD_MEDIA_PREFIX) ? mediaPath.slice(WORD_MEDIA_PREFIX.length) : mediaPath;
63130
+ const rId = addImageRelationship({ editor, path });
63131
+ tr.setNodeMarkup(pos, void 0, {
63132
+ ...node.attrs,
63133
+ src: mediaPath,
63134
+ rId
63135
+ });
63136
+ });
63137
+ return tr;
63138
+ };
63139
+ const handleBrowserPath = (foundImages, editor, view, state2) => {
63140
+ registerImages(foundImages, editor, view);
63141
+ const tr = state2.tr;
63142
+ let { set } = key.getState(state2);
63143
+ foundImages.slice().sort((a, b2) => a.pos - b2.pos).forEach(({ pos, id }) => {
63144
+ let deco = Decoration.widget(pos, () => document.createElement("placeholder"), {
63145
+ side: -1,
63146
+ id
63147
+ });
63148
+ set = set.add(tr.doc, [deco]);
63149
+ });
63150
+ foundImages.slice().sort((a, b2) => b2.pos - a.pos).forEach(({ node, pos }) => {
63151
+ tr.delete(pos, pos + node.nodeSize);
63152
+ });
63153
+ set = set.map(tr.mapping, tr.doc);
63154
+ tr.setMeta(key, { set });
63155
+ return tr;
63156
+ };
62985
63157
  const findPlaceholder = (state2, id) => {
62986
63158
  let { set } = key.getState(state2);
62987
63159
  let found2 = set?.find(null, null, (spec) => spec.id === id);
@@ -70099,6 +70271,7 @@ function getActualBreakCoords(view, pos, calculatedThreshold) {
70099
70271
  return actualBreak;
70100
70272
  }
70101
70273
  const onImageLoad = (editor) => {
70274
+ if (typeof requestAnimationFrame !== "function") return;
70102
70275
  requestAnimationFrame(() => {
70103
70276
  const newTr = editor.view.state.tr;
70104
70277
  newTr.setMeta("forceUpdatePagination", true);
@@ -71310,7 +71483,7 @@ const _sfc_main$4$1 = {
71310
71483
  };
71311
71484
  const handleInputSubmit = () => {
71312
71485
  const value = inlineTextInput.value;
71313
- const cleanValue = value.replace(/[^0-9]/g, "");
71486
+ const cleanValue = value.match(/^\d+(\.5)?$/) ? value : Math.floor(parseFloat(value)).toString();
71314
71487
  emit("textSubmit", cleanValue);
71315
71488
  inlineTextInput.value = cleanValue;
71316
71489
  };
@@ -71392,7 +71565,7 @@ const _sfc_main$4$1 = {
71392
71565
  };
71393
71566
  }
71394
71567
  };
71395
- const ToolbarButton = /* @__PURE__ */ _export_sfc(_sfc_main$4$1, [["__scopeId", "data-v-303b3245"]]);
71568
+ const ToolbarButton = /* @__PURE__ */ _export_sfc(_sfc_main$4$1, [["__scopeId", "data-v-cea02a58"]]);
71396
71569
  const _hoisted_1$2$1 = {
71397
71570
  class: "toolbar-separator",
71398
71571
  role: "separator",