@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
|
@@ -1,27 +1,107 @@
|
|
|
1
1
|
//#region src/docx/xmlResourceLimits.d.ts
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Shared bounds for XML parts parsed by Folio.
|
|
4
|
+
*
|
|
5
|
+
* `maxBytes` and the package expansion ceiling bound the *markup*; they do not
|
|
6
|
+
* bound what parsing that markup allocates. A parsed element retains far more
|
|
7
|
+
* than the bytes it was written as, so a part that satisfies a byte bound can
|
|
8
|
+
* still cost multiples of it in tree. Measured on this repository's corpus
|
|
9
|
+
* generators (Bun 1.4, arm64, heap retained after a forced GC):
|
|
10
|
+
*
|
|
11
|
+
* shape bytes/element tree heap / part bytes
|
|
12
|
+
* `<w:r/>` 49.5 B 8.3x
|
|
13
|
+
* `<w:r a=".." x4/>` 105-124 B 2.8-3.3x
|
|
14
|
+
* `<w:r><w:t>x</w:t></w:r>` 162-171 B 14.1-14.8x
|
|
15
|
+
*
|
|
16
|
+
* An element is therefore the unit a memory bound has to count, because the
|
|
17
|
+
* adversarial shape is the cheap one: `<w:r/>` is 7 bytes of markup and 49.5
|
|
18
|
+
* bytes of tree, so 128 MiB of markup buys ~19M elements and ~950 MB of tree
|
|
19
|
+
* inside a byte budget that never trips.
|
|
20
|
+
*
|
|
21
|
+
* Corpus distribution (5,314 readable packages, every XML and .rels part):
|
|
22
|
+
*
|
|
23
|
+
* metric p50 p90 p99 p99.9 max
|
|
24
|
+
* elements / part 16 227 1,590 24,719 596,668
|
|
25
|
+
* elements / package 917 3,230 29,106 71,975 602,212
|
|
26
|
+
* attributes / part 27 577 1,993 21,037 630,374
|
|
27
|
+
* attributes / package 1,783 4,711 25,896 91,946 639,110
|
|
28
|
+
* depth / part 3 9 15 22 15,005
|
|
29
|
+
* elements per byte 0.012 0.027 0.036 0.043 0.111
|
|
30
|
+
*
|
|
31
|
+
* The defaults below reject no corpus package that today's bounds accept. The
|
|
32
|
+
* package budget is the one that matters: it caps a whole package at ~2.5M
|
|
33
|
+
* elements and ~3M attributes, which is at most ~425 MB of tree at the densest
|
|
34
|
+
* measured shape and ~124 MB at the cheapest. Before it existed, only
|
|
35
|
+
* `word/document.xml`, `word/styles.xml` and `word/numbering.xml` were counted
|
|
36
|
+
* at all, so a package of many merely-large parts could reach the expansion
|
|
37
|
+
* ceiling of 250 MiB, ~37M elements and well past 1.8 GB of tree while passing
|
|
38
|
+
* every bound. Lower these to trade format reach for a smaller ceiling.
|
|
39
|
+
*/
|
|
3
40
|
declare const FOLIO_XML_RESOURCE_LIMITS: {
|
|
4
41
|
readonly maxBytes: number;
|
|
5
42
|
readonly maxDepth: 100;
|
|
6
|
-
|
|
43
|
+
/** 1.68x the corpus maximum (596,668). Unchanged; a shipped bound is not loosened. */
|
|
44
|
+
readonly maxElementsPerPart: 1000000;
|
|
45
|
+
/** 3.97x the corpus maximum (630,374). */
|
|
46
|
+
readonly maxAttributesPerPart: 2500000;
|
|
47
|
+
/** 4.15x the corpus maximum (602,212). */
|
|
48
|
+
readonly maxElementsPerPackage: 2500000;
|
|
49
|
+
/** 4.69x the corpus maximum (639,110). */
|
|
50
|
+
readonly maxAttributesPerPackage: 3000000;
|
|
7
51
|
};
|
|
8
52
|
type XmlResourceLimits = {
|
|
9
53
|
maxBytes: number;
|
|
10
54
|
maxDepth: number;
|
|
11
|
-
|
|
55
|
+
maxElementsPerPart: number;
|
|
56
|
+
maxAttributesPerPart: number;
|
|
57
|
+
maxElementsPerPackage: number;
|
|
58
|
+
maxAttributesPerPackage: number;
|
|
12
59
|
};
|
|
13
|
-
type XmlResourceLimitKind = "bytes" | "depth" | "
|
|
60
|
+
type XmlResourceLimitKind = "bytes" | "depth" | "elements" | "attributes" | "package-elements" | "package-attributes" | "syntax";
|
|
14
61
|
declare const XmlResourceLimitError_base: import("better-result").TaggedErrorClass<"XmlResourceLimitError">;
|
|
15
62
|
/** XML input exceeded a parser resource bound or could not be scanned safely. */
|
|
16
63
|
declare class XmlResourceLimitError extends XmlResourceLimitError_base<{
|
|
17
64
|
message: string;
|
|
18
65
|
limit: XmlResourceLimitKind;
|
|
66
|
+
/** The package part being scanned, when the caller named one. */
|
|
67
|
+
partPath?: string;
|
|
68
|
+
/** The count reached at the point of refusal, not the count of the whole input. */
|
|
69
|
+
observed: number;
|
|
70
|
+
allowed: number;
|
|
19
71
|
}> {}
|
|
20
72
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
73
|
+
* What a package has spent so far, shared by every part in one package.
|
|
74
|
+
*
|
|
75
|
+
* Per-part bounds alone do not bound a package: a package may hold hundreds of
|
|
76
|
+
* parts, each individually modest. The budget is the accumulator the readers
|
|
77
|
+
* carry across parts so the ceiling is the package's, not each part's.
|
|
78
|
+
*/
|
|
79
|
+
type XmlPackageBudget = {
|
|
80
|
+
elements: number;
|
|
81
|
+
attributes: number;
|
|
82
|
+
};
|
|
83
|
+
declare const createXmlPackageBudget: () => XmlPackageBudget;
|
|
84
|
+
type XmlResourceScanOptions = {
|
|
85
|
+
xml: string;
|
|
86
|
+
limits?: XmlResourceLimits;
|
|
87
|
+
/** The package path scanned, carried on any refusal so a host can name it. */
|
|
88
|
+
partPath?: string;
|
|
89
|
+
/** Charged as the scan proceeds; omit for a part with no package context. */
|
|
90
|
+
budget?: XmlPackageBudget;
|
|
91
|
+
};
|
|
92
|
+
/** What the preflight counted, for callers that reconcile it against the tree. */
|
|
93
|
+
type XmlResourceScanResult = {
|
|
94
|
+
elements: number;
|
|
95
|
+
attributes: number;
|
|
96
|
+
maxDepth: number;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Bound XML bytes, element count, attribute count and nesting before building
|
|
100
|
+
* an object tree. The lexical scan is iterative, so deeply nested input cannot
|
|
101
|
+
* consume the JS call stack before the depth limit is enforced, and every
|
|
102
|
+
* bound is checked at the point it is crossed, so the work done before a
|
|
103
|
+
* refusal is proportional to the limit rather than to the input.
|
|
24
104
|
*/
|
|
25
|
-
declare const assertXmlResourceLimits: (xml
|
|
105
|
+
declare const assertXmlResourceLimits: ({ xml, limits, partPath, budget }: XmlResourceScanOptions) => XmlResourceScanResult;
|
|
26
106
|
//#endregion
|
|
27
|
-
export { FOLIO_XML_RESOURCE_LIMITS, XmlResourceLimitError, assertXmlResourceLimits };
|
|
107
|
+
export { FOLIO_XML_RESOURCE_LIMITS, XmlPackageBudget, XmlResourceLimitError, XmlResourceLimits, XmlResourceScanOptions, XmlResourceScanResult, assertXmlResourceLimits, createXmlPackageBudget };
|
|
@@ -1,12 +1,60 @@
|
|
|
1
1
|
import { TaggedError } from "better-result";
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Shared bounds for XML parts parsed by Folio.
|
|
4
|
+
*
|
|
5
|
+
* `maxBytes` and the package expansion ceiling bound the *markup*; they do not
|
|
6
|
+
* bound what parsing that markup allocates. A parsed element retains far more
|
|
7
|
+
* than the bytes it was written as, so a part that satisfies a byte bound can
|
|
8
|
+
* still cost multiples of it in tree. Measured on this repository's corpus
|
|
9
|
+
* generators (Bun 1.4, arm64, heap retained after a forced GC):
|
|
10
|
+
*
|
|
11
|
+
* shape bytes/element tree heap / part bytes
|
|
12
|
+
* `<w:r/>` 49.5 B 8.3x
|
|
13
|
+
* `<w:r a=".." x4/>` 105-124 B 2.8-3.3x
|
|
14
|
+
* `<w:r><w:t>x</w:t></w:r>` 162-171 B 14.1-14.8x
|
|
15
|
+
*
|
|
16
|
+
* An element is therefore the unit a memory bound has to count, because the
|
|
17
|
+
* adversarial shape is the cheap one: `<w:r/>` is 7 bytes of markup and 49.5
|
|
18
|
+
* bytes of tree, so 128 MiB of markup buys ~19M elements and ~950 MB of tree
|
|
19
|
+
* inside a byte budget that never trips.
|
|
20
|
+
*
|
|
21
|
+
* Corpus distribution (5,314 readable packages, every XML and .rels part):
|
|
22
|
+
*
|
|
23
|
+
* metric p50 p90 p99 p99.9 max
|
|
24
|
+
* elements / part 16 227 1,590 24,719 596,668
|
|
25
|
+
* elements / package 917 3,230 29,106 71,975 602,212
|
|
26
|
+
* attributes / part 27 577 1,993 21,037 630,374
|
|
27
|
+
* attributes / package 1,783 4,711 25,896 91,946 639,110
|
|
28
|
+
* depth / part 3 9 15 22 15,005
|
|
29
|
+
* elements per byte 0.012 0.027 0.036 0.043 0.111
|
|
30
|
+
*
|
|
31
|
+
* The defaults below reject no corpus package that today's bounds accept. The
|
|
32
|
+
* package budget is the one that matters: it caps a whole package at ~2.5M
|
|
33
|
+
* elements and ~3M attributes, which is at most ~425 MB of tree at the densest
|
|
34
|
+
* measured shape and ~124 MB at the cheapest. Before it existed, only
|
|
35
|
+
* `word/document.xml`, `word/styles.xml` and `word/numbering.xml` were counted
|
|
36
|
+
* at all, so a package of many merely-large parts could reach the expansion
|
|
37
|
+
* ceiling of 250 MiB, ~37M elements and well past 1.8 GB of tree while passing
|
|
38
|
+
* every bound. Lower these to trade format reach for a smaller ceiling.
|
|
39
|
+
*/
|
|
3
40
|
const FOLIO_XML_RESOURCE_LIMITS = {
|
|
4
41
|
maxBytes: 128 * (1024 * 1024),
|
|
5
42
|
maxDepth: 100,
|
|
6
|
-
|
|
43
|
+
/** 1.68x the corpus maximum (596,668). Unchanged; a shipped bound is not loosened. */
|
|
44
|
+
maxElementsPerPart: 1e6,
|
|
45
|
+
/** 3.97x the corpus maximum (630,374). */
|
|
46
|
+
maxAttributesPerPart: 25e5,
|
|
47
|
+
/** 4.15x the corpus maximum (602,212). */
|
|
48
|
+
maxElementsPerPackage: 25e5,
|
|
49
|
+
/** 4.69x the corpus maximum (639,110). */
|
|
50
|
+
maxAttributesPerPackage: 3e6
|
|
7
51
|
};
|
|
8
52
|
/** XML input exceeded a parser resource bound or could not be scanned safely. */
|
|
9
53
|
var XmlResourceLimitError = class extends TaggedError("XmlResourceLimitError") {};
|
|
54
|
+
const createXmlPackageBudget = () => ({
|
|
55
|
+
elements: 0,
|
|
56
|
+
attributes: 0
|
|
57
|
+
});
|
|
10
58
|
const exceedsUtf8ByteLimit = (value, maxBytes) => {
|
|
11
59
|
let bytes = 0;
|
|
12
60
|
for (let index = 0; index < value.length; index += 1) {
|
|
@@ -22,8 +70,9 @@ const exceedsUtf8ByteLimit = (value, maxBytes) => {
|
|
|
22
70
|
return false;
|
|
23
71
|
};
|
|
24
72
|
const isXmlWhitespace = (code) => code === 9 || code === 10 || code === 13 || code === 32;
|
|
25
|
-
const
|
|
73
|
+
const scanTag = (xml, start) => {
|
|
26
74
|
let quote = 0;
|
|
75
|
+
let attributes = 0;
|
|
27
76
|
for (let cursor = start; cursor < xml.length; cursor += 1) {
|
|
28
77
|
const code = xml.charCodeAt(cursor);
|
|
29
78
|
if (quote !== 0) {
|
|
@@ -34,29 +83,53 @@ const findTagClose = (xml, start) => {
|
|
|
34
83
|
quote = code;
|
|
35
84
|
continue;
|
|
36
85
|
}
|
|
37
|
-
if (code ===
|
|
86
|
+
if (code === 61) {
|
|
87
|
+
attributes += 1;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (code === 62) return {
|
|
91
|
+
close: cursor,
|
|
92
|
+
attributes
|
|
93
|
+
};
|
|
38
94
|
}
|
|
39
|
-
return
|
|
95
|
+
return {
|
|
96
|
+
close: -1,
|
|
97
|
+
attributes
|
|
98
|
+
};
|
|
40
99
|
};
|
|
41
100
|
const throwSyntaxLimit = () => {
|
|
42
101
|
throw new XmlResourceLimitError({
|
|
43
102
|
message: "XML resource preflight could not safely scan malformed markup",
|
|
44
|
-
limit: "syntax"
|
|
103
|
+
limit: "syntax",
|
|
104
|
+
observed: 0,
|
|
105
|
+
allowed: 0
|
|
45
106
|
});
|
|
46
107
|
};
|
|
47
108
|
/**
|
|
48
|
-
* Bound XML bytes, element count, and nesting before building
|
|
49
|
-
* The lexical scan is iterative, so deeply nested input cannot
|
|
50
|
-
* call stack before the depth limit is enforced
|
|
109
|
+
* Bound XML bytes, element count, attribute count and nesting before building
|
|
110
|
+
* an object tree. The lexical scan is iterative, so deeply nested input cannot
|
|
111
|
+
* consume the JS call stack before the depth limit is enforced, and every
|
|
112
|
+
* bound is checked at the point it is crossed, so the work done before a
|
|
113
|
+
* refusal is proportional to the limit rather than to the input.
|
|
51
114
|
*/
|
|
52
|
-
const assertXmlResourceLimits = (xml, limits = FOLIO_XML_RESOURCE_LIMITS) => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
115
|
+
const assertXmlResourceLimits = ({ xml, limits = FOLIO_XML_RESOURCE_LIMITS, partPath, budget }) => {
|
|
116
|
+
const refuse = (limit, message, observed, allowed) => {
|
|
117
|
+
throw new XmlResourceLimitError({
|
|
118
|
+
message: partPath === void 0 ? message : `${message} (part ${partPath})`,
|
|
119
|
+
limit,
|
|
120
|
+
...partPath === void 0 ? {} : { partPath },
|
|
121
|
+
observed,
|
|
122
|
+
allowed
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
if (exceedsUtf8ByteLimit(xml, limits.maxBytes)) refuse("bytes", `XML part exceeds ${String(limits.maxBytes)} bytes`, limits.maxBytes + 1, limits.maxBytes);
|
|
126
|
+
const budgetElements = budget?.elements ?? 0;
|
|
127
|
+
const budgetAttributes = budget?.attributes ?? 0;
|
|
57
128
|
let cursor = 0;
|
|
58
129
|
let depth = 0;
|
|
130
|
+
let maxDepth = 0;
|
|
59
131
|
let nodes = 0;
|
|
132
|
+
let attributes = 0;
|
|
60
133
|
while (cursor < xml.length) {
|
|
61
134
|
const open = xml.indexOf("<", cursor);
|
|
62
135
|
if (open === -1) break;
|
|
@@ -79,7 +152,7 @@ const assertXmlResourceLimits = (xml, limits = FOLIO_XML_RESOURCE_LIMITS) => {
|
|
|
79
152
|
continue;
|
|
80
153
|
}
|
|
81
154
|
if (xml.startsWith("<!", open)) throwSyntaxLimit();
|
|
82
|
-
const close =
|
|
155
|
+
const { close, attributes: tagAttributes } = scanTag(xml, open + 1);
|
|
83
156
|
if (close === -1) throwSyntaxLimit();
|
|
84
157
|
if (xml.charCodeAt(open + 1) === 47) {
|
|
85
158
|
if (depth === 0) throwSyntaxLimit();
|
|
@@ -88,21 +161,29 @@ const assertXmlResourceLimits = (xml, limits = FOLIO_XML_RESOURCE_LIMITS) => {
|
|
|
88
161
|
continue;
|
|
89
162
|
}
|
|
90
163
|
nodes += 1;
|
|
91
|
-
if (nodes > limits.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
});
|
|
164
|
+
if (nodes > limits.maxElementsPerPart) refuse("elements", `XML part contains more than ${String(limits.maxElementsPerPart)} elements`, nodes, limits.maxElementsPerPart);
|
|
165
|
+
if (budgetElements + nodes > limits.maxElementsPerPackage) refuse("package-elements", `DOCX package contains more than ${String(limits.maxElementsPerPackage)} XML elements`, budgetElements + nodes, limits.maxElementsPerPackage);
|
|
166
|
+
attributes += tagAttributes;
|
|
167
|
+
if (attributes > limits.maxAttributesPerPart) refuse("attributes", `XML part contains more than ${String(limits.maxAttributesPerPart)} attributes`, attributes, limits.maxAttributesPerPart);
|
|
168
|
+
if (budgetAttributes + attributes > limits.maxAttributesPerPackage) refuse("package-attributes", `DOCX package contains more than ${String(limits.maxAttributesPerPackage)} XML attributes`, budgetAttributes + attributes, limits.maxAttributesPerPackage);
|
|
95
169
|
let lastContent = close - 1;
|
|
96
170
|
while (lastContent > open && isXmlWhitespace(xml.charCodeAt(lastContent))) lastContent -= 1;
|
|
97
171
|
const elementDepth = depth + 1;
|
|
98
|
-
if (elementDepth > limits.maxDepth)
|
|
99
|
-
|
|
100
|
-
limit: "depth"
|
|
101
|
-
});
|
|
172
|
+
if (elementDepth > limits.maxDepth) refuse("depth", `XML part is nested deeper than ${String(limits.maxDepth)} elements`, elementDepth, limits.maxDepth);
|
|
173
|
+
if (elementDepth > maxDepth) maxDepth = elementDepth;
|
|
102
174
|
if (xml.charCodeAt(lastContent) !== 47) depth = elementDepth;
|
|
103
175
|
cursor = close + 1;
|
|
104
176
|
}
|
|
105
177
|
if (depth !== 0) throwSyntaxLimit();
|
|
178
|
+
if (budget) {
|
|
179
|
+
budget.elements += nodes;
|
|
180
|
+
budget.attributes += attributes;
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
elements: nodes,
|
|
184
|
+
attributes,
|
|
185
|
+
maxDepth
|
|
186
|
+
};
|
|
106
187
|
};
|
|
107
188
|
//#endregion
|
|
108
|
-
export { FOLIO_XML_RESOURCE_LIMITS, XmlResourceLimitError, assertXmlResourceLimits };
|
|
189
|
+
export { FOLIO_XML_RESOURCE_LIMITS, XmlResourceLimitError, assertXmlResourceLimits, createXmlPackageBudget };
|
package/dist/headless-layout.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { resolveDocumentGridLinePitch } from "./docx/documentGrid.js";
|
|
2
2
|
import { formatOoxmlCounter } from "./docx/ooxmlCounterFormatter.js";
|
|
3
|
+
import { createParseWarningCollector } from "./docx/parseContext.js";
|
|
4
|
+
import { formatParseWarnings } from "./docx/parseWarningMessage.js";
|
|
3
5
|
import { parseDocx } from "./docx/parser.js";
|
|
4
6
|
import { buildHeaderFooterFieldValues } from "./fields/resolveFieldValues.js";
|
|
5
7
|
import { extractEmbeddedFonts } from "./fonts/embeddedFonts.js";
|
|
@@ -209,14 +211,21 @@ const layoutDocxHeadless = async (input, options = {}) => {
|
|
|
209
211
|
});
|
|
210
212
|
if (parsed.isErr()) return Result.err(parsed.error);
|
|
211
213
|
const document = parsed.value;
|
|
214
|
+
const { context: projectionContext, warnings: projectionWarnings } = createParseWarningCollector("word/document.xml");
|
|
212
215
|
const projected = Result.try(() => toProseDoc(document, {
|
|
213
216
|
...document.package.styles ? { styles: document.package.styles } : {},
|
|
214
|
-
...document.package.theme ? { theme: document.package.theme } : {}
|
|
217
|
+
...document.package.theme ? { theme: document.package.theme } : {},
|
|
218
|
+
warn: projectionContext.warn
|
|
215
219
|
}));
|
|
216
220
|
if (projected.isErr()) return Result.err(new HeadlessLayoutError({
|
|
217
221
|
message: "The document could not be projected to the editable model.",
|
|
218
222
|
cause: projected.error
|
|
219
223
|
}));
|
|
224
|
+
const recorded = projectionWarnings();
|
|
225
|
+
if (recorded.length > 0) {
|
|
226
|
+
document.parseWarnings = [...document.parseWarnings ?? [], ...recorded];
|
|
227
|
+
document.warnings = [...document.warnings ?? [], ...formatParseWarnings(recorded)];
|
|
228
|
+
}
|
|
220
229
|
if (packageNeedsShaping(document.package)) {
|
|
221
230
|
const loaded = await Result.tryPromise({
|
|
222
231
|
try: () => getShaper(),
|
package/dist/index.d.ts
CHANGED
|
@@ -38,7 +38,8 @@ import { fromMarkdown } from "./markdown/fromMarkdown.js";
|
|
|
38
38
|
import { toMarkdown, toMarkdownResult } from "./markdown/index.js";
|
|
39
39
|
import { EmbeddedFont, EmbeddedFontParts, buildEmbeddedFontFamilyMap, extractEmbeddedFonts, getEmbeddedFontFaces, scopeEmbeddedFontFamily } from "./fonts/embeddedFonts.js";
|
|
40
40
|
import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "./utils/fontResolver.js";
|
|
41
|
+
import { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersion, FolioYjsAttrSchemaVersionError } from "./prosemirror/yjsDocumentMetadata.js";
|
|
41
42
|
import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
|
|
42
43
|
type Document = document_d_exports.Document;
|
|
43
44
|
type DocxConformanceClass = document_d_exports.DocxConformanceClass;
|
|
44
|
-
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareCompatibility, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFolioRequirement, type CompareResult, type CompareRevisionFormat, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, DRAWING_SAFETY_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentPropertiesOptions, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type DocxDrawingClassification, type DrawingSafetyClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_CONTENT_COMPARISON_LIMITS, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockStructuralBoundary, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIInlineBooleanProperty, type FolioAIInlineFormatting, type FolioAIInlineFormattingPatch, type FolioAIParagraphSpacing, type FolioAISignatureParty, type FolioBlockId, type FolioContentBlock, type FolioContentBlockProperty, type FolioContentComparison, type FolioContentComparisonError, type FolioContentComparisonEvent, type FolioContentComparisonLimit, FolioContentComparisonLimitError, type FolioContentContainerPathEntry, type FolioContentFormatRange, type FolioContentFormattingChange, type FolioContentIdStability, type FolioContentInlineBooleanProperty, type FolioContentInlineComparisonResult, type FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, FolioContentInlinePresentationProjectionError, type FolioContentLineSpacingRule, type FolioContentParagraphAlignment, type FolioContentParagraphFormattingPatch, type FolioContentParagraphKind, type FolioContentParagraphSpacing, type FolioContentRun, type FolioContentSnapshot, type FolioContentStructuralChange, type FolioContentTableLocation, type FolioContentTextSegment, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewHiddenRange, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareContent, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
45
|
+
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareCompatibility, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFolioRequirement, type CompareResult, type CompareRevisionFormat, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, DRAWING_SAFETY_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentPropertiesOptions, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type DocxDrawingClassification, type DrawingSafetyClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_CONTENT_COMPARISON_LIMITS, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FOLIO_YJS_ATTR_SCHEMA_VERSION, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockStructuralBoundary, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIInlineBooleanProperty, type FolioAIInlineFormatting, type FolioAIInlineFormattingPatch, type FolioAIParagraphSpacing, type FolioAISignatureParty, type FolioBlockId, type FolioContentBlock, type FolioContentBlockProperty, type FolioContentComparison, type FolioContentComparisonError, type FolioContentComparisonEvent, type FolioContentComparisonLimit, FolioContentComparisonLimitError, type FolioContentContainerPathEntry, type FolioContentFormatRange, type FolioContentFormattingChange, type FolioContentIdStability, type FolioContentInlineBooleanProperty, type FolioContentInlineComparisonResult, type FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, FolioContentInlinePresentationProjectionError, type FolioContentLineSpacingRule, type FolioContentParagraphAlignment, type FolioContentParagraphFormattingPatch, type FolioContentParagraphKind, type FolioContentParagraphSpacing, type FolioContentRun, type FolioContentSnapshot, type FolioContentStructuralChange, type FolioContentTableLocation, type FolioContentTextSegment, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type FolioYjsAttrSchemaVersion, FolioYjsAttrSchemaVersionError, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewHiddenRange, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareContent, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ import { DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, acceptAutocompleteSuggestion, acc
|
|
|
25
25
|
import { getTemplateDirectives, scanDirectives } from "./prosemirror/plugins/templateDirectives.js";
|
|
26
26
|
import { setTemplatePreviewValues } from "./prosemirror/plugins/templatePreviewValues.js";
|
|
27
27
|
import { clearTemplateSlashMenu, consumeTemplateSlashQuery, getTemplateSlashMenu, resetTemplateSlashQuery, templateSlashMenuKey } from "./prosemirror/plugins/templateSlashMenu.js";
|
|
28
|
+
import { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersionError } from "./prosemirror/yjsDocumentMetadata.js";
|
|
28
29
|
import { extractDocumentStyleSet, extractDocumentStyleSetFromDocx, inspectDocumentStyles, inspectDocumentStylesFromDocx } from "./style-sets/extract.js";
|
|
29
30
|
import { STELLA_STYLE_SET_NAME, createStellaStyleDocumentPreset, createStellaStyleSet } from "./style-sets/stellaStyle.js";
|
|
30
31
|
import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION } from "./style-sets/types.js";
|
|
@@ -33,4 +34,4 @@ import { createEmptyDocument } from "./utils/createDocument.js";
|
|
|
33
34
|
import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "./utils/fontResolver.js";
|
|
34
35
|
import { mergeDocumentContent } from "./utils/mergeDocumentContent.js";
|
|
35
36
|
import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
|
|
36
|
-
export { COMPARE_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, DRAWING_SAFETY_CLASSES, FOLIO_CONTENT_COMPARISON_LIMITS, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioContentComparisonLimitError, FolioContentInlinePresentationProjectionError, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareContent, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
37
|
+
export { COMPARE_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, DRAWING_SAFETY_CLASSES, FOLIO_CONTENT_COMPARISON_LIMITS, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioContentComparisonLimitError, FolioContentInlinePresentationProjectionError, FolioYjsAttrSchemaVersionError, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareContent, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
@@ -37,6 +37,7 @@ const buildPageBreakRunSourceDescendantIndex = (rootContent) => {
|
|
|
37
37
|
case "footnoteRef":
|
|
38
38
|
case "instrText":
|
|
39
39
|
case "noBreakHyphen":
|
|
40
|
+
case "preservedXml":
|
|
40
41
|
case "renderedPageBreak":
|
|
41
42
|
case "softHyphen":
|
|
42
43
|
case "symbol":
|
|
@@ -60,7 +61,7 @@ const buildPageBreakRunSourceDescendantIndex = (rootContent) => {
|
|
|
60
61
|
case "moveFrom":
|
|
61
62
|
case "moveTo":
|
|
62
63
|
case "inlineSdt":
|
|
63
|
-
case "
|
|
64
|
+
case "inlineWrapper": return inspectMany(content.content, inspectParagraphContent);
|
|
64
65
|
case "simpleField": {
|
|
65
66
|
const fieldResultFlags = inspectMany(content.content, inspectParagraphContent);
|
|
66
67
|
if (hasFlag(fieldResultFlags, SOURCE_FLAGS.paragraphPageBreak) && hasFlag(fieldResultFlags, SOURCE_FLAGS.paragraphTextBoxShape)) return fieldResultFlags | SOURCE_FLAGS.pageBreakSharesTextBoxShape;
|
|
@@ -82,7 +83,8 @@ const buildPageBreakRunSourceDescendantIndex = (rootContent) => {
|
|
|
82
83
|
case "moveFromRangeEnd":
|
|
83
84
|
case "moveToRangeStart":
|
|
84
85
|
case "moveToRangeEnd":
|
|
85
|
-
case "mathEquation":
|
|
86
|
+
case "mathEquation":
|
|
87
|
+
case "preservedInline": return 0;
|
|
86
88
|
default: return content;
|
|
87
89
|
}
|
|
88
90
|
});
|
|
@@ -94,6 +96,7 @@ const buildPageBreakRunSourceDescendantIndex = (rootContent) => {
|
|
|
94
96
|
case "paragraph": return inspectMany(block.content, inspectParagraphContent);
|
|
95
97
|
case "table": return inspectMany(block.rows, inspectTableRow);
|
|
96
98
|
case "blockSdt": return inspectBlocks(block.content);
|
|
99
|
+
case "preservedBlock": return 0;
|
|
97
100
|
default: return block;
|
|
98
101
|
}
|
|
99
102
|
});
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { serializeBorder } from "../docx/serializer/borderSerializer.js";
|
|
2
2
|
import { serializeShading, serializeTextFormatting } from "../docx/serializer/textFormattingSerializer.js";
|
|
3
|
-
import {
|
|
3
|
+
import { intAttr } from "../docx/serializer/xmlUtils.js";
|
|
4
4
|
import { sanitizeCapturedXmlElement } from "../docx/verbatimCapture.js";
|
|
5
5
|
import { NAMESPACES, OOXML_NAMESPACE_SCOPE } from "../docx/xmlParser.js";
|
|
6
|
+
import { escapeXmlAttribute } from "@stll/docx-core";
|
|
6
7
|
//#region src/internal/paragraphFormattingSerialization.ts
|
|
7
8
|
const modelParagraphNumberingReference = (reference) => {
|
|
8
9
|
if (!reference) return null;
|
|
@@ -140,7 +141,7 @@ const modelParagraphFormattingEmission = (input) => {
|
|
|
140
141
|
const { alignment, bidi, kinsoku, overflowPunctuation, spaceBefore, spaceAfter, lineSpacing, lineSpacingRule, snapToGrid, beforeAutospacing, afterAutospacing, spacingExplicit, indentLeft, indentRight, indentFirstLine, hangingIndent, borders, shading, tabs, keepNext, keepLines, widowControl, pageBreakBefore, contextualSpacing, numPr, numPrFromStyle, numberingChangeXml, outlineLevel, styleId, frame, suppressLineNumbers, suppressAutoHyphens, runProperties, runInWithNext } = input;
|
|
141
142
|
modelSpacingProvenance(spacingExplicit);
|
|
142
143
|
const propertiesXml = [
|
|
143
|
-
styleId ? `<w:pStyle w:val="${
|
|
144
|
+
styleId ? `<w:pStyle w:val="${escapeXmlAttribute(styleId)}"/>` : "",
|
|
144
145
|
serializeToggle("keepNext", keepNext),
|
|
145
146
|
serializeToggle("keepLines", keepLines),
|
|
146
147
|
serializeToggle("pageBreakBefore", pageBreakBefore),
|
|
@@ -8,12 +8,11 @@ import { setParagraphFrame } from "../../layout-engine/paragraphFrame.js";
|
|
|
8
8
|
import { setTextBoxGroupId } from "../../layout-engine/textBoxGroup.js";
|
|
9
9
|
import { DEFAULT_TEXTBOX_MARGINS } from "../../layout-engine/types.js";
|
|
10
10
|
import { getPageNumbering } from "../../paged-layout/sectionGeometry.js";
|
|
11
|
-
import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectSymbolAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../../prosemirror/attrs/index.js";
|
|
11
|
+
import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectInlineWrapperMarkAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectPreservedXmlAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectSymbolAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../../prosemirror/attrs/index.js";
|
|
12
12
|
import { autospacingMatchesBase } from "../../prosemirror/autospacingBase.js";
|
|
13
13
|
import { runShadingAttrsToShading } from "../../prosemirror/conversion/runShadingMark.js";
|
|
14
14
|
import { advanceListMarker, advanceVisibleListMarker, cloneListCounterState, formatCounter, resolveListTemplate } from "../../prosemirror/listMarker.js";
|
|
15
15
|
import { resolveNumberedRefFields } from "../../prosemirror/numberedRefFields.js";
|
|
16
|
-
import { pageBreakRunParagraphProjectionDisposition } from "../../prosemirror/pageBreakRunProjection.js";
|
|
17
16
|
import { directionToBidi } from "../../prosemirror/paragraphDirection.js";
|
|
18
17
|
import { resolveEffectiveRunStyleFormatting } from "../../prosemirror/runStyleFormatting.js";
|
|
19
18
|
import { expectTextBoxAnchorAttrs } from "../../prosemirror/textBoxAnchorAttrs.js";
|
|
@@ -102,6 +101,74 @@ function resetBlockIdCounter() {
|
|
|
102
101
|
blockIdCounter = 0;
|
|
103
102
|
}
|
|
104
103
|
/**
|
|
104
|
+
* What the painter does with each mark the schema declares.
|
|
105
|
+
*
|
|
106
|
+
* The switch below used to end in `default: break`, so a mark that reached it
|
|
107
|
+
* was silently not painted whether that was the decision or an omission. The
|
|
108
|
+
* table is total over {@link SchemaMarkName}: a mark added to the schema
|
|
109
|
+
* without a paint decision does not compile, and a mark this table says is
|
|
110
|
+
* painted but the switch does not handle panics rather than disappearing.
|
|
111
|
+
*/
|
|
112
|
+
const MARK_PAINT_DISPOSITIONS = {
|
|
113
|
+
bold: "runFormatting",
|
|
114
|
+
italic: "runFormatting",
|
|
115
|
+
underline: "runFormatting",
|
|
116
|
+
strike: "runFormatting",
|
|
117
|
+
textColor: "runFormatting",
|
|
118
|
+
runShading: "runFormatting",
|
|
119
|
+
highlight: "runFormatting",
|
|
120
|
+
fontSize: "runFormatting",
|
|
121
|
+
fontFamily: "runFormatting",
|
|
122
|
+
language: "runFormatting",
|
|
123
|
+
superscript: "runFormatting",
|
|
124
|
+
subscript: "runFormatting",
|
|
125
|
+
hyperlink: "runFormatting",
|
|
126
|
+
allCaps: "runFormatting",
|
|
127
|
+
smallCaps: "runFormatting",
|
|
128
|
+
footnoteRef: "runFormatting",
|
|
129
|
+
characterSpacing: "runFormatting",
|
|
130
|
+
emboss: "runFormatting",
|
|
131
|
+
imprint: "runFormatting",
|
|
132
|
+
hidden: "runFormatting",
|
|
133
|
+
textShadow: "runFormatting",
|
|
134
|
+
emphasisMark: "runFormatting",
|
|
135
|
+
textOutline: "runFormatting",
|
|
136
|
+
rtl: "runFormatting",
|
|
137
|
+
textEffect: "runFormatting",
|
|
138
|
+
runFormattingOverride: "runFormatting",
|
|
139
|
+
comment: "runFormatting",
|
|
140
|
+
insertion: "runFormatting",
|
|
141
|
+
deletion: "runFormatting",
|
|
142
|
+
inlineWrapper: "runFormatting",
|
|
143
|
+
characterStyle: "resolvedElsewhere",
|
|
144
|
+
pageBreakRunOwner: "notPainted",
|
|
145
|
+
runPropertyChange: "notPainted"
|
|
146
|
+
};
|
|
147
|
+
const markPaintDisposition = (name) => {
|
|
148
|
+
return MARK_PAINT_DISPOSITIONS[name];
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* The direction one bidirectional wrapper lays its content out in, as the
|
|
152
|
+
* innermost layer of a stack states it.
|
|
153
|
+
*
|
|
154
|
+
* Only the innermost is read: a wrapper inside another is the one whose
|
|
155
|
+
* direction the text is laid out in, and the outer layers are what the save
|
|
156
|
+
* leg rebuilds the nesting from.
|
|
157
|
+
*/
|
|
158
|
+
const innermostBidiWrapper = (stack) => {
|
|
159
|
+
const layer = stack.at(-1);
|
|
160
|
+
if (layer === void 0) return;
|
|
161
|
+
switch (layer.kind) {
|
|
162
|
+
case "bidi": return layer.direction === void 0 ? { control: layer.control } : {
|
|
163
|
+
control: layer.control,
|
|
164
|
+
direction: layer.direction
|
|
165
|
+
};
|
|
166
|
+
default:
|
|
167
|
+
layer.kind;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
105
172
|
* Extract run formatting from ProseMirror marks.
|
|
106
173
|
*/
|
|
107
174
|
function extractRunFormatting(marks, theme, fontAlternates) {
|
|
@@ -282,7 +349,14 @@ function extractRunFormatting(marks, theme, fontAlternates) {
|
|
|
282
349
|
}
|
|
283
350
|
break;
|
|
284
351
|
}
|
|
285
|
-
|
|
352
|
+
case "inlineWrapper": {
|
|
353
|
+
const bidiWrapper = innermostBidiWrapper(expectInlineWrapperMarkAttrs(mark).stack);
|
|
354
|
+
if (bidiWrapper) formatting.bidiWrapper = bidiWrapper;
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
default:
|
|
358
|
+
if (markPaintDisposition(mark.type.name) === "runFormatting") panic(`Mark ${mark.type.name} is painted as run formatting but has no branch here`);
|
|
359
|
+
break;
|
|
286
360
|
}
|
|
287
361
|
if (runFormattingOverride) applyRunFormattingOverrides(formatting, runFormattingOverride);
|
|
288
362
|
if (hasNoteRef && formatting.subscript) delete formatting.superscript;
|
|
@@ -530,6 +604,8 @@ function buildImageRun(attrs, constrained, pmStart, pmEnd, trackedChange) {
|
|
|
530
604
|
if (attrs.alt !== void 0) run.alt = attrs.alt;
|
|
531
605
|
if (attrs.transform !== void 0) run.transform = attrs.transform;
|
|
532
606
|
if (attrs.opacity != null) run.opacity = attrs.opacity;
|
|
607
|
+
if (attrs.brightness != null) run.brightness = attrs.brightness;
|
|
608
|
+
if (attrs.contrast != null) run.contrast = attrs.contrast;
|
|
533
609
|
if (attrs.wrapType !== void 0) run.wrapType = attrs.wrapType;
|
|
534
610
|
if (attrs.displayMode !== void 0) run.displayMode = attrs.displayMode;
|
|
535
611
|
if (attrs.cssFloat !== void 0) run.cssFloat = attrs.cssFloat;
|
|
@@ -684,6 +760,25 @@ function paragraphToRuns(node, startPos, _options, pageBreaks) {
|
|
|
684
760
|
});
|
|
685
761
|
return;
|
|
686
762
|
}
|
|
763
|
+
if (child.type.name === "preservedXml") {
|
|
764
|
+
const { text } = expectPreservedXmlAttrs(child);
|
|
765
|
+
if (text === "") return;
|
|
766
|
+
const formatting = extractRunFormatting(effectiveMarks, theme, fontAlternates);
|
|
767
|
+
applyCharacterStyleToggleFormatting({
|
|
768
|
+
formatting,
|
|
769
|
+
marks: effectiveMarks,
|
|
770
|
+
paragraphFormatting: pmAttrs.defaultTextFormatting,
|
|
771
|
+
styleResolver: _options.styleResolver
|
|
772
|
+
});
|
|
773
|
+
runs.push({
|
|
774
|
+
kind: "text",
|
|
775
|
+
text,
|
|
776
|
+
...mergeRunFormatting(paraDefaults, formatting),
|
|
777
|
+
pmStart: childPos,
|
|
778
|
+
pmEnd: childPos + child.nodeSize
|
|
779
|
+
});
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
687
782
|
if (child.type.name === "hardBreak") {
|
|
688
783
|
runs.push({
|
|
689
784
|
kind: "lineBreak",
|
|
@@ -1357,8 +1452,7 @@ function convertTableCell(node, startPos, options, tableCellMargins) {
|
|
|
1357
1452
|
const blocks = [];
|
|
1358
1453
|
let offset = startPos + 1;
|
|
1359
1454
|
const authoredPageBreakPosition = options.firstPageBreakRunPosition(node);
|
|
1360
|
-
const leadingParagraph = node.firstChild?.type.name === "paragraph" ? node.firstChild : void 0;
|
|
1361
|
-
if (authoredPageBreakPosition !== void 0 && (leadingParagraph === void 0 || countPageBreakRuns(node) !== 1 || options.firstPageBreakRunPosition(leadingParagraph) !== authoredPageBreakPosition)) panic(`An explicit page-break run at ${String(authoredPageBreakPosition)} cannot be projected inside a table cell`);
|
|
1455
|
+
const leadingParagraph = node.firstChild?.type.name === "paragraph" && countPageBreakRuns(node) === 1 && options.firstPageBreakRunPosition(node.firstChild) === authoredPageBreakPosition ? node.firstChild : void 0;
|
|
1362
1456
|
const pageBreaks = [];
|
|
1363
1457
|
node.forEach((child) => {
|
|
1364
1458
|
if (child.type.name === "paragraph") {
|
|
@@ -1406,7 +1500,7 @@ function convertTableCell(node, startPos, options, tableCellMargins) {
|
|
|
1406
1500
|
if (attrs.noWrap) cell.noWrap = true;
|
|
1407
1501
|
if (authoredPageBreakPosition === void 0 || pageBreaks.length === 0) return { cell };
|
|
1408
1502
|
const paragraph = blocks.at(0);
|
|
1409
|
-
if (paragraph?.kind !== "paragraph" || !hasSingleLeadingProjectedPageBreak(paragraph.runs, pageBreaks))
|
|
1503
|
+
if (paragraph?.kind !== "paragraph" || !hasSingleLeadingProjectedPageBreak(paragraph.runs, pageBreaks)) return { cell };
|
|
1410
1504
|
return {
|
|
1411
1505
|
cell,
|
|
1412
1506
|
breakBefore: "page"
|
|
@@ -1523,6 +1617,8 @@ function convertImage(node, startPos, pageContentHeight) {
|
|
|
1523
1617
|
if (attrs.alt) imgBlock.alt = attrs.alt;
|
|
1524
1618
|
if (attrs.transform) imgBlock.transform = attrs.transform;
|
|
1525
1619
|
if (attrs.opacity != null) imgBlock.opacity = attrs.opacity;
|
|
1620
|
+
if (attrs.brightness != null) imgBlock.brightness = attrs.brightness;
|
|
1621
|
+
if (attrs.contrast != null) imgBlock.contrast = attrs.contrast;
|
|
1526
1622
|
if (shouldAnchor) {
|
|
1527
1623
|
const anchor = {
|
|
1528
1624
|
isAnchored: true,
|
|
@@ -1544,8 +1640,6 @@ function convertImage(node, startPos, pageContentHeight) {
|
|
|
1544
1640
|
}
|
|
1545
1641
|
/** Convert a textBox PM node to a TextBoxBlock. */
|
|
1546
1642
|
function convertTextBoxNode(node, startPos, opts) {
|
|
1547
|
-
const pageBreakPosition = opts.firstPageBreakRunPosition(node);
|
|
1548
|
-
if (pageBreakPosition !== void 0) panic(`An explicit page-break run at ${String(pageBreakPosition)} cannot be projected inside a text box`);
|
|
1549
1643
|
const attrs = expectTextBoxAttrs(node);
|
|
1550
1644
|
const contentBlocks = [];
|
|
1551
1645
|
node.forEach((child, offset) => {
|
|
@@ -1746,10 +1840,6 @@ function toFlowBlocks(doc, options = {}) {
|
|
|
1746
1840
|
const pushParagraphProjection = (node, pos, stripLeadingLineBreak = false) => {
|
|
1747
1841
|
const pageBreaks = [];
|
|
1748
1842
|
const paragraph = convertParagraph(node, pos, opts, pageBreaks);
|
|
1749
|
-
if (pageBreaks.length > 0) {
|
|
1750
|
-
const disposition = pageBreakRunParagraphProjectionDisposition(node);
|
|
1751
|
-
if (disposition.status === "unsupported" && (disposition.reason === "textBoxAnchor" || !hasSingleLeadingProjectedPageBreak(paragraph.runs, pageBreaks))) panic(disposition.message);
|
|
1752
|
-
}
|
|
1753
1843
|
if (stripLeadingLineBreak && paragraph.runs.at(0)?.kind === "lineBreak") paragraph.runs.shift();
|
|
1754
1844
|
for (const block of splitParagraphAtPageBreaks({
|
|
1755
1845
|
pageBreaks,
|