@stll/folio-core 0.66.0 → 0.66.2
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 +13 -1
- package/dist/ai-edits/apply.js +533 -136
- package/dist/ai-edits/batch-claims.d.ts +26 -0
- package/dist/ai-edits/batch-claims.js +30 -5
- package/dist/ai-edits/headless.d.ts +6 -0
- package/dist/ai-edits/headless.js +25 -3
- package/dist/ai-edits/newListNumbering.d.ts +4 -1
- package/dist/ai-edits/newListNumbering.js +4 -2
- package/dist/ai-edits/types.d.ts +1 -1
- package/dist/document-operations.d.ts +13 -1
- package/dist/document-operations.js +11 -4
- package/dist/docx/listNumberingInstances.d.ts +6 -4
- package/dist/docx/listNumberingInstances.js +12 -11
- package/dist/docx/numberingIds.d.ts +10 -0
- package/dist/docx/numberingIds.js +5 -1
- package/dist/docx/paragraphParser.js +16 -3
- package/dist/docx/paragraphProperties.js +2 -1
- package/dist/docx/serializer/paragraphSerializer.js +86 -66
- package/dist/fonts/bundledFonts.d.ts +54 -0
- package/dist/fonts/bundledFonts.js +45 -0
- package/dist/fonts/fontsourceFaces.d.ts +9 -14
- package/dist/fonts/fontsourceFaces.js +10 -22
- package/dist/i18n/messages/ar.gen.js +1 -0
- package/dist/i18n/messages/catalogs.gen.d.ts +17 -0
- package/dist/i18n/messages/catalogs.gen.js +17 -0
- package/dist/i18n/messages/cs.gen.js +1 -0
- package/dist/i18n/messages/de.gen.js +1 -0
- package/dist/i18n/messages/en.gen.js +1 -0
- package/dist/i18n/messages/es.gen.js +1 -0
- package/dist/i18n/messages/et.gen.js +1 -0
- package/dist/i18n/messages/fr.gen.js +1 -0
- package/dist/i18n/messages/he.gen.js +1 -0
- package/dist/i18n/messages/hi.gen.js +1 -0
- package/dist/i18n/messages/hu.gen.js +1 -0
- package/dist/i18n/messages/lt.gen.js +1 -0
- package/dist/i18n/messages/lv.gen.js +1 -0
- package/dist/i18n/messages/messages.gen.d.ts +1 -0
- package/dist/i18n/messages/pl.gen.js +1 -0
- package/dist/i18n/messages/pt-BR.gen.js +1 -0
- package/dist/i18n/messages/sk.gen.js +1 -0
- package/dist/i18n/messages/tr.gen.js +1 -0
- package/dist/i18n/messages/zh-CN.gen.js +1 -0
- package/dist/internal/wholeStoryRevisionResolution.d.ts +1 -1
- package/dist/internal/wholeStoryRevisionResolution.js +24 -9
- package/dist/layout-bridge/convert/runMarkFormatting.js +1 -0
- package/dist/markdown/renderRuns.js +68 -12
- package/dist/prosemirror/commands/comments.js +2 -0
- package/dist/prosemirror/commands/resolveParagraphProperties.js +15 -2
- package/dist/prosemirror/conversion/fromProseDoc.js +55 -18
- package/dist/prosemirror/conversion/hyphenTextCarriers.d.ts +23 -1
- package/dist/prosemirror/conversion/hyphenTextCarriers.js +46 -1
- package/dist/prosemirror/conversion/toProseDoc.js +15 -9
- package/dist/prosemirror/extensions/StarterKit.js +1 -1
- package/dist/prosemirror/extensions/features/pasteCleanup.js +6 -0
- package/dist/prosemirror/extensions/features/pastedHtmlLists.js +2 -1
- package/dist/prosemirror/extensions/markRegistry.d.ts +3 -1
- package/dist/prosemirror/extensions/markRegistry.js +3 -0
- package/dist/prosemirror/extensions/marks/HyphenElementExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/marks/HyphenElementExtension.js +54 -0
- package/dist/prosemirror/fieldRepresentation.js +2 -1
- package/dist/prosemirror/hyphenElementAttrs.d.ts +10 -0
- package/dist/prosemirror/hyphenElementAttrs.js +32 -0
- package/dist/prosemirror/keptRangeBoundaries.d.ts +2 -0
- package/dist/prosemirror/keptRangeBoundaries.js +1 -1
- package/dist/prosemirror/listNumbering.js +3 -2
- package/dist/prosemirror/paragraphIndentation.js +2 -1
- package/dist/prosemirror/paragraphPropertyCarry.d.ts +1 -14
- package/dist/prosemirror/paragraphPropertyCarry.js +4 -28
- package/dist/prosemirror/plugins/suggestionMode.js +19 -6
- package/dist/prosemirror/replacedAnnotations.d.ts +1 -0
- package/dist/prosemirror/replacedAnnotations.js +1 -0
- package/dist/prosemirror/sectionCarrier.d.ts +8 -0
- package/dist/prosemirror/sectionCarrier.js +29 -1
- package/dist/prosemirror/styles/paragraphStyleCascade.d.ts +10 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.js +12 -2
- package/dist/prosemirror/tableRunIn.d.ts +24 -9
- package/dist/prosemirror/tableRunIn.js +107 -21
- package/dist/prosemirror/textInput.js +3 -1
- package/dist/prosemirror/validation.js +6 -0
- package/dist/utils/createDocument.js +11 -8
- package/dist/utils/fontLoader.d.ts +1 -1
- package/dist/utils/fontLoader.js +3 -11
- package/dist/utils/formatToStyle.js +2 -2
- package/dist/utils/units.d.ts +5 -0
- package/dist/utils/units.js +6 -1
- package/package.json +6 -4
|
@@ -59,6 +59,7 @@ import { expectTextBoxAnchorAttrs } from "../textBoxAnchorAttrs.js";
|
|
|
59
59
|
import { textBoxHostParagraph } from "../textBoxHostParagraph.js";
|
|
60
60
|
import { enclosingInsertionAncestors, inlineWrapperStackOf, trackedRevisionLayerOf } from "../trackedRevisionPath.js";
|
|
61
61
|
import { assertValidProseMirrorDocument } from "../validation.js";
|
|
62
|
+
import { hyphenElementRunContent } from "./hyphenTextCarriers.js";
|
|
62
63
|
import { hasSinkChildren } from "./preservedSinkCarriers.js";
|
|
63
64
|
import { decodeSdtListItems, sdtPropertiesFromAttrs, sdtPropertiesMatchAttrs } from "./sdtAttrs.js";
|
|
64
65
|
import { TaggedError, panic } from "better-result";
|
|
@@ -1659,13 +1660,13 @@ function extractParagraphContent(originalParagraph, _documentCounts, emptyHyperl
|
|
|
1659
1660
|
}));
|
|
1660
1661
|
const ownerId = runIdentityId(node);
|
|
1661
1662
|
const currentOwnerId = currentRun ? sourceRunOwners.get(currentRun) : void 0;
|
|
1662
|
-
const currentRunIsPlainText = currentRun?.content.every(
|
|
1663
|
+
const currentRunIsPlainText = currentRun?.content.every(isTextLeafContent);
|
|
1663
1664
|
const joinsOwnedSourceRun = ownerId !== void 0 && ownerId === currentOwnerId && currentRun !== null && runsShareProperties(currentRun, run);
|
|
1664
1665
|
const joinsOrdinaryText = coalescePlainText && currentRun !== null && runsShareProperties(currentRun, run) && currentRunIsPlainText === true && currentMarksKey === marksKey;
|
|
1665
1666
|
if (currentRun && (joinsOwnedSourceRun || joinsOrdinaryText)) {
|
|
1666
|
-
if (joinsOrdinaryText)
|
|
1667
|
-
|
|
1668
|
-
|
|
1667
|
+
if (joinsOrdinaryText) for (const runContent of run.content) if (runContent.type === "text") appendTextToRun(currentRun, runContent.text);
|
|
1668
|
+
else currentRun.content.push(runContent);
|
|
1669
|
+
else currentRun.content.push(...run.content);
|
|
1669
1670
|
return;
|
|
1670
1671
|
}
|
|
1671
1672
|
if (currentRun) content.push(currentRun);
|
|
@@ -2266,10 +2267,7 @@ function createTrackedChangeRun({ baseParagraphFormatting, inheritedFormatting,
|
|
|
2266
2267
|
const formatting = marksToTextFormatting(marks, formattingContext);
|
|
2267
2268
|
run = {
|
|
2268
2269
|
type: "run",
|
|
2269
|
-
content: node.text ? [
|
|
2270
|
-
type: "text",
|
|
2271
|
-
text: node.text
|
|
2272
|
-
}] : [],
|
|
2270
|
+
content: node.text ? textLeafRunContent(node.text, marks) : [],
|
|
2273
2271
|
...Object.keys(formatting).length > 0 ? { formatting } : {}
|
|
2274
2272
|
};
|
|
2275
2273
|
restoreRunRecord(run, marks);
|
|
@@ -2355,7 +2353,7 @@ function getLinkKey(mark) {
|
|
|
2355
2353
|
* Create a unique key for a set of marks (excluding hyperlink)
|
|
2356
2354
|
*/
|
|
2357
2355
|
function getMarksKey(marks) {
|
|
2358
|
-
const nonLinkMarks = marks.filter((m) => m.type.name !== "hyperlink");
|
|
2356
|
+
const nonLinkMarks = marks.filter((m) => m.type.name !== "hyperlink" && m.type.name !== "hyphenElement");
|
|
2359
2357
|
if (nonLinkMarks.length === 0) return "";
|
|
2360
2358
|
return nonLinkMarks.map((m) => `${m.type.name}:${JSON.stringify(m.attrs)}`).toSorted().join("|");
|
|
2361
2359
|
}
|
|
@@ -2526,6 +2524,23 @@ function createNoteReferenceRun(noteRefMark, marks, formattingContext) {
|
|
|
2526
2524
|
restoreRunRecord(run, marks);
|
|
2527
2525
|
return run;
|
|
2528
2526
|
}
|
|
2527
|
+
/**
|
|
2528
|
+
* The run content one ProseMirror text leaf writes.
|
|
2529
|
+
*
|
|
2530
|
+
* Text by default; a leaf carrying the hyphen-element mark writes its
|
|
2531
|
+
* carriers back as the elements they were read from.
|
|
2532
|
+
*/
|
|
2533
|
+
function textLeafRunContent(text, marks) {
|
|
2534
|
+
if (marks.some(({ type }) => type.name === "hyphenElement")) return hyphenElementRunContent(text);
|
|
2535
|
+
return [{
|
|
2536
|
+
type: "text",
|
|
2537
|
+
text
|
|
2538
|
+
}];
|
|
2539
|
+
}
|
|
2540
|
+
/** Content an ordinary text run may hold and still join the next text leaf. */
|
|
2541
|
+
function isTextLeafContent(content) {
|
|
2542
|
+
return content.type === "text" || content.type === "softHyphen" || content.type === "noBreakHyphen";
|
|
2543
|
+
}
|
|
2529
2544
|
function createRunFromText({ baseParagraphFormatting, inheritedFormatting, marks, paragraphMarkFormatting, paragraphMarkPrecedesStyle, styleResolver, text }) {
|
|
2530
2545
|
const formatting = getRunFormattingFromMarks(marks, {
|
|
2531
2546
|
baseParagraphFormatting,
|
|
@@ -2536,10 +2551,7 @@ function createRunFromText({ baseParagraphFormatting, inheritedFormatting, marks
|
|
|
2536
2551
|
});
|
|
2537
2552
|
const run = {
|
|
2538
2553
|
type: "run",
|
|
2539
|
-
content:
|
|
2540
|
-
type: "text",
|
|
2541
|
-
text
|
|
2542
|
-
}]
|
|
2554
|
+
content: textLeafRunContent(text, marks)
|
|
2543
2555
|
};
|
|
2544
2556
|
if (formatting) run.formatting = formatting;
|
|
2545
2557
|
restoreRunRecord(run, marks);
|
|
@@ -2876,11 +2888,37 @@ const reconcileEmptyFieldResultRuns = (runs, displayRun) => {
|
|
|
2876
2888
|
}
|
|
2877
2889
|
return reconciled;
|
|
2878
2890
|
};
|
|
2879
|
-
|
|
2880
|
-
|
|
2891
|
+
/**
|
|
2892
|
+
* A result without its hyphen elements, and without a run that held nothing
|
|
2893
|
+
* else. They are part of the text a new display text replaces.
|
|
2894
|
+
*/
|
|
2895
|
+
const withoutHyphenElements = (items) => items.filter((item) => {
|
|
2896
|
+
switch (item.type) {
|
|
2897
|
+
case "run": {
|
|
2898
|
+
const kept = item.content.filter(({ type }) => type !== "softHyphen" && type !== "noBreakHyphen");
|
|
2899
|
+
if (kept.length === item.content.length) return true;
|
|
2900
|
+
item.content = kept;
|
|
2901
|
+
return kept.length > 0;
|
|
2902
|
+
}
|
|
2903
|
+
case "hyperlink":
|
|
2904
|
+
item.children = withoutHyphenElements(item.children);
|
|
2905
|
+
return true;
|
|
2906
|
+
case "inlineWrapper":
|
|
2907
|
+
case "insertion":
|
|
2908
|
+
case "deletion":
|
|
2909
|
+
case "moveFrom":
|
|
2910
|
+
case "moveTo":
|
|
2911
|
+
item.content = withoutHyphenElements(item.content);
|
|
2912
|
+
return true;
|
|
2913
|
+
default: return true;
|
|
2914
|
+
}
|
|
2915
|
+
});
|
|
2916
|
+
const synchronizeFieldDisplayText = (fieldContent, displayText, fallbackRun) => {
|
|
2917
|
+
if (getFindParagraphText({
|
|
2881
2918
|
type: "paragraph",
|
|
2882
|
-
content
|
|
2883
|
-
});
|
|
2919
|
+
content: fieldContent
|
|
2920
|
+
}) === displayText) return fieldContent;
|
|
2921
|
+
const content = withoutHyphenElements(fieldContent);
|
|
2884
2922
|
const visitRunsIn = (items, visit) => {
|
|
2885
2923
|
for (const child of items) {
|
|
2886
2924
|
if (child.type === "run") {
|
|
@@ -2893,7 +2931,6 @@ const synchronizeFieldDisplayText = (content, displayText, fallbackRun) => {
|
|
|
2893
2931
|
const visitRuns = (visit) => {
|
|
2894
2932
|
visitRunsIn(content, visit);
|
|
2895
2933
|
};
|
|
2896
|
-
if (currentText === displayText) return content;
|
|
2897
2934
|
let replacedText = false;
|
|
2898
2935
|
visitRuns((run) => {
|
|
2899
2936
|
for (const runContent of run.content) {
|
|
@@ -1,5 +1,27 @@
|
|
|
1
|
+
import { document_d_exports } from "../../types/document.js";
|
|
1
2
|
/** These source units render as native text while keeping one logical atom each. */
|
|
2
3
|
export declare const HYPHEN_TEXT_CARRIERS: {
|
|
3
4
|
readonly softHyphen: "";
|
|
4
5
|
readonly noBreakHyphen: "‑";
|
|
5
|
-
};
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* The mark that tells a carrier written for `w:softHyphen` or
|
|
9
|
+
* `w:noBreakHyphen` apart from the same character authored inside `w:t`.
|
|
10
|
+
*
|
|
11
|
+
* Both render identically, so the text alone cannot say which one the source
|
|
12
|
+
* held; the save leg reads this mark to write each back as it was read.
|
|
13
|
+
*/
|
|
14
|
+
export declare const HYPHEN_ELEMENT_MARK_NAME = "hyphenElement";
|
|
15
|
+
type HyphenElementRunContent = document_d_exports.TextContent | document_d_exports.SoftHyphenContent | document_d_exports.NoBreakHyphenContent;
|
|
16
|
+
/**
|
|
17
|
+
* The run content a leaf carrying {@link HYPHEN_ELEMENT_MARK_NAME} writes back.
|
|
18
|
+
*
|
|
19
|
+
* Each carrier becomes its element again and any other character stays text.
|
|
20
|
+
* Typing does not normally reach a marked leaf: the mark is not inclusive and
|
|
21
|
+
* neighbouring carriers hold different ids. Ids only repeat when a copy is pasted
|
|
22
|
+
* beside its source or two paragraphs join; a character typed exactly between
|
|
23
|
+
* two such carriers takes the mark, so a letter stays text here and a typed
|
|
24
|
+
* U+00AD or U+2011 saves as the element.
|
|
25
|
+
*/
|
|
26
|
+
export declare const hyphenElementRunContent: (text: string) => HyphenElementRunContent[];
|
|
27
|
+
export {};
|
|
@@ -4,4 +4,49 @@ const HYPHEN_TEXT_CARRIERS = {
|
|
|
4
4
|
softHyphen: "",
|
|
5
5
|
noBreakHyphen: "‑"
|
|
6
6
|
};
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The mark that tells a carrier written for `w:softHyphen` or
|
|
9
|
+
* `w:noBreakHyphen` apart from the same character authored inside `w:t`.
|
|
10
|
+
*
|
|
11
|
+
* Both render identically, so the text alone cannot say which one the source
|
|
12
|
+
* held; the save leg reads this mark to write each back as it was read.
|
|
13
|
+
*/
|
|
14
|
+
const HYPHEN_ELEMENT_MARK_NAME = "hyphenElement";
|
|
15
|
+
const isHyphenElementType = (key) => Object.hasOwn(HYPHEN_TEXT_CARRIERS, key);
|
|
16
|
+
/** The inverse of {@link HYPHEN_TEXT_CARRIERS}, derived so the two cannot drift. */
|
|
17
|
+
const HYPHEN_ELEMENT_BY_CARRIER = new Map(Object.keys(HYPHEN_TEXT_CARRIERS).filter(isHyphenElementType).map((type) => [HYPHEN_TEXT_CARRIERS[type], type]));
|
|
18
|
+
/**
|
|
19
|
+
* The run content a leaf carrying {@link HYPHEN_ELEMENT_MARK_NAME} writes back.
|
|
20
|
+
*
|
|
21
|
+
* Each carrier becomes its element again and any other character stays text.
|
|
22
|
+
* Typing does not normally reach a marked leaf: the mark is not inclusive and
|
|
23
|
+
* neighbouring carriers hold different ids. Ids only repeat when a copy is pasted
|
|
24
|
+
* beside its source or two paragraphs join; a character typed exactly between
|
|
25
|
+
* two such carriers takes the mark, so a letter stays text here and a typed
|
|
26
|
+
* U+00AD or U+2011 saves as the element.
|
|
27
|
+
*/
|
|
28
|
+
const hyphenElementRunContent = (text) => {
|
|
29
|
+
const content = [];
|
|
30
|
+
let pending = "";
|
|
31
|
+
for (const char of text) {
|
|
32
|
+
const type = HYPHEN_ELEMENT_BY_CARRIER.get(char);
|
|
33
|
+
if (type === void 0) {
|
|
34
|
+
pending += char;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (pending.length > 0) {
|
|
38
|
+
content.push({
|
|
39
|
+
type: "text",
|
|
40
|
+
text: pending
|
|
41
|
+
});
|
|
42
|
+
pending = "";
|
|
43
|
+
}
|
|
44
|
+
content.push({ type });
|
|
45
|
+
}
|
|
46
|
+
if (pending.length > 0) content.push({
|
|
47
|
+
type: "text",
|
|
48
|
+
text: pending
|
|
49
|
+
});
|
|
50
|
+
return content;
|
|
51
|
+
};
|
|
52
|
+
export { HYPHEN_ELEMENT_MARK_NAME, HYPHEN_TEXT_CARRIERS, hyphenElementRunContent };
|
|
@@ -50,17 +50,17 @@ import { lineSpacingProvenanceFromSpacing } from "../paragraphSpacing.js";
|
|
|
50
50
|
import { isRunContentProjectionNode } from "../runContentProjection.js";
|
|
51
51
|
import { RUN_IDENTITY_MARK_NAME, hasRunIdentityPayload, runIdentityAttrs } from "../runIdentity.js";
|
|
52
52
|
import { continueSourceCarrierIdentitiesAcrossInsertedParagraphMarks, continueSourceCarrierIdentitiesAcrossRevisions } from "../runIdentityAcrossRevisions.js";
|
|
53
|
-
import { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, isParagraphMarkSuppressionEligible, resolveParagraphInheritedRunFormatting,
|
|
53
|
+
import { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, isParagraphMarkSuppressionEligible, resolveParagraphInheritedRunFormatting, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
|
|
54
54
|
import { schema } from "../schema/index.js";
|
|
55
55
|
import { PRESERVED_XML_LEVELS } from "../schema/nodes.js";
|
|
56
|
-
import { extractTableParagraphOverlay, paragraphStyleCascadeAttrs, resolveRunFormattingWithoutDefaults } from "../styles/paragraphStyleCascade.js";
|
|
56
|
+
import { extractTableParagraphOverlay, inheritableParagraphMarkFormatting, paragraphStyleCascadeAttrs, resolveRunFormattingWithoutDefaults } from "../styles/paragraphStyleCascade.js";
|
|
57
57
|
import { listIndentationProvenancePatch } from "../styles/resolvedStyleAttrs.js";
|
|
58
58
|
import { cascadeStyleTextFormatting } from "../styles/styleToggleCascade.js";
|
|
59
59
|
import { tableCellStyleRegions, tableRowBand } from "../styles/tableStyleRegions.js";
|
|
60
60
|
import { canCarryTrackedRunMark, trackedRunInlineAtomDisposition } from "../trackedRunInlineAtoms.js";
|
|
61
61
|
import { assertValidProseMirrorDocument } from "../validation.js";
|
|
62
62
|
import { resolveEffectiveTableCellFormatting } from "./effectiveTableCellFormatting.js";
|
|
63
|
-
import { HYPHEN_TEXT_CARRIERS } from "./hyphenTextCarriers.js";
|
|
63
|
+
import { HYPHEN_ELEMENT_MARK_NAME, HYPHEN_TEXT_CARRIERS } from "./hyphenTextCarriers.js";
|
|
64
64
|
import { createMarkInterner } from "./markInterner.js";
|
|
65
65
|
import { hasSinkChildren } from "./preservedSinkCarriers.js";
|
|
66
66
|
import { sdtAttrsFromProperties } from "./sdtAttrs.js";
|
|
@@ -425,8 +425,10 @@ const resolveListRendering = (numPr, context) => {
|
|
|
425
425
|
function convertParagraph(paragraph, styleResolver, context, extraRunFormatting, tableParagraphOverlay, textBoxAnchors) {
|
|
426
426
|
const { nextHyperlinkInstanceIndex, pairedBookmarkIds, pageBreakRunSourceDescendants, storyRangedCommentIds, openCommentIds } = context;
|
|
427
427
|
let runIdentityId = 0;
|
|
428
|
+
let hyphenElementId = 0;
|
|
428
429
|
const runScope = {
|
|
429
430
|
nextRunIdentityId: () => runIdentityId++,
|
|
431
|
+
nextHyphenElementId: () => hyphenElementId++,
|
|
430
432
|
nextNoteReferenceOccurrenceId: context.nextNoteReferenceOccurrenceId,
|
|
431
433
|
createMark: context.createMark
|
|
432
434
|
};
|
|
@@ -500,9 +502,11 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
|
|
|
500
502
|
if (!node) return;
|
|
501
503
|
emitInlineNodes([node]);
|
|
502
504
|
};
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
|
|
505
|
+
const inheritableParagraphRunFormatting = isTocParagraph ? void 0 : inheritableParagraphMarkFormatting({
|
|
506
|
+
runProperties: paragraph.formatting?.runProperties,
|
|
507
|
+
styleId: paragraph.formatting?.styleId,
|
|
508
|
+
styleResolver
|
|
509
|
+
});
|
|
506
510
|
const { baseFormatting: baseRunFormatting, baseToggleCascade: orderedToggleFormatting, defaultFormatting: ordinaryBaseWithDefaultCharacter, defaultToggleCascade: defaultCharacterStyleCascade, inheritedFormatting: defaultRunFormatting, inheritedToggleCascade: defaultToggleCascade } = resolveParagraphInheritedRunFormatting({
|
|
507
511
|
styleId: paragraph.formatting?.styleId,
|
|
508
512
|
tableRunFormatting: extraRunFormatting,
|
|
@@ -1739,6 +1743,7 @@ function convertRun(run, resolvedStyleFormatting, runScope, styleResolver, textB
|
|
|
1739
1743
|
formatting: mergedFormatting,
|
|
1740
1744
|
textBoxAnchors,
|
|
1741
1745
|
authoredFormatting: run.formatting,
|
|
1746
|
+
nextHyphenElementId: runScope.nextHyphenElementId,
|
|
1742
1747
|
nextNoteReferenceOccurrenceId: runScope.nextNoteReferenceOccurrenceId
|
|
1743
1748
|
});
|
|
1744
1749
|
for (const node of contentNodes) if (!isRunContentProjectionNode(content.type, node.type.name)) panic(`Run content ${content.type} projected unsupported inline node ${node.type.name}`);
|
|
@@ -2147,7 +2152,7 @@ const noteReferenceVertAlign = (vertAlign) => {
|
|
|
2147
2152
|
* run was authored with.
|
|
2148
2153
|
*/
|
|
2149
2154
|
const carriedRunFormatting = (formatting) => formatting && Object.keys(formatting).length > 0 ? formatting : void 0;
|
|
2150
|
-
function convertRunContent({ content, marks, formatting, textBoxAnchors, authoredFormatting, nextNoteReferenceOccurrenceId }) {
|
|
2155
|
+
function convertRunContent({ content, marks, formatting, textBoxAnchors, authoredFormatting, nextHyphenElementId, nextNoteReferenceOccurrenceId }) {
|
|
2151
2156
|
switch (content.type) {
|
|
2152
2157
|
case "noteMarker": return [schema.node("noteMarker", { kind: content.kind }).mark(marks)];
|
|
2153
2158
|
case "text":
|
|
@@ -2214,8 +2219,8 @@ function convertRunContent({ content, marks, formatting, textBoxAnchors, authore
|
|
|
2214
2219
|
text: content.text,
|
|
2215
2220
|
level: PRESERVED_XML_LEVELS.run
|
|
2216
2221
|
}).mark(marks)];
|
|
2217
|
-
case "noBreakHyphen":
|
|
2218
|
-
case "softHyphen": return [schema.text(HYPHEN_TEXT_CARRIERS.
|
|
2222
|
+
case "noBreakHyphen":
|
|
2223
|
+
case "softHyphen": return [schema.text(HYPHEN_TEXT_CARRIERS[content.type], [...marks, schema.mark(HYPHEN_ELEMENT_MARK_NAME, { id: nextHyphenElementId() })])];
|
|
2219
2224
|
case "symbol": return [schema.node("symbol", {
|
|
2220
2225
|
font: content.font,
|
|
2221
2226
|
char: content.char
|
|
@@ -2459,6 +2464,7 @@ function convertHyperlink(hyperlink, { getInheritedRunFormatting, styleResolver,
|
|
|
2459
2464
|
formatting: mergedFormatting,
|
|
2460
2465
|
textBoxAnchors,
|
|
2461
2466
|
authoredFormatting: child.formatting,
|
|
2467
|
+
nextHyphenElementId: runScope.nextHyphenElementId,
|
|
2462
2468
|
nextNoteReferenceOccurrenceId: runScope.nextNoteReferenceOccurrenceId
|
|
2463
2469
|
}));
|
|
2464
2470
|
break;
|
|
@@ -69,7 +69,7 @@ function createStarterKit(options = {}) {
|
|
|
69
69
|
...options.historyNewGroupDelay !== void 0 ? { newGroupDelay: options.historyNewGroupDelay } : {},
|
|
70
70
|
...options.historyShortcuts !== void 0 ? { shortcuts: options.historyShortcuts } : {}
|
|
71
71
|
}));
|
|
72
|
-
for (const name of MARK_NESTING_ORDER) add(name, MARK_EXTENSIONS[name]());
|
|
72
|
+
for (const name of MARK_NESTING_ORDER) add(name, MARK_EXTENSIONS[name]({ getInternalClipboardToken }));
|
|
73
73
|
add("bookmarkBoundary", BookmarkBoundaryExtension({ getInternalClipboardToken }));
|
|
74
74
|
add("blockBookmarkBoundary", BlockBookmarkBoundaryExtension({ getInternalClipboardToken }));
|
|
75
75
|
add("blockMoveRangeBoundary", BlockMoveRangeBoundaryExtension({ getInternalClipboardToken }));
|
|
@@ -124,6 +124,7 @@ const EMPTY_SPAN = new RegExp(`<span(?:\\s${TAG_TAIL})?><\\/span>`, "gi");
|
|
|
124
124
|
const MAX_EMPTY_SPAN_PASSES = 5;
|
|
125
125
|
const INTERNAL_CLIPBOARD_ATTR_PATTERN = /\s+data-docx-internal-clipboard(?:="([^"]*)"|='([^']*)'|=([^\s>]+))?/gi;
|
|
126
126
|
const TEXTBOX_ANCHOR_ATTR = /\s+data-docx-textbox-anchor(?:="[^"]*"|='[^']*')?/gi;
|
|
127
|
+
const HYPHEN_ELEMENT_ATTR = /\s+data-docx-hyphen-element(?:="[^"]*"|='[^']*'|=[^\s>]+)?/gi;
|
|
127
128
|
const BOOKMARK_BOUNDARY_ATTR = /\s+data-docx-bookmark-(?:boundary|id|name|col-first|col-last)(?:="[^"]*"|='[^']*'|=[^\s>]+)?/gi;
|
|
128
129
|
const RANGE_ANCHOR_ATTR = /\s+data-docx-range-anchor(?:="[^"]*"|='[^']*'|=[^\s>]+)?/gi;
|
|
129
130
|
const COMMENT_RANGE_BOUNDARY_ATTR = /\s+data-docx-comment-range-boundary(?:="[^"]*"|='[^']*'|=[^\s>]+)?/gi;
|
|
@@ -145,6 +146,10 @@ function stripForeignTextBoxAnchors(html, internal) {
|
|
|
145
146
|
if (internal) return html;
|
|
146
147
|
return html.replace(TEXTBOX_ANCHOR_ATTR, "");
|
|
147
148
|
}
|
|
149
|
+
function stripForeignHyphenElements(html, internal) {
|
|
150
|
+
if (internal) return html;
|
|
151
|
+
return html.replace(HYPHEN_ELEMENT_ATTR, "");
|
|
152
|
+
}
|
|
148
153
|
function stripForeignBookmarkBoundaries(html, internal) {
|
|
149
154
|
if (internal) return html;
|
|
150
155
|
return html.replace(BOOKMARK_BOUNDARY_ATTR, "");
|
|
@@ -187,6 +192,7 @@ function cleanPastedHtml(html, options = {}) {
|
|
|
187
192
|
cleaned = stripMsoStyles(cleaned);
|
|
188
193
|
cleaned = stripEmptySpans(cleaned, internal);
|
|
189
194
|
cleaned = stripForeignTextBoxAnchors(cleaned, internal);
|
|
195
|
+
cleaned = stripForeignHyphenElements(cleaned, internal);
|
|
190
196
|
cleaned = stripForeignBookmarkBoundaries(cleaned, internal);
|
|
191
197
|
cleaned = stripForeignRangeCarriers(cleaned, internal);
|
|
192
198
|
cleaned = stripForeignStructuredFields(cleaned, internal);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { mintListInstance } from "../../../docx/listNumberingInstances.js";
|
|
2
|
+
import { NO_NUMBERING_IDS_IN_USE } from "../../../docx/numberingIds.js";
|
|
2
3
|
import { createNumberingMap } from "../../../docx/numberingParser.js";
|
|
3
4
|
import { expectParagraphAttrs } from "../../attrs/index.js";
|
|
4
5
|
import { completeNumberingForDoc } from "../../listInstanceReferences.js";
|
|
@@ -93,7 +94,7 @@ const numberPastedHtmlLists = (slice, view) => {
|
|
|
93
94
|
const minted = mintListInstance(definitions, {
|
|
94
95
|
kind: hint.kind,
|
|
95
96
|
...hint.start === void 0 ? {} : { start: hint.start }
|
|
96
|
-
});
|
|
97
|
+
}, NO_NUMBERING_IDS_IN_USE);
|
|
97
98
|
definitions = minted.definitions;
|
|
98
99
|
numbering = createNumberingMap(definitions);
|
|
99
100
|
group = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MarkExtension } from "./types.js";
|
|
2
|
+
import { HyphenElementExtension } from "./marks/HyphenElementExtension.js";
|
|
2
3
|
export declare const MARK_EXTENSIONS: {
|
|
3
4
|
readonly bold: (options?: Partial<Record<string, unknown>> | undefined) => MarkExtension;
|
|
4
5
|
readonly italic: (options?: Partial<Record<string, unknown>> | undefined) => MarkExtension;
|
|
@@ -27,6 +28,7 @@ export declare const MARK_EXTENSIONS: {
|
|
|
27
28
|
readonly textEffect: (options?: Partial<Record<string, unknown>> | undefined) => MarkExtension;
|
|
28
29
|
readonly runFormattingOverride: (options?: Partial<Record<string, unknown>> | undefined) => MarkExtension;
|
|
29
30
|
readonly characterStyle: (options?: Partial<Record<string, unknown>> | undefined) => MarkExtension;
|
|
31
|
+
readonly hyphenElement: typeof HyphenElementExtension;
|
|
30
32
|
readonly runIdentity: (options?: Partial<Record<string, unknown>> | undefined) => MarkExtension;
|
|
31
33
|
readonly comment: (options?: Partial<Record<string, unknown>> | undefined) => MarkExtension;
|
|
32
34
|
readonly insertion: (options?: Partial<Record<string, unknown>> | undefined) => MarkExtension;
|
|
@@ -56,4 +58,4 @@ export type SchemaMarkName = keyof typeof MARK_EXTENSIONS;
|
|
|
56
58
|
* own in OOXML, so the save leg ranks it against nothing and its place here is
|
|
57
59
|
* a presentation decision.
|
|
58
60
|
*/
|
|
59
|
-
export declare const MARK_NESTING_ORDER: readonly ["bold", "italic", "underline", "strike", "textColor", "runShading", "highlight", "fontSize", "fontFamily", "language", "superscript", "subscript", "allCaps", "smallCaps", "footnoteRef", "characterSpacing", "emboss", "imprint", "hidden", "textShadow", "emphasisMark", "textOutline", "rtl", "textEffect", "runFormattingOverride", "characterStyle", "comment", "inlineWrapper", "insertion", "deletion", "hyperlink", "runPropertyChange", "runIdentity"];
|
|
61
|
+
export declare const MARK_NESTING_ORDER: readonly ["bold", "italic", "underline", "strike", "textColor", "runShading", "highlight", "fontSize", "fontFamily", "language", "superscript", "subscript", "allCaps", "smallCaps", "footnoteRef", "characterSpacing", "emboss", "imprint", "hidden", "textShadow", "emphasisMark", "textOutline", "rtl", "textEffect", "runFormattingOverride", "characterStyle", "hyphenElement", "comment", "inlineWrapper", "insertion", "deletion", "hyperlink", "runPropertyChange", "runIdentity"];
|
|
@@ -9,6 +9,7 @@ import { FootnoteRefExtension } from "./marks/FootnoteRefExtension.js";
|
|
|
9
9
|
import { HiddenTextExtension } from "./marks/HiddenTextExtension.js";
|
|
10
10
|
import { HighlightExtension } from "./marks/HighlightExtension.js";
|
|
11
11
|
import { HyperlinkExtension } from "./marks/HyperlinkExtension.js";
|
|
12
|
+
import { HyphenElementExtension } from "./marks/HyphenElementExtension.js";
|
|
12
13
|
import { InlineWrapperExtension } from "./marks/InlineWrapperExtension.js";
|
|
13
14
|
import { ItalicExtension } from "./marks/ItalicExtension.js";
|
|
14
15
|
import { LanguageExtension } from "./marks/LanguageExtension.js";
|
|
@@ -67,6 +68,7 @@ const MARK_EXTENSIONS = {
|
|
|
67
68
|
textEffect: TextEffectExtension,
|
|
68
69
|
runFormattingOverride: RunFormattingOverrideExtension,
|
|
69
70
|
characterStyle: CharacterStyleExtension,
|
|
71
|
+
hyphenElement: HyphenElementExtension,
|
|
70
72
|
runIdentity: RunIdentityExtension,
|
|
71
73
|
comment: CommentExtension,
|
|
72
74
|
insertion: InsertionExtension,
|
|
@@ -123,6 +125,7 @@ const MARK_NESTING_ORDER = markNestingOrder([
|
|
|
123
125
|
"textEffect",
|
|
124
126
|
"runFormattingOverride",
|
|
125
127
|
"characterStyle",
|
|
128
|
+
"hyphenElement",
|
|
126
129
|
"comment",
|
|
127
130
|
"inlineWrapper",
|
|
128
131
|
"insertion",
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { HYPHEN_ELEMENT_MARK_NAME } from "../../conversion/hyphenTextCarriers.js";
|
|
2
|
+
import { expectHyphenElementMarkAttrs } from "../../hyphenElementAttrs.js";
|
|
3
|
+
import { createMarkExtension } from "../create.js";
|
|
4
|
+
// src/prosemirror/extensions/marks/HyphenElementExtension.ts
|
|
5
|
+
/**
|
|
6
|
+
* Marks the native text that stands for a `w:softHyphen` or `w:noBreakHyphen`
|
|
7
|
+
* run child (ECMA-376 Part 1, 17.3.3.29 and 17.3.3.18).
|
|
8
|
+
*
|
|
9
|
+
* The editor renders both elements as their Unicode characters so line
|
|
10
|
+
* breaking and measurement treat them as text. The same characters may also be
|
|
11
|
+
* authored inside `w:t`, so without this mark the save leg could not tell
|
|
12
|
+
* which of the two the source held. Nothing is painted for it.
|
|
13
|
+
*
|
|
14
|
+
* Not inclusive, and each carrier in a paragraph has its own `id`: ProseMirror
|
|
15
|
+
* keeps a non-inclusive mark only where both neighbours hold an equal mark, so
|
|
16
|
+
* distinct ids mean a character typed beside or between carriers is text. The
|
|
17
|
+
* ids only tell neighbours apart. They can repeat after a paste beside the
|
|
18
|
+
* source or a paragraph join, which `hyphenElementRunContent` describes.
|
|
19
|
+
*
|
|
20
|
+
* External HTML must not be able to claim the element: `cleanPastedHtml` strips
|
|
21
|
+
* the attribute unless the slice carries the internal clipboard capability, so
|
|
22
|
+
* `toDOM` stamps that capability on every carrier it writes.
|
|
23
|
+
*/
|
|
24
|
+
const HYPHEN_ELEMENT_ATTRIBUTE = "data-docx-hyphen-element";
|
|
25
|
+
const CANONICAL_HYPHEN_ELEMENT_ID = /^(?:0|[1-9]\d*)$/u;
|
|
26
|
+
const HyphenElementExtension = createMarkExtension({
|
|
27
|
+
name: HYPHEN_ELEMENT_MARK_NAME,
|
|
28
|
+
schemaMarkName: HYPHEN_ELEMENT_MARK_NAME,
|
|
29
|
+
markSpec: (options) => ({
|
|
30
|
+
attrs: { id: {} },
|
|
31
|
+
inclusive: false,
|
|
32
|
+
parseDOM: [{
|
|
33
|
+
tag: `span[${HYPHEN_ELEMENT_ATTRIBUTE}]`,
|
|
34
|
+
getAttrs(dom) {
|
|
35
|
+
const rawId = dom.getAttribute(HYPHEN_ELEMENT_ATTRIBUTE);
|
|
36
|
+
if (rawId === null || !CANONICAL_HYPHEN_ELEMENT_ID.test(rawId)) return false;
|
|
37
|
+
const id = Number(rawId);
|
|
38
|
+
return Number.isSafeInteger(id) ? { id } : false;
|
|
39
|
+
}
|
|
40
|
+
}],
|
|
41
|
+
toDOM(mark) {
|
|
42
|
+
const { id } = expectHyphenElementMarkAttrs(mark);
|
|
43
|
+
return [
|
|
44
|
+
"span",
|
|
45
|
+
{
|
|
46
|
+
[HYPHEN_ELEMENT_ATTRIBUTE]: String(id),
|
|
47
|
+
...options.getInternalClipboardToken ? { "data-docx-internal-clipboard": options.getInternalClipboardToken() } : {}
|
|
48
|
+
},
|
|
49
|
+
0
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
});
|
|
54
|
+
export { HyphenElementExtension };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import "./conversion/hyphenTextCarriers.js";
|
|
1
2
|
import "./extensions/marks/InlineWrapperExtension.js";
|
|
2
3
|
import { getInlineDisplayText } from "./inlineDisplayText.js";
|
|
3
4
|
import "./runIdentity.js";
|
|
@@ -11,7 +12,7 @@ const fieldCommentCoverage = (fieldKind) => FIELD_COMMENT_COVERAGE[fieldKind];
|
|
|
11
12
|
/** Current children alone decide whether a field needs editable structural content. */
|
|
12
13
|
const fieldRequiresStructuredContent = (children) => {
|
|
13
14
|
const first = children.at(0);
|
|
14
|
-
return children.some((child) => !child.isText || first !== void 0 && !Mark.sameSet(first.marks, child.marks) || child.marks.some((mark) => mark.type.name === "runIdentity" || mark.type.name === "footnoteRef" || mark.type.name === "hyperlink" || mark.type.name === "inlineWrapper" || mark.type.name === "insertion" || mark.type.name === "deletion"));
|
|
15
|
+
return children.some((child) => !child.isText || first !== void 0 && !Mark.sameSet(first.marks, child.marks) || child.marks.some((mark) => mark.type.name === "runIdentity" || mark.type.name === "hyphenElement" || mark.type.name === "footnoteRef" || mark.type.name === "hyperlink" || mark.type.name === "inlineWrapper" || mark.type.name === "insertion" || mark.type.name === "deletion"));
|
|
15
16
|
};
|
|
16
17
|
/** Resolution collapses a field only when the atom can retain its result. */
|
|
17
18
|
const canonicalFieldNode = (node) => {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ReadProseMirrorAttrsResult } from "../internal/prosemirrorAttrBoundary.js";
|
|
2
|
+
import "./attrs/index.js";
|
|
3
|
+
import { Mark } from "prosemirror-model";
|
|
4
|
+
type HyphenElementMarkAttrs = {
|
|
5
|
+
/** Tells this carrier from its neighbours. Monotonic within one paragraph. */
|
|
6
|
+
id: number;
|
|
7
|
+
};
|
|
8
|
+
export declare const readHyphenElementMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<HyphenElementMarkAttrs>;
|
|
9
|
+
export declare const expectHyphenElementMarkAttrs: (mark: Mark) => HyphenElementMarkAttrs;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { panic } from "better-result";
|
|
2
|
+
// src/prosemirror/hyphenElementAttrs.ts
|
|
3
|
+
const readHyphenElementMarkAttrs = (mark) => {
|
|
4
|
+
const id = mark.attrs["id"];
|
|
5
|
+
if (mark.type.name !== "hyphenElement") return {
|
|
6
|
+
ok: false,
|
|
7
|
+
issues: [{
|
|
8
|
+
path: "mark.type.name",
|
|
9
|
+
message: `Expected hyphenElement, got ${mark.type.name}.`
|
|
10
|
+
}]
|
|
11
|
+
};
|
|
12
|
+
if (typeof id !== "number" || !Number.isSafeInteger(id) || id < 0) return {
|
|
13
|
+
ok: false,
|
|
14
|
+
issues: [{
|
|
15
|
+
path: "hyphenElement.attrs.id",
|
|
16
|
+
message: "Expected a non-negative safe integer."
|
|
17
|
+
}]
|
|
18
|
+
};
|
|
19
|
+
return {
|
|
20
|
+
ok: true,
|
|
21
|
+
value: { id }
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
const expectHyphenElementMarkAttrs = (mark) => {
|
|
25
|
+
const result = readHyphenElementMarkAttrs(mark);
|
|
26
|
+
if (!result.ok) {
|
|
27
|
+
const details = result.issues.map((issue) => `${issue.path}: ${issue.message}`).join("\n");
|
|
28
|
+
panic(`Invalid ProseMirror hyphen element attrs:\n${details}`);
|
|
29
|
+
}
|
|
30
|
+
return result.value;
|
|
31
|
+
};
|
|
32
|
+
export { expectHyphenElementMarkAttrs, readHyphenElementMarkAttrs };
|
|
@@ -6,6 +6,8 @@ import { Transaction } from "prosemirror-state";
|
|
|
6
6
|
type BoundaryItem = Extract<document_d_exports.ParagraphContent, {
|
|
7
7
|
type: "bookmarkStart" | "bookmarkEnd" | "commentRangeStart" | "commentRangeEnd" | "moveFromRangeStart" | "moveFromRangeEnd" | "moveToRangeStart" | "moveToRangeEnd";
|
|
8
8
|
}>;
|
|
9
|
+
/** The marks that say a node is in a revision: its wrappers, in the engine. */
|
|
10
|
+
export declare const REVISION_MARK_NAMES: ReadonlySet<string>;
|
|
9
11
|
/** The range boundaries `node` carries; none for any other node. */
|
|
10
12
|
export declare const rangeBoundaryItemsOf: (node: Node) => readonly BoundaryItem[];
|
|
11
13
|
/** Range boundary nodes, as the nodes that stand for them between blocks. */
|
|
@@ -377,4 +377,4 @@ const removeResolvedSubtree = (node, selection) => {
|
|
|
377
377
|
if (selection.mode === "reject") visit(node);
|
|
378
378
|
return { kept };
|
|
379
379
|
};
|
|
380
|
-
export { blockBoundariesOf, carriesCommentAnchor, inlineBoundariesOf, isBlockBoundaryNode, normalizeKeptRangeBoundaries, paragraphRemainsOf, rangeBoundaryItemsOf, removeResolvedSubtree, revisionLayerRemovesContent };
|
|
380
|
+
export { REVISION_MARK_NAMES, blockBoundariesOf, carriesCommentAnchor, inlineBoundariesOf, isBlockBoundaryNode, normalizeKeptRangeBoundaries, paragraphRemainsOf, rangeBoundaryItemsOf, removeResolvedSubtree, revisionLayerRemovesContent };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { mintListInstance, restartListInstance } from "../docx/listNumberingInstances.js";
|
|
2
|
+
import { NO_NUMBERING_IDS_IN_USE } from "../docx/numberingIds.js";
|
|
2
3
|
import { createNumberingMap, isBulletLevel } from "../docx/numberingParser.js";
|
|
3
4
|
import { paragraphNumberingReferenceId } from "../docx/numberingReference.js";
|
|
4
5
|
import { expectParagraphAttrs } from "./attrs/index.js";
|
|
@@ -179,7 +180,7 @@ const resolveListTarget = ({ numbering, $from, $to, requests }) => {
|
|
|
179
180
|
ilvl: 0,
|
|
180
181
|
numbering
|
|
181
182
|
};
|
|
182
|
-
const minted = mintListInstance(numbering?.definitions, first);
|
|
183
|
+
const minted = mintListInstance(numbering?.definitions, first, NO_NUMBERING_IDS_IN_USE);
|
|
183
184
|
return {
|
|
184
185
|
numId: minted.numId,
|
|
185
186
|
ilvl: 0,
|
|
@@ -289,7 +290,7 @@ const setNumberingValue = (value) => withCanonicalCommand((state, dispatch) => {
|
|
|
289
290
|
abstractNumId,
|
|
290
291
|
ilvl: selected.membership.ilvl,
|
|
291
292
|
start: value
|
|
292
|
-
});
|
|
293
|
+
}, NO_NUMBERING_IDS_IN_USE);
|
|
293
294
|
dispatch(moveItems({
|
|
294
295
|
state,
|
|
295
296
|
items: itemsFrom(state, selected.membership.numId, selected.pos),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { hangingFirstLineIndent } from "../utils/units.js";
|
|
1
2
|
import { effectiveParagraphNumberingReference, paragraphNumberingSourcesFromBoundary } from "./numberingAttr.js";
|
|
2
3
|
import { panic } from "better-result";
|
|
3
4
|
// src/prosemirror/paragraphIndentation.ts
|
|
@@ -70,7 +71,7 @@ const directParagraphIndentation = (attrs) => {
|
|
|
70
71
|
if (indentation.indentFirstLine !== void 0) {
|
|
71
72
|
const hanging = attrs.hangingIndent === true;
|
|
72
73
|
indentation.hangingIndent = hanging;
|
|
73
|
-
if (hanging) indentation.indentFirstLine =
|
|
74
|
+
if (hanging) indentation.indentFirstLine = hangingFirstLineIndent(indentation.indentFirstLine);
|
|
74
75
|
} else if (original?.hangingIndent !== void 0 && original.indentFirstLine === void 0 && typeof attrs.hangingIndent === "boolean") indentation.hangingIndent = attrs.hangingIndent;
|
|
75
76
|
return Object.keys(indentation).length > 0 ? indentation : void 0;
|
|
76
77
|
};
|
|
@@ -3,7 +3,6 @@ import { NumberingMap } from "../docx/numberingParser.js";
|
|
|
3
3
|
import { RunStyleResolver } from "./runStyleFormatting.js";
|
|
4
4
|
import { Node } from "prosemirror-model";
|
|
5
5
|
import { Transaction } from "prosemirror-state";
|
|
6
|
-
type RecordedFormatting = NonNullable<ParagraphPropertyChangeAttrs["previousFormatting"]>;
|
|
7
6
|
type CarryParagraphPropertiesOptions = {
|
|
8
7
|
tr: Transaction;
|
|
9
8
|
/** The paragraph that takes the properties. */
|
|
@@ -14,14 +13,7 @@ type CarryParagraphPropertiesOptions = {
|
|
|
14
13
|
numbering: NumberingMap | null;
|
|
15
14
|
/** Records the change as a tracked property change; applied directly when omitted. */
|
|
16
15
|
revision?: ParagraphPropertyChangeAttrs["info"];
|
|
17
|
-
/** Properties the paragraph keeps its own values of: ones its own batch set. */
|
|
18
|
-
keep?: ReadonlySet<string>;
|
|
19
16
|
};
|
|
20
|
-
type CarriedParagraphPropertiesOptions = Pick<CarryParagraphPropertiesOptions, "source" | "keep"> & {
|
|
21
|
-
target: Node;
|
|
22
|
-
};
|
|
23
|
-
/** The exact formatting transfer, shared with pre-mutation capacity checks. */
|
|
24
|
-
export declare const carriedParagraphProperties: ({ source, target, keep }: CarriedParagraphPropertiesOptions) => RecordedFormatting;
|
|
25
17
|
/**
|
|
26
18
|
* Give a paragraph another one's properties: the pPr a property change
|
|
27
19
|
* covers. Its identity, mark, mark run properties and section stay its own,
|
|
@@ -29,7 +21,7 @@ export declare const carriedParagraphProperties: ({ source, target, keep }: Carr
|
|
|
29
21
|
* change now records what it had: a paragraph holds one, and a pending one
|
|
30
22
|
* already records it.
|
|
31
23
|
*/
|
|
32
|
-
export declare const carryParagraphProperties: ({ tr, position, source, styleResolver, numbering, revision
|
|
24
|
+
export declare const carryParagraphProperties: ({ tr, position, source, styleResolver, numbering, revision }: CarryParagraphPropertiesOptions) => {
|
|
33
25
|
tr: Transaction;
|
|
34
26
|
changed: boolean;
|
|
35
27
|
tracked: boolean;
|
|
@@ -60,9 +52,4 @@ export declare const recordReplacedParagraphProperties: ({ tr, position, replace
|
|
|
60
52
|
replaced: Node;
|
|
61
53
|
revision: ParagraphPropertyChangeAttrs["info"];
|
|
62
54
|
}) => boolean;
|
|
63
|
-
/**
|
|
64
|
-
* The properties a batch's own property change set on a paragraph: the ones
|
|
65
|
-
* whose value differs from what that change records as before.
|
|
66
|
-
*/
|
|
67
|
-
export declare const propertiesSetInBatch: (node: Node, batchRevisionIds: ReadonlySet<number>) => ReadonlySet<string>;
|
|
68
55
|
export {};
|