@stll/folio-core 0.52.0 → 0.54.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/README.md +23 -0
- package/dist/ai-edits/apply.d.ts +26 -1
- package/dist/ai-edits/apply.js +1779 -141
- package/dist/ai-edits/batch-claims.d.ts +145 -0
- package/dist/ai-edits/batch-claims.js +275 -0
- package/dist/ai-edits/blockRange.js +9 -3
- package/dist/ai-edits/character-boundaries.d.ts +43 -0
- package/dist/ai-edits/character-boundaries.js +95 -0
- package/dist/ai-edits/clean-text.d.ts +33 -3
- package/dist/ai-edits/clean-text.js +52 -6
- package/dist/ai-edits/comment-lifecycle.d.ts +18 -0
- package/dist/ai-edits/comment-lifecycle.js +52 -0
- package/dist/ai-edits/headless.d.ts +91 -7
- package/dist/ai-edits/headless.js +520 -51
- package/dist/ai-edits/index.d.ts +2 -1
- package/dist/ai-edits/index.js +2 -1
- package/dist/ai-edits/minimal-replacement.d.ts +21 -6
- package/dist/ai-edits/minimal-replacement.js +134 -15
- package/dist/ai-edits/newListNumbering.d.ts +23 -0
- package/dist/ai-edits/newListNumbering.js +94 -0
- package/dist/ai-edits/note-references.d.ts +96 -0
- package/dist/ai-edits/note-references.js +139 -0
- package/dist/ai-edits/pending-suggestions.d.ts +79 -0
- package/dist/ai-edits/pending-suggestions.js +306 -0
- package/dist/ai-edits/read.d.ts +6 -4
- package/dist/ai-edits/read.js +113 -50
- package/dist/ai-edits/result-validation.d.ts +29 -0
- package/dist/ai-edits/result-validation.js +164 -0
- package/dist/ai-edits/revisionStretches.d.ts +17 -0
- package/dist/ai-edits/revisionStretches.js +80 -0
- package/dist/ai-edits/snapshot.d.ts +36 -3
- package/dist/ai-edits/snapshot.js +180 -25
- package/dist/ai-edits/table-cell-mutations.d.ts +4 -2
- package/dist/ai-edits/table-cell-mutations.js +6 -2
- package/dist/ai-edits/table-geometry.d.ts +1 -1
- package/dist/ai-edits/table-row-column-mutations.d.ts +44 -17
- package/dist/ai-edits/table-row-column-mutations.js +86 -34
- package/dist/ai-edits/types.d.ts +155 -16
- package/dist/compare/compare.d.ts +1 -1
- package/dist/compare/compare.js +65 -16
- package/dist/compare/content-alignment.d.ts +5 -1
- package/dist/compare/content-alignment.js +52 -34
- package/dist/compare/content-types.d.ts +7 -0
- package/dist/compare/content.d.ts +4 -1
- package/dist/compare/content.js +6 -1
- package/dist/compare/formatting.js +2 -1
- package/dist/compare/inline-atoms.d.ts +21 -4
- package/dist/compare/inline-atoms.js +138 -16
- package/dist/compare/inline-provenance.js +1 -1
- package/dist/compare/plan.js +10 -5
- package/dist/compare/scenario.js +14 -3
- package/dist/compare/section-boundary-properties.js +1 -1
- package/dist/compare/types.d.ts +4 -2
- package/dist/compare/types.js +2 -1
- package/dist/compare/verification.d.ts +1 -1
- package/dist/compare/verification.js +15 -3
- package/dist/controller/committedLayoutDiff.d.ts +25 -0
- package/dist/controller/committedLayoutDiff.js +71 -0
- package/dist/controller/contentControlWidgetController.d.ts +1 -1
- package/dist/controller/folioEditor.d.ts +1 -1
- package/dist/controller/fontReadiness.d.ts +70 -3
- package/dist/controller/fontReadiness.js +100 -10
- package/dist/controller/headerFooterEditorManager.js +6 -1
- package/dist/controller/layoutPipeline.d.ts +12 -10
- package/dist/controller/layoutPipeline.js +65 -11
- package/dist/controller/layoutRunOptions.d.ts +24 -0
- package/dist/controller/layoutRunOptions.js +17 -0
- package/dist/controller/layoutScheduler.d.ts +19 -14
- package/dist/controller/layoutScheduler.js +15 -12
- package/dist/controller/layoutSession.d.ts +26 -2
- package/dist/controller/layoutSession.js +1 -1
- package/dist/controller/noteEditorManager.js +8 -3
- package/dist/document-operations.d.ts +11 -2
- package/dist/document-operations.js +230 -21
- package/dist/docx/altChunk.d.ts +8 -0
- package/dist/docx/altChunk.js +17 -0
- package/dist/docx/archiveInflation.d.ts +127 -0
- package/dist/docx/archiveInflation.js +181 -0
- package/dist/docx/attributeRemainder.d.ts +1 -1
- package/dist/docx/blockContentParser.d.ts +64 -1
- package/dist/docx/blockContentParser.js +17 -4
- package/dist/docx/blockCustomXmlShell.d.ts +7 -0
- package/dist/docx/blockCustomXmlShell.js +14 -0
- package/dist/docx/blockPlainText.js +7 -0
- package/dist/docx/commentAnchorIndex.js +1 -1
- package/dist/docx/commentRangeIntegrity.js +8 -3
- package/dist/docx/commentReferenceNormalization.js +1 -1
- package/dist/docx/commentReplyMarkers.js +20 -1
- package/dist/docx/compatibility.d.ts +1 -1
- package/dist/docx/compatibility.js +34 -13
- package/dist/docx/containerChildren.gen.d.ts +1 -1
- package/dist/docx/containerChildren.gen.js +1 -0
- package/dist/docx/documentParser.js +12 -12
- package/dist/docx/drawingIdNormalization.d.ts +3 -1
- package/dist/docx/drawingIdNormalization.js +6 -1
- package/dist/docx/ensureParaIds.js +119 -97
- package/dist/docx/footnoteParser.js +8 -4
- package/dist/docx/headerFooterParser.js +3 -3
- package/dist/docx/headerFooterReferenceNormalization.d.ts +20 -1
- package/dist/docx/headerFooterReferenceNormalization.js +52 -27
- package/dist/docx/hyperlinkParser.d.ts +1 -1
- package/dist/docx/index.d.ts +1 -1
- package/dist/docx/listNumberingInstances.d.ts +59 -0
- package/dist/docx/listNumberingInstances.js +249 -0
- package/dist/docx/metadataPrivacy.js +24 -1
- package/dist/docx/normalizeBaseDirection.js +2 -1
- package/dist/docx/noteReferenceMark.d.ts +15 -0
- package/dist/docx/noteReferenceMark.js +48 -0
- package/dist/docx/opaqueCarrier.d.ts +7 -0
- package/dist/docx/opaqueCarrier.js +38 -0
- package/dist/docx/packageParts.js +4 -1
- package/dist/docx/paragraphParser.js +96 -27
- package/dist/docx/paragraphPropertySource.d.ts +4 -2
- package/dist/docx/paragraphPropertySource.js +10 -2
- package/dist/docx/paragraphTraversal.js +1 -0
- package/dist/docx/parseWarningMessage.js +4 -1
- package/dist/docx/parser.js +175 -22
- package/dist/docx/rezip.js +31 -7
- package/dist/docx/sdtProperties.js +1 -1
- package/dist/docx/sdtPropertiesPatch.js +3 -0
- package/dist/docx/selectiveSave.js +16 -9
- package/dist/docx/selectiveXmlPatch.d.ts +3 -1
- package/dist/docx/selectiveXmlPatch.js +186 -39
- package/dist/docx/serializer/blockCustomXmlSerializer.d.ts +5 -0
- package/dist/docx/serializer/blockCustomXmlSerializer.js +4 -0
- package/dist/docx/serializer/documentSerializer.js +2 -0
- package/dist/docx/serializer/headerFooterSerializer.js +2 -0
- package/dist/docx/serializer/noteSerializer.js +3 -1
- package/dist/docx/serializer/paragraphSerializer.js +33 -9
- package/dist/docx/serializer/tableSerializer.js +25 -38
- package/dist/docx/server/boundedArchive.d.ts +8 -13
- package/dist/docx/server/boundedArchive.js +70 -59
- package/dist/docx/server/createBilingualDocument.js +3 -3
- package/dist/docx/server/extractDocxText.d.ts +8 -2
- package/dist/docx/server/extractDocxText.js +2 -2
- package/dist/docx/server/validateDocxConformance.d.ts +1 -1
- package/dist/docx/server/validateDocxConformance.js +1 -0
- package/dist/docx/tableParser.d.ts +157 -1
- package/dist/docx/tableParser.js +89 -10
- package/dist/docx/textBoxParser.js +1 -1
- package/dist/docx/unzip.d.ts +20 -2
- package/dist/docx/unzip.js +136 -25
- package/dist/docx/wordprocessingPrefixes.d.ts +78 -0
- package/dist/docx/wordprocessingPrefixes.js +286 -0
- package/dist/fonts/embeddedFonts.js +1 -1
- package/dist/i18n/messages/catalogs.gen.d.ts +170 -34
- package/dist/i18n/messages/catalogs.gen.js +187 -51
- package/dist/i18n/messages/messages.gen.d.ts +10 -2
- package/dist/internal/compare/inline-presentation.d.ts +2 -1
- package/dist/internal/compare/inline-presentation.js +11 -10
- package/dist/internal/headlessRevisionResolutionGuard.d.ts +2 -8
- package/dist/internal/headlessRevisionResolutionGuard.js +2 -11
- package/dist/internal/indexedPositionMap.d.ts +11 -0
- package/dist/internal/indexedPositionMap.js +42 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +2 -1
- package/dist/internal/revisionResolutionEdits.d.ts +13 -0
- package/dist/internal/revisionResolutionEdits.js +19 -0
- package/dist/internal/revisionResolutionInline.d.ts +24 -0
- package/dist/internal/{headlessRevisionResolution.js → revisionResolutionInline.js} +61 -43
- package/dist/internal/revisionResolutionStep.d.ts +34 -0
- package/dist/internal/revisionResolutionStep.js +282 -0
- package/dist/internal/revisionResolutionTracking.d.ts +11 -0
- package/dist/internal/revisionResolutionTracking.js +124 -0
- package/dist/internal/wholeStoryRevisionResolution.d.ts +56 -0
- package/dist/internal/wholeStoryRevisionResolution.js +600 -0
- package/dist/layout-bridge/convert/markupViewFlow.d.ts +20 -0
- package/dist/layout-bridge/convert/markupViewFlow.js +123 -0
- package/dist/layout-bridge/convert/tableConversion.js +1 -1
- package/dist/layout-bridge/convert/toFlowBlocks.js +10 -1
- package/dist/layout-engine/layoutInstrumentation.d.ts +9 -1
- package/dist/layout-engine/layoutInstrumentation.js +4 -1
- package/dist/layout-engine/measure/cache.d.ts +18 -1
- package/dist/layout-engine/measure/cache.js +31 -1
- package/dist/layout-engine/measure/font-metrics.worker.js +3 -7
- package/dist/layout-engine/measure/measureContainer.js +7 -47
- package/dist/layout-engine/measure/measureHelpers.d.ts +6 -1
- package/dist/layout-engine/measure/measureHelpers.js +22 -2
- package/dist/layout-engine/measure/measureParagraph.js +2 -2
- package/dist/layout-engine/measure/measureWorker.js +2 -3
- package/dist/layout-engine/measure/measureWorkerProtocol.d.ts +6 -7
- package/dist/layout-engine/measure/measureWorkerProtocol.js +1 -2
- package/dist/layout-engine/measure/paragraphMeasureShared.d.ts +12 -1
- package/dist/layout-engine/measure/paragraphMeasureShared.js +14 -1
- package/dist/layout-engine/types.d.ts +6 -0
- package/dist/layout-painter/renderPage.js +1 -0
- package/dist/layout-painter/renderParagraph.js +1 -1
- package/dist/managers/ContextMenuManager.js +5 -2
- package/dist/managers/types.d.ts +3 -0
- package/dist/markdown/escape.d.ts +2 -2
- package/dist/markdown/escape.js +4 -5
- package/dist/markdown/fromMarkdown.js +2 -1
- package/dist/markdown/internals.d.ts +11 -1
- package/dist/markdown/internals.js +24 -3
- package/dist/markdown/renderBlock.js +121 -25
- package/dist/markdown/renderParagraph.d.ts +13 -1
- package/dist/markdown/renderParagraph.js +85 -38
- package/dist/markdown/renderRuns.d.ts +10 -1
- package/dist/markdown/renderRuns.js +323 -69
- package/dist/markdown/renderTable.js +24 -12
- package/dist/markdown/trailers.js +2 -2
- package/dist/markdown/types.d.ts +29 -7
- package/dist/paged-layout/incrementalMeasure.d.ts +1 -2
- package/dist/paged-layout/incrementalMeasure.js +1 -9
- package/dist/paged-layout/transactionDirtyRange.d.ts +1 -3
- package/dist/paged-layout/transactionDirtyRange.js +29 -41
- package/dist/panel-layout.d.ts +83 -0
- package/dist/panel-layout.js +96 -0
- package/dist/prosemirror/anchoredTextBoxes.d.ts +37 -0
- package/dist/prosemirror/anchoredTextBoxes.js +156 -0
- package/dist/prosemirror/attrs/index.d.ts +6 -2
- package/dist/prosemirror/attrs/index.js +172 -1
- package/dist/prosemirror/clearRunColor.d.ts +6 -0
- package/dist/prosemirror/clearRunColor.js +46 -0
- package/dist/prosemirror/commands/comments.d.ts +7 -8
- package/dist/prosemirror/commands/comments.js +281 -212
- package/dist/prosemirror/commands/contentControls.d.ts +1 -1
- package/dist/prosemirror/commands/formatPainter.d.ts +1 -1
- package/dist/prosemirror/commands/formatPainter.js +1 -1
- package/dist/prosemirror/commands/formatting.d.ts +1 -1
- package/dist/prosemirror/commands/hyperlink.js +2 -1
- package/dist/prosemirror/commands/index.d.ts +2 -2
- package/dist/prosemirror/commands/index.js +2 -2
- package/dist/prosemirror/commands/paragraph.d.ts +7 -1
- package/dist/prosemirror/commands/paragraph.js +9 -1
- package/dist/prosemirror/commands/paragraphBookmarkJoin.d.ts +13 -0
- package/dist/prosemirror/commands/paragraphBookmarkJoin.js +22 -0
- package/dist/prosemirror/commands/pastePlainText.d.ts +1 -1
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +3 -2
- package/dist/prosemirror/commands/propertyChangeScope.js +24 -3
- package/dist/prosemirror/commands/resolveAllTableChanges.d.ts +40 -0
- package/dist/prosemirror/commands/resolveAllTableChanges.js +620 -0
- package/dist/prosemirror/commands/resolveNodePropertyChangeAttrs.d.ts +15 -0
- package/dist/prosemirror/commands/resolveNodePropertyChangeAttrs.js +46 -0
- package/dist/prosemirror/commands/resolveParagraphProperties.d.ts +16 -0
- package/dist/prosemirror/commands/resolveParagraphProperties.js +73 -0
- package/dist/prosemirror/commands/sectionBreak.js +2 -1
- package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +15 -2
- package/dist/prosemirror/commands/tableCellMergeResolution.js +23 -7
- package/dist/prosemirror/containerFinalParagraph.d.ts +11 -5
- package/dist/prosemirror/containerFinalParagraph.js +7 -6
- package/dist/prosemirror/contentControlRevisions.d.ts +1 -1
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
- package/dist/prosemirror/conversion/fromProseDoc.js +177 -605
- package/dist/prosemirror/conversion/toProseDoc.d.ts +4 -11
- package/dist/prosemirror/conversion/toProseDoc.js +70 -154
- package/dist/prosemirror/documentSchema.d.ts +8 -0
- package/dist/prosemirror/documentSchema.js +18 -0
- package/dist/prosemirror/emptyFieldResultRuns.d.ts +18 -0
- package/dist/prosemirror/emptyFieldResultRuns.js +33 -0
- package/dist/prosemirror/extensions/ExtensionManager.d.ts +1 -1
- package/dist/prosemirror/extensions/ExtensionManager.js +3 -1
- package/dist/prosemirror/extensions/StarterKit.js +5 -1
- package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +116 -63
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +4 -1
- package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +24 -3
- package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.d.ts +20 -0
- package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.js +43 -0
- package/dist/prosemirror/extensions/features/ListExtension.js +167 -128
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +19 -2
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +33 -20
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +31 -2
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +270 -99
- package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +3 -2
- package/dist/prosemirror/extensions/features/pasteCleanup.js +2 -1
- package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +1 -1
- package/dist/prosemirror/extensions/features/pastedHtmlLists.d.ts +12 -0
- package/dist/prosemirror/extensions/features/pastedHtmlLists.js +124 -0
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +33 -11
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +8 -4
- package/dist/prosemirror/extensions/marks/RunIdentityExtension.d.ts +21 -18
- package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +37 -17
- package/dist/prosemirror/extensions/marks/StrikeExtension.js +2 -2
- package/dist/prosemirror/extensions/marks/SubscriptExtension.js +2 -2
- package/dist/prosemirror/extensions/marks/SuperscriptExtension.js +2 -2
- package/dist/prosemirror/extensions/marks/TextColorExtension.js +4 -3
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +15 -8
- package/dist/prosemirror/extensions/marks/markUtils.js +25 -10
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.d.ts +12 -0
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +46 -0
- package/dist/prosemirror/extensions/nodes/BlockCustomXmlExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/BlockCustomXmlExtension.js +52 -0
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +2 -2
- package/dist/prosemirror/extensions/nodes/FieldExtension.d.ts +3 -3
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +50 -15
- package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +5 -3
- package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +4 -1
- package/dist/prosemirror/extensions/nodes/TableExtension.d.ts +1 -1
- package/dist/prosemirror/extensions/nodes/TableExtension.js +121 -226
- package/dist/prosemirror/extensions/types.d.ts +11 -1
- package/dist/prosemirror/findReplaceSelection.js +1 -1
- package/dist/prosemirror/hyperlinkRemoval.d.ts +9 -0
- package/dist/prosemirror/hyperlinkRemoval.js +129 -0
- package/dist/prosemirror/index.d.ts +5 -3
- package/dist/prosemirror/index.js +5 -3
- package/dist/prosemirror/indexedNodeLookup.d.ts +17 -0
- package/dist/prosemirror/indexedNodeLookup.js +103 -0
- package/dist/prosemirror/listAutoformatMarkers.d.ts +19 -0
- package/dist/prosemirror/listAutoformatMarkers.js +98 -0
- package/dist/prosemirror/listInstanceReferences.d.ts +12 -0
- package/dist/prosemirror/listInstanceReferences.js +72 -0
- package/dist/prosemirror/listLabels.d.ts +24 -0
- package/dist/prosemirror/listLabels.js +111 -0
- package/dist/prosemirror/listNumbering.d.ts +92 -0
- package/dist/prosemirror/listNumbering.js +330 -0
- package/dist/prosemirror/listRendering.d.ts +27 -0
- package/dist/prosemirror/listRendering.js +27 -0
- package/dist/prosemirror/listRenderingAttrs.d.ts +11 -2
- package/dist/prosemirror/listRenderingAttrs.js +8 -1
- package/dist/prosemirror/markupViewNotes.d.ts +8 -0
- package/dist/prosemirror/markupViewNotes.js +49 -0
- package/dist/prosemirror/markupViewProjection.d.ts +97 -0
- package/dist/prosemirror/markupViewProjection.js +88 -0
- package/dist/prosemirror/noteReferenceReview.d.ts +77 -0
- package/dist/prosemirror/noteReferenceReview.js +332 -0
- package/dist/prosemirror/numberingAttr.d.ts +9 -1
- package/dist/prosemirror/numberingAttr.js +9 -1
- package/dist/prosemirror/outlineLevelAttr.js +1 -1
- package/dist/prosemirror/paragraphIndentation.d.ts +10 -1
- package/dist/prosemirror/paragraphIndentation.js +32 -7
- package/dist/prosemirror/paragraphMarkJoin.d.ts +21 -0
- package/dist/prosemirror/paragraphMarkJoin.js +26 -0
- package/dist/prosemirror/paragraphPropertyCarry.d.ts +64 -0
- package/dist/prosemirror/paragraphPropertyCarry.js +158 -0
- package/dist/prosemirror/plugins/createDocScanPlugin.d.ts +1 -1
- package/dist/prosemirror/plugins/documentNumbering.d.ts +27 -1
- package/dist/prosemirror/plugins/documentNumbering.js +97 -11
- package/dist/prosemirror/plugins/documentStyleState.d.ts +26 -0
- package/dist/prosemirror/plugins/documentStyleState.js +32 -0
- package/dist/prosemirror/plugins/documentStyles.d.ts +3 -13
- package/dist/prosemirror/plugins/documentStyles.js +67 -17
- package/dist/prosemirror/plugins/index.d.ts +2 -1
- package/dist/prosemirror/plugins/index.js +2 -1
- package/dist/prosemirror/plugins/paragraphStyleResolution.d.ts +15 -0
- package/dist/prosemirror/plugins/paragraphStyleResolution.js +230 -0
- package/dist/prosemirror/plugins/suggestionMode.d.ts +27 -3
- package/dist/prosemirror/plugins/suggestionMode.js +490 -63
- package/dist/prosemirror/plugins/templateDirectives.d.ts +1 -1
- package/dist/prosemirror/plugins/transactionInvariants.d.ts +32 -0
- package/dist/prosemirror/plugins/transactionInvariants.js +86 -0
- package/dist/prosemirror/positionSweep.d.ts +24 -0
- package/dist/prosemirror/positionSweep.js +222 -0
- package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +23 -3
- package/dist/prosemirror/rebaseParagraphRunFormatting.js +39 -13
- package/dist/prosemirror/rebaseParagraphRuns.d.ts +36 -0
- package/dist/prosemirror/rebaseParagraphRuns.js +99 -0
- package/dist/prosemirror/rejoinRunCarriers.d.ts +1 -1
- package/dist/prosemirror/replacedAnnotations.d.ts +33 -1
- package/dist/prosemirror/replacedAnnotations.js +170 -1
- package/dist/prosemirror/runFormattingFromMarks.d.ts +18 -0
- package/dist/prosemirror/runFormattingFromMarks.js +567 -0
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +1 -1
- package/dist/prosemirror/runFormattingReconciliation.js +10 -9
- package/dist/prosemirror/schema/index.d.ts +2 -2
- package/dist/prosemirror/schema/index.js +3 -0
- package/dist/prosemirror/schema/nodes.d.ts +44 -11
- package/dist/prosemirror/sectionMarkEdits.d.ts +20 -0
- package/dist/prosemirror/sectionMarkEdits.js +59 -0
- package/dist/prosemirror/storyListNumbering.d.ts +17 -0
- package/dist/prosemirror/storyListNumbering.js +102 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.d.ts +59 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.js +145 -0
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +21 -2
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +38 -1
- package/dist/prosemirror/styles/tableStyleRegions.d.ts +31 -0
- package/dist/prosemirror/styles/tableStyleRegions.js +55 -0
- package/dist/prosemirror/tableCellPaste.d.ts +74 -0
- package/dist/prosemirror/tableCellPaste.js +525 -0
- package/dist/prosemirror/tableGridMutation.d.ts +87 -2
- package/dist/prosemirror/tableGridMutation.js +255 -2
- package/dist/prosemirror/tableRunIn.d.ts +51 -0
- package/dist/prosemirror/tableRunIn.js +165 -0
- package/dist/prosemirror/textInput.js +11 -2
- package/dist/prosemirror/trackedRevisionPath.d.ts +17 -0
- package/dist/prosemirror/trackedRevisionPath.js +32 -0
- package/dist/prosemirror/validation.js +5 -1
- package/dist/redline.js +93 -9
- package/dist/render-dom/BodySelectionOverlay.d.ts +4 -1
- package/dist/render-dom/BodySelectionOverlay.js +3 -2
- package/dist/server.d.ts +2 -2
- package/dist/utils/findReplace.js +2 -2
- package/dist/utils/mergeDocumentContent.js +1 -1
- package/dist/utils/noteReferenceLabels.d.ts +36 -0
- package/dist/utils/noteReferenceLabels.js +32 -0
- package/dist/utils/replaceText.js +1 -1
- package/dist/version-comparison.d.ts +1 -0
- package/dist/version-comparison.js +1 -0
- package/package.json +6 -5
- package/dist/internal/headlessRevisionResolution.d.ts +0 -23
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { indexedPositionMap } from "../../internal/indexedPositionMap.js";
|
|
2
|
+
//#region src/layout-bridge/convert/markupViewFlow.ts
|
|
3
|
+
/**
|
|
4
|
+
* Re-address blocks built from a view projection in editor positions, and mark
|
|
5
|
+
* the paragraphs the view flags with a change bar.
|
|
6
|
+
*/
|
|
7
|
+
function remapMarkupViewBlocks(blocks, { positionMap, changeBarRanges }) {
|
|
8
|
+
const inverse = positionMap.invert();
|
|
9
|
+
const cutSet = /* @__PURE__ */ new Set();
|
|
10
|
+
inverse.forEach((oldStart, oldEnd) => {
|
|
11
|
+
cutSet.add(oldStart);
|
|
12
|
+
cutSet.add(oldEnd);
|
|
13
|
+
});
|
|
14
|
+
const context = {
|
|
15
|
+
toSource: indexedPositionMap(inverse),
|
|
16
|
+
cuts: [...cutSet].sort((left, right) => left - right),
|
|
17
|
+
changeBarRanges
|
|
18
|
+
};
|
|
19
|
+
return blocks.map((block) => remapBlock(block, context));
|
|
20
|
+
}
|
|
21
|
+
const touchesChangeBar = (block, ranges) => {
|
|
22
|
+
const { pmStart, pmEnd } = block;
|
|
23
|
+
if (pmStart === void 0 || pmEnd === void 0) return false;
|
|
24
|
+
return ranges.some((range) => range.from < pmEnd && range.to > pmStart);
|
|
25
|
+
};
|
|
26
|
+
/** A node's own positions: its start after any hidden content before it, its end before any after. */
|
|
27
|
+
const remapNodeRange = (range, toSource) => {
|
|
28
|
+
if (range.pmStart === void 0 || range.pmEnd === void 0) return {};
|
|
29
|
+
const pmStart = toSource(range.pmStart, 1);
|
|
30
|
+
return {
|
|
31
|
+
pmStart,
|
|
32
|
+
pmEnd: Math.max(pmStart, toSource(range.pmEnd, -1))
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
const remapSdtGroups = (groups, toSource) => groups === void 0 ? {} : { sdtGroups: groups.map((group) => ({
|
|
36
|
+
...group,
|
|
37
|
+
pmPos: toSource(group.pmPos, 1)
|
|
38
|
+
})) };
|
|
39
|
+
function remapBlock(block, context) {
|
|
40
|
+
switch (block.kind) {
|
|
41
|
+
case "paragraph": return remapParagraph(block, context);
|
|
42
|
+
case "table": return remapTable(block, context);
|
|
43
|
+
case "image":
|
|
44
|
+
case "pageBreak":
|
|
45
|
+
case "columnBreak": return {
|
|
46
|
+
...block,
|
|
47
|
+
...remapNodeRange(block, context.toSource)
|
|
48
|
+
};
|
|
49
|
+
case "textBox": return {
|
|
50
|
+
...block,
|
|
51
|
+
...remapNodeRange(block, context.toSource),
|
|
52
|
+
content: block.content.map((contentBlock) => contentBlock.kind === "table" ? remapTable(contentBlock, context) : remapParagraph(contentBlock, context))
|
|
53
|
+
};
|
|
54
|
+
case "sectionBreak": return block;
|
|
55
|
+
default: return block;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function remapTable(block, context) {
|
|
59
|
+
return {
|
|
60
|
+
...block,
|
|
61
|
+
...remapNodeRange(block, context.toSource),
|
|
62
|
+
...remapSdtGroups(block.sdtGroups, context.toSource),
|
|
63
|
+
rows: block.rows.map((row) => ({
|
|
64
|
+
...row,
|
|
65
|
+
cells: row.cells.map((cell) => ({
|
|
66
|
+
...cell,
|
|
67
|
+
blocks: cell.blocks.map((cellBlock) => remapBlock(cellBlock, context))
|
|
68
|
+
}))
|
|
69
|
+
}))
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function remapParagraph(block, context) {
|
|
73
|
+
const runs = [];
|
|
74
|
+
for (const run of block.runs) pushRemappedRun(run, context, runs);
|
|
75
|
+
return {
|
|
76
|
+
...block,
|
|
77
|
+
...remapNodeRange(block, context.toSource),
|
|
78
|
+
...remapSdtGroups(block.sdtGroups, context.toSource),
|
|
79
|
+
...touchesChangeBar(block, context.changeBarRanges) ? { reviewIndicator: "change-bar" } : {},
|
|
80
|
+
runs
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/** Index of the first cut strictly after `position`. */
|
|
84
|
+
const firstCutAfter = (cuts, position) => {
|
|
85
|
+
let low = 0;
|
|
86
|
+
let high = cuts.length;
|
|
87
|
+
while (low < high) {
|
|
88
|
+
const middle = Math.floor((low + high) / 2);
|
|
89
|
+
const cut = cuts.at(middle);
|
|
90
|
+
if (cut !== void 0 && cut <= position) low = middle + 1;
|
|
91
|
+
else high = middle;
|
|
92
|
+
}
|
|
93
|
+
return low;
|
|
94
|
+
};
|
|
95
|
+
/** Whether each character of the run occupies exactly one position. */
|
|
96
|
+
const addressesPerCharacter = (run) => run.pmStart !== void 0 && run.pmEnd !== void 0 && run.templatePreview === void 0 && run.text.length === run.pmEnd - run.pmStart;
|
|
97
|
+
function pushRemappedRun(run, context, out) {
|
|
98
|
+
if (run.kind !== "text" || !addressesPerCharacter(run)) {
|
|
99
|
+
out.push({
|
|
100
|
+
...run,
|
|
101
|
+
...remapNodeRange(run, context.toSource)
|
|
102
|
+
});
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const { pmStart, pmEnd } = run;
|
|
106
|
+
let pieceStart = pmStart;
|
|
107
|
+
for (let index = firstCutAfter(context.cuts, pmStart);; index++) {
|
|
108
|
+
const cut = context.cuts.at(index);
|
|
109
|
+
const pieceEnd = cut === void 0 || cut >= pmEnd ? pmEnd : cut;
|
|
110
|
+
out.push({
|
|
111
|
+
...run,
|
|
112
|
+
text: run.text.slice(pieceStart - pmStart, pieceEnd - pmStart),
|
|
113
|
+
...remapNodeRange({
|
|
114
|
+
pmStart: pieceStart,
|
|
115
|
+
pmEnd: pieceEnd
|
|
116
|
+
}, context.toSource)
|
|
117
|
+
});
|
|
118
|
+
if (pieceEnd === pmEnd) return;
|
|
119
|
+
pieceStart = pieceEnd;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
export { remapMarkupViewBlocks };
|
|
@@ -65,7 +65,7 @@ function convertTableCell(node, startPos, options, tableCellMargins) {
|
|
|
65
65
|
blocks.push(block);
|
|
66
66
|
} else if (child.type.name === "table") blocks.push(convertTable(child, childStart, options));
|
|
67
67
|
else if (child.type.name === "textBox") blocks.push(convertTextBoxNode(child, childStart, options));
|
|
68
|
-
else if (child.type.name === "blockSdt") {
|
|
68
|
+
else if (child.type.name === "blockSdt" || child.type.name === "blockCustomXml") {
|
|
69
69
|
let sdtChildStart = childStart + 1;
|
|
70
70
|
child.forEach((sdtChild) => {
|
|
71
71
|
convertCellChild(sdtChild, sdtChildStart);
|
|
@@ -192,13 +192,22 @@ function toFlowBlocks(doc, options = {}) {
|
|
|
192
192
|
trailingPageBreakSectionPositions.add(childStart);
|
|
193
193
|
consumedPageBreakPositions.add(childStart + child.nodeSize);
|
|
194
194
|
}
|
|
195
|
-
if (child.type.name === "blockSdt") collectTrailingPageBreakSections(child, childStart + 1);
|
|
195
|
+
if (child.type.name === "blockSdt" || child.type.name === "blockCustomXml") collectTrailingPageBreakSections(child, childStart + 1);
|
|
196
196
|
childStart += child.nodeSize;
|
|
197
197
|
}
|
|
198
198
|
};
|
|
199
199
|
collectTrailingPageBreakSections(doc, offset);
|
|
200
200
|
const visit = (node, pos) => {
|
|
201
201
|
switch (node.type.name) {
|
|
202
|
+
case "blockCustomXml": {
|
|
203
|
+
let childOffset = pos + 1;
|
|
204
|
+
for (let i = 0; i < node.childCount; i += 1) {
|
|
205
|
+
const child = node.child(i);
|
|
206
|
+
visit(child, childOffset);
|
|
207
|
+
childOffset += child.nodeSize;
|
|
208
|
+
}
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
202
211
|
case "blockSdt": {
|
|
203
212
|
const attrs = expectBlockSdtAttrs(node);
|
|
204
213
|
sdtSeq += 1;
|
|
@@ -32,6 +32,13 @@ type LayoutInstrumentation = {
|
|
|
32
32
|
onLayoutStart?: (event: {
|
|
33
33
|
reason: LayoutRunReason;
|
|
34
34
|
}) => void;
|
|
35
|
+
/**
|
|
36
|
+
* A review view (the editor's `DisplayMode`) laid out part of the story as
|
|
37
|
+
* authored: a revision there has no resolution.
|
|
38
|
+
*/
|
|
39
|
+
onMarkupViewIncomplete?: (event: {
|
|
40
|
+
view: string;
|
|
41
|
+
}) => void;
|
|
35
42
|
onLayoutPhase?: (event: {
|
|
36
43
|
durationMs: number;
|
|
37
44
|
phase: LayoutPhase;
|
|
@@ -55,6 +62,7 @@ declare function recordMeasureBlockError(blockIndex: number, block: FlowBlock, e
|
|
|
55
62
|
declare function recordLayoutComplete(reason?: LayoutRunReason): void;
|
|
56
63
|
declare function recordLayoutStart(reason: LayoutRunReason): void;
|
|
57
64
|
declare function recordLayoutError(reason: LayoutRunReason, error: unknown): void;
|
|
65
|
+
declare function recordMarkupViewIncomplete(view: string): void;
|
|
58
66
|
/** A dictionary failed to load; layout continues without hyphenating that language. */
|
|
59
67
|
declare function recordHyphenationDictionaryError(dictionary: string, error: Error): void;
|
|
60
68
|
declare function recordLayoutPhase(reason: LayoutRunReason, phase: LayoutPhase, durationMs: number): void;
|
|
@@ -62,4 +70,4 @@ declare function recordHiddenEditorStateCreate(reason: HiddenEditorStateReason):
|
|
|
62
70
|
declare function recordHiddenEditorPhase(reason: HiddenEditorStateReason, phase: HiddenEditorPhase, durationMs: number): void;
|
|
63
71
|
declare function recordDocumentLoadPhase(phase: DocumentLoadPhase, durationMs: number): void;
|
|
64
72
|
//#endregion
|
|
65
|
-
export { DocumentLoadPhase, HiddenEditorPhase, HiddenEditorStateReason, LayoutInstrumentation, LayoutPhase, LayoutRunReason, recordDocumentLoadPhase, recordHiddenEditorPhase, recordHiddenEditorStateCreate, recordHyphenationDictionaryError, recordLayoutComplete, recordLayoutError, recordLayoutPhase, recordLayoutStart, recordMeasureBlock, recordMeasureBlockError };
|
|
73
|
+
export { DocumentLoadPhase, HiddenEditorPhase, HiddenEditorStateReason, LayoutInstrumentation, LayoutPhase, LayoutRunReason, recordDocumentLoadPhase, recordHiddenEditorPhase, recordHiddenEditorStateCreate, recordHyphenationDictionaryError, recordLayoutComplete, recordLayoutError, recordLayoutPhase, recordLayoutStart, recordMarkupViewIncomplete, recordMeasureBlock, recordMeasureBlockError };
|
|
@@ -25,6 +25,9 @@ function recordLayoutError(reason, error) {
|
|
|
25
25
|
reason
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
|
+
function recordMarkupViewIncomplete(view) {
|
|
29
|
+
globalThis.__folioLayoutInstrumentation?.onMarkupViewIncomplete?.({ view });
|
|
30
|
+
}
|
|
28
31
|
/** A dictionary failed to load; layout continues without hyphenating that language. */
|
|
29
32
|
function recordHyphenationDictionaryError(dictionary, error) {
|
|
30
33
|
globalThis.__folioLayoutInstrumentation?.onHyphenationDictionaryError?.({
|
|
@@ -56,4 +59,4 @@ function recordDocumentLoadPhase(phase, durationMs) {
|
|
|
56
59
|
});
|
|
57
60
|
}
|
|
58
61
|
//#endregion
|
|
59
|
-
export { recordDocumentLoadPhase, recordHiddenEditorPhase, recordHiddenEditorStateCreate, recordHyphenationDictionaryError, recordLayoutComplete, recordLayoutError, recordLayoutPhase, recordLayoutStart, recordMeasureBlock, recordMeasureBlockError };
|
|
62
|
+
export { recordDocumentLoadPhase, recordHiddenEditorPhase, recordHiddenEditorStateCreate, recordHyphenationDictionaryError, recordLayoutComplete, recordLayoutError, recordLayoutPhase, recordLayoutStart, recordMarkupViewIncomplete, recordMeasureBlock, recordMeasureBlockError };
|
|
@@ -83,9 +83,26 @@ declare function getParagraphCacheSize(): number;
|
|
|
83
83
|
* Call when fonts change, page width changes, or for testing
|
|
84
84
|
*/
|
|
85
85
|
declare function clearAllCaches(): void;
|
|
86
|
+
/**
|
|
87
|
+
* Bind the caches to the font set the next measurements are taken in. When a
|
|
88
|
+
* face has loaded (or been added or removed) since the cached entries were
|
|
89
|
+
* measured, they are dropped: a width measured in a fallback cannot be served
|
|
90
|
+
* once the face it stood in for is available. Entries measured before the
|
|
91
|
+
* caches were first bound are dropped too: nothing records their font set.
|
|
92
|
+
* Returns whether it cleared.
|
|
93
|
+
*/
|
|
94
|
+
declare function syncMeasureCachesToFontSet(fontSet: string): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Rename the font set the cached entries were measured in, without dropping
|
|
97
|
+
* them: for a layout run that has just measured, whose signature now also
|
|
98
|
+
* names the families it measured first. Only valid within the run that bound
|
|
99
|
+
* the caches with {@link syncMeasureCachesToFontSet}, since no face can load
|
|
100
|
+
* during a synchronous run.
|
|
101
|
+
*/
|
|
102
|
+
declare function labelMeasureCachesFontSet(fontSet: string): void;
|
|
86
103
|
/**
|
|
87
104
|
* Get total size of all caches
|
|
88
105
|
*/
|
|
89
106
|
declare function getTotalCacheSize(): number;
|
|
90
107
|
//#endregion
|
|
91
|
-
export { clearAllCaches, clearFontMetricsCache, clearParagraphMeasureCache, clearTextWidthCache, getCachedFontMetrics, getCachedParagraphMeasure, getCachedTextWidth, getFontCacheSize, getParagraphCacheSize, getTextCacheSize, getTextWidthCacheGeneration, getTotalCacheSize, hashParagraphBlock, setCachedFontMetrics, setCachedParagraphMeasure, setCachedTextWidth, setFontCacheSize, setParagraphCacheSize, setTextCacheSize };
|
|
108
|
+
export { clearAllCaches, clearFontMetricsCache, clearParagraphMeasureCache, clearTextWidthCache, getCachedFontMetrics, getCachedParagraphMeasure, getCachedTextWidth, getFontCacheSize, getParagraphCacheSize, getTextCacheSize, getTextWidthCacheGeneration, getTotalCacheSize, hashParagraphBlock, labelMeasureCachesFontSet, setCachedFontMetrics, setCachedParagraphMeasure, setCachedTextWidth, setFontCacheSize, setParagraphCacheSize, setTextCacheSize, syncMeasureCachesToFontSet };
|
|
@@ -259,6 +259,11 @@ function getParagraphCacheSize() {
|
|
|
259
259
|
return paragraphMeasureCache.size;
|
|
260
260
|
}
|
|
261
261
|
/**
|
|
262
|
+
* The font set (a `readFontSetSignature` value) every cached measurement was
|
|
263
|
+
* taken in; `null` once the caches are cleared and before anything measures.
|
|
264
|
+
*/
|
|
265
|
+
let cachedFontSet = null;
|
|
266
|
+
/**
|
|
262
267
|
* Clear all measurement caches
|
|
263
268
|
* Call when fonts change, page width changes, or for testing
|
|
264
269
|
*/
|
|
@@ -267,6 +272,31 @@ function clearAllCaches() {
|
|
|
267
272
|
clearFontMetricsCache();
|
|
268
273
|
clearParagraphMeasureCache();
|
|
269
274
|
clearFontResolvedCache();
|
|
275
|
+
cachedFontSet = null;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Bind the caches to the font set the next measurements are taken in. When a
|
|
279
|
+
* face has loaded (or been added or removed) since the cached entries were
|
|
280
|
+
* measured, they are dropped: a width measured in a fallback cannot be served
|
|
281
|
+
* once the face it stood in for is available. Entries measured before the
|
|
282
|
+
* caches were first bound are dropped too: nothing records their font set.
|
|
283
|
+
* Returns whether it cleared.
|
|
284
|
+
*/
|
|
285
|
+
function syncMeasureCachesToFontSet(fontSet) {
|
|
286
|
+
if (cachedFontSet === fontSet) return false;
|
|
287
|
+
clearAllCaches();
|
|
288
|
+
cachedFontSet = fontSet;
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Rename the font set the cached entries were measured in, without dropping
|
|
293
|
+
* them: for a layout run that has just measured, whose signature now also
|
|
294
|
+
* names the families it measured first. Only valid within the run that bound
|
|
295
|
+
* the caches with {@link syncMeasureCachesToFontSet}, since no face can load
|
|
296
|
+
* during a synchronous run.
|
|
297
|
+
*/
|
|
298
|
+
function labelMeasureCachesFontSet(fontSet) {
|
|
299
|
+
cachedFontSet = fontSet;
|
|
270
300
|
}
|
|
271
301
|
/**
|
|
272
302
|
* Get total size of all caches
|
|
@@ -275,4 +305,4 @@ function getTotalCacheSize() {
|
|
|
275
305
|
return getTextCacheSize() + getFontCacheSize() + getParagraphCacheSize();
|
|
276
306
|
}
|
|
277
307
|
//#endregion
|
|
278
|
-
export { clearAllCaches, clearFontMetricsCache, clearParagraphMeasureCache, clearTextWidthCache, getCachedFontMetrics, getCachedParagraphMeasure, getCachedTextWidth, getFontCacheSize, getParagraphCacheSize, getTextCacheSize, getTextWidthCacheGeneration, getTotalCacheSize, hashParagraphBlock, setCachedFontMetrics, setCachedParagraphMeasure, setCachedTextWidth, setFontCacheSize, setParagraphCacheSize, setTextCacheSize };
|
|
308
|
+
export { clearAllCaches, clearFontMetricsCache, clearParagraphMeasureCache, clearTextWidthCache, getCachedFontMetrics, getCachedParagraphMeasure, getCachedTextWidth, getFontCacheSize, getParagraphCacheSize, getTextCacheSize, getTextWidthCacheGeneration, getTotalCacheSize, hashParagraphBlock, labelMeasureCachesFontSet, setCachedFontMetrics, setCachedParagraphMeasure, setCachedTextWidth, setFontCacheSize, setParagraphCacheSize, setTextCacheSize, syncMeasureCachesToFontSet };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { countCodePoints } from "./measureWorkerProtocol.js";
|
|
2
2
|
import { TaggedError } from "better-result";
|
|
3
3
|
//#region src/layout-engine/measure/font-metrics.worker.ts
|
|
4
4
|
/**
|
|
@@ -36,16 +36,12 @@ function getCtx() {
|
|
|
36
36
|
ctx = next;
|
|
37
37
|
return ctx;
|
|
38
38
|
}
|
|
39
|
-
function isFontFingerprintMatch(context, expectedWidth) {
|
|
40
|
-
const actualWidth = context.measureText(WORKER_FONT_FINGERPRINT_TEXT).width;
|
|
41
|
-
const tolerance = Math.max(FONT_FINGERPRINT_EPSILON, expectedWidth * 1e-4);
|
|
42
|
-
return Math.abs(actualWidth - expectedWidth) <= tolerance;
|
|
43
|
-
}
|
|
44
39
|
function measureEntry(entry) {
|
|
45
40
|
const context = getCtx();
|
|
46
41
|
context.font = entry.font;
|
|
47
42
|
context.fontKerning = entry.fontKerning;
|
|
48
|
-
|
|
43
|
+
const actualFingerprintWidth = context.measureText(entry.fontFingerprintText).width;
|
|
44
|
+
if (Math.abs(actualFingerprintWidth - entry.fontFingerprintWidth) > FONT_FINGERPRINT_EPSILON) return null;
|
|
49
45
|
let width = context.measureText(entry.text).width;
|
|
50
46
|
const codePoints = countCodePoints(entry.text);
|
|
51
47
|
if (entry.letterSpacing !== 0 && codePoints > 1) width += entry.letterSpacing * (codePoints - 1);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { getHorizontalScaleFactor } from "../../utils/horizontalScale.js";
|
|
2
2
|
import { SCRIPT_CLASS, hasComplexScript, hasEastAsiaSlotText, scriptClassOf, segmentByScript } from "../../utils/scriptSegments.js";
|
|
3
|
-
import { getCachedFontMetrics, getCachedTextWidth,
|
|
3
|
+
import { getCachedFontMetrics, getCachedTextWidth, setCachedFontMetrics, setCachedTextWidth } from "./cache.js";
|
|
4
4
|
import { applyComplexScriptFormatting, hasComplexScriptFormatting } from "./complexScriptFormatting.js";
|
|
5
5
|
import { buildFontString, getResolvedData, ptToPx } from "./measureHelpers.js";
|
|
6
6
|
import { setMeasureProvider } from "./measureProvider.js";
|
|
7
7
|
import { canPrefetchMeasurement, prefetchMeasurement } from "./measureWorker.js";
|
|
8
|
-
import {
|
|
8
|
+
import { countCodePoints } from "./measureWorkerProtocol.js";
|
|
9
9
|
import { SMALL_CAPS_SCALE, smallCapsMask, smallCapsSegments } from "./smallCapsCasing.js";
|
|
10
10
|
import { getFontKerningMode } from "./textMeasurementPolicy.js";
|
|
11
11
|
import { panic } from "better-result";
|
|
@@ -31,7 +31,6 @@ const DEFAULT_LINE_HEIGHT_MULTIPLIER = 1;
|
|
|
31
31
|
const DEFAULT_ASCENT_RATIO = .8;
|
|
32
32
|
const DEFAULT_DESCENT_RATIO = .2;
|
|
33
33
|
let canvasContext = null;
|
|
34
|
-
const workerFontFingerprintCache = /* @__PURE__ */ new Map();
|
|
35
34
|
/**
|
|
36
35
|
* Get or create a canvas 2D context for text measurement
|
|
37
36
|
*/
|
|
@@ -50,19 +49,6 @@ function getCanvasContext() {
|
|
|
50
49
|
function resetCanvasContext() {
|
|
51
50
|
canvasContext = null;
|
|
52
51
|
}
|
|
53
|
-
function getWorkerFontFingerprintWidth(ctx, font, fontCacheKey, fontKerning) {
|
|
54
|
-
const generation = getTextWidthCacheGeneration();
|
|
55
|
-
const cached = workerFontFingerprintCache.get(fontCacheKey);
|
|
56
|
-
if (cached?.generation === generation) return cached.width;
|
|
57
|
-
ctx.font = font;
|
|
58
|
-
ctx.fontKerning = fontKerning;
|
|
59
|
-
const width = ctx.measureText(WORKER_FONT_FINGERPRINT_TEXT).width;
|
|
60
|
-
workerFontFingerprintCache.set(fontCacheKey, {
|
|
61
|
-
generation,
|
|
62
|
-
width
|
|
63
|
-
});
|
|
64
|
-
return width;
|
|
65
|
-
}
|
|
66
52
|
/**
|
|
67
53
|
* Get typography metrics for a given font size and family
|
|
68
54
|
*
|
|
@@ -149,7 +135,8 @@ function canvasMeasureTextWidth(text, sourceStyle) {
|
|
|
149
135
|
if (cached !== void 0) return cached;
|
|
150
136
|
ctx.font = font;
|
|
151
137
|
ctx.fontKerning = fontKerning;
|
|
152
|
-
|
|
138
|
+
const metrics = ctx.measureText(measuredText);
|
|
139
|
+
let width = metrics.width;
|
|
153
140
|
if (letterSpacing) {
|
|
154
141
|
const codePoints = countCodePoints(measuredText);
|
|
155
142
|
if (codePoints > 1) width += letterSpacing * (codePoints - 1);
|
|
@@ -157,17 +144,18 @@ function canvasMeasureTextWidth(text, sourceStyle) {
|
|
|
157
144
|
const scaledWidth = width * horizontalScale;
|
|
158
145
|
setCachedTextWidth(measuredText, fontCacheKey, letterSpacing, scaledWidth);
|
|
159
146
|
if (!canPrefetchMeasurement()) return scaledWidth;
|
|
160
|
-
const
|
|
147
|
+
const fontFingerprintText = measuredText;
|
|
148
|
+
const fontFingerprintWidth = metrics.width;
|
|
161
149
|
prefetchMeasurement({
|
|
162
150
|
text: measuredText,
|
|
163
151
|
font,
|
|
164
152
|
letterSpacing,
|
|
165
153
|
horizontalScale,
|
|
166
154
|
fontCacheKey,
|
|
155
|
+
fontFingerprintText,
|
|
167
156
|
fontFingerprintWidth,
|
|
168
157
|
fontKerning
|
|
169
158
|
});
|
|
170
|
-
prefetchBinarySearchProbes(measuredText, font, fontCacheKey, fontFingerprintWidth, letterSpacing, horizontalScale, fontKerning);
|
|
171
159
|
return scaledWidth;
|
|
172
160
|
}
|
|
173
161
|
/**
|
|
@@ -262,34 +250,6 @@ function measureSmallCapsWidth(measuredText, style) {
|
|
|
262
250
|
return width * horizontalScale;
|
|
263
251
|
}
|
|
264
252
|
/**
|
|
265
|
-
* Speculatively enqueue the slice lengths that a subsequent
|
|
266
|
-
* `findMaxFittingLength` binary search is likely to probe. We pick the
|
|
267
|
-
* geometric series (full, half, quarter, eighth) which covers the
|
|
268
|
-
* majority of probe points the binary search uses, without flooding
|
|
269
|
-
* the worker for runs that will never trigger a line break.
|
|
270
|
-
*
|
|
271
|
-
* The worker is racing the main thread here: if the main thread asks
|
|
272
|
-
* for slice(0, n/2) before the worker has answered, the cache miss
|
|
273
|
-
* pays the main-thread cost as usual. When the worker wins, that probe
|
|
274
|
-
* lands on a hit.
|
|
275
|
-
*/
|
|
276
|
-
function prefetchBinarySearchProbes(text, font, fontCacheKey, fontFingerprintWidth, letterSpacing, horizontalScale, fontKerning) {
|
|
277
|
-
if (text.length < 4) return;
|
|
278
|
-
for (let denom = 2; denom <= 8; denom *= 2) {
|
|
279
|
-
const len = Math.floor(text.length / denom);
|
|
280
|
-
if (len < 2) break;
|
|
281
|
-
prefetchMeasurement({
|
|
282
|
-
text: text.slice(0, len),
|
|
283
|
-
font,
|
|
284
|
-
letterSpacing,
|
|
285
|
-
horizontalScale,
|
|
286
|
-
fontCacheKey,
|
|
287
|
-
fontFingerprintWidth,
|
|
288
|
-
fontKerning
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
253
|
* Measure text and return full metrics
|
|
294
254
|
*/
|
|
295
255
|
function canvasMeasureText(text, style) {
|
|
@@ -34,6 +34,11 @@ type ResolvedFontCache = {
|
|
|
34
34
|
* Get the resolved font data for a font family, with caching.
|
|
35
35
|
*/
|
|
36
36
|
declare function getResolvedData(fontFamily: string, alternateFontFamily?: string): ResolvedFontCache;
|
|
37
|
+
/**
|
|
38
|
+
* Whether a face of `family` (a `FontFace.family`, possibly quoted) can change
|
|
39
|
+
* a width this page has measured.
|
|
40
|
+
*/
|
|
41
|
+
declare function isLayoutFontFamily(family: string): boolean;
|
|
37
42
|
/**
|
|
38
43
|
* Clear the resolved-font-family cache. `resolveFontFamily`'s output for a
|
|
39
44
|
* given key can change even when the raw font names don't — e.g. when the
|
|
@@ -100,4 +105,4 @@ declare function halfPtToPx(halfPt: number): number;
|
|
|
100
105
|
*/
|
|
101
106
|
declare function pxToHalfPt(px: number): number;
|
|
102
107
|
//#endregion
|
|
103
|
-
export { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, buildFontString, buildRunFontStyle, clearFontResolvedCache, docxScriptFontSize, findCharacterAtX, getResolvedData, getXForCharacter, halfPtToPx, ptToPx, pxToHalfPt, pxToPt, pxToTwips, twipsToPx };
|
|
108
|
+
export { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, buildFontString, buildRunFontStyle, clearFontResolvedCache, docxScriptFontSize, findCharacterAtX, getResolvedData, getXForCharacter, halfPtToPx, isLayoutFontFamily, ptToPx, pxToHalfPt, pxToPt, pxToTwips, twipsToPx };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveFontFamily } from "../../utils/fontResolver.js";
|
|
1
|
+
import { parseFontFamilyList, resolveFontFamily } from "../../utils/fontResolver.js";
|
|
2
2
|
import "../../utils/fontWeights.js";
|
|
3
3
|
import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
|
|
4
4
|
import { eastAsiaHintApplies } from "../../utils/scriptSegments.js";
|
|
@@ -93,10 +93,30 @@ function getResolvedData(fontFamily, alternateFontFamily) {
|
|
|
93
93
|
singleLineRatio: resolved.singleLineRatio
|
|
94
94
|
};
|
|
95
95
|
fontResolvedCache.set(cacheKey, cached);
|
|
96
|
+
for (const family of parseFontFamilyList(resolved.cssFallback)) layoutFontFamilies.add(normalizeFontFamilyName(family));
|
|
96
97
|
}
|
|
97
98
|
return cached;
|
|
98
99
|
}
|
|
99
100
|
/**
|
|
101
|
+
* Every family a measured font stack has named on this page, normalized.
|
|
102
|
+
*
|
|
103
|
+
* Recorded where measurement resolves its stacks, so it is exactly the set of
|
|
104
|
+
* families whose faces can change a measured width: a face of any other family
|
|
105
|
+
* loading (the host's UI font, say) cannot. Never cleared, because a family
|
|
106
|
+
* stays relevant for as long as a cached or committed measurement may hold it,
|
|
107
|
+
* and the set is bounded by the families the page's documents name.
|
|
108
|
+
*/
|
|
109
|
+
const layoutFontFamilies = /* @__PURE__ */ new Set();
|
|
110
|
+
/** CSS family names match ASCII case-insensitively, quotes aside. */
|
|
111
|
+
const normalizeFontFamilyName = (family) => family.trim().replace(/^(["'])(.*)\1$/u, "$2").toLowerCase();
|
|
112
|
+
/**
|
|
113
|
+
* Whether a face of `family` (a `FontFace.family`, possibly quoted) can change
|
|
114
|
+
* a width this page has measured.
|
|
115
|
+
*/
|
|
116
|
+
function isLayoutFontFamily(family) {
|
|
117
|
+
return layoutFontFamilies.has(normalizeFontFamilyName(family));
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
100
120
|
* Get the CSS fallback string for a font family, with caching.
|
|
101
121
|
*/
|
|
102
122
|
function getResolvedFallback(fontFamily, alternateFontFamily) {
|
|
@@ -207,4 +227,4 @@ function pxToHalfPt(px) {
|
|
|
207
227
|
return pxToPt(px) * 2;
|
|
208
228
|
}
|
|
209
229
|
//#endregion
|
|
210
|
-
export { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, buildFontString, buildRunFontStyle, clearFontResolvedCache, docxScriptFontSize, findCharacterAtX, getResolvedData, getXForCharacter, halfPtToPx, ptToPx, pxToHalfPt, pxToPt, pxToTwips, twipsToPx };
|
|
230
|
+
export { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, buildFontString, buildRunFontStyle, clearFontResolvedCache, docxScriptFontSize, findCharacterAtX, getResolvedData, getXForCharacter, halfPtToPx, isLayoutFontFamily, ptToPx, pxToHalfPt, pxToPt, pxToTwips, twipsToPx };
|
|
@@ -15,7 +15,7 @@ import { applyDocumentGrid, calculateEmptyParagraphMetrics, calculateTypographyM
|
|
|
15
15
|
import { getListMarkerInlineWidth } from "./listMarkerWidth.js";
|
|
16
16
|
import { DEFAULT_FONT_FAMILY, buildRunFontStyle, ptToPx } from "./measureHelpers.js";
|
|
17
17
|
import { getFontMetrics, measureRun, measureTextWidth } from "./measureProvider.js";
|
|
18
|
-
import { WIDTH_TOLERANCE, fieldMeasureText, isEmptyTextRun, isFieldRun, isImageRun, isLineBreakRun, isMathRun, isTabRun, isTextRun, runToFontStyle } from "./paragraphMeasureShared.js";
|
|
18
|
+
import { WIDTH_TOLERANCE, canonicalLineWidth, fieldMeasureText, isEmptyTextRun, isFieldRun, isImageRun, isLineBreakRun, isMathRun, isTabRun, isTextRun, runToFontStyle } from "./paragraphMeasureShared.js";
|
|
19
19
|
import { canClampTabToRightEdge, hasFollowingTabOnLine, hasPriorTabOnLine, measureDecimalPrefixWidthAfterTab, measureInlineWidthAfterTab } from "./paragraphTabs.js";
|
|
20
20
|
import { calculateTabWidth, pixelsToTwips } from "./tabCalculator.js";
|
|
21
21
|
//#region src/layout-engine/measure/measureParagraph.ts
|
|
@@ -215,7 +215,7 @@ function measureParagraph(block, maxWidth, options) {
|
|
|
215
215
|
fromChar: currentLine.fromChar,
|
|
216
216
|
toRun: currentLine.toRun,
|
|
217
217
|
toChar: currentLine.toChar,
|
|
218
|
-
width:
|
|
218
|
+
width: canonicalLineWidth(currentLine.width - currentLine.trailingWhitespaceWidth),
|
|
219
219
|
...finalTypography,
|
|
220
220
|
...currentLine.justificationPaint !== void 0 ? { justificationPaint: currentLine.justificationPaint } : {},
|
|
221
221
|
...currentLine.discretionaryHyphen ? { discretionaryHyphen: currentLine.discretionaryHyphen } : {},
|
|
@@ -118,9 +118,8 @@ function ensureProxy() {
|
|
|
118
118
|
}
|
|
119
119
|
/**
|
|
120
120
|
* How long to wait before flushing the queue, in milliseconds. Short
|
|
121
|
-
* enough to
|
|
122
|
-
*
|
|
123
|
-
* paragraph's worth of probes.
|
|
121
|
+
* enough to process measured entries promptly, long enough to amortise
|
|
122
|
+
* `postMessage` overhead across a typical paragraph's runs.
|
|
124
123
|
*/
|
|
125
124
|
const FLUSH_INTERVAL_MS = 10;
|
|
126
125
|
/**
|
|
@@ -14,22 +14,21 @@ import { FontKerningMode } from "./textMeasurementPolicy.js";
|
|
|
14
14
|
* `fontCacheKey` is the main-thread cache identity. It intentionally
|
|
15
15
|
* differs from `font` when scale metadata is appended.
|
|
16
16
|
*
|
|
17
|
-
* `
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* poisoning the main-thread cache.
|
|
17
|
+
* `fontFingerprintText` is text already measured on the main thread in
|
|
18
|
+
* this font. The worker checks its unscaled width against
|
|
19
|
+
* `fontFingerprintWidth` before caching a result. This covers the actual
|
|
20
|
+
* glyphs and font subsets used by the request, including non-Latin text.
|
|
22
21
|
*/
|
|
23
22
|
type MeasureRequestEntry = {
|
|
24
23
|
text: string;
|
|
25
24
|
font: string;
|
|
26
25
|
fontCacheKey: string;
|
|
26
|
+
fontFingerprintText: string;
|
|
27
27
|
fontFingerprintWidth: number;
|
|
28
28
|
letterSpacing: number;
|
|
29
29
|
horizontalScale: number;
|
|
30
30
|
fontKerning: FontKerningMode;
|
|
31
31
|
};
|
|
32
|
-
declare const WORKER_FONT_FINGERPRINT_TEXT = "HAMBURGEFONTS ivwqy 0123456789";
|
|
33
32
|
/**
|
|
34
33
|
* Count whole code points (not UTF-16 units) so letter spacing is applied once
|
|
35
34
|
* per rendered glyph — an astral character is one glyph spanning two units.
|
|
@@ -73,4 +72,4 @@ type MeasureWorkerResponse = {
|
|
|
73
72
|
error: string;
|
|
74
73
|
};
|
|
75
74
|
//#endregion
|
|
76
|
-
export { MeasureRequestEntry, MeasureResponseEntry, MeasureWorkerRequest, MeasureWorkerResponse,
|
|
75
|
+
export { MeasureRequestEntry, MeasureResponseEntry, MeasureWorkerRequest, MeasureWorkerResponse, countCodePoints };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
//#region src/layout-engine/measure/measureWorkerProtocol.ts
|
|
2
|
-
const WORKER_FONT_FINGERPRINT_TEXT = "HAMBURGEFONTS ivwqy 0123456789";
|
|
3
2
|
/**
|
|
4
3
|
* Count whole code points (not UTF-16 units) so letter spacing is applied once
|
|
5
4
|
* per rendered glyph — an astral character is one glyph spanning two units.
|
|
@@ -17,4 +16,4 @@ function countCodePoints(text) {
|
|
|
17
16
|
return count;
|
|
18
17
|
}
|
|
19
18
|
//#endregion
|
|
20
|
-
export {
|
|
19
|
+
export { countCodePoints };
|
|
@@ -5,6 +5,17 @@ import { FloatingLineSegmentZone } from "./floatingZones.js";
|
|
|
5
5
|
declare const DEFAULT_FONT_SIZE = 11;
|
|
6
6
|
declare const DEFAULT_LINE_HEIGHT_MULTIPLIER = 1;
|
|
7
7
|
declare const WIDTH_TOLERANCE = 0.5;
|
|
8
|
+
/**
|
|
9
|
+
* The width a finished line reports. A line's width is a floating-point sum
|
|
10
|
+
* of per-token measurements, and the same text can reach it through different
|
|
11
|
+
* token groupings, e.g. a run split where a hidden revision sat measures
|
|
12
|
+
* "confirm" + "ation" where the resolved text measures "confirmation". Those
|
|
13
|
+
* sums agree only up to the last few bits, so the result snaps to a
|
|
14
|
+
* binary-exact 1/1024 px grid (under 0.0005 px, far below a device pixel):
|
|
15
|
+
* the same text yields the same width whichever grouping summed it, and the
|
|
16
|
+
* alignment offsets derived from it agree too.
|
|
17
|
+
*/
|
|
18
|
+
declare const canonicalLineWidth: (width: number) => number;
|
|
8
19
|
/**
|
|
9
20
|
* Typography metrics for a line
|
|
10
21
|
*/
|
|
@@ -106,4 +117,4 @@ declare function isEmptyTextRun(run: TextRun): boolean;
|
|
|
106
117
|
declare function isBlockLayoutImageRun(run: ImageRun): boolean;
|
|
107
118
|
declare function isSpaceOrTab(char: string | undefined): boolean;
|
|
108
119
|
//#endregion
|
|
109
|
-
export { DEFAULT_FONT_SIZE, DEFAULT_LINE_HEIGHT_MULTIPLIER, LineState, LineTypography, WIDTH_TOLERANCE, fieldMeasureText, isBlockLayoutImageRun, isEmptyTextRun, isFieldRun, isImageRun, isLineBreakRun, isMathRun, isSpaceOrTab, isTabRun, isTextRun, runToFontStyle };
|
|
120
|
+
export { DEFAULT_FONT_SIZE, DEFAULT_LINE_HEIGHT_MULTIPLIER, LineState, LineTypography, WIDTH_TOLERANCE, canonicalLineWidth, fieldMeasureText, isBlockLayoutImageRun, isEmptyTextRun, isFieldRun, isImageRun, isLineBreakRun, isMathRun, isSpaceOrTab, isTabRun, isTextRun, runToFontStyle };
|
|
@@ -4,6 +4,19 @@ import { DEFAULT_FONT_FAMILY, buildRunFontStyle } from "./measureHelpers.js";
|
|
|
4
4
|
const DEFAULT_FONT_SIZE = 11;
|
|
5
5
|
const DEFAULT_LINE_HEIGHT_MULTIPLIER = 1;
|
|
6
6
|
const WIDTH_TOLERANCE = .5;
|
|
7
|
+
/** Grid a finished line's width snaps to: 1/1024 px, exact in binary floating point. */
|
|
8
|
+
const LINE_WIDTH_GRID = 1024;
|
|
9
|
+
/**
|
|
10
|
+
* The width a finished line reports. A line's width is a floating-point sum
|
|
11
|
+
* of per-token measurements, and the same text can reach it through different
|
|
12
|
+
* token groupings, e.g. a run split where a hidden revision sat measures
|
|
13
|
+
* "confirm" + "ation" where the resolved text measures "confirmation". Those
|
|
14
|
+
* sums agree only up to the last few bits, so the result snaps to a
|
|
15
|
+
* binary-exact 1/1024 px grid (under 0.0005 px, far below a device pixel):
|
|
16
|
+
* the same text yields the same width whichever grouping summed it, and the
|
|
17
|
+
* alignment offsets derived from it agree too.
|
|
18
|
+
*/
|
|
19
|
+
const canonicalLineWidth = (width) => Math.round(Math.max(0, width) * LINE_WIDTH_GRID) / LINE_WIDTH_GRID;
|
|
7
20
|
/**
|
|
8
21
|
* Extract FontStyle from a run that carries RunFormatting (text, tab, or
|
|
9
22
|
* field). All three share the same formatting shape, so they measure the
|
|
@@ -79,4 +92,4 @@ function isSpaceOrTab(char) {
|
|
|
79
92
|
return char === " " || char === " ";
|
|
80
93
|
}
|
|
81
94
|
//#endregion
|
|
82
|
-
export { DEFAULT_FONT_SIZE, DEFAULT_LINE_HEIGHT_MULTIPLIER, WIDTH_TOLERANCE, fieldMeasureText, isBlockLayoutImageRun, isEmptyTextRun, isFieldRun, isImageRun, isLineBreakRun, isMathRun, isSpaceOrTab, isTabRun, isTextRun, runToFontStyle };
|
|
95
|
+
export { DEFAULT_FONT_SIZE, DEFAULT_LINE_HEIGHT_MULTIPLIER, WIDTH_TOLERANCE, canonicalLineWidth, fieldMeasureText, isBlockLayoutImageRun, isEmptyTextRun, isFieldRun, isImageRun, isLineBreakRun, isMathRun, isSpaceOrTab, isTabRun, isTextRun, runToFontStyle };
|
|
@@ -585,6 +585,12 @@ type ParagraphBlock = {
|
|
|
585
585
|
* the innermost group and draws boundary chrome per outer→inner level.
|
|
586
586
|
*/
|
|
587
587
|
sdtGroups?: SdtGroup[];
|
|
588
|
+
/**
|
|
589
|
+
* Set by a review view that lays out resolved text (Simple Markup) on a
|
|
590
|
+
* paragraph whose authored text carries a revision the view resolved: the
|
|
591
|
+
* painter marks it with the change bar its runs no longer show.
|
|
592
|
+
*/
|
|
593
|
+
reviewIndicator?: "change-bar";
|
|
588
594
|
};
|
|
589
595
|
/**
|
|
590
596
|
* Cell border specification for rendering.
|
|
@@ -1326,6 +1326,7 @@ function collectContentFingerprint(block, parts) {
|
|
|
1326
1326
|
if (block.kind === "paragraph") {
|
|
1327
1327
|
if (block.attrs?.styleId) parts.push(`p:st:${block.attrs.styleId}`);
|
|
1328
1328
|
if (block.attrs?.alignment) parts.push(`p:al:${block.attrs.alignment}`);
|
|
1329
|
+
if (block.reviewIndicator) parts.push(`p:ri:${block.reviewIndicator}`);
|
|
1329
1330
|
for (let index = 0; index < block.runs.length; index++) {
|
|
1330
1331
|
const run = block.runs[index];
|
|
1331
1332
|
if (!run) continue;
|
|
@@ -1500,7 +1500,7 @@ function bordersFormGroup(a, b) {
|
|
|
1500
1500
|
if (!a || !b) return false;
|
|
1501
1501
|
return bordersEqual(a.top, b.top) && bordersEqual(a.bottom, b.bottom) && bordersEqual(a.left, b.left) && bordersEqual(a.right, b.right) && bordersEqual(a.between, b.between);
|
|
1502
1502
|
}
|
|
1503
|
-
const paragraphHasTrackedChanges = (block) => block.attrs?.listMarkerRevision !== void 0 || block.runs.some((run) => run.kind !== "lineBreak" && (run.isInsertion === true || run.isDeletion === true));
|
|
1503
|
+
const paragraphHasTrackedChanges = (block) => block.reviewIndicator === "change-bar" || block.attrs?.listMarkerRevision !== void 0 || block.runs.some((run) => run.kind !== "lineBreak" && (run.isInsertion === true || run.isDeletion === true));
|
|
1504
1504
|
/**
|
|
1505
1505
|
* Render a paragraph fragment
|
|
1506
1506
|
*
|