@stll/folio-core 0.47.4 → 0.47.6
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/compare/inline-atoms.js +218 -31
- package/dist/compare/section-boundary-properties.js +1 -0
- package/dist/content-controls/mutateContentControls.js +1 -3
- package/dist/controller/headerFooterEditorManager.d.ts +2 -1
- package/dist/controller/headerFooterEditorManager.js +2 -1
- package/dist/controller/noteEditorManager.d.ts +2 -1
- package/dist/controller/noteEditorManager.js +2 -1
- package/dist/docx/commentRangeIntegrity.js +7 -0
- package/dist/docx/documentParser.js +55 -3
- package/dist/docx/inlineWrapperContent.d.ts +18 -16
- package/dist/docx/inlineWrapperContent.js +18 -16
- package/dist/docx/normalizeBaseDirection.js +4 -0
- package/dist/docx/rezip.js +1 -0
- package/dist/docx/selectiveSave.js +11 -2
- package/dist/docx/serializer/documentSerializer.js +16 -1
- package/dist/docx/serializer/paragraphSerializer.js +8 -0
- package/dist/docx/serializer/tableSerializer.js +5 -2
- package/dist/docx/server/createBilingualDocument.js +23 -14
- package/dist/docx/tableParser.js +101 -75
- package/dist/markdown/renderRuns.js +4 -0
- package/dist/markdown/renderTable.js +46 -12
- package/dist/prosemirror/attrs/index.d.ts +3 -2
- package/dist/prosemirror/attrs/index.js +85 -4
- package/dist/prosemirror/commands/comments.js +61 -3
- package/dist/prosemirror/commentReferenceAttrs.js +2 -2
- package/dist/prosemirror/commentReferenceIntegrity.d.ts +7 -3
- package/dist/prosemirror/commentReferenceIntegrity.js +9 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +177 -51
- package/dist/prosemirror/conversion/toProseDoc.js +108 -55
- package/dist/prosemirror/extensions/markRegistry.d.ts +5 -8
- package/dist/prosemirror/extensions/markRegistry.js +5 -8
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +13 -6
- package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +24 -6
- package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +2 -1
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +32 -7
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +9 -5
- package/dist/prosemirror/extensions/nodes/TableExtension.js +2 -2
- package/dist/prosemirror/runIdentity.d.ts +5 -5
- package/dist/prosemirror/runIdentity.js +5 -5
- package/dist/prosemirror/schema/index.d.ts +2 -2
- package/dist/prosemirror/schema/marks.d.ts +28 -2
- package/dist/prosemirror/schema/nodes.d.ts +6 -4
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -1
- package/dist/prosemirror/trackedRunInlineAtoms.js +1 -1
- package/dist/prosemirror/utils/extractTrackedChanges.js +21 -6
- package/dist/prosemirror/validation.js +48 -7
- package/dist/types/content.d.ts +2 -2
- package/dist/types/index.d.ts +3 -1
- package/dist/utils/mergeDocumentContent.js +1 -7
- package/package.json +2 -2
|
@@ -272,6 +272,7 @@ function fromProseDoc(pmDoc, baseDocument, { reuse = "none" } = {}) {
|
|
|
272
272
|
if (tokenSources) restoreParagraphPropertySourcesByToken(blocks, tokenSources);
|
|
273
273
|
else if (baseDocument) restoreParagraphPropertySources(blocks, baseDocument.package.document.content, linkedSources.targets, linkedSources.sources);
|
|
274
274
|
const documentBody = { content: blocks };
|
|
275
|
+
if (baseDocument?.package.document.background) documentBody.background = baseDocument.package.document.background;
|
|
275
276
|
if (baseDocument?.package.document.finalSectionProperties) documentBody.finalSectionProperties = baseDocument.package.document.finalSectionProperties;
|
|
276
277
|
if (baseDocument?.package.document.sections) documentBody.sections = baseDocument.package.document.sections;
|
|
277
278
|
if (baseDocument?.package.document.comments) documentBody.comments = baseDocument.package.document.comments;
|
|
@@ -1137,6 +1138,17 @@ const inlineWrapperStackOf = (node) => {
|
|
|
1137
1138
|
const mark = node.marks.find((candidate) => candidate.type.name === INLINE_WRAPPER_MARK_NAME);
|
|
1138
1139
|
return mark ? expectInlineWrapperMarkAttrs(mark).stack : [];
|
|
1139
1140
|
};
|
|
1141
|
+
/** The authored hyperlink that owns a suffix of the node's wrapper stack. */
|
|
1142
|
+
const inlineWrapperHyperlinkOriginOf = (node) => {
|
|
1143
|
+
const mark = node.marks.find((candidate) => candidate.type.name === INLINE_WRAPPER_MARK_NAME);
|
|
1144
|
+
if (!mark) return;
|
|
1145
|
+
const attrs = expectInlineWrapperMarkAttrs(mark);
|
|
1146
|
+
if (typeof attrs._docxHyperlinkIndex !== "number" || typeof attrs._docxInsideHyperlinkStackStart !== "number") return;
|
|
1147
|
+
return {
|
|
1148
|
+
hyperlinkIndex: attrs._docxHyperlinkIndex,
|
|
1149
|
+
stackStart: attrs._docxInsideHyperlinkStackStart
|
|
1150
|
+
};
|
|
1151
|
+
};
|
|
1140
1152
|
const isRevisionWrapper = (item) => item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo";
|
|
1141
1153
|
/** `stack` closed around `content`, outermost layer first. */
|
|
1142
1154
|
const nestInlineWrappers = (stack, content) => {
|
|
@@ -1150,42 +1162,132 @@ const nestInlineWrappers = (stack, content) => {
|
|
|
1150
1162
|
* The emitted sequence with each wrapper group nested back into the wrappers
|
|
1151
1163
|
* `toProseDoc` lifted off it.
|
|
1152
1164
|
*
|
|
1153
|
-
*
|
|
1154
|
-
*
|
|
1155
|
-
*
|
|
1156
|
-
*
|
|
1157
|
-
* per wrapper. So a revision in the group keeps its place and takes the nest
|
|
1158
|
-
* inside it, and the items around it share a nest of their own.
|
|
1165
|
+
* A revision may be inside some wrapper layers and outside others. Its mark
|
|
1166
|
+
* records how many layers preceded it in the source, since a ProseMirror mark
|
|
1167
|
+
* set cannot express that order. Adjacent items with the same outer layers
|
|
1168
|
+
* share one wrapper rather than splitting it around each revision.
|
|
1159
1169
|
*
|
|
1160
1170
|
* A group with nothing in it writes no wrapper: an authored wrapper whose
|
|
1161
1171
|
* content was deleted or rejected is gone, and an empty one says nothing.
|
|
1162
1172
|
*/
|
|
1163
|
-
const
|
|
1173
|
+
const nestInsideHyperlink = (item, stack, hyperlinkIndex, indices) => {
|
|
1174
|
+
if (item.type === "hyperlink") {
|
|
1175
|
+
if (indices.get(item) !== hyperlinkIndex) return false;
|
|
1176
|
+
item.children = [nestInlineWrappers(stack, item.children)];
|
|
1177
|
+
return true;
|
|
1178
|
+
}
|
|
1179
|
+
if (isRevisionWrapper(item)) {
|
|
1180
|
+
let nested = false;
|
|
1181
|
+
for (const child of item.content) if (nestInsideHyperlink(child, stack, hyperlinkIndex, indices)) nested = true;
|
|
1182
|
+
return nested;
|
|
1183
|
+
}
|
|
1184
|
+
return false;
|
|
1185
|
+
};
|
|
1186
|
+
const nestRevisionAwareInlineWrappers = (items, stack, revisionOuterWrapperCounts, layerIndex = 0) => {
|
|
1187
|
+
if (layerIndex === stack.length) return [...items];
|
|
1188
|
+
const nested = [];
|
|
1189
|
+
let pending = [];
|
|
1190
|
+
const closeLayer = () => {
|
|
1191
|
+
if (pending.length === 0) return;
|
|
1192
|
+
const layer = stack[layerIndex];
|
|
1193
|
+
if (layer === void 0) panic("An inline wrapper layer disappeared during reconstruction");
|
|
1194
|
+
nested.push(inlineWrapperMember(layer, nestRevisionAwareInlineWrappers(pending, stack, revisionOuterWrapperCounts, layerIndex + 1)));
|
|
1195
|
+
pending = [];
|
|
1196
|
+
};
|
|
1197
|
+
for (const item of items) {
|
|
1198
|
+
if (!isRevisionWrapper(item) || (revisionOuterWrapperCounts.get(item) ?? 0) > layerIndex) {
|
|
1199
|
+
pending.push(item);
|
|
1200
|
+
continue;
|
|
1201
|
+
}
|
|
1202
|
+
closeLayer();
|
|
1203
|
+
item.content = [nestInlineWrappers(stack.slice(layerIndex), item.content)];
|
|
1204
|
+
nested.push(item);
|
|
1205
|
+
}
|
|
1206
|
+
closeLayer();
|
|
1207
|
+
return nested;
|
|
1208
|
+
};
|
|
1209
|
+
const sameRevisionLayer = (left, right) => left.type === right.type && left.revisionId === right.revisionId && left.author === right.author && left.date === right.date && left.utcDate === right.utcDate && left.initials === right.initials && left.outerWrapperCount === right.outerWrapperCount;
|
|
1210
|
+
const revisionInfoFromLayer = (layer) => ({
|
|
1211
|
+
id: layer.revisionId,
|
|
1212
|
+
author: layer.author,
|
|
1213
|
+
...layer.date ? { date: layer.date } : {},
|
|
1214
|
+
...layer.utcDate ? { utcDate: {
|
|
1215
|
+
attribute: DATE_UTC_ATTRIBUTE,
|
|
1216
|
+
value: layer.utcDate
|
|
1217
|
+
} } : {},
|
|
1218
|
+
...layer.initials ? { initials: layer.initials } : {}
|
|
1219
|
+
});
|
|
1220
|
+
const nestRevisionAncestors = (items, ancestorsByWrapper, revisionOuterWrapperCounts) => {
|
|
1221
|
+
const nested = [];
|
|
1222
|
+
const open = [];
|
|
1223
|
+
for (const item of items) {
|
|
1224
|
+
if (!isRevisionWrapper(item)) {
|
|
1225
|
+
open.length = 0;
|
|
1226
|
+
nested.push(item);
|
|
1227
|
+
continue;
|
|
1228
|
+
}
|
|
1229
|
+
const ownLayer = {
|
|
1230
|
+
type: item.type,
|
|
1231
|
+
revisionId: item.info.id,
|
|
1232
|
+
author: item.info.author,
|
|
1233
|
+
...item.info.date ? { date: item.info.date } : {},
|
|
1234
|
+
...item.info.utcDate ? { utcDate: item.info.utcDate.value } : {},
|
|
1235
|
+
...item.info.initials ? { initials: item.info.initials } : {},
|
|
1236
|
+
outerWrapperCount: revisionOuterWrapperCounts.get(item) ?? 0
|
|
1237
|
+
};
|
|
1238
|
+
const path = [...ancestorsByWrapper.get(item) ?? [], ownLayer];
|
|
1239
|
+
let shared = 0;
|
|
1240
|
+
while (shared < open.length && path[shared] && sameRevisionLayer(open[shared].layer, path[shared])) shared += 1;
|
|
1241
|
+
open.length = shared;
|
|
1242
|
+
for (const layer of path.slice(shared)) {
|
|
1243
|
+
const wrapper = createTrackedRunWrapper(layer.type, revisionInfoFromLayer(layer));
|
|
1244
|
+
revisionOuterWrapperCounts.set(wrapper, layer.outerWrapperCount);
|
|
1245
|
+
const parent = open.at(-1)?.wrapper;
|
|
1246
|
+
if (parent) parent.content.push(wrapper);
|
|
1247
|
+
else nested.push(wrapper);
|
|
1248
|
+
open.push({
|
|
1249
|
+
layer,
|
|
1250
|
+
wrapper
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1253
|
+
const owner = open.at(-1)?.wrapper;
|
|
1254
|
+
if (!owner) panic("A tracked revision path has no owner");
|
|
1255
|
+
owner.content.push(...item.content);
|
|
1256
|
+
}
|
|
1257
|
+
return nested;
|
|
1258
|
+
};
|
|
1259
|
+
const nestInlineWrapperGroups = (items, groups, hyperlinkIndices, revisionOuterWrapperCounts, ancestorsByWrapper) => {
|
|
1164
1260
|
const nested = [];
|
|
1165
1261
|
for (const [index, group] of groups.entries()) {
|
|
1166
|
-
const slice = items.slice(group.start, groups[index + 1]?.start ?? items.length);
|
|
1262
|
+
const slice = nestRevisionAncestors(items.slice(group.start, groups[index + 1]?.start ?? items.length), ancestorsByWrapper, revisionOuterWrapperCounts);
|
|
1167
1263
|
if (group.stack.length === 0) {
|
|
1168
1264
|
nested.push(...slice);
|
|
1169
1265
|
continue;
|
|
1170
1266
|
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
closeNest();
|
|
1183
|
-
if (item.content.length > 0) item.content = [nestInlineWrappers(group.stack, item.content)];
|
|
1184
|
-
nested.push(item);
|
|
1267
|
+
const origin = group.origin;
|
|
1268
|
+
let outerStack = group.stack;
|
|
1269
|
+
if (origin !== void 0) {
|
|
1270
|
+
const innerStack = group.stack.slice(origin.stackStart);
|
|
1271
|
+
let nestedInsideOrigin = false;
|
|
1272
|
+
for (const item of slice) if (nestInsideHyperlink(item, innerStack, origin.hyperlinkIndex, hyperlinkIndices)) nestedInsideOrigin = true;
|
|
1273
|
+
if (nestedInsideOrigin) outerStack = group.stack.slice(0, origin.stackStart);
|
|
1274
|
+
}
|
|
1275
|
+
if (outerStack.length === 0) {
|
|
1276
|
+
nested.push(...slice);
|
|
1277
|
+
continue;
|
|
1185
1278
|
}
|
|
1186
|
-
|
|
1279
|
+
nested.push(...nestRevisionAwareInlineWrappers(slice, outerStack, revisionOuterWrapperCounts));
|
|
1187
1280
|
}
|
|
1188
|
-
|
|
1281
|
+
const coalesced = [];
|
|
1282
|
+
for (const item of nested) {
|
|
1283
|
+
const previous = coalesced.at(-1);
|
|
1284
|
+
if (previous && isRevisionWrapper(previous) && isRevisionWrapper(item) && previous.type === item.type && JSON.stringify(previous.info) === JSON.stringify(item.info) && revisionOuterWrapperCounts.get(previous) === revisionOuterWrapperCounts.get(item)) {
|
|
1285
|
+
previous.content.push(...item.content);
|
|
1286
|
+
continue;
|
|
1287
|
+
}
|
|
1288
|
+
coalesced.push(item);
|
|
1289
|
+
}
|
|
1290
|
+
return coalesced;
|
|
1189
1291
|
};
|
|
1190
1292
|
function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, textBoxAnchorMarkers, skipLeadingRenderedPageBreak = false, inheritedFormattingOverride) {
|
|
1191
1293
|
const content = [];
|
|
@@ -1214,7 +1316,16 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1214
1316
|
let currentHyperlinkKey = null;
|
|
1215
1317
|
let currentTrackedChange;
|
|
1216
1318
|
const sourceRunOwners = /* @__PURE__ */ new WeakMap();
|
|
1319
|
+
const sourceHyperlinkIndices = /* @__PURE__ */ new WeakMap();
|
|
1320
|
+
const revisionOuterWrapperCounts = /* @__PURE__ */ new WeakMap();
|
|
1321
|
+
const revisionAncestorsByWrapper = /* @__PURE__ */ new WeakMap();
|
|
1217
1322
|
const openedComments = /* @__PURE__ */ new Set();
|
|
1323
|
+
const createIndexedHyperlink = (mark) => {
|
|
1324
|
+
const hyperlink = createHyperlink(mark);
|
|
1325
|
+
const index = expectHyperlinkMarkAttrs(mark)._docxHyperlinkIndex;
|
|
1326
|
+
if (typeof index === "number") sourceHyperlinkIndices.set(hyperlink, index);
|
|
1327
|
+
return hyperlink;
|
|
1328
|
+
};
|
|
1218
1329
|
const commentLastOffset = /* @__PURE__ */ new Map();
|
|
1219
1330
|
paragraph.forEach((node, offset) => {
|
|
1220
1331
|
for (const commentId of getCommentMarkIds(node.marks)) commentLastOffset.set(commentId, offset);
|
|
@@ -1298,14 +1409,20 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1298
1409
|
*/
|
|
1299
1410
|
const enterWrapperGroup = (node) => {
|
|
1300
1411
|
const stack = inlineWrapperStackOf(node);
|
|
1301
|
-
const
|
|
1412
|
+
const origin = inlineWrapperHyperlinkOriginOf(node);
|
|
1413
|
+
const key = [
|
|
1414
|
+
inlineWrapperStackKey(stack),
|
|
1415
|
+
origin?.hyperlinkIndex ?? "",
|
|
1416
|
+
origin?.stackStart ?? ""
|
|
1417
|
+
].join("\0");
|
|
1302
1418
|
if (key === wrapperGroupKey) return;
|
|
1303
1419
|
flushCurrentInline();
|
|
1304
1420
|
currentTrackedChange = void 0;
|
|
1305
1421
|
wrapperGroupKey = key;
|
|
1306
1422
|
wrapperGroups.push({
|
|
1307
1423
|
start: content.length,
|
|
1308
|
-
stack
|
|
1424
|
+
stack,
|
|
1425
|
+
...origin ? { origin } : {}
|
|
1309
1426
|
});
|
|
1310
1427
|
};
|
|
1311
1428
|
const processInlineNode = (node, offset) => {
|
|
@@ -1332,12 +1449,6 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1332
1449
|
content.push({ ...start }, { ...end });
|
|
1333
1450
|
return;
|
|
1334
1451
|
}
|
|
1335
|
-
if (node.type.name === "moveRangeBoundary") {
|
|
1336
|
-
flushCurrentInline();
|
|
1337
|
-
currentTrackedChange = void 0;
|
|
1338
|
-
content.push({ ...expectMoveRangeBoundaryAttrs(node) });
|
|
1339
|
-
return;
|
|
1340
|
-
}
|
|
1341
1452
|
const linkMark = node.marks.find((m) => m.type.name === "hyperlink");
|
|
1342
1453
|
const noteRefMark = node.marks.find((m) => m.type.name === "footnoteRef");
|
|
1343
1454
|
const insertionMark = node.marks.find((m) => m.type.name === "insertion");
|
|
@@ -1354,10 +1465,8 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1354
1465
|
};
|
|
1355
1466
|
if (textBoxAnchorMarkers.has(anchorId)) return;
|
|
1356
1467
|
textBoxAnchorMarkers.set(anchorId, marker);
|
|
1357
|
-
const anchoredContent = linkMark ?
|
|
1358
|
-
|
|
1359
|
-
children: [marker]
|
|
1360
|
-
} : marker;
|
|
1468
|
+
const anchoredContent = linkMark ? createIndexedHyperlink(linkMark) : marker;
|
|
1469
|
+
if (anchoredContent.type === "hyperlink") anchoredContent.children.push(marker);
|
|
1361
1470
|
const changeMark = insertionMark ?? deletionMark;
|
|
1362
1471
|
if (!changeMark) {
|
|
1363
1472
|
content.push(anchoredContent);
|
|
@@ -1374,16 +1483,13 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1374
1483
|
} } : {},
|
|
1375
1484
|
...changeAttrs.initials ? { initials: changeAttrs.initials } : {}
|
|
1376
1485
|
};
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
info,
|
|
1385
|
-
content: [anchoredContent]
|
|
1386
|
-
});
|
|
1486
|
+
let type;
|
|
1487
|
+
if (insertionMark) type = changeAttrs.moveKind === "moveTo" ? "moveTo" : "insertion";
|
|
1488
|
+
else type = changeAttrs.moveKind === "moveFrom" ? "moveFrom" : "deletion";
|
|
1489
|
+
const wrapper = createTrackedRunWrapper(type, info, anchoredContent);
|
|
1490
|
+
revisionOuterWrapperCounts.set(wrapper, changeAttrs._docxOuterWrapperCount ?? inlineWrapperStackOf(node).length);
|
|
1491
|
+
revisionAncestorsByWrapper.set(wrapper, changeAttrs._docxRevisionAncestors ?? []);
|
|
1492
|
+
content.push(wrapper);
|
|
1387
1493
|
return;
|
|
1388
1494
|
}
|
|
1389
1495
|
if (insertionMark || deletionMark) {
|
|
@@ -1405,12 +1511,15 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1405
1511
|
let type;
|
|
1406
1512
|
if (insertionMark) type = changeAttrs.moveKind === "moveTo" ? "moveTo" : "insertion";
|
|
1407
1513
|
else type = changeAttrs.moveKind === "moveFrom" ? "moveFrom" : "deletion";
|
|
1408
|
-
const
|
|
1514
|
+
const outerWrapperCount = changeAttrs._docxOuterWrapperCount ?? inlineWrapperStackOf(node).length;
|
|
1515
|
+
const trackedChangeKey = `${type}:${JSON.stringify(info)}:${outerWrapperCount}:${JSON.stringify(changeAttrs._docxRevisionAncestors ?? [])}`;
|
|
1409
1516
|
if (linkMark) {
|
|
1410
1517
|
const linkKey = getLinkKey(linkMark);
|
|
1411
1518
|
if (!currentTrackedChange || currentTrackedChange.type !== "hyperlink" || currentTrackedChange.key !== trackedChangeKey || currentTrackedChange.hyperlinkKey !== linkKey) {
|
|
1412
|
-
const hyperlink =
|
|
1519
|
+
const hyperlink = createIndexedHyperlink(linkMark);
|
|
1413
1520
|
const wrapper = createTrackedRunWrapper(type, info, hyperlink);
|
|
1521
|
+
revisionOuterWrapperCounts.set(wrapper, outerWrapperCount);
|
|
1522
|
+
revisionAncestorsByWrapper.set(wrapper, changeAttrs._docxRevisionAncestors ?? []);
|
|
1414
1523
|
content.push(wrapper);
|
|
1415
1524
|
currentTrackedChange = {
|
|
1416
1525
|
type: "hyperlink",
|
|
@@ -1444,6 +1553,8 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1444
1553
|
}
|
|
1445
1554
|
if (!currentTrackedChange || currentTrackedChange.type !== "direct" || currentTrackedChange.key !== trackedChangeKey) {
|
|
1446
1555
|
const wrapper = createTrackedRunWrapper(type, info);
|
|
1556
|
+
revisionOuterWrapperCounts.set(wrapper, outerWrapperCount);
|
|
1557
|
+
revisionAncestorsByWrapper.set(wrapper, changeAttrs._docxRevisionAncestors ?? []);
|
|
1447
1558
|
content.push(wrapper);
|
|
1448
1559
|
currentTrackedChange = {
|
|
1449
1560
|
type: "direct",
|
|
@@ -1455,6 +1566,10 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1455
1566
|
currentTrackedChange.wrapper.content.push(bookmarkMarkerFromAttrs(expectBookmarkBoundaryAttrs(node)));
|
|
1456
1567
|
return;
|
|
1457
1568
|
}
|
|
1569
|
+
if (node.type.name === "moveRangeBoundary") {
|
|
1570
|
+
currentTrackedChange.wrapper.content.push({ ...expectMoveRangeBoundaryAttrs(node) });
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1458
1573
|
if (node.type.name === "field" || node.type.name === "structuredField") {
|
|
1459
1574
|
currentTrackedChange.wrapper.content.push(createFieldFromNode(node, {
|
|
1460
1575
|
...formattingContext,
|
|
@@ -1488,6 +1603,12 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1488
1603
|
appendDirectRun(node, ownedRun, node.isText);
|
|
1489
1604
|
return;
|
|
1490
1605
|
}
|
|
1606
|
+
if (node.type.name === "moveRangeBoundary") {
|
|
1607
|
+
flushCurrentInline();
|
|
1608
|
+
currentTrackedChange = void 0;
|
|
1609
|
+
content.push({ ...expectMoveRangeBoundaryAttrs(node) });
|
|
1610
|
+
return;
|
|
1611
|
+
}
|
|
1491
1612
|
if (noteRefMark && !linkMark) {
|
|
1492
1613
|
flushCurrentInline();
|
|
1493
1614
|
content.push(createNoteReferenceRun(noteRefMark, node.marks, formattingContext));
|
|
@@ -1497,7 +1618,7 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1497
1618
|
const linkKey = getLinkKey(linkMark);
|
|
1498
1619
|
if (currentHyperlink && currentHyperlinkKey === linkKey) {} else {
|
|
1499
1620
|
flushCurrentInline();
|
|
1500
|
-
currentHyperlink =
|
|
1621
|
+
currentHyperlink = createIndexedHyperlink(linkMark);
|
|
1501
1622
|
currentHyperlinkKey = linkKey;
|
|
1502
1623
|
}
|
|
1503
1624
|
addNodeToHyperlink({
|
|
@@ -1588,7 +1709,7 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1588
1709
|
type: "commentRangeEnd",
|
|
1589
1710
|
id: commentId
|
|
1590
1711
|
});
|
|
1591
|
-
return nestInlineWrapperGroups(content, wrapperGroups);
|
|
1712
|
+
return nestInlineWrapperGroups(content, wrapperGroups, sourceHyperlinkIndices, revisionOuterWrapperCounts, revisionAncestorsByWrapper);
|
|
1592
1713
|
}
|
|
1593
1714
|
function createTrackedChangeRun({ baseParagraphFormatting, inheritedFormatting, marks, node, paragraphMarkFormatting, paragraphMarkPrecedesStyle, styleResolver }) {
|
|
1594
1715
|
const formattingContext = {
|
|
@@ -1646,6 +1767,7 @@ function createEmptyHyperlink(attrs) {
|
|
|
1646
1767
|
if (attrs.target !== void 0) hyperlink.target = attrs.target;
|
|
1647
1768
|
if (attrs.history !== void 0) hyperlink.history = attrs.history;
|
|
1648
1769
|
if (attrs.docLocation !== void 0) hyperlink.docLocation = attrs.docLocation;
|
|
1770
|
+
for (const stack of attrs._docxEmptyWrapperStacks ?? []) hyperlink.children.push(nestInlineWrappers(stack, []));
|
|
1649
1771
|
return hyperlink;
|
|
1650
1772
|
}
|
|
1651
1773
|
function getCommentMarkIds(marks) {
|
|
@@ -1948,7 +2070,7 @@ function restoreRunRecord(run, marks) {
|
|
|
1948
2070
|
}
|
|
1949
2071
|
const identityMark = marks.find((mark) => mark.type.name === RUN_IDENTITY_MARK_NAME);
|
|
1950
2072
|
if (!identityMark) return;
|
|
1951
|
-
const { preservedAttributes, preserved } = expectRunIdentityMarkAttrs(identityMark);
|
|
2073
|
+
const { preservedAttributes, preserved, emptyFormatting } = expectRunIdentityMarkAttrs(identityMark);
|
|
1952
2074
|
if (preservedAttributes && preservedAttributes.length > 0) run.preservedAttributes = preservedAttributes.map(({ namespace, name, value }) => namespace === void 0 ? {
|
|
1953
2075
|
name,
|
|
1954
2076
|
value
|
|
@@ -1961,6 +2083,7 @@ function restoreRunRecord(run, marks) {
|
|
|
1961
2083
|
...run.formatting,
|
|
1962
2084
|
preserved
|
|
1963
2085
|
};
|
|
2086
|
+
if (emptyFormatting && run.formatting === void 0) run.formatting = {};
|
|
1964
2087
|
}
|
|
1965
2088
|
function getRunFormattingFromMarks(marks, options) {
|
|
1966
2089
|
if (!marks || marks.length === 0 && !options) return;
|
|
@@ -3298,6 +3421,9 @@ function convertPMTableCell(node, documentCounts, styleResolver = null) {
|
|
|
3298
3421
|
} else if (contentNode.type.name === "table") {
|
|
3299
3422
|
content.push(convertPMTable(contentNode, documentCounts, styleResolver));
|
|
3300
3423
|
previousStandaloneTextBox = null;
|
|
3424
|
+
} else if (contentNode.type.name === "blockSdt") {
|
|
3425
|
+
content.push(convertPMBlockSdt(contentNode, styleResolver));
|
|
3426
|
+
previousStandaloneTextBox = null;
|
|
3301
3427
|
} else if (contentNode.type.name === "textBox") previousStandaloneTextBox = appendTextBoxBlock(content, contentNode, {
|
|
3302
3428
|
pendingPageBreaks: 0,
|
|
3303
3429
|
previousStandaloneTextBox,
|
|
@@ -16,7 +16,7 @@ import { mergeParagraphFormatting, mergeParagraphTabStops } from "../../utils/pa
|
|
|
16
16
|
import { tableOfContentsStyleLevel } from "../../utils/tableOfContentsStyle.js";
|
|
17
17
|
import { mergeTextFormatting } from "../../utils/textFormattingMerge.js";
|
|
18
18
|
import { emuToPixels, emuToStrokePixels } from "../../utils/units.js";
|
|
19
|
-
import { expectInlineWrapperMarkAttrs } from "../attrs/index.js";
|
|
19
|
+
import { expectInlineWrapperMarkAttrs, expectTrackedChangeMarkAttrs } from "../attrs/index.js";
|
|
20
20
|
import { authoredTransformAttrs } from "../authoredTransformAttrs.js";
|
|
21
21
|
import { setAutospacingBaseValue } from "../autospacingBase.js";
|
|
22
22
|
import { planEmptyRanges } from "../emptyRangeAnchor.js";
|
|
@@ -77,16 +77,17 @@ const createTextBoxGroupIdFactory = () => {
|
|
|
77
77
|
* paragraph's and the hyperlink's — so the next payload field is added once
|
|
78
78
|
* rather than to whichever site the author happened to open.
|
|
79
79
|
*
|
|
80
|
-
* Minted when the run holds a page break
|
|
81
|
-
* rejoined into one `w:r` on save), an
|
|
82
|
-
*
|
|
80
|
+
* Minted when the run holds a page break or multiple content items including
|
|
81
|
+
* an inline atom (the leaves have to be rejoined into one `w:r` on save), an
|
|
82
|
+
* attribute remainder, a `w:rPr` sink, or an authored empty `w:rPr`.
|
|
83
83
|
*/
|
|
84
84
|
const runIdentityMark = (run, nextRunIdentityId) => {
|
|
85
85
|
const payload = {
|
|
86
86
|
preservedAttributes: run.preservedAttributes,
|
|
87
|
-
preserved: run.formatting?.preserved
|
|
87
|
+
preserved: run.formatting?.preserved,
|
|
88
|
+
emptyFormatting: run.formatting !== void 0 && Object.keys(run.formatting).length === 0 ? true : void 0
|
|
88
89
|
};
|
|
89
|
-
if (!runHasPageBreakContent(run) && !hasRunIdentityPayload(payload)) return null;
|
|
90
|
+
if (!runHasPageBreakContent(run) && !runHasMixedContent(run) && !hasRunIdentityPayload(payload)) return null;
|
|
90
91
|
return schema.mark(RUN_IDENTITY_MARK_NAME, runIdentityAttrs(nextRunIdentityId(), payload));
|
|
91
92
|
};
|
|
92
93
|
/** Keep imported hyperlink identity unique across every nested conversion scope. */
|
|
@@ -396,8 +397,8 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
|
|
|
396
397
|
type: "direct"
|
|
397
398
|
}], { ordinaryFormatting: ordinaryDefaultRunFormatting });
|
|
398
399
|
const defaultRunFormatting = defaultToggleCascade.formatting;
|
|
399
|
-
if (extraRunFormatting !== void 0) {
|
|
400
|
-
attrs._tableRunFormatting = extraRunFormatting;
|
|
400
|
+
if (extraRunFormatting !== void 0 || paragraph.content.length > 0) {
|
|
401
|
+
if (extraRunFormatting !== void 0) attrs._tableRunFormatting = extraRunFormatting;
|
|
401
402
|
if (defaultRunFormatting) attrs.defaultTextFormatting = defaultRunFormatting;
|
|
402
403
|
else delete attrs.defaultTextFormatting;
|
|
403
404
|
}
|
|
@@ -486,6 +487,7 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
|
|
|
486
487
|
nextRunIdentityId
|
|
487
488
|
});
|
|
488
489
|
if (linkNodes.length === 0) {
|
|
490
|
+
const emptyWrapperStacks = emptyInlineWrapperStacks(content.children);
|
|
489
491
|
emptyHyperlinks ??= [];
|
|
490
492
|
emptyHyperlinks.push({
|
|
491
493
|
offset: inlineOffset,
|
|
@@ -495,7 +497,8 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
|
|
|
495
497
|
...content.rId !== void 0 ? { rId: content.rId } : {},
|
|
496
498
|
...content.target !== void 0 ? { target: content.target } : {},
|
|
497
499
|
...content.history !== void 0 ? { history: content.history } : {},
|
|
498
|
-
...content.docLocation !== void 0 ? { docLocation: content.docLocation } : {}
|
|
500
|
+
...content.docLocation !== void 0 ? { docLocation: content.docLocation } : {},
|
|
501
|
+
...emptyWrapperStacks.length === 0 ? {} : { _docxEmptyWrapperStacks: emptyWrapperStacks }
|
|
499
502
|
});
|
|
500
503
|
break;
|
|
501
504
|
}
|
|
@@ -604,13 +607,21 @@ function anchorPointComment(nodes, commentId) {
|
|
|
604
607
|
* and it is what lets the save leg hoist a revision covering all of them back
|
|
605
608
|
* around the control instead of losing it.
|
|
606
609
|
*/
|
|
607
|
-
const withTrackedRunMark = (node, mark) => {
|
|
608
|
-
if (node.marks.some(({ type }) => type.name === "insertion" || type.name === "deletion")) return node;
|
|
610
|
+
const withTrackedRunMark = (node, mark, ancestor) => {
|
|
609
611
|
if (node.type.name === "sdt") {
|
|
610
612
|
const marked = [];
|
|
611
|
-
for (let index = 0; index < node.childCount; index += 1) marked.push(withTrackedRunMark(node.child(index), mark));
|
|
613
|
+
for (let index = 0; index < node.childCount; index += 1) marked.push(withTrackedRunMark(node.child(index), mark, ancestor));
|
|
612
614
|
return recreateProseNodeWithParagraphPropertySource(node, { content: marked });
|
|
613
615
|
}
|
|
616
|
+
const nestedMark = node.marks.find(({ type }) => type.name === "insertion" || type.name === "deletion");
|
|
617
|
+
if (nestedMark) {
|
|
618
|
+
const nestedAttrs = expectTrackedChangeMarkAttrs(nestedMark);
|
|
619
|
+
const updatedMark = schema.mark(nestedMark.type.name, {
|
|
620
|
+
...nestedMark.attrs,
|
|
621
|
+
_docxRevisionAncestors: [ancestor, ...nestedAttrs._docxRevisionAncestors ?? []]
|
|
622
|
+
});
|
|
623
|
+
return node.mark(updatedMark.addToSet(node.marks));
|
|
624
|
+
}
|
|
614
625
|
if (trackedRunInlineAtomDisposition(node) === "outside-wrapper") panic(`Inline atom ${JSON.stringify(node.type.name)} cannot occur in a tracked-run wrapper`);
|
|
615
626
|
if (canCarryTrackedRunMark(node)) return node.mark(mark.addToSet(node.marks));
|
|
616
627
|
return node;
|
|
@@ -650,7 +661,7 @@ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, next
|
|
|
650
661
|
} else if (item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") {
|
|
651
662
|
const nestedMarkType = item.type === "insertion" || item.type === "moveTo" ? "insertion" : "deletion";
|
|
652
663
|
const nestedMoveKind = item.type === "moveFrom" || item.type === "moveTo" ? item.type : null;
|
|
653
|
-
itemNodes.push(...convertTrackedChange(item, nestedMarkType, nextHyperlinkInstanceIndex, nextRunIdentityId, runFormattingResolvers, styleResolver, nestedMoveKind, textBoxAnchors));
|
|
664
|
+
itemNodes.push(...convertTrackedChange(item, nestedMarkType, nextHyperlinkInstanceIndex, nextRunIdentityId, runFormattingResolvers, styleResolver, nestedMoveKind, textBoxAnchors, [...wrappedBy, ...stack]));
|
|
654
665
|
} else if (item.type === "inlineSdt") {
|
|
655
666
|
const sdtNode = convertInlineSdt(item, nextHyperlinkInstanceIndex, nextRunIdentityId, getTrackedRunFormatting, runFormattingResolvers, styleResolver, textBoxAnchors, [...wrappedBy, ...stack]);
|
|
656
667
|
if (sdtNode) itemNodes.push(sdtNode);
|
|
@@ -667,6 +678,7 @@ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, next
|
|
|
667
678
|
id: item.id,
|
|
668
679
|
displacedByCustomXml: item.displacedByCustomXml
|
|
669
680
|
}));
|
|
681
|
+
else if (item.type === "moveFromRangeStart" || item.type === "moveFromRangeEnd" || item.type === "moveToRangeStart" || item.type === "moveToRangeEnd") itemNodes.push(schema.node(MOVE_RANGE_BOUNDARY_NODE_NAME, { marker: item }));
|
|
670
682
|
else if (item.type === "preservedInline") itemNodes.push(preservedInlineNode(item));
|
|
671
683
|
else panic(`Unsupported tracked-run content: ${JSON.stringify(item)}`);
|
|
672
684
|
nodes.push(...withInlineWrapperMark(itemNodes, stack));
|
|
@@ -678,9 +690,19 @@ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, next
|
|
|
678
690
|
utcDate: change.info.utcDate?.value ?? null,
|
|
679
691
|
initials: change.info.initials ?? null,
|
|
680
692
|
moveKind,
|
|
693
|
+
_docxOuterWrapperCount: wrappedBy.length,
|
|
681
694
|
...markType === "deletion" ? { _historicalFormatting: true } : {}
|
|
682
695
|
});
|
|
683
|
-
|
|
696
|
+
const ancestor = {
|
|
697
|
+
type: change.type,
|
|
698
|
+
revisionId: change.info.id,
|
|
699
|
+
author: change.info.author,
|
|
700
|
+
...change.info.date ? { date: change.info.date } : {},
|
|
701
|
+
...change.info.utcDate ? { utcDate: change.info.utcDate.value } : {},
|
|
702
|
+
...change.info.initials ? { initials: change.info.initials } : {},
|
|
703
|
+
outerWrapperCount: wrappedBy.length
|
|
704
|
+
};
|
|
705
|
+
return nodes.map((node) => withTrackedRunMark(node, mark, ancestor));
|
|
684
706
|
}
|
|
685
707
|
function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOverlay) {
|
|
686
708
|
const formatting = paragraph.formatting;
|
|
@@ -1035,6 +1057,7 @@ function blockHasMeaningfulContent(block) {
|
|
|
1035
1057
|
if (block.type === "preservedBlock") return true;
|
|
1036
1058
|
if (block.type === "bookmarkStart" || block.type === "bookmarkEnd") return true;
|
|
1037
1059
|
if (block.type === "table") return block.rows.some((row) => row.cells.some((cell) => tableCellHasMeaningfulContent(cell)));
|
|
1060
|
+
if (block.type === "blockSdt") return true;
|
|
1038
1061
|
return block.content.some(paragraphContentHasMeaningfulContent);
|
|
1039
1062
|
}
|
|
1040
1063
|
function paragraphContentHasMeaningfulContent(content) {
|
|
@@ -1394,28 +1417,35 @@ function convertTableCell({ cell, styleResolver, context, isHeader, gridWidthPer
|
|
|
1394
1417
|
}
|
|
1395
1418
|
if (preserveVMergeRestart) attrs._preserveVMergeRestart = true;
|
|
1396
1419
|
if (vMergeContinuationCells && vMergeContinuationCells.length > 0) attrs._docxVMergeContinuationCells = transportTableCellsWithParagraphPropertySources(vMergeContinuationCells);
|
|
1397
|
-
const
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1420
|
+
const convertCellBlocks = (blocks) => {
|
|
1421
|
+
const nodes = [];
|
|
1422
|
+
for (const block of blocks) switch (block.type) {
|
|
1423
|
+
case "paragraph":
|
|
1424
|
+
nodes.push(...convertParagraphWithTextBoxes(block, styleResolver, {
|
|
1425
|
+
textBoxGroupId: context.nextTextBoxGroupId(),
|
|
1426
|
+
context,
|
|
1427
|
+
...conditionalStyle?.rPr !== void 0 ? { extraRunFormatting: conditionalStyle.rPr } : {},
|
|
1428
|
+
...conditionalStyle?.pPr !== void 0 ? { tableParagraphOverlay: conditionalStyle.pPr } : {}
|
|
1429
|
+
}));
|
|
1430
|
+
break;
|
|
1431
|
+
case "table":
|
|
1432
|
+
nodes.push(convertTable(block, styleResolver, context));
|
|
1433
|
+
break;
|
|
1434
|
+
case "blockSdt":
|
|
1435
|
+
nodes.push(convertBlockSdt(block, convertCellBlocks));
|
|
1436
|
+
break;
|
|
1437
|
+
case "preservedBlock":
|
|
1438
|
+
nodes.push(convertPreservedBlock(block));
|
|
1439
|
+
break;
|
|
1440
|
+
case "bookmarkStart":
|
|
1441
|
+
case "bookmarkEnd":
|
|
1442
|
+
nodes.push(convertBlockBookmarkBoundary(block));
|
|
1443
|
+
break;
|
|
1444
|
+
default: panic(`Unsupported table cell content: ${JSON.stringify(block)}`);
|
|
1445
|
+
}
|
|
1446
|
+
return nodes;
|
|
1447
|
+
};
|
|
1448
|
+
const contentNodes = convertCellBlocks(cell.content);
|
|
1419
1449
|
if (contentNodes.length === 0) contentNodes.push(schema.node("paragraph", {}, []));
|
|
1420
1450
|
const nodeType = isHeader ? "tableHeader" : "tableCell";
|
|
1421
1451
|
return schema.node(nodeType, attrs, contentNodes);
|
|
@@ -1527,27 +1557,32 @@ const withInlineWrapperStacks = (content, stack = []) => content.flatMap((item)
|
|
|
1527
1557
|
content: item,
|
|
1528
1558
|
stack
|
|
1529
1559
|
}]);
|
|
1530
|
-
/**
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
* wrapper would be the one lost.
|
|
1538
|
-
*
|
|
1539
|
-
* A node that holds its own leaves, a content control, is marked here as the
|
|
1540
|
-
* one node it is; its leaves were marked with the whole enclosing stack when
|
|
1541
|
-
* it was built, because the painter reads the wrapper off the leaf.
|
|
1542
|
-
*/
|
|
1543
|
-
const withInlineWrapperMark = (nodes, stack) => {
|
|
1560
|
+
/** Wrapper nests with no leaf to carry their stack as a ProseMirror mark. */
|
|
1561
|
+
const emptyInlineWrapperStacks = (content, stack = []) => content.flatMap((item) => {
|
|
1562
|
+
if (item.type !== "inlineWrapper") return [];
|
|
1563
|
+
const nested = [...stack, inlineWrapperLayer(item)];
|
|
1564
|
+
return item.content.length === 0 ? [nested] : emptyInlineWrapperStacks(item.content, nested);
|
|
1565
|
+
});
|
|
1566
|
+
const withInlineWrapperMark = (nodes, stack, origin) => {
|
|
1544
1567
|
const markType = schema.marks["inlineWrapper"];
|
|
1545
1568
|
if (stack.length === 0 || !markType) return nodes;
|
|
1546
1569
|
return nodes.map((node) => {
|
|
1547
|
-
if (!node.
|
|
1570
|
+
if (!node.isInline) return node;
|
|
1548
1571
|
const inner = node.marks.find((mark) => mark.type === markType);
|
|
1549
|
-
const
|
|
1550
|
-
|
|
1572
|
+
const innerAttrs = inner === void 0 ? void 0 : expectInlineWrapperMarkAttrs(inner);
|
|
1573
|
+
const layers = innerAttrs === void 0 ? stack : [...stack, ...innerAttrs.stack];
|
|
1574
|
+
const inheritedOrigin = typeof innerAttrs?._docxHyperlinkIndex !== "number" || typeof innerAttrs._docxInsideHyperlinkStackStart !== "number" ? void 0 : {
|
|
1575
|
+
hyperlinkIndex: innerAttrs._docxHyperlinkIndex,
|
|
1576
|
+
stackStart: stack.length + innerAttrs._docxInsideHyperlinkStackStart
|
|
1577
|
+
};
|
|
1578
|
+
const provenance = origin ?? inheritedOrigin;
|
|
1579
|
+
return node.mark(markType.create({
|
|
1580
|
+
stack: layers,
|
|
1581
|
+
...provenance === void 0 ? {} : {
|
|
1582
|
+
_docxHyperlinkIndex: provenance.hyperlinkIndex,
|
|
1583
|
+
_docxInsideHyperlinkStackStart: provenance.stackStart
|
|
1584
|
+
}
|
|
1585
|
+
}).addToSet(node.marks));
|
|
1551
1586
|
});
|
|
1552
1587
|
};
|
|
1553
1588
|
/**
|
|
@@ -1570,9 +1605,17 @@ function convertMathEquation(math) {
|
|
|
1570
1605
|
function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextRunIdentityId, getInheritedRunFormatting, trackedRunFormattingResolvers, styleResolver, textBoxAnchors, wrappedBy = []) {
|
|
1571
1606
|
const props = sdt.properties;
|
|
1572
1607
|
const inlineNodes = [];
|
|
1573
|
-
|
|
1608
|
+
const stacked = withInlineWrapperStacks(sdt.content, wrappedBy);
|
|
1609
|
+
const emptyRanges = planEmptyRanges(stacked.map(({ content }) => content));
|
|
1610
|
+
for (const [index, { content, stack }] of stacked.entries()) {
|
|
1574
1611
|
if (!isInlineSdtContent(content)) continue;
|
|
1575
1612
|
const itemNodes = [];
|
|
1613
|
+
const anchored = emptyRanges.anchorAt.get(index);
|
|
1614
|
+
if (anchored) {
|
|
1615
|
+
inlineNodes.push(...withInlineWrapperMark([schema.node(RANGE_ANCHOR_NODE_NAME, anchored)], stack));
|
|
1616
|
+
continue;
|
|
1617
|
+
}
|
|
1618
|
+
if (emptyRanges.closedAt.has(index)) continue;
|
|
1576
1619
|
switch (content.type) {
|
|
1577
1620
|
case "run":
|
|
1578
1621
|
itemNodes.push(...convertRun(content, getInheritedRunFormatting(content.formatting), nextRunIdentityId, styleResolver, textBoxAnchors));
|
|
@@ -1633,6 +1676,12 @@ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextRunIdentityId, ge
|
|
|
1633
1676
|
displacedByCustomXml: content.displacedByCustomXml
|
|
1634
1677
|
}));
|
|
1635
1678
|
break;
|
|
1679
|
+
case "moveFromRangeStart":
|
|
1680
|
+
case "moveFromRangeEnd":
|
|
1681
|
+
case "moveToRangeStart":
|
|
1682
|
+
case "moveToRangeEnd":
|
|
1683
|
+
itemNodes.push(schema.node(MOVE_RANGE_BOUNDARY_NODE_NAME, { marker: content }));
|
|
1684
|
+
break;
|
|
1636
1685
|
case "preservedInline":
|
|
1637
1686
|
itemNodes.push(preservedInlineNode(content));
|
|
1638
1687
|
break;
|
|
@@ -1661,6 +1710,7 @@ function convertRun(run, resolvedStyleFormatting, nextRunIdentityId, styleResolv
|
|
|
1661
1710
|
return nodes;
|
|
1662
1711
|
}
|
|
1663
1712
|
const runHasPageBreakContent = (run) => run.content.some((content) => content.type === "break" && content.breakType === "page");
|
|
1713
|
+
const runHasMixedContent = (run) => run.content.length > 1 && run.content.some((content) => content.type !== "text");
|
|
1664
1714
|
/**
|
|
1665
1715
|
* Whether a field's result holds an explicit page break.
|
|
1666
1716
|
*
|
|
@@ -2331,7 +2381,10 @@ function convertHyperlink(hyperlink, { getInheritedRunFormatting, styleResolver,
|
|
|
2331
2381
|
}
|
|
2332
2382
|
default: break;
|
|
2333
2383
|
}
|
|
2334
|
-
nodes.push(...withInlineWrapperMark(childNodes, stack
|
|
2384
|
+
nodes.push(...withInlineWrapperMark(childNodes, stack, {
|
|
2385
|
+
hyperlinkIndex,
|
|
2386
|
+
stackStart: 0
|
|
2387
|
+
}));
|
|
2335
2388
|
}
|
|
2336
2389
|
return nodes;
|
|
2337
2390
|
}
|