@stll/folio-core 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/apply.d.ts +2 -1
- package/dist/ai-edits/apply.js +693 -63
- package/dist/ai-edits/block-identity.d.ts +4 -0
- package/dist/ai-edits/block-identity.js +9 -0
- package/dist/ai-edits/blockRange.d.ts +28 -1
- package/dist/ai-edits/blockRange.js +68 -2
- package/dist/ai-edits/clean-text.js +2 -1
- package/dist/ai-edits/headless.d.ts +4 -4
- package/dist/ai-edits/headless.js +9 -9
- package/dist/ai-edits/index.d.ts +2 -2
- package/dist/ai-edits/index.js +2 -2
- package/dist/ai-edits/read.d.ts +7 -7
- package/dist/ai-edits/read.js +110 -3
- package/dist/ai-edits/snapshot.js +21 -3
- package/dist/ai-edits/table-cell-mutations.d.ts +48 -0
- package/dist/ai-edits/table-cell-mutations.js +238 -0
- package/dist/ai-edits/table-mutation-plan.d.ts +38 -0
- package/dist/ai-edits/table-mutation-plan.js +90 -0
- package/dist/ai-edits/table-row-column-mutations.d.ts +108 -0
- package/dist/ai-edits/table-row-column-mutations.js +300 -0
- package/dist/ai-edits/table-targets.d.ts +32 -0
- package/dist/ai-edits/table-targets.js +70 -0
- package/dist/ai-edits/types.d.ts +62 -1
- package/dist/ai-edits/word-diff.js +21 -0
- package/dist/compat/eigenpal.d.ts +3 -3
- package/dist/compat/eigenpal.js +3 -3
- package/dist/content-controls/mutateContentControls.js +1 -1
- package/dist/controller/activeEditorStory.d.ts +36 -0
- package/dist/controller/activeEditorStory.js +30 -0
- package/dist/controller/contentControlWidgetController.d.ts +55 -0
- package/dist/controller/contentControlWidgetController.js +141 -0
- package/dist/controller/fontReadiness.js +2 -0
- package/dist/controller/headerFooterEditorManager.js +2 -2
- package/dist/controller/hiddenEditorApi.js +2 -2
- package/dist/controller/hiddenEditorManager.d.ts +12 -1
- package/dist/controller/hiddenEditorManager.js +44 -12
- package/dist/controller/layoutPipeline.d.ts +2 -0
- package/dist/controller/layoutPipeline.js +17 -2
- package/dist/controller/noteEditorManager.d.ts +36 -0
- package/dist/controller/noteEditorManager.js +210 -0
- package/dist/document-operations.d.ts +43 -11
- package/dist/document-operations.js +186 -18
- package/dist/docx/blockContentParser.js +21 -7
- package/dist/docx/commentParser.js +6 -1
- package/dist/docx/commentRangeIntegrity.d.ts +6 -0
- package/dist/docx/commentRangeIntegrity.js +186 -0
- package/dist/docx/conformance.js +62 -1
- package/dist/docx/documentGrid.d.ts +8 -0
- package/dist/docx/documentGrid.js +8 -0
- package/dist/docx/drawingUtils.js +1 -1
- package/dist/docx/encryption/agileDecryption.js +12 -2
- package/dist/docx/encryption/compoundFile.js +6 -1
- package/dist/docx/encryption/encryptionInfo.d.ts +9 -1
- package/dist/docx/encryption/encryptionInfo.js +18 -2
- package/dist/docx/encryption/openEncryptedDocx.js +1 -1
- package/dist/docx/ensureParaIds.js +8 -7
- package/dist/docx/fieldParser.js +1 -1
- package/dist/docx/groupDrawingParser.js +10 -5
- package/dist/docx/hyperlinkParser.js +1 -1
- package/dist/docx/imageParser.js +10 -6
- package/dist/docx/metadataPrivacy.js +17 -3
- package/dist/docx/notePropertiesParser.js +1 -1
- package/dist/docx/numberingParser.js +1 -1
- package/dist/docx/paragraphParser.js +70 -61
- package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
- package/dist/docx/paragraphTextBoxEnrichment.js +67 -13
- package/dist/docx/paragraphTraversal.js +1 -1
- package/dist/docx/parser.js +3 -3
- package/dist/docx/rezip.js +20 -9
- package/dist/docx/runParser.js +17 -6
- package/dist/docx/sdtProperties.js +1 -1
- package/dist/docx/sectionParser.js +18 -5
- package/dist/docx/selectiveSave.js +5 -1
- package/dist/docx/selectiveXmlPatch.d.ts +22 -1
- package/dist/docx/selectiveXmlPatch.js +61 -1
- package/dist/docx/serializer/blockSdtSerializer.js +3 -2
- package/dist/docx/serializer/commentSerializer.js +5 -6
- package/dist/docx/serializer/documentSerializer.js +2 -2
- package/dist/docx/serializer/headerFooterSerializer.js +2 -2
- package/dist/docx/serializer/noteSerializer.js +2 -2
- package/dist/docx/serializer/paragraphSerializer.js +23 -15
- package/dist/docx/serializer/runSerializer.js +25 -21
- package/dist/docx/serializer/sectionPropertiesSerializer.js +2 -1
- package/dist/docx/serializer/stylesSerializer.js +1 -1
- package/dist/docx/serializer/tableSerializer.d.ts +5 -4
- package/dist/docx/serializer/tableSerializer.js +26 -20
- package/dist/docx/serializer/xmlUtils.d.ts +13 -1
- package/dist/docx/serializer/xmlUtils.js +27 -1
- package/dist/docx/server/applyDocxXmlPatchProposal.d.ts +87 -0
- package/dist/docx/server/applyDocxXmlPatchProposal.js +204 -0
- package/dist/docx/server/boundedArchive.d.ts +14 -3
- package/dist/docx/server/boundedArchive.js +56 -11
- package/dist/docx/server/evaluateDocxXmlPatchProposal.d.ts +85 -0
- package/dist/docx/server/evaluateDocxXmlPatchProposal.js +361 -0
- package/dist/docx/server/extractDocxText.js +55 -8
- package/dist/docx/server/inspectDocxPackage.d.ts +70 -0
- package/dist/docx/server/inspectDocxPackage.js +217 -0
- package/dist/docx/server/validateDocxConformance.d.ts +41 -0
- package/dist/docx/server/validateDocxConformance.js +336 -0
- package/dist/docx/settingsParser.js +26 -3
- package/dist/docx/shapeParser.js +1 -1
- package/dist/docx/styleParser.js +4 -2
- package/dist/docx/tableParser.d.ts +8 -1
- package/dist/docx/tableParser.js +31 -10
- package/dist/docx/textBoxParser.d.ts +3 -3
- package/dist/docx/textBoxParser.js +16 -12
- package/dist/docx/unzip.js +1 -0
- package/dist/docx/vmlImageParser.js +11 -3
- package/dist/docx/xmlParser.js +11 -1
- package/dist/docx/xmlSafety.d.ts +5 -0
- package/dist/docx/xmlSafety.js +9 -0
- package/dist/fields/resolveFieldValues.js +1 -3
- package/dist/fonts/embeddedFonts.d.ts +33 -5
- package/dist/fonts/embeddedFonts.js +37 -8
- package/dist/i18n/messages/catalogs.gen.d.ts +17 -0
- package/dist/i18n/messages/catalogs.gen.js +17 -0
- package/dist/i18n/messages/messages.gen.d.ts +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +47 -40
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.js +3 -0
- package/dist/layout-bridge/convert/templatePreviewFlow.js +3 -3
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +4 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +151 -20
- package/dist/layout-bridge/dom/noteStoryDom.d.ts +6 -0
- package/dist/layout-bridge/dom/noteStoryDom.js +17 -0
- package/dist/layout-bridge/engine/clickToPosition.js +2 -2
- package/dist/layout-engine/index.d.ts +2 -2
- package/dist/layout-engine/index.js +58 -30
- package/dist/layout-engine/justificationCompatibility.d.ts +6 -0
- package/dist/layout-engine/justificationCompatibility.js +8 -0
- package/dist/layout-engine/keep-together.js +11 -1
- package/dist/layout-engine/measure/cache.js +23 -5
- package/dist/layout-engine/measure/effectiveLineBreakPolicy.js +8 -2
- package/dist/layout-engine/measure/lineBreakProvider.d.ts +2 -2
- package/dist/layout-engine/measure/lineBreakProvider.js +56 -37
- package/dist/layout-engine/measure/measureBlocks.js +15 -4
- package/dist/layout-engine/measure/measureContainer.js +1 -1
- package/dist/layout-engine/measure/measureHelpers.d.ts +11 -2
- package/dist/layout-engine/measure/measureHelpers.js +15 -4
- package/dist/layout-engine/measure/measureParagraph.js +85 -25
- package/dist/layout-engine/measure/measureProvider.js +4 -3
- package/dist/layout-engine/measure/tableCellFlow.js +5 -2
- package/dist/layout-engine/measure/textBoxParagraphLayout.d.ts +9 -7
- package/dist/layout-engine/measure/textBoxParagraphLayout.js +22 -6
- package/dist/layout-engine/measure/textMeasurementPolicy.d.ts +3 -1
- package/dist/layout-engine/measure/textMeasurementPolicy.js +7 -1
- package/dist/layout-engine/paginator.js +5 -1
- package/dist/layout-engine/paragraphSpacing.d.ts +28 -4
- package/dist/layout-engine/paragraphSpacing.js +107 -13
- package/dist/layout-engine/renderedBreakReconciliation.js +1 -1
- package/dist/layout-engine/types.d.ts +48 -15
- package/dist/layout-painter/registry/modules/textBox.js +5 -1
- package/dist/layout-painter/renderImage.d.ts +12 -1
- package/dist/layout-painter/renderImage.js +21 -4
- package/dist/layout-painter/renderPage.d.ts +5 -2
- package/dist/layout-painter/renderPage.js +59 -14
- package/dist/layout-painter/renderParagraph.js +55 -15
- package/dist/layout-painter/renderTable.d.ts +5 -1
- package/dist/layout-painter/renderTable.js +7 -3
- package/dist/layout-painter/renderTextBox.d.ts +2 -1
- package/dist/layout-painter/renderTextBox.js +25 -14
- package/dist/layout-painter/renderWatermark.d.ts +1 -1
- package/dist/layout-painter/renderWatermark.js +2 -1
- package/dist/managers/DocumentLoaderManager.js +1 -1
- package/dist/markdown/fromMarkdown.js +1 -1
- package/dist/model.js +1 -1
- package/dist/prosemirror/attrs/index.d.ts +4 -2
- package/dist/prosemirror/attrs/index.js +175 -18
- package/dist/prosemirror/commands/comments.d.ts +79 -4
- package/dist/prosemirror/commands/comments.js +622 -13
- package/dist/prosemirror/commands/contentControls.js +1 -1
- package/dist/prosemirror/commands/hyperlink.js +15 -1
- package/dist/prosemirror/commands/image.js +7 -1
- package/dist/prosemirror/commands/index.d.ts +2 -2
- package/dist/prosemirror/commands/index.js +2 -2
- package/dist/prosemirror/commands/pageBreak.js +1 -1
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +2 -2
- package/dist/prosemirror/commands/propertyChangeScope.js +3 -2
- package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +9 -0
- package/dist/prosemirror/commands/tableCellMergeResolution.js +181 -0
- package/dist/prosemirror/commentIdAllocator.js +13 -3
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +404 -62
- package/dist/prosemirror/conversion/index.js +1 -1
- package/dist/prosemirror/conversion/sdtAttrs.d.ts +9 -0
- package/dist/prosemirror/conversion/sdtAttrs.js +49 -0
- package/dist/prosemirror/conversion/toProseDoc.d.ts +2 -1
- package/dist/prosemirror/conversion/toProseDoc.js +364 -103
- package/dist/prosemirror/extensions/ExtensionManager.js +1 -1
- package/dist/prosemirror/extensions/StarterKit.js +6 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +6 -2
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +1 -0
- package/dist/prosemirror/extensions/features/ImagePasteExtension.js +10 -2
- package/dist/prosemirror/extensions/features/ListExtension.js +1 -1
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +10 -1
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +93 -2
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +2 -1
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +6 -2
- package/dist/prosemirror/extensions/features/pasteCleanup.js +15 -2
- package/dist/prosemirror/extensions/marks/CharacterSpacingExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +30 -4
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.d.ts +9 -1
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +70 -11
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +1 -1
- package/dist/prosemirror/extensions/nodes/RenderedPageBreakExtension.d.ts +7 -0
- package/dist/prosemirror/extensions/nodes/RenderedPageBreakExtension.js +22 -0
- package/dist/prosemirror/extensions/nodes/TableExtension.d.ts +1 -1
- package/dist/prosemirror/extensions/nodes/TableExtension.js +14 -6
- package/dist/prosemirror/extensions/nodes/TextBoxAnchorExtension.d.ts +13 -0
- package/dist/prosemirror/extensions/nodes/TextBoxAnchorExtension.js +41 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +5 -2
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +4 -1
- package/dist/prosemirror/index.d.ts +1 -1
- package/dist/prosemirror/index.js +1 -1
- package/dist/prosemirror/plugins/contentControlWidgets.d.ts +36 -10
- package/dist/prosemirror/plugins/contentControlWidgets.js +128 -94
- package/dist/prosemirror/plugins/revisionIds.d.ts +23 -0
- package/dist/prosemirror/plugins/revisionIds.js +57 -0
- package/dist/prosemirror/plugins/selectionTracker.js +1 -0
- package/dist/prosemirror/plugins/suggestionMode.js +5 -4
- package/dist/prosemirror/runFormattingMarkNames.d.ts +14 -0
- package/dist/prosemirror/runFormattingMarkNames.js +40 -0
- package/dist/prosemirror/schema/index.d.ts +2 -2
- package/dist/prosemirror/schema/marks.d.ts +30 -3
- package/dist/prosemirror/schema/marks.js +15 -0
- package/dist/prosemirror/schema/nodes.d.ts +111 -6
- package/dist/prosemirror/selectionState.js +1 -0
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
- package/dist/prosemirror/tableCellMergeRevision.d.ts +9 -0
- package/dist/prosemirror/tableCellMergeRevision.js +22 -0
- package/dist/prosemirror/textBoxAnchorAttrs.d.ts +9 -0
- package/dist/prosemirror/textBoxAnchorAttrs.js +33 -0
- package/dist/prosemirror/utils/extractTrackedChanges.d.ts +1 -1
- package/dist/prosemirror/utils/extractTrackedChanges.js +62 -14
- package/dist/prosemirror/validation.js +9 -1
- package/dist/render-dom/RemoteSelectionOverlay.js +2 -2
- package/dist/server.d.ts +7 -3
- package/dist/server.js +7 -3
- package/dist/utils/clipboard.d.ts +10 -1
- package/dist/utils/clipboard.js +33 -6
- package/dist/utils/colorResolver.d.ts +8 -1
- package/dist/utils/colorResolver.js +35 -5
- package/dist/utils/fontFamilyMerge.js +9 -11
- package/dist/utils/fontLoader.js +3 -2
- package/dist/utils/fontResolver.d.ts +2 -1
- package/dist/utils/fontResolver.js +31 -7
- package/dist/utils/fontWeights.d.ts +1 -1
- package/dist/utils/fontWeights.js +1 -1
- package/dist/utils/hexId.d.ts +11 -1
- package/dist/utils/hexId.js +11 -1
- package/dist/utils/paragraphFormattingMerge.js +1 -0
- package/dist/utils/sanitizeImageSrc.d.ts +21 -0
- package/dist/utils/sanitizeImageSrc.js +30 -0
- package/dist/utils/stripXmlDeclarations.d.ts +11 -0
- package/dist/utils/stripXmlDeclarations.js +35 -0
- package/dist/version-comparison.d.ts +22 -2
- package/dist/version-comparison.js +41 -12
- package/dist/watermark/index.d.ts +11 -1
- package/dist/watermark/index.js +22 -1
- package/package.json +3 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { formatDate } from "../../docx/fieldParser.js";
|
|
2
1
|
import { expectBlockSdtAttrs } from "../attrs/index.js";
|
|
3
2
|
import { ContentControlBoundError, ContentControlLockedError, ContentControlTypeError } from "../../content-controls/errors.js";
|
|
3
|
+
import { formatDate } from "../../docx/fieldParser.js";
|
|
4
4
|
import { SUGGESTION_BYPASS_META } from "../plugins/suggestionMode.js";
|
|
5
5
|
//#region src/prosemirror/commands/contentControls.ts
|
|
6
6
|
function nodeMatchesFilter(node, pos, filter) {
|
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
import { expectHyperlinkMarkAttrs } from "../attrs/index.js";
|
|
2
|
+
import { normalizeUserUrl } from "../../utils/urlSecurity.js";
|
|
2
3
|
//#region src/prosemirror/commands/hyperlink.ts
|
|
3
4
|
const hyperlinkHref = (mark) => expectHyperlinkMarkAttrs(mark).href;
|
|
4
5
|
/**
|
|
6
|
+
* Normalize/sanitize a URL typed by a user (hyperlink popup edit) before it
|
|
7
|
+
* is written into a mark. Internal bookmark anchors (`#name`) bypass
|
|
8
|
+
* `normalizeUserUrl` (which parses via the `URL` constructor and would
|
|
9
|
+
* reject a bare fragment); protocol-less input (e.g. "example.com") is
|
|
10
|
+
* accepted and normalized to https; anything resolving to a disallowed
|
|
11
|
+
* scheme (javascript:, data:, file:, ...) is dropped to an empty href.
|
|
12
|
+
*/
|
|
13
|
+
const normalizeHyperlinkInput = (rawHref) => {
|
|
14
|
+
const trimmed = rawHref.trim();
|
|
15
|
+
if (trimmed.startsWith("#")) return trimmed;
|
|
16
|
+
return normalizeUserUrl(trimmed);
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
5
19
|
* Contiguous ranges of text nodes in `parent` (starting at `parentStart`) that
|
|
6
20
|
* carry a hyperlink mark with the given `href`.
|
|
7
21
|
*/
|
|
@@ -44,7 +58,7 @@ const editHyperlinkAtCursor = (view, { displayText, href }) => {
|
|
|
44
58
|
if (!targetRange) return false;
|
|
45
59
|
const { tooltip } = expectHyperlinkMarkAttrs(linkMark);
|
|
46
60
|
const newMark = hlType.create({
|
|
47
|
-
href,
|
|
61
|
+
href: normalizeHyperlinkInput(href),
|
|
48
62
|
tooltip
|
|
49
63
|
});
|
|
50
64
|
const textNode = view.state.schema.text(displayText, [...$from.marks().filter((m) => m.type !== hlType), newMark]);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IMAGE_HORIZONTAL_ALIGNMENT_VALUES, IMAGE_HORIZONTAL_RELATIVE_TO_VALUES, IMAGE_VERTICAL_ALIGNMENT_VALUES, IMAGE_VERTICAL_RELATIVE_TO_VALUES } from "../../types/documentEnumValues.js";
|
|
2
2
|
import { expectImageAttrs, mergeImageAttrs } from "../attrs/index.js";
|
|
3
|
+
import { sanitizeImageSrc } from "../../utils/sanitizeImageSrc.js";
|
|
3
4
|
import { isSafeImageFile } from "../../utils/imageValidation.js";
|
|
4
5
|
//#region src/prosemirror/commands/image.ts
|
|
5
6
|
/** Map a toolbar wrap selection to the image's wrapType/displayMode/cssFloat, or null when unknown. */
|
|
@@ -203,6 +204,11 @@ function readFileAsDataUrl(file) {
|
|
|
203
204
|
}
|
|
204
205
|
function loadImageDimensions(src) {
|
|
205
206
|
return new Promise((resolve, reject) => {
|
|
207
|
+
const safeSrc = sanitizeImageSrc(src);
|
|
208
|
+
if (!safeSrc) {
|
|
209
|
+
reject(/* @__PURE__ */ new Error("Rejected unsafe image source"));
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
206
212
|
const img = new Image();
|
|
207
213
|
img.addEventListener("load", () => {
|
|
208
214
|
resolve({
|
|
@@ -213,7 +219,7 @@ function loadImageDimensions(src) {
|
|
|
213
219
|
img.addEventListener("error", () => {
|
|
214
220
|
reject(/* @__PURE__ */ new Error("Failed to load image"));
|
|
215
221
|
});
|
|
216
|
-
img.src =
|
|
222
|
+
img.src = safeSrc;
|
|
217
223
|
});
|
|
218
224
|
}
|
|
219
225
|
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { acceptAIEditRevision, acceptAllChanges, acceptChange, addCommentMark, findAIEditRevisionRange, findNextChange, findPreviousChange, rejectAIEditRevision, rejectAllChanges, rejectChange, removeCommentMark } from "./comments.js";
|
|
1
|
+
import { AcceptSuggestionOptions, FolioSuggestion, SuggestionAppliedAs, SuggestionKind, acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addCommentMark, findAIEditRevisionRange, findNextChange, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark } from "./comments.js";
|
|
2
2
|
import { PAINTABLE_MARK_NAMES, applyFormatMarks, captureFormatMarks } from "./formatPainter.js";
|
|
3
3
|
import { clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive } from "../extensions/marks/markUtils.js";
|
|
4
4
|
import { getHyperlinkAttrs, getSelectedText, isHyperlinkActive } from "../extensions/marks/HyperlinkExtension.js";
|
|
@@ -10,4 +10,4 @@ import { BorderPreset, TableBorderPreset, TableContextInfo, getTableContext, isI
|
|
|
10
10
|
import { addColumnLeft, addColumnRight, addRowAbove, addRowBelow, applyTableStyle, autoFitContents, deleteColumn, deleteRow, deleteTable, distributeColumns, insertTable, mergeCells, removeTableBorders, selectColumn, selectRow, selectTable, setAllTableBorders, setCellBorder, setCellFillColor, setCellMargins, setCellTextDirection, setCellVerticalAlign, setInsideTableBorders, setOutsideTableBorders, setRowHeight, setTableBorderColor, setTableBorderPreset, setTableBorderWidth, setTableBorders, setTableProperties, splitCell, toggleHeaderRow, toggleNoWrap } from "./table.js";
|
|
11
11
|
import { insertPageBreak } from "./pageBreak.js";
|
|
12
12
|
import { CLIPBOARD_READ_ERROR_EVENT, buildPlainTextSlice, pasteWithoutFormatting } from "./pastePlainText.js";
|
|
13
|
-
export { type BorderPreset, CLIPBOARD_READ_ERROR_EVENT, PAINTABLE_MARK_NAMES, type ResolvedStyleAttrs, type TableBorderPreset, type TableContextInfo, acceptAIEditRevision, acceptAllChanges, acceptChange, addColumnLeft, addColumnRight, addCommentMark, addRowAbove, addRowBelow, addTabStop, alignCenter, alignJustify, alignLeft, alignRight, applyFormatMarks, applyStyle, applyTableStyle, autoFitContents, buildPlainTextSlice, captureFormatMarks, clearFontFamily, clearFontSize, clearFormatting, clearHighlight, clearStyle, clearTextColor, createRemoveMarkCommand, createSetMarkCommand, decreaseIndent, decreaseListLevel, deleteColumn, deleteRow, deleteTable, distributeColumns, doubleSpacing, findAIEditRevisionRange, findNextChange, findPreviousChange, generateTOC, getHyperlinkAttrs, getListInfo, getMarkAttr, getParagraphAlignment, getParagraphBidi, getSelectedText, getStyleId, getTableContext, increaseIndent, increaseListLevel, insertHyperlink, insertPageBreak, insertTable, isHyperlinkActive, isInList, isInTableCell as isInTable, isMarkActive, mergeCells, oneAndHalfSpacing, pasteWithoutFormatting, rejectAIEditRevision, rejectAllChanges, rejectChange, removeCommentMark, removeHyperlink, removeList, removeTabStop, removeTableBorders, selectColumn, selectRow, selectTable, setAlignment, setAllTableBorders, setCellBorder, setCellFillColor, setCellMargins, setCellTextDirection, setCellVerticalAlign, setFontFamily, setFontSize, setHighlight, setHyperlink, setIndentFirstLine, setIndentLeft, setIndentRight, setInsideTableBorders, setLineSpacing, setLtr, setOutsideTableBorders, setRowHeight, setRtl, setSpaceAfter, setSpaceBefore, setTableBorderColor, setTableBorderPreset, setTableBorderWidth, setTableBorders, setTableProperties, setTextColor, setUnderlineStyle, singleSpacing, splitCell, toggleBidi, toggleBold, toggleBulletList, toggleHeaderRow, toggleItalic, toggleNoWrap, toggleNumberedList, toggleStrike, toggleSubscript, toggleSuperscript, toggleUnderline };
|
|
13
|
+
export { type AcceptSuggestionOptions, type BorderPreset, CLIPBOARD_READ_ERROR_EVENT, type FolioSuggestion, PAINTABLE_MARK_NAMES, type ResolvedStyleAttrs, type SuggestionAppliedAs, type SuggestionKind, type TableBorderPreset, type TableContextInfo, acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addColumnLeft, addColumnRight, addCommentMark, addRowAbove, addRowBelow, addTabStop, alignCenter, alignJustify, alignLeft, alignRight, applyFormatMarks, applyStyle, applyTableStyle, autoFitContents, buildPlainTextSlice, captureFormatMarks, clearFontFamily, clearFontSize, clearFormatting, clearHighlight, clearStyle, clearTextColor, createRemoveMarkCommand, createSetMarkCommand, decreaseIndent, decreaseListLevel, deleteColumn, deleteRow, deleteTable, distributeColumns, doubleSpacing, findAIEditRevisionRange, findNextChange, findPreviousChange, findSuggestionRange, generateTOC, getHyperlinkAttrs, getListInfo, getMarkAttr, getParagraphAlignment, getParagraphBidi, getSelectedText, getStyleId, getSuggestions, getTableContext, increaseIndent, increaseListLevel, insertHyperlink, insertPageBreak, insertTable, isHyperlinkActive, isInList, isInTableCell as isInTable, isMarkActive, mergeCells, oneAndHalfSpacing, pasteWithoutFormatting, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark, removeHyperlink, removeList, removeTabStop, removeTableBorders, selectColumn, selectRow, selectTable, setAlignment, setAllTableBorders, setCellBorder, setCellFillColor, setCellMargins, setCellTextDirection, setCellVerticalAlign, setFontFamily, setFontSize, setHighlight, setHyperlink, setIndentFirstLine, setIndentLeft, setIndentRight, setInsideTableBorders, setLineSpacing, setLtr, setOutsideTableBorders, setRowHeight, setRtl, setSpaceAfter, setSpaceBefore, setTableBorderColor, setTableBorderPreset, setTableBorderWidth, setTableBorders, setTableProperties, setTextColor, setUnderlineStyle, singleSpacing, splitCell, toggleBidi, toggleBold, toggleBulletList, toggleHeaderRow, toggleItalic, toggleNoWrap, toggleNumberedList, toggleStrike, toggleSubscript, toggleSuperscript, toggleUnderline };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { acceptAIEditRevision, acceptAllChanges, acceptChange, addCommentMark, findAIEditRevisionRange, findNextChange, findPreviousChange, rejectAIEditRevision, rejectAllChanges, rejectChange, removeCommentMark } from "./comments.js";
|
|
2
1
|
import { getParagraphAlignment, getParagraphBidi, getStyleId } from "../extensions/core/ParagraphExtension.js";
|
|
3
2
|
import { clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive } from "../extensions/marks/markUtils.js";
|
|
4
3
|
import { getTableContext, isInTable as isInTableCell } from "../extensions/nodes/TableExtension.js";
|
|
5
4
|
import { getListInfo, isInList } from "../extensions/features/ListExtension.js";
|
|
6
5
|
import { CLIPBOARD_READ_ERROR_EVENT, buildPlainTextSlice, pasteWithoutFormatting } from "./pastePlainText.js";
|
|
7
6
|
import { getHyperlinkAttrs, getSelectedText, isHyperlinkActive } from "../extensions/marks/HyperlinkExtension.js";
|
|
7
|
+
import { acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addCommentMark, findAIEditRevisionRange, findNextChange, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark } from "./comments.js";
|
|
8
8
|
import { addColumnLeft, addColumnRight, addRowAbove, addRowBelow, applyTableStyle, autoFitContents, deleteColumn, deleteRow, deleteTable, distributeColumns, insertTable, mergeCells, removeTableBorders, selectColumn, selectRow, selectTable, setAllTableBorders, setCellBorder, setCellFillColor, setCellMargins, setCellTextDirection, setCellVerticalAlign, setInsideTableBorders, setOutsideTableBorders, setRowHeight, setTableBorderColor, setTableBorderPreset, setTableBorderWidth, setTableBorders, setTableProperties, splitCell, toggleHeaderRow, toggleNoWrap } from "./table.js";
|
|
9
9
|
import { clearFontFamily, clearFontSize, clearHighlight, clearTextColor, insertHyperlink, removeHyperlink, setFontFamily, setFontSize, setHighlight, setHyperlink, setTextColor, setUnderlineStyle, toggleBold, toggleItalic, toggleStrike, toggleSubscript, toggleSuperscript, toggleUnderline } from "./formatting.js";
|
|
10
10
|
import { addTabStop, alignCenter, alignJustify, alignLeft, alignRight, applyStyle, clearStyle, decreaseIndent, decreaseListLevel, doubleSpacing, generateTOC, increaseIndent, increaseListLevel, oneAndHalfSpacing, removeList, removeTabStop, setAlignment, setIndentFirstLine, setIndentLeft, setIndentRight, setLineSpacing, setLtr, setRtl, setSpaceAfter, setSpaceBefore, singleSpacing, toggleBidi, toggleBulletList, toggleNumberedList } from "./paragraph.js";
|
|
11
11
|
import { PAINTABLE_MARK_NAMES, applyFormatMarks, captureFormatMarks } from "./formatPainter.js";
|
|
12
12
|
import { insertPageBreak } from "./pageBreak.js";
|
|
13
|
-
export { CLIPBOARD_READ_ERROR_EVENT, PAINTABLE_MARK_NAMES, acceptAIEditRevision, acceptAllChanges, acceptChange, addColumnLeft, addColumnRight, addCommentMark, addRowAbove, addRowBelow, addTabStop, alignCenter, alignJustify, alignLeft, alignRight, applyFormatMarks, applyStyle, applyTableStyle, autoFitContents, buildPlainTextSlice, captureFormatMarks, clearFontFamily, clearFontSize, clearFormatting, clearHighlight, clearStyle, clearTextColor, createRemoveMarkCommand, createSetMarkCommand, decreaseIndent, decreaseListLevel, deleteColumn, deleteRow, deleteTable, distributeColumns, doubleSpacing, findAIEditRevisionRange, findNextChange, findPreviousChange, generateTOC, getHyperlinkAttrs, getListInfo, getMarkAttr, getParagraphAlignment, getParagraphBidi, getSelectedText, getStyleId, getTableContext, increaseIndent, increaseListLevel, insertHyperlink, insertPageBreak, insertTable, isHyperlinkActive, isInList, isInTableCell as isInTable, isMarkActive, mergeCells, oneAndHalfSpacing, pasteWithoutFormatting, rejectAIEditRevision, rejectAllChanges, rejectChange, removeCommentMark, removeHyperlink, removeList, removeTabStop, removeTableBorders, selectColumn, selectRow, selectTable, setAlignment, setAllTableBorders, setCellBorder, setCellFillColor, setCellMargins, setCellTextDirection, setCellVerticalAlign, setFontFamily, setFontSize, setHighlight, setHyperlink, setIndentFirstLine, setIndentLeft, setIndentRight, setInsideTableBorders, setLineSpacing, setLtr, setOutsideTableBorders, setRowHeight, setRtl, setSpaceAfter, setSpaceBefore, setTableBorderColor, setTableBorderPreset, setTableBorderWidth, setTableBorders, setTableProperties, setTextColor, setUnderlineStyle, singleSpacing, splitCell, toggleBidi, toggleBold, toggleBulletList, toggleHeaderRow, toggleItalic, toggleNoWrap, toggleNumberedList, toggleStrike, toggleSubscript, toggleSuperscript, toggleUnderline };
|
|
13
|
+
export { CLIPBOARD_READ_ERROR_EVENT, PAINTABLE_MARK_NAMES, acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addColumnLeft, addColumnRight, addCommentMark, addRowAbove, addRowBelow, addTabStop, alignCenter, alignJustify, alignLeft, alignRight, applyFormatMarks, applyStyle, applyTableStyle, autoFitContents, buildPlainTextSlice, captureFormatMarks, clearFontFamily, clearFontSize, clearFormatting, clearHighlight, clearStyle, clearTextColor, createRemoveMarkCommand, createSetMarkCommand, decreaseIndent, decreaseListLevel, deleteColumn, deleteRow, deleteTable, distributeColumns, doubleSpacing, findAIEditRevisionRange, findNextChange, findPreviousChange, findSuggestionRange, generateTOC, getHyperlinkAttrs, getListInfo, getMarkAttr, getParagraphAlignment, getParagraphBidi, getSelectedText, getStyleId, getSuggestions, getTableContext, increaseIndent, increaseListLevel, insertHyperlink, insertPageBreak, insertTable, isHyperlinkActive, isInList, isInTableCell as isInTable, isMarkActive, mergeCells, oneAndHalfSpacing, pasteWithoutFormatting, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark, removeHyperlink, removeList, removeTabStop, removeTableBorders, selectColumn, selectRow, selectTable, setAlignment, setAllTableBorders, setCellBorder, setCellFillColor, setCellMargins, setCellTextDirection, setCellVerticalAlign, setFontFamily, setFontSize, setHighlight, setHyperlink, setIndentFirstLine, setIndentLeft, setIndentRight, setInsideTableBorders, setLineSpacing, setLtr, setOutsideTableBorders, setRowHeight, setRtl, setSpaceAfter, setSpaceBefore, setTableBorderColor, setTableBorderPreset, setTableBorderWidth, setTableBorders, setTableProperties, setTextColor, setUnderlineStyle, singleSpacing, splitCell, toggleBidi, toggleBold, toggleBulletList, toggleHeaderRow, toggleItalic, toggleNoWrap, toggleNumberedList, toggleStrike, toggleSubscript, toggleSuperscript, toggleUnderline };
|
|
@@ -18,9 +18,9 @@ type AttrPatch = Record<string, unknown>;
|
|
|
18
18
|
* `runInWithNext` (`w:specVanish` lives in that rPr)
|
|
19
19
|
* - load-time style/numbering bookkeeping the command layer cannot recompute
|
|
20
20
|
* without a style resolver: `numPrFromStyle`, the `list*` rendering attrs,
|
|
21
|
-
* `spacingFromDocDefaults`
|
|
21
|
+
* `spacingFromDocDefaults`, `spacingFromImplicitDefaultStyle`
|
|
22
22
|
*/
|
|
23
|
-
declare const PPR_CHANGE_SCOPED_ATTR_KEYS: readonly ["styleId", "numPr", "alignment", "spaceBefore", "spaceAfter", "lineSpacing", "lineSpacingRule", "spacingExplicit", "indentLeft", "indentRight", "indentFirstLine", "hangingIndent", "borders", "shading", "tabs", "pageBreakBefore", "keepNext", "keepLines", "widowControl", "contextualSpacing", "outlineLevel", "direction", "_autospacingBase"];
|
|
23
|
+
declare const PPR_CHANGE_SCOPED_ATTR_KEYS: readonly ["styleId", "numPr", "alignment", "spaceBefore", "spaceAfter", "lineSpacing", "lineSpacingRule", "snapToGrid", "spacingExplicit", "indentLeft", "indentRight", "indentFirstLine", "hangingIndent", "borders", "shading", "tabs", "pageBreakBefore", "keepNext", "keepLines", "widowControl", "contextualSpacing", "outlineLevel", "direction", "_autospacingBase"];
|
|
24
24
|
/**
|
|
25
25
|
* Build the attr patch that rejecting one pPrChange applies to a paragraph:
|
|
26
26
|
* every in-scope key set to the stored previous value, or reset to `null`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { setAutospacingBaseValue } from "../autospacingBase.js";
|
|
2
1
|
import { directionFromBidi } from "../paragraphDirection.js";
|
|
2
|
+
import { setAutospacingBaseValue } from "../autospacingBase.js";
|
|
3
3
|
//#region src/prosemirror/commands/propertyChangeScope.ts
|
|
4
4
|
/**
|
|
5
5
|
* Paragraph attrs governed by a `w:pPrChange` — the attrs
|
|
@@ -17,7 +17,7 @@ import { directionFromBidi } from "../paragraphDirection.js";
|
|
|
17
17
|
* `runInWithNext` (`w:specVanish` lives in that rPr)
|
|
18
18
|
* - load-time style/numbering bookkeeping the command layer cannot recompute
|
|
19
19
|
* without a style resolver: `numPrFromStyle`, the `list*` rendering attrs,
|
|
20
|
-
* `spacingFromDocDefaults`
|
|
20
|
+
* `spacingFromDocDefaults`, `spacingFromImplicitDefaultStyle`
|
|
21
21
|
*/
|
|
22
22
|
const PPR_CHANGE_SCOPED_ATTR_KEYS = [
|
|
23
23
|
"styleId",
|
|
@@ -27,6 +27,7 @@ const PPR_CHANGE_SCOPED_ATTR_KEYS = [
|
|
|
27
27
|
"spaceAfter",
|
|
28
28
|
"lineSpacing",
|
|
29
29
|
"lineSpacingRule",
|
|
30
|
+
"snapToGrid",
|
|
30
31
|
"spacingExplicit",
|
|
31
32
|
"indentLeft",
|
|
32
33
|
"indentRight",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Transaction } from "prosemirror-state";
|
|
2
|
+
import { Node } from "prosemirror-model";
|
|
3
|
+
|
|
4
|
+
//#region src/prosemirror/commands/tableCellMergeResolution.d.ts
|
|
5
|
+
declare const hasMatchingCollapsedTableCellMerge: (node: Node, revisionSet: Set<number> | null) => boolean;
|
|
6
|
+
declare const resolveVisibleTableCellMerge: (tr: Transaction, cellPos: number, mode: "accept" | "reject") => boolean;
|
|
7
|
+
declare const resolveCollapsedTableCellMerge: (tr: Transaction, cellPos: number, mode: "accept" | "reject", revisionSet: Set<number> | null) => boolean;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { hasMatchingCollapsedTableCellMerge, resolveCollapsedTableCellMerge, resolveVisibleTableCellMerge };
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { standaloneTableCellToProseMirror } from "../conversion/toProseDoc.js";
|
|
2
|
+
import { standaloneTableCellFromProseMirror } from "../conversion/fromProseDoc.js";
|
|
3
|
+
import { getTableCellMergeChange } from "../tableCellMergeRevision.js";
|
|
4
|
+
import { Result } from "better-result";
|
|
5
|
+
import { TableMap } from "prosemirror-tables";
|
|
6
|
+
//#region src/prosemirror/commands/tableCellMergeResolution.ts
|
|
7
|
+
const hasMatchingCollapsedTableCellMerge = (node, revisionSet) => {
|
|
8
|
+
const continuationCells = node.attrs["_docxVMergeContinuationCells"];
|
|
9
|
+
if (!Array.isArray(continuationCells)) return false;
|
|
10
|
+
return continuationCells.some((cell) => {
|
|
11
|
+
const change = getTableCellMergeChange(cell);
|
|
12
|
+
return change !== null && (revisionSet === null || revisionSet.has(change.info.id));
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
const isTableCellMergeRevisionAttr = (value) => {
|
|
16
|
+
if (typeof value !== "object" || value === null || !("kind" in value) || value.kind !== "merge" || !("info" in value)) return false;
|
|
17
|
+
const info = value.info;
|
|
18
|
+
return typeof info === "object" && info !== null && "revisionId" in info && typeof info.revisionId === "number";
|
|
19
|
+
};
|
|
20
|
+
const tableCellContext = (doc, cellPos) => {
|
|
21
|
+
const resolved = doc.resolve(cellPos);
|
|
22
|
+
for (let depth = resolved.depth; depth > 0; depth -= 1) {
|
|
23
|
+
const node = resolved.node(depth);
|
|
24
|
+
if (node.type.spec["tableRole"] !== "table") continue;
|
|
25
|
+
const tablePos = resolved.before(depth);
|
|
26
|
+
return {
|
|
27
|
+
table: node,
|
|
28
|
+
tableStart: tablePos + 1,
|
|
29
|
+
relativeCellPos: cellPos - tablePos - 1
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
};
|
|
34
|
+
const resolveVisibleTableCellMerge = (tr, cellPos, mode) => {
|
|
35
|
+
const cell = tr.doc.nodeAt(cellPos);
|
|
36
|
+
const marker = cell?.attrs["cellMarker"];
|
|
37
|
+
if (!cell || !isTableCellMergeRevisionAttr(marker)) return false;
|
|
38
|
+
if (mode === "accept") {
|
|
39
|
+
tr.setNodeAttribute(cellPos, "cellMarker", null);
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
if ((marker.verticalMergeOriginal ?? "rest") === "continue") return mergeTableCellWithCellAbove(tr, cellPos);
|
|
43
|
+
const originalFormatting = cell.attrs["_originalFormatting"];
|
|
44
|
+
let nextOriginalFormatting = originalFormatting;
|
|
45
|
+
if (typeof originalFormatting === "object" && originalFormatting !== null) {
|
|
46
|
+
nextOriginalFormatting = { ...originalFormatting };
|
|
47
|
+
delete nextOriginalFormatting.vMerge;
|
|
48
|
+
}
|
|
49
|
+
tr.setNodeMarkup(cellPos, void 0, {
|
|
50
|
+
...cell.attrs,
|
|
51
|
+
cellMarker: null,
|
|
52
|
+
_originalFormatting: nextOriginalFormatting
|
|
53
|
+
});
|
|
54
|
+
return true;
|
|
55
|
+
};
|
|
56
|
+
const mergeTableCellWithCellAbove = (tr, cellPos) => {
|
|
57
|
+
const context = tableCellContext(tr.doc, cellPos);
|
|
58
|
+
const cell = tr.doc.nodeAt(cellPos);
|
|
59
|
+
if (!context || !cell) return false;
|
|
60
|
+
const map = TableMap.get(context.table);
|
|
61
|
+
const rectangle = map.findCell(context.relativeCellPos);
|
|
62
|
+
if (rectangle.top === 0) return false;
|
|
63
|
+
const aboveRelativePos = map.map[(rectangle.top - 1) * map.width + rectangle.left];
|
|
64
|
+
if (aboveRelativePos === void 0 || aboveRelativePos === context.relativeCellPos) return false;
|
|
65
|
+
const aboveRectangle = map.findCell(aboveRelativePos);
|
|
66
|
+
if (aboveRectangle.left !== rectangle.left || aboveRectangle.right !== rectangle.right || aboveRectangle.bottom !== rectangle.top) return false;
|
|
67
|
+
const abovePos = context.tableStart + aboveRelativePos;
|
|
68
|
+
const aboveCell = tr.doc.nodeAt(abovePos);
|
|
69
|
+
const aboveRowspan = aboveCell?.attrs["rowspan"];
|
|
70
|
+
const cellRowspan = cell.attrs["rowspan"];
|
|
71
|
+
if (!aboveCell || typeof aboveRowspan !== "number" || typeof cellRowspan !== "number" || aboveRowspan < 1 || cellRowspan < 1) return false;
|
|
72
|
+
const continuationCells = tableCellContinuationCells(aboveCell, aboveRowspan);
|
|
73
|
+
continuationCells.push(tableCellContinuationFromNode(cell));
|
|
74
|
+
const nestedContinuations = cell.attrs["_docxVMergeContinuationCells"];
|
|
75
|
+
if (Array.isArray(nestedContinuations)) continuationCells.push(...nestedContinuations);
|
|
76
|
+
tr.delete(cellPos, cellPos + cell.nodeSize);
|
|
77
|
+
tr.setNodeMarkup(abovePos, void 0, {
|
|
78
|
+
...aboveCell.attrs,
|
|
79
|
+
rowspan: aboveRowspan + cellRowspan,
|
|
80
|
+
_docxVMergeContinuationCells: continuationCells
|
|
81
|
+
});
|
|
82
|
+
return true;
|
|
83
|
+
};
|
|
84
|
+
const tableCellContinuationCells = (cell, rowspan) => {
|
|
85
|
+
const stored = cell.attrs["_docxVMergeContinuationCells"];
|
|
86
|
+
const cells = Array.isArray(stored) ? [...stored] : [];
|
|
87
|
+
while (cells.length < rowspan - 1) cells.push(emptyVerticalMergeContinuation());
|
|
88
|
+
return cells;
|
|
89
|
+
};
|
|
90
|
+
const tableCellContinuationFromNode = (cell) => {
|
|
91
|
+
const continuation = standaloneTableCellFromProseMirror(cell);
|
|
92
|
+
const formatting = {
|
|
93
|
+
...continuation.formatting,
|
|
94
|
+
vMerge: "continue"
|
|
95
|
+
};
|
|
96
|
+
const colspan = cell.attrs["colspan"];
|
|
97
|
+
if (typeof colspan === "number" && colspan > 1) formatting.gridSpan = colspan;
|
|
98
|
+
continuation.formatting = formatting;
|
|
99
|
+
delete continuation.structuralChange;
|
|
100
|
+
return continuation;
|
|
101
|
+
};
|
|
102
|
+
const emptyVerticalMergeContinuation = () => ({
|
|
103
|
+
type: "tableCell",
|
|
104
|
+
formatting: { vMerge: "continue" },
|
|
105
|
+
content: [{
|
|
106
|
+
type: "paragraph",
|
|
107
|
+
content: []
|
|
108
|
+
}]
|
|
109
|
+
});
|
|
110
|
+
const resolveCollapsedTableCellMerge = (tr, cellPos, mode, revisionSet) => {
|
|
111
|
+
const cell = tr.doc.nodeAt(cellPos);
|
|
112
|
+
const stored = cell?.attrs["_docxVMergeContinuationCells"];
|
|
113
|
+
if (!cell || !Array.isArray(stored)) return false;
|
|
114
|
+
const matchingIndices = [];
|
|
115
|
+
const nextCells = stored.map((continuationCell, index) => {
|
|
116
|
+
const change = getTableCellMergeChange(continuationCell);
|
|
117
|
+
if (!change || revisionSet !== null && !revisionSet.has(change.info.id)) return continuationCell;
|
|
118
|
+
matchingIndices.push(index);
|
|
119
|
+
const nextCell = { ...continuationCell };
|
|
120
|
+
delete nextCell.structuralChange;
|
|
121
|
+
return nextCell;
|
|
122
|
+
});
|
|
123
|
+
if (matchingIndices.length === 0) return false;
|
|
124
|
+
if (mode === "accept") {
|
|
125
|
+
tr.setNodeAttribute(cellPos, "_docxVMergeContinuationCells", nextCells);
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
const splitIndices = matchingIndices.filter((index) => {
|
|
129
|
+
const change = getTableCellMergeChange(stored[index]);
|
|
130
|
+
return change?.verticalMerge === "continue" && (change.verticalMergeOriginal ?? "rest") === "rest";
|
|
131
|
+
});
|
|
132
|
+
if (splitIndices.length === 0) {
|
|
133
|
+
tr.setNodeAttribute(cellPos, "_docxVMergeContinuationCells", nextCells);
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
const firstSplitIndex = splitIndices.at(0);
|
|
137
|
+
if (firstSplitIndex === void 0 || splitIndices.length !== stored.length - firstSplitIndex || splitIndices.some((index, offset) => index !== firstSplitIndex + offset)) return false;
|
|
138
|
+
const context = tableCellContext(tr.doc, cellPos);
|
|
139
|
+
if (!context) return false;
|
|
140
|
+
const map = TableMap.get(context.table);
|
|
141
|
+
const rectangle = map.findCell(context.relativeCellPos);
|
|
142
|
+
const rowspan = cell.attrs["rowspan"];
|
|
143
|
+
if (typeof rowspan !== "number" || rowspan !== stored.length + 1 || rectangle.bottom - rectangle.top !== rowspan) return false;
|
|
144
|
+
const restorations = [];
|
|
145
|
+
for (const index of splitIndices) {
|
|
146
|
+
const source = nextCells[index];
|
|
147
|
+
if (!source) return false;
|
|
148
|
+
const restoredCell = createRestoredTableCell(cell, source);
|
|
149
|
+
if (!restoredCell) return false;
|
|
150
|
+
restorations.push({
|
|
151
|
+
index,
|
|
152
|
+
cell: restoredCell
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
const mapFrom = tr.mapping.maps.length;
|
|
156
|
+
for (const restoration of restorations) {
|
|
157
|
+
const row = rectangle.top + restoration.index + 1;
|
|
158
|
+
const insertionPos = context.tableStart + map.positionAt(row, rectangle.left, context.table);
|
|
159
|
+
tr.insert(tr.mapping.slice(mapFrom).map(insertionPos, 1), restoration.cell);
|
|
160
|
+
}
|
|
161
|
+
const remainingCells = nextCells.slice(0, firstSplitIndex);
|
|
162
|
+
tr.setNodeMarkup(cellPos, void 0, {
|
|
163
|
+
...cell.attrs,
|
|
164
|
+
rowspan: firstSplitIndex + 1,
|
|
165
|
+
_docxVMergeContinuationCells: remainingCells.length > 0 ? remainingCells : null
|
|
166
|
+
});
|
|
167
|
+
return true;
|
|
168
|
+
};
|
|
169
|
+
const createRestoredTableCell = (origin, source) => {
|
|
170
|
+
const formatting = source.formatting ? { ...source.formatting } : void 0;
|
|
171
|
+
if (formatting) delete formatting.vMerge;
|
|
172
|
+
const restored = standaloneTableCellToProseMirror({
|
|
173
|
+
type: "tableCell",
|
|
174
|
+
...formatting ? { formatting } : {},
|
|
175
|
+
...source.propertyChanges ? { propertyChanges: source.propertyChanges } : {},
|
|
176
|
+
content: source.content
|
|
177
|
+
}, origin.type.name === "tableHeader" ? "tableHeader" : "tableCell");
|
|
178
|
+
return Result.try(() => origin.type.schema.nodeFromJSON(restored.toJSON())).unwrapOr(null);
|
|
179
|
+
};
|
|
180
|
+
//#endregion
|
|
181
|
+
export { hasMatchingCollapsedTableCellMerge, resolveCollapsedTableCellMerge, resolveVisibleTableCellMerge };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { seedRevisionIdsAbove } from "./plugins/revisionIds.js";
|
|
2
|
+
import { MAX_REVISION_ID } from "@stll/docx-core/model";
|
|
1
3
|
//#region src/prosemirror/commentIdAllocator.ts
|
|
2
4
|
/** Sentinel ID for a comment that hasn't been persisted yet (anchored to selection). */
|
|
3
5
|
const PENDING_COMMENT_ID = -1;
|
|
@@ -9,8 +11,12 @@ const PENDING_COMMENT_ID = -1;
|
|
|
9
11
|
function createCommentIdAllocator() {
|
|
10
12
|
let nextId = 1;
|
|
11
13
|
return {
|
|
12
|
-
next: () =>
|
|
14
|
+
next: () => {
|
|
15
|
+
if (nextId > MAX_REVISION_ID) nextId = 1;
|
|
16
|
+
return nextId++;
|
|
17
|
+
},
|
|
13
18
|
seedAbove(maxId) {
|
|
19
|
+
if (!Number.isInteger(maxId) || maxId < 0 || maxId >= MAX_REVISION_ID) return;
|
|
14
20
|
if (maxId >= nextId) nextId = maxId + 1;
|
|
15
21
|
}
|
|
16
22
|
};
|
|
@@ -25,11 +31,15 @@ function createCommentIdAllocator() {
|
|
|
25
31
|
*/
|
|
26
32
|
function seedCommentAllocator(allocator, comments, view) {
|
|
27
33
|
let max = 0;
|
|
28
|
-
for (const comment of comments ?? []) max
|
|
34
|
+
for (const comment of comments ?? []) if (Number.isInteger(comment.id) && comment.id > max && comment.id <= MAX_REVISION_ID) max = comment.id;
|
|
29
35
|
if (view) view.state.doc.descendants((node) => {
|
|
30
|
-
for (const mark of node.marks)
|
|
36
|
+
for (const mark of node.marks) {
|
|
37
|
+
const revisionId = mark.attrs["revisionId"];
|
|
38
|
+
if (typeof revisionId === "number" && Number.isInteger(revisionId) && revisionId > max && revisionId <= MAX_REVISION_ID) max = revisionId;
|
|
39
|
+
}
|
|
31
40
|
});
|
|
32
41
|
allocator.seedAbove(max);
|
|
42
|
+
seedRevisionIdsAbove(max);
|
|
33
43
|
}
|
|
34
44
|
//#endregion
|
|
35
45
|
export { PENDING_COMMENT_ID, createCommentIdAllocator, seedCommentAllocator };
|
|
@@ -10,6 +10,7 @@ declare function fromProseDoc(pmDoc: Node, baseDocument?: document_d_exports.Doc
|
|
|
10
10
|
* Convert ProseMirror marks to TextFormatting
|
|
11
11
|
*/
|
|
12
12
|
declare function marksToTextFormatting(marks: readonly Mark[]): document_d_exports.TextFormatting;
|
|
13
|
+
declare const standaloneTableCellFromProseMirror: (node: Node) => document_d_exports.TableCell;
|
|
13
14
|
/**
|
|
14
15
|
* Update a Document with content from a ProseMirror document
|
|
15
16
|
* Preserves all non-content parts of the original document
|
|
@@ -24,4 +25,4 @@ declare function updateDocumentContent(originalDocument: document_d_exports.Docu
|
|
|
24
25
|
*/
|
|
25
26
|
declare function proseDocToBlocks(pmDoc: Node): document_d_exports.BlockContent[];
|
|
26
27
|
//#endregion
|
|
27
|
-
export { fromProseDoc, marksToTextFormatting, proseDocToBlocks, updateDocumentContent };
|
|
28
|
+
export { fromProseDoc, marksToTextFormatting, proseDocToBlocks, standaloneTableCellFromProseMirror, updateDocumentContent };
|