@beyondwork/docx-react-component 1.0.120 → 1.0.122
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/api/public-types.cjs +1713 -55
- package/dist/api/public-types.d.cts +2 -2
- package/dist/api/public-types.d.ts +2 -2
- package/dist/api/public-types.js +6 -6
- package/dist/api/v3.cjs +4958 -406
- package/dist/api/v3.d.cts +3 -3
- package/dist/api/v3.d.ts +3 -3
- package/dist/api/v3.js +14 -14
- package/dist/{canonical-document-fNawStsc.d.cts → canonical-document-ByIqTd4s.d.cts} +9 -1
- package/dist/{canonical-document-fNawStsc.d.ts → canonical-document-ByIqTd4s.d.ts} +9 -1
- package/dist/{chunk-5RNMPLXU.js → chunk-37SEJQ3G.js} +4 -4
- package/dist/{chunk-FXGQM2JB.js → chunk-3OFSP2IX.js} +11 -5
- package/dist/{chunk-U5BSQXF4.js → chunk-3OHVK2D6.js} +70 -12
- package/dist/{chunk-AUQDC5BD.js → chunk-3TUQCHYT.js} +101 -2
- package/dist/{chunk-SJSMYEMU.js → chunk-B4YHWFE3.js} +3 -3
- package/dist/{chunk-XC56YLIS.js → chunk-C2LWJ4CZ.js} +4 -0
- package/dist/{chunk-VDIUVT46.js → chunk-CX42VC67.js} +1 -1
- package/dist/{chunk-KCHEAX4Z.js → chunk-EMDH4IQN.js} +148 -70
- package/dist/{chunk-TMQGWF7R.js → chunk-G3B2OBCZ.js} +352 -17
- package/dist/{chunk-VCL5MJMZ.js → chunk-GON2DNTE.js} +149 -28
- package/dist/{chunk-WVZX4NYG.js → chunk-GZW2ERUO.js} +601 -47
- package/dist/{chunk-WDNEPRFW.js → chunk-ICX54W4U.js} +1 -1
- package/dist/{chunk-FIGWJ43K.js → chunk-IT2DK3A7.js} +1883 -90
- package/dist/{chunk-2ZWFQ74R.js → chunk-OBCP6VTG.js} +1 -1
- package/dist/{chunk-FLNQY74K.js → chunk-OYGMRRR7.js} +1 -1
- package/dist/{chunk-MPYYBRVN.js → chunk-PCXTMEGY.js} +782 -124
- package/dist/{chunk-4JNUMMM7.js → chunk-PGGPPZ65.js} +17 -2
- package/dist/{chunk-KHZNNBTN.js → chunk-QFU7ZOAD.js} +43 -39
- package/dist/{chunk-4ZNQFWFM.js → chunk-QIO6V46H.js} +84 -4
- package/dist/{chunk-IQ2VJEF6.js → chunk-QNGJRZ2D.js} +1 -1
- package/dist/{chunk-BM5NSDII.js → chunk-S4ANOS2M.js} +2 -2
- package/dist/{chunk-AQA7OZ2R.js → chunk-TFSXOIAI.js} +959 -43
- package/dist/{chunk-NQZUGMLW.js → chunk-TMU7JMXX.js} +184 -32
- package/dist/{chunk-KD5K5XIA.js → chunk-UHQOUTAX.js} +568 -88
- package/dist/{chunk-327AIUXL.js → chunk-UWDWGQH5.js} +11 -4
- package/dist/{chunk-BBB4GSDB.js → chunk-XVFENXLK.js} +2 -2
- package/dist/{chunk-MUEN2WOG.js → chunk-ZKSDVHGH.js} +6 -3
- package/dist/compare.cjs +17 -2
- package/dist/compare.d.cts +1 -1
- package/dist/compare.d.ts +1 -1
- package/dist/compare.js +3 -3
- package/dist/core/commands/formatting-commands.d.cts +2 -2
- package/dist/core/commands/formatting-commands.d.ts +2 -2
- package/dist/core/commands/image-commands.cjs +814 -45
- package/dist/core/commands/image-commands.d.cts +2 -2
- package/dist/core/commands/image-commands.d.ts +2 -2
- package/dist/core/commands/image-commands.js +8 -8
- package/dist/core/commands/section-layout-commands.d.cts +2 -2
- package/dist/core/commands/section-layout-commands.d.ts +2 -2
- package/dist/core/commands/style-commands.d.cts +2 -2
- package/dist/core/commands/style-commands.d.ts +2 -2
- package/dist/core/commands/table-structure-commands.cjs +750 -42
- package/dist/core/commands/table-structure-commands.d.cts +2 -2
- package/dist/core/commands/table-structure-commands.d.ts +2 -2
- package/dist/core/commands/table-structure-commands.js +6 -6
- package/dist/core/commands/text-commands.cjs +910 -57
- package/dist/core/commands/text-commands.d.cts +2 -2
- package/dist/core/commands/text-commands.d.ts +2 -2
- package/dist/core/commands/text-commands.js +8 -8
- package/dist/core/selection/mapping.d.cts +2 -2
- package/dist/core/selection/mapping.d.ts +2 -2
- package/dist/core/state/editor-state.cjs +17 -2
- package/dist/core/state/editor-state.d.cts +2 -2
- package/dist/core/state/editor-state.d.ts +2 -2
- package/dist/core/state/editor-state.js +2 -2
- package/dist/index.cjs +6203 -625
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +299 -67
- package/dist/io/docx-session.cjs +354 -102
- package/dist/io/docx-session.d.cts +4 -4
- package/dist/io/docx-session.d.ts +4 -4
- package/dist/io/docx-session.js +5 -5
- package/dist/legal.cjs +183 -31
- package/dist/legal.d.cts +1 -1
- package/dist/legal.d.ts +1 -1
- package/dist/legal.js +3 -3
- package/dist/{loader-CaohrhNl.d.ts → loader-BF8ju_LK.d.ts} +22 -4
- package/dist/{loader-BpCyGnZl.d.cts → loader-g54WRvj1.d.cts} +22 -4
- package/dist/{public-types-Dpch9JG0.d.cts → public-types-D_y4Ptcj.d.cts} +747 -21
- package/dist/{public-types-C948HNVF.d.ts → public-types-Dl1jiWjk.d.ts} +747 -21
- package/dist/public-types.cjs +1713 -55
- package/dist/public-types.d.cts +2 -2
- package/dist/public-types.d.ts +2 -2
- package/dist/public-types.js +6 -6
- package/dist/runtime/collab.cjs +4 -0
- package/dist/runtime/collab.d.cts +3 -3
- package/dist/runtime/collab.d.ts +3 -3
- package/dist/runtime/collab.js +2 -2
- package/dist/runtime/document-runtime.cjs +3699 -507
- package/dist/runtime/document-runtime.d.cts +2 -2
- package/dist/runtime/document-runtime.d.ts +2 -2
- package/dist/runtime/document-runtime.js +18 -18
- package/dist/{session-Dqg17V3s.d.ts → session-C1EPAkcI.d.ts} +3 -3
- package/dist/{session-BlXE5zxz.d.cts → session-D15QOO0Q.d.cts} +3 -3
- package/dist/session.cjs +951 -104
- package/dist/session.d.cts +5 -5
- package/dist/session.d.ts +5 -5
- package/dist/session.js +10 -8
- package/dist/tailwind.cjs +1752 -91
- package/dist/tailwind.d.cts +2 -2
- package/dist/tailwind.d.ts +2 -2
- package/dist/tailwind.js +10 -10
- package/dist/{types-C9vZVpKy.d.cts → types-BoSRp2Vg.d.cts} +2 -2
- package/dist/{types-B1tlF1bq.d.ts → types-DEvRwq9C.d.ts} +2 -2
- package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +3 -3
- package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +3 -3
- package/dist/ui-tailwind/editor-surface/search-plugin.js +7 -7
- package/dist/ui-tailwind/theme/editor-theme.css +5 -5
- package/dist/ui-tailwind.cjs +1752 -91
- package/dist/ui-tailwind.d.cts +8 -8
- package/dist/ui-tailwind.d.ts +8 -8
- package/dist/ui-tailwind.js +10 -10
- package/package.json +17 -5
- package/dist/ui-tailwind/theme/tokens.css +0 -382
|
@@ -7,27 +7,27 @@ import {
|
|
|
7
7
|
resolveSectionForStoryTarget,
|
|
8
8
|
searchSecondaryStories,
|
|
9
9
|
searchSurfaceBlocks
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-G3B2OBCZ.js";
|
|
11
11
|
import {
|
|
12
12
|
createEditorSurfaceSnapshot,
|
|
13
13
|
createFormattingContext,
|
|
14
14
|
resolveTableStyleResolution
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-3TUQCHYT.js";
|
|
16
16
|
import {
|
|
17
17
|
createSelectionSnapshot
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-OYGMRRR7.js";
|
|
19
19
|
import {
|
|
20
20
|
normalizeParsedTextDocument
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-UWDWGQH5.js";
|
|
22
22
|
import {
|
|
23
23
|
buildFieldRegistry,
|
|
24
24
|
parseMainDocumentXml,
|
|
25
25
|
parseTocLevelRange
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-TMU7JMXX.js";
|
|
27
27
|
import {
|
|
28
28
|
collectEditableTargetRefs,
|
|
29
29
|
validateEditableTargetRef
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-TFSXOIAI.js";
|
|
31
31
|
import {
|
|
32
32
|
serializeMainDocument
|
|
33
33
|
} from "./chunk-EB6M3GE6.js";
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
} from "./chunk-UFVDIR2C.js";
|
|
37
37
|
import {
|
|
38
38
|
createPublicRangeAnchor
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-PGGPPZ65.js";
|
|
40
40
|
import {
|
|
41
41
|
MAIN_STORY_TARGET,
|
|
42
42
|
storyTargetsEqual
|
|
@@ -372,75 +372,83 @@ function deriveWorkflowEditableTargetBlockerFacts(input) {
|
|
|
372
372
|
(input.targetRanges ?? []).map((range) => [range.targetKey, range])
|
|
373
373
|
);
|
|
374
374
|
const currentTargets = input.currentTargets ? new Map(input.currentTargets.map((target) => [target.targetKey, target])) : null;
|
|
375
|
-
const auditOperations =
|
|
376
|
-
(input.auditIntents ?? []).map((intent) => [intent.targetKey, intent.operation])
|
|
377
|
-
);
|
|
375
|
+
const auditOperations = auditOperationsByTarget(input.auditIntents);
|
|
378
376
|
for (const target of input.targets) {
|
|
379
|
-
const
|
|
377
|
+
const targetAuditOperations = auditOperationsForTarget(target, auditOperations);
|
|
380
378
|
if (input.activeStoryKey !== void 0 && input.activeStoryKey !== null && target.storyKey !== input.activeStoryKey) {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
379
|
+
for (const auditOperation of targetAuditOperations) {
|
|
380
|
+
facts.push({
|
|
381
|
+
...baseFact(target),
|
|
382
|
+
blocker: "wrong-story",
|
|
383
|
+
refusalId: "editable_target_wrong_story",
|
|
384
|
+
source: "target-resolution",
|
|
385
|
+
audit: auditFact(target, "wrong-story", "editable_target_wrong_story", auditOperation),
|
|
386
|
+
message: `Editable target belongs to story "${target.storyKey}", not active story "${input.activeStoryKey}".`
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
389
|
}
|
|
390
390
|
const currentTarget = currentTargets?.get(target.targetKey);
|
|
391
391
|
if (currentTargets && (!currentTarget || !sameResolvedTarget(target, currentTarget))) {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
392
|
+
for (const auditOperation of targetAuditOperations) {
|
|
393
|
+
facts.push({
|
|
394
|
+
...baseFact(target),
|
|
395
|
+
blocker: "stale-ref",
|
|
396
|
+
refusalId: "editable_target_stale",
|
|
397
|
+
source: "target-resolution",
|
|
398
|
+
audit: auditFact(target, "stale-ref", "editable_target_stale", auditOperation),
|
|
399
|
+
message: "Editable target ref is stale for the current canonical document."
|
|
400
|
+
});
|
|
401
|
+
}
|
|
400
402
|
}
|
|
401
403
|
for (const blocker of target.posture.blockers) {
|
|
402
404
|
const refusalId = refusalIdForPostureBlocker(target, blocker);
|
|
403
405
|
const message = messageForPostureBlocker(blocker);
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
source: "editable-target-posture",
|
|
409
|
-
audit: auditFact(
|
|
410
|
-
target,
|
|
411
|
-
auditCategoryForPostureBlocker(target, blocker),
|
|
406
|
+
for (const auditOperation of targetAuditOperations) {
|
|
407
|
+
facts.push({
|
|
408
|
+
...baseFact(target),
|
|
409
|
+
blocker,
|
|
412
410
|
refusalId,
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
411
|
+
source: "editable-target-posture",
|
|
412
|
+
audit: auditFact(
|
|
413
|
+
target,
|
|
414
|
+
auditCategoryForPostureBlocker(target, blocker),
|
|
415
|
+
refusalId,
|
|
416
|
+
auditOperation
|
|
417
|
+
),
|
|
418
|
+
...message !== void 0 ? { message } : {}
|
|
419
|
+
});
|
|
420
|
+
}
|
|
417
421
|
}
|
|
418
422
|
const range = targetRanges.get(target.targetKey);
|
|
419
423
|
const protectedRange = range && input.protectionSnapshot ? findProtectionBlocker(input.protectionSnapshot, range) : null;
|
|
420
424
|
if (protectedRange) {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
425
|
+
for (const auditOperation of targetAuditOperations) {
|
|
426
|
+
facts.push({
|
|
427
|
+
...baseFact(target),
|
|
428
|
+
blocker: "protected-range",
|
|
429
|
+
refusalId: "protected_range",
|
|
430
|
+
source: "protection-snapshot",
|
|
431
|
+
audit: auditFact(target, "protected-content", "protected_range", auditOperation),
|
|
432
|
+
message: protectedRange.enforcementReason,
|
|
433
|
+
rangeId: protectedRange.rangeId
|
|
434
|
+
});
|
|
435
|
+
}
|
|
430
436
|
}
|
|
431
437
|
for (const reason of input.guard?.blockedReasons ?? []) {
|
|
432
438
|
const mapped = mapGuardReason(reason);
|
|
433
439
|
if (!mapped) continue;
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
440
|
+
for (const auditOperation of targetAuditOperations) {
|
|
441
|
+
facts.push({
|
|
442
|
+
...baseFact(target),
|
|
443
|
+
blocker: mapped.blocker,
|
|
444
|
+
refusalId: reason.code,
|
|
445
|
+
source: "interaction-guard",
|
|
446
|
+
audit: auditFact(target, mapped.auditCategory, reason.code, auditOperation),
|
|
447
|
+
message: reason.message,
|
|
448
|
+
...reason.scopeId !== void 0 ? { scopeId: reason.scopeId } : {},
|
|
449
|
+
...reason.workItemId !== void 0 ? { workItemId: reason.workItemId } : {}
|
|
450
|
+
});
|
|
451
|
+
}
|
|
444
452
|
}
|
|
445
453
|
}
|
|
446
454
|
return Object.freeze(dedupeFacts(facts).sort(compareFacts));
|
|
@@ -453,6 +461,22 @@ function baseFact(target) {
|
|
|
453
461
|
blockPath: target.blockPath
|
|
454
462
|
};
|
|
455
463
|
}
|
|
464
|
+
function auditOperationsByTarget(auditIntents) {
|
|
465
|
+
const byTarget = /* @__PURE__ */ new Map();
|
|
466
|
+
for (const intent of auditIntents ?? []) {
|
|
467
|
+
const operations = byTarget.get(intent.targetKey);
|
|
468
|
+
if (!operations) {
|
|
469
|
+
byTarget.set(intent.targetKey, [intent.operation]);
|
|
470
|
+
} else if (!operations.includes(intent.operation)) {
|
|
471
|
+
operations.push(intent.operation);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return byTarget;
|
|
475
|
+
}
|
|
476
|
+
function auditOperationsForTarget(target, auditOperations) {
|
|
477
|
+
const operations = auditOperations.get(target.targetKey);
|
|
478
|
+
return operations && operations.length > 0 ? operations : [auditOperationForTarget(target)];
|
|
479
|
+
}
|
|
456
480
|
function findProtectionBlocker(protection, targetRange) {
|
|
457
481
|
const enforcedRanges = protection.ranges.filter(
|
|
458
482
|
(range) => range.enforced && typeof range.start === "number" && typeof range.end === "number"
|
|
@@ -553,7 +577,7 @@ function auditOperationForTarget(target) {
|
|
|
553
577
|
case "field":
|
|
554
578
|
return target.field?.fieldFamily === "TOC" ? "toc-refresh" : "field-update";
|
|
555
579
|
case "link-bookmark":
|
|
556
|
-
return target.kind === "bookmark-anchor" ? "bookmark-update" : "hyperlink-update";
|
|
580
|
+
return target.kind === "bookmark-anchor" || target.kind === "bookmark-content-range" ? "bookmark-update" : "hyperlink-update";
|
|
557
581
|
case "comment-revision":
|
|
558
582
|
return target.kind === "revision-anchor" ? "revision-action" : "comment-action";
|
|
559
583
|
case "metadata":
|
|
@@ -567,7 +591,7 @@ function auditOperationForTarget(target) {
|
|
|
567
591
|
}
|
|
568
592
|
}
|
|
569
593
|
function sameResolvedTarget(left, right) {
|
|
570
|
-
return left.kind === right.kind && left.storyKey === right.storyKey && left.blockPath === right.blockPath && left.leafPath === right.leafPath && left.commandFamily === right.commandFamily && left.editability === right.editability && stableJson(left.sourceRef) === stableJson(right.sourceRef) && stableJson(left.staleCheck) === stableJson(right.staleCheck);
|
|
594
|
+
return left.kind === right.kind && left.storyKey === right.storyKey && left.blockPath === right.blockPath && left.leafPath === right.leafPath && left.commandFamily === right.commandFamily && left.editability === right.editability && stableJson(left.sourceRef) === stableJson(right.sourceRef) && stableJson(left.staleCheck) === stableJson(right.staleCheck) && stableJson(left.editableOwner) === stableJson(right.editableOwner);
|
|
571
595
|
}
|
|
572
596
|
function stableJson(value) {
|
|
573
597
|
if (Array.isArray(value)) {
|
|
@@ -2003,7 +2027,8 @@ function compileTableScope(entry, options = {}) {
|
|
|
2003
2027
|
classifications: entry.classifications,
|
|
2004
2028
|
content: {
|
|
2005
2029
|
text: summary,
|
|
2006
|
-
excerpt: buildExcerpt(summary)
|
|
2030
|
+
excerpt: buildExcerpt(summary),
|
|
2031
|
+
authority: "structural-summary"
|
|
2007
2032
|
},
|
|
2008
2033
|
formatting,
|
|
2009
2034
|
layout: {},
|
|
@@ -2045,7 +2070,9 @@ function compileTableCellScope(entry, options = {}) {
|
|
|
2045
2070
|
classifications: entry.classifications,
|
|
2046
2071
|
content: {
|
|
2047
2072
|
text: summary,
|
|
2048
|
-
excerpt: buildExcerpt(summary)
|
|
2073
|
+
excerpt: buildExcerpt(summary),
|
|
2074
|
+
authority: "structural-summary",
|
|
2075
|
+
editableTextPath: "evidence.editableTargets.entries[].readback"
|
|
2049
2076
|
},
|
|
2050
2077
|
formatting,
|
|
2051
2078
|
layout: {},
|
|
@@ -2077,7 +2104,8 @@ function compileTableRowScope(entry, options = {}) {
|
|
|
2077
2104
|
classifications: entry.classifications,
|
|
2078
2105
|
content: {
|
|
2079
2106
|
text: summary,
|
|
2080
|
-
excerpt: buildExcerpt(summary)
|
|
2107
|
+
excerpt: buildExcerpt(summary),
|
|
2108
|
+
authority: "structural-summary"
|
|
2081
2109
|
},
|
|
2082
2110
|
formatting,
|
|
2083
2111
|
layout: {},
|
|
@@ -2918,6 +2946,22 @@ function supported(reason, warnings = []) {
|
|
|
2918
2946
|
...hasWarnings ? { warnings: freezeList(warnings) } : {}
|
|
2919
2947
|
};
|
|
2920
2948
|
}
|
|
2949
|
+
function supportedCommand(reason, entries, warnings = []) {
|
|
2950
|
+
const verdict = supported(reason, warnings);
|
|
2951
|
+
const actionHandles = freezeUnique(
|
|
2952
|
+
entries.flatMap(
|
|
2953
|
+
(entry) => entry.runtimeCommand.actionHandle ? [entry.runtimeCommand.actionHandle] : []
|
|
2954
|
+
)
|
|
2955
|
+
);
|
|
2956
|
+
const intents = freezeUnique(
|
|
2957
|
+
entries.flatMap((entry) => [...entry.runtimeCommand.intents])
|
|
2958
|
+
);
|
|
2959
|
+
return {
|
|
2960
|
+
...verdict,
|
|
2961
|
+
...actionHandles.length > 0 ? { actionHandles } : {},
|
|
2962
|
+
...intents.length > 0 ? { intents } : {}
|
|
2963
|
+
};
|
|
2964
|
+
}
|
|
2921
2965
|
function unsupported(reason, blockers = [reason], warnings = []) {
|
|
2922
2966
|
return {
|
|
2923
2967
|
supported: false,
|
|
@@ -2959,6 +3003,27 @@ function contentControlBlockers(context) {
|
|
|
2959
3003
|
if (entries.length === 0) return [];
|
|
2960
3004
|
return freezeList(entries.map((entry) => `preserve:content-control:${entry.evidenceId}`));
|
|
2961
3005
|
}
|
|
3006
|
+
function generatedOrLinkedContentBlockers(context) {
|
|
3007
|
+
const blockers = [];
|
|
3008
|
+
for (const entry of context?.editableTargets?.entries ?? []) {
|
|
3009
|
+
if (entry.kind === "field-result-text") {
|
|
3010
|
+
blockers.push("field-generated-text");
|
|
3011
|
+
continue;
|
|
3012
|
+
}
|
|
3013
|
+
if (entry.kind === "bookmark-anchor") {
|
|
3014
|
+
blockers.push("link-bookmark:bookmark-anchor");
|
|
3015
|
+
continue;
|
|
3016
|
+
}
|
|
3017
|
+
if (entry.kind === "hyperlink-text") {
|
|
3018
|
+
blockers.push("link-bookmark:hyperlink-text");
|
|
3019
|
+
continue;
|
|
3020
|
+
}
|
|
3021
|
+
if (entry.commandFamily === "link-bookmark" && entry.runtimeCommand.status !== "supported") {
|
|
3022
|
+
blockers.push(`link-bookmark:${entry.kind}`);
|
|
3023
|
+
}
|
|
3024
|
+
}
|
|
3025
|
+
return freezeUnique(blockers);
|
|
3026
|
+
}
|
|
2962
3027
|
function evidenceWarnings(context) {
|
|
2963
3028
|
const warnings = [];
|
|
2964
3029
|
if (context?.layout) {
|
|
@@ -2991,9 +3056,11 @@ function editableTargetWarnings(context) {
|
|
|
2991
3056
|
[...kinds].sort().map((kind) => `editable-target:${kind}:available`)
|
|
2992
3057
|
);
|
|
2993
3058
|
}
|
|
2994
|
-
function
|
|
2995
|
-
return
|
|
2996
|
-
entries
|
|
3059
|
+
function supportedCommandTargets(context, predicate) {
|
|
3060
|
+
return Object.freeze(
|
|
3061
|
+
[...context?.editableTargets?.entries ?? []].filter(
|
|
3062
|
+
(entry) => entry.runtimeCommand.status === "supported" && predicate(entry)
|
|
3063
|
+
)
|
|
2997
3064
|
);
|
|
2998
3065
|
}
|
|
2999
3066
|
function commandTargetBlockers(entries) {
|
|
@@ -3008,6 +3075,9 @@ function commandTargetBlockers(entries) {
|
|
|
3008
3075
|
}
|
|
3009
3076
|
return freezeUnique(blockers.filter((blocker) => blocker.length > 0));
|
|
3010
3077
|
}
|
|
3078
|
+
function hasRuntimeIntent(entry, intent) {
|
|
3079
|
+
return entry.runtimeCommand.intents.includes(intent);
|
|
3080
|
+
}
|
|
3011
3081
|
function insertCapability(scope, edge, context) {
|
|
3012
3082
|
const guard = guardBlocker(scope);
|
|
3013
3083
|
if (guard) return blocked(guard);
|
|
@@ -3029,10 +3099,26 @@ function insertCapability(scope, edge, context) {
|
|
|
3029
3099
|
function replaceTextCapability(scope, context) {
|
|
3030
3100
|
const guard = guardBlocker(scope);
|
|
3031
3101
|
if (guard) return blocked(guard);
|
|
3102
|
+
if (scope.kind === "list-item") {
|
|
3103
|
+
return blocked(
|
|
3104
|
+
"compile-blocked:list-text:authoritative-readback-required",
|
|
3105
|
+
[
|
|
3106
|
+
"capability:list-item:authoritative-readback-required",
|
|
3107
|
+
"capability:list-text:export-persistent-target-required"
|
|
3108
|
+
]
|
|
3109
|
+
);
|
|
3110
|
+
}
|
|
3032
3111
|
const contentControls = contentControlBlockers(context);
|
|
3033
3112
|
if (contentControls.length > 0) {
|
|
3034
3113
|
return blocked("preserve:content-control", contentControls);
|
|
3035
3114
|
}
|
|
3115
|
+
const generatedOrLinked = generatedOrLinkedContentBlockers(context);
|
|
3116
|
+
if (generatedOrLinked.length > 0) {
|
|
3117
|
+
return blocked(
|
|
3118
|
+
"compile-refused:paragraph:generated-or-linked-content",
|
|
3119
|
+
generatedOrLinked
|
|
3120
|
+
);
|
|
3121
|
+
}
|
|
3036
3122
|
if (!PARAGRAPH_LIKE.has(scope.kind)) {
|
|
3037
3123
|
if (scope.kind === "table-cell") {
|
|
3038
3124
|
if (context?.tableCellTextRange?.status === "ok") {
|
|
@@ -3080,6 +3166,13 @@ function replaceFragmentCapability(scope, context) {
|
|
|
3080
3166
|
if (contentControls.length > 0) {
|
|
3081
3167
|
return blocked("preserve:content-control", contentControls);
|
|
3082
3168
|
}
|
|
3169
|
+
const generatedOrLinked = generatedOrLinkedContentBlockers(context);
|
|
3170
|
+
if (generatedOrLinked.length > 0) {
|
|
3171
|
+
return blocked(
|
|
3172
|
+
"compile-refused:paragraph:generated-or-linked-content",
|
|
3173
|
+
generatedOrLinked
|
|
3174
|
+
);
|
|
3175
|
+
}
|
|
3083
3176
|
if (!PARAGRAPH_LIKE.has(scope.kind)) {
|
|
3084
3177
|
const reason = scope.kind === "scope" && scope.replaceability.reason ? MULTI_PARAGRAPH_REPLACEMENT_REFUSAL : `compile-refused:${scope.kind}`;
|
|
3085
3178
|
return unsupported(
|
|
@@ -3140,14 +3233,38 @@ function taxonomyRefusalCapability(action) {
|
|
|
3140
3233
|
]
|
|
3141
3234
|
);
|
|
3142
3235
|
}
|
|
3236
|
+
function fieldUpdateCapability(context) {
|
|
3237
|
+
const supportedTargets = supportedCommandTargets(
|
|
3238
|
+
context,
|
|
3239
|
+
(entry) => entry.commandFamily === "field" && (entry.runtimeCommand.intents.includes("field-update") || entry.runtimeCommand.intents.includes("toc-refresh"))
|
|
3240
|
+
);
|
|
3241
|
+
if (supportedTargets.length === 0) return taxonomyRefusalCapability("field-update");
|
|
3242
|
+
return supportedCommand(
|
|
3243
|
+
supportedTargets.some((entry) => entry.runtimeCommand.intents.includes("toc-refresh")) ? "compile-supported:field-update:toc-refresh-target" : "compile-supported:field-update:editable-target",
|
|
3244
|
+
supportedTargets
|
|
3245
|
+
);
|
|
3246
|
+
}
|
|
3143
3247
|
function linkEditCapability(context) {
|
|
3144
3248
|
const supportedDisplayTextTarget = context?.editableTargets?.entries.find(
|
|
3145
3249
|
(entry) => entry.kind === "hyperlink-text" && entry.commandFamily === "text-leaf" && entry.runtimeCommand.status === "supported" && entry.runtimeCommand.intents.includes("hyperlink-display-text-edit")
|
|
3146
3250
|
);
|
|
3147
|
-
|
|
3251
|
+
const supportedDestinationTarget = context?.editableTargets?.entries.find(
|
|
3252
|
+
(entry) => entry.kind === "hyperlink-destination" && entry.commandFamily === "link-bookmark" && entry.runtimeCommand.status === "supported" && entry.runtimeCommand.intents.includes("hyperlink-update")
|
|
3253
|
+
);
|
|
3254
|
+
if (!supportedDisplayTextTarget && !supportedDestinationTarget) {
|
|
3148
3255
|
return taxonomyRefusalCapability("link-edit");
|
|
3149
3256
|
}
|
|
3150
|
-
return
|
|
3257
|
+
return supportedCommand(
|
|
3258
|
+
supportedDestinationTarget ? "compile-supported:link-edit:hyperlink-destination" : "compile-supported:link-edit:hyperlink-display-text",
|
|
3259
|
+
supportedDestinationTarget ? [supportedDestinationTarget] : supportedDisplayTextTarget ? [supportedDisplayTextTarget] : []
|
|
3260
|
+
);
|
|
3261
|
+
}
|
|
3262
|
+
function bookmarkEditCapability(context) {
|
|
3263
|
+
const supportedRangeTarget = context?.editableTargets?.entries.find(
|
|
3264
|
+
(entry) => entry.kind === "bookmark-content-range" && entry.commandFamily === "link-bookmark" && entry.runtimeCommand.status === "supported" && entry.runtimeCommand.intents.includes("bookmark-update")
|
|
3265
|
+
);
|
|
3266
|
+
if (!supportedRangeTarget) return taxonomyRefusalCapability("bookmark-edit");
|
|
3267
|
+
return supportedCommand("compile-supported:bookmark-edit:content-range", [supportedRangeTarget]);
|
|
3151
3268
|
}
|
|
3152
3269
|
function tableTextCapability(scope, context) {
|
|
3153
3270
|
const guard = guardBlocker(scope);
|
|
@@ -3159,10 +3276,10 @@ function tableTextCapability(scope, context) {
|
|
|
3159
3276
|
(entry) => entry.runtimeTextCommand.status === "supported" && entry.runtimeCommand.status === "supported" && entry.runtimeCommand.intents.includes("text-leaf-edit")
|
|
3160
3277
|
);
|
|
3161
3278
|
if (supportedTargets.length > 0) {
|
|
3162
|
-
return
|
|
3279
|
+
return supportedCommand(
|
|
3163
3280
|
"compile-supported:table-text:editable-target",
|
|
3281
|
+
supportedTargets,
|
|
3164
3282
|
[
|
|
3165
|
-
...commandSafeTargetWarnings(supportedTargets),
|
|
3166
3283
|
...evidenceWarnings(context)
|
|
3167
3284
|
]
|
|
3168
3285
|
);
|
|
@@ -3203,10 +3320,10 @@ function tableStructureCapability(scope, context) {
|
|
|
3203
3320
|
(entry) => entry.runtimeCommand.status === "supported" && entry.runtimeCommand.intents.includes("table-structure-action")
|
|
3204
3321
|
);
|
|
3205
3322
|
if (supportedTargets.length > 0) {
|
|
3206
|
-
return
|
|
3323
|
+
return supportedCommand(
|
|
3207
3324
|
"compile-supported:table-structure:editable-target",
|
|
3325
|
+
supportedTargets,
|
|
3208
3326
|
[
|
|
3209
|
-
...commandSafeTargetWarnings(supportedTargets),
|
|
3210
3327
|
...tableFormattingWarnings(scope),
|
|
3211
3328
|
...evidenceWarnings(context)
|
|
3212
3329
|
]
|
|
@@ -3288,15 +3405,13 @@ function listTextCapability(scope, context) {
|
|
|
3288
3405
|
(entry) => entry.commandFamily === "text-leaf" && LIST_TEXT_TARGET_KINDS.has(entry.kind) && (entry.relation === "exact-scope" || entry.relation === "descendant-of-scope")
|
|
3289
3406
|
);
|
|
3290
3407
|
const supportedTargets = listTextTargets.filter(
|
|
3291
|
-
(entry) => entry.runtimeTextCommand.status === "supported" && entry.runtimeCommand.status === "supported" && entry
|
|
3408
|
+
(entry) => entry.runtimeTextCommand.status === "supported" && entry.runtimeCommand.status === "supported" && hasRuntimeIntent(entry, "list-text-edit")
|
|
3292
3409
|
);
|
|
3293
3410
|
if (supportedTargets.length > 0) {
|
|
3294
|
-
return
|
|
3411
|
+
return supportedCommand(
|
|
3295
3412
|
"compile-supported:list-text:editable-target",
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
...evidenceWarnings(context)
|
|
3299
|
-
]
|
|
3413
|
+
supportedTargets,
|
|
3414
|
+
evidenceWarnings(context)
|
|
3300
3415
|
);
|
|
3301
3416
|
}
|
|
3302
3417
|
if (listTextTargets.length > 0) {
|
|
@@ -3318,7 +3433,7 @@ function listTextCapability(scope, context) {
|
|
|
3318
3433
|
]
|
|
3319
3434
|
);
|
|
3320
3435
|
}
|
|
3321
|
-
function listStructureCapability(scope) {
|
|
3436
|
+
function listStructureCapability(scope, context) {
|
|
3322
3437
|
if (scope.kind !== "list-item") {
|
|
3323
3438
|
return unsupported(
|
|
3324
3439
|
"compile-unsupported:list-structure:unsupported-target-family",
|
|
@@ -3328,6 +3443,26 @@ function listStructureCapability(scope) {
|
|
|
3328
3443
|
]
|
|
3329
3444
|
);
|
|
3330
3445
|
}
|
|
3446
|
+
const listStructureTargets = (context?.editableTargets?.entries ?? []).filter(
|
|
3447
|
+
(entry) => entry.commandFamily === "text-leaf" && LIST_TEXT_TARGET_KINDS.has(entry.kind) && (entry.relation === "exact-scope" || entry.relation === "descendant-of-scope")
|
|
3448
|
+
);
|
|
3449
|
+
const supportedTargets = listStructureTargets.filter(
|
|
3450
|
+
(entry) => entry.runtimeCommand.status === "supported" && hasRuntimeIntent(entry, "list-structure-action")
|
|
3451
|
+
);
|
|
3452
|
+
if (supportedTargets.length > 0) {
|
|
3453
|
+
return supportedCommand(
|
|
3454
|
+
"compile-supported:list-structure:editable-target",
|
|
3455
|
+
supportedTargets,
|
|
3456
|
+
evidenceWarnings(context)
|
|
3457
|
+
);
|
|
3458
|
+
}
|
|
3459
|
+
if (listStructureTargets.length > 0) {
|
|
3460
|
+
const blockers = commandTargetBlockers(listStructureTargets);
|
|
3461
|
+
return blocked(
|
|
3462
|
+
"compile-blocked:list-structure:target-ref-blocked",
|
|
3463
|
+
blockers.length > 0 ? blockers : ["compile-blocked:list-structure:target-ref-blocked"]
|
|
3464
|
+
);
|
|
3465
|
+
}
|
|
3331
3466
|
return unsupported(
|
|
3332
3467
|
"compile-unsupported:list-structure:no-target-family",
|
|
3333
3468
|
[
|
|
@@ -3348,14 +3483,14 @@ function deriveScopeCapabilities(scope, context = {}) {
|
|
|
3348
3483
|
canApplyFormatting: formattingCapability(scope, context),
|
|
3349
3484
|
canClearFormattingLayer: formattingCapability(scope, context),
|
|
3350
3485
|
canAttachMetadata: metadataCapability(scope),
|
|
3351
|
-
canUpdateField:
|
|
3486
|
+
canUpdateField: fieldUpdateCapability(context),
|
|
3352
3487
|
canEditLink: linkEditCapability(context),
|
|
3353
|
-
canEditBookmark:
|
|
3488
|
+
canEditBookmark: bookmarkEditCapability(context),
|
|
3354
3489
|
canEditTableText: tableTextCapability(scope, context),
|
|
3355
3490
|
canEditTableStructure: tableStructureCapability(scope, context),
|
|
3356
3491
|
canUseTableContinuationEvidence: tableContinuationEvidenceCapability(scope, context),
|
|
3357
3492
|
canEditListText: listTextCapability(scope, context),
|
|
3358
|
-
canEditListStructure: listStructureCapability(scope)
|
|
3493
|
+
canEditListStructure: listStructureCapability(scope, context)
|
|
3359
3494
|
};
|
|
3360
3495
|
}
|
|
3361
3496
|
|
|
@@ -3662,6 +3797,22 @@ function relationForTarget(target, scope, entry) {
|
|
|
3662
3797
|
if (entry?.kind === "revision" && target.kind === "revision-anchor" && target.review?.reviewId === entry.revision.changeId) {
|
|
3663
3798
|
return "exact-scope";
|
|
3664
3799
|
}
|
|
3800
|
+
if (entry?.kind === "field") {
|
|
3801
|
+
if (target.kind === "field-result-text" && target.blockPath === `main/block[${entry.blockIndex}]/inline[${entry.inlineIndex}]`) {
|
|
3802
|
+
return "exact-scope";
|
|
3803
|
+
}
|
|
3804
|
+
if ((target.kind === "field-region-refresh" || target.kind === "toc-region-refresh") && target.field?.canonicalFieldId !== void 0 && target.field.canonicalFieldId === entry.field.canonicalFieldId) {
|
|
3805
|
+
return "exact-scope";
|
|
3806
|
+
}
|
|
3807
|
+
}
|
|
3808
|
+
if (entry && (entry.kind === "paragraph" || entry.kind === "heading" || entry.kind === "list-item")) {
|
|
3809
|
+
if ((target.kind === "field-region-refresh" || target.kind === "toc-region-refresh") && target.field?.canonicalFieldId !== void 0 && paragraphHasFieldId(entry.paragraph, target.field.canonicalFieldId)) {
|
|
3810
|
+
return "descendant-of-scope";
|
|
3811
|
+
}
|
|
3812
|
+
if (target.kind === "bookmark-content-range" && target.link?.bookmarkId !== void 0 && paragraphHasBookmarkId(entry.paragraph, target.link.bookmarkId)) {
|
|
3813
|
+
return "descendant-of-scope";
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3665
3816
|
const parsedTargetPath = parsePath(target.blockPath);
|
|
3666
3817
|
if (!parsedTargetPath) return null;
|
|
3667
3818
|
const targetTokens = parsedTargetPath.tokens;
|
|
@@ -3681,6 +3832,27 @@ function relationForTarget(target, scope, entry) {
|
|
|
3681
3832
|
if (targetTokens.length === scopeTokens.length) return "exact-scope";
|
|
3682
3833
|
return targetInScope ? "descendant-of-scope" : "scope-descendant-of-target";
|
|
3683
3834
|
}
|
|
3835
|
+
function paragraphHasFieldId(paragraph, canonicalFieldId) {
|
|
3836
|
+
return paragraph.children.some(
|
|
3837
|
+
(child) => child.type === "field" && child.canonicalFieldId === canonicalFieldId
|
|
3838
|
+
);
|
|
3839
|
+
}
|
|
3840
|
+
function paragraphHasBookmarkId(paragraph, bookmarkId) {
|
|
3841
|
+
return paragraph.children.some(
|
|
3842
|
+
(child) => (child.type === "bookmark_start" || child.type === "bookmark_end") && child.bookmarkId === bookmarkId
|
|
3843
|
+
);
|
|
3844
|
+
}
|
|
3845
|
+
function commandActionHandleForAddress(commandFamily, address) {
|
|
3846
|
+
return address ? `scope-command:${commandFamily}:${address.addressKey}` : void 0;
|
|
3847
|
+
}
|
|
3848
|
+
function withCommandAction(evidence, target) {
|
|
3849
|
+
if (evidence.status !== "supported" || !target.canonicalAddress) return evidence;
|
|
3850
|
+
return {
|
|
3851
|
+
...evidence,
|
|
3852
|
+
actionHandle: commandActionHandleForAddress(target.commandFamily, target.canonicalAddress),
|
|
3853
|
+
canonicalAddress: target.canonicalAddress
|
|
3854
|
+
};
|
|
3855
|
+
}
|
|
3684
3856
|
function runtimeTextCommandEvidence(target, workflowBlockers) {
|
|
3685
3857
|
const shapeIssues = validateEditableTargetRef(target);
|
|
3686
3858
|
if (shapeIssues.length > 0) {
|
|
@@ -3730,6 +3902,11 @@ var TABLE_TEXT_TARGET_KINDS2 = /* @__PURE__ */ new Set([
|
|
|
3730
3902
|
"nested-table-cell-paragraph-text",
|
|
3731
3903
|
"sdt-table-cell-paragraph-text"
|
|
3732
3904
|
]);
|
|
3905
|
+
var LIST_TEXT_TARGET_KINDS2 = /* @__PURE__ */ new Set([
|
|
3906
|
+
"paragraph-text",
|
|
3907
|
+
"sdt-paragraph-text",
|
|
3908
|
+
"secondary-story-paragraph-text"
|
|
3909
|
+
]);
|
|
3733
3910
|
function tableTextScopeReplacementPosture(target) {
|
|
3734
3911
|
if (target.posture.preserveOnly) {
|
|
3735
3912
|
return {
|
|
@@ -3760,15 +3937,25 @@ function tableTextScopeReplacementPosture(target) {
|
|
|
3760
3937
|
reason: "secondary-story-table-text-target-not-callable-by-scope-replacement"
|
|
3761
3938
|
};
|
|
3762
3939
|
}
|
|
3763
|
-
function runtimeCommandEvidence(target, workflowBlockers, textCommand) {
|
|
3764
|
-
|
|
3940
|
+
function runtimeCommandEvidence(target, workflowBlockers, textCommand, scopeKind) {
|
|
3941
|
+
const shapeIssues = validateEditableTargetRef(target);
|
|
3942
|
+
if (shapeIssues.length > 0) {
|
|
3765
3943
|
return {
|
|
3766
|
-
status:
|
|
3944
|
+
status: "blocked",
|
|
3767
3945
|
commandFamily: target.commandFamily,
|
|
3768
3946
|
intents: commandIntentsForTarget(target),
|
|
3947
|
+
reason: "editable_target_malformed",
|
|
3948
|
+
blockers: Object.freeze(["editable_target_malformed"])
|
|
3949
|
+
};
|
|
3950
|
+
}
|
|
3951
|
+
if (target.commandFamily === "text-leaf") {
|
|
3952
|
+
return withCommandAction({
|
|
3953
|
+
status: textCommand.status,
|
|
3954
|
+
commandFamily: target.commandFamily,
|
|
3955
|
+
intents: commandIntentsForTarget(target, scopeKind),
|
|
3769
3956
|
reason: textCommand.reason,
|
|
3770
3957
|
...textCommand.blockers ? { blockers: textCommand.blockers } : {}
|
|
3771
|
-
};
|
|
3958
|
+
}, target);
|
|
3772
3959
|
}
|
|
3773
3960
|
if (target.commandFamily === "comment-revision") {
|
|
3774
3961
|
const isOpen = target.review?.status === "open";
|
|
@@ -3793,16 +3980,22 @@ function runtimeCommandEvidence(target, workflowBlockers, textCommand) {
|
|
|
3793
3980
|
blockers: Object.freeze(actionableBlockers.map((fact) => fact.blocker))
|
|
3794
3981
|
};
|
|
3795
3982
|
}
|
|
3796
|
-
return {
|
|
3983
|
+
return withCommandAction({
|
|
3797
3984
|
status: "supported",
|
|
3798
3985
|
commandFamily: target.commandFamily,
|
|
3799
3986
|
intents: commandIntentsForTarget(target),
|
|
3800
3987
|
reason: commentRevisionCommandReason(target, true)
|
|
3801
|
-
};
|
|
3988
|
+
}, target);
|
|
3802
3989
|
}
|
|
3803
3990
|
if (target.commandFamily === "table-structure") {
|
|
3804
3991
|
return tableStructureCommandEvidence(target, workflowBlockers);
|
|
3805
3992
|
}
|
|
3993
|
+
if (target.commandFamily === "field") {
|
|
3994
|
+
return generatedFieldCommandEvidence(target, workflowBlockers);
|
|
3995
|
+
}
|
|
3996
|
+
if (target.commandFamily === "link-bookmark") {
|
|
3997
|
+
return linkBookmarkCommandEvidence(target, workflowBlockers);
|
|
3998
|
+
}
|
|
3806
3999
|
const actionableWorkflowBlockers = workflowBlockers.filter(
|
|
3807
4000
|
(fact) => fact.source !== "editable-target-posture"
|
|
3808
4001
|
);
|
|
@@ -3815,6 +4008,8 @@ function runtimeCommandEvidence(target, workflowBlockers, textCommand) {
|
|
|
3815
4008
|
blockers: Object.freeze(actionableWorkflowBlockers.map((fact) => fact.blocker))
|
|
3816
4009
|
};
|
|
3817
4010
|
}
|
|
4011
|
+
const commandSupported = supportedNonTextCommandEvidence(target);
|
|
4012
|
+
if (commandSupported) return commandSupported;
|
|
3818
4013
|
return {
|
|
3819
4014
|
status: "blocked",
|
|
3820
4015
|
commandFamily: target.commandFamily,
|
|
@@ -3828,6 +4023,158 @@ function runtimeCommandEvidence(target, workflowBlockers, textCommand) {
|
|
|
3828
4023
|
])
|
|
3829
4024
|
};
|
|
3830
4025
|
}
|
|
4026
|
+
function generatedFieldCommandEvidence(target, workflowBlockers) {
|
|
4027
|
+
const actionableWorkflowBlockers = workflowBlockers.filter(
|
|
4028
|
+
(fact) => fact.source !== "editable-target-posture"
|
|
4029
|
+
);
|
|
4030
|
+
if (actionableWorkflowBlockers.length > 0) {
|
|
4031
|
+
return {
|
|
4032
|
+
status: "blocked",
|
|
4033
|
+
commandFamily: target.commandFamily,
|
|
4034
|
+
intents: commandIntentsForTarget(target),
|
|
4035
|
+
reason: actionableWorkflowBlockers[0]?.refusalId ?? "editable_target_blocked_by_workflow",
|
|
4036
|
+
blockers: Object.freeze(actionableWorkflowBlockers.map((fact) => fact.blocker))
|
|
4037
|
+
};
|
|
4038
|
+
}
|
|
4039
|
+
if (target.posture.preserveOnly || target.posture.blockers.includes("preserve-only")) {
|
|
4040
|
+
return {
|
|
4041
|
+
status: "blocked",
|
|
4042
|
+
commandFamily: target.commandFamily,
|
|
4043
|
+
intents: commandIntentsForTarget(target),
|
|
4044
|
+
reason: target.field?.fieldFamily === "TOC" ? "l07:toc-refresh-preserve-only-refused" : "l07:field-update-preserve-only-refused",
|
|
4045
|
+
blockers: Object.freeze([...target.posture.blockers])
|
|
4046
|
+
};
|
|
4047
|
+
}
|
|
4048
|
+
if (contentControlLocksTarget(target)) {
|
|
4049
|
+
return {
|
|
4050
|
+
status: "blocked",
|
|
4051
|
+
commandFamily: target.commandFamily,
|
|
4052
|
+
intents: commandIntentsForTarget(target),
|
|
4053
|
+
reason: "editable_target_non_editable",
|
|
4054
|
+
blockers: Object.freeze(["locked-content-control"])
|
|
4055
|
+
};
|
|
4056
|
+
}
|
|
4057
|
+
if (target.kind !== "field-result-text" && target.kind !== "field-region-refresh" && target.kind !== "toc-region-refresh") {
|
|
4058
|
+
return {
|
|
4059
|
+
status: "blocked",
|
|
4060
|
+
commandFamily: target.commandFamily,
|
|
4061
|
+
intents: commandIntentsForTarget(target),
|
|
4062
|
+
reason: "editable_target_kind_unsupported",
|
|
4063
|
+
blockers: Object.freeze(["editable_target_kind_unsupported"])
|
|
4064
|
+
};
|
|
4065
|
+
}
|
|
4066
|
+
if (!target.canonicalAddress) {
|
|
4067
|
+
return {
|
|
4068
|
+
status: "blocked",
|
|
4069
|
+
commandFamily: target.commandFamily,
|
|
4070
|
+
intents: commandIntentsForTarget(target),
|
|
4071
|
+
reason: "editable_target_command_address_missing",
|
|
4072
|
+
blockers: Object.freeze(["editable_target_command_address_missing"])
|
|
4073
|
+
};
|
|
4074
|
+
}
|
|
4075
|
+
const expectedScope = target.kind === "toc-region-refresh" ? "toc-refresh" : "field-refresh";
|
|
4076
|
+
if (target.canonicalAddress.operationScope !== expectedScope || target.field?.refreshStatus === "preserve-only" || !onlyBlockers(target.posture.blockers, ["field-generated-text", "unmodeled-target"])) {
|
|
4077
|
+
return {
|
|
4078
|
+
status: "blocked",
|
|
4079
|
+
commandFamily: target.commandFamily,
|
|
4080
|
+
intents: commandIntentsForTarget(target),
|
|
4081
|
+
reason: commandRefusalReasonForTarget(target),
|
|
4082
|
+
blockers: Object.freeze([...target.posture.blockers])
|
|
4083
|
+
};
|
|
4084
|
+
}
|
|
4085
|
+
return withCommandAction({
|
|
4086
|
+
status: "supported",
|
|
4087
|
+
commandFamily: target.commandFamily,
|
|
4088
|
+
intents: commandIntentsForTarget(target),
|
|
4089
|
+
reason: target.kind === "toc-region-refresh" || target.field?.fieldFamily === "TOC" ? "l07:toc-refresh-target-supported" : "l07:field-refresh-target-supported"
|
|
4090
|
+
}, target);
|
|
4091
|
+
}
|
|
4092
|
+
function linkBookmarkCommandEvidence(target, workflowBlockers) {
|
|
4093
|
+
const actionableWorkflowBlockers = workflowBlockers.filter(
|
|
4094
|
+
(fact) => fact.source !== "editable-target-posture"
|
|
4095
|
+
);
|
|
4096
|
+
if (actionableWorkflowBlockers.length > 0) {
|
|
4097
|
+
return {
|
|
4098
|
+
status: "blocked",
|
|
4099
|
+
commandFamily: target.commandFamily,
|
|
4100
|
+
intents: commandIntentsForTarget(target),
|
|
4101
|
+
reason: actionableWorkflowBlockers[0]?.refusalId ?? "editable_target_blocked_by_workflow",
|
|
4102
|
+
blockers: Object.freeze(actionableWorkflowBlockers.map((fact) => fact.blocker))
|
|
4103
|
+
};
|
|
4104
|
+
}
|
|
4105
|
+
if (target.posture.preserveOnly || target.posture.blockers.includes("preserve-only")) {
|
|
4106
|
+
return {
|
|
4107
|
+
status: "blocked",
|
|
4108
|
+
commandFamily: target.commandFamily,
|
|
4109
|
+
intents: commandIntentsForTarget(target),
|
|
4110
|
+
reason: commandRefusalReasonForTarget(target),
|
|
4111
|
+
blockers: Object.freeze([...target.posture.blockers])
|
|
4112
|
+
};
|
|
4113
|
+
}
|
|
4114
|
+
if (contentControlLocksTarget(target)) {
|
|
4115
|
+
return {
|
|
4116
|
+
status: "blocked",
|
|
4117
|
+
commandFamily: target.commandFamily,
|
|
4118
|
+
intents: commandIntentsForTarget(target),
|
|
4119
|
+
reason: "editable_target_non_editable",
|
|
4120
|
+
blockers: Object.freeze(["locked-content-control"])
|
|
4121
|
+
};
|
|
4122
|
+
}
|
|
4123
|
+
if (target.kind === "hyperlink-destination") {
|
|
4124
|
+
if (!target.canonicalAddress || target.canonicalAddress.operationScope !== "link-destination" || !onlyBlockers(target.posture.blockers, ["unmodeled-target"])) {
|
|
4125
|
+
return {
|
|
4126
|
+
status: "blocked",
|
|
4127
|
+
commandFamily: target.commandFamily,
|
|
4128
|
+
intents: commandIntentsForTarget(target),
|
|
4129
|
+
reason: commandRefusalReasonForTarget(target),
|
|
4130
|
+
blockers: Object.freeze([...target.posture.blockers])
|
|
4131
|
+
};
|
|
4132
|
+
}
|
|
4133
|
+
return withCommandAction({
|
|
4134
|
+
status: "supported",
|
|
4135
|
+
commandFamily: target.commandFamily,
|
|
4136
|
+
intents: commandIntentsForTarget(target),
|
|
4137
|
+
reason: "l07:hyperlink-destination-target-supported"
|
|
4138
|
+
}, target);
|
|
4139
|
+
}
|
|
4140
|
+
if (target.kind === "bookmark-content-range") {
|
|
4141
|
+
if (!target.canonicalAddress || target.canonicalAddress.operationScope !== "bookmark-range" || !onlyBlockers(target.posture.blockers, ["unmodeled-target"])) {
|
|
4142
|
+
return {
|
|
4143
|
+
status: "blocked",
|
|
4144
|
+
commandFamily: target.commandFamily,
|
|
4145
|
+
intents: commandIntentsForTarget(target),
|
|
4146
|
+
reason: commandRefusalReasonForTarget(target),
|
|
4147
|
+
blockers: Object.freeze([...target.posture.blockers])
|
|
4148
|
+
};
|
|
4149
|
+
}
|
|
4150
|
+
return withCommandAction({
|
|
4151
|
+
status: "supported",
|
|
4152
|
+
commandFamily: target.commandFamily,
|
|
4153
|
+
intents: commandIntentsForTarget(target),
|
|
4154
|
+
reason: "l07:bookmark-content-range-target-supported"
|
|
4155
|
+
}, target);
|
|
4156
|
+
}
|
|
4157
|
+
return {
|
|
4158
|
+
status: "blocked",
|
|
4159
|
+
commandFamily: target.commandFamily,
|
|
4160
|
+
intents: commandIntentsForTarget(target),
|
|
4161
|
+
reason: "l07:bookmark-boundary-mutation-refused",
|
|
4162
|
+
blockers: Object.freeze(["bookmark-boundary-mutation"])
|
|
4163
|
+
};
|
|
4164
|
+
}
|
|
4165
|
+
function supportedNonTextCommandEvidence(target) {
|
|
4166
|
+
if (target.commandFamily === "field") {
|
|
4167
|
+
return generatedFieldCommandEvidence(target, []);
|
|
4168
|
+
}
|
|
4169
|
+
if (target.commandFamily === "link-bookmark") {
|
|
4170
|
+
return linkBookmarkCommandEvidence(target, []);
|
|
4171
|
+
}
|
|
4172
|
+
return null;
|
|
4173
|
+
}
|
|
4174
|
+
function onlyBlockers(blockers, allowed) {
|
|
4175
|
+
const allowedSet = new Set(allowed);
|
|
4176
|
+
return blockers.every((blocker) => allowedSet.has(blocker));
|
|
4177
|
+
}
|
|
3831
4178
|
function tableStructureCommandEvidence(target, workflowBlockers) {
|
|
3832
4179
|
const shapeIssues = validateEditableTargetRef(target);
|
|
3833
4180
|
if (shapeIssues.length > 0) {
|
|
@@ -3897,12 +4244,12 @@ function tableStructureCommandEvidence(target, workflowBlockers) {
|
|
|
3897
4244
|
blockers: Object.freeze(["editable_target_table_path_unsupported"])
|
|
3898
4245
|
};
|
|
3899
4246
|
}
|
|
3900
|
-
return {
|
|
4247
|
+
return withCommandAction({
|
|
3901
4248
|
status: "supported",
|
|
3902
4249
|
commandFamily: target.commandFamily,
|
|
3903
4250
|
intents: commandIntentsForTarget(target),
|
|
3904
4251
|
reason: tableStructureSupportedReason(target)
|
|
3905
|
-
};
|
|
4252
|
+
}, target);
|
|
3906
4253
|
}
|
|
3907
4254
|
function tableStructureSupportedReason(target) {
|
|
3908
4255
|
const table = target.table;
|
|
@@ -3927,17 +4274,32 @@ function commentRevisionCommandReason(target, isOpen) {
|
|
|
3927
4274
|
}
|
|
3928
4275
|
return isOpen ? "l07:comment-command-family-supported" : "l07:comment-command-not-open";
|
|
3929
4276
|
}
|
|
3930
|
-
function commandIntentsForTarget(target) {
|
|
4277
|
+
function commandIntentsForTarget(target, scopeKind) {
|
|
3931
4278
|
switch (target.commandFamily) {
|
|
3932
4279
|
case "text-leaf":
|
|
3933
|
-
|
|
4280
|
+
if (target.kind === "hyperlink-text") {
|
|
4281
|
+
return Object.freeze(["text-leaf-edit", "hyperlink-display-text-edit"]);
|
|
4282
|
+
}
|
|
4283
|
+
if (target.table?.operationScope === "text") {
|
|
4284
|
+
return Object.freeze([
|
|
4285
|
+
"text-leaf-edit",
|
|
4286
|
+
"table-text-paste",
|
|
4287
|
+
"table-text-drop",
|
|
4288
|
+
"table-structured-fragment-paste",
|
|
4289
|
+
"table-structured-fragment-drop"
|
|
4290
|
+
]);
|
|
4291
|
+
}
|
|
4292
|
+
if (scopeKind === "list-item" && LIST_TEXT_TARGET_KINDS2.has(target.kind)) {
|
|
4293
|
+
return Object.freeze(["text-leaf-edit", "list-text-edit", "list-structure-action"]);
|
|
4294
|
+
}
|
|
4295
|
+
return Object.freeze(["text-leaf-edit"]);
|
|
3934
4296
|
case "field":
|
|
3935
4297
|
return Object.freeze(
|
|
3936
4298
|
target.field?.fieldFamily === "TOC" ? ["toc-refresh", "field-update"] : ["field-update"]
|
|
3937
4299
|
);
|
|
3938
4300
|
case "link-bookmark":
|
|
3939
4301
|
return Object.freeze(
|
|
3940
|
-
target.kind === "bookmark-anchor" ? ["bookmark-update"] : ["hyperlink-update"]
|
|
4302
|
+
target.kind === "bookmark-anchor" || target.kind === "bookmark-content-range" ? ["bookmark-update"] : ["hyperlink-update"]
|
|
3941
4303
|
);
|
|
3942
4304
|
case "comment-revision":
|
|
3943
4305
|
return Object.freeze(
|
|
@@ -3950,7 +4312,7 @@ function commandIntentsForTarget(target) {
|
|
|
3950
4312
|
case "preserve-only-refusal":
|
|
3951
4313
|
return target.object?.objectKind === "chart" ? Object.freeze(["chart-edit", "preserve-only-refusal"]) : target.object?.objectKind === "custom-xml" ? Object.freeze(["custom-xml-update", "preserve-only-refusal"]) : target.object?.objectKind === "ole" ? Object.freeze(["embedded-content-update", "preserve-only-refusal"]) : isOpaqueObjectTarget(target) ? Object.freeze(["opaque-content-preserve", "preserve-only-refusal"]) : isImageObjectTarget(target) ? Object.freeze(["image-layout", "image-frame", "preserve-only-refusal"]) : Object.freeze(["preserve-only-refusal"]);
|
|
3952
4314
|
case "table-structure":
|
|
3953
|
-
return Object.freeze(["table-structure-action"]);
|
|
4315
|
+
return target.table?.operationScope === "span" ? Object.freeze(["table-structure-action", "table-merge-cells", "table-split-cell"]) : Object.freeze(["table-structure-action"]);
|
|
3954
4316
|
}
|
|
3955
4317
|
}
|
|
3956
4318
|
function commandRefusalReasonForTarget(target) {
|
|
@@ -3961,7 +4323,10 @@ function commandRefusalReasonForTarget(target) {
|
|
|
3961
4323
|
}
|
|
3962
4324
|
return target.posture.preserveOnly ? "l07:field-update-preserve-only-refused" : "l07:field-update-command-family-unimplemented";
|
|
3963
4325
|
case "link-bookmark":
|
|
3964
|
-
|
|
4326
|
+
if (target.kind === "bookmark-anchor") {
|
|
4327
|
+
return "l07:bookmark-boundary-mutation-refused";
|
|
4328
|
+
}
|
|
4329
|
+
return target.kind === "bookmark-content-range" ? "l07:bookmark-command-family-unimplemented" : "l07:hyperlink-command-family-unimplemented";
|
|
3965
4330
|
case "comment-revision":
|
|
3966
4331
|
return target.kind === "revision-anchor" ? "l07:revision-command-family-unimplemented" : "l07:comment-command-family-unimplemented";
|
|
3967
4332
|
case "object":
|
|
@@ -4067,12 +4432,14 @@ function readbackForTarget(document, target, runtimeTextCommand) {
|
|
|
4067
4432
|
}
|
|
4068
4433
|
const leafBlock = resolveMainStoryLeafBlock(document, target.leafPath);
|
|
4069
4434
|
if (!leafBlock) return void 0;
|
|
4435
|
+
const text = collectBlockText(leafBlock);
|
|
4070
4436
|
return {
|
|
4071
|
-
text
|
|
4437
|
+
text,
|
|
4438
|
+
isEmpty: text.length === 0,
|
|
4072
4439
|
source: "canonical-text-leaf"
|
|
4073
4440
|
};
|
|
4074
4441
|
}
|
|
4075
|
-
function projectTarget(document, target, relation, workflowBlockers) {
|
|
4442
|
+
function projectTarget(document, target, relation, workflowBlockers, scopeKind) {
|
|
4076
4443
|
const runtimeTextCommand = runtimeTextCommandEvidence(target, workflowBlockers);
|
|
4077
4444
|
const readback = readbackForTarget(document, target, runtimeTextCommand);
|
|
4078
4445
|
return {
|
|
@@ -4091,11 +4458,13 @@ function projectTarget(document, target, relation, workflowBlockers) {
|
|
|
4091
4458
|
...target.review ? { review: target.review } : {},
|
|
4092
4459
|
...target.object ? { object: target.object } : {},
|
|
4093
4460
|
...target.table ? { table: target.table } : {},
|
|
4461
|
+
...target.editableOwner ? { editableOwner: target.editableOwner } : {},
|
|
4462
|
+
...target.canonicalAddress ? { canonicalAddress: target.canonicalAddress } : {},
|
|
4094
4463
|
staleCheck: target.staleCheck,
|
|
4095
4464
|
posture: target.posture,
|
|
4096
4465
|
...workflowBlockers.length > 0 ? { workflowBlockers: Object.freeze([...workflowBlockers]) } : {},
|
|
4097
4466
|
runtimeTextCommand,
|
|
4098
|
-
runtimeCommand: runtimeCommandEvidence(target, workflowBlockers, runtimeTextCommand),
|
|
4467
|
+
runtimeCommand: runtimeCommandEvidence(target, workflowBlockers, runtimeTextCommand, scopeKind),
|
|
4099
4468
|
...readback ? { readback } : {}
|
|
4100
4469
|
};
|
|
4101
4470
|
}
|
|
@@ -4114,7 +4483,7 @@ function deriveScopeEditableTargetEvidence(document, scope, entry, options = {})
|
|
|
4114
4483
|
(left, right) => left.source.localeCompare(right.source) || left.blocker.localeCompare(right.blocker) || left.refusalId.localeCompare(right.refusalId)
|
|
4115
4484
|
)
|
|
4116
4485
|
);
|
|
4117
|
-
return projectTarget(document, target, relation, workflowBlockers);
|
|
4486
|
+
return projectTarget(document, target, relation, workflowBlockers, scope.kind);
|
|
4118
4487
|
}).filter((target) => target !== null).sort((a, b) => a.targetKey.localeCompare(b.targetKey));
|
|
4119
4488
|
const blockers = /* @__PURE__ */ new Set();
|
|
4120
4489
|
let supportedTextTargetCount = 0;
|
|
@@ -4211,42 +4580,76 @@ function verticalMergeFact(table, rowIndex, cellIndex) {
|
|
|
4211
4580
|
role: "none"
|
|
4212
4581
|
};
|
|
4213
4582
|
}
|
|
4214
|
-
function
|
|
4583
|
+
function textTargetsForCell(editableTargets, blockIndex, rowIndex, cellIndex) {
|
|
4584
|
+
if (!editableTargets) return Object.freeze([]);
|
|
4585
|
+
const tablePath = `main/block[${blockIndex}]`;
|
|
4586
|
+
return Object.freeze(
|
|
4587
|
+
editableTargets.entries.filter(
|
|
4588
|
+
(target) => target.commandFamily === "text-leaf" && target.table?.operationScope === "text" && target.table.tablePath === tablePath && target.table.rowIndex === rowIndex && target.table.cellIndex === cellIndex
|
|
4589
|
+
)
|
|
4590
|
+
);
|
|
4591
|
+
}
|
|
4592
|
+
function textState(targets, readbacks) {
|
|
4593
|
+
if (targets.length === 0) return "unavailable";
|
|
4594
|
+
if (readbacks.length === 0) {
|
|
4595
|
+
return targets.some((target) => target.runtimeTextCommand.status === "supported") ? "unavailable" : "blocked";
|
|
4596
|
+
}
|
|
4597
|
+
return readbacks.some((readback) => !readback.isEmpty) ? "non-empty" : "empty";
|
|
4598
|
+
}
|
|
4599
|
+
function cellFact(table, blockIndex, rowIndex, cellIndex, editableTargets) {
|
|
4215
4600
|
const row = table.rows[rowIndex];
|
|
4216
4601
|
const cell = row.cells[cellIndex];
|
|
4217
4602
|
const merge = verticalMergeFact(table, rowIndex, cellIndex);
|
|
4603
|
+
const textTargets = textTargetsForCell(editableTargets, blockIndex, rowIndex, cellIndex);
|
|
4604
|
+
const supportedTextTargetCount = textTargets.filter(
|
|
4605
|
+
(target) => target.runtimeTextCommand.status === "supported"
|
|
4606
|
+
).length;
|
|
4607
|
+
const readbacks = Object.freeze(
|
|
4608
|
+
textTargets.map((target) => target.readback).filter((readback) => Boolean(readback))
|
|
4609
|
+
);
|
|
4218
4610
|
return {
|
|
4219
4611
|
rowIndex,
|
|
4220
4612
|
cellIndex,
|
|
4613
|
+
...cell.sourceRef ? { cellSourceRef: cell.sourceRef } : {},
|
|
4221
4614
|
gridColumnStart: merge.gridColumnStart,
|
|
4222
4615
|
gridSpan: merge.gridSpan,
|
|
4223
4616
|
verticalMerge: merge,
|
|
4224
|
-
childBlockCount: cell.children.length
|
|
4617
|
+
childBlockCount: cell.children.length,
|
|
4618
|
+
textTargetCount: textTargets.length,
|
|
4619
|
+
supportedTextTargetCount,
|
|
4620
|
+
textState: textState(textTargets, readbacks),
|
|
4621
|
+
...readbacks.length > 0 ? { textReadbacks: readbacks } : {}
|
|
4225
4622
|
};
|
|
4226
4623
|
}
|
|
4227
|
-
function rowFact(table, rowIndex) {
|
|
4624
|
+
function rowFact(table, blockIndex, rowIndex, editableTargets) {
|
|
4228
4625
|
const row = table.rows[rowIndex];
|
|
4229
4626
|
return {
|
|
4230
4627
|
rowIndex,
|
|
4628
|
+
...row.sourceRef ? { rowSourceRef: row.sourceRef } : {},
|
|
4231
4629
|
cellCount: row.cells.length,
|
|
4232
4630
|
...row.gridBefore !== void 0 ? { gridBefore: row.gridBefore } : {},
|
|
4233
4631
|
...row.gridAfter !== void 0 ? { gridAfter: row.gridAfter } : {},
|
|
4234
4632
|
repeatedHeader: row.isHeader === true,
|
|
4235
4633
|
splitRowAllowed: row.cantSplit !== true,
|
|
4236
|
-
cells: Object.freeze(
|
|
4634
|
+
cells: Object.freeze(
|
|
4635
|
+
row.cells.map((_, cellIndex) => cellFact(table, blockIndex, rowIndex, cellIndex, editableTargets))
|
|
4636
|
+
)
|
|
4237
4637
|
};
|
|
4238
4638
|
}
|
|
4239
|
-
function structureFacts(entry) {
|
|
4639
|
+
function structureFacts(entry, editableTargets) {
|
|
4240
4640
|
const table = entry.table;
|
|
4241
|
-
const rows = Object.freeze(
|
|
4641
|
+
const rows = Object.freeze(
|
|
4642
|
+
table.rows.map((_, rowIndex) => rowFact(table, entry.blockIndex, rowIndex, editableTargets))
|
|
4643
|
+
);
|
|
4242
4644
|
return {
|
|
4645
|
+
...table.sourceRef ? { sourceRef: table.sourceRef } : {},
|
|
4243
4646
|
rowCount: table.rows.length,
|
|
4244
4647
|
columnCount: columnCount(table),
|
|
4245
4648
|
...entry.kind === "table" ? { rows } : {},
|
|
4246
4649
|
...entry.kind === "table-row" ? { row: rows[entry.rowIndex] } : {},
|
|
4247
4650
|
...entry.kind === "table-cell" ? {
|
|
4248
4651
|
row: rows[entry.rowIndex],
|
|
4249
|
-
cell: cellFact(table, entry.rowIndex, entry.cellIndex)
|
|
4652
|
+
cell: cellFact(table, entry.blockIndex, entry.rowIndex, entry.cellIndex, editableTargets)
|
|
4250
4653
|
} : {}
|
|
4251
4654
|
};
|
|
4252
4655
|
}
|
|
@@ -4285,23 +4688,33 @@ function tableAction(entry, index) {
|
|
|
4285
4688
|
if (!family || !entry.table) return null;
|
|
4286
4689
|
const status = actionStatus(entry);
|
|
4287
4690
|
const blockers = actionBlockers(entry);
|
|
4691
|
+
const fullFidelityTableText = family === "table-text" && Boolean(entry.readback);
|
|
4692
|
+
const actionHandle = entry.canonicalAddress ? `table-action:${entry.canonicalAddress.addressKey}` : `table-action:${family}:${index}`;
|
|
4288
4693
|
return {
|
|
4289
|
-
handle:
|
|
4694
|
+
handle: actionHandle,
|
|
4290
4695
|
family,
|
|
4291
4696
|
status,
|
|
4292
|
-
posture: status === "supported" ? "warn-and-proceed" : "hard-refusal",
|
|
4697
|
+
posture: status === "supported" ? fullFidelityTableText ? "supported" : "warn-and-proceed" : "hard-refusal",
|
|
4293
4698
|
reason: actionReason(entry),
|
|
4294
4699
|
operationScope: entry.table.operationScope,
|
|
4295
4700
|
targetKind: entry.kind,
|
|
4296
4701
|
relation: entry.relation,
|
|
4297
4702
|
intents: entry.runtimeCommand.intents,
|
|
4703
|
+
...entry.runtimeCommand.actionHandle ? { actionHandle: entry.runtimeCommand.actionHandle } : {},
|
|
4704
|
+
...entry.canonicalAddress ? { canonicalAddress: entry.canonicalAddress } : {},
|
|
4705
|
+
...entry.readback ? { readback: entry.readback } : {},
|
|
4298
4706
|
...blockers && blockers.length > 0 ? { blockers } : {},
|
|
4299
|
-
...status === "supported" ? { warnings: [`editable-target:${entry.kind}:available`] } : {},
|
|
4707
|
+
...status === "supported" && !fullFidelityTableText ? { warnings: [`editable-target:${entry.kind}:available`] } : {},
|
|
4300
4708
|
diagnostics: {
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4709
|
+
...entry.table.sourceRef ? { sourceRef: entry.table.sourceRef } : {},
|
|
4710
|
+
...entry.table.rowSourceRef ? { rowSourceRef: entry.table.rowSourceRef } : {},
|
|
4711
|
+
...entry.table.cellSourceRef ? { cellSourceRef: entry.table.cellSourceRef } : {},
|
|
4712
|
+
raw: {
|
|
4713
|
+
targetKey: entry.targetKey,
|
|
4714
|
+
blockPath: entry.blockPath,
|
|
4715
|
+
leafPath: entry.leafPath,
|
|
4716
|
+
tableKey: entry.table.tableKey
|
|
4717
|
+
}
|
|
4305
4718
|
}
|
|
4306
4719
|
};
|
|
4307
4720
|
}
|
|
@@ -4331,7 +4744,7 @@ function deriveScopeTableEvidence(scope, entry, options = {}) {
|
|
|
4331
4744
|
status: "present",
|
|
4332
4745
|
semanticHandle: semanticHandle(scope, entry),
|
|
4333
4746
|
diagnostics: diagnostics(scope, entry),
|
|
4334
|
-
structure: structureFacts(entry),
|
|
4747
|
+
structure: structureFacts(entry, options.editableTargets),
|
|
4335
4748
|
actions: actions(options.editableTargets),
|
|
4336
4749
|
...fragments ? { layoutFragments: fragments } : {}
|
|
4337
4750
|
};
|
|
@@ -4493,6 +4906,8 @@ function mapSemanticEntry(entry) {
|
|
|
4493
4906
|
return null;
|
|
4494
4907
|
}
|
|
4495
4908
|
const targetKey = stringValue(entry.editableTargetKey);
|
|
4909
|
+
const editableTargetOwnerKey = stringValue(entry.editableTargetOwnerKey);
|
|
4910
|
+
const editableTargetOwnerReason = stringValue(entry.editableTargetOwnerReason);
|
|
4496
4911
|
const blockers = stringList(entry.editableTargetBlockers);
|
|
4497
4912
|
const divergenceIds = stringList(entry.layoutDivergenceIds);
|
|
4498
4913
|
const layoutDivergenceObjectIds = stringList(entry.layoutDivergenceObjectIds);
|
|
@@ -4522,7 +4937,13 @@ function mapSemanticEntry(entry) {
|
|
|
4522
4937
|
...stringValue(entry.editableTargetCommandFamily) ? { commandFamily: stringValue(entry.editableTargetCommandFamily) } : {},
|
|
4523
4938
|
...stringValue(entry.editableTargetEditability) ? { editability: stringValue(entry.editableTargetEditability) } : {},
|
|
4524
4939
|
...blockers ? { blockers } : {},
|
|
4525
|
-
...stringValue(entry.editableTargetLeafPath) ? { leafPath: stringValue(entry.editableTargetLeafPath) } : {}
|
|
4940
|
+
...stringValue(entry.editableTargetLeafPath) ? { leafPath: stringValue(entry.editableTargetLeafPath) } : {},
|
|
4941
|
+
...editableTargetOwnerKey ? {
|
|
4942
|
+
editableOwner: {
|
|
4943
|
+
targetKey: editableTargetOwnerKey,
|
|
4944
|
+
reason: editableTargetOwnerReason ?? "unknown"
|
|
4945
|
+
}
|
|
4946
|
+
} : {}
|
|
4526
4947
|
}
|
|
4527
4948
|
} : {},
|
|
4528
4949
|
...entry.sourceIdentity ? { sourceIdentity: { ...entry.sourceIdentity } } : {}
|
|
@@ -5811,7 +6232,7 @@ function collectPreservationVerdict(inputs, blockedReasons, warnings) {
|
|
|
5811
6232
|
}
|
|
5812
6233
|
if (!document) return;
|
|
5813
6234
|
const pm = positionMap ?? buildScopePositionMap(document);
|
|
5814
|
-
const range = inputs.enumeratedScope ? resolveScopeRange(inputs.enumeratedScope, scope.handle, pm) : scope.handle.stableRef.kind === "scope-id" ? pm.markerScopes.get(scope.handle.stableRef.value) ?? null :
|
|
6235
|
+
const range = inputs.enumeratedScope ? resolveScopeRange(inputs.enumeratedScope, scope.handle, pm) : scope.handle.stableRef.kind === "scope-id" ? pm.markerScopes.get(scope.handle.stableRef.value) ?? null : rangeFromSemanticPath(scope.handle.semanticPath, pm);
|
|
5815
6236
|
const verdict = computePreservationVerdict(document, range, pm);
|
|
5816
6237
|
if (verdict.replaceable) return;
|
|
5817
6238
|
const opaqueOptIn = inputs.preservePolicy?.opaqueFragments === true;
|
|
@@ -5843,6 +6264,134 @@ function collectCompatibilityVerdict(runtime, blockedReasons, warnings) {
|
|
|
5843
6264
|
}
|
|
5844
6265
|
}
|
|
5845
6266
|
}
|
|
6267
|
+
function collectCapabilityVerdict(inputs, blockedReasons, warnings) {
|
|
6268
|
+
if (inputs.operation === "replace" && inputs.proposedContent.kind === "text") {
|
|
6269
|
+
for (const blocker of generatedOrLinkedContentBlockers2(inputs)) {
|
|
6270
|
+
blockedReasons.push(blocker);
|
|
6271
|
+
warnings.push({
|
|
6272
|
+
code: blocker,
|
|
6273
|
+
message: blocker === "field-generated-text" ? "target range includes generated field text; use a field/TOC command path or refuse" : "target range includes bookmark/link boundary content; use a link/bookmark command path or refuse",
|
|
6274
|
+
source: "capability"
|
|
6275
|
+
});
|
|
6276
|
+
}
|
|
6277
|
+
}
|
|
6278
|
+
if (inputs.scope.kind === "list-item" && inputs.operation === "replace" && inputs.proposedContent.kind === "text") {
|
|
6279
|
+
const code = "capability:list-item:authoritative-readback-required";
|
|
6280
|
+
blockedReasons.push(code);
|
|
6281
|
+
warnings.push({
|
|
6282
|
+
code,
|
|
6283
|
+
message: "list-item flat text replacement is blocked until the runtime validates an export-persistent list text command path",
|
|
6284
|
+
source: "capability"
|
|
6285
|
+
});
|
|
6286
|
+
}
|
|
6287
|
+
}
|
|
6288
|
+
function generatedOrLinkedContentBlockers2(inputs) {
|
|
6289
|
+
const { document, scope, positionMap } = inputs;
|
|
6290
|
+
if (!document) return [];
|
|
6291
|
+
const pm = positionMap ?? buildScopePositionMap(document);
|
|
6292
|
+
const range = inputs.enumeratedScope ? resolveScopeRange(inputs.enumeratedScope, scope.handle, pm) : scope.handle.stableRef.kind === "scope-id" ? pm.markerScopes.get(scope.handle.stableRef.value) ?? null : rangeFromSemanticPath(scope.handle.semanticPath, pm);
|
|
6293
|
+
if (!range) return [];
|
|
6294
|
+
const root = document.content;
|
|
6295
|
+
if (!root || root.type !== "doc" || !Array.isArray(root.children)) return [];
|
|
6296
|
+
const blockers = /* @__PURE__ */ new Set();
|
|
6297
|
+
if (scope.kind === "table-cell") {
|
|
6298
|
+
const cell = tableCellFromSemanticPath(root, scope.handle.semanticPath);
|
|
6299
|
+
if (cell) {
|
|
6300
|
+
collectGeneratedOrLinkedBlocksBlockers(cell.children, blockers);
|
|
6301
|
+
return [...blockers].sort();
|
|
6302
|
+
}
|
|
6303
|
+
}
|
|
6304
|
+
root.children.forEach((block, blockIndex) => {
|
|
6305
|
+
if (block.type !== "paragraph") return;
|
|
6306
|
+
const blockRange = pm.blocks.get(blockIndex);
|
|
6307
|
+
if (!blockRange || !rangesOverlapOrTouch(range, blockRange)) return;
|
|
6308
|
+
collectGeneratedOrLinkedInlineBlockers(block, blockIndex, pm, range, blockers);
|
|
6309
|
+
});
|
|
6310
|
+
return [...blockers].sort();
|
|
6311
|
+
}
|
|
6312
|
+
function tableCellFromSemanticPath(root, semanticPath) {
|
|
6313
|
+
const tableIndex = semanticPath.findIndex((part) => part === "table");
|
|
6314
|
+
const rowIndex = semanticPath.findIndex((part) => part === "row");
|
|
6315
|
+
const cellIndex = semanticPath.findIndex((part) => part === "cell");
|
|
6316
|
+
const tableBlockIndex = tableIndex >= 0 ? Number(semanticPath[tableIndex + 1]) : NaN;
|
|
6317
|
+
const rowOrdinal = rowIndex >= 0 ? Number(semanticPath[rowIndex + 1]) : NaN;
|
|
6318
|
+
const cellOrdinal = cellIndex >= 0 ? Number(semanticPath[cellIndex + 1]) : NaN;
|
|
6319
|
+
if (!Number.isInteger(tableBlockIndex) || !Number.isInteger(rowOrdinal) || !Number.isInteger(cellOrdinal)) {
|
|
6320
|
+
return null;
|
|
6321
|
+
}
|
|
6322
|
+
const table = root.children[tableBlockIndex];
|
|
6323
|
+
if (!table || table.type !== "table") return null;
|
|
6324
|
+
return table.rows[rowOrdinal]?.cells[cellOrdinal] ?? null;
|
|
6325
|
+
}
|
|
6326
|
+
function collectGeneratedOrLinkedBlocksBlockers(blocks, blockers) {
|
|
6327
|
+
for (const block of blocks) {
|
|
6328
|
+
if (block.type === "paragraph") {
|
|
6329
|
+
for (const child of block.children) {
|
|
6330
|
+
collectGeneratedOrLinkedNodeBlockers(child, blockers);
|
|
6331
|
+
}
|
|
6332
|
+
continue;
|
|
6333
|
+
}
|
|
6334
|
+
if (block.type === "table") {
|
|
6335
|
+
for (const row of block.rows) {
|
|
6336
|
+
for (const cell of row.cells) {
|
|
6337
|
+
collectGeneratedOrLinkedBlocksBlockers(cell.children, blockers);
|
|
6338
|
+
}
|
|
6339
|
+
}
|
|
6340
|
+
continue;
|
|
6341
|
+
}
|
|
6342
|
+
if (block.type === "sdt") {
|
|
6343
|
+
collectGeneratedOrLinkedBlocksBlockers(block.children, blockers);
|
|
6344
|
+
}
|
|
6345
|
+
}
|
|
6346
|
+
}
|
|
6347
|
+
function rangeFromSemanticPath(semanticPath, positionMap) {
|
|
6348
|
+
const paragraphIndex = semanticPath.findIndex(
|
|
6349
|
+
(part) => part === "paragraph" || part === "heading" || part === "list-item"
|
|
6350
|
+
);
|
|
6351
|
+
if (paragraphIndex < 0) return null;
|
|
6352
|
+
const rawIndex = semanticPath[paragraphIndex + 1] ?? semanticPath[semanticPath.length - 1];
|
|
6353
|
+
const blockIndex = rawIndex !== void 0 ? Number(rawIndex) : NaN;
|
|
6354
|
+
if (!Number.isInteger(blockIndex)) return null;
|
|
6355
|
+
return positionMap.blocks.get(blockIndex) ?? null;
|
|
6356
|
+
}
|
|
6357
|
+
function collectGeneratedOrLinkedInlineBlockers(paragraph, blockIndex, positionMap, range, blockers) {
|
|
6358
|
+
paragraph.children.forEach((child, inlineIndex) => {
|
|
6359
|
+
const inlineRange = positionMap.inlines.get(`${blockIndex}:${inlineIndex}`);
|
|
6360
|
+
if (!inlineRange || !rangesOverlapOrTouch(range, inlineRange)) return;
|
|
6361
|
+
collectGeneratedOrLinkedNodeBlockers(child, blockers);
|
|
6362
|
+
});
|
|
6363
|
+
}
|
|
6364
|
+
function collectGeneratedOrLinkedNodeBlockers(node, blockers) {
|
|
6365
|
+
switch (node.type) {
|
|
6366
|
+
case "field":
|
|
6367
|
+
blockers.add("field-generated-text");
|
|
6368
|
+
node.children.forEach(
|
|
6369
|
+
(child) => collectGeneratedOrLinkedNodeBlockers(child, blockers)
|
|
6370
|
+
);
|
|
6371
|
+
break;
|
|
6372
|
+
case "bookmark_start":
|
|
6373
|
+
case "bookmark_end":
|
|
6374
|
+
blockers.add("link-bookmark:bookmark-anchor");
|
|
6375
|
+
break;
|
|
6376
|
+
case "hyperlink":
|
|
6377
|
+
blockers.add("link-bookmark:hyperlink-text");
|
|
6378
|
+
node.children.forEach(
|
|
6379
|
+
(child) => collectGeneratedOrLinkedNodeBlockers(child, blockers)
|
|
6380
|
+
);
|
|
6381
|
+
break;
|
|
6382
|
+
default:
|
|
6383
|
+
break;
|
|
6384
|
+
}
|
|
6385
|
+
}
|
|
6386
|
+
function rangesOverlapOrTouch(left, right) {
|
|
6387
|
+
if (right.from === right.to) {
|
|
6388
|
+
return right.from >= left.from && right.from <= left.to;
|
|
6389
|
+
}
|
|
6390
|
+
if (left.from === left.to) {
|
|
6391
|
+
return left.from >= right.from && left.from <= right.to;
|
|
6392
|
+
}
|
|
6393
|
+
return left.from < right.to && right.from < left.to;
|
|
6394
|
+
}
|
|
5846
6395
|
function collectPolicyVerdict(actionId, blockedReasons, warnings) {
|
|
5847
6396
|
let policy;
|
|
5848
6397
|
try {
|
|
@@ -5882,6 +6431,7 @@ function composeScopeValidation(inputs) {
|
|
|
5882
6431
|
collectGuardVerdict(inputs.scope, inputs.runtime, blockedReasons, warnings);
|
|
5883
6432
|
collectPreservationVerdict(inputs, blockedReasons, warnings);
|
|
5884
6433
|
collectCompatibilityVerdict(inputs.runtime, blockedReasons, warnings);
|
|
6434
|
+
collectCapabilityVerdict(inputs, blockedReasons, warnings);
|
|
5885
6435
|
const actionId = inputs.actionId ?? inferActionId(inputs.operation, inputs.proposedContent);
|
|
5886
6436
|
const approval = collectPolicyVerdict(actionId, blockedReasons, warnings);
|
|
5887
6437
|
const safe = blockedReasons.length === 0;
|
|
@@ -6124,8 +6674,10 @@ function applyScopeReplacement(inputs) {
|
|
|
6124
6674
|
proposed.targetHandle.scopeId
|
|
6125
6675
|
);
|
|
6126
6676
|
const proposedText = proposed.proposedContent.kind === "text" ? proposed.proposedContent.text ?? "" : null;
|
|
6127
|
-
const
|
|
6128
|
-
const
|
|
6677
|
+
const paragraphLikeReadback = resolvedScope.kind === "paragraph" || resolvedScope.kind === "heading" || resolvedScope.kind === "list-item";
|
|
6678
|
+
const shouldVerifyExactReadback = inputs.sink.verifyReadback === true && paragraphLikeReadback && resolvedScope.handle.provenance !== "marker-backed" && proposed.preserve?.opaqueFragments !== true && posture === "direct-edit" && proposed.operation === "replace" && proposedText !== null && proposedText !== resolvedScope.content.text;
|
|
6679
|
+
const shouldVerifyOpaqueNoopReadback = inputs.sink.verifyReadback === true && proposed.preserve?.opaqueFragments === true;
|
|
6680
|
+
const readbackFailureReason = shouldVerifyExactReadback && !readback ? `apply-readback-unresolvable:${proposed.targetHandle.scopeId}` : shouldVerifyExactReadback && readback?.scope.content.text !== proposedText ? readback?.scope.content.text === resolvedScope.content.text ? `apply-readback-unchanged:${proposed.targetHandle.scopeId}` : `apply-readback-mismatch:${proposed.targetHandle.scopeId}` : shouldVerifyOpaqueNoopReadback && documentHashAfter === documentHashBefore && posture === "direct-edit" && !readback ? `apply-readback-unresolvable:${proposed.targetHandle.scopeId}` : shouldVerifyOpaqueNoopReadback && documentHashAfter === documentHashBefore && posture === "direct-edit" && proposed.operation === "replace" && proposedText !== null && proposedText !== resolvedScope.content.text && readback?.scope.content.text === resolvedScope.content.text ? `apply-readback-unchanged:${proposed.targetHandle.scopeId}` : void 0;
|
|
6129
6681
|
if (readbackFailureReason) {
|
|
6130
6682
|
const blockers = Object.freeze([
|
|
6131
6683
|
readbackFailureReason,
|
|
@@ -7283,7 +7835,8 @@ function resolveEditableTextTarget(input) {
|
|
|
7283
7835
|
"Editable target ref does not belong to the active story."
|
|
7284
7836
|
);
|
|
7285
7837
|
}
|
|
7286
|
-
const
|
|
7838
|
+
const currentTargets = collectEditableTargetRefs(input.document);
|
|
7839
|
+
const current = currentTargets.find(
|
|
7287
7840
|
(candidate) => candidate.targetKey === input.target.targetKey
|
|
7288
7841
|
);
|
|
7289
7842
|
if (!current) {
|
|
@@ -7310,19 +7863,26 @@ function resolveEditableTextTarget(input) {
|
|
|
7310
7863
|
`Editable target command family "${input.target.commandFamily}" is not supported by text commands.`
|
|
7311
7864
|
);
|
|
7312
7865
|
}
|
|
7313
|
-
|
|
7866
|
+
const dispatchTarget = resolveEditableDispatchTarget(currentTargets, current);
|
|
7867
|
+
if (!dispatchTarget) {
|
|
7868
|
+
return reject(
|
|
7869
|
+
"editable_target_synthetic_layout_cell",
|
|
7870
|
+
"Vertical-merge continuation cells are synthetic layout cells and do not have an editable restart-cell owner."
|
|
7871
|
+
);
|
|
7872
|
+
}
|
|
7873
|
+
if (dispatchTarget.editability !== "editable" || dispatchTarget.posture.blockers.length > 0) {
|
|
7314
7874
|
return reject(
|
|
7315
7875
|
"editable_target_non_editable",
|
|
7316
|
-
`Editable target is not editable${
|
|
7876
|
+
`Editable target is not editable${dispatchTarget.posture.blockers.length > 0 ? `: ${dispatchTarget.posture.blockers.join(", ")}` : "."}`
|
|
7317
7877
|
);
|
|
7318
7878
|
}
|
|
7319
|
-
if (contentControlLocksTarget2(
|
|
7879
|
+
if (contentControlLocksTarget2(dispatchTarget)) {
|
|
7320
7880
|
return reject(
|
|
7321
7881
|
"editable_target_non_editable",
|
|
7322
7882
|
"Editable target is inside a locked content control."
|
|
7323
7883
|
);
|
|
7324
7884
|
}
|
|
7325
|
-
const range = locateTargetRange(input.document, input.surface,
|
|
7885
|
+
const range = locateTargetRange(input.document, input.surface, dispatchTarget);
|
|
7326
7886
|
if (!range) {
|
|
7327
7887
|
return reject(
|
|
7328
7888
|
"editable_target_surface_unavailable",
|
|
@@ -7351,6 +7911,97 @@ function resolveEditableTextTarget(input) {
|
|
|
7351
7911
|
range: { from: range.from, to: range.to }
|
|
7352
7912
|
};
|
|
7353
7913
|
}
|
|
7914
|
+
function resolveEditableCommandTarget(input) {
|
|
7915
|
+
if (!input.target) {
|
|
7916
|
+
return rejectCommand(
|
|
7917
|
+
"editable_target_required",
|
|
7918
|
+
"Runtime target commands require a validated editable target ref."
|
|
7919
|
+
);
|
|
7920
|
+
}
|
|
7921
|
+
const shapeIssues = validateEditableTargetRef(input.target);
|
|
7922
|
+
if (shapeIssues.length > 0) {
|
|
7923
|
+
return rejectCommand(
|
|
7924
|
+
"editable_target_malformed",
|
|
7925
|
+
`Editable target ref is malformed: ${shapeIssues[0]?.path ?? "$"}.`
|
|
7926
|
+
);
|
|
7927
|
+
}
|
|
7928
|
+
const activeStoryKey = input.activeStoryKey ?? input.target.storyKey;
|
|
7929
|
+
if (input.target.storyKey !== activeStoryKey) {
|
|
7930
|
+
return rejectCommand(
|
|
7931
|
+
"editable_target_wrong_story",
|
|
7932
|
+
"Editable target ref does not belong to the active story."
|
|
7933
|
+
);
|
|
7934
|
+
}
|
|
7935
|
+
if (!input.commandFamilies.includes(input.target.commandFamily)) {
|
|
7936
|
+
return rejectCommand(
|
|
7937
|
+
"editable_target_command_family_unsupported",
|
|
7938
|
+
`Editable target command family "${input.target.commandFamily}" is not supported by this command.`
|
|
7939
|
+
);
|
|
7940
|
+
}
|
|
7941
|
+
if (input.targetKinds && !input.targetKinds.includes(input.target.kind)) {
|
|
7942
|
+
return rejectCommand(
|
|
7943
|
+
"editable_target_kind_unsupported",
|
|
7944
|
+
`Editable target kind "${input.target.kind}" is not supported by this command.`
|
|
7945
|
+
);
|
|
7946
|
+
}
|
|
7947
|
+
const currentTargets = collectEditableTargetRefs(input.document);
|
|
7948
|
+
const current = currentTargets.find(
|
|
7949
|
+
(candidate) => candidate.targetKey === input.target?.targetKey
|
|
7950
|
+
);
|
|
7951
|
+
if (!current) {
|
|
7952
|
+
return rejectCommand(
|
|
7953
|
+
"editable_target_not_found",
|
|
7954
|
+
"Editable target ref no longer resolves in the current canonical document."
|
|
7955
|
+
);
|
|
7956
|
+
}
|
|
7957
|
+
if (!sameResolvedTarget2(input.target, current)) {
|
|
7958
|
+
return rejectCommand(
|
|
7959
|
+
"editable_target_stale",
|
|
7960
|
+
"Editable target ref is stale for the current canonical document."
|
|
7961
|
+
);
|
|
7962
|
+
}
|
|
7963
|
+
if (contentControlLocksTarget2(current)) {
|
|
7964
|
+
return rejectCommand(
|
|
7965
|
+
"editable_target_non_editable",
|
|
7966
|
+
"Editable target is inside a locked content control."
|
|
7967
|
+
);
|
|
7968
|
+
}
|
|
7969
|
+
if (current.posture.preserveOnly || current.posture.blockers.includes("preserve-only")) {
|
|
7970
|
+
return rejectCommand(
|
|
7971
|
+
"editable_target_preserve_only",
|
|
7972
|
+
"Editable target is preserve-only and cannot be mutated by runtime commands."
|
|
7973
|
+
);
|
|
7974
|
+
}
|
|
7975
|
+
if (!input.allowGeneratedPosture) {
|
|
7976
|
+
const blockers = current.posture.blockers.filter(
|
|
7977
|
+
(blocker) => blocker !== "unmodeled-target"
|
|
7978
|
+
);
|
|
7979
|
+
if (current.editability !== "editable" || blockers.length > 0) {
|
|
7980
|
+
return rejectCommand(
|
|
7981
|
+
"editable_target_non_editable",
|
|
7982
|
+
`Editable target is not editable${blockers.length > 0 ? `: ${blockers.join(", ")}` : "."}`
|
|
7983
|
+
);
|
|
7984
|
+
}
|
|
7985
|
+
}
|
|
7986
|
+
return {
|
|
7987
|
+
kind: "accepted",
|
|
7988
|
+
target: current
|
|
7989
|
+
};
|
|
7990
|
+
}
|
|
7991
|
+
function resolveEditableDispatchTarget(currentTargets, target) {
|
|
7992
|
+
if (!isSyntheticLayoutContinuationTarget(target)) return target;
|
|
7993
|
+
const owner = target.editableOwner;
|
|
7994
|
+
if (!owner) return null;
|
|
7995
|
+
const ownerTarget = currentTargets.find((candidate) => candidate.targetKey === owner.targetKey);
|
|
7996
|
+
if (!ownerTarget) return null;
|
|
7997
|
+
if (ownerTarget.commandFamily !== "text-leaf" || ownerTarget.storyKey !== owner.storyKey || ownerTarget.blockPath !== owner.blockPath || ownerTarget.leafPath !== owner.leafPath || ownerTarget.kind !== owner.kind) {
|
|
7998
|
+
return null;
|
|
7999
|
+
}
|
|
8000
|
+
return ownerTarget;
|
|
8001
|
+
}
|
|
8002
|
+
function isSyntheticLayoutContinuationTarget(target) {
|
|
8003
|
+
return target.commandFamily === "text-leaf" && target.table?.operationScope === "text" && target.table.verticalMerge === "continue" && target.posture.blockers.includes("synthetic-layout-cell");
|
|
8004
|
+
}
|
|
7354
8005
|
function contentControlLocksTarget2(target) {
|
|
7355
8006
|
const lock = target.contentControl?.lock;
|
|
7356
8007
|
return lock !== void 0 && lock !== "unlocked" && lock !== "none";
|
|
@@ -7361,8 +8012,14 @@ function reject(code, message) {
|
|
|
7361
8012
|
blockedReason: { code, message }
|
|
7362
8013
|
};
|
|
7363
8014
|
}
|
|
8015
|
+
function rejectCommand(code, message) {
|
|
8016
|
+
return {
|
|
8017
|
+
kind: "rejected",
|
|
8018
|
+
blockedReason: { code, message }
|
|
8019
|
+
};
|
|
8020
|
+
}
|
|
7364
8021
|
function sameResolvedTarget2(left, right) {
|
|
7365
|
-
return left.kind === right.kind && left.storyKey === right.storyKey && left.blockPath === right.blockPath && left.leafPath === right.leafPath && left.commandFamily === right.commandFamily && left.editability === right.editability && left.staleCheck.paragraphTextHash === right.staleCheck.paragraphTextHash && left.staleCheck.paragraphTextLength === right.staleCheck.paragraphTextLength && left.staleCheck.inlineCount === right.staleCheck.inlineCount && left.staleCheck.targetHash === right.staleCheck.targetHash && left.staleCheck.targetTextLength === right.staleCheck.targetTextLength && left.staleCheck.childCount === right.staleCheck.childCount && left.staleCheck.blockType === right.staleCheck.blockType && left.staleCheck.wordParaId === right.staleCheck.wordParaId && left.staleCheck.wordTextId === right.staleCheck.wordTextId && jsonStable(left.staleCheck.sourceRef) === jsonStable(right.staleCheck.sourceRef) && jsonStable(left.sourceRef) === jsonStable(right.sourceRef) && jsonStable(left.table) === jsonStable(right.table);
|
|
8022
|
+
return left.kind === right.kind && left.storyKey === right.storyKey && left.blockPath === right.blockPath && left.leafPath === right.leafPath && left.commandFamily === right.commandFamily && left.editability === right.editability && left.staleCheck.paragraphTextHash === right.staleCheck.paragraphTextHash && left.staleCheck.paragraphTextLength === right.staleCheck.paragraphTextLength && left.staleCheck.inlineCount === right.staleCheck.inlineCount && left.staleCheck.targetHash === right.staleCheck.targetHash && left.staleCheck.targetTextLength === right.staleCheck.targetTextLength && left.staleCheck.childCount === right.staleCheck.childCount && left.staleCheck.blockType === right.staleCheck.blockType && left.staleCheck.wordParaId === right.staleCheck.wordParaId && left.staleCheck.wordTextId === right.staleCheck.wordTextId && jsonStable(left.staleCheck.sourceRef) === jsonStable(right.staleCheck.sourceRef) && jsonStable(left.sourceRef) === jsonStable(right.sourceRef) && jsonStable(left.table) === jsonStable(right.table) && jsonStable(left.editableOwner) === jsonStable(right.editableOwner);
|
|
7366
8023
|
}
|
|
7367
8024
|
function locateTargetRange(document, surface, target) {
|
|
7368
8025
|
if (target.kind === "hyperlink-text") {
|
|
@@ -7853,5 +8510,6 @@ export {
|
|
|
7853
8510
|
parseCanonicalFragmentFromWordML,
|
|
7854
8511
|
serializeFragmentToWordML,
|
|
7855
8512
|
resolveEditableTextTarget,
|
|
8513
|
+
resolveEditableCommandTarget,
|
|
7856
8514
|
resolveEditableTableStructureTarget
|
|
7857
8515
|
};
|