docx-diff-editor 1.0.58 → 1.0.59
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/README.md +13 -0
- package/dist/index.js +80 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +80 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -269,6 +269,11 @@ Convert HTML strings to ProseMirror JSON without visible rendering. **Inline sty
|
|
|
269
269
|
const json = await editorRef.current?.parseHtml('<h1>Title</h1><p>Content here</p>');
|
|
270
270
|
console.log(json); // { type: 'doc', content: [...] }
|
|
271
271
|
|
|
272
|
+
// Lists work correctly - numbering definitions are synced to the main document
|
|
273
|
+
const listJson = await editorRef.current?.parseHtml(
|
|
274
|
+
'<ul><li>Item 1</li><li>Item 2</li></ul>'
|
|
275
|
+
);
|
|
276
|
+
|
|
272
277
|
// Inline styles are converted to marks
|
|
273
278
|
const styledJson = await editorRef.current?.parseHtml(
|
|
274
279
|
'<p><span style="color: red; font-weight: bold;">styled text</span></p>'
|
|
@@ -283,6 +288,14 @@ import { parseHtmlToJson } from 'docx-diff-editor';
|
|
|
283
288
|
const json = await parseHtmlToJson(htmlString, SuperDocClass);
|
|
284
289
|
```
|
|
285
290
|
|
|
291
|
+
### Linked Parsing for Lists
|
|
292
|
+
|
|
293
|
+
When the main editor is ready, `parseHtml()` automatically uses a **linked child editor** approach. This ensures that list numbering definitions (for `<ol>` and `<ul>` elements) are synced to the main document's numbering store.
|
|
294
|
+
|
|
295
|
+
This prevents crashes when parsed content with lists is later spliced into the main document and rendered via `compareWith()`.
|
|
296
|
+
|
|
297
|
+
If the main editor isn't ready yet, the method falls back to an isolated SuperDoc instance.
|
|
298
|
+
|
|
286
299
|
### Supported Inline Styles
|
|
287
300
|
|
|
288
301
|
| CSS Property | ProseMirror Mark |
|
package/dist/index.js
CHANGED
|
@@ -970,6 +970,67 @@ async function parseHtmlToJson(html, SuperDoc) {
|
|
|
970
970
|
}, 50);
|
|
971
971
|
});
|
|
972
972
|
}
|
|
973
|
+
async function parseHtmlWithLinkedEditor(html, mainEditor) {
|
|
974
|
+
const container = document.createElement("div");
|
|
975
|
+
container.style.cssText = "position:absolute;top:-9999px;left:-9999px;width:800px;height:600px;visibility:hidden;";
|
|
976
|
+
document.body.appendChild(container);
|
|
977
|
+
return new Promise((resolve, reject) => {
|
|
978
|
+
let resolved = false;
|
|
979
|
+
let childEditor = null;
|
|
980
|
+
const cleanup = () => {
|
|
981
|
+
setTimeout(() => {
|
|
982
|
+
if (childEditor) {
|
|
983
|
+
try {
|
|
984
|
+
childEditor.destroy?.();
|
|
985
|
+
} catch {
|
|
986
|
+
}
|
|
987
|
+
childEditor = null;
|
|
988
|
+
}
|
|
989
|
+
if (container.parentNode) {
|
|
990
|
+
container.parentNode.removeChild(container);
|
|
991
|
+
}
|
|
992
|
+
}, TIMEOUTS.CLEANUP_DELAY);
|
|
993
|
+
};
|
|
994
|
+
try {
|
|
995
|
+
mainEditor.createChildEditor({
|
|
996
|
+
element: container,
|
|
997
|
+
html,
|
|
998
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
999
|
+
onCreate: ({ editor: localEditor }) => {
|
|
1000
|
+
if (resolved) return;
|
|
1001
|
+
try {
|
|
1002
|
+
childEditor = localEditor;
|
|
1003
|
+
const json = localEditor.getJSON();
|
|
1004
|
+
const normalizedJson = normalizeRunProperties(json);
|
|
1005
|
+
resolved = true;
|
|
1006
|
+
cleanup();
|
|
1007
|
+
resolve(normalizedJson);
|
|
1008
|
+
} catch (err) {
|
|
1009
|
+
resolved = true;
|
|
1010
|
+
cleanup();
|
|
1011
|
+
reject(err);
|
|
1012
|
+
}
|
|
1013
|
+
},
|
|
1014
|
+
onError: (error) => {
|
|
1015
|
+
if (resolved) return;
|
|
1016
|
+
resolved = true;
|
|
1017
|
+
cleanup();
|
|
1018
|
+
reject(error);
|
|
1019
|
+
}
|
|
1020
|
+
});
|
|
1021
|
+
setTimeout(() => {
|
|
1022
|
+
if (!resolved) {
|
|
1023
|
+
resolved = true;
|
|
1024
|
+
cleanup();
|
|
1025
|
+
reject(new Error("Linked HTML parsing timed out"));
|
|
1026
|
+
}
|
|
1027
|
+
}, TIMEOUTS.PARSE_TIMEOUT);
|
|
1028
|
+
} catch (err) {
|
|
1029
|
+
cleanup();
|
|
1030
|
+
reject(err);
|
|
1031
|
+
}
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
973
1034
|
async function parseDocxFile(file, SuperDoc) {
|
|
974
1035
|
const container = document.createElement("div");
|
|
975
1036
|
container.style.cssText = "position:absolute;top:-9999px;left:-9999px;width:800px;height:600px;visibility:hidden;";
|
|
@@ -3672,13 +3733,30 @@ var DocxDiffEditor = react.forwardRef(
|
|
|
3672
3733
|
}
|
|
3673
3734
|
},
|
|
3674
3735
|
/**
|
|
3675
|
-
* Parse HTML string to ProseMirror JSON
|
|
3676
|
-
*
|
|
3736
|
+
* Parse HTML string to ProseMirror JSON.
|
|
3737
|
+
*
|
|
3738
|
+
* When the main editor is ready, this uses a linked child editor approach
|
|
3739
|
+
* which ensures list numbering definitions are synced to the main document.
|
|
3740
|
+
* This prevents crashes when parsed content with lists is spliced into
|
|
3741
|
+
* the main document via compareWith().
|
|
3742
|
+
*
|
|
3743
|
+
* Falls back to an isolated SuperDoc instance if the main editor isn't ready.
|
|
3677
3744
|
*/
|
|
3678
3745
|
async parseHtml(html) {
|
|
3679
3746
|
if (!SuperDocRef.current) {
|
|
3680
3747
|
throw new Error("Editor not initialized");
|
|
3681
3748
|
}
|
|
3749
|
+
const mainEditor = superdocRef.current?.activeEditor;
|
|
3750
|
+
if (mainEditor?.createChildEditor) {
|
|
3751
|
+
try {
|
|
3752
|
+
return await parseHtmlWithLinkedEditor(html, mainEditor);
|
|
3753
|
+
} catch (err) {
|
|
3754
|
+
console.warn(
|
|
3755
|
+
"[DocxDiffEditor] Linked HTML parsing failed, falling back to isolated approach:",
|
|
3756
|
+
err
|
|
3757
|
+
);
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3682
3760
|
return parseHtmlToJson(html, SuperDocRef.current);
|
|
3683
3761
|
}
|
|
3684
3762
|
}),
|