@stll/folio-core 0.48.0 → 0.50.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.js +565 -121
- package/dist/ai-edits/headless.d.ts +37 -1
- package/dist/ai-edits/headless.js +47 -16
- package/dist/ai-edits/minimal-replacement.d.ts +64 -0
- package/dist/ai-edits/minimal-replacement.js +282 -0
- package/dist/controller/layoutPipeline.js +11 -1
- package/dist/display-list/build/paragraphPrimitives.js +63 -7
- package/dist/display-list/build/textBoxPrimitives.js +1 -1
- package/dist/display-list/build/unsupported.d.ts +2 -2
- package/dist/display-list/build/unsupported.js +0 -0
- package/dist/display-list/dom/renderDisplayListToDom.d.ts +10 -1
- package/dist/display-list/dom/renderDisplayListToDom.js +8 -8
- package/dist/display-list/html/renderDisplayListToHtml.d.ts +21 -0
- package/dist/display-list/html/renderDisplayListToHtml.js +126 -0
- package/dist/display-list/selectDisplayPages.d.ts +6 -0
- package/dist/display-list/selectDisplayPages.js +44 -0
- package/dist/docx/blockContentParser.js +2 -2
- package/dist/docx/bulletMarkers.d.ts +18 -2
- package/dist/docx/bulletMarkers.js +27 -2
- package/dist/docx/drawingGroupChildren.d.ts +60 -0
- package/dist/docx/drawingGroupChildren.js +176 -0
- package/dist/docx/drawingUtils.js +3 -0
- package/dist/docx/groupDrawingParser.d.ts +7 -1
- package/dist/docx/groupDrawingParser.js +123 -32
- package/dist/docx/packageParts.d.ts +45 -1
- package/dist/docx/packageParts.js +93 -2
- package/dist/docx/paraIdAttribute.d.ts +3 -2
- package/dist/docx/paragraphParser.js +91 -7
- package/dist/docx/paragraphTextBoxEnrichment.js +126 -4
- package/dist/docx/runParser.js +10 -0
- package/dist/docx/selectiveSaveFlags.d.ts +10 -3
- package/dist/docx/selectiveSaveFlags.js +1 -1
- package/dist/docx/selectiveXmlPatch.d.ts +56 -34
- package/dist/docx/selectiveXmlPatch.js +222 -115
- package/dist/docx/serializer/groupTextBoxWriteBack.d.ts +12 -0
- package/dist/docx/serializer/groupTextBoxWriteBack.js +101 -0
- package/dist/docx/serializer/paragraphSerializer.js +5 -4
- package/dist/docx/serializer/runSerializer.d.ts +5 -1
- package/dist/docx/serializer/runSerializer.js +4 -3
- package/dist/docx/shapeAlternateContent.d.ts +25 -0
- package/dist/docx/shapeAlternateContent.js +52 -0
- package/dist/docx/textBoxParser.d.ts +10 -2
- package/dist/docx/textBoxParser.js +9 -3
- package/dist/export-pdf.d.ts +35 -2
- package/dist/export-pdf.js +51 -20
- package/dist/fonts/fontsourceFaces.d.ts +47 -0
- package/dist/fonts/fontsourceFaces.js +230 -0
- package/dist/internal/headlessRevisionResolution.js +50 -13
- package/dist/layout-bridge/convert/flowBlockPostprocessing.d.ts +8 -0
- package/dist/layout-bridge/convert/flowBlockPostprocessing.js +106 -0
- package/dist/layout-bridge/convert/flowBorders.d.ts +17 -0
- package/dist/layout-bridge/convert/flowBorders.js +31 -0
- package/dist/layout-bridge/convert/flowConversionShared.d.ts +111 -0
- package/dist/layout-bridge/convert/flowConversionShared.js +23 -0
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +2 -1
- package/dist/layout-bridge/convert/footnoteLayout.js +2 -1
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +2 -1
- package/dist/layout-bridge/convert/imageConversion.d.ts +33 -0
- package/dist/layout-bridge/convert/imageConversion.js +118 -0
- package/dist/layout-bridge/convert/listMarkers.d.ts +28 -0
- package/dist/layout-bridge/convert/listMarkers.js +98 -0
- package/dist/layout-bridge/convert/noteReferences.d.ts +14 -0
- package/dist/layout-bridge/convert/noteReferences.js +29 -0
- package/dist/layout-bridge/convert/pageBreakSplitting.d.ts +16 -0
- package/dist/layout-bridge/convert/pageBreakSplitting.js +140 -0
- package/dist/layout-bridge/convert/paragraphAttrs.d.ts +20 -0
- package/dist/layout-bridge/convert/paragraphAttrs.js +234 -0
- package/dist/layout-bridge/convert/paragraphConversion.d.ts +12 -0
- package/dist/layout-bridge/convert/paragraphConversion.js +112 -0
- package/dist/layout-bridge/convert/paragraphRuns.d.ts +15 -0
- package/dist/layout-bridge/convert/paragraphRuns.js +281 -0
- package/dist/layout-bridge/convert/runFormattingMerge.d.ts +19 -0
- package/dist/layout-bridge/convert/runFormattingMerge.js +167 -0
- package/dist/layout-bridge/convert/runMarkFormatting.d.ts +11 -0
- package/dist/layout-bridge/convert/runMarkFormatting.js +291 -0
- package/dist/layout-bridge/convert/sectionBoundaries.d.ts +35 -0
- package/dist/layout-bridge/convert/sectionBoundaries.js +114 -0
- package/dist/layout-bridge/convert/tableConversion.d.ts +12 -0
- package/dist/layout-bridge/convert/tableConversion.js +303 -0
- package/dist/layout-bridge/convert/textBoxFill.d.ts +20 -0
- package/dist/layout-bridge/convert/textBoxFill.js +42 -0
- package/dist/layout-bridge/convert/textFormattingConversion.d.ts +22 -0
- package/dist/layout-bridge/convert/textFormattingConversion.js +120 -0
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +5 -113
- package/dist/layout-bridge/convert/toFlowBlocks.js +11 -2060
- package/dist/layout-bridge/engine/hitTest.js +1 -1
- package/dist/layout-bridge/engine/measuring/index.d.ts +2 -1
- package/dist/layout-bridge/engine/measuring/index.js +2 -1
- package/dist/layout-bridge/engine/selectionRects.js +1 -1
- package/dist/layout-engine/imageLayout.d.ts +9 -0
- package/dist/layout-engine/imageLayout.js +48 -0
- package/dist/layout-engine/index.d.ts +4 -19
- package/dist/layout-engine/index.js +14 -910
- package/dist/layout-engine/keep-together.d.ts +5 -2
- package/dist/layout-engine/keep-together.js +5 -1
- package/dist/layout-engine/layoutFlowShared.d.ts +6 -0
- package/dist/layout-engine/layoutFlowShared.js +8 -0
- package/dist/layout-engine/measure/advanceComposition.js +49 -3
- package/dist/layout-engine/measure/crossRunWords.d.ts +45 -0
- package/dist/layout-engine/measure/crossRunWords.js +172 -0
- package/dist/layout-engine/measure/floatingLineClearance.d.ts +24 -0
- package/dist/layout-engine/measure/floatingLineClearance.js +44 -0
- package/dist/layout-engine/measure/inlineObjectMetrics.d.ts +6 -0
- package/dist/layout-engine/measure/inlineObjectMetrics.js +52 -0
- package/dist/layout-engine/measure/justification.d.ts +32 -0
- package/dist/layout-engine/measure/justification.js +83 -0
- package/dist/layout-engine/measure/lineFitting.d.ts +48 -0
- package/dist/layout-engine/measure/lineFitting.js +145 -0
- package/dist/layout-engine/measure/lineTypography.d.ts +44 -0
- package/dist/layout-engine/measure/lineTypography.js +124 -0
- package/dist/layout-engine/measure/measureBlocks.js +7 -4
- package/dist/layout-engine/measure/measureContainer.js +46 -3
- package/dist/layout-engine/measure/measureHelpers.js +13 -3
- package/dist/layout-engine/measure/measureParagraph.d.ts +1 -20
- package/dist/layout-engine/measure/measureParagraph.js +41 -780
- package/dist/layout-engine/measure/paragraphMeasureShared.d.ts +109 -0
- package/dist/layout-engine/measure/paragraphMeasureShared.js +82 -0
- package/dist/layout-engine/measure/paragraphTabs.d.ts +18 -0
- package/dist/layout-engine/measure/paragraphTabs.js +78 -0
- package/dist/layout-engine/measure/smallCapsCasing.d.ts +56 -0
- package/dist/layout-engine/measure/smallCapsCasing.js +88 -0
- package/dist/layout-engine/paginator.d.ts +2 -0
- package/dist/layout-engine/paginator.js +5 -1
- package/dist/layout-engine/paragraphLayout.d.ts +23 -0
- package/dist/layout-engine/paragraphLayout.js +204 -0
- package/dist/layout-engine/paragraphSpacing.d.ts +4 -2
- package/dist/layout-engine/paragraphSpacing.js +2 -1
- package/dist/layout-engine/sectionLayout.d.ts +45 -0
- package/dist/layout-engine/sectionLayout.js +216 -0
- package/dist/layout-engine/tableLayout.d.ts +17 -0
- package/dist/layout-engine/tableLayout.js +369 -0
- package/dist/layout-engine/tableRowBreak.d.ts +8 -1
- package/dist/layout-engine/tableRowBreak.js +22 -1
- package/dist/layout-engine/textBoxLayout.d.ts +15 -0
- package/dist/layout-engine/textBoxLayout.js +137 -0
- package/dist/layout-engine/types.d.ts +21 -2
- package/dist/layout-painter/renderPage.js +1 -0
- package/dist/layout-painter/renderParagraph.js +41 -4
- package/dist/layout-painter/renderTextBox.d.ts +12 -2
- package/dist/layout-painter/renderTextBox.js +26 -2
- package/dist/paged-layout/sectionBlockWidths.d.ts +2 -1
- package/dist/paged-layout/sectionBlockWidths.js +1 -1
- package/dist/prosemirror/alternateContentAttrs.d.ts +9 -0
- package/dist/prosemirror/alternateContentAttrs.js +35 -0
- package/dist/prosemirror/attrs/index.js +90 -0
- package/dist/prosemirror/commands/comments.js +51 -41
- package/dist/prosemirror/contentControlRevisions.d.ts +43 -0
- package/dist/prosemirror/contentControlRevisions.js +84 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +46 -22
- package/dist/prosemirror/conversion/toProseDoc.js +42 -19
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.d.ts +7 -7
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -7
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +6 -3
- package/dist/prosemirror/extensions/nodes/SdtExtension.js +9 -2
- package/dist/prosemirror/extensions/nodes/ShapeExtension.js +1 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +3 -0
- package/dist/prosemirror/listMarker.js +2 -2
- package/dist/prosemirror/paragraphDirection.d.ts +29 -2
- package/dist/prosemirror/paragraphDirection.js +21 -2
- package/dist/prosemirror/plugins/suggestionMode.js +37 -8
- package/dist/prosemirror/rejoinRunCarriers.d.ts +27 -0
- package/dist/prosemirror/rejoinRunCarriers.js +66 -0
- package/dist/prosemirror/runIdentityAcrossRevisions.d.ts +10 -0
- package/dist/prosemirror/runIdentityAcrossRevisions.js +90 -0
- package/dist/prosemirror/schema/nodes.d.ts +37 -5
- package/dist/server.d.ts +3 -2
- package/dist/types/content.d.ts +2 -2
- package/package.json +2 -2
- package/dist/layout-engine/justifiedLineFit.d.ts +0 -7
- package/dist/layout-engine/justifiedLineFit.js +0 -6
|
@@ -5,6 +5,7 @@ import { isInlineSdtContent, isSimpleFieldContent } from "../../docx/inlineWrapp
|
|
|
5
5
|
import { paragraphNumberingReferenceId as paragraphNumberingReferenceId$1, sameStatedParagraphNumbering as sameStatedParagraphNumbering$1 } from "../../docx/numberingReference.js";
|
|
6
6
|
import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, ParagraphPropertySourceValidationError, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, isParagraphPropertySourceToken, linkParagraphPropertySourceCandidate, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceTokenMatchesContract, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings } from "../../docx/paragraphPropertySource.js";
|
|
7
7
|
import { BLOCK_TREE_DESCENT, visitBlockTreeRecords, visitDocxParagraphs } from "../../docx/paragraphTraversal.js";
|
|
8
|
+
import { refingerprintShapeAlternateContent } from "../../docx/shapeAlternateContent.js";
|
|
8
9
|
import { DATE_UTC_ATTRIBUTE } from "../../docx/trackedChangeInfo.js";
|
|
9
10
|
import { copiedWrapPolygon } from "../../docx/wrapPolygon.js";
|
|
10
11
|
import { isStyleSourcedParagraphNumbering, modelParagraphFormattingEmission } from "../../internal/paragraphFormattingSerialization.js";
|
|
@@ -15,12 +16,14 @@ import { canonicalJson } from "../../utils/canonicalJson.js";
|
|
|
15
16
|
import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
|
|
16
17
|
import { mergeTextFormatting } from "../../utils/textFormattingMerge.js";
|
|
17
18
|
import { emuToPixels, emuToStrokePixels, pixelsToEmu } from "../../utils/units.js";
|
|
19
|
+
import { unchangedAlternateContentXml } from "../alternateContentAttrs.js";
|
|
18
20
|
import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectInlineWrapperMarkAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectPageBreakRunAttrs, expectParagraphAttrs, expectPreservedBlockAttrs, expectPreservedXmlAttrs, expectRunFormattingOverrideMarkAttrs, expectRunIdentityMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../attrs/index.js";
|
|
19
21
|
import { readAuthoredTransform } from "../authoredTransformAttrs.js";
|
|
20
22
|
import { autospacingMatchesBase, hasAutospacingBaseSide } from "../autospacingBase.js";
|
|
21
23
|
import { bookmarkMarkerFromAttrs, expectBookmarkBoundaryAttrs } from "../bookmarkBoundaryAttrs.js";
|
|
22
24
|
import { paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges } from "../commands/propertyChangeScope.js";
|
|
23
25
|
import { expectCommentReferenceAttrs } from "../commentReferenceAttrs.js";
|
|
26
|
+
import { enclosingRevisionIds } from "../contentControlRevisions.js";
|
|
24
27
|
import { INLINE_WRAPPER_MARK_NAME } from "../extensions/marks/InlineWrapperExtension.js";
|
|
25
28
|
import { applyRunFormattingOverrideAttrs, buildRunFormattingOverrideAttrs } from "../extensions/marks/RunFormattingOverrideExtension.js";
|
|
26
29
|
import { textFormattingToMarks } from "../extensions/marks/markUtils.js";
|
|
@@ -31,7 +34,7 @@ import { listRenderingFromAttrs as listRenderingFromAttrs$1 } from "../listRende
|
|
|
31
34
|
import { expectMoveRangeBoundaryAttrs } from "../moveRangeBoundaryAttrs.js";
|
|
32
35
|
import { resolveNumberedRefFields } from "../numberedRefFields.js";
|
|
33
36
|
import { directParagraphAlignment } from "../paragraphAlignment.js";
|
|
34
|
-
import {
|
|
37
|
+
import { directionToAuthoredBidi } from "../paragraphDirection.js";
|
|
35
38
|
import { directParagraphSpacing } from "../paragraphSpacing.js";
|
|
36
39
|
import { expectRangeAnchorAttrs } from "../rangeAnchorAttrs.js";
|
|
37
40
|
import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
|
|
@@ -1050,7 +1053,7 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
1050
1053
|
assignBooleanToggle(result, attrs, orig, "suppressAutoHyphens");
|
|
1051
1054
|
if (attrs.spacingExplicit !== orig.spacingExplicit) if (attrs.spacingExplicit) result.spacingExplicit = attrs.spacingExplicit;
|
|
1052
1055
|
else delete result.spacingExplicit;
|
|
1053
|
-
const bidi = authoredParagraphValue("bidi",
|
|
1056
|
+
const bidi = authoredParagraphValue("bidi", directionToAuthoredBidi(attrs.direction), orig, attrs._resolvedFormatting);
|
|
1054
1057
|
if (bidi !== (orig.bidi ?? void 0)) if (bidi === void 0) delete result.bidi;
|
|
1055
1058
|
else result.bidi = bidi;
|
|
1056
1059
|
return result;
|
|
@@ -1058,7 +1061,7 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
1058
1061
|
const resolved = attrs._resolvedFormatting;
|
|
1059
1062
|
const authored = (field, value) => authoredParagraphValue(field, value ?? void 0, void 0, resolved);
|
|
1060
1063
|
const outlineLevel = authored("outlineLevel", Reflect.get(attrs, "outlineLevel"));
|
|
1061
|
-
const bidi = authored("bidi",
|
|
1064
|
+
const bidi = authored("bidi", directionToAuthoredBidi(attrs.direction));
|
|
1062
1065
|
const snapToGrid = authored("snapToGrid", attrs.snapToGrid);
|
|
1063
1066
|
const indentLeft = authored("indentLeft", attrs.indentLeft);
|
|
1064
1067
|
const indentRight = authored("indentRight", attrs.indentRight);
|
|
@@ -1350,6 +1353,7 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1350
1353
|
}
|
|
1351
1354
|
};
|
|
1352
1355
|
const appendDirectRun = (node, run, coalescePlainText = false) => {
|
|
1356
|
+
if (currentHyperlink) flushCurrentInline();
|
|
1353
1357
|
const marksKey = getMarksKey(node.marks);
|
|
1354
1358
|
const ownerId = runIdentityId(node);
|
|
1355
1359
|
const currentOwnerId = currentRun ? sourceRunOwners.get(currentRun) : void 0;
|
|
@@ -2262,6 +2266,7 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
2262
2266
|
};
|
|
2263
2267
|
if (attrs.fldLock !== void 0) complex.fldLock = attrs.fldLock;
|
|
2264
2268
|
if (attrs.dirty !== void 0) complex.dirty = attrs.dirty;
|
|
2269
|
+
if (attrs.fieldResultIsFallback !== void 0) complex.fieldResultIsFallback = attrs.fieldResultIsFallback;
|
|
2265
2270
|
return complex;
|
|
2266
2271
|
}
|
|
2267
2272
|
const simple = {
|
|
@@ -2324,21 +2329,21 @@ function createMathFromNode(node) {
|
|
|
2324
2329
|
return math;
|
|
2325
2330
|
}
|
|
2326
2331
|
/**
|
|
2327
|
-
* A revision
|
|
2332
|
+
* A revision that encloses a control, written around the control.
|
|
2328
2333
|
*
|
|
2329
2334
|
* `w:ins > w:sdt` and `w:sdt > w:ins` reach the editor as the same revision
|
|
2330
|
-
* mark on the same leaves
|
|
2331
|
-
*
|
|
2332
|
-
*
|
|
2333
|
-
*
|
|
2334
|
-
*
|
|
2335
|
+
* mark on the same leaves; the control's enclosing-revision record says which
|
|
2336
|
+
* one it was (`contentControlRevisions.ts`). A revision it names that still
|
|
2337
|
+
* covers every child goes outermost, the only form in which accepting or
|
|
2338
|
+
* rejecting the change is an operation over the whole control: the reader who
|
|
2339
|
+
* inserted a bound field inserted the field, not its text.
|
|
2335
2340
|
*
|
|
2336
|
-
*
|
|
2337
|
-
* where the editor holds it, per child.
|
|
2341
|
+
* Any other revision, including one over all of the content, revises the
|
|
2342
|
+
* content and stays where the editor holds it, per child.
|
|
2338
2343
|
*/
|
|
2339
|
-
const hoistUniformRevision = (sdt) => {
|
|
2344
|
+
const hoistUniformRevision = (sdt, enclosingIds) => {
|
|
2340
2345
|
const only = sdt.content.length === 1 ? sdt.content.at(0) : void 0;
|
|
2341
|
-
if (only === void 0 || !isRevisionWrapper(only)) return sdt;
|
|
2346
|
+
if (only === void 0 || !isRevisionWrapper(only) || !enclosingIds.includes(only.info.id)) return sdt;
|
|
2342
2347
|
const admitted = only.content.filter(isInlineSdtContent);
|
|
2343
2348
|
if (admitted.length !== only.content.length) return sdt;
|
|
2344
2349
|
return {
|
|
@@ -2359,7 +2364,7 @@ function createInlineSdtFromNode(node, textBoxAnchorMarkers, formattingContext)
|
|
|
2359
2364
|
type: "inlineSdt",
|
|
2360
2365
|
properties,
|
|
2361
2366
|
content
|
|
2362
|
-
});
|
|
2367
|
+
}, enclosingRevisionIds(node));
|
|
2363
2368
|
}
|
|
2364
2369
|
/**
|
|
2365
2370
|
* Create a Run containing an image
|
|
@@ -2488,6 +2493,17 @@ const drawingFromImageAttrs = (image, attrs) => {
|
|
|
2488
2493
|
default: return mode;
|
|
2489
2494
|
}
|
|
2490
2495
|
};
|
|
2496
|
+
const shapeContentFromNode = ({ node, shape, captured }) => {
|
|
2497
|
+
const xml = unchangedAlternateContentXml(node, captured);
|
|
2498
|
+
return xml === void 0 ? {
|
|
2499
|
+
type: "shape",
|
|
2500
|
+
shape
|
|
2501
|
+
} : {
|
|
2502
|
+
type: "shape",
|
|
2503
|
+
shape,
|
|
2504
|
+
alternateContent: refingerprintShapeAlternateContent(shape, xml)
|
|
2505
|
+
};
|
|
2506
|
+
};
|
|
2491
2507
|
/**
|
|
2492
2508
|
* Create a Run from a ProseMirror shape node
|
|
2493
2509
|
*/
|
|
@@ -2557,10 +2573,11 @@ function createShapeRun(node) {
|
|
|
2557
2573
|
if (attrs.outlineColor) shapeOutline.color = attrs.outlineColorValue ?? { rgb: attrs.outlineColor.replace("#", "") };
|
|
2558
2574
|
shape.outline = shapeOutline;
|
|
2559
2575
|
}
|
|
2560
|
-
const shapeContent = {
|
|
2561
|
-
|
|
2562
|
-
shape
|
|
2563
|
-
|
|
2576
|
+
const shapeContent = shapeContentFromNode({
|
|
2577
|
+
node,
|
|
2578
|
+
shape,
|
|
2579
|
+
captured: attrs._docxAlternateContent
|
|
2580
|
+
});
|
|
2564
2581
|
const run = {
|
|
2565
2582
|
type: "run",
|
|
2566
2583
|
...carriedRunFormatting(attrs._docxRunFormatting),
|
|
@@ -3583,6 +3600,7 @@ function convertPMTextBox(node, styleResolver = null) {
|
|
|
3583
3600
|
type: "solid",
|
|
3584
3601
|
color: { rgb: attrs.fillColor.replace("#", "") }
|
|
3585
3602
|
};
|
|
3603
|
+
else if (attrs.gradientFill?.gradient) shape.fill = structuredClone(attrs.gradientFill);
|
|
3586
3604
|
if (attrs.outlineStyle !== "none" && attrs.outlineWidth && attrs.outlineWidth > 0) {
|
|
3587
3605
|
const tbOutline = {
|
|
3588
3606
|
width: emuFromPixels(attrs.outlineWidth, "outlineWidth", authoredEmu, emuToStrokePixels),
|
|
@@ -3597,12 +3615,18 @@ function convertPMTextBox(node, styleResolver = null) {
|
|
|
3597
3615
|
if (position) shape.position = position;
|
|
3598
3616
|
const anchor = restoredDrawingAnchor(attrs.anchor);
|
|
3599
3617
|
if (anchor) shape.anchor = anchor;
|
|
3618
|
+
if (attrs._docxGroupChild) shape.groupChild = {
|
|
3619
|
+
path: [...attrs._docxGroupChild.path],
|
|
3620
|
+
group: attrs._docxGroupChild.group,
|
|
3621
|
+
content: attrs._docxGroupChild.content
|
|
3622
|
+
};
|
|
3600
3623
|
const run = {
|
|
3601
3624
|
type: "run",
|
|
3602
|
-
content: [{
|
|
3603
|
-
|
|
3604
|
-
shape
|
|
3605
|
-
|
|
3625
|
+
content: [shapeContentFromNode({
|
|
3626
|
+
node,
|
|
3627
|
+
shape,
|
|
3628
|
+
captured: attrs._docxAlternateContent
|
|
3629
|
+
})]
|
|
3606
3630
|
};
|
|
3607
3631
|
const trackedChange = attrs._docxTrackedChange;
|
|
3608
3632
|
const inlineSdts = attrs._docxInlineSdts ?? [];
|
|
@@ -4,6 +4,7 @@ import { isInlineSdtContent, isTrackedChangeWrapperChild } from "../../docx/inli
|
|
|
4
4
|
import { mergeParagraphNumbering as mergeParagraphNumbering$1, paragraphNumberingReferenceId as paragraphNumberingReferenceId$1 } from "../../docx/numberingReference.js";
|
|
5
5
|
import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, createProseParagraphWithPropertySource, getDocumentParagraphPropertySourceContract, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithParagraphPropertySource, transportTableCellsWithParagraphPropertySources } from "../../docx/paragraphPropertySource.js";
|
|
6
6
|
import { isBaselineVertAlign } from "../../docx/runParser.js";
|
|
7
|
+
import { replayableShapeAlternateContent } from "../../docx/shapeAlternateContent.js";
|
|
7
8
|
import { resolveTableLook } from "../../docx/tableLook.js";
|
|
8
9
|
import { isCellMergeContinuation } from "../../docx/tableParser.js";
|
|
9
10
|
import { copiedWrapPolygon } from "../../docx/wrapPolygon.js";
|
|
@@ -16,9 +17,11 @@ import { mergeParagraphFormatting, mergeParagraphTabStops } from "../../utils/pa
|
|
|
16
17
|
import { tableOfContentsStyleLevel } from "../../utils/tableOfContentsStyle.js";
|
|
17
18
|
import { mergeTextFormatting } from "../../utils/textFormattingMerge.js";
|
|
18
19
|
import { emuToPixels, emuToStrokePixels } from "../../utils/units.js";
|
|
20
|
+
import { withAlternateContent } from "../alternateContentAttrs.js";
|
|
19
21
|
import { expectInlineWrapperMarkAttrs, expectTrackedChangeMarkAttrs } from "../attrs/index.js";
|
|
20
22
|
import { authoredTransformAttrs } from "../authoredTransformAttrs.js";
|
|
21
23
|
import { setAutospacingBaseValue } from "../autospacingBase.js";
|
|
24
|
+
import { withEnclosingRevision } from "../contentControlRevisions.js";
|
|
22
25
|
import { planEmptyRanges } from "../emptyRangeAnchor.js";
|
|
23
26
|
import { INLINE_WRAPPER_MARK_NAME } from "../extensions/marks/InlineWrapperExtension.js";
|
|
24
27
|
import { textFormattingToMarks } from "../extensions/marks/markUtils.js";
|
|
@@ -34,6 +37,7 @@ import { directionFromBidi } from "../paragraphDirection.js";
|
|
|
34
37
|
import { styleResolvedParagraphFormatting } from "../paragraphFormattingProvenance.js";
|
|
35
38
|
import { lineSpacingProvenanceFromSpacing } from "../paragraphSpacing.js";
|
|
36
39
|
import { RUN_IDENTITY_MARK_NAME, hasRunIdentityPayload, runIdentityAttrs } from "../runIdentity.js";
|
|
40
|
+
import { continueRunIdentitiesAcrossRevisions } from "../runIdentityAcrossRevisions.js";
|
|
37
41
|
import { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, resolveParagraphBodyRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
|
|
38
42
|
import { schema } from "../schema/index.js";
|
|
39
43
|
import { PRESERVED_XML_LEVELS } from "../schema/nodes.js";
|
|
@@ -86,7 +90,7 @@ const runIdentityMark = (run, nextRunIdentityId) => {
|
|
|
86
90
|
const payload = {
|
|
87
91
|
preservedAttributes: run.preservedAttributes,
|
|
88
92
|
preserved: run.formatting?.preserved,
|
|
89
|
-
emptyFormatting: run.formatting !== void 0 && Object.keys(run.formatting).length === 0 ? true : void 0
|
|
93
|
+
emptyFormatting: run.formatting !== void 0 && Object.keys(run.formatting).length === 0 && (run.propertyChanges?.length ?? 0) === 0 ? true : void 0
|
|
90
94
|
};
|
|
91
95
|
if (!runHasPageBreakContent(run) && !runHasMixedContent(run) && !hasRunIdentityPayload(payload)) return null;
|
|
92
96
|
return schema.mark(RUN_IDENTITY_MARK_NAME, runIdentityAttrs(nextRunIdentityId(), payload));
|
|
@@ -577,7 +581,7 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
|
|
|
577
581
|
if (emptyHyperlinks) attrs._emptyHyperlinks = emptyHyperlinks;
|
|
578
582
|
return createProseParagraphWithPropertySource(schema.nodes["paragraph"], paragraph, {
|
|
579
583
|
attrs,
|
|
580
|
-
content: inlineNodes
|
|
584
|
+
content: continueRunIdentitiesAcrossRevisions(inlineNodes)
|
|
581
585
|
});
|
|
582
586
|
}
|
|
583
587
|
/**
|
|
@@ -609,16 +613,20 @@ function anchorPointComment(nodes, commentId) {
|
|
|
609
613
|
* One node of a revision's content with the revision recorded on it.
|
|
610
614
|
*
|
|
611
615
|
* An inline content control is an `inline*` node rather than an atom, so it is
|
|
612
|
-
* not a run carrier: the revision goes on the leaves it holds
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
* around the control
|
|
616
|
+
* not a run carrier: the revision goes on the leaves it holds, and the control
|
|
617
|
+
* records that the revision encloses it. The leaves alone would read the same
|
|
618
|
+
* for `w:ins > w:sdt` and `w:sdt > w:ins`; the record is what lets the save leg
|
|
619
|
+
* write the revision back around the control, and resolving it remove the
|
|
620
|
+
* control, only for the first.
|
|
616
621
|
*/
|
|
617
622
|
const withTrackedRunMark = (node, mark, ancestor) => {
|
|
618
623
|
if (node.type.name === "sdt") {
|
|
619
624
|
const marked = [];
|
|
620
625
|
for (let index = 0; index < node.childCount; index += 1) marked.push(withTrackedRunMark(node.child(index), mark, ancestor));
|
|
621
|
-
return recreateProseNodeWithParagraphPropertySource(node, {
|
|
626
|
+
return recreateProseNodeWithParagraphPropertySource(node, {
|
|
627
|
+
attrs: withEnclosingRevision(node, ancestor.revisionId) ?? node.attrs,
|
|
628
|
+
content: marked
|
|
629
|
+
});
|
|
622
630
|
}
|
|
623
631
|
const nestedMark = node.marks.find(({ type }) => type.name === "insertion" || type.name === "deletion");
|
|
624
632
|
if (nestedMark) {
|
|
@@ -1547,7 +1555,8 @@ function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyp
|
|
|
1547
1555
|
displayText,
|
|
1548
1556
|
fieldKind: field.type === "simpleField" ? "simple" : "complex",
|
|
1549
1557
|
fldLock: field.fldLock ?? null,
|
|
1550
|
-
dirty: field.dirty ?? null
|
|
1558
|
+
dirty: field.dirty ?? null,
|
|
1559
|
+
fieldResultIsFallback: field.type === "complexField" ? field.fieldResultIsFallback ?? null : null
|
|
1551
1560
|
}, createStructuredField ? inlineNodes : void 0, marks);
|
|
1552
1561
|
}
|
|
1553
1562
|
/**
|
|
@@ -2163,7 +2172,7 @@ function convertRunContent(content, marks, formatting, textBoxAnchors, authoredF
|
|
|
2163
2172
|
const anchorId = textBoxAnchors?.get(shp);
|
|
2164
2173
|
return anchorId ? [schema.node("textBoxAnchor", { anchorId }).mark(marks)] : [];
|
|
2165
2174
|
}
|
|
2166
|
-
return [withRunBoundaryMarks(convertShape(shp, carriedRunFormatting(authoredFormatting)), marks)];
|
|
2175
|
+
return [withRunBoundaryMarks(withAlternateContent(convertShape(shp, carriedRunFormatting(authoredFormatting)), replayableShapeAlternateContent(content)), marks)];
|
|
2167
2176
|
}
|
|
2168
2177
|
case "footnoteRef": {
|
|
2169
2178
|
const footnoteMark = schema.mark("footnoteRef", {
|
|
@@ -2214,6 +2223,12 @@ function withRunBoundaryMarks(node, marks) {
|
|
|
2214
2223
|
*/
|
|
2215
2224
|
const authoredEmuAttrs = (values) => Object.values(values).some((value) => value !== void 0) ? values : void 0;
|
|
2216
2225
|
/**
|
|
2226
|
+
* A text box's gradient fill, copied for the reason {@link copiedDrawingAnchor}
|
|
2227
|
+
* is: ProseMirror keeps object-valued attrs by reference. Any other fill is
|
|
2228
|
+
* stated by `fillColor`, or not at all.
|
|
2229
|
+
*/
|
|
2230
|
+
const copiedGradientFill = (fill) => fill?.type === "gradient" && fill.gradient !== void 0 ? structuredClone(fill) : void 0;
|
|
2231
|
+
/**
|
|
2217
2232
|
* A copy of the anchor record: ProseMirror keeps object-valued attrs by
|
|
2218
2233
|
* reference, so sharing it with the source would let a mutation of either reach
|
|
2219
2234
|
* the other outside a transaction.
|
|
@@ -2535,16 +2550,19 @@ function convertParagraphWithTextBoxes(block, styleResolver, { textBoxGroupId, c
|
|
|
2535
2550
|
const keepWrapperParagraph = isEmptyAfterExtraction && (preserveEmptyWrapper === true || hasParagraphBoundaryPayload(block, pmParagraph));
|
|
2536
2551
|
if (!isEmptyAfterExtraction || keepWrapperParagraph) nodes.push(pmParagraph);
|
|
2537
2552
|
const standalone = isEmptyAfterExtraction && !keepWrapperParagraph;
|
|
2538
|
-
for (const [index, { textBox, anchorId, trackedChange, inlineSdts }] of textBoxes.entries())
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2553
|
+
for (const [index, { textBox, alternateContentXml, anchorId, trackedChange, inlineSdts }] of textBoxes.entries()) {
|
|
2554
|
+
const textBoxNode = convertTextBox(textBox, styleResolver, {
|
|
2555
|
+
placement: standalone ? "standalone" : "inlineWithPrevious",
|
|
2556
|
+
groupId: textBoxGroupId,
|
|
2557
|
+
anchorId,
|
|
2558
|
+
context,
|
|
2559
|
+
trackedChange,
|
|
2560
|
+
inlineSdts,
|
|
2561
|
+
...standalone && index === 0 && block.preservedAttributes ? { hostPreservedAttributes: block.preservedAttributes } : {},
|
|
2562
|
+
...standalone && index === 0 ? { hostParagraph: hostParagraphAttrs(pmParagraph.attrs) } : {}
|
|
2563
|
+
});
|
|
2564
|
+
nodes.push(withAlternateContent(textBoxNode, alternateContentXml));
|
|
2565
|
+
}
|
|
2548
2566
|
return nodes;
|
|
2549
2567
|
}
|
|
2550
2568
|
/**
|
|
@@ -2602,6 +2620,7 @@ function extractTextBoxes(paragraph, textBoxGroupId) {
|
|
|
2602
2620
|
textBoxAnchors.set(runContent.shape, anchorId);
|
|
2603
2621
|
textBoxes.push({
|
|
2604
2622
|
textBox: textBoxFromShape(runContent.shape, runContent.shape.textBody),
|
|
2623
|
+
alternateContentXml: replayableShapeAlternateContent(runContent),
|
|
2605
2624
|
anchorId,
|
|
2606
2625
|
trackedChange: context.trackedChange,
|
|
2607
2626
|
inlineSdts: context.inlineSdts
|
|
@@ -2694,6 +2713,7 @@ function textBoxFromShape(shape, textBody) {
|
|
|
2694
2713
|
if (textBody.textWrap) textBox.textWrap = textBody.textWrap;
|
|
2695
2714
|
if (textBody.anchor) textBox.verticalAlign = textBody.anchor;
|
|
2696
2715
|
if (textBody.wordArt) textBox.wordArt = textBody.wordArt;
|
|
2716
|
+
if (shape.groupChild) textBox.groupChild = shape.groupChild;
|
|
2697
2717
|
return textBox;
|
|
2698
2718
|
}
|
|
2699
2719
|
/**
|
|
@@ -2706,6 +2726,7 @@ function convertTextBox(textBox, styleResolver, options) {
|
|
|
2706
2726
|
const heightPx = textBoxSize?.height ? emuToPixels(textBoxSize.height) : void 0;
|
|
2707
2727
|
let fillColor;
|
|
2708
2728
|
if (textBox.fill?.color?.rgb) fillColor = `#${textBox.fill.color.rgb}`;
|
|
2729
|
+
const gradientFill = copiedGradientFill(textBox.fill);
|
|
2709
2730
|
let outlineWidth;
|
|
2710
2731
|
let outlineColor;
|
|
2711
2732
|
let outlineStyle;
|
|
@@ -2796,6 +2817,7 @@ function convertTextBox(textBox, styleResolver, options) {
|
|
|
2796
2817
|
alt: textBox.alt,
|
|
2797
2818
|
title: textBox.title,
|
|
2798
2819
|
fillColor,
|
|
2820
|
+
gradientFill,
|
|
2799
2821
|
outlineWidth,
|
|
2800
2822
|
outlineColor,
|
|
2801
2823
|
outlineStyle,
|
|
@@ -2816,6 +2838,7 @@ function convertTextBox(textBox, styleResolver, options) {
|
|
|
2816
2838
|
_docxPlacement: options.placement,
|
|
2817
2839
|
_docxGroupId: options.groupId,
|
|
2818
2840
|
_docxAnchorId: options.anchorId,
|
|
2841
|
+
_docxGroupChild: textBox.groupChild,
|
|
2819
2842
|
_docxTextBodyContentState: textBox.content.length === 0 ? { type: "source-empty" } : { type: "authored" },
|
|
2820
2843
|
_docxTrackedChange: options.trackedChange,
|
|
2821
2844
|
_docxInlineSdts: options.inlineSdts.length > 0 ? options.inlineSdts : void 0,
|
|
@@ -8,13 +8,13 @@ declare const autoBidiDetectionKey: PluginKey<any>;
|
|
|
8
8
|
* fire for the initial document, so seeded content needs this pass.
|
|
9
9
|
*
|
|
10
10
|
* Like the paraId allocator this is `ignoreTrackedChanges`, so a normalized
|
|
11
|
-
* paragraph the user never edits is not in `changedParaIds`.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* selective-save path (dark
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
11
|
+
* paragraph the user never edits is not in `changedParaIds`. An imported DOCX
|
|
12
|
+
* whose Arabic arrived without `w:bidi` gets `{ source: "auto" }` here purely
|
|
13
|
+
* for rendering; because `directionToAuthoredBidi` treats `"auto"` the same
|
|
14
|
+
* as undecided, neither a full-repack save nor the selective-save path (dark
|
|
15
|
+
* `selectiveSave` flag) writes `w:bidi` for it when the paragraph is not
|
|
16
|
+
* otherwise edited. A manual toggle, or a paragraph whose `w:bidi` the source
|
|
17
|
+
* document already carried, is unaffected — it always round-trips.
|
|
18
18
|
*/
|
|
19
19
|
declare const ensureBaseDirectionInState: (state: EditorState) => EditorState;
|
|
20
20
|
declare const AutoBidiDetectionExtension: (options?: Partial<{}> | undefined) => Extension;
|
|
@@ -80,13 +80,13 @@ const applyBidiUpdates = (state, updates) => {
|
|
|
80
80
|
* fire for the initial document, so seeded content needs this pass.
|
|
81
81
|
*
|
|
82
82
|
* Like the paraId allocator this is `ignoreTrackedChanges`, so a normalized
|
|
83
|
-
* paragraph the user never edits is not in `changedParaIds`.
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* selective-save path (dark
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
83
|
+
* paragraph the user never edits is not in `changedParaIds`. An imported DOCX
|
|
84
|
+
* whose Arabic arrived without `w:bidi` gets `{ source: "auto" }` here purely
|
|
85
|
+
* for rendering; because `directionToAuthoredBidi` treats `"auto"` the same
|
|
86
|
+
* as undecided, neither a full-repack save nor the selective-save path (dark
|
|
87
|
+
* `selectiveSave` flag) writes `w:bidi` for it when the paragraph is not
|
|
88
|
+
* otherwise edited. A manual toggle, or a paragraph whose `w:bidi` the source
|
|
89
|
+
* document already carried, is unaffected — it always round-trips.
|
|
90
90
|
*/
|
|
91
91
|
const ensureBaseDirectionInState = (state) => {
|
|
92
92
|
if (!autoBidiDetectionKey.get(state)) return state;
|
|
@@ -9,7 +9,8 @@ const createFieldAttrs = () => ({
|
|
|
9
9
|
_numberedRefBaseline: { default: void 0 },
|
|
10
10
|
fieldKind: { default: "simple" },
|
|
11
11
|
fldLock: { default: null },
|
|
12
|
-
dirty: { default: null }
|
|
12
|
+
dirty: { default: null },
|
|
13
|
+
fieldResultIsFallback: { default: null }
|
|
13
14
|
});
|
|
14
15
|
/** A `data-` flag a pasted field carried: absent states nothing. */
|
|
15
16
|
const statedFlag = (value) => value === void 0 ? null : value === "true";
|
|
@@ -19,10 +20,11 @@ const readFieldDomAttrs = (dom) => ({
|
|
|
19
20
|
displayText: dom.textContent ?? "",
|
|
20
21
|
fieldKind: dom.dataset["fieldKind"] ?? "simple",
|
|
21
22
|
fldLock: statedFlag(dom.dataset["fldLock"]),
|
|
22
|
-
dirty: statedFlag(dom.dataset["dirty"])
|
|
23
|
+
dirty: statedFlag(dom.dataset["dirty"]),
|
|
24
|
+
fieldResultIsFallback: statedFlag(dom.dataset["fieldResultIsFallback"])
|
|
23
25
|
});
|
|
24
26
|
const getFieldDomAttrs = (node) => {
|
|
25
|
-
const { fieldType, instruction, fieldKind, fldLock, dirty } = expectFieldAttrs(node);
|
|
27
|
+
const { fieldType, instruction, fieldKind, fldLock, dirty, fieldResultIsFallback } = expectFieldAttrs(node);
|
|
26
28
|
return {
|
|
27
29
|
class: `docx-field docx-field-${fieldType.toLowerCase()}`,
|
|
28
30
|
"data-field-type": fieldType,
|
|
@@ -30,6 +32,7 @@ const getFieldDomAttrs = (node) => {
|
|
|
30
32
|
"data-field-kind": fieldKind,
|
|
31
33
|
...fldLock === void 0 ? {} : { "data-fld-lock": String(fldLock) },
|
|
32
34
|
...dirty === void 0 ? {} : { "data-dirty": String(dirty) },
|
|
35
|
+
...fieldResultIsFallback === void 0 ? {} : { "data-field-result-is-fallback": String(fieldResultIsFallback) },
|
|
33
36
|
style: "outline: 1px solid var(--doc-field-outline, rgba(200,200,200,0.4)); padding: 0 1px; border-radius: 2px;"
|
|
34
37
|
};
|
|
35
38
|
};
|
|
@@ -54,7 +54,13 @@ const SdtExtension = createNodeExtension({
|
|
|
54
54
|
* `w:sdtEndPr` as a record, so a control the editor rebuilds still
|
|
55
55
|
* writes its end mark once the captured bytes are gone.
|
|
56
56
|
*/
|
|
57
|
-
endProperties: { default: null }
|
|
57
|
+
endProperties: { default: null },
|
|
58
|
+
/**
|
|
59
|
+
* The revisions whose element encloses the control (`w:ins > w:sdt`),
|
|
60
|
+
* as opposed to revising the content inside it (`w:sdt > w:ins`). Both
|
|
61
|
+
* put the same marks on the leaves; see `contentControlRevisions.ts`.
|
|
62
|
+
*/
|
|
63
|
+
_docxEnclosingRevisionIds: { default: null }
|
|
58
64
|
},
|
|
59
65
|
parseDOM: [{
|
|
60
66
|
tag: "span.docx-sdt",
|
|
@@ -78,7 +84,8 @@ const SdtExtension = createNodeExtension({
|
|
|
78
84
|
checked: onOffFromDataset(el.dataset["checked"]),
|
|
79
85
|
_preserved: null,
|
|
80
86
|
rawEndPropertiesXml: null,
|
|
81
|
-
endProperties: null
|
|
87
|
+
endProperties: null,
|
|
88
|
+
_docxEnclosingRevisionIds: null
|
|
82
89
|
};
|
|
83
90
|
}
|
|
84
91
|
}],
|
|
@@ -370,6 +370,7 @@ const ShapeExtension = createNodeExtension({
|
|
|
370
370
|
shapeType: { default: "rect" },
|
|
371
371
|
geometryAdjustments: { default: null },
|
|
372
372
|
_docxRunFormatting: { default: null },
|
|
373
|
+
_docxAlternateContent: { default: null },
|
|
373
374
|
shapeId: { default: null },
|
|
374
375
|
shapeName: { default: null },
|
|
375
376
|
alt: { default: null },
|
|
@@ -86,6 +86,7 @@ const TextBoxExtension = createNodeExtension({
|
|
|
86
86
|
alt: { default: null },
|
|
87
87
|
title: { default: null },
|
|
88
88
|
fillColor: { default: null },
|
|
89
|
+
gradientFill: { default: null },
|
|
89
90
|
outlineWidth: { default: null },
|
|
90
91
|
outlineColor: { default: null },
|
|
91
92
|
outlineStyle: { default: null },
|
|
@@ -111,9 +112,11 @@ const TextBoxExtension = createNodeExtension({
|
|
|
111
112
|
wrapDistanceSlots: { default: null },
|
|
112
113
|
wrapEffectExtentSlots: { default: null },
|
|
113
114
|
wrapPolygon: { default: null },
|
|
115
|
+
_docxAlternateContent: { default: null },
|
|
114
116
|
_docxPlacement: { default: null },
|
|
115
117
|
_docxGroupId: { default: null },
|
|
116
118
|
_docxAnchorId: { default: null },
|
|
119
|
+
_docxGroupChild: { default: null },
|
|
117
120
|
_docxTextBodyContentState: { default: { type: "authored" } },
|
|
118
121
|
_docxTrackedChange: { default: null },
|
|
119
122
|
_docxInlineSdts: { default: null },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { convertBulletToUnicode } from "../docx/bulletMarkers.js";
|
|
1
|
+
import { bulletMarkerFontName, convertBulletToUnicode } from "../docx/bulletMarkers.js";
|
|
2
2
|
import { paragraphNumberingLevel, paragraphNumberingReferenceId, sameStatedParagraphNumbering } from "../docx/numberingReference.js";
|
|
3
3
|
import { formatOoxmlCounter } from "../docx/ooxmlCounterFormatter.js";
|
|
4
4
|
import { isListNumPr } from "../layout-engine/types.js";
|
|
@@ -205,7 +205,7 @@ function advanceListMarker(attrs, state) {
|
|
|
205
205
|
fromStyle: false,
|
|
206
206
|
numId: null
|
|
207
207
|
};
|
|
208
|
-
return convertBulletToUnicode(attrs.listMarker ?? markerTemplate ?? "");
|
|
208
|
+
return convertBulletToUnicode(attrs.listMarker ?? markerTemplate ?? "", bulletMarkerFontName(attrs.listMarkerFormatting));
|
|
209
209
|
}
|
|
210
210
|
const firstInstanceEncounter = !state.counters.has(numId);
|
|
211
211
|
let counters = state.counters.get(numId) ?? Array.from({ length: 9 }, () => NaN);
|
|
@@ -15,6 +15,17 @@
|
|
|
15
15
|
* The persisted/serialized model keeps the flat OOXML tri-state
|
|
16
16
|
* (`ParagraphFormatting.bidi: boolean | undefined`); `directionToBidi` /
|
|
17
17
|
* `directionFromBidi` bridge the two at the conversion boundary.
|
|
18
|
+
*
|
|
19
|
+
* `source: "auto"` is a *rendering* decision only — it makes the layout
|
|
20
|
+
* painter and the editor's DOM shape the paragraph RTL, so newly typed or
|
|
21
|
+
* pasted directional text displays correctly before the user ever makes an
|
|
22
|
+
* explicit choice. It must never reach the saved package on its own: a
|
|
23
|
+
* paragraph that arrived without `w:bidi` and was never touched by the user
|
|
24
|
+
* must save without `w:bidi` too, no matter how many auto-detection passes
|
|
25
|
+
* ran over it on load. Only `source: "manual"` (an explicit user toggle, or
|
|
26
|
+
* a `w:bidi` the source document already carried) is authored content and
|
|
27
|
+
* belongs in `w:pPr`. Use `directionToBidi` for layout/rendering and
|
|
28
|
+
* `directionToAuthoredBidi` for anything that gets serialized.
|
|
18
29
|
*/
|
|
19
30
|
type ParagraphDirection = {
|
|
20
31
|
source: "auto";
|
|
@@ -29,8 +40,24 @@ declare const directionIsRtl: (direction: ParagraphDirection | null | undefined)
|
|
|
29
40
|
* AutoBidiDetection may (re-)evaluate. A manual decision is left untouched.
|
|
30
41
|
*/
|
|
31
42
|
declare const directionIsAutoManaged: (direction: ParagraphDirection | null | undefined) => boolean;
|
|
32
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Map a direction to the OOXML `w:bidi` tri-state for layout/rendering: an
|
|
45
|
+
* auto-detected direction lays out RTL exactly like a manual one. Do not use
|
|
46
|
+
* this to decide what gets written to the saved package — see
|
|
47
|
+
* `directionToAuthoredBidi`.
|
|
48
|
+
*/
|
|
33
49
|
declare const directionToBidi: (direction: ParagraphDirection | null | undefined) => boolean | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Map a direction to the OOXML `w:bidi` tri-state as *authored* content, for
|
|
52
|
+
* serialization. Only a manual decision (explicit user toggle, or a `w:bidi`
|
|
53
|
+
* the source document already carried) is ever written: `undefined` here
|
|
54
|
+
* means "the paragraph does not state its own direction," which keeps
|
|
55
|
+
* `w:pPr` free of a flag the user never asked for. An auto-detected
|
|
56
|
+
* direction (`source: "auto"`) resolves to `undefined` — same as undecided —
|
|
57
|
+
* regardless of which way detection currently leans, so it stays a view-only
|
|
58
|
+
* aid until the user makes it explicit.
|
|
59
|
+
*/
|
|
60
|
+
declare const directionToAuthoredBidi: (direction: ParagraphDirection | null | undefined) => boolean | undefined;
|
|
34
61
|
/**
|
|
35
62
|
* Reconstruct a direction from a model `bidi` value (DOCX import / load): an
|
|
36
63
|
* explicit `true`/`false` is a manual decision, absence is undecided.
|
|
@@ -39,4 +66,4 @@ declare const directionFromBidi: (bidi: boolean | null | undefined) => Paragraph
|
|
|
39
66
|
/** Runtime guard for the PM attribute validator. */
|
|
40
67
|
declare const isParagraphDirection: (value: unknown) => value is ParagraphDirection;
|
|
41
68
|
//#endregion
|
|
42
|
-
export { ParagraphDirection, directionFromBidi, directionIsAutoManaged, directionIsRtl, directionToBidi, isParagraphDirection };
|
|
69
|
+
export { ParagraphDirection, directionFromBidi, directionIsAutoManaged, directionIsRtl, directionToAuthoredBidi, directionToBidi, isParagraphDirection };
|
|
@@ -6,13 +6,32 @@ const directionIsRtl = (direction) => direction?.source === "auto" || direction?
|
|
|
6
6
|
* AutoBidiDetection may (re-)evaluate. A manual decision is left untouched.
|
|
7
7
|
*/
|
|
8
8
|
const directionIsAutoManaged = (direction) => direction == null || direction.source === "auto";
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Map a direction to the OOXML `w:bidi` tri-state for layout/rendering: an
|
|
11
|
+
* auto-detected direction lays out RTL exactly like a manual one. Do not use
|
|
12
|
+
* this to decide what gets written to the saved package — see
|
|
13
|
+
* `directionToAuthoredBidi`.
|
|
14
|
+
*/
|
|
10
15
|
const directionToBidi = (direction) => {
|
|
11
16
|
if (direction == null) return;
|
|
12
17
|
if (direction.source === "auto") return true;
|
|
13
18
|
return direction.value === "rtl";
|
|
14
19
|
};
|
|
15
20
|
/**
|
|
21
|
+
* Map a direction to the OOXML `w:bidi` tri-state as *authored* content, for
|
|
22
|
+
* serialization. Only a manual decision (explicit user toggle, or a `w:bidi`
|
|
23
|
+
* the source document already carried) is ever written: `undefined` here
|
|
24
|
+
* means "the paragraph does not state its own direction," which keeps
|
|
25
|
+
* `w:pPr` free of a flag the user never asked for. An auto-detected
|
|
26
|
+
* direction (`source: "auto"`) resolves to `undefined` — same as undecided —
|
|
27
|
+
* regardless of which way detection currently leans, so it stays a view-only
|
|
28
|
+
* aid until the user makes it explicit.
|
|
29
|
+
*/
|
|
30
|
+
const directionToAuthoredBidi = (direction) => {
|
|
31
|
+
if (direction == null || direction.source === "auto") return;
|
|
32
|
+
return direction.value === "rtl";
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
16
35
|
* Reconstruct a direction from a model `bidi` value (DOCX import / load): an
|
|
17
36
|
* explicit `true`/`false` is a manual decision, absence is undecided.
|
|
18
37
|
*/
|
|
@@ -30,4 +49,4 @@ const isParagraphDirection = (value) => {
|
|
|
30
49
|
return value.source === "manual" && "value" in value && (value.value === "rtl" || value.value === "ltr");
|
|
31
50
|
};
|
|
32
51
|
//#endregion
|
|
33
|
-
export { directionFromBidi, directionIsAutoManaged, directionIsRtl, directionToBidi, isParagraphDirection };
|
|
52
|
+
export { directionFromBidi, directionIsAutoManaged, directionIsRtl, directionToAuthoredBidi, directionToBidi, isParagraphDirection };
|