@stll/folio-react 0.10.2 → 0.11.0

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.
@@ -7,6 +7,7 @@ import { AlertCircleIcon, AlertTriangleIcon, AlignCenterIcon, AlignJustifyIcon,
7
7
  import { closeHistory, redo, undo } from "prosemirror-history";
8
8
  import { IntlProvider, useTranslations } from "use-intl";
9
9
  import { FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, createFolioAIEditSnapshot, getCommentAnchorsFromDoc, getFolioDocumentOperationIssues, getTrackedChangesFromDoc } from "@stll/folio-core/ai-edits";
10
+ import { resolveActiveEditorStory } from "@stll/folio-core/controller/activeEditorStory";
10
11
  import { normalizeBaseDirection } from "@stll/folio-core/docx/normalizeBaseDirection";
11
12
  import { getCachedNumberingMap } from "@stll/folio-core/docx/numberingParser";
12
13
  import { computeScrollPageInfo, updateScrollPageTotal } from "@stll/folio-core/paged-layout/scrollPageInfo";
@@ -24,7 +25,7 @@ import { createAICitationDecorationsPlugin } from "@stll/folio-core/prosemirror/
24
25
  import { AI_SUGGESTION_SEVERITY_CLASS, aiSuggestionDecorationsKey, createAISuggestionDecorationsPlugin } from "@stll/folio-core/prosemirror/plugins/aiSuggestionDecorations";
25
26
  import { anonymizationDecorationsKey, createAnonymizationDecorationsPlugin, slugAnonymizationLabel } from "@stll/folio-core/prosemirror/plugins/anonymizationDecorations";
26
27
  import { autocompleteSuggestionKey, autocompleteSuggestionPlugin } from "@stll/folio-core/prosemirror/plugins/autocompleteSuggestion";
27
- import { createSuggestionModePlugin, setSuggestionMode } from "@stll/folio-core/prosemirror/plugins/suggestionMode";
28
+ import { createSuggestionModePlugin, setSuggestionMode, suggestionModeKey } from "@stll/folio-core/prosemirror/plugins/suggestionMode";
28
29
  import { createTemplateDirectivesPlugin, templateDirectivesKey } from "@stll/folio-core/prosemirror/plugins/templateDirectives";
29
30
  import { createTemplatePreviewValuesPlugin, templatePreviewValuesKey } from "@stll/folio-core/prosemirror/plugins/templatePreviewValues";
30
31
  import { getTemplateSlashMenu, templateSlashMenuPlugin } from "@stll/folio-core/prosemirror/plugins/templateSlashMenu";
@@ -40,6 +41,7 @@ import { NodeSelection, Selection, TextSelection as TextSelection$1 } from "pros
40
41
  import { CellSelection } from "prosemirror-tables";
41
42
  import { createHeaderFooterEditorManager } from "@stll/folio-core/controller/headerFooterEditorManager";
42
43
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
44
+ import { createNoteEditorManager } from "@stll/folio-core/controller/noteEditorManager";
43
45
  import { createFolioEditor } from "@stll/folio-core/controller/folioEditor";
44
46
  import { createFolioEditorEmitter } from "@stll/folio-core/controller/folioEditorEvents";
45
47
  import { createLatestRequestGate } from "@stll/folio-core/controller/latestRequestGate";
@@ -53,6 +55,7 @@ import { templatePreviewDirtyRange } from "@stll/folio-core/layout-bridge/conver
53
55
  import { clickToPositionDom } from "@stll/folio-core/layout-bridge/dom/clickToPositionDom";
54
56
  import { findBodyEmptyRuns, findBodyPmAnchor, findBodyPmAnchors, findBodyPmSpans } from "@stll/folio-core/layout-bridge/dom/findBodyPmSpans";
55
57
  import { clickToPositionInHfSlot, findHfCaretSpan, findHfPmSpans, findHfSlotForTarget, findHfSlotKindForTarget } from "@stll/folio-core/layout-bridge/dom/findHfPmSpans";
58
+ import { findNoteStoryForTarget } from "@stll/folio-core/layout-bridge/dom/noteStoryDom";
56
59
  import { clickToPosition } from "@stll/folio-core/layout-bridge/engine/clickToPosition";
57
60
  import { getPageTop, hitTestFragment, hitTestTableCell } from "@stll/folio-core/layout-bridge/engine/hitTest";
58
61
  import { clearAllCaches, resetCanvasContext } from "@stll/folio-core/layout-bridge/engine/measuring";
@@ -76,9 +79,10 @@ import { extractEmbeddedFonts } from "@stll/folio-core/fonts/embeddedFonts";
76
79
  import { panic } from "better-result";
77
80
  import { collectRemoteSelections, createHiddenEditorManager, createHiddenEditorState } from "@stll/folio-core/controller/hiddenEditorManager";
78
81
  import { loadCollaborationModules } from "@stll/folio-core/controller/collaborationModules";
79
- import { clampRangeToDocSize, resolveFolioAIBlockRange, resolveFolioAITextRange } from "@stll/folio-core/ai-edits/blockRange";
82
+ import { clampRangeToDocSize, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange } from "@stll/folio-core/ai-edits/blockRange";
83
+ import { getFolioParaIdFromBlockId } from "@stll/folio-core/types/block-id";
80
84
  import { getPageTextFromLayout } from "@stll/folio-core/paged-layout/pageText";
81
- import { CONTENT_CONTROL_WIDGET_EVENT_NAME, dispatchDatePick, dispatchDropdownPick } from "@stll/folio-core/prosemirror/plugins/contentControlWidgets";
85
+ import { ContentControlWidgetController } from "@stll/folio-core/controller/contentControlWidgetController";
82
86
  import { createDefaultFindOptions, findInDocument } from "@stll/folio-core/utils/findReplace";
83
87
  import { ErrorManager } from "@stll/folio-core/managers/ErrorManager";
84
88
  import { ContextMenuManager } from "@stll/folio-core/managers/ContextMenuManager";
@@ -194,7 +198,7 @@ function useDocumentHistory(document, t0) {
194
198
  $[1] = t1;
195
199
  } else t1 = $[1];
196
200
  const options = t1;
197
- const isEqual = _temp$10;
201
+ const isEqual = _temp$11;
198
202
  let t2;
199
203
  if ($[2] !== options) {
200
204
  t2 = {
@@ -206,7 +210,7 @@ function useDocumentHistory(document, t0) {
206
210
  } else t2 = $[3];
207
211
  return useHistory(document, t2);
208
212
  }
209
- function _temp$10(a, b) {
213
+ function _temp$11(a, b) {
210
214
  if (a === b) return true;
211
215
  const aPackage = a?.package;
212
216
  const bPackage = b?.package;
@@ -361,6 +365,292 @@ const HiddenHeaderFooterPMs = memo(forwardRef(function HiddenHeaderFooterPMs({ d
361
365
  }));
362
366
  HiddenHeaderFooterPMs.displayName = "HiddenHeaderFooterPMs";
363
367
  //#endregion
368
+ //#region src/components/NoteStoryEditor.tsx
369
+ /** Thin React surface over core's persistent note-story editor manager. */
370
+ const panelStyle = {
371
+ position: "absolute",
372
+ right: 24,
373
+ bottom: 24,
374
+ width: "min(560px, calc(100% - 48px))",
375
+ maxHeight: "45%",
376
+ overflow: "auto",
377
+ zIndex: 30,
378
+ background: "var(--doc-canvas, #fff)",
379
+ color: "var(--doc-canvas-text, #000)",
380
+ border: "1px solid var(--doc-border, rgba(0, 0, 0, 0.18))",
381
+ borderRadius: 6,
382
+ boxShadow: "0 8px 28px rgba(0, 0, 0, 0.18)"
383
+ };
384
+ const headerStyle = {
385
+ position: "sticky",
386
+ top: 0,
387
+ zIndex: 1,
388
+ display: "flex",
389
+ alignItems: "center",
390
+ justifyContent: "space-between",
391
+ padding: "8px 12px",
392
+ background: "var(--doc-canvas, #fff)",
393
+ borderBottom: "1px solid var(--doc-border, rgba(0, 0, 0, 0.12))",
394
+ fontSize: 12,
395
+ fontWeight: 600
396
+ };
397
+ const hostStyle = {
398
+ padding: "12px 16px",
399
+ minHeight: 72
400
+ };
401
+ const EMPTY_PLUGINS$1 = [];
402
+ const NoteStoryEditor = forwardRef(function NoteStoryEditor(t0, ref) {
403
+ const $ = c(51);
404
+ const { document, onActiveChange, onDocumentChange, onStoryChange, plugins, styles, suggestionAuthor, suggestionModeActive, theme } = t0;
405
+ const t = useTranslations("folio");
406
+ const resolvedPlugins = plugins ?? EMPTY_PLUGINS$1;
407
+ const isSuggestionModeActive = suggestionModeActive ?? false;
408
+ const hostRef = useRef(null);
409
+ const documentRef = useRef(document);
410
+ const stylesRef = useRef(styles);
411
+ const themeRef = useRef(theme);
412
+ const pluginsRef = useRef(resolvedPlugins);
413
+ const onDocumentChangeRef = useRef(onDocumentChange);
414
+ const onActiveChangeRef = useRef(onActiveChange);
415
+ const onStoryChangeRef = useRef(onStoryChange);
416
+ const [active, setActive] = useState(null);
417
+ const managerRef = useRef(null);
418
+ const footnotes = document?.package.footnotes;
419
+ const endnotes = document?.package.endnotes;
420
+ let t1;
421
+ if ($[0] !== active || $[1] !== document || $[2] !== onActiveChange || $[3] !== onDocumentChange || $[4] !== onStoryChange || $[5] !== resolvedPlugins || $[6] !== styles || $[7] !== theme) {
422
+ t1 = () => {
423
+ documentRef.current = document;
424
+ stylesRef.current = styles;
425
+ themeRef.current = theme;
426
+ pluginsRef.current = resolvedPlugins;
427
+ onDocumentChangeRef.current = onDocumentChange;
428
+ onActiveChangeRef.current = onActiveChange;
429
+ onStoryChangeRef.current = onStoryChange;
430
+ if (managerRef.current === null) managerRef.current = createNoteEditorManager({
431
+ getDocument: () => documentRef.current,
432
+ getHost: () => hostRef.current,
433
+ getPlugins: () => pluginsRef.current,
434
+ getStyles: () => stylesRef.current,
435
+ getTheme: () => themeRef.current,
436
+ onTransaction: (t2) => {
437
+ const { docChanged, selectionChanged, view } = t2;
438
+ if (docChanged) {
439
+ const current = documentRef.current;
440
+ if (current) onDocumentChangeRef.current(managerRef.current?.snapshotDocument(current) ?? current);
441
+ }
442
+ onStoryChangeRef.current(view, docChanged, selectionChanged);
443
+ }
444
+ });
445
+ const manager = managerRef.current;
446
+ manager.sync();
447
+ if (active && !manager?.getActive()) {
448
+ setActive(null);
449
+ onActiveChangeRef.current(null);
450
+ }
451
+ };
452
+ $[0] = active;
453
+ $[1] = document;
454
+ $[2] = onActiveChange;
455
+ $[3] = onDocumentChange;
456
+ $[4] = onStoryChange;
457
+ $[5] = resolvedPlugins;
458
+ $[6] = styles;
459
+ $[7] = theme;
460
+ $[8] = t1;
461
+ } else t1 = $[8];
462
+ let t2;
463
+ if ($[9] !== active || $[10] !== document || $[11] !== endnotes || $[12] !== footnotes || $[13] !== onActiveChange || $[14] !== onDocumentChange || $[15] !== onStoryChange || $[16] !== resolvedPlugins || $[17] !== styles || $[18] !== theme) {
464
+ t2 = [
465
+ active,
466
+ document,
467
+ endnotes,
468
+ footnotes,
469
+ onActiveChange,
470
+ onDocumentChange,
471
+ onStoryChange,
472
+ resolvedPlugins,
473
+ styles,
474
+ theme
475
+ ];
476
+ $[9] = active;
477
+ $[10] = document;
478
+ $[11] = endnotes;
479
+ $[12] = footnotes;
480
+ $[13] = onActiveChange;
481
+ $[14] = onDocumentChange;
482
+ $[15] = onStoryChange;
483
+ $[16] = resolvedPlugins;
484
+ $[17] = styles;
485
+ $[18] = theme;
486
+ $[19] = t2;
487
+ } else t2 = $[19];
488
+ useEffect(t1, t2);
489
+ let t3;
490
+ let t4;
491
+ if ($[20] !== isSuggestionModeActive || $[21] !== suggestionAuthor) {
492
+ t3 = () => {
493
+ const manager_0 = managerRef.current;
494
+ if (!manager_0) return;
495
+ for (const story of manager_0.listStories()) {
496
+ const view_0 = manager_0.getView(story);
497
+ if (view_0) setSuggestionMode(isSuggestionModeActive, view_0.state, view_0.dispatch, suggestionAuthor);
498
+ }
499
+ };
500
+ t4 = [isSuggestionModeActive, suggestionAuthor];
501
+ $[20] = isSuggestionModeActive;
502
+ $[21] = suggestionAuthor;
503
+ $[22] = t3;
504
+ $[23] = t4;
505
+ } else {
506
+ t3 = $[22];
507
+ t4 = $[23];
508
+ }
509
+ useEffect(t3, t4);
510
+ let t5;
511
+ let t6;
512
+ if ($[24] === Symbol.for("react.memo_cache_sentinel")) {
513
+ t5 = () => () => {
514
+ managerRef.current?.destroy();
515
+ };
516
+ t6 = [];
517
+ $[24] = t5;
518
+ $[25] = t6;
519
+ } else {
520
+ t5 = $[24];
521
+ t6 = $[25];
522
+ }
523
+ useEffect(t5, t6);
524
+ let t7;
525
+ if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
526
+ t7 = () => {
527
+ managerRef.current?.activate(null);
528
+ setActive(null);
529
+ onActiveChangeRef.current(null);
530
+ };
531
+ $[26] = t7;
532
+ } else t7 = $[26];
533
+ const closeEditor = t7;
534
+ let t8;
535
+ if ($[27] !== isSuggestionModeActive || $[28] !== suggestionAuthor) {
536
+ t8 = () => ({
537
+ close: closeEditor,
538
+ getActiveView: () => {
539
+ const story_0 = managerRef.current?.getActive();
540
+ return story_0 ? managerRef.current?.getView(story_0) ?? null : null;
541
+ },
542
+ open: (story_1) => {
543
+ const view_1 = managerRef.current?.activate(story_1);
544
+ if (!view_1) return;
545
+ setSuggestionMode(isSuggestionModeActive, view_1.state, view_1.dispatch, suggestionAuthor);
546
+ setActive(story_1);
547
+ onActiveChangeRef.current(story_1);
548
+ requestAnimationFrame(() => view_1.focus());
549
+ },
550
+ snapshotDocument: (current_0) => managerRef.current?.snapshotDocument(current_0) ?? current_0
551
+ });
552
+ $[27] = isSuggestionModeActive;
553
+ $[28] = suggestionAuthor;
554
+ $[29] = t8;
555
+ } else t8 = $[29];
556
+ useImperativeHandle(ref, t8);
557
+ let t9;
558
+ if ($[30] !== active || $[31] !== t) {
559
+ t9 = active ? t(active.kind === "footnote" ? "dialogs.footnoteProperties.footnotes" : "dialogs.footnoteProperties.endnotes") : "";
560
+ $[30] = active;
561
+ $[31] = t;
562
+ $[32] = t9;
563
+ } else t9 = $[32];
564
+ const title = t9;
565
+ const t10 = active ? "block" : "none";
566
+ let t11;
567
+ if ($[33] !== t10) {
568
+ t11 = {
569
+ ...panelStyle,
570
+ display: t10
571
+ };
572
+ $[33] = t10;
573
+ $[34] = t11;
574
+ } else t11 = $[34];
575
+ let t12;
576
+ if ($[35] === Symbol.for("react.memo_cache_sentinel")) {
577
+ t12 = (event) => {
578
+ if (event.key !== "Escape") return;
579
+ event.preventDefault();
580
+ event.stopPropagation();
581
+ closeEditor();
582
+ };
583
+ $[35] = t12;
584
+ } else t12 = $[35];
585
+ let t13;
586
+ if ($[36] !== title) {
587
+ t13 = /* @__PURE__ */ jsx("span", { children: title });
588
+ $[36] = title;
589
+ $[37] = t13;
590
+ } else t13 = $[37];
591
+ let t14;
592
+ if ($[38] !== t) {
593
+ t14 = t("common.closeDialog");
594
+ $[38] = t;
595
+ $[39] = t14;
596
+ } else t14 = $[39];
597
+ let t15;
598
+ if ($[40] === Symbol.for("react.memo_cache_sentinel")) {
599
+ t15 = {
600
+ border: 0,
601
+ background: "transparent",
602
+ color: "inherit",
603
+ cursor: "pointer"
604
+ };
605
+ $[40] = t15;
606
+ } else t15 = $[40];
607
+ let t16;
608
+ if ($[41] !== t14) {
609
+ t16 = /* @__PURE__ */ jsx("button", {
610
+ type: "button",
611
+ "aria-label": t14,
612
+ onClick: closeEditor,
613
+ style: t15,
614
+ children: "×"
615
+ });
616
+ $[41] = t14;
617
+ $[42] = t16;
618
+ } else t16 = $[42];
619
+ let t17;
620
+ if ($[43] !== t13 || $[44] !== t16) {
621
+ t17 = /* @__PURE__ */ jsxs("div", {
622
+ style: headerStyle,
623
+ children: [t13, t16]
624
+ });
625
+ $[43] = t13;
626
+ $[44] = t16;
627
+ $[45] = t17;
628
+ } else t17 = $[45];
629
+ let t18;
630
+ if ($[46] === Symbol.for("react.memo_cache_sentinel")) {
631
+ t18 = /* @__PURE__ */ jsx("div", {
632
+ ref: hostRef,
633
+ style: hostStyle
634
+ });
635
+ $[46] = t18;
636
+ } else t18 = $[46];
637
+ let t19;
638
+ if ($[47] !== t11 || $[48] !== t17 || $[49] !== title) {
639
+ t19 = /* @__PURE__ */ jsxs("aside", {
640
+ style: t11,
641
+ "aria-label": title,
642
+ onKeyDown: t12,
643
+ children: [t17, t18]
644
+ });
645
+ $[47] = t11;
646
+ $[48] = t17;
647
+ $[49] = title;
648
+ $[50] = t19;
649
+ } else t19 = $[50];
650
+ return t19;
651
+ });
652
+ NoteStoryEditor.displayName = "NoteStoryEditor";
653
+ //#endregion
364
654
  //#region src/utils/contained-handler.ts
365
655
  /**
366
656
  * Wrap a React event handler so it only fires when the event target
@@ -403,7 +693,7 @@ const containedHandler = (handler) => (event) => {
403
693
  };
404
694
  //#endregion
405
695
  //#region src/paged-editor/AISuggestionRectsOverlay.tsx
406
- const overlayStyles$5 = {
696
+ const overlayStyles$6 = {
407
697
  position: "absolute",
408
698
  top: 0,
409
699
  left: "50%",
@@ -425,14 +715,14 @@ const AISuggestionRectsOverlay = (t0) => {
425
715
  if (groups.length === 0) return null;
426
716
  let t1;
427
717
  if ($[0] !== groups) {
428
- t1 = groups.map(_temp$9);
718
+ t1 = groups.map(_temp$10);
429
719
  $[0] = groups;
430
720
  $[1] = t1;
431
721
  } else t1 = $[1];
432
722
  let t2;
433
723
  if ($[2] !== t1) {
434
724
  t2 = /* @__PURE__ */ jsx("div", {
435
- style: overlayStyles$5,
725
+ style: overlayStyles$6,
436
726
  "data-folio-ai-suggestions-overlay": "",
437
727
  children: t1
438
728
  });
@@ -441,7 +731,7 @@ const AISuggestionRectsOverlay = (t0) => {
441
731
  } else t2 = $[3];
442
732
  return t2;
443
733
  };
444
- function _temp$9(t0) {
734
+ function _temp$10(t0) {
445
735
  const { suggestion, rects, focused, font } = t0;
446
736
  const replacementAnchor = rects.at(-1);
447
737
  const showReplacement = focused && suggestion.suggestedText.length > 0 && replacementAnchor !== void 0;
@@ -502,7 +792,7 @@ function _temp$9(t0) {
502
792
  * `selectionSeq` changes — repeated clicks of the same
503
793
  * canonical in the sidebar re-trigger the scroll).
504
794
  */
505
- const overlayStyles$4 = {
795
+ const overlayStyles$5 = {
506
796
  position: "absolute",
507
797
  top: 0,
508
798
  left: "50%",
@@ -562,7 +852,7 @@ const AnonymizationRectsOverlay = ({ groups, onTermClick, selectedCanonical = nu
562
852
  if (groups.length === 0) return null;
563
853
  return /* @__PURE__ */ jsx("div", {
564
854
  ref: overlayRef,
565
- style: overlayStyles$4,
855
+ style: overlayStyles$5,
566
856
  "data-folio-anonymization-overlay": "",
567
857
  children: groups.flatMap((group) => {
568
858
  const isSelected = selectedCanonical === group.canonical;
@@ -592,7 +882,7 @@ const AnonymizationRectsOverlay = ({ groups, onTermClick, selectedCanonical = nu
592
882
  };
593
883
  //#endregion
594
884
  //#region src/paged-editor/AutocompleteCaretOverlay.tsx
595
- const overlayStyles$3 = {
885
+ const overlayStyles$4 = {
596
886
  position: "absolute",
597
887
  top: 0,
598
888
  left: "50%",
@@ -643,7 +933,7 @@ const AutocompleteCaretOverlay = (t0) => {
643
933
  let t6;
644
934
  if ($[9] !== t3 || $[10] !== t5 || $[11] !== text) {
645
935
  t6 = /* @__PURE__ */ jsx("div", {
646
- style: overlayStyles$3,
936
+ style: overlayStyles$4,
647
937
  "data-folio-autocomplete-overlay": "",
648
938
  children: /* @__PURE__ */ jsxs("span", {
649
939
  className: "folio-autocomplete-ghost",
@@ -659,6 +949,52 @@ const AutocompleteCaretOverlay = (t0) => {
659
949
  return t6;
660
950
  };
661
951
  //#endregion
952
+ //#region src/paged-editor/PassageHighlightOverlay.tsx
953
+ const overlayStyles$3 = {
954
+ position: "absolute",
955
+ top: 0,
956
+ left: "50%",
957
+ width: "100vw",
958
+ height: "100%",
959
+ transform: "translateX(-50%)",
960
+ pointerEvents: "none",
961
+ zIndex: 1
962
+ };
963
+ const PassageHighlightOverlay = (t0) => {
964
+ const $ = c(4);
965
+ const { rects } = t0;
966
+ if (rects.length === 0) return null;
967
+ let t1;
968
+ if ($[0] !== rects) {
969
+ t1 = rects.map(_temp$9);
970
+ $[0] = rects;
971
+ $[1] = t1;
972
+ } else t1 = $[1];
973
+ let t2;
974
+ if ($[2] !== t1) {
975
+ t2 = /* @__PURE__ */ jsx("div", {
976
+ style: overlayStyles$3,
977
+ "data-folio-passage-highlight-overlay": "",
978
+ children: t1
979
+ });
980
+ $[2] = t1;
981
+ $[3] = t2;
982
+ } else t2 = $[3];
983
+ return t2;
984
+ };
985
+ function _temp$9(rect, idx) {
986
+ return /* @__PURE__ */ jsx("span", {
987
+ className: "folio-passage-highlight",
988
+ style: {
989
+ position: "absolute",
990
+ left: rect.x,
991
+ top: rect.y,
992
+ width: rect.width,
993
+ height: rect.height
994
+ }
995
+ }, `${idx}:${rect.pageIndex}:${rect.x}:${rect.y}`);
996
+ }
997
+ //#endregion
662
998
  //#region src/paged-editor/embeddedFonts.ts
663
999
  /**
664
1000
  * Registers a document's embedded fonts with the browser via the `FontFace`
@@ -764,6 +1100,7 @@ function toFontFaceInputs(fonts) {
764
1100
  if (!isValidFontDefinition(font)) continue;
765
1101
  const descriptors = { display: "swap" };
766
1102
  if (typeof font.weight === "number" || typeof font.weight === "string") descriptors.weight = String(font.weight);
1103
+ if (isNonEmptyString$1(font.style)) descriptors.style = font.style.trim();
767
1104
  inputs.push({
768
1105
  family: font.family.trim(),
769
1106
  source: `url(${JSON.stringify(font.src.trim())})`,
@@ -843,7 +1180,7 @@ const HIDDEN_HOST_STYLES = {
843
1180
  * HiddenProseMirror - Off-screen ProseMirror editor for keyboard input
844
1181
  */
845
1182
  const HiddenProseMirror = forwardRef((props, ref) => {
846
- const { document, documentKey, styles, theme: _theme, widthPx = 612, readOnly = false, onTransaction, onSelectionChange, externalPlugins = EMPTY_EXTERNAL_PLUGINS, collaboration, extensionManager, onEditorViewReady, onEditorViewDestroy, onKeyDown, onReadOnlyEditAttempt, onRemoteSelectionsChange, precomputedInitialState } = props;
1183
+ const { document, documentKey, styles, theme: _theme, widthPx = 612, readOnly = false, onTransaction, onSelectionChange, externalPlugins = EMPTY_EXTERNAL_PLUGINS, collaboration, extensionManager, onEditorViewReady, onEditorViewDestroy, onKeyDown, onCopy, onCut, onPaste, onReadOnlyEditAttempt, onRemoteSelectionsChange, precomputedInitialState } = props;
847
1184
  const [collaborationModules, setCollaborationModules] = useState(null);
848
1185
  const [collaborationModulesError, setCollaborationModulesError] = useState(null);
849
1186
  const hasCollaboration = collaboration !== void 0;
@@ -862,6 +1199,9 @@ const HiddenProseMirror = forwardRef((props, ref) => {
862
1199
  const onEditorViewReadyRef = useRef(onEditorViewReady);
863
1200
  const onEditorViewDestroyRef = useRef(onEditorViewDestroy);
864
1201
  const onKeyDownRef = useRef(onKeyDown);
1202
+ const onCopyRef = useRef(onCopy);
1203
+ const onCutRef = useRef(onCut);
1204
+ const onPasteRef = useRef(onPaste);
865
1205
  const onReadOnlyEditAttemptRef = useRef(onReadOnlyEditAttempt);
866
1206
  const onRemoteSelectionsChangeRef = useRef(onRemoteSelectionsChange);
867
1207
  readOnlyRef.current = readOnly;
@@ -874,6 +1214,9 @@ const HiddenProseMirror = forwardRef((props, ref) => {
874
1214
  onEditorViewReadyRef.current = onEditorViewReady;
875
1215
  onEditorViewDestroyRef.current = onEditorViewDestroy;
876
1216
  onKeyDownRef.current = onKeyDown;
1217
+ onCopyRef.current = onCopy;
1218
+ onCutRef.current = onCut;
1219
+ onPasteRef.current = onPaste;
877
1220
  onReadOnlyEditAttemptRef.current = onReadOnlyEditAttempt;
878
1221
  onRemoteSelectionsChangeRef.current = onRemoteSelectionsChange;
879
1222
  collaborationRef.current = collaboration;
@@ -896,6 +1239,9 @@ const HiddenProseMirror = forwardRef((props, ref) => {
896
1239
  onTransaction: (transaction, newState) => onTransactionRef.current?.(transaction, newState),
897
1240
  onSelectionChange: (state) => onSelectionChangeRef.current?.(state),
898
1241
  onKeyDown: (view, event) => onKeyDownRef.current?.(view, event) ?? false,
1242
+ onCopy: () => onCopyRef.current?.(),
1243
+ onCut: () => onCutRef.current?.(),
1244
+ onPaste: () => onPasteRef.current?.(),
899
1245
  onReadOnlyEditAttempt: () => onReadOnlyEditAttemptRef.current?.(),
900
1246
  onEditorViewReady: (view_0) => onEditorViewReadyRef.current?.(view_0),
901
1247
  onEditorViewDestroy: () => onEditorViewDestroyRef.current?.(),
@@ -2697,6 +3043,7 @@ function buildFootnoteRenderItems(pageFootnoteMap, footnoteContentMap, doc) {
2697
3043
  const text = getFootnoteText(fn);
2698
3044
  items.push({
2699
3045
  displayNumber: String(displayNum),
3046
+ noteId: fnId,
2700
3047
  text,
2701
3048
  ...content ? { content: {
2702
3049
  blocks: content.blocks,
@@ -2713,7 +3060,7 @@ function buildFootnoteRenderItems(pageFootnoteMap, footnoteContentMap, doc) {
2713
3060
  * PagedEditor - Main paginated editing component.
2714
3061
  */
2715
3062
  const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2716
- const { document, documentKey, fonts: hostFonts, styles, theme: _theme, sectionProperties, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, headerContentRId, footerContentRId, firstPageHeaderContentRId, firstPageFooterContentRId, readOnly = false, pageGap = 24, zoom = 1, onDocumentChange, onReadOnlyEditAttempt, onSelectionChange, onSelectionTextChange, onEditorViewReady, externalPlugins = EMPTY_PLUGINS, showTemplateDirectives = true, collaboration, extensionManager, onHeaderFooterDoubleClick, hfEditMode, onBodyClick, className, style, commentsSidebarOpen = false, sidebarOverlay, scrollContainerRef: scrollContainerRefProp, onHyperlinkClick, onContextMenu, onAnchorPositionsChange, onTotalPagesChange, anchorPositionMode = "comments-and-revisions", onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq } = props;
3063
+ const { document, documentKey, fonts: hostFonts, styles, theme: _theme, sectionProperties, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, headerContentRId, footerContentRId, firstPageHeaderContentRId, firstPageFooterContentRId, readOnly = false, pageGap = 24, zoom = 1, showMarginGuides = false, marginGuideColor, onDocumentChange, onReadOnlyEditAttempt, onCopy, onCut, onPaste, onSelectionChange, onSelectionTextChange, onEditorViewReady, externalPlugins = EMPTY_PLUGINS, showTemplateDirectives = true, collaboration, extensionManager, suggestionModeActive = false, suggestionAuthor, onActiveNoteStoryChange, onHeaderFooterDoubleClick, hfEditMode, activeHeaderFooterRId, onBodyClick, className, style, commentsSidebarOpen = false, sidebarOverlay, scrollContainerRef: scrollContainerRefProp, onHyperlinkClick, onContextMenu, onAnchorPositionsChange, onTotalPagesChange, anchorPositionMode = "comments-and-revisions", onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq } = props;
2717
3064
  const getScrollContainer = useCallback(() => {
2718
3065
  if (scrollContainerRefProp && typeof scrollContainerRefProp === "object") return scrollContainerRefProp.current;
2719
3066
  return containerRef.current;
@@ -2723,7 +3070,17 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2723
3070
  const folioEmitterRef = useRef(createFolioEditorEmitter());
2724
3071
  const hiddenPMRef = useRef(null);
2725
3072
  const hfPMsRef = useRef(null);
3073
+ const noteEditorRef = useRef(null);
3074
+ const [noteStoryActive, setNoteStoryActive] = useState(false);
2726
3075
  const painterRef = useRef(null);
3076
+ const noteStoryPlugins = useMemo(() => externalPlugins.filter(({ spec }) => spec.key === suggestionModeKey), [externalPlugins]);
3077
+ const handleActiveNoteStoryChange = useCallback((story) => {
3078
+ setNoteStoryActive(story !== null);
3079
+ onActiveNoteStoryChange?.(story);
3080
+ }, [onActiveNoteStoryChange]);
3081
+ useEffect(() => {
3082
+ if (readOnly) noteEditorRef.current?.close();
3083
+ }, [readOnly]);
2727
3084
  const { handlePMKeyDown } = useVisualLineNavigation({ pagesContainerRef });
2728
3085
  const handleHiddenEditorKeyDown = useCallback((view, event) => {
2729
3086
  if (getTemplateSlashMenu(view.state).active) return false;
@@ -2788,6 +3145,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2788
3145
  focusedId: null
2789
3146
  });
2790
3147
  const [aiSuggestionsOverlayRequestGate] = useState(createLatestRequestGate);
3148
+ const passageHighlightRangeRef = useRef(null);
3149
+ const [passageHighlightRects, setPassageHighlightRects] = useState([]);
3150
+ const [passageHighlightOverlayRequestGate] = useState(createLatestRequestGate);
2791
3151
  const [remoteSelections, setRemoteSelections] = useState([]);
2792
3152
  const suppressSelectionOverlayRef = useRef(false);
2793
3153
  const revealSelectionOverlayTimerRef = useRef(null);
@@ -2974,6 +3334,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2974
3334
  pageSize,
2975
3335
  margins,
2976
3336
  pageGap,
3337
+ showMarginGuides,
3338
+ marginGuideColor,
2977
3339
  syncCoordinator,
2978
3340
  headerContent,
2979
3341
  footerContent,
@@ -3017,6 +3379,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3017
3379
  margins,
3018
3380
  pageGap,
3019
3381
  zoom,
3382
+ showMarginGuides,
3383
+ marginGuideColor,
3020
3384
  syncCoordinator,
3021
3385
  headerContent,
3022
3386
  footerContent,
@@ -3044,6 +3408,27 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3044
3408
  emitter: folioEmitterRef.current
3045
3409
  });
3046
3410
  const folioEditor = folioEditorRef.current;
3411
+ const getActiveEditorStory = useCallback(() => resolveActiveEditorStory({
3412
+ bodyView: folioEditor.getView(),
3413
+ headerFooterView: hfEditMode && activeHeaderFooterRId ? hfPMsRef.current?.getView(activeHeaderFooterRId) ?? null : null,
3414
+ noteView: noteEditorRef.current?.getActiveView() ?? null
3415
+ }), [
3416
+ activeHeaderFooterRId,
3417
+ folioEditor,
3418
+ hfEditMode
3419
+ ]);
3420
+ const marginGuideSettingsInitializedRef = useRef(false);
3421
+ useEffect(() => {
3422
+ if (!marginGuideSettingsInitializedRef.current) {
3423
+ marginGuideSettingsInitializedRef.current = true;
3424
+ return;
3425
+ }
3426
+ folioEditor.relayout();
3427
+ }, [
3428
+ folioEditor,
3429
+ marginGuideColor,
3430
+ showMarginGuides
3431
+ ]);
3047
3432
  const layoutSchedulerRef = useRef(null);
3048
3433
  if (layoutSchedulerRef.current === null) layoutSchedulerRef.current = createLayoutScheduler({
3049
3434
  runLayout: (state_1, options_1) => runLayoutPipelineRef.current(state_1, options_1),
@@ -3531,6 +3916,41 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3531
3916
  measures,
3532
3917
  zoom
3533
3918
  ]);
3919
+ const updatePassageHighlightOverlay = useCallback(() => {
3920
+ const isCurrentRequest_4 = passageHighlightOverlayRequestGate.begin();
3921
+ const range_5 = passageHighlightRangeRef.current;
3922
+ const pagesContainer_3 = pagesContainerRef.current;
3923
+ if (range_5 === null || !pagesContainer_3) {
3924
+ setPassageHighlightRects((prev_0) => prev_0.length === 0 ? prev_0 : []);
3925
+ return;
3926
+ }
3927
+ (async () => {
3928
+ const projected_1 = await projectRangesToRects([range_5], {
3929
+ pagesContainer: pagesContainer_3,
3930
+ zoom,
3931
+ layout,
3932
+ blocks,
3933
+ measures
3934
+ });
3935
+ if (!isCurrentRequest_4()) return;
3936
+ setPassageHighlightRects(projected_1.at(0)?.rects ?? []);
3937
+ })();
3938
+ }, [
3939
+ passageHighlightOverlayRequestGate,
3940
+ layout,
3941
+ blocks,
3942
+ measures,
3943
+ zoom
3944
+ ]);
3945
+ const setPassageHighlightImpl = useCallback((range_6) => {
3946
+ passageHighlightRangeRef.current = range_6;
3947
+ if (range_6 === null) {
3948
+ passageHighlightOverlayRequestGate.invalidate();
3949
+ setPassageHighlightRects((prev_1) => prev_1.length === 0 ? prev_1 : []);
3950
+ return;
3951
+ }
3952
+ updatePassageHighlightOverlay();
3953
+ }, [passageHighlightOverlayRequestGate, updatePassageHighlightOverlay]);
3534
3954
  const hideSelectionOverlayDuringInput = useCallback((state_4) => {
3535
3955
  selectionOverlayRequestGate.invalidate();
3536
3956
  suppressSelectionOverlayRef.current = true;
@@ -3549,6 +3969,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3549
3969
  autocompleteOverlayRequestGate.invalidate();
3550
3970
  directivesOverlayRequestGate.invalidate();
3551
3971
  aiSuggestionsOverlayRequestGate.invalidate();
3972
+ passageHighlightOverlayRequestGate.invalidate();
3552
3973
  if (revealSelectionOverlayTimerRef.current !== null) {
3553
3974
  window.clearTimeout(revealSelectionOverlayTimerRef.current);
3554
3975
  revealSelectionOverlayTimerRef.current = null;
@@ -3558,6 +3979,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3558
3979
  anonymizationOverlayRequestGate,
3559
3980
  autocompleteOverlayRequestGate,
3560
3981
  directivesOverlayRequestGate,
3982
+ passageHighlightOverlayRequestGate,
3561
3983
  selectionOverlayRequestGate
3562
3984
  ]);
3563
3985
  /**
@@ -3605,6 +4027,11 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3605
4027
  }
3606
4028
  if (transaction.docChanged) {
3607
4029
  syncCoordinator.incrementStateSeq();
4030
+ if (passageHighlightRangeRef.current !== null) {
4031
+ passageHighlightRangeRef.current = null;
4032
+ passageHighlightOverlayRequestGate.invalidate();
4033
+ setPassageHighlightRects((prev_2) => prev_2.length === 0 ? prev_2 : []);
4034
+ }
3608
4035
  hideSelectionOverlayDuringInput(newState);
3609
4036
  scheduleLayout(newState, getTransactionDirtyRange(transaction));
3610
4037
  scheduleDocumentChangeNotification();
@@ -3620,6 +4047,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3620
4047
  updateAutocompleteOverlay,
3621
4048
  updateDirectivesOverlay,
3622
4049
  updateAISuggestionsOverlay,
4050
+ passageHighlightOverlayRequestGate,
3623
4051
  syncCoordinator
3624
4052
  ]);
3625
4053
  /**
@@ -3666,6 +4094,24 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3666
4094
  });
3667
4095
  }
3668
4096
  }, [scheduleLayout, ensureHiddenEditorView]);
4097
+ const handleNoteStoryTransaction = useCallback((view_2, docChanged_0, selectionChanged_0) => {
4098
+ if (docChanged_0) {
4099
+ const bodyState_0 = hiddenPMRef.current?.getState();
4100
+ if (bodyState_0) scheduleLayout(bodyState_0, null);
4101
+ }
4102
+ if (docChanged_0 || selectionChanged_0) {
4103
+ const { from: from_2, to: to_2 } = view_2.state.selection;
4104
+ onSelectionChangeRef.current?.(from_2, to_2);
4105
+ folioEmitterRef.current.emit("selectionChange", {
4106
+ from: from_2,
4107
+ to: to_2
4108
+ });
4109
+ }
4110
+ }, [scheduleLayout]);
4111
+ const handleNoteDocumentChange = useCallback((updated) => {
4112
+ onDocumentChangeRef.current?.(updated);
4113
+ folioEmitterRef.current.emit("docChange", updated);
4114
+ }, []);
3669
4115
  useEffect(() => {
3670
4116
  if (!hfEditMode) setHfCaretSelection(null);
3671
4117
  dragAnchorRef.current = null;
@@ -3682,12 +4128,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3682
4128
  setCaretPosition(null);
3683
4129
  } else if (syncCoordinator.isSafeToRender()) updateSelectionOverlay(state_5);
3684
4130
  requestAnimationFrame(() => {
3685
- const view_2 = hiddenPMRef.current?.getView();
3686
- if (!view_2) {
4131
+ const view_3 = hiddenPMRef.current?.getView();
4132
+ if (!view_3) {
3687
4133
  setSelectedImageInfo(null);
3688
4134
  return;
3689
4135
  }
3690
- const { selection: sel_0 } = view_2.state;
4136
+ const { selection: sel_0 } = view_3.state;
3691
4137
  if (sel_0 instanceof NodeSelection && sel_0.node.type.name === "image") {
3692
4138
  const pmPos_2 = sel_0.from;
3693
4139
  const imgEl = pagesContainerRef.current ? findBodyPmAnchor(pagesContainerRef.current, pmPos_2) : null;
@@ -3763,9 +4209,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3763
4209
  return null;
3764
4210
  }, []);
3765
4211
  const findCellPosFromPmPos = useCallback((pmPos_4) => {
3766
- const view_3 = hiddenPMRef.current?.getView();
3767
- if (!view_3) return null;
3768
- return findCellPosInDoc(view_3.state.doc, pmPos_4);
4212
+ const view_4 = hiddenPMRef.current?.getView();
4213
+ if (!view_4) return null;
4214
+ return findCellPosInDoc(view_4.state.doc, pmPos_4);
3769
4215
  }, [findCellPosInDoc]);
3770
4216
  /**
3771
4217
  * Find the closest image element from a click target.
@@ -3853,10 +4299,10 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3853
4299
  cellDragAnchorPosRef.current = null;
3854
4300
  cellDragContentEndRef.current = null;
3855
4301
  isCellDraggingRef.current = false;
3856
- const view_4 = hiddenPMRef.current?.getView();
4302
+ const view_5 = hiddenPMRef.current?.getView();
3857
4303
  let endPos;
3858
- if (view_4) {
3859
- endPos = Math.max(0, view_4.state.doc.content.size - 1);
4304
+ if (view_5) {
4305
+ endPos = Math.max(0, view_5.state.doc.content.size - 1);
3860
4306
  hiddenPMRef.current?.setSelection(endPos);
3861
4307
  } else {
3862
4308
  endPos = Math.max(0, (precomputedInitialStateRef.current?.doc.content.size ?? 1) - 1);
@@ -3876,11 +4322,11 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3876
4322
  queueHiddenEditorSelection
3877
4323
  ]);
3878
4324
  const copySelectionText = useCallback(() => {
3879
- const view_5 = hiddenPMRef.current?.getView();
3880
- if (!view_5) return false;
3881
- const { from: from_2, to: to_2 } = view_5.state.selection;
3882
- if (from_2 === to_2) return false;
3883
- const text_1 = view_5.state.doc.textBetween(from_2, to_2, "\n");
4325
+ const view_6 = hiddenPMRef.current?.getView();
4326
+ if (!view_6) return false;
4327
+ const { from: from_3, to: to_3 } = view_6.state.selection;
4328
+ if (from_3 === to_3) return false;
4329
+ const text_1 = view_6.state.doc.textBetween(from_3, to_3, "\n");
3884
4330
  if (!text_1) return false;
3885
4331
  if (navigator.clipboard === void 0) return false;
3886
4332
  navigator.clipboard.writeText(text_1).catch(() => void 0);
@@ -3900,6 +4346,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3900
4346
  clearTableInsertTimer();
3901
4347
  const target_1 = e.target instanceof HTMLElement ? e.target : null;
3902
4348
  if (!target_1) return;
4349
+ noteEditorRef.current?.close();
3903
4350
  const anchorClosest = target_1.closest("a[href]");
3904
4351
  if (anchorClosest instanceof HTMLAnchorElement ? anchorClosest : null) e.preventDefault();
3905
4352
  if (!readOnly && hfEditMode && onBodyClick) {
@@ -3973,9 +4420,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3973
4420
  const colIndex = Number.parseInt(target_1.dataset["columnIndex"] ?? "0", 10);
3974
4421
  resizeColumnIndexRef.current = colIndex;
3975
4422
  resizeTablePmStartRef.current = Number.parseInt(target_1.dataset["tablePmStart"] ?? "0", 10);
3976
- const view_6 = resizeViewForRead;
3977
- if (view_6) {
3978
- const $pos_1 = view_6.state.doc.resolve(resizeTablePmStartRef.current + 1);
4423
+ const view_7 = resizeViewForRead;
4424
+ if (view_7) {
4425
+ const $pos_1 = view_7.state.doc.resolve(resizeTablePmStartRef.current + 1);
3979
4426
  for (let d_0 = $pos_1.depth; d_0 >= 0; d_0--) {
3980
4427
  const node_1 = $pos_1.node(d_0);
3981
4428
  if (node_1.type.name === "table") {
@@ -4005,9 +4452,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4005
4452
  const rowIndex = Number.parseInt(target_1.dataset["rowIndex"] ?? "0", 10);
4006
4453
  resizeRowIndexRef.current = rowIndex;
4007
4454
  resizeRowTablePmStartRef.current = Number.parseInt(target_1.dataset["tablePmStart"] ?? "0", 10);
4008
- const view_7 = resizeViewForRead;
4009
- if (view_7) {
4010
- const $pos_2 = view_7.state.doc.resolve(resizeRowTablePmStartRef.current + 1);
4455
+ const view_8 = resizeViewForRead;
4456
+ if (view_8) {
4457
+ const $pos_2 = view_8.state.doc.resolve(resizeRowTablePmStartRef.current + 1);
4011
4458
  for (let d_1 = $pos_2.depth; d_1 >= 0; d_1--) {
4012
4459
  const node_2 = $pos_2.node(d_1);
4013
4460
  if (node_2.type.name === "table") {
@@ -4040,9 +4487,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4040
4487
  const colIndex_0 = Number.parseInt(target_1.dataset["columnIndex"] ?? "0", 10);
4041
4488
  resizeRightEdgeColIndexRef.current = colIndex_0;
4042
4489
  resizeRightEdgePmStartRef.current = Number.parseInt(target_1.dataset["tablePmStart"] ?? "0", 10);
4043
- const view_8 = resizeViewForRead;
4044
- if (view_8) {
4045
- const $pos_3 = view_8.state.doc.resolve(resizeRightEdgePmStartRef.current + 1);
4490
+ const view_9 = resizeViewForRead;
4491
+ if (view_9) {
4492
+ const $pos_3 = view_9.state.doc.resolve(resizeRightEdgePmStartRef.current + 1);
4046
4493
  for (let d_2 = $pos_3.depth; d_2 >= 0; d_2--) {
4047
4494
  const node_3 = $pos_3.node(d_2);
4048
4495
  if (node_3.type.name === "table") {
@@ -4241,18 +4688,18 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4241
4688
  resizeHandleRef.current.classList.remove("dragging");
4242
4689
  resizeHandleRef.current = null;
4243
4690
  }
4244
- const view_9 = (resizingHfSurfaceRef.current ? hfPMsRef.current?.getView(resizingHfSurfaceRef.current.rId) : hiddenPMRef.current?.getView()) ?? null;
4691
+ const view_10 = (resizingHfSurfaceRef.current ? hfPMsRef.current?.getView(resizingHfSurfaceRef.current.rId) : hiddenPMRef.current?.getView()) ?? null;
4245
4692
  resizingHfSurfaceRef.current = null;
4246
- if (view_9) {
4693
+ if (view_10) {
4247
4694
  const pmStart_4 = resizeTablePmStartRef.current;
4248
4695
  const colIdx = resizeColumnIndexRef.current;
4249
4696
  const { left: newLeft, right: newRight } = resizeOrigWidthsRef.current;
4250
- const $pos_5 = view_9.state.doc.resolve(pmStart_4 + 1);
4697
+ const $pos_5 = view_10.state.doc.resolve(pmStart_4 + 1);
4251
4698
  for (let d_3 = $pos_5.depth; d_3 >= 0; d_3--) {
4252
4699
  const node_4 = $pos_5.node(d_3);
4253
4700
  if (node_4.type.name === "table") {
4254
4701
  const tablePos = $pos_5.before(d_3);
4255
- const tr = view_9.state.tr;
4702
+ const tr = view_10.state.tr;
4256
4703
  const tableAttrs = expectTableAttrs(node_4);
4257
4704
  if (!tableAttrs.columnWidths) break;
4258
4705
  const widths_1 = [...tableAttrs.columnWidths];
@@ -4278,7 +4725,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4278
4725
  });
4279
4726
  rowOffset += row.nodeSize;
4280
4727
  });
4281
- view_9.dispatch(tr);
4728
+ view_10.dispatch(tr);
4282
4729
  break;
4283
4730
  }
4284
4731
  }
@@ -4291,18 +4738,18 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4291
4738
  resizeRowHandleRef.current.classList.remove("dragging");
4292
4739
  resizeRowHandleRef.current = null;
4293
4740
  }
4294
- const view_10 = (resizingHfSurfaceRef.current ? hfPMsRef.current?.getView(resizingHfSurfaceRef.current.rId) : hiddenPMRef.current?.getView()) ?? null;
4741
+ const view_11 = (resizingHfSurfaceRef.current ? hfPMsRef.current?.getView(resizingHfSurfaceRef.current.rId) : hiddenPMRef.current?.getView()) ?? null;
4295
4742
  resizingHfSurfaceRef.current = null;
4296
- if (view_10) {
4743
+ if (view_11) {
4297
4744
  const pmStart_5 = resizeRowTablePmStartRef.current;
4298
4745
  const rowIdx = resizeRowIndexRef.current;
4299
4746
  const newHeight_0 = resizeRowOrigHeightRef.current;
4300
- const $pos_6 = view_10.state.doc.resolve(pmStart_5 + 1);
4747
+ const $pos_6 = view_11.state.doc.resolve(pmStart_5 + 1);
4301
4748
  for (let d_4 = $pos_6.depth; d_4 >= 0; d_4--) {
4302
4749
  const node_5 = $pos_6.node(d_4);
4303
4750
  if (node_5.type.name === "table") {
4304
4751
  const tablePos_0 = $pos_6.before(d_4);
4305
- const tr_0 = view_10.state.tr;
4752
+ const tr_0 = view_11.state.tr;
4306
4753
  let rowOffset_0 = tablePos_0 + 1;
4307
4754
  let idx = 0;
4308
4755
  node_5.forEach((row_0) => {
@@ -4313,7 +4760,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4313
4760
  rowOffset_0 += row_0.nodeSize;
4314
4761
  idx++;
4315
4762
  });
4316
- view_10.dispatch(tr_0);
4763
+ view_11.dispatch(tr_0);
4317
4764
  break;
4318
4765
  }
4319
4766
  }
@@ -4326,18 +4773,18 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4326
4773
  resizeRightEdgeHandleRef.current.classList.remove("dragging");
4327
4774
  resizeRightEdgeHandleRef.current = null;
4328
4775
  }
4329
- const view_11 = (resizingHfSurfaceRef.current ? hfPMsRef.current?.getView(resizingHfSurfaceRef.current.rId) : hiddenPMRef.current?.getView()) ?? null;
4776
+ const view_12 = (resizingHfSurfaceRef.current ? hfPMsRef.current?.getView(resizingHfSurfaceRef.current.rId) : hiddenPMRef.current?.getView()) ?? null;
4330
4777
  resizingHfSurfaceRef.current = null;
4331
- if (view_11) {
4778
+ if (view_12) {
4332
4779
  const pmStart_6 = resizeRightEdgePmStartRef.current;
4333
4780
  const colIdx_0 = resizeRightEdgeColIndexRef.current;
4334
4781
  const newWidth_1 = resizeRightEdgeOrigWidthRef.current;
4335
- const $pos_7 = view_11.state.doc.resolve(pmStart_6 + 1);
4782
+ const $pos_7 = view_12.state.doc.resolve(pmStart_6 + 1);
4336
4783
  for (let d_5 = $pos_7.depth; d_5 >= 0; d_5--) {
4337
4784
  const node_6 = $pos_7.node(d_5);
4338
4785
  if (node_6.type.name === "table") {
4339
4786
  const tablePos_1 = $pos_7.before(d_5);
4340
- const tr_1 = view_11.state.tr;
4787
+ const tr_1 = view_12.state.tr;
4341
4788
  const tableAttrs_0 = expectTableAttrs(node_6);
4342
4789
  if (!tableAttrs_0.columnWidths) break;
4343
4790
  const widths_2 = [...tableAttrs_0.columnWidths];
@@ -4359,7 +4806,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4359
4806
  });
4360
4807
  rowOffset_1 += row_1.nodeSize;
4361
4808
  });
4362
- view_11.dispatch(tr_1);
4809
+ view_12.dispatch(tr_1);
4363
4810
  break;
4364
4811
  }
4365
4812
  }
@@ -4501,13 +4948,13 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4501
4948
  e_2.preventDefault();
4502
4949
  e_2.stopPropagation();
4503
4950
  if (!tableInsertButton || !hiddenPMRef.current) return;
4504
- const view_12 = hiddenPMRef.current.getView();
4505
- if (!view_12) return;
4951
+ const view_13 = hiddenPMRef.current.getView();
4952
+ if (!view_13) return;
4506
4953
  const { type, cellPmPos } = tableInsertButton;
4507
- const tr_2 = view_12.state.tr.setSelection(TextSelection$1.create(view_12.state.doc, cellPmPos + 1));
4508
- view_12.dispatch(tr_2);
4509
- if (type === "row") addRowBelow(view_12.state, view_12.dispatch);
4510
- else addColumnRight(view_12.state, view_12.dispatch);
4954
+ const tr_2 = view_13.state.tr.setSelection(TextSelection$1.create(view_13.state.doc, cellPmPos + 1));
4955
+ view_13.dispatch(tr_2);
4956
+ if (type === "row") addRowBelow(view_13.state, view_13.dispatch);
4957
+ else addColumnRight(view_13.state, view_13.dispatch);
4511
4958
  setTableInsertButton(null);
4512
4959
  hiddenPMRef.current.focus();
4513
4960
  }, [tableInsertButton]);
@@ -4517,6 +4964,15 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4517
4964
  const handlePagesClick = useCallback((e_3) => {
4518
4965
  const target_2 = e_3.target instanceof HTMLElement ? e_3.target : null;
4519
4966
  if (!target_2) return;
4967
+ if (!readOnly && e_3.detail === 2) {
4968
+ const story_0 = findNoteStoryForTarget(target_2);
4969
+ if (story_0) {
4970
+ e_3.preventDefault();
4971
+ e_3.stopPropagation();
4972
+ noteEditorRef.current?.open(story_0);
4973
+ return;
4974
+ }
4975
+ }
4520
4976
  const anchorClosest_0 = target_2.closest("a[href]");
4521
4977
  const anchorEl_0 = anchorClosest_0 instanceof HTMLAnchorElement ? anchorClosest_0 : null;
4522
4978
  if (anchorEl_0) {
@@ -4525,10 +4981,10 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4525
4981
  if (href.startsWith("#")) {
4526
4982
  const bookmarkName = href.slice(1);
4527
4983
  if (bookmarkName && hiddenPMRef.current) {
4528
- const view_13 = hiddenPMRef.current.getView();
4529
- if (view_13) {
4984
+ const view_14 = hiddenPMRef.current.getView();
4985
+ if (view_14) {
4530
4986
  const targetPos = { value: null };
4531
- view_13.state.doc.descendants((node_7, pos_2) => {
4987
+ view_14.state.doc.descendants((node_7, pos_2) => {
4532
4988
  if (targetPos.value !== null) return false;
4533
4989
  if (node_7.type.name === "paragraph") {
4534
4990
  if (node_7.attrs["bookmarks"]?.some((b) => b.name === bookmarkName)) {
@@ -4617,9 +5073,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4617
5073
  if (e_3.detail === 2 && hiddenPMRef.current) {
4618
5074
  const pmPos_12 = getPositionFromMouse(e_3.clientX, e_3.clientY);
4619
5075
  if (pmPos_12 !== null) {
4620
- const view_14 = hiddenPMRef.current.getView();
4621
- if (view_14) {
4622
- const { doc: doc_0 } = view_14.state;
5076
+ const view_15 = hiddenPMRef.current.getView();
5077
+ if (view_15) {
5078
+ const { doc: doc_0 } = view_15.state;
4623
5079
  const $pos_9 = doc_0.resolve(pmPos_12);
4624
5080
  const parent_0 = $pos_9.parent;
4625
5081
  if (parent_0.isTextblock) {
@@ -4645,9 +5101,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4645
5101
  if (e_3.detail === 3 && hiddenPMRef.current) {
4646
5102
  const pmPos_13 = getPositionFromMouse(e_3.clientX, e_3.clientY);
4647
5103
  if (pmPos_13 !== null) {
4648
- const view_15 = hiddenPMRef.current.getView();
4649
- if (view_15) {
4650
- const { doc: doc_1 } = view_15.state;
5104
+ const view_16 = hiddenPMRef.current.getView();
5105
+ if (view_16) {
5106
+ const { doc: doc_1 } = view_16.state;
4651
5107
  const $pos_10 = doc_1.resolve(pmPos_13);
4652
5108
  const paragraphStart = $pos_10.start($pos_10.depth);
4653
5109
  const paragraphEnd = $pos_10.end($pos_10.depth);
@@ -4673,9 +5129,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4673
5129
  if (slot_2) {
4674
5130
  const hfView_4 = hfPMsRef.current?.getView(slot_2.rId);
4675
5131
  if (hfView_4) {
4676
- const { from: from_3, to: to_3 } = hfView_4.state.selection;
5132
+ const { from: from_4, to: to_4 } = hfView_4.state.selection;
4677
5133
  const pmPos_14 = clickToPositionInHfSlot(pagesContainerRef.current ?? slot_2.element, slot_2.kind, slot_2.rId, e_4.clientX, e_4.clientY);
4678
- if (pmPos_14 !== null && (from_3 === to_3 || pmPos_14 < from_3 || pmPos_14 > to_3)) {
5134
+ if (pmPos_14 !== null && (from_4 === to_4 || pmPos_14 < from_4 || pmPos_14 > to_4)) {
4679
5135
  const docEnd_3 = hfView_4.state.doc.content.size;
4680
5136
  const clamped_1 = Math.max(0, Math.min(pmPos_14, docEnd_3));
4681
5137
  const $pos_11 = hfView_4.state.doc.resolve(clamped_1);
@@ -4692,11 +5148,11 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4692
5148
  }
4693
5149
  }
4694
5150
  }
4695
- const view_16 = hiddenPMRef.current?.getView();
4696
- if (!view_16) return;
4697
- const { from: from_4, to: to_4 } = view_16.state.selection;
5151
+ const view_17 = hiddenPMRef.current?.getView();
5152
+ if (!view_17) return;
5153
+ const { from: from_5, to: to_5 } = view_17.state.selection;
4698
5154
  const pmPos_15 = getPositionFromMouse(e_4.clientX, e_4.clientY);
4699
- if (pmPos_15 !== null && (from_4 === to_4 || pmPos_15 < from_4 || pmPos_15 > to_4)) {
5155
+ if (pmPos_15 !== null && (from_5 === to_5 || pmPos_15 < from_5 || pmPos_15 > to_5)) {
4700
5156
  hiddenPMRef.current?.setSelection(pmPos_15);
4701
5157
  hiddenPMRef.current?.focus();
4702
5158
  setIsFocused(true);
@@ -4719,7 +5175,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4719
5175
  */
4720
5176
  const handleContainerFocus = useCallback((e_5) => {
4721
5177
  if (e_5.target instanceof HTMLElement && e_5.target.closest(".docx-comments-sidebar")) return;
4722
- if (e_5.target instanceof HTMLElement && e_5.target.closest("[data-hf-r-id]")) return;
5178
+ if (e_5.target instanceof HTMLElement && e_5.target.closest("[data-hf-r-id], [data-note-kind][data-note-id]")) return;
4723
5179
  focusHiddenEditor();
4724
5180
  }, [focusHiddenEditor]);
4725
5181
  /**
@@ -4735,16 +5191,16 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4735
5191
  * Handle image resize from the overlay.
4736
5192
  */
4737
5193
  const handleImageResize = useCallback((pmPos_16, newWidth_2, newHeight_1) => {
4738
- const view_17 = hiddenPMRef.current?.getView();
4739
- if (!view_17) return;
5194
+ const view_18 = hiddenPMRef.current?.getView();
5195
+ if (!view_18) return;
4740
5196
  try {
4741
- const node_10 = view_17.state.doc.nodeAt(pmPos_16);
5197
+ const node_10 = view_18.state.doc.nodeAt(pmPos_16);
4742
5198
  if (!node_10 || node_10.type.name !== "image") return;
4743
- const tr_3 = view_17.state.tr.setNodeMarkup(pmPos_16, void 0, mergeImageAttrs(node_10, {
5199
+ const tr_3 = view_18.state.tr.setNodeMarkup(pmPos_16, void 0, mergeImageAttrs(node_10, {
4744
5200
  width: newWidth_2,
4745
5201
  height: newHeight_1
4746
5202
  }));
4747
- view_17.dispatch(tr_3);
5203
+ view_18.dispatch(tr_3);
4748
5204
  hiddenPMRef.current?.setNodeSelection(pmPos_16);
4749
5205
  } catch {}
4750
5206
  }, []);
@@ -4765,10 +5221,10 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4765
5221
  * to the drop position determined by mouse coordinates.
4766
5222
  */
4767
5223
  const handleImageDragMove = useCallback((pmPos_17, clientX_1, clientY_1) => {
4768
- const view_18 = hiddenPMRef.current?.getView();
4769
- if (!view_18) return;
5224
+ const view_19 = hiddenPMRef.current?.getView();
5225
+ if (!view_19) return;
4770
5226
  try {
4771
- const node_11 = view_18.state.doc.nodeAt(pmPos_17);
5227
+ const node_11 = view_19.state.doc.nodeAt(pmPos_17);
4772
5228
  if (!node_11 || node_11.type.name !== "image") return;
4773
5229
  const attrs = expectImageAttrs(node_11);
4774
5230
  if (attrs.displayMode === "float" || attrs.wrapType === "square" || attrs.wrapType === "tight" || attrs.wrapType === "through") {
@@ -4803,14 +5259,14 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4803
5259
  relativeTo: "margin"
4804
5260
  }
4805
5261
  };
4806
- const tr_4 = view_18.state.tr.setNodeMarkup(pmPos_17, void 0, mergeImageAttrs(node_11, { position: newPosition }));
4807
- view_18.dispatch(tr_4);
5262
+ const tr_4 = view_19.state.tr.setNodeMarkup(pmPos_17, void 0, mergeImageAttrs(node_11, { position: newPosition }));
5263
+ view_19.dispatch(tr_4);
4808
5264
  hiddenPMRef.current?.setNodeSelection(pmPos_17);
4809
5265
  } else {
4810
5266
  const dropPos = getPositionFromMouse(clientX_1, clientY_1);
4811
5267
  if (dropPos === null) return;
4812
5268
  if (dropPos === pmPos_17 || dropPos === pmPos_17 + 1) return;
4813
- let tr_5 = view_18.state.tr;
5269
+ let tr_5 = view_19.state.tr;
4814
5270
  tr_5 = tr_5.delete(pmPos_17, pmPos_17 + node_11.nodeSize);
4815
5271
  let selectionPos;
4816
5272
  if (dropPos <= pmPos_17) {
@@ -4822,7 +5278,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4822
5278
  selectionPos = Math.min(adjusted, tr_5.doc.content.size - 1);
4823
5279
  }
4824
5280
  hiddenPMRef.current?.setNodeSelection(selectionPos);
4825
- view_18.dispatch(tr_5);
5281
+ view_19.dispatch(tr_5);
4826
5282
  }
4827
5283
  } catch {}
4828
5284
  }, [getPositionFromMouse, zoom]);
@@ -4849,12 +5305,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4849
5305
  }
4850
5306
  return;
4851
5307
  }
4852
- if (e_7.target instanceof HTMLElement && e_7.target.closest("[data-hf-r-id]")) return;
4853
- let view_19 = hiddenPMRef.current?.getView();
4854
- if (!view_19) {
5308
+ if (e_7.target instanceof HTMLElement && e_7.target.closest("[data-hf-r-id], [data-note-kind][data-note-id]")) return;
5309
+ let view_20 = hiddenPMRef.current?.getView();
5310
+ if (!view_20) {
4855
5311
  ensureHiddenEditorView({ sync: true });
4856
- view_19 = hiddenPMRef.current?.getView();
4857
- if (view_19) {
5312
+ view_20 = hiddenPMRef.current?.getView();
5313
+ if (view_20) {
4858
5314
  if (isPlainTextInputEvent(e_7)) {
4859
5315
  e_7.preventDefault();
4860
5316
  queueHiddenEditorTextInput(e_7.key);
@@ -4877,11 +5333,11 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4877
5333
  }
4878
5334
  return;
4879
5335
  }
4880
- if (pendingHiddenEditorSelectionRef.current || queuedInputBeforeHiddenEditorRef.current.length > 0) applyPendingHiddenEditorInput(view_19);
5336
+ if (pendingHiddenEditorSelectionRef.current || queuedInputBeforeHiddenEditorRef.current.length > 0) applyPendingHiddenEditorInput(view_20);
4881
5337
  if (!hiddenPMRef.current?.isFocused()) focusHiddenEditor();
4882
5338
  if (e_7.key === " " && !e_7.ctrlKey && !e_7.metaKey && !e_7.nativeEvent.isComposing) {
4883
5339
  e_7.preventDefault();
4884
- dispatchEditorTextInput(view_19, " ");
5340
+ dispatchEditorTextInput(view_20, " ");
4885
5341
  return;
4886
5342
  }
4887
5343
  if (["PageUp", "PageDown"].includes(e_7.key) && !e_7.metaKey && !e_7.ctrlKey) {}
@@ -4909,7 +5365,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4909
5365
  */
4910
5366
  const handleContainerMouseDown = useCallback((e_8) => {
4911
5367
  if (e_8.target instanceof HTMLElement && e_8.target.closest(".docx-comments-sidebar")) return;
4912
- if (e_8.target instanceof HTMLElement && e_8.target.closest("[data-hf-r-id]")) return;
5368
+ if (e_8.target instanceof HTMLElement && e_8.target.closest("[data-hf-r-id], [data-note-kind][data-note-id]")) return;
4913
5369
  if (!hiddenPMRef.current?.isFocused()) focusHiddenEditor();
4914
5370
  }, [focusHiddenEditor]);
4915
5371
  useEffect(() => {
@@ -4975,19 +5431,19 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4975
5431
  /**
4976
5432
  * Run initial layout when document or view changes.
4977
5433
  */
4978
- const handleEditorViewReady = useCallback((view_20) => {
4979
- onEditorViewReadyRef.current?.(view_20);
4980
- anonymizationMatchesRef.current = anonymizationDecorationsKey.getState(view_20.state)?.matches ?? [];
4981
- const initialSuggestion = autocompleteSuggestionKey.getState(view_20.state)?.suggestion;
5434
+ const handleEditorViewReady = useCallback((view_21) => {
5435
+ onEditorViewReadyRef.current?.(view_21);
5436
+ anonymizationMatchesRef.current = anonymizationDecorationsKey.getState(view_21.state)?.matches ?? [];
5437
+ const initialSuggestion = autocompleteSuggestionKey.getState(view_21.state)?.suggestion;
4982
5438
  if (initialSuggestion !== void 0) autocompleteSuggestionRef.current = initialSuggestion;
4983
5439
  updateAutocompleteOverlay();
4984
- directivesRef.current = templateDirectivesKey.getState(view_20.state)?.ranges ?? [];
4985
- const previewState = templatePreviewValuesKey.getState(view_20.state);
5440
+ directivesRef.current = templateDirectivesKey.getState(view_21.state)?.ranges ?? [];
5441
+ const previewState = templatePreviewValuesKey.getState(view_21.state);
4986
5442
  templatePreviewRef.current = {
4987
5443
  entries: previewState?.entries ?? EMPTY_TEMPLATE_PREVIEW_ENTRIES,
4988
5444
  mode: previewState?.preview?.mode ?? "plain"
4989
5445
  };
4990
- const aiState = aiSuggestionDecorationsKey.getState(view_20.state);
5446
+ const aiState = aiSuggestionDecorationsKey.getState(view_21.state);
4991
5447
  aiSuggestionsRef.current = {
4992
5448
  suggestions: aiState?.suggestions ?? EMPTY_AI_SUGGESTIONS,
4993
5449
  focusedId: aiState?.focusedId ?? null
@@ -4995,16 +5451,16 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4995
5451
  const focusReadyView = () => {
4996
5452
  if (readOnly || !shouldFocusHiddenEditorOnReadyRef.current) return;
4997
5453
  requestAnimationFrame(() => {
4998
- if (hiddenPMRef.current?.getView() !== view_20) return;
4999
- applyPendingHiddenEditorInput(view_20);
5000
- view_20.focus();
5454
+ if (hiddenPMRef.current?.getView() !== view_21) return;
5455
+ applyPendingHiddenEditorInput(view_21);
5456
+ view_21.focus();
5001
5457
  setIsFocused(true);
5002
5458
  });
5003
5459
  };
5004
- if (layoutSessionRef.current.lastPmDoc?.eq(view_20.state.doc)) {
5460
+ if (layoutSessionRef.current.lastPmDoc?.eq(view_21.state.doc)) {
5005
5461
  const lastPreview = layoutSessionRef.current.lastTemplatePreview;
5006
- if (templatePreviewRef.current.mode !== lastPreview.mode || templatePreviewDirtyRange(lastPreview.entries, templatePreviewRef.current.entries) !== null) runLayoutPipeline$1(view_20.state, { reason: "manual" });
5007
- updateSelectionOverlay(view_20.state);
5462
+ if (templatePreviewRef.current.mode !== lastPreview.mode || templatePreviewDirtyRange(lastPreview.entries, templatePreviewRef.current.entries) !== null) runLayoutPipeline$1(view_21.state, { reason: "manual" });
5463
+ updateSelectionOverlay(view_21.state);
5008
5464
  updateAnonymizationOverlay();
5009
5465
  updateDirectivesOverlay();
5010
5466
  updateAISuggestionsOverlay();
@@ -5023,7 +5479,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5023
5479
  const runAfterFontWait_0 = (fontsLoaded_0) => {
5024
5480
  pendingInitialFontReadyLayoutRef.current = false;
5025
5481
  const currentView_0 = hiddenPMRef.current?.getView();
5026
- if (currentView_0 !== view_20) return;
5482
+ if (currentView_0 !== view_21) return;
5027
5483
  recordLayoutPhase("initial", "initial-fonts", performance.now() - fontWaitStartedAt_0);
5028
5484
  resetCanvasContext();
5029
5485
  clearAllCaches();
@@ -5033,7 +5489,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5033
5489
  suppressFontReadyUntilRef.current = performance.now() + INITIAL_FONT_READY_SUPPRESSION_MS;
5034
5490
  }
5035
5491
  };
5036
- waitForInitialLayoutFonts(document, view_20.state.doc).then(runAfterFontWait_0, () => runAfterFontWait_0(false));
5492
+ waitForInitialLayoutFonts(document, view_21.state.doc).then(runAfterFontWait_0, () => runAfterFontWait_0(false));
5037
5493
  focusReadyView();
5038
5494
  }, [
5039
5495
  applyPendingHiddenEditorInput,
@@ -5058,6 +5514,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5058
5514
  useEffect(() => {
5059
5515
  updateAISuggestionsOverlay();
5060
5516
  }, [updateAISuggestionsOverlay]);
5517
+ useEffect(() => {
5518
+ updatePassageHighlightOverlay();
5519
+ }, [updatePassageHighlightOverlay]);
5061
5520
  useEffect(() => {
5062
5521
  if (!onAnchorPositionsChange || !layout) return;
5063
5522
  let cancelled_0 = false;
@@ -5091,12 +5550,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5091
5550
  };
5092
5551
  const handleFontsLoaded = () => {
5093
5552
  if (pendingInitialFontReadyLayoutRef.current || performance.now() < suppressFontReadyUntilRef.current || layoutSessionRef.current.usedLoadedFonts) return;
5094
- const view_21 = hiddenPMRef.current?.getView();
5095
- if (view_21) {
5553
+ const view_22 = hiddenPMRef.current?.getView();
5554
+ if (view_22) {
5096
5555
  resetCanvasContext();
5097
5556
  clearAllCaches();
5098
- runLayoutPipelineRef.current(view_21.state, { reason: "font-ready" });
5099
- updateSelectionOverlayRef.current(view_21.state);
5557
+ runLayoutPipelineRef.current(view_22.state, { reason: "font-ready" });
5558
+ updateSelectionOverlayRef.current(view_22.state);
5100
5559
  }
5101
5560
  };
5102
5561
  fontSet.addEventListener("loading", handleFontsLoading);
@@ -5120,12 +5579,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5120
5579
  }
5121
5580
  registered = faces;
5122
5581
  if (faces.length === 0) return;
5123
- const view_22 = hiddenPMRef.current?.getView();
5124
- if (!view_22) return;
5582
+ const view_23 = hiddenPMRef.current?.getView();
5583
+ if (!view_23) return;
5125
5584
  resetCanvasContext();
5126
5585
  clearAllCaches();
5127
- runLayoutPipelineRef.current(view_22.state, { reason: "font-ready" });
5128
- updateSelectionOverlayRef.current(view_22.state);
5586
+ runLayoutPipelineRef.current(view_23.state, { reason: "font-ready" });
5587
+ updateSelectionOverlayRef.current(view_23.state);
5129
5588
  });
5130
5589
  return () => {
5131
5590
  cancelled_1 = true;
@@ -5137,12 +5596,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5137
5596
  let cancelled_2 = false;
5138
5597
  let registered_0 = [];
5139
5598
  const remeasureForFontChange = () => {
5140
- const view_23 = hiddenPMRef.current?.getView();
5141
- if (!view_23) return;
5599
+ const view_24 = hiddenPMRef.current?.getView();
5600
+ if (!view_24) return;
5142
5601
  resetCanvasContext();
5143
5602
  clearAllCaches();
5144
- runLayoutPipelineRef.current(view_23.state, { reason: "font-ready" });
5145
- updateSelectionOverlayRef.current(view_23.state);
5603
+ runLayoutPipelineRef.current(view_24.state, { reason: "font-ready" });
5604
+ updateSelectionOverlayRef.current(view_24.state);
5146
5605
  };
5147
5606
  loadHostFontFaces(hostFonts).then((faces_0) => {
5148
5607
  if (cancelled_2) {
@@ -5168,12 +5627,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5168
5627
  lastLayoutInputSignatureRef.current = layoutInputSignature;
5169
5628
  return;
5170
5629
  }
5171
- const view_24 = hiddenPMRef.current?.getView();
5172
- if (view_24) {
5630
+ const view_25 = hiddenPMRef.current?.getView();
5631
+ if (view_25) {
5173
5632
  const layoutInputsChanged = lastLayoutInputSignatureRef.current !== layoutInputSignature;
5174
5633
  lastLayoutInputSignatureRef.current = layoutInputSignature;
5175
- if (!layoutInputsChanged && view_24.state.doc === layoutSessionRef.current.lastPmDoc) return;
5176
- runLayoutPipelineRef.current(view_24.state, { reason: "layout-input" });
5634
+ if (!layoutInputsChanged && view_25.state.doc === layoutSessionRef.current.lastPmDoc) return;
5635
+ runLayoutPipelineRef.current(view_25.state, { reason: "layout-input" });
5177
5636
  }
5178
5637
  }, [document, layoutInputSignature]);
5179
5638
  useEffect(() => {
@@ -5191,7 +5650,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5191
5650
  return folioEditor;
5192
5651
  },
5193
5652
  getDocument() {
5194
- return folioEditor.getDocument();
5653
+ const current_0 = folioEditor.getDocument();
5654
+ return current_0 ? noteEditorRef.current?.snapshotDocument(current_0) ?? current_0 : null;
5195
5655
  },
5196
5656
  getState() {
5197
5657
  return folioEditor.getState();
@@ -5199,6 +5659,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5199
5659
  getView() {
5200
5660
  return folioEditor.getView();
5201
5661
  },
5662
+ getActiveView() {
5663
+ return getActiveEditorStory().view;
5664
+ },
5665
+ closeNoteStory() {
5666
+ noteEditorRef.current?.close();
5667
+ },
5202
5668
  getHfView(rId_0) {
5203
5669
  return hfPMsRef.current?.getView(rId_0) ?? null;
5204
5670
  },
@@ -5206,30 +5672,37 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5206
5672
  ensureHiddenEditorView(options_4);
5207
5673
  },
5208
5674
  focus() {
5209
- folioEditor.focus();
5675
+ getActiveEditorStory().view?.focus();
5210
5676
  setIsFocused(true);
5211
5677
  },
5212
5678
  blur() {
5213
- folioEditor.blur();
5679
+ const view_26 = getActiveEditorStory().view;
5680
+ if (view_26?.hasFocus() && view_26.dom instanceof HTMLElement) view_26.dom.blur();
5214
5681
  setIsFocused(false);
5215
5682
  },
5216
5683
  isFocused() {
5217
- return folioEditor.isFocused();
5684
+ return getActiveEditorStory().view?.hasFocus() ?? false;
5218
5685
  },
5219
5686
  dispatch(tr_6) {
5220
5687
  folioEditor.dispatch(tr_6);
5221
5688
  },
5222
5689
  undo() {
5223
- return folioEditor.undo();
5690
+ const target_4 = getActiveEditorStory();
5691
+ if (target_4.type === "none") return false;
5692
+ return undo(target_4.view.state, target_4.view.dispatch);
5224
5693
  },
5225
5694
  redo() {
5226
- return folioEditor.redo();
5695
+ const target_5 = getActiveEditorStory();
5696
+ if (target_5.type === "none") return false;
5697
+ return redo(target_5.view.state, target_5.view.dispatch);
5227
5698
  },
5228
5699
  canUndo() {
5229
- return folioEditor.canUndo();
5700
+ const target_6 = getActiveEditorStory();
5701
+ return target_6.type === "none" ? false : undo(target_6.view.state);
5230
5702
  },
5231
5703
  canRedo() {
5232
- return folioEditor.canRedo();
5704
+ const target_7 = getActiveEditorStory();
5705
+ return target_7.type === "none" ? false : redo(target_7.view.state);
5233
5706
  },
5234
5707
  setSelection(anchor_3, head_1) {
5235
5708
  folioEditor.setSelection(anchor_3, head_1);
@@ -5243,6 +5716,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5243
5716
  scrollToPosition: scrollToPositionImpl,
5244
5717
  scrollToPage: scrollToPageImpl,
5245
5718
  scrollToParaId: scrollToParaIdImpl,
5719
+ setPassageHighlight: setPassageHighlightImpl,
5246
5720
  getPageNumberForPmPos(pmPos_18) {
5247
5721
  const container_0 = pagesContainerRef.current;
5248
5722
  if (!container_0) return null;
@@ -5281,9 +5755,11 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5281
5755
  }), [
5282
5756
  ensureHiddenEditorView,
5283
5757
  folioEditor,
5758
+ getActiveEditorStory,
5284
5759
  scrollToPageImpl,
5285
5760
  scrollToParaIdImpl,
5286
- scrollToPositionImpl
5761
+ scrollToPositionImpl,
5762
+ setPassageHighlightImpl
5287
5763
  ]);
5288
5764
  useEffect(() => {
5289
5765
  if (!layout) return;
@@ -5350,6 +5826,18 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5350
5826
  ...styles !== void 0 ? { styles } : {},
5351
5827
  ..._theme !== void 0 ? { theme: _theme } : {}
5352
5828
  }),
5829
+ /* @__PURE__ */ jsx(NoteStoryEditor, {
5830
+ ref: noteEditorRef,
5831
+ document,
5832
+ onActiveChange: handleActiveNoteStoryChange,
5833
+ onDocumentChange: handleNoteDocumentChange,
5834
+ onStoryChange: handleNoteStoryTransaction,
5835
+ plugins: noteStoryPlugins,
5836
+ suggestionModeActive,
5837
+ ...suggestionAuthor !== void 0 ? { suggestionAuthor } : {},
5838
+ ...styles !== void 0 ? { styles } : {},
5839
+ ..._theme !== void 0 ? { theme: _theme } : {}
5840
+ }),
5353
5841
  /* @__PURE__ */ jsx(HiddenProseMirror, {
5354
5842
  ref: hiddenPMRef,
5355
5843
  document,
@@ -5363,6 +5851,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5363
5851
  onEditorViewReady: handleEditorViewReady,
5364
5852
  onEditorViewDestroy: handleEditorViewDestroy,
5365
5853
  onKeyDown: handleHiddenEditorKeyDown,
5854
+ ...onCopy !== void 0 ? { onCopy } : {},
5855
+ ...onCut !== void 0 ? { onCut } : {},
5856
+ ...onPaste !== void 0 ? { onPaste } : {},
5366
5857
  ...styles !== void 0 ? { styles } : {},
5367
5858
  externalPlugins,
5368
5859
  ...collaboration !== void 0 ? { collaboration } : {},
@@ -5392,6 +5883,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5392
5883
  selectedCanonical: selectedAnonymizationCanonical,
5393
5884
  selectionSeq: anonymizationSelectionSeq
5394
5885
  }),
5886
+ /* @__PURE__ */ jsx(PassageHighlightOverlay, { rects: passageHighlightRects }),
5395
5887
  /* @__PURE__ */ jsx(AutocompleteCaretOverlay, {
5396
5888
  caret: autocompleteCaret,
5397
5889
  text: autocompleteText,
@@ -5405,8 +5897,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5405
5897
  ranges: directivesRef.current
5406
5898
  }),
5407
5899
  /* @__PURE__ */ jsx(SelectionOverlay, {
5408
- selectionRects: hfEditMode ? EMPTY_SELECTION_RECTS : selectionRects,
5409
- caretPosition: hfEditMode ? null : caretPosition,
5900
+ selectionRects: hfEditMode || noteStoryActive ? EMPTY_SELECTION_RECTS : selectionRects,
5901
+ caretPosition: hfEditMode || noteStoryActive ? null : caretPosition,
5410
5902
  isFocused,
5411
5903
  pageGap,
5412
5904
  markCaretRect: true
@@ -6689,133 +7181,145 @@ function removePendingCommentMarkRange(view, range) {
6689
7181
  }
6690
7182
  //#endregion
6691
7183
  //#region src/components/ContentControlWidgetsOverlay.tsx
6692
- /**
6693
- * React shell for the content-control widgets plugin.
6694
- *
6695
- * The plugin (see `core/prosemirror/plugins/contentControlWidgets`) emits a
6696
- * `folio:content-control-widget` CustomEvent on the editor's view DOM
6697
- * whenever the user clicks a typed control. This component subscribes to
6698
- * those events and renders a small floating picker positioned at the
6699
- * anchor element — a list of menu items for dropdown / comboBox
6700
- * controls, a shared date picker for date controls — then dispatches back
6701
- * through `dispatchDropdownPick` / `dispatchDatePick` so the change rides
6702
- * the normal undo stack.
6703
- *
6704
- * The dropdown popover uses the injected `MenuItem` for visual + a11y
6705
- * consistency with the rest of the editor.
6706
- */
6707
- function parseListItems(raw) {
6708
- if (!raw) return [];
6709
- try {
6710
- const parsed = JSON.parse(raw);
6711
- if (!Array.isArray(parsed)) return [];
6712
- const out = [];
6713
- for (const entry of parsed) if (entry !== null && typeof entry === "object" && "displayText" in entry && "value" in entry && typeof entry.displayText === "string" && typeof entry.value === "string") out.push(entry);
6714
- return out;
6715
- } catch {
6716
- return [];
6717
- }
6718
- }
6719
- function ContentControlWidgetsOverlay({ getEditorView }) {
7184
+ /** Thin React renderer for the shared content-control widget controller. */
7185
+ function ContentControlWidgetsOverlay(t0) {
7186
+ const $ = c(32);
7187
+ const { getEventRoot, getEditorView } = t0;
6720
7188
  const folioUI = useFolioUI();
6721
- const { Item: MenuItem } = folioUI.Menu;
7189
+ const { Root: Menu, Item: MenuItem } = folioUI.Menu;
6722
7190
  const DatePickerPopover = folioUI.DatePickerPopover;
6723
7191
  const t = useTranslations("folio");
6724
- const [open, setOpen] = useState(null);
6725
- const getEditorViewRef = useRef(getEditorView);
6726
- getEditorViewRef.current = getEditorView;
6727
- const close = useCallback(() => setOpen(null), []);
6728
- const viewDom = getEditorView()?.dom ?? null;
6729
- useEffect(() => {
6730
- if (!viewDom) return;
6731
- const onWidget = (event) => {
6732
- const detail = event.detail;
6733
- if (detail.kind === "dropdownOpen") {
6734
- const items = parseListItems(detail.listItemsJson);
6735
- setOpen({
6736
- kind: "dropdown",
6737
- pmPos: detail.pmPos,
6738
- items,
6739
- anchorRect: detail.anchor.getBoundingClientRect()
6740
- });
6741
- return;
6742
- }
6743
- if (detail.kind === "datePick") setOpen({
6744
- kind: "date",
6745
- pmPos: detail.pmPos,
6746
- anchorRect: detail.anchor.getBoundingClientRect()
6747
- });
6748
- };
6749
- viewDom.addEventListener(CONTENT_CONTROL_WIDGET_EVENT_NAME, onWidget);
6750
- return () => {
6751
- viewDom.removeEventListener(CONTENT_CONTROL_WIDGET_EVENT_NAME, onWidget);
6752
- };
6753
- }, [viewDom]);
6754
- useEffect(() => {
6755
- if (!open) return;
6756
- const onKey = (event_0) => {
6757
- if (event_0.key === "Escape") close();
6758
- };
6759
- const onScroll = () => close();
6760
- window.addEventListener("keydown", onKey);
6761
- window.addEventListener("scroll", onScroll, true);
6762
- return () => {
6763
- window.removeEventListener("keydown", onKey);
6764
- window.removeEventListener("scroll", onScroll, true);
7192
+ let t1;
7193
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
7194
+ t1 = new ContentControlWidgetController();
7195
+ $[0] = t1;
7196
+ } else t1 = $[0];
7197
+ const controller = t1;
7198
+ const snapshot = useSyncExternalStore(controller.subscribe, controller.getSnapshot, controller.getSnapshot);
7199
+ let t2;
7200
+ if ($[1] !== getEditorView) {
7201
+ t2 = getEditorView();
7202
+ $[1] = getEditorView;
7203
+ $[2] = t2;
7204
+ } else t2 = $[2];
7205
+ const view = t2;
7206
+ let t3;
7207
+ let t4;
7208
+ if ($[3] !== getEventRoot || $[4] !== view) {
7209
+ t3 = () => {
7210
+ controller.bind(view, getEventRoot());
7211
+ return () => controller.destroy();
6765
7212
  };
6766
- }, [open, close]);
6767
- const style = useMemo(() => {
6768
- if (!open) return;
6769
- return {
7213
+ t4 = [
7214
+ controller,
7215
+ getEventRoot,
7216
+ view
7217
+ ];
7218
+ $[3] = getEventRoot;
7219
+ $[4] = view;
7220
+ $[5] = t3;
7221
+ $[6] = t4;
7222
+ } else {
7223
+ t3 = $[5];
7224
+ t4 = $[6];
7225
+ }
7226
+ useEffect(t3, t4);
7227
+ let t5;
7228
+ if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
7229
+ t5 = (value) => controller.pickDropdown(value);
7230
+ $[7] = t5;
7231
+ } else t5 = $[7];
7232
+ const onDropdownPick = t5;
7233
+ let t6;
7234
+ if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
7235
+ t6 = (value_0) => value_0 ? controller.pickDate(value_0) : false;
7236
+ $[8] = t6;
7237
+ } else t6 = $[8];
7238
+ const onDateChange = t6;
7239
+ if (snapshot.status === "closed") return null;
7240
+ const t7 = `${snapshot.position.y}px`;
7241
+ const t8 = `${snapshot.position.x}px`;
7242
+ let t9;
7243
+ if ($[9] !== t7 || $[10] !== t8) {
7244
+ t9 = {
6770
7245
  position: "fixed",
6771
- top: `${open.anchorRect.bottom + 4}px`,
6772
- insetInlineStart: `${open.anchorRect.left}px`,
7246
+ top: t7,
7247
+ insetInlineStart: t8,
6773
7248
  zIndex: 9999
6774
7249
  };
6775
- }, [open]);
6776
- const openPmPos = open?.pmPos;
6777
- const onDropdownPick = useCallback((value) => {
6778
- const liveView = getEditorViewRef.current();
6779
- if (liveView && typeof openPmPos === "number") dispatchDropdownPick(liveView, openPmPos, value);
6780
- close();
6781
- }, [close, openPmPos]);
6782
- const onDatePick = useCallback((value_0) => {
6783
- const liveView_0 = getEditorViewRef.current();
6784
- if (liveView_0 && value_0.length > 0 && typeof openPmPos === "number") dispatchDatePick(liveView_0, openPmPos, value_0);
6785
- close();
6786
- }, [close, openPmPos]);
6787
- const handleDateChange = useCallback((value_1) => {
6788
- if (value_1) onDatePick(value_1);
6789
- }, [onDatePick]);
6790
- if (!open) return null;
6791
- return createPortal(/* @__PURE__ */ jsx("div", {
6792
- className: "folio-root",
6793
- style: { display: "contents" },
6794
- children: /* @__PURE__ */ jsxs("div", {
6795
- role: "dialog",
6796
- "aria-label": open.kind === "dropdown" ? t("contentControlDropdownAriaLabel") : t("contentControlDateAriaLabel"),
6797
- style,
6798
- className: "bg-popover text-popover-foreground min-w-[10rem] rounded-md border p-1 shadow-md",
6799
- children: [open.kind === "dropdown" && /* @__PURE__ */ jsx("div", {
6800
- role: "menu",
6801
- className: "flex flex-col",
6802
- children: open.items.length === 0 ? /* @__PURE__ */ jsx("div", {
6803
- className: "text-muted-foreground px-2 py-1 text-sm",
6804
- children: t("contentControlDropdownNoOptions")
6805
- }) : open.items.map((item) => /* @__PURE__ */ jsx(ContentControlDropdownItem, {
6806
- item,
6807
- MenuItem,
6808
- onPick: onDropdownPick
6809
- }, `${item.value}::${item.displayText}`))
6810
- }), open.kind === "date" && /* @__PURE__ */ jsx(DatePickerPopover, {
6811
- clearLabel: t("clearDate"),
6812
- defaultOpen: true,
6813
- onChange: handleDateChange,
6814
- showIcon: false,
6815
- value: null
6816
- })]
6817
- })
6818
- }), document.body);
7250
+ $[9] = t7;
7251
+ $[10] = t8;
7252
+ $[11] = t9;
7253
+ } else t9 = $[11];
7254
+ const style = t9;
7255
+ let t10;
7256
+ if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
7257
+ t10 = { display: "contents" };
7258
+ $[12] = t10;
7259
+ } else t10 = $[12];
7260
+ let t11;
7261
+ if ($[13] !== snapshot.status || $[14] !== t) {
7262
+ t11 = snapshot.status === "dropdown" ? t("contentControlDropdownAriaLabel") : t("contentControlDateAriaLabel");
7263
+ $[13] = snapshot.status;
7264
+ $[14] = t;
7265
+ $[15] = t11;
7266
+ } else t11 = $[15];
7267
+ let t12;
7268
+ if ($[16] !== Menu || $[17] !== MenuItem || $[18] !== snapshot.items || $[19] !== snapshot.status || $[20] !== t) {
7269
+ t12 = snapshot.status === "dropdown" && /* @__PURE__ */ jsx(Menu, { children: /* @__PURE__ */ jsx("div", {
7270
+ role: "menu",
7271
+ className: "flex flex-col",
7272
+ children: snapshot.items.length === 0 ? /* @__PURE__ */ jsx("div", {
7273
+ className: "text-muted-foreground px-2 py-1 text-sm",
7274
+ children: t("contentControlDropdownNoOptions")
7275
+ }) : snapshot.items.map((item) => /* @__PURE__ */ jsx(ContentControlDropdownItem, {
7276
+ item,
7277
+ MenuItem,
7278
+ onPick: onDropdownPick
7279
+ }, `${item.value}::${item.displayText}`))
7280
+ }) });
7281
+ $[16] = Menu;
7282
+ $[17] = MenuItem;
7283
+ $[18] = snapshot.items;
7284
+ $[19] = snapshot.status;
7285
+ $[20] = t;
7286
+ $[21] = t12;
7287
+ } else t12 = $[21];
7288
+ let t13;
7289
+ if ($[22] !== DatePickerPopover || $[23] !== snapshot.currentValue || $[24] !== snapshot.status || $[25] !== t) {
7290
+ t13 = snapshot.status === "date" && /* @__PURE__ */ jsx(DatePickerPopover, {
7291
+ clearLabel: t("clearDate"),
7292
+ defaultOpen: true,
7293
+ onChange: onDateChange,
7294
+ showIcon: false,
7295
+ value: snapshot.currentValue
7296
+ });
7297
+ $[22] = DatePickerPopover;
7298
+ $[23] = snapshot.currentValue;
7299
+ $[24] = snapshot.status;
7300
+ $[25] = t;
7301
+ $[26] = t13;
7302
+ } else t13 = $[26];
7303
+ let t14;
7304
+ if ($[27] !== style || $[28] !== t11 || $[29] !== t12 || $[30] !== t13) {
7305
+ t14 = createPortal(/* @__PURE__ */ jsx("div", {
7306
+ className: "folio-root",
7307
+ style: t10,
7308
+ children: /* @__PURE__ */ jsxs("div", {
7309
+ role: "dialog",
7310
+ "aria-label": t11,
7311
+ style,
7312
+ className: "bg-popover text-popover-foreground min-w-[10rem] rounded-md border p-1 shadow-md",
7313
+ children: [t12, t13]
7314
+ })
7315
+ }), document.body);
7316
+ $[27] = style;
7317
+ $[28] = t11;
7318
+ $[29] = t12;
7319
+ $[30] = t13;
7320
+ $[31] = t14;
7321
+ } else t14 = $[31];
7322
+ return t14;
6819
7323
  }
6820
7324
  function ContentControlDropdownItem(t0) {
6821
7325
  const $ = c(7);
@@ -11843,7 +12347,7 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
11843
12347
  * - Error boundary
11844
12348
  * - Loading states
11845
12349
  */
11846
- const CommentsSidebar = lazy(() => import("./CommentsSidebar-DOSa22AJ.js").then((m) => ({ default: m.CommentsSidebar })));
12350
+ const CommentsSidebar = lazy(() => import("./CommentsSidebar-ml91aGZ1.js").then((m) => ({ default: m.CommentsSidebar })));
11847
12351
  const TextContextMenu = lazy(() => import("./TextContextMenu-Ci7-M4oU.js").then((m) => ({ default: m.TextContextMenu })));
11848
12352
  const loadAttemptSelectiveSave = async () => {
11849
12353
  const { attemptSelectiveSave } = await import("@stll/folio-core/docx/selectiveSave");
@@ -11905,7 +12409,7 @@ function areActiveTrackedChangesEqual(a, b) {
11905
12409
  /**
11906
12410
  * DocxEditor - Complete DOCX editor component
11907
12411
  */
11908
- const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, document: initialDocument, documentKey, onSave, author = "User", onChange, onSelectionChange, onSelectionTextChange, onError, onFontsLoaded: onFontsLoadedCallback, fontFamilies, fonts, theme, showToolbar = true, showZoomControl = true, showReviewControls = true, showHeaderFooterEditing = true, showMarginGuides: _showMarginGuides = false, marginGuideColor: _marginGuideColor, showRuler: showRulerProp = false, rulerUnit = "inch", initialZoom = 1, enableWheelZoom = true, 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: _onCopy, onCut: _onCut, onPaste: _onPaste, mode: modeProp, onModeChange, onReadonlyEditAttempt, onCompatibilityChange, onEditorViewReady, onAnonymizationMatchesChange, onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq, showTemplateDirectives = false, onSlashMenuChange, onSlashMenuKeyAction, customContextMenuItems, onCustomContextAction, comments: commentsProp, onCommentsChange, collaboration, featureFlags, onSelectiveSaveTripwire }, ref) {
12412
+ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, document: initialDocument, documentKey, onSave, author = "User", onChange, onSelectionChange, onSelectionTextChange, onError, onFontsLoaded: onFontsLoadedCallback, fontFamilies, fonts, theme, showToolbar = true, showZoomControl = true, showReviewControls = true, showHeaderFooterEditing = true, showMarginGuides = false, marginGuideColor, showRuler: showRulerProp = false, rulerUnit = "inch", initialZoom = 1, enableWheelZoom = true, 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, featureFlags, onSelectiveSaveTripwire }, ref) {
11909
12413
  const t = useTranslations("folio");
11910
12414
  useEffect(() => {
11911
12415
  const onClipboardReadError = () => {
@@ -12153,6 +12657,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12153
12657
  canRedo: false,
12154
12658
  canUndo: false
12155
12659
  });
12660
+ const [activeNoteStory, setActiveNoteStory] = useState(null);
12156
12661
  const toolbarRefCallback = useCallback((el) => {
12157
12662
  toolbarWrapperRef.current = el;
12158
12663
  if (toolbarRoRef.current) {
@@ -12190,28 +12695,42 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12190
12695
  pushDocument,
12191
12696
  getHfView: (rId) => pagedEditorRef.current?.getHfView(rId) ?? null
12192
12697
  });
12193
- const getActiveEditorView = useCallback(() => {
12194
- if (hfEditPosition && hfEditorRef.current) return hfEditorRef.current.getView();
12195
- return pagedEditorRef.current?.getView();
12196
- }, [hfEditPosition]);
12698
+ let activeHfRId = hfEditIsFirstPage ? activeFirstFooterRId : activeFooterRId;
12699
+ if (hfEditPosition === "header") activeHfRId = hfEditIsFirstPage ? activeFirstHeaderRId : activeHeaderRId;
12700
+ const getActiveEditorStory = useCallback(() => {
12701
+ return resolveActiveEditorStory({
12702
+ bodyView: pagedEditorRef.current?.getView() ?? null,
12703
+ headerFooterView: hfEditPosition && hfEditorRef.current ? hfEditorRef.current.getView() : null,
12704
+ noteView: activeNoteStory ? pagedEditorRef.current?.getActiveView() ?? null : null
12705
+ });
12706
+ }, [activeNoteStory, hfEditPosition]);
12707
+ const getActiveEditorView = useCallback(() => getActiveEditorStory().view, [getActiveEditorStory]);
12197
12708
  const focusActiveEditor = useCallback(() => {
12198
- if (hfEditPosition && hfEditorRef.current) hfEditorRef.current.focus();
12709
+ if (getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) hfEditorRef.current.focus();
12199
12710
  else pagedEditorRef.current?.focus();
12200
- }, [hfEditPosition]);
12711
+ }, [getActiveEditorStory]);
12201
12712
  const undoActiveEditor = useCallback(() => {
12202
- if (hfEditPosition && hfEditorRef.current) hfEditorRef.current.undo();
12713
+ if (getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) hfEditorRef.current.undo();
12203
12714
  else {
12204
12715
  pagedEditorRef.current?.undo();
12205
12716
  requestAnimationFrame(refreshBodyHistoryAvailability);
12206
12717
  }
12207
- }, [hfEditPosition, refreshBodyHistoryAvailability]);
12718
+ }, [getActiveEditorStory, refreshBodyHistoryAvailability]);
12208
12719
  const redoActiveEditor = useCallback(() => {
12209
- if (hfEditPosition && hfEditorRef.current) hfEditorRef.current.redo();
12720
+ if (getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) hfEditorRef.current.redo();
12210
12721
  else {
12211
12722
  pagedEditorRef.current?.redo();
12212
12723
  requestAnimationFrame(refreshBodyHistoryAvailability);
12213
12724
  }
12214
- }, [hfEditPosition, refreshBodyHistoryAvailability]);
12725
+ }, [getActiveEditorStory, refreshBodyHistoryAvailability]);
12726
+ const handleActiveNoteStoryChange = useCallback((story) => {
12727
+ setActiveNoteStory(story);
12728
+ if (story && hfEditPosition) handleBodyClick();
12729
+ }, [handleBodyClick, hfEditPosition]);
12730
+ const handleHeaderFooterStoryOpen = useCallback((position, pageNumber) => {
12731
+ pagedEditorRef.current?.closeNoteStory();
12732
+ handleHeaderFooterDoubleClick(position, pageNumber);
12733
+ }, [handleHeaderFooterDoubleClick]);
12215
12734
  const findReplace = useFindReplace$1();
12216
12735
  const [showPageSetup, setShowPageSetup] = useState(false);
12217
12736
  const { hyperlinkPopupData, handleHyperlinkClick, handleHyperlinkPopupNavigate, handleHyperlinkPopupCopy, handleHyperlinkPopupEdit, handleHyperlinkPopupRemove, handleHyperlinkPopupClose } = useHyperlinkHandlers({
@@ -12358,8 +12877,11 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12358
12877
  if (!history.state) return null;
12359
12878
  let doc_0 = structuredClone(history.state);
12360
12879
  const pmDoc = pagedEditorRef.current?.getDocument();
12361
- if (pmDoc) doc_0.package.document.content = pmDoc.package.document.content;
12362
- else doc_0 = normalizeBaseDirection(doc_0);
12880
+ if (pmDoc) {
12881
+ doc_0.package.document.content = pmDoc.package.document.content;
12882
+ if (pmDoc.package.footnotes !== void 0) doc_0.package.footnotes = pmDoc.package.footnotes;
12883
+ if (pmDoc.package.endnotes !== void 0) doc_0.package.endnotes = pmDoc.package.endnotes;
12884
+ } else doc_0 = normalizeBaseDirection(doc_0);
12363
12885
  const editor = pagedEditorRef.current;
12364
12886
  if (editor) {
12365
12887
  const flushBag = (bag) => {
@@ -13134,14 +13656,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13134
13656
  if (readOnly) return;
13135
13657
  const { from: from_7, to: to_7 } = view_12.state.selection;
13136
13658
  const text_2 = view_12.state.doc.textBetween(from_7, to_7, "\n");
13137
- navigator.clipboard.writeText(text_2);
13659
+ navigator.clipboard.writeText(text_2).catch(() => void 0);
13138
13660
  view_12.dispatch(view_12.state.tr.deleteSelection());
13661
+ onCut?.();
13139
13662
  break;
13140
13663
  }
13141
13664
  case "copy": {
13142
13665
  const { from: cf, to: ct } = view_12.state.selection;
13143
13666
  const copied = view_12.state.doc.textBetween(cf, ct, "\n");
13144
- navigator.clipboard.writeText(copied);
13667
+ navigator.clipboard.writeText(copied).catch(() => void 0);
13668
+ onCopy?.();
13145
13669
  break;
13146
13670
  }
13147
13671
  case "paste":
@@ -13166,7 +13690,10 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13166
13690
  } catch {
13167
13691
  try {
13168
13692
  const text_0 = await navigator.clipboard.readText();
13169
- if (text_0) view_12.dispatch(view_12.state.tr.insertText(text_0));
13693
+ if (text_0) {
13694
+ view_12.dispatch(view_12.state.tr.insertText(text_0));
13695
+ onPaste?.();
13696
+ }
13170
13697
  } catch {}
13171
13698
  }
13172
13699
  break;
@@ -13176,6 +13703,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13176
13703
  if (text && !view_12.isDestroyed) {
13177
13704
  const slice = buildPlainTextSlice(text, view_12.state.schema);
13178
13705
  view_12.dispatch(view_12.state.tr.replaceSelection(slice).scrollIntoView());
13706
+ onPaste?.();
13179
13707
  }
13180
13708
  } catch {
13181
13709
  toast(t("clipboardReadFailed"));
@@ -13249,6 +13777,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13249
13777
  getActiveEditorView,
13250
13778
  focusActiveEditor,
13251
13779
  onCustomContextAction,
13780
+ onCopy,
13781
+ onCut,
13782
+ onPaste,
13252
13783
  readOnly,
13253
13784
  contextMenu.selectionRange.from,
13254
13785
  contextMenu.selectionRange.to,
@@ -13385,8 +13916,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13385
13916
  },
13386
13917
  getCurrentPage: () => scrollPageInfo.currentPage,
13387
13918
  getTotalPages: () => scrollPageInfo.totalPages,
13388
- scrollToPage: (pageNumber) => {
13389
- pagedEditorRef.current?.scrollToPage(pageNumber);
13919
+ scrollToPage: (pageNumber_0) => {
13920
+ pagedEditorRef.current?.scrollToPage(pageNumber_0);
13390
13921
  },
13391
13922
  scrollToParaId: (paraId, options_0) => pagedEditorRef.current?.scrollToParaId(paraId, options_0) ?? false,
13392
13923
  openPrintPreview: handleDirectPrint,
@@ -13536,13 +14067,13 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13536
14067
  return rejectAIEditRevision(revisionId_0)(view_24.state, view_24.dispatch);
13537
14068
  },
13538
14069
  undo: () => {
13539
- if (hfEditPosition && hfEditorRef.current) return hfEditorRef.current.undo();
14070
+ if (getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) return hfEditorRef.current.undo();
13540
14071
  const undone = pagedEditorRef.current?.undo() ?? false;
13541
14072
  requestAnimationFrame(refreshBodyHistoryAvailability);
13542
14073
  return undone;
13543
14074
  },
13544
14075
  redo: () => {
13545
- if (hfEditPosition && hfEditorRef.current) return hfEditorRef.current.redo();
14076
+ if (getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) return hfEditorRef.current.redo();
13546
14077
  const redone = pagedEditorRef.current?.redo() ?? false;
13547
14078
  requestAnimationFrame(refreshBodyHistoryAvailability);
13548
14079
  return redone;
@@ -13579,104 +14110,141 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13579
14110
  });
13580
14111
  return true;
13581
14112
  },
13582
- showInDocument: (target_1, snapshot_2) => {
14113
+ highlightPassage: ({ blockId: blockId_0, text: text_5, snapshot: snapshot_2 }) => {
13583
14114
  const view_27 = pagedEditorRef.current?.getView();
13584
- if (!view_27) return false;
13585
- const range_4 = target_1.type === "textRange" ? resolveFolioAITextRange({
13586
- range: target_1,
14115
+ if (!view_27) return "none";
14116
+ const passageRange = resolvePassageRange({
14117
+ blockId: blockId_0,
14118
+ text: text_5,
13587
14119
  doc: view_27.state.doc,
13588
14120
  snapshot: snapshot_2
13589
- }) : resolveFolioAIBlockRange({
13590
- blockId: target_1.blockId,
14121
+ });
14122
+ if (passageRange !== null) {
14123
+ pagedEditorRef.current?.setPassageHighlight(passageRange);
14124
+ requestAnimationFrame(() => {
14125
+ pagedEditorRef.current?.scrollToPosition(passageRange.from);
14126
+ });
14127
+ return "passage";
14128
+ }
14129
+ pagedEditorRef.current?.setPassageHighlight(null);
14130
+ const blockRange = resolveFolioAIBlockRange({
14131
+ blockId: blockId_0,
13591
14132
  doc: view_27.state.doc,
13592
14133
  snapshot: snapshot_2
13593
14134
  });
13594
- if (range_4 === null) return false;
13595
- const { from: from_10, to: to_10 } = range_4;
14135
+ if (blockRange === null) return "none";
14136
+ const paraId_0 = getFolioParaIdFromBlockId(blockId_0);
14137
+ if (paraId_0 !== null && pagedEditorRef.current?.scrollToParaId(paraId_0, { highlight: {} })) return "block";
14138
+ const { from: from_10, to: to_10 } = blockRange;
13596
14139
  const $from_1 = view_27.state.doc.resolve(from_10);
13597
14140
  const $to_1 = view_27.state.doc.resolve(to_10);
13598
14141
  view_27.dispatch(view_27.state.tr.setSelection(TextSelection.between($from_1, $to_1)));
13599
14142
  requestAnimationFrame(() => {
13600
14143
  pagedEditorRef.current?.scrollToPosition(from_10);
13601
14144
  });
13602
- return true;
14145
+ return "block";
13603
14146
  },
13604
- getTrackedChanges: () => {
14147
+ clearPassageHighlight: () => {
14148
+ pagedEditorRef.current?.setPassageHighlight(null);
14149
+ },
14150
+ showInDocument: (target_1, snapshot_3) => {
13605
14151
  const view_28 = pagedEditorRef.current?.getView();
13606
- return view_28 ? getTrackedChangesFromDoc(view_28.state.doc) : [];
14152
+ if (!view_28) return false;
14153
+ const range_4 = target_1.type === "textRange" ? resolveFolioAITextRange({
14154
+ range: target_1,
14155
+ doc: view_28.state.doc,
14156
+ snapshot: snapshot_3
14157
+ }) : resolveFolioAIBlockRange({
14158
+ blockId: target_1.blockId,
14159
+ doc: view_28.state.doc,
14160
+ snapshot: snapshot_3
14161
+ });
14162
+ if (range_4 === null) return false;
14163
+ const { from: from_11, to: to_11 } = range_4;
14164
+ const $from_2 = view_28.state.doc.resolve(from_11);
14165
+ const $to_2 = view_28.state.doc.resolve(to_11);
14166
+ view_28.dispatch(view_28.state.tr.setSelection(TextSelection.between($from_2, $to_2)));
14167
+ requestAnimationFrame(() => {
14168
+ pagedEditorRef.current?.scrollToPosition(from_11);
14169
+ });
14170
+ return true;
13607
14171
  },
13608
- getCommentAnchors: () => {
14172
+ getTrackedChanges: () => {
13609
14173
  const view_29 = pagedEditorRef.current?.getView();
13610
- return view_29 ? getCommentAnchorsFromDoc(view_29.state.doc) : [];
14174
+ return view_29 ? getTrackedChangesFromDoc(view_29.state.doc) : [];
13611
14175
  },
13612
- getSelectionText: () => {
14176
+ getCommentAnchors: () => {
13613
14177
  const view_30 = pagedEditorRef.current?.getView();
13614
- return view_30 ? getSelectedText(view_30.state) : "";
14178
+ return view_30 ? getCommentAnchorsFromDoc(view_30.state.doc) : [];
13615
14179
  },
13616
- getPageText: (page_0) => {
14180
+ getSelectionText: () => {
13617
14181
  const view_31 = pagedEditorRef.current?.getView();
13618
- if (!view_31) return null;
13619
- return getPageTextFromLayout(pagedEditorRef.current?.getEditor()?.getLayout() ?? null, view_31.state.doc, page_0);
14182
+ return view_31 ? getSelectedText(view_31.state) : "";
13620
14183
  },
13621
- getTargetPage: (target_2, snapshot_3) => {
14184
+ getPageText: (page_0) => {
13622
14185
  const view_32 = pagedEditorRef.current?.getView();
13623
14186
  if (!view_32) return null;
14187
+ return getPageTextFromLayout(pagedEditorRef.current?.getEditor()?.getLayout() ?? null, view_32.state.doc, page_0);
14188
+ },
14189
+ getTargetPage: (target_2, snapshot_4) => {
14190
+ const view_33 = pagedEditorRef.current?.getView();
14191
+ if (!view_33) return null;
13624
14192
  const range_5 = target_2.type === "textRange" ? resolveFolioAITextRange({
13625
14193
  range: target_2,
13626
- doc: view_32.state.doc,
13627
- snapshot: snapshot_3
14194
+ doc: view_33.state.doc,
14195
+ snapshot: snapshot_4
13628
14196
  }) : resolveFolioAIBlockRange({
13629
14197
  blockId: target_2.blockId,
13630
- doc: view_32.state.doc,
13631
- snapshot: snapshot_3
14198
+ doc: view_33.state.doc,
14199
+ snapshot: snapshot_4
13632
14200
  });
13633
14201
  if (range_5 === null) return null;
13634
14202
  return pagedEditorRef.current?.getPageNumberForPmPos(range_5.from) ?? null;
13635
14203
  },
13636
14204
  getContentControls: (filter = {}) => {
13637
- const view_33 = pagedEditorRef.current?.getView();
13638
- if (!view_33) return [];
13639
- return findBlockSdtMatches(view_33.state.doc, filter).map((match_0) => ({
14205
+ const view_34 = pagedEditorRef.current?.getView();
14206
+ if (!view_34) return [];
14207
+ return findBlockSdtMatches(view_34.state.doc, filter).map((match_0) => ({
13640
14208
  properties: blockSdtAttrsToSdtProperties(match_0.node),
13641
14209
  path: match_0.path,
13642
14210
  pmPos: match_0.pos
13643
14211
  }));
13644
14212
  },
13645
14213
  scrollToContentControl: (filter_0) => {
13646
- const view_34 = pagedEditorRef.current?.getView();
13647
- if (!view_34) return false;
13648
- const match_1 = findBlockSdtMatch(view_34.state.doc, filter_0);
14214
+ const view_35 = pagedEditorRef.current?.getView();
14215
+ if (!view_35) return false;
14216
+ const match_1 = findBlockSdtMatch(view_35.state.doc, filter_0);
13649
14217
  if (!match_1) return false;
13650
14218
  const inside = match_1.pos + 1;
13651
- const $pos = view_34.state.doc.resolve(inside);
13652
- view_34.dispatch(view_34.state.tr.setSelection(TextSelection.near($pos)));
14219
+ const $pos = view_35.state.doc.resolve(inside);
14220
+ view_35.dispatch(view_35.state.tr.setSelection(TextSelection.near($pos)));
13653
14221
  requestAnimationFrame(() => {
13654
14222
  pagedEditorRef.current?.scrollToPosition(inside);
13655
14223
  });
13656
14224
  return true;
13657
14225
  },
13658
14226
  setContentControlContent: (filter_1, input, options_2 = {}) => {
13659
- const view_35 = pagedEditorRef.current?.getView();
13660
- if (!view_35) return false;
13661
- const tr_0 = typeof input === "string" ? setContentControlContentTr(view_35.state, filter_1, input, options_2) : setContentControlContentBlocksTr(view_35.state, filter_1, input, options_2);
14227
+ const view_36 = pagedEditorRef.current?.getView();
14228
+ if (!view_36) return false;
14229
+ const tr_0 = typeof input === "string" ? setContentControlContentTr(view_36.state, filter_1, input, options_2) : setContentControlContentBlocksTr(view_36.state, filter_1, input, options_2);
13662
14230
  if (!tr_0) return false;
13663
- view_35.dispatch(tr_0);
14231
+ view_36.dispatch(tr_0);
13664
14232
  return true;
13665
14233
  },
13666
14234
  setContentControlValue: (filter_2, input_0, options_3 = {}) => {
13667
- const view_36 = pagedEditorRef.current?.getView();
13668
- if (!view_36) return false;
13669
- const tr_1 = setContentControlValueTr(view_36.state, filter_2, input_0, options_3);
14235
+ const view_37 = pagedEditorRef.current?.getView();
14236
+ if (!view_37) return false;
14237
+ const tr_1 = setContentControlValueTr(view_37.state, filter_2, input_0, options_3);
13670
14238
  if (!tr_1) return false;
13671
- view_36.dispatch(tr_1);
14239
+ view_37.dispatch(tr_1);
13672
14240
  return true;
13673
14241
  },
13674
14242
  removeContentControl: (filter_3, options_4 = {}) => {
13675
- const view_37 = pagedEditorRef.current?.getView();
13676
- if (!view_37) return false;
13677
- const tr_2 = removeContentControlTr(view_37.state, filter_3, options_4);
14243
+ const view_38 = pagedEditorRef.current?.getView();
14244
+ if (!view_38) return false;
14245
+ const tr_2 = removeContentControlTr(view_38.state, filter_3, options_4);
13678
14246
  if (!tr_2) return false;
13679
- view_37.dispatch(tr_2);
14247
+ view_38.dispatch(tr_2);
13680
14248
  return true;
13681
14249
  }
13682
14250
  }), [
@@ -13693,7 +14261,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13693
14261
  replaceComments,
13694
14262
  commentsRef,
13695
14263
  commentsDirtyRef,
13696
- hfEditPosition,
14264
+ getActiveEditorStory,
13697
14265
  refreshBodyHistoryAvailability
13698
14266
  ]);
13699
14267
  const getHfTargetElement = useCallback((pos_0) => {
@@ -13706,6 +14274,17 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13706
14274
  value: mode_0,
13707
14275
  label: t(DISPLAY_MODE_LABEL_KEYS[mode_0])
13708
14276
  })), [t]);
14277
+ const activeHistoryAvailability = (() => {
14278
+ if (activeNoteStory) return {
14279
+ canRedo: pagedEditorRef.current?.canRedo() ?? false,
14280
+ canUndo: pagedEditorRef.current?.canUndo() ?? false
14281
+ };
14282
+ if (hfEditPosition) return {
14283
+ canRedo: history.canRedo,
14284
+ canUndo: history.canUndo
14285
+ };
14286
+ return bodyHistoryAvailability;
14287
+ })();
13709
14288
  const toolbarChildren = toolbarExtra ?? null;
13710
14289
  const visibleCommentAuthorCount = commentAuthors.filter((commentAuthor) => visibleCommentAuthorSet.has(commentAuthor)).length;
13711
14290
  const allCommentAuthorsVisible = commentAuthors.length > 0 && showCommentsSidebar && visibleCommentAuthorCount === commentAuthors.length;
@@ -13747,39 +14326,39 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13747
14326
  if (isDisplayMode(value)) setDisplayMode(value);
13748
14327
  }, [setDisplayMode]);
13749
14328
  const handleAcceptActiveChange = useCallback(() => {
13750
- const view_38 = pagedEditorRef.current?.getView();
13751
- if (!view_38) return;
13752
- const { from: from_11, to: to_11 } = view_38.state.selection;
13753
- const range_6 = findChangeAtPosition(view_38.state, from_11, to_11);
13754
- acceptChange(range_6.from, range_6.to)(view_38.state, view_38.dispatch);
13755
- }, []);
13756
- const handleRejectActiveChange = useCallback(() => {
13757
14329
  const view_39 = pagedEditorRef.current?.getView();
13758
14330
  if (!view_39) return;
13759
14331
  const { from: from_12, to: to_12 } = view_39.state.selection;
13760
- const range_7 = findChangeAtPosition(view_39.state, from_12, to_12);
13761
- rejectChange(range_7.from, range_7.to)(view_39.state, view_39.dispatch);
14332
+ const range_6 = findChangeAtPosition(view_39.state, from_12, to_12);
14333
+ acceptChange(range_6.from, range_6.to)(view_39.state, view_39.dispatch);
13762
14334
  }, []);
13763
- const handlePreviousChange = useCallback(() => {
14335
+ const handleRejectActiveChange = useCallback(() => {
13764
14336
  const view_40 = pagedEditorRef.current?.getView();
13765
14337
  if (!view_40) return;
13766
- const { from: from_13 } = view_40.state.selection;
13767
- const change = findPreviousChange(view_40.state, from_13);
14338
+ const { from: from_13, to: to_13 } = view_40.state.selection;
14339
+ const range_7 = findChangeAtPosition(view_40.state, from_13, to_13);
14340
+ rejectChange(range_7.from, range_7.to)(view_40.state, view_40.dispatch);
14341
+ }, []);
14342
+ const handlePreviousChange = useCallback(() => {
14343
+ const view_41 = pagedEditorRef.current?.getView();
14344
+ if (!view_41) return;
14345
+ const { from: from_14 } = view_41.state.selection;
14346
+ const change = findPreviousChange(view_41.state, from_14);
13768
14347
  if (!change) return;
13769
- view_40.dispatch(view_40.state.tr.setSelection(TextSelection.create(view_40.state.doc, change.from, change.to)));
13770
- view_40.focus();
14348
+ view_41.dispatch(view_41.state.tr.setSelection(TextSelection.create(view_41.state.doc, change.from, change.to)));
14349
+ view_41.focus();
13771
14350
  requestAnimationFrame(() => {
13772
14351
  pagedEditorRef.current?.scrollToPosition(change.from);
13773
14352
  });
13774
14353
  }, []);
13775
14354
  const handleNextChange = useCallback(() => {
13776
- const view_41 = pagedEditorRef.current?.getView();
13777
- if (!view_41) return;
13778
- const { to: to_13 } = view_41.state.selection;
13779
- const change_0 = findNextChange(view_41.state, to_13);
14355
+ const view_42 = pagedEditorRef.current?.getView();
14356
+ if (!view_42) return;
14357
+ const { to: to_14 } = view_42.state.selection;
14358
+ const change_0 = findNextChange(view_42.state, to_14);
13780
14359
  if (!change_0) return;
13781
- view_41.dispatch(view_41.state.tr.setSelection(TextSelection.create(view_41.state.doc, change_0.from, change_0.to)));
13782
- view_41.focus();
14360
+ view_42.dispatch(view_42.state.tr.setSelection(TextSelection.create(view_42.state.doc, change_0.from, change_0.to)));
14361
+ view_42.focus();
13783
14362
  requestAnimationFrame(() => {
13784
14363
  pagedEditorRef.current?.scrollToPosition(change_0.from);
13785
14364
  });
@@ -13949,8 +14528,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13949
14528
  requestAnimationFrame(syncCommentHighlightStyles);
13950
14529
  }, [onScrollTopChange, syncCommentHighlightStyles]);
13951
14530
  const handlePagedSelectionChange = useCallback((_from, _to) => {
13952
- const view_42 = getActiveEditorView() ?? pagedEditorRef.current?.getView() ?? null;
13953
- handleSelectionChange(view_42 ? extractSelectionState(view_42.state) : null);
14531
+ const view_43 = getActiveEditorView() ?? pagedEditorRef.current?.getView() ?? null;
14532
+ handleSelectionChange(view_43 ? extractSelectionState(view_43.state) : null);
13954
14533
  }, [getActiveEditorView, handleSelectionChange]);
13955
14534
  const handleTotalPagesChange = useCallback((totalPages) => {
13956
14535
  setScrollPageInfo((previous) => updateScrollPageTotal(previous, totalPages));
@@ -13970,14 +14549,14 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13970
14549
  setActiveCommentId,
13971
14550
  updateComments
13972
14551
  ]);
13973
- const handleCommentReply = useCallback((id_2, text_5) => {
13974
- updateComments((previous_2) => [...previous_2, createComment(text_5, author, id_2)]);
14552
+ const handleCommentReply = useCallback((id_2, text_6) => {
14553
+ updateComments((previous_2) => [...previous_2, createComment(text_6, author, id_2)]);
13975
14554
  }, [author, updateComments]);
13976
14555
  const handleAddComment = useCallback((addText) => {
13977
14556
  const comment_3 = createComment(addText, author);
13978
- const view_43 = pagedEditorRef.current?.getView();
13979
- if (!view_43 || !commentSelectionRange) return false;
13980
- if (!applyCommentMarkRange(view_43, commentSelectionRange, comment_3.id, { replacePending: true })) return false;
14557
+ const view_44 = pagedEditorRef.current?.getView();
14558
+ if (!view_44 || !commentSelectionRange) return false;
14559
+ if (!applyCommentMarkRange(view_44, commentSelectionRange, comment_3.id, { replacePending: true })) return false;
13981
14560
  const commentAuthor_2 = getCommentAuthorKey(comment_3.author);
13982
14561
  setVisibleCommentAuthors((current) => {
13983
14562
  if (current === null) return null;
@@ -14007,12 +14586,12 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14007
14586
  syncCommentHighlightStyles,
14008
14587
  updateComments
14009
14588
  ]);
14010
- const handleTrackedChangeReply = useCallback((revisionId_2, text_6) => {
14011
- updateComments((previous_4) => [...previous_4, createComment(text_6, author, revisionId_2)]);
14589
+ const handleTrackedChangeReply = useCallback((revisionId_2, text_7) => {
14590
+ updateComments((previous_4) => [...previous_4, createComment(text_7, author, revisionId_2)]);
14012
14591
  }, [author, updateComments]);
14013
14592
  const handleCancelAddComment = useCallback(() => {
14014
- const view_44 = pagedEditorRef.current?.getView();
14015
- if (view_44 && commentSelectionRange) removePendingCommentMarkRange(view_44, commentSelectionRange);
14593
+ const view_45 = pagedEditorRef.current?.getView();
14594
+ if (view_45 && commentSelectionRange) removePendingCommentMarkRange(view_45, commentSelectionRange);
14016
14595
  setIsAddingComment(false);
14017
14596
  setCommentSelectionRange(null);
14018
14597
  setAddCommentYPosition(null);
@@ -14022,16 +14601,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14022
14601
  setCommentSelectionRange,
14023
14602
  setIsAddingComment
14024
14603
  ]);
14025
- const handleSidebarAcceptChange = useCallback((from_14, to_14) => {
14026
- const view_45 = pagedEditorRef.current?.getView();
14027
- if (!view_45) return;
14028
- acceptChange(from_14, to_14)(view_45.state, view_45.dispatch);
14029
- extractTrackedChanges();
14030
- }, [extractTrackedChanges]);
14031
- const handleSidebarRejectChange = useCallback((from_15, to_15) => {
14604
+ const handleSidebarAcceptChange = useCallback((from_15, to_15) => {
14032
14605
  const view_46 = pagedEditorRef.current?.getView();
14033
14606
  if (!view_46) return;
14034
- rejectChange(from_15, to_15)(view_46.state, view_46.dispatch);
14607
+ acceptChange(from_15, to_15)(view_46.state, view_46.dispatch);
14608
+ extractTrackedChanges();
14609
+ }, [extractTrackedChanges]);
14610
+ const handleSidebarRejectChange = useCallback((from_16, to_16) => {
14611
+ const view_47 = pagedEditorRef.current?.getView();
14612
+ if (!view_47) return;
14613
+ rejectChange(from_16, to_16)(view_47.state, view_47.dispatch);
14035
14614
  extractTrackedChanges();
14036
14615
  }, [extractTrackedChanges]);
14037
14616
  const commentsPageWidth = history.state?.package.document.finalSectionProperties?.pageWidth;
@@ -14077,8 +14656,6 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14077
14656
  showCommentsSidebar,
14078
14657
  visibleComments
14079
14658
  ]);
14080
- let activeHfRId = hfEditIsFirstPage ? activeFirstFooterRId : activeFooterRId;
14081
- if (hfEditPosition === "header") activeHfRId = hfEditIsFirstPage ? activeFirstHeaderRId : activeHeaderRId;
14082
14659
  const getActiveHfView = useCallback(() => activeHfRId ? pagedEditorRef.current?.getHfView(activeHfRId) ?? null : null, [activeHfRId]);
14083
14660
  const handleOutlineHeadingClick = useCallback((pmPos) => {
14084
14661
  pagedEditorRef.current?.scrollToPosition(pmPos);
@@ -14102,10 +14679,15 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14102
14679
  handleContextMenuAction(action_3);
14103
14680
  }, [handleContextMenuAction]);
14104
14681
  const getBodyEditorView = useCallback(() => pagedEditorRef.current?.getView() ?? null, []);
14682
+ const getContentControlEventRoot = useCallback(() => {
14683
+ if (readOnly) return null;
14684
+ const root = containerRef.current?.querySelector(".paged-editor__pages");
14685
+ return root instanceof HTMLElement ? root : null;
14686
+ }, [readOnly]);
14105
14687
  const closeTableProperties = useCallback(() => setTablePropsOpen(false), []);
14106
14688
  const applyTableProperties = useCallback((props_0) => {
14107
- const view_47 = getActiveEditorView();
14108
- if (view_47) setTableProperties(props_0)(view_47.state, view_47.dispatch);
14689
+ const view_48 = getActiveEditorView();
14690
+ if (view_48) setTableProperties(props_0)(view_48.state, view_48.dispatch);
14109
14691
  }, [getActiveEditorView]);
14110
14692
  const closeImagePosition = useCallback(() => setImagePositionOpen(false), [setImagePositionOpen]);
14111
14693
  const closeImageProperties = useCallback(() => setImagePropsOpen(false), [setImagePropsOpen]);
@@ -14113,8 +14695,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14113
14695
  const closeFootnoteProperties = useCallback(() => setFootnotePropsOpen(false), []);
14114
14696
  const closeInsertSymbol = useCallback(() => setShowInsertSymbol(false), []);
14115
14697
  const insertSymbol = useCallback((symbol) => {
14116
- const view_48 = getActiveEditorView();
14117
- if (view_48) view_48.dispatch(view_48.state.tr.insertText(symbol).scrollIntoView());
14698
+ const view_49 = getActiveEditorView();
14699
+ if (view_49) view_49.dispatch(view_49.state.tr.insertText(symbol).scrollIntoView());
14118
14700
  }, [getActiveEditorView]);
14119
14701
  const imagePropertiesCurrentData = useMemo(() => buildImagePropertiesData(state.pmImageContext), [state.pmImageContext]);
14120
14702
  const currentFindResult = findResultRef.current;
@@ -14281,8 +14863,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14281
14863
  onFormat: handleFormat,
14282
14864
  onUndo: undoActiveEditor,
14283
14865
  onRedo: redoActiveEditor,
14284
- canUndo: hfEditPosition ? history.canUndo : bodyHistoryAvailability.canUndo,
14285
- canRedo: hfEditPosition ? history.canRedo : bodyHistoryAvailability.canRedo,
14866
+ canUndo: activeHistoryAvailability.canUndo,
14867
+ canRedo: activeHistoryAvailability.canRedo,
14286
14868
  disabled: readOnly,
14287
14869
  theme: history.state.package.theme || theme || null,
14288
14870
  fontFamilies,
@@ -14405,13 +14987,22 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14405
14987
  firstPageHeaderContentRId: activeFirstHeaderRId,
14406
14988
  firstPageFooterContentRId: activeFirstFooterRId,
14407
14989
  ...history.state.package.styles ? { styles: history.state.package.styles } : {},
14408
- onHeaderFooterDoubleClick: showHeaderFooterEditing ? handleHeaderFooterDoubleClick : void 0,
14990
+ onHeaderFooterDoubleClick: showHeaderFooterEditing ? handleHeaderFooterStoryOpen : void 0,
14409
14991
  hfEditMode: hfEditPosition,
14992
+ activeHeaderFooterRId: activeHfRId,
14410
14993
  onBodyClick: handleBodyClick,
14994
+ onActiveNoteStoryChange: handleActiveNoteStoryChange,
14411
14995
  zoom,
14996
+ showMarginGuides,
14997
+ ...marginGuideColor !== void 0 ? { marginGuideColor } : {},
14412
14998
  readOnly,
14413
14999
  onDocumentChange: handleDocumentChange,
14414
15000
  extensionManager,
15001
+ suggestionModeActive: editingMode === "suggesting",
15002
+ suggestionAuthor: author,
15003
+ ...onCopy !== void 0 ? { onCopy } : {},
15004
+ ...onCut !== void 0 ? { onCut } : {},
15005
+ ...onPaste !== void 0 ? { onPaste } : {},
14415
15006
  ...onReadonlyEditAttempt !== void 0 ? { onReadOnlyEditAttempt: onReadonlyEditAttempt } : {},
14416
15007
  onSelectionChange: handlePagedSelectionChange,
14417
15008
  ...onSelectionTextChange !== void 0 ? { onSelectionTextChange } : {},
@@ -14440,8 +15031,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14440
15031
  onMouseDown: (e_1) => {
14441
15032
  e_1.preventDefault();
14442
15033
  e_1.stopPropagation();
14443
- const view_49 = pagedEditorRef.current?.getView();
14444
- if (!view_49) {
15034
+ const view_50 = pagedEditorRef.current?.getView();
15035
+ if (!view_50) {
14445
15036
  setFloatingCommentBtn(null);
14446
15037
  return;
14447
15038
  }
@@ -14449,9 +15040,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14449
15040
  from: floatingCommentBtn.from,
14450
15041
  to: floatingCommentBtn.to
14451
15042
  };
14452
- const currentSelection = view_49.state.selection;
15043
+ const currentSelection = view_50.state.selection;
14453
15044
  const safeRange = resolveCommentCreationRange({
14454
- docSize: view_49.state.doc.content.size,
15045
+ docSize: view_50.state.doc.content.size,
14455
15046
  capturedRange,
14456
15047
  currentRange: {
14457
15048
  from: currentSelection.from,
@@ -14465,7 +15056,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14465
15056
  return;
14466
15057
  }
14467
15058
  setCommentSelectionRange(safeRange);
14468
- if (!applyCommentMarkRange(view_49, safeRange, -1, { selectEnd: true })) {
15059
+ if (!applyCommentMarkRange(view_50, safeRange, -1, { selectEnd: true })) {
14469
15060
  setCommentSelectionRange(null);
14470
15061
  setFloatingCommentBtn(null);
14471
15062
  return;
@@ -14595,7 +15186,10 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14595
15186
  onClose: handleContextMenuClose
14596
15187
  })
14597
15188
  }),
14598
- /* @__PURE__ */ jsx(ContentControlWidgetsOverlay, { getEditorView: getBodyEditorView }),
15189
+ /* @__PURE__ */ jsx(ContentControlWidgetsOverlay, {
15190
+ getEventRoot: getContentControlEventRoot,
15191
+ getEditorView: getBodyEditorView
15192
+ }),
14599
15193
  /* @__PURE__ */ jsx(DocxEditorDialogs, {
14600
15194
  findReplace: findReplaceDialog,
14601
15195
  tableProperties: tablePropertiesDialog,