@stll/folio-react 0.25.1 → 0.25.3

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.
@@ -9,6 +9,7 @@ import { closeHistory, redo, undo } from "prosemirror-history";
9
9
  import { IntlProvider, useFormatter, useTranslations } from "use-intl";
10
10
  import { FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FolioPendingSuggestionRegistry, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, createFolioAIEditSnapshot, createPendingSuggestionSourceSnapshot, getCommentAnchorsFromDoc, getFolioDocumentOperationIssues, getTrackedChangesFromDoc } from "@stll/folio-core/ai-edits";
11
11
  import { resolveCanonicalReviewRange } from "@stll/folio-core/controller/canonicalReview";
12
+ import { afterCanonicalCompositionSettles } from "@stll/folio-core/controller/canonicalInputTimer";
12
13
  import { resolveActiveEditorStory } from "@stll/folio-core/controller/activeEditorStory";
13
14
  import { FOLIO_DOCX_SERIALIZATION_MODE, createFolioEditor } from "@stll/folio-core/controller/folioEditor";
14
15
  import { createNoteReferenceFollower, withoutUnreferencedNotes } from "@stll/folio-core/prosemirror/noteReferenceReview";
@@ -43,14 +44,15 @@ import { resolveColor } from "@stll/folio-core/utils/colorResolver";
43
44
  import { closestHtmlElement, htmlQueryAll, queryHtmlElement } from "@stll/folio-core/utils/domGuards";
44
45
  import { onFontsLoaded } from "@stll/folio-core/utils/fontLoader";
45
46
  import { collectHeadings } from "@stll/folio-core/utils/headingCollector";
47
+ import { DEFAULT_OUTLINE_DEPTH, filterHeadingsByDepth } from "@stll/folio-core/utils/outlineDepth";
46
48
  import { formatPx, pixelsToTwips, pointsToHalfPoints, twipsToPixels } from "@stll/folio-core/utils/units";
47
49
  import { HistoryManager, classifyHistoryShortcut } from "@stll/folio-core/managers/HistoryManager";
48
- import { createCanonicalHeaderFooterOperation, createCanonicalSectionPropertiesOperation, removeCanonicalHeaderFooterOperations } from "@stll/folio-core/controller/canonicalOperations";
49
50
  import { CanonicalSaveDiagnosticError, serializeCanonicalSave } from "@stll/folio-core/docx/canonicalSave";
50
51
  import { TableSelectionManager } from "@stll/folio-core/managers/TableSelectionManager";
51
52
  import { DEFAULT_PAGE_HEIGHT_PX, getMargins, getPageSize, twipsToPixels as twipsToPixels$1 } from "@stll/folio-core/paged-layout/sectionGeometry";
52
53
  import { getFootnoteText } from "@stll/folio-core/docx/storyPlainText";
53
54
  import { createPortal } from "react-dom";
55
+ import { panic } from "better-result";
54
56
  import { NodeSelection, Selection, TextSelection as TextSelection$1 } from "prosemirror-state";
55
57
  import { CellSelection } from "prosemirror-tables";
56
58
  import { createHeaderFooterEditorManager } from "@stll/folio-core/controller/headerFooterEditorManager";
@@ -97,7 +99,6 @@ import { findStartPosForParaId } from "@stll/folio-core/prosemirror/utils/findPa
97
99
  import { allowsDirectDrawingEdit } from "@stll/folio-core/docx/imageRawXml";
98
100
  import { commitImageFloatMove, commitImageInlineMove, commitImageResize, isFloatingImage } from "@stll/folio-core/prosemirror/imageCommit";
99
101
  import { buildEmbeddedFontFamilyMap, extractEmbeddedFonts } from "@stll/folio-core/fonts/embeddedFonts";
100
- import { panic } from "better-result";
101
102
  import { loadCollaborationModules } from "@stll/folio-core/controller/collaborationModules";
102
103
  import { createVisualLineState, handleVisualLineKeyDown } from "@stll/folio-core/prosemirror/utils/visualLineNavigation";
103
104
  import { clampRangeToDocSize, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange } from "@stll/folio-core/ai-edits/blockRange";
@@ -114,6 +115,7 @@ import { getDocumentLoadSource } from "@stll/folio-core/utils/documentLoaderBeha
114
115
  import { DISPLAY_MODES, EditorModeManager, isReadOnlyMode, isTrackChangesMode, toggledTrackChangesMode } from "@stll/folio-core/managers/EditorModeManager";
115
116
  import { FindReplaceManager } from "@stll/folio-core/managers/FindReplaceManager";
116
117
  import { createEmptyHeaderFooter, pickActiveHeaderFooterRId, removeHeaderFooter, resolveEffectiveSectionProperties, resolveHeaderFooterContent, saveHeaderFooterContent } from "@stll/folio-core/utils/headerFooter";
118
+ import { createCanonicalHeaderFooterOperation, removeCanonicalHeaderFooterOperations } from "@stll/folio-core/controller/canonicalOperations";
117
119
  import { editHyperlinkAtCursor, removeHyperlinkAtCursor } from "@stll/folio-core/prosemirror/commands/hyperlink";
118
120
  import { anchorTargetAttrs, sanitizeExternalUrl, windowFeaturesFor } from "@stll/folio-core/utils/urlSecurity";
119
121
  import { applyImagePosition, applyImageProperties, applyImageTransform, applyImageWrapType, insertImageFromFile } from "@stll/folio-core/prosemirror/commands/image";
@@ -369,7 +371,7 @@ const HiddenHeaderFooterPMs = memo(forwardRef(function HiddenHeaderFooterPMs({ d
369
371
  getTheme: () => themeRef.current,
370
372
  getCanonicalApi: () => canonicalApiRef.current?.() ?? null,
371
373
  getExperimentalSession: () => sessionRef.current,
372
- onSessionRefusal: (reason, gap) => refusalRef.current?.(reason, gap),
374
+ onSessionRefusal: (reason, gap, error) => refusalRef.current?.(reason, gap, error),
373
375
  onTransaction: ({ rId, kind, view, docChanged, selectionChanged }) => {
374
376
  onTransactionRef.current?.(rId, kind, view, docChanged, selectionChanged);
375
377
  }
@@ -476,14 +478,11 @@ const NoteStoryEditor = forwardRef(function NoteStoryEditor(t0, ref) {
476
478
  getTheme: () => themeRef.current,
477
479
  getCanonicalApi: () => canonicalApiRef.current?.() ?? null,
478
480
  getExperimentalSession: () => sessionRef.current,
479
- onSessionRefusal: (reason, gap) => refusalRef.current?.(reason, gap),
481
+ onSessionRefusal: (reason, gap, error) => refusalRef.current?.(reason, gap, error),
480
482
  onTransaction: (t2) => {
481
483
  const { docChanged, selectionChanged, view } = t2;
482
- if (docChanged) if (usesCanonicalSession(sessionRef.current, CANONICAL_GAP.secondaryStories)) {
483
- const canonical = canonicalApiRef.current?.()?.getCanonicalDocument();
484
- if (canonical) onDocumentChangeRef.current(canonical);
485
- } else {
486
- const current = documentRef.current;
484
+ if (docChanged) {
485
+ const current = canonicalApiRef.current?.()?.getCanonicalDocument() ?? documentRef.current;
487
486
  if (current) onDocumentChangeRef.current(managerRef.current?.snapshotDocument(current) ?? current);
488
487
  }
489
488
  onStoryChangeRef.current(view, docChanged, selectionChanged);
@@ -1319,7 +1318,7 @@ const HiddenProseMirror = forwardRef((props, ref) => {
1319
1318
  getExperimentalSession: () => experimentalSessionRef.current,
1320
1319
  getEditingMode: () => suggestionModeActiveRef.current ? "suggesting" : "editing",
1321
1320
  getSuggestionAuthor: () => suggestionAuthorRef.current,
1322
- onSessionRefusal: (reason, gap) => onSessionRefusalRef.current?.(reason, gap),
1321
+ onSessionRefusal: (reason, gap, error) => onSessionRefusalRef.current?.(reason, gap, error),
1323
1322
  getDocumentIdentity: () => documentIdentityRef.current,
1324
1323
  getDocumentContext: () => documentRef.current,
1325
1324
  onTransaction: (update) => onTransactionRef.current?.(update),
@@ -1346,10 +1345,10 @@ const HiddenProseMirror = forwardRef((props, ref) => {
1346
1345
  setCollaborationModules(modules);
1347
1346
  setCollaborationModulesError(null);
1348
1347
  }
1349
- }, (error) => {
1348
+ }, (error_0) => {
1350
1349
  if (!cancelled) {
1351
1350
  setCollaborationModules(null);
1352
- setCollaborationModulesError(error);
1351
+ setCollaborationModulesError(error_0);
1353
1352
  }
1354
1353
  });
1355
1354
  return () => {
@@ -1403,7 +1402,8 @@ const HiddenProseMirror = forwardRef((props, ref) => {
1403
1402
  }, [readOnly]);
1404
1403
  useImperativeHandle(ref, () => ({
1405
1404
  ...managerRef.current.api,
1406
- getHostElement: () => hostRef.current
1405
+ getHostElement: () => hostRef.current,
1406
+ isCanonicalComposing: () => managerRef.current?.isCanonicalComposing() ?? false
1407
1407
  }), []);
1408
1408
  if (hasCollaboration && collaborationModulesError) {
1409
1409
  let detail = "unknown error";
@@ -2901,8 +2901,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2901
2901
  onActiveNoteStoryChange?.(story);
2902
2902
  }, [onActiveNoteStoryChange]);
2903
2903
  useEffect(() => {
2904
- if (readOnly || usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) noteEditorRef.current?.close();
2905
- }, [experimentalSession, readOnly]);
2904
+ if (readOnly) noteEditorRef.current?.close();
2905
+ }, [readOnly]);
2906
2906
  const getCanonicalApi = useCallback(() => hiddenPMRef.current, []);
2907
2907
  const { handlePMKeyDown } = useVisualLineNavigation({ pagesContainerRef });
2908
2908
  const handleHiddenEditorKeyDown = useCallback((view, event) => {
@@ -2923,8 +2923,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2923
2923
  onDocumentChangeRef.current = onDocumentChange;
2924
2924
  onTotalPagesChangeRef.current = onTotalPagesChange;
2925
2925
  onErrorRef.current = onError;
2926
- const handleSessionRefusal = useCallback((message, gap) => {
2927
- onErrorRef.current?.(new CanonicalSessionRefusalError({
2926
+ const handleSessionRefusal = useCallback((message, gap, error) => {
2927
+ onErrorRef.current?.(error ?? new CanonicalSessionRefusalError({
2928
2928
  gap,
2929
2929
  message
2930
2930
  }));
@@ -3175,7 +3175,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3175
3175
  runLayoutPipelineRef.current(state, { reason: "hyphenation-ready" });
3176
3176
  if (view_1) updateSelectionOverlayRef.current(view_1.state);
3177
3177
  },
3178
- onError: (error) => onErrorRef.current?.(error)
3178
+ onError: (error_0) => onErrorRef.current?.(error_0)
3179
3179
  }));
3180
3180
  useEffect(() => hyphenationReadiness.cancel, [hyphenationReadiness]);
3181
3181
  const laidOutLayoutInputSignatureRef = useRef(null);
@@ -3313,6 +3313,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3313
3313
  clock: browserClock
3314
3314
  });
3315
3315
  const documentChangeNotifyTimerRef = useRef(null);
3316
+ const compositionNotificationRetryRef = useRef(null);
3316
3317
  const [noteFollower] = useState(createNoteReferenceFollower);
3317
3318
  useEffect(() => {
3318
3319
  noteFollower.reset();
@@ -3322,6 +3323,16 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3322
3323
  window.clearTimeout(documentChangeNotifyTimerRef.current);
3323
3324
  documentChangeNotifyTimerRef.current = null;
3324
3325
  }
3326
+ if (hiddenPMRef.current?.isCanonicalComposing()) {
3327
+ const activeView = getActiveEditorStory().view ?? panic("Canonical composition requires an editor view.");
3328
+ if (compositionNotificationRetryRef.current === null) compositionNotificationRetryRef.current = afterCanonicalCompositionSettles(activeView, () => {
3329
+ compositionNotificationRetryRef.current = null;
3330
+ flushDocumentChangeNotification();
3331
+ });
3332
+ return;
3333
+ }
3334
+ compositionNotificationRetryRef.current?.();
3335
+ compositionNotificationRetryRef.current = null;
3325
3336
  let newDoc = hiddenPMRef.current?.getDocument();
3326
3337
  const body = hiddenPMRef.current?.getState()?.doc;
3327
3338
  if (newDoc && body && !usesCanonicalSession(experimentalSession, CANONICAL_GAP.save)) newDoc = noteFollower.reconcile(newDoc, body);
@@ -3329,7 +3340,11 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3329
3340
  onDocumentChangeRef.current?.(usesCanonicalSession(experimentalSession, CANONICAL_GAP.save) ? cloneDocumentWithParagraphPropertySources(newDoc) : newDoc);
3330
3341
  folioEmitterRef.current.emit("docChange", usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? cloneDocumentWithParagraphPropertySources(newDoc) : newDoc);
3331
3342
  }
3332
- }, [experimentalSession, noteFollower]);
3343
+ }, [
3344
+ experimentalSession,
3345
+ noteFollower,
3346
+ getActiveEditorStory
3347
+ ]);
3333
3348
  const scheduleDocumentChangeNotification = useCallback(() => {
3334
3349
  if (documentChangeNotifyTimerRef.current !== null) window.clearTimeout(documentChangeNotifyTimerRef.current);
3335
3350
  documentChangeNotifyTimerRef.current = window.setTimeout(() => {
@@ -3342,6 +3357,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3342
3357
  }, []);
3343
3358
  useEffect(() => () => {
3344
3359
  layoutSchedulerRef.current?.dispose();
3360
+ compositionNotificationRetryRef.current?.();
3361
+ compositionNotificationRetryRef.current = null;
3345
3362
  if (documentChangeNotifyTimerRef.current !== null) {
3346
3363
  window.clearTimeout(documentChangeNotifyTimerRef.current);
3347
3364
  documentChangeNotifyTimerRef.current = null;
@@ -4837,10 +4854,6 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4837
4854
  if (story_0) {
4838
4855
  e_3.preventDefault();
4839
4856
  e_3.stopPropagation();
4840
- if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
4841
- handleSessionRefusal("Footnote and endnote editing is unavailable in this session.", CANONICAL_GAP.secondaryStories);
4842
- return;
4843
- }
4844
4857
  noteEditorRef.current?.open(story_0);
4845
4858
  return;
4846
4859
  }
@@ -4984,9 +4997,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4984
4997
  }
4985
4998
  }
4986
4999
  }, [
4987
- experimentalSession,
4988
5000
  getPositionFromMouse,
4989
- handleSessionRefusal,
4990
5001
  onHeaderFooterDoubleClick,
4991
5002
  onHyperlinkClick,
4992
5003
  readOnly
@@ -5505,14 +5516,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5505
5516
  return folioEditor.getView();
5506
5517
  },
5507
5518
  getActiveView() {
5508
- if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return folioEditor.getView();
5509
5519
  return getActiveEditorStory().view;
5510
5520
  },
5511
5521
  closeNoteStory() {
5512
5522
  noteEditorRef.current?.close();
5513
5523
  },
5514
5524
  getHfView(rId_0) {
5515
- if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return null;
5516
5525
  return hfPMsRef.current?.getView(rId_0) ?? null;
5517
5526
  },
5518
5527
  ensureView(options_4) {
@@ -7649,35 +7658,31 @@ const initialFocusTarget = (container, initial) => {
7649
7658
  if (initial === "container") return container;
7650
7659
  return container.querySelector("[aria-current=\"true\"]") ?? container.querySelector(LIST_TAB_STOP) ?? container.querySelector(FOCUSABLE) ?? container;
7651
7660
  };
7652
- /**
7653
- * While `onClose` is set, `container` is an open drawer: focus moves into it,
7654
- * Escape calls `onClose`, and once it closes focus returns to what had it
7655
- * before, if that is still in the document.
7656
- */
7657
- const useDrawerFocus = (container, onClose, t0) => {
7658
- const $ = c(8);
7659
- const initial = t0 === void 0 ? "item" : t0;
7661
+ const useDrawerFocus = (options) => {
7662
+ const $ = c(9);
7663
+ const { container, onClose, returnFocusRef } = options;
7664
+ const initial = options.initial ?? "item";
7660
7665
  const onCloseRef = useRef(onClose);
7666
+ let t0;
7661
7667
  let t1;
7662
- let t2;
7663
7668
  if ($[0] !== onClose) {
7664
- t1 = () => {
7669
+ t0 = () => {
7665
7670
  onCloseRef.current = onClose;
7666
7671
  };
7667
- t2 = [onClose];
7672
+ t1 = [onClose];
7668
7673
  $[0] = onClose;
7669
- $[1] = t1;
7670
- $[2] = t2;
7674
+ $[1] = t0;
7675
+ $[2] = t1;
7671
7676
  } else {
7672
- t1 = $[1];
7673
- t2 = $[2];
7677
+ t0 = $[1];
7678
+ t1 = $[2];
7674
7679
  }
7675
- useEffect(t1, t2);
7680
+ useEffect(t0, t1);
7676
7681
  const active = onClose !== null;
7682
+ let t2;
7677
7683
  let t3;
7678
- let t4;
7679
- if ($[3] !== active || $[4] !== container || $[5] !== initial) {
7680
- t3 = () => {
7684
+ if ($[3] !== active || $[4] !== container || $[5] !== initial || $[6] !== returnFocusRef) {
7685
+ t2 = () => {
7681
7686
  if (!active) return;
7682
7687
  const previous = document.activeElement instanceof HTMLElement ? document.activeElement : null;
7683
7688
  const element = container.current;
@@ -7690,24 +7695,28 @@ const useDrawerFocus = (container, onClose, t0) => {
7690
7695
  document.addEventListener("keydown", handleKeyDown);
7691
7696
  return () => {
7692
7697
  document.removeEventListener("keydown", handleKeyDown);
7693
- if (previous?.isConnected) previous.focus({ preventScroll: true });
7698
+ const returnTarget = returnFocusRef?.current;
7699
+ const target = returnTarget?.isConnected ? returnTarget : previous;
7700
+ if (target?.isConnected) target.focus({ preventScroll: true });
7694
7701
  };
7695
7702
  };
7696
- t4 = [
7703
+ t3 = [
7697
7704
  active,
7698
7705
  container,
7699
- initial
7706
+ initial,
7707
+ returnFocusRef
7700
7708
  ];
7701
7709
  $[3] = active;
7702
7710
  $[4] = container;
7703
7711
  $[5] = initial;
7704
- $[6] = t3;
7705
- $[7] = t4;
7712
+ $[6] = returnFocusRef;
7713
+ $[7] = t2;
7714
+ $[8] = t3;
7706
7715
  } else {
7707
- t3 = $[6];
7708
- t4 = $[7];
7716
+ t2 = $[7];
7717
+ t3 = $[8];
7709
7718
  }
7710
- useEffect(t3, t4);
7719
+ useEffect(t2, t3);
7711
7720
  };
7712
7721
  /** Dims the page under an open drawer; pressing it closes the drawer. */
7713
7722
  const PanelScrim = (t0) => {
@@ -7734,164 +7743,188 @@ const PanelScrim = (t0) => {
7734
7743
  const SURFACE_WIDTH = {
7735
7744
  column: PANEL_METRICS.outlineColumnWidth,
7736
7745
  rail: PANEL_METRICS.outlineRailWidth,
7737
- drawer: PANEL_METRICS.drawerWidth
7746
+ expanded: PANEL_METRICS.outlineColumnWidth
7738
7747
  };
7739
7748
  const DocumentOutline = (t0) => {
7740
- const $ = c(55);
7741
- const { headings, scrollContainerRef, docSize, activeId, onJump, surface, expanded, onExpand, onClose } = t0;
7749
+ const $ = c(91);
7750
+ const { headings, available, outlineDepth, onOutlineDepthChange, scrollContainerRef, docSize, activeId, onJump, surface, expanded, onExpand, onClose, width: widthOverride } = t0;
7742
7751
  const t = useTranslations("folio");
7743
7752
  const OutlineRail = useFolioUI().OutlineRail;
7744
7753
  const navRef = useRef(null);
7745
- useDrawerFocus(navRef, surface === "drawer" && onClose ? onClose : null);
7746
- let t1;
7747
- if ($[0] !== headings) {
7748
- t1 = headings.map(_temp$7);
7749
- $[0] = headings;
7750
- $[1] = t1;
7751
- } else t1 = $[1];
7752
- const items = t1;
7754
+ const expandButtonRef = useRef(null);
7755
+ const t1 = surface === "expanded" && onClose ? onClose : null;
7756
+ let t2;
7757
+ if ($[0] !== t1) {
7758
+ t2 = {
7759
+ container: navRef,
7760
+ onClose: t1,
7761
+ returnFocusRef: expandButtonRef
7762
+ };
7763
+ $[0] = t1;
7764
+ $[1] = t2;
7765
+ } else t2 = $[1];
7766
+ useDrawerFocus(t2);
7767
+ let t3;
7768
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
7769
+ t3 = {
7770
+ minWidth: PANEL_METRICS.controlMinimumSize,
7771
+ minHeight: PANEL_METRICS.controlMinimumSize
7772
+ };
7773
+ $[2] = t3;
7774
+ } else t3 = $[2];
7775
+ const controlMinimumStyle = t3;
7776
+ let t4;
7777
+ if ($[3] !== headings) {
7778
+ t4 = headings.map(_temp$7);
7779
+ $[3] = headings;
7780
+ $[4] = t4;
7781
+ } else t4 = $[4];
7782
+ const items = t4;
7753
7783
  let map;
7754
- if ($[2] !== docSize || $[3] !== headings) {
7784
+ if ($[5] !== docSize || $[6] !== headings) {
7755
7785
  map = /* @__PURE__ */ new Map();
7756
7786
  if (docSize > 0) for (const heading_0 of headings) map.set(headingId(heading_0), Math.min(99, Math.max(1, heading_0.pmPos / docSize * 100)));
7757
- $[2] = docSize;
7758
- $[3] = headings;
7759
- $[4] = map;
7760
- } else map = $[4];
7787
+ $[5] = docSize;
7788
+ $[6] = headings;
7789
+ $[7] = map;
7790
+ } else map = $[7];
7761
7791
  const pctById = map;
7762
- let t2;
7763
- if ($[5] !== onClose || $[6] !== onJump || $[7] !== surface) {
7764
- t2 = (id) => {
7792
+ let t5;
7793
+ if ($[8] !== onClose || $[9] !== onJump || $[10] !== surface) {
7794
+ t5 = (id) => {
7765
7795
  onJump(id);
7766
- if (surface === "drawer") onClose?.();
7796
+ if (surface === "expanded") onClose?.();
7767
7797
  };
7768
- $[5] = onClose;
7769
- $[6] = onJump;
7770
- $[7] = surface;
7771
- $[8] = t2;
7772
- } else t2 = $[8];
7773
- const handleJump = t2;
7774
- let t3;
7775
- if ($[9] !== pctById) {
7776
- t3 = (id_0) => pctById.get(id_0) ?? null;
7777
- $[9] = pctById;
7778
- $[10] = t3;
7779
- } else t3 = $[10];
7780
- const resolvePct = t3;
7781
- if (headings.length < 2) return null;
7782
- let t4;
7783
- if ($[11] !== t) {
7784
- t4 = t("editor.showDocumentOutline");
7785
- $[11] = t;
7786
- $[12] = t4;
7787
- } else t4 = $[12];
7788
- const outlineLabel = t4;
7789
- const width = SURFACE_WIDTH[surface];
7790
- const t5 = surface === "rail" ? "rail" : "panel";
7798
+ $[8] = onClose;
7799
+ $[9] = onJump;
7800
+ $[10] = surface;
7801
+ $[11] = t5;
7802
+ } else t5 = $[11];
7803
+ const handleJump = t5;
7791
7804
  let t6;
7792
- if ($[13] !== OutlineRail || $[14] !== activeId || $[15] !== handleJump || $[16] !== items || $[17] !== outlineLabel || $[18] !== resolvePct || $[19] !== scrollContainerRef || $[20] !== t5 || $[21] !== width) {
7793
- t6 = /* @__PURE__ */ jsx(OutlineRail, {
7805
+ if ($[12] !== pctById) {
7806
+ t6 = (id_0) => pctById.get(id_0) ?? null;
7807
+ $[12] = pctById;
7808
+ $[13] = t6;
7809
+ } else t6 = $[13];
7810
+ const resolvePct = t6;
7811
+ if (!available) return null;
7812
+ let t7;
7813
+ if ($[14] !== t) {
7814
+ t7 = t("editor.showDocumentOutline");
7815
+ $[14] = t;
7816
+ $[15] = t7;
7817
+ } else t7 = $[15];
7818
+ const outlineLabel = t7;
7819
+ const width = widthOverride ?? SURFACE_WIDTH[surface];
7820
+ const t8 = surface === "rail" ? "rail" : "panel";
7821
+ let t9;
7822
+ if ($[16] !== OutlineRail || $[17] !== activeId || $[18] !== handleJump || $[19] !== items || $[20] !== outlineLabel || $[21] !== resolvePct || $[22] !== scrollContainerRef || $[23] !== t8 || $[24] !== width) {
7823
+ t9 = /* @__PURE__ */ jsx(OutlineRail, {
7794
7824
  activeId,
7795
7825
  ariaLabel: outlineLabel,
7796
7826
  items,
7797
7827
  onJump: handleJump,
7798
7828
  panelWidth: width,
7799
- presentation: t5,
7829
+ presentation: t8,
7800
7830
  resolvePct,
7801
7831
  scrollContainerRef,
7802
7832
  topOffset: 0
7803
7833
  });
7804
- $[13] = OutlineRail;
7805
- $[14] = activeId;
7806
- $[15] = handleJump;
7807
- $[16] = items;
7808
- $[17] = outlineLabel;
7809
- $[18] = resolvePct;
7810
- $[19] = scrollContainerRef;
7811
- $[20] = t5;
7812
- $[21] = width;
7813
- $[22] = t6;
7814
- } else t6 = $[22];
7815
- const rail = t6;
7834
+ $[16] = OutlineRail;
7835
+ $[17] = activeId;
7836
+ $[18] = handleJump;
7837
+ $[19] = items;
7838
+ $[20] = outlineLabel;
7839
+ $[21] = resolvePct;
7840
+ $[22] = scrollContainerRef;
7841
+ $[23] = t8;
7842
+ $[24] = width;
7843
+ $[25] = t9;
7844
+ } else t9 = $[25];
7845
+ const rail = t9;
7816
7846
  if (surface === "rail") {
7817
- let t7;
7818
- if ($[23] !== width) {
7819
- t7 = { width };
7820
- $[23] = width;
7821
- $[24] = t7;
7822
- } else t7 = $[24];
7823
- const t8 = expanded ?? false;
7824
- let t9;
7825
- if ($[25] === Symbol.for("react.memo_cache_sentinel")) {
7826
- t9 = /* @__PURE__ */ jsx(PanelLeftOpenIcon, {
7847
+ let t10;
7848
+ if ($[26] !== width) {
7849
+ t10 = { width };
7850
+ $[26] = width;
7851
+ $[27] = t10;
7852
+ } else t10 = $[27];
7853
+ const t11 = expanded ?? false;
7854
+ let t12;
7855
+ if ($[28] === Symbol.for("react.memo_cache_sentinel")) {
7856
+ t12 = /* @__PURE__ */ jsx(PanelLeftOpenIcon, {
7827
7857
  "aria-hidden": "true",
7828
7858
  size: 16
7829
7859
  });
7830
- $[25] = t9;
7831
- } else t9 = $[25];
7832
- let t10;
7833
- if ($[26] !== onExpand || $[27] !== outlineLabel || $[28] !== t8) {
7834
- t10 = /* @__PURE__ */ jsx("button", {
7835
- "aria-expanded": t8,
7860
+ $[28] = t12;
7861
+ } else t12 = $[28];
7862
+ let t13;
7863
+ if ($[29] !== onExpand || $[30] !== outlineLabel || $[31] !== t11) {
7864
+ t13 = /* @__PURE__ */ jsx("button", {
7865
+ ref: expandButtonRef,
7866
+ "aria-expanded": t11,
7836
7867
  "aria-label": outlineLabel,
7837
7868
  className: "folio-outline-icon-button",
7838
7869
  "data-testid": "folio-outline-expand",
7839
7870
  onClick: onExpand,
7871
+ style: controlMinimumStyle,
7840
7872
  title: outlineLabel,
7841
7873
  type: "button",
7842
- children: t9
7874
+ children: t12
7843
7875
  });
7844
- $[26] = onExpand;
7845
- $[27] = outlineLabel;
7846
- $[28] = t8;
7847
- $[29] = t10;
7848
- } else t10 = $[29];
7849
- let t11;
7850
- if ($[30] !== outlineLabel || $[31] !== rail || $[32] !== t10 || $[33] !== t7) {
7851
- t11 = /* @__PURE__ */ jsxs("nav", {
7876
+ $[29] = onExpand;
7877
+ $[30] = outlineLabel;
7878
+ $[31] = t11;
7879
+ $[32] = t13;
7880
+ } else t13 = $[32];
7881
+ let t14;
7882
+ if ($[33] !== outlineLabel || $[34] !== rail || $[35] !== t10 || $[36] !== t13) {
7883
+ t14 = /* @__PURE__ */ jsxs("nav", {
7852
7884
  "aria-label": outlineLabel,
7853
7885
  className: "folio-outline folio-outline--rail",
7854
7886
  "data-testid": "folio-outline",
7855
7887
  "data-folio-outline-surface": "rail",
7856
- style: t7,
7857
- children: [t10, rail]
7888
+ style: t10,
7889
+ children: [t13, rail]
7858
7890
  });
7859
- $[30] = outlineLabel;
7860
- $[31] = rail;
7861
- $[32] = t10;
7862
- $[33] = t7;
7863
- $[34] = t11;
7864
- } else t11 = $[34];
7865
- return t11;
7891
+ $[33] = outlineLabel;
7892
+ $[34] = rail;
7893
+ $[35] = t10;
7894
+ $[36] = t13;
7895
+ $[37] = t14;
7896
+ } else t14 = $[37];
7897
+ return t14;
7866
7898
  }
7867
- const t7 = `folio-outline folio-outline--${surface}`;
7868
- let t8;
7869
- if ($[35] !== width) {
7870
- t8 = { width };
7871
- $[35] = width;
7872
- $[36] = t8;
7873
- } else t8 = $[36];
7874
- let t9;
7875
- if ($[37] !== t) {
7876
- t9 = t("editor.outlineTitle");
7877
- $[37] = t;
7878
- $[38] = t9;
7879
- } else t9 = $[38];
7880
- let t10;
7881
- if ($[39] !== t9) {
7882
- t10 = /* @__PURE__ */ jsx("span", {
7899
+ const t10 = `folio-outline folio-outline--${surface === "expanded" ? "column" : surface}`;
7900
+ let t11;
7901
+ if ($[38] !== width) {
7902
+ t11 = { width };
7903
+ $[38] = width;
7904
+ $[39] = t11;
7905
+ } else t11 = $[39];
7906
+ let t12;
7907
+ if ($[40] !== t) {
7908
+ t12 = t("editor.outlineTitle");
7909
+ $[40] = t;
7910
+ $[41] = t12;
7911
+ } else t12 = $[41];
7912
+ let t13;
7913
+ if ($[42] !== t12) {
7914
+ t13 = /* @__PURE__ */ jsx("span", {
7883
7915
  className: "folio-outline-title",
7884
- children: t9
7916
+ children: t12
7885
7917
  });
7886
- $[39] = t9;
7887
- $[40] = t10;
7888
- } else t10 = $[40];
7889
- let t11;
7890
- if ($[41] !== onClose || $[42] !== surface || $[43] !== t) {
7891
- t11 = surface === "drawer" && onClose && /* @__PURE__ */ jsx("button", {
7918
+ $[42] = t12;
7919
+ $[43] = t13;
7920
+ } else t13 = $[43];
7921
+ let t14;
7922
+ if ($[44] !== onClose || $[45] !== surface || $[46] !== t) {
7923
+ t14 = surface === "expanded" && onClose && /* @__PURE__ */ jsx("button", {
7892
7924
  "aria-label": t("common.closeDialog"),
7893
7925
  className: "folio-outline-icon-button",
7894
7926
  onClick: onClose,
7927
+ style: controlMinimumStyle,
7895
7928
  title: t("common.closeDialog"),
7896
7929
  type: "button",
7897
7930
  children: /* @__PURE__ */ jsx(XIcon, {
@@ -7899,41 +7932,157 @@ const DocumentOutline = (t0) => {
7899
7932
  size: 16
7900
7933
  })
7901
7934
  });
7902
- $[41] = onClose;
7903
- $[42] = surface;
7904
- $[43] = t;
7905
- $[44] = t11;
7906
- } else t11 = $[44];
7907
- let t12;
7908
- if ($[45] !== t10 || $[46] !== t11) {
7909
- t12 = /* @__PURE__ */ jsxs("div", {
7935
+ $[44] = onClose;
7936
+ $[45] = surface;
7937
+ $[46] = t;
7938
+ $[47] = t14;
7939
+ } else t14 = $[47];
7940
+ let t15;
7941
+ if ($[48] !== t13 || $[49] !== t14) {
7942
+ t15 = /* @__PURE__ */ jsxs("div", {
7943
+ className: "folio-outline-heading-row",
7944
+ children: [t13, t14]
7945
+ });
7946
+ $[48] = t13;
7947
+ $[49] = t14;
7948
+ $[50] = t15;
7949
+ } else t15 = $[50];
7950
+ let t16;
7951
+ if ($[51] !== t) {
7952
+ t16 = t("editor.outlineDepthLabel");
7953
+ $[51] = t;
7954
+ $[52] = t16;
7955
+ } else t16 = $[52];
7956
+ let t17;
7957
+ if ($[53] !== t16) {
7958
+ t17 = /* @__PURE__ */ jsx("span", { children: t16 });
7959
+ $[53] = t16;
7960
+ $[54] = t17;
7961
+ } else t17 = $[54];
7962
+ let t18;
7963
+ if ($[55] !== t) {
7964
+ t18 = t("editor.outlineDepthLabel");
7965
+ $[55] = t;
7966
+ $[56] = t18;
7967
+ } else t18 = $[56];
7968
+ let t19;
7969
+ if ($[57] !== onOutlineDepthChange) {
7970
+ t19 = (event) => {
7971
+ const value = event.currentTarget.value;
7972
+ if (value === "all") {
7973
+ onOutlineDepthChange("all");
7974
+ return;
7975
+ }
7976
+ onOutlineDepthChange(value === "3" ? 3 : 2);
7977
+ };
7978
+ $[57] = onOutlineDepthChange;
7979
+ $[58] = t19;
7980
+ } else t19 = $[58];
7981
+ let t20;
7982
+ if ($[59] !== t) {
7983
+ t20 = t("editor.outlineDepthTwo");
7984
+ $[59] = t;
7985
+ $[60] = t20;
7986
+ } else t20 = $[60];
7987
+ let t21;
7988
+ if ($[61] !== t20) {
7989
+ t21 = /* @__PURE__ */ jsx("option", {
7990
+ value: 2,
7991
+ children: t20
7992
+ });
7993
+ $[61] = t20;
7994
+ $[62] = t21;
7995
+ } else t21 = $[62];
7996
+ let t22;
7997
+ if ($[63] !== t) {
7998
+ t22 = t("editor.outlineDepthThree");
7999
+ $[63] = t;
8000
+ $[64] = t22;
8001
+ } else t22 = $[64];
8002
+ let t23;
8003
+ if ($[65] !== t22) {
8004
+ t23 = /* @__PURE__ */ jsx("option", {
8005
+ value: 3,
8006
+ children: t22
8007
+ });
8008
+ $[65] = t22;
8009
+ $[66] = t23;
8010
+ } else t23 = $[66];
8011
+ let t24;
8012
+ if ($[67] !== t) {
8013
+ t24 = t("editor.outlineDepthAll");
8014
+ $[67] = t;
8015
+ $[68] = t24;
8016
+ } else t24 = $[68];
8017
+ let t25;
8018
+ if ($[69] !== t24) {
8019
+ t25 = /* @__PURE__ */ jsx("option", {
8020
+ value: "all",
8021
+ children: t24
8022
+ });
8023
+ $[69] = t24;
8024
+ $[70] = t25;
8025
+ } else t25 = $[70];
8026
+ let t26;
8027
+ if ($[71] !== outlineDepth || $[72] !== t18 || $[73] !== t19 || $[74] !== t21 || $[75] !== t23 || $[76] !== t25) {
8028
+ t26 = /* @__PURE__ */ jsxs("select", {
8029
+ "aria-label": t18,
8030
+ onChange: t19,
8031
+ value: outlineDepth,
8032
+ children: [
8033
+ t21,
8034
+ t23,
8035
+ t25
8036
+ ]
8037
+ });
8038
+ $[71] = outlineDepth;
8039
+ $[72] = t18;
8040
+ $[73] = t19;
8041
+ $[74] = t21;
8042
+ $[75] = t23;
8043
+ $[76] = t25;
8044
+ $[77] = t26;
8045
+ } else t26 = $[77];
8046
+ let t27;
8047
+ if ($[78] !== t17 || $[79] !== t26) {
8048
+ t27 = /* @__PURE__ */ jsxs("label", {
8049
+ className: "folio-outline-depth-control",
8050
+ children: [t17, t26]
8051
+ });
8052
+ $[78] = t17;
8053
+ $[79] = t26;
8054
+ $[80] = t27;
8055
+ } else t27 = $[80];
8056
+ let t28;
8057
+ if ($[81] !== t15 || $[82] !== t27) {
8058
+ t28 = /* @__PURE__ */ jsxs("div", {
7910
8059
  className: "folio-outline-header",
7911
- children: [t10, t11]
8060
+ children: [t15, t27]
7912
8061
  });
7913
- $[45] = t10;
7914
- $[46] = t11;
7915
- $[47] = t12;
7916
- } else t12 = $[47];
7917
- let t13;
7918
- if ($[48] !== outlineLabel || $[49] !== rail || $[50] !== surface || $[51] !== t12 || $[52] !== t7 || $[53] !== t8) {
7919
- t13 = /* @__PURE__ */ jsxs("nav", {
8062
+ $[81] = t15;
8063
+ $[82] = t27;
8064
+ $[83] = t28;
8065
+ } else t28 = $[83];
8066
+ let t29;
8067
+ if ($[84] !== outlineLabel || $[85] !== rail || $[86] !== surface || $[87] !== t10 || $[88] !== t11 || $[89] !== t28) {
8068
+ t29 = /* @__PURE__ */ jsxs("nav", {
7920
8069
  ref: navRef,
7921
8070
  "aria-label": outlineLabel,
7922
- className: t7,
8071
+ className: t10,
7923
8072
  "data-testid": "folio-outline",
7924
8073
  "data-folio-outline-surface": surface,
7925
- style: t8,
7926
- children: [t12, rail]
8074
+ style: t11,
8075
+ children: [t28, rail]
7927
8076
  });
7928
- $[48] = outlineLabel;
7929
- $[49] = rail;
7930
- $[50] = surface;
7931
- $[51] = t12;
7932
- $[52] = t7;
7933
- $[53] = t8;
7934
- $[54] = t13;
7935
- } else t13 = $[54];
7936
- return t13;
8077
+ $[84] = outlineLabel;
8078
+ $[85] = rail;
8079
+ $[86] = surface;
8080
+ $[87] = t10;
8081
+ $[88] = t11;
8082
+ $[89] = t28;
8083
+ $[90] = t29;
8084
+ } else t29 = $[90];
8085
+ return t29;
7937
8086
  };
7938
8087
  function _temp$7(heading) {
7939
8088
  const item = {
@@ -10603,7 +10752,7 @@ const useHeaderFooterEditor = ({ history, pushDocument, getHfView, getCanonicalA
10603
10752
  setHfEditPosition(position);
10604
10753
  return;
10605
10754
  }
10606
- if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.secondaryStories)) {
10755
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
10607
10756
  const api = getCanonicalApi?.();
10608
10757
  api?.ensureView();
10609
10758
  const canonical = api?.getCanonicalDocument();
@@ -10633,7 +10782,7 @@ const useHeaderFooterEditor = ({ history, pushDocument, getHfView, getCanonicalA
10633
10782
  experimentalSession
10634
10783
  ]);
10635
10784
  const handleHeaderFooterSave = useCallback(() => {
10636
- if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.secondaryStories)) {
10785
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
10637
10786
  setHfEditPosition(null);
10638
10787
  return;
10639
10788
  }
@@ -10687,7 +10836,7 @@ const useHeaderFooterEditor = ({ history, pushDocument, getHfView, getCanonicalA
10687
10836
  return;
10688
10837
  }
10689
10838
  const activeRId_0 = pickActiveHeaderFooterRId(resolution, hfEditPosition, hfEditIsFirstPage);
10690
- if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.secondaryStories)) {
10839
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
10691
10840
  const api_0 = getCanonicalApi?.();
10692
10841
  const canonical_0 = api_0?.getCanonicalDocument();
10693
10842
  if (api_0 && canonical_0 && activeRId_0) api_0.applyCanonicalOperations(removeCanonicalHeaderFooterOperations({
@@ -11028,22 +11177,23 @@ const usePanelLayout = (t0) => {
11028
11177
  t2 = $[3];
11029
11178
  }
11030
11179
  useLayoutEffect(t1, t2);
11180
+ const requestedOutline = overlay === "outline" && outline !== "absent" ? "expanded" : outline;
11031
11181
  let t3;
11032
- if ($[4] !== availableWidth || $[5] !== comments || $[6] !== outline || $[7] !== pageWidth) {
11182
+ if ($[4] !== availableWidth || $[5] !== comments || $[6] !== pageWidth || $[7] !== requestedOutline) {
11033
11183
  t3 = computePanelLayout({
11034
11184
  availableWidth,
11035
11185
  pageWidth,
11036
- outline,
11186
+ outline: requestedOutline,
11037
11187
  comments
11038
11188
  });
11039
11189
  $[4] = availableWidth;
11040
11190
  $[5] = comments;
11041
- $[6] = outline;
11042
- $[7] = pageWidth;
11191
+ $[6] = pageWidth;
11192
+ $[7] = requestedOutline;
11043
11193
  $[8] = t3;
11044
11194
  } else t3 = $[8];
11045
11195
  const layout = t3;
11046
- const outlineDrawn = layout.outline === "rail" || layout.outline === "drawer";
11196
+ const outlineDrawn = layout.outline !== "none" && layout.outline !== "column";
11047
11197
  const commentsDrawn = layout.comments === "drawer";
11048
11198
  let t4;
11049
11199
  let t5;
@@ -11067,16 +11217,16 @@ const usePanelLayout = (t0) => {
11067
11217
  }
11068
11218
  useEffect(t4, t5);
11069
11219
  let t6;
11070
- if ($[14] !== availableWidth || $[15] !== outline || $[16] !== pageWidth) {
11220
+ if ($[14] !== availableWidth || $[15] !== pageWidth || $[16] !== requestedOutline) {
11071
11221
  t6 = () => computePanelLayout({
11072
11222
  availableWidth,
11073
11223
  pageWidth,
11074
- outline,
11224
+ outline: requestedOutline,
11075
11225
  comments: "open"
11076
11226
  });
11077
11227
  $[14] = availableWidth;
11078
- $[15] = outline;
11079
- $[16] = pageWidth;
11228
+ $[15] = pageWidth;
11229
+ $[16] = requestedOutline;
11080
11230
  $[17] = t6;
11081
11231
  } else t6 = $[17];
11082
11232
  const layoutWithCommentsOpen = t6;
@@ -12777,7 +12927,7 @@ function sanitizeControlledComments(comments) {
12777
12927
  }
12778
12928
  return sanitized;
12779
12929
  }
12780
- function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorContentRef, commentsProp, onCommentsChange }) {
12930
+ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorContentRef, commentsProp, onCommentsChange, committedComments }) {
12781
12931
  const [showCommentsSidebar, setShowCommentsSidebar] = useState(false);
12782
12932
  const [visibleCommentAuthors, setVisibleCommentAuthors] = useState(null);
12783
12933
  const [activeCommentId, setActiveCommentId] = useState(null);
@@ -12814,11 +12964,10 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
12814
12964
  const [floatingCommentBtn, setFloatingCommentBtn] = useState(null);
12815
12965
  const commentsLoadedRef = useRef(false);
12816
12966
  useEffect(() => {
12817
- if (isControlledComments || commentsLoadedRef.current) return;
12818
- if (!doc) return;
12819
- const bodyComments = doc.package.document.comments;
12967
+ if (commentsLoadedRef.current || committedComments == null && isControlledComments) return;
12968
+ const bodyComments = committedComments ?? doc?.package.document.comments;
12820
12969
  if (bodyComments && bodyComments.length > 0) {
12821
- setComments(bodyComments);
12970
+ if (committedComments == null && doc?.package.document.comments) setComments(doc.package.document.comments);
12822
12971
  setVisibleCommentAuthors(null);
12823
12972
  setActiveCommentId(null);
12824
12973
  if (autoOpenReviewSidebar && countOpenCommentThreads(bodyComments) > 0) setShowCommentsSidebar(true);
@@ -12826,14 +12975,16 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
12826
12975
  }
12827
12976
  }, [
12828
12977
  autoOpenReviewSidebar,
12978
+ committedComments,
12829
12979
  doc,
12830
12980
  isControlledComments,
12831
12981
  setComments
12832
12982
  ]);
12983
+ const listedComments = committedComments ?? comments;
12833
12984
  const commentAuthors = useMemo(() => {
12834
12985
  const seen = /* @__PURE__ */ new Set();
12835
12986
  const authors = [];
12836
- for (const comment of comments) {
12987
+ for (const comment of listedComments) {
12837
12988
  const commentAuthor = getCommentAuthorKey(comment.author);
12838
12989
  if (!seen.has(commentAuthor)) {
12839
12990
  seen.add(commentAuthor);
@@ -12841,26 +12992,26 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
12841
12992
  }
12842
12993
  }
12843
12994
  return authors;
12844
- }, [comments]);
12995
+ }, [listedComments]);
12845
12996
  const visibleCommentAuthorSet = useMemo(() => visibleCommentAuthors ?? new Set(commentAuthors), [visibleCommentAuthors, commentAuthors]);
12846
12997
  const visibleCommentIds = useMemo(() => {
12847
12998
  const ids = /* @__PURE__ */ new Set([-1]);
12848
- for (const comment_0 of comments) if (visibleCommentAuthorSet.has(getCommentAuthorKey(comment_0.author))) ids.add(comment_0.id);
12999
+ for (const comment_0 of listedComments) if (visibleCommentAuthorSet.has(getCommentAuthorKey(comment_0.author))) ids.add(comment_0.id);
12849
13000
  return ids;
12850
- }, [comments, visibleCommentAuthorSet]);
13001
+ }, [listedComments, visibleCommentAuthorSet]);
12851
13002
  const visibleComments = useMemo(() => {
12852
13003
  const visibleRootIds = /* @__PURE__ */ new Set();
12853
- for (const comment_1 of comments) {
13004
+ for (const comment_1 of listedComments) {
12854
13005
  const parentId_0 = getCommentParentId(comment_1);
12855
13006
  if (parentId_0 === null || parentId_0 === void 0 || !visibleCommentIds.has(comment_1.id)) continue;
12856
13007
  visibleRootIds.add(parentId_0);
12857
13008
  }
12858
- return comments.filter((comment_2) => {
13009
+ return listedComments.filter((comment_2) => {
12859
13010
  const parentId_1 = getCommentParentId(comment_2);
12860
13011
  if (parentId_1 !== null && parentId_1 !== void 0) return visibleCommentIds.has(comment_2.id);
12861
13012
  return visibleCommentIds.has(comment_2.id) || visibleRootIds.has(comment_2.id);
12862
13013
  });
12863
- }, [comments, visibleCommentIds]);
13014
+ }, [listedComments, visibleCommentIds]);
12864
13015
  const activeCommentVisible = activeCommentId !== null && visibleCommentIds.has(activeCommentId);
12865
13016
  useEffect(() => {
12866
13017
  if (!activeCommentVisible) setActiveCommentId(null);
@@ -12953,7 +13104,7 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
12953
13104
  */
12954
13105
  /** No headings to track while the outline is not shown. */
12955
13106
  const NO_HEADINGS = [];
12956
- const CommentsSidebar = lazy(() => import("./CommentsSidebar-D8sljCtX.js").then((m) => ({ default: m.CommentsSidebar })));
13107
+ const CommentsSidebar = lazy(() => import("./CommentsSidebar-IR9uTkkk.js").then((m) => ({ default: m.CommentsSidebar })));
12957
13108
  const TextContextMenu = lazy(() => import("./TextContextMenu-Bqth8itn.js").then((m) => ({ default: m.TextContextMenu })));
12958
13109
  const loadAttemptSelectiveSave = async () => {
12959
13110
  const { attemptSelectiveSave } = await import("@stll/folio-core/docx/selectiveSave");
@@ -13024,8 +13175,14 @@ function areActiveTrackedChangesEqual(a, b) {
13024
13175
  /**
13025
13176
  * DocxEditor - Complete DOCX editor component
13026
13177
  */
13027
- const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, document: initialDocument, onSave, author = "User", onChange, onSelectionChange, onSelectionTextChange, onError, onFontsLoaded: onFontsLoadedCallback, fontFamilies, fonts, theme, showToolbar = true, showZoomControl = true, showReviewControls = true, showHeaderFooterEditing = true, pageRenderer, showMarginGuides = false, marginGuideColor, showRuler: showRulerProp = false, rulerUnit = "inch", initialZoom = 1, enableWheelZoom = true, keyboardShortcuts = "document", hostShortcuts: hostShortcutsProp, readOnly: readOnlyProp = false, autoOpenReviewSidebar = true, components, toolbarExtra, className = "", style, placeholder, loadingIndicator, preserveDocumentWhileLoading = false, initialScrollTop, onScrollTopChange, showOutline: showOutlineProp = true, onPrint, onInsertImage, onInsertTable, showTableInsert = true, onInsertPageBreak, onInsertTOC, onCopy, onCut, onPaste, mode: modeProp, onModeChange, onReadonlyEditAttempt, onCompatibilityChange, onEditorViewReady, onAnonymizationMatchesChange, onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq, showTemplateDirectives = false, onSlashMenuChange, onSlashMenuKeyAction, customContextMenuItems, onCustomContextAction, comments: commentsProp, onCommentsChange, collaboration, plugins, featureFlags, experimentalSession, onSelectiveSaveTripwire }, ref) {
13178
+ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, document: initialDocument, onSave, author = "User", onChange, onSelectionChange, onSelectionTextChange, onError, onFontsLoaded: onFontsLoadedCallback, fontFamilies, fonts, theme, showToolbar = true, showZoomControl = true, showReviewControls = true, showHeaderFooterEditing = true, pageRenderer, showMarginGuides = false, marginGuideColor, showRuler: showRulerProp = false, rulerUnit = "inch", initialZoom = 1, enableWheelZoom = true, keyboardShortcuts = "document", hostShortcuts: hostShortcutsProp, readOnly: readOnlyProp = false, autoOpenReviewSidebar = true, components, toolbarExtra, className = "", style, placeholder, loadingIndicator, preserveDocumentWhileLoading = false, initialScrollTop, onScrollTopChange, showOutline: showOutlineProp = true, outlineDepth: outlineDepthProp, onOutlineDepthChange, onPrint, onInsertImage, onInsertTable, showTableInsert = true, onInsertPageBreak, onInsertTOC, onCopy, onCut, onPaste, mode: modeProp, onModeChange, onReadonlyEditAttempt, onCompatibilityChange, onEditorViewReady, onAnonymizationMatchesChange, onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq, showTemplateDirectives = false, onSlashMenuChange, onSlashMenuKeyAction, customContextMenuItems, onCustomContextAction, comments: commentsProp, onCommentsChange, collaboration, plugins, featureFlags, experimentalSession, onSelectiveSaveTripwire }, ref) {
13028
13179
  const t = useTranslations("folio");
13180
+ const [outlineDepthState, setOutlineDepthState] = useState(DEFAULT_OUTLINE_DEPTH);
13181
+ const outlineDepth = outlineDepthProp ?? outlineDepthState;
13182
+ const handleOutlineDepthChange = useCallback((depth) => {
13183
+ if (outlineDepthProp === void 0) setOutlineDepthState(depth);
13184
+ onOutlineDepthChange?.(depth);
13185
+ }, [onOutlineDepthChange, outlineDepthProp]);
13029
13186
  useEffect(() => {
13030
13187
  const onClipboardReadError = () => {
13031
13188
  toast(t("clipboardReadFailed"));
@@ -13063,28 +13220,17 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13063
13220
  const [, setTrackedChanges] = useState([]);
13064
13221
  const trackedChangesRef = useRef([]);
13065
13222
  const [anchorPositions, setAnchorPositions] = useState(EMPTY_ANCHOR_POSITIONS);
13066
- const { editingMode, readOnly, trackChangesOn, toggleTrackChanges: toggleTrackChangesUnrestricted, displayMode, setDisplayMode } = useEditorMode({
13223
+ const { editingMode, readOnly, trackChangesOn, toggleTrackChanges, displayMode, setDisplayMode } = useEditorMode({
13067
13224
  modeProp,
13068
13225
  onModeChange,
13069
13226
  readOnlyProp
13070
13227
  });
13071
- const toggleTrackChanges = useCallback(() => {
13072
- if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.suggesting) && !trackChangesOn) {
13073
- const error = new CanonicalSessionRefusalError({
13074
- gap: CANONICAL_GAP.suggesting,
13075
- message: canonicalRefusalMessage(CANONICAL_GAP.suggesting, "Canonical sessions do not support suggesting mode.")
13076
- });
13077
- toast(error.message);
13078
- onError?.(error);
13079
- return;
13080
- }
13081
- toggleTrackChangesUnrestricted();
13082
- }, [
13083
- experimentalSession,
13084
- trackChangesOn,
13085
- onError,
13086
- toggleTrackChangesUnrestricted
13087
- ]);
13228
+ useEffect(() => {
13229
+ pagedEditorRef.current?.getEditor().setCanonicalMode(editingMode === "suggesting" ? {
13230
+ type: "suggesting",
13231
+ author
13232
+ } : { type: "editing" });
13233
+ }, [editingMode, author]);
13088
13234
  const extractTrackedChangesTimerRef = useRef(null);
13089
13235
  const collectHeadingsTimerRef = useRef(null);
13090
13236
  const extractTrackedChanges = useCallback(() => {
@@ -13137,12 +13283,12 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13137
13283
  });
13138
13284
  const refuseCanonicalModelEdit = useCallback((gap, message) => {
13139
13285
  if (!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return false;
13140
- const error_0 = new CanonicalSessionRefusalError({
13286
+ const error = new CanonicalSessionRefusalError({
13141
13287
  gap,
13142
13288
  message: canonicalRefusalMessage(gap, message)
13143
13289
  });
13144
- toast(error_0.message);
13145
- onError?.(error_0);
13290
+ toast(error.message);
13291
+ onError?.(error);
13146
13292
  return true;
13147
13293
  }, [experimentalSession, onError]);
13148
13294
  const extensionManager = useMemo(() => {
@@ -13326,14 +13472,23 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13326
13472
  size: 4,
13327
13473
  color: { rgb: "000000" }
13328
13474
  });
13329
- const { comments, createComment, setComments, commentsRef, commentsDirtyRef, commentsLoadedRef, showCommentsSidebar, setShowCommentsSidebar, setVisibleCommentAuthors, activeCommentId, setActiveCommentId, isAddingComment, setIsAddingComment, commentSelectionRange, setCommentSelectionRange, addCommentYPosition, setAddCommentYPosition, floatingCommentBtn, setFloatingCommentBtn, commentAuthors, visibleCommentAuthorSet, visibleComments, syncCommentHighlightStyles } = useFolioComments({
13330
- doc: history.state,
13475
+ const canonicalCommentApi = pagedEditorRef.current?.getEditor();
13476
+ const canonicalCommentsVersion = canonicalCommentApi?.getCanonicalCommittedVersion() ?? null;
13477
+ const canonicalComments = useMemo(() => canonicalCommentsVersion === null ? null : canonicalCommentApi?.getCanonicalComments() ?? null, [canonicalCommentApi, canonicalCommentsVersion]);
13478
+ const canonicalCommentsSerialized = useMemo(() => canonicalComments === null ? null : JSON.stringify(canonicalComments), [canonicalComments]);
13479
+ const canonicalCommentsSnapshotRef = useRef(canonicalCommentsSerialized);
13480
+ const lastControlledCommentsRef = useRef(void 0);
13481
+ const { comments: legacyComments, createComment, setComments, commentsRef, commentsDirtyRef, commentsLoadedRef, showCommentsSidebar, setShowCommentsSidebar, setVisibleCommentAuthors, activeCommentId, setActiveCommentId, isAddingComment, setIsAddingComment, commentSelectionRange, setCommentSelectionRange, addCommentYPosition, setAddCommentYPosition, floatingCommentBtn, setFloatingCommentBtn, commentAuthors, visibleCommentAuthorSet, visibleComments, syncCommentHighlightStyles } = useFolioComments({
13482
+ doc: canonicalComments === null ? history.state : null,
13331
13483
  autoOpenReviewSidebar,
13332
13484
  anchorPositions,
13333
13485
  editorContentRef,
13334
13486
  commentsProp,
13335
- onCommentsChange
13487
+ onCommentsChange,
13488
+ committedComments: canonicalComments
13336
13489
  });
13490
+ const comments = canonicalComments ?? legacyComments;
13491
+ const commentDraftMode = usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? "canonical" : "prosemirror";
13337
13492
  const documentOperationUndoEntriesRef = useRef([]);
13338
13493
  const pendingSuggestionRegistryRef = useRef(new FolioPendingSuggestionRegistry());
13339
13494
  const styleResolverCacheRef = useRef(null);
@@ -13387,6 +13542,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13387
13542
  });
13388
13543
  let activeHfRId = hfEditIsFirstPage ? activeFirstFooterRId : activeFooterRId;
13389
13544
  if (hfEditPosition === "header") activeHfRId = hfEditIsFirstPage ? activeFirstHeaderRId : activeHeaderRId;
13545
+ const visibleOutlineHeadings = useMemo(() => filterHeadingsByDepth(outlineHeadings, outlineDepth), [outlineDepth, outlineHeadings]);
13390
13546
  const panels = usePanelLayout({
13391
13547
  pageWidth: (widestLaidOutPageWidth ?? getPageSize(effectiveSectionProperties).w) * zoom,
13392
13548
  outline: showOutline && outlineHeadings.length > 1 ? "available" : "absent",
@@ -13399,7 +13555,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13399
13555
  if (panels.layout.comments === "drawer" && panelOverlay === "comments") return "drawer";
13400
13556
  return null;
13401
13557
  })();
13402
- const { activeId: activeHeadingId, markJumped: markHeadingJumped } = useActiveHeading(scrollContainerRef, panels.layout.outline === "none" ? NO_HEADINGS : outlineHeadings);
13558
+ const { activeId: activeHeadingId, markJumped: markHeadingJumped } = useActiveHeading(scrollContainerRef, panels.layout.outline === "none" ? NO_HEADINGS : visibleOutlineHeadings);
13403
13559
  const closePanelOverlay = useCallback(() => setPanelOverlay("none"), [setPanelOverlay]);
13404
13560
  const toggleOutlineOverlay = useCallback(() => setPanelOverlay(panelOverlay === "outline" ? "none" : "outline"), [panelOverlay, setPanelOverlay]);
13405
13561
  const getActiveEditorStory = useCallback(() => {
@@ -13561,8 +13717,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13561
13717
  if (view_4) setSuggestionMode(editingMode === "suggesting", view_4.state, view_4.dispatch, author);
13562
13718
  }, [editingMode, author]);
13563
13719
  const handleDocumentChange = useCallback((newDocument) => {
13720
+ const canonical = usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting);
13564
13721
  const currentComments = commentsRef.current;
13565
- const documentWithComments = {
13722
+ const documentWithComments = canonical ? newDocument : {
13566
13723
  ...newDocument,
13567
13724
  package: {
13568
13725
  ...newDocument.package,
@@ -13573,7 +13730,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13573
13730
  }
13574
13731
  };
13575
13732
  pushDocument(documentWithComments);
13576
- onChange?.(usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? cloneDocumentWithParagraphPropertySources(documentWithComments) : documentWithComments);
13733
+ onChange?.(canonical ? cloneDocumentWithParagraphPropertySources(documentWithComments) : documentWithComments);
13577
13734
  if (showOutlineRef.current) {
13578
13735
  if (collectHeadingsTimerRef.current) clearTimeout(collectHeadingsTimerRef.current);
13579
13736
  collectHeadingsTimerRef.current = setTimeout(() => {
@@ -13595,12 +13752,14 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13595
13752
  extractTrackedChanges,
13596
13753
  refreshBodyHistoryAvailability,
13597
13754
  commentsRef,
13598
- experimentalSession
13755
+ experimentalSession,
13756
+ history.state,
13757
+ onCommentsChange
13599
13758
  ]);
13600
13759
  const buildCurrentDocument = useCallback(() => {
13601
13760
  if (!history.state) return null;
13602
- const canonical = pagedEditorRef.current?.getEditor().getCanonicalDocument();
13603
- if (canonical) return canonical;
13761
+ const canonical_0 = pagedEditorRef.current?.getEditor().getCanonicalDocument();
13762
+ if (canonical_0) return canonical_0;
13604
13763
  if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return null;
13605
13764
  let doc_0 = cloneDocumentWithParagraphPropertySources(history.state);
13606
13765
  const pmDoc = pagedEditorRef.current?.getDocument();
@@ -13631,11 +13790,14 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13631
13790
  commentsRef,
13632
13791
  experimentalSession
13633
13792
  ]);
13793
+ const applyCanonicalComment = useCallback((request) => {
13794
+ return getCanonicalApi()?.applyCanonicalComment(request) ?? null;
13795
+ }, [getCanonicalApi]);
13634
13796
  const replaceComments = useCallback((nextComments) => {
13635
- if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
13636
- refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.");
13637
- return;
13638
- }
13797
+ if (applyCanonicalComment({
13798
+ type: "replace",
13799
+ comments: nextComments
13800
+ }) !== null) return;
13639
13801
  commentsDirtyRef.current = true;
13640
13802
  setComments(nextComments);
13641
13803
  const currentDocument = buildCurrentDocument();
@@ -13645,13 +13807,57 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13645
13807
  buildCurrentDocument,
13646
13808
  commentsDirtyRef,
13647
13809
  experimentalSession,
13810
+ applyCanonicalComment,
13648
13811
  onChange,
13649
- refuseCanonicalModelEdit,
13650
13812
  setComments
13651
13813
  ]);
13652
13814
  const updateComments = useCallback((updater) => {
13653
13815
  replaceComments(updater(commentsRef.current));
13654
13816
  }, [commentsRef, replaceComments]);
13817
+ const [controlledCommentsRetry, setControlledCommentsRetry] = useState(0);
13818
+ useEffect(() => {
13819
+ if (commentsProp === void 0 || canonicalComments === null) {
13820
+ lastControlledCommentsRef.current = void 0;
13821
+ return;
13822
+ }
13823
+ const requested = JSON.stringify(legacyComments);
13824
+ if (lastControlledCommentsRef.current === requested) return;
13825
+ if (canonicalCommentsSerialized === requested) {
13826
+ lastControlledCommentsRef.current = requested;
13827
+ return;
13828
+ }
13829
+ const result = applyCanonicalComment({
13830
+ type: "replace",
13831
+ comments: legacyComments
13832
+ });
13833
+ if (result?.status === "applied") {
13834
+ lastControlledCommentsRef.current = requested;
13835
+ return;
13836
+ }
13837
+ if (result?.status !== "refused" || result.retry !== "afterComposition") return;
13838
+ const view_7 = getCanonicalApi()?.getView();
13839
+ if (!view_7) return;
13840
+ return afterCanonicalCompositionSettles(view_7, () => setControlledCommentsRetry((attempt) => attempt + 1));
13841
+ }, [
13842
+ applyCanonicalComment,
13843
+ commentsProp,
13844
+ controlledCommentsRetry,
13845
+ getCanonicalApi,
13846
+ legacyComments,
13847
+ canonicalCommentsSerialized
13848
+ ]);
13849
+ useEffect(() => {
13850
+ if (canonicalComments === null) return;
13851
+ const nextComments_0 = canonicalComments;
13852
+ const serialized = canonicalCommentsSerialized;
13853
+ if (canonicalCommentsSnapshotRef.current === null) {
13854
+ canonicalCommentsSnapshotRef.current = serialized;
13855
+ return;
13856
+ }
13857
+ if (canonicalCommentsSnapshotRef.current === serialized) return;
13858
+ canonicalCommentsSnapshotRef.current = serialized;
13859
+ onCommentsChange?.(structuredClone(nextComments_0));
13860
+ }, [canonicalCommentsSerialized, onCommentsChange]);
13655
13861
  const { findResultRef, handleFind, handleFindNext, handleFindPrevious, handleReplace, handleReplaceAll } = useFindReplace({
13656
13862
  getDocumentState: buildCurrentDocument,
13657
13863
  containerRef,
@@ -13659,9 +13865,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13659
13865
  findReplace,
13660
13866
  selectMatch: useCallback((match) => {
13661
13867
  const editor_0 = pagedEditorRef.current;
13662
- const view_7 = editor_0?.getView();
13663
- if (!editor_0 || !view_7) return false;
13664
- const range = resolveFindMatchRange(view_7.state.doc, match);
13868
+ const view_8 = editor_0?.getView();
13869
+ if (!editor_0 || !view_8) return false;
13870
+ const range = resolveFindMatchRange(view_8.state.doc, match);
13665
13871
  if (!range) return false;
13666
13872
  editor_0.setSelection(range.from, range.to);
13667
13873
  requestAnimationFrame(() => {
@@ -13671,17 +13877,17 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13671
13877
  }, [])
13672
13878
  });
13673
13879
  const handleSelectionChange = useCallback((selectionState) => {
13674
- const view_8 = getActiveEditorView();
13675
- if (view_8) {
13676
- const { from, to } = view_8.state.selection;
13880
+ const view_9 = getActiveEditorView();
13881
+ if (view_9) {
13882
+ const { from, to } = view_9.state.selection;
13677
13883
  lastSelectionRef.current = {
13678
13884
  from,
13679
13885
  to
13680
13886
  };
13681
13887
  }
13682
13888
  let pmTableCtx = null;
13683
- if (view_8) {
13684
- pmTableCtx = getTableContext(view_8.state);
13889
+ if (view_9) {
13890
+ pmTableCtx = getTableContext(view_9.state);
13685
13891
  if (!pmTableCtx.isInTable) pmTableCtx = null;
13686
13892
  }
13687
13893
  if (pmTableCtx?.cellBorderColor) {
@@ -13693,8 +13899,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13693
13899
  color: { rgb }
13694
13900
  };
13695
13901
  }
13696
- const pmImageCtx = view_8 ? detectImageContext(view_8.state) : null;
13697
- const trackedChange = view_8 ? detectActiveTrackedChange(view_8.state) : null;
13902
+ const pmImageCtx = view_9 ? detectImageContext(view_9.state) : null;
13903
+ const trackedChange = view_9 ? detectActiveTrackedChange(view_9.state) : null;
13698
13904
  if (!selectionState) {
13699
13905
  setFloatingCommentBtn(null);
13700
13906
  setState((prev_1) => {
@@ -13757,10 +13963,10 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13757
13963
  activeTrackedChange: activeTrackedChange_0
13758
13964
  };
13759
13965
  });
13760
- if (view_8 && selectionState.hasSelection && !isAddingComment && !readOnly) {
13966
+ if (view_9 && selectionState.hasSelection && !isAddingComment && !readOnly) {
13761
13967
  const container = scrollContainerRef.current;
13762
13968
  const parentEl = editorContentRef.current;
13763
- const { from: selFrom } = view_8.state.selection;
13969
+ const { from: selFrom } = view_9.state.selection;
13764
13970
  const top = findSelectionYPosition(container, parentEl, selFrom);
13765
13971
  if (top !== null && container && parentEl) {
13766
13972
  const pagesEl = container.querySelector(".paged-editor__pages");
@@ -13768,7 +13974,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13768
13974
  const parentRect = parentEl.getBoundingClientRect();
13769
13975
  const rawLeft = pageEl ? pageEl.getBoundingClientRect().right - parentRect.left + 12 : parentRect.width / 2 + 408;
13770
13976
  const left = Math.max(16, Math.min(rawLeft, parentRect.width - 16));
13771
- const { from: from_0, to: to_0 } = view_8.state.selection;
13977
+ const { from: from_0, to: to_0 } = view_9.state.selection;
13772
13978
  if (from_0 !== to_0) setFloatingCommentBtn({
13773
13979
  top,
13774
13980
  left,
@@ -13899,16 +14105,15 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13899
14105
  roots: shortcutRoots
13900
14106
  });
13901
14107
  const handleApplyFootnoteProperties = useCallback((footnotePr, endnotePr) => {
13902
- if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
13903
- const api = getCanonicalApi();
13904
- api?.ensureView();
13905
- const canonical_0 = api?.getCanonicalDocument();
13906
- if (!canonical_0 || !api?.applyCanonicalOperations([createCanonicalSectionPropertiesOperation(canonical_0, {
13907
- footnotePr,
13908
- endnotePr
13909
- })])) refuseCanonicalModelEdit(CANONICAL_GAP.sectionProperties, "Section property changes could not be applied.");
14108
+ const api = getCanonicalApi();
14109
+ if (!api) {
14110
+ refuseCanonicalModelEdit(CANONICAL_GAP.sectionProperties, "The editor is not ready for section changes.");
13910
14111
  return;
13911
14112
  }
14113
+ if (api.applyCanonicalSectionProperties({
14114
+ footnotePr,
14115
+ endnotePr
14116
+ }) !== null) return;
13912
14117
  if (!history.state?.package) return;
13913
14118
  const newDoc = {
13914
14119
  ...history.state.package.document,
@@ -13928,103 +14133,102 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13928
14133
  }, [
13929
14134
  history,
13930
14135
  pushDocument,
13931
- experimentalSession,
13932
14136
  getCanonicalApi,
13933
14137
  refuseCanonicalModelEdit
13934
14138
  ]);
13935
14139
  const handleTableAction = useCallback((action_0) => {
13936
- const view_9 = getActiveEditorView();
13937
- if (!view_9) return;
14140
+ const view_10 = getActiveEditorView();
14141
+ if (!view_10) return;
13938
14142
  switch (action_0) {
13939
14143
  case "addRowAbove":
13940
- addRowAbove(view_9.state, view_9.dispatch);
14144
+ addRowAbove(view_10.state, view_10.dispatch);
13941
14145
  break;
13942
14146
  case "addRowBelow":
13943
- addRowBelow(view_9.state, view_9.dispatch);
14147
+ addRowBelow(view_10.state, view_10.dispatch);
13944
14148
  break;
13945
14149
  case "addColumnLeft":
13946
- addColumnLeft(view_9.state, view_9.dispatch);
14150
+ addColumnLeft(view_10.state, view_10.dispatch);
13947
14151
  break;
13948
14152
  case "addColumnRight":
13949
- addColumnRight(view_9.state, view_9.dispatch);
14153
+ addColumnRight(view_10.state, view_10.dispatch);
13950
14154
  break;
13951
14155
  case "deleteRow":
13952
- deleteRow(view_9.state, view_9.dispatch);
14156
+ deleteRow(view_10.state, view_10.dispatch);
13953
14157
  break;
13954
14158
  case "deleteColumn":
13955
- deleteColumn(view_9.state, view_9.dispatch);
14159
+ deleteColumn(view_10.state, view_10.dispatch);
13956
14160
  break;
13957
14161
  case "deleteTable":
13958
- deleteTable(view_9.state, view_9.dispatch);
14162
+ deleteTable(view_10.state, view_10.dispatch);
13959
14163
  break;
13960
14164
  case "selectTable":
13961
- selectTable(view_9.state, view_9.dispatch);
14165
+ selectTable(view_10.state, view_10.dispatch);
13962
14166
  break;
13963
14167
  case "selectRow":
13964
- selectRow(view_9.state, view_9.dispatch);
14168
+ selectRow(view_10.state, view_10.dispatch);
13965
14169
  break;
13966
14170
  case "selectColumn":
13967
- selectColumn(view_9.state, view_9.dispatch);
14171
+ selectColumn(view_10.state, view_10.dispatch);
13968
14172
  break;
13969
14173
  case "mergeCells":
13970
- mergeCells(view_9.state, view_9.dispatch);
14174
+ mergeCells(view_10.state, view_10.dispatch);
13971
14175
  break;
13972
14176
  case "splitCell":
13973
- splitCell(view_9.state, view_9.dispatch);
14177
+ splitCell(view_10.state, view_10.dispatch);
13974
14178
  break;
13975
14179
  case "borderAll":
13976
- setAllTableBorders(view_9.state, view_9.dispatch, borderSpecRef.current);
14180
+ setAllTableBorders(view_10.state, view_10.dispatch, borderSpecRef.current);
13977
14181
  break;
13978
14182
  case "borderOutside":
13979
- setOutsideTableBorders(view_9.state, view_9.dispatch, borderSpecRef.current);
14183
+ setOutsideTableBorders(view_10.state, view_10.dispatch, borderSpecRef.current);
13980
14184
  break;
13981
14185
  case "borderInside":
13982
- setInsideTableBorders(view_9.state, view_9.dispatch, borderSpecRef.current);
14186
+ setInsideTableBorders(view_10.state, view_10.dispatch, borderSpecRef.current);
13983
14187
  break;
13984
14188
  case "borderNone":
13985
- removeTableBorders(view_9.state, view_9.dispatch);
14189
+ removeTableBorders(view_10.state, view_10.dispatch);
13986
14190
  break;
13987
14191
  case "borderTop":
13988
- setCellBorder("top", borderSpecRef.current, true)(view_9.state, view_9.dispatch);
14192
+ setCellBorder("top", borderSpecRef.current, true)(view_10.state, view_10.dispatch);
13989
14193
  break;
13990
14194
  case "borderBottom":
13991
- setCellBorder("bottom", borderSpecRef.current, true)(view_9.state, view_9.dispatch);
14195
+ setCellBorder("bottom", borderSpecRef.current, true)(view_10.state, view_10.dispatch);
13992
14196
  break;
13993
14197
  case "borderLeft":
13994
- setCellBorder("left", borderSpecRef.current, true)(view_9.state, view_9.dispatch);
14198
+ setCellBorder("left", borderSpecRef.current, true)(view_10.state, view_10.dispatch);
13995
14199
  break;
13996
14200
  case "borderRight":
13997
- setCellBorder("right", borderSpecRef.current, true)(view_9.state, view_9.dispatch);
14201
+ setCellBorder("right", borderSpecRef.current, true)(view_10.state, view_10.dispatch);
13998
14202
  break;
13999
- default: if (typeof action_0 === "object") if (action_0.type === "cellFillColor") setCellFillColor(action_0.color)(view_9.state, view_9.dispatch);
14203
+ default: if (typeof action_0 === "object") if (action_0.type === "cellFillColor") setCellFillColor(action_0.color)(view_10.state, view_10.dispatch);
14000
14204
  else if (action_0.type === "borderColor") {
14001
14205
  const rgb_0 = action_0.color.replace(/^#/u, "");
14002
14206
  borderSpecRef.current = {
14003
14207
  ...borderSpecRef.current,
14004
14208
  color: { rgb: rgb_0 }
14005
14209
  };
14006
- setTableBorderColor(action_0.color)(view_9.state, view_9.dispatch);
14210
+ setTableBorderColor(action_0.color)(view_10.state, view_10.dispatch);
14007
14211
  } else if (action_0.type === "borderWidth") {
14008
14212
  borderSpecRef.current = {
14009
14213
  ...borderSpecRef.current,
14010
14214
  size: action_0.size
14011
14215
  };
14012
- setTableBorderWidth(action_0.size)(view_9.state, view_9.dispatch);
14216
+ setTableBorderWidth(action_0.size)(view_10.state, view_10.dispatch);
14013
14217
  } else if (action_0.type === "cellBorder") setCellBorder(action_0.side, {
14014
14218
  style: action_0.style,
14015
14219
  size: action_0.size,
14016
14220
  color: { rgb: action_0.color.replace(/^#/u, "") }
14017
- })(view_9.state, view_9.dispatch);
14018
- else if (action_0.type === "cellVerticalAlign") setCellVerticalAlign(action_0.align)(view_9.state, view_9.dispatch);
14019
- else if (action_0.type === "cellMargins") setCellMargins(action_0.margins)(view_9.state, view_9.dispatch);
14020
- else if (action_0.type === "cellTextDirection") setCellTextDirection(action_0.direction)(view_9.state, view_9.dispatch);
14021
- else if (action_0.type === "toggleNoWrap") toggleNoWrap()(view_9.state, view_9.dispatch);
14022
- else if (action_0.type === "rowHeight") setRowHeight(action_0.height, action_0.rule)(view_9.state, view_9.dispatch);
14023
- else if (action_0.type === "toggleHeaderRow") toggleHeaderRow()(view_9.state, view_9.dispatch);
14024
- else if (action_0.type === "distributeColumns") distributeColumns()(view_9.state, view_9.dispatch);
14025
- else if (action_0.type === "autoFitContents") autoFitContents()(view_9.state, view_9.dispatch);
14221
+ })(view_10.state, view_10.dispatch);
14222
+ else if (action_0.type === "cellVerticalAlign") setCellVerticalAlign(action_0.align)(view_10.state, view_10.dispatch);
14223
+ else if (action_0.type === "cellMargins") setCellMargins(action_0.margins)(view_10.state, view_10.dispatch);
14224
+ else if (action_0.type === "cellTextDirection") setCellTextDirection(action_0.direction)(view_10.state, view_10.dispatch);
14225
+ else if (action_0.type === "toggleNoWrap") toggleNoWrap()(view_10.state, view_10.dispatch);
14226
+ else if (action_0.type === "rowHeight") setRowHeight(action_0.height, action_0.rule)(view_10.state, view_10.dispatch);
14227
+ else if (action_0.type === "toggleHeaderRow") toggleHeaderRow()(view_10.state, view_10.dispatch);
14228
+ else if (action_0.type === "distributeColumns") distributeColumns()(view_10.state, view_10.dispatch);
14229
+ else if (action_0.type === "autoFitContents") autoFitContents()(view_10.state, view_10.dispatch);
14026
14230
  else if (action_0.type === "openTableProperties") setTablePropsOpen(true);
14027
- else if (action_0.type === "tableProperties") setTableProperties(action_0.props)(view_9.state, view_9.dispatch);
14231
+ else if (action_0.type === "tableProperties") setTableProperties(action_0.props)(view_10.state, view_10.dispatch);
14028
14232
  else {
14029
14233
  let preset = getBuiltinTableStyle(action_0.styleId);
14030
14234
  const currentDocForTable = historyStateRef.current;
@@ -14095,7 +14299,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14095
14299
  if (preset.tableBorders) styleArg.tableBorders = preset.tableBorders;
14096
14300
  if (preset.conditionals) styleArg.conditionals = preset.conditionals;
14097
14301
  if (preset.look) styleArg.look = preset.look;
14098
- applyTableStyle(styleArg)(view_9.state, view_9.dispatch);
14302
+ applyTableStyle(styleArg)(view_10.state, view_10.dispatch);
14099
14303
  }
14100
14304
  }
14101
14305
  else tableSelection.handleAction(action_0);
@@ -14116,86 +14320,86 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14116
14320
  });
14117
14321
  }, [openContextMenu]);
14118
14322
  const handleFormat = useCallback((action_1) => {
14119
- const view_10 = getActiveEditorView();
14120
- if (!view_10) return;
14121
- view_10.focus();
14122
- const isBodyEditor = view_10 === pagedEditorRef.current?.getView();
14123
- const { from: from_1, to: to_1 } = view_10.state.selection;
14323
+ const view_11 = getActiveEditorView();
14324
+ if (!view_11) return;
14325
+ view_11.focus();
14326
+ const isBodyEditor = view_11 === pagedEditorRef.current?.getView();
14327
+ const { from: from_1, to: to_1 } = view_11.state.selection;
14124
14328
  const savedSelection = lastSelectionRef.current;
14125
14329
  if (isBodyEditor && savedSelection && (from_1 !== savedSelection.from || to_1 !== savedSelection.to)) try {
14126
- const tr = view_10.state.tr.setSelection(TextSelection.create(view_10.state.doc, savedSelection.from, savedSelection.to));
14127
- view_10.dispatch(tr);
14330
+ const tr = view_11.state.tr.setSelection(TextSelection.create(view_11.state.doc, savedSelection.from, savedSelection.to));
14331
+ view_11.dispatch(tr);
14128
14332
  } catch {}
14129
14333
  if (action_1 === "bold") {
14130
- executeEditorCommand(view_10, toggleBold);
14334
+ executeEditorCommand(view_11, toggleBold);
14131
14335
  return;
14132
14336
  }
14133
14337
  if (action_1 === "italic") {
14134
- executeEditorCommand(view_10, toggleItalic);
14338
+ executeEditorCommand(view_11, toggleItalic);
14135
14339
  return;
14136
14340
  }
14137
14341
  if (action_1 === "underline") {
14138
- executeEditorCommand(view_10, toggleUnderline);
14342
+ executeEditorCommand(view_11, toggleUnderline);
14139
14343
  return;
14140
14344
  }
14141
14345
  if (action_1 === "strikethrough") {
14142
- executeEditorCommand(view_10, toggleStrike);
14346
+ executeEditorCommand(view_11, toggleStrike);
14143
14347
  return;
14144
14348
  }
14145
14349
  if (action_1 === "superscript") {
14146
- executeEditorCommand(view_10, toggleSuperscript);
14350
+ executeEditorCommand(view_11, toggleSuperscript);
14147
14351
  return;
14148
14352
  }
14149
14353
  if (action_1 === "subscript") {
14150
- executeEditorCommand(view_10, toggleSubscript);
14354
+ executeEditorCommand(view_11, toggleSubscript);
14151
14355
  return;
14152
14356
  }
14153
14357
  if (action_1 === "bulletList") {
14154
- executeEditorCommand(view_10, toggleBulletList);
14358
+ executeEditorCommand(view_11, toggleBulletList);
14155
14359
  return;
14156
14360
  }
14157
14361
  if (action_1 === "numberedList") {
14158
- executeEditorCommand(view_10, toggleNumberedList);
14362
+ executeEditorCommand(view_11, toggleNumberedList);
14159
14363
  return;
14160
14364
  }
14161
14365
  if (action_1 === "indent") {
14162
- executeFirstEditorCommand(view_10, [increaseListLevel, increaseIndent()]);
14366
+ executeFirstEditorCommand(view_11, [increaseListLevel, increaseIndent()]);
14163
14367
  return;
14164
14368
  }
14165
14369
  if (action_1 === "outdent") {
14166
- executeFirstEditorCommand(view_10, [decreaseListLevel, decreaseIndent()]);
14370
+ executeFirstEditorCommand(view_11, [decreaseListLevel, decreaseIndent()]);
14167
14371
  return;
14168
14372
  }
14169
14373
  if (action_1 === "clearFormatting") {
14170
- executeEditorCommand(view_10, clearFormatting);
14374
+ executeEditorCommand(view_11, clearFormatting);
14171
14375
  return;
14172
14376
  }
14173
14377
  if (action_1 === "setRtl") {
14174
- executeEditorCommand(view_10, setRtl);
14378
+ executeEditorCommand(view_11, setRtl);
14175
14379
  return;
14176
14380
  }
14177
14381
  if (action_1 === "setLtr") {
14178
- executeEditorCommand(view_10, setLtr);
14382
+ executeEditorCommand(view_11, setLtr);
14179
14383
  return;
14180
14384
  }
14181
14385
  if (action_1 === "insertPageBreak") {
14182
- executeEditorCommand(view_10, insertPageBreak);
14386
+ executeEditorCommand(view_11, insertPageBreak);
14183
14387
  return;
14184
14388
  }
14185
14389
  if (typeof action_1 === "object") switch (action_1.type) {
14186
14390
  case "alignment":
14187
- executeEditorCommand(view_10, setAlignment(action_1.value));
14391
+ executeEditorCommand(view_11, setAlignment(action_1.value));
14188
14392
  break;
14189
14393
  case "toggleDirection":
14190
- executeEditorCommand(view_10, toggleBidi);
14394
+ executeEditorCommand(view_11, toggleBidi);
14191
14395
  break;
14192
14396
  case "textColor": {
14193
14397
  const colorVal_0 = action_1.value;
14194
- if (typeof colorVal_0 === "string") executeEditorCommand(view_10, setTextColor({ rgb: colorVal_0.replace("#", "") }));
14195
- else if (colorVal_0.auto) executeEditorCommand(view_10, clearTextColor);
14398
+ if (typeof colorVal_0 === "string") executeEditorCommand(view_11, setTextColor({ rgb: colorVal_0.replace("#", "") }));
14399
+ else if (colorVal_0.auto) executeEditorCommand(view_11, clearTextColor);
14196
14400
  else {
14197
14401
  const themeColor = typeof colorVal_0.themeColor === "string" ? colorVal_0.themeColor : void 0;
14198
- executeEditorCommand(view_10, setTextColor({
14402
+ executeEditorCommand(view_11, setTextColor({
14199
14403
  ...colorVal_0.rgb === void 0 ? {} : { rgb: colorVal_0.rgb },
14200
14404
  ...themeColor ? { themeColor } : {},
14201
14405
  ...colorVal_0.themeTint === void 0 ? {} : { themeTint: colorVal_0.themeTint },
@@ -14205,16 +14409,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14205
14409
  break;
14206
14410
  }
14207
14411
  case "highlightColor":
14208
- executeEditorCommand(view_10, setHighlight((action_1.value ? mapHexToHighlightName(action_1.value) : "") || action_1.value));
14412
+ executeEditorCommand(view_11, setHighlight((action_1.value ? mapHexToHighlightName(action_1.value) : "") || action_1.value));
14209
14413
  break;
14210
14414
  case "fontSize":
14211
- executeEditorCommand(view_10, setFontSize(pointsToHalfPoints(action_1.value)));
14415
+ executeEditorCommand(view_11, setFontSize(pointsToHalfPoints(action_1.value)));
14212
14416
  break;
14213
14417
  case "fontFamily":
14214
- executeEditorCommand(view_10, setFontFamily(action_1.value));
14418
+ executeEditorCommand(view_11, setFontFamily(action_1.value));
14215
14419
  break;
14216
14420
  case "lineSpacing":
14217
- executeEditorCommand(view_10, setLineSpacing(action_1.value));
14421
+ executeEditorCommand(view_11, setLineSpacing(action_1.value));
14218
14422
  break;
14219
14423
  case "applyStyle": {
14220
14424
  const currentDoc_0 = historyStateRef.current;
@@ -14227,22 +14431,22 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14227
14431
  const styleName = styleResolver_0.getStyle(action_1.value)?.name;
14228
14432
  if (styleName) styleAttrs.styleName = styleName;
14229
14433
  styleAttrs.numbering = currentDoc_0?.package.numbering ? getCachedNumberingMap(currentDoc_0.package.numbering) : null;
14230
- executeEditorCommand(view_10, applyStyle(action_1.value, styleAttrs));
14231
- } else executeEditorCommand(view_10, applyStyle(action_1.value));
14434
+ executeEditorCommand(view_11, applyStyle(action_1.value, styleAttrs));
14435
+ } else executeEditorCommand(view_11, applyStyle(action_1.value));
14232
14436
  break;
14233
14437
  }
14234
14438
  default: break;
14235
14439
  }
14236
14440
  }, [getActiveEditorView, getCachedStyleResolver]);
14237
14441
  const captureFormatPainter = useCallback(() => {
14238
- const view_11 = getActiveEditorView();
14239
- capturedFormatMarksRef.current = view_11 ? captureFormatMarks(view_11.state) : null;
14442
+ const view_12 = getActiveEditorView();
14443
+ capturedFormatMarksRef.current = view_12 ? captureFormatMarks(view_12.state) : null;
14240
14444
  }, [getActiveEditorView]);
14241
14445
  const paintFormatToSelection = useCallback(() => {
14242
- const view_12 = getActiveEditorView();
14243
- if (!view_12) return false;
14244
- const applied = applyFormatMarks(capturedFormatMarksRef.current)(view_12.state, view_12.dispatch);
14245
- if (applied) requestAnimationFrame(() => view_12.focus());
14446
+ const view_13 = getActiveEditorView();
14447
+ if (!view_13) return false;
14448
+ const applied = applyFormatMarks(capturedFormatMarksRef.current)(view_13.state, view_13.dispatch);
14449
+ if (applied) requestAnimationFrame(() => view_13.focus());
14246
14450
  return applied;
14247
14451
  }, [getActiveEditorView]);
14248
14452
  const handleFormatPainter = useCallback((sticky) => {
@@ -14420,12 +14624,12 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14420
14624
  t
14421
14625
  ]);
14422
14626
  const handleContextMenuAction = useCallback(async (action_2) => {
14423
- const view_13 = getActiveEditorView();
14424
- if (!view_13) return;
14627
+ const view_14 = getActiveEditorView();
14628
+ if (!view_14) return;
14425
14629
  focusActiveEditor();
14426
14630
  if (readOnly && action_2 !== "copy" && action_2 !== "selectAll") return;
14427
14631
  if (action_2.startsWith("custom:")) {
14428
- const { from: from_2, to: to_2 } = contextMenu.selectionRange.from !== contextMenu.selectionRange.to ? contextMenu.selectionRange : view_13.state.selection;
14632
+ const { from: from_2, to: to_2 } = contextMenu.selectionRange.from !== contextMenu.selectionRange.to ? contextMenu.selectionRange : view_14.state.selection;
14429
14633
  onCustomContextAction?.(action_2.slice(7), {
14430
14634
  from: from_2,
14431
14635
  to: to_2
@@ -14435,16 +14639,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14435
14639
  switch (action_2) {
14436
14640
  case "cut": {
14437
14641
  if (readOnly) return;
14438
- const { from: from_7, to: to_7 } = view_13.state.selection;
14439
- const text_2 = view_13.state.doc.textBetween(from_7, to_7, "\n");
14642
+ const { from: from_7, to: to_7 } = view_14.state.selection;
14643
+ const text_2 = view_14.state.doc.textBetween(from_7, to_7, "\n");
14440
14644
  navigator.clipboard.writeText(text_2).catch(() => void 0);
14441
- if (!deleteSelectionAsSuggestion(view_13.state, view_13.dispatch)) view_13.dispatch(view_13.state.tr.deleteSelection());
14645
+ if (!deleteSelectionAsSuggestion(view_14.state, view_14.dispatch)) view_14.dispatch(view_14.state.tr.deleteSelection());
14442
14646
  onCut?.();
14443
14647
  break;
14444
14648
  }
14445
14649
  case "copy": {
14446
- const { from: cf, to: ct } = view_13.state.selection;
14447
- const copied = view_13.state.doc.textBetween(cf, ct, "\n");
14650
+ const { from: cf, to: ct } = view_14.state.selection;
14651
+ const copied = view_14.state.doc.textBetween(cf, ct, "\n");
14448
14652
  navigator.clipboard.writeText(copied).catch(() => void 0);
14449
14653
  onCopy?.();
14450
14654
  break;
@@ -14467,12 +14671,12 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14467
14671
  bubbles: true,
14468
14672
  cancelable: true
14469
14673
  });
14470
- view_13.dom.dispatchEvent(pasteEvent);
14674
+ view_14.dom.dispatchEvent(pasteEvent);
14471
14675
  } catch {
14472
14676
  try {
14473
14677
  const text_0 = await navigator.clipboard.readText();
14474
14678
  if (text_0) {
14475
- view_13.dispatch(view_13.state.tr.insertText(text_0));
14679
+ view_14.dispatch(view_14.state.tr.insertText(text_0));
14476
14680
  onPaste?.();
14477
14681
  }
14478
14682
  } catch {}
@@ -14481,9 +14685,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14481
14685
  case "pasteAsPlainText":
14482
14686
  try {
14483
14687
  const text = await navigator.clipboard.readText();
14484
- if (text && !view_13.isDestroyed) {
14485
- const slice = buildPlainTextSlice(text, view_13.state.schema);
14486
- view_13.dispatch(view_13.state.tr.replaceSelection(slice).scrollIntoView());
14688
+ if (text && !view_14.isDestroyed) {
14689
+ const slice = buildPlainTextSlice(text, view_14.state.schema);
14690
+ view_14.dispatch(view_14.state.tr.replaceSelection(slice).scrollIntoView());
14487
14691
  onPaste?.();
14488
14692
  }
14489
14693
  } catch {
@@ -14491,49 +14695,51 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14491
14695
  }
14492
14696
  break;
14493
14697
  case "delete": {
14494
- const { from: from_6, to: to_6 } = view_13.state.selection;
14495
- if (from_6 !== to_6) view_13.dispatch(view_13.state.tr.deleteRange(from_6, to_6));
14698
+ const { from: from_6, to: to_6 } = view_14.state.selection;
14699
+ if (from_6 !== to_6) view_14.dispatch(view_14.state.tr.deleteRange(from_6, to_6));
14496
14700
  break;
14497
14701
  }
14498
14702
  case "selectAll":
14499
- view_13.dispatch(view_13.state.tr.setSelection(TextSelection.create(view_13.state.doc, 0, view_13.state.doc.content.size)));
14703
+ view_14.dispatch(view_14.state.tr.setSelection(TextSelection.create(view_14.state.doc, 0, view_14.state.doc.content.size)));
14500
14704
  break;
14501
14705
  case "addRowAbove":
14502
- addRowAbove(view_13.state, view_13.dispatch);
14706
+ addRowAbove(view_14.state, view_14.dispatch);
14503
14707
  break;
14504
14708
  case "addRowBelow":
14505
- addRowBelow(view_13.state, view_13.dispatch);
14709
+ addRowBelow(view_14.state, view_14.dispatch);
14506
14710
  break;
14507
14711
  case "deleteRow":
14508
- deleteRow(view_13.state, view_13.dispatch);
14712
+ deleteRow(view_14.state, view_14.dispatch);
14509
14713
  break;
14510
14714
  case "addColumnLeft":
14511
- addColumnLeft(view_13.state, view_13.dispatch);
14715
+ addColumnLeft(view_14.state, view_14.dispatch);
14512
14716
  break;
14513
14717
  case "addColumnRight":
14514
- addColumnRight(view_13.state, view_13.dispatch);
14718
+ addColumnRight(view_14.state, view_14.dispatch);
14515
14719
  break;
14516
14720
  case "deleteColumn":
14517
- deleteColumn(view_13.state, view_13.dispatch);
14721
+ deleteColumn(view_14.state, view_14.dispatch);
14518
14722
  break;
14519
14723
  case "tableBordersAll":
14520
- setTableBorderPreset("all")(view_13.state, view_13.dispatch);
14724
+ setTableBorderPreset("all")(view_14.state, view_14.dispatch);
14521
14725
  break;
14522
14726
  case "tableBordersNone":
14523
- setTableBorderPreset("none")(view_13.state, view_13.dispatch);
14727
+ setTableBorderPreset("none")(view_14.state, view_14.dispatch);
14524
14728
  break;
14525
14729
  case "addComment": {
14526
- const { from: from_5, to: to_5 } = contextMenu.selectionRange.from !== contextMenu.selectionRange.to ? contextMenu.selectionRange : view_13.state.selection;
14730
+ const { from: from_5, to: to_5 } = contextMenu.selectionRange.from !== contextMenu.selectionRange.to ? contextMenu.selectionRange : view_14.state.selection;
14527
14731
  if (from_5 === to_5) break;
14528
14732
  const commentY = findSelectionYPosition(scrollContainerRef.current, editorContentRef.current, from_5) ?? getFallbackCommentYPosition(scrollContainerRef.current);
14529
14733
  setCommentSelectionRange({
14530
14734
  from: from_5,
14531
14735
  to: to_5
14532
14736
  });
14533
- if (!applyCommentMarkRange(view_13, {
14534
- from: from_5,
14535
- to: to_5
14536
- }, -1, { selectEnd: true })) break;
14737
+ if (commentDraftMode === "prosemirror") {
14738
+ if (!applyCommentMarkRange(view_14, {
14739
+ from: from_5,
14740
+ to: to_5
14741
+ }, -1, { selectEnd: true })) break;
14742
+ }
14537
14743
  setAddCommentYPosition(commentY);
14538
14744
  setShowCommentsSidebar(true);
14539
14745
  setIsAddingComment(true);
@@ -14541,30 +14747,30 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14541
14747
  break;
14542
14748
  }
14543
14749
  case "acceptChange": {
14544
- const { from: from_4, to: to_4 } = view_13.state.selection;
14545
- const range_1 = findChangeAtPosition(view_13.state, from_4, to_4);
14750
+ const { from: from_4, to: to_4 } = view_14.state.selection;
14751
+ const range_1 = findChangeAtPosition(view_14.state, from_4, to_4);
14546
14752
  if (resolveCanonicalReviewRange({
14547
14753
  editor: pagedEditorRef.current?.getEditor(),
14548
14754
  ...range_1,
14549
14755
  resolution: "accept"
14550
- }) === null) acceptChange(range_1.from, range_1.to)(view_13.state, view_13.dispatch);
14756
+ }) === null) acceptChange(range_1.from, range_1.to)(view_14.state, view_14.dispatch);
14551
14757
  break;
14552
14758
  }
14553
14759
  case "rejectChange": {
14554
- const { from: from_3, to: to_3 } = view_13.state.selection;
14555
- const range_0 = findChangeAtPosition(view_13.state, from_3, to_3);
14760
+ const { from: from_3, to: to_3 } = view_14.state.selection;
14761
+ const range_0 = findChangeAtPosition(view_14.state, from_3, to_3);
14556
14762
  if (resolveCanonicalReviewRange({
14557
14763
  editor: pagedEditorRef.current?.getEditor(),
14558
14764
  ...range_0,
14559
14765
  resolution: "reject"
14560
- }) === null) rejectChange(range_0.from, range_0.to)(view_13.state, view_13.dispatch);
14766
+ }) === null) rejectChange(range_0.from, range_0.to)(view_14.state, view_14.dispatch);
14561
14767
  break;
14562
14768
  }
14563
14769
  case "restartNumbering":
14564
- restartNumbering(view_13.state, view_13.dispatch);
14770
+ restartNumbering(view_14.state, view_14.dispatch);
14565
14771
  break;
14566
14772
  case "continueNumbering":
14567
- continueNumbering(view_13.state, view_13.dispatch);
14773
+ continueNumbering(view_14.state, view_14.dispatch);
14568
14774
  break;
14569
14775
  case "setNumberingValue":
14570
14776
  setNumberingValueDialogOpen(true);
@@ -14590,13 +14796,12 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14590
14796
  ]);
14591
14797
  const handlePageSetupApply = useCallback((props) => {
14592
14798
  if (readOnly) return;
14593
- if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
14594
- const api_0 = getCanonicalApi();
14595
- api_0?.ensureView();
14596
- const canonical_1 = api_0?.getCanonicalDocument();
14597
- if (!canonical_1 || !api_0?.applyCanonicalOperations([createCanonicalSectionPropertiesOperation(canonical_1, props)])) refuseCanonicalModelEdit(CANONICAL_GAP.sectionProperties, "Section property changes could not be applied.");
14799
+ const api_0 = getCanonicalApi();
14800
+ if (!api_0) {
14801
+ refuseCanonicalModelEdit(CANONICAL_GAP.sectionProperties, "The editor is not ready for section changes.");
14598
14802
  return;
14599
14803
  }
14804
+ if (api_0.applyCanonicalSectionProperties(props) !== null) return;
14600
14805
  if (!history.state || readOnly) return;
14601
14806
  const newDoc_0 = {
14602
14807
  ...history.state,
@@ -14616,7 +14821,6 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14616
14821
  history.state,
14617
14822
  readOnly,
14618
14823
  handleDocumentChange,
14619
- experimentalSession,
14620
14824
  getCanonicalApi,
14621
14825
  refuseCanonicalModelEdit
14622
14826
  ]);
@@ -14625,25 +14829,25 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14625
14829
  const handleTopMarginChange = useCallback((twips_1) => handlePageSetupApply({ marginTop: twips_1 }), [handlePageSetupApply]);
14626
14830
  const handleBottomMarginChange = useCallback((twips_2) => handlePageSetupApply({ marginBottom: twips_2 }), [handlePageSetupApply]);
14627
14831
  const handleIndentLeftChange = useCallback((twips_3) => {
14628
- const view_14 = getActiveEditorView();
14629
- if (!view_14) return;
14630
- setIndentLeft(twips_3)(view_14.state, view_14.dispatch);
14631
- }, [getActiveEditorView]);
14632
- const handleIndentRightChange = useCallback((twips_4) => {
14633
14832
  const view_15 = getActiveEditorView();
14634
14833
  if (!view_15) return;
14635
- setIndentRight(twips_4)(view_15.state, view_15.dispatch);
14834
+ setIndentLeft(twips_3)(view_15.state, view_15.dispatch);
14636
14835
  }, [getActiveEditorView]);
14637
- const handleFirstLineIndentChange = useCallback((twips_5) => {
14836
+ const handleIndentRightChange = useCallback((twips_4) => {
14638
14837
  const view_16 = getActiveEditorView();
14639
14838
  if (!view_16) return;
14640
- if (twips_5 < 0) setIndentFirstLine(-twips_5, true)(view_16.state, view_16.dispatch);
14641
- else setIndentFirstLine(twips_5, false)(view_16.state, view_16.dispatch);
14839
+ setIndentRight(twips_4)(view_16.state, view_16.dispatch);
14642
14840
  }, [getActiveEditorView]);
14643
- const handleTabStopRemove = useCallback((positionTwips) => {
14841
+ const handleFirstLineIndentChange = useCallback((twips_5) => {
14644
14842
  const view_17 = getActiveEditorView();
14645
14843
  if (!view_17) return;
14646
- removeTabStop(positionTwips)(view_17.state, view_17.dispatch);
14844
+ if (twips_5 < 0) setIndentFirstLine(-twips_5, true)(view_17.state, view_17.dispatch);
14845
+ else setIndentFirstLine(twips_5, false)(view_17.state, view_17.dispatch);
14846
+ }, [getActiveEditorView]);
14847
+ const handleTabStopRemove = useCallback((positionTwips) => {
14848
+ const view_18 = getActiveEditorView();
14849
+ if (!view_18) return;
14850
+ removeTabStop(positionTwips)(view_18.state, view_18.dispatch);
14647
14851
  }, [getActiveEditorView]);
14648
14852
  const serializeCurrentDocx = useCallback(async (options) => {
14649
14853
  let tripwireResult = null;
@@ -14652,25 +14856,25 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14652
14856
  const editor_1 = pagedEditorRef.current?.getEditor();
14653
14857
  const snapshot = editor_1?.captureCanonicalSave();
14654
14858
  if (snapshot && editor_1) {
14655
- const view_18 = editor_1.getView();
14656
- const editorState = view_18?.state;
14657
- const result = await serializeCanonicalSave({
14859
+ const view_19 = editor_1.getView();
14860
+ const editorState = view_19?.state;
14861
+ const result_2 = await serializeCanonicalSave({
14658
14862
  snapshot,
14659
14863
  options,
14660
14864
  featureFlags
14661
14865
  });
14662
- for (const diagnostic of result.diagnostics) if (!options?.onDiagnostic) onError?.(new CanonicalSaveDiagnosticError({
14866
+ for (const diagnostic of result_2.diagnostics) if (!options?.onDiagnostic) onError?.(new CanonicalSaveDiagnosticError({
14663
14867
  gap: CANONICAL_GAP.save,
14664
14868
  diagnostic,
14665
14869
  message: `Canonical save used a fidelity fallback: ${diagnostic.type} (${diagnostic.part}).`
14666
14870
  }));
14667
- tripwireResult = result.tripwireResult;
14668
- if (view_18 && pagedEditorRef.current?.getEditor() === editor_1 && editor_1.getView() === view_18 && view_18.state.doc === editorState?.doc && editor_1.isCanonicalSaveCurrent(snapshot.version)) view_18.dispatch(clearTrackedChanges(view_18.state));
14669
- savedBuffer = result.buffer;
14871
+ tripwireResult = result_2.tripwireResult;
14872
+ if (view_19 && pagedEditorRef.current?.getEditor() === editor_1 && editor_1.getView() === view_19 && view_19.state.doc === editorState?.doc && editor_1.isCanonicalSaveCurrent(snapshot.version)) view_19.dispatch(clearTrackedChanges(view_19.state));
14873
+ savedBuffer = result_2.buffer;
14670
14874
  } else {
14671
14875
  if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.save)) return null;
14672
- const view_19 = pagedEditorRef.current?.getView();
14673
- const editorState_0 = view_19?.state;
14876
+ const view_20 = pagedEditorRef.current?.getView();
14877
+ const editorState_0 = view_20?.state;
14674
14878
  const baselineBuffer = originalBufferRef.current;
14675
14879
  const current = buildCurrentDocument();
14676
14880
  const doc_1 = current ? withoutUnreferencedNotes(current) : null;
@@ -14711,14 +14915,14 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14711
14915
  const { compareSelectiveVsFull } = await import("@stll/folio-core/docx/selectiveSaveTripwire");
14712
14916
  tripwireResult = await compareSelectiveVsFull(selectiveBuffer, fullBuffer);
14713
14917
  } catch {}
14714
- if (view_19 && pagedEditorRef.current?.getView() === view_19 && view_19.state.doc === editorState_0?.doc) {
14918
+ if (view_20 && pagedEditorRef.current?.getView() === view_20 && view_20.state.doc === editorState_0?.doc) {
14715
14919
  originalBufferRef.current = buffer;
14716
- view_19.dispatch(clearTrackedChanges(view_19.state));
14920
+ view_20.dispatch(clearTrackedChanges(view_20.state));
14717
14921
  }
14718
14922
  savedBuffer = buffer;
14719
14923
  }
14720
- } catch (error_1) {
14721
- onError?.(error_1 instanceof Error ? error_1 : /* @__PURE__ */ new Error("Failed to save document"));
14924
+ } catch (error_0) {
14925
+ onError?.(error_0 instanceof Error ? error_0 : /* @__PURE__ */ new Error("Failed to save document"));
14722
14926
  return null;
14723
14927
  }
14724
14928
  if (tripwireResult && onSelectiveSaveTripwire) onSelectiveSaveTripwire(tripwireResult);
@@ -14753,16 +14957,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14753
14957
  loadParsedDocument,
14754
14958
  serializeCurrentDocx
14755
14959
  ]);
14756
- const handleEditorError = useCallback((error_2) => {
14757
- if (CanonicalSessionRefusalError.is(error_2)) toast(error_2.message);
14758
- onError?.(error_2);
14960
+ const handleEditorError = useCallback((error_1) => {
14961
+ if (CanonicalSessionRefusalError.is(error_1)) toast(error_1.message);
14962
+ onError?.(error_1);
14759
14963
  }, [onError]);
14760
14964
  useImperativeHandle(ref, () => ({
14761
14965
  getDocument: () => buildCurrentDocument(),
14762
14966
  hasPendingChanges: () => {
14763
- const view_20 = pagedEditorRef.current?.getView();
14764
- if (!view_20) return false;
14765
- return commentsDirtyRef.current || getChangedParagraphIds(view_20.state).size > 0 || hasStructuralChanges(view_20.state) || hasUntrackedChanges(view_20.state);
14967
+ const view_21 = pagedEditorRef.current?.getView();
14968
+ if (!view_21) return false;
14969
+ return commentsDirtyRef.current || getChangedParagraphIds(view_21.state).size > 0 || hasStructuralChanges(view_21.state) || hasUntrackedChanges(view_21.state);
14766
14970
  },
14767
14971
  getEditorRef: () => pagedEditorRef.current,
14768
14972
  getEditor: () => pagedEditorRef.current?.getEditor() ?? null,
@@ -14803,13 +15007,13 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14803
15007
  pagedEditorRef.current?.ensureView(options_2);
14804
15008
  },
14805
15009
  createAIEditSnapshot: () => {
14806
- const view_21 = pagedEditorRef.current?.getView();
14807
- return view_21 ? createFolioAIEditSnapshot(view_21.state.doc) : null;
15010
+ const view_22 = pagedEditorRef.current?.getView();
15011
+ return view_22 ? createFolioAIEditSnapshot(view_22.state.doc) : null;
14808
15012
  },
14809
15013
  applyDocumentOperations: ({ snapshot: snapshot_0, batch, author: operationAuthor = author }) => {
14810
15014
  assertSupportedFolioDocumentOperationVersion(batch.version);
14811
- const view_22 = pagedEditorRef.current?.getView();
14812
- if (!view_22) {
15015
+ const view_23 = pagedEditorRef.current?.getView();
15016
+ if (!view_23) {
14813
15017
  let status = "committed";
14814
15018
  if (batch.dryRun === true) status = "previewed";
14815
15019
  else if (batch.atomic === true) status = "rejected";
@@ -14827,25 +15031,25 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14827
15031
  undoHandle: null
14828
15032
  };
14829
15033
  }
14830
- const canonical_2 = getCanonicalApi()?.applyCanonicalDocumentOperations({
15034
+ const canonical_1 = getCanonicalApi()?.applyCanonicalDocumentOperations({
14831
15035
  snapshot: snapshot_0,
14832
15036
  batch,
14833
15037
  author: operationAuthor
14834
15038
  });
14835
- if (canonical_2) return canonical_2;
15039
+ if (canonical_1) return canonical_1;
14836
15040
  const existingUndoEntry = documentOperationUndoEntriesRef.current.at(-1);
14837
- if (existingUndoEntry && (!view_22.state.doc.eq(existingUndoEntry.afterState.doc) || commentsRef.current !== existingUndoEntry.commentsAfter)) documentOperationUndoEntriesRef.current.length = 0;
15041
+ if (existingUndoEntry && (!view_23.state.doc.eq(existingUndoEntry.afterState.doc) || commentsRef.current !== existingUndoEntry.commentsAfter)) documentOperationUndoEntriesRef.current.length = 0;
14838
15042
  const commentsBefore = commentsRef.current;
14839
15043
  const createdComments = [];
14840
15044
  const operationView = {
14841
- state: view_22.state,
15045
+ state: view_23.state,
14842
15046
  dispatch: (transaction) => {
14843
- view_22.dispatch(closeHistory(transaction));
14844
- operationView.state = view_22.state;
15047
+ view_23.dispatch(closeHistory(transaction));
15048
+ operationView.state = view_23.state;
14845
15049
  }
14846
15050
  };
14847
- const activeSuggestionIds = new Set(getSuggestions(view_22.state).map((s_0) => s_0.suggestionId));
14848
- const result_0 = applyFolioDocumentOperations({
15051
+ const activeSuggestionIds = new Set(getSuggestions(view_23.state).map((s_0) => s_0.suggestionId));
15052
+ const result_3 = applyFolioDocumentOperations({
14849
15053
  view: operationView,
14850
15054
  snapshot: snapshot_0,
14851
15055
  batch,
@@ -14860,27 +15064,27 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14860
15064
  id: `react-${String(documentOperationUndoHandleCursor++)}`
14861
15065
  })
14862
15066
  });
14863
- if (batch.mode === "suggested" && result_0.status === "committed") pendingSuggestionRegistryRef.current.recordApplied({
15067
+ if (batch.mode === "suggested" && result_3.status === "committed") pendingSuggestionRegistryRef.current.recordApplied({
14864
15068
  snapshot: snapshot_0,
14865
15069
  story: { type: "main" },
14866
15070
  operations: batch.operations,
14867
- applied: result_0.applied,
15071
+ applied: result_3.applied,
14868
15072
  author: operationAuthor,
14869
15073
  activeSuggestionIds
14870
15074
  });
14871
- const batchComments = appliedOperationComments(createdComments, result_0.applied);
15075
+ const batchComments = appliedOperationComments(createdComments, result_3.applied);
14872
15076
  if (batchComments.length > 0) updateComments((currentComments_0) => [...currentComments_0, ...batchComments]);
14873
- if (result_0.undoHandle !== null) documentOperationUndoEntriesRef.current.push({
14874
- undoHandle: result_0.undoHandle,
14875
- afterState: view_22.state,
15077
+ if (result_3.undoHandle !== null) documentOperationUndoEntriesRef.current.push({
15078
+ undoHandle: result_3.undoHandle,
15079
+ afterState: view_23.state,
14876
15080
  commentsBefore,
14877
15081
  commentsAfter: commentsRef.current
14878
15082
  });
14879
- return result_0;
15083
+ return result_3;
14880
15084
  },
14881
15085
  undoDocumentOperations: (undoHandle) => {
14882
- const canonical_3 = getCanonicalApi()?.undoCanonicalDocumentOperations(undoHandle);
14883
- if (canonical_3) return canonical_3;
15086
+ const canonical_2 = getCanonicalApi()?.undoCanonicalDocumentOperations(undoHandle);
15087
+ if (canonical_2) return canonical_2;
14884
15088
  const entries = documentOperationUndoEntriesRef.current;
14885
15089
  const entryIndex = entries.findIndex((entry_2) => entry_2.undoHandle.type === undoHandle.type && entry_2.undoHandle.id === undoHandle.id);
14886
15090
  if (entryIndex === -1) return {
@@ -14894,18 +15098,18 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14894
15098
  reason: "notLatest"
14895
15099
  };
14896
15100
  const entry_3 = entries.at(-1);
14897
- const view_23 = pagedEditorRef.current?.getView();
14898
- if (!entry_3 || !view_23) return {
15101
+ const view_24 = pagedEditorRef.current?.getView();
15102
+ if (!entry_3 || !view_24) return {
14899
15103
  status: "rejected",
14900
15104
  undoHandle,
14901
15105
  reason: "unknownHandle"
14902
15106
  };
14903
- if (!view_23.state.doc.eq(entry_3.afterState.doc) || commentsRef.current !== entry_3.commentsAfter) return {
15107
+ if (!view_24.state.doc.eq(entry_3.afterState.doc) || commentsRef.current !== entry_3.commentsAfter) return {
14904
15108
  status: "rejected",
14905
15109
  undoHandle,
14906
15110
  reason: "documentChanged"
14907
15111
  };
14908
- if (!undo(view_23.state, view_23.dispatch)) return {
15112
+ if (!undo(view_24.state, view_24.dispatch)) return {
14909
15113
  status: "rejected",
14910
15114
  undoHandle,
14911
15115
  reason: "documentChanged"
@@ -14919,15 +15123,15 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14919
15123
  };
14920
15124
  },
14921
15125
  applyAIEditOperations: ({ snapshot: snapshot_1, operations, mode = "tracked-changes", author: operationAuthor_0 = author }) => {
14922
- const view_24 = pagedEditorRef.current?.getView();
14923
- if (!view_24) return {
15126
+ const view_25 = pagedEditorRef.current?.getView();
15127
+ if (!view_25) return {
14924
15128
  applied: [],
14925
15129
  skipped: operations.map((operation_0) => ({
14926
15130
  id: operation_0.id,
14927
15131
  reason: "unsupportedBlock"
14928
15132
  }))
14929
15133
  };
14930
- const canonical_4 = getCanonicalApi()?.applyCanonicalDocumentOperations({
15134
+ const canonical_3 = getCanonicalApi()?.applyCanonicalDocumentOperations({
14931
15135
  snapshot: snapshot_1,
14932
15136
  batch: {
14933
15137
  version: FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION,
@@ -14936,11 +15140,11 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14936
15140
  },
14937
15141
  author: operationAuthor_0
14938
15142
  });
14939
- if (canonical_4) return canonical_4;
15143
+ if (canonical_3) return canonical_3;
14940
15144
  const createdComments_0 = [];
14941
- const activeSuggestionIds_0 = new Set(getSuggestions(view_24.state).map((s_1) => s_1.suggestionId));
15145
+ const activeSuggestionIds_0 = new Set(getSuggestions(view_25.state).map((s_1) => s_1.suggestionId));
14942
15146
  const { applied: applied_0, skipped: skipped_0 } = applyFolioDocumentOperations({
14943
- view: view_24,
15147
+ view: view_25,
14944
15148
  snapshot: snapshot_1,
14945
15149
  batch: {
14946
15150
  version: FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION,
@@ -14970,18 +15174,18 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14970
15174
  };
14971
15175
  },
14972
15176
  acceptAIEditOperation: (revisionId) => {
14973
- const view_25 = pagedEditorRef.current?.getView();
14974
- if (!view_25) return false;
15177
+ const view_26 = pagedEditorRef.current?.getView();
15178
+ if (!view_26) return false;
14975
15179
  const editor_4 = pagedEditorRef.current?.getEditor();
14976
15180
  if (editor_4?.getCanonicalDocument()) return editor_4.resolveCanonicalRevisions(typeof revisionId === "number" ? [revisionId] : revisionId, "accept");
14977
- return acceptAIEditRevision(revisionId)(view_25.state, view_25.dispatch);
15181
+ return acceptAIEditRevision(revisionId)(view_26.state, view_26.dispatch);
14978
15182
  },
14979
15183
  rejectAIEditOperation: (revisionId_0) => {
14980
- const view_26 = pagedEditorRef.current?.getView();
14981
- if (!view_26) return false;
15184
+ const view_27 = pagedEditorRef.current?.getView();
15185
+ if (!view_27) return false;
14982
15186
  const editor_5 = pagedEditorRef.current?.getEditor();
14983
15187
  if (editor_5?.getCanonicalDocument()) return editor_5.resolveCanonicalRevisions(typeof revisionId_0 === "number" ? [revisionId_0] : revisionId_0, "reject");
14984
- return rejectAIEditRevision(revisionId_0)(view_26.state, view_26.dispatch);
15188
+ return rejectAIEditRevision(revisionId_0)(view_27.state, view_27.dispatch);
14985
15189
  },
14986
15190
  undo: () => {
14987
15191
  if (!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) && getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) return hfEditorRef.current.undo();
@@ -14996,44 +15200,44 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14996
15200
  return redone;
14997
15201
  },
14998
15202
  scrollToAIEditOperation: (revisionId_1) => {
14999
- const view_27 = pagedEditorRef.current?.getView();
15000
- if (!view_27) return false;
15001
- const range_2 = findAIEditRevisionRange(view_27.state, revisionId_1);
15203
+ const view_28 = pagedEditorRef.current?.getView();
15204
+ if (!view_28) return false;
15205
+ const range_2 = findAIEditRevisionRange(view_28.state, revisionId_1);
15002
15206
  if (!range_2) return false;
15003
- const { from: from_8, to: to_8 } = clampRangeToDocSize(view_27.state.doc.content.size, range_2);
15004
- const $from = view_27.state.doc.resolve(from_8);
15005
- const $to = view_27.state.doc.resolve(to_8);
15006
- view_27.dispatch(view_27.state.tr.setSelection(TextSelection.between($from, $to)));
15207
+ const { from: from_8, to: to_8 } = clampRangeToDocSize(view_28.state.doc.content.size, range_2);
15208
+ const $from = view_28.state.doc.resolve(from_8);
15209
+ const $to = view_28.state.doc.resolve(to_8);
15210
+ view_28.dispatch(view_28.state.tr.setSelection(TextSelection.between($from, $to)));
15007
15211
  requestAnimationFrame(() => {
15008
15212
  pagedEditorRef.current?.scrollToPosition(from_8);
15009
15213
  });
15010
15214
  return true;
15011
15215
  },
15012
15216
  scrollToBlock: (blockId, snapshot_2) => {
15013
- const view_28 = pagedEditorRef.current?.getView();
15014
- if (!view_28) return false;
15217
+ const view_29 = pagedEditorRef.current?.getView();
15218
+ if (!view_29) return false;
15015
15219
  const range_3 = resolveFolioAIBlockRange({
15016
15220
  blockId,
15017
- doc: view_28.state.doc,
15221
+ doc: view_29.state.doc,
15018
15222
  snapshot: snapshot_2
15019
15223
  });
15020
15224
  if (range_3 === null) return false;
15021
15225
  const { from: from_9, to: to_9 } = range_3;
15022
- const $from_0 = view_28.state.doc.resolve(from_9);
15023
- const $to_0 = view_28.state.doc.resolve(to_9);
15024
- view_28.dispatch(view_28.state.tr.setSelection(TextSelection.between($from_0, $to_0)));
15226
+ const $from_0 = view_29.state.doc.resolve(from_9);
15227
+ const $to_0 = view_29.state.doc.resolve(to_9);
15228
+ view_29.dispatch(view_29.state.tr.setSelection(TextSelection.between($from_0, $to_0)));
15025
15229
  requestAnimationFrame(() => {
15026
15230
  pagedEditorRef.current?.scrollToPosition(from_9);
15027
15231
  });
15028
15232
  return true;
15029
15233
  },
15030
15234
  highlightPassage: ({ blockId: blockId_0, text: text_5, snapshot: snapshot_3 }) => {
15031
- const view_29 = pagedEditorRef.current?.getView();
15032
- if (!view_29) return "none";
15235
+ const view_30 = pagedEditorRef.current?.getView();
15236
+ if (!view_30) return "none";
15033
15237
  const passageRange = resolvePassageRange({
15034
15238
  blockId: blockId_0,
15035
15239
  text: text_5,
15036
- doc: view_29.state.doc,
15240
+ doc: view_30.state.doc,
15037
15241
  snapshot: snapshot_3
15038
15242
  });
15039
15243
  if (passageRange !== null) {
@@ -15046,16 +15250,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15046
15250
  pagedEditorRef.current?.setPassageHighlight(null);
15047
15251
  const blockRange = resolveFolioAIBlockRange({
15048
15252
  blockId: blockId_0,
15049
- doc: view_29.state.doc,
15253
+ doc: view_30.state.doc,
15050
15254
  snapshot: snapshot_3
15051
15255
  });
15052
15256
  if (blockRange === null) return "none";
15053
15257
  const paraId_0 = getFolioParaIdFromBlockId(blockId_0);
15054
15258
  if (paraId_0 !== null && pagedEditorRef.current?.scrollToParaId(paraId_0, { highlight: {} })) return "block";
15055
15259
  const { from: from_10, to: to_10 } = blockRange;
15056
- const $from_1 = view_29.state.doc.resolve(from_10);
15057
- const $to_1 = view_29.state.doc.resolve(to_10);
15058
- view_29.dispatch(view_29.state.tr.setSelection(TextSelection.between($from_1, $to_1)));
15260
+ const $from_1 = view_30.state.doc.resolve(from_10);
15261
+ const $to_1 = view_30.state.doc.resolve(to_10);
15262
+ view_30.dispatch(view_30.state.tr.setSelection(TextSelection.between($from_1, $to_1)));
15059
15263
  requestAnimationFrame(() => {
15060
15264
  pagedEditorRef.current?.scrollToPosition(from_10);
15061
15265
  });
@@ -15065,56 +15269,56 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15065
15269
  pagedEditorRef.current?.setPassageHighlight(null);
15066
15270
  },
15067
15271
  showInDocument: (target_1, snapshot_4) => {
15068
- const view_30 = pagedEditorRef.current?.getView();
15069
- if (!view_30) return false;
15272
+ const view_31 = pagedEditorRef.current?.getView();
15273
+ if (!view_31) return false;
15070
15274
  const range_4 = target_1.type === "textRange" ? resolveFolioAITextRange({
15071
15275
  range: target_1,
15072
- doc: view_30.state.doc,
15276
+ doc: view_31.state.doc,
15073
15277
  snapshot: snapshot_4
15074
15278
  }) : resolveFolioAIBlockRange({
15075
15279
  blockId: target_1.blockId,
15076
- doc: view_30.state.doc,
15280
+ doc: view_31.state.doc,
15077
15281
  snapshot: snapshot_4
15078
15282
  });
15079
15283
  if (range_4 === null) return false;
15080
15284
  const { from: from_11, to: to_11 } = range_4;
15081
- const $from_2 = view_30.state.doc.resolve(from_11);
15082
- const $to_2 = view_30.state.doc.resolve(to_11);
15083
- view_30.dispatch(view_30.state.tr.setSelection(TextSelection.between($from_2, $to_2)));
15285
+ const $from_2 = view_31.state.doc.resolve(from_11);
15286
+ const $to_2 = view_31.state.doc.resolve(to_11);
15287
+ view_31.dispatch(view_31.state.tr.setSelection(TextSelection.between($from_2, $to_2)));
15084
15288
  requestAnimationFrame(() => {
15085
15289
  pagedEditorRef.current?.scrollToPosition(from_11);
15086
15290
  });
15087
15291
  return true;
15088
15292
  },
15089
15293
  getSuggestions: () => {
15090
- const view_31 = pagedEditorRef.current?.getView();
15091
- return view_31 ? getSuggestions(view_31.state) : [];
15294
+ const view_32 = pagedEditorRef.current?.getView();
15295
+ return view_32 ? getSuggestions(view_32.state) : [];
15092
15296
  },
15093
15297
  exportPendingSuggestions: () => {
15094
- const view_32 = pagedEditorRef.current?.getView();
15095
- const activeIds = new Set(view_32 ? getSuggestions(view_32.state).map((s_2) => s_2.suggestionId) : []);
15298
+ const view_33 = pagedEditorRef.current?.getView();
15299
+ const activeIds = new Set(view_33 ? getSuggestions(view_33.state).map((s_2) => s_2.suggestionId) : []);
15096
15300
  return pendingSuggestionRegistryRef.current.exportPendingSuggestions({
15097
15301
  activeSuggestionIds: activeIds,
15098
- snapshotForStory: (story_0, commentIds) => story_0.type === "main" && view_32 ? createPendingSuggestionSourceSnapshot(view_32.state, commentIds) : null
15302
+ snapshotForStory: (story_0, commentIds) => story_0.type === "main" && view_33 ? createPendingSuggestionSourceSnapshot(view_33.state, commentIds) : null
15099
15303
  });
15100
15304
  },
15101
15305
  loadPendingSuggestions: (records) => pendingSuggestionRegistryRef.current.loadPendingSuggestions({
15102
15306
  records,
15103
15307
  snapshotForStory: (story_1) => {
15104
- const view_33 = pagedEditorRef.current?.getView();
15105
- return story_1.type === "main" && view_33 ? createFolioAIEditSnapshot(view_33.state.doc) : null;
15308
+ const view_34 = pagedEditorRef.current?.getView();
15309
+ return story_1.type === "main" && view_34 ? createFolioAIEditSnapshot(view_34.state.doc) : null;
15106
15310
  },
15107
15311
  sourceSnapshotForStory: (story_2, commentIds_0) => {
15108
- const view_34 = pagedEditorRef.current?.getView();
15109
- return story_2.type === "main" && view_34 ? createPendingSuggestionSourceSnapshot(view_34.state, commentIds_0) : null;
15312
+ const view_35 = pagedEditorRef.current?.getView();
15313
+ return story_2.type === "main" && view_35 ? createPendingSuggestionSourceSnapshot(view_35.state, commentIds_0) : null;
15110
15314
  },
15111
15315
  apply: (record, snapshot_5) => {
15112
- const view_35 = pagedEditorRef.current?.getView();
15113
- if (!view_35) return {
15316
+ const view_36 = pagedEditorRef.current?.getView();
15317
+ if (!view_36) return {
15114
15318
  applied: [],
15115
15319
  skipped: []
15116
15320
  };
15117
- const canonical_5 = getCanonicalApi()?.applyCanonicalDocumentOperations({
15321
+ const canonical_4 = getCanonicalApi()?.applyCanonicalDocumentOperations({
15118
15322
  snapshot: snapshot_5,
15119
15323
  batch: {
15120
15324
  version: FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION,
@@ -15123,10 +15327,10 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15123
15327
  },
15124
15328
  author: record.author
15125
15329
  });
15126
- if (canonical_5) return canonical_5;
15330
+ if (canonical_4) return canonical_4;
15127
15331
  const createdComments_1 = [];
15128
- const result_1 = applyFolioDocumentOperations({
15129
- view: view_35,
15332
+ const result_4 = applyFolioDocumentOperations({
15333
+ view: view_36,
15130
15334
  snapshot: snapshot_5,
15131
15335
  batch: {
15132
15336
  version: FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION,
@@ -15140,77 +15344,77 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15140
15344
  return comment_1.id;
15141
15345
  }
15142
15346
  });
15143
- const appliedComments = appliedOperationComments(createdComments_1, result_1.applied);
15347
+ const appliedComments = appliedOperationComments(createdComments_1, result_4.applied);
15144
15348
  if (appliedComments.length > 0) updateComments((currentComments_2) => [...currentComments_2, ...appliedComments]);
15145
15349
  return {
15146
- applied: result_1.applied,
15147
- skipped: result_1.skipped
15350
+ applied: result_4.applied,
15351
+ skipped: result_4.skipped
15148
15352
  };
15149
15353
  },
15150
15354
  activeSuggestionIds: () => {
15151
- const view_36 = pagedEditorRef.current?.getView();
15152
- return new Set(view_36 ? getSuggestions(view_36.state).map((s_3) => s_3.suggestionId) : []);
15355
+ const view_37 = pagedEditorRef.current?.getView();
15356
+ return new Set(view_37 ? getSuggestions(view_37.state).map((s_3) => s_3.suggestionId) : []);
15153
15357
  }
15154
15358
  }),
15155
15359
  acceptSuggestion: (suggestionId, options_3) => {
15156
- const view_37 = pagedEditorRef.current?.getView();
15157
- if (!view_37) return {
15360
+ const view_38 = pagedEditorRef.current?.getView();
15361
+ if (!view_38) return {
15158
15362
  accepted: false,
15159
15363
  appliedAs: null
15160
15364
  };
15161
- const appliedAs = getSuggestions(view_37.state).find((s_4) => s_4.suggestionId === suggestionId)?.appliedAs ?? null;
15162
- const accepted = acceptSuggestion(suggestionId, { author: options_3?.author ?? author })(view_37.state, view_37.dispatch);
15365
+ const appliedAs = getSuggestions(view_38.state).find((s_4) => s_4.suggestionId === suggestionId)?.appliedAs ?? null;
15366
+ const accepted = acceptSuggestion(suggestionId, { author: options_3?.author ?? author })(view_38.state, view_38.dispatch);
15163
15367
  return {
15164
15368
  accepted,
15165
15369
  appliedAs: accepted ? appliedAs : null
15166
15370
  };
15167
15371
  },
15168
15372
  rejectSuggestion: (suggestionId_0) => {
15169
- const view_38 = pagedEditorRef.current?.getView();
15170
- if (!view_38) return false;
15171
- return rejectSuggestion(suggestionId_0)(view_38.state, view_38.dispatch);
15172
- },
15173
- scrollToSuggestion: (suggestionId_1) => {
15174
15373
  const view_39 = pagedEditorRef.current?.getView();
15175
15374
  if (!view_39) return false;
15176
- const range_5 = findSuggestionRange(view_39.state, suggestionId_1);
15375
+ return rejectSuggestion(suggestionId_0)(view_39.state, view_39.dispatch);
15376
+ },
15377
+ scrollToSuggestion: (suggestionId_1) => {
15378
+ const view_40 = pagedEditorRef.current?.getView();
15379
+ if (!view_40) return false;
15380
+ const range_5 = findSuggestionRange(view_40.state, suggestionId_1);
15177
15381
  if (!range_5) return false;
15178
- const { from: from_12, to: to_12 } = clampRangeToDocSize(view_39.state.doc.content.size, range_5);
15179
- const $from_3 = view_39.state.doc.resolve(from_12);
15180
- const $to_3 = view_39.state.doc.resolve(to_12);
15181
- view_39.dispatch(view_39.state.tr.setSelection(TextSelection.between($from_3, $to_3)));
15382
+ const { from: from_12, to: to_12 } = clampRangeToDocSize(view_40.state.doc.content.size, range_5);
15383
+ const $from_3 = view_40.state.doc.resolve(from_12);
15384
+ const $to_3 = view_40.state.doc.resolve(to_12);
15385
+ view_40.dispatch(view_40.state.tr.setSelection(TextSelection.between($from_3, $to_3)));
15182
15386
  requestAnimationFrame(() => {
15183
15387
  pagedEditorRef.current?.scrollToPosition(from_12);
15184
15388
  });
15185
15389
  return true;
15186
15390
  },
15187
15391
  getTrackedChanges: () => {
15188
- const view_40 = pagedEditorRef.current?.getView();
15189
- return view_40 ? getTrackedChangesFromDoc(view_40.state.doc) : [];
15190
- },
15191
- getCommentAnchors: () => {
15192
15392
  const view_41 = pagedEditorRef.current?.getView();
15193
- return view_41 ? getCommentAnchorsFromDoc(view_41.state.doc) : [];
15393
+ return view_41 ? getTrackedChangesFromDoc(view_41.state.doc) : [];
15194
15394
  },
15195
- getSelectionText: () => {
15395
+ getCommentAnchors: () => {
15196
15396
  const view_42 = pagedEditorRef.current?.getView();
15197
- return view_42 ? getSelectedText(view_42.state) : "";
15397
+ return view_42 ? getCommentAnchorsFromDoc(view_42.state.doc) : [];
15198
15398
  },
15199
- getPageText: (page_1) => {
15399
+ getSelectionText: () => {
15200
15400
  const view_43 = pagedEditorRef.current?.getView();
15201
- if (!view_43) return null;
15202
- return getPageTextFromLayout(pagedEditorRef.current?.getEditor()?.getLayout() ?? null, view_43.state.doc, page_1);
15401
+ return view_43 ? getSelectedText(view_43.state) : "";
15203
15402
  },
15204
- getTargetPage: (target_2, snapshot_6) => {
15403
+ getPageText: (page_1) => {
15205
15404
  const view_44 = pagedEditorRef.current?.getView();
15206
15405
  if (!view_44) return null;
15406
+ return getPageTextFromLayout(pagedEditorRef.current?.getEditor()?.getLayout() ?? null, view_44.state.doc, page_1);
15407
+ },
15408
+ getTargetPage: (target_2, snapshot_6) => {
15409
+ const view_45 = pagedEditorRef.current?.getView();
15410
+ if (!view_45) return null;
15207
15411
  const range_6 = target_2.type === "textRange" ? resolveFolioAITextRange({
15208
15412
  range: target_2,
15209
- doc: view_44.state.doc,
15413
+ doc: view_45.state.doc,
15210
15414
  snapshot: snapshot_6
15211
15415
  }) : resolveFolioAIBlockRange({
15212
15416
  blockId: target_2.blockId,
15213
- doc: view_44.state.doc,
15417
+ doc: view_45.state.doc,
15214
15418
  snapshot: snapshot_6
15215
15419
  });
15216
15420
  if (range_6 === null) return null;
@@ -15221,49 +15425,49 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15221
15425
  getScrollRoot: () => pagedEditorRef.current?.getScrollRoot() ?? null,
15222
15426
  onLayoutChange: (listener) => pagedEditorRef.current?.onLayoutChange(listener) ?? (() => {}),
15223
15427
  getContentControls: (filter = {}) => {
15224
- const view_45 = pagedEditorRef.current?.getView();
15225
- if (!view_45) return [];
15226
- return findBlockSdtMatches(view_45.state.doc, filter).map((match_0) => ({
15428
+ const view_46 = pagedEditorRef.current?.getView();
15429
+ if (!view_46) return [];
15430
+ return findBlockSdtMatches(view_46.state.doc, filter).map((match_0) => ({
15227
15431
  properties: blockSdtAttrsToSdtProperties(match_0.node),
15228
15432
  path: match_0.path,
15229
15433
  pmPos: match_0.pos
15230
15434
  }));
15231
15435
  },
15232
15436
  scrollToContentControl: (filter_0) => {
15233
- const view_46 = pagedEditorRef.current?.getView();
15234
- if (!view_46) return false;
15235
- const match_1 = findBlockSdtMatch(view_46.state.doc, filter_0);
15437
+ const view_47 = pagedEditorRef.current?.getView();
15438
+ if (!view_47) return false;
15439
+ const match_1 = findBlockSdtMatch(view_47.state.doc, filter_0);
15236
15440
  if (!match_1) return false;
15237
15441
  const inside = match_1.pos + 1;
15238
- const $pos = view_46.state.doc.resolve(inside);
15239
- view_46.dispatch(view_46.state.tr.setSelection(TextSelection.near($pos)));
15442
+ const $pos = view_47.state.doc.resolve(inside);
15443
+ view_47.dispatch(view_47.state.tr.setSelection(TextSelection.near($pos)));
15240
15444
  requestAnimationFrame(() => {
15241
15445
  pagedEditorRef.current?.scrollToPosition(inside);
15242
15446
  });
15243
15447
  return true;
15244
15448
  },
15245
15449
  setContentControlContent: (filter_1, input, options_4 = {}) => {
15246
- const view_47 = pagedEditorRef.current?.getView();
15247
- if (!view_47) return false;
15248
- const tr_0 = typeof input === "string" ? setContentControlContentTr(view_47.state, filter_1, input, options_4) : setContentControlContentBlocksTr(view_47.state, filter_1, input, options_4);
15450
+ const view_48 = pagedEditorRef.current?.getView();
15451
+ if (!view_48) return false;
15452
+ const tr_0 = typeof input === "string" ? setContentControlContentTr(view_48.state, filter_1, input, options_4) : setContentControlContentBlocksTr(view_48.state, filter_1, input, options_4);
15249
15453
  if (!tr_0) return false;
15250
- view_47.dispatch(tr_0);
15454
+ view_48.dispatch(tr_0);
15251
15455
  return true;
15252
15456
  },
15253
15457
  setContentControlValue: (filter_2, input_0, options_5 = {}) => {
15254
- const view_48 = pagedEditorRef.current?.getView();
15255
- if (!view_48) return false;
15256
- const tr_1 = setContentControlValueTr(view_48.state, filter_2, input_0, options_5);
15458
+ const view_49 = pagedEditorRef.current?.getView();
15459
+ if (!view_49) return false;
15460
+ const tr_1 = setContentControlValueTr(view_49.state, filter_2, input_0, options_5);
15257
15461
  if (!tr_1) return false;
15258
- view_48.dispatch(tr_1);
15462
+ view_49.dispatch(tr_1);
15259
15463
  return true;
15260
15464
  },
15261
15465
  removeContentControl: (filter_3, options_6 = {}) => {
15262
- const view_49 = pagedEditorRef.current?.getView();
15263
- if (!view_49) return false;
15264
- const tr_2 = removeContentControlTr(view_49.state, filter_3, options_6);
15466
+ const view_50 = pagedEditorRef.current?.getView();
15467
+ if (!view_50) return false;
15468
+ const tr_2 = removeContentControlTr(view_50.state, filter_3, options_6);
15265
15469
  if (!tr_2) return false;
15266
- view_49.dispatch(tr_2);
15470
+ view_50.dispatch(tr_2);
15267
15471
  return true;
15268
15472
  }
15269
15473
  }), [
@@ -15353,47 +15557,47 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15353
15557
  if (isDisplayMode(value)) setDisplayMode(value);
15354
15558
  }, [setDisplayMode]);
15355
15559
  const handleAcceptActiveChange = useCallback(() => {
15356
- const view_50 = pagedEditorRef.current?.getView();
15357
- if (!view_50) return;
15358
- const { from: from_13, to: to_13 } = view_50.state.selection;
15359
- const range_7 = findChangeAtPosition(view_50.state, from_13, to_13);
15560
+ const view_51 = pagedEditorRef.current?.getView();
15561
+ if (!view_51) return;
15562
+ const { from: from_13, to: to_13 } = view_51.state.selection;
15563
+ const range_7 = findChangeAtPosition(view_51.state, from_13, to_13);
15360
15564
  if (resolveCanonicalReviewRange({
15361
15565
  editor: pagedEditorRef.current?.getEditor(),
15362
15566
  ...range_7,
15363
15567
  resolution: "accept"
15364
- }) === null) acceptChange(range_7.from, range_7.to)(view_50.state, view_50.dispatch);
15568
+ }) === null) acceptChange(range_7.from, range_7.to)(view_51.state, view_51.dispatch);
15365
15569
  }, []);
15366
15570
  const handleRejectActiveChange = useCallback(() => {
15367
- const view_51 = pagedEditorRef.current?.getView();
15368
- if (!view_51) return;
15369
- const { from: from_14, to: to_14 } = view_51.state.selection;
15370
- const range_8 = findChangeAtPosition(view_51.state, from_14, to_14);
15571
+ const view_52 = pagedEditorRef.current?.getView();
15572
+ if (!view_52) return;
15573
+ const { from: from_14, to: to_14 } = view_52.state.selection;
15574
+ const range_8 = findChangeAtPosition(view_52.state, from_14, to_14);
15371
15575
  if (resolveCanonicalReviewRange({
15372
15576
  editor: pagedEditorRef.current?.getEditor(),
15373
15577
  ...range_8,
15374
15578
  resolution: "reject"
15375
- }) === null) rejectChange(range_8.from, range_8.to)(view_51.state, view_51.dispatch);
15579
+ }) === null) rejectChange(range_8.from, range_8.to)(view_52.state, view_52.dispatch);
15376
15580
  }, []);
15377
15581
  const handlePreviousChange = useCallback(() => {
15378
- const view_52 = pagedEditorRef.current?.getView();
15379
- if (!view_52) return;
15380
- const { from: from_15 } = view_52.state.selection;
15381
- const change = findPreviousChange(view_52.state, from_15);
15582
+ const view_53 = pagedEditorRef.current?.getView();
15583
+ if (!view_53) return;
15584
+ const { from: from_15 } = view_53.state.selection;
15585
+ const change = findPreviousChange(view_53.state, from_15);
15382
15586
  if (!change) return;
15383
- view_52.dispatch(view_52.state.tr.setSelection(TextSelection.create(view_52.state.doc, change.from, change.to)));
15384
- view_52.focus();
15587
+ view_53.dispatch(view_53.state.tr.setSelection(TextSelection.create(view_53.state.doc, change.from, change.to)));
15588
+ view_53.focus();
15385
15589
  requestAnimationFrame(() => {
15386
15590
  pagedEditorRef.current?.scrollToPosition(change.from);
15387
15591
  });
15388
15592
  }, []);
15389
15593
  const handleNextChange = useCallback(() => {
15390
- const view_53 = pagedEditorRef.current?.getView();
15391
- if (!view_53) return;
15392
- const { to: to_15 } = view_53.state.selection;
15393
- const change_0 = findNextChange(view_53.state, to_15);
15594
+ const view_54 = pagedEditorRef.current?.getView();
15595
+ if (!view_54) return;
15596
+ const { to: to_15 } = view_54.state.selection;
15597
+ const change_0 = findNextChange(view_54.state, to_15);
15394
15598
  if (!change_0) return;
15395
- view_53.dispatch(view_53.state.tr.setSelection(TextSelection.create(view_53.state.doc, change_0.from, change_0.to)));
15396
- view_53.focus();
15599
+ view_54.dispatch(view_54.state.tr.setSelection(TextSelection.create(view_54.state.doc, change_0.from, change_0.to)));
15600
+ view_54.focus();
15397
15601
  requestAnimationFrame(() => {
15398
15602
  pagedEditorRef.current?.scrollToPosition(change_0.from);
15399
15603
  });
@@ -15563,51 +15767,94 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15563
15767
  requestAnimationFrame(syncCommentHighlightStyles);
15564
15768
  }, [onScrollTopChange, syncCommentHighlightStyles]);
15565
15769
  const handlePagedSelectionChange = useCallback((_from, _to) => {
15566
- const view_54 = getActiveEditorView() ?? pagedEditorRef.current?.getView() ?? null;
15567
- handleSelectionChange(view_54 ? extractSelectionState(view_54.state) : null);
15770
+ const view_55 = getActiveEditorView() ?? pagedEditorRef.current?.getView() ?? null;
15771
+ handleSelectionChange(view_55 ? extractSelectionState(view_55.state) : null);
15568
15772
  }, [getActiveEditorView, handleSelectionChange]);
15569
15773
  const handleTotalPagesChange = useCallback((totalPages) => {
15570
15774
  setScrollPageInfo((previous) => updateScrollPageTotal(previous, totalPages));
15571
15775
  }, [setScrollPageInfo]);
15572
15776
  const handleCommentClick = useCallback((id) => setActiveCommentId(id), [setActiveCommentId]);
15573
15777
  const handleCommentResolve = useCallback((id_0) => {
15574
- if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return;
15778
+ if (applyCanonicalComment({
15779
+ type: "resolve",
15780
+ id: id_0,
15781
+ status: "resolved"
15782
+ }) !== null) return;
15575
15783
  updateComments((previous_0) => previous_0.map((comment_2) => comment_2.id === id_0 ? {
15576
15784
  ...comment_2,
15577
15785
  done: true
15578
15786
  } : comment_2));
15579
- }, [refuseCanonicalModelEdit, updateComments]);
15787
+ }, [applyCanonicalComment, updateComments]);
15580
15788
  const handleCommentDelete = useCallback((id_1) => {
15581
- if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return;
15789
+ const result_5 = applyCanonicalComment({
15790
+ type: "delete",
15791
+ id: id_1
15792
+ });
15793
+ if (result_5 !== null) {
15794
+ if (result_5.status === "applied" && activeCommentId === id_1) setActiveCommentId(null);
15795
+ return;
15796
+ }
15582
15797
  updateComments((previous_1) => previous_1.filter((comment_3) => comment_3.id !== id_1 && comment_3.parentId !== id_1));
15583
15798
  if (activeCommentId === id_1) setActiveCommentId(null);
15584
15799
  }, [
15585
15800
  activeCommentId,
15586
- refuseCanonicalModelEdit,
15801
+ applyCanonicalComment,
15587
15802
  setActiveCommentId,
15588
15803
  updateComments
15589
15804
  ]);
15590
15805
  const handleCommentReply = useCallback((id_2, text_6) => {
15591
- if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return;
15806
+ if (applyCanonicalComment({
15807
+ type: "create",
15808
+ text: text_6,
15809
+ author,
15810
+ anchor: {
15811
+ kind: "reply",
15812
+ parentId: id_2
15813
+ }
15814
+ }) !== null) return;
15592
15815
  updateComments((previous_2) => [...previous_2, createComment(text_6, author, id_2)]);
15593
15816
  }, [
15817
+ applyCanonicalComment,
15594
15818
  author,
15595
15819
  createComment,
15596
- refuseCanonicalModelEdit,
15597
15820
  updateComments
15598
15821
  ]);
15599
15822
  const handleAddComment = useCallback((addText) => {
15600
- if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return false;
15823
+ const view_56 = pagedEditorRef.current?.getView();
15824
+ if (!view_56 || !commentSelectionRange) return false;
15825
+ const result_6 = applyCanonicalComment({
15826
+ type: "create",
15827
+ text: addText,
15828
+ author,
15829
+ anchor: {
15830
+ kind: "selection",
15831
+ ...commentSelectionRange,
15832
+ story: "main"
15833
+ }
15834
+ });
15835
+ if (result_6 !== null) {
15836
+ if (result_6?.status !== "applied") return false;
15837
+ setVisibleCommentAuthors((current_0) => {
15838
+ if (current_0 === null) return null;
15839
+ const next_1 = new Set(current_0);
15840
+ const created = result_6.comments.find(({ id: id_3 }) => id_3 === result_6.commentId);
15841
+ if (created) next_1.add(getCommentAuthorKey(created.author));
15842
+ return next_1;
15843
+ });
15844
+ if (result_6.commentId !== void 0) setActiveCommentId(result_6.commentId);
15845
+ setIsAddingComment(false);
15846
+ setCommentSelectionRange(null);
15847
+ setAddCommentYPosition(null);
15848
+ return true;
15849
+ }
15601
15850
  const comment_4 = createComment(addText, author);
15602
- const view_55 = pagedEditorRef.current?.getView();
15603
- if (!view_55 || !commentSelectionRange) return false;
15604
- if (!applyCommentMarkRange(view_55, commentSelectionRange, comment_4.id, { replacePending: true })) return false;
15851
+ if (!applyCommentMarkRange(view_56, commentSelectionRange, comment_4.id, { replacePending: true })) return false;
15605
15852
  const commentAuthor_2 = getCommentAuthorKey(comment_4.author);
15606
- setVisibleCommentAuthors((current_0) => {
15607
- if (current_0 === null) return null;
15608
- const next_1 = new Set(current_0);
15609
- next_1.add(commentAuthor_2);
15610
- return next_1;
15853
+ setVisibleCommentAuthors((current_1) => {
15854
+ if (current_1 === null) return null;
15855
+ const next_2 = new Set(current_1);
15856
+ next_2.add(commentAuthor_2);
15857
+ return next_2;
15611
15858
  });
15612
15859
  setActiveCommentId(comment_4.id);
15613
15860
  updateComments((previous_3) => [...previous_3, comment_4]);
@@ -15622,9 +15869,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15622
15869
  return true;
15623
15870
  }, [
15624
15871
  author,
15872
+ applyCanonicalComment,
15625
15873
  commentSelectionRange,
15626
15874
  createComment,
15627
- refuseCanonicalModelEdit,
15628
15875
  setActiveCommentId,
15629
15876
  setAddCommentYPosition,
15630
15877
  setCommentSelectionRange,
@@ -15634,22 +15881,32 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15634
15881
  updateComments
15635
15882
  ]);
15636
15883
  const handleTrackedChangeReply = useCallback((revisionId_2, text_7) => {
15637
- if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return;
15884
+ if (applyCanonicalComment({
15885
+ type: "create",
15886
+ text: text_7,
15887
+ author,
15888
+ anchor: {
15889
+ kind: "revision",
15890
+ story: "main",
15891
+ revisionId: revisionId_2
15892
+ }
15893
+ }) !== null) return;
15638
15894
  updateComments((previous_4) => [...previous_4, createComment(text_7, author, revisionId_2)]);
15639
15895
  }, [
15896
+ applyCanonicalComment,
15640
15897
  author,
15641
15898
  createComment,
15642
- refuseCanonicalModelEdit,
15643
15899
  updateComments
15644
15900
  ]);
15645
15901
  const handleCancelAddComment = useCallback(() => {
15646
- const view_56 = pagedEditorRef.current?.getView();
15647
- if (view_56 && commentSelectionRange) removePendingCommentMarkRange(view_56, commentSelectionRange);
15902
+ const view_57 = pagedEditorRef.current?.getView();
15903
+ if (view_57 && commentSelectionRange && commentDraftMode === "prosemirror") removePendingCommentMarkRange(view_57, commentSelectionRange);
15648
15904
  setIsAddingComment(false);
15649
15905
  setCommentSelectionRange(null);
15650
15906
  setAddCommentYPosition(null);
15651
15907
  }, [
15652
15908
  commentSelectionRange,
15909
+ commentDraftMode,
15653
15910
  setAddCommentYPosition,
15654
15911
  setCommentSelectionRange,
15655
15912
  setIsAddingComment
@@ -15660,23 +15917,23 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15660
15917
  })?.revisionId ?? null;
15661
15918
  }, []);
15662
15919
  const handleSidebarAcceptChange = useCallback((from_17, to_17) => {
15663
- const view_57 = pagedEditorRef.current?.getView();
15664
- if (!view_57) return;
15920
+ const view_58 = pagedEditorRef.current?.getView();
15921
+ if (!view_58) return;
15665
15922
  const revisionId_3 = resolveSidebarChangeRevisionId(from_17, to_17);
15666
15923
  if (revisionId_3 === null) return;
15667
15924
  const editor_6 = pagedEditorRef.current?.getEditor();
15668
15925
  if (editor_6?.getCanonicalDocument()) editor_6.resolveCanonicalRevisions([revisionId_3], "accept");
15669
- else acceptAIEditRevision(revisionId_3)(view_57.state, view_57.dispatch);
15926
+ else acceptAIEditRevision(revisionId_3)(view_58.state, view_58.dispatch);
15670
15927
  extractTrackedChanges();
15671
15928
  }, [extractTrackedChanges, resolveSidebarChangeRevisionId]);
15672
15929
  const handleSidebarRejectChange = useCallback((from_18, to_18) => {
15673
- const view_58 = pagedEditorRef.current?.getView();
15674
- if (!view_58) return;
15930
+ const view_59 = pagedEditorRef.current?.getView();
15931
+ if (!view_59) return;
15675
15932
  const revisionId_4 = resolveSidebarChangeRevisionId(from_18, to_18);
15676
15933
  if (revisionId_4 === null) return;
15677
15934
  const editor_7 = pagedEditorRef.current?.getEditor();
15678
15935
  if (editor_7?.getCanonicalDocument()) editor_7.resolveCanonicalRevisions([revisionId_4], "reject");
15679
- else rejectAIEditRevision(revisionId_4)(view_58.state, view_58.dispatch);
15936
+ else rejectAIEditRevision(revisionId_4)(view_59.state, view_59.dispatch);
15680
15937
  extractTrackedChanges();
15681
15938
  }, [extractTrackedChanges, resolveSidebarChangeRevisionId]);
15682
15939
  const commentsPageWidth = history.state?.package.document.finalSectionProperties?.pageWidth;
@@ -15724,7 +15981,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15724
15981
  ]);
15725
15982
  const openCommentThreadCount = useMemo(() => countOpenCommentThreads(comments), [comments]);
15726
15983
  const outlineToggle = (() => {
15727
- if (panels.layout.outline !== "drawer") return "absent";
15984
+ if (panels.layout.outline !== "drawer" && panels.layout.outline !== "expanded") return "absent";
15728
15985
  return panelOverlay === "outline" ? "open" : "closed";
15729
15986
  })();
15730
15987
  const panelToggles = useMemo(() => /* @__PURE__ */ jsx(PanelToggles, {
@@ -15804,9 +16061,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15804
16061
  };
15805
16062
  requestAnimationFrame(flash);
15806
16063
  }, []);
15807
- const handleOutlineJump = useCallback((id_3) => {
15808
- markHeadingJumped(id_3);
15809
- handleOutlineHeadingClick(Number(id_3));
16064
+ const handleOutlineJump = useCallback((id_4) => {
16065
+ markHeadingJumped(id_4);
16066
+ handleOutlineHeadingClick(Number(id_4));
15810
16067
  }, [handleOutlineHeadingClick, markHeadingJumped]);
15811
16068
  const handleTextContextAction = useCallback((action_3) => {
15812
16069
  handleContextMenuAction(action_3);
@@ -15819,8 +16076,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15819
16076
  }, [readOnly]);
15820
16077
  const closeTableProperties = useCallback(() => setTablePropsOpen(false), []);
15821
16078
  const applyTableProperties = useCallback((props_0) => {
15822
- const view_59 = getActiveEditorView();
15823
- if (view_59) setTableProperties(props_0)(view_59.state, view_59.dispatch);
16079
+ const view_60 = getActiveEditorView();
16080
+ if (view_60) setTableProperties(props_0)(view_60.state, view_60.dispatch);
15824
16081
  }, [getActiveEditorView]);
15825
16082
  const closeImagePosition = useCallback(() => setImagePositionOpen(false), [setImagePositionOpen]);
15826
16083
  const closeImageProperties = useCallback(() => setImagePropsOpen(false), [setImagePropsOpen]);
@@ -15828,8 +16085,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15828
16085
  const closeFootnoteProperties = useCallback(() => setFootnotePropsOpen(false), []);
15829
16086
  const closeInsertSymbol = useCallback(() => setShowInsertSymbol(false), []);
15830
16087
  const insertSymbol = useCallback((symbol) => {
15831
- const view_60 = getActiveEditorView();
15832
- if (view_60) view_60.dispatch(view_60.state.tr.insertText(symbol).scrollIntoView());
16088
+ const view_61 = getActiveEditorView();
16089
+ if (view_61) view_61.dispatch(view_61.state.tr.insertText(symbol).scrollIntoView());
15833
16090
  }, [getActiveEditorView]);
15834
16091
  const imagePropertiesCurrentData = useMemo(() => buildImagePropertiesData(state.pmImageContext), [state.pmImageContext]);
15835
16092
  const currentFindResult = findResultRef.current;
@@ -15912,8 +16169,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15912
16169
  ]);
15913
16170
  const closeNumberingValueDialog = useCallback(() => setNumberingValueDialogOpen(false), []);
15914
16171
  const applyNumberingValue = useCallback((value_0) => {
15915
- const view_61 = getActiveEditorView();
15916
- if (view_61) setNumberingValue(value_0)(view_61.state, view_61.dispatch);
16172
+ const view_62 = getActiveEditorView();
16173
+ if (view_62) setNumberingValue(value_0)(view_62.state, view_62.dispatch);
15917
16174
  }, [getActiveEditorView]);
15918
16175
  const numberingValueDialog = useMemo(() => ({
15919
16176
  isOpen: numberingValueDialogOpen,
@@ -16060,15 +16317,20 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
16060
16317
  "data-folio-outline": panels.layout.outline,
16061
16318
  "data-folio-comments": panels.layout.comments,
16062
16319
  children: [
16063
- (panels.layout.outline === "column" || panels.layout.outline === "rail") && /* @__PURE__ */ jsx(DocumentOutline, {
16064
- headings: outlineHeadings,
16320
+ panels.layout.outline !== "none" && panels.layout.outline !== "drawer" && /* @__PURE__ */ jsx(DocumentOutline, {
16321
+ headings: visibleOutlineHeadings,
16322
+ available: outlineHeadings.length > 1,
16323
+ outlineDepth,
16324
+ onOutlineDepthChange: handleOutlineDepthChange,
16065
16325
  scrollContainerRef,
16066
16326
  docSize: pagedEditorRef.current?.getView()?.state.doc.content.size ?? 0,
16067
16327
  activeId: activeHeadingId,
16068
16328
  onJump: handleOutlineJump,
16069
16329
  surface: panels.layout.outline,
16330
+ width: panels.layout.outlineTrackWidth,
16070
16331
  expanded: panelOverlay === "outline",
16071
- onExpand: toggleOutlineOverlay
16332
+ onExpand: toggleOutlineOverlay,
16333
+ ...panels.layout.outline === "expanded" ? { onClose: closePanelOverlay } : {}
16072
16334
  }),
16073
16335
  /* @__PURE__ */ jsxs("div", {
16074
16336
  ref: scrollContainerRef,
@@ -16212,8 +16474,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
16212
16474
  onMouseDown: (e_1) => {
16213
16475
  e_1.preventDefault();
16214
16476
  e_1.stopPropagation();
16215
- const view_62 = pagedEditorRef.current?.getView();
16216
- if (!view_62) {
16477
+ const view_63 = pagedEditorRef.current?.getView();
16478
+ if (!view_63) {
16217
16479
  setFloatingCommentBtn(null);
16218
16480
  return;
16219
16481
  }
@@ -16221,9 +16483,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
16221
16483
  from: floatingCommentBtn.from,
16222
16484
  to: floatingCommentBtn.to
16223
16485
  };
16224
- const currentSelection = view_62.state.selection;
16486
+ const currentSelection = view_63.state.selection;
16225
16487
  const safeRange = resolveCommentCreationRange({
16226
- docSize: view_62.state.doc.content.size,
16488
+ docSize: view_63.state.doc.content.size,
16227
16489
  capturedRange,
16228
16490
  currentRange: {
16229
16491
  from: currentSelection.from,
@@ -16237,10 +16499,12 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
16237
16499
  return;
16238
16500
  }
16239
16501
  setCommentSelectionRange(safeRange);
16240
- if (!applyCommentMarkRange(view_62, safeRange, -1, { selectEnd: true })) {
16241
- setCommentSelectionRange(null);
16242
- setFloatingCommentBtn(null);
16243
- return;
16502
+ if (commentDraftMode === "prosemirror") {
16503
+ if (!applyCommentMarkRange(view_63, safeRange, -1, { selectEnd: true })) {
16504
+ setCommentSelectionRange(null);
16505
+ setFloatingCommentBtn(null);
16506
+ return;
16507
+ }
16244
16508
  }
16245
16509
  const yPos_0 = findSelectionYPosition(scrollContainerRef.current, editorContentRef.current, safeRange.from);
16246
16510
  setAddCommentYPosition(yPos_0 ?? floatingCommentBtn.top);
@@ -16310,15 +16574,6 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
16310
16574
  })
16311
16575
  })]
16312
16576
  }),
16313
- panelOverlay === "outline" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(PanelScrim, { onDismiss: closePanelOverlay }), /* @__PURE__ */ jsx(DocumentOutline, {
16314
- headings: outlineHeadings,
16315
- scrollContainerRef,
16316
- docSize: pagedEditorRef.current?.getView()?.state.doc.content.size ?? 0,
16317
- activeId: activeHeadingId,
16318
- onJump: handleOutlineJump,
16319
- surface: "drawer",
16320
- onClose: closePanelOverlay
16321
- })] }),
16322
16577
  commentsSurface === "drawer" && /* @__PURE__ */ jsx(PanelScrim, { onDismiss: dismissCommentsDrawer })
16323
16578
  ]
16324
16579
  }),