@stll/folio-core 0.60.0 → 0.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/ai-edits/apply.js +139 -32
- package/dist/ai-edits/headless.d.ts +3 -0
- package/dist/ai-edits/headless.js +70 -75
- package/dist/ai-edits/note-story-inventory.d.ts +7 -0
- package/dist/ai-edits/note-story-inventory.js +11 -0
- package/dist/ai-edits/read.js +16 -9
- package/dist/ai-edits/revisionStretches.js +52 -1
- package/dist/ai-edits/table-row-column-mutations.js +6 -1
- package/dist/compare/reproducible-package.js +2 -1
- package/dist/compare/verification.js +1 -0
- package/dist/compat/eigenpal.d.ts +3 -1
- package/dist/controller/canonicalClipboard.js +2 -1
- package/dist/controller/canonicalListRendering.d.ts +4 -6
- package/dist/controller/canonicalListRendering.js +3 -157
- package/dist/controller/headerFooterEditorManager.d.ts +1 -0
- package/dist/controller/headerFooterEditorManager.js +11 -0
- package/dist/controller/hiddenEditorManager.d.ts +1 -1
- package/dist/controller/hiddenEditorManager.js +3 -1
- package/dist/controller/layoutPipeline.d.ts +3 -1
- package/dist/controller/layoutPipeline.js +13 -4
- package/dist/controller/layoutSession.d.ts +2 -1
- package/dist/controller/noteEditorManager.d.ts +1 -1
- package/dist/display-list/build/imagePrimitives.js +28 -12
- package/dist/display-list/build/paragraphPrimitives.js +15 -2
- package/dist/display-list/dom/renderDisplayListToDom.js +8 -5
- package/dist/display-list/types.d.ts +7 -3
- package/dist/docx/canonicalStoryRepack.js +3 -2
- package/dist/docx/commentTextParagraph.d.ts +6 -0
- package/dist/docx/commentTextParagraph.js +15 -0
- package/dist/docx/conformance.js +6 -1
- package/dist/docx/diagramPreview.js +2 -1
- package/dist/docx/documentParser.d.ts +13 -1
- package/dist/docx/documentParser.js +1 -1
- package/dist/docx/encryption/compoundFile.d.ts +0 -8
- package/dist/docx/encryption/compoundFile.js +2 -1
- package/dist/docx/encryption/cryptoBytes.d.ts +2 -2
- package/dist/docx/encryption/cryptoBytes.js +3 -18
- package/dist/docx/encryption/encryptionInfo.d.ts +0 -5
- package/dist/docx/encryption/encryptionInfo.js +2 -1
- package/dist/docx/ensureParaIds.js +2 -1
- package/dist/docx/groupDrawingParser.js +28 -13
- package/dist/docx/listModelNormalization.d.ts +10 -0
- package/dist/docx/listModelNormalization.js +166 -0
- package/dist/docx/metadataPrivacy.js +3 -2
- package/dist/docx/metafileRaster.js +2 -1
- package/dist/docx/packageParts.js +6 -5
- package/dist/docx/paragraphParser.js +6 -4
- package/dist/docx/parser.js +5 -4
- package/dist/docx/preservedRunContent.js +11 -2
- package/dist/docx/removeHeaderFooterParts.js +8 -7
- package/dist/docx/replyToComment.js +3 -13
- package/dist/docx/rezip.js +88 -89
- package/dist/docx/runParser.js +12 -6
- package/dist/docx/runPropertyPresence.d.ts +11 -0
- package/dist/docx/runPropertyPresence.js +14 -0
- package/dist/docx/selectiveSave.js +15 -14
- package/dist/docx/serializer/runSerializer.js +3 -2
- package/dist/docx/serializer/tableSerializer.js +2 -1
- package/dist/docx/server/applyDocxXmlPatchProposal.js +2 -2
- package/dist/docx/server/boundedArchive.js +2 -1
- package/dist/docx/server/evaluateDocxXmlPatchProposal.js +2 -1
- package/dist/docx/server/inspectDocxPackage.js +5 -1
- package/dist/docx/server/validateDocxConformance.js +2 -1
- package/dist/docx/tableParser.js +7 -4
- package/dist/docx/tableRowPropertyPresence.d.ts +9 -0
- package/dist/docx/tableRowPropertyPresence.js +15 -0
- package/dist/docx/unzip.js +2 -1
- package/dist/docx/xmlEncoding.js +6 -5
- package/dist/fonts/fontsourceFaces.js +2 -1
- package/dist/fonts/sfnt/parse.js +6 -9
- package/dist/fonts/sfnt/subset.js +2 -1
- package/dist/fonts/sfnt/tables.js +2 -3
- package/dist/fonts/sfnt/woff.js +2 -1
- 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/index.d.ts +3 -1
- package/dist/internal/revisionResolutionInline.d.ts +2 -1
- package/dist/internal/revisionResolutionInline.js +22 -1
- package/dist/internal/wholeStoryRevisionResolution.js +24 -7
- package/dist/layout-bridge/convert/endnoteLayout.d.ts +1 -1
- package/dist/layout-bridge/convert/endnoteLayout.js +1 -3
- package/dist/layout-bridge/convert/flowConversionShared.d.ts +2 -0
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +4 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +13 -3
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +5 -0
- package/dist/layout-bridge/convert/headerFooterLayout.js +12 -15
- package/dist/layout-bridge/convert/paragraphRuns.js +2 -1
- package/dist/layout-engine/index.js +2 -2
- package/dist/layout-engine/measure/crossRunWords.js +12 -2
- package/dist/layout-engine/noteAreaFlow.d.ts +4 -4
- package/dist/layout-engine/noteAreaFlow.js +12 -6
- package/dist/layout-engine/types.d.ts +5 -2
- package/dist/layout-painter/index.d.ts +1 -1
- package/dist/managers/AutoSaveManager.js +2 -1
- package/dist/managers/EditorModeManager.d.ts +10 -1
- package/dist/managers/EditorModeManager.js +15 -1
- package/dist/managers/FindReplaceManager.d.ts +13 -6
- package/dist/managers/FindReplaceManager.js +15 -9
- package/dist/managers/TableSelectionManager.d.ts +1 -1
- package/dist/managers/autoSaveCodec.js +2 -6
- package/dist/managers/reviewDisplayMode.d.ts +8 -0
- package/dist/managers/reviewDisplayMode.js +15 -0
- package/dist/paged-layout/editorScrollRoot.d.ts +3 -1
- package/dist/paged-layout/editorScrollRoot.js +2 -2
- package/dist/paged-layout/pageText.d.ts +11 -2
- package/dist/paged-layout/pageText.js +8 -3
- package/dist/pdf/fonts.js +5 -14
- package/dist/pdf/images.js +4 -2
- package/dist/pdf/objects.d.ts +0 -11
- package/dist/pdf/objects.js +7 -9
- package/dist/pdf/writePdf.js +2 -1
- package/dist/prosemirror/commands/comments.js +51 -13
- package/dist/prosemirror/commentRangeInlineAtoms.d.ts +40 -0
- package/dist/prosemirror/commentRangeInlineAtoms.js +33 -0
- package/dist/prosemirror/containerFinalParagraph.d.ts +8 -8
- package/dist/prosemirror/containerFinalParagraph.js +8 -8
- package/dist/prosemirror/conversion/fromProseDoc.js +14 -8
- package/dist/prosemirror/conversion/toProseDoc.js +16 -23
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +16 -2
- package/dist/prosemirror/fieldRepresentation.js +4 -2
- package/dist/prosemirror/findReplaceSelection.d.ts +48 -2
- package/dist/prosemirror/findReplaceSelection.js +153 -38
- package/dist/prosemirror/inlineDisplayText.d.ts +10 -0
- package/dist/prosemirror/inlineDisplayText.js +29 -0
- package/dist/prosemirror/markupViewProjection.d.ts +10 -1
- package/dist/prosemirror/markupViewProjection.js +21 -3
- package/dist/prosemirror/plugins/transactionInvariants.js +6 -1
- package/dist/prosemirror/replacedAnnotations.d.ts +15 -1
- package/dist/prosemirror/replacedAnnotations.js +71 -12
- package/dist/prosemirror/runFormattingReconciliation.d.ts +3 -1
- package/dist/prosemirror/runFormattingReconciliation.js +10 -2
- package/dist/prosemirror/runIdentityAcrossRevisions.d.ts +5 -7
- package/dist/prosemirror/runIdentityAcrossRevisions.js +66 -38
- package/dist/prosemirror/runPropertyChangeResolution.js +13 -1
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -1
- package/dist/prosemirror/trackedRunInlineAtoms.js +1 -1
- package/dist/utils/base64.d.ts +1 -31
- package/dist/utils/base64.js +19 -33
- package/dist/utils/clipboard.js +5 -4
- package/dist/utils/colorResolver.js +11 -2
- package/dist/utils/findMatchView.d.ts +32 -0
- package/dist/utils/findMatchView.js +406 -0
- package/dist/utils/findReplace.d.ts +67 -4
- package/dist/utils/findReplace.js +359 -37
- package/dist/utils/findSearchKey.d.ts +29 -0
- package/dist/utils/findSearchKey.js +34 -0
- package/dist/utils/replaceText.js +138 -94
- package/dist/utils/sliceText.d.ts +2 -0
- package/dist/utils/sliceText.js +2 -0
- package/dist/utils/textEncoding.d.ts +2 -0
- package/dist/utils/textEncoding.js +2 -0
- package/dist/utils/tiffConverter.d.ts +0 -9
- package/dist/utils/tiffConverter.js +2 -4
- package/package.json +51 -25
|
@@ -58,7 +58,6 @@ function prepareEndnoteAreas(input) {
|
|
|
58
58
|
notesBySection.set(section, noteIds);
|
|
59
59
|
}
|
|
60
60
|
const separatorBlockIds = /* @__PURE__ */ new Map();
|
|
61
|
-
const contentBlockIds = /* @__PURE__ */ new Set();
|
|
62
61
|
const noteStoryByBlockId = /* @__PURE__ */ new Map();
|
|
63
62
|
const areas = [];
|
|
64
63
|
for (const [section, noteIds] of [...notesBySection].sort(([left], [right]) => left - right)) {
|
|
@@ -82,7 +81,6 @@ function prepareEndnoteAreas(input) {
|
|
|
82
81
|
const id = `endnote-${String(noteId)}-${String(index)}`;
|
|
83
82
|
blocks.push(withId(stripFlowBlockPmAnchors(block), id));
|
|
84
83
|
measures.push(content.measures[index]);
|
|
85
|
-
contentBlockIds.add(id);
|
|
86
84
|
noteStoryByBlockId.set(id, {
|
|
87
85
|
kind: "endnote",
|
|
88
86
|
noteId
|
|
@@ -101,7 +99,7 @@ function prepareEndnoteAreas(input) {
|
|
|
101
99
|
areas,
|
|
102
100
|
noteAreas: {
|
|
103
101
|
separatorBlockIds,
|
|
104
|
-
|
|
102
|
+
noteStoryByBlockId,
|
|
105
103
|
continuationSeparator
|
|
106
104
|
},
|
|
107
105
|
noteStoryByBlockId
|
|
@@ -9,6 +9,8 @@ import { Node } from "prosemirror-model";
|
|
|
9
9
|
* Options for the conversion.
|
|
10
10
|
*/
|
|
11
11
|
type ToFlowBlocksOptions = {
|
|
12
|
+
/** Paint comment anchors and highlights; false leaves authored marks intact. */
|
|
13
|
+
showCommentHighlights?: boolean;
|
|
12
14
|
/** Embedded families owned by this editor, never ambient process state. */
|
|
13
15
|
embeddedFontFamilyMap?: ReadonlyMap<string, string>;
|
|
14
16
|
/** Default font family. */
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { document_d_exports } from "../../types/document.js";
|
|
2
|
+
import { DisplayMode } from "../../managers/EditorModeManager.js";
|
|
2
3
|
import { FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FlowBlock, FootnoteContent, Measure, Page } from "../../layout-engine/types.js";
|
|
3
4
|
import { ToFlowBlocksOptions } from "./flowConversionShared.js";
|
|
4
5
|
import "./toFlowBlocks.js";
|
|
5
6
|
//#region src/layout-bridge/convert/footnoteLayout.d.ts
|
|
6
7
|
type MeasureBlocksFn = (blocks: FlowBlock[], contentWidth: number) => Measure[];
|
|
7
8
|
type ConvertFootnoteOptions = Pick<ToFlowBlocksOptions, "embeddedFontFamilyMap"> & {
|
|
9
|
+
/** Whether comment highlights are painted. Defaults to true. */
|
|
10
|
+
showCommentHighlights?: boolean;
|
|
11
|
+
markupView?: DisplayMode;
|
|
8
12
|
styles?: document_d_exports.StyleDefinitions | null;
|
|
9
13
|
numbering?: document_d_exports.NumberingDefinitions;
|
|
10
14
|
theme?: document_d_exports.Theme | null;
|
|
@@ -2,6 +2,8 @@ import { measureParagraph } from "../../layout-engine/measure/measureParagraph.j
|
|
|
2
2
|
import { layoutTextBoxContent } from "../../layout-engine/measure/textBoxParagraphLayout.js";
|
|
3
3
|
import { DEFAULT_TEXTBOX_MARGINS, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, isFloatingImageRun, resolveTableWidthPx } from "../../layout-engine/types.js";
|
|
4
4
|
import { footnoteToProseDoc } from "../../prosemirror/conversion/toProseDoc.js";
|
|
5
|
+
import { projectStoryMarkupView } from "../../prosemirror/markupViewProjection.js";
|
|
6
|
+
import { remapMarkupViewBlocks } from "./markupViewFlow.js";
|
|
5
7
|
import { collectNoteRefs } from "./noteReferences.js";
|
|
6
8
|
import { toFlowBlocks } from "./toFlowBlocks.js";
|
|
7
9
|
//#region src/layout-bridge/convert/footnoteLayout.ts
|
|
@@ -204,7 +206,7 @@ function convertNoteStoryToFlowBlocks(content, options, referenceMarkText) {
|
|
|
204
206
|
if (options.theme !== void 0) proseOptions.theme = options.theme;
|
|
205
207
|
if (options.numbering !== void 0) proseOptions.numbering = options.numbering;
|
|
206
208
|
const pmDoc = footnoteToProseDoc(content, proseOptions);
|
|
207
|
-
const flowOptions = {};
|
|
209
|
+
const flowOptions = { showCommentHighlights: options.showCommentHighlights !== false && options.markupView !== "no-markup" && options.markupView !== "original" };
|
|
208
210
|
if (options.defaultSize !== void 0) flowOptions.defaultSize = options.defaultSize;
|
|
209
211
|
if (options.styles) flowOptions.styles = options.styles;
|
|
210
212
|
if (options.theme !== void 0) flowOptions.theme = options.theme;
|
|
@@ -215,10 +217,18 @@ function convertNoteStoryToFlowBlocks(content, options, referenceMarkText) {
|
|
|
215
217
|
if (options.justificationCompatibility) flowOptions.justificationCompatibility = options.justificationCompatibility;
|
|
216
218
|
if (options.tableIndentCompatibility) flowOptions.tableIndentCompatibility = options.tableIndentCompatibility;
|
|
217
219
|
if (options.automaticHyphenation) flowOptions.automaticHyphenation = options.automaticHyphenation;
|
|
218
|
-
const
|
|
220
|
+
const projection = projectStoryMarkupView({
|
|
221
|
+
doc: pmDoc,
|
|
222
|
+
markupView: options.markupView ?? "all-markup",
|
|
223
|
+
styles: options.styles,
|
|
224
|
+
numbering: options.numbering
|
|
225
|
+
});
|
|
226
|
+
const viewDoc = projection.type === "resolved" ? projection.doc : pmDoc;
|
|
227
|
+
const hasReferenceMark = containsNoteReferenceMark(viewDoc);
|
|
219
228
|
if (hasReferenceMark && referenceMarkText !== void 0) flowOptions.noteReferenceMarkText = referenceMarkText;
|
|
229
|
+
const converted = toFlowBlocks(viewDoc, flowOptions);
|
|
220
230
|
return {
|
|
221
|
-
flowBlocks: preserveAuthoredFootnoteTerminalParagraph(
|
|
231
|
+
flowBlocks: preserveAuthoredFootnoteTerminalParagraph(projection.type === "resolved" ? remapMarkupViewBlocks(converted, projection) : converted),
|
|
222
232
|
hasReferenceMark
|
|
223
233
|
};
|
|
224
234
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { document_d_exports } from "../../types/document.js";
|
|
2
|
+
import { DisplayMode } from "../../managers/EditorModeManager.js";
|
|
2
3
|
import { FlowBlock, HeaderFooterContent, ImageRun, ImageRunPosition, Measure, PageMargins } from "../../layout-engine/types.js";
|
|
3
4
|
import { ToFlowBlocksOptions } from "./flowConversionShared.js";
|
|
4
5
|
import "./toFlowBlocks.js";
|
|
@@ -40,6 +41,10 @@ declare function calculateHeaderFooterMarginPushBounds(blocks: FlowBlock[], meas
|
|
|
40
41
|
*/
|
|
41
42
|
declare function calculateHeaderFooterBodyTopClearance(blocks: FlowBlock[], flowHeight: number, metrics: HeaderFooterMetrics): number | undefined;
|
|
42
43
|
type ConvertHeaderFooterOptions = {
|
|
44
|
+
/** Review projection applied before header/footer measurement. Defaults to All Markup. */
|
|
45
|
+
markupView?: DisplayMode;
|
|
46
|
+
/** Whether comment highlights are painted. Defaults to true. */
|
|
47
|
+
showCommentHighlights?: boolean;
|
|
43
48
|
styles?: document_d_exports.StyleDefinitions | null;
|
|
44
49
|
numbering?: document_d_exports.NumberingDefinitions;
|
|
45
50
|
theme?: document_d_exports.Theme | null;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { cloneParagraphWithPropertySource } from "../../docx/paragraphPropertySource.js";
|
|
2
2
|
import { isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun } from "../../layout-engine/types.js";
|
|
3
3
|
import { headerFooterToProseDoc } from "../../prosemirror/conversion/toProseDoc.js";
|
|
4
|
+
import { projectStoryMarkupView } from "../../prosemirror/markupViewProjection.js";
|
|
4
5
|
import { emuToPixels } from "../../utils/units.js";
|
|
6
|
+
import { remapMarkupViewBlocks } from "./markupViewFlow.js";
|
|
5
7
|
import { toFlowBlocks } from "./toFlowBlocks.js";
|
|
6
8
|
//#region src/layout-bridge/convert/headerFooterLayout.ts
|
|
7
9
|
const DETACHED_WATERMARK_HOST = Symbol.for("stll.detachedWatermarkHost");
|
|
@@ -341,19 +343,7 @@ function convertHeaderFooterToContent(headerFooter, contentWidth, metrics, optio
|
|
|
341
343
|
if (options.styles) proseDocOptions.styles = options.styles;
|
|
342
344
|
if (options.theme !== void 0) proseDocOptions.theme = options.theme;
|
|
343
345
|
if (options.numbering !== void 0) proseDocOptions.numbering = options.numbering;
|
|
344
|
-
|
|
345
|
-
const flowOptions = {};
|
|
346
|
-
if (options.defaultSize !== void 0) flowOptions.defaultSize = options.defaultSize;
|
|
347
|
-
if (options.styles) flowOptions.styles = options.styles;
|
|
348
|
-
if (options.theme !== void 0) flowOptions.theme = options.theme;
|
|
349
|
-
if (options.embeddedFontFamilyMap !== void 0) flowOptions.embeddedFontFamilyMap = options.embeddedFontFamilyMap;
|
|
350
|
-
if (options.fontAlternates !== void 0) flowOptions.fontAlternates = options.fontAlternates;
|
|
351
|
-
if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
|
|
352
|
-
if (options.lineBreakRules) flowOptions.lineBreakRules = options.lineBreakRules;
|
|
353
|
-
if (options.justificationCompatibility) flowOptions.justificationCompatibility = options.justificationCompatibility;
|
|
354
|
-
if (options.tableIndentCompatibility) flowOptions.tableIndentCompatibility = options.tableIndentCompatibility;
|
|
355
|
-
if (options.automaticHyphenation) flowOptions.automaticHyphenation = options.automaticHyphenation;
|
|
356
|
-
return finalizeHeaderFooterContent(toFlowBlocks(pmDoc, flowOptions), contentWidth, metrics, options);
|
|
346
|
+
return convertHeaderFooterPmDocToContent(headerFooter.watermarkBlockIndex === void 0 ? headerFooterToProseDoc(headerFooter.content, proseDocOptions) : headerFooterToProseDocWithDetachedWatermarkHost(headerFooter, proseDocOptions), contentWidth, metrics, options);
|
|
357
347
|
}
|
|
358
348
|
/**
|
|
359
349
|
* Same as {@link convertHeaderFooterToContent}, but sourced from a live
|
|
@@ -368,7 +358,7 @@ function convertHeaderFooterToContent(headerFooter, contentWidth, metrics, optio
|
|
|
368
358
|
*/
|
|
369
359
|
function convertHeaderFooterPmDocToContent(pmDoc, contentWidth, metrics, options) {
|
|
370
360
|
if (!pmDoc || pmDoc.content.size === 0) return;
|
|
371
|
-
const flowOptions = {};
|
|
361
|
+
const flowOptions = { showCommentHighlights: options.showCommentHighlights !== false && options.markupView !== "no-markup" && options.markupView !== "original" };
|
|
372
362
|
if (options.defaultSize !== void 0) flowOptions.defaultSize = options.defaultSize;
|
|
373
363
|
if (options.styles) flowOptions.styles = options.styles;
|
|
374
364
|
if (options.theme !== void 0) flowOptions.theme = options.theme;
|
|
@@ -379,7 +369,14 @@ function convertHeaderFooterPmDocToContent(pmDoc, contentWidth, metrics, options
|
|
|
379
369
|
if (options.justificationCompatibility) flowOptions.justificationCompatibility = options.justificationCompatibility;
|
|
380
370
|
if (options.tableIndentCompatibility) flowOptions.tableIndentCompatibility = options.tableIndentCompatibility;
|
|
381
371
|
if (options.automaticHyphenation) flowOptions.automaticHyphenation = options.automaticHyphenation;
|
|
382
|
-
|
|
372
|
+
const projection = projectStoryMarkupView({
|
|
373
|
+
doc: pmDoc,
|
|
374
|
+
markupView: options.markupView ?? "all-markup",
|
|
375
|
+
styles: options.styles,
|
|
376
|
+
numbering: options.numbering
|
|
377
|
+
});
|
|
378
|
+
const flowBlocks = toFlowBlocks(projection.type === "resolved" ? projection.doc : pmDoc, flowOptions);
|
|
379
|
+
return finalizeHeaderFooterContent(projection.type === "resolved" ? remapMarkupViewBlocks(flowBlocks, projection) : flowBlocks, contentWidth, metrics, options);
|
|
383
380
|
}
|
|
384
381
|
function horizontalImageLeft({ run, contentWidth, metrics }) {
|
|
385
382
|
const horizontal = run.position?.horizontal;
|
|
@@ -58,7 +58,8 @@ function paragraphToRuns(node, startPos, _options, pageBreaks) {
|
|
|
58
58
|
});
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
|
-
const
|
|
61
|
+
const projectedMarks = mergeProjectedInlineMarks(inheritedMarks, child.marks);
|
|
62
|
+
const effectiveMarks = _options.showCommentHighlights === false ? projectedMarks.filter((mark) => mark.type.name !== "comment") : projectedMarks;
|
|
62
63
|
if (child.type.name === "pageBreakRun") {
|
|
63
64
|
const trackedChange = extractRunFormatting(effectiveMarks, theme, fontAlternates);
|
|
64
65
|
if (trackedChange.isDeletion) {
|
|
@@ -4,7 +4,7 @@ import { layoutImage } from "./imageLayout.js";
|
|
|
4
4
|
import { calculateChainHeight, computeKeepNextChains, getMidChainIndices, hasKeepLines, hasPageBreakBefore } from "./keep-together.js";
|
|
5
5
|
import "./layoutFlowShared.js";
|
|
6
6
|
import { measuredLineAdvance } from "./lineFlow.js";
|
|
7
|
-
import {
|
|
7
|
+
import { annotateNoteAreas, continuesNoteArea, createNoteAreaContinuation } from "./noteAreaFlow.js";
|
|
8
8
|
import { createPaginator } from "./paginator.js";
|
|
9
9
|
import { layoutParagraph } from "./paragraphLayout.js";
|
|
10
10
|
import { paragraphsShareStyle, resolveEffectiveParagraphSpacingTree } from "./paragraphSpacing.js";
|
|
@@ -63,7 +63,7 @@ function applyContextualSpacing(blocks) {
|
|
|
63
63
|
*/
|
|
64
64
|
function layoutDocument(blocks, measures, options) {
|
|
65
65
|
const initialLayout = layoutDocumentPass(blocks, measures, options);
|
|
66
|
-
return
|
|
66
|
+
return annotateNoteAreas(applySectionVerticalAlignment(options.footnoteHeightById ? reflowFootnoteColumns({
|
|
67
67
|
initialLayout,
|
|
68
68
|
...options.footnoteReservedHeights ? { initialReserveFloors: options.footnoteReservedHeights } : {},
|
|
69
69
|
runLayout: (reserveFloors) => layoutDocumentPass(blocks, measures, {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sliceText } from "../../utils/sliceText.js";
|
|
1
2
|
import { splitTrailingToken } from "../../utils/trailingText.js";
|
|
2
3
|
import { resolveEffectiveLineBreakPolicy } from "./effectiveLineBreakPolicy.js";
|
|
3
4
|
import "./lineBreakProvider.js";
|
|
@@ -47,7 +48,11 @@ function computeFollowingTextLeads(block) {
|
|
|
47
48
|
leads[index] = lead;
|
|
48
49
|
const run = block.runs[index];
|
|
49
50
|
if (!run || !isTextRun(run)) lead = void 0;
|
|
50
|
-
else if (run.text) lead =
|
|
51
|
+
else if (run.text) lead = sliceText({
|
|
52
|
+
text: run.text,
|
|
53
|
+
units: "codePoints",
|
|
54
|
+
end: 1
|
|
55
|
+
});
|
|
51
56
|
}
|
|
52
57
|
return leads;
|
|
53
58
|
}
|
|
@@ -101,6 +106,7 @@ function computeProtectedCrossRunGlueWidths(block) {
|
|
|
101
106
|
* invoked from, without the per-word text-length budget ever kicking in.
|
|
102
107
|
*/
|
|
103
108
|
const MAX_CROSS_RUN_SEGMENTS = 64;
|
|
109
|
+
const MAX_SCALAR_CODE_UNITS = 2;
|
|
104
110
|
/** Collect one lexical word continued through adjacent formatting runs. */
|
|
105
111
|
function collectCrossRunWord({ block, startRunIndex, startChar }) {
|
|
106
112
|
const segments = [];
|
|
@@ -115,7 +121,11 @@ function collectCrossRunWord({ block, startRunIndex, startChar }) {
|
|
|
115
121
|
if (remainder.length === 0) continue;
|
|
116
122
|
if (runIndex !== startRunIndex && isSpaceOrTab(remainder[0])) break;
|
|
117
123
|
const remainingBudget = 256 - text.length;
|
|
118
|
-
const boundedRemainder =
|
|
124
|
+
const boundedRemainder = sliceText({
|
|
125
|
+
text: remainder,
|
|
126
|
+
units: "codeUnits",
|
|
127
|
+
end: remainingBudget + MAX_SCALAR_CODE_UNITS
|
|
128
|
+
});
|
|
119
129
|
const firstBreak = findWordBreaks(boundedRemainder, resolveEffectiveLineBreakPolicy({
|
|
120
130
|
attrs: block.attrs,
|
|
121
131
|
run
|
|
@@ -10,10 +10,10 @@ declare function createNoteAreaContinuation(noteAreas: NoteAreaLayout | undefine
|
|
|
10
10
|
/** Whether laying out `block` continues a note area onto any page it opens. */
|
|
11
11
|
declare function continuesNoteArea(noteAreas: NoteAreaLayout | undefined, block: FlowBlock): boolean;
|
|
12
12
|
/**
|
|
13
|
-
* Record where each separator mark landed. A rule is centred
|
|
14
|
-
* of the separator paragraph: a `w:separator` spans part of the column and a
|
|
13
|
+
* Record note identities and where each separator mark landed. A rule is centred
|
|
14
|
+
* on the first line of the separator paragraph: a `w:separator` spans part of the column and a
|
|
15
15
|
* `w:continuationSeparator` all of it.
|
|
16
16
|
*/
|
|
17
|
-
declare function
|
|
17
|
+
declare function annotateNoteAreas(layout: Layout, blocks: readonly FlowBlock[], measures: readonly Measure[], noteAreas: NoteAreaLayout | undefined): Layout;
|
|
18
18
|
//#endregion
|
|
19
|
-
export {
|
|
19
|
+
export { annotateNoteAreas, continuesNoteArea, createNoteAreaContinuation };
|
|
@@ -39,15 +39,15 @@ function createNoteAreaContinuation(noteAreas, paginator) {
|
|
|
39
39
|
}
|
|
40
40
|
/** Whether laying out `block` continues a note area onto any page it opens. */
|
|
41
41
|
function continuesNoteArea(noteAreas, block) {
|
|
42
|
-
return noteAreas?.
|
|
42
|
+
return noteAreas?.noteStoryByBlockId.has(String(block.id)) === true;
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
|
-
* Record where each separator mark landed. A rule is centred
|
|
46
|
-
* of the separator paragraph: a `w:separator` spans part of the column and a
|
|
45
|
+
* Record note identities and where each separator mark landed. A rule is centred
|
|
46
|
+
* on the first line of the separator paragraph: a `w:separator` spans part of the column and a
|
|
47
47
|
* `w:continuationSeparator` all of it.
|
|
48
48
|
*/
|
|
49
|
-
function
|
|
50
|
-
if (noteAreas === void 0
|
|
49
|
+
function annotateNoteAreas(layout, blocks, measures, noteAreas) {
|
|
50
|
+
if (noteAreas === void 0) return layout;
|
|
51
51
|
const measureById = /* @__PURE__ */ new Map();
|
|
52
52
|
for (const [index, block] of blocks.entries()) {
|
|
53
53
|
const measure = measures[index];
|
|
@@ -56,6 +56,12 @@ function annotateNoteSeparators(layout, blocks, measures, noteAreas) {
|
|
|
56
56
|
const continuation = noteAreas.continuationSeparator;
|
|
57
57
|
if (continuation !== void 0) measureById.set(String(continuation.block.id), continuation.measure);
|
|
58
58
|
for (const page of layout.pages) {
|
|
59
|
+
const endnoteIds = /* @__PURE__ */ new Set();
|
|
60
|
+
for (const fragment of page.fragments) {
|
|
61
|
+
const story = noteAreas.noteStoryByBlockId.get(String(fragment.blockId));
|
|
62
|
+
if (story?.kind === "endnote") endnoteIds.add(story.noteId);
|
|
63
|
+
}
|
|
64
|
+
if (endnoteIds.size > 0) page.endnoteIds = [...endnoteIds];
|
|
59
65
|
const rules = [];
|
|
60
66
|
for (const fragment of page.fragments) {
|
|
61
67
|
if (fragment.kind !== "paragraph" || fragment.fromLine !== 0) continue;
|
|
@@ -80,4 +86,4 @@ function separatorWidthFraction(kind) {
|
|
|
80
86
|
}
|
|
81
87
|
}
|
|
82
88
|
//#endregion
|
|
83
|
-
export {
|
|
89
|
+
export { annotateNoteAreas, continuesNoteArea, createNoteAreaContinuation };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { OutlineStyleAttr } from "../types/documentEnumValues.js";
|
|
2
|
+
import { NoteStoryKey } from "../types/editor-story.js";
|
|
2
3
|
import { CssBorderStyle } from "../utils/borderCss.js";
|
|
3
4
|
import { ImagePosition, ImageWrap, InlineWrapper, NumberFormat, OutlineLevel, ParagraphNumberingOverride, PreviewDescriptor, SdtProperties, SdtType, SectionStart, ShapeTextBody, TableCellFormatting, TableWidthType, UnderlineStyle, VerticalAlign } from "@stll/docx-core/model";
|
|
4
5
|
declare namespace types_d_exports {
|
|
@@ -1268,6 +1269,8 @@ type Page = {
|
|
|
1268
1269
|
headerFooterRefs?: PageHeaderFooterRefs;
|
|
1269
1270
|
/** Footnote IDs that appear on this page (for rendering). */
|
|
1270
1271
|
footnoteIds?: number[];
|
|
1272
|
+
/** Endnote IDs whose content fragments appear on this page. */
|
|
1273
|
+
endnoteIds?: number[];
|
|
1271
1274
|
/** Height reserved for the footnote area at page bottom (pixels). */
|
|
1272
1275
|
footnoteReservedHeight?: number;
|
|
1273
1276
|
/**
|
|
@@ -1436,10 +1439,10 @@ type NoteAreaLayout = {
|
|
|
1436
1439
|
*/
|
|
1437
1440
|
separatorBlockIds: ReadonlyMap<string, NoteSeparatorKind>;
|
|
1438
1441
|
/**
|
|
1439
|
-
* Note content
|
|
1442
|
+
* Note identities keyed by content block. A page opened while one is laid out
|
|
1440
1443
|
* continues the area, so it starts with the continuation separator.
|
|
1441
1444
|
*/
|
|
1442
|
-
|
|
1445
|
+
noteStoryByBlockId: ReadonlyMap<string, NoteStoryKey>;
|
|
1443
1446
|
/** The `w:continuationSeparator` story's first paragraph, already measured. */
|
|
1444
1447
|
continuationSeparator?: {
|
|
1445
1448
|
block: ParagraphBlock;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FlowBlock, Layout, Measure } from "../layout-engine/types.js";
|
|
2
1
|
import { NoteStoryKey } from "../types/editor-story.js";
|
|
2
|
+
import { FlowBlock, Layout, Measure } from "../layout-engine/types.js";
|
|
3
3
|
import { RenderContext } from "./renderUtils.js";
|
|
4
4
|
import { BlockFor, FeatureDispatchInput, FeatureFallback, FeatureModule, FeatureRenderInput, FragmentFor, MeasureFor } from "./registry/types.js";
|
|
5
5
|
import { FeatureRegistry, createFeatureRegistry } from "./registry/registry.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { encodeUtf8 } from "../utils/textEncoding.js";
|
|
1
2
|
import { Subscribable } from "./Subscribable.js";
|
|
2
3
|
import { decodeAutoSaveEnvelope, encodeAutoSaveDocument, encodeAutoSaveEnvelopeFromDocument } from "./autoSaveCodec.js";
|
|
3
4
|
//#region src/managers/AutoSaveManager.ts
|
|
@@ -228,7 +229,7 @@ function getAutoSaveStorageSize(storageKey = DEFAULT_STORAGE_KEY) {
|
|
|
228
229
|
try {
|
|
229
230
|
const data = localStorage.getItem(storageKey);
|
|
230
231
|
if (!data) return 0;
|
|
231
|
-
return
|
|
232
|
+
return encodeUtf8(data).byteLength;
|
|
232
233
|
} catch {
|
|
233
234
|
return 0;
|
|
234
235
|
}
|
|
@@ -5,6 +5,15 @@ type EditorMode = "editing" | "suggesting" | "viewing";
|
|
|
5
5
|
/** How tracked changes render. Drives the display mode dropdown. */
|
|
6
6
|
declare const DISPLAY_MODES: readonly ["all-markup", "simple-markup", "no-markup", "original"];
|
|
7
7
|
type DisplayMode = (typeof DISPLAY_MODES)[number];
|
|
8
|
+
/** Why a user action cannot edit the displayed document. */
|
|
9
|
+
type EditorReadOnlyReason = "host-read-only" | "viewing-mode" | "review-display-mode";
|
|
10
|
+
declare const getReviewViewReadOnlyReason: (displayMode: DisplayMode) => EditorReadOnlyReason | null;
|
|
11
|
+
type EditorReadOnlyReasonOptions = {
|
|
12
|
+
editingMode: EditorMode;
|
|
13
|
+
readOnlyProp: boolean;
|
|
14
|
+
displayMode: DisplayMode;
|
|
15
|
+
};
|
|
16
|
+
declare const getEditorReadOnlyReason: ({ editingMode, readOnlyProp, displayMode }: EditorReadOnlyReasonOptions) => EditorReadOnlyReason | null;
|
|
8
17
|
/** EditorModeManager snapshot. */
|
|
9
18
|
type EditorModeSnapshot = {
|
|
10
19
|
/** Uncontrolled internal editing mode (the host's controlled prop wins over this). */
|
|
@@ -26,4 +35,4 @@ declare class EditorModeManager extends Subscribable<EditorModeSnapshot> {
|
|
|
26
35
|
setDisplayMode(mode: DisplayMode): void;
|
|
27
36
|
}
|
|
28
37
|
//#endregion
|
|
29
|
-
export { DISPLAY_MODES, DisplayMode, EditorMode, EditorModeManager, EditorModeSnapshot, isReadOnlyMode, isTrackChangesMode, toggledTrackChangesMode };
|
|
38
|
+
export { DISPLAY_MODES, DisplayMode, EditorMode, EditorModeManager, EditorModeSnapshot, EditorReadOnlyReason, getEditorReadOnlyReason, getReviewViewReadOnlyReason, isReadOnlyMode, isTrackChangesMode, toggledTrackChangesMode };
|
|
@@ -18,6 +18,20 @@ const DISPLAY_MODES = [
|
|
|
18
18
|
"no-markup",
|
|
19
19
|
"original"
|
|
20
20
|
];
|
|
21
|
+
const REVIEW_VIEW_ACCESS = {
|
|
22
|
+
"all-markup": "editable",
|
|
23
|
+
"simple-markup": "read-only",
|
|
24
|
+
"no-markup": "read-only",
|
|
25
|
+
original: "read-only"
|
|
26
|
+
};
|
|
27
|
+
const getReviewViewReadOnlyReason = (displayMode) => REVIEW_VIEW_ACCESS[displayMode] === "read-only" ? "review-display-mode" : null;
|
|
28
|
+
const getEditorReadOnlyReason = ({ editingMode, readOnlyProp, displayMode }) => {
|
|
29
|
+
const viewReason = getReviewViewReadOnlyReason(displayMode);
|
|
30
|
+
if (viewReason) return viewReason;
|
|
31
|
+
if (readOnlyProp) return "host-read-only";
|
|
32
|
+
if (editingMode === "viewing") return "viewing-mode";
|
|
33
|
+
return null;
|
|
34
|
+
};
|
|
21
35
|
/** True when the host opts into read-only OR the mode is `"viewing"`. */
|
|
22
36
|
const isReadOnlyMode = (editingMode, readOnlyProp) => readOnlyProp || editingMode === "viewing";
|
|
23
37
|
/** True when the mode is `"suggesting"`. */
|
|
@@ -47,4 +61,4 @@ var EditorModeManager = class extends Subscribable {
|
|
|
47
61
|
}
|
|
48
62
|
};
|
|
49
63
|
//#endregion
|
|
50
|
-
export { DISPLAY_MODES, EditorModeManager, isReadOnlyMode, isTrackChangesMode, toggledTrackChangesMode };
|
|
64
|
+
export { DISPLAY_MODES, EditorModeManager, getEditorReadOnlyReason, getReviewViewReadOnlyReason, isReadOnlyMode, isTrackChangesMode, toggledTrackChangesMode };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { ReplaceAllSummary, ReplaceEligibility } from "../utils/findReplace.js";
|
|
2
3
|
import { FindMatchPosition } from "../prosemirror/findReplaceSelection.js";
|
|
4
|
+
import { OpStory } from "@stll/docx-core/ops";
|
|
3
5
|
//#region src/managers/FindReplaceManager.d.ts
|
|
4
6
|
type FindDirection = "next" | "previous";
|
|
5
7
|
type FindReplaceResult<TMatch> = {
|
|
@@ -7,16 +9,21 @@ type FindReplaceResult<TMatch> = {
|
|
|
7
9
|
totalCount: number;
|
|
8
10
|
currentIndex: number;
|
|
9
11
|
};
|
|
10
|
-
type ReplaceAllOutcome = {
|
|
12
|
+
type ReplaceAllOutcome = ReplaceAllSummary & {
|
|
11
13
|
document: document_d_exports.Document;
|
|
12
|
-
replacedCount: number;
|
|
13
14
|
};
|
|
14
15
|
/**
|
|
15
16
|
* The cursor index after stepping `direction` over `totalCount` matches,
|
|
16
17
|
* wrapping at both ends. Returns 0 when there are no matches.
|
|
17
18
|
*/
|
|
18
19
|
declare const getAdjacentFindIndex: (currentIndex: number, totalCount: number, direction: FindDirection) => number;
|
|
19
|
-
|
|
20
|
+
type ReplaceableFindPosition = FindMatchPosition & {
|
|
21
|
+
story?: OpStory;
|
|
22
|
+
textBoxIndex?: number;
|
|
23
|
+
commentId?: number;
|
|
24
|
+
replacement: ReplaceEligibility;
|
|
25
|
+
};
|
|
26
|
+
declare class FindReplaceManager<TMatch extends ReplaceableFindPosition> {
|
|
20
27
|
private result;
|
|
21
28
|
/** The active find result, or null when there is no active search. */
|
|
22
29
|
getResult(): FindReplaceResult<TMatch> | null;
|
|
@@ -27,7 +34,7 @@ declare class FindReplaceManager<TMatch extends FindMatchPosition> {
|
|
|
27
34
|
* first match. The result is kept even when `matches` is empty so callers can
|
|
28
35
|
* surface a "no results" state.
|
|
29
36
|
*/
|
|
30
|
-
setMatches(matches: TMatch[]): FindReplaceResult<TMatch>;
|
|
37
|
+
setMatches(matches: TMatch[], currentIndex?: number): FindReplaceResult<TMatch>;
|
|
31
38
|
/**
|
|
32
39
|
* Step the cursor and return the now-current match with its index, or null
|
|
33
40
|
* when there are no matches to navigate.
|
|
@@ -51,8 +58,8 @@ declare class FindReplaceManager<TMatch extends FindMatchPosition> {
|
|
|
51
58
|
replaceCurrent(document: document_d_exports.Document, replaceText: string): document_d_exports.Document | null;
|
|
52
59
|
/**
|
|
53
60
|
* Replace every match. Matches are replaced from the end of the document
|
|
54
|
-
* backwards so earlier offsets stay valid as the text shifts.
|
|
55
|
-
*
|
|
61
|
+
* backwards so earlier offsets stay valid as the text shifts. Ineligible
|
|
62
|
+
* matches are skipped and counted. Clears the active result, or returns null
|
|
56
63
|
* when there is nothing to replace.
|
|
57
64
|
*/
|
|
58
65
|
replaceAll(document: document_d_exports.Document, matches: readonly TMatch[], replaceText: string): ReplaceAllOutcome | null;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { replaceEligibility } from "../utils/findReplace.js";
|
|
1
2
|
import { replaceTextInDocument } from "../utils/replaceText.js";
|
|
2
3
|
//#region src/managers/FindReplaceManager.ts
|
|
3
4
|
/**
|
|
@@ -34,11 +35,11 @@ var FindReplaceManager = class {
|
|
|
34
35
|
* first match. The result is kept even when `matches` is empty so callers can
|
|
35
36
|
* surface a "no results" state.
|
|
36
37
|
*/
|
|
37
|
-
setMatches(matches) {
|
|
38
|
+
setMatches(matches, currentIndex = 0) {
|
|
38
39
|
this.result = {
|
|
39
40
|
matches,
|
|
40
41
|
totalCount: matches.length,
|
|
41
|
-
currentIndex: 0
|
|
42
|
+
currentIndex: Math.max(0, Math.min(currentIndex, matches.length - 1))
|
|
42
43
|
};
|
|
43
44
|
return this.result;
|
|
44
45
|
}
|
|
@@ -86,7 +87,7 @@ var FindReplaceManager = class {
|
|
|
86
87
|
const result = this.result;
|
|
87
88
|
if (!result || result.matches.length === 0) return null;
|
|
88
89
|
const match = result.matches[result.currentIndex];
|
|
89
|
-
if (!match) return null;
|
|
90
|
+
if (!match || replaceEligibility(match).status === "blocked") return null;
|
|
90
91
|
try {
|
|
91
92
|
return replaceTextInDocument(document, toReplaceRange(match), replaceText);
|
|
92
93
|
} catch {
|
|
@@ -95,26 +96,31 @@ var FindReplaceManager = class {
|
|
|
95
96
|
}
|
|
96
97
|
/**
|
|
97
98
|
* Replace every match. Matches are replaced from the end of the document
|
|
98
|
-
* backwards so earlier offsets stay valid as the text shifts.
|
|
99
|
-
*
|
|
99
|
+
* backwards so earlier offsets stay valid as the text shifts. Ineligible
|
|
100
|
+
* matches are skipped and counted. Clears the active result, or returns null
|
|
100
101
|
* when there is nothing to replace.
|
|
101
102
|
*/
|
|
102
103
|
replaceAll(document, matches, replaceText) {
|
|
103
104
|
if (matches.length === 0) return null;
|
|
104
|
-
const
|
|
105
|
+
const eligibleMatches = matches.filter((match) => replaceEligibility(match).status === "allowed");
|
|
106
|
+
let skippedCount = matches.length - eligibleMatches.length;
|
|
107
|
+
let replacedCount = 0;
|
|
108
|
+
const sortedMatches = [...eligibleMatches].toSorted((a, b) => {
|
|
105
109
|
if (a.paragraphIndex !== b.paragraphIndex) return b.paragraphIndex - a.paragraphIndex;
|
|
106
110
|
return b.startOffset - a.startOffset;
|
|
107
111
|
});
|
|
108
112
|
let nextDocument = document;
|
|
109
113
|
for (const match of sortedMatches) try {
|
|
110
114
|
nextDocument = replaceTextInDocument(nextDocument, toReplaceRange(match), replaceText);
|
|
115
|
+
replacedCount++;
|
|
111
116
|
} catch {
|
|
112
|
-
|
|
117
|
+
skippedCount++;
|
|
113
118
|
}
|
|
114
|
-
this.result = null;
|
|
119
|
+
if (replacedCount > 0) this.result = null;
|
|
115
120
|
return {
|
|
116
121
|
document: nextDocument,
|
|
117
|
-
replacedCount
|
|
122
|
+
replacedCount,
|
|
123
|
+
skippedCount
|
|
118
124
|
};
|
|
119
125
|
}
|
|
120
126
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
|
-
import { TableAction, TableContext } from "../utils/tableOperations.js";
|
|
3
2
|
import { Subscribable } from "./Subscribable.js";
|
|
3
|
+
import { TableAction, TableContext } from "../utils/tableOperations.js";
|
|
4
4
|
import { CellCoordinates } from "./types.js";
|
|
5
5
|
//#region src/managers/TableSelectionManager.d.ts
|
|
6
6
|
/** Data attributes for table elements in the rendered DOM */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { validateFolioDocumentModel } from "../docx/modelValidation.js";
|
|
2
2
|
import { bytesToBase64 } from "../utils/base64.js";
|
|
3
|
+
import { base64ToBytes } from "../utils/textEncoding.js";
|
|
3
4
|
//#region src/managers/autoSaveCodec.ts
|
|
4
5
|
/**
|
|
5
6
|
* Version 3 renamed the model's `bidiWrapper` to `inlineWrapper` and gave it a
|
|
@@ -10,12 +11,7 @@ import { bytesToBase64 } from "../utils/base64.js";
|
|
|
10
11
|
* re-taken rather than migrated.
|
|
11
12
|
*/
|
|
12
13
|
const AUTOSAVE_FORMAT_VERSION = 3;
|
|
13
|
-
const decodeBase64 = (value) =>
|
|
14
|
-
const binary = atob(value);
|
|
15
|
-
const bytes = new Uint8Array(binary.length);
|
|
16
|
-
for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
|
|
17
|
-
return bytes.buffer;
|
|
18
|
-
};
|
|
14
|
+
const decodeBase64 = (value) => base64ToBytes(value).buffer;
|
|
19
15
|
const encodeValue = (value) => {
|
|
20
16
|
if (value === void 0) return { type: "undefined" };
|
|
21
17
|
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DisplayMode } from "./EditorModeManager.js";
|
|
2
|
+
//#region src/managers/reviewDisplayMode.d.ts
|
|
3
|
+
/** The host's reading of pending revisions; it never changes the saved document. */
|
|
4
|
+
declare const REVIEW_DISPLAY_MODES: readonly ["all-markup", "final", "original"];
|
|
5
|
+
type ReviewDisplayMode = (typeof REVIEW_DISPLAY_MODES)[number];
|
|
6
|
+
declare const reviewDisplayModeToDisplayMode: (mode: ReviewDisplayMode) => DisplayMode;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { REVIEW_DISPLAY_MODES, ReviewDisplayMode, reviewDisplayModeToDisplayMode };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/managers/reviewDisplayMode.ts
|
|
2
|
+
/** The host's reading of pending revisions; it never changes the saved document. */
|
|
3
|
+
const REVIEW_DISPLAY_MODES = [
|
|
4
|
+
"all-markup",
|
|
5
|
+
"final",
|
|
6
|
+
"original"
|
|
7
|
+
];
|
|
8
|
+
const REVIEW_DISPLAY_MODE_VIEWS = {
|
|
9
|
+
"all-markup": "all-markup",
|
|
10
|
+
final: "no-markup",
|
|
11
|
+
original: "original"
|
|
12
|
+
};
|
|
13
|
+
const reviewDisplayModeToDisplayMode = (mode) => REVIEW_DISPLAY_MODE_VIEWS[mode];
|
|
14
|
+
//#endregion
|
|
15
|
+
export { REVIEW_DISPLAY_MODES, reviewDisplayModeToDisplayMode };
|
|
@@ -8,8 +8,10 @@ type ScrollEditorElementOptions = {
|
|
|
8
8
|
behavior?: ScrollBehavior;
|
|
9
9
|
/** Space to leave between the target and the visible root edge. */
|
|
10
10
|
margin?: number;
|
|
11
|
+
/** Measured target range when only part of the element should be revealed. */
|
|
12
|
+
rect?: DOMRectReadOnly;
|
|
11
13
|
};
|
|
12
14
|
/** Scroll only the marked root, including when the target is inside a scaled viewport. */
|
|
13
|
-
declare const scrollEditorElementIntoView: (element: HTMLElement | null, { block, behavior, margin }?: ScrollEditorElementOptions) => void;
|
|
15
|
+
declare const scrollEditorElementIntoView: (element: HTMLElement | null, { block, behavior, margin, rect }?: ScrollEditorElementOptions) => void;
|
|
14
16
|
//#endregion
|
|
15
17
|
export { getEditorScrollRoot, scrollEditorBy, scrollEditorElementIntoView, scrollEditorTo };
|
|
@@ -25,10 +25,10 @@ const nearestScrollOffset = ({ targetStart, targetEnd, viewportStart, viewportEn
|
|
|
25
25
|
return 0;
|
|
26
26
|
};
|
|
27
27
|
/** Scroll only the marked root, including when the target is inside a scaled viewport. */
|
|
28
|
-
const scrollEditorElementIntoView = (element, { block = "center", behavior = prefersReducedMotionBehavior(), margin = 0 } = {}) => {
|
|
28
|
+
const scrollEditorElementIntoView = (element, { block = "center", behavior = prefersReducedMotionBehavior(), margin = 0, rect } = {}) => {
|
|
29
29
|
const root = getEditorScrollRoot(element);
|
|
30
30
|
if (!root || !element) return;
|
|
31
|
-
const targetRect = element.getBoundingClientRect();
|
|
31
|
+
const targetRect = rect ?? element.getBoundingClientRect();
|
|
32
32
|
const rootRect = root.getBoundingClientRect();
|
|
33
33
|
const visibleTop = rootRect.top + root.clientTop;
|
|
34
34
|
const targetTop = targetRect.top - visibleTop + root.scrollTop;
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
import { Layout } from "../layout-engine/types.js";
|
|
2
2
|
import "../layout-engine/index.js";
|
|
3
|
+
import { MarkupViewProjection } from "../prosemirror/markupViewProjection.js";
|
|
3
4
|
import { Node } from "prosemirror-model";
|
|
4
5
|
//#region src/paged-layout/pageText.d.ts
|
|
6
|
+
type PageTextOptions = {
|
|
7
|
+
layout: Layout | null;
|
|
8
|
+
doc: Node;
|
|
9
|
+
page: number;
|
|
10
|
+
projection?: MarkupViewProjection;
|
|
11
|
+
};
|
|
5
12
|
/**
|
|
6
13
|
* The plain text of a single rendered page (1-based), read by joining each of
|
|
7
14
|
* the page's layout fragments' `[pmStart, pmEnd)` document text with a
|
|
8
|
-
* newline.
|
|
15
|
+
* newline. A review projection maps those authored ranges to the displayed
|
|
16
|
+
* document, excluding text the view hides. Fragments with no `pmStart`/`pmEnd`
|
|
17
|
+
* (e.g. a page-shell placeholder)
|
|
9
18
|
* are skipped. Returns `null` when the layout hasn't been computed yet or the
|
|
10
19
|
* page number is out of range.
|
|
11
20
|
*/
|
|
12
|
-
declare const getPageTextFromLayout: (layout
|
|
21
|
+
declare const getPageTextFromLayout: ({ layout, doc, page, projection }: PageTextOptions) => string | null;
|
|
13
22
|
//#endregion
|
|
14
23
|
export { getPageTextFromLayout };
|