@superdoc/mcp 1.6.1-next.1 → 1.6.1-next.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/index.js +1018 -356
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -31600,7 +31600,7 @@ var init_host = __esm(() => {
|
|
|
31600
31600
|
});
|
|
31601
31601
|
|
|
31602
31602
|
// ../../packages/sdk/langs/node/src/runtime/sdk-version.generated.ts
|
|
31603
|
-
var SDK_VERSION = "2.19.1-next.
|
|
31603
|
+
var SDK_VERSION = "2.19.1-next.2";
|
|
31604
31604
|
|
|
31605
31605
|
// ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
|
|
31606
31606
|
import { accessSync, chmodSync, constants, existsSync, statSync } from "node:fs";
|
|
@@ -127288,7 +127288,8 @@ function buildStructuralBoundaryMap(bytes) {
|
|
|
127288
127288
|
sdtOrdinal: sdtCounter,
|
|
127289
127289
|
wrapperLocked: lockPolicy.wrapperLocked,
|
|
127290
127290
|
contentLocked: lockPolicy.contentLocked,
|
|
127291
|
-
contentEditable: !lockPolicy.contentLocked && isSdtContentEditable(sdtXml)
|
|
127291
|
+
contentEditable: !lockPolicy.contentLocked && isSdtContentEditable(sdtXml),
|
|
127292
|
+
textAtomic: isTextAtomicBlockSdt(sdtXml)
|
|
127292
127293
|
});
|
|
127293
127294
|
sdtCounter += 1;
|
|
127294
127295
|
} else if (tag.local === "customXml") {
|
|
@@ -127311,6 +127312,7 @@ function recordParagraph2(input) {
|
|
|
127311
127312
|
const blockCustomXmlPath = [];
|
|
127312
127313
|
let hasLockedBlockSdt = false;
|
|
127313
127314
|
let hasNonEditableBlockSdtContent = false;
|
|
127315
|
+
let hasTextAtomicBlockSdt = false;
|
|
127314
127316
|
let hasContentLockedBlockSdt = false;
|
|
127315
127317
|
let lastTable = -1;
|
|
127316
127318
|
let lastRow = -1;
|
|
@@ -127330,6 +127332,7 @@ function recordParagraph2(input) {
|
|
|
127330
127332
|
blockSdtPath.push(frame.sdtOrdinal);
|
|
127331
127333
|
hasLockedBlockSdt || (hasLockedBlockSdt = frame.wrapperLocked);
|
|
127332
127334
|
hasNonEditableBlockSdtContent || (hasNonEditableBlockSdtContent = !frame.contentEditable);
|
|
127335
|
+
hasTextAtomicBlockSdt || (hasTextAtomicBlockSdt = frame.textAtomic);
|
|
127333
127336
|
hasContentLockedBlockSdt || (hasContentLockedBlockSdt = frame.contentLocked);
|
|
127334
127337
|
} else if (frame.kind === "customXml") {
|
|
127335
127338
|
blockCustomXmlPath.push(frame.customXmlOrdinal);
|
|
@@ -127342,6 +127345,7 @@ function recordParagraph2(input) {
|
|
|
127342
127345
|
blockSdtPath,
|
|
127343
127346
|
hasLockedBlockSdt,
|
|
127344
127347
|
hasNonEditableBlockSdtContent,
|
|
127348
|
+
hasTextAtomicBlockSdt,
|
|
127345
127349
|
hasContentLockedBlockSdt,
|
|
127346
127350
|
blockCustomXmlPath,
|
|
127347
127351
|
sectionIndex: input.sectionIndex,
|
|
@@ -127351,6 +127355,13 @@ function recordParagraph2(input) {
|
|
|
127351
127355
|
carriesSectionBreak: carriesSectionBreak(input.paragraphXml)
|
|
127352
127356
|
};
|
|
127353
127357
|
}
|
|
127358
|
+
function isTextAtomicBlockSdt(sdtXml) {
|
|
127359
|
+
const contentMatch = /<(?:[\w.-]+:)?sdtContent\b/iu.exec(sdtXml);
|
|
127360
|
+
if (!contentMatch)
|
|
127361
|
+
return false;
|
|
127362
|
+
const properties = sdtXml.slice(0, contentMatch.index);
|
|
127363
|
+
return /<(?:[\w.-]+:)?(?:checkbox|dropDownList)\b/iu.test(properties);
|
|
127364
|
+
}
|
|
127354
127365
|
function blockSdtLockPolicy(sdtXml) {
|
|
127355
127366
|
const properties = /<(?:[\w.-]+:)?sdtPr\b[^>]*>([\s\S]*?)<\/(?:[\w.-]+:)?sdtPr\s*>/.exec(sdtXml)?.[1];
|
|
127356
127367
|
if (!properties)
|
|
@@ -165856,7 +165867,7 @@ function planDirectInlineEdit(paragraphBytes, startOffset, endOffset, newText, c
|
|
|
165856
165867
|
if (tocPlan)
|
|
165857
165868
|
return tocPlan;
|
|
165858
165869
|
if (startOffset === endOffset) {
|
|
165859
|
-
const beside = planCollapsedInsertBesideContainer(paragraphBytes, xml, model.pieces, startOffset, newText);
|
|
165870
|
+
const beside = planCollapsedInsertBesideContainer(paragraphBytes, xml, model.pieces, startOffset, newText, collapsedInlineAffinity);
|
|
165860
165871
|
if (beside)
|
|
165861
165872
|
return beside;
|
|
165862
165873
|
}
|
|
@@ -166330,19 +166341,22 @@ function planCollapsedInsert(paragraphBytes, xml, pieces, leaves, at, newText, t
|
|
|
166330
166341
|
runPropertiesXml: carrier?.runProperties ?? paragraphMarkRPr
|
|
166331
166342
|
};
|
|
166332
166343
|
}
|
|
166333
|
-
function planCollapsedInsertBesideContainer(paragraphBytes, xml, pieces, at, newText) {
|
|
166344
|
+
function planCollapsedInsertBesideContainer(paragraphBytes, xml, pieces, at, newText, collapsedInlineAffinity) {
|
|
166334
166345
|
if (newText.length === 0)
|
|
166335
166346
|
return null;
|
|
166336
166347
|
for (const piece of pieces) {
|
|
166337
166348
|
if (piece.kind !== "container")
|
|
166338
166349
|
continue;
|
|
166339
|
-
if (piece.containerKind !== "hyperlink" && piece.containerKind !== "fldSimple")
|
|
166350
|
+
if (piece.containerKind !== "hyperlink" && piece.containerKind !== "fldSimple" && piece.containerKind !== "sdt")
|
|
166340
166351
|
continue;
|
|
166341
166352
|
if (piece.visibleEnd <= piece.visibleStart)
|
|
166342
166353
|
continue;
|
|
166343
166354
|
const atLeading = piece.visibleStart === at && !hasVisibleSiblingEndingAt(pieces, at);
|
|
166344
166355
|
const atTrailing = piece.visibleEnd === at && !hasVisibleSiblingStartingAt(pieces, at);
|
|
166345
|
-
|
|
166356
|
+
const isSdt = piece.containerKind === "sdt";
|
|
166357
|
+
const leading = isSdt ? piece.visibleStart === at && collapsedInlineAffinity === "upstream" : atLeading;
|
|
166358
|
+
const trailing = isSdt ? piece.visibleEnd === at && collapsedInlineAffinity === "downstream" : atTrailing;
|
|
166359
|
+
if (!leading && !trailing)
|
|
166346
166360
|
continue;
|
|
166347
166361
|
const blocked = findBlockingPiece(pieces, at, at);
|
|
166348
166362
|
if (blocked)
|
|
@@ -166354,7 +166368,7 @@ function planCollapsedInsertBesideContainer(paragraphBytes, xml, pieces, at, new
|
|
|
166354
166368
|
const freshRunQnames = paragraphRunQnames(xml);
|
|
166355
166369
|
if (!freshRunQnames)
|
|
166356
166370
|
return { ok: false, reason: "invalid-range" };
|
|
166357
|
-
const insertByte =
|
|
166371
|
+
const insertByte = leading ? Math.min(piece.byteStart, ...leadingRangeStarts.map((marker) => marker.runByteStart ?? marker.byteStart)) : Math.max(piece.byteEnd, ...trailingRangeEnds.map((marker) => marker.runByteEnd ?? marker.byteEnd));
|
|
166358
166372
|
const op = {
|
|
166359
166373
|
start: insertByte,
|
|
166360
166374
|
end: insertByte,
|
|
@@ -166363,7 +166377,8 @@ function planCollapsedInsertBesideContainer(paragraphBytes, xml, pieces, at, new
|
|
|
166363
166377
|
return {
|
|
166364
166378
|
ok: true,
|
|
166365
166379
|
bytes: spliceBytes(paragraphBytes, [op]),
|
|
166366
|
-
runPropertiesXml: paragraphMarkRPr
|
|
166380
|
+
runPropertiesXml: paragraphMarkRPr,
|
|
166381
|
+
...isSdt ? { requiresCollaborationSessionSync: true } : {}
|
|
166367
166382
|
};
|
|
166368
166383
|
}
|
|
166369
166384
|
return null;
|
|
@@ -171992,6 +172007,7 @@ function isTerminalDeletionOfPendingFullParagraphInsertion(fragment3, entries) {
|
|
|
171992
172007
|
}
|
|
171993
172008
|
function collectTextCandidates(lookupContext, partXml, entries, storyId) {
|
|
171994
172009
|
const out = [];
|
|
172010
|
+
const bookmarkGroups = collectBookmarkRevisionGroups(entries.filter((entry) => entry.type === "insertion").flatMap((entry) => entry.fragments), partXml);
|
|
171995
172011
|
for (const entry of entries) {
|
|
171996
172012
|
if (entry.type !== "insertion" || entry.subtype !== "text-insertion")
|
|
171997
172013
|
continue;
|
|
@@ -172003,6 +172019,8 @@ function collectTextCandidates(lookupContext, partXml, entries, storyId) {
|
|
|
172003
172019
|
continue;
|
|
172004
172020
|
if (entry.fragments.length === 0)
|
|
172005
172021
|
continue;
|
|
172022
|
+
if (entry.fragments.every((fragment3) => bookmarkGroups.has(fragment3)))
|
|
172023
|
+
continue;
|
|
172006
172024
|
if (!entry.fragments.every((fragment3) => fragment3.kind === "ins"))
|
|
172007
172025
|
continue;
|
|
172008
172026
|
let paragraphStart = null;
|
|
@@ -173852,6 +173870,7 @@ var init_review_groups = __esm(() => {
|
|
|
173852
173870
|
init_structural_groups();
|
|
173853
173871
|
init_numbering_catalog();
|
|
173854
173872
|
init_field_paragraph_deletion_groups();
|
|
173873
|
+
init_bookmark_revision_groups();
|
|
173855
173874
|
init_field_paragraph_range_deletion_groups();
|
|
173856
173875
|
init_image_paragraph_deletion_groups();
|
|
173857
173876
|
});
|
|
@@ -194696,7 +194715,7 @@ var init_created_text_span_proof = __esm(() => {
|
|
|
194696
194715
|
});
|
|
194697
194716
|
|
|
194698
194717
|
// ../../../v2/editor-core/dist/document/transactions/content-locked-block-sdt.js
|
|
194699
|
-
function
|
|
194718
|
+
function isParagraphInsideNonEditableBlockSdt(state, address2) {
|
|
194700
194719
|
const index = address2.storyId === state.mainStoryId ? getMainParagraphIndexFromState(state) : getStoryParagraphIndexFromState(state, address2.storyId);
|
|
194701
194720
|
const entry = index?.byParaId(address2.blockId);
|
|
194702
194721
|
if (!entry || entry.directBodyChildOrdinal != null || entry.containingBodyChildOrdinal == null) {
|
|
@@ -194711,7 +194730,7 @@ function isParagraphInsideContentLockedBlockSdt(state, address2) {
|
|
|
194711
194730
|
return false;
|
|
194712
194731
|
const map3 = buildStructuralBoundaryMap(scanBytes);
|
|
194713
194732
|
const context = map3.byBlockId(entry.blockId) ?? map3.contexts[entry.ordinal - (chunk?.scanParagraphStartOrdinal ?? 0)] ?? null;
|
|
194714
|
-
return context?.hasContentLockedBlockSdt === true;
|
|
194733
|
+
return context?.hasContentLockedBlockSdt === true || context?.hasTextAtomicBlockSdt === true;
|
|
194715
194734
|
}
|
|
194716
194735
|
function provesNoSdtCarrier(bytes) {
|
|
194717
194736
|
if (bytes.length === 0 || bytes.includes(0))
|
|
@@ -198895,7 +198914,7 @@ function runEditTextCommit(input) {
|
|
|
198895
198914
|
return rejected2(txId, "unsupported-context");
|
|
198896
198915
|
return rejected2(txId, classifyCrossBlockEditText(bytes, op));
|
|
198897
198916
|
}
|
|
198898
|
-
if (
|
|
198917
|
+
if (isParagraphInsideNonEditableBlockSdt(state, {
|
|
198899
198918
|
storyId: op.on.storyId,
|
|
198900
198919
|
partUri: op.on.partUri,
|
|
198901
198920
|
blockId: op.on.startBlockId
|
|
@@ -198959,7 +198978,10 @@ function runDirectEditTextBatchCommit(input, edits) {
|
|
|
198959
198978
|
for (const [blockId, blockEdits] of byBlock) {
|
|
198960
198979
|
let blockUsedOverlapCompiler = false;
|
|
198961
198980
|
const paragraph = index.byParaId(blockId);
|
|
198962
|
-
if (
|
|
198981
|
+
if (isParagraphInsideNonEditableBlockSdt(state, { storyId, partUri, blockId })) {
|
|
198982
|
+
return rejected2(txId, "text-range-in-sdt");
|
|
198983
|
+
}
|
|
198984
|
+
if (!paragraph || index.duplicateParaIds.has(blockId) || paragraph.partUri !== partUri || paragraph.partRevision !== first.on.partRevision || paragraph.storyRevision !== first.on.storyRevision) {
|
|
198963
198985
|
return rejected2(txId, "patch-precondition-failed");
|
|
198964
198986
|
}
|
|
198965
198987
|
for (const edit of blockEdits) {
|
|
@@ -199378,7 +199400,10 @@ function runTrackedEditTextBatchCommit(input, edits) {
|
|
|
199378
199400
|
let requiresCollaborationSessionSync = false;
|
|
199379
199401
|
for (const [blockId, blockEdits] of byBlock) {
|
|
199380
199402
|
const paragraph = index.byParaId(blockId);
|
|
199381
|
-
if (
|
|
199403
|
+
if (isParagraphInsideNonEditableBlockSdt(state, { storyId, partUri, blockId })) {
|
|
199404
|
+
return rejected2(txId, "text-range-in-sdt");
|
|
199405
|
+
}
|
|
199406
|
+
if (!paragraph || index.duplicateParaIds.has(blockId) || paragraph.partUri !== partUri || paragraph.partRevision !== first.on.partRevision || paragraph.storyRevision !== first.on.storyRevision) {
|
|
199382
199407
|
return rejected2(txId, "patch-precondition-failed");
|
|
199383
199408
|
}
|
|
199384
199409
|
for (const edit of blockEdits) {
|
|
@@ -199774,7 +199799,7 @@ function runInsertInlineControlCommit(input) {
|
|
|
199774
199799
|
if (op.on.startByte < 0 || op.on.endByte > bytes.length || op.on.startByte > op.on.endByte) {
|
|
199775
199800
|
return rejected2(txId, "invalid-range");
|
|
199776
199801
|
}
|
|
199777
|
-
if (
|
|
199802
|
+
if (isParagraphInsideNonEditableBlockSdt(state, {
|
|
199778
199803
|
storyId: op.on.storyId,
|
|
199779
199804
|
partUri: op.on.partUri,
|
|
199780
199805
|
blockId: op.on.startBlockId
|
|
@@ -217912,6 +217937,45 @@ function collectFieldChar(fieldChars, { tag, start, end }) {
|
|
|
217912
217937
|
locked: lock === "true" || lock === "1" || lock === "on"
|
|
217913
217938
|
});
|
|
217914
217939
|
}
|
|
217940
|
+
function createFieldTokenCollector(fieldChars, instructionTokens) {
|
|
217941
|
+
const instructionContexts = [];
|
|
217942
|
+
return {
|
|
217943
|
+
onOpenTag({ tag, start, end, namespaceBindings }) {
|
|
217944
|
+
const parent = instructionContexts.at(-1);
|
|
217945
|
+
const inWordRun = parent?.inWordRun ?? false;
|
|
217946
|
+
const isWord = tag.namespaceUri === NS_W || tag.namespaceUri === NS_WSTRICT;
|
|
217947
|
+
const isMce = tag.namespaceUri === NS_MC;
|
|
217948
|
+
const isRunProxy = isMce && (tag.localName === "AlternateContent" || tag.localName === "Choice" || tag.localName === "Fallback");
|
|
217949
|
+
const context = {
|
|
217950
|
+
inWordRun: isWord && tag.localName === "r" || isRunProxy && inWordRun,
|
|
217951
|
+
deleted: (parent?.deleted ?? false) || isWord && (tag.localName === "del" || tag.localName === "moveFrom"),
|
|
217952
|
+
effective: parent?.effective ?? true,
|
|
217953
|
+
choiceSelected: isMce && tag.localName === "AlternateContent" ? false : undefined
|
|
217954
|
+
};
|
|
217955
|
+
if (isMce && parent?.choiceSelected != null) {
|
|
217956
|
+
if (tag.localName === "Choice") {
|
|
217957
|
+
const requires = readXmlAttribute(tag, "", "Requires")?.value.trim().split(/\s+/).filter(Boolean) ?? [];
|
|
217958
|
+
const selected = !parent.choiceSelected && requires.length > 0 && requires.every((prefix) => UNDERSTOOD_FIELD_INSTRUCTION_NAMESPACES.has(namespaceBindings[prefix] ?? ""));
|
|
217959
|
+
context.effective && (context.effective = selected);
|
|
217960
|
+
if (selected)
|
|
217961
|
+
parent.choiceSelected = true;
|
|
217962
|
+
} else if (tag.localName === "Fallback") {
|
|
217963
|
+
context.effective && (context.effective = !parent.choiceSelected);
|
|
217964
|
+
}
|
|
217965
|
+
}
|
|
217966
|
+
instructionContexts.push(context);
|
|
217967
|
+
if (!isWord)
|
|
217968
|
+
return;
|
|
217969
|
+
if (tag.localName === "tab" && inWordRun && !context.deleted && context.effective) {
|
|
217970
|
+
instructionTokens.push({ start, text: "\t", inlineTab: true });
|
|
217971
|
+
}
|
|
217972
|
+
collectFieldChar(fieldChars, { tag, start, end, namespaceBindings });
|
|
217973
|
+
},
|
|
217974
|
+
onCloseTag() {
|
|
217975
|
+
instructionContexts.pop();
|
|
217976
|
+
}
|
|
217977
|
+
};
|
|
217978
|
+
}
|
|
217915
217979
|
function buildFieldCatalogFromXml(input, xml, utf8Offsets) {
|
|
217916
217980
|
let paragraphScan = input.sharedParagraphScan ?? null;
|
|
217917
217981
|
const ownerResolution = {
|
|
@@ -217976,12 +218040,29 @@ function buildFieldCatalogFromXml(input, xml, utf8Offsets) {
|
|
|
217976
218040
|
}
|
|
217977
218041
|
const discovered = [];
|
|
217978
218042
|
const fieldChars = input.preparedFieldChars ?? discovered;
|
|
218043
|
+
const instructionTokens = [...input.preparedInstructionTokens ?? []];
|
|
217979
218044
|
if (input.preparedFieldChars === undefined && /<(?:[\w.-]+:)?fldChar\b/.test(xml)) {
|
|
217980
|
-
walkXmlElements(xml,
|
|
218045
|
+
walkXmlElements(xml, createFieldTokenCollector(discovered, instructionTokens));
|
|
218046
|
+
}
|
|
218047
|
+
if (fieldChars.length > 0) {
|
|
218048
|
+
const instrTextRe = /<[\w.-]+:instrText\b[^>]*>([\s\S]*?)<\/[\w.-]+:instrText>/g;
|
|
218049
|
+
for (let match = instrTextRe.exec(xml);match; match = instrTextRe.exec(xml)) {
|
|
218050
|
+
instructionTokens.push({ start: match.index, text: decodeXmlText(match[1]) });
|
|
218051
|
+
}
|
|
218052
|
+
instructionTokens.sort((left, right) => left.start - right.start);
|
|
217981
218053
|
}
|
|
217982
|
-
|
|
218054
|
+
let instructionIndex = 0;
|
|
217983
218055
|
const stack = [];
|
|
217984
218056
|
for (const marker of fieldChars) {
|
|
218057
|
+
while (instructionIndex < instructionTokens.length && instructionTokens[instructionIndex].start < marker.start) {
|
|
218058
|
+
const token = instructionTokens[instructionIndex++];
|
|
218059
|
+
if (token.inlineTab && stack.at(-1)?.separateAt != null)
|
|
218060
|
+
continue;
|
|
218061
|
+
for (const frame of stack) {
|
|
218062
|
+
if (frame.separateAt == null)
|
|
218063
|
+
frame.instructionFragments.push(token.text);
|
|
218064
|
+
}
|
|
218065
|
+
}
|
|
217985
218066
|
const charType = marker.type;
|
|
217986
218067
|
const matchStart = marker.start;
|
|
217987
218068
|
const matchEnd = marker.end;
|
|
@@ -218016,16 +218097,7 @@ function buildFieldCatalogFromXml(input, xml, utf8Offsets) {
|
|
|
218016
218097
|
const fieldEnd = endEnclosingRunEnd;
|
|
218017
218098
|
const resultStart = frame.resultStartOffset ?? fieldEnd;
|
|
218018
218099
|
const resultEnd = Math.max(resultStart, enclosingRunStart(xml, matchStart));
|
|
218019
|
-
const
|
|
218020
|
-
const instrSpanEnd = frame.separateAt ?? matchStart;
|
|
218021
|
-
const instrSlice = xml.slice(instrSpanStart, instrSpanEnd);
|
|
218022
|
-
const instrTextParts = [];
|
|
218023
|
-
let instrM;
|
|
218024
|
-
const instrLocal = new RegExp(instrTextRe.source, "g");
|
|
218025
|
-
while ((instrM = instrLocal.exec(instrSlice)) != null) {
|
|
218026
|
-
instrTextParts.push(decodeXmlText(instrM[2] ?? ""));
|
|
218027
|
-
}
|
|
218028
|
-
const instructionText = instrTextParts.join("").trim();
|
|
218100
|
+
const instructionText = frame.instructionFragments.join("").trim();
|
|
218029
218101
|
const resultText = frame.separateAt != null ? extractText(xml.slice(resultStart, resultEnd)) : "";
|
|
218030
218102
|
const paraId = enclosingParaId(frame.beginOffset);
|
|
218031
218103
|
const byteStart = byteOffsetAt3(utf8Offsets, fieldStart);
|
|
@@ -218539,12 +218611,13 @@ async function buildFieldCatalogForStoryCooperatively(input) {
|
|
|
218539
218611
|
}
|
|
218540
218612
|
}
|
|
218541
218613
|
const preparedFieldChars = [];
|
|
218614
|
+
const preparedInstructionTokens = [];
|
|
218542
218615
|
if (/<(?:[\w.-]+:)?fldChar\b/.test(decoded.xml)) {
|
|
218543
218616
|
let aborted2 = false;
|
|
218544
218617
|
let yieldFailed = false;
|
|
218545
218618
|
let yieldError;
|
|
218546
218619
|
await walkXmlElementsCooperatively(decoded.xml, {
|
|
218547
|
-
|
|
218620
|
+
...createFieldTokenCollector(preparedFieldChars, preparedInstructionTokens),
|
|
218548
218621
|
yieldPoint: async () => {
|
|
218549
218622
|
let current;
|
|
218550
218623
|
try {
|
|
@@ -218576,6 +218649,7 @@ async function buildFieldCatalogForStoryCooperatively(input) {
|
|
|
218576
218649
|
storyId: input.storyId,
|
|
218577
218650
|
partUri: input.partUri,
|
|
218578
218651
|
preparedFieldChars,
|
|
218652
|
+
preparedInstructionTokens,
|
|
218579
218653
|
...paragraphOwnerResolver ? { paragraphOwnerResolver } : { sharedParagraphScan }
|
|
218580
218654
|
}, decoded.xml, utf8Offsets);
|
|
218581
218655
|
catalog.ownerResolution.packedRejectionReason = ownerDiagnostics.rejectionReason;
|
|
@@ -218606,7 +218680,7 @@ function listFieldCatalogsForState(state) {
|
|
|
218606
218680
|
}
|
|
218607
218681
|
return out;
|
|
218608
218682
|
}
|
|
218609
|
-
var TD53, UTF8_OFFSET_CHECKPOINT_STRIDE = 256, FIELD_CANDIDATE_BYTES, FIELD_CANDIDATE_SEARCHES, STATE_CACHE2, STATE_IN_FLIGHT, DECODED_PART_IN_FLIGHT;
|
|
218683
|
+
var TD53, UTF8_OFFSET_CHECKPOINT_STRIDE = 256, UNDERSTOOD_FIELD_INSTRUCTION_NAMESPACES, FIELD_CANDIDATE_BYTES, FIELD_CANDIDATE_SEARCHES, STATE_CACHE2, STATE_IN_FLIGHT, DECODED_PART_IN_FLIGHT;
|
|
218610
218684
|
var init_field_catalog = __esm(() => {
|
|
218611
218685
|
init_sd_document_state();
|
|
218612
218686
|
init_xml_text();
|
|
@@ -218615,6 +218689,7 @@ var init_field_catalog = __esm(() => {
|
|
|
218615
218689
|
init_part_wml_scan_cache();
|
|
218616
218690
|
init_field_paragraph_owner();
|
|
218617
218691
|
TD53 = new TextDecoder;
|
|
218692
|
+
UNDERSTOOD_FIELD_INSTRUCTION_NAMESPACES = new Set([NS_W, NS_WSTRICT, NS_W14]);
|
|
218618
218693
|
FIELD_CANDIDATE_BYTES = [["fldSimple", 3], ["fldChar", 3], ["instrText", 7]];
|
|
218619
218694
|
FIELD_CANDIDATE_SEARCHES = FIELD_CANDIDATE_BYTES.map(([token, anchorOffset]) => ({
|
|
218620
218695
|
token: new TextEncoder().encode(token),
|
|
@@ -224191,11 +224266,11 @@ function runTrackedTextMoveCommit(input) {
|
|
|
224191
224266
|
if (source.value.entry.storyId !== input.state.mainStoryId) {
|
|
224192
224267
|
return rejected10(input.txId, "tracked-text-move-cross-story");
|
|
224193
224268
|
}
|
|
224194
|
-
if (
|
|
224269
|
+
if (isParagraphInsideNonEditableBlockSdt(input.state, {
|
|
224195
224270
|
storyId: source.value.entry.storyId,
|
|
224196
224271
|
partUri: source.value.entry.partUri,
|
|
224197
224272
|
blockId: source.value.entry.blockId
|
|
224198
|
-
}) ||
|
|
224273
|
+
}) || isParagraphInsideNonEditableBlockSdt(input.state, {
|
|
224199
224274
|
storyId: destination.entry.storyId,
|
|
224200
224275
|
partUri: destination.entry.partUri,
|
|
224201
224276
|
blockId: destination.entry.blockId
|
|
@@ -290292,6 +290367,107 @@ var init_section_xml = __esm(() => {
|
|
|
290292
290367
|
SECTPR_CHILD_RANK = new Map(SECTPR_CHILD_ORDER.map((name, index) => [name, index]));
|
|
290293
290368
|
});
|
|
290294
290369
|
|
|
290370
|
+
// ../../../v2/document-api-v2-adapter/dist/formatting/paragraph-property-order.js
|
|
290371
|
+
function setParagraphPropertyChild(children2, localName2, xml) {
|
|
290372
|
+
const parsed = parseSingleElement(xml);
|
|
290373
|
+
const existingIndex = children2.findIndex((child) => child.localName === localName2);
|
|
290374
|
+
if (existingIndex >= 0) {
|
|
290375
|
+
const next = [...children2];
|
|
290376
|
+
next[existingIndex] = parsed;
|
|
290377
|
+
return next;
|
|
290378
|
+
}
|
|
290379
|
+
const targetRank = PARAGRAPH_PROPERTY_CHILD_RANK.get(localName2);
|
|
290380
|
+
if (targetRank == null)
|
|
290381
|
+
throw new Error(`Unknown paragraph property child: ${localName2}`);
|
|
290382
|
+
let insertionIndex = 0;
|
|
290383
|
+
for (const [index, child] of children2.entries()) {
|
|
290384
|
+
const childRank = paragraphPropertyRankRange(child);
|
|
290385
|
+
if (!childRank)
|
|
290386
|
+
continue;
|
|
290387
|
+
if (childRank.minimum > targetRank) {
|
|
290388
|
+
return [...children2.slice(0, index), parsed, ...children2.slice(index)];
|
|
290389
|
+
}
|
|
290390
|
+
if (childRank.maximum >= targetRank) {
|
|
290391
|
+
throw new ParagraphPropertyMutationUnavailableError(`Cannot safely insert w:${localName2} within mc:AlternateContent paragraph properties`);
|
|
290392
|
+
}
|
|
290393
|
+
insertionIndex = index + 1;
|
|
290394
|
+
}
|
|
290395
|
+
return [...children2.slice(0, insertionIndex), parsed, ...children2.slice(insertionIndex)];
|
|
290396
|
+
}
|
|
290397
|
+
function paragraphPropertyRankRange(child) {
|
|
290398
|
+
const directRank = PARAGRAPH_PROPERTY_CHILD_RANK.get(child.localName);
|
|
290399
|
+
if (directRank != null)
|
|
290400
|
+
return { minimum: directRank, maximum: directRank };
|
|
290401
|
+
if (child.localName !== "AlternateContent")
|
|
290402
|
+
return null;
|
|
290403
|
+
const alternateContent = parseContainerXml(child.xml, "AlternateContent");
|
|
290404
|
+
if (!alternateContent)
|
|
290405
|
+
return null;
|
|
290406
|
+
const ranks = parseTopLevelChildren(alternateContent.inner).flatMap((branch) => {
|
|
290407
|
+
if (branch.localName !== "Choice" && branch.localName !== "Fallback")
|
|
290408
|
+
return [];
|
|
290409
|
+
const branchContainer = parseContainerXml(branch.xml, branch.localName);
|
|
290410
|
+
if (!branchContainer)
|
|
290411
|
+
return [];
|
|
290412
|
+
return parseTopLevelChildren(branchContainer.inner).flatMap((candidate2) => {
|
|
290413
|
+
const range = paragraphPropertyRankRange(candidate2);
|
|
290414
|
+
return range ? [range.minimum, range.maximum] : [];
|
|
290415
|
+
});
|
|
290416
|
+
});
|
|
290417
|
+
if (ranks.length === 0)
|
|
290418
|
+
return null;
|
|
290419
|
+
return { minimum: Math.min(...ranks), maximum: Math.max(...ranks) };
|
|
290420
|
+
}
|
|
290421
|
+
var PARAGRAPH_PROPERTY_CHILD_ORDER, PARAGRAPH_PROPERTY_CHILD_RANK, ParagraphPropertyMutationUnavailableError;
|
|
290422
|
+
var init_paragraph_property_order = __esm(() => {
|
|
290423
|
+
init_common();
|
|
290424
|
+
PARAGRAPH_PROPERTY_CHILD_ORDER = [
|
|
290425
|
+
"pStyle",
|
|
290426
|
+
"keepNext",
|
|
290427
|
+
"keepLines",
|
|
290428
|
+
"pageBreakBefore",
|
|
290429
|
+
"framePr",
|
|
290430
|
+
"widowControl",
|
|
290431
|
+
"numPr",
|
|
290432
|
+
"suppressLineNumbers",
|
|
290433
|
+
"pBdr",
|
|
290434
|
+
"shd",
|
|
290435
|
+
"tabs",
|
|
290436
|
+
"suppressAutoHyphens",
|
|
290437
|
+
"kinsoku",
|
|
290438
|
+
"wordWrap",
|
|
290439
|
+
"overflowPunct",
|
|
290440
|
+
"topLinePunct",
|
|
290441
|
+
"autoSpaceDE",
|
|
290442
|
+
"autoSpaceDN",
|
|
290443
|
+
"bidi",
|
|
290444
|
+
"adjustRightInd",
|
|
290445
|
+
"snapToGrid",
|
|
290446
|
+
"spacing",
|
|
290447
|
+
"ind",
|
|
290448
|
+
"contextualSpacing",
|
|
290449
|
+
"mirrorIndents",
|
|
290450
|
+
"suppressOverlap",
|
|
290451
|
+
"jc",
|
|
290452
|
+
"textDirection",
|
|
290453
|
+
"textAlignment",
|
|
290454
|
+
"textboxTightWrap",
|
|
290455
|
+
"outlineLvl",
|
|
290456
|
+
"divId",
|
|
290457
|
+
"cnfStyle",
|
|
290458
|
+
"rPr",
|
|
290459
|
+
"sectPr",
|
|
290460
|
+
"pPrChange"
|
|
290461
|
+
];
|
|
290462
|
+
PARAGRAPH_PROPERTY_CHILD_RANK = new Map(PARAGRAPH_PROPERTY_CHILD_ORDER.map((name, index) => [name, index]));
|
|
290463
|
+
ParagraphPropertyMutationUnavailableError = class ParagraphPropertyMutationUnavailableError extends Error {
|
|
290464
|
+
constructor(message) {
|
|
290465
|
+
super(message);
|
|
290466
|
+
this.name = "ParagraphPropertyMutationUnavailableError";
|
|
290467
|
+
}
|
|
290468
|
+
};
|
|
290469
|
+
});
|
|
290470
|
+
|
|
290295
290471
|
// ../../../v2/document-api-v2-adapter/dist/references/date-time-field.js
|
|
290296
290472
|
function readDateTimePictureSwitch(instruction) {
|
|
290297
290473
|
return /\\@\s+"([^"]*)"/u.exec(instruction)?.[1] ?? null;
|
|
@@ -292099,17 +292275,18 @@ function buildTocFieldBodyXml(context, instruction, options) {
|
|
|
292099
292275
|
return buildComplexFieldXml(instruction, buildTocFieldResultXml(context, instruction, options));
|
|
292100
292276
|
}
|
|
292101
292277
|
function buildTocFieldResultXml(context, instruction, options) {
|
|
292102
|
-
|
|
292103
|
-
|
|
292104
|
-
|
|
292105
|
-
const
|
|
292278
|
+
return buildTocFieldResult(context, instruction, options).xml;
|
|
292279
|
+
}
|
|
292280
|
+
function buildTocFieldResult(context, instruction, options) {
|
|
292281
|
+
const emptyText = shouldUseV1EmptyTocSourceSet(instruction) ? "No table of contents entries found." : "";
|
|
292282
|
+
const entries = emptyText ? [] : buildTocEntries(context, instruction, options?.currentField, options?.preservedTocPages, options?.tocBookmarkNames);
|
|
292106
292283
|
if (options?.currentField) {
|
|
292107
|
-
return buildTocResultXmlPreservingParagraphs(context, instruction, entries, options.currentField);
|
|
292284
|
+
return buildTocResultXmlPreservingParagraphs(context, instruction, entries, options.currentField, emptyText);
|
|
292108
292285
|
}
|
|
292109
|
-
return buildTocResultRunsXml(instruction, entries);
|
|
292286
|
+
return { xml: emptyText ? buildTextRunXml(emptyText) : buildTocResultRunsXml(instruction, entries) };
|
|
292110
292287
|
}
|
|
292111
292288
|
function buildTocFieldXml(context, instruction, options) {
|
|
292112
|
-
const contentXml = options?.currentField && options.preserveParagraphs ? buildTocFieldBodyXml(context, instruction, options) : buildNewTocFieldContentXml(context, instruction, options?.seedParagraph, options?.currentField, options?.preservedTocPages, options?.reservedParaIds, options?.tocBookmarkNames);
|
|
292289
|
+
const contentXml = options?.currentField && options.preserveParagraphs ? buildTocFieldBodyXml(context, instruction, options) : buildNewTocFieldContentXml(context, instruction, options?.seedParagraph, options?.currentField, options?.preservedTocPages, options?.reservedParaIds, options?.tocBookmarkNames, options?.insertionByteStart);
|
|
292113
292290
|
if (options?.bare)
|
|
292114
292291
|
return contentXml;
|
|
292115
292292
|
return "<w:sdt>" + "<w:sdtPr>" + "<w:docPartObj>" + '<w:docPartGallery w:val="Table of Contents"/>' + "<w:docPartUnique/>" + "</w:docPartObj>" + "</w:sdtPr>" + "<w:sdtContent>" + contentXml + "</w:sdtContent>" + "</w:sdt>";
|
|
@@ -292496,28 +292673,8 @@ function prepareTocSdtReplacement(context, entry, instruction, tocBookmarkNames)
|
|
|
292496
292673
|
afterXml: buildNewTocFieldContentXml(context, instruction, paragraph2, entry, preservedTocPages, reservedParaIds, tocBookmarkNames)
|
|
292497
292674
|
};
|
|
292498
292675
|
}
|
|
292499
|
-
function replaceTocSdtXml(context, entry, instruction, txIdPrefix) {
|
|
292500
|
-
const prepared = prepareTocSdtReplacement(context, entry, instruction);
|
|
292501
|
-
if (!prepared.ok)
|
|
292502
|
-
return prepared;
|
|
292503
|
-
const nextBytes = spliceBytes3(prepared.bytes, prepared.byteStart, prepared.byteEnd, encodeXml(prepared.afterXml));
|
|
292504
|
-
return commitKernelStorySurfacePatch({
|
|
292505
|
-
context,
|
|
292506
|
-
txIdPrefix,
|
|
292507
|
-
perPart: { [entry.partUri]: replaceWholePartEntry(prepared.bytes, nextBytes) },
|
|
292508
|
-
storyIds: [entry.storyId],
|
|
292509
|
-
signalLanesToRebuild: ["paragraphIndex", "headings", "noteAnchorRefs"]
|
|
292510
|
-
});
|
|
292511
|
-
}
|
|
292512
292676
|
function replaceTocXml(context, entry, instruction, txIdPrefix) {
|
|
292513
|
-
const
|
|
292514
|
-
if (sdtReplacement.ok || sdtReplacement.message !== "Unable to locate the containing TOC content control.") {
|
|
292515
|
-
return sdtReplacement;
|
|
292516
|
-
}
|
|
292517
|
-
return replaceBareTocFieldXml(context, entry, instruction, txIdPrefix);
|
|
292518
|
-
}
|
|
292519
|
-
function replaceBareTocFieldXml(context, entry, instruction, txIdPrefix) {
|
|
292520
|
-
const prepared = prepareBareTocFieldReplacement(context, entry, instruction);
|
|
292677
|
+
const prepared = prepareTocReplacement(context, entry, instruction);
|
|
292521
292678
|
if (!prepared.ok)
|
|
292522
292679
|
return prepared;
|
|
292523
292680
|
const nextBytes = spliceBytes3(prepared.bytes, prepared.byteStart, prepared.byteEnd, encodeXml(prepared.afterXml));
|
|
@@ -292529,6 +292686,10 @@ function replaceBareTocFieldXml(context, entry, instruction, txIdPrefix) {
|
|
|
292529
292686
|
signalLanesToRebuild: ["paragraphIndex", "headings", "noteAnchorRefs"]
|
|
292530
292687
|
});
|
|
292531
292688
|
}
|
|
292689
|
+
function prepareTocReplacement(context, entry, instruction, tocBookmarkNames) {
|
|
292690
|
+
const sdt = prepareTocSdtReplacement(context, entry, instruction, tocBookmarkNames);
|
|
292691
|
+
return !sdt.ok && sdt.message === "Unable to locate the containing TOC content control." ? prepareBareTocFieldReplacement(context, entry, instruction, tocBookmarkNames) : sdt;
|
|
292692
|
+
}
|
|
292532
292693
|
function prepareBareTocReplacement(context, entry, instruction, tocBookmarkNames) {
|
|
292533
292694
|
const prepared = prepareBareTocFieldReplacement(context, entry, instruction, tocBookmarkNames);
|
|
292534
292695
|
if (!prepared.ok)
|
|
@@ -292568,18 +292729,112 @@ function prepareBareTocFieldReplacement(context, entry, instruction, tocBookmark
|
|
|
292568
292729
|
}
|
|
292569
292730
|
const xml = TD83.decode(bytes);
|
|
292570
292731
|
const preservedTocPages = readPreservedTocPagesFromPartXml(xml);
|
|
292571
|
-
const
|
|
292732
|
+
const result = buildTocFieldResult(context, instruction, { currentField: entry, preservedTocPages, tocBookmarkNames });
|
|
292733
|
+
const nextFieldXml = buildComplexFieldXml(instruction, result.xml);
|
|
292734
|
+
const fieldStartChar = TD83.decode(bytes.subarray(0, entry.descriptor.byteStart)).length;
|
|
292735
|
+
const fieldEndChar = TD83.decode(bytes.subarray(0, entry.descriptor.byteEnd)).length;
|
|
292736
|
+
const paragraphStart = findEnclosingParagraphStart(xml, fieldStartChar, 0);
|
|
292737
|
+
const paragraphOpenEnd = paragraphStart >= 0 ? findXmlTagEnd4(xml, paragraphStart + 1) : -1;
|
|
292738
|
+
const paragraphCloseStart = xml.indexOf("</w:p>", fieldStartChar);
|
|
292739
|
+
const paragraphPropertiesStart = paragraphOpenEnd >= 0 ? skipXmlWhitespace(xml, paragraphOpenEnd) : -1;
|
|
292740
|
+
const paragraphProperties = paragraphOpenEnd >= 0 ? matchLeadingElement(xml.slice(paragraphPropertiesStart, fieldStartChar), "pPr") : "";
|
|
292741
|
+
const ownsFirstParagraph = entry.descriptor.complete && paragraphOpenEnd >= 0 && paragraphCloseStart >= fieldStartChar && readTocParagraphLevel(paragraphProperties) != null && xml.slice(paragraphPropertiesStart + paragraphProperties.length, fieldStartChar).trim() === "" && (fieldEndChar >= paragraphCloseStart || xml.slice(fieldEndChar, paragraphCloseStart).trim() === "");
|
|
292742
|
+
const replaceParagraphProperties = ownsFirstParagraph && result.firstParagraphProperties != null;
|
|
292743
|
+
const byteStart = replaceParagraphProperties ? encodeXml(xml.slice(0, paragraphOpenEnd)).length : entry.descriptor.byteStart;
|
|
292744
|
+
const nextParagraphProperties = replaceParagraphProperties ? preserveTocOwnerProperties(result.firstParagraphProperties, paragraphProperties) : "";
|
|
292745
|
+
const afterXml = nextParagraphProperties + nextFieldXml;
|
|
292746
|
+
const nextXml = TD83.decode(spliceBytes3(bytes, byteStart, entry.descriptor.byteEnd, encodeXml(afterXml)));
|
|
292747
|
+
if (collectXmlElementRanges(nextXml).errors.length > 0) {
|
|
292748
|
+
return {
|
|
292749
|
+
ok: false,
|
|
292750
|
+
code: "CAPABILITY_UNAVAILABLE",
|
|
292751
|
+
message: "The bare TOC replacement crosses unsupported XML boundaries."
|
|
292752
|
+
};
|
|
292753
|
+
}
|
|
292572
292754
|
return {
|
|
292573
292755
|
ok: true,
|
|
292574
292756
|
bytes,
|
|
292575
|
-
byteStart
|
|
292757
|
+
byteStart,
|
|
292576
292758
|
byteEnd: entry.descriptor.byteEnd,
|
|
292577
|
-
beforeXml: TD83.decode(bytes.subarray(
|
|
292578
|
-
afterXml
|
|
292759
|
+
beforeXml: TD83.decode(bytes.subarray(byteStart, entry.descriptor.byteEnd)),
|
|
292760
|
+
afterXml
|
|
292579
292761
|
};
|
|
292580
292762
|
}
|
|
292763
|
+
function findDirectChild(xml, localName2) {
|
|
292764
|
+
return scanDirectElementChildren(xml).find((child) => xmlLocalName(child.qname) === localName2);
|
|
292765
|
+
}
|
|
292766
|
+
function removeTocOwnerPropertiesFromTemplate(xml) {
|
|
292767
|
+
const properties = matchLeadingElement(xml, "pPr") || findDirectChild(xml, "pPr")?.xml;
|
|
292768
|
+
if (!properties)
|
|
292769
|
+
return xml;
|
|
292770
|
+
for (const child of scanDirectElementChildren(properties)) {
|
|
292771
|
+
if (["rPr", "sectPr", "pPrChange"].includes(xmlLocalName(child.qname))) {
|
|
292772
|
+
xml = xml.replace(child.xml, "");
|
|
292773
|
+
}
|
|
292774
|
+
}
|
|
292775
|
+
return xml;
|
|
292776
|
+
}
|
|
292777
|
+
function preserveTocOwnerProperties(template, ownerProperties) {
|
|
292778
|
+
const properties = removeTocOwnerPropertiesFromTemplate(template);
|
|
292779
|
+
const retained = ["rPr", "sectPr", "pPrChange"].map((name) => {
|
|
292780
|
+
const child = findDirectChild(ownerProperties, name);
|
|
292781
|
+
return child ? inheritRunNamespaceDeclarations(child.xml, ownerProperties, ownerProperties.indexOf(child.xml), ownerProperties.slice(0, findXmlTagEnd4(ownerProperties, 1))) : "";
|
|
292782
|
+
}).join("");
|
|
292783
|
+
const insertAt = properties.lastIndexOf("</");
|
|
292784
|
+
return properties.slice(0, insertAt) + retained + properties.slice(insertAt);
|
|
292785
|
+
}
|
|
292786
|
+
function removeTocSectionBoundaryFromTemplate(xml) {
|
|
292787
|
+
const properties = matchLeadingElement(xml, "pPr") || findDirectChild(xml, "pPr")?.xml;
|
|
292788
|
+
if (!properties)
|
|
292789
|
+
return xml;
|
|
292790
|
+
const section = findDirectChild(properties, "sectPr");
|
|
292791
|
+
return section ? xml.replace(section.xml, "") : xml;
|
|
292792
|
+
}
|
|
292793
|
+
function readTocContinuationSectionPlacement(paragraphs, entryCount) {
|
|
292794
|
+
const byEntryIndex = new Map;
|
|
292795
|
+
const carriers = [];
|
|
292796
|
+
for (const [index, paragraph2] of paragraphs.entries()) {
|
|
292797
|
+
if (index === 0)
|
|
292798
|
+
continue;
|
|
292799
|
+
const properties = findDirectChild(paragraph2, "pPr");
|
|
292800
|
+
if (!properties || !findDirectChild(properties.xml, "sectPr"))
|
|
292801
|
+
continue;
|
|
292802
|
+
if (index === paragraphs.length - 1) {
|
|
292803
|
+
const lastEntryIndex = entryCount - 1;
|
|
292804
|
+
if (readTocParagraphTemplateText(paragraph2) && lastEntryIndex > 0 && !byEntryIndex.has(lastEntryIndex) && carriers.length === 0) {
|
|
292805
|
+
byEntryIndex.set(lastEntryIndex, paragraph2);
|
|
292806
|
+
} else {
|
|
292807
|
+
carriers.push(paragraph2);
|
|
292808
|
+
}
|
|
292809
|
+
} else if (index < entryCount) {
|
|
292810
|
+
byEntryIndex.set(index, paragraph2);
|
|
292811
|
+
} else {
|
|
292812
|
+
carriers.push(paragraph2);
|
|
292813
|
+
}
|
|
292814
|
+
}
|
|
292815
|
+
return { byEntryIndex, carriers };
|
|
292816
|
+
}
|
|
292817
|
+
function buildTocSectionOwnerParagraphOpen(template, owner) {
|
|
292818
|
+
const openEnd = findXmlTagEnd4(template, 1);
|
|
292819
|
+
const properties = inheritRunNamespaceDeclarations(template.slice(openEnd) || "<w:pPr></w:pPr>", template, openEnd, template.slice(0, openEnd));
|
|
292820
|
+
const ownerProperties = findDirectChild(owner, "pPr").xml;
|
|
292821
|
+
const retainedProperties = inheritRunNamespaceDeclarations(ownerProperties, owner, owner.indexOf(ownerProperties), readParagraphOpenTag(owner));
|
|
292822
|
+
return readParagraphOpenTag(owner) + preserveTocOwnerProperties(properties, retainedProperties);
|
|
292823
|
+
}
|
|
292824
|
+
function preserveTocContinuationSectionOpen(template, index, sectionOwners, usedParaIds) {
|
|
292825
|
+
const owner = sectionOwners.get(index);
|
|
292826
|
+
const open2 = removeTocSectionBoundaryFromTemplate(template);
|
|
292827
|
+
if (!owner)
|
|
292828
|
+
return open2 === template ? open2 : removeTocOwnerPropertiesFromTemplate(template);
|
|
292829
|
+
for (const id of collectParaIdsInXml(readParagraphOpenTag(owner)))
|
|
292830
|
+
usedParaIds.delete(id);
|
|
292831
|
+
return buildTocSectionOwnerParagraphOpen(open2, owner);
|
|
292832
|
+
}
|
|
292833
|
+
function buildTocSectionCarrierXml(owner) {
|
|
292834
|
+
return buildTocSectionOwnerParagraphOpen("<w:p><w:pPr></w:pPr>", owner) + "</w:p>";
|
|
292835
|
+
}
|
|
292581
292836
|
function shouldUseV1EmptyTocSourceSet(instruction) {
|
|
292582
|
-
return parseQuotedSwitch(instruction, "t") != null && parseNumericSwitchRange(instruction, "o") == null && !/\\u\b/i.test(instruction) &&
|
|
292837
|
+
return parseQuotedSwitch(instruction, "t") != null && parseNumericSwitchRange(instruction, "o") == null && !/\\u\b/i.test(instruction) && !parseTocTcSourceSelection(instruction).enabled;
|
|
292583
292838
|
}
|
|
292584
292839
|
function findLastSdtStart(xmlPrefix2) {
|
|
292585
292840
|
let start = -1;
|
|
@@ -292873,6 +293128,104 @@ function resolveBookmarkSpanInParagraph(context, entry) {
|
|
|
292873
293128
|
text: map3.visibleText().slice(startOffset, endOffset)
|
|
292874
293129
|
};
|
|
292875
293130
|
}
|
|
293131
|
+
function buildParagraphBookmarkMarkers(paragraph2, insertion, id) {
|
|
293132
|
+
const namespace = insertion.fieldSource || paragraph2.namespaceBindings?.w !== WORDPROCESSINGML_NAMESPACE5 ? ` xmlns:w="${WORDPROCESSINGML_NAMESPACE5}"` : "";
|
|
293133
|
+
return {
|
|
293134
|
+
startXml: `<w:bookmarkStart${namespace} w:id="${xmlEscapeAttr(String(id))}" w:name="${xmlEscapeAttr(insertion.name)}"${insertion.tableColumn ? ` w:colFirst="${insertion.tableColumn.colFirst}" w:colLast="${insertion.tableColumn.colLast}"` : ""}/>`,
|
|
293135
|
+
endXml: `<w:bookmarkEnd${namespace} w:id="${xmlEscapeAttr(String(id))}"/>`
|
|
293136
|
+
};
|
|
293137
|
+
}
|
|
293138
|
+
function readBookmarkInsertionNamespaceBindings(paragraph2, insertion) {
|
|
293139
|
+
if (!insertion.fieldSource)
|
|
293140
|
+
return new Map(Object.entries(paragraph2.namespaceBindings ?? {}));
|
|
293141
|
+
const relativeByte = insertion.fieldSource.byteStart - paragraph2.byteStart;
|
|
293142
|
+
const charStart = TD83.decode(encodeXml(paragraph2.rawXml).subarray(0, relativeByte)).length;
|
|
293143
|
+
const parsed = collectXmlElementRanges(paragraph2.rawXml, {
|
|
293144
|
+
fragment: true,
|
|
293145
|
+
additionalNamespaces: paragraph2.namespaceBindings
|
|
293146
|
+
});
|
|
293147
|
+
const parent = parsed.ranges.filter((range) => !range.tag.isSelfClosing && range.openEnd <= charStart && range.closeStart > charStart).sort((left, right) => right.start - left.start)[0];
|
|
293148
|
+
return parsed.errors.length || !parent ? null : new Map(Object.entries(parent.namespaceBindings));
|
|
293149
|
+
}
|
|
293150
|
+
function canPlaceBookmarkAtFieldSource(paragraph2, fieldSource) {
|
|
293151
|
+
return prepareBookmarkParagraphGroups([paragraph2], [{
|
|
293152
|
+
blockId: paragraph2.blockId,
|
|
293153
|
+
name: "_TocPlacement",
|
|
293154
|
+
fieldSource,
|
|
293155
|
+
startXml: `<w:bookmarkStart xmlns:w="${WORDPROCESSINGML_NAMESPACE5}" w:id="0" w:name="_TocPlacement"/>`,
|
|
293156
|
+
endXml: `<w:bookmarkEnd xmlns:w="${WORDPROCESSINGML_NAMESPACE5}" w:id="0"/>`
|
|
293157
|
+
}]) != null;
|
|
293158
|
+
}
|
|
293159
|
+
function prepareBookmarkParagraphGroups(paragraphs, insertions) {
|
|
293160
|
+
const paragraphsById = new Map;
|
|
293161
|
+
for (const paragraph2 of paragraphs) {
|
|
293162
|
+
paragraphsById.set(paragraph2.blockId, paragraphsById.has(paragraph2.blockId) ? null : paragraph2);
|
|
293163
|
+
}
|
|
293164
|
+
const groups = new Map;
|
|
293165
|
+
for (const insertion of insertions) {
|
|
293166
|
+
if (!paragraphsById.get(insertion.blockId))
|
|
293167
|
+
return null;
|
|
293168
|
+
const group = groups.get(insertion.blockId) ?? [];
|
|
293169
|
+
group.push(insertion);
|
|
293170
|
+
groups.set(insertion.blockId, group);
|
|
293171
|
+
}
|
|
293172
|
+
const result = [];
|
|
293173
|
+
for (const [blockId, group] of groups) {
|
|
293174
|
+
const paragraph2 = paragraphsById.get(blockId);
|
|
293175
|
+
const generic = group.filter((insertion) => !insertion.fieldSource);
|
|
293176
|
+
if (generic.length > 1)
|
|
293177
|
+
return null;
|
|
293178
|
+
const parsed = collectXmlElementRanges(paragraph2.rawXml, {
|
|
293179
|
+
fragment: true,
|
|
293180
|
+
additionalNamespaces: paragraph2.namespaceBindings
|
|
293181
|
+
});
|
|
293182
|
+
const root = parsed.ranges.find((range) => range.start === 0 && range.end === paragraph2.rawXml.length);
|
|
293183
|
+
if (parsed.errors.length || !root || root.tag.localName !== "p" || root.tag.namespaceUri !== WORDPROCESSINGML_NAMESPACE5)
|
|
293184
|
+
return null;
|
|
293185
|
+
const fields = group.filter((insertion) => insertion.fieldSource).sort((left, right) => right.fieldSource.byteStart - left.fieldSource.byteStart);
|
|
293186
|
+
const original = encodeXml(paragraph2.rawXml);
|
|
293187
|
+
let next = original;
|
|
293188
|
+
let previousStart = paragraph2.byteEnd;
|
|
293189
|
+
const keys = new Set;
|
|
293190
|
+
for (const insertion of fields) {
|
|
293191
|
+
const source = insertion.fieldSource;
|
|
293192
|
+
if (keys.has(source.key) || !Number.isInteger(source.byteStart) || !Number.isInteger(source.byteEnd) || source.byteStart < paragraph2.byteStart || source.byteEnd > previousStart || source.byteEnd <= source.byteStart)
|
|
293193
|
+
return null;
|
|
293194
|
+
keys.add(source.key);
|
|
293195
|
+
const start = source.byteStart - paragraph2.byteStart;
|
|
293196
|
+
const end = source.byteEnd - paragraph2.byteStart;
|
|
293197
|
+
const startChar = TD83.decode(original.subarray(0, start)).length;
|
|
293198
|
+
const endChar = TD83.decode(original.subarray(0, end)).length;
|
|
293199
|
+
if (encodeXml(paragraph2.rawXml.slice(0, startChar)).length !== start || encodeXml(paragraph2.rawXml.slice(0, endChar)).length !== end)
|
|
293200
|
+
return null;
|
|
293201
|
+
const first = parsed.ranges.find((range) => range.start === startChar && range.tag.namespaceUri === WORDPROCESSINGML_NAMESPACE5 && (range.tag.localName === "r" || range.tag.localName === "fldSimple"));
|
|
293202
|
+
const last = parsed.ranges.find((range) => range.end === endChar && range.tag.namespaceUri === WORDPROCESSINGML_NAMESPACE5 && range.tag.localName === first?.tag.localName);
|
|
293203
|
+
const parent = (range) => parsed.ranges.filter((candidate2) => candidate2.start < range.start && candidate2.end > range.end).sort((a, b) => b.start - a.start)[0];
|
|
293204
|
+
if (!first || !last || first.start < root.openEnd || last.end > root.closeStart || parent(first)?.start !== parent(last)?.start || first.tag.localName === "fldSimple" && first !== last)
|
|
293205
|
+
return null;
|
|
293206
|
+
if (first.tag.localName === "r") {
|
|
293207
|
+
const hasMarker = (run, kind) => parsed.ranges.some((range) => range.start >= run.start && range.end <= run.end && range.tag.namespaceUri === WORDPROCESSINGML_NAMESPACE5 && range.tag.localName === "fldChar" && range.tag.attributes.some((attribute) => attribute.namespaceUri === WORDPROCESSINGML_NAMESPACE5 && attribute.localName === "fldCharType" && attribute.value === kind));
|
|
293208
|
+
if (!hasMarker(first, "begin") || !hasMarker(last, "end"))
|
|
293209
|
+
return null;
|
|
293210
|
+
}
|
|
293211
|
+
next = spliceBytes3(next, end, end, encodeXml(insertion.endXml));
|
|
293212
|
+
next = spliceBytes3(next, start, start, encodeXml(insertion.startXml));
|
|
293213
|
+
previousStart = source.byteStart;
|
|
293214
|
+
}
|
|
293215
|
+
let xml = TD83.decode(next);
|
|
293216
|
+
if (generic[0]) {
|
|
293217
|
+
const withStart = injectParagraphPrefix(xml, generic[0].startXml);
|
|
293218
|
+
const withEnd = withStart && injectParagraphSuffix(withStart, generic[0].endXml);
|
|
293219
|
+
if (!withEnd)
|
|
293220
|
+
return null;
|
|
293221
|
+
xml = withEnd;
|
|
293222
|
+
}
|
|
293223
|
+
if (collectXmlElementRanges(xml, { fragment: true, additionalNamespaces: paragraph2.namespaceBindings }).errors.length)
|
|
293224
|
+
return null;
|
|
293225
|
+
result.push({ paragraph: paragraph2, xml });
|
|
293226
|
+
}
|
|
293227
|
+
return result;
|
|
293228
|
+
}
|
|
292876
293229
|
function insertBookmarksIntoParagraphs(context, insertions, txIdPrefix) {
|
|
292877
293230
|
if (insertions.length === 0) {
|
|
292878
293231
|
return {
|
|
@@ -292881,59 +293234,46 @@ function insertBookmarksIntoParagraphs(context, insertions, txIdPrefix) {
|
|
|
292881
293234
|
message: "At least one bookmark insertion is required."
|
|
292882
293235
|
};
|
|
292883
293236
|
}
|
|
292884
|
-
const
|
|
292885
|
-
|
|
292886
|
-
|
|
293237
|
+
const paragraphs = readBodyParagraphs(context);
|
|
293238
|
+
const paragraphGroups = new Map;
|
|
293239
|
+
for (const paragraph2 of paragraphs) {
|
|
293240
|
+
const group = paragraphGroups.get(paragraph2.blockId) ?? [];
|
|
293241
|
+
group.push(paragraph2);
|
|
293242
|
+
paragraphGroups.set(paragraph2.blockId, group);
|
|
292887
293243
|
}
|
|
292888
293244
|
const existingNames = new Set(readBookmarkEntries(context).map((entry) => entry.name));
|
|
292889
|
-
const requestedBlockIds = new Set;
|
|
292890
293245
|
const requestedNames = new Set;
|
|
292891
|
-
const replacementsByPart = new Map;
|
|
292892
|
-
const storyIds = new Set;
|
|
292893
293246
|
const bookmarkIds = [];
|
|
292894
293247
|
let nextBookmarkId = nextBookmarkNumericId(context);
|
|
293248
|
+
const markers = [];
|
|
292895
293249
|
for (const insertion of insertions) {
|
|
292896
|
-
if (requestedBlockIds.has(insertion.blockId)) {
|
|
292897
|
-
return {
|
|
292898
|
-
ok: false,
|
|
292899
|
-
code: "INVALID_TARGET",
|
|
292900
|
-
message: `Paragraph "${insertion.blockId}" was requested more than once.`
|
|
292901
|
-
};
|
|
292902
|
-
}
|
|
292903
293250
|
if (existingNames.has(insertion.name) || requestedNames.has(insertion.name)) {
|
|
292904
|
-
return {
|
|
292905
|
-
ok: false,
|
|
292906
|
-
code: "INVALID_TARGET",
|
|
292907
|
-
message: `Bookmark name "${insertion.name}" already exists.`
|
|
292908
|
-
};
|
|
293251
|
+
return { ok: false, code: "INVALID_TARGET", message: `Bookmark name "${insertion.name}" already exists.` };
|
|
292909
293252
|
}
|
|
292910
|
-
const
|
|
292911
|
-
if (
|
|
293253
|
+
const targets = paragraphGroups.get(insertion.blockId);
|
|
293254
|
+
if (targets?.length !== 1)
|
|
292912
293255
|
return {
|
|
292913
293256
|
ok: false,
|
|
292914
293257
|
code: "TARGET_NOT_FOUND",
|
|
292915
293258
|
message: `Paragraph "${insertion.blockId}" was not found or is ambiguous.`
|
|
292916
293259
|
};
|
|
292917
|
-
}
|
|
292918
293260
|
const bookmarkId = String(nextBookmarkId++);
|
|
292919
|
-
|
|
292920
|
-
|
|
292921
|
-
|
|
292922
|
-
|
|
292923
|
-
|
|
292924
|
-
|
|
292925
|
-
|
|
292926
|
-
|
|
292927
|
-
|
|
292928
|
-
|
|
292929
|
-
|
|
293261
|
+
markers.push({ ...insertion, ...buildParagraphBookmarkMarkers(targets[0], insertion, bookmarkId) });
|
|
293262
|
+
bookmarkIds.push(bookmarkId);
|
|
293263
|
+
requestedNames.add(insertion.name);
|
|
293264
|
+
}
|
|
293265
|
+
const prepared = prepareBookmarkParagraphGroups(paragraphs, markers);
|
|
293266
|
+
if (!prepared)
|
|
293267
|
+
return { ok: false, code: "INVALID_TARGET", message: "Bookmark targets have unavailable or unsupported paragraph or field boundaries." };
|
|
293268
|
+
const replacementsByPart = new Map;
|
|
293269
|
+
const storyIds = new Set;
|
|
293270
|
+
const requestedBlockIds = new Set;
|
|
293271
|
+
for (const { paragraph: paragraph2, xml } of prepared) {
|
|
292930
293272
|
const replacements = replacementsByPart.get(paragraph2.partUri) ?? [];
|
|
292931
|
-
replacements.push({ paragraph: paragraph2, bytes: encodeXml(
|
|
293273
|
+
replacements.push({ paragraph: paragraph2, bytes: encodeXml(xml) });
|
|
292932
293274
|
replacementsByPart.set(paragraph2.partUri, replacements);
|
|
292933
293275
|
storyIds.add(paragraph2.storyId);
|
|
292934
|
-
|
|
292935
|
-
requestedBlockIds.add(insertion.blockId);
|
|
292936
|
-
requestedNames.add(insertion.name);
|
|
293276
|
+
requestedBlockIds.add(paragraph2.blockId);
|
|
292937
293277
|
}
|
|
292938
293278
|
const perPart = {};
|
|
292939
293279
|
for (const [partUri, replacements] of replacementsByPart) {
|
|
@@ -293390,6 +293730,34 @@ function parseQuotedSwitch(instruction, flag) {
|
|
|
293390
293730
|
const re = new RegExp(`\\\\${escapeRegExp15(flag)}\\s+"([^"]*)"`);
|
|
293391
293731
|
return re.exec(instruction)?.[1];
|
|
293392
293732
|
}
|
|
293733
|
+
function parseTocFieldIdentifier(instruction) {
|
|
293734
|
+
return parseTocTcSourceSelection(instruction).identifier;
|
|
293735
|
+
}
|
|
293736
|
+
function parseTocTcSourceSelection(instruction) {
|
|
293737
|
+
const tokens = instruction.match(/"[^"]*"|[^\s"]+/g) ?? [];
|
|
293738
|
+
const fieldIndex = tokens.findIndex((token) => token.toLowerCase() === "\\f");
|
|
293739
|
+
const levelIndex = tokens.findIndex((token) => token.toLowerCase() === "\\l");
|
|
293740
|
+
const argument = (index) => {
|
|
293741
|
+
const value2 = index < 0 ? undefined : tokens[index + 1];
|
|
293742
|
+
if (value2 == null || value2.startsWith("\\"))
|
|
293743
|
+
return;
|
|
293744
|
+
return value2.startsWith('"') ? value2.slice(1, -1) : value2;
|
|
293745
|
+
};
|
|
293746
|
+
const identifier = argument(fieldIndex);
|
|
293747
|
+
const levelArgument = argument(levelIndex);
|
|
293748
|
+
const range = /^(\d+)-(\d+)$/.exec(levelArgument ?? "");
|
|
293749
|
+
return {
|
|
293750
|
+
enabled: fieldIndex >= 0 || levelIndex >= 0,
|
|
293751
|
+
hasFieldSwitch: fieldIndex >= 0,
|
|
293752
|
+
hasLevelSwitch: levelIndex >= 0,
|
|
293753
|
+
...identifier != null ? { identifier } : {},
|
|
293754
|
+
...levelArgument != null ? { levelArgument } : {},
|
|
293755
|
+
...range ? { levels: { from: Number(range[1]), to: Number(range[2]) } } : {}
|
|
293756
|
+
};
|
|
293757
|
+
}
|
|
293758
|
+
function matchesTocTcSourceSelection(selection, entry) {
|
|
293759
|
+
return selection.enabled && entry.text.length > 0 && (selection.identifier == null || (entry.tableIdentifier ?? "C") === selection.identifier) && (selection.levels == null || entry.level >= selection.levels.from && entry.level <= selection.levels.to);
|
|
293760
|
+
}
|
|
293393
293761
|
function parseNumericSwitchRange(instruction, flag) {
|
|
293394
293762
|
const re = new RegExp(`\\\\${escapeRegExp15(flag)}\\s+"?(\\d+)-(\\d+)"?`);
|
|
293395
293763
|
const match = re.exec(instruction);
|
|
@@ -293771,16 +294139,26 @@ function buildTocResultRunsXml(instruction, entries) {
|
|
|
293771
294139
|
return chunks.join("");
|
|
293772
294140
|
}).join("");
|
|
293773
294141
|
}
|
|
293774
|
-
function buildTocResultXmlPreservingParagraphs(context, instruction,
|
|
293775
|
-
if (entries.length === 0)
|
|
293776
|
-
return buildTextRunXml("");
|
|
294142
|
+
function buildTocResultXmlPreservingParagraphs(context, instruction, sourceEntries, currentField, emptyText = "") {
|
|
293777
294143
|
const sourceParagraphs = readCurrentTocParagraphXmls(context, currentField, true);
|
|
293778
|
-
const
|
|
294144
|
+
const sectionPlacement = readTocContinuationSectionPlacement(sourceParagraphs, sourceEntries.length);
|
|
294145
|
+
const sectionOwners = sectionPlacement.byEntryIndex;
|
|
294146
|
+
if (sourceEntries.length === 0) {
|
|
294147
|
+
const carriers = sectionPlacement.carriers.map(buildTocSectionCarrierXml);
|
|
294148
|
+
return { xml: buildTextRunXml(emptyText) + (carriers.length ? `</w:p>${carriers.join("").slice(0, -6)}` : "") };
|
|
294149
|
+
}
|
|
294150
|
+
const paragraphTemplates = buildTocParagraphTemplatesFromParagraphXml([
|
|
294151
|
+
removeTocOwnerPropertiesFromTemplate(sourceParagraphs[0] ?? ""),
|
|
294152
|
+
...sourceParagraphs.slice(1)
|
|
294153
|
+
].join(""));
|
|
293779
294154
|
const entryRunPropertiesTemplates = readTocEntryRunPropertiesTemplates(context, currentField);
|
|
293780
|
-
const entryRunProperties = resolveTocEntryRunProperties(
|
|
294155
|
+
const entryRunProperties = resolveTocEntryRunProperties(sourceEntries, entryRunPropertiesTemplates);
|
|
294156
|
+
const entryParagraphOpens = resolveTocEntryParagraphOpens(sourceEntries, entryRunProperties, entryRunPropertiesTemplates, sourceParagraphs[0]);
|
|
294157
|
+
const entries = sourceEntries.map((entry, index) => applyCachedTcEntrySeparator(entry, entryRunProperties[index]));
|
|
294158
|
+
const withPageTab = createTocPageTabFallback(context, instruction, currentField.descriptor.byteStart);
|
|
293781
294159
|
const documentParaIds = collectDocumentParaIds(context);
|
|
293782
294160
|
const reusableParaIds = collectParaIdsInXml(sourceParagraphs.slice(1).join(""));
|
|
293783
|
-
for (const id of collectParaIdsInXml(sourceParagraphs[0] ?? ""))
|
|
294161
|
+
for (const id of collectParaIdsInXml((sourceParagraphs[0] ?? "") + [...sectionOwners.values(), ...sectionPlacement.carriers].join("")))
|
|
293784
294162
|
reusableParaIds.delete(id);
|
|
293785
294163
|
const usedParaIds = new Set(documentParaIds);
|
|
293786
294164
|
const nextParaId = createUniqueParaIdAllocator(documentParaIds);
|
|
@@ -293797,31 +294175,47 @@ function buildTocResultXmlPreservingParagraphs(context, instruction, entries, cu
|
|
|
293797
294175
|
}
|
|
293798
294176
|
let xml = buildTocEntryRunsXml(instruction, entries[0], entryRunProperties[0]);
|
|
293799
294177
|
for (const [index, entry] of entries.slice(1).entries()) {
|
|
293800
|
-
const retained = remainingTemplates.get(`${normalizeTocLevel(entry.level)}:${normalizeTocEntryText(entry.text)}`)?.pop();
|
|
294178
|
+
const retained = entryParagraphOpens[index + 1] ?? remainingTemplates.get(`${normalizeTocLevel(entry.level)}:${normalizeTocEntryText(entry.cachedParagraphText ?? entry.text)}`)?.pop();
|
|
293801
294179
|
if (retained) {
|
|
293802
294180
|
for (const id of collectParaIdsInXml(retained)) {
|
|
293803
294181
|
if (reusableParaIds.delete(id))
|
|
293804
294182
|
usedParaIds.delete(id);
|
|
293805
294183
|
}
|
|
293806
294184
|
}
|
|
293807
|
-
xml += `</w:p>${dedupeParagraphOpenParaId(retained ?? buildTocContinuationParagraphOpen(entry, paragraphTemplates), usedParaIds, nextParaId)}` + buildTocEntryRunsXml(instruction, entry, entryRunProperties[index + 1]);
|
|
294185
|
+
xml += `</w:p>${dedupeParagraphOpenParaId(preserveTocContinuationSectionOpen(withPageTab(retained ?? buildTocContinuationParagraphOpen(entry, paragraphTemplates), entry), index + 1, sectionOwners, usedParaIds), usedParaIds, nextParaId)}` + buildTocEntryRunsXml(instruction, entry, entryRunProperties[index + 1]);
|
|
293808
294186
|
}
|
|
293809
|
-
|
|
294187
|
+
for (const owner of sectionPlacement.carriers) {
|
|
294188
|
+
xml += `</w:p>${buildTocSectionCarrierXml(owner).slice(0, -6)}`;
|
|
294189
|
+
}
|
|
294190
|
+
const firstParagraphOpen = removeTocSectionBoundaryFromTemplate(withPageTab(entryParagraphOpens[0] ?? buildTocContinuationParagraphOpen(entries[0], paragraphTemplates), entries[0]));
|
|
294191
|
+
const firstParagraphOpenEnd = findXmlTagEnd4(firstParagraphOpen, 1);
|
|
294192
|
+
return {
|
|
294193
|
+
xml,
|
|
294194
|
+
firstParagraphProperties: inheritRunNamespaceDeclarations(firstParagraphOpen.slice(firstParagraphOpenEnd), firstParagraphOpen, firstParagraphOpenEnd, firstParagraphOpen.slice(0, firstParagraphOpenEnd))
|
|
294195
|
+
};
|
|
293810
294196
|
}
|
|
293811
|
-
function buildNewTocFieldContentXml(context, instruction, seedParagraph, currentField, preservedTocPages, reservedParaIds, tocBookmarkNames) {
|
|
294197
|
+
function buildNewTocFieldContentXml(context, instruction, seedParagraph, currentField, preservedTocPages, reservedParaIds, tocBookmarkNames, insertionByteStart) {
|
|
293812
294198
|
const useEmptyPlaceholder = shouldUseV1EmptyTocSourceSet(instruction);
|
|
293813
294199
|
const paragraphs = readBodyParagraphs(context, { includeListState: false });
|
|
293814
|
-
const
|
|
293815
|
-
const paragraphTemplates = readDocumentTocParagraphTemplates(paragraphs);
|
|
294200
|
+
const sourceEntries = useEmptyPlaceholder ? [] : buildTocEntries(context, instruction, currentField, preservedTocPages, tocBookmarkNames, paragraphs);
|
|
294201
|
+
const paragraphTemplates = readDocumentTocParagraphTemplates(paragraphs, currentField?.blockId);
|
|
293816
294202
|
const entryRunPropertiesTemplates = readTocEntryRunPropertiesTemplates(context, currentField);
|
|
293817
|
-
const entryRunProperties = resolveTocEntryRunProperties(
|
|
294203
|
+
const entryRunProperties = resolveTocEntryRunProperties(sourceEntries, entryRunPropertiesTemplates);
|
|
294204
|
+
const entryParagraphOpens = resolveTocEntryParagraphOpens(sourceEntries, entryRunProperties, entryRunPropertiesTemplates, seedParagraph?.rawXml);
|
|
294205
|
+
const entries = sourceEntries.map((entry, index) => applyCachedTcEntrySeparator(entry, entryRunProperties[index]));
|
|
294206
|
+
const withPageTab = createTocPageTabFallback(context, instruction, currentField?.descriptor.byteStart ?? insertionByteStart ?? seedParagraph?.byteStart ?? 0);
|
|
294207
|
+
const sectionPlacement = readTocContinuationSectionPlacement(currentField ? readCurrentTocParagraphXmls(context, currentField, true) : [], entries.length);
|
|
294208
|
+
const sectionOwners = sectionPlacement.byEntryIndex;
|
|
294209
|
+
const carriers = sectionPlacement.carriers.map(buildTocSectionCarrierXml);
|
|
293818
294210
|
if (entries.length === 0) {
|
|
293819
|
-
return buildGeneratedTocParagraphOpen(1, seedParagraph, paragraphTemplates) + '<w:r><w:fldChar w:fldCharType="begin" /></w:r>' + buildInstructionRunXml(instruction) + '<w:r><w:fldChar w:fldCharType="separate" /></w:r>' + buildTextRunXml(useEmptyPlaceholder ? "No table of contents entries found." : "") + '<w:r><w:fldChar w:fldCharType="end" /></w:r>' + "</w:p>";
|
|
294211
|
+
return buildGeneratedTocParagraphOpen(1, seedParagraph, paragraphTemplates, undefined, currentField != null) + '<w:r><w:fldChar w:fldCharType="begin" /></w:r>' + buildInstructionRunXml(instruction) + '<w:r><w:fldChar w:fldCharType="separate" /></w:r>' + buildTextRunXml(useEmptyPlaceholder ? "No table of contents entries found." : "") + (carriers.length ? `</w:p>${carriers.join("").slice(0, -6)}` : "") + '<w:r><w:fldChar w:fldCharType="end" /></w:r>' + "</w:p>";
|
|
293820
294212
|
}
|
|
293821
294213
|
const documentParaIds = collectDocumentParaIds(context);
|
|
293822
294214
|
const usedParaIds = new Set(reservedParaIds ?? []);
|
|
294215
|
+
for (const id of collectParaIdsInXml([...sectionOwners.values(), ...sectionPlacement.carriers].join("")))
|
|
294216
|
+
usedParaIds.add(id);
|
|
293823
294217
|
const nextParaId = createUniqueParaIdAllocator(documentParaIds);
|
|
293824
|
-
return entries.map((entry, index) => `${dedupeParagraphOpenParaId(index === 0 ? buildGeneratedTocParagraphOpen(entry.level, seedParagraph, paragraphTemplates, entry.text) : buildTocContinuationParagraphOpen(entry, paragraphTemplates), usedParaIds, nextParaId)}` + (index === 0 ? '<w:r><w:fldChar w:fldCharType="begin" /></w:r>' + buildInstructionRunXml(instruction) + '<w:r><w:fldChar w:fldCharType="separate" /></w:r>' : "") + buildTocEntryRunsXml(instruction, entry, entryRunProperties[index]) + (index === entries.length - 1 ? '<w:r><w:fldChar w:fldCharType="end" /></w:r>' : "") + "</w:p>").join("");
|
|
294218
|
+
return entries.map((entry, index) => `${dedupeParagraphOpenParaId(withPageTab(index === 0 ? buildGeneratedTocParagraphOpen(entry.level, seedParagraph, paragraphTemplates, entry.cachedParagraphText ?? entry.text, currentField != null, entryParagraphOpens[index]) : currentField ? preserveTocContinuationSectionOpen(entryParagraphOpens[index] ?? buildTocContinuationParagraphOpen(entry, paragraphTemplates), index, sectionOwners, usedParaIds) : entryParagraphOpens[index] ?? buildTocContinuationParagraphOpen(entry, paragraphTemplates), entry), usedParaIds, nextParaId)}` + (index === 0 ? '<w:r><w:fldChar w:fldCharType="begin" /></w:r>' + buildInstructionRunXml(instruction) + '<w:r><w:fldChar w:fldCharType="separate" /></w:r>' : "") + buildTocEntryRunsXml(instruction, entry, entryRunProperties[index]) + (index === entries.length - 1 ? (carriers.length ? `</w:p>${carriers.join("").slice(0, -6)}` : "") + '<w:r><w:fldChar w:fldCharType="end" /></w:r>' : "") + "</w:p>").join("");
|
|
293825
294219
|
}
|
|
293826
294220
|
function collectDocumentParaIds(context) {
|
|
293827
294221
|
const existing = new Set;
|
|
@@ -293889,7 +294283,8 @@ function buildTocEntryRunsXml(instruction, entry, entryRunProperties) {
|
|
|
293889
294283
|
function buildTocEntries(context, instruction, currentField, preservedTocPages, tocBookmarkNames, paragraphs = readBodyParagraphs(context, { includeListState: false })) {
|
|
293890
294284
|
const pages = estimateDocumentPages(context);
|
|
293891
294285
|
const numberingMarkers = buildBodyParagraphNumberReferenceMap(context, paragraphs);
|
|
293892
|
-
const
|
|
294286
|
+
const bodyBookmarks = readBookmarkEntries(context);
|
|
294287
|
+
const tocBookmarks = buildBodyTocBookmarkMap(bodyBookmarks);
|
|
293893
294288
|
if (tocBookmarkNames)
|
|
293894
294289
|
for (const [key2, name] of tocBookmarkNames)
|
|
293895
294290
|
tocBookmarks.set(key2, name);
|
|
@@ -293911,6 +294306,7 @@ function buildTocEntries(context, instruction, currentField, preservedTocPages,
|
|
|
293911
294306
|
const bookmarkKey = bookmarkName ? normalizeTocBookmarkKey(bookmarkName) : undefined;
|
|
293912
294307
|
const preservedPage = (bookmarkKey ? preservedPagesByBookmark.get(bookmarkKey) : undefined) ?? readPreservedTocPageByText(preservedPages, text);
|
|
293913
294308
|
return {
|
|
294309
|
+
sourceByteStart: paragraph2.byteStart,
|
|
293914
294310
|
text,
|
|
293915
294311
|
page: preservedPage ?? String(pages.displayPageByBlockId.get(paragraph2.blockId) ?? 1),
|
|
293916
294312
|
level: derivedLevel,
|
|
@@ -293922,17 +294318,30 @@ function buildTocEntries(context, instruction, currentField, preservedTocPages,
|
|
|
293922
294318
|
...bookmarkName ? { bookmarkName } : {}
|
|
293923
294319
|
};
|
|
293924
294320
|
}).filter((entry) => entry != null).filter((entry) => entry.text.length > 0);
|
|
293925
|
-
const
|
|
293926
|
-
const
|
|
293927
|
-
const
|
|
293928
|
-
|
|
294321
|
+
const tcSelection = parseTocTcSourceSelection(instruction);
|
|
294322
|
+
const bodyParagraphs = new Map(paragraphs.map((paragraph2) => [`${paragraph2.storyId}:${paragraph2.blockId}`, paragraph2]));
|
|
294323
|
+
const tcFields = listCanonicalFieldEntries(context).filter((entry) => instructionKeyword(entry.descriptor.instructionText) === "TC").filter((entry) => bodyParagraphs.has(`${entry.storyId}:${entry.blockId}`));
|
|
294324
|
+
const tcBookmarkNames = resolveTocTcBookmarkNames(bodyBookmarks, paragraphs, tcFields);
|
|
294325
|
+
const tcEntries = tcFields.map((entry) => ({ entry, parsed: parseTocEntryInstruction(entry.descriptor.instructionText) })).filter(({ parsed }) => matchesTocTcSourceSelection(tcSelection, parsed)).map(({ entry, parsed }) => {
|
|
294326
|
+
const text = parsed.text;
|
|
294327
|
+
const separatorIndex = text.indexOf("\t");
|
|
294328
|
+
const marker = separatorIndex > 0 ? text.slice(0, separatorIndex) : undefined;
|
|
294329
|
+
const title = separatorIndex > 0 ? text.slice(separatorIndex + 1) : undefined;
|
|
294330
|
+
const fieldKey = tocTcFieldSourceKey(entry);
|
|
294331
|
+
const bookmarkName = tocBookmarkNames?.get(fieldKey) ?? tcBookmarkNames.get(fieldKey);
|
|
294332
|
+
const bookmarkKey = bookmarkName ? normalizeTocBookmarkKey(bookmarkName) : undefined;
|
|
294333
|
+
const preservedPage = (bookmarkKey ? preservedPagesByBookmark.get(bookmarkKey) : undefined) ?? readPreservedTocPageByText(preservedPages, text);
|
|
293929
294334
|
return {
|
|
293930
|
-
|
|
294335
|
+
sourceByteStart: entry.descriptor.byteStart,
|
|
294336
|
+
text,
|
|
293931
294337
|
page: preservedPage ?? String(pages.displayPageByBlockId.get(entry.blockId) ?? 1),
|
|
293932
|
-
level: parsed.level
|
|
294338
|
+
level: parsed.level,
|
|
294339
|
+
isTcEntry: true,
|
|
294340
|
+
...marker && title ? { marker, title, markerSeparator: "tab" } : {},
|
|
294341
|
+
...bookmarkName ? { bookmarkName } : {}
|
|
293933
294342
|
};
|
|
293934
|
-
})
|
|
293935
|
-
return [...headings, ...tcEntries];
|
|
294343
|
+
});
|
|
294344
|
+
return [...headings, ...tcEntries].sort((left, right) => left.sourceByteStart - right.sourceByteStart).map(({ sourceByteStart: _sourceByteStart, ...entry }) => entry);
|
|
293936
294345
|
}
|
|
293937
294346
|
function parseTocCustomStyles(instruction) {
|
|
293938
294347
|
const raw = parseQuotedSwitch(instruction, "t");
|
|
@@ -293952,18 +294361,19 @@ function parseTocCustomStyles(instruction) {
|
|
|
293952
294361
|
function normalizeStyleId(value2) {
|
|
293953
294362
|
return value2.replace(/\s+/g, "").trim().toLowerCase();
|
|
293954
294363
|
}
|
|
293955
|
-
function readDocumentTocParagraphTemplates(paragraphs) {
|
|
294364
|
+
function readDocumentTocParagraphTemplates(paragraphs, ownerBlockId) {
|
|
293956
294365
|
const templates = emptyTocParagraphTemplates();
|
|
293957
294366
|
for (const paragraph2 of paragraphs) {
|
|
293958
294367
|
const level = readTocParagraphLevel(paragraph2.rawXml);
|
|
293959
294368
|
if (level == null)
|
|
293960
294369
|
continue;
|
|
293961
|
-
const open2 = buildTocParagraphTemplateOpen(paragraph2.rawXml);
|
|
294370
|
+
const open2 = buildTocParagraphTemplateOpen(paragraph2.blockId === ownerBlockId ? removeTocOwnerPropertiesFromTemplate(paragraph2.rawXml) : paragraph2.rawXml);
|
|
293962
294371
|
if (!templates.byLevel.has(level))
|
|
293963
294372
|
templates.byLevel.set(level, open2);
|
|
293964
294373
|
const entryText = readTocParagraphTemplateText(paragraph2.rawXml);
|
|
293965
|
-
|
|
293966
|
-
|
|
294374
|
+
const key2 = `${level}:${entryText}`;
|
|
294375
|
+
if (entryText && !templates.byLevelAndText.has(key2))
|
|
294376
|
+
templates.byLevelAndText.set(key2, open2);
|
|
293967
294377
|
}
|
|
293968
294378
|
return templates;
|
|
293969
294379
|
}
|
|
@@ -293971,7 +294381,8 @@ function readTocEntryRunPropertiesTemplates(context, currentField) {
|
|
|
293971
294381
|
const templates = {
|
|
293972
294382
|
byBookmark: new Map,
|
|
293973
294383
|
byText: new Map,
|
|
293974
|
-
byLevel: new Map
|
|
294384
|
+
byLevel: new Map,
|
|
294385
|
+
paragraphByRunTemplate: new Map
|
|
293975
294386
|
};
|
|
293976
294387
|
if (!currentField)
|
|
293977
294388
|
return templates;
|
|
@@ -293986,12 +294397,18 @@ function readTocEntryRunPropertiesTemplates(context, currentField) {
|
|
|
293986
294397
|
const { runProperties } = visibleEntry;
|
|
293987
294398
|
if (runProperties.length === 0)
|
|
293988
294399
|
continue;
|
|
294400
|
+
templates.paragraphByRunTemplate.set(runProperties, {
|
|
294401
|
+
level,
|
|
294402
|
+
open: buildTocParagraphTemplateOpen(paragraphXml)
|
|
294403
|
+
});
|
|
293989
294404
|
const hyperlinkXml = findFirstElement(paragraphXml, "hyperlink")?.xml ?? "";
|
|
293990
294405
|
const hyperlinkBookmark = readXmlAttributeByLocalName(hyperlinkXml, "anchor");
|
|
293991
294406
|
const bookmark = hyperlinkBookmark ? decodeXmlEntities2(hyperlinkBookmark) : readTocPageReferenceBookmarkName(paragraphXml);
|
|
293992
294407
|
const bookmarkKey = bookmark ? normalizeTocBookmarkKey(bookmark) : "";
|
|
293993
|
-
if (bookmarkKey
|
|
293994
|
-
templates.byBookmark.
|
|
294408
|
+
if (bookmarkKey) {
|
|
294409
|
+
const byBookmark = templates.byBookmark.get(bookmarkKey) ?? [];
|
|
294410
|
+
byBookmark.push(runProperties);
|
|
294411
|
+
templates.byBookmark.set(bookmarkKey, byBookmark);
|
|
293995
294412
|
}
|
|
293996
294413
|
const entryText = readTocParagraphTemplateText(visibleEntry);
|
|
293997
294414
|
if (entryText) {
|
|
@@ -294255,24 +294672,54 @@ function hasEnabledWebHidden(xml) {
|
|
|
294255
294672
|
}
|
|
294256
294673
|
function resolveTocEntryRunProperties(entries, templates) {
|
|
294257
294674
|
const usedTemplates = new Set;
|
|
294675
|
+
const bookmarkEntryCounts = new Map;
|
|
294676
|
+
for (const entry of entries) {
|
|
294677
|
+
if (!entry.bookmarkName)
|
|
294678
|
+
continue;
|
|
294679
|
+
const key2 = normalizeTocBookmarkKey(entry.bookmarkName);
|
|
294680
|
+
bookmarkEntryCounts.set(key2, (bookmarkEntryCounts.get(key2) ?? 0) + 1);
|
|
294681
|
+
}
|
|
294258
294682
|
const byTextQueues = new Map([...templates.byText].map(([text, matches]) => [text, [...matches]]));
|
|
294259
|
-
const takeByText = (text) => {
|
|
294683
|
+
const takeByText = (text, accept) => {
|
|
294260
294684
|
const queue = byTextQueues.get(text);
|
|
294261
|
-
|
|
294262
|
-
|
|
294263
|
-
if (candidate2 && !usedTemplates.has(candidate2))
|
|
294264
|
-
return candidate2;
|
|
294265
|
-
}
|
|
294266
|
-
return;
|
|
294685
|
+
const index = queue?.findIndex((candidate2) => !usedTemplates.has(candidate2) && (!accept || accept(candidate2))) ?? -1;
|
|
294686
|
+
return index >= 0 ? queue?.splice(index, 1)[0] : undefined;
|
|
294267
294687
|
};
|
|
294268
294688
|
const resolved = entries.map((entry) => {
|
|
294269
294689
|
const bookmarkKey = entry.bookmarkName ? normalizeTocBookmarkKey(entry.bookmarkName) : "";
|
|
294270
|
-
const
|
|
294271
|
-
const
|
|
294272
|
-
|
|
294273
|
-
|
|
294274
|
-
|
|
294275
|
-
|
|
294690
|
+
const bookmarkTemplates = bookmarkKey ? templates.byBookmark.get(bookmarkKey) : undefined;
|
|
294691
|
+
const byBookmark = bookmarkEntryCounts.get(bookmarkKey) === 1 && bookmarkTemplates?.length === 1 ? bookmarkTemplates[0] : undefined;
|
|
294692
|
+
if (byBookmark)
|
|
294693
|
+
usedTemplates.add(byBookmark);
|
|
294694
|
+
return byBookmark;
|
|
294695
|
+
});
|
|
294696
|
+
entries.forEach((entry, index) => {
|
|
294697
|
+
if (resolved[index] || !entry.isTcEntry)
|
|
294698
|
+
return;
|
|
294699
|
+
const levelTemplates = templates.byLevel.get(normalizeTocLevel(entry.level));
|
|
294700
|
+
const byText = takeByText(normalizeTocEntryText(entry.text), (template) => levelTemplates?.includes(template) === true && !template.some((run) => run.separator === "tab"));
|
|
294701
|
+
if (!byText)
|
|
294702
|
+
return;
|
|
294703
|
+
resolved[index] = byText;
|
|
294704
|
+
usedTemplates.add(byText);
|
|
294705
|
+
});
|
|
294706
|
+
entries.forEach((entry, index) => {
|
|
294707
|
+
if (resolved[index] || !entry.isTcEntry)
|
|
294708
|
+
return;
|
|
294709
|
+
const cachedSeparatorTemplate = templates.byLevel.get(normalizeTocLevel(entry.level))?.find((template) => !usedTemplates.has(template) && applyCachedTcEntrySeparator(entry, template) !== entry);
|
|
294710
|
+
if (!cachedSeparatorTemplate)
|
|
294711
|
+
return;
|
|
294712
|
+
resolved[index] = cachedSeparatorTemplate;
|
|
294713
|
+
usedTemplates.add(cachedSeparatorTemplate);
|
|
294714
|
+
});
|
|
294715
|
+
entries.forEach((entry, index) => {
|
|
294716
|
+
if (resolved[index])
|
|
294717
|
+
return;
|
|
294718
|
+
const byText = takeByText(normalizeTocEntryText(entry.text));
|
|
294719
|
+
if (!byText)
|
|
294720
|
+
return;
|
|
294721
|
+
resolved[index] = byText;
|
|
294722
|
+
usedTemplates.add(byText);
|
|
294276
294723
|
});
|
|
294277
294724
|
for (const level of new Set(entries.map((entry) => normalizeTocLevel(entry.level)))) {
|
|
294278
294725
|
const entryIndexes = entries.map((entry, index) => normalizeTocLevel(entry.level) === level ? index : -1).filter((index) => index >= 0);
|
|
@@ -294308,6 +294755,49 @@ function resolveTocEntryRunProperties(entries, templates) {
|
|
|
294308
294755
|
}
|
|
294309
294756
|
return resolved;
|
|
294310
294757
|
}
|
|
294758
|
+
function resolveTocEntryParagraphOpens(entries, runTemplates, templates, ownerParagraphXml) {
|
|
294759
|
+
const ownerOpen = ownerParagraphXml ? buildTocParagraphTemplateOpen(ownerParagraphXml) : undefined;
|
|
294760
|
+
return entries.map((entry, index) => {
|
|
294761
|
+
const runs = runTemplates[index];
|
|
294762
|
+
const paired = runs && templates.paragraphByRunTemplate.get(runs);
|
|
294763
|
+
if (!paired || paired.level !== normalizeTocLevel(entry.level))
|
|
294764
|
+
return;
|
|
294765
|
+
return paired.open === ownerOpen ? removeTocOwnerPropertiesFromTemplate(paired.open) : paired.open;
|
|
294766
|
+
});
|
|
294767
|
+
}
|
|
294768
|
+
function applyCachedTcEntrySeparator(entry, template) {
|
|
294769
|
+
if (!entry.isTcEntry || !template || entry.text.includes("\t"))
|
|
294770
|
+
return entry;
|
|
294771
|
+
const separatorIndex = template.findIndex((run) => run.separator === "tab");
|
|
294772
|
+
if (separatorIndex <= 0 || template.slice(separatorIndex + 1).some((run) => run.separator === "tab"))
|
|
294773
|
+
return entry;
|
|
294774
|
+
const cachedLabel = template.map((run) => run.separator === "tab" ? "\t" : run.text).join("");
|
|
294775
|
+
const compactLabel = normalizeCompactTocEntryText(cachedLabel).replace(/\.$/, "");
|
|
294776
|
+
if (compactLabel !== normalizeCompactTocEntryText(entry.text).replace(/\.$/, ""))
|
|
294777
|
+
return entry;
|
|
294778
|
+
const marker = normalizeTocEntryText(template.slice(0, separatorIndex).map((run) => run.text).join(""));
|
|
294779
|
+
const compactMarker = normalizeCompactTocEntryText(marker);
|
|
294780
|
+
if (!compactMarker || !normalizeCompactTocEntryText(entry.text).startsWith(compactMarker))
|
|
294781
|
+
return entry;
|
|
294782
|
+
let markerEnd = 0;
|
|
294783
|
+
let remainingMarkerLength = compactMarker.length;
|
|
294784
|
+
while (markerEnd < entry.text.length && remainingMarkerLength > 0) {
|
|
294785
|
+
if (!/\s/.test(entry.text[markerEnd]))
|
|
294786
|
+
remainingMarkerLength -= 1;
|
|
294787
|
+
markerEnd += 1;
|
|
294788
|
+
}
|
|
294789
|
+
const title = entry.text.slice(markerEnd).trim();
|
|
294790
|
+
if (!title)
|
|
294791
|
+
return entry;
|
|
294792
|
+
return {
|
|
294793
|
+
...entry,
|
|
294794
|
+
text: joinMarkerAndText(marker, title),
|
|
294795
|
+
marker,
|
|
294796
|
+
title,
|
|
294797
|
+
markerSeparator: "tab",
|
|
294798
|
+
cachedParagraphText: cachedLabel
|
|
294799
|
+
};
|
|
294800
|
+
}
|
|
294311
294801
|
function readUnanimousTocTextTemplate(matchingTemplates) {
|
|
294312
294802
|
const template = matchingTemplates?.[0];
|
|
294313
294803
|
if (!template)
|
|
@@ -294340,16 +294830,61 @@ function readUniformTocLevelRunProperties(siblingTemplates) {
|
|
|
294340
294830
|
return uniformRunProperties;
|
|
294341
294831
|
}
|
|
294342
294832
|
function buildTocContinuationParagraphOpen(entry, templates) {
|
|
294343
|
-
return resolveTocParagraphOpen(entry.level, templates, entry.text);
|
|
294833
|
+
return resolveTocParagraphOpen(entry.level, templates, entry.cachedParagraphText ?? entry.text);
|
|
294834
|
+
}
|
|
294835
|
+
function createTocPageTabFallback(context, instruction, fieldByteStart) {
|
|
294836
|
+
if (/\\n\b/.test(instruction) || parseQuotedSwitch(instruction, "p") != null)
|
|
294837
|
+
return (paragraphOpen) => paragraphOpen;
|
|
294838
|
+
let model;
|
|
294839
|
+
let position;
|
|
294840
|
+
return (paragraphOpen, entry) => {
|
|
294841
|
+
if (entry.markerSeparator === "tab" || entry.text.includes("\t"))
|
|
294842
|
+
return paragraphOpen;
|
|
294843
|
+
const properties = findDirectChild(paragraphOpen + "</w:p>", "pPr");
|
|
294844
|
+
if (!properties || findDirectChild(properties.xml, "tabs") || findDirectChild(properties.xml, "AlternateContent"))
|
|
294845
|
+
return paragraphOpen;
|
|
294846
|
+
model ?? (model = compileWordStyleModel({
|
|
294847
|
+
stylesXml: readStyleDefinitionsPartBytes(context),
|
|
294848
|
+
settingsXml: readPartBytes2(context, "/word/settings.xml"),
|
|
294849
|
+
numberingXml: readPartBytes2(context, "/word/numbering.xml")
|
|
294850
|
+
}));
|
|
294851
|
+
const style = findDirectChild(properties.xml, "pStyle");
|
|
294852
|
+
const styleId = style ? readXmlAttributeByLocalName(style.xml, "val") : undefined;
|
|
294853
|
+
if (model.resolveParagraph({ inlineProps: { styleId } }).tabStops?.length)
|
|
294854
|
+
return paragraphOpen;
|
|
294855
|
+
const container = parseContainerXml(properties.xml.replace(/\/>$/, `></${properties.qname}>`), "pPr");
|
|
294856
|
+
if (!container)
|
|
294857
|
+
return paragraphOpen;
|
|
294858
|
+
if (position == null) {
|
|
294859
|
+
const sections = readLiveSectionSignals(context);
|
|
294860
|
+
const section = sections.find((candidate2) => fieldByteStart < candidate2.sectPr.rawXmlByteEnd) ?? sections.at(-1);
|
|
294861
|
+
const setup = section?.pageSetup;
|
|
294862
|
+
const width = (setup?.pageSize.widthTwips ?? 12240) - (setup?.margins.leftTwips ?? 1440) - (setup?.margins.rightTwips ?? 1440) - (setup?.margins.gutterTwips ?? 0);
|
|
294863
|
+
const count = Math.max(1, section?.columns?.count ?? 1);
|
|
294864
|
+
const columnWidth = section?.columns?.columns[0]?.widthTwips ?? (width - (count - 1) * (section?.columns?.spaceTwips ?? 720)) / count;
|
|
294865
|
+
position = Math.max(0, Math.floor(columnWidth) - 10);
|
|
294866
|
+
}
|
|
294867
|
+
const prefix = container.prefix;
|
|
294868
|
+
const tabs2 = `<${prefix}:tabs><${prefix}:tab ${prefix}:val="right" ${prefix}:leader="dot" ${prefix}:pos="${position}"/></${prefix}:tabs>`;
|
|
294869
|
+
const children2 = setParagraphPropertyChild(parseTopLevelChildrenPreservingTrivia(container.inner), "tabs", tabs2);
|
|
294870
|
+
return paragraphOpen.replace(properties.xml, () => container.open + serializeTopLevelChildren(children2) + container.close);
|
|
294871
|
+
};
|
|
294344
294872
|
}
|
|
294345
|
-
function buildGeneratedTocParagraphOpen(level, seedParagraph, templates, entryText) {
|
|
294346
|
-
const template = resolveTocParagraphTemplate(level, templates, entryText);
|
|
294347
|
-
if (template)
|
|
294873
|
+
function buildGeneratedTocParagraphOpen(level, seedParagraph, templates, entryText, retainOwner = false, pairedTemplate) {
|
|
294874
|
+
const template = pairedTemplate ?? resolveTocParagraphTemplate(level, templates, entryText);
|
|
294875
|
+
if (template && !(retainOwner && seedParagraph))
|
|
294348
294876
|
return template;
|
|
294349
294877
|
const normalizedLevel = normalizeTocLevel(level);
|
|
294350
294878
|
if (!seedParagraph)
|
|
294351
294879
|
return `<w:p><w:pPr><w:pStyle w:val="TOC${normalizedLevel}"/></w:pPr>`;
|
|
294352
|
-
|
|
294880
|
+
const ownerOpenTag = readParagraphOpenTag(seedParagraph.rawXml);
|
|
294881
|
+
if (!retainOwner)
|
|
294882
|
+
return `${ownerOpenTag}<w:pPr><w:pStyle w:val="TOC${normalizedLevel}"/></w:pPr>`;
|
|
294883
|
+
const templateOpenEnd = template ? findXmlTagEnd4(template, 1) : -1;
|
|
294884
|
+
const properties = template ? inheritRunNamespaceDeclarations(template.slice(templateOpenEnd), template, templateOpenEnd, template.slice(0, templateOpenEnd)) : `<w:pPr><w:pStyle w:val="TOC${normalizedLevel}"/></w:pPr>`;
|
|
294885
|
+
const ownerPropertiesStart = skipXmlWhitespace(seedParagraph.rawXml, ownerOpenTag.length);
|
|
294886
|
+
const ownerProperties = matchLeadingElement(seedParagraph.rawXml.slice(ownerPropertiesStart), "pPr");
|
|
294887
|
+
return ownerOpenTag + preserveTocOwnerProperties(properties, ownerProperties);
|
|
294353
294888
|
}
|
|
294354
294889
|
function readParagraphOpenTag(paragraphXml) {
|
|
294355
294890
|
const match = /^<w:p\b([^>]*?)(?:\/>|>)/s.exec(paragraphXml);
|
|
@@ -294360,6 +294895,9 @@ function normalizeTocLevel(level) {
|
|
|
294360
294895
|
}
|
|
294361
294896
|
function buildTocEntryTextRuns(entry, runProperties, includeHyperlinks) {
|
|
294362
294897
|
const buildLabelRun = (text, template) => {
|
|
294898
|
+
if (entry.isTcEntry && text.includes("\t")) {
|
|
294899
|
+
return text.split("\t").map((part, index) => (index > 0 ? "<w:r><w:tab/></w:r>" : "") + (part ? buildLabelRun(part, template) : "")).join("");
|
|
294900
|
+
}
|
|
294363
294901
|
const sanitized = template ? sanitizeTocLabelRunProperties(template.runProperties, includeHyperlinks) : "";
|
|
294364
294902
|
if (!sanitized)
|
|
294365
294903
|
return buildTextRunXml(text);
|
|
@@ -294388,7 +294926,7 @@ function buildTocEntryTextRuns(entry, runProperties, includeHyperlinks) {
|
|
|
294388
294926
|
}
|
|
294389
294927
|
const cachedFirstRunText = runProperties?.[0]?.text;
|
|
294390
294928
|
const matchesCompleteMarkerBoundary = cachedFirstRunText === entry.marker || entry.markerSeparator === "space" && cachedFirstRunText?.startsWith(`${entry.marker} `);
|
|
294391
|
-
if (markerSeparatorIndex < 0 && matchesCompleteMarkerBoundary) {
|
|
294929
|
+
if (markerSeparatorIndex < 0 && entry.markerSeparator !== "tab" && matchesCompleteMarkerBoundary) {
|
|
294392
294930
|
return buildLabelRuns(entry.text, runProperties);
|
|
294393
294931
|
}
|
|
294394
294932
|
if (markerSeparatorIndex < 0 && entry.markerSeparator === "space" && runProperties?.[0]) {
|
|
@@ -294408,8 +294946,28 @@ function buildTocEntryTextRuns(entry, runProperties, includeHyperlinks) {
|
|
|
294408
294946
|
}
|
|
294409
294947
|
}
|
|
294410
294948
|
}
|
|
294411
|
-
|
|
294412
|
-
|
|
294949
|
+
let markerTemplates = markerSeparatorIndex >= 0 ? runProperties?.slice(0, markerSeparatorIndex) : runProperties?.slice(0, 1);
|
|
294950
|
+
let titleTemplates = markerSeparatorIndex >= 0 ? runProperties?.slice(markerSeparatorIndex + 1) : runProperties && runProperties.length > 1 ? runProperties.slice(1) : runProperties;
|
|
294951
|
+
if (markerSeparatorIndex < 0 && entry.markerSeparator === "tab" && runProperties) {
|
|
294952
|
+
const cachedLabel = runProperties.map((template) => template.text).join("");
|
|
294953
|
+
const markerEnd = entry.marker.length;
|
|
294954
|
+
const titleStart = markerEnd + /^\s*/.exec(cachedLabel.slice(markerEnd))[0].length;
|
|
294955
|
+
if (cachedLabel.startsWith(entry.marker) && cachedLabel.slice(titleStart) === entry.title) {
|
|
294956
|
+
markerTemplates = [];
|
|
294957
|
+
titleTemplates = [];
|
|
294958
|
+
let offset = 0;
|
|
294959
|
+
for (const template of runProperties) {
|
|
294960
|
+
const end = offset + template.text.length;
|
|
294961
|
+
if (offset < markerEnd) {
|
|
294962
|
+
markerTemplates.push({ ...template, text: template.text.slice(0, markerEnd - offset) });
|
|
294963
|
+
}
|
|
294964
|
+
if (end > titleStart) {
|
|
294965
|
+
titleTemplates.push({ ...template, text: template.text.slice(Math.max(0, titleStart - offset)) });
|
|
294966
|
+
}
|
|
294967
|
+
offset = end;
|
|
294968
|
+
}
|
|
294969
|
+
}
|
|
294970
|
+
}
|
|
294413
294971
|
const markerRuns = buildLabelRuns(entry.marker, markerTemplates);
|
|
294414
294972
|
if (entry.markerSeparator === "tab") {
|
|
294415
294973
|
return [...markerRuns, "<w:r><w:tab/></w:r>", ...buildLabelRuns(entry.title, titleTemplates)];
|
|
@@ -294426,9 +294984,42 @@ function sanitizeTocLabelRunProperties(runPropertiesXml, includeHyperlinks) {
|
|
|
294426
294984
|
return runPropertiesXml;
|
|
294427
294985
|
return runPropertiesXml.replace(/<(?:[\w.-]+:)?rStyle\b(?=[^>]*\b(?:[\w.-]+:)?val=(["'])Hyperlink\1)[^>]*(?:\/>|>\s*<\/(?:[\w.-]+:)?rStyle\s*>)/gi, "");
|
|
294428
294986
|
}
|
|
294429
|
-
function
|
|
294987
|
+
function tocTcFieldSourceKey(field) {
|
|
294988
|
+
return `tc:${field.storyId}:${field.stableFieldId}`;
|
|
294989
|
+
}
|
|
294990
|
+
function resolveTocTcBookmarkNames(bookmarks, paragraphs, fields) {
|
|
294991
|
+
if (fields.length === 0)
|
|
294992
|
+
return new Map;
|
|
294993
|
+
const sourceKeys = new Set(fields.map((field) => `${field.storyId}:${field.blockId}`));
|
|
294994
|
+
const sourceParagraphs = paragraphs.filter((paragraph2) => sourceKeys.has(`${paragraph2.storyId}:${paragraph2.blockId}`));
|
|
294995
|
+
const paragraphBookmarks = buildBodyTocBookmarkMap(bookmarks);
|
|
294996
|
+
const paragraphsByKey = new Map(sourceParagraphs.map((paragraph2) => [`${paragraph2.storyId}:${paragraph2.blockId}`, paragraph2]));
|
|
294997
|
+
const ranges = buildBodyTocBookmarkRangeMap(bookmarks, sourceParagraphs);
|
|
294998
|
+
const siblings = new Map;
|
|
294999
|
+
for (const field of fields) {
|
|
295000
|
+
const key2 = `${field.storyId}:${field.blockId}`;
|
|
295001
|
+
const group = siblings.get(key2) ?? [];
|
|
295002
|
+
group.push(field);
|
|
295003
|
+
siblings.set(key2, group);
|
|
295004
|
+
}
|
|
295005
|
+
const names = new Map;
|
|
295006
|
+
for (const field of fields) {
|
|
295007
|
+
const paragraphKey = `${field.storyId}:${field.blockId}`;
|
|
295008
|
+
const bookmarkRanges = ranges.get(paragraphKey);
|
|
295009
|
+
const paragraphBookmark = paragraphBookmarks.get(paragraphKey);
|
|
295010
|
+
const fallbackRange = bookmarkRanges?.find((bookmark) => bookmark.name === paragraphBookmark);
|
|
295011
|
+
const belongsToSibling = fallbackRange && siblings.get(paragraphKey)?.some((sibling) => sibling.stableFieldId !== field.stableFieldId && (fallbackRange.start >= sibling.descriptor.byteStart && fallbackRange.end <= sibling.descriptor.byteEnd || fallbackRange.start <= sibling.descriptor.byteStart && fallbackRange.end >= sibling.descriptor.byteEnd));
|
|
295012
|
+
const paragraph2 = paragraphsByKey.get(paragraphKey);
|
|
295013
|
+
const coversCrossParagraphStart = paragraph2 && fallbackRange && field.descriptor.byteEnd > paragraph2.byteEnd && fallbackRange.start <= field.descriptor.byteStart && fallbackRange.end > field.descriptor.byteStart;
|
|
295014
|
+
const name = bookmarkRanges?.find((bookmark) => bookmark.start >= field.descriptor.byteStart && bookmark.end <= field.descriptor.byteEnd)?.name ?? bookmarkRanges?.find((bookmark) => bookmark.start <= field.descriptor.byteStart && bookmark.end >= field.descriptor.byteEnd)?.name ?? (belongsToSibling && !coversCrossParagraphStart ? undefined : paragraphBookmark);
|
|
295015
|
+
if (name)
|
|
295016
|
+
names.set(tocTcFieldSourceKey(field), name);
|
|
295017
|
+
}
|
|
295018
|
+
return names;
|
|
295019
|
+
}
|
|
295020
|
+
function buildBodyTocBookmarkMap(entries) {
|
|
294430
295021
|
const bookmarks = new Map;
|
|
294431
|
-
for (const entry of
|
|
295022
|
+
for (const entry of entries) {
|
|
294432
295023
|
if (!entry.name.startsWith("_Toc"))
|
|
294433
295024
|
continue;
|
|
294434
295025
|
const key2 = `${entry.storyId}:${entry.blockId}`;
|
|
@@ -294437,6 +295028,43 @@ function buildBodyTocBookmarkMap(context) {
|
|
|
294437
295028
|
}
|
|
294438
295029
|
return bookmarks;
|
|
294439
295030
|
}
|
|
295031
|
+
function buildBodyTocBookmarkRangeMap(bookmarks, paragraphs) {
|
|
295032
|
+
if (paragraphs.length === 0)
|
|
295033
|
+
return new Map;
|
|
295034
|
+
const paragraphsByKey = new Map(paragraphs.map((paragraph2) => [`${paragraph2.storyId}:${paragraph2.blockId}`, paragraph2]));
|
|
295035
|
+
const scans = new Map;
|
|
295036
|
+
const ranges = new Map;
|
|
295037
|
+
for (const bookmark of bookmarks) {
|
|
295038
|
+
if (!bookmark.name.startsWith("_Toc"))
|
|
295039
|
+
continue;
|
|
295040
|
+
const key2 = `${bookmark.storyId}:${bookmark.blockId}`;
|
|
295041
|
+
const paragraph2 = paragraphsByKey.get(key2);
|
|
295042
|
+
if (!paragraph2)
|
|
295043
|
+
continue;
|
|
295044
|
+
if (!scans.has(key2))
|
|
295045
|
+
scans.set(key2, readBookmarkMarkerSpans(paragraph2.rawXml, paragraph2.namespaceBindings));
|
|
295046
|
+
const scan = scans.get(key2);
|
|
295047
|
+
if (!scan || scan.invalidBookmarkIds.has(bookmark.bookmarkId))
|
|
295048
|
+
continue;
|
|
295049
|
+
const endMarker = scan.markers.find((marker) => marker.kind === "end" && marker.bookmarkId === bookmark.bookmarkId);
|
|
295050
|
+
if (!endMarker)
|
|
295051
|
+
continue;
|
|
295052
|
+
const range = {
|
|
295053
|
+
name: bookmark.name,
|
|
295054
|
+
start: bookmark.markerByteStart,
|
|
295055
|
+
end: paragraph2.byteStart + encodeXml(paragraph2.rawXml.slice(0, endMarker.start)).length
|
|
295056
|
+
};
|
|
295057
|
+
if (range.end < range.start)
|
|
295058
|
+
continue;
|
|
295059
|
+
const paragraphRanges = ranges.get(key2) ?? [];
|
|
295060
|
+
paragraphRanges.push(range);
|
|
295061
|
+
ranges.set(key2, paragraphRanges);
|
|
295062
|
+
}
|
|
295063
|
+
for (const paragraphRanges of ranges.values()) {
|
|
295064
|
+
paragraphRanges.sort((left, right) => left.end - left.start - (right.end - right.start));
|
|
295065
|
+
}
|
|
295066
|
+
return ranges;
|
|
295067
|
+
}
|
|
294440
295068
|
function buildTocPageReferenceRunsXml(bookmarkName, page, separator) {
|
|
294441
295069
|
return buildTocPageSeparatorRunsXml(separator) + buildWebHiddenFieldCharRunXml("begin") + buildWebHiddenInstructionRunXml(` PAGEREF ${bookmarkName} \\h `) + buildWebHiddenEmptyRunXml() + buildWebHiddenFieldCharRunXml("separate") + buildWebHiddenTextRunXml(page) + buildWebHiddenFieldCharRunXml("end");
|
|
294442
295070
|
}
|
|
@@ -294466,7 +295094,7 @@ function buildWebHiddenEmptyRunXml() {
|
|
|
294466
295094
|
function emptyTocParagraphTemplates() {
|
|
294467
295095
|
return {
|
|
294468
295096
|
byLevel: new Map,
|
|
294469
|
-
|
|
295097
|
+
byLevelAndText: new Map
|
|
294470
295098
|
};
|
|
294471
295099
|
}
|
|
294472
295100
|
function buildTocParagraphTemplatesFromParagraphXml(xml) {
|
|
@@ -294480,18 +295108,20 @@ function buildTocParagraphTemplatesFromParagraphXml(xml) {
|
|
|
294480
295108
|
if (!templates.byLevel.has(level))
|
|
294481
295109
|
templates.byLevel.set(level, open2);
|
|
294482
295110
|
const entryText = readTocParagraphTemplateText(paragraphXml);
|
|
294483
|
-
|
|
294484
|
-
|
|
295111
|
+
const key2 = `${level}:${entryText}`;
|
|
295112
|
+
if (entryText && !templates.byLevelAndText.has(key2))
|
|
295113
|
+
templates.byLevelAndText.set(key2, open2);
|
|
294485
295114
|
}
|
|
294486
295115
|
return templates;
|
|
294487
295116
|
}
|
|
294488
295117
|
function buildTocParagraphTemplateOpen(paragraphXml) {
|
|
294489
295118
|
const openTag = /^<w:p\b[^>]*>/s.exec(paragraphXml)?.[0] ?? "";
|
|
294490
|
-
const pPrXml = openTag ? matchLeadingElement(paragraphXml.slice(openTag.length), "pPr") : "";
|
|
295119
|
+
const pPrXml = openTag ? matchLeadingElement(paragraphXml.slice(skipXmlWhitespace(paragraphXml, openTag.length)), "pPr") : "";
|
|
294491
295120
|
return `${readParagraphOpenTag(paragraphXml)}${pPrXml}`;
|
|
294492
295121
|
}
|
|
294493
295122
|
function readTocParagraphLevel(paragraphXml) {
|
|
294494
|
-
const
|
|
295123
|
+
const propertiesXml = matchLeadingElement(paragraphXml, "pPr") || findDirectChild(paragraphXml, "pPr")?.xml;
|
|
295124
|
+
const paragraphStyle = propertiesXml ? findDirectChild(propertiesXml, "pStyle") : undefined;
|
|
294495
295125
|
const style = paragraphStyle ? /^TOC(\d+)$/.exec(readXmlAttributeByLocalName(paragraphStyle.xml, "val") ?? "")?.[1] : undefined;
|
|
294496
295126
|
if (!style)
|
|
294497
295127
|
return null;
|
|
@@ -294514,13 +295144,14 @@ function resolveTocParagraphOpen(level, templates, entryText) {
|
|
|
294514
295144
|
return `<w:p><w:pPr><w:pStyle w:val="TOC${normalizedLevel}"/></w:pPr>`;
|
|
294515
295145
|
}
|
|
294516
295146
|
function resolveTocParagraphTemplate(level, templates, entryText) {
|
|
295147
|
+
const normalizedLevel = normalizeTocLevel(level);
|
|
294517
295148
|
const normalizedText = entryText ? normalizeTocEntryText(entryText) : "";
|
|
294518
295149
|
if (normalizedText.length > 0) {
|
|
294519
|
-
const
|
|
294520
|
-
if (
|
|
294521
|
-
return
|
|
295150
|
+
const byLevelAndText = templates.byLevelAndText.get(`${normalizedLevel}:${normalizedText}`);
|
|
295151
|
+
if (byLevelAndText)
|
|
295152
|
+
return byLevelAndText;
|
|
294522
295153
|
}
|
|
294523
|
-
return templates.byLevel.get(
|
|
295154
|
+
return templates.byLevel.get(normalizedLevel);
|
|
294524
295155
|
}
|
|
294525
295156
|
function readPreservedTocPagesByText(context, currentField, paragraphs = readBodyParagraphs(context, { includeListState: false })) {
|
|
294526
295157
|
const preserved = new Map;
|
|
@@ -295210,7 +295841,7 @@ function joinMarkerAndText(marker, text) {
|
|
|
295210
295841
|
return text.length > 0 ? `${marker} ${text}` : marker;
|
|
295211
295842
|
}
|
|
295212
295843
|
function parseTocEntryInstruction(instruction) {
|
|
295213
|
-
const tableIdentifier =
|
|
295844
|
+
const tableIdentifier = parseTocFieldIdentifier(instruction) ?? parseQuotedSwitch(instruction, "t");
|
|
295214
295845
|
return {
|
|
295215
295846
|
text: parseFirstQuotedValue(instruction) ?? "",
|
|
295216
295847
|
level: Number(parseNumericSwitchValue(instruction, "l") ?? "1"),
|
|
@@ -295319,6 +295950,10 @@ var init_runtime2 = __esm(() => {
|
|
|
295319
295950
|
init_registry3();
|
|
295320
295951
|
init_stories();
|
|
295321
295952
|
init_section_xml();
|
|
295953
|
+
init_src6();
|
|
295954
|
+
init_part();
|
|
295955
|
+
init_common();
|
|
295956
|
+
init_paragraph_property_order();
|
|
295322
295957
|
init_scalar_evaluation();
|
|
295323
295958
|
init_bookmark_insertion();
|
|
295324
295959
|
init_xml();
|
|
@@ -340500,10 +341135,18 @@ class V2ContentControlsAdapter {
|
|
|
340500
341135
|
if (controlPlacement(part.xml, control2) !== control2.info.kind) {
|
|
340501
341136
|
throw operationError("CAPABILITY_UNAVAILABLE", "Row and cell controls are not supported adjacent insertion targets.");
|
|
340502
341137
|
}
|
|
340503
|
-
|
|
341138
|
+
const allocator = createParaIdAllocator(this.context);
|
|
341139
|
+
let createdBlockId = null;
|
|
341140
|
+
const captureParaId = () => {
|
|
341141
|
+
const id = allocator();
|
|
341142
|
+
if (createdBlockId == null)
|
|
341143
|
+
createdBlockId = id;
|
|
341144
|
+
return id;
|
|
341145
|
+
};
|
|
341146
|
+
let fragment4 = buildAdjacentContent(input.content ?? "", control2.info.kind, captureParaId);
|
|
340504
341147
|
let commitOptions = {
|
|
340505
341148
|
partUri: part.partUri,
|
|
340506
|
-
storySurface: { family: "storyBlocks", contentControlRewrite: true, targetBlockIds: [] },
|
|
341149
|
+
storySurface: { family: "storyBlocks", contentControlRewrite: true, changeMode: "direct", targetBlockIds: [] },
|
|
340507
341150
|
preserveRenderCommit: true
|
|
340508
341151
|
};
|
|
340509
341152
|
if (options?.changeMode === "tracked") {
|
|
@@ -340529,7 +341172,7 @@ class V2ContentControlsAdapter {
|
|
|
340529
341172
|
return this.validateDryRun(input, options, control2.target);
|
|
340530
341173
|
const index2 = placement3 === "before" ? control2.start : control2.end;
|
|
340531
341174
|
const nextXml = `${part.xml.slice(0, index2)}${fragment4}${part.xml.slice(index2)}`;
|
|
340532
|
-
return this.commitDocument(nextXml, `content-control-insert-${placement3}`, input, options, control2.target, commitOptions);
|
|
341175
|
+
return this.commitDocument(nextXml, `content-control-insert-${placement3}`, input, options, control2.target, { ...commitOptions, ...createdBlockId != null ? { createdBlockId } : {} });
|
|
340533
341176
|
}
|
|
340534
341177
|
mutatePr(input, options, transform2) {
|
|
340535
341178
|
return this.mutateControl(input.target, input, options, (control2) => {
|
|
@@ -340920,6 +341563,7 @@ class V2ContentControlsAdapter {
|
|
|
340920
341563
|
if (!documentProtectionAllowsXmlRewrite(this.context, partUri, before, nextXml)) {
|
|
340921
341564
|
return { success: false, failure: { code: "PERMISSION_DENIED", message: DOCUMENT_PROTECTION_MESSAGE } };
|
|
340922
341565
|
}
|
|
341566
|
+
let remappedCreatedBlockId = commitOptions.createdBlockId;
|
|
340923
341567
|
if (commitOptions.storySurface?.contentControlRewrite && this.context.isCollaborativeSession()) {
|
|
340924
341568
|
const existingIds = new Set(this.load().parts.flatMap((part) => Array.from(part.xml.matchAll(/\bw14:paraId="([^"]+)"/g), (match) => match[1])));
|
|
340925
341569
|
const newIds = [...new Set(Array.from(nextXml.matchAll(/\bw14:paraId="([^"]+)"/g), (match) => match[1]))].filter((id) => !existingIds.has(id));
|
|
@@ -340929,6 +341573,9 @@ class V2ContentControlsAdapter {
|
|
|
340929
341573
|
return { success: false, failure: { code: "PRECONDITION_FAILED", message: "Could not reserve content-control paragraph identities." } };
|
|
340930
341574
|
const remap = new Map(newIds.map((id, index2) => [id, allocated[index2]]));
|
|
340931
341575
|
nextXml = nextXml.replace(/\bw14:paraId="([^"]+)"/g, (attribute, id) => remap.has(id) ? `w14:paraId="${remap.get(id)}"` : attribute);
|
|
341576
|
+
if (remappedCreatedBlockId != null) {
|
|
341577
|
+
remappedCreatedBlockId = remap.get(remappedCreatedBlockId) ?? remappedCreatedBlockId;
|
|
341578
|
+
}
|
|
340932
341579
|
}
|
|
340933
341580
|
}
|
|
340934
341581
|
const committed = commitWholePartUpdates(this.context, prefix, { [partUri]: encodeXml(nextXml) }, {
|
|
@@ -340953,7 +341600,8 @@ class V2ContentControlsAdapter {
|
|
|
340953
341600
|
contentControl: target,
|
|
340954
341601
|
...commitOptions.updatedRef ? { updatedRef: commitOptions.updatedRef } : {},
|
|
340955
341602
|
affectedStories: [...commitOptions.affectedStories ?? [target.story ?? { kind: "story", storyType: "body" }]],
|
|
340956
|
-
...trackedChangeRefs && trackedChangeRefs.length > 0 ? { trackedChangeRefs } : {}
|
|
341603
|
+
...trackedChangeRefs && trackedChangeRefs.length > 0 ? { trackedChangeRefs } : {},
|
|
341604
|
+
...remappedCreatedBlockId != null ? { createdBlockId: remappedCreatedBlockId } : {}
|
|
340957
341605
|
};
|
|
340958
341606
|
if (commitOptions.preserveRenderCommit) {
|
|
340959
341607
|
const renderCommit = getSDRenderCommitEnvelope(committed);
|
|
@@ -343099,10 +343747,12 @@ function regenerateTrackedToc(context, entry, instruction, dryRun) {
|
|
|
343099
343747
|
}));
|
|
343100
343748
|
if (missing2.some((bookmark) => !bookmark.paragraph))
|
|
343101
343749
|
return unavailable4("A TOC heading target is unavailable.");
|
|
343102
|
-
const names = new Map
|
|
343103
|
-
|
|
343104
|
-
bookmark.name
|
|
343105
|
-
|
|
343750
|
+
const names = new Map;
|
|
343751
|
+
for (const bookmark of missing2) {
|
|
343752
|
+
names.set(bookmark.fieldSource?.key ?? `${bookmark.paragraph.storyId}:${bookmark.blockId}`, bookmark.name);
|
|
343753
|
+
for (const key2 of bookmark.fieldSourceKeys ?? [])
|
|
343754
|
+
names.set(key2, bookmark.name);
|
|
343755
|
+
}
|
|
343106
343756
|
const sdt = prepareTocSdtReplacement(context, entry, instruction, names);
|
|
343107
343757
|
const rendered = !sdt.ok && sdt.message === "Unable to locate the containing TOC content control." ? prepareBareTocReplacement(context, entry, instruction, names) : sdt;
|
|
343108
343758
|
if (!rendered.ok)
|
|
@@ -343141,16 +343791,18 @@ function regenerateTrackedToc(context, entry, instruction, dryRun) {
|
|
|
343141
343791
|
];
|
|
343142
343792
|
let count = content3.wordIds.length;
|
|
343143
343793
|
let bookmarkId = nextBookmarkNumericId(context);
|
|
343794
|
+
const bookmarkMarkers = [];
|
|
343144
343795
|
for (const bookmark of missing2) {
|
|
343145
343796
|
const paragraph4 = bookmark.paragraph;
|
|
343146
|
-
const
|
|
343147
|
-
|
|
343148
|
-
|
|
343149
|
-
|
|
343797
|
+
const markerBindings = readBookmarkInsertionNamespaceBindings(paragraph4, bookmark);
|
|
343798
|
+
if (!markerBindings)
|
|
343799
|
+
return null;
|
|
343800
|
+
const fragments = buildParagraphBookmarkMarkers(paragraph4, bookmark, bookmarkId++);
|
|
343801
|
+
const markers = [fragments.startXml, fragments.endXml].map((xml) => {
|
|
343150
343802
|
const marker = prepareTrackedInlineXmlReplacement({
|
|
343151
343803
|
beforeXml: "",
|
|
343152
|
-
afterXml:
|
|
343153
|
-
namespaceBindings:
|
|
343804
|
+
afterXml: xml,
|
|
343805
|
+
namespaceBindings: markerBindings,
|
|
343154
343806
|
stamp: {
|
|
343155
343807
|
...stamp,
|
|
343156
343808
|
revisionId: revisionIds?.[count] ?? count,
|
|
@@ -343163,10 +343815,12 @@ function regenerateTrackedToc(context, entry, instruction, dryRun) {
|
|
|
343163
343815
|
});
|
|
343164
343816
|
if (!markers[0] || !markers[1])
|
|
343165
343817
|
return null;
|
|
343166
|
-
|
|
343167
|
-
|
|
343168
|
-
|
|
343169
|
-
|
|
343818
|
+
bookmarkMarkers.push({ ...bookmark, startXml: markers[0].xml, endXml: markers[1].xml });
|
|
343819
|
+
}
|
|
343820
|
+
const grouped = prepareBookmarkParagraphGroups(paragraphs, bookmarkMarkers);
|
|
343821
|
+
if (!grouped)
|
|
343822
|
+
return null;
|
|
343823
|
+
for (const { paragraph: paragraph4, xml } of grouped) {
|
|
343170
343824
|
edits.push({
|
|
343171
343825
|
partUri: paragraph4.partUri,
|
|
343172
343826
|
storyId: paragraph4.storyId,
|
|
@@ -343202,6 +343856,8 @@ function regenerateTrackedToc(context, entry, instruction, dryRun) {
|
|
|
343202
343856
|
return unavailable4("This TOC rebuild requires unsupported existing field, paragraph, or heading boundaries.");
|
|
343203
343857
|
if (dryRun)
|
|
343204
343858
|
return { ok: true };
|
|
343859
|
+
if (context.isCollaborativeSession())
|
|
343860
|
+
return { ok: false, code: "INVALID_CONTEXT", message: "toc-regenerate-tracked: unsupported-context" };
|
|
343205
343861
|
const ids = reserveTrackedReferenceRevisionIds(context, preview.count, false);
|
|
343206
343862
|
if (!ids)
|
|
343207
343863
|
return unavailable4("The TOC rebuild could not reserve its complete revision identity batch.");
|
|
@@ -344461,9 +345117,11 @@ class V2TocAdapter {
|
|
|
344461
345117
|
}
|
|
344462
345118
|
if (options?.dryRun)
|
|
344463
345119
|
return success3(input.target.nodeId);
|
|
345120
|
+
if (this.context.isCollaborativeSession())
|
|
345121
|
+
return failure6("INVALID_CONTEXT", "toc-configure: unsupported-context");
|
|
344464
345122
|
let refreshed = entry;
|
|
344465
345123
|
if (!usesV1EmptyTocSourceSet(nextInstruction)) {
|
|
344466
|
-
const seeded = seedMissingTocBookmarks(this.context, nextInstruction);
|
|
345124
|
+
const seeded = seedMissingTocBookmarks(this.context, nextInstruction, entry.field);
|
|
344467
345125
|
if (!seeded.ok)
|
|
344468
345126
|
return failure6(seeded.code, seeded.message);
|
|
344469
345127
|
const seededEntry = findTocBlock(this.context, input.target.nodeId);
|
|
@@ -344495,9 +345153,11 @@ class V2TocAdapter {
|
|
|
344495
345153
|
}
|
|
344496
345154
|
if (options?.dryRun)
|
|
344497
345155
|
return success3(input.target.nodeId);
|
|
345156
|
+
if (this.context.isCollaborativeSession())
|
|
345157
|
+
return failure6("INVALID_CONTEXT", "toc-update: unsupported-context");
|
|
344498
345158
|
let refreshed = entry;
|
|
344499
345159
|
if (!usesV1EmptyTocSourceSet(entry.field.descriptor.instructionText)) {
|
|
344500
|
-
const seeded = seedMissingTocBookmarks(this.context, entry.field.descriptor.instructionText);
|
|
345160
|
+
const seeded = seedMissingTocBookmarks(this.context, entry.field.descriptor.instructionText, entry.field);
|
|
344501
345161
|
if (!seeded.ok)
|
|
344502
345162
|
return failure6(seeded.code, seeded.message);
|
|
344503
345163
|
const seededEntry = findTocBlock(this.context, input.target.nodeId);
|
|
@@ -344679,6 +345339,9 @@ function listTocBlocks(context) {
|
|
|
344679
345339
|
function findTocBlock(context, nodeId) {
|
|
344680
345340
|
return listTocBlocks(context).find((entry) => entry.field.blockId === nodeId) ?? null;
|
|
344681
345341
|
}
|
|
345342
|
+
function guardTocBookmarkInsertion(context, instruction, operation) {
|
|
345343
|
+
return guardTocContentMutation(context, null, instruction, operation);
|
|
345344
|
+
}
|
|
344682
345345
|
function guardTocContentMutation(context, field, instruction, operation) {
|
|
344683
345346
|
const unavailable4 = () => ({ code: "CAPABILITY_UNAVAILABLE", message: `${operation}: the TOC source is unavailable.` });
|
|
344684
345347
|
const decoder7 = new TextDecoder;
|
|
@@ -344698,15 +345361,28 @@ function guardTocContentMutation(context, field, instruction, operation) {
|
|
|
344698
345361
|
});
|
|
344699
345362
|
return true;
|
|
344700
345363
|
};
|
|
344701
|
-
if (!add(field.partUri, field.descriptor.byteStart, field.descriptor.byteEnd))
|
|
345364
|
+
if (field && !add(field.partUri, field.descriptor.byteStart, field.descriptor.byteEnd))
|
|
344702
345365
|
return unavailable4();
|
|
344703
345366
|
const missing2 = planMissingTocBookmarks(context, instruction);
|
|
344704
345367
|
if (missing2.length) {
|
|
344705
345368
|
const paragraphs = new Map(readBodyParagraphs(context, { includeListState: false }).map((paragraph4) => [paragraph4.blockId, paragraph4]));
|
|
345369
|
+
const aliasedFields = missing2.some((bookmark) => bookmark.fieldSourceKeys?.length) ? new Map(listCanonicalFieldEntries(context).map((source) => [tocTcFieldSourceKey(source), source])) : null;
|
|
344706
345370
|
for (const bookmark of missing2) {
|
|
344707
345371
|
const paragraph4 = paragraphs.get(bookmark.blockId);
|
|
344708
|
-
if (!paragraph4
|
|
345372
|
+
if (!paragraph4)
|
|
344709
345373
|
return unavailable4();
|
|
345374
|
+
const start = bookmark.fieldSource?.byteStart ?? paragraph4.byteStart;
|
|
345375
|
+
const end = bookmark.fieldSource?.byteEnd ?? paragraph4.byteStart;
|
|
345376
|
+
if (!add(paragraph4.partUri, start, start + 1) || bookmark.fieldSource && !add(paragraph4.partUri, end - 1, end))
|
|
345377
|
+
return unavailable4();
|
|
345378
|
+
for (const key2 of bookmark.fieldSourceKeys ?? []) {
|
|
345379
|
+
const source = aliasedFields?.get(key2);
|
|
345380
|
+
if (!source?.descriptor.complete)
|
|
345381
|
+
continue;
|
|
345382
|
+
const fieldSource = { key: key2, byteStart: source.descriptor.byteStart, byteEnd: source.descriptor.byteEnd };
|
|
345383
|
+
if (canPlaceBookmarkAtFieldSource(paragraph4, fieldSource) && (!add(source.partUri, fieldSource.byteStart, fieldSource.byteStart + 1) || !add(source.partUri, fieldSource.byteEnd - 1, fieldSource.byteEnd)))
|
|
345384
|
+
return unavailable4();
|
|
345385
|
+
}
|
|
344710
345386
|
}
|
|
344711
345387
|
}
|
|
344712
345388
|
for (const part of parts.values()) {
|
|
@@ -344714,6 +345390,20 @@ function guardTocContentMutation(context, field, instruction, operation) {
|
|
|
344714
345390
|
if (locked)
|
|
344715
345391
|
return locked;
|
|
344716
345392
|
}
|
|
345393
|
+
if (missing2.length) {
|
|
345394
|
+
const paragraphs = readBodyParagraphs(context, { includeListState: false });
|
|
345395
|
+
const byId = new Map(paragraphs.map((paragraph4) => [paragraph4.blockId, paragraph4]));
|
|
345396
|
+
let id = nextBookmarkNumericId(context);
|
|
345397
|
+
const markers = missing2.map((bookmark) => ({
|
|
345398
|
+
...bookmark,
|
|
345399
|
+
...buildParagraphBookmarkMarkers(byId.get(bookmark.blockId), bookmark, id++)
|
|
345400
|
+
}));
|
|
345401
|
+
if (!prepareBookmarkParagraphGroups(paragraphs, markers))
|
|
345402
|
+
return {
|
|
345403
|
+
code: "CAPABILITY_UNAVAILABLE",
|
|
345404
|
+
message: `${operation}: TOC bookmark targets have unsupported paragraph or field boundaries.`
|
|
345405
|
+
};
|
|
345406
|
+
}
|
|
344717
345407
|
return null;
|
|
344718
345408
|
}
|
|
344719
345409
|
function paragraphOverlapsSpan(entry, span) {
|
|
@@ -344797,10 +345487,11 @@ function projectTocInlineDomain(entry) {
|
|
|
344797
345487
|
};
|
|
344798
345488
|
}
|
|
344799
345489
|
function projectTocSourceConfig(instruction) {
|
|
345490
|
+
const tcSelection = parseTocTcSourceSelection(instruction);
|
|
344800
345491
|
return {
|
|
344801
345492
|
...parseNumericSwitchRange(instruction, "o") ? { outlineLevels: parseNumericSwitchRange(instruction, "o") } : {},
|
|
344802
|
-
...
|
|
344803
|
-
...
|
|
345493
|
+
...tcSelection.identifier ? { tcFieldIdentifier: tcSelection.identifier } : {},
|
|
345494
|
+
...tcSelection.levels ? { tcFieldLevels: tcSelection.levels } : {},
|
|
344804
345495
|
...instruction.includes("\\u") ? { useAppliedOutlineLevel: true } : {}
|
|
344805
345496
|
};
|
|
344806
345497
|
}
|
|
@@ -344828,23 +345519,22 @@ function countGeneratedTocEntries(context, instruction, sourceConfig) {
|
|
|
344828
345519
|
const outline = sourceConfig.outlineLevels ?? { from: 1, to: 3 };
|
|
344829
345520
|
const customStyles = parseTocCustomStyles2(parseQuotedSwitch(instruction, "t") ?? "");
|
|
344830
345521
|
const includeOutlineEntries = customStyles.length === 0 || sourceConfig.outlineLevels != null;
|
|
344831
|
-
const
|
|
345522
|
+
const paragraphs = readBodyParagraphs(context, { includeListState: false });
|
|
345523
|
+
const bodyParagraphs = new Set(paragraphs.map((paragraph4) => `${paragraph4.storyId}:${paragraph4.blockId}`));
|
|
345524
|
+
const headings = paragraphs.filter((paragraph4) => {
|
|
344832
345525
|
const matchesCustomStyle = paragraph4.styleId != null && customStyles.some((entry) => normalizeStyleId2(entry.styleName) === normalizeStyleId2(paragraph4.styleId ?? ""));
|
|
344833
345526
|
const matchesOutline = includeOutlineEntries && paragraph4.headingLevel >= outline.from && paragraph4.headingLevel <= outline.to;
|
|
344834
345527
|
return matchesCustomStyle || matchesOutline;
|
|
344835
345528
|
}).length;
|
|
344836
|
-
const
|
|
345529
|
+
const tcSelection = parseTocTcSourceSelection(instruction);
|
|
345530
|
+
const tcEntries = listTocInlineEntries(context).filter((entry) => bodyParagraphs.has(`${entry.field.storyId}:${entry.field.blockId}`)).filter((entry) => {
|
|
344837
345531
|
const parsed = parseTocEntryInstruction(entry.field.descriptor.instructionText);
|
|
344838
|
-
|
|
344839
|
-
return false;
|
|
344840
|
-
if (sourceConfig.tcFieldLevels && (parsed.level < sourceConfig.tcFieldLevels.from || parsed.level > sourceConfig.tcFieldLevels.to))
|
|
344841
|
-
return false;
|
|
344842
|
-
return true;
|
|
345532
|
+
return matchesTocTcSourceSelection(tcSelection, parsed);
|
|
344843
345533
|
}).length;
|
|
344844
345534
|
return headings + tcEntries;
|
|
344845
345535
|
}
|
|
344846
345536
|
function usesV1EmptyTocSourceSet(instruction) {
|
|
344847
|
-
return parseQuotedSwitch(instruction, "t") != null && parseNumericSwitchRange(instruction, "o") == null && !/\\u\b/i.test(instruction) &&
|
|
345537
|
+
return parseQuotedSwitch(instruction, "t") != null && parseNumericSwitchRange(instruction, "o") == null && !/\\u\b/i.test(instruction) && !parseTocTcSourceSelection(instruction).enabled;
|
|
344848
345538
|
}
|
|
344849
345539
|
function countMaterializedTocResultParagraphs(context, field) {
|
|
344850
345540
|
if (field.descriptor.resultText.length === 0)
|
|
@@ -344867,6 +345557,7 @@ function isTocResultParagraph(rawXml) {
|
|
|
344867
345557
|
return /<[\w.-]+:pStyle\b[^>]*\b(?:[\w.-]+:)?val="TOC[1-9]"/.test(rawXml);
|
|
344868
345558
|
}
|
|
344869
345559
|
function applyTocPatch(instruction, patch) {
|
|
345560
|
+
const tcSelection = parseTocTcSourceSelection(instruction);
|
|
344870
345561
|
const nextParts = ["TOC"];
|
|
344871
345562
|
const outlineLevels = patch.outlineLevels ?? parseNumericSwitchRange(instruction, "o");
|
|
344872
345563
|
if (outlineLevels)
|
|
@@ -344883,12 +345574,17 @@ function applyTocPatch(instruction, patch) {
|
|
|
344883
345574
|
nextParts.push(`\\p "${separator}"`);
|
|
344884
345575
|
if ((patch.useAppliedOutlineLevel ?? instruction.includes("\\u")) === true)
|
|
344885
345576
|
nextParts.push("\\u");
|
|
344886
|
-
const tcIdentifier = patch.tcFieldIdentifier ??
|
|
345577
|
+
const tcIdentifier = patch.tcFieldIdentifier ?? tcSelection.identifier;
|
|
344887
345578
|
if (tcIdentifier != null)
|
|
344888
345579
|
nextParts.push(`\\f "${tcIdentifier}"`);
|
|
344889
|
-
|
|
345580
|
+
else if (tcSelection.hasFieldSwitch)
|
|
345581
|
+
nextParts.push("\\f");
|
|
345582
|
+
const tcLevels = patch.tcFieldLevels ?? tcSelection.levels;
|
|
344890
345583
|
if (tcLevels)
|
|
344891
345584
|
nextParts.push(`\\l "${tcLevels.from}-${tcLevels.to}"`);
|
|
345585
|
+
else if (tcSelection.hasLevelSwitch) {
|
|
345586
|
+
nextParts.push(tcSelection.levelArgument == null ? "\\l" : `\\l "${tcSelection.levelArgument}"`);
|
|
345587
|
+
}
|
|
344892
345588
|
return [...nextParts, ...readPreservedTocSwitchFragments(instruction)].join(" ");
|
|
344893
345589
|
}
|
|
344894
345590
|
function serializeTocEntryInstruction(text4, level, tableIdentifier, omitPageNumber) {
|
|
@@ -344986,9 +345682,19 @@ function parseTocCustomStyles2(value2) {
|
|
|
344986
345682
|
function normalizeStyleId2(value2) {
|
|
344987
345683
|
return value2.replace(/\s+/g, "").trim().toLowerCase();
|
|
344988
345684
|
}
|
|
344989
|
-
function seedMissingTocBookmarks(context, instruction) {
|
|
345685
|
+
function seedMissingTocBookmarks(context, instruction, field) {
|
|
344990
345686
|
const insertions = planMissingTocBookmarks(context, instruction);
|
|
344991
345687
|
if (insertions.length > 0) {
|
|
345688
|
+
const paragraphs = new Map(readBodyParagraphs(context, { includeListState: false }).map((paragraph4) => [paragraph4.blockId, paragraph4]));
|
|
345689
|
+
const names = new Map;
|
|
345690
|
+
for (const bookmark of insertions) {
|
|
345691
|
+
names.set(bookmark.fieldSource?.key ?? `${paragraphs.get(bookmark.blockId).storyId}:${bookmark.blockId}`, bookmark.name);
|
|
345692
|
+
for (const key2 of bookmark.fieldSourceKeys ?? [])
|
|
345693
|
+
names.set(key2, bookmark.name);
|
|
345694
|
+
}
|
|
345695
|
+
const prepared = prepareTocReplacement(context, field, instruction, names);
|
|
345696
|
+
if (!prepared.ok)
|
|
345697
|
+
return prepared;
|
|
344992
345698
|
const committed = insertBookmarksIntoParagraphs(context, insertions, "toc-bookmark-seed");
|
|
344993
345699
|
if (!committed.ok)
|
|
344994
345700
|
return committed;
|
|
@@ -344998,44 +345704,91 @@ function seedMissingTocBookmarks(context, instruction) {
|
|
|
344998
345704
|
function planMissingTocBookmarks(context, instruction) {
|
|
344999
345705
|
if (usesV1EmptyTocSourceSet(instruction))
|
|
345000
345706
|
return [];
|
|
345001
|
-
const
|
|
345002
|
-
const existingNames = new Set;
|
|
345003
|
-
|
|
345004
|
-
|
|
345005
|
-
|
|
345006
|
-
|
|
345007
|
-
|
|
345008
|
-
|
|
345009
|
-
|
|
345010
|
-
}
|
|
345707
|
+
const bookmarks = readBookmarkEntries(context);
|
|
345708
|
+
const existingNames = new Set(bookmarks.map((bookmark) => bookmark.name));
|
|
345709
|
+
const existingParagraphs = new Set(bookmarks.filter((bookmark) => bookmark.name.startsWith("_Toc")).map((bookmark) => `${bookmark.storyId}:${bookmark.blockId}`));
|
|
345710
|
+
const paragraphs = readBodyParagraphs(context, { includeListState: false });
|
|
345711
|
+
const bodyKeys = new Set(paragraphs.map((paragraph4) => `${paragraph4.storyId}:${paragraph4.blockId}`));
|
|
345712
|
+
const canonicalFields = listCanonicalFieldEntries(context);
|
|
345713
|
+
const tcFields = canonicalFields.filter((field) => instructionKeyword(field.descriptor.instructionText) === "TC" && bodyKeys.has(`${field.storyId}:${field.blockId}`));
|
|
345714
|
+
const incompleteFields = canonicalFields.filter((field) => !field.descriptor.complete);
|
|
345715
|
+
const tcBookmarkNames = resolveTocTcBookmarkNames(bookmarks, paragraphs, tcFields);
|
|
345011
345716
|
let nextOrdinal = nextTocBookmarkOrdinal(existingNames);
|
|
345012
345717
|
const insertions = [];
|
|
345013
|
-
|
|
345014
|
-
|
|
345015
|
-
|
|
345016
|
-
|
|
345017
|
-
|
|
345018
|
-
|
|
345019
|
-
nextOrdinal += 1;
|
|
345020
|
-
name = buildTocBookmarkName(nextOrdinal);
|
|
345021
|
-
}
|
|
345022
|
-
insertions.push({ blockId: paragraph4.blockId, name });
|
|
345023
|
-
existing.set(key2, name);
|
|
345718
|
+
const genericByParagraph = new Map;
|
|
345719
|
+
const paragraphsByKey = new Map(paragraphs.map((paragraph4) => [`${paragraph4.storyId}:${paragraph4.blockId}`, paragraph4]));
|
|
345720
|
+
const allocateName = () => {
|
|
345721
|
+
let name = buildTocBookmarkName(nextOrdinal++);
|
|
345722
|
+
while (existingNames.has(name))
|
|
345723
|
+
name = buildTocBookmarkName(nextOrdinal++);
|
|
345024
345724
|
existingNames.add(name);
|
|
345025
|
-
|
|
345026
|
-
}
|
|
345027
|
-
return insertions;
|
|
345028
|
-
}
|
|
345029
|
-
function listIncludedTocParagraphs(context, instruction) {
|
|
345725
|
+
return name;
|
|
345726
|
+
};
|
|
345030
345727
|
const customStyles = parseTocCustomStyles2(parseQuotedSwitch(instruction, "t") ?? "");
|
|
345031
345728
|
const explicitOutlineRange = parseNumericSwitchRange(instruction, "o");
|
|
345032
345729
|
const outlineRange = explicitOutlineRange ?? { from: 1, to: 3 };
|
|
345033
345730
|
const includeOutlineEntries = customStyles.length === 0 || explicitOutlineRange != null;
|
|
345034
|
-
|
|
345731
|
+
for (const paragraph4 of paragraphs) {
|
|
345035
345732
|
const matchesCustomStyle = paragraph4.styleId != null && customStyles.some((entry) => normalizeStyleId2(entry.styleName) === normalizeStyleId2(paragraph4.styleId ?? ""));
|
|
345036
345733
|
const matchesOutline = includeOutlineEntries && paragraph4.headingLevel >= outlineRange.from && paragraph4.headingLevel <= outlineRange.to;
|
|
345037
|
-
|
|
345038
|
-
|
|
345734
|
+
if ((matchesCustomStyle || matchesOutline) && !existingParagraphs.has(`${paragraph4.storyId}:${paragraph4.blockId}`)) {
|
|
345735
|
+
const insertion = { blockId: paragraph4.blockId, name: allocateName() };
|
|
345736
|
+
insertions.push(insertion);
|
|
345737
|
+
genericByParagraph.set(`${paragraph4.storyId}:${paragraph4.blockId}`, insertion);
|
|
345738
|
+
}
|
|
345739
|
+
}
|
|
345740
|
+
const selection = parseTocTcSourceSelection(instruction);
|
|
345741
|
+
const missingFields = tcFields.filter((field) => matchesTocTcSourceSelection(selection, parseTocEntryInstruction(field.descriptor.instructionText)) && !tcBookmarkNames.has(tocTcFieldSourceKey(field))).map((field) => {
|
|
345742
|
+
const key2 = tocTcFieldSourceKey(field);
|
|
345743
|
+
const fieldSource = { key: key2, byteStart: field.descriptor.byteStart, byteEnd: field.descriptor.byteEnd };
|
|
345744
|
+
const paragraphKey = `${field.storyId}:${field.blockId}`;
|
|
345745
|
+
const paragraph4 = paragraphsByKey.get(paragraphKey);
|
|
345746
|
+
const bytes = readPartBytes2(context, field.partUri);
|
|
345747
|
+
const validCanonicalField = Boolean(field.descriptor.complete && Number.isInteger(fieldSource.byteStart) && Number.isInteger(fieldSource.byteEnd) && fieldSource.byteStart >= paragraph4.byteStart && fieldSource.byteEnd > fieldSource.byteStart && bytes && fieldSource.byteEnd <= bytes.length);
|
|
345748
|
+
return { field, key: key2, fieldSource, paragraphKey, paragraph: paragraph4, validCanonicalField };
|
|
345749
|
+
});
|
|
345750
|
+
const fieldsByParagraph = new Map;
|
|
345751
|
+
for (const source of missingFields) {
|
|
345752
|
+
const group = fieldsByParagraph.get(source.paragraphKey) ?? [];
|
|
345753
|
+
group.push(source);
|
|
345754
|
+
fieldsByParagraph.set(source.paragraphKey, group);
|
|
345755
|
+
}
|
|
345756
|
+
const collidingKeys = new Set;
|
|
345757
|
+
for (const group of fieldsByParagraph.values()) {
|
|
345758
|
+
group.sort((left, right) => left.fieldSource.byteStart - right.fieldSource.byteStart);
|
|
345759
|
+
let component = [];
|
|
345760
|
+
let componentEnd = -1;
|
|
345761
|
+
const finishComponent = () => {
|
|
345762
|
+
if (component.length > 1 && component.every((source) => source.validCanonicalField) && !incompleteFields.some((field) => field.storyId === component[0].field.storyId && field.blockId === component[0].field.blockId && field.descriptor.byteStart >= component[0].fieldSource.byteStart && field.descriptor.byteStart < componentEnd)) {
|
|
345763
|
+
for (const source of component)
|
|
345764
|
+
collidingKeys.add(source.key);
|
|
345765
|
+
}
|
|
345766
|
+
};
|
|
345767
|
+
for (const source of group) {
|
|
345768
|
+
if (source.fieldSource.byteStart >= componentEnd) {
|
|
345769
|
+
finishComponent();
|
|
345770
|
+
component = [];
|
|
345771
|
+
componentEnd = -1;
|
|
345772
|
+
}
|
|
345773
|
+
component.push(source);
|
|
345774
|
+
componentEnd = Math.max(componentEnd, source.fieldSource.byteEnd);
|
|
345775
|
+
}
|
|
345776
|
+
finishComponent();
|
|
345777
|
+
}
|
|
345778
|
+
for (const { field, key: key2, fieldSource, paragraphKey, paragraph: paragraph4, validCanonicalField } of missingFields) {
|
|
345779
|
+
if (validCanonicalField && (collidingKeys.has(key2) || !canPlaceBookmarkAtFieldSource(paragraph4, fieldSource))) {
|
|
345780
|
+
let generic = genericByParagraph.get(paragraphKey);
|
|
345781
|
+
if (!generic) {
|
|
345782
|
+
generic = { blockId: field.blockId, name: allocateName() };
|
|
345783
|
+
genericByParagraph.set(paragraphKey, generic);
|
|
345784
|
+
insertions.push(generic);
|
|
345785
|
+
}
|
|
345786
|
+
(generic.fieldSourceKeys ?? (generic.fieldSourceKeys = [])).push(key2);
|
|
345787
|
+
} else {
|
|
345788
|
+
insertions.push({ blockId: field.blockId, name: allocateName(), fieldSource });
|
|
345789
|
+
}
|
|
345790
|
+
}
|
|
345791
|
+
return insertions;
|
|
345039
345792
|
}
|
|
345040
345793
|
function nextTocBookmarkOrdinal(existingNames) {
|
|
345041
345794
|
let largest = 0;
|
|
@@ -345134,14 +345887,17 @@ function insertTrackedToc(context, input) {
|
|
|
345134
345887
|
}));
|
|
345135
345888
|
if (missing2.some((bookmark) => !bookmark.paragraph))
|
|
345136
345889
|
return unavailable4("A TOC heading target is unavailable.");
|
|
345137
|
-
const names = new Map
|
|
345138
|
-
|
|
345139
|
-
bookmark.name
|
|
345140
|
-
|
|
345890
|
+
const names = new Map;
|
|
345891
|
+
for (const bookmark of missing2) {
|
|
345892
|
+
names.set(bookmark.fieldSource?.key ?? `${bookmark.paragraph.storyId}:${bookmark.blockId}`, bookmark.name);
|
|
345893
|
+
for (const key2 of bookmark.fieldSourceKeys ?? [])
|
|
345894
|
+
names.set(key2, bookmark.name);
|
|
345895
|
+
}
|
|
345141
345896
|
let tocXml = buildTocFieldXml(context, input.instruction, {
|
|
345142
345897
|
bare: true,
|
|
345143
345898
|
tocBookmarkNames: names,
|
|
345144
|
-
reservedParaIds: occupied
|
|
345899
|
+
reservedParaIds: occupied,
|
|
345900
|
+
insertionByteStart: insertByte
|
|
345145
345901
|
});
|
|
345146
345902
|
tocXml = tocXml.replace(/<w:p\b[^>]*>/g, (open2) => /\sxmlns:w14\s*=/.test(open2) ? open2 : open2.replace("<w:p", '<w:p xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"'));
|
|
345147
345903
|
const tocRanges = collectXmlElementRanges(tocXml, {
|
|
@@ -345153,17 +345909,8 @@ function insertTrackedToc(context, input) {
|
|
|
345153
345909
|
const tocParagraphs = tocRanges.ranges.filter((range) => range.tag.namespaceUri === bindings.get("w") && range.tag.localName === "p");
|
|
345154
345910
|
if (!tocParagraphs.length)
|
|
345155
345911
|
return unavailable4("The generated TOC has no paragraphs.");
|
|
345156
|
-
const coordinated = context.isCollaborativeSession() && !input.dryRun ? context.allocateCollaborativeStoryParaIds({
|
|
345157
|
-
count: tocParagraphs.length,
|
|
345158
|
-
inUse: [...occupied]
|
|
345159
|
-
}) : null;
|
|
345160
|
-
if (context.isCollaborativeSession() && !input.dryRun && (coordinated?.length !== tocParagraphs.length || new Set(coordinated.map((id) => id.toUpperCase())).size !== coordinated.length || coordinated.some((id) => !/^[0-9a-f]{8}$/i.test(id) || occupied.has(id.toUpperCase())))) {
|
|
345161
|
-
return unavailable4("TOC insertion could not reserve its complete paragraph identity batch.");
|
|
345162
|
-
}
|
|
345163
345912
|
let nextParagraphId = 184549376;
|
|
345164
|
-
const paragraphIds = tocParagraphs.map((
|
|
345165
|
-
if (coordinated)
|
|
345166
|
-
return coordinated[index2];
|
|
345913
|
+
const paragraphIds = tocParagraphs.map(() => {
|
|
345167
345914
|
let id;
|
|
345168
345915
|
do {
|
|
345169
345916
|
id = (++nextParagraphId).toString(16).toUpperCase().padStart(8, "0");
|
|
@@ -345188,6 +345935,12 @@ function insertTrackedToc(context, input) {
|
|
|
345188
345935
|
const preview = prepareTrackedTocInsertion({ xml: tocXml, namespaceBindings: bindings, stamp });
|
|
345189
345936
|
if (!preview)
|
|
345190
345937
|
return unavailable4("The generated TOC content cannot be represented by supported run revisions.");
|
|
345938
|
+
if (context.isCollaborativeSession() && !input.dryRun)
|
|
345939
|
+
return {
|
|
345940
|
+
ok: false,
|
|
345941
|
+
code: "INVALID_CONTEXT",
|
|
345942
|
+
message: "create-table-of-contents-tracked: unsupported-context"
|
|
345943
|
+
};
|
|
345191
345944
|
const ids = reserveTrackedReferenceRevisionIds(context, preview.wordIds.length + missing2.length * 2, input.dryRun);
|
|
345192
345945
|
if (!ids)
|
|
345193
345946
|
return unavailable4("TOC insertion could not reserve its complete revision identity batch.");
|
|
@@ -345204,24 +345957,29 @@ function insertTrackedToc(context, input) {
|
|
|
345204
345957
|
const storyIds = new Set([input.storyId]);
|
|
345205
345958
|
let idIndex = preview.wordIds.length;
|
|
345206
345959
|
let bookmarkId = nextBookmarkNumericId(context);
|
|
345960
|
+
const bookmarkMarkers = [];
|
|
345207
345961
|
for (const bookmark of missing2) {
|
|
345208
345962
|
const paragraph4 = bookmark.paragraph;
|
|
345209
|
-
const
|
|
345210
|
-
|
|
345963
|
+
const markerBindings = readBookmarkInsertionNamespaceBindings(paragraph4, bookmark);
|
|
345964
|
+
if (!markerBindings)
|
|
345965
|
+
return unavailable4("TOC bookmark namespace context is unavailable.");
|
|
345966
|
+
const { startXml, endXml } = buildParagraphBookmarkMarkers(paragraph4, bookmark, bookmarkId++);
|
|
345211
345967
|
const markers = [startXml, endXml].map((xml) => prepareTrackedInlineXmlReplacement({
|
|
345212
345968
|
beforeXml: "",
|
|
345213
345969
|
afterXml: xml,
|
|
345214
|
-
namespaceBindings:
|
|
345970
|
+
namespaceBindings: markerBindings,
|
|
345215
345971
|
stamp: { ...stamp, revisionId: ids[idIndex], revisionIds: [ids[idIndex++]] }
|
|
345216
345972
|
}));
|
|
345217
345973
|
if (!markers[0] || !markers[1])
|
|
345218
345974
|
return unavailable4("TOC bookmark markers cannot be revision marked.");
|
|
345219
|
-
|
|
345220
|
-
|
|
345221
|
-
|
|
345222
|
-
|
|
345975
|
+
bookmarkMarkers.push({ ...bookmark, startXml: markers[0].xml, endXml: markers[1].xml });
|
|
345976
|
+
}
|
|
345977
|
+
const grouped = prepareBookmarkParagraphGroups(paragraphs, bookmarkMarkers);
|
|
345978
|
+
if (!grouped)
|
|
345979
|
+
return unavailable4("TOC bookmark markers could not be placed.");
|
|
345980
|
+
for (const { paragraph: paragraph4, xml } of grouped) {
|
|
345223
345981
|
const perPart2 = edits.get(paragraph4.partUri) ?? [];
|
|
345224
|
-
perPart2.push({ start: paragraph4.byteStart, end: paragraph4.byteEnd, bytes: encodeXml(
|
|
345982
|
+
perPart2.push({ start: paragraph4.byteStart, end: paragraph4.byteEnd, bytes: encodeXml(xml) });
|
|
345225
345983
|
edits.set(paragraph4.partUri, perPart2);
|
|
345226
345984
|
storyIds.add(paragraph4.storyId);
|
|
345227
345985
|
}
|
|
@@ -346189,10 +346947,14 @@ class V2CreateAdapter {
|
|
|
346189
346947
|
return { success: true, section, ...trackedChangeRefs.length ? { trackedChangeRefs } : {} };
|
|
346190
346948
|
}
|
|
346191
346949
|
tableOfContents(input, options) {
|
|
346950
|
+
const guard = beginCanonicalMutation(this.context, options, "create.tableOfContents");
|
|
346951
|
+
if (guard)
|
|
346952
|
+
return createFailure(guard.code, guard.message);
|
|
346953
|
+
const instruction = buildEffectiveTocInstruction(input.instruction, input.config);
|
|
346954
|
+
const locked = guardTocBookmarkInsertion(this.context, instruction, "create.tableOfContents");
|
|
346955
|
+
if (locked)
|
|
346956
|
+
return createFailure(locked.code, locked.message);
|
|
346192
346957
|
if (options?.changeMode === "tracked") {
|
|
346193
|
-
const guard = beginCanonicalMutation(this.context, options, "create.tableOfContents");
|
|
346194
|
-
if (guard)
|
|
346195
|
-
return createFailure(guard.code, guard.message);
|
|
346196
346958
|
const paragraphInput = { at: input.at, text: "" };
|
|
346197
346959
|
const story = resolveStoryTarget(this.context, effectiveStoryLocator(paragraphInput));
|
|
346198
346960
|
if ("failure" in story)
|
|
@@ -346212,7 +346974,7 @@ class V2CreateAdapter {
|
|
|
346212
346974
|
...site,
|
|
346213
346975
|
storyId: anchor.storyId,
|
|
346214
346976
|
documentBoundary: input.at?.kind === "documentStart" || input.at?.kind === "documentEnd" ? input.at.kind : undefined,
|
|
346215
|
-
instruction
|
|
346977
|
+
instruction,
|
|
346216
346978
|
dryRun: options.dryRun
|
|
346217
346979
|
});
|
|
346218
346980
|
if (!inserted.ok)
|
|
@@ -346225,6 +346987,8 @@ class V2CreateAdapter {
|
|
|
346225
346987
|
toc: { kind: "block", nodeType: "tableOfContents", nodeId: "(dry-run)" }
|
|
346226
346988
|
};
|
|
346227
346989
|
}
|
|
346990
|
+
if (this.context.isCollaborativeSession())
|
|
346991
|
+
return createFailure("INVALID_CONTEXT", "create-table-of-contents: unsupported-context");
|
|
346228
346992
|
const created = this.paragraph({ at: input.at, text: "" }, options);
|
|
346229
346993
|
if (!created.success) {
|
|
346230
346994
|
return {
|
|
@@ -346233,7 +346997,6 @@ class V2CreateAdapter {
|
|
|
346233
346997
|
};
|
|
346234
346998
|
}
|
|
346235
346999
|
const nodeId = created.paragraph.nodeId;
|
|
346236
|
-
const instruction = buildEffectiveTocInstruction(input.instruction, input.config);
|
|
346237
347000
|
const committed = prependTocFieldToGeneratedParagraph(this.context, nodeId, instruction, "create-table-of-contents", undefined, input.at?.kind === "documentStart" || input.at?.kind === "documentEnd" ? input.at.kind : undefined);
|
|
346238
347001
|
if (!committed.ok)
|
|
346239
347002
|
return createFailure(committed.code, committed.message);
|
|
@@ -346964,107 +347727,6 @@ var init_adapter14 = __esm(() => {
|
|
|
346964
347727
|
VALUED_TOC_SWITCHES = new Set(["\\o", "\\n", "\\p", "\\f", "\\l"]);
|
|
346965
347728
|
});
|
|
346966
347729
|
|
|
346967
|
-
// ../../../v2/document-api-v2-adapter/dist/formatting/paragraph-property-order.js
|
|
346968
|
-
function setParagraphPropertyChild(children2, localName2, xml) {
|
|
346969
|
-
const parsed = parseSingleElement(xml);
|
|
346970
|
-
const existingIndex = children2.findIndex((child) => child.localName === localName2);
|
|
346971
|
-
if (existingIndex >= 0) {
|
|
346972
|
-
const next = [...children2];
|
|
346973
|
-
next[existingIndex] = parsed;
|
|
346974
|
-
return next;
|
|
346975
|
-
}
|
|
346976
|
-
const targetRank = PARAGRAPH_PROPERTY_CHILD_RANK.get(localName2);
|
|
346977
|
-
if (targetRank == null)
|
|
346978
|
-
throw new Error(`Unknown paragraph property child: ${localName2}`);
|
|
346979
|
-
let insertionIndex = 0;
|
|
346980
|
-
for (const [index2, child] of children2.entries()) {
|
|
346981
|
-
const childRank = paragraphPropertyRankRange(child);
|
|
346982
|
-
if (!childRank)
|
|
346983
|
-
continue;
|
|
346984
|
-
if (childRank.minimum > targetRank) {
|
|
346985
|
-
return [...children2.slice(0, index2), parsed, ...children2.slice(index2)];
|
|
346986
|
-
}
|
|
346987
|
-
if (childRank.maximum >= targetRank) {
|
|
346988
|
-
throw new ParagraphPropertyMutationUnavailableError(`Cannot safely insert w:${localName2} within mc:AlternateContent paragraph properties`);
|
|
346989
|
-
}
|
|
346990
|
-
insertionIndex = index2 + 1;
|
|
346991
|
-
}
|
|
346992
|
-
return [...children2.slice(0, insertionIndex), parsed, ...children2.slice(insertionIndex)];
|
|
346993
|
-
}
|
|
346994
|
-
function paragraphPropertyRankRange(child) {
|
|
346995
|
-
const directRank = PARAGRAPH_PROPERTY_CHILD_RANK.get(child.localName);
|
|
346996
|
-
if (directRank != null)
|
|
346997
|
-
return { minimum: directRank, maximum: directRank };
|
|
346998
|
-
if (child.localName !== "AlternateContent")
|
|
346999
|
-
return null;
|
|
347000
|
-
const alternateContent = parseContainerXml(child.xml, "AlternateContent");
|
|
347001
|
-
if (!alternateContent)
|
|
347002
|
-
return null;
|
|
347003
|
-
const ranks = parseTopLevelChildren(alternateContent.inner).flatMap((branch) => {
|
|
347004
|
-
if (branch.localName !== "Choice" && branch.localName !== "Fallback")
|
|
347005
|
-
return [];
|
|
347006
|
-
const branchContainer = parseContainerXml(branch.xml, branch.localName);
|
|
347007
|
-
if (!branchContainer)
|
|
347008
|
-
return [];
|
|
347009
|
-
return parseTopLevelChildren(branchContainer.inner).flatMap((candidate2) => {
|
|
347010
|
-
const range = paragraphPropertyRankRange(candidate2);
|
|
347011
|
-
return range ? [range.minimum, range.maximum] : [];
|
|
347012
|
-
});
|
|
347013
|
-
});
|
|
347014
|
-
if (ranks.length === 0)
|
|
347015
|
-
return null;
|
|
347016
|
-
return { minimum: Math.min(...ranks), maximum: Math.max(...ranks) };
|
|
347017
|
-
}
|
|
347018
|
-
var PARAGRAPH_PROPERTY_CHILD_ORDER, PARAGRAPH_PROPERTY_CHILD_RANK, ParagraphPropertyMutationUnavailableError;
|
|
347019
|
-
var init_paragraph_property_order = __esm(() => {
|
|
347020
|
-
init_common();
|
|
347021
|
-
PARAGRAPH_PROPERTY_CHILD_ORDER = [
|
|
347022
|
-
"pStyle",
|
|
347023
|
-
"keepNext",
|
|
347024
|
-
"keepLines",
|
|
347025
|
-
"pageBreakBefore",
|
|
347026
|
-
"framePr",
|
|
347027
|
-
"widowControl",
|
|
347028
|
-
"numPr",
|
|
347029
|
-
"suppressLineNumbers",
|
|
347030
|
-
"pBdr",
|
|
347031
|
-
"shd",
|
|
347032
|
-
"tabs",
|
|
347033
|
-
"suppressAutoHyphens",
|
|
347034
|
-
"kinsoku",
|
|
347035
|
-
"wordWrap",
|
|
347036
|
-
"overflowPunct",
|
|
347037
|
-
"topLinePunct",
|
|
347038
|
-
"autoSpaceDE",
|
|
347039
|
-
"autoSpaceDN",
|
|
347040
|
-
"bidi",
|
|
347041
|
-
"adjustRightInd",
|
|
347042
|
-
"snapToGrid",
|
|
347043
|
-
"spacing",
|
|
347044
|
-
"ind",
|
|
347045
|
-
"contextualSpacing",
|
|
347046
|
-
"mirrorIndents",
|
|
347047
|
-
"suppressOverlap",
|
|
347048
|
-
"jc",
|
|
347049
|
-
"textDirection",
|
|
347050
|
-
"textAlignment",
|
|
347051
|
-
"textboxTightWrap",
|
|
347052
|
-
"outlineLvl",
|
|
347053
|
-
"divId",
|
|
347054
|
-
"cnfStyle",
|
|
347055
|
-
"rPr",
|
|
347056
|
-
"sectPr",
|
|
347057
|
-
"pPrChange"
|
|
347058
|
-
];
|
|
347059
|
-
PARAGRAPH_PROPERTY_CHILD_RANK = new Map(PARAGRAPH_PROPERTY_CHILD_ORDER.map((name, index2) => [name, index2]));
|
|
347060
|
-
ParagraphPropertyMutationUnavailableError = class ParagraphPropertyMutationUnavailableError extends Error {
|
|
347061
|
-
constructor(message) {
|
|
347062
|
-
super(message);
|
|
347063
|
-
this.name = "ParagraphPropertyMutationUnavailableError";
|
|
347064
|
-
}
|
|
347065
|
-
};
|
|
347066
|
-
});
|
|
347067
|
-
|
|
347068
347730
|
// ../../../v2/document-api-v2-adapter/dist/formatting/paragraph.js
|
|
347069
347731
|
function classifyParagraphNodeType(input) {
|
|
347070
347732
|
if (input.headingLevel > 0)
|