@stll/folio-core 0.52.0 → 0.53.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 +1519 -105
- package/dist/ai-edits/batch-claims.d.ts +130 -0
- package/dist/ai-edits/batch-claims.js +244 -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 +71 -7
- package/dist/ai-edits/headless.js +381 -41
- 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 +1 -1
- package/dist/ai-edits/read.js +56 -43
- package/dist/ai-edits/result-validation.d.ts +29 -0
- package/dist/ai-edits/result-validation.js +164 -0
- package/dist/ai-edits/snapshot.d.ts +36 -3
- package/dist/ai-edits/snapshot.js +177 -23
- package/dist/ai-edits/table-cell-mutations.d.ts +1 -1
- package/dist/ai-edits/table-cell-mutations.js +4 -1
- package/dist/ai-edits/table-geometry.d.ts +1 -1
- package/dist/ai-edits/table-row-column-mutations.d.ts +38 -16
- package/dist/ai-edits/table-row-column-mutations.js +61 -26
- 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.js +13 -2
- 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/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 +62 -9
- 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/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/normalizeBaseDirection.js +2 -1
- 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 +91 -24
- package/dist/docx/paragraphPropertySource.d.ts +4 -2
- package/dist/docx/paragraphPropertySource.js +7 -1
- package/dist/docx/paragraphTraversal.js +1 -0
- package/dist/docx/parseWarningMessage.js +4 -1
- package/dist/docx/parser.js +173 -20
- package/dist/docx/rezip.js +27 -5
- 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.js +106 -37
- 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/createBilingualDocument.js +3 -3
- 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 +2 -1
- package/dist/docx/unzip.js +1 -1
- package/dist/docx/wordprocessingPrefixes.d.ts +78 -0
- package/dist/docx/wordprocessingPrefixes.js +286 -0
- package/dist/i18n/messages/catalogs.gen.d.ts +136 -0
- package/dist/i18n/messages/catalogs.gen.js +153 -17
- package/dist/i18n/messages/messages.gen.d.ts +8 -0
- 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 +530 -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/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/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/fromMarkdown.js +2 -1
- package/dist/markdown/internals.d.ts +11 -1
- package/dist/markdown/internals.js +24 -3
- package/dist/markdown/renderBlock.js +39 -9
- package/dist/markdown/renderParagraph.d.ts +13 -1
- package/dist/markdown/renderParagraph.js +85 -38
- package/dist/markdown/renderRuns.js +3 -10
- 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/commands/comments.d.ts +7 -8
- package/dist/prosemirror/commands/comments.js +241 -207
- package/dist/prosemirror/commands/contentControls.d.ts +1 -1
- package/dist/prosemirror/commands/formatPainter.d.ts +1 -1
- package/dist/prosemirror/commands/formatting.d.ts +1 -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/resolveAllTableChanges.d.ts +40 -0
- package/dist/prosemirror/commands/resolveAllTableChanges.js +615 -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 +59 -0
- package/dist/prosemirror/commands/sectionBreak.js +2 -1
- package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +8 -2
- package/dist/prosemirror/commands/tableCellMergeResolution.js +1 -1
- package/dist/prosemirror/contentControlRevisions.d.ts +1 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +181 -31
- package/dist/prosemirror/conversion/toProseDoc.js +39 -4
- 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 +3 -1
- package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +12 -0
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +3 -0
- package/dist/prosemirror/extensions/features/ListExtension.js +161 -123
- 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/pastedHtmlLists.d.ts +12 -0
- package/dist/prosemirror/extensions/features/pastedHtmlLists.js +126 -0
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +21 -5
- package/dist/prosemirror/extensions/marks/RunIdentityExtension.d.ts +21 -18
- package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +37 -17
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +7 -2
- package/dist/prosemirror/extensions/marks/markUtils.js +8 -2
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.d.ts +10 -0
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +35 -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/FieldExtension.d.ts +3 -3
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +50 -15
- 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 +19 -18
- package/dist/prosemirror/extensions/types.d.ts +4 -1
- package/dist/prosemirror/findReplaceSelection.js +1 -1
- package/dist/prosemirror/index.d.ts +3 -2
- package/dist/prosemirror/index.js +3 -2
- 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 +110 -0
- package/dist/prosemirror/listNumbering.js +345 -0
- package/dist/prosemirror/listRenderingAttrs.d.ts +11 -2
- package/dist/prosemirror/listRenderingAttrs.js +8 -1
- package/dist/prosemirror/markupViewProjection.d.ts +95 -0
- package/dist/prosemirror/markupViewProjection.js +83 -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 +29 -7
- package/dist/prosemirror/paragraphMarkJoin.d.ts +19 -0
- package/dist/prosemirror/paragraphMarkJoin.js +24 -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/documentStyles.d.ts +10 -1
- package/dist/prosemirror/plugins/documentStyles.js +14 -1
- package/dist/prosemirror/plugins/suggestionMode.d.ts +16 -2
- package/dist/prosemirror/plugins/suggestionMode.js +116 -52
- 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 +1 -1
- 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/runFormattingInlineCarriers.d.ts +1 -1
- package/dist/prosemirror/schema/index.d.ts +2 -2
- package/dist/prosemirror/schema/index.js +3 -0
- package/dist/prosemirror/schema/nodes.d.ts +42 -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/tableGridMutation.d.ts +48 -2
- package/dist/prosemirror/tableGridMutation.js +106 -1
- 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/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 +3 -2
- package/dist/internal/headlessRevisionResolution.d.ts +0 -23
|
@@ -22,6 +22,7 @@ import { expectInlineWrapperMarkAttrs, expectTrackedChangeMarkAttrs } from "../a
|
|
|
22
22
|
import { authoredTransformAttrs } from "../authoredTransformAttrs.js";
|
|
23
23
|
import { setAutospacingBaseValue } from "../autospacingBase.js";
|
|
24
24
|
import { withEnclosingRevision } from "../contentControlRevisions.js";
|
|
25
|
+
import { emptyFieldRunPropertyChanges } from "../emptyFieldResultRuns.js";
|
|
25
26
|
import { planEmptyRanges } from "../emptyRangeAnchor.js";
|
|
26
27
|
import { INLINE_WRAPPER_MARK_NAME } from "../extensions/marks/InlineWrapperExtension.js";
|
|
27
28
|
import { textFormattingToMarks } from "../extensions/marks/markUtils.js";
|
|
@@ -197,6 +198,7 @@ const collectPairedBookmarkIds = (blocks) => {
|
|
|
197
198
|
}
|
|
198
199
|
break;
|
|
199
200
|
case "blockSdt":
|
|
201
|
+
case "blockCustomXml":
|
|
200
202
|
visitBlocks(block.content);
|
|
201
203
|
break;
|
|
202
204
|
case "preservedBlock": break;
|
|
@@ -250,6 +252,9 @@ function toProseDoc(document, options) {
|
|
|
250
252
|
case "blockSdt":
|
|
251
253
|
out.push(convertBlockSdt(block, convertBodyBlocks));
|
|
252
254
|
break;
|
|
255
|
+
case "blockCustomXml":
|
|
256
|
+
out.push(convertBlockCustomXml(block, convertBodyBlocks));
|
|
257
|
+
break;
|
|
253
258
|
case "preservedBlock":
|
|
254
259
|
out.push(convertPreservedBlock(block));
|
|
255
260
|
break;
|
|
@@ -282,7 +287,10 @@ function toProseDoc(document, options) {
|
|
|
282
287
|
* no index and nothing has to keep one honest as the blocks around it change.
|
|
283
288
|
*/
|
|
284
289
|
function convertPreservedBlock(block) {
|
|
285
|
-
return schema.node("preservedBlock", {
|
|
290
|
+
return schema.node("preservedBlock", {
|
|
291
|
+
xml: block.xml,
|
|
292
|
+
readerText: block.readerText ?? null
|
|
293
|
+
});
|
|
286
294
|
}
|
|
287
295
|
/**
|
|
288
296
|
* Carry a bookmark marker that stands between two blocks into the editor.
|
|
@@ -354,6 +362,15 @@ function convertBlockSdt(blockSdt, convertBlocks) {
|
|
|
354
362
|
if (children.length === 0) children.push(schema.node("paragraph", {}, []));
|
|
355
363
|
return schema.node("blockSdt", attrs, children);
|
|
356
364
|
}
|
|
365
|
+
function convertBlockCustomXml(block, convertBlocks) {
|
|
366
|
+
const children = convertBlocks(block.content);
|
|
367
|
+
if (children.length === 0) children.push(schema.node("paragraph", {}, []));
|
|
368
|
+
return schema.node("blockCustomXml", {
|
|
369
|
+
openingXml: block.openingXml,
|
|
370
|
+
closingXml: block.closingXml,
|
|
371
|
+
_originallyEmpty: block.content.length === 0
|
|
372
|
+
}, children);
|
|
373
|
+
}
|
|
357
374
|
/**
|
|
358
375
|
* Convert a Paragraph to a ProseMirror paragraph node
|
|
359
376
|
*
|
|
@@ -1072,7 +1089,7 @@ function blockHasMeaningfulContent(block) {
|
|
|
1072
1089
|
if (block.type === "preservedBlock") return true;
|
|
1073
1090
|
if (block.type === "bookmarkStart" || block.type === "bookmarkEnd") return true;
|
|
1074
1091
|
if (block.type === "table") return block.rows.some((row) => row.cells.some((cell) => tableCellHasMeaningfulContent(cell)));
|
|
1075
|
-
if (block.type === "blockSdt") return true;
|
|
1092
|
+
if (block.type === "blockSdt" || block.type === "blockCustomXml") return true;
|
|
1076
1093
|
return block.content.some(paragraphContentHasMeaningfulContent);
|
|
1077
1094
|
}
|
|
1078
1095
|
function paragraphContentHasMeaningfulContent(content) {
|
|
@@ -1132,6 +1149,7 @@ function convertTable(table, styleResolver, context) {
|
|
|
1132
1149
|
if (table.propertyChanges && table.propertyChanges.length > 0) attrs.tblPrChange = [...table.propertyChanges];
|
|
1133
1150
|
if (table.bookmarks && table.bookmarks.length > 0) attrs._bookmarks = table.bookmarks;
|
|
1134
1151
|
if (hasSinkChildren(table.preserved)) attrs._preserved = table.preserved;
|
|
1152
|
+
if (table.carrierStack?.length) attrs.carrierStack = table.carrierStack;
|
|
1135
1153
|
const conditionalStyles = {};
|
|
1136
1154
|
const setCS = (key, type) => {
|
|
1137
1155
|
const val = resolveTableStyleConditional(styleResolver, conditionalTableStyleId, type);
|
|
@@ -1212,6 +1230,7 @@ function convertTableRow(row, styleResolver, context, isHeaderRow, columnWidths,
|
|
|
1212
1230
|
if (row.preservedAttributes && row.preservedAttributes.length > 0) attrsWithoutStructuralChange._preservedAttributes = row.preservedAttributes;
|
|
1213
1231
|
if (row.bookmarks && row.bookmarks.length > 0) attrsWithoutStructuralChange._bookmarks = row.bookmarks;
|
|
1214
1232
|
if (row.contentControls && row.contentControls.length > 0) attrsWithoutStructuralChange.contentControls = row.contentControls;
|
|
1233
|
+
if (row.carrierStack?.length) attrsWithoutStructuralChange.carrierStack = row.carrierStack;
|
|
1215
1234
|
if (hasSinkChildren(row.preserved)) attrsWithoutStructuralChange._preserved = row.preserved;
|
|
1216
1235
|
let attrs = attrsWithoutStructuralChange;
|
|
1217
1236
|
const rowStructuralChange = row.structuralChange;
|
|
@@ -1394,6 +1413,7 @@ function convertTableCell({ cell, styleResolver, context, isHeader, gridWidthPer
|
|
|
1394
1413
|
if (formatting) attrs._originalFormatting = formatting;
|
|
1395
1414
|
if (cell.propertyChanges && cell.propertyChanges.length > 0) attrs.tcPrChange = [...cell.propertyChanges];
|
|
1396
1415
|
if (cell.contentControls && cell.contentControls.length > 0) attrs.contentControls = cell.contentControls;
|
|
1416
|
+
if (cell.carrierStack?.length) attrs.carrierStack = cell.carrierStack;
|
|
1397
1417
|
const cellStructuralChange = cell.structuralChange;
|
|
1398
1418
|
if (cellStructuralChange) {
|
|
1399
1419
|
const info = {
|
|
@@ -1448,6 +1468,9 @@ function convertTableCell({ cell, styleResolver, context, isHeader, gridWidthPer
|
|
|
1448
1468
|
case "blockSdt":
|
|
1449
1469
|
nodes.push(convertBlockSdt(block, convertCellBlocks));
|
|
1450
1470
|
break;
|
|
1471
|
+
case "blockCustomXml":
|
|
1472
|
+
nodes.push(convertBlockCustomXml(block, convertCellBlocks));
|
|
1473
|
+
break;
|
|
1451
1474
|
case "preservedBlock":
|
|
1452
1475
|
nodes.push(convertPreservedBlock(block));
|
|
1453
1476
|
break;
|
|
@@ -1548,7 +1571,10 @@ function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyp
|
|
|
1548
1571
|
const hasConvertedPreservedContent = inlineNodes.some((node) => node.type.name === "preservedXml");
|
|
1549
1572
|
const hasConvertedWrapperContent = inlineNodes.some((node) => node.marks.some((mark) => mark.type.name === INLINE_WRAPPER_MARK_NAME));
|
|
1550
1573
|
const createStructuredField = hasConvertedPageBreakContent || hasConvertedPreservedContent || hasStructuredSourceContent && (hasConvertedHyperlinkContent || hasConvertedWrapperContent);
|
|
1551
|
-
|
|
1574
|
+
const resultRuns = field.type === "simpleField" ? field.content.flatMap((content) => content.type === "run" ? [content] : []) : field.fieldResult;
|
|
1575
|
+
const emptyResultRuns = displayText === "" && resultRuns.length > 0 && (field.type === "complexField" || field.content.length === resultRuns.length) && resultRuns.every((run) => run.content.every((item) => item.type === "text" && item.text === "")) ? resultRuns : void 0;
|
|
1576
|
+
const resultPropertyChanges = emptyResultRuns ? emptyFieldRunPropertyChanges(emptyResultRuns) : fieldPropertyChanges;
|
|
1577
|
+
if (!createStructuredField && resultPropertyChanges && resultPropertyChanges.length > 0) marks.push(schema.mark("runPropertyChange", { changes: [...resultPropertyChanges] }));
|
|
1552
1578
|
return schema.node(createStructuredField ? "structuredField" : "field", {
|
|
1553
1579
|
fieldType: field.fieldType,
|
|
1554
1580
|
instruction: field.instruction,
|
|
@@ -1556,7 +1582,13 @@ function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyp
|
|
|
1556
1582
|
fieldKind: field.type === "simpleField" ? "simple" : "complex",
|
|
1557
1583
|
fldLock: field.fldLock ?? null,
|
|
1558
1584
|
dirty: field.dirty ?? null,
|
|
1559
|
-
fieldResultIsFallback: field.type === "complexField" ? field.fieldResultIsFallback ?? null : null
|
|
1585
|
+
fieldResultIsFallback: field.type === "complexField" ? field.fieldResultIsFallback ?? null : null,
|
|
1586
|
+
formFieldDataXml: field.type === "complexField" ? field.formFieldDataXml ?? null : null,
|
|
1587
|
+
_docxEmptyResultRuns: emptyResultRuns ?? null,
|
|
1588
|
+
_docxFieldCode: field.type === "complexField" && field.fieldCode.length > 0 ? {
|
|
1589
|
+
instruction: field.instruction,
|
|
1590
|
+
runs: field.fieldCode
|
|
1591
|
+
} : null
|
|
1560
1592
|
}, createStructuredField ? inlineNodes : void 0, marks);
|
|
1561
1593
|
}
|
|
1562
1594
|
/**
|
|
@@ -2897,6 +2929,9 @@ function headerFooterToProseDoc(content, options) {
|
|
|
2897
2929
|
case "blockSdt":
|
|
2898
2930
|
out.push(convertBlockSdt(block, convertBlocks));
|
|
2899
2931
|
break;
|
|
2932
|
+
case "blockCustomXml":
|
|
2933
|
+
out.push(convertBlockCustomXml(block, convertBlocks));
|
|
2934
|
+
break;
|
|
2900
2935
|
case "preservedBlock":
|
|
2901
2936
|
out.push(convertPreservedBlock(block));
|
|
2902
2937
|
break;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
//#region src/prosemirror/emptyFieldResultRuns.d.ts
|
|
3
|
+
/** The single field mark lists every revision held by its invisible result runs. */
|
|
4
|
+
declare const emptyFieldRunPropertyChanges: (runs: readonly document_d_exports.Run[]) => document_d_exports.RunPropertyChange[];
|
|
5
|
+
type ResolveEmptyFieldResultRunsOptions = {
|
|
6
|
+
runs: readonly document_d_exports.Run[];
|
|
7
|
+
mode: "accept" | "reject";
|
|
8
|
+
revisionIds: ReadonlySet<number> | null;
|
|
9
|
+
};
|
|
10
|
+
type ResolvedEmptyFieldResultRuns = {
|
|
11
|
+
runs: document_d_exports.Run[];
|
|
12
|
+
visibleFormatting: document_d_exports.TextFormatting | undefined;
|
|
13
|
+
visibleFormattingChanged: boolean;
|
|
14
|
+
};
|
|
15
|
+
/** Resolve each authored run separately; a field mark carries their combined revisions. */
|
|
16
|
+
declare const resolveEmptyFieldResultRuns: ({ runs, mode, revisionIds }: ResolveEmptyFieldResultRunsOptions) => ResolvedEmptyFieldResultRuns | null;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { emptyFieldRunPropertyChanges, resolveEmptyFieldResultRuns };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { canonicalJson } from "../utils/canonicalJson.js";
|
|
2
|
+
//#region src/prosemirror/emptyFieldResultRuns.ts
|
|
3
|
+
/** The single field mark lists every revision held by its invisible result runs. */
|
|
4
|
+
const emptyFieldRunPropertyChanges = (runs) => runs.flatMap((run) => run.propertyChanges ?? []);
|
|
5
|
+
const visibleFormatting = (runs) => runs.find((run) => run.formatting !== void 0)?.formatting;
|
|
6
|
+
/** Resolve each authored run separately; a field mark carries their combined revisions. */
|
|
7
|
+
const resolveEmptyFieldResultRuns = ({ runs, mode, revisionIds }) => {
|
|
8
|
+
let changed = false;
|
|
9
|
+
const resolved = runs.map((run) => {
|
|
10
|
+
const matches = run.propertyChanges?.filter((change) => revisionIds === null || revisionIds.has(change.info.id));
|
|
11
|
+
if (!matches?.length) return run;
|
|
12
|
+
changed = true;
|
|
13
|
+
const remaining = run.propertyChanges?.filter((change) => revisionIds !== null && !revisionIds.has(change.info.id));
|
|
14
|
+
const formatting = mode === "reject" ? matches.at(0)?.previousFormatting : run.formatting;
|
|
15
|
+
return {
|
|
16
|
+
type: "run",
|
|
17
|
+
content: run.content,
|
|
18
|
+
...formatting !== void 0 ? { formatting } : {},
|
|
19
|
+
...remaining?.length ? { propertyChanges: remaining } : {},
|
|
20
|
+
...run.preservedAttributes ? { preservedAttributes: run.preservedAttributes } : {}
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
if (!changed) return null;
|
|
24
|
+
const before = visibleFormatting(runs);
|
|
25
|
+
const after = visibleFormatting(resolved);
|
|
26
|
+
return {
|
|
27
|
+
runs: resolved,
|
|
28
|
+
visibleFormatting: after,
|
|
29
|
+
visibleFormattingChanged: canonicalJson(before) !== canonicalJson(after)
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
export { emptyFieldRunPropertyChanges, resolveEmptyFieldResultRuns };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AnyExtension, CommandFactory, CommandMap, FolioCommandArguments, FolioCommandName } from "./types.js";
|
|
2
|
-
import { Plugin } from "prosemirror-state";
|
|
3
2
|
import { Schema } from "prosemirror-model";
|
|
3
|
+
import { Plugin } from "prosemirror-state";
|
|
4
4
|
//#region src/prosemirror/extensions/ExtensionManager.d.ts
|
|
5
5
|
declare class ExtensionManager {
|
|
6
6
|
private readonly extensions;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { areTransactionInvariantsEnabled, createTransactionInvariantPlugin } from "../plugins/transactionInvariants.js";
|
|
1
2
|
import { createTextInputPlugin } from "../textInput.js";
|
|
2
3
|
import { panic } from "better-result";
|
|
3
4
|
import { Schema } from "prosemirror-model";
|
|
@@ -50,7 +51,8 @@ var ExtensionManager = class {
|
|
|
50
51
|
this.plugins = [
|
|
51
52
|
createTextInputPlugin(),
|
|
52
53
|
...allPlugins,
|
|
53
|
-
...allKeyboardShortcuts.map((shortcuts) => keymap(shortcuts))
|
|
54
|
+
...allKeyboardShortcuts.map((shortcuts) => keymap(shortcuts)),
|
|
55
|
+
...areTransactionInvariantsEnabled() ? [createTransactionInvariantPlugin()] : []
|
|
54
56
|
];
|
|
55
57
|
this.commands = allCommands;
|
|
56
58
|
}
|
|
@@ -19,6 +19,7 @@ import { PasteStyleInlinerExtension } from "./features/PasteStyleInlinerExtensio
|
|
|
19
19
|
import { SelectionTrackerExtension } from "./features/SelectionTrackerExtension.js";
|
|
20
20
|
import { MARK_EXTENSIONS, MARK_NESTING_ORDER } from "./markRegistry.js";
|
|
21
21
|
import { BlockBookmarkBoundaryExtension } from "./nodes/BlockBookmarkBoundaryExtension.js";
|
|
22
|
+
import { BlockCustomXmlExtension } from "./nodes/BlockCustomXmlExtension.js";
|
|
22
23
|
import { BlockSdtExtension } from "./nodes/BlockSdtExtension.js";
|
|
23
24
|
import { BookmarkBoundaryExtension } from "./nodes/BookmarkBoundaryExtension.js";
|
|
24
25
|
import { CommentReferenceExtension } from "./nodes/CommentReferenceExtension.js";
|
|
@@ -86,10 +87,11 @@ function createStarterKit(options = {}) {
|
|
|
86
87
|
add("pageBreak", PageBreakExtension());
|
|
87
88
|
add("pageBreakRun", PageBreakRunExtension());
|
|
88
89
|
add("renderedPageBreak", RenderedPageBreakExtension());
|
|
89
|
-
add("field", FieldExtension());
|
|
90
|
+
add("field", FieldExtension({ getInternalClipboardToken }));
|
|
90
91
|
add("field", StructuredFieldExtension({ getInternalClipboardToken }));
|
|
91
92
|
add("sdt", SdtExtension());
|
|
92
93
|
add("blockSdt", BlockSdtExtension());
|
|
94
|
+
add("blockCustomXml", BlockCustomXmlExtension());
|
|
93
95
|
add("preservedBlock", PreservedBlockExtension());
|
|
94
96
|
add("math", MathExtension());
|
|
95
97
|
if (!disabled.has("table")) extensions.push(...createTableExtensions());
|
|
@@ -14,7 +14,7 @@ const DocExtension = createNodeExtension({
|
|
|
14
14
|
_adjustLineHeightInTable: { default: false },
|
|
15
15
|
_doNotUseIndentAsNumberingTabStop: { default: false }
|
|
16
16
|
},
|
|
17
|
-
content: "(paragraph | horizontalRule | pageBreak | table | textBox | blockSdt | preservedBlock | blockBookmarkBoundary)+"
|
|
17
|
+
content: "(paragraph | horizontalRule | pageBreak | table | textBox | blockSdt | blockCustomXml | preservedBlock | blockBookmarkBoundary)+"
|
|
18
18
|
}
|
|
19
19
|
});
|
|
20
20
|
//#endregion
|
|
@@ -213,6 +213,7 @@ const paragraphNodeSpec = {
|
|
|
213
213
|
indentFirstLine: { default: null },
|
|
214
214
|
hangingIndent: { default: false },
|
|
215
215
|
numPr: { default: null },
|
|
216
|
+
_pastedHtmlList: { default: void 0 },
|
|
216
217
|
numPrFromStyle: { default: null },
|
|
217
218
|
listNumFmt: { default: null },
|
|
218
219
|
listIsBullet: { default: null },
|
|
@@ -273,11 +274,22 @@ const paragraphNodeSpec = {
|
|
|
273
274
|
const styleId = element.dataset["styleId"];
|
|
274
275
|
const tableOfContentsLevel = Number(element.dataset["tableOfContentsLevel"]);
|
|
275
276
|
const sectionBreakType = parseSectionBreakType(element.dataset["sectionBreak"]);
|
|
277
|
+
const pastedListGroup = Number(element.dataset["folioListGroup"]);
|
|
278
|
+
const pastedListLevel = Number(element.dataset["folioListLevel"]);
|
|
279
|
+
const pastedListKind = element.dataset["folioListKind"];
|
|
280
|
+
const pastedListStart = Number(element.dataset["folioListStart"]);
|
|
281
|
+
const pastedHtmlList = Number.isSafeInteger(pastedListGroup) && pastedListGroup > 0 && Number.isSafeInteger(pastedListLevel) && pastedListLevel >= 0 && pastedListLevel <= 8 && (pastedListKind === "bullet" || pastedListKind === "numbered") ? {
|
|
282
|
+
group: pastedListGroup,
|
|
283
|
+
level: pastedListLevel,
|
|
284
|
+
kind: pastedListKind,
|
|
285
|
+
...Number.isSafeInteger(pastedListStart) && pastedListStart > 0 ? { start: pastedListStart } : {}
|
|
286
|
+
} : void 0;
|
|
276
287
|
const attrs = {
|
|
277
288
|
...paraId ? { paraId } : {},
|
|
278
289
|
...alignment ? { alignment } : {},
|
|
279
290
|
...alignmentFromStyle ? { alignmentFromStyle } : {},
|
|
280
291
|
...styleId ? { styleId } : {},
|
|
292
|
+
...pastedHtmlList ? { _pastedHtmlList: pastedHtmlList } : {},
|
|
281
293
|
...Number.isSafeInteger(tableOfContentsLevel) && tableOfContentsLevel > 0 ? { _tableOfContentsLevel: tableOfContentsLevel } : {},
|
|
282
294
|
...sectionBreakType ? { _sectionProperties: mintSectionProperties(sectionBreakType) } : {}
|
|
283
295
|
};
|
|
@@ -63,6 +63,9 @@ const INHERITED_PARA_ATTRS = [
|
|
|
63
63
|
"snapToGrid",
|
|
64
64
|
"spaceAfter",
|
|
65
65
|
"spaceBefore",
|
|
66
|
+
"spacingExplicit",
|
|
67
|
+
"spacingFromDocDefaults",
|
|
68
|
+
"spacingFromImplicitDefaultStyle",
|
|
66
69
|
"contextualSpacing"
|
|
67
70
|
];
|
|
68
71
|
/** Style formatting needed when the caret has no marks of its own. */
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { NO_PARAGRAPH_NUMBERING, paragraphNumberingLevel, paragraphNumberingReference, paragraphNumberingReferenceId } from "../../../docx/numberingReference.js";
|
|
1
|
+
import { paragraphNumberingLevel, paragraphNumberingReferenceId } from "../../../docx/numberingReference.js";
|
|
3
2
|
import { expectParagraphAttrs } from "../../attrs/index.js";
|
|
4
|
-
import {
|
|
3
|
+
import { LIST_MARKER_PATTERN, listRequestsForMarker } from "../../listAutoformatMarkers.js";
|
|
5
4
|
import { CLEARED_LIST_RENDERING_ATTRS } from "../../listMarker.js";
|
|
6
|
-
import {
|
|
5
|
+
import { applyParagraphUpdates, continueNumbering, listItemAttrs, resolveListTarget, restartNumbering, setNumberingValue } from "../../listNumbering.js";
|
|
7
6
|
import { resolveListState } from "../../listState.js";
|
|
8
|
-
import {
|
|
7
|
+
import { removedNumberingAttr } from "../../numberingAttr.js";
|
|
9
8
|
import { getDocumentNumbering } from "../../plugins/documentNumbering.js";
|
|
10
|
-
import { SUGGESTION_META, makeRevisionInfo } from "../../plugins/suggestionMode.js";
|
|
9
|
+
import { SUGGESTION_META, makeRevisionInfo, suggestRangeDeletion } from "../../plugins/suggestionMode.js";
|
|
11
10
|
import { listLevelAttrPatch } from "../../styles/resolvedStyleAttrs.js";
|
|
12
11
|
import { createExtension } from "../create.js";
|
|
13
12
|
import { goToNextCell, goToPrevCell } from "../nodes/TableExtension.js";
|
|
14
13
|
import { Priority } from "../types.js";
|
|
15
14
|
import { panic } from "better-result";
|
|
15
|
+
import { Plugin } from "prosemirror-state";
|
|
16
16
|
import { InputRule, inputRules, undoInputRule } from "prosemirror-inputrules";
|
|
17
17
|
//#region src/prosemirror/extensions/features/ListExtension.ts
|
|
18
18
|
/**
|
|
@@ -27,113 +27,87 @@ function chainCommands(...commands) {
|
|
|
27
27
|
return false;
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
|
-
function appendParagraphPropertyChange(attrs, existing, previousFormatting, rev) {
|
|
31
|
-
return {
|
|
32
|
-
...attrs,
|
|
33
|
-
_propertyChanges: [...existing ?? [], {
|
|
34
|
-
type: "paragraphPropertyChange",
|
|
35
|
-
info: {
|
|
36
|
-
id: rev.id,
|
|
37
|
-
author: rev.author,
|
|
38
|
-
date: rev.date
|
|
39
|
-
},
|
|
40
|
-
previousFormatting
|
|
41
|
-
}]
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
function getPreviousListFormatting(attrs) {
|
|
45
|
-
const previousFormatting = {};
|
|
46
|
-
for (const key of PPR_CHANGE_SCOPED_ATTR_KEYS) {
|
|
47
|
-
const value = attrs[key];
|
|
48
|
-
if (value != null) previousFormatting[key] = value;
|
|
49
|
-
}
|
|
50
|
-
previousFormatting["numPr"] = attrs["numPr"] ?? null;
|
|
51
|
-
for (const key of LIST_RENDERING_ATTR_KEYS) previousFormatting[key] = attrs[key] ?? null;
|
|
52
|
-
return previousFormatting;
|
|
53
|
-
}
|
|
54
30
|
function clearListAttrs(attrs) {
|
|
55
|
-
const numPr = paragraphNumberingReferenceId(attrs.numPrFromStyle) === void 0 ? null : paragraphNumberingAttr(NO_PARAGRAPH_NUMBERING);
|
|
56
31
|
return {
|
|
57
32
|
...attrs,
|
|
58
|
-
numPr,
|
|
33
|
+
numPr: removedNumberingAttr(attrs.numPrFromStyle),
|
|
59
34
|
...CLEARED_LIST_RENDERING_ATTRS
|
|
60
35
|
};
|
|
61
36
|
}
|
|
62
37
|
function hasActiveListNumbering(attrs) {
|
|
63
38
|
return attrs.numPr?.kind === "reference";
|
|
64
39
|
}
|
|
40
|
+
const paragraphsBetween = (doc, from, to) => {
|
|
41
|
+
const paragraphs = [];
|
|
42
|
+
doc.nodesBetween(from, to, (node, pos) => {
|
|
43
|
+
if (node.type.name !== "paragraph") return true;
|
|
44
|
+
paragraphs.push({
|
|
45
|
+
pos,
|
|
46
|
+
node
|
|
47
|
+
});
|
|
48
|
+
return false;
|
|
49
|
+
});
|
|
50
|
+
return paragraphs;
|
|
51
|
+
};
|
|
65
52
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
53
|
+
* Make every paragraph from `from` to `to` an item of one list: the list next
|
|
54
|
+
* to them when it matches, else a new one (see `listNumbering.ts`). One
|
|
55
|
+
* target for the whole range, so a selection of plain paragraphs becomes one
|
|
56
|
+
* list rather than one list apiece.
|
|
70
57
|
*/
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
};
|
|
78
|
-
if (
|
|
79
|
-
|
|
58
|
+
const numberParagraphs = ({ state, tr, from, to, requests }) => {
|
|
59
|
+
const target = resolveListTarget({
|
|
60
|
+
numbering: getDocumentNumbering(state),
|
|
61
|
+
$from: tr.doc.resolve(from),
|
|
62
|
+
$to: tr.doc.resolve(to),
|
|
63
|
+
requests
|
|
64
|
+
});
|
|
65
|
+
if (!target) return false;
|
|
66
|
+
applyParagraphUpdates({
|
|
67
|
+
tr,
|
|
68
|
+
state,
|
|
69
|
+
updates: paragraphsBetween(tr.doc, from, to).map(({ pos, node }) => ({
|
|
70
|
+
pos,
|
|
71
|
+
node,
|
|
72
|
+
next: listItemAttrs(node.attrs, {
|
|
73
|
+
numId: target.numId,
|
|
74
|
+
ilvl: paragraphNumberingLevel(expectParagraphAttrs(node).numPr) ?? target.ilvl
|
|
75
|
+
}, target.numbering)
|
|
76
|
+
}))
|
|
77
|
+
});
|
|
78
|
+
return true;
|
|
80
79
|
};
|
|
81
|
-
function toggleList(
|
|
80
|
+
function toggleList(intent) {
|
|
82
81
|
return (state, dispatch) => {
|
|
83
82
|
const { $from, $to } = state.selection;
|
|
84
83
|
const paragraph = $from.parent;
|
|
85
84
|
if (paragraph.type.name !== "paragraph") return false;
|
|
86
|
-
const numbering = getDocumentNumbering(state);
|
|
87
|
-
const isInSameList = resolveListState(numbering, expectParagraphAttrs(paragraph).numPr).type === intent;
|
|
88
|
-
const rev = makeRevisionInfo(state);
|
|
89
|
-
if (rev) {
|
|
90
|
-
let hasPendingChange = false;
|
|
91
|
-
state.doc.nodesBetween($from.pos, $to.pos, (node) => {
|
|
92
|
-
if (node.type.name === "paragraph" && hasSerializableParagraphPropertyChange(expectParagraphAttrs(node)._propertyChanges)) {
|
|
93
|
-
hasPendingChange = true;
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
if (hasPendingChange) return false;
|
|
98
|
-
}
|
|
99
85
|
if (!dispatch) return true;
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
})),
|
|
119
|
-
listIsBullet: isBullet,
|
|
120
|
-
listNumFmt: isBullet ? null : definition?.numFmt ?? "decimal"
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
if (rev) {
|
|
124
|
-
const existing = expectParagraphAttrs(node)._propertyChanges;
|
|
125
|
-
nextAttrs = appendParagraphPropertyChange(nextAttrs, existing, getPreviousListFormatting(node.attrs), rev);
|
|
126
|
-
}
|
|
127
|
-
tr = tr.setNodeMarkup(pos, void 0, nextAttrs);
|
|
128
|
-
}
|
|
86
|
+
const numbering = getDocumentNumbering(state);
|
|
87
|
+
const isItemOfKind = (node) => resolveListState(numbering, expectParagraphAttrs(node).numPr).type === intent;
|
|
88
|
+
const tr = state.tr;
|
|
89
|
+
if (isItemOfKind(paragraph)) applyParagraphUpdates({
|
|
90
|
+
tr,
|
|
91
|
+
state,
|
|
92
|
+
updates: paragraphsBetween(state.doc, $from.pos, $to.pos).filter(({ node }) => isItemOfKind(node)).map(({ pos, node }) => ({
|
|
93
|
+
pos,
|
|
94
|
+
node,
|
|
95
|
+
next: clearListAttrs(expectParagraphAttrs(node))
|
|
96
|
+
}))
|
|
97
|
+
});
|
|
98
|
+
else numberParagraphs({
|
|
99
|
+
state,
|
|
100
|
+
tr,
|
|
101
|
+
from: $from.pos,
|
|
102
|
+
to: $to.pos,
|
|
103
|
+
requests: [{ kind: intent }]
|
|
129
104
|
});
|
|
130
|
-
if (rev) tr.setMeta(SUGGESTION_META, true);
|
|
131
105
|
dispatch(tr.scrollIntoView());
|
|
132
106
|
return true;
|
|
133
107
|
};
|
|
134
108
|
}
|
|
135
|
-
const toggleBulletList = (state, dispatch) => toggleList(
|
|
136
|
-
const toggleNumberedList = (state, dispatch) => toggleList(
|
|
109
|
+
const toggleBulletList = (state, dispatch) => toggleList("bullet")(state, dispatch);
|
|
110
|
+
const toggleNumberedList = (state, dispatch) => toggleList("numbered")(state, dispatch);
|
|
137
111
|
const attrsForListLevel = (state, attrs, level) => {
|
|
138
112
|
if (!hasActiveListNumbering(attrs)) panic("Cannot change the level of a list without a numbering id");
|
|
139
113
|
return {
|
|
@@ -215,7 +189,19 @@ function exitListOnEmptyEnter() {
|
|
|
215
189
|
const attrs = expectParagraphAttrs(paragraph);
|
|
216
190
|
if (!hasActiveListNumbering(attrs)) return false;
|
|
217
191
|
if (paragraph.textContent.length > 0) return false;
|
|
218
|
-
if (dispatch)
|
|
192
|
+
if (dispatch) {
|
|
193
|
+
const tr = state.tr;
|
|
194
|
+
applyParagraphUpdates({
|
|
195
|
+
tr,
|
|
196
|
+
state,
|
|
197
|
+
updates: [{
|
|
198
|
+
pos: $from.before(),
|
|
199
|
+
node: paragraph,
|
|
200
|
+
next: clearListAttrs(attrs)
|
|
201
|
+
}]
|
|
202
|
+
});
|
|
203
|
+
dispatch(tr);
|
|
204
|
+
}
|
|
219
205
|
return true;
|
|
220
206
|
};
|
|
221
207
|
}
|
|
@@ -229,10 +215,19 @@ function splitListItem() {
|
|
|
229
215
|
if (dispatch) {
|
|
230
216
|
const { tr } = state;
|
|
231
217
|
const pos = $from.pos;
|
|
218
|
+
const paragraphPos = $from.before();
|
|
219
|
+
const revision = makeRevisionInfo(state);
|
|
232
220
|
tr.split(pos, 1, [{
|
|
233
221
|
type: state.schema.nodes["paragraph"],
|
|
234
222
|
attrs: { ...paragraph.attrs }
|
|
235
223
|
}]);
|
|
224
|
+
if (revision && paragraph.attrs["pPrMark"] == null) {
|
|
225
|
+
tr.setNodeAttribute(paragraphPos, "pPrMark", {
|
|
226
|
+
kind: "ins",
|
|
227
|
+
info: revision
|
|
228
|
+
});
|
|
229
|
+
tr.setMeta(SUGGESTION_META, true);
|
|
230
|
+
}
|
|
236
231
|
dispatch(tr.scrollIntoView());
|
|
237
232
|
}
|
|
238
233
|
return true;
|
|
@@ -247,7 +242,19 @@ function backspaceExitList() {
|
|
|
247
242
|
if (paragraph.type.name !== "paragraph") return false;
|
|
248
243
|
const attrs = expectParagraphAttrs(paragraph);
|
|
249
244
|
if (!hasActiveListNumbering(attrs)) return false;
|
|
250
|
-
if (dispatch)
|
|
245
|
+
if (dispatch) {
|
|
246
|
+
const tr = state.tr;
|
|
247
|
+
applyParagraphUpdates({
|
|
248
|
+
tr,
|
|
249
|
+
state,
|
|
250
|
+
updates: [{
|
|
251
|
+
pos: $from.before(),
|
|
252
|
+
node: paragraph,
|
|
253
|
+
next: clearListAttrs(attrs)
|
|
254
|
+
}]
|
|
255
|
+
});
|
|
256
|
+
dispatch(tr);
|
|
257
|
+
}
|
|
251
258
|
return true;
|
|
252
259
|
};
|
|
253
260
|
}
|
|
@@ -314,53 +321,84 @@ function insertTab() {
|
|
|
314
321
|
return true;
|
|
315
322
|
};
|
|
316
323
|
}
|
|
324
|
+
/** Whether a typed marker may become a list here at all. */
|
|
325
|
+
const acceptsListMarker = (paragraph) => paragraph.type.name === "paragraph" && paragraphNumberingReferenceId(expectParagraphAttrs(paragraph).numPr) === void 0;
|
|
317
326
|
/**
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
327
|
+
* Replace a typed marker with the list the toolbar button produces: the same
|
|
328
|
+
* target resolution and the same attrs, so an autoformatted list saves exactly
|
|
329
|
+
* like a clicked one. The marker's format and value choose the list (see
|
|
330
|
+
* `listAutoformatMarkers.ts`).
|
|
321
331
|
*/
|
|
322
|
-
const
|
|
323
|
-
const NUMBERED_AUTOFORMAT = /^1\. $/u;
|
|
324
|
-
const captureTransaction = (command, state) => {
|
|
325
|
-
const captured = { transaction: null };
|
|
326
|
-
command(state, (transaction) => {
|
|
327
|
-
captured.transaction = transaction;
|
|
328
|
-
});
|
|
329
|
-
return captured.transaction;
|
|
330
|
-
};
|
|
331
|
-
/**
|
|
332
|
-
* Replace a typed marker with the list the toolbar button produces. Running the
|
|
333
|
-
* command itself (rather than writing `numPr` here) keeps an autoformatted list
|
|
334
|
-
* identical to a clicked one, down to what the document saves.
|
|
335
|
-
*/
|
|
336
|
-
const listAutoformat = (marker, toggleCommand) => new InputRule(marker, (state, _match, start, end) => {
|
|
332
|
+
const listAutoformatRule = () => new InputRule(LIST_MARKER_PATTERN, (state, match, start, end) => {
|
|
337
333
|
const { $from } = state.selection;
|
|
338
|
-
if ($from.parent
|
|
334
|
+
if (!acceptsListMarker($from.parent)) return null;
|
|
339
335
|
if (start !== $from.start()) return null;
|
|
340
|
-
if (paragraphNumberingReferenceId(expectParagraphAttrs($from.parent).numPr) !== void 0) return null;
|
|
341
336
|
if (makeRevisionInfo(state)) return null;
|
|
342
|
-
const
|
|
343
|
-
if (!
|
|
337
|
+
const requests = listRequestsForMarker(match[0]);
|
|
338
|
+
if (!requests) return null;
|
|
344
339
|
const tr = state.tr.delete(start, end);
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
340
|
+
return numberParagraphs({
|
|
341
|
+
state,
|
|
342
|
+
tr,
|
|
343
|
+
from: start,
|
|
344
|
+
to: start,
|
|
345
|
+
requests
|
|
346
|
+
}) ? tr : null;
|
|
350
347
|
});
|
|
351
|
-
|
|
348
|
+
/**
|
|
349
|
+
* List autoformat while suggesting. The suggestion plugin has already
|
|
350
|
+
* recorded the typed space as a tracked insertion; this follows it with the
|
|
351
|
+
* marker's removal (a retraction of the author's own typing, or a tracked
|
|
352
|
+
* deletion of text that was there before) and the list as a tracked
|
|
353
|
+
* paragraph-property change. The follow-up is appended to the typing
|
|
354
|
+
* transaction, so one undo reverts both, and it is stored as the input rule's
|
|
355
|
+
* last conversion, so Backspace puts the marker back as it does while editing.
|
|
356
|
+
*/
|
|
357
|
+
const suggestedListAutoformat = (autoformat) => new Plugin({ appendTransaction(transactions, _oldState, state) {
|
|
358
|
+
if (!transactions.some((tr) => tr.getMeta("suggestionModeTextInput") === " ")) return null;
|
|
359
|
+
const { $head, empty } = state.selection;
|
|
360
|
+
if (!empty || !makeRevisionInfo(state) || !acceptsListMarker($head.parent)) return null;
|
|
361
|
+
const requests = listRequestsForMarker($head.parent.textBetween(0, $head.parentOffset, null, ""));
|
|
362
|
+
if (!requests) return null;
|
|
363
|
+
const start = $head.start();
|
|
364
|
+
const tr = state.tr;
|
|
365
|
+
if (!suggestRangeDeletion(state, tr, start, $head.pos)) return null;
|
|
366
|
+
const from = tr.mapping.map(start);
|
|
367
|
+
if (!numberParagraphs({
|
|
368
|
+
state,
|
|
369
|
+
tr,
|
|
370
|
+
from,
|
|
371
|
+
to: from,
|
|
372
|
+
requests
|
|
373
|
+
})) return null;
|
|
374
|
+
const caret = tr.mapping.map($head.pos);
|
|
375
|
+
tr.setMeta(autoformat, {
|
|
376
|
+
transform: tr,
|
|
377
|
+
from: caret,
|
|
378
|
+
to: caret,
|
|
379
|
+
text: ""
|
|
380
|
+
});
|
|
381
|
+
return tr;
|
|
382
|
+
} });
|
|
383
|
+
const listAutoformatPlugins = () => {
|
|
384
|
+
const autoformat = inputRules({ rules: [listAutoformatRule()] });
|
|
385
|
+
return [autoformat, suggestedListAutoformat(autoformat)];
|
|
386
|
+
};
|
|
352
387
|
const ListExtension = createExtension({
|
|
353
388
|
name: "list",
|
|
354
389
|
priority: Priority.High,
|
|
355
390
|
onSchemaReady() {
|
|
356
391
|
return {
|
|
357
|
-
plugins:
|
|
392
|
+
plugins: listAutoformatPlugins(),
|
|
358
393
|
commands: {
|
|
359
394
|
toggleBulletList: () => toggleBulletList,
|
|
360
395
|
toggleNumberedList: () => toggleNumberedList,
|
|
361
396
|
increaseListLevel: () => increaseListLevel,
|
|
362
397
|
decreaseListLevel: () => decreaseListLevel,
|
|
363
|
-
removeList: () => removeList
|
|
398
|
+
removeList: () => removeList,
|
|
399
|
+
restartNumbering: () => restartNumbering,
|
|
400
|
+
continueNumbering: () => continueNumbering,
|
|
401
|
+
setNumberingValue: (value) => setNumberingValue(value)
|
|
364
402
|
},
|
|
365
403
|
keyboardShortcuts: {
|
|
366
404
|
Tab: chainCommands(goToNextCell(), increaseListIndent(), insertTab()),
|