@stll/folio-core 0.44.0 → 0.46.0
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/ai-edits/__fixtures__/paragraphs.js +2 -2
- package/dist/ai-edits/apply.js +59 -19
- package/dist/ai-edits/headless.js +2 -1
- package/dist/compare/compare.js +2 -5
- package/dist/compare/content-alignment.js +78 -53
- package/dist/compare/inline-atoms.js +34 -20
- package/dist/compare/scenario.js +2 -5
- package/dist/compare/types.d.ts +9 -1
- package/dist/compare/types.js +12 -1
- package/dist/compat/eigenpal.d.ts +2 -1
- package/dist/compat/eigenpal.js +2 -1
- package/dist/content-controls/checkboxDisplay.d.ts +11 -0
- package/dist/content-controls/checkboxDisplay.js +40 -0
- package/dist/content-controls/findContentControls.js +3 -1
- package/dist/content-controls/mutateContentControls.js +21 -4
- package/dist/controller/contentControlWidgetController.d.ts +1 -0
- package/dist/controller/contentControlWidgetController.js +3 -0
- package/dist/controller/hiddenEditorApi.js +3 -1
- package/dist/controller/hiddenEditorManager.d.ts +1 -1
- package/dist/controller/hiddenEditorManager.js +6 -3
- package/dist/display-list/build/buildDisplayList.js +20 -1
- package/dist/display-list/build/imagePrimitives.d.ts +1 -1
- package/dist/display-list/build/imagePrimitives.js +3 -1
- package/dist/display-list/build/paragraphPrimitives.js +21 -2
- package/dist/display-list/dom/renderDisplayListToDom.js +18 -10
- package/dist/display-list/types.d.ts +17 -0
- package/dist/document-operations.js +14 -3
- package/dist/docx/attributeRemainder.d.ts +43 -0
- package/dist/docx/attributeRemainder.js +65 -0
- package/dist/docx/blockContentParser.d.ts +1 -1
- package/dist/docx/blockContentParser.js +87 -63
- package/dist/docx/blockPlainText.d.ts +3 -4
- package/dist/docx/blockPlainText.js +1 -0
- package/dist/docx/bookmarkPlacement.js +2 -0
- package/dist/docx/borderParser.js +5 -5
- package/dist/docx/commentAnchorIndex.d.ts +30 -0
- package/dist/docx/commentAnchorIndex.js +50 -0
- package/dist/docx/commentParser.d.ts +1 -1
- package/dist/docx/commentParser.js +78 -50
- package/dist/docx/commentRangeIntegrity.d.ts +16 -1
- package/dist/docx/commentRangeIntegrity.js +42 -1
- package/dist/docx/commentRangeJoin.d.ts +9 -0
- package/dist/docx/commentRangeJoin.js +33 -0
- package/dist/docx/commentReferenceCompletion.d.ts +9 -0
- package/dist/docx/commentReferenceCompletion.js +47 -0
- package/dist/docx/commentReferenceNormalization.js +1 -0
- package/dist/docx/commentReplyMarkers.js +11 -19
- package/dist/docx/commentThreadKey.d.ts +18 -0
- package/dist/docx/commentThreadKey.js +22 -0
- package/dist/docx/compatibility.js +1 -0
- package/dist/docx/containerChildren.d.ts +111 -0
- package/dist/docx/containerChildren.gen.d.ts +28 -0
- package/dist/docx/containerChildren.gen.js +246 -0
- package/dist/docx/containerChildren.js +103 -0
- package/dist/docx/diagramPreview.js +87 -27
- package/dist/docx/documentParser.d.ts +1 -1
- package/dist/docx/documentParser.js +3 -3
- package/dist/docx/ensureParaIds.js +17 -7
- package/dist/docx/fieldParser.d.ts +1 -1
- package/dist/docx/fieldParser.js +4 -4
- package/dist/docx/fieldState.d.ts +26 -0
- package/dist/docx/fieldState.js +53 -0
- package/dist/docx/footnoteParser.d.ts +1 -1
- package/dist/docx/graphicFrameLocks.d.ts +16 -4
- package/dist/docx/graphicFrameLocks.js +19 -6
- package/dist/docx/groupDrawingParser.js +3 -3
- package/dist/docx/headerFooterParser.js +1 -1
- package/dist/docx/headerFooterReferenceNormalization.js +1 -0
- package/dist/docx/hyperlinkParser.d.ts +27 -8
- package/dist/docx/hyperlinkParser.js +78 -20
- package/dist/docx/imageParser.d.ts +9 -1
- package/dist/docx/imageParser.js +91 -20
- package/dist/docx/imageRawXml.d.ts +14 -1
- package/dist/docx/imageRawXml.js +30 -6
- package/dist/docx/inlineWrapperContent.d.ts +85 -0
- package/dist/docx/inlineWrapperContent.js +84 -0
- package/dist/docx/mathToMathml.js +12 -14
- package/dist/docx/nonVisualDrawingProps.d.ts +34 -0
- package/dist/docx/nonVisualDrawingProps.js +46 -0
- package/dist/docx/normalizeBaseDirection.js +10 -1
- package/dist/docx/paraIdAttribute.d.ts +21 -0
- package/dist/docx/paraIdAttribute.js +64 -0
- package/dist/docx/paragraphParser.d.ts +1 -1
- package/dist/docx/paragraphParser.js +277 -168
- package/dist/docx/paragraphPropertySource.js +5 -1
- package/dist/docx/paragraphTextBoxEnrichment.d.ts +1 -1
- package/dist/docx/paragraphTextBoxEnrichment.js +9 -52
- package/dist/docx/paragraphTraversal.js +7 -4
- package/dist/docx/parseWarningMessage.js +2 -1
- package/dist/docx/parser.js +2 -2
- package/dist/docx/preservedRunContent.d.ts +32 -0
- package/dist/docx/preservedRunContent.js +86 -0
- package/dist/docx/previewBudget.d.ts +64 -0
- package/dist/docx/previewBudget.js +88 -0
- package/dist/docx/renderedPageBreakNormalization.js +2 -4
- package/dist/docx/revisionIdNormalization.js +17 -5
- package/dist/docx/rezip.js +91 -36
- package/dist/docx/runParser.d.ts +1 -1
- package/dist/docx/runParser.js +16 -12
- package/dist/docx/sdtPropertiesPatch.js +24 -18
- package/dist/docx/sectionParser.js +8 -1
- package/dist/docx/sectionReferenceHistory.js +2 -2
- package/dist/docx/selectiveSave.js +6 -6
- package/dist/docx/selectiveXmlPatch.d.ts +46 -2
- package/dist/docx/selectiveXmlPatch.js +86 -39
- package/dist/docx/serializer/blockSdtSerializer.js +38 -26
- package/dist/docx/serializer/borderSerializer.d.ts +1 -1
- package/dist/docx/serializer/borderSerializer.js +15 -14
- package/dist/docx/serializer/commentSerializer.d.ts +41 -16
- package/dist/docx/serializer/commentSerializer.js +87 -92
- package/dist/docx/serializer/documentSerializer.js +8 -11
- package/dist/docx/serializer/fontTableSerializer.js +6 -6
- package/dist/docx/serializer/headerFooterSerializer.js +12 -14
- package/dist/docx/serializer/markupRangeAttributes.js +2 -2
- package/dist/docx/serializer/noteSerializer.js +8 -8
- package/dist/docx/serializer/numberingSerializer.js +7 -6
- package/dist/docx/serializer/paragraphSerializer.js +93 -72
- package/dist/docx/serializer/partNamespaces.js +2 -2
- package/dist/docx/serializer/runSerializer.js +73 -44
- package/dist/docx/serializer/sectionPropertiesSerializer.js +19 -14
- package/dist/docx/serializer/settingsSerializer.js +4 -3
- package/dist/docx/serializer/stylesSerializer.js +6 -6
- package/dist/docx/serializer/tableSerializer.js +28 -17
- package/dist/docx/serializer/textFormattingSerializer.js +29 -28
- package/dist/docx/serializer/themeSerializer.js +6 -6
- package/dist/docx/serializer/trackedChangeAttributes.js +2 -2
- package/dist/docx/serializer/xmlUtils.d.ts +1 -2
- package/dist/docx/serializer/xmlUtils.js +1 -13
- package/dist/docx/server/boundedArchive.d.ts +12 -0
- package/dist/docx/server/boundedArchive.js +20 -1
- package/dist/docx/server/createBilingualDocument.js +3 -1
- package/dist/docx/server/materializeYjsDocx.d.ts +1 -1
- package/dist/docx/server/materializeYjsDocx.js +9 -1
- package/dist/docx/server/migrateYjsAttrSchema.d.ts +55 -0
- package/dist/docx/server/migrateYjsAttrSchema.js +95 -0
- package/dist/docx/server/validateDocxConformance.js +22 -1
- package/dist/docx/shapeParser.js +12 -10
- package/dist/docx/tableParser.d.ts +1 -1
- package/dist/docx/tableParser.js +206 -85
- package/dist/docx/textBoxParser.d.ts +25 -2
- package/dist/docx/textBoxParser.js +59 -4
- package/dist/docx/unzip.d.ts +23 -0
- package/dist/docx/unzip.js +37 -26
- package/dist/docx/verbatimCapture.js +1 -1
- package/dist/docx/vmlImageParser.d.ts +17 -1
- package/dist/docx/vmlImageParser.js +20 -3
- package/dist/docx/vmlPreview.d.ts +1 -3
- package/dist/docx/vmlPreview.js +2 -30
- package/dist/docx/xmlEncoding.d.ts +5 -0
- package/dist/docx/xmlEncoding.js +12 -0
- package/dist/docx/xmlParser.d.ts +26 -2
- package/dist/docx/xmlParser.js +70 -27
- package/dist/docx/xmlResourceLimits.d.ts +89 -9
- package/dist/docx/xmlResourceLimits.js +105 -24
- package/dist/headless-layout.js +10 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +5 -2
- package/dist/internal/paragraphFormattingSerialization.js +3 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +102 -12
- package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
- package/dist/layout-engine/measure/tableCellFloating.js +2 -0
- package/dist/layout-engine/types.d.ts +23 -1
- package/dist/layout-painter/renderImage.d.ts +5 -1
- package/dist/layout-painter/renderImage.js +14 -6
- package/dist/layout-painter/renderPage.d.ts +2 -0
- package/dist/layout-painter/renderPage.js +4 -0
- package/dist/layout-painter/renderParagraph.d.ts +13 -1
- package/dist/layout-painter/renderParagraph.js +26 -6
- package/dist/managers/autoSaveCodec.d.ts +9 -1
- package/dist/managers/autoSaveCodec.js +14 -12
- package/dist/markdown/images.js +1 -4
- package/dist/markdown/renderBlock.js +1 -0
- package/dist/markdown/renderRuns.d.ts +1 -1
- package/dist/markdown/renderRuns.js +28 -5
- package/dist/markdown/renderTable.js +22 -5
- package/dist/markdown/trailers.js +4 -1
- package/dist/pdf/images.js +142 -6
- package/dist/prosemirror/attrs/index.d.ts +14 -3
- package/dist/prosemirror/attrs/index.js +224 -2
- package/dist/prosemirror/authoredTransformAttrs.d.ts +28 -0
- package/dist/prosemirror/authoredTransformAttrs.js +64 -0
- package/dist/prosemirror/commands/contentControls.js +10 -2
- package/dist/prosemirror/commands/image.d.ts +9 -2
- package/dist/prosemirror/commands/image.js +43 -28
- package/dist/prosemirror/commands/pageBreak.js +1 -1
- package/dist/prosemirror/commentReferenceAttrs.d.ts +8 -0
- package/dist/prosemirror/commentReferenceAttrs.js +33 -0
- package/dist/prosemirror/commentReferenceIntegrity.d.ts +47 -0
- package/dist/prosemirror/commentReferenceIntegrity.js +43 -0
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
- package/dist/prosemirror/conversion/fromProseDoc.js +338 -99
- package/dist/prosemirror/conversion/index.d.ts +2 -2
- package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -9
- package/dist/prosemirror/conversion/toProseDoc.js +551 -327
- package/dist/prosemirror/extensions/StarterKit.js +8 -58
- package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -1
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +45 -27
- package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -1
- package/dist/prosemirror/extensions/features/ImagePasteExtension.js +5 -3
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -0
- package/dist/prosemirror/extensions/markRegistry.d.ts +41 -0
- package/dist/prosemirror/extensions/markRegistry.js +75 -0
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +2 -3
- package/dist/prosemirror/extensions/marks/InlineWrapperExtension.d.ts +18 -0
- package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +63 -0
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +2 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +47 -4
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.d.ts +11 -0
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +87 -0
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +9 -7
- package/dist/prosemirror/extensions/nodes/ImageExtension.js +20 -0
- package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.d.ts +32 -0
- package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +67 -0
- package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.d.ts +16 -0
- package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +60 -0
- package/dist/prosemirror/extensions/nodes/ShapeExtension.js +10 -2
- package/dist/prosemirror/extensions/nodes/TableExtension.js +3 -2
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +13 -5
- package/dist/prosemirror/inlineWrapperStack.d.ts +39 -0
- package/dist/prosemirror/inlineWrapperStack.js +75 -0
- package/dist/prosemirror/pageBreakRunProjection.d.ts +17 -7
- package/dist/prosemirror/pageBreakRunProjection.js +19 -9
- package/dist/prosemirror/paragraphFormattingProvenance.d.ts +6 -3
- package/dist/prosemirror/paragraphFormattingProvenance.js +12 -3
- package/dist/prosemirror/replacedAnnotations.d.ts +59 -0
- package/dist/prosemirror/replacedAnnotations.js +165 -0
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +3 -1
- package/dist/prosemirror/runFormattingInlineCarriers.js +5 -1
- package/dist/prosemirror/schema/index.d.ts +3 -3
- package/dist/prosemirror/schema/marks.d.ts +25 -1
- package/dist/prosemirror/schema/nodes.d.ts +139 -3
- package/dist/prosemirror/schema/nodes.js +16 -1
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +2 -0
- package/dist/prosemirror/trackedRunInlineAtoms.js +2 -0
- package/dist/prosemirror/validation.js +16 -2
- package/dist/prosemirror/yjsDocumentMetadata.d.ts +73 -0
- package/dist/prosemirror/yjsDocumentMetadata.js +171 -0
- package/dist/prosemirror/zeroWidthAnchors.js +2 -0
- package/dist/render-dom/commentAnchorAttributes.d.ts +37 -0
- package/dist/render-dom/commentAnchorAttributes.js +54 -0
- package/dist/server.d.ts +3 -1
- package/dist/server.js +3 -1
- package/dist/types/content.d.ts +2 -2
- package/dist/utils/base64.d.ts +36 -0
- package/dist/utils/base64.js +40 -0
- package/dist/utils/clipboard.d.ts +9 -1
- package/dist/utils/clipboard.js +29 -2
- package/dist/utils/findReplace.js +1 -1
- package/dist/utils/imageLuminance.d.ts +15 -0
- package/dist/utils/imageLuminance.js +32 -0
- package/dist/utils/mergeDocumentContent.js +7 -17
- package/dist/utils/replaceText.js +1 -0
- package/dist/utils/units.d.ts +10 -1
- package/dist/utils/units.js +12 -1
- package/dist/utils/urlSecurity.d.ts +8 -2
- package/dist/utils/urlSecurity.js +21 -3
- package/package.json +2 -2
- package/dist/docx/blockRangeMarkers.d.ts +0 -36
- package/dist/docx/blockRangeMarkers.js +0 -59
- package/dist/prosemirror/yjsParagraphSourceContract.d.ts +0 -9
- package/dist/prosemirror/yjsParagraphSourceContract.js +0 -26
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { OOXML_NAMESPACES } from "./serializer/partNamespaces.js";
|
|
2
|
+
import { getLocalName, resolveAttributeNamespaceUri } from "./xmlParser.js";
|
|
3
|
+
import { escapeXmlAttribute } from "@stll/docx-core";
|
|
4
|
+
//#region src/docx/attributeRemainder.ts
|
|
5
|
+
/** Namespace URI to the prefix a rebuilt part binds for it. */
|
|
6
|
+
const CANONICAL_PREFIX = new Map(Object.entries(OOXML_NAMESPACES).map(([prefix, { uri }]) => [uri, prefix]));
|
|
7
|
+
/**
|
|
8
|
+
* The modelled set of an element whose serializer writes no attribute at all.
|
|
9
|
+
*
|
|
10
|
+
* `w:r`, `w:tr` and `w:sectPr` are rebuilt as bare start tags, so everything
|
|
11
|
+
* their source wrote is the remainder. Named rather than spelled `new Set()`
|
|
12
|
+
* at each call site, so the claim is visible and one place has to change when
|
|
13
|
+
* one of them gains a modelled attribute.
|
|
14
|
+
*/
|
|
15
|
+
const NO_MODELLED_ATTRIBUTES = /* @__PURE__ */ new Set();
|
|
16
|
+
/**
|
|
17
|
+
* Every attribute on the element the model has no field for.
|
|
18
|
+
*
|
|
19
|
+
* @returns the remainder, or `undefined` when the parser read them all — an
|
|
20
|
+
* empty list is never written, so a fully modelled element stays identical
|
|
21
|
+
* in the model.
|
|
22
|
+
*/
|
|
23
|
+
const attributeRemainder = ({ element, modelled }) => {
|
|
24
|
+
const attributes = element.attributes;
|
|
25
|
+
if (!attributes) return;
|
|
26
|
+
const remainder = [];
|
|
27
|
+
for (const [spelling, value] of Object.entries(attributes)) {
|
|
28
|
+
if (value === void 0 || spelling === "xmlns" || spelling.startsWith("xmlns:")) continue;
|
|
29
|
+
const name = getLocalName(spelling);
|
|
30
|
+
if (modelled.has(name)) continue;
|
|
31
|
+
const namespace = resolveAttributeNamespaceUri(element, spelling);
|
|
32
|
+
if (namespace !== void 0 && !CANONICAL_PREFIX.has(namespace)) continue;
|
|
33
|
+
remainder.push({
|
|
34
|
+
...namespace === void 0 ? {} : { namespace },
|
|
35
|
+
name,
|
|
36
|
+
value: String(value)
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return remainder.length === 0 ? void 0 : remainder;
|
|
40
|
+
};
|
|
41
|
+
/** The name a fragment such as `w14:paraId="1F2E"` writes. */
|
|
42
|
+
const spelledName = (fragment) => fragment.slice(0, fragment.indexOf("="));
|
|
43
|
+
/**
|
|
44
|
+
* The element's attributes, modelled first and the remainder after them.
|
|
45
|
+
*
|
|
46
|
+
* @param modelled the fragments the serializer is about to emit, already
|
|
47
|
+
* spelled — they win a collision, because the model is the editable copy
|
|
48
|
+
* @returns the fragments to write, so an element with neither writes nothing
|
|
49
|
+
*/
|
|
50
|
+
const serializePreservedAttributes = (modelled, preserved) => {
|
|
51
|
+
if (preserved === void 0 || preserved.length === 0) return [...modelled];
|
|
52
|
+
const written = new Set(modelled.map(spelledName));
|
|
53
|
+
const fragments = [...modelled];
|
|
54
|
+
for (const { namespace, name, value } of preserved) {
|
|
55
|
+
const prefix = namespace === void 0 ? void 0 : CANONICAL_PREFIX.get(namespace);
|
|
56
|
+
if (namespace !== void 0 && prefix === void 0) continue;
|
|
57
|
+
const spelling = prefix === void 0 ? name : `${prefix}:${name}`;
|
|
58
|
+
if (written.has(spelling)) continue;
|
|
59
|
+
written.add(spelling);
|
|
60
|
+
fragments.push(`${spelling}="${escapeXmlAttribute(value)}"`);
|
|
61
|
+
}
|
|
62
|
+
return fragments;
|
|
63
|
+
};
|
|
64
|
+
//#endregion
|
|
65
|
+
export { NO_MODELLED_ATTRIBUTES, attributeRemainder, serializePreservedAttributes };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
2
|
import { NumberingMap } from "./numberingParser.js";
|
|
3
|
-
import { StyleMap } from "./styleParser.js";
|
|
4
3
|
import { XmlElement } from "./xmlParser.js";
|
|
4
|
+
import { StyleMap } from "./styleParser.js";
|
|
5
5
|
//#region src/docx/blockContentParser.d.ts
|
|
6
6
|
type ParseBlockContentOptions = {
|
|
7
7
|
inHeaderFooter?: boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { attachPendingRangeMarkers, attachTrailingRangeMarkers, isBlockRangeMarker } from "./blockRangeMarkers.js";
|
|
2
1
|
import { parseBookmarkEnd, parseBookmarkStart } from "./bookmarkParser.js";
|
|
3
2
|
import { appendBookmarkMarkerToLastParagraphInBlocks, prependBookmarkMarkersToFirstParagraphInBlocks } from "./bookmarkPlacement.js";
|
|
4
3
|
import { convertBulletToUnicode } from "./bulletMarkers.js";
|
|
4
|
+
import { CAPTURE, OWNED_ELSEWHERE, dispatchChildren, withPreservedChildren } from "./containerChildren.js";
|
|
5
5
|
import { isNumberingReference } from "./numberingReference.js";
|
|
6
6
|
import { formatOoxmlCounter } from "./ooxmlCounterFormatter.js";
|
|
7
7
|
import { parseParagraph } from "./paragraphParser.js";
|
|
@@ -9,7 +9,7 @@ import { enrichParagraphTextBoxes } from "./paragraphTextBoxEnrichment.js";
|
|
|
9
9
|
import { parseSdtProperties } from "./sdtProperties.js";
|
|
10
10
|
import { parseTable } from "./tableParser.js";
|
|
11
11
|
import { captureVerbatimXml } from "./verbatimCapture.js";
|
|
12
|
-
import { findChild,
|
|
12
|
+
import { findChild, getLocalName, mergeXmlnsDeclarations, selectAlternateContentBranch } from "./xmlParser.js";
|
|
13
13
|
//#region src/docx/blockContentParser.ts
|
|
14
14
|
const computeListMarker = (paragraph, { numbering, listCounters, abstractCounters, restartedNumIds, previousList }) => {
|
|
15
15
|
const listRendering = paragraph.listRendering;
|
|
@@ -104,72 +104,100 @@ const parseBlockContent = (parent, styles, theme, numbering, rels, media, option
|
|
|
104
104
|
}
|
|
105
105
|
});
|
|
106
106
|
const parseBlockContentWithState = (parent, styles, theme, numbering, rels, media, state) => {
|
|
107
|
-
const
|
|
108
|
-
const children = getChildElements(parent);
|
|
107
|
+
const modelled = [];
|
|
109
108
|
const pendingBookmarkMarkers = [];
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
prependPendingBookmarkMarkers(paragraph, pendingBookmarkMarkers);
|
|
116
|
-
enrichParagraphTextBoxes(paragraph, child, styles, theme, numbering, rels, media, parseTable);
|
|
117
|
-
computeListMarker(paragraph, {
|
|
118
|
-
numbering,
|
|
119
|
-
listCounters: state.listCounters,
|
|
120
|
-
abstractCounters: state.abstractCounters,
|
|
121
|
-
restartedNumIds: state.restartedNumIds,
|
|
122
|
-
previousList: state.previousList
|
|
123
|
-
});
|
|
124
|
-
attachPendingRangeMarkers(paragraph, pendingRangeMarkers);
|
|
125
|
-
content.push(paragraph);
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
if (localName === "tbl") {
|
|
129
|
-
const table = parseTable(child, styles, theme, numbering, rels, media, state.options);
|
|
130
|
-
if (!table) continue;
|
|
131
|
-
if (prependBookmarkMarkersToFirstParagraphInBlocks([table], pendingBookmarkMarkers)) pendingBookmarkMarkers.length = 0;
|
|
132
|
-
attachPendingRangeMarkers(table, pendingRangeMarkers);
|
|
133
|
-
content.push(table);
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
if (localName === "sdt") {
|
|
137
|
-
const sdtPr = findChild(child, "w", "sdtPr");
|
|
138
|
-
const sdtEndPr = findChild(child, "w", "sdtEndPr");
|
|
139
|
-
const sdtContent = findChild(child, "w", "sdtContent");
|
|
140
|
-
const properties = parseSdtProperties(sdtPr, sdtEndPr);
|
|
141
|
-
const captured = captureSdtSiblingMarkers(child);
|
|
142
|
-
if (captured.before.length > 0) properties.rawSdtChildrenBeforeContent = captured.before;
|
|
143
|
-
if (captured.after.length > 0) properties.rawSdtChildrenAfterContent = captured.after;
|
|
144
|
-
const blockSdt = {
|
|
145
|
-
type: "blockSdt",
|
|
146
|
-
properties,
|
|
147
|
-
content: sdtContent ? parseBlockContentWithState(sdtContent, styles, theme, numbering, rels, media, withContainerXmlns(withContainerXmlns(state, child), sdtContent)) : []
|
|
148
|
-
};
|
|
149
|
-
if (prependBookmarkMarkersToFirstParagraphInBlocks(blockSdt.content, pendingBookmarkMarkers)) pendingBookmarkMarkers.length = 0;
|
|
150
|
-
attachPendingRangeMarkers(blockSdt, pendingRangeMarkers);
|
|
151
|
-
content.push(blockSdt);
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
if (localName === "AlternateContent") {
|
|
109
|
+
const content = withPreservedChildren(modelled, dispatchChildren({
|
|
110
|
+
element: parent,
|
|
111
|
+
container: "block-content",
|
|
112
|
+
modelledCount: () => modelled.length,
|
|
113
|
+
undeclared: { AlternateContent: (child) => {
|
|
155
114
|
const selectedBranch = selectAlternateContentBranch(child);
|
|
156
|
-
if (selectedBranch)
|
|
157
|
-
|
|
115
|
+
if (!selectedBranch) return;
|
|
116
|
+
modelled.push(...parseBlockContentWithState(selectedBranch, styles, theme, numbering, rels, media, withContainerXmlns(withContainerXmlns(state, child), selectedBranch)));
|
|
117
|
+
} },
|
|
118
|
+
handlers: {
|
|
119
|
+
p: (child) => {
|
|
120
|
+
const paragraph = parseParagraph(child, styles, theme, numbering, rels, media, state.options);
|
|
121
|
+
prependPendingBookmarkMarkers(paragraph, pendingBookmarkMarkers);
|
|
122
|
+
enrichParagraphTextBoxes(paragraph, child, styles, theme, numbering, rels, media, parseTable);
|
|
123
|
+
computeListMarker(paragraph, {
|
|
124
|
+
numbering,
|
|
125
|
+
listCounters: state.listCounters,
|
|
126
|
+
abstractCounters: state.abstractCounters,
|
|
127
|
+
restartedNumIds: state.restartedNumIds,
|
|
128
|
+
previousList: state.previousList
|
|
129
|
+
});
|
|
130
|
+
modelled.push(paragraph);
|
|
131
|
+
},
|
|
132
|
+
tbl: (child) => {
|
|
133
|
+
const table = parseTable(child, styles, theme, numbering, rels, media, state.options);
|
|
134
|
+
if (!table) return;
|
|
135
|
+
if (prependBookmarkMarkersToFirstParagraphInBlocks([table], pendingBookmarkMarkers)) pendingBookmarkMarkers.length = 0;
|
|
136
|
+
modelled.push(table);
|
|
137
|
+
},
|
|
138
|
+
sdt: (child) => {
|
|
139
|
+
const blockSdt = parseBlockSdt(child, styles, theme, numbering, rels, media, state);
|
|
140
|
+
if (prependBookmarkMarkersToFirstParagraphInBlocks(blockSdt.content, pendingBookmarkMarkers)) pendingBookmarkMarkers.length = 0;
|
|
141
|
+
modelled.push(blockSdt);
|
|
142
|
+
},
|
|
143
|
+
bookmarkStart: (child) => {
|
|
144
|
+
collectBookmarkMarker(child, "bookmarkStart", modelled, pendingBookmarkMarkers);
|
|
145
|
+
},
|
|
146
|
+
bookmarkEnd: (child) => {
|
|
147
|
+
collectBookmarkMarker(child, "bookmarkEnd", modelled, pendingBookmarkMarkers);
|
|
148
|
+
},
|
|
149
|
+
sectPr: OWNED_ELSEWHERE,
|
|
150
|
+
tcPr: OWNED_ELSEWHERE,
|
|
151
|
+
altChunk: CAPTURE,
|
|
152
|
+
commentRangeEnd: CAPTURE,
|
|
153
|
+
commentRangeStart: CAPTURE,
|
|
154
|
+
customXml: CAPTURE,
|
|
155
|
+
customXmlDelRangeEnd: CAPTURE,
|
|
156
|
+
customXmlDelRangeStart: CAPTURE,
|
|
157
|
+
customXmlInsRangeEnd: CAPTURE,
|
|
158
|
+
customXmlInsRangeStart: CAPTURE,
|
|
159
|
+
customXmlMoveFromRangeEnd: CAPTURE,
|
|
160
|
+
customXmlMoveFromRangeStart: CAPTURE,
|
|
161
|
+
customXmlMoveToRangeEnd: CAPTURE,
|
|
162
|
+
customXmlMoveToRangeStart: CAPTURE,
|
|
163
|
+
del: CAPTURE,
|
|
164
|
+
ins: CAPTURE,
|
|
165
|
+
moveFrom: CAPTURE,
|
|
166
|
+
moveFromRangeEnd: CAPTURE,
|
|
167
|
+
moveFromRangeStart: CAPTURE,
|
|
168
|
+
moveTo: CAPTURE,
|
|
169
|
+
moveToRangeEnd: CAPTURE,
|
|
170
|
+
moveToRangeStart: CAPTURE,
|
|
171
|
+
permEnd: CAPTURE,
|
|
172
|
+
permStart: CAPTURE,
|
|
173
|
+
proofErr: CAPTURE
|
|
158
174
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
if (isBlockRangeMarker(localName)) pendingRangeMarkers.push(captureVerbatimXml(child));
|
|
165
|
-
}
|
|
175
|
+
}), (xml) => ({
|
|
176
|
+
type: "preservedBlock",
|
|
177
|
+
xml
|
|
178
|
+
}));
|
|
166
179
|
if (pendingBookmarkMarkers.length > 0) content.push({
|
|
167
180
|
type: "paragraph",
|
|
168
181
|
content: [...pendingBookmarkMarkers]
|
|
169
182
|
});
|
|
170
|
-
attachTrailingRangeMarkers(content, pendingRangeMarkers);
|
|
171
183
|
return content;
|
|
172
184
|
};
|
|
185
|
+
const parseBlockSdt = (child, styles, theme, numbering, rels, media, state) => {
|
|
186
|
+
const sdtContent = findChild(child, "w", "sdtContent");
|
|
187
|
+
const properties = parseSdtProperties(findChild(child, "w", "sdtPr"), findChild(child, "w", "sdtEndPr"));
|
|
188
|
+
const captured = captureSdtSiblingMarkers(child);
|
|
189
|
+
if (captured.before.length > 0) properties.rawSdtChildrenBeforeContent = captured.before;
|
|
190
|
+
if (captured.after.length > 0) properties.rawSdtChildrenAfterContent = captured.after;
|
|
191
|
+
return {
|
|
192
|
+
type: "blockSdt",
|
|
193
|
+
properties,
|
|
194
|
+
content: sdtContent ? parseBlockContentWithState(sdtContent, styles, theme, numbering, rels, media, withContainerXmlns(withContainerXmlns(state, child), sdtContent)) : []
|
|
195
|
+
};
|
|
196
|
+
};
|
|
197
|
+
const collectBookmarkMarker = (child, localName, content, pending) => {
|
|
198
|
+
const marker = localName === "bookmarkStart" ? parseBookmarkStart(child) : parseBookmarkEnd(child);
|
|
199
|
+
if (!appendBookmarkMarkerToLastParagraphInBlocks(content, marker)) pending.push(marker);
|
|
200
|
+
};
|
|
173
201
|
/**
|
|
174
202
|
* Walk a `<w:sdt>` element's direct children and return the verbatim XML
|
|
175
203
|
* for every child that is NOT `<w:sdtPr>`, `<w:sdtEndPr>`, or
|
|
@@ -202,10 +230,6 @@ const captureSdtSiblingMarkers = (sdt) => {
|
|
|
202
230
|
after: afterParts.join("")
|
|
203
231
|
};
|
|
204
232
|
};
|
|
205
|
-
const parseBookmarkMarker = (child, localName) => {
|
|
206
|
-
if (localName === "bookmarkStart") return parseBookmarkStart(child);
|
|
207
|
-
return parseBookmarkEnd(child);
|
|
208
|
-
};
|
|
209
233
|
const prependPendingBookmarkMarkers = (paragraph, pendingBookmarkMarkers) => {
|
|
210
234
|
if (pendingBookmarkMarkers.length === 0) return;
|
|
211
235
|
paragraph.content.unshift(...pendingBookmarkMarkers);
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
2
|
//#region src/docx/blockPlainText.d.ts
|
|
3
|
-
type PlainTextBlock = document_d_exports.Paragraph | document_d_exports.Table | document_d_exports.BlockSdt;
|
|
4
3
|
/** One entry per block, so callers can join or count lines as they need. */
|
|
5
|
-
declare const collectBlockTexts: (blocks: readonly
|
|
6
|
-
declare const blockPlainText: (blocks: readonly
|
|
4
|
+
declare const collectBlockTexts: (blocks: readonly document_d_exports.BlockContent[]) => string[];
|
|
5
|
+
declare const blockPlainText: (blocks: readonly document_d_exports.BlockContent[]) => string;
|
|
7
6
|
//#endregion
|
|
8
|
-
export {
|
|
7
|
+
export { blockPlainText, collectBlockTexts };
|
|
@@ -31,6 +31,7 @@ const collectBlockTexts = (blocks) => {
|
|
|
31
31
|
case "blockSdt":
|
|
32
32
|
texts.push(...collectBlockTexts(block.content));
|
|
33
33
|
break;
|
|
34
|
+
case "preservedBlock": break;
|
|
34
35
|
default: panic(`Unsupported block in plain-text extraction: ${JSON.stringify(block)}`);
|
|
35
36
|
}
|
|
36
37
|
return texts;
|
|
@@ -25,6 +25,7 @@ const appendBookmarkMarkerToLastParagraph = (block, marker) => {
|
|
|
25
25
|
return true;
|
|
26
26
|
}
|
|
27
27
|
if (block.type === "table") return appendBookmarkMarkerToLastParagraphInTable(block, marker);
|
|
28
|
+
if (block.type === "preservedBlock") return false;
|
|
28
29
|
return appendBookmarkMarkerToLastParagraphInBlocks(block.content, marker);
|
|
29
30
|
};
|
|
30
31
|
const appendBookmarkMarkerToLastParagraphInTable = (table, marker) => {
|
|
@@ -40,6 +41,7 @@ const prependBookmarkMarkersToFirstParagraph = (block, markers) => {
|
|
|
40
41
|
return true;
|
|
41
42
|
}
|
|
42
43
|
if (block.type === "table") return prependBookmarkMarkersToFirstParagraphInTable(block, markers);
|
|
44
|
+
if (block.type === "preservedBlock") return false;
|
|
43
45
|
return prependBookmarkMarkersToFirstParagraphInBlocks(block.content, markers);
|
|
44
46
|
};
|
|
45
47
|
const prependBookmarkMarkersToFirstParagraphInTable = (table, markers) => {
|
|
@@ -55,15 +55,15 @@ function parseBorderSpec(border, context) {
|
|
|
55
55
|
if (shadow !== void 0) spec.shadow = shadow;
|
|
56
56
|
const frame = parseOnOffAttribute(border, "w", "frame");
|
|
57
57
|
if (frame !== void 0) spec.frame = frame;
|
|
58
|
-
const artRelationshipId = getAttribute(border, "
|
|
58
|
+
const artRelationshipId = getAttribute(border, "r", "id")?.trim();
|
|
59
59
|
if (artRelationshipId) spec.artRelationshipId = artRelationshipId;
|
|
60
|
-
const topLeftArtRelationshipId = getAttribute(border, "
|
|
60
|
+
const topLeftArtRelationshipId = getAttribute(border, "r", "topLeft")?.trim();
|
|
61
61
|
if (topLeftArtRelationshipId) spec.topLeftArtRelationshipId = topLeftArtRelationshipId;
|
|
62
|
-
const topRightArtRelationshipId = getAttribute(border, "
|
|
62
|
+
const topRightArtRelationshipId = getAttribute(border, "r", "topRight")?.trim();
|
|
63
63
|
if (topRightArtRelationshipId) spec.topRightArtRelationshipId = topRightArtRelationshipId;
|
|
64
|
-
const bottomLeftArtRelationshipId = getAttribute(border, "
|
|
64
|
+
const bottomLeftArtRelationshipId = getAttribute(border, "r", "bottomLeft")?.trim();
|
|
65
65
|
if (bottomLeftArtRelationshipId) spec.bottomLeftArtRelationshipId = bottomLeftArtRelationshipId;
|
|
66
|
-
const bottomRightArtRelationshipId = getAttribute(border, "
|
|
66
|
+
const bottomRightArtRelationshipId = getAttribute(border, "r", "bottomRight")?.trim();
|
|
67
67
|
if (bottomRightArtRelationshipId) spec.bottomRightArtRelationshipId = bottomRightArtRelationshipId;
|
|
68
68
|
return spec;
|
|
69
69
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
//#region src/docx/commentAnchorIndex.d.ts
|
|
3
|
+
type CommentMarkerSlot = {
|
|
4
|
+
/** The inline-content array the marker sits in, so a caller can splice it. */
|
|
5
|
+
content: document_d_exports.ParagraphContent[];
|
|
6
|
+
index: number;
|
|
7
|
+
item: Extract<document_d_exports.ParagraphContent, {
|
|
8
|
+
type: "commentRangeStart";
|
|
9
|
+
} | {
|
|
10
|
+
type: "commentRangeEnd";
|
|
11
|
+
} | {
|
|
12
|
+
type: "commentReference";
|
|
13
|
+
}>;
|
|
14
|
+
};
|
|
15
|
+
declare const visitCommentMarkers: (blocks: readonly document_d_exports.BlockContent[], visit: (slot: CommentMarkerSlot) => void) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Comments that open a range anywhere in these blocks.
|
|
18
|
+
*
|
|
19
|
+
* A `commentReference` whose id is absent has no highlight of its own — the
|
|
20
|
+
* point-comment shape the model's `CommentReference` documents — and only that
|
|
21
|
+
* one needs its mark anchored onto neighbouring text. Anchoring one whose range
|
|
22
|
+
* exists stretches that range to wherever the reference sits, which is how a
|
|
23
|
+
* comment on one word came back covering the rest of the sentence. The range
|
|
24
|
+
* and the reference need not share a paragraph, so the question is asked of the
|
|
25
|
+
* whole story: a reference that trails the end of a range three paragraphs back
|
|
26
|
+
* is still not a point comment.
|
|
27
|
+
*/
|
|
28
|
+
declare const rangedCommentIds: (blocks: readonly document_d_exports.BlockContent[]) => ReadonlySet<number>;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { CommentMarkerSlot, rangedCommentIds, visitCommentMarkers };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { visitInlineContentSlots } from "./paragraphTraversal.js";
|
|
2
|
+
//#region src/docx/commentAnchorIndex.ts
|
|
3
|
+
const visitCommentMarkers = (blocks, visit) => {
|
|
4
|
+
const visitParagraph = (paragraph) => {
|
|
5
|
+
visitInlineContentSlots(paragraph, ({ content, index, item }) => {
|
|
6
|
+
if (item.type === "commentRangeStart" || item.type === "commentRangeEnd" || item.type === "commentReference") visit({
|
|
7
|
+
content,
|
|
8
|
+
index,
|
|
9
|
+
item
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
const visitBlock = (block) => {
|
|
14
|
+
if (block.type === "paragraph") {
|
|
15
|
+
visitParagraph(block);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (block.type === "table") {
|
|
19
|
+
for (const row of block.rows) for (const cell of row.cells) visitBlocks(cell.content);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (block.type === "preservedBlock") return;
|
|
23
|
+
visitBlocks(block.content);
|
|
24
|
+
};
|
|
25
|
+
const visitBlocks = (nested) => {
|
|
26
|
+
for (const block of nested) visitBlock(block);
|
|
27
|
+
};
|
|
28
|
+
visitBlocks(blocks);
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Comments that open a range anywhere in these blocks.
|
|
32
|
+
*
|
|
33
|
+
* A `commentReference` whose id is absent has no highlight of its own — the
|
|
34
|
+
* point-comment shape the model's `CommentReference` documents — and only that
|
|
35
|
+
* one needs its mark anchored onto neighbouring text. Anchoring one whose range
|
|
36
|
+
* exists stretches that range to wherever the reference sits, which is how a
|
|
37
|
+
* comment on one word came back covering the rest of the sentence. The range
|
|
38
|
+
* and the reference need not share a paragraph, so the question is asked of the
|
|
39
|
+
* whole story: a reference that trails the end of a range three paragraphs back
|
|
40
|
+
* is still not a point comment.
|
|
41
|
+
*/
|
|
42
|
+
const rangedCommentIds = (blocks) => {
|
|
43
|
+
const ids = /* @__PURE__ */ new Set();
|
|
44
|
+
visitCommentMarkers(blocks, ({ item }) => {
|
|
45
|
+
if (item.type === "commentRangeStart") ids.add(item.id);
|
|
46
|
+
});
|
|
47
|
+
return ids;
|
|
48
|
+
};
|
|
49
|
+
//#endregion
|
|
50
|
+
export { rangedCommentIds, visitCommentMarkers };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
|
-
import { StyleMap } from "./styleParser.js";
|
|
3
2
|
import { ParseContext } from "./parseContext.js";
|
|
3
|
+
import { StyleMap } from "./styleParser.js";
|
|
4
4
|
//#region src/docx/commentParser.d.ts
|
|
5
5
|
type CommentExtendedInfo = {
|
|
6
6
|
parentParaId?: string;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { commentThreadParaId } from "./commentThreadKey.js";
|
|
2
|
+
import { CAPTURE, dispatchChildren } from "./containerChildren.js";
|
|
3
|
+
import { PARA_ID_NAMESPACE_URIS, paraIdAttribute, paraIdParentAttribute } from "./paraIdAttribute.js";
|
|
1
4
|
import { parseParagraph } from "./paragraphParser.js";
|
|
2
5
|
import { cloneParagraphWithPropertySource } from "./paragraphPropertySource.js";
|
|
3
6
|
import { parseRunProperties } from "./runParser.js";
|
|
4
|
-
import { findChild, getAttribute, getChildElements, getLocalName, parseOnOffValue, parseXml } from "./xmlParser.js";
|
|
7
|
+
import { findChild, getAttribute, getAttributeByNamespaceUri, getChildElements, getLocalName, parseOnOffValue, parseXml } from "./xmlParser.js";
|
|
5
8
|
import { PARSE_WARNING_CODES } from "@stll/docx-core/model";
|
|
6
9
|
//#region src/docx/commentParser.ts
|
|
7
10
|
/**
|
|
@@ -36,7 +39,7 @@ const normalizeFirstCommentParagraph = (paragraphElement, paragraph, theme) => {
|
|
|
36
39
|
const annotationReferenceFormatting = normalizeAnnotationReferenceFormatting(runProperties ? parseRunProperties(runProperties, theme) : void 0);
|
|
37
40
|
const firstParsedContent = paragraph.content.at(0);
|
|
38
41
|
return {
|
|
39
|
-
paragraph: firstParsedContent?.type === "run" && firstParsedContent.content.
|
|
42
|
+
paragraph: firstParsedContent?.type === "run" && firstParsedContent.content.every((item) => item.type === "preservedXml" && item.text === "") ? cloneParagraphWithPropertySource(paragraph, { content: paragraph.content.slice(1) }) : paragraph,
|
|
40
43
|
...annotationReferenceFormatting !== void 0 ? { annotationReferenceFormatting } : {}
|
|
41
44
|
};
|
|
42
45
|
};
|
|
@@ -54,9 +57,10 @@ function parseCommentsExtensible(xml) {
|
|
|
54
57
|
const container = findChild(root, "w16cex", "commentsExtensible") ?? root;
|
|
55
58
|
for (const child of getChildElements(container)) {
|
|
56
59
|
if ((child.name?.replace(/^.*:/u, "") ?? "") !== "comment") continue;
|
|
57
|
-
const paraId =
|
|
58
|
-
const dateUtc =
|
|
59
|
-
|
|
60
|
+
const paraId = paraIdAttribute(child);
|
|
61
|
+
const dateUtc = getAttributeByNamespaceUri(child, PARA_ID_NAMESPACE_URIS, "dateUtc") ?? child.attributes?.["w16cex:dateUtc"] ?? child.attributes?.["w15:dateUtc"];
|
|
62
|
+
const key = paraId === void 0 ? null : paraId.toUpperCase();
|
|
63
|
+
if (key && dateUtc && !dateUtcByParaId.has(key)) dateUtcByParaId.set(key, String(dateUtc));
|
|
60
64
|
}
|
|
61
65
|
return dateUtcByParaId;
|
|
62
66
|
}
|
|
@@ -80,14 +84,16 @@ function parseCommentsExtended(xml) {
|
|
|
80
84
|
const container = findChild(root, "w15", "commentsEx") ?? root;
|
|
81
85
|
for (const child of getChildElements(container)) {
|
|
82
86
|
if ((child.name?.replace(/^.*:/u, "") ?? "") !== "commentEx") continue;
|
|
83
|
-
const paraId =
|
|
87
|
+
const paraId = paraIdAttribute(child);
|
|
84
88
|
if (!paraId) continue;
|
|
85
|
-
const
|
|
89
|
+
const key = paraId.toUpperCase();
|
|
90
|
+
if (infoByParaId.has(key)) continue;
|
|
91
|
+
const parentParaId = paraIdParentAttribute(child);
|
|
86
92
|
const doneAttr = getAttribute(child, "w15", "done") ?? child.attributes?.["w15:done"];
|
|
87
93
|
const info = {};
|
|
88
94
|
if (parentParaId) info.parentParaId = String(parentParaId).toUpperCase();
|
|
89
95
|
if (doneAttr !== void 0) info.done = parseOnOffValue(String(doneAttr).toLowerCase()) ?? false;
|
|
90
|
-
infoByParaId.set(
|
|
96
|
+
infoByParaId.set(key, info);
|
|
91
97
|
}
|
|
92
98
|
return infoByParaId;
|
|
93
99
|
}
|
|
@@ -105,9 +111,8 @@ function parseComments(commentsXml, styles, theme, rels, media, commentsExtensib
|
|
|
105
111
|
const dateUtcByParaId = commentsExtensibleXml ? parseCommentsExtensible(commentsExtensibleXml) : /* @__PURE__ */ new Map();
|
|
106
112
|
const extendedByParaId = commentsExtendedXml ? parseCommentsExtended(commentsExtendedXml) : /* @__PURE__ */ new Map();
|
|
107
113
|
const children = getChildElements(findChild(root, "w", "comments") ?? root);
|
|
108
|
-
const
|
|
114
|
+
const parsed = [];
|
|
109
115
|
const commentIdByParaId = /* @__PURE__ */ new Map();
|
|
110
|
-
const paraIdByCommentIndex = /* @__PURE__ */ new Map();
|
|
111
116
|
for (const child of children) {
|
|
112
117
|
if ((child.name?.replace(/^.*:/u, "") ?? "") !== "comment") continue;
|
|
113
118
|
const rawId = getAttribute(child, "w", "id");
|
|
@@ -126,54 +131,77 @@ function parseComments(commentsXml, styles, theme, rels, media, commentsExtensib
|
|
|
126
131
|
const initials = rawInitials !== null ? String(rawInitials) : void 0;
|
|
127
132
|
const rawDate = getAttribute(child, "w", "date");
|
|
128
133
|
const localDate = rawDate !== null ? String(rawDate) : void 0;
|
|
129
|
-
|
|
130
|
-
if (!rawParaId) for (const sub of getChildElements(child)) {
|
|
131
|
-
if ((sub.name?.replace(/^.*:/u, "") ?? "") !== "p") continue;
|
|
132
|
-
const subParaId = getAttribute(sub, "w14", "paraId") ?? sub.attributes?.["w14:paraId"] ?? getAttribute(sub, "w15", "paraId") ?? sub.attributes?.["w15:paraId"] ?? getAttribute(sub, "w", "paraId");
|
|
133
|
-
if (subParaId) rawParaId = subParaId;
|
|
134
|
-
}
|
|
134
|
+
const rawParaId = paraIdAttribute(child) ?? commentThreadParaId(getChildElements(child).filter((sub) => (sub.name?.replace(/^.*:/u, "") ?? "") === "p").map(paraIdAttribute));
|
|
135
135
|
const paraId = rawParaId ? String(rawParaId).toUpperCase() : null;
|
|
136
136
|
const date = (paraId ? dateUtcByParaId.get(paraId) : void 0) ?? localDate;
|
|
137
137
|
const done = (paraId ? extendedByParaId.get(paraId) : void 0)?.done;
|
|
138
138
|
const paragraphs = [];
|
|
139
139
|
let annotationReferenceFormatting;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
140
|
+
const preserved = dispatchChildren({
|
|
141
|
+
element: child,
|
|
142
|
+
container: "w:comment",
|
|
143
|
+
modelledCount: () => paragraphs.length,
|
|
144
|
+
handlers: {
|
|
145
|
+
p: (contentChild) => {
|
|
146
|
+
const paragraph = parseParagraph(contentChild, styles, theme, null, rels, media);
|
|
147
|
+
if (paragraphs.length > 0) {
|
|
148
|
+
paragraphs.push(paragraph);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const normalized = normalizeFirstCommentParagraph(contentChild, paragraph, theme);
|
|
152
|
+
annotationReferenceFormatting = normalized.annotationReferenceFormatting;
|
|
153
|
+
paragraphs.push(normalized.paragraph);
|
|
154
|
+
},
|
|
155
|
+
altChunk: CAPTURE,
|
|
156
|
+
bookmarkEnd: CAPTURE,
|
|
157
|
+
bookmarkStart: CAPTURE,
|
|
158
|
+
commentRangeEnd: CAPTURE,
|
|
159
|
+
commentRangeStart: CAPTURE,
|
|
160
|
+
customXml: CAPTURE,
|
|
161
|
+
customXmlDelRangeEnd: CAPTURE,
|
|
162
|
+
customXmlDelRangeStart: CAPTURE,
|
|
163
|
+
customXmlInsRangeEnd: CAPTURE,
|
|
164
|
+
customXmlInsRangeStart: CAPTURE,
|
|
165
|
+
customXmlMoveFromRangeEnd: CAPTURE,
|
|
166
|
+
customXmlMoveFromRangeStart: CAPTURE,
|
|
167
|
+
customXmlMoveToRangeEnd: CAPTURE,
|
|
168
|
+
customXmlMoveToRangeStart: CAPTURE,
|
|
169
|
+
del: CAPTURE,
|
|
170
|
+
ins: CAPTURE,
|
|
171
|
+
moveFrom: CAPTURE,
|
|
172
|
+
moveFromRangeEnd: CAPTURE,
|
|
173
|
+
moveFromRangeStart: CAPTURE,
|
|
174
|
+
moveTo: CAPTURE,
|
|
175
|
+
moveToRangeEnd: CAPTURE,
|
|
176
|
+
moveToRangeStart: CAPTURE,
|
|
177
|
+
permEnd: CAPTURE,
|
|
178
|
+
permStart: CAPTURE,
|
|
179
|
+
proofErr: CAPTURE,
|
|
180
|
+
sdt: CAPTURE,
|
|
181
|
+
tbl: CAPTURE
|
|
145
182
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
...done !== void 0 ? { done } : {},
|
|
161
|
-
...annotationReferenceFormatting !== void 0 ? { annotationReferenceFormatting } : {},
|
|
162
|
-
content: paragraphs
|
|
183
|
+
});
|
|
184
|
+
if (paraId && !commentIdByParaId.has(paraId)) commentIdByParaId.set(paraId, id);
|
|
185
|
+
parsed.push({
|
|
186
|
+
comment: {
|
|
187
|
+
id,
|
|
188
|
+
author,
|
|
189
|
+
...initials !== void 0 ? { initials } : {},
|
|
190
|
+
...date !== void 0 ? { date } : {},
|
|
191
|
+
...done !== void 0 ? { done } : {},
|
|
192
|
+
...annotationReferenceFormatting !== void 0 ? { annotationReferenceFormatting } : {},
|
|
193
|
+
...preserved !== void 0 ? { preserved } : {},
|
|
194
|
+
content: paragraphs
|
|
195
|
+
},
|
|
196
|
+
threadParaId: paraId
|
|
163
197
|
});
|
|
164
198
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const
|
|
169
|
-
if (
|
|
170
|
-
|
|
171
|
-
if (!parentParaId) continue;
|
|
172
|
-
const parentId = commentIdByParaId.get(parentParaId);
|
|
173
|
-
if (parentId !== void 0 && parentId !== comment.id) comments[i] = {
|
|
174
|
-
...comment,
|
|
175
|
-
parentId
|
|
176
|
-
};
|
|
199
|
+
const comments = [];
|
|
200
|
+
for (const { comment, threadParaId } of parsed) {
|
|
201
|
+
const parentParaId = threadParaId ? extendedByParaId.get(threadParaId)?.parentParaId : void 0;
|
|
202
|
+
const parentId = parentParaId ? commentIdByParaId.get(parentParaId) : void 0;
|
|
203
|
+
if (parentId !== void 0 && parentId !== comment.id) comment.parentId = parentId;
|
|
204
|
+
comments.push(comment);
|
|
177
205
|
}
|
|
178
206
|
return comments;
|
|
179
207
|
}
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
2
|
//#region src/docx/commentRangeIntegrity.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Comment ids whose range is not a start followed by an end in this story's
|
|
5
|
+
* XML. Either half alone is invalid OOXML and anchors nothing: Word shows no
|
|
6
|
+
* comment for a range that never opens.
|
|
7
|
+
*/
|
|
8
|
+
declare const unbalancedCommentRangeIds: (xml: string) => Set<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Whether rewriting `originalXml` into `patchedXml` left a comment range with
|
|
11
|
+
* only one half. A save patches the paragraphs an edit touched and keeps the
|
|
12
|
+
* rest of the part byte-for-byte, so an edit that moves a range's only start
|
|
13
|
+
* out of a patched paragraph and into an untouched one writes an end with no
|
|
14
|
+
* start. Ranges the source already had unbalanced are not this save's doing
|
|
15
|
+
* and stay tolerated.
|
|
16
|
+
*/
|
|
17
|
+
declare const patchBreaksCommentRangeBalance: (originalXml: string, patchedXml: string) => boolean;
|
|
3
18
|
declare const withoutOrphanCommentRanges: (doc: document_d_exports.Document) => document_d_exports.Document;
|
|
4
19
|
//#endregion
|
|
5
|
-
export { withoutOrphanCommentRanges };
|
|
20
|
+
export { patchBreaksCommentRangeBalance, unbalancedCommentRangeIds, withoutOrphanCommentRanges };
|