docx-diff-editor 1.0.9 → 1.0.14

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.mjs CHANGED
@@ -715,6 +715,74 @@ var DocxDiffEditor = forwardRef(
715
715
  }
716
716
  readyRef.current = false;
717
717
  }, []);
718
+ const convertHtmlToDocxBlob = useCallback(
719
+ async (html) => {
720
+ if (!SuperDocRef.current) {
721
+ throw new Error("SuperDoc not loaded");
722
+ }
723
+ const hiddenContainer = document.createElement("div");
724
+ hiddenContainer.id = `dde-hidden-${Date.now()}`;
725
+ hiddenContainer.style.cssText = "position:absolute;top:-9999px;left:-9999px;width:800px;height:600px;visibility:hidden;pointer-events:none;";
726
+ document.body.appendChild(hiddenContainer);
727
+ return new Promise((resolve, reject) => {
728
+ let resolved = false;
729
+ let tempSuperdoc = null;
730
+ const cleanup = () => {
731
+ try {
732
+ tempSuperdoc?.destroy?.();
733
+ } catch {
734
+ }
735
+ hiddenContainer.parentNode?.removeChild(hiddenContainer);
736
+ };
737
+ try {
738
+ tempSuperdoc = new SuperDocRef.current({
739
+ selector: `#${hiddenContainer.id}`,
740
+ html,
741
+ documentMode: "editing",
742
+ rulers: false,
743
+ user: { name: "Converter", email: "converter@local" },
744
+ onReady: async ({ superdoc: sd }) => {
745
+ if (resolved) return;
746
+ try {
747
+ const json = sd?.activeEditor?.getJSON() || { type: "doc", content: [] };
748
+ const blob = await sd?.activeEditor?.exportDocx({ isFinalDoc: true });
749
+ if (!blob) {
750
+ throw new Error("Export returned no data");
751
+ }
752
+ resolved = true;
753
+ cleanup();
754
+ resolve({ blob, json });
755
+ } catch (err) {
756
+ resolved = true;
757
+ cleanup();
758
+ reject(err);
759
+ }
760
+ },
761
+ onException: ({ error: err }) => {
762
+ if (resolved) return;
763
+ resolved = true;
764
+ cleanup();
765
+ reject(err);
766
+ }
767
+ });
768
+ setTimeout(() => {
769
+ if (!resolved) {
770
+ resolved = true;
771
+ cleanup();
772
+ reject(new Error("HTML to DOCX conversion timed out"));
773
+ }
774
+ }, TIMEOUTS.PARSE_TIMEOUT);
775
+ } catch (err) {
776
+ if (!resolved) {
777
+ resolved = true;
778
+ cleanup();
779
+ reject(err);
780
+ }
781
+ }
782
+ });
783
+ },
784
+ []
785
+ );
718
786
  const createSuperdoc = useCallback(
719
787
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
720
788
  async (options) => {
@@ -724,25 +792,29 @@ var DocxDiffEditor = forwardRef(
724
792
  if (!containerRef.current) {
725
793
  throw new Error("Container not available");
726
794
  }
795
+ containerRef.current.innerHTML = "";
796
+ if (toolbarRef.current) {
797
+ toolbarRef.current.innerHTML = "";
798
+ }
727
799
  containerRef.current.id = editorId;
728
800
  if (toolbarRef.current) {
729
801
  toolbarRef.current.id = toolbarId;
730
802
  }
731
803
  return new Promise((resolve, reject) => {
804
+ let resolved = false;
732
805
  try {
733
806
  const superdoc = new SuperDocRef.current({
734
807
  selector: `#${editorId}`,
735
808
  toolbar: showToolbar ? `#${toolbarId}` : void 0,
736
809
  document: options.document,
737
- html: options.html,
738
810
  documentMode: "editing",
739
811
  role: "editor",
740
812
  rulers: showRulers,
741
813
  user: DEFAULT_SUPERDOC_USER,
742
814
  permissionResolver,
743
- // Enable comments module for track changes sidebar
744
- modules: { comments: {} },
745
815
  onReady: ({ superdoc: sd }) => {
816
+ if (resolved) return;
817
+ resolved = true;
746
818
  superdocRef.current = sd;
747
819
  readyRef.current = true;
748
820
  let json = { type: "doc", content: [] };
@@ -756,18 +828,24 @@ var DocxDiffEditor = forwardRef(
756
828
  resolve({ superdoc: sd, json });
757
829
  },
758
830
  onException: ({ error: err }) => {
831
+ if (resolved) return;
832
+ resolved = true;
759
833
  console.error("SuperDoc error:", err);
760
834
  reject(err);
761
835
  }
762
836
  });
763
837
  superdocRef.current = superdoc;
764
838
  setTimeout(() => {
765
- if (!readyRef.current) {
839
+ if (!resolved) {
840
+ resolved = true;
766
841
  reject(new Error("SuperDoc initialization timed out"));
767
842
  }
768
843
  }, TIMEOUTS.PARSE_TIMEOUT);
769
844
  } catch (err) {
770
- reject(err);
845
+ if (!resolved) {
846
+ resolved = true;
847
+ reject(err);
848
+ }
771
849
  }
772
850
  });
773
851
  },
@@ -791,12 +869,15 @@ var DocxDiffEditor = forwardRef(
791
869
  const { SuperDoc } = await import('superdoc');
792
870
  SuperDocRef.current = SuperDoc;
793
871
  let initOptions = {};
872
+ let extractedJson = null;
794
873
  if (initialSource) {
795
874
  const contentType = detectContentType(initialSource);
796
875
  if (contentType === "file") {
797
876
  initOptions = { document: initialSource };
798
877
  } else if (contentType === "html") {
799
- initOptions = { html: initialSource };
878
+ const { blob, json: htmlJson } = await convertHtmlToDocxBlob(initialSource);
879
+ initOptions = { document: blob };
880
+ extractedJson = htmlJson;
800
881
  } else if (contentType === "json") {
801
882
  initOptions = templateDocx ? { document: templateDocx } : {};
802
883
  }
@@ -811,8 +892,9 @@ var DocxDiffEditor = forwardRef(
811
892
  onSourceLoaded?.(initialSource);
812
893
  }
813
894
  } else {
814
- setSourceJson(json);
815
- onSourceLoaded?.(json);
895
+ const sourceJsonToUse = extractedJson || json;
896
+ setSourceJson(sourceJsonToUse);
897
+ onSourceLoaded?.(sourceJsonToUse);
816
898
  }
817
899
  setIsLoading(false);
818
900
  onReady?.();
@@ -831,6 +913,7 @@ var DocxDiffEditor = forwardRef(
831
913
  onSourceLoaded,
832
914
  destroySuperdoc,
833
915
  createSuperdoc,
916
+ convertHtmlToDocxBlob,
834
917
  setEditorContent,
835
918
  handleError
836
919
  ]);
@@ -846,7 +929,10 @@ var DocxDiffEditor = forwardRef(
846
929
  ref,
847
930
  () => ({
848
931
  /**
849
- * Set the source/base document
932
+ * Set the source/base document.
933
+ *
934
+ * IMPORTANT: For HTML content, we convert to DOCX first using a hidden
935
+ * SuperDoc instance. This is required for track bubbles to work properly.
850
936
  */
851
937
  async setSource(content) {
852
938
  if (!SuperDocRef.current) {
@@ -862,8 +948,9 @@ var DocxDiffEditor = forwardRef(
862
948
  const result = await createSuperdoc({ document: content });
863
949
  json = result.json;
864
950
  } else if (contentType === "html") {
865
- const result = await createSuperdoc({ html: content });
866
- json = result.json;
951
+ const { blob, json: htmlJson } = await convertHtmlToDocxBlob(content);
952
+ const result = await createSuperdoc({ document: blob });
953
+ json = htmlJson;
867
954
  } else {
868
955
  const result = await createSuperdoc(templateDocx ? { document: templateDocx } : {});
869
956
  if (result.superdoc?.activeEditor && isProseMirrorJSON(content)) {
@@ -958,11 +1045,24 @@ var DocxDiffEditor = forwardRef(
958
1045
  const merged = mergeDocuments(sourceJson, newJson, diff, author);
959
1046
  setMergedJson(merged);
960
1047
  if (superdocRef.current?.activeEditor) {
961
- if (superdocRef.current.setDocumentMode) {
962
- superdocRef.current.setDocumentMode("suggesting");
963
- }
964
1048
  setEditorContent(superdocRef.current.activeEditor, merged);
965
1049
  enableReviewMode(superdocRef.current);
1050
+ const sd = superdocRef.current;
1051
+ if (sd.commentsStore?.processLoadedDocxComments) {
1052
+ setTimeout(() => {
1053
+ try {
1054
+ sd.commentsStore.processLoadedDocxComments({
1055
+ superdoc: sd,
1056
+ editor: sd.activeEditor,
1057
+ comments: [],
1058
+ // Empty array - we just want to trigger createCommentForTrackChanges
1059
+ documentId: sd.activeEditor?.options?.documentId || "primary"
1060
+ });
1061
+ } catch (err) {
1062
+ console.warn("[DocxDiffEditor] Failed to process track changes for bubbles:", err);
1063
+ }
1064
+ }, 50);
1065
+ }
966
1066
  }
967
1067
  const insertions = diff.segments.filter((s) => s.type === "insert").length;
968
1068
  const deletions = diff.segments.filter((s) => s.type === "delete").length;
@@ -1053,6 +1153,7 @@ var DocxDiffEditor = forwardRef(
1053
1153
  author,
1054
1154
  destroySuperdoc,
1055
1155
  createSuperdoc,
1156
+ convertHtmlToDocxBlob,
1056
1157
  setEditorContent,
1057
1158
  enableReviewMode,
1058
1159
  setEditingMode,