@beyondwork/docx-react-component 1.0.133 → 1.0.134
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/api/public-types.cjs +3 -1
- package/dist/api/public-types.d.cts +1 -1
- package/dist/api/public-types.d.ts +1 -1
- package/dist/api/public-types.js +1 -1
- package/dist/api/v3.cjs +688 -45
- package/dist/api/v3.d.cts +2 -2
- package/dist/api/v3.d.ts +2 -2
- package/dist/api/v3.js +3 -3
- package/dist/{chunk-S3PEKX6H.js → chunk-3YR47WTD.js} +53 -547
- package/dist/{chunk-57HTKX3P.js → chunk-74R5B2EZ.js} +1 -1
- package/dist/{chunk-KL4TZSZV.js → chunk-7Y6JCIK3.js} +1 -1
- package/dist/{chunk-3JEE5RJU.js → chunk-EBSI6VQX.js} +457 -16
- package/dist/{chunk-OTRVGNZQ.js → chunk-ESEEWELA.js} +547 -2
- package/dist/{chunk-224TSMEB.js → chunk-IJD6D7HU.js} +137 -41
- package/dist/{chunk-CVSD3UNK.js → chunk-O4EDZR44.js} +3 -1
- package/dist/{chunk-ZFCZ7XXH.js → chunk-VA24T4EB.js} +1 -1
- package/dist/core/commands/formatting-commands.d.cts +1 -1
- package/dist/core/commands/formatting-commands.d.ts +1 -1
- package/dist/core/commands/image-commands.d.cts +1 -1
- package/dist/core/commands/image-commands.d.ts +1 -1
- package/dist/core/commands/section-layout-commands.d.cts +1 -1
- package/dist/core/commands/section-layout-commands.d.ts +1 -1
- package/dist/core/commands/style-commands.d.cts +1 -1
- package/dist/core/commands/style-commands.d.ts +1 -1
- package/dist/core/commands/table-structure-commands.d.cts +1 -1
- package/dist/core/commands/table-structure-commands.d.ts +1 -1
- package/dist/core/commands/text-commands.d.cts +1 -1
- package/dist/core/commands/text-commands.d.ts +1 -1
- package/dist/core/selection/mapping.d.cts +1 -1
- package/dist/core/selection/mapping.d.ts +1 -1
- package/dist/core/state/editor-state.d.cts +1 -1
- package/dist/core/state/editor-state.d.ts +1 -1
- package/dist/index.cjs +1289 -615
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +105 -19
- package/dist/io/docx-session.d.cts +3 -3
- package/dist/io/docx-session.d.ts +3 -3
- package/dist/{loader-B2H99237.d.cts → loader-CK3lZy4h.d.cts} +2 -2
- package/dist/{loader-DfTjqVwn.d.ts → loader-CQXplstv.d.ts} +2 -2
- package/dist/{public-types-S8gTYwKo.d.cts → public-types-BR1SYK2F.d.cts} +140 -3
- package/dist/{public-types-B5lOUIrP.d.ts → public-types-DXNZVKrS.d.ts} +140 -3
- package/dist/public-types.cjs +3 -1
- package/dist/public-types.d.cts +1 -1
- package/dist/public-types.d.ts +1 -1
- package/dist/public-types.js +1 -1
- package/dist/runtime/collab.d.cts +2 -2
- package/dist/runtime/collab.d.ts +2 -2
- package/dist/runtime/document-runtime.cjs +591 -54
- package/dist/runtime/document-runtime.d.cts +1 -1
- package/dist/runtime/document-runtime.d.ts +1 -1
- package/dist/runtime/document-runtime.js +4 -4
- package/dist/{session-CBDIOYXA.d.ts → session-C9UjrhJF.d.ts} +2 -2
- package/dist/{session-CR2A1hGZ.d.cts → session-CSbwkgII.d.cts} +2 -2
- package/dist/session.d.cts +4 -4
- package/dist/session.d.ts +4 -4
- package/dist/tailwind.cjs +54 -546
- package/dist/tailwind.d.cts +1 -1
- package/dist/tailwind.d.ts +1 -1
- package/dist/tailwind.js +4 -4
- package/dist/{types-yty2K-hk.d.cts → types-CZtAueri.d.cts} +1 -1
- package/dist/{types-B-90ywjU.d.ts → types-RzkCXDNV.d.ts} +1 -1
- package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +2 -2
- package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +2 -2
- package/dist/ui-tailwind/editor-surface/search-plugin.js +2 -2
- package/dist/ui-tailwind.cjs +54 -546
- package/dist/ui-tailwind.d.cts +2 -2
- package/dist/ui-tailwind.d.ts +2 -2
- package/dist/ui-tailwind.js +4 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -15747,7 +15747,8 @@ function buildResolvedSections(document2) {
|
|
|
15747
15747
|
const mainSurface = createEditorSurfaceSnapshot(
|
|
15748
15748
|
document2,
|
|
15749
15749
|
createSelectionSnapshot(0, 0),
|
|
15750
|
-
MAIN_STORY_TARGET
|
|
15750
|
+
MAIN_STORY_TARGET,
|
|
15751
|
+
{ editableTargetsByBlockPath: NO_EDITABLE_TARGETS_INDEX }
|
|
15751
15752
|
);
|
|
15752
15753
|
const sections = [];
|
|
15753
15754
|
let sectionStart = 0;
|
|
@@ -35768,9 +35769,11 @@ function applyRevisionAction(options) {
|
|
|
35768
35769
|
);
|
|
35769
35770
|
}
|
|
35770
35771
|
const slice = story.units.slice(range.from, range.to);
|
|
35771
|
-
|
|
35772
|
-
(unit) => unit.kind === "
|
|
35773
|
-
)
|
|
35772
|
+
const touchesStructuralContent = slice.some(
|
|
35773
|
+
(unit) => unit.kind === "opaque_block" || unit.kind === "structural_block"
|
|
35774
|
+
);
|
|
35775
|
+
const touchesParagraphBoundary = slice.some((unit) => unit.kind === "paragraph_break");
|
|
35776
|
+
if (touchesStructuralContent || touchesParagraphBoundary && !canApplyRuntimeTextBlockDeletion(revision, options.intent)) {
|
|
35774
35777
|
return skippedResult(
|
|
35775
35778
|
options,
|
|
35776
35779
|
"structural-range",
|
|
@@ -35778,7 +35781,7 @@ function applyRevisionAction(options) {
|
|
|
35778
35781
|
);
|
|
35779
35782
|
}
|
|
35780
35783
|
if (slice.some(
|
|
35781
|
-
(unit) => unit.kind === "image" || unit.kind === "opaque_inline"
|
|
35784
|
+
(unit) => unit.kind === "image" || unit.kind === "opaque_inline" || unit.kind === "protected_inline"
|
|
35782
35785
|
)) {
|
|
35783
35786
|
return skippedResult(
|
|
35784
35787
|
options,
|
|
@@ -35833,6 +35836,9 @@ function applyRevisionAction(options) {
|
|
|
35833
35836
|
detachedRevisionIds: findNewDetachedRevisionIds(options.store, nextStore)
|
|
35834
35837
|
};
|
|
35835
35838
|
}
|
|
35839
|
+
function canApplyRuntimeTextBlockDeletion(revision, intent) {
|
|
35840
|
+
return revision.metadata.source === "runtime" && (intent === "accept" && revision.kind === "deletion" && (revision.metadata.semanticKind === "replacement" || revision.metadata.semanticKind === "deletion") || intent === "reject" && revision.kind === "insertion" && (revision.metadata.semanticKind === "replacement" || revision.metadata.semanticKind === "structural-change"));
|
|
35841
|
+
}
|
|
35836
35842
|
function applyPairedMoveAction(options, revision) {
|
|
35837
35843
|
const resultingStatus = toResultingStatus(options.intent);
|
|
35838
35844
|
return {
|
|
@@ -36936,6 +36942,11 @@ function executeEditorCommand(state, command, context) {
|
|
|
36936
36942
|
);
|
|
36937
36943
|
return buildDocumentReplaceTransaction(state, context, result);
|
|
36938
36944
|
}
|
|
36945
|
+
case "fragment.insert-tracked": {
|
|
36946
|
+
const result = applySuggestingFragmentInsert(state, command.fragment, context);
|
|
36947
|
+
if (result) return result;
|
|
36948
|
+
return createTransaction(state, { historyBoundary: "skip", markDirty: false });
|
|
36949
|
+
}
|
|
36939
36950
|
case "runtime.set-read-only":
|
|
36940
36951
|
return createTransaction(
|
|
36941
36952
|
{
|
|
@@ -38181,7 +38192,7 @@ function applyTextCommand(state, timestamp, apply) {
|
|
|
38181
38192
|
const reviewState = remapReviewStateAfterContentChange(
|
|
38182
38193
|
state,
|
|
38183
38194
|
result.document,
|
|
38184
|
-
result.mapping
|
|
38195
|
+
result.mapping ?? createEmptyMapping()
|
|
38185
38196
|
);
|
|
38186
38197
|
const scopeTagTouches = collectScopeTagTouches(
|
|
38187
38198
|
state.document.review.comments,
|
|
@@ -38521,6 +38532,38 @@ function isSingleParagraphSuggestingRange(document2, from, to) {
|
|
|
38521
38532
|
);
|
|
38522
38533
|
return ranges.some((range) => from >= range.start && to <= range.end);
|
|
38523
38534
|
}
|
|
38535
|
+
function isTextOnlySuggestingRange(document2, from, to) {
|
|
38536
|
+
const story = parseTextStory(document2.content);
|
|
38537
|
+
const range = normalizeTextStoryRange(story, from, to);
|
|
38538
|
+
if (!range) {
|
|
38539
|
+
return isSingleParagraphSuggestingRange(document2, from, to);
|
|
38540
|
+
}
|
|
38541
|
+
const rootStoryTextOnly = story.units.slice(range.from, range.to).every(isSuggestingTextReplacementUnit);
|
|
38542
|
+
if (rootStoryTextOnly) return true;
|
|
38543
|
+
return isSingleParagraphSuggestingRange(document2, from, to);
|
|
38544
|
+
}
|
|
38545
|
+
function normalizeTextStoryRange(story, from, to) {
|
|
38546
|
+
const start = Math.min(from, to);
|
|
38547
|
+
const end = Math.max(from, to);
|
|
38548
|
+
if (start < 0 || end > story.size) return null;
|
|
38549
|
+
return { from: start, to: end };
|
|
38550
|
+
}
|
|
38551
|
+
function isSuggestingTextReplacementUnit(unit) {
|
|
38552
|
+
switch (unit.kind) {
|
|
38553
|
+
case "text":
|
|
38554
|
+
case "tab":
|
|
38555
|
+
case "hard_break":
|
|
38556
|
+
case "paragraph_break":
|
|
38557
|
+
case "scope_marker":
|
|
38558
|
+
return true;
|
|
38559
|
+
case "protected_inline":
|
|
38560
|
+
case "image":
|
|
38561
|
+
case "opaque_inline":
|
|
38562
|
+
case "opaque_block":
|
|
38563
|
+
case "structural_block":
|
|
38564
|
+
return false;
|
|
38565
|
+
}
|
|
38566
|
+
}
|
|
38524
38567
|
function collectSuggestingParagraphRanges(blocks, startCursor, output, addRootParagraphBoundaries) {
|
|
38525
38568
|
let cursor = startCursor;
|
|
38526
38569
|
for (let index = 0; index < blocks.length; index += 1) {
|
|
@@ -38593,10 +38636,10 @@ function applySuggestingInsert(state, text, context, formatting) {
|
|
|
38593
38636
|
const from = Math.min(selection.anchor, selection.head);
|
|
38594
38637
|
const to = Math.max(selection.anchor, selection.head);
|
|
38595
38638
|
const isCollapsed = from === to;
|
|
38596
|
-
if (!isCollapsed && !
|
|
38639
|
+
if (!isCollapsed && !isTextOnlySuggestingRange(state.document, from, to)) {
|
|
38597
38640
|
return createSuggestingUnsupportedTransaction(
|
|
38598
38641
|
state,
|
|
38599
|
-
"Suggesting mode
|
|
38642
|
+
"Suggesting mode text replacement ranges must contain only editable text and paragraph breaks."
|
|
38600
38643
|
);
|
|
38601
38644
|
}
|
|
38602
38645
|
if (isCollapsed) {
|
|
@@ -38705,7 +38748,7 @@ function applySuggestingInsert(state, text, context, formatting) {
|
|
|
38705
38748
|
const reviewState = remapReviewStateAfterContentChange(
|
|
38706
38749
|
state,
|
|
38707
38750
|
result.document,
|
|
38708
|
-
result.mapping
|
|
38751
|
+
result.mapping ?? createEmptyMapping()
|
|
38709
38752
|
);
|
|
38710
38753
|
const replacementSuggestionId = createSuggestingRevisionId(
|
|
38711
38754
|
reviewState.document.review.revisions,
|
|
@@ -38770,6 +38813,131 @@ function applySuggestingInsert(state, text, context, formatting) {
|
|
|
38770
38813
|
activeCommentId: reviewState.activeCommentId
|
|
38771
38814
|
}
|
|
38772
38815
|
},
|
|
38816
|
+
{
|
|
38817
|
+
historyBoundary: "push",
|
|
38818
|
+
markDirty: true,
|
|
38819
|
+
mapping: result.mapping ?? createEmptyMapping(),
|
|
38820
|
+
effects: {
|
|
38821
|
+
...reviewState.effects,
|
|
38822
|
+
revisionAuthored: { changeId: insertionRevision.changeId, kind: "insertion" }
|
|
38823
|
+
}
|
|
38824
|
+
}
|
|
38825
|
+
);
|
|
38826
|
+
}
|
|
38827
|
+
function applySuggestingFragmentInsert(state, fragment, context) {
|
|
38828
|
+
if (state.readOnly) {
|
|
38829
|
+
return createTransaction(state, { historyBoundary: "skip", markDirty: false });
|
|
38830
|
+
}
|
|
38831
|
+
if (fragment.blocks.length === 0) {
|
|
38832
|
+
return createTransaction(state, { historyBoundary: "skip", markDirty: false });
|
|
38833
|
+
}
|
|
38834
|
+
if (!isTrackableSuggestingFragment(fragment)) {
|
|
38835
|
+
return createSuggestingUnsupportedTransaction(
|
|
38836
|
+
state,
|
|
38837
|
+
"Suggesting mode structured fragment replacement supports paragraph/text fragments only."
|
|
38838
|
+
);
|
|
38839
|
+
}
|
|
38840
|
+
const authorId = context.defaultAuthorId ?? "unknown";
|
|
38841
|
+
const selection = state.selection;
|
|
38842
|
+
const from = Math.min(selection.anchor, selection.head);
|
|
38843
|
+
const to = Math.max(selection.anchor, selection.head);
|
|
38844
|
+
const isCollapsed = from === to;
|
|
38845
|
+
if (!isCollapsed && !isTextOnlySuggestingRange(state.document, from, to)) {
|
|
38846
|
+
return createSuggestingUnsupportedTransaction(
|
|
38847
|
+
state,
|
|
38848
|
+
"Suggesting mode structured fragment replacement ranges must contain only editable text and paragraph breaks."
|
|
38849
|
+
);
|
|
38850
|
+
}
|
|
38851
|
+
const storyBefore = parseTextStory(state.document.content);
|
|
38852
|
+
const insertSelection = createSelectionSnapshot(to, to);
|
|
38853
|
+
const result = structureLayer.applyFragmentInsert(
|
|
38854
|
+
state.document,
|
|
38855
|
+
insertSelection,
|
|
38856
|
+
fragment,
|
|
38857
|
+
context
|
|
38858
|
+
);
|
|
38859
|
+
if (!result.changed) {
|
|
38860
|
+
return createTransaction(state, { historyBoundary: "skip", markDirty: false });
|
|
38861
|
+
}
|
|
38862
|
+
const storyAfter = parseTextStory(result.document.content);
|
|
38863
|
+
const insertedFrom = to;
|
|
38864
|
+
const insertedTo = to + Math.max(0, storyAfter.size - storyBefore.size);
|
|
38865
|
+
if (insertedTo <= insertedFrom) {
|
|
38866
|
+
return createTransaction(state, { historyBoundary: "skip", markDirty: false });
|
|
38867
|
+
}
|
|
38868
|
+
const reviewState = remapReviewStateAfterContentChange(
|
|
38869
|
+
state,
|
|
38870
|
+
result.document,
|
|
38871
|
+
result.mapping ?? createEmptyMapping()
|
|
38872
|
+
);
|
|
38873
|
+
const replacementSuggestionId = !isCollapsed ? createSuggestingRevisionId(
|
|
38874
|
+
reviewState.document.review.revisions,
|
|
38875
|
+
context.timestamp,
|
|
38876
|
+
authorId
|
|
38877
|
+
) : void 0;
|
|
38878
|
+
let deletionRevision = !isCollapsed ? createAuthoredRevision(
|
|
38879
|
+
reviewState.document.review.revisions,
|
|
38880
|
+
"deletion",
|
|
38881
|
+
from,
|
|
38882
|
+
to,
|
|
38883
|
+
authorId,
|
|
38884
|
+
context.timestamp,
|
|
38885
|
+
createSuggestionMetadata({
|
|
38886
|
+
suggestionId: replacementSuggestionId,
|
|
38887
|
+
semanticKind: "replacement"
|
|
38888
|
+
})
|
|
38889
|
+
) : void 0;
|
|
38890
|
+
const insertionRevision = createAuthoredRevision(
|
|
38891
|
+
{
|
|
38892
|
+
...reviewState.document.review.revisions,
|
|
38893
|
+
...deletionRevision ? { [deletionRevision.changeId]: deletionRevision } : {}
|
|
38894
|
+
},
|
|
38895
|
+
"insertion",
|
|
38896
|
+
insertedFrom,
|
|
38897
|
+
insertedTo,
|
|
38898
|
+
authorId,
|
|
38899
|
+
context.timestamp,
|
|
38900
|
+
createSuggestionMetadata(
|
|
38901
|
+
deletionRevision ? {
|
|
38902
|
+
suggestionId: replacementSuggestionId,
|
|
38903
|
+
semanticKind: "replacement",
|
|
38904
|
+
linkedRevisionIds: [deletionRevision.changeId]
|
|
38905
|
+
} : {
|
|
38906
|
+
semanticKind: "structural-change"
|
|
38907
|
+
}
|
|
38908
|
+
)
|
|
38909
|
+
);
|
|
38910
|
+
if (deletionRevision) {
|
|
38911
|
+
deletionRevision = {
|
|
38912
|
+
...deletionRevision,
|
|
38913
|
+
metadata: {
|
|
38914
|
+
...deletionRevision.metadata,
|
|
38915
|
+
linkedRevisionIds: [insertionRevision.changeId]
|
|
38916
|
+
}
|
|
38917
|
+
};
|
|
38918
|
+
}
|
|
38919
|
+
const finalDocument = {
|
|
38920
|
+
...reviewState.document,
|
|
38921
|
+
review: {
|
|
38922
|
+
...reviewState.document.review,
|
|
38923
|
+
revisions: {
|
|
38924
|
+
...reviewState.document.review.revisions,
|
|
38925
|
+
...deletionRevision ? { [deletionRevision.changeId]: deletionRevision } : {},
|
|
38926
|
+
[insertionRevision.changeId]: insertionRevision
|
|
38927
|
+
}
|
|
38928
|
+
}
|
|
38929
|
+
};
|
|
38930
|
+
return createTransaction(
|
|
38931
|
+
{
|
|
38932
|
+
...state,
|
|
38933
|
+
document: finalDocument,
|
|
38934
|
+
selection: createSelectionSnapshot(insertedTo, insertedTo),
|
|
38935
|
+
warnings: reviewState.warnings,
|
|
38936
|
+
runtime: {
|
|
38937
|
+
...state.runtime,
|
|
38938
|
+
activeCommentId: reviewState.activeCommentId
|
|
38939
|
+
}
|
|
38940
|
+
},
|
|
38773
38941
|
{
|
|
38774
38942
|
historyBoundary: "push",
|
|
38775
38943
|
markDirty: true,
|
|
@@ -38781,6 +38949,10 @@ function applySuggestingInsert(state, text, context, formatting) {
|
|
|
38781
38949
|
}
|
|
38782
38950
|
);
|
|
38783
38951
|
}
|
|
38952
|
+
function isTrackableSuggestingFragment(fragment) {
|
|
38953
|
+
const story = parseTextStory({ type: "doc", children: fragment.blocks });
|
|
38954
|
+
return story.units.every(isSuggestingTextReplacementUnit);
|
|
38955
|
+
}
|
|
38784
38956
|
function applySuggestingDelete(state, direction, context) {
|
|
38785
38957
|
if (state.readOnly) {
|
|
38786
38958
|
return createTransaction(state, { historyBoundary: "skip", markDirty: false });
|
|
@@ -38790,10 +38962,10 @@ function applySuggestingDelete(state, direction, context) {
|
|
|
38790
38962
|
const from = Math.min(selection.anchor, selection.head);
|
|
38791
38963
|
const to = Math.max(selection.anchor, selection.head);
|
|
38792
38964
|
const isCollapsed = from === to;
|
|
38793
|
-
if (!isCollapsed && !
|
|
38965
|
+
if (!isCollapsed && !isTextOnlySuggestingRange(state.document, from, to)) {
|
|
38794
38966
|
return createSuggestingUnsupportedTransaction(
|
|
38795
38967
|
state,
|
|
38796
|
-
"Suggesting mode
|
|
38968
|
+
"Suggesting mode text deletion ranges must contain only editable text and paragraph breaks."
|
|
38797
38969
|
);
|
|
38798
38970
|
}
|
|
38799
38971
|
let deleteFrom;
|
|
@@ -49918,11 +50090,9 @@ function compileParagraphReplacement(entry, proposed, options) {
|
|
|
49918
50090
|
};
|
|
49919
50091
|
}
|
|
49920
50092
|
if (proposed.proposedContent.kind === "structured") {
|
|
49921
|
-
if (options.posture === "suggest-mode") {
|
|
49922
|
-
return null;
|
|
49923
|
-
}
|
|
49924
50093
|
const fragment = proposed.proposedContent.structured;
|
|
49925
50094
|
if (!isStructuredReplacementContent(fragment)) return null;
|
|
50095
|
+
const stepKind = options.posture === "suggest-mode" ? "fragment-replace-tracked" : "fragment-replace";
|
|
49926
50096
|
const blockCount = fragment.blocks.length;
|
|
49927
50097
|
const summaryScope = rangeKind === "inline-marker" ? `paragraph #${entry.blockIndex} inline-marker range [${effectiveRange.from}..${effectiveRange.to}]` : rangeKind === "opaque-preserving-text" ? `paragraph #${entry.blockIndex} opaque-preserving text range [${effectiveRange.from}..${effectiveRange.to}]` : `paragraph #${entry.blockIndex}`;
|
|
49928
50098
|
const actionVerb = proposed.operation === "insert-before" ? "insert before" : proposed.operation === "insert-after" ? "insert after" : "replace";
|
|
@@ -49933,8 +50103,8 @@ function compileParagraphReplacement(entry, proposed, options) {
|
|
|
49933
50103
|
operation: proposed.operation,
|
|
49934
50104
|
steps: Object.freeze([
|
|
49935
50105
|
{
|
|
49936
|
-
kind:
|
|
49937
|
-
summary: actionSummary
|
|
50106
|
+
kind: stepKind,
|
|
50107
|
+
summary: stepKind === "fragment-replace" ? actionSummary : `suggest-mode ${actionSummary}`,
|
|
49938
50108
|
...textLeafEditableTargetHint(entry, blockRange) ? { editableTargetHint: textLeafEditableTargetHint(entry, blockRange) } : {},
|
|
49939
50109
|
range: { from: operationRange.from, to: operationRange.to },
|
|
49940
50110
|
fragment
|
|
@@ -50021,7 +50191,7 @@ function compileScopeKind(entry, options) {
|
|
|
50021
50191
|
};
|
|
50022
50192
|
}
|
|
50023
50193
|
function compileScopeReplacement(entry, proposed, options) {
|
|
50024
|
-
if (entry.handle.provenance !== "marker-backed" || proposed.operation !== "replace"
|
|
50194
|
+
if (entry.handle.provenance !== "marker-backed" || proposed.operation !== "replace") {
|
|
50025
50195
|
return null;
|
|
50026
50196
|
}
|
|
50027
50197
|
const markerRange = buildScopePositionMap(options.document).markerScopes.get(
|
|
@@ -50030,14 +50200,15 @@ function compileScopeReplacement(entry, proposed, options) {
|
|
|
50030
50200
|
if (!markerRange) return null;
|
|
50031
50201
|
if (proposed.proposedContent.kind === "text") {
|
|
50032
50202
|
const text = proposed.proposedContent.text ?? "";
|
|
50203
|
+
const stepKind = options.posture === "suggest-mode" ? "text-insert-tracked" : "text-replace";
|
|
50033
50204
|
return {
|
|
50034
50205
|
scopeId: entry.handle.scopeId,
|
|
50035
50206
|
targetKind: "scope",
|
|
50036
50207
|
operation: proposed.operation,
|
|
50037
50208
|
steps: Object.freeze([
|
|
50038
50209
|
{
|
|
50039
|
-
kind:
|
|
50040
|
-
summary: `replace multi-paragraph scope ${entry.handle.scopeId} text [${markerRange.from}..${markerRange.to}] (len ${text.length})`,
|
|
50210
|
+
kind: stepKind,
|
|
50211
|
+
summary: stepKind === "text-replace" ? `replace multi-paragraph scope ${entry.handle.scopeId} text [${markerRange.from}..${markerRange.to}] (len ${text.length})` : `suggest-mode replace multi-paragraph scope ${entry.handle.scopeId} text [${markerRange.from}..${markerRange.to}] (len ${text.length})`,
|
|
50041
50212
|
range: { from: markerRange.from, to: markerRange.to },
|
|
50042
50213
|
text,
|
|
50043
50214
|
...proposed.formatting ? { formatting: proposed.formatting } : {}
|
|
@@ -50050,14 +50221,15 @@ function compileScopeReplacement(entry, proposed, options) {
|
|
|
50050
50221
|
if (proposed.proposedContent.kind === "structured") {
|
|
50051
50222
|
const fragment = proposed.proposedContent.structured;
|
|
50052
50223
|
if (!isStructuredReplacementContent(fragment)) return null;
|
|
50224
|
+
const stepKind = options.posture === "suggest-mode" ? "fragment-replace-tracked" : "fragment-replace";
|
|
50053
50225
|
return {
|
|
50054
50226
|
scopeId: entry.handle.scopeId,
|
|
50055
50227
|
targetKind: "scope",
|
|
50056
50228
|
operation: proposed.operation,
|
|
50057
50229
|
steps: Object.freeze([
|
|
50058
50230
|
{
|
|
50059
|
-
kind:
|
|
50060
|
-
summary: `replace multi-paragraph scope ${entry.handle.scopeId} with structured fragment [${markerRange.from}..${markerRange.to}] (${fragment.blocks.length} block(s))`,
|
|
50231
|
+
kind: stepKind,
|
|
50232
|
+
summary: stepKind === "fragment-replace" ? `replace multi-paragraph scope ${entry.handle.scopeId} with structured fragment [${markerRange.from}..${markerRange.to}] (${fragment.blocks.length} block(s))` : `suggest-mode replace multi-paragraph scope ${entry.handle.scopeId} with structured fragment [${markerRange.from}..${markerRange.to}] (${fragment.blocks.length} block(s))`,
|
|
50061
50233
|
range: { from: markerRange.from, to: markerRange.to },
|
|
50062
50234
|
fragment
|
|
50063
50235
|
}
|
|
@@ -50439,6 +50611,99 @@ function paragraphFirstMarkerStart(paragraph, knownScopeIds) {
|
|
|
50439
50611
|
}
|
|
50440
50612
|
return null;
|
|
50441
50613
|
}
|
|
50614
|
+
function paragraphHasMarkerEnd(paragraph, scopeId) {
|
|
50615
|
+
return paragraph.children.some(
|
|
50616
|
+
(child) => child.type === "scope_marker_end" && child.scopeId === scopeId
|
|
50617
|
+
);
|
|
50618
|
+
}
|
|
50619
|
+
function paragraphSameParagraphMarkerScopeId(paragraph, knownScopeIds) {
|
|
50620
|
+
const markerScopeId = paragraphFirstMarkerStart(paragraph, knownScopeIds);
|
|
50621
|
+
if (!markerScopeId) return null;
|
|
50622
|
+
return paragraphHasMarkerEnd(paragraph, markerScopeId) ? markerScopeId : null;
|
|
50623
|
+
}
|
|
50624
|
+
function markerStableRefOverride(markerScopeId, semanticPath, overlay) {
|
|
50625
|
+
const hint = stableRefHintForScopeId(markerScopeId, overlay);
|
|
50626
|
+
if (hint === "semantic-path") {
|
|
50627
|
+
return {
|
|
50628
|
+
kind: "semantic-path",
|
|
50629
|
+
value: semanticPath.join("/")
|
|
50630
|
+
};
|
|
50631
|
+
}
|
|
50632
|
+
return { kind: "scope-id", value: markerScopeId };
|
|
50633
|
+
}
|
|
50634
|
+
function enumerateNestedMarkerBackedParagraphs(blocks, input) {
|
|
50635
|
+
const out = [];
|
|
50636
|
+
for (let childIndex = 0; childIndex < blocks.length; childIndex += 1) {
|
|
50637
|
+
const block = blocks[childIndex];
|
|
50638
|
+
if (!block) continue;
|
|
50639
|
+
if (block.type === "paragraph") {
|
|
50640
|
+
const markerScopeId = paragraphSameParagraphMarkerScopeId(
|
|
50641
|
+
block,
|
|
50642
|
+
input.knownOverlayScopeIds
|
|
50643
|
+
);
|
|
50644
|
+
if (!markerScopeId) continue;
|
|
50645
|
+
const kind = detectParagraphKind(block);
|
|
50646
|
+
const semanticPath = [
|
|
50647
|
+
...input.semanticPrefix,
|
|
50648
|
+
kind,
|
|
50649
|
+
String(childIndex)
|
|
50650
|
+
];
|
|
50651
|
+
const handle = buildHandle(
|
|
50652
|
+
markerScopeId,
|
|
50653
|
+
input.documentId,
|
|
50654
|
+
semanticPath,
|
|
50655
|
+
"marker-backed",
|
|
50656
|
+
"marker-backed",
|
|
50657
|
+
input.parentScopeId,
|
|
50658
|
+
markerStableRefOverride(markerScopeId, semanticPath, input.overlay)
|
|
50659
|
+
);
|
|
50660
|
+
out.push({
|
|
50661
|
+
kind,
|
|
50662
|
+
handle,
|
|
50663
|
+
paragraph: block,
|
|
50664
|
+
blockIndex: input.rootBlockIndex,
|
|
50665
|
+
classifications: input.classificationIndex.get(markerScopeId) ?? Object.freeze([])
|
|
50666
|
+
});
|
|
50667
|
+
continue;
|
|
50668
|
+
}
|
|
50669
|
+
if (block.type === "sdt") {
|
|
50670
|
+
out.push(
|
|
50671
|
+
...enumerateNestedMarkerBackedParagraphs(block.children, {
|
|
50672
|
+
...input,
|
|
50673
|
+
semanticPrefix: [
|
|
50674
|
+
...input.semanticPrefix,
|
|
50675
|
+
"sdt",
|
|
50676
|
+
String(childIndex)
|
|
50677
|
+
]
|
|
50678
|
+
})
|
|
50679
|
+
);
|
|
50680
|
+
continue;
|
|
50681
|
+
}
|
|
50682
|
+
if (block.type === "table") {
|
|
50683
|
+
for (let rowIdx = 0; rowIdx < block.rows.length; rowIdx += 1) {
|
|
50684
|
+
const row2 = block.rows[rowIdx];
|
|
50685
|
+
for (let cellIdx = 0; cellIdx < row2.cells.length; cellIdx += 1) {
|
|
50686
|
+
const cell = row2.cells[cellIdx];
|
|
50687
|
+
out.push(
|
|
50688
|
+
...enumerateNestedMarkerBackedParagraphs(cell.children, {
|
|
50689
|
+
...input,
|
|
50690
|
+
semanticPrefix: [
|
|
50691
|
+
...input.semanticPrefix,
|
|
50692
|
+
"table",
|
|
50693
|
+
String(childIndex),
|
|
50694
|
+
"row",
|
|
50695
|
+
String(rowIdx),
|
|
50696
|
+
"cell",
|
|
50697
|
+
String(cellIdx)
|
|
50698
|
+
]
|
|
50699
|
+
})
|
|
50700
|
+
);
|
|
50701
|
+
}
|
|
50702
|
+
}
|
|
50703
|
+
}
|
|
50704
|
+
}
|
|
50705
|
+
return out;
|
|
50706
|
+
}
|
|
50442
50707
|
function enumerateFieldsInParagraph(paragraph, blockIndex, documentId, parentScopeId) {
|
|
50443
50708
|
const out = [];
|
|
50444
50709
|
for (let i = 0; i < paragraph.children.length; i += 1) {
|
|
@@ -50721,6 +50986,17 @@ function enumerateScopes(document2, inputs = {}) {
|
|
|
50721
50986
|
cellIndex: cellIdx,
|
|
50722
50987
|
classifications: Object.freeze([])
|
|
50723
50988
|
});
|
|
50989
|
+
for (const nested of enumerateNestedMarkerBackedParagraphs(cell.children, {
|
|
50990
|
+
documentId,
|
|
50991
|
+
rootBlockIndex: index,
|
|
50992
|
+
semanticPrefix: cellSemanticPath,
|
|
50993
|
+
parentScopeId: cellScopeId,
|
|
50994
|
+
knownOverlayScopeIds,
|
|
50995
|
+
classificationIndex,
|
|
50996
|
+
overlay: inputs.overlay
|
|
50997
|
+
})) {
|
|
50998
|
+
results.push(nested);
|
|
50999
|
+
}
|
|
50724
51000
|
}
|
|
50725
51001
|
}
|
|
50726
51002
|
}
|
|
@@ -51206,16 +51482,12 @@ function replaceTextCapability(scope, context) {
|
|
|
51206
51482
|
);
|
|
51207
51483
|
}
|
|
51208
51484
|
if (scope.kind === "scope") {
|
|
51209
|
-
if (scope.workflow.effectiveMode === "suggest") {
|
|
51210
|
-
return unsupported(
|
|
51211
|
-
"compile-refused:scope:multi-paragraph-suggesting-not-implemented",
|
|
51212
|
-
["compile-refused:scope:multi-paragraph-suggesting-not-implemented"],
|
|
51213
|
-
["guard:suggest-mode", ...evidenceWarnings(context)]
|
|
51214
|
-
);
|
|
51215
|
-
}
|
|
51216
51485
|
return supported(
|
|
51217
51486
|
"compile-supported:scope:multi-paragraph-text-replace",
|
|
51218
|
-
|
|
51487
|
+
[
|
|
51488
|
+
...scope.workflow.effectiveMode === "suggest" ? ["guard:suggest-mode"] : [],
|
|
51489
|
+
...evidenceWarnings(context)
|
|
51490
|
+
]
|
|
51219
51491
|
);
|
|
51220
51492
|
}
|
|
51221
51493
|
if (!PARAGRAPH_LIKE.has(scope.kind)) {
|
|
@@ -51269,34 +51541,24 @@ function replaceFragmentCapability(scope, context) {
|
|
|
51269
51541
|
);
|
|
51270
51542
|
}
|
|
51271
51543
|
if (scope.kind === "scope") {
|
|
51272
|
-
if (scope.workflow.effectiveMode === "suggest") {
|
|
51273
|
-
return unsupported(
|
|
51274
|
-
"compile-refused:scope:multi-paragraph-structured-suggesting-not-implemented",
|
|
51275
|
-
[
|
|
51276
|
-
"compile-refused:scope:multi-paragraph-structured-suggesting-not-implemented"
|
|
51277
|
-
],
|
|
51278
|
-
["guard:suggest-mode", ...evidenceWarnings(context)]
|
|
51279
|
-
);
|
|
51280
|
-
}
|
|
51281
51544
|
return supported(
|
|
51282
51545
|
"compile-supported:scope:multi-paragraph-fragment-replace",
|
|
51283
|
-
|
|
51546
|
+
[
|
|
51547
|
+
...scope.workflow.effectiveMode === "suggest" ? ["guard:suggest-mode"] : [],
|
|
51548
|
+
...evidenceWarnings(context)
|
|
51549
|
+
]
|
|
51284
51550
|
);
|
|
51285
51551
|
}
|
|
51286
51552
|
if (!PARAGRAPH_LIKE.has(scope.kind)) {
|
|
51287
51553
|
const reason = `compile-refused:${scope.kind}`;
|
|
51288
51554
|
return unsupported(reason, [reason], evidenceWarnings(context));
|
|
51289
51555
|
}
|
|
51290
|
-
if (scope.workflow.effectiveMode === "suggest") {
|
|
51291
|
-
return unsupported(
|
|
51292
|
-
`compile-refused:${scope.kind}:structured-suggesting-not-implemented`,
|
|
51293
|
-
[`compile-refused:${scope.kind}:structured-suggesting-not-implemented`],
|
|
51294
|
-
["guard:suggest-mode"]
|
|
51295
|
-
);
|
|
51296
|
-
}
|
|
51297
51556
|
return supported(
|
|
51298
|
-
"compile-supported:paragraph-like:fragment-replace",
|
|
51299
|
-
|
|
51557
|
+
scope.workflow.effectiveMode === "suggest" ? "compile-supported:paragraph-like:fragment-replace-tracked" : "compile-supported:paragraph-like:fragment-replace",
|
|
51558
|
+
[
|
|
51559
|
+
...scope.workflow.effectiveMode === "suggest" ? ["guard:suggest-mode"] : [],
|
|
51560
|
+
...evidenceWarnings(context)
|
|
51561
|
+
]
|
|
51300
51562
|
);
|
|
51301
51563
|
}
|
|
51302
51564
|
function formattingCapability(scope, context) {
|
|
@@ -52350,6 +52612,14 @@ function supportedNonTextCommandEvidence(target) {
|
|
|
52350
52612
|
if (target.commandFamily === "link-bookmark") {
|
|
52351
52613
|
return linkBookmarkCommandEvidence(target, []);
|
|
52352
52614
|
}
|
|
52615
|
+
if (target.commandFamily === "object" && isImageObjectTarget(target) && typeof target.object?.mediaId === "string" && target.object.mediaId.length > 0 && onlyBlockers(target.posture.blockers, ["unmodeled-target"])) {
|
|
52616
|
+
return {
|
|
52617
|
+
status: "supported",
|
|
52618
|
+
commandFamily: target.commandFamily,
|
|
52619
|
+
intents: commandIntentsForTarget(target),
|
|
52620
|
+
reason: "l07:image-layout-target-supported"
|
|
52621
|
+
};
|
|
52622
|
+
}
|
|
52353
52623
|
return null;
|
|
52354
52624
|
}
|
|
52355
52625
|
function onlyBlockers(blockers, allowed) {
|
|
@@ -54850,9 +55120,7 @@ function applyScopeReplacement(inputs) {
|
|
|
54850
55120
|
});
|
|
54851
55121
|
if (!plan) {
|
|
54852
55122
|
const paragraphLike = resolvedScope.kind === "paragraph" || resolvedScope.kind === "heading" || resolvedScope.kind === "list-item";
|
|
54853
|
-
const blockers = resolvedScope.kind === "scope" &&
|
|
54854
|
-
proposed.proposedContent.kind === "structured" ? "compile-refused:scope:multi-paragraph-structured-suggesting-not-implemented" : "compile-refused:scope:multi-paragraph-suggesting-not-implemented"
|
|
54855
|
-
] : resolvedScope.kind === "scope" && proposed.operation !== "replace" ? [
|
|
55123
|
+
const blockers = resolvedScope.kind === "scope" && proposed.operation !== "replace" ? [
|
|
54856
55124
|
`compile-refused:scope:operation-not-implemented:${proposed.operation}`
|
|
54857
55125
|
] : resolvedScope.kind === "scope" ? multiParagraphReplacementBlockers(
|
|
54858
55126
|
proposed.proposedContent.kind === "structured" ? "fragment" : "text"
|
|
@@ -72310,7 +72578,20 @@ function createDocumentRuntime(options) {
|
|
|
72310
72578
|
selection: prepared.selection
|
|
72311
72579
|
};
|
|
72312
72580
|
resolvedReplayTextTarget = prepared.textTarget;
|
|
72313
|
-
} else
|
|
72581
|
+
} else {
|
|
72582
|
+
const selectedListItemDeleteCommand = createSelectedListItemDeleteReplayCommand({
|
|
72583
|
+
command,
|
|
72584
|
+
document: replayState.document,
|
|
72585
|
+
selection: replayState.selection,
|
|
72586
|
+
surface: replaySnapshot.surface?.blocks ?? [],
|
|
72587
|
+
storyTarget: replayStory,
|
|
72588
|
+
timestamp: context.timestamp
|
|
72589
|
+
});
|
|
72590
|
+
if (selectedListItemDeleteCommand) {
|
|
72591
|
+
executableCommand = selectedListItemDeleteCommand;
|
|
72592
|
+
}
|
|
72593
|
+
}
|
|
72594
|
+
if (command.type === "field.refresh" || command.type === "toc.refresh" || command.type === "bookmark.edit-content" || command.type === "hyperlink.update-destination") {
|
|
72314
72595
|
const prepared = prepareModeledTargetCommandForExecution(
|
|
72315
72596
|
command,
|
|
72316
72597
|
replayState.document,
|
|
@@ -72454,7 +72735,20 @@ function createDocumentRuntime(options) {
|
|
|
72454
72735
|
selection: prepared.selection
|
|
72455
72736
|
};
|
|
72456
72737
|
resolvedReplayTextTarget = prepared.textTarget;
|
|
72457
|
-
} else
|
|
72738
|
+
} else {
|
|
72739
|
+
const selectedListItemDeleteCommand = createSelectedListItemDeleteReplayCommand({
|
|
72740
|
+
command,
|
|
72741
|
+
document: stateForCommand.document,
|
|
72742
|
+
selection: stateForCommand.selection,
|
|
72743
|
+
surface: snapshotForCommand.surface?.blocks ?? [],
|
|
72744
|
+
storyTarget: replayStory,
|
|
72745
|
+
timestamp: context.timestamp
|
|
72746
|
+
});
|
|
72747
|
+
if (selectedListItemDeleteCommand) {
|
|
72748
|
+
executableCommand = selectedListItemDeleteCommand;
|
|
72749
|
+
}
|
|
72750
|
+
}
|
|
72751
|
+
if (command.type === "field.refresh" || command.type === "toc.refresh" || command.type === "bookmark.edit-content" || command.type === "hyperlink.update-destination") {
|
|
72458
72752
|
const prepared = prepareModeledTargetCommandForExecution(
|
|
72459
72753
|
command,
|
|
72460
72754
|
stateForCommand.document,
|
|
@@ -72875,6 +73169,50 @@ function createDocumentRuntime(options) {
|
|
|
72875
73169
|
} catch (error) {
|
|
72876
73170
|
emitError(toRuntimeError(error));
|
|
72877
73171
|
}
|
|
73172
|
+
} else if (step.kind === "fragment-replace-tracked" && step.range && step.fragment && Array.isArray(step.fragment.blocks)) {
|
|
73173
|
+
const editableTarget = resolveEditableTargetHint(step.editableTargetHint);
|
|
73174
|
+
if (editableTarget === null) {
|
|
73175
|
+
emit2({
|
|
73176
|
+
type: "command_blocked",
|
|
73177
|
+
documentId: state.documentId,
|
|
73178
|
+
command: "applyScopeReplacement",
|
|
73179
|
+
reasons: [{
|
|
73180
|
+
code: "unsupported_surface",
|
|
73181
|
+
message: "Scope replacement editable target no longer resolves."
|
|
73182
|
+
}]
|
|
73183
|
+
});
|
|
73184
|
+
continue;
|
|
73185
|
+
}
|
|
73186
|
+
const dispatchRange = mapSemanticStepRangeToEditableTarget(
|
|
73187
|
+
step.range,
|
|
73188
|
+
step.editableTargetHint,
|
|
73189
|
+
editableTarget?.range
|
|
73190
|
+
);
|
|
73191
|
+
const anchor = {
|
|
73192
|
+
kind: "range",
|
|
73193
|
+
from: dispatchRange.from,
|
|
73194
|
+
to: dispatchRange.to,
|
|
73195
|
+
assoc: { start: -1, end: 1 }
|
|
73196
|
+
};
|
|
73197
|
+
const timestamp = clock();
|
|
73198
|
+
try {
|
|
73199
|
+
applyTextCommandInActiveStory(
|
|
73200
|
+
{
|
|
73201
|
+
type: "fragment.insert-tracked",
|
|
73202
|
+
fragment: step.fragment,
|
|
73203
|
+
...editableTarget?.target ? { editableTarget: editableTarget.target } : {},
|
|
73204
|
+
origin: createOrigin("api", timestamp)
|
|
73205
|
+
},
|
|
73206
|
+
{
|
|
73207
|
+
selection: createSelectionFromPublicAnchor(anchor),
|
|
73208
|
+
blockedCommandName: "applyScopeReplacement",
|
|
73209
|
+
documentModeOverride: "suggesting",
|
|
73210
|
+
skipWorkflowGuard: true
|
|
73211
|
+
}
|
|
73212
|
+
);
|
|
73213
|
+
} catch (error) {
|
|
73214
|
+
emitError(toRuntimeError(error));
|
|
73215
|
+
}
|
|
72878
73216
|
} else if (step.kind === "text-insert-tracked" && step.range && typeof step.text === "string") {
|
|
72879
73217
|
const editableTarget = resolveEditableTargetHint(step.editableTargetHint);
|
|
72880
73218
|
if (editableTarget === null) {
|
|
@@ -74857,6 +75195,38 @@ function createDocumentRuntime(options) {
|
|
|
74857
75195
|
const preSelection = selection;
|
|
74858
75196
|
const preActiveStory = activeStory;
|
|
74859
75197
|
const priorDocument = state.document;
|
|
75198
|
+
const selectedListItemDelete = createSelectedListItemDeleteReplacement({
|
|
75199
|
+
command: commandForDispatch,
|
|
75200
|
+
document: state.document,
|
|
75201
|
+
editableTarget,
|
|
75202
|
+
selection,
|
|
75203
|
+
targetResolution,
|
|
75204
|
+
timestamp
|
|
75205
|
+
});
|
|
75206
|
+
if (selectedListItemDelete && activeStory.kind === "main" && context.documentMode !== "suggesting") {
|
|
75207
|
+
const replacementCommand = {
|
|
75208
|
+
type: "document.replace",
|
|
75209
|
+
document: selectedListItemDelete.document,
|
|
75210
|
+
selection: selectedListItemDelete.selection,
|
|
75211
|
+
mapping: selectedListItemDelete.mapping,
|
|
75212
|
+
protectionSelection: selection,
|
|
75213
|
+
origin: commandForDispatch.origin
|
|
75214
|
+
};
|
|
75215
|
+
const transaction = executeEditorCommand(baseState, replacementCommand, context);
|
|
75216
|
+
commit(transaction);
|
|
75217
|
+
options.onCommandApplied?.(commandForDispatch, transaction, context, {
|
|
75218
|
+
preSelection,
|
|
75219
|
+
activeStory: preActiveStory,
|
|
75220
|
+
priorDocument
|
|
75221
|
+
});
|
|
75222
|
+
return completeDispatch(classifyAck({
|
|
75223
|
+
command: commandForDispatch,
|
|
75224
|
+
opId,
|
|
75225
|
+
priorState: baseState,
|
|
75226
|
+
transaction,
|
|
75227
|
+
newRevisionToken: state.revisionToken
|
|
75228
|
+
}));
|
|
75229
|
+
}
|
|
74860
75230
|
if (activeStory.kind === "main") {
|
|
74861
75231
|
const mainTransaction = executeEditorCommand(baseState, commandForDispatch, context);
|
|
74862
75232
|
commit(mainTransaction);
|
|
@@ -76051,7 +76421,8 @@ function getStoryPlainText(document2, storyTarget, cache) {
|
|
|
76051
76421
|
const plainText = createEditorSurfaceSnapshot(
|
|
76052
76422
|
document2,
|
|
76053
76423
|
createSelectionSnapshot(0, 0),
|
|
76054
|
-
storyTarget
|
|
76424
|
+
storyTarget,
|
|
76425
|
+
{ editableTargetsByBlockPath: NO_EDITABLE_TARGETS_INDEX }
|
|
76055
76426
|
).plainText;
|
|
76056
76427
|
cache.set(key, plainText);
|
|
76057
76428
|
return plainText;
|
|
@@ -77727,6 +78098,172 @@ function stripStoryTarget2(selection) {
|
|
|
77727
78098
|
function isTopLevelMainStoryBlockPath(blockPath) {
|
|
77728
78099
|
return typeof blockPath === "string" && /^main\/block\[\d+\]$/u.test(blockPath);
|
|
77729
78100
|
}
|
|
78101
|
+
function createSelectedListItemDeleteReplacement(input) {
|
|
78102
|
+
const { command, document: document2, editableTarget, selection, targetResolution, timestamp } = input;
|
|
78103
|
+
if (command.type !== "text.delete-backward" && command.type !== "text.delete-forward") {
|
|
78104
|
+
return null;
|
|
78105
|
+
}
|
|
78106
|
+
if (selection.isCollapsed || editableTarget?.listAddress?.operationScope !== "list-text" || targetResolution?.kind !== "accepted") {
|
|
78107
|
+
return null;
|
|
78108
|
+
}
|
|
78109
|
+
const selectionFrom = Math.min(selection.anchor, selection.head);
|
|
78110
|
+
const selectionTo = Math.max(selection.anchor, selection.head);
|
|
78111
|
+
if (selectionFrom !== targetResolution.range.from || selectionTo !== targetResolution.range.to) {
|
|
78112
|
+
return null;
|
|
78113
|
+
}
|
|
78114
|
+
const root = document2.content;
|
|
78115
|
+
const replacement = removeNumberedParagraphAtMainStoryPath(root.children, editableTarget.blockPath);
|
|
78116
|
+
if (!replacement) {
|
|
78117
|
+
return null;
|
|
78118
|
+
}
|
|
78119
|
+
const nextDocument = {
|
|
78120
|
+
...document2,
|
|
78121
|
+
updatedAt: timestamp,
|
|
78122
|
+
content: {
|
|
78123
|
+
...root,
|
|
78124
|
+
children: replacement.blocks
|
|
78125
|
+
}
|
|
78126
|
+
};
|
|
78127
|
+
const nextStorySize = parseTextStory(nextDocument.content).size;
|
|
78128
|
+
const nextAnchor = Math.min(selectionFrom, nextStorySize);
|
|
78129
|
+
return {
|
|
78130
|
+
document: nextDocument,
|
|
78131
|
+
selection: createSelectionSnapshot(nextAnchor, nextAnchor),
|
|
78132
|
+
mapping: {
|
|
78133
|
+
steps: [{
|
|
78134
|
+
from: selectionFrom,
|
|
78135
|
+
to: selectionTo,
|
|
78136
|
+
insertSize: 0
|
|
78137
|
+
}],
|
|
78138
|
+
metadata: {
|
|
78139
|
+
invalidatesStructures: true
|
|
78140
|
+
}
|
|
78141
|
+
}
|
|
78142
|
+
};
|
|
78143
|
+
}
|
|
78144
|
+
function removeNumberedParagraphAtMainStoryPath(blocks, blockPath) {
|
|
78145
|
+
const tokens = parseMainStoryBlockPathTokens(blockPath);
|
|
78146
|
+
if (!tokens) return null;
|
|
78147
|
+
return removeNumberedParagraphFromBlocks(blocks, tokens);
|
|
78148
|
+
}
|
|
78149
|
+
function removeNumberedParagraphFromBlocks(blocks, tokens) {
|
|
78150
|
+
const [token, ...rest] = tokens;
|
|
78151
|
+
if (!token || token.kind !== "block") return null;
|
|
78152
|
+
const block = blocks[token.index];
|
|
78153
|
+
if (!block) return null;
|
|
78154
|
+
if (rest.length === 0) {
|
|
78155
|
+
if (block.type !== "paragraph" || !block.numbering) {
|
|
78156
|
+
return null;
|
|
78157
|
+
}
|
|
78158
|
+
if (blocks.length === 1) {
|
|
78159
|
+
return { blocks: [{ type: "paragraph", children: [] }] };
|
|
78160
|
+
}
|
|
78161
|
+
return {
|
|
78162
|
+
blocks: [
|
|
78163
|
+
...blocks.slice(0, token.index),
|
|
78164
|
+
...blocks.slice(token.index + 1)
|
|
78165
|
+
]
|
|
78166
|
+
};
|
|
78167
|
+
}
|
|
78168
|
+
const next = rest[0];
|
|
78169
|
+
if (block.type === "table" && next?.kind === "row") {
|
|
78170
|
+
const updatedTable = removeNumberedParagraphFromTable(block, rest);
|
|
78171
|
+
if (!updatedTable) return null;
|
|
78172
|
+
return {
|
|
78173
|
+
blocks: [
|
|
78174
|
+
...blocks.slice(0, token.index),
|
|
78175
|
+
updatedTable,
|
|
78176
|
+
...blocks.slice(token.index + 1)
|
|
78177
|
+
]
|
|
78178
|
+
};
|
|
78179
|
+
}
|
|
78180
|
+
if ((block.type === "sdt" || block.type === "custom_xml") && next?.kind === "block") {
|
|
78181
|
+
const updatedChildren = removeNumberedParagraphFromBlocks(block.children, rest);
|
|
78182
|
+
if (!updatedChildren) return null;
|
|
78183
|
+
return {
|
|
78184
|
+
blocks: [
|
|
78185
|
+
...blocks.slice(0, token.index),
|
|
78186
|
+
{ ...block, children: updatedChildren.blocks },
|
|
78187
|
+
...blocks.slice(token.index + 1)
|
|
78188
|
+
]
|
|
78189
|
+
};
|
|
78190
|
+
}
|
|
78191
|
+
return null;
|
|
78192
|
+
}
|
|
78193
|
+
function removeNumberedParagraphFromTable(table, tokens) {
|
|
78194
|
+
const [rowToken, cellToken, ...childTokens] = tokens;
|
|
78195
|
+
if (rowToken?.kind !== "row" || cellToken?.kind !== "cell" || childTokens[0]?.kind !== "block") {
|
|
78196
|
+
return null;
|
|
78197
|
+
}
|
|
78198
|
+
const row2 = table.rows[rowToken.index];
|
|
78199
|
+
const cell = row2?.cells[cellToken.index];
|
|
78200
|
+
if (!row2 || !cell) return null;
|
|
78201
|
+
const updatedChildren = removeNumberedParagraphFromBlocks(cell.children, childTokens);
|
|
78202
|
+
if (!updatedChildren) return null;
|
|
78203
|
+
const nextCells = [
|
|
78204
|
+
...row2.cells.slice(0, cellToken.index),
|
|
78205
|
+
{ ...cell, children: updatedChildren.blocks },
|
|
78206
|
+
...row2.cells.slice(cellToken.index + 1)
|
|
78207
|
+
];
|
|
78208
|
+
const nextRows = [
|
|
78209
|
+
...table.rows.slice(0, rowToken.index),
|
|
78210
|
+
{ ...row2, cells: nextCells },
|
|
78211
|
+
...table.rows.slice(rowToken.index + 1)
|
|
78212
|
+
];
|
|
78213
|
+
return { ...table, rows: nextRows };
|
|
78214
|
+
}
|
|
78215
|
+
function createSelectedListItemDeleteReplayCommand(input) {
|
|
78216
|
+
const { command, document: document2, selection, surface, storyTarget, timestamp } = input;
|
|
78217
|
+
if (command.type !== "text.delete-backward" && command.type !== "text.delete-forward") {
|
|
78218
|
+
return null;
|
|
78219
|
+
}
|
|
78220
|
+
const editableTarget = command.editableTarget;
|
|
78221
|
+
if (!editableTarget) {
|
|
78222
|
+
return null;
|
|
78223
|
+
}
|
|
78224
|
+
const targetResolution = resolveEditableTextTarget({
|
|
78225
|
+
document: document2,
|
|
78226
|
+
selection,
|
|
78227
|
+
surface,
|
|
78228
|
+
target: editableTarget,
|
|
78229
|
+
activeStoryKey: canonicalEditableTargetStoryKey(storyTarget)
|
|
78230
|
+
});
|
|
78231
|
+
const replacement = createSelectedListItemDeleteReplacement({
|
|
78232
|
+
command,
|
|
78233
|
+
document: document2,
|
|
78234
|
+
editableTarget,
|
|
78235
|
+
selection,
|
|
78236
|
+
targetResolution,
|
|
78237
|
+
timestamp
|
|
78238
|
+
});
|
|
78239
|
+
if (!replacement || storyTarget.kind !== "main") {
|
|
78240
|
+
return null;
|
|
78241
|
+
}
|
|
78242
|
+
return {
|
|
78243
|
+
type: "document.replace",
|
|
78244
|
+
document: replacement.document,
|
|
78245
|
+
selection: replacement.selection,
|
|
78246
|
+
mapping: replacement.mapping,
|
|
78247
|
+
protectionSelection: selection,
|
|
78248
|
+
origin: command.origin
|
|
78249
|
+
};
|
|
78250
|
+
}
|
|
78251
|
+
function parseMainStoryBlockPathTokens(blockPath) {
|
|
78252
|
+
const parts = blockPath?.split("/") ?? [];
|
|
78253
|
+
if (parts[0] !== "main" || parts.length < 2) {
|
|
78254
|
+
return null;
|
|
78255
|
+
}
|
|
78256
|
+
const tokens = [];
|
|
78257
|
+
for (const part of parts.slice(1)) {
|
|
78258
|
+
const match = /^(block|row|cell)\[(\d+)\]$/u.exec(part);
|
|
78259
|
+
if (!match) return null;
|
|
78260
|
+
tokens.push({
|
|
78261
|
+
kind: match[1],
|
|
78262
|
+
index: Number.parseInt(match[2], 10)
|
|
78263
|
+
});
|
|
78264
|
+
}
|
|
78265
|
+
return tokens;
|
|
78266
|
+
}
|
|
77730
78267
|
function toInternalSelectionSnapshot2(selection) {
|
|
77731
78268
|
return {
|
|
77732
78269
|
anchor: selection.anchor,
|
|
@@ -94621,18 +95158,7 @@ function findScrollAnchor(root, options) {
|
|
|
94621
95158
|
offsetWithinBlock: viewportTopFramePx - blockTop
|
|
94622
95159
|
};
|
|
94623
95160
|
}
|
|
94624
|
-
|
|
94625
|
-
const rootRect = root.getBoundingClientRect();
|
|
94626
|
-
const rootTop = rootRect.top;
|
|
94627
|
-
for (const block of blocks) {
|
|
94628
|
-
const rect3 = block.getBoundingClientRect();
|
|
94629
|
-
if (rect3.bottom < rootTop) continue;
|
|
94630
|
-
const blockId = block.getAttribute("data-block-id");
|
|
94631
|
-
if (!blockId) continue;
|
|
94632
|
-
return {
|
|
94633
|
-
blockId,
|
|
94634
|
-
offsetWithinBlock: rootTop - rect3.top
|
|
94635
|
-
};
|
|
95161
|
+
return null;
|
|
94636
95162
|
}
|
|
94637
95163
|
return null;
|
|
94638
95164
|
}
|
|
@@ -94650,17 +95176,9 @@ function resolveScrollTopForAnchor(root, anchor, options) {
|
|
|
94650
95176
|
const rect3 = geometry.rects[0];
|
|
94651
95177
|
return rect3.topPx + anchor.offsetWithinBlock;
|
|
94652
95178
|
}
|
|
95179
|
+
return null;
|
|
94653
95180
|
}
|
|
94654
|
-
|
|
94655
|
-
const block = root.querySelector(selector);
|
|
94656
|
-
if (!block) return null;
|
|
94657
|
-
const rootRect = root.getBoundingClientRect();
|
|
94658
|
-
const blockRect = block.getBoundingClientRect();
|
|
94659
|
-
const delta = blockRect.top - rootRect.top + anchor.offsetWithinBlock;
|
|
94660
|
-
return root.scrollTop + delta;
|
|
94661
|
-
}
|
|
94662
|
-
function cssEscape(value) {
|
|
94663
|
-
return value.replace(/[^a-zA-Z0-9_-]/g, (ch) => `\\${ch}`);
|
|
95181
|
+
return null;
|
|
94664
95182
|
}
|
|
94665
95183
|
|
|
94666
95184
|
// src/ui-tailwind/chrome/tw-alert-banner.tsx
|
|
@@ -103245,6 +103763,14 @@ var EDITOR_ACTION_REGISTRY = [
|
|
|
103245
103763
|
targetKinds: ["generated-field"],
|
|
103246
103764
|
callback: "onUpdateFields"
|
|
103247
103765
|
}),
|
|
103766
|
+
mk({
|
|
103767
|
+
id: "toc-refresh",
|
|
103768
|
+
label: "Refresh table of contents",
|
|
103769
|
+
description: "Refresh TOC entries through the runtime table-of-contents updater.",
|
|
103770
|
+
group: "misc",
|
|
103771
|
+
targetKinds: ["toc-field"],
|
|
103772
|
+
callback: "onUpdateTableOfContents"
|
|
103773
|
+
}),
|
|
103248
103774
|
// -------- Workflow scope --------
|
|
103249
103775
|
mk({
|
|
103250
103776
|
id: "scope-open-card",
|
|
@@ -104138,6 +104664,18 @@ function hasAncestorAttributeValue(el, attribute, expected, root) {
|
|
|
104138
104664
|
}
|
|
104139
104665
|
return false;
|
|
104140
104666
|
}
|
|
104667
|
+
function hasAncestorAttributeValueInsensitive(el, attribute, expected, root) {
|
|
104668
|
+
const normalizedExpected = expected.toLowerCase();
|
|
104669
|
+
let cursor = el;
|
|
104670
|
+
while (cursor) {
|
|
104671
|
+
if (cursor.getAttribute?.(attribute)?.toLowerCase() === normalizedExpected) {
|
|
104672
|
+
return true;
|
|
104673
|
+
}
|
|
104674
|
+
if (cursor === root) return false;
|
|
104675
|
+
cursor = cursor.parentElement;
|
|
104676
|
+
}
|
|
104677
|
+
return false;
|
|
104678
|
+
}
|
|
104141
104679
|
function resolveTargetKind(target, options = {}) {
|
|
104142
104680
|
const kinds = [];
|
|
104143
104681
|
const el = toElement(target);
|
|
@@ -104152,7 +104690,12 @@ function resolveTargetKind(target, options = {}) {
|
|
|
104152
104690
|
const insideListItem = insideNumberingMarker || hasAncestorAttributeValue(el, "data-numbered", "true", root);
|
|
104153
104691
|
const insideGeneratedField = hasAncestorAttributeValue(el, "data-generated-field", "true", root) || hasAncestorAttributeValue(el, "data-node-type", "field_ref_atom", root) || hasAncestorAttributeValue(el, "data-node-type", "field_ref", root);
|
|
104154
104692
|
if (insideListItem) kinds.push("list-item");
|
|
104155
|
-
if (insideGeneratedField)
|
|
104693
|
+
if (insideGeneratedField) {
|
|
104694
|
+
kinds.push("generated-field");
|
|
104695
|
+
if (hasAncestorAttributeValueInsensitive(el, "data-field-family", "TOC", root)) {
|
|
104696
|
+
kinds.push("toc-field");
|
|
104697
|
+
}
|
|
104698
|
+
}
|
|
104156
104699
|
if (hasAncestorTag(el, "a", root)) kinds.push("hyperlink");
|
|
104157
104700
|
if (!insideNumberingMarker && hasAncestorTag(el, "img", root)) {
|
|
104158
104701
|
kinds.push("image");
|
|
@@ -105225,294 +105768,6 @@ function resolveSkeletalPageOverlayRectsFromLayout(facet) {
|
|
|
105225
105768
|
}
|
|
105226
105769
|
return rects;
|
|
105227
105770
|
}
|
|
105228
|
-
function pageOverlayLastBottom(rects) {
|
|
105229
|
-
let bottom = 0;
|
|
105230
|
-
for (const rect3 of rects) {
|
|
105231
|
-
if (rect3.bottomPx > bottom) bottom = rect3.bottomPx;
|
|
105232
|
-
}
|
|
105233
|
-
return bottom;
|
|
105234
|
-
}
|
|
105235
|
-
function extendFinalPageOverlayRectToFlowHeight(rects, flowHeightPx) {
|
|
105236
|
-
if (rects.length === 0 || !Number.isFinite(flowHeightPx)) return rects;
|
|
105237
|
-
const last = rects[rects.length - 1];
|
|
105238
|
-
if (flowHeightPx <= last.bottomPx + 1) return rects;
|
|
105239
|
-
return [
|
|
105240
|
-
...rects.slice(0, -1),
|
|
105241
|
-
{
|
|
105242
|
-
...last,
|
|
105243
|
-
bottomPx: flowHeightPx,
|
|
105244
|
-
heightPx: Math.max(0, flowHeightPx - last.topPx)
|
|
105245
|
-
}
|
|
105246
|
-
];
|
|
105247
|
-
}
|
|
105248
|
-
function extendPageOverlayRectsAcrossTableBoundaryGaps(rects, tableBoundaryIndices) {
|
|
105249
|
-
if (rects.length === 0 || tableBoundaryIndices.length === 0) return rects;
|
|
105250
|
-
const tableBoundaries = new Set(tableBoundaryIndices);
|
|
105251
|
-
const byPageIndex = /* @__PURE__ */ new Map();
|
|
105252
|
-
for (const rect3 of rects) {
|
|
105253
|
-
byPageIndex.set(rect3.pageIndex, rect3);
|
|
105254
|
-
}
|
|
105255
|
-
let changed = false;
|
|
105256
|
-
const bridged = rects.map((rect3) => {
|
|
105257
|
-
if (!tableBoundaries.has(rect3.pageIndex)) return rect3;
|
|
105258
|
-
const next = byPageIndex.get(rect3.pageIndex + 1);
|
|
105259
|
-
if (!next || next.topPx <= rect3.bottomPx + 1) return rect3;
|
|
105260
|
-
changed = true;
|
|
105261
|
-
return {
|
|
105262
|
-
...rect3,
|
|
105263
|
-
bottomPx: next.topPx,
|
|
105264
|
-
heightPx: Math.max(0, next.topPx - rect3.topPx)
|
|
105265
|
-
};
|
|
105266
|
-
});
|
|
105267
|
-
return changed ? bridged : rects;
|
|
105268
|
-
}
|
|
105269
|
-
function mergePageOverlayRectsByPageIndex(baseRects, flowRects) {
|
|
105270
|
-
if (baseRects.length === 0 || flowRects.length === 0) return baseRects;
|
|
105271
|
-
const flowByIndex = /* @__PURE__ */ new Map();
|
|
105272
|
-
for (const rect3 of flowRects) {
|
|
105273
|
-
flowByIndex.set(rect3.pageIndex, rect3);
|
|
105274
|
-
}
|
|
105275
|
-
return baseRects.map((rect3) => flowByIndex.get(rect3.pageIndex) ?? rect3);
|
|
105276
|
-
}
|
|
105277
|
-
function normalizeVisiblePageIndexRange(range, pageCount) {
|
|
105278
|
-
if (!range || pageCount <= 0) return null;
|
|
105279
|
-
const start = Math.max(0, Math.min(range.start, pageCount));
|
|
105280
|
-
const end = Math.max(start, Math.min(range.end, pageCount));
|
|
105281
|
-
if (start >= end) return null;
|
|
105282
|
-
return { start, end };
|
|
105283
|
-
}
|
|
105284
|
-
function collectBoundaryIndicesForVisibleRange(range, pageCount) {
|
|
105285
|
-
if (pageCount <= 1) return [];
|
|
105286
|
-
const startBoundaryIndex = Math.max(0, range.start - 1);
|
|
105287
|
-
const endBoundaryIndex = Math.min(pageCount - 2, range.end - 1);
|
|
105288
|
-
if (startBoundaryIndex > endBoundaryIndex) return [];
|
|
105289
|
-
const indices = [];
|
|
105290
|
-
for (let index = startBoundaryIndex; index <= endBoundaryIndex; index += 1) {
|
|
105291
|
-
indices.push(index);
|
|
105292
|
-
}
|
|
105293
|
-
return indices;
|
|
105294
|
-
}
|
|
105295
|
-
function parsePageBoundaryIndex(prevPageId) {
|
|
105296
|
-
const match = /^page-(\d+)$/.exec(prevPageId);
|
|
105297
|
-
if (!match) return void 0;
|
|
105298
|
-
return Number.parseInt(match[1] ?? "", 10);
|
|
105299
|
-
}
|
|
105300
|
-
function collectTableEmbeddedBoundaryIndices(queryRoot) {
|
|
105301
|
-
if (!queryRoot) return [];
|
|
105302
|
-
const indices = [];
|
|
105303
|
-
const widgets = Array.from(
|
|
105304
|
-
queryRoot.querySelectorAll("[data-page-frame-end]")
|
|
105305
|
-
);
|
|
105306
|
-
for (const widget of widgets) {
|
|
105307
|
-
const prevPageId = widget.getAttribute("data-page-frame-end");
|
|
105308
|
-
if (!prevPageId) continue;
|
|
105309
|
-
const boundaryIndex = parsePageBoundaryIndex(prevPageId);
|
|
105310
|
-
if (boundaryIndex === void 0) continue;
|
|
105311
|
-
if (widget.closest("[data-pm-table-root='true'], table")) {
|
|
105312
|
-
indices.push(boundaryIndex);
|
|
105313
|
-
}
|
|
105314
|
-
}
|
|
105315
|
-
return indices;
|
|
105316
|
-
}
|
|
105317
|
-
function containsTableBoundaryRisk(queryRoot) {
|
|
105318
|
-
if (!queryRoot) return false;
|
|
105319
|
-
if (queryRoot.getElementsByTagName("table").length > 0) return true;
|
|
105320
|
-
const descendants = queryRoot.getElementsByTagName("*");
|
|
105321
|
-
for (let i = 0; i < descendants.length; i += 1) {
|
|
105322
|
-
const element = descendants[i];
|
|
105323
|
-
if (element.getAttribute("data-pm-table-root") === "true") {
|
|
105324
|
-
return true;
|
|
105325
|
-
}
|
|
105326
|
-
}
|
|
105327
|
-
return false;
|
|
105328
|
-
}
|
|
105329
|
-
function resolvePageOverlayRects(input, legacyPageCount) {
|
|
105330
|
-
let widgets;
|
|
105331
|
-
let pageCount;
|
|
105332
|
-
let scrollHeight;
|
|
105333
|
-
if (Array.isArray(input)) {
|
|
105334
|
-
const [scrollRoot, count] = input;
|
|
105335
|
-
if (!scrollRoot || count <= 0) return [];
|
|
105336
|
-
widgets = measureWidgetsViaOffsetChain(scrollRoot);
|
|
105337
|
-
pageCount = count;
|
|
105338
|
-
scrollHeight = scrollRoot.clientHeight;
|
|
105339
|
-
} else if (input !== null && typeof input === "object" && "widgets" in input) {
|
|
105340
|
-
widgets = input.widgets;
|
|
105341
|
-
pageCount = input.pageCount;
|
|
105342
|
-
scrollHeight = input.scrollHeight;
|
|
105343
|
-
} else if (input && legacyPageCount !== void 0) {
|
|
105344
|
-
const scrollRoot = input;
|
|
105345
|
-
if (legacyPageCount <= 0) return [];
|
|
105346
|
-
widgets = measureWidgetsViaOffsetChain(scrollRoot);
|
|
105347
|
-
pageCount = legacyPageCount;
|
|
105348
|
-
scrollHeight = scrollRoot.clientHeight;
|
|
105349
|
-
} else {
|
|
105350
|
-
return [];
|
|
105351
|
-
}
|
|
105352
|
-
if (pageCount <= 0) return [];
|
|
105353
|
-
const boundaries = [...widgets].sort((a, b) => a.topPx - b.topPx);
|
|
105354
|
-
const normalizedVisiblePageIndexRange = Array.isArray(input) ? null : normalizeVisiblePageIndexRange(input.visiblePageIndexRange, pageCount);
|
|
105355
|
-
const boundaryByIndex = /* @__PURE__ */ new Map();
|
|
105356
|
-
boundaries.forEach((boundary, index) => {
|
|
105357
|
-
const boundaryIndex = boundary.boundaryIndex ?? parsePageBoundaryIndex(boundary.prevPageId) ?? index;
|
|
105358
|
-
boundaryByIndex.set(boundaryIndex, boundary);
|
|
105359
|
-
});
|
|
105360
|
-
const pageStart = normalizedVisiblePageIndexRange?.start ?? 0;
|
|
105361
|
-
const pageEnd = normalizedVisiblePageIndexRange?.end ?? pageCount;
|
|
105362
|
-
const rects = [];
|
|
105363
|
-
for (let pageIndex = pageStart; pageIndex < pageEnd; pageIndex += 1) {
|
|
105364
|
-
const boundaryBefore = pageIndex === 0 ? null : boundaryByIndex.get(pageIndex - 1) ?? null;
|
|
105365
|
-
const boundaryAfter = pageIndex === pageCount - 1 ? null : boundaryByIndex.get(pageIndex) ?? null;
|
|
105366
|
-
let pageId = null;
|
|
105367
|
-
if (boundaryBefore) pageId = boundaryBefore.nextPageId;
|
|
105368
|
-
else if (boundaryAfter) pageId = boundaryAfter.prevPageId;
|
|
105369
|
-
if (!pageId) pageId = `page-${pageIndex}`;
|
|
105370
|
-
const topPx = boundaryBefore ? boundaryBefore.bottomPx : 0;
|
|
105371
|
-
const bottomPx = boundaryAfter ? boundaryAfter.topPx : scrollHeight;
|
|
105372
|
-
if (bottomPx <= topPx) continue;
|
|
105373
|
-
rects.push({
|
|
105374
|
-
pageId,
|
|
105375
|
-
pageIndex,
|
|
105376
|
-
topPx,
|
|
105377
|
-
bottomPx,
|
|
105378
|
-
heightPx: bottomPx - topPx
|
|
105379
|
-
});
|
|
105380
|
-
}
|
|
105381
|
-
return rects;
|
|
105382
|
-
}
|
|
105383
|
-
function measureWidgetsViaBoundingRect(queryRoot, originElement, options) {
|
|
105384
|
-
if (!queryRoot || !originElement) return [];
|
|
105385
|
-
const originRect = originElement.getBoundingClientRect();
|
|
105386
|
-
const normalizedVisiblePageIndexRange = normalizeVisiblePageIndexRange(
|
|
105387
|
-
options?.visiblePageIndexRange,
|
|
105388
|
-
options?.pageCount ?? 0
|
|
105389
|
-
);
|
|
105390
|
-
const queryOne = typeof queryRoot.querySelector === "function" ? queryRoot.querySelector.bind(queryRoot) : null;
|
|
105391
|
-
const widgets = normalizedVisiblePageIndexRange && queryOne && options?.pageCount ? collectBoundaryIndicesForVisibleRange(
|
|
105392
|
-
normalizedVisiblePageIndexRange,
|
|
105393
|
-
options.pageCount
|
|
105394
|
-
).map(
|
|
105395
|
-
(boundaryIndex) => queryOne(`[data-page-frame-end="page-${boundaryIndex}"]`)
|
|
105396
|
-
).filter((widget) => widget !== null) : Array.from(
|
|
105397
|
-
queryRoot.querySelectorAll("[data-page-frame-end]")
|
|
105398
|
-
);
|
|
105399
|
-
const out = [];
|
|
105400
|
-
for (const widget of widgets) {
|
|
105401
|
-
const prevPageId = widget.getAttribute("data-page-frame-end");
|
|
105402
|
-
const nextPageId = widget.getAttribute("data-page-frame-start");
|
|
105403
|
-
if (!prevPageId || !nextPageId) continue;
|
|
105404
|
-
const rect3 = widget.getBoundingClientRect();
|
|
105405
|
-
out.push({
|
|
105406
|
-
prevPageId,
|
|
105407
|
-
nextPageId,
|
|
105408
|
-
boundaryIndex: parsePageBoundaryIndex(prevPageId),
|
|
105409
|
-
topPx: rect3.top - originRect.top,
|
|
105410
|
-
bottomPx: rect3.bottom - originRect.top
|
|
105411
|
-
});
|
|
105412
|
-
}
|
|
105413
|
-
return out;
|
|
105414
|
-
}
|
|
105415
|
-
function measureWidgetsViaOffsetChain(scrollRoot, options) {
|
|
105416
|
-
const normalizedVisiblePageIndexRange = normalizeVisiblePageIndexRange(
|
|
105417
|
-
options?.visiblePageIndexRange,
|
|
105418
|
-
options?.pageCount ?? 0
|
|
105419
|
-
);
|
|
105420
|
-
const queryOne = typeof scrollRoot.querySelector === "function" ? scrollRoot.querySelector.bind(scrollRoot) : null;
|
|
105421
|
-
const widgets = normalizedVisiblePageIndexRange && queryOne && options?.pageCount ? collectBoundaryIndicesForVisibleRange(
|
|
105422
|
-
normalizedVisiblePageIndexRange,
|
|
105423
|
-
options.pageCount
|
|
105424
|
-
).map(
|
|
105425
|
-
(boundaryIndex) => queryOne(`[data-page-frame-end="page-${boundaryIndex}"]`)
|
|
105426
|
-
).filter((widget) => widget !== null) : Array.from(
|
|
105427
|
-
scrollRoot.querySelectorAll("[data-page-frame-end]")
|
|
105428
|
-
);
|
|
105429
|
-
const out = [];
|
|
105430
|
-
for (const widget of widgets) {
|
|
105431
|
-
const prevPageId = widget.getAttribute("data-page-frame-end");
|
|
105432
|
-
const nextPageId = widget.getAttribute("data-page-frame-start");
|
|
105433
|
-
if (!prevPageId || !nextPageId) continue;
|
|
105434
|
-
const topPx = resolveOffsetTop(widget, scrollRoot);
|
|
105435
|
-
const bottomPx = topPx + resolveOffsetHeight(widget);
|
|
105436
|
-
out.push({
|
|
105437
|
-
prevPageId,
|
|
105438
|
-
nextPageId,
|
|
105439
|
-
boundaryIndex: parsePageBoundaryIndex(prevPageId),
|
|
105440
|
-
topPx,
|
|
105441
|
-
bottomPx
|
|
105442
|
-
});
|
|
105443
|
-
}
|
|
105444
|
-
return out;
|
|
105445
|
-
}
|
|
105446
|
-
function resolveOffsetTop(widget, scrollRoot) {
|
|
105447
|
-
let node = widget;
|
|
105448
|
-
let top = 0;
|
|
105449
|
-
while (node) {
|
|
105450
|
-
top += node.offsetTop ?? 0;
|
|
105451
|
-
const parent = node.offsetParent;
|
|
105452
|
-
if (parent === scrollRoot || parent === null) break;
|
|
105453
|
-
node = parent;
|
|
105454
|
-
}
|
|
105455
|
-
return top;
|
|
105456
|
-
}
|
|
105457
|
-
function resolveOffsetHeight(widget) {
|
|
105458
|
-
return widget.offsetHeight ?? 0;
|
|
105459
|
-
}
|
|
105460
|
-
function readElementFlowHeight(element, options = {}) {
|
|
105461
|
-
if (!element) return 0;
|
|
105462
|
-
let height = 0;
|
|
105463
|
-
height = Math.max(height, element.clientHeight || 0);
|
|
105464
|
-
if (options.includeScrollHeight !== false) {
|
|
105465
|
-
height = Math.max(height, element.scrollHeight || 0);
|
|
105466
|
-
}
|
|
105467
|
-
if (height <= 0) {
|
|
105468
|
-
const rect3 = element.getBoundingClientRect();
|
|
105469
|
-
height = Math.max(height, rect3.height || 0);
|
|
105470
|
-
}
|
|
105471
|
-
return height;
|
|
105472
|
-
}
|
|
105473
|
-
function readOverlayFlowHeight(origin) {
|
|
105474
|
-
if (!origin) return 0;
|
|
105475
|
-
const parent = origin.parentElement instanceof HTMLElement ? origin.parentElement : null;
|
|
105476
|
-
const parentHeight = readElementFlowHeight(parent);
|
|
105477
|
-
if (parentHeight > 0) return parentHeight;
|
|
105478
|
-
return readElementFlowHeight(origin, { includeScrollHeight: false });
|
|
105479
|
-
}
|
|
105480
|
-
function reconcilePageStackRectsWithFlow(input) {
|
|
105481
|
-
const { baseRects, pageCount, scrollRoot, originElement } = input;
|
|
105482
|
-
if (baseRects.length === 0 || pageCount <= 0) return baseRects;
|
|
105483
|
-
const flowHeight = readOverlayFlowHeight(originElement);
|
|
105484
|
-
if (flowHeight <= 0) return baseRects;
|
|
105485
|
-
const geometryBottom = pageOverlayLastBottom(baseRects);
|
|
105486
|
-
const tableBoundaryRisk = containsTableBoundaryRisk(scrollRoot);
|
|
105487
|
-
if (!tableBoundaryRisk && flowHeight <= geometryBottom + 1) {
|
|
105488
|
-
return extendFinalPageOverlayRectToFlowHeight(baseRects, flowHeight);
|
|
105489
|
-
}
|
|
105490
|
-
const bridgedBase = extendPageOverlayRectsAcrossTableBoundaryGaps(
|
|
105491
|
-
baseRects,
|
|
105492
|
-
tableBoundaryRisk ? collectTableEmbeddedBoundaryIndices(scrollRoot) : []
|
|
105493
|
-
);
|
|
105494
|
-
const extendedBase = extendFinalPageOverlayRectToFlowHeight(
|
|
105495
|
-
bridgedBase,
|
|
105496
|
-
flowHeight
|
|
105497
|
-
);
|
|
105498
|
-
if (!originElement || !scrollRoot) return extendedBase;
|
|
105499
|
-
if (flowHeight <= pageOverlayLastBottom(bridgedBase) + 1) {
|
|
105500
|
-
return extendedBase;
|
|
105501
|
-
}
|
|
105502
|
-
const widgets = measureWidgetsViaBoundingRect(scrollRoot, originElement, {
|
|
105503
|
-
pageCount,
|
|
105504
|
-
visiblePageIndexRange: null
|
|
105505
|
-
});
|
|
105506
|
-
if (widgets.length === 0) return extendedBase;
|
|
105507
|
-
const flowRects = resolvePageOverlayRects({
|
|
105508
|
-
widgets,
|
|
105509
|
-
pageCount,
|
|
105510
|
-
scrollHeight: flowHeight,
|
|
105511
|
-
visiblePageIndexRange: null
|
|
105512
|
-
});
|
|
105513
|
-
const merged = mergePageOverlayRectsByPageIndex(extendedBase, flowRects);
|
|
105514
|
-
return extendFinalPageOverlayRectToFlowHeight(merged, flowHeight);
|
|
105515
|
-
}
|
|
105516
105771
|
var resolvePageOverlayRectsFromGeometry2 = resolvePageOverlayRectsFromGeometry;
|
|
105517
105772
|
function resolvePageOverlayRectsFromUiApi(ui, pageCount, visiblePageIndexRange, pageIds) {
|
|
105518
105773
|
if (pageCount <= 0) return [];
|
|
@@ -105570,17 +105825,6 @@ var TwPageStackOverlayLayer = ({
|
|
|
105570
105825
|
},
|
|
105571
105826
|
[]
|
|
105572
105827
|
);
|
|
105573
|
-
const reconcilePaperRectsWithFlow = React23.useCallback(
|
|
105574
|
-
(baseRects, pageCount) => {
|
|
105575
|
-
return reconcilePageStackRectsWithFlow({
|
|
105576
|
-
baseRects,
|
|
105577
|
-
pageCount,
|
|
105578
|
-
scrollRoot,
|
|
105579
|
-
originElement: overlayRootRef.current
|
|
105580
|
-
});
|
|
105581
|
-
},
|
|
105582
|
-
[scrollRoot]
|
|
105583
|
-
);
|
|
105584
105828
|
const refreshRectsNow = React23.useCallback(() => {
|
|
105585
105829
|
const pageCount = facet.getPageCount();
|
|
105586
105830
|
const skeletalRects = resolveSkeletalPageOverlayRectsFromLayout(facet);
|
|
@@ -105621,51 +105865,11 @@ var TwPageStackOverlayLayer = ({
|
|
|
105621
105865
|
setRectsIfChanged(skeletalRects);
|
|
105622
105866
|
return;
|
|
105623
105867
|
}
|
|
105624
|
-
|
|
105625
|
-
|
|
105626
|
-
return;
|
|
105627
|
-
}
|
|
105628
|
-
const origin = overlayRootRef.current;
|
|
105629
|
-
incrementInvalidationCounter("overlay.page.dom_fallback");
|
|
105630
|
-
if (origin) {
|
|
105631
|
-
incrementInvalidationCounter("overlay.page.dom.degraded");
|
|
105632
|
-
const widgets = measureWidgetsViaBoundingRect(scrollRoot, origin, {
|
|
105633
|
-
pageCount,
|
|
105634
|
-
visiblePageIndexRange: null
|
|
105635
|
-
});
|
|
105636
|
-
const originRect = origin.getBoundingClientRect();
|
|
105637
|
-
const domRects = resolvePageOverlayRects({
|
|
105638
|
-
widgets,
|
|
105639
|
-
pageCount,
|
|
105640
|
-
scrollHeight: (
|
|
105641
|
-
// geometry:allow-dom-fallback
|
|
105642
|
-
origin.clientHeight > 0 ? origin.clientHeight : originRect.height
|
|
105643
|
-
),
|
|
105644
|
-
visiblePageIndexRange: null
|
|
105645
|
-
});
|
|
105646
|
-
const reconciled = reconcilePaperRectsWithFlow(domRects, pageCount);
|
|
105647
|
-
setRectsIfChanged(reconciled.length > 0 ? reconciled : skeletalRects);
|
|
105648
|
-
} else {
|
|
105649
|
-
incrementInvalidationCounter("overlay.page.dom.degraded");
|
|
105650
|
-
const widgets = measureWidgetsViaOffsetChain(scrollRoot, {
|
|
105651
|
-
pageCount,
|
|
105652
|
-
visiblePageIndexRange: null
|
|
105653
|
-
});
|
|
105654
|
-
const domRects = resolvePageOverlayRects({
|
|
105655
|
-
widgets,
|
|
105656
|
-
pageCount,
|
|
105657
|
-
// geometry:allow-dom-fallback
|
|
105658
|
-
scrollHeight: scrollRoot.clientHeight,
|
|
105659
|
-
visiblePageIndexRange: null
|
|
105660
|
-
});
|
|
105661
|
-
const reconciled = reconcilePaperRectsWithFlow(domRects, pageCount);
|
|
105662
|
-
setRectsIfChanged(reconciled.length > 0 ? reconciled : skeletalRects);
|
|
105663
|
-
}
|
|
105868
|
+
incrementInvalidationCounter("overlay.page.skeletal_fallback");
|
|
105869
|
+
setRectsIfChanged(skeletalRects);
|
|
105664
105870
|
}, [
|
|
105665
105871
|
facet,
|
|
105666
105872
|
geometryFacet,
|
|
105667
|
-
reconcilePaperRectsWithFlow,
|
|
105668
|
-
scrollRoot,
|
|
105669
105873
|
setRectsIfChanged,
|
|
105670
105874
|
ui
|
|
105671
105875
|
]);
|
|
@@ -105696,33 +105900,6 @@ var TwPageStackOverlayLayer = ({
|
|
|
105696
105900
|
}
|
|
105697
105901
|
};
|
|
105698
105902
|
}, [refreshRects, renderFrameRevision, scrollRoot]);
|
|
105699
|
-
React23.useEffect(() => {
|
|
105700
|
-
if (geometryFacet) return;
|
|
105701
|
-
if (!scrollRoot) return;
|
|
105702
|
-
const runtime = scrollRoot.ownerDocument?.defaultView;
|
|
105703
|
-
if (!runtime?.ResizeObserver) return;
|
|
105704
|
-
const observer = new runtime.ResizeObserver(() => refreshRects());
|
|
105705
|
-
observer.observe(scrollRoot);
|
|
105706
|
-
return () => observer.disconnect();
|
|
105707
|
-
}, [geometryFacet, scrollRoot, refreshRects]);
|
|
105708
|
-
React23.useEffect(() => {
|
|
105709
|
-
if (geometryFacet) return;
|
|
105710
|
-
if (!scrollRoot) return;
|
|
105711
|
-
const runtime = scrollRoot.ownerDocument?.defaultView;
|
|
105712
|
-
if (!runtime?.MutationObserver) return;
|
|
105713
|
-
const observer = new runtime.MutationObserver((records) => {
|
|
105714
|
-
const overlay = overlayRootRef.current;
|
|
105715
|
-
if (overlay) {
|
|
105716
|
-
const allSelf = records.every(
|
|
105717
|
-
(r) => r.target instanceof Node && overlay.contains(r.target)
|
|
105718
|
-
);
|
|
105719
|
-
if (allSelf) return;
|
|
105720
|
-
}
|
|
105721
|
-
refreshRects();
|
|
105722
|
-
});
|
|
105723
|
-
observer.observe(scrollRoot, { childList: true, subtree: false });
|
|
105724
|
-
return () => observer.disconnect();
|
|
105725
|
-
}, [geometryFacet, scrollRoot, refreshRects]);
|
|
105726
105903
|
if (rects.length === 0) {
|
|
105727
105904
|
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
105728
105905
|
"div",
|
|
@@ -107814,25 +107991,23 @@ var TwPageStackChromeLayerInner = ({
|
|
|
107814
107991
|
const pageCount = facet.getPageCount();
|
|
107815
107992
|
const uiRects = resolveUiPageRects(pageCount);
|
|
107816
107993
|
if (uiRects !== null) return uiRects;
|
|
107817
|
-
if (
|
|
107818
|
-
|
|
107819
|
-
|
|
107820
|
-
|
|
107821
|
-
|
|
107994
|
+
if (geometryFacet) {
|
|
107995
|
+
const warm = resolvePageOverlayRectsFromGeometry2(
|
|
107996
|
+
geometryFacet,
|
|
107997
|
+
pageCount,
|
|
107998
|
+
visiblePageIndexRange
|
|
107999
|
+
);
|
|
108000
|
+
if (warm !== null) return warm;
|
|
108001
|
+
}
|
|
108002
|
+
return resolveSkeletalPageOverlayRectsFromLayout(facet).filter(
|
|
108003
|
+
(rect3) => !visiblePageIndexRange || rect3.pageIndex >= visiblePageIndexRange.start && rect3.pageIndex < visiblePageIndexRange.end
|
|
107822
108004
|
);
|
|
107823
|
-
return warm ?? [];
|
|
107824
108005
|
});
|
|
107825
108006
|
const overlayRootRef = import_react33.default.useRef(null);
|
|
107826
108007
|
const rafHandleRef = import_react33.default.useRef(null);
|
|
107827
108008
|
const [activeStoryPageIndex, setActiveStoryPageIndex] = import_react33.default.useState(null);
|
|
107828
108009
|
const refreshRectsNow = import_react33.default.useCallback(() => {
|
|
107829
108010
|
const pageCount = facet.getPageCount();
|
|
107830
|
-
const reconcileDomRects = (baseRects) => reconcilePageStackRectsWithFlow({
|
|
107831
|
-
baseRects,
|
|
107832
|
-
pageCount,
|
|
107833
|
-
scrollRoot,
|
|
107834
|
-
originElement: overlayRootRef.current
|
|
107835
|
-
});
|
|
107836
108011
|
const uiRects = resolveUiPageRects(pageCount);
|
|
107837
108012
|
if (uiRects !== null) {
|
|
107838
108013
|
setRects(uiRects);
|
|
@@ -107851,47 +108026,11 @@ var TwPageStackChromeLayerInner = ({
|
|
|
107851
108026
|
setRects([]);
|
|
107852
108027
|
return;
|
|
107853
108028
|
}
|
|
107854
|
-
|
|
107855
|
-
|
|
107856
|
-
|
|
107857
|
-
|
|
107858
|
-
|
|
107859
|
-
if (origin) {
|
|
107860
|
-
const widgets = measureWidgetsViaBoundingRect(scrollRoot, origin, {
|
|
107861
|
-
pageCount,
|
|
107862
|
-
visiblePageIndexRange
|
|
107863
|
-
});
|
|
107864
|
-
const originRect = origin.getBoundingClientRect();
|
|
107865
|
-
const scrollHeight = (
|
|
107866
|
-
// geometry:allow-dom-fallback
|
|
107867
|
-
origin.clientHeight > 0 ? origin.clientHeight : originRect.height > 0 ? originRect.height : scrollRoot.clientHeight
|
|
107868
|
-
);
|
|
107869
|
-
const domRects = resolvePageOverlayRects({
|
|
107870
|
-
widgets,
|
|
107871
|
-
pageCount,
|
|
107872
|
-
scrollHeight,
|
|
107873
|
-
visiblePageIndexRange
|
|
107874
|
-
});
|
|
107875
|
-
setRects(
|
|
107876
|
-
reconcileDomRects(domRects)
|
|
107877
|
-
);
|
|
107878
|
-
} else {
|
|
107879
|
-
const widgets = measureWidgetsViaOffsetChain(scrollRoot, {
|
|
107880
|
-
pageCount,
|
|
107881
|
-
visiblePageIndexRange
|
|
107882
|
-
});
|
|
107883
|
-
const domRects = resolvePageOverlayRects({
|
|
107884
|
-
widgets,
|
|
107885
|
-
pageCount,
|
|
107886
|
-
// geometry:allow-dom-fallback
|
|
107887
|
-
scrollHeight: scrollRoot.clientHeight,
|
|
107888
|
-
visiblePageIndexRange
|
|
107889
|
-
});
|
|
107890
|
-
setRects(
|
|
107891
|
-
reconcileDomRects(domRects)
|
|
107892
|
-
);
|
|
107893
|
-
}
|
|
107894
|
-
}, [facet, geometryFacet, resolveUiPageRects, scrollRoot, visiblePageIndexRange]);
|
|
108029
|
+
const skeletalRects = resolveSkeletalPageOverlayRectsFromLayout(facet).filter(
|
|
108030
|
+
(rect3) => !visiblePageIndexRange || rect3.pageIndex >= visiblePageIndexRange.start && rect3.pageIndex < visiblePageIndexRange.end
|
|
108031
|
+
);
|
|
108032
|
+
setRects(skeletalRects);
|
|
108033
|
+
}, [facet, geometryFacet, resolveUiPageRects, visiblePageIndexRange]);
|
|
107895
108034
|
const refreshRects = import_react33.default.useCallback(() => {
|
|
107896
108035
|
if (!scrollRoot) {
|
|
107897
108036
|
refreshRectsNow();
|
|
@@ -107931,33 +108070,6 @@ var TwPageStackChromeLayerInner = ({
|
|
|
107931
108070
|
},
|
|
107932
108071
|
[onOpenStory]
|
|
107933
108072
|
);
|
|
107934
|
-
import_react33.default.useEffect(() => {
|
|
107935
|
-
if (geometryFacet) return;
|
|
107936
|
-
if (!scrollRoot) return;
|
|
107937
|
-
const runtime = scrollRoot.ownerDocument?.defaultView;
|
|
107938
|
-
if (!runtime?.ResizeObserver) return;
|
|
107939
|
-
const observer = new runtime.ResizeObserver(() => refreshRects());
|
|
107940
|
-
observer.observe(scrollRoot);
|
|
107941
|
-
return () => observer.disconnect();
|
|
107942
|
-
}, [geometryFacet, scrollRoot, refreshRects]);
|
|
107943
|
-
import_react33.default.useEffect(() => {
|
|
107944
|
-
if (geometryFacet) return;
|
|
107945
|
-
if (!scrollRoot) return;
|
|
107946
|
-
const runtime = scrollRoot.ownerDocument?.defaultView;
|
|
107947
|
-
if (!runtime?.MutationObserver) return;
|
|
107948
|
-
const observer = new runtime.MutationObserver((records) => {
|
|
107949
|
-
const overlay = overlayRootRef.current;
|
|
107950
|
-
if (overlay) {
|
|
107951
|
-
const allSelf = records.every(
|
|
107952
|
-
(r) => r.target instanceof Node && overlay.contains(r.target)
|
|
107953
|
-
);
|
|
107954
|
-
if (allSelf) return;
|
|
107955
|
-
}
|
|
107956
|
-
refreshRects();
|
|
107957
|
-
});
|
|
107958
|
-
observer.observe(scrollRoot, { childList: true, subtree: false });
|
|
107959
|
-
return () => observer.disconnect();
|
|
107960
|
-
}, [geometryFacet, scrollRoot, refreshRects]);
|
|
107961
108073
|
import_react33.default.useLayoutEffect(() => {
|
|
107962
108074
|
if (!pmSurfaceElement) return;
|
|
107963
108075
|
const overlay = overlayRootRef.current;
|
|
@@ -109439,45 +109551,17 @@ var TwFloatingImageLayer = ({
|
|
|
109439
109551
|
const [pageRects, setPageRects] = React39.useState([]);
|
|
109440
109552
|
const refreshPageRectsNow = React39.useCallback(() => {
|
|
109441
109553
|
const pageCount = facet.getPageCount();
|
|
109442
|
-
if (geometryFacet) {
|
|
109443
|
-
const geometryRects = resolvePageOverlayRectsFromGeometry2(
|
|
109444
|
-
geometryFacet,
|
|
109445
|
-
pageCount,
|
|
109446
|
-
visiblePageIndexRange
|
|
109447
|
-
);
|
|
109448
|
-
if (geometryRects !== null) {
|
|
109449
|
-
setPageRects(geometryRects);
|
|
109450
|
-
return;
|
|
109451
|
-
}
|
|
109452
|
-
setPageRects([]);
|
|
109453
|
-
return;
|
|
109454
|
-
}
|
|
109455
|
-
if (!scrollRoot) {
|
|
109456
|
-
setPageRects([]);
|
|
109457
|
-
return;
|
|
109458
|
-
}
|
|
109459
|
-
const origin = overlayRootRef.current;
|
|
109460
|
-
if (!origin) {
|
|
109554
|
+
if (!geometryFacet) {
|
|
109461
109555
|
setPageRects([]);
|
|
109462
109556
|
return;
|
|
109463
109557
|
}
|
|
109464
|
-
const
|
|
109558
|
+
const geometryRects = resolvePageOverlayRectsFromGeometry2(
|
|
109559
|
+
geometryFacet,
|
|
109465
109560
|
pageCount,
|
|
109466
109561
|
visiblePageIndexRange
|
|
109467
|
-
});
|
|
109468
|
-
const originRect = origin.getBoundingClientRect();
|
|
109469
|
-
setPageRects(
|
|
109470
|
-
resolvePageOverlayRects({
|
|
109471
|
-
widgets,
|
|
109472
|
-
pageCount,
|
|
109473
|
-
scrollHeight: (
|
|
109474
|
-
// geometry:allow-dom-fallback
|
|
109475
|
-
origin.clientHeight > 0 ? origin.clientHeight : originRect.height
|
|
109476
|
-
),
|
|
109477
|
-
visiblePageIndexRange
|
|
109478
|
-
})
|
|
109479
109562
|
);
|
|
109480
|
-
|
|
109563
|
+
setPageRects(geometryRects ?? []);
|
|
109564
|
+
}, [facet, geometryFacet, visiblePageIndexRange]);
|
|
109481
109565
|
const refreshPageRects = React39.useCallback(() => {
|
|
109482
109566
|
if (!scrollRoot) {
|
|
109483
109567
|
refreshPageRectsNow();
|
|
@@ -109507,47 +109591,6 @@ var TwFloatingImageLayer = ({
|
|
|
109507
109591
|
}
|
|
109508
109592
|
};
|
|
109509
109593
|
}, [refreshPageRects, renderFrameRevision, scrollRoot]);
|
|
109510
|
-
React39.useEffect(() => {
|
|
109511
|
-
if (geometryFacet) {
|
|
109512
|
-
return;
|
|
109513
|
-
}
|
|
109514
|
-
if (!scrollRoot) {
|
|
109515
|
-
return;
|
|
109516
|
-
}
|
|
109517
|
-
const runtime = scrollRoot.ownerDocument?.defaultView;
|
|
109518
|
-
if (!runtime?.ResizeObserver) {
|
|
109519
|
-
return;
|
|
109520
|
-
}
|
|
109521
|
-
const observer = new runtime.ResizeObserver(() => refreshPageRects());
|
|
109522
|
-
observer.observe(scrollRoot);
|
|
109523
|
-
return () => observer.disconnect();
|
|
109524
|
-
}, [geometryFacet, refreshPageRects, scrollRoot]);
|
|
109525
|
-
React39.useEffect(() => {
|
|
109526
|
-
if (geometryFacet) {
|
|
109527
|
-
return;
|
|
109528
|
-
}
|
|
109529
|
-
if (!scrollRoot) {
|
|
109530
|
-
return;
|
|
109531
|
-
}
|
|
109532
|
-
const runtime = scrollRoot.ownerDocument?.defaultView;
|
|
109533
|
-
if (!runtime?.MutationObserver) {
|
|
109534
|
-
return;
|
|
109535
|
-
}
|
|
109536
|
-
const observer = new runtime.MutationObserver((records) => {
|
|
109537
|
-
const overlay = overlayRootRef.current;
|
|
109538
|
-
if (overlay) {
|
|
109539
|
-
const allSelf = records.every(
|
|
109540
|
-
(record) => record.target instanceof Node && overlay.contains(record.target)
|
|
109541
|
-
);
|
|
109542
|
-
if (allSelf) {
|
|
109543
|
-
return;
|
|
109544
|
-
}
|
|
109545
|
-
}
|
|
109546
|
-
refreshPageRects();
|
|
109547
|
-
});
|
|
109548
|
-
observer.observe(scrollRoot, { childList: true, subtree: false });
|
|
109549
|
-
return () => observer.disconnect();
|
|
109550
|
-
}, [geometryFacet, refreshPageRects, scrollRoot]);
|
|
109551
109594
|
const items = React39.useMemo(() => {
|
|
109552
109595
|
const viewportScale = geometryFacet?.getViewport().pxPerTwip;
|
|
109553
109596
|
const pxPerTwip = typeof viewportScale === "number" && viewportScale > 0 ? viewportScale : void 0;
|
|
@@ -112526,7 +112569,7 @@ function createOverlaysFamily(ctx) {
|
|
|
112526
112569
|
return {
|
|
112527
112570
|
handle: {
|
|
112528
112571
|
kind: "table-action",
|
|
112529
|
-
id: tableActionHandle2(
|
|
112572
|
+
id: tableActionHandle2(documentSeed3(), targetKey),
|
|
112530
112573
|
targetKind,
|
|
112531
112574
|
commandFamily,
|
|
112532
112575
|
scope: tableActionScope(entry)
|
|
@@ -112550,9 +112593,9 @@ function createOverlaysFamily(ctx) {
|
|
|
112550
112593
|
};
|
|
112551
112594
|
}
|
|
112552
112595
|
function tableActionHandle2(seed, targetKey) {
|
|
112553
|
-
return `table-action:${
|
|
112596
|
+
return `table-action:${hashOpaque4(`${seed}::${targetKey}`)}`;
|
|
112554
112597
|
}
|
|
112555
|
-
function
|
|
112598
|
+
function hashOpaque4(input) {
|
|
112556
112599
|
let h = 2166136261;
|
|
112557
112600
|
for (let i = 0; i < input.length; i += 1) {
|
|
112558
112601
|
h ^= input.charCodeAt(i);
|
|
@@ -112560,7 +112603,7 @@ function createOverlaysFamily(ctx) {
|
|
|
112560
112603
|
}
|
|
112561
112604
|
return (h >>> 0).toString(36).padStart(7, "0");
|
|
112562
112605
|
}
|
|
112563
|
-
function
|
|
112606
|
+
function documentSeed3() {
|
|
112564
112607
|
return ctx.handle.getSessionState().documentId ?? "document";
|
|
112565
112608
|
}
|
|
112566
112609
|
function modeledTargetSourceIdentity(target) {
|
|
@@ -117036,8 +117079,39 @@ function buildPositionMap(surface) {
|
|
|
117036
117079
|
}
|
|
117037
117080
|
return lastStoryRestorableEntry(entries)?.pmEnd ?? 1;
|
|
117038
117081
|
};
|
|
117082
|
+
const runtimeToPmWithBias = (runtimePos, bias) => {
|
|
117083
|
+
if (bias > 0) return runtimeToPm(runtimePos);
|
|
117084
|
+
const firstEditable = entries.find(isStoryRuntimeRestorableEntry);
|
|
117085
|
+
if (runtimePos <= 0) {
|
|
117086
|
+
return firstEditable?.pmStart ?? 1;
|
|
117087
|
+
}
|
|
117088
|
+
if (runtimePos >= runtimeStorySize) {
|
|
117089
|
+
return lastStoryRestorableEntry(entries)?.pmEnd ?? pmDocSize - 1;
|
|
117090
|
+
}
|
|
117091
|
+
let previous = null;
|
|
117092
|
+
for (const entry of entries) {
|
|
117093
|
+
if (!isStoryRuntimeRestorableEntry(entry)) {
|
|
117094
|
+
continue;
|
|
117095
|
+
}
|
|
117096
|
+
if (entry.runtimeStart === entry.runtimeEnd && runtimePos === entry.runtimeStart) {
|
|
117097
|
+
return previous?.pmEnd ?? entry.pmStart;
|
|
117098
|
+
}
|
|
117099
|
+
if (runtimePos > entry.runtimeStart && runtimePos <= entry.runtimeEnd) {
|
|
117100
|
+
return entry.pmStart + (runtimePos - entry.runtimeStart);
|
|
117101
|
+
}
|
|
117102
|
+
if (runtimePos <= entry.runtimeStart) {
|
|
117103
|
+
if (runtimePos === entry.runtimeStart && previous) {
|
|
117104
|
+
return previous.pmEnd;
|
|
117105
|
+
}
|
|
117106
|
+
return nearestRuntimeGapPm(runtimePos, previous, entry);
|
|
117107
|
+
}
|
|
117108
|
+
previous = entry;
|
|
117109
|
+
}
|
|
117110
|
+
return lastStoryRestorableEntry(entries)?.pmEnd ?? 1;
|
|
117111
|
+
};
|
|
117039
117112
|
return {
|
|
117040
117113
|
runtimeToPm,
|
|
117114
|
+
runtimeToPmWithBias,
|
|
117041
117115
|
runtimeToPmWithContext(input) {
|
|
117042
117116
|
const targetEntry = input.editableTarget ? findRestorableEntryForTarget(entries, input.editableTarget, input.runtimePos) : void 0;
|
|
117043
117117
|
if (targetEntry) {
|
|
@@ -119785,9 +119859,10 @@ function buildAnchorPmRange(anchor, positionMap) {
|
|
|
119785
119859
|
return null;
|
|
119786
119860
|
}
|
|
119787
119861
|
if (anchor.kind === "range") {
|
|
119862
|
+
const mapBoundary = (runtimePos, bias) => positionMap.runtimeToPmWithBias ? positionMap.runtimeToPmWithBias(runtimePos, bias) : positionMap.runtimeToPm(runtimePos);
|
|
119788
119863
|
return {
|
|
119789
|
-
from:
|
|
119790
|
-
to:
|
|
119864
|
+
from: mapBoundary(anchor.from, anchor.assoc?.start ?? 1),
|
|
119865
|
+
to: mapBoundary(anchor.to, anchor.assoc?.end ?? -1),
|
|
119791
119866
|
allowInline: true
|
|
119792
119867
|
};
|
|
119793
119868
|
}
|
|
@@ -121494,13 +121569,6 @@ function resolvePmPageBodyPatchPlan(input) {
|
|
|
121494
121569
|
...input.patchPlan.addedPages,
|
|
121495
121570
|
...input.patchPlan.removedPages
|
|
121496
121571
|
];
|
|
121497
|
-
if (membershipChangedPageIds.length > 0 && input.currentDoc.childCount !== input.nextDoc.childCount) {
|
|
121498
|
-
return {
|
|
121499
|
-
status: "fallback",
|
|
121500
|
-
reason: "page-membership-change",
|
|
121501
|
-
pageIds: membershipChangedPageIds
|
|
121502
|
-
};
|
|
121503
|
-
}
|
|
121504
121572
|
if (input.currentDoc.childCount !== input.previousSurface.blocks.length || input.nextDoc.childCount !== input.nextSurface.blocks.length) {
|
|
121505
121573
|
return {
|
|
121506
121574
|
status: "fallback",
|
|
@@ -121577,6 +121645,21 @@ function resolvePmPageBodyPatchPlan(input) {
|
|
|
121577
121645
|
]
|
|
121578
121646
|
);
|
|
121579
121647
|
}
|
|
121648
|
+
if (membershipChangedPageIds.length > 0 && !input.currentDoc.eq(input.nextDoc)) {
|
|
121649
|
+
const membershipSpan = resolveTopLevelMembershipPatchSpan({
|
|
121650
|
+
pageIds: membershipChangedPageIds,
|
|
121651
|
+
previousSurface: input.previousSurface,
|
|
121652
|
+
nextSurface: input.nextSurface
|
|
121653
|
+
});
|
|
121654
|
+
if (!membershipSpan) {
|
|
121655
|
+
return {
|
|
121656
|
+
status: "fallback",
|
|
121657
|
+
reason: "page-membership-change",
|
|
121658
|
+
pageIds: membershipChangedPageIds
|
|
121659
|
+
};
|
|
121660
|
+
}
|
|
121661
|
+
rawSpans.push(membershipSpan);
|
|
121662
|
+
}
|
|
121580
121663
|
if (rawSpans.length === 0) {
|
|
121581
121664
|
if (membershipChangedPageIds.length > 0 && !input.currentDoc.eq(input.nextDoc)) {
|
|
121582
121665
|
return {
|
|
@@ -121653,17 +121736,17 @@ function resolveNestedPatchSpan(input) {
|
|
|
121653
121736
|
(id) => findNestedBlockSpanById(input.nextSurface.blocks, input.nextDoc, id)
|
|
121654
121737
|
);
|
|
121655
121738
|
if (previousLocated.some((span) => !span) || nextLocated.some((span) => !span)) {
|
|
121656
|
-
return { status: "
|
|
121739
|
+
return { status: "top-level" };
|
|
121657
121740
|
}
|
|
121658
121741
|
if (previousLocated.some(isUnpatchableVerticalMergeContinuationSpan) || nextLocated.some(isUnpatchableVerticalMergeContinuationSpan)) {
|
|
121659
|
-
return { status: "
|
|
121742
|
+
return { status: "top-level" };
|
|
121660
121743
|
}
|
|
121661
121744
|
const previousSpans = previousLocated;
|
|
121662
121745
|
const nextSpans = nextLocated;
|
|
121663
121746
|
const previousKinds = new Set(previousSpans.map((span) => span.block.kind));
|
|
121664
121747
|
const nextKinds = new Set(nextSpans.map((span) => span.block.kind));
|
|
121665
121748
|
if (previousKinds.size !== nextKinds.size || [...previousKinds].some((kind) => !nextKinds.has(kind))) {
|
|
121666
|
-
return { status: "
|
|
121749
|
+
return { status: "top-level" };
|
|
121667
121750
|
}
|
|
121668
121751
|
return {
|
|
121669
121752
|
status: "nested",
|
|
@@ -121686,6 +121769,46 @@ function isUnpatchableVerticalMergeContinuationSpan(span) {
|
|
|
121686
121769
|
span?.insideVerticalMergeContinuation && span.fromPm >= span.toPm
|
|
121687
121770
|
);
|
|
121688
121771
|
}
|
|
121772
|
+
function resolveTopLevelMembershipPatchSpan(input) {
|
|
121773
|
+
const previousBlocks = input.previousSurface.blocks;
|
|
121774
|
+
const nextBlocks = input.nextSurface.blocks;
|
|
121775
|
+
let prefix = 0;
|
|
121776
|
+
while (prefix < previousBlocks.length && prefix < nextBlocks.length && sameTopLevelBlockIdentity(previousBlocks[prefix], nextBlocks[prefix])) {
|
|
121777
|
+
prefix += 1;
|
|
121778
|
+
}
|
|
121779
|
+
let suffix = 0;
|
|
121780
|
+
while (suffix < previousBlocks.length - prefix && suffix < nextBlocks.length - prefix && sameTopLevelBlockIdentity(
|
|
121781
|
+
previousBlocks[previousBlocks.length - 1 - suffix],
|
|
121782
|
+
nextBlocks[nextBlocks.length - 1 - suffix]
|
|
121783
|
+
)) {
|
|
121784
|
+
suffix += 1;
|
|
121785
|
+
}
|
|
121786
|
+
let fromBlockIndex = prefix;
|
|
121787
|
+
let toBlockIndex = previousBlocks.length - suffix;
|
|
121788
|
+
let nextFromBlockIndex = prefix;
|
|
121789
|
+
let nextToBlockIndex = nextBlocks.length - suffix;
|
|
121790
|
+
if (fromBlockIndex === toBlockIndex && nextFromBlockIndex === nextToBlockIndex) {
|
|
121791
|
+
if (previousBlocks.length === 0 && nextBlocks.length === 0) return null;
|
|
121792
|
+
fromBlockIndex = 0;
|
|
121793
|
+
toBlockIndex = previousBlocks.length;
|
|
121794
|
+
nextFromBlockIndex = 0;
|
|
121795
|
+
nextToBlockIndex = nextBlocks.length;
|
|
121796
|
+
}
|
|
121797
|
+
return {
|
|
121798
|
+
pageIds: [...input.pageIds],
|
|
121799
|
+
fromBlockIndex,
|
|
121800
|
+
toBlockIndex,
|
|
121801
|
+
nextFromBlockIndex,
|
|
121802
|
+
nextToBlockIndex,
|
|
121803
|
+
replacedBlockCount: Math.max(
|
|
121804
|
+
toBlockIndex - fromBlockIndex,
|
|
121805
|
+
nextToBlockIndex - nextFromBlockIndex
|
|
121806
|
+
)
|
|
121807
|
+
};
|
|
121808
|
+
}
|
|
121809
|
+
function sameTopLevelBlockIdentity(left, right) {
|
|
121810
|
+
return Boolean(left && right && left.blockId === right.blockId && left.kind === right.kind);
|
|
121811
|
+
}
|
|
121689
121812
|
function resolveTopLevelFragmentPatchSpans(input) {
|
|
121690
121813
|
const changedIds = uniqueStableFragmentIds(input.changedFragmentIds);
|
|
121691
121814
|
if (changedIds.length !== input.changedFragmentIds.length || changedIds.length === 0) {
|
|
@@ -121753,6 +121876,7 @@ function findBlockSpanByIdInContainer(input) {
|
|
|
121753
121876
|
let cursor = input.contentStartPm;
|
|
121754
121877
|
for (let blockIndex = 0; blockIndex < input.blocks.length; blockIndex += 1) {
|
|
121755
121878
|
const block = input.blocks[blockIndex];
|
|
121879
|
+
if (blockIndex >= input.containerNode.childCount) return null;
|
|
121756
121880
|
const childNode = input.containerNode.child(blockIndex);
|
|
121757
121881
|
const fromPm = cursor;
|
|
121758
121882
|
const toPm = fromPm + childNode.nodeSize;
|
|
@@ -121792,10 +121916,12 @@ function findBlockSpanByIdInTable(input) {
|
|
|
121792
121916
|
let rowCursor = input.tableStartPm + 1;
|
|
121793
121917
|
for (let rowIndex = 0; rowIndex < input.table.rows.length; rowIndex += 1) {
|
|
121794
121918
|
const row2 = input.table.rows[rowIndex];
|
|
121919
|
+
if (rowIndex >= input.tableNode.childCount) return null;
|
|
121795
121920
|
const rowNode = input.tableNode.child(rowIndex);
|
|
121796
121921
|
let cellCursor = rowCursor + 1;
|
|
121797
121922
|
for (let cellIndex = 0; cellIndex < row2.cells.length; cellIndex += 1) {
|
|
121798
121923
|
const cell = row2.cells[cellIndex];
|
|
121924
|
+
if (cellIndex >= rowNode.childCount) return null;
|
|
121799
121925
|
const cellNode = rowNode.child(cellIndex);
|
|
121800
121926
|
const found = findBlockSpanByIdInContainer({
|
|
121801
121927
|
blocks: cell.content,
|
|
@@ -133061,6 +133187,216 @@ function createOutlineFamily(runtime) {
|
|
|
133061
133187
|
};
|
|
133062
133188
|
}
|
|
133063
133189
|
|
|
133190
|
+
// src/api/v3/ai/object.ts
|
|
133191
|
+
var applyObjectActionMetadata = {
|
|
133192
|
+
name: "ai.applyObjectAction",
|
|
133193
|
+
status: "live-with-adapter",
|
|
133194
|
+
sourceLayer: "runtime-core",
|
|
133195
|
+
liveEvidence: {
|
|
133196
|
+
runnerTest: "test/api/v3/ai/ai-object-actions.test.ts",
|
|
133197
|
+
commit: "refactor-09-object-actions"
|
|
133198
|
+
},
|
|
133199
|
+
uxIntent: {
|
|
133200
|
+
uiVisible: true,
|
|
133201
|
+
expectsUxResponse: "inline-change",
|
|
133202
|
+
expectedDelta: "image object layout changes"
|
|
133203
|
+
},
|
|
133204
|
+
agentMetadata: {
|
|
133205
|
+
readOrMutate: "mutate",
|
|
133206
|
+
boundedScope: "scope",
|
|
133207
|
+
auditCategory: "object-action-apply",
|
|
133208
|
+
contextPromptShape: "Apply an image object layout operation to an opaque actionHandle from ai.listObjectActions; preserve-only objects return typed blockers."
|
|
133209
|
+
},
|
|
133210
|
+
stateClass: "A-canonical",
|
|
133211
|
+
persistsTo: "canonical",
|
|
133212
|
+
broadcastsVia: "crdt",
|
|
133213
|
+
rwdReference: "\xA7AI API \xA7 ai.applyObjectAction"
|
|
133214
|
+
};
|
|
133215
|
+
function createObjectActionFamily(runtime) {
|
|
133216
|
+
const compiler = createScopeCompilerService(runtime);
|
|
133217
|
+
return {
|
|
133218
|
+
listObjectActions(input) {
|
|
133219
|
+
const bundle = compiler.compileBundleById(input.handle.scopeId, input.nowUtc);
|
|
133220
|
+
if (!bundle) {
|
|
133221
|
+
return {
|
|
133222
|
+
scopeId: input.handle.scopeId,
|
|
133223
|
+
actions: [],
|
|
133224
|
+
blockers: [`scope-not-resolvable:${input.handle.scopeId}`]
|
|
133225
|
+
};
|
|
133226
|
+
}
|
|
133227
|
+
const seed = documentSeed2(runtime);
|
|
133228
|
+
return {
|
|
133229
|
+
scopeId: input.handle.scopeId,
|
|
133230
|
+
actions: bundle.evidence.editableTargets?.entries.filter(isSupportedImageObjectEvidence).map((entry) => projectObjectDescriptor(runtime, seed, entry)) ?? []
|
|
133231
|
+
};
|
|
133232
|
+
},
|
|
133233
|
+
applyObjectAction(input) {
|
|
133234
|
+
emitUxResponse(runtime, {
|
|
133235
|
+
apiFn: applyObjectActionMetadata.name,
|
|
133236
|
+
intent: "object-action-apply",
|
|
133237
|
+
mockOrLive: applyObjectActionMetadata.status,
|
|
133238
|
+
uiVisible: true,
|
|
133239
|
+
expectedDelta: applyObjectActionMetadata.uxIntent.expectedDelta
|
|
133240
|
+
});
|
|
133241
|
+
const nowUtc = currentAuditTimestamp(runtime);
|
|
133242
|
+
const proposalId = input.proposalId ?? mockId(documentSeed2(runtime), `object-action-${input.actionHandle || "missing-handle"}-${input.operation.kind}`);
|
|
133243
|
+
if (!input.actionHandle) {
|
|
133244
|
+
return blockedResult2(input, proposalId, {
|
|
133245
|
+
code: "object-action-handle-required",
|
|
133246
|
+
category: "unresolved-target",
|
|
133247
|
+
message: "Object actions require an actionHandle from ai.listObjectActions.",
|
|
133248
|
+
nextStep: "Call ai.listObjectActions for the owning scope and retry with one returned actionHandle.",
|
|
133249
|
+
operation: input.operation.kind
|
|
133250
|
+
});
|
|
133251
|
+
}
|
|
133252
|
+
const target = resolveObjectActionHandle(runtime, documentSeed2(runtime), input.actionHandle);
|
|
133253
|
+
if (!target) {
|
|
133254
|
+
return blockedResult2(input, proposalId, {
|
|
133255
|
+
code: `object-action-handle-not-found:${input.actionHandle}`,
|
|
133256
|
+
category: "unresolved-target",
|
|
133257
|
+
message: "No current object action matches the supplied opaque action handle.",
|
|
133258
|
+
nextStep: "Refresh the scope bundle or call ai.listObjectActions before retrying.",
|
|
133259
|
+
actionHandle: input.actionHandle,
|
|
133260
|
+
operation: input.operation.kind
|
|
133261
|
+
});
|
|
133262
|
+
}
|
|
133263
|
+
if (!isSupportedImageTarget(target)) {
|
|
133264
|
+
return blockedResult2(input, proposalId, {
|
|
133265
|
+
code: "object-action-image-target-required",
|
|
133266
|
+
category: "blocked-target",
|
|
133267
|
+
message: "The supplied object action handle no longer identifies a mutable image target.",
|
|
133268
|
+
nextStep: "Refresh object actions; chart, OLE, custom XML, opaque, and stale object targets remain refused.",
|
|
133269
|
+
actionHandle: input.actionHandle,
|
|
133270
|
+
operation: input.operation.kind
|
|
133271
|
+
});
|
|
133272
|
+
}
|
|
133273
|
+
const mediaId = target.object?.mediaId;
|
|
133274
|
+
if (!mediaId) {
|
|
133275
|
+
return blockedResult2(input, proposalId, {
|
|
133276
|
+
code: "object-action-media-id-required",
|
|
133277
|
+
category: "blocked-target",
|
|
133278
|
+
message: "Image object layout mutation requires a mediaId-backed target.",
|
|
133279
|
+
nextStep: "Retry only with an image action handle whose readback includes mediaId.",
|
|
133280
|
+
actionHandle: input.actionHandle,
|
|
133281
|
+
operation: input.operation.kind
|
|
133282
|
+
});
|
|
133283
|
+
}
|
|
133284
|
+
const before = runtime.getCanonicalDocument();
|
|
133285
|
+
runtime.dispatch({
|
|
133286
|
+
type: "image.set-layout",
|
|
133287
|
+
mediaId,
|
|
133288
|
+
dimensions: {
|
|
133289
|
+
widthEmu: input.operation.dimensions.widthEmu,
|
|
133290
|
+
heightEmu: input.operation.dimensions.heightEmu
|
|
133291
|
+
},
|
|
133292
|
+
origin: { source: "api", timestamp: nowUtc }
|
|
133293
|
+
});
|
|
133294
|
+
const changed = runtime.getCanonicalDocument() !== before;
|
|
133295
|
+
if (!changed) {
|
|
133296
|
+
return blockedResult2(input, proposalId, {
|
|
133297
|
+
code: `object-action-noop:${input.operation.kind}:${input.actionHandle}`,
|
|
133298
|
+
category: "runtime-noop",
|
|
133299
|
+
message: "The runtime accepted the image target but the object operation produced no document change.",
|
|
133300
|
+
nextStep: "Refresh object actions and verify the image media item still exists before retrying.",
|
|
133301
|
+
actionHandle: input.actionHandle,
|
|
133302
|
+
operation: input.operation.kind
|
|
133303
|
+
});
|
|
133304
|
+
}
|
|
133305
|
+
return {
|
|
133306
|
+
proposalId,
|
|
133307
|
+
applied: true,
|
|
133308
|
+
changed: true,
|
|
133309
|
+
actionHandle: input.actionHandle,
|
|
133310
|
+
operation: input.operation.kind,
|
|
133311
|
+
commandReference: {
|
|
133312
|
+
command: "image.set-layout",
|
|
133313
|
+
actorId: input.actorId ?? "v3-ai-api",
|
|
133314
|
+
origin: input.origin ?? "agent",
|
|
133315
|
+
emittedAtUtc: nowUtc
|
|
133316
|
+
},
|
|
133317
|
+
readback: objectReadback(runtime, target),
|
|
133318
|
+
posture: "supported",
|
|
133319
|
+
support: objectActionSupport()
|
|
133320
|
+
};
|
|
133321
|
+
}
|
|
133322
|
+
};
|
|
133323
|
+
}
|
|
133324
|
+
function isSupportedImageObjectEvidence(entry) {
|
|
133325
|
+
return entry.kind === "object-anchor" && entry.commandFamily === "object" && entry.runtimeCommand.status === "supported" && entry.runtimeCommand.intents.includes("image-layout") && isImageKind(entry.object?.objectKind) && typeof entry.object?.mediaId === "string";
|
|
133326
|
+
}
|
|
133327
|
+
function projectObjectDescriptor(runtime, seed, entry) {
|
|
133328
|
+
return {
|
|
133329
|
+
actionHandle: objectActionHandle(seed, entry.targetKey),
|
|
133330
|
+
objectKind: entry.object?.objectKind ?? "unknown",
|
|
133331
|
+
targetKind: entry.kind,
|
|
133332
|
+
relation: entry.relation,
|
|
133333
|
+
callableOperations: ["set-image-layout"],
|
|
133334
|
+
supportedOperations: ["set-image-layout"],
|
|
133335
|
+
readback: objectReadback(runtime, entry),
|
|
133336
|
+
reason: entry.runtimeCommand.reason
|
|
133337
|
+
};
|
|
133338
|
+
}
|
|
133339
|
+
function resolveObjectActionHandle(runtime, seed, actionHandle) {
|
|
133340
|
+
return collectEditableTargetRefs(runtime.getCanonicalDocument()).find(
|
|
133341
|
+
(target) => objectActionHandle(seed, target.targetKey) === actionHandle && isSupportedImageTarget(target)
|
|
133342
|
+
) ?? null;
|
|
133343
|
+
}
|
|
133344
|
+
function isSupportedImageTarget(target) {
|
|
133345
|
+
return target.kind === "object-anchor" && target.commandFamily === "object" && isImageKind(target.object?.objectKind) && typeof target.object?.mediaId === "string" && target.object.mediaId.length > 0 && onlyObjectActionBlockers(target.posture.blockers, ["unmodeled-target"]);
|
|
133346
|
+
}
|
|
133347
|
+
function isImageKind(kind) {
|
|
133348
|
+
return kind === "legacy-image" || kind === "picture";
|
|
133349
|
+
}
|
|
133350
|
+
function onlyObjectActionBlockers(blockers, allowed) {
|
|
133351
|
+
const allowedSet = new Set(allowed);
|
|
133352
|
+
return blockers.every((blocker2) => allowedSet.has(blocker2));
|
|
133353
|
+
}
|
|
133354
|
+
function objectReadback(runtime, target) {
|
|
133355
|
+
const mediaId = target.object?.mediaId;
|
|
133356
|
+
if (!mediaId) return {};
|
|
133357
|
+
const media = runtime.getCanonicalDocument().media.items[mediaId];
|
|
133358
|
+
return {
|
|
133359
|
+
mediaId,
|
|
133360
|
+
...media?.widthEmu !== void 0 ? { widthEmu: media.widthEmu } : {},
|
|
133361
|
+
...media?.heightEmu !== void 0 ? { heightEmu: media.heightEmu } : {}
|
|
133362
|
+
};
|
|
133363
|
+
}
|
|
133364
|
+
function blockedResult2(input, proposalId, detail) {
|
|
133365
|
+
return {
|
|
133366
|
+
proposalId,
|
|
133367
|
+
applied: false,
|
|
133368
|
+
changed: false,
|
|
133369
|
+
actionHandle: input.actionHandle,
|
|
133370
|
+
operation: input.operation.kind,
|
|
133371
|
+
reason: detail.code,
|
|
133372
|
+
blockers: [detail.code],
|
|
133373
|
+
blockerDetails: [detail]
|
|
133374
|
+
};
|
|
133375
|
+
}
|
|
133376
|
+
function objectActionSupport() {
|
|
133377
|
+
return {
|
|
133378
|
+
undo: "supported",
|
|
133379
|
+
replay: "supported",
|
|
133380
|
+
exportReopen: "supported",
|
|
133381
|
+
audit: "command-reference"
|
|
133382
|
+
};
|
|
133383
|
+
}
|
|
133384
|
+
function objectActionHandle(seed, targetKey) {
|
|
133385
|
+
return `object-action:${hashOpaque3(`${seed}::${targetKey}`)}`;
|
|
133386
|
+
}
|
|
133387
|
+
function documentSeed2(runtime) {
|
|
133388
|
+
const state = runtime.getSessionState();
|
|
133389
|
+
return state.documentId ?? "document";
|
|
133390
|
+
}
|
|
133391
|
+
function hashOpaque3(input) {
|
|
133392
|
+
let h = 2166136261;
|
|
133393
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
133394
|
+
h ^= input.charCodeAt(i);
|
|
133395
|
+
h = Math.imul(h, 16777619);
|
|
133396
|
+
}
|
|
133397
|
+
return (h >>> 0).toString(36).padStart(7, "0");
|
|
133398
|
+
}
|
|
133399
|
+
|
|
133064
133400
|
// src/api/v3/ai/actions.ts
|
|
133065
133401
|
function actionMethodMetadata(method, readOrMutate, auditCategory, contextPromptShape, uxIntent) {
|
|
133066
133402
|
return {
|
|
@@ -133105,6 +133441,17 @@ var locateAllMetadata = actionMethodMetadata(
|
|
|
133105
133441
|
"Find scope/table-text targets by query; table text matches include readback {text,isEmpty}.",
|
|
133106
133442
|
{ uiVisible: false, expectsUxResponse: "none" }
|
|
133107
133443
|
);
|
|
133444
|
+
var createPlaceholderScopesMetadata = actionMethodMetadata(
|
|
133445
|
+
"createPlaceholderScopes",
|
|
133446
|
+
"mutate",
|
|
133447
|
+
"actions-placeholder-scopes",
|
|
133448
|
+
"Create marker-backed workflow scopes for bracketed placeholder matches in paragraphs, tables, and lists using one bounded regex search.",
|
|
133449
|
+
{
|
|
133450
|
+
uiVisible: true,
|
|
133451
|
+
expectsUxResponse: "scope-created",
|
|
133452
|
+
expectedDelta: "placeholder text ranges become workflow scopes"
|
|
133453
|
+
}
|
|
133454
|
+
);
|
|
133108
133455
|
var rewriteMetadata = actionMethodMetadata(
|
|
133109
133456
|
"rewrite",
|
|
133110
133457
|
"mutate",
|
|
@@ -133317,6 +133664,7 @@ var ACTION_METHODS = Object.freeze([
|
|
|
133317
133664
|
"discover",
|
|
133318
133665
|
"locate",
|
|
133319
133666
|
"locateAll",
|
|
133667
|
+
"createPlaceholderScopes",
|
|
133320
133668
|
"rewrite",
|
|
133321
133669
|
"rewriteAll",
|
|
133322
133670
|
"insertText",
|
|
@@ -133342,6 +133690,8 @@ var DEFAULT_LOCATE_LIMIT = 20;
|
|
|
133342
133690
|
var DEFAULT_REWRITE_ALL_LIMIT = 10;
|
|
133343
133691
|
var DEFAULT_TABLE_TEXT_SCOPE_LIMIT = 3;
|
|
133344
133692
|
var DEFAULT_PLAN_STEP_LIMIT = 20;
|
|
133693
|
+
var DEFAULT_PLACEHOLDER_QUERY = "\\[[^\\[\\]]{1,200}\\]";
|
|
133694
|
+
var DEFAULT_PLACEHOLDER_LIMIT = 200;
|
|
133345
133695
|
function createActionsFamily(runtime) {
|
|
133346
133696
|
const category = {
|
|
133347
133697
|
discover(input) {
|
|
@@ -133396,6 +133746,9 @@ function createActionsFamily(runtime) {
|
|
|
133396
133746
|
locateAll(input) {
|
|
133397
133747
|
return locateAll(runtime, input);
|
|
133398
133748
|
},
|
|
133749
|
+
createPlaceholderScopes(input) {
|
|
133750
|
+
return createPlaceholderScopes(runtime, input ?? {});
|
|
133751
|
+
},
|
|
133399
133752
|
rewrite(input) {
|
|
133400
133753
|
if (input.text === void 0) {
|
|
133401
133754
|
return blockedApply(
|
|
@@ -134164,6 +134517,169 @@ function locateAll(runtime, input) {
|
|
|
134164
134517
|
...matches.length === 0 ? { blockers: Object.freeze([`actions:locate:not-found:${input.query}`]) } : {}
|
|
134165
134518
|
};
|
|
134166
134519
|
}
|
|
134520
|
+
function createPlaceholderScopes(runtime, input) {
|
|
134521
|
+
const query = input.query ?? DEFAULT_PLACEHOLDER_QUERY;
|
|
134522
|
+
if (!query) {
|
|
134523
|
+
const detail = blocker(
|
|
134524
|
+
"actions:placeholder-scopes:query-required",
|
|
134525
|
+
"input",
|
|
134526
|
+
"Placeholder scope creation requires a non-empty query.",
|
|
134527
|
+
"Retry with a non-empty query string or omit query to use the bracketed-placeholder default."
|
|
134528
|
+
);
|
|
134529
|
+
return {
|
|
134530
|
+
status: "blocked",
|
|
134531
|
+
totalHits: 0,
|
|
134532
|
+
created: 0,
|
|
134533
|
+
blocked: 0,
|
|
134534
|
+
scopes: Object.freeze([]),
|
|
134535
|
+
blockers: Object.freeze([detail.code]),
|
|
134536
|
+
blockerDetails: Object.freeze([detail])
|
|
134537
|
+
};
|
|
134538
|
+
}
|
|
134539
|
+
const limit = Math.max(0, input.limit ?? DEFAULT_PLACEHOLDER_LIMIT);
|
|
134540
|
+
let hits;
|
|
134541
|
+
try {
|
|
134542
|
+
hits = runtime.findAllText(query, {
|
|
134543
|
+
regex: input.regex ?? true,
|
|
134544
|
+
matchCase: input.matchCase ?? true,
|
|
134545
|
+
limit
|
|
134546
|
+
});
|
|
134547
|
+
} catch {
|
|
134548
|
+
const detail = blocker(
|
|
134549
|
+
"actions:placeholder-scopes:invalid-query",
|
|
134550
|
+
"input",
|
|
134551
|
+
"The placeholder query could not be compiled or searched.",
|
|
134552
|
+
"Retry with a valid literal query or JavaScript regex pattern."
|
|
134553
|
+
);
|
|
134554
|
+
return {
|
|
134555
|
+
status: "blocked",
|
|
134556
|
+
totalHits: 0,
|
|
134557
|
+
created: 0,
|
|
134558
|
+
blocked: 0,
|
|
134559
|
+
scopes: Object.freeze([]),
|
|
134560
|
+
blockers: Object.freeze([detail.code]),
|
|
134561
|
+
blockerDetails: Object.freeze([detail])
|
|
134562
|
+
};
|
|
134563
|
+
}
|
|
134564
|
+
if (hits.length === 0) {
|
|
134565
|
+
return {
|
|
134566
|
+
status: "not-found",
|
|
134567
|
+
totalHits: 0,
|
|
134568
|
+
created: 0,
|
|
134569
|
+
blocked: 0,
|
|
134570
|
+
scopes: Object.freeze([]),
|
|
134571
|
+
blockers: Object.freeze([`actions:placeholder-scopes:not-found:${query}`])
|
|
134572
|
+
};
|
|
134573
|
+
}
|
|
134574
|
+
const surface = runtime.getRenderSnapshot().surface;
|
|
134575
|
+
const orderedHits = hits.filter((hit) => hit.kind === "range").map((hit, originalIndex) => ({
|
|
134576
|
+
hit,
|
|
134577
|
+
originalIndex,
|
|
134578
|
+
text: surface ? textForSurfaceRange(surface.blocks, hit.from, hit.to) : ""
|
|
134579
|
+
})).sort((a, b) => b.hit.from - a.hit.from || b.originalIndex - a.originalIndex);
|
|
134580
|
+
if (orderedHits.length === 0) {
|
|
134581
|
+
const detail = blocker(
|
|
134582
|
+
"actions:placeholder-scopes:no-range-hits",
|
|
134583
|
+
"unsupported",
|
|
134584
|
+
"The placeholder query matched only projections that cannot be converted into workflow ranges.",
|
|
134585
|
+
"Retry with a text query that resolves to concrete document text ranges."
|
|
134586
|
+
);
|
|
134587
|
+
return {
|
|
134588
|
+
status: "blocked",
|
|
134589
|
+
totalHits: hits.length,
|
|
134590
|
+
created: 0,
|
|
134591
|
+
blocked: hits.length,
|
|
134592
|
+
scopes: Object.freeze([]),
|
|
134593
|
+
blockers: Object.freeze([detail.code]),
|
|
134594
|
+
blockerDetails: Object.freeze([detail])
|
|
134595
|
+
};
|
|
134596
|
+
}
|
|
134597
|
+
const compiler = createScopeCompilerService(runtime);
|
|
134598
|
+
const byOriginalIndex = /* @__PURE__ */ new Map();
|
|
134599
|
+
for (const item of orderedHits) {
|
|
134600
|
+
const text = item.text || query;
|
|
134601
|
+
const label = input.labelPrefix === void 0 ? text : `${input.labelPrefix} ${item.originalIndex + 1}`;
|
|
134602
|
+
const result = createScopeFromAnchor(runtime, {
|
|
134603
|
+
anchor: { from: item.hit.from, to: item.hit.to },
|
|
134604
|
+
mode: input.mode ?? "edit",
|
|
134605
|
+
label,
|
|
134606
|
+
...input.visibility ? { visibility: input.visibility } : {},
|
|
134607
|
+
...input.guardPolicy ? { guardPolicy: input.guardPolicy } : {},
|
|
134608
|
+
...input.assoc ? { assoc: input.assoc } : {},
|
|
134609
|
+
...input.stableRefHint ? { stableRefHint: input.stableRefHint } : {}
|
|
134610
|
+
});
|
|
134611
|
+
if (result.status === "created") {
|
|
134612
|
+
const compiled = compiler.compileScopeById(result.scopeId)?.scope;
|
|
134613
|
+
byOriginalIndex.set(item.originalIndex, {
|
|
134614
|
+
status: "created",
|
|
134615
|
+
text,
|
|
134616
|
+
excerpt: excerpt(text),
|
|
134617
|
+
scopeId: result.scopeId,
|
|
134618
|
+
...compiled?.handle ? { handle: compiled.handle } : {}
|
|
134619
|
+
});
|
|
134620
|
+
continue;
|
|
134621
|
+
}
|
|
134622
|
+
const detail = blockerWithOwner(
|
|
134623
|
+
`actions:placeholder-scopes:create-refused:${result.reason}`,
|
|
134624
|
+
"blocked",
|
|
134625
|
+
"The placeholder match could not be converted into a workflow scope.",
|
|
134626
|
+
"Refresh the document and retry; if it still refuses, route the target to the workflow/scope writer owner.",
|
|
134627
|
+
"L06"
|
|
134628
|
+
);
|
|
134629
|
+
byOriginalIndex.set(item.originalIndex, {
|
|
134630
|
+
status: "blocked",
|
|
134631
|
+
text,
|
|
134632
|
+
excerpt: excerpt(text),
|
|
134633
|
+
blockers: Object.freeze([detail.code]),
|
|
134634
|
+
blockerDetails: Object.freeze([detail])
|
|
134635
|
+
});
|
|
134636
|
+
}
|
|
134637
|
+
const scopes = orderedHits.map((item) => byOriginalIndex.get(item.originalIndex)).filter((value) => value !== void 0);
|
|
134638
|
+
const created = scopes.filter((scope) => scope.status === "created").length;
|
|
134639
|
+
const blocked2 = scopes.length - created;
|
|
134640
|
+
const blockerDetails = scopes.flatMap((scope) => scope.blockerDetails ?? []);
|
|
134641
|
+
return {
|
|
134642
|
+
status: created === scopes.length ? "created" : created > 0 ? "partial" : "blocked",
|
|
134643
|
+
totalHits: hits.length,
|
|
134644
|
+
created,
|
|
134645
|
+
blocked: blocked2,
|
|
134646
|
+
scopes: Object.freeze(scopes),
|
|
134647
|
+
...blockerDetails.length > 0 ? {
|
|
134648
|
+
blockers: Object.freeze(blockerDetails.map((detail) => detail.code)),
|
|
134649
|
+
blockerDetails: Object.freeze(blockerDetails)
|
|
134650
|
+
} : {}
|
|
134651
|
+
};
|
|
134652
|
+
}
|
|
134653
|
+
function textForSurfaceRange(blocks, from, to) {
|
|
134654
|
+
let acc = "";
|
|
134655
|
+
const visit = (items) => {
|
|
134656
|
+
for (const block of items) {
|
|
134657
|
+
if (block.kind === "paragraph") {
|
|
134658
|
+
for (const segment of block.segments) {
|
|
134659
|
+
if (segment.kind !== "text") continue;
|
|
134660
|
+
if (segment.from >= to) return;
|
|
134661
|
+
if (segment.to <= from) continue;
|
|
134662
|
+
acc += segment.text.slice(
|
|
134663
|
+
Math.max(0, from - segment.from),
|
|
134664
|
+
Math.min(segment.text.length, to - segment.from)
|
|
134665
|
+
);
|
|
134666
|
+
}
|
|
134667
|
+
continue;
|
|
134668
|
+
}
|
|
134669
|
+
if (block.kind === "table") {
|
|
134670
|
+
for (const row2 of block.rows) {
|
|
134671
|
+
for (const cell of row2.cells) visit(cell.content);
|
|
134672
|
+
}
|
|
134673
|
+
continue;
|
|
134674
|
+
}
|
|
134675
|
+
if (block.kind === "sdt_block") {
|
|
134676
|
+
visit(block.children);
|
|
134677
|
+
}
|
|
134678
|
+
}
|
|
134679
|
+
};
|
|
134680
|
+
visit(blocks);
|
|
134681
|
+
return acc;
|
|
134682
|
+
}
|
|
134167
134683
|
function validateTemplateTargets(runtime, input) {
|
|
134168
134684
|
if (!Array.isArray(input.targets) || input.targets.length === 0) {
|
|
134169
134685
|
const detail = blocker(
|
|
@@ -134584,6 +135100,15 @@ function applyRewrite(runtime, target, input) {
|
|
|
134584
135100
|
if (!listTextTarget.ok) return blockedApplyFromResolution(listTextTarget);
|
|
134585
135101
|
return applyEditableTextRewrite(runtime, listTextTarget.target, input);
|
|
134586
135102
|
}
|
|
135103
|
+
const tableTextTarget = uniqueTableTextActionForScope(runtime, target.handle);
|
|
135104
|
+
if (tableTextTarget.ok && tableTextTarget.action.readback?.text === target.scope.content.text) {
|
|
135105
|
+
return applyTableScopedMarkerRewrite(
|
|
135106
|
+
runtime,
|
|
135107
|
+
target,
|
|
135108
|
+
tableTextTarget.action,
|
|
135109
|
+
input
|
|
135110
|
+
);
|
|
135111
|
+
}
|
|
134587
135112
|
const rewriteBlocker = scopeRewriteCapabilityBlocker(target.scope);
|
|
134588
135113
|
if (rewriteBlocker) {
|
|
134589
135114
|
return blockedApply(
|
|
@@ -134716,6 +135241,106 @@ function applyEditableTextRewrite(runtime, target, input) {
|
|
|
134716
135241
|
afterReadback
|
|
134717
135242
|
};
|
|
134718
135243
|
}
|
|
135244
|
+
function applyTableScopedMarkerRewrite(runtime, target, action, input) {
|
|
135245
|
+
const workflowScope = runtime.getScope(target.handle.scopeId);
|
|
135246
|
+
const editableTarget = tableEditableTargetForActionHandle(
|
|
135247
|
+
runtime,
|
|
135248
|
+
action.actionHandle
|
|
135249
|
+
);
|
|
135250
|
+
if (!workflowScope || workflowScope.anchor.kind !== "range" || !editableTarget) {
|
|
135251
|
+
return blockedApply(
|
|
135252
|
+
`actions:rewrite:table-marker-target-unresolved:${target.handle.scopeId}`,
|
|
135253
|
+
"unresolved-target",
|
|
135254
|
+
"The table-contained marker scope could not be joined to a current table text target.",
|
|
135255
|
+
"Refresh placeholder scopes and retry; route persistent failures to L08 table scope target mapping."
|
|
135256
|
+
);
|
|
135257
|
+
}
|
|
135258
|
+
const before = runtime.getCanonicalDocument();
|
|
135259
|
+
try {
|
|
135260
|
+
runtime.dispatch({
|
|
135261
|
+
type: "selection.set",
|
|
135262
|
+
selection: {
|
|
135263
|
+
anchor: workflowScope.anchor.from,
|
|
135264
|
+
head: workflowScope.anchor.to,
|
|
135265
|
+
isCollapsed: workflowScope.anchor.from === workflowScope.anchor.to,
|
|
135266
|
+
activeRange: {
|
|
135267
|
+
kind: "range",
|
|
135268
|
+
from: workflowScope.anchor.from,
|
|
135269
|
+
to: workflowScope.anchor.to,
|
|
135270
|
+
assoc: workflowScope.anchor.assoc ?? { start: -1, end: 1 }
|
|
135271
|
+
}
|
|
135272
|
+
},
|
|
135273
|
+
origin: actionOrigin(runtime, input)
|
|
135274
|
+
});
|
|
135275
|
+
runtime.applyActiveStoryTextCommand({
|
|
135276
|
+
type: "text.insert",
|
|
135277
|
+
text: input.text,
|
|
135278
|
+
editableTarget,
|
|
135279
|
+
origin: actionOrigin(runtime, input)
|
|
135280
|
+
});
|
|
135281
|
+
} catch {
|
|
135282
|
+
return blockedApply(
|
|
135283
|
+
`actions:rewrite:table-marker-command-refused:${target.handle.scopeId}`,
|
|
135284
|
+
"blocked",
|
|
135285
|
+
"The table-contained marker scope could not be rewritten by the runtime text command.",
|
|
135286
|
+
"Retry with an exact table text actionHandle; route repeated failures to L07 table text command support.",
|
|
135287
|
+
[
|
|
135288
|
+
blockerWithOwner(
|
|
135289
|
+
`actions:rewrite:table-marker-command-refused:${target.handle.scopeId}`,
|
|
135290
|
+
"blocked",
|
|
135291
|
+
"The table-contained marker scope could not be rewritten by the runtime text command.",
|
|
135292
|
+
"Retry with an exact table text actionHandle; route repeated failures to L07 table text command support.",
|
|
135293
|
+
"L07 runtime text command support"
|
|
135294
|
+
)
|
|
135295
|
+
]
|
|
135296
|
+
);
|
|
135297
|
+
}
|
|
135298
|
+
const changed = runtime.getCanonicalDocument() !== before;
|
|
135299
|
+
const paragraph = resolveParagraphTextTarget2(
|
|
135300
|
+
runtime.getCanonicalDocument(),
|
|
135301
|
+
editableTarget
|
|
135302
|
+
);
|
|
135303
|
+
const afterText = paragraph ? collectInlineText4(paragraph.children) : void 0;
|
|
135304
|
+
const afterReadback = afterText === void 0 ? void 0 : { text: afterText, isEmpty: afterText.length === 0 };
|
|
135305
|
+
if (!changed || afterReadback?.text !== input.text) {
|
|
135306
|
+
return {
|
|
135307
|
+
status: "blocked",
|
|
135308
|
+
applied: false,
|
|
135309
|
+
changed,
|
|
135310
|
+
target: summarizeTarget({ kind: "table-text", action }),
|
|
135311
|
+
posture: "suspect-readback",
|
|
135312
|
+
blockers: Object.freeze([
|
|
135313
|
+
`actions:rewrite:table-marker-readback-mismatch:${target.handle.scopeId}`
|
|
135314
|
+
]),
|
|
135315
|
+
blockerDetails: Object.freeze([
|
|
135316
|
+
blocker(
|
|
135317
|
+
`actions:rewrite:table-marker-readback-mismatch:${target.handle.scopeId}`,
|
|
135318
|
+
"blocked",
|
|
135319
|
+
"The table-contained marker rewrite did not produce the requested exact table-cell readback.",
|
|
135320
|
+
"Treat the mutation as suspect. Re-read the target and export before claiming success."
|
|
135321
|
+
)
|
|
135322
|
+
]),
|
|
135323
|
+
...afterReadback ? { afterReadback } : {}
|
|
135324
|
+
};
|
|
135325
|
+
}
|
|
135326
|
+
return {
|
|
135327
|
+
status: "applied",
|
|
135328
|
+
applied: true,
|
|
135329
|
+
changed: true,
|
|
135330
|
+
target: summarizeTarget({
|
|
135331
|
+
kind: "table-text",
|
|
135332
|
+
action: { ...action, readback: afterReadback }
|
|
135333
|
+
}),
|
|
135334
|
+
commandReference: {
|
|
135335
|
+
command: "text.insert",
|
|
135336
|
+
actorId: input.actorId ?? "v3-ai-api",
|
|
135337
|
+
origin: input.origin ?? "agent",
|
|
135338
|
+
emittedAtUtc: currentAuditTimestamp(runtime)
|
|
135339
|
+
},
|
|
135340
|
+
...action.readback ? { beforeReadback: action.readback } : {},
|
|
135341
|
+
afterReadback
|
|
135342
|
+
};
|
|
135343
|
+
}
|
|
134719
135344
|
function projectRewriteScopeResult(runtime, result, target, beforeText, proposedText, documentMutated) {
|
|
134720
135345
|
if (!result.applied) return projectApplyResult(result, target);
|
|
134721
135346
|
const compiledAfter = createScopeCompilerService(runtime).compileScopeById(
|
|
@@ -134832,6 +135457,51 @@ function tableTextActionsForScope(runtime, handle) {
|
|
|
134832
135457
|
});
|
|
134833
135458
|
return result.actions.filter((action) => action.family === "table-text");
|
|
134834
135459
|
}
|
|
135460
|
+
function uniqueTableTextActionForScope(runtime, handle) {
|
|
135461
|
+
const actions2 = tableTextActionsForScope(runtime, handle).filter(
|
|
135462
|
+
(action) => action.readback !== void 0
|
|
135463
|
+
);
|
|
135464
|
+
if (actions2.length === 1 && actions2[0]) {
|
|
135465
|
+
return { ok: true, action: actions2[0] };
|
|
135466
|
+
}
|
|
135467
|
+
if (actions2.length === 0) {
|
|
135468
|
+
return {
|
|
135469
|
+
ok: false,
|
|
135470
|
+
blockers: Object.freeze(["actions:rewrite:table-text-target-missing"]),
|
|
135471
|
+
blockerDetails: Object.freeze([
|
|
135472
|
+
blocker(
|
|
135473
|
+
"actions:rewrite:table-text-target-missing",
|
|
135474
|
+
"unsupported",
|
|
135475
|
+
"The scope does not expose a unique command-safe table text target.",
|
|
135476
|
+
"Use a paragraph/list scope, or retry with an exact table text actionHandle returned by ai.actions.locateAll."
|
|
135477
|
+
)
|
|
135478
|
+
])
|
|
135479
|
+
};
|
|
135480
|
+
}
|
|
135481
|
+
return {
|
|
135482
|
+
ok: false,
|
|
135483
|
+
blockers: Object.freeze(["actions:rewrite:table-text-target-ambiguous"]),
|
|
135484
|
+
blockerDetails: Object.freeze([
|
|
135485
|
+
blocker(
|
|
135486
|
+
"actions:rewrite:table-text-target-ambiguous",
|
|
135487
|
+
"ambiguous-target",
|
|
135488
|
+
"The scope exposes multiple table text targets, so broad rewrite would be ambiguous.",
|
|
135489
|
+
"Retry with the exact table text actionHandle returned by ai.actions.locateAll or ai.listTableActions."
|
|
135490
|
+
)
|
|
135491
|
+
])
|
|
135492
|
+
};
|
|
135493
|
+
}
|
|
135494
|
+
function tableEditableTargetForActionHandle(runtime, actionHandle) {
|
|
135495
|
+
for (const target of collectEditableTargetRefs(runtime.getCanonicalDocument())) {
|
|
135496
|
+
if (target.commandFamily !== "text-leaf" || target.table?.operationScope !== "text") {
|
|
135497
|
+
continue;
|
|
135498
|
+
}
|
|
135499
|
+
if (deriveTableActionHandleForTarget(runtime, target.targetKey) === actionHandle) {
|
|
135500
|
+
return target;
|
|
135501
|
+
}
|
|
135502
|
+
}
|
|
135503
|
+
return null;
|
|
135504
|
+
}
|
|
134835
135505
|
function editableTextActionsForScope(runtime, handle) {
|
|
134836
135506
|
const bundle = createScopeCompilerService(runtime).compileBundleById(
|
|
134837
135507
|
handle.scopeId,
|
|
@@ -136355,6 +137025,7 @@ function createApiV3(handle, opts) {
|
|
|
136355
137025
|
...createStatsFamily(handle),
|
|
136356
137026
|
...createOutlineFamily(handle),
|
|
136357
137027
|
...createTableActionFamily(handle),
|
|
137028
|
+
...createObjectActionFamily(handle),
|
|
136358
137029
|
...createActionsFamily(handle)
|
|
136359
137030
|
};
|
|
136360
137031
|
const runtime = {
|
|
@@ -139162,6 +139833,9 @@ var WordReviewEditor = (0, import_react71.forwardRef)(
|
|
|
139162
139833
|
onUpdateFields: () => {
|
|
139163
139834
|
activeRuntime.updateFields();
|
|
139164
139835
|
},
|
|
139836
|
+
onUpdateTableOfContents: () => {
|
|
139837
|
+
activeRuntime.updateTableOfContents();
|
|
139838
|
+
},
|
|
139165
139839
|
onAskAgentForSelection: () => {
|
|
139166
139840
|
const { selection } = snapshot;
|
|
139167
139841
|
onEventRef.current?.({
|