@stll/folio-react 0.24.1 → 0.24.2
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.
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { f as containedHandler, u as useDrawerFocus } from "./renderAsync-
|
|
1
|
+
import { f as containedHandler, u as useDrawerFocus } from "./renderAsync-6eWf0MfZ.js";
|
|
2
2
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { CheckIcon, MoreVerticalIcon } from "lucide-react";
|
|
4
4
|
import { useLocale, useTranslations } from "use-intl";
|
|
5
|
+
import { scrollEditorTo } from "@stll/folio-core/paged-layout/editorScrollRoot";
|
|
5
6
|
import { closestHtmlElement, queryHtmlElement } from "@stll/folio-core/utils/domGuards";
|
|
6
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
8
|
import { PANEL_METRICS } from "@stll/folio-core/panel-layout";
|
|
@@ -369,7 +370,10 @@ const CommentsSidebar = ({ comments, onCommentClick, activeCommentId = null, onC
|
|
|
369
370
|
const scrollEl_1 = editorContainerRef?.current;
|
|
370
371
|
const anchorY = lastKnownCardPositionsRef.current.get(cardId_1) ?? anchorPositions?.get(cardId_1);
|
|
371
372
|
if (!scrollEl_1 || anchorY === void 0) return;
|
|
372
|
-
scrollEl_1
|
|
373
|
+
scrollEditorTo(scrollEl_1, {
|
|
374
|
+
top: Math.max(0, anchorY - scrollEl_1.clientHeight / 3),
|
|
375
|
+
behavior: "instant"
|
|
376
|
+
});
|
|
373
377
|
};
|
|
374
378
|
const hasPositions = !isDrawer && cardPositions.size > 0;
|
|
375
379
|
const avatarStyle = (name, size = 28) => ({
|
package/dist/compat/eigenpal.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as DocxEditor$1, t as renderAsync } from "../renderAsync-
|
|
1
|
+
import { n as DocxEditor$1, t as renderAsync } from "../renderAsync-6eWf0MfZ.js";
|
|
2
2
|
import { t as messages_exports } from "../messages.js";
|
|
3
3
|
import { c } from "react-compiler-runtime";
|
|
4
4
|
import { forwardRef } from "react";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as formatZoom, c as FormattingBar, d as AutocompleteCaretOverlay, i as clampZoom, l as ZoomControl, n as DocxEditor, o as parseZoom, r as ZOOM_PRESETS, s as useWheelZoom, t as renderAsync } from "./renderAsync-
|
|
1
|
+
import { a as formatZoom, c as FormattingBar, d as AutocompleteCaretOverlay, i as clampZoom, l as ZoomControl, n as DocxEditor, o as parseZoom, r as ZOOM_PRESETS, s as useWheelZoom, t as renderAsync } from "./renderAsync-6eWf0MfZ.js";
|
|
2
2
|
import { n as FolioUIProvider } from "./folio-ui-DO95voaI.js";
|
|
3
3
|
import { t as FindReplaceDialog } from "./FindReplaceDialog-BUwFQWaq.js";
|
|
4
4
|
import { t as FootnotePropertiesDialog } from "./FootnotePropertiesDialog-6XdO0zBH.js";
|
|
@@ -14,6 +14,7 @@ import { cloneDocumentWithParagraphPropertySources } from "@stll/folio-core/docx
|
|
|
14
14
|
import { normalizeBaseDirection } from "@stll/folio-core/docx/normalizeBaseDirection";
|
|
15
15
|
import { getCachedNumberingMap } from "@stll/folio-core/docx/numberingParser";
|
|
16
16
|
import { classifyEditorKeydown, deleteSelectedTable, historyShortcutOwner, isFocusInInputLike, isKeydownInShortcutScope, isMacPlatform } from "@stll/folio-core/managers/editorShortcuts";
|
|
17
|
+
import { getEditorScrollRoot, scrollEditorBy, scrollEditorElementIntoView, scrollEditorTo } from "@stll/folio-core/paged-layout/editorScrollRoot";
|
|
17
18
|
import { computeScrollPageInfo, updateScrollPageTotal } from "@stll/folio-core/paged-layout/scrollPageInfo";
|
|
18
19
|
import { NO_LIST_STATE, TextSelection, addColumnLeft, addColumnRight, addRowAbove, addRowBelow, applyFormatMarks, applyStyle, applyTableStyle, autoFitContents, captureFormatMarks, clearFormatting, clearTextColor, continueNumbering, createStyleResolver, decreaseIndent, decreaseListLevel, deleteColumn, deleteRow, deleteTable, distributeColumns, extractSelectionState, getDocumentBuiltInStyles, getSelectedText, getTableContext, increaseIndent, increaseListLevel, listStateLevel, mergeCells, removeTabStop, removeTableBorders, restartNumbering, sameListState, schema, selectColumn, selectRow, selectTable, setAlignment, setAllTableBorders, setCellBorder, setCellFillColor, setCellMargins, setCellTextDirection, setCellVerticalAlign, setFontFamily, setFontSize, setHighlight, setIndentFirstLine, setIndentLeft, setIndentRight, setInsideTableBorders, setLineSpacing, setLtr, setNumberingValue, setOutsideTableBorders, setRowHeight, setRtl, setTableBorderColor, setTableBorderPreset, setTableBorderWidth, setTableProperties, setTextColor, splitCell, toggleBidi, toggleBold, toggleBulletList, toggleHeaderRow, toggleItalic, toggleNoWrap, toggleNumberedList, toggleStrike, toggleSubscript, toggleSuperscript, toggleUnderline } from "@stll/folio-core/prosemirror";
|
|
19
20
|
import { acceptAIEditRevision, acceptChange, acceptSuggestion, findAIEditRevisionRange, findChangeAtPosition, findNextChange, findParagraphBoundaryChangeAtPosition, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectChange, rejectSuggestion } from "@stll/folio-core/prosemirror/commands/comments";
|
|
@@ -80,7 +81,7 @@ import { onPaintedLayoutChange, readBlockRects } from "@stll/folio-core/paged-la
|
|
|
80
81
|
import { LayoutSelectionGate } from "@stll/folio-core/paged-layout/LayoutSelectionGate";
|
|
81
82
|
import { collectRunFontsAtPmPositions, measureDirectiveGutter, projectRangesToRects } from "@stll/folio-core/paged-layout/rangeProjection";
|
|
82
83
|
import { isReadOnlyEditKey } from "@stll/folio-core/paged-layout/readOnlyEditAttempt";
|
|
83
|
-
import { getPageScrollTarget
|
|
84
|
+
import { getPageScrollTarget } from "@stll/folio-core/paged-layout/scrollNavigation";
|
|
84
85
|
import { PAGES_CONTAINER_CLASS, scrollPagesToPmPosition } from "@stll/folio-core/paged-layout/scrollToPmPosition";
|
|
85
86
|
import { flashParagraphFragmentsByParaId } from "@stll/folio-core/paged-layout/paragraphFlash";
|
|
86
87
|
import { resizeColumnPair } from "@stll/folio-core/paged-layout/tableColumnResize";
|
|
@@ -96,6 +97,7 @@ import { createVisualLineState, handleVisualLineKeyDown } from "@stll/folio-core
|
|
|
96
97
|
import { clampRangeToDocSize, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange } from "@stll/folio-core/ai-edits/blockRange";
|
|
97
98
|
import { getFolioParaIdFromBlockId } from "@stll/folio-core/types/block-id";
|
|
98
99
|
import { getPageTextFromLayout } from "@stll/folio-core/paged-layout/pageText";
|
|
100
|
+
import { allocateCommentId, seedCommentIdAbove } from "@stll/folio-core/prosemirror/commentIdAllocator";
|
|
99
101
|
import { ContentControlWidgetController } from "@stll/folio-core/controller/contentControlWidgetController";
|
|
100
102
|
import { createDefaultFindOptions, findInDocument } from "@stll/folio-core/utils/findReplace";
|
|
101
103
|
import { PANEL_METRICS, computePanelLayout } from "@stll/folio-core/panel-layout";
|
|
@@ -853,10 +855,7 @@ const AnonymizationRectsOverlay = ({ groups, onTermClick, selectedCanonical = nu
|
|
|
853
855
|
index: nextIndex
|
|
854
856
|
};
|
|
855
857
|
const el = spans[nextIndex];
|
|
856
|
-
if (el) el
|
|
857
|
-
block: "center",
|
|
858
|
-
behavior: prefersReducedMotionBehavior()
|
|
859
|
-
});
|
|
858
|
+
if (el) scrollEditorElementIntoView(el);
|
|
860
859
|
}, [selectedCanonical, selectionSeq]);
|
|
861
860
|
const overlayRef = useRef(null);
|
|
862
861
|
useEffect(() => {
|
|
@@ -2170,18 +2169,6 @@ const TemplateDirectivesOverlay = (t0) => {
|
|
|
2170
2169
|
const EDGE_ZONE = 40;
|
|
2171
2170
|
/** Maximum scroll speed in pixels per frame (~60fps). */
|
|
2172
2171
|
const MAX_SPEED = 12;
|
|
2173
|
-
/**
|
|
2174
|
-
* Find the nearest scrollable ancestor.
|
|
2175
|
-
*/
|
|
2176
|
-
function findScrollParent(el) {
|
|
2177
|
-
let parent = el.parentElement;
|
|
2178
|
-
while (parent && parent !== document.documentElement) {
|
|
2179
|
-
const { overflowY } = getComputedStyle(parent);
|
|
2180
|
-
if ((overflowY === "auto" || overflowY === "scroll") && parent.scrollHeight > parent.clientHeight) return parent;
|
|
2181
|
-
parent = parent.parentElement;
|
|
2182
|
-
}
|
|
2183
|
-
return null;
|
|
2184
|
-
}
|
|
2185
2172
|
function useDragAutoScroll({ pagesContainerRef, onScrollExtendSelection }) {
|
|
2186
2173
|
const rafIdRef = useRef(null);
|
|
2187
2174
|
const lastMouseRef = useRef({
|
|
@@ -2189,14 +2176,7 @@ function useDragAutoScroll({ pagesContainerRef, onScrollExtendSelection }) {
|
|
|
2189
2176
|
y: 0
|
|
2190
2177
|
});
|
|
2191
2178
|
const activeRef = useRef(false);
|
|
2192
|
-
const
|
|
2193
|
-
const getScrollParent = useCallback(() => {
|
|
2194
|
-
if (scrollParentRef.current) return scrollParentRef.current;
|
|
2195
|
-
const pages = pagesContainerRef.current;
|
|
2196
|
-
if (!pages) return null;
|
|
2197
|
-
scrollParentRef.current = findScrollParent(pages);
|
|
2198
|
-
return scrollParentRef.current;
|
|
2199
|
-
}, [pagesContainerRef]);
|
|
2179
|
+
const getScrollParent = useCallback(() => getEditorScrollRoot(pagesContainerRef.current), [pagesContainerRef]);
|
|
2200
2180
|
const stopAutoScroll = useCallback(() => {
|
|
2201
2181
|
activeRef.current = false;
|
|
2202
2182
|
if (rafIdRef.current !== null) {
|
|
@@ -2219,7 +2199,7 @@ function useDragAutoScroll({ pagesContainerRef, onScrollExtendSelection }) {
|
|
|
2219
2199
|
scrollDelta = Math.min(MAX_SPEED, proximity_0 / EDGE_ZONE * MAX_SPEED);
|
|
2220
2200
|
}
|
|
2221
2201
|
if (scrollDelta !== 0) {
|
|
2222
|
-
container
|
|
2202
|
+
scrollEditorBy(container, scrollDelta);
|
|
2223
2203
|
onScrollExtendSelection(mx, my);
|
|
2224
2204
|
}
|
|
2225
2205
|
rafIdRef.current = requestAnimationFrame(tick);
|
|
@@ -2841,11 +2821,18 @@ function buildFootnoteRenderItems(pageFootnoteMap, footnoteContentMap, doc) {
|
|
|
2841
2821
|
const PagedEditor = forwardRef(function PagedEditor(props, ref) {
|
|
2842
2822
|
const { document, documentIO, documentIdentity, fonts: hostFonts, styles, theme: _theme, sectionProperties, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, headerContentRId, footerContentRId, firstPageHeaderContentRId, firstPageFooterContentRId, readOnly = false, pageGap = 24, zoom = 1, pageRenderer, markupView, 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, pageEndGutter = 0, sidebarOverlay, scrollContainerRef: scrollContainerRefProp, onHyperlinkClick, onContextMenu, onAnchorPositionsChange, onTotalPagesChange, onError, anchorPositionMode = "comments-and-revisions", onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq } = props;
|
|
2843
2823
|
const getScrollContainer = useCallback(() => {
|
|
2844
|
-
if (scrollContainerRefProp && typeof scrollContainerRefProp === "object") return scrollContainerRefProp.current;
|
|
2845
|
-
return containerRef.current;
|
|
2824
|
+
if (scrollContainerRefProp && typeof scrollContainerRefProp === "object") return getEditorScrollRoot(scrollContainerRefProp.current);
|
|
2825
|
+
return getEditorScrollRoot(containerRef.current);
|
|
2846
2826
|
}, [scrollContainerRefProp]);
|
|
2847
2827
|
const containerRef = useRef(null);
|
|
2848
2828
|
const pagesContainerRef = useRef(null);
|
|
2829
|
+
useLayoutEffect(() => {
|
|
2830
|
+
if (!scrollContainerRefProp || typeof scrollContainerRefProp !== "object") return;
|
|
2831
|
+
const root = scrollContainerRefProp.current;
|
|
2832
|
+
if (!root || root.hasAttribute("data-folio-scroll")) return;
|
|
2833
|
+
root.setAttribute("data-folio-scroll", "");
|
|
2834
|
+
return () => root.removeAttribute("data-folio-scroll");
|
|
2835
|
+
}, [scrollContainerRefProp]);
|
|
2849
2836
|
const folioEmitterRef = useRef(createFolioEditorEmitter());
|
|
2850
2837
|
const hiddenPMRef = useRef(null);
|
|
2851
2838
|
const hfPMsRef = useRef(null);
|
|
@@ -4029,10 +4016,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
|
|
|
4029
4016
|
scrollToPositionImpl(target_0.pmPos);
|
|
4030
4017
|
return;
|
|
4031
4018
|
}
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
inline: "nearest"
|
|
4035
|
-
});
|
|
4019
|
+
const shell = pagesContainerRef.current?.querySelector(`[data-page-number="${String(target_0.pageIndex + 1)}"]`);
|
|
4020
|
+
scrollEditorElementIntoView(shell ?? null);
|
|
4036
4021
|
}, [layout, scrollToPositionImpl]);
|
|
4037
4022
|
const scrollToParaIdImpl = useCallback((paraId, options_2) => {
|
|
4038
4023
|
const state_7 = hiddenPMRef.current?.getState();
|
|
@@ -5100,11 +5085,17 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
|
|
|
5100
5085
|
if (["PageUp", "PageDown"].includes(e_7.key) && !e_7.metaKey && !e_7.ctrlKey) {}
|
|
5101
5086
|
if (e_7.key === "Home" && (e_7.metaKey || e_7.ctrlKey)) {
|
|
5102
5087
|
const sc = getScrollContainer();
|
|
5103
|
-
if (sc) sc
|
|
5088
|
+
if (sc) scrollEditorTo(sc, {
|
|
5089
|
+
top: 0,
|
|
5090
|
+
behavior: "instant"
|
|
5091
|
+
});
|
|
5104
5092
|
}
|
|
5105
5093
|
if (e_7.key === "End" && (e_7.metaKey || e_7.ctrlKey)) {
|
|
5106
5094
|
const sc_0 = getScrollContainer();
|
|
5107
|
-
if (sc_0) sc_0
|
|
5095
|
+
if (sc_0) scrollEditorTo(sc_0, {
|
|
5096
|
+
top: sc_0.scrollHeight,
|
|
5097
|
+
behavior: "instant"
|
|
5098
|
+
});
|
|
5108
5099
|
}
|
|
5109
5100
|
}, [
|
|
5110
5101
|
copySelectionText,
|
|
@@ -5451,20 +5442,22 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
|
|
|
5451
5442
|
undo() {
|
|
5452
5443
|
const target_5 = getActiveEditorStory();
|
|
5453
5444
|
if (target_5.type === "none") return false;
|
|
5454
|
-
return undo(target_5.view.state, target_5.view.dispatch);
|
|
5445
|
+
return target_5.type === "body" ? hiddenPMRef.current?.undo() ?? false : undo(target_5.view.state, target_5.view.dispatch);
|
|
5455
5446
|
},
|
|
5456
5447
|
redo() {
|
|
5457
5448
|
const target_6 = getActiveEditorStory();
|
|
5458
5449
|
if (target_6.type === "none") return false;
|
|
5459
|
-
return redo(target_6.view.state, target_6.view.dispatch);
|
|
5450
|
+
return target_6.type === "body" ? hiddenPMRef.current?.redo() ?? false : redo(target_6.view.state, target_6.view.dispatch);
|
|
5460
5451
|
},
|
|
5461
5452
|
canUndo() {
|
|
5462
5453
|
const target_7 = getActiveEditorStory();
|
|
5463
|
-
|
|
5454
|
+
if (target_7.type === "none") return false;
|
|
5455
|
+
return target_7.type === "body" ? hiddenPMRef.current?.canUndo() ?? false : undo(target_7.view.state);
|
|
5464
5456
|
},
|
|
5465
5457
|
canRedo() {
|
|
5466
5458
|
const target_8 = getActiveEditorStory();
|
|
5467
|
-
|
|
5459
|
+
if (target_8.type === "none") return false;
|
|
5460
|
+
return target_8.type === "body" ? hiddenPMRef.current?.canRedo() ?? false : redo(target_8.view.state);
|
|
5468
5461
|
},
|
|
5469
5462
|
setSelection(anchor_3, head_1) {
|
|
5470
5463
|
folioEditor.setSelection(anchor_3, head_1);
|
|
@@ -5603,6 +5596,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
|
|
|
5603
5596
|
};
|
|
5604
5597
|
return /* @__PURE__ */ jsxs("div", {
|
|
5605
5598
|
ref: containerRef,
|
|
5599
|
+
"data-folio-scroll": scrollContainerRefProp && typeof scrollContainerRefProp === "object" ? void 0 : "",
|
|
5606
5600
|
className: `folio-root paged-editor ${className ?? ""}`,
|
|
5607
5601
|
style: {
|
|
5608
5602
|
...containerStyles,
|
|
@@ -6804,20 +6798,6 @@ const toast = (msg) => {
|
|
|
6804
6798
|
};
|
|
6805
6799
|
/** Stable empty anchor positions Map used as the initial state. */
|
|
6806
6800
|
const EMPTY_ANCHOR_POSITIONS = /* @__PURE__ */ new Map();
|
|
6807
|
-
let nextCommentId = Date.now();
|
|
6808
|
-
function allocateCommentId() {
|
|
6809
|
-
return nextCommentId++;
|
|
6810
|
-
}
|
|
6811
|
-
/**
|
|
6812
|
-
* Bump the in-process comment-id counter above `id` so a later
|
|
6813
|
-
* `allocateCommentId()` can never re-mint an id that was adopted from an
|
|
6814
|
-
* external source-of-truth model. No-op when `id` is already below the
|
|
6815
|
-
* current counter. Mirrors the allocator-seeding behaviour of upstream
|
|
6816
|
-
* docx-editor's `CommentIdAllocator.seedAbove` (05f2ab84).
|
|
6817
|
-
*/
|
|
6818
|
-
function seedCommentIdAbove(id) {
|
|
6819
|
-
if (id >= nextCommentId) nextCommentId = id + 1;
|
|
6820
|
-
}
|
|
6821
6801
|
function getCommentAuthorKey(author) {
|
|
6822
6802
|
const trimmed = author?.trim();
|
|
6823
6803
|
return trimmed && trimmed.length > 0 ? trimmed : "Unknown";
|
|
@@ -7176,10 +7156,7 @@ const readFindSelectionSeed = () => {
|
|
|
7176
7156
|
//#region src/components/dialogs/findReplaceUtils.ts
|
|
7177
7157
|
const scrollToMatch = (containerElement, match) => {
|
|
7178
7158
|
if (!containerElement) return;
|
|
7179
|
-
(containerElement.querySelector(`[data-paragraph-index="${match.paragraphIndex}"]`) ?? containerElement.querySelector(`.layout-paragraph[data-block-id="block-${match.paragraphIndex + 1}"]`) ?? containerElement.querySelectorAll(".layout-paragraph").item(match.paragraphIndex))
|
|
7180
|
-
behavior: prefersReducedMotionBehavior(),
|
|
7181
|
-
block: "center"
|
|
7182
|
-
});
|
|
7159
|
+
scrollEditorElementIntoView(containerElement.querySelector(`[data-paragraph-index="${match.paragraphIndex}"]`) ?? containerElement.querySelector(`.layout-paragraph[data-block-id="block-${match.paragraphIndex + 1}"]`) ?? containerElement.querySelectorAll(".layout-paragraph").item(match.paragraphIndex));
|
|
7183
7160
|
};
|
|
7184
7161
|
//#endregion
|
|
7185
7162
|
//#region src/components/dialogs/useFindReplace.ts
|
|
@@ -10083,9 +10060,10 @@ function useContextMenu(t0) {
|
|
|
10083
10060
|
* callbacks each render.
|
|
10084
10061
|
*/
|
|
10085
10062
|
const useDocumentLoader = (t0) => {
|
|
10086
|
-
const $ = c(
|
|
10063
|
+
const $ = c(22);
|
|
10087
10064
|
const { documentBuffer, initialDocument, password, history, onError, onCompatibilityChange, onReset, setDocumentLoadState } = t0;
|
|
10088
10065
|
const originalBufferRef = useRef(null);
|
|
10066
|
+
const originalBufferIdentityRef = useRef(null);
|
|
10089
10067
|
const [loadedDocumentIdentity, setLoadedDocumentIdentity] = useState("0");
|
|
10090
10068
|
let t1;
|
|
10091
10069
|
if ($[0] !== history || $[1] !== onCompatibilityChange || $[2] !== onError || $[3] !== onReset || $[4] !== setDocumentLoadState) {
|
|
@@ -10158,26 +10136,33 @@ const useDocumentLoader = (t0) => {
|
|
|
10158
10136
|
useEffect(t3, t4);
|
|
10159
10137
|
let t5;
|
|
10160
10138
|
let t6;
|
|
10161
|
-
if ($[12] !== documentBuffer || $[13] !== history.state) {
|
|
10139
|
+
if ($[12] !== documentBuffer || $[13] !== history.state || $[14] !== loadedDocumentIdentity) {
|
|
10162
10140
|
t5 = () => {
|
|
10141
|
+
if (originalBufferIdentityRef.current === loadedDocumentIdentity) return;
|
|
10142
|
+
originalBufferIdentityRef.current = loadedDocumentIdentity;
|
|
10163
10143
|
if (history.state?.originalBuffer) {
|
|
10164
10144
|
originalBufferRef.current = history.state.originalBuffer;
|
|
10165
10145
|
return;
|
|
10166
10146
|
}
|
|
10167
|
-
|
|
10147
|
+
originalBufferRef.current = documentBuffer instanceof ArrayBuffer ? documentBuffer : null;
|
|
10168
10148
|
};
|
|
10169
|
-
t6 = [
|
|
10149
|
+
t6 = [
|
|
10150
|
+
history.state,
|
|
10151
|
+
documentBuffer,
|
|
10152
|
+
loadedDocumentIdentity
|
|
10153
|
+
];
|
|
10170
10154
|
$[12] = documentBuffer;
|
|
10171
10155
|
$[13] = history.state;
|
|
10172
|
-
$[14] =
|
|
10173
|
-
$[15] =
|
|
10156
|
+
$[14] = loadedDocumentIdentity;
|
|
10157
|
+
$[15] = t5;
|
|
10158
|
+
$[16] = t6;
|
|
10174
10159
|
} else {
|
|
10175
|
-
t5 = $[
|
|
10176
|
-
t6 = $[
|
|
10160
|
+
t5 = $[15];
|
|
10161
|
+
t6 = $[16];
|
|
10177
10162
|
}
|
|
10178
10163
|
useEffect(t5, t6);
|
|
10179
10164
|
let t7;
|
|
10180
|
-
if ($[
|
|
10165
|
+
if ($[17] !== api.loadBuffer || $[18] !== api.loadParsedDocument || $[19] !== api.resetForNewDocument || $[20] !== loadedDocumentIdentity) {
|
|
10181
10166
|
t7 = {
|
|
10182
10167
|
loadBuffer: api.loadBuffer,
|
|
10183
10168
|
loadParsedDocument: api.loadParsedDocument,
|
|
@@ -10185,12 +10170,12 @@ const useDocumentLoader = (t0) => {
|
|
|
10185
10170
|
originalBufferRef,
|
|
10186
10171
|
loadedDocumentIdentity
|
|
10187
10172
|
};
|
|
10188
|
-
$[
|
|
10189
|
-
$[
|
|
10190
|
-
$[
|
|
10191
|
-
$[
|
|
10192
|
-
$[
|
|
10193
|
-
} else t7 = $[
|
|
10173
|
+
$[17] = api.loadBuffer;
|
|
10174
|
+
$[18] = api.loadParsedDocument;
|
|
10175
|
+
$[19] = api.resetForNewDocument;
|
|
10176
|
+
$[20] = loadedDocumentIdentity;
|
|
10177
|
+
$[21] = t7;
|
|
10178
|
+
} else t7 = $[21];
|
|
10194
10179
|
return t7;
|
|
10195
10180
|
};
|
|
10196
10181
|
//#endregion
|
|
@@ -11019,7 +11004,10 @@ function useZoomAndPageInfo({ scrollContainerRef, pagedEditorRef, initialZoom })
|
|
|
11019
11004
|
if (anchor.zoom === zoom) return;
|
|
11020
11005
|
const scrollContainer_1 = scrollContainerRef.current;
|
|
11021
11006
|
if (!scrollContainer_1) return;
|
|
11022
|
-
scrollContainer_1
|
|
11007
|
+
scrollEditorTo(scrollContainer_1, {
|
|
11008
|
+
top: getScrollTopForZoomAnchor(anchor, zoom),
|
|
11009
|
+
behavior: "instant"
|
|
11010
|
+
});
|
|
11023
11011
|
updateScrollPageInfo(scrollContainer_1);
|
|
11024
11012
|
scheduleScrollPageInfoFade();
|
|
11025
11013
|
}, [
|
|
@@ -12637,15 +12625,25 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
|
|
|
12637
12625
|
const sanitizedCommentsProp = useMemo(() => commentsProp !== void 0 ? sanitizeControlledComments(commentsProp) : void 0, [commentsProp]);
|
|
12638
12626
|
const isControlledComments = sanitizedCommentsProp !== void 0;
|
|
12639
12627
|
const comments = isControlledComments ? sanitizedCommentsProp : internalComments;
|
|
12628
|
+
useLayoutEffect(() => {
|
|
12629
|
+
for (const { id } of doc?.package.document.comments ?? []) seedCommentIdAbove(id);
|
|
12630
|
+
for (const { id: id_0 } of comments) seedCommentIdAbove(id_0);
|
|
12631
|
+
}, [comments, doc]);
|
|
12640
12632
|
const commentsDirtyRef = useRef(false);
|
|
12641
12633
|
const commentsRef = useRef(comments);
|
|
12642
12634
|
commentsRef.current = comments;
|
|
12643
12635
|
const readonlyCommentsRef = commentsRef;
|
|
12644
12636
|
const onCommentsChangeRef = useRef(onCommentsChange);
|
|
12645
12637
|
onCommentsChangeRef.current = onCommentsChange;
|
|
12638
|
+
const createComment$1 = useCallback((text, author, parentId) => {
|
|
12639
|
+
for (const { id: id_1 } of doc?.package.document.comments ?? []) seedCommentIdAbove(id_1);
|
|
12640
|
+
for (const { id: id_2 } of commentsRef.current) seedCommentIdAbove(id_2);
|
|
12641
|
+
return createComment(text, author, parentId);
|
|
12642
|
+
}, [doc]);
|
|
12646
12643
|
const setComments = useCallback((next) => {
|
|
12647
12644
|
const resolved = typeof next === "function" ? next(commentsRef.current) : next;
|
|
12648
12645
|
if (resolved === commentsRef.current) return;
|
|
12646
|
+
for (const { id: id_3 } of resolved) seedCommentIdAbove(id_3);
|
|
12649
12647
|
commentsRef.current = resolved;
|
|
12650
12648
|
if (!isControlledComments) setInternalComments(resolved);
|
|
12651
12649
|
onCommentsChangeRef.current?.(resolved);
|
|
@@ -12693,13 +12691,13 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
|
|
|
12693
12691
|
const visibleComments = useMemo(() => {
|
|
12694
12692
|
const visibleRootIds = /* @__PURE__ */ new Set();
|
|
12695
12693
|
for (const comment_1 of comments) {
|
|
12696
|
-
const
|
|
12697
|
-
if (
|
|
12698
|
-
visibleRootIds.add(
|
|
12694
|
+
const parentId_0 = getCommentParentId(comment_1);
|
|
12695
|
+
if (parentId_0 === null || parentId_0 === void 0 || !visibleCommentIds.has(comment_1.id)) continue;
|
|
12696
|
+
visibleRootIds.add(parentId_0);
|
|
12699
12697
|
}
|
|
12700
12698
|
return comments.filter((comment_2) => {
|
|
12701
|
-
const
|
|
12702
|
-
if (
|
|
12699
|
+
const parentId_1 = getCommentParentId(comment_2);
|
|
12700
|
+
if (parentId_1 !== null && parentId_1 !== void 0) return visibleCommentIds.has(comment_2.id);
|
|
12703
12701
|
return visibleCommentIds.has(comment_2.id) || visibleRootIds.has(comment_2.id);
|
|
12704
12702
|
});
|
|
12705
12703
|
}, [comments, visibleCommentIds]);
|
|
@@ -12712,7 +12710,7 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
|
|
|
12712
12710
|
if (!root) return;
|
|
12713
12711
|
const nodes = root.querySelectorAll(`.layout-run-text${COMMENT_ANCHOR_SELECTOR}`);
|
|
12714
12712
|
for (const node of nodes) {
|
|
12715
|
-
const commentIds = commentAnchorIds(node).map((
|
|
12713
|
+
const commentIds = commentAnchorIds(node).map((id_4) => Number.parseInt(id_4, 10));
|
|
12716
12714
|
if (!commentIds.some((commentId) => commentId === -1 || visibleCommentIds.has(commentId))) {
|
|
12717
12715
|
node.style.backgroundColor = "transparent";
|
|
12718
12716
|
node.style.borderBottom = "2px solid transparent";
|
|
@@ -12757,6 +12755,7 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
|
|
|
12757
12755
|
return {
|
|
12758
12756
|
comments,
|
|
12759
12757
|
setComments,
|
|
12758
|
+
createComment: createComment$1,
|
|
12760
12759
|
isControlledComments,
|
|
12761
12760
|
commentsRef: readonlyCommentsRef,
|
|
12762
12761
|
commentsDirtyRef,
|
|
@@ -12794,7 +12793,7 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
|
|
|
12794
12793
|
*/
|
|
12795
12794
|
/** No headings to track while the outline is not shown. */
|
|
12796
12795
|
const NO_HEADINGS = [];
|
|
12797
|
-
const CommentsSidebar = lazy(() => import("./CommentsSidebar-
|
|
12796
|
+
const CommentsSidebar = lazy(() => import("./CommentsSidebar-Bk5pQ_2C.js").then((m) => ({ default: m.CommentsSidebar })));
|
|
12798
12797
|
const TextContextMenu = lazy(() => import("./TextContextMenu-Bqth8itn.js").then((m) => ({ default: m.TextContextMenu })));
|
|
12799
12798
|
const loadAttemptSelectiveSave = async () => {
|
|
12800
12799
|
const { attemptSelectiveSave } = await import("@stll/folio-core/docx/selectiveSave");
|
|
@@ -13017,8 +13016,30 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
13017
13016
|
if (!onEditorViewReady) return;
|
|
13018
13017
|
if (lastReportedViewRef.current === view_0) return;
|
|
13019
13018
|
lastReportedViewRef.current = view_0;
|
|
13019
|
+
if (view_0 && initialScrollTop !== void 0) {
|
|
13020
|
+
const initialScroll = initialScrollRef.current;
|
|
13021
|
+
switch (initialScroll.status) {
|
|
13022
|
+
case "scheduled":
|
|
13023
|
+
cancelAnimationFrame(initialScroll.frame);
|
|
13024
|
+
scrollEditorTo(scrollContainerRef.current, {
|
|
13025
|
+
top: initialScrollTop,
|
|
13026
|
+
behavior: "instant"
|
|
13027
|
+
});
|
|
13028
|
+
initialScrollRef.current = { status: "applied" };
|
|
13029
|
+
break;
|
|
13030
|
+
case "waiting":
|
|
13031
|
+
scrollEditorTo(scrollContainerRef.current, {
|
|
13032
|
+
top: initialScrollTop,
|
|
13033
|
+
behavior: "instant"
|
|
13034
|
+
});
|
|
13035
|
+
initialScrollRef.current = { status: "applied" };
|
|
13036
|
+
break;
|
|
13037
|
+
case "applied": break;
|
|
13038
|
+
default: return initialScroll;
|
|
13039
|
+
}
|
|
13040
|
+
}
|
|
13020
13041
|
onEditorViewReady(view_0);
|
|
13021
|
-
}, [onEditorViewReady]);
|
|
13042
|
+
}, [onEditorViewReady, initialScrollTop]);
|
|
13022
13043
|
useLayoutEffect(() => {
|
|
13023
13044
|
if (!onEditorViewReady) return;
|
|
13024
13045
|
const view_1 = pagedEditorRef.current?.getView() ?? null;
|
|
@@ -13077,7 +13098,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
13077
13098
|
const imageInputRef = useRef(null);
|
|
13078
13099
|
const editorContentRef = useRef(null);
|
|
13079
13100
|
const scrollContainerRef = useRef(null);
|
|
13080
|
-
const
|
|
13101
|
+
const initialScrollRef = useRef({ status: "waiting" });
|
|
13081
13102
|
const [widestLaidOutPageWidth, setWidestLaidOutPageWidth] = useState(null);
|
|
13082
13103
|
const hasDocument = history.state !== null;
|
|
13083
13104
|
useEffect(() => {
|
|
@@ -13118,7 +13139,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
13118
13139
|
size: 4,
|
|
13119
13140
|
color: { rgb: "000000" }
|
|
13120
13141
|
});
|
|
13121
|
-
const { comments, setComments, commentsRef, commentsDirtyRef, commentsLoadedRef, showCommentsSidebar, setShowCommentsSidebar, setVisibleCommentAuthors, activeCommentId, setActiveCommentId, isAddingComment, setIsAddingComment, commentSelectionRange, setCommentSelectionRange, addCommentYPosition, setAddCommentYPosition, floatingCommentBtn, setFloatingCommentBtn, commentAuthors, visibleCommentAuthorSet, visibleComments, syncCommentHighlightStyles } = useFolioComments({
|
|
13142
|
+
const { comments, createComment, setComments, commentsRef, commentsDirtyRef, commentsLoadedRef, showCommentsSidebar, setShowCommentsSidebar, setVisibleCommentAuthors, activeCommentId, setActiveCommentId, isAddingComment, setIsAddingComment, commentSelectionRange, setCommentSelectionRange, addCommentYPosition, setAddCommentYPosition, floatingCommentBtn, setFloatingCommentBtn, commentAuthors, visibleCommentAuthorSet, visibleComments, syncCommentHighlightStyles } = useFolioComments({
|
|
13122
13143
|
doc: history.state,
|
|
13123
13144
|
autoOpenReviewSidebar,
|
|
13124
13145
|
anchorPositions,
|
|
@@ -13243,11 +13264,14 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
13243
13264
|
onError,
|
|
13244
13265
|
onCompatibilityChange,
|
|
13245
13266
|
onReset: useCallback(() => {
|
|
13246
|
-
|
|
13247
|
-
if (
|
|
13248
|
-
|
|
13249
|
-
|
|
13250
|
-
|
|
13267
|
+
const initialScroll_0 = initialScrollRef.current;
|
|
13268
|
+
if (initialScroll_0.status === "scheduled") cancelAnimationFrame(initialScroll_0.frame);
|
|
13269
|
+
initialScrollRef.current = { status: "waiting" };
|
|
13270
|
+
if (scrollContainerRef.current) scrollEditorTo(scrollContainerRef.current, {
|
|
13271
|
+
top: 0,
|
|
13272
|
+
left: 0,
|
|
13273
|
+
behavior: "instant"
|
|
13274
|
+
});
|
|
13251
13275
|
commentsDirtyRef.current = false;
|
|
13252
13276
|
commentsLoadedRef.current = false;
|
|
13253
13277
|
setComments([]);
|
|
@@ -13303,13 +13327,24 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
13303
13327
|
extractTrackedChanges
|
|
13304
13328
|
]);
|
|
13305
13329
|
useEffect(() => {
|
|
13306
|
-
if (initialScrollTop === void 0 || state.documentLoad.status !== "ready" ||
|
|
13307
|
-
initialScrollAppliedRef.current = true;
|
|
13330
|
+
if (initialScrollTop === void 0 || state.documentLoad.status !== "ready" || initialScrollRef.current.status !== "waiting") return;
|
|
13308
13331
|
const frame = requestAnimationFrame(() => {
|
|
13309
|
-
|
|
13332
|
+
initialScrollRef.current = { status: "applied" };
|
|
13333
|
+
scrollEditorTo(scrollContainerRef.current, {
|
|
13334
|
+
top: initialScrollTop,
|
|
13335
|
+
behavior: "instant"
|
|
13336
|
+
});
|
|
13310
13337
|
});
|
|
13338
|
+
initialScrollRef.current = {
|
|
13339
|
+
status: "scheduled",
|
|
13340
|
+
frame
|
|
13341
|
+
};
|
|
13311
13342
|
return () => {
|
|
13312
|
-
|
|
13343
|
+
const initialScroll_1 = initialScrollRef.current;
|
|
13344
|
+
if (initialScroll_1.status === "scheduled" && initialScroll_1.frame === frame) {
|
|
13345
|
+
cancelAnimationFrame(frame);
|
|
13346
|
+
initialScrollRef.current = { status: "waiting" };
|
|
13347
|
+
}
|
|
13313
13348
|
};
|
|
13314
13349
|
}, [
|
|
13315
13350
|
initialScrollTop,
|
|
@@ -14362,6 +14397,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
14362
14397
|
let tripwireResult = null;
|
|
14363
14398
|
let savedBuffer = null;
|
|
14364
14399
|
try {
|
|
14400
|
+
const view_18 = pagedEditorRef.current?.getView();
|
|
14401
|
+
const editorState = view_18?.state;
|
|
14402
|
+
const baselineBuffer = originalBufferRef.current;
|
|
14365
14403
|
const current = buildCurrentDocument();
|
|
14366
14404
|
const doc_1 = current ? withoutUnreferencedNotes(current) : null;
|
|
14367
14405
|
if (!doc_1) return null;
|
|
@@ -14369,18 +14407,13 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
14369
14407
|
const flags = resolveSelectiveSaveFlags(featureFlags);
|
|
14370
14408
|
const useSelectiveForSave = flags.selectiveSave && options?.mode !== FOLIO_DOCX_SERIALIZATION_MODE.full;
|
|
14371
14409
|
const shouldAttemptSelective = useSelectiveForSave || flags.selectiveSaveTripwire;
|
|
14372
|
-
const view_18 = pagedEditorRef.current?.getView();
|
|
14373
|
-
const baselineBuffer = originalBufferRef.current;
|
|
14374
14410
|
let selectiveBuffer = null;
|
|
14375
|
-
if (shouldAttemptSelective &&
|
|
14376
|
-
|
|
14377
|
-
|
|
14378
|
-
|
|
14379
|
-
|
|
14380
|
-
|
|
14381
|
-
maxBytes: flags.selectiveSaveMaxBytes
|
|
14382
|
-
});
|
|
14383
|
-
}
|
|
14411
|
+
if (shouldAttemptSelective && editorState && baselineBuffer) selectiveBuffer = await (await loadAttemptSelectiveSave())(doc_1, baselineBuffer, {
|
|
14412
|
+
changedParaIds: getChangedParagraphIds(editorState),
|
|
14413
|
+
structuralChange: hasStructuralChanges(editorState),
|
|
14414
|
+
hasUntrackedChanges: hasUntrackedChanges(editorState),
|
|
14415
|
+
maxBytes: flags.selectiveSaveMaxBytes
|
|
14416
|
+
});
|
|
14384
14417
|
let buffer = useSelectiveForSave ? selectiveBuffer : null;
|
|
14385
14418
|
let fullBuffer = null;
|
|
14386
14419
|
const repackSourceDoc = baselineBuffer ? {
|
|
@@ -14390,8 +14423,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
14390
14423
|
const repackFull = async () => {
|
|
14391
14424
|
const repackDocx = await loadRepackDocx();
|
|
14392
14425
|
const repack = () => repackDocx(repackSourceDoc);
|
|
14393
|
-
return
|
|
14394
|
-
state:
|
|
14426
|
+
return editorState ? repackWithEditorSectionRemovals({
|
|
14427
|
+
state: editorState,
|
|
14395
14428
|
document: repackSourceDoc,
|
|
14396
14429
|
repack
|
|
14397
14430
|
}) : repack();
|
|
@@ -14406,7 +14439,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
14406
14439
|
const { compareSelectiveVsFull } = await import("@stll/folio-core/docx/selectiveSaveTripwire");
|
|
14407
14440
|
tripwireResult = await compareSelectiveVsFull(selectiveBuffer, fullBuffer);
|
|
14408
14441
|
} catch {}
|
|
14409
|
-
if (view_18) {
|
|
14442
|
+
if (view_18 && pagedEditorRef.current?.getView() === view_18 && view_18.state.doc === editorState?.doc) {
|
|
14410
14443
|
originalBufferRef.current = buffer;
|
|
14411
14444
|
view_18.dispatch(clearTrackedChanges(view_18.state));
|
|
14412
14445
|
}
|
|
@@ -14940,6 +14973,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
14940
14973
|
loadBuffer,
|
|
14941
14974
|
updateComments,
|
|
14942
14975
|
replaceComments,
|
|
14976
|
+
createComment,
|
|
14943
14977
|
commentsRef,
|
|
14944
14978
|
commentsDirtyRef,
|
|
14945
14979
|
getActiveEditorStory,
|
|
@@ -15232,7 +15266,11 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
15232
15266
|
]);
|
|
15233
15267
|
const handleCommentReply = useCallback((id_2, text_6) => {
|
|
15234
15268
|
updateComments((previous_2) => [...previous_2, createComment(text_6, author, id_2)]);
|
|
15235
|
-
}, [
|
|
15269
|
+
}, [
|
|
15270
|
+
author,
|
|
15271
|
+
createComment,
|
|
15272
|
+
updateComments
|
|
15273
|
+
]);
|
|
15236
15274
|
const handleAddComment = useCallback((addText) => {
|
|
15237
15275
|
const comment_4 = createComment(addText, author);
|
|
15238
15276
|
const view_54 = pagedEditorRef.current?.getView();
|
|
@@ -15259,6 +15297,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
15259
15297
|
}, [
|
|
15260
15298
|
author,
|
|
15261
15299
|
commentSelectionRange,
|
|
15300
|
+
createComment,
|
|
15262
15301
|
setActiveCommentId,
|
|
15263
15302
|
setAddCommentYPosition,
|
|
15264
15303
|
setCommentSelectionRange,
|
|
@@ -15269,7 +15308,11 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
|
|
|
15269
15308
|
]);
|
|
15270
15309
|
const handleTrackedChangeReply = useCallback((revisionId_2, text_7) => {
|
|
15271
15310
|
updateComments((previous_4) => [...previous_4, createComment(text_7, author, revisionId_2)]);
|
|
15272
|
-
}, [
|
|
15311
|
+
}, [
|
|
15312
|
+
author,
|
|
15313
|
+
createComment,
|
|
15314
|
+
updateComments
|
|
15315
|
+
]);
|
|
15273
15316
|
const handleCancelAddComment = useCallback(() => {
|
|
15274
15317
|
const view_55 = pagedEditorRef.current?.getView();
|
|
15275
15318
|
if (view_55 && commentSelectionRange) removePendingCommentMarkRange(view_55, commentSelectionRange);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-react",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.2",
|
|
4
4
|
"description": "React editor for folio: a Word-document (.docx) editor for the browser, built on @stll/folio-core and ProseMirror.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"document-editor",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"@fontsource/noto-sans-arabic": "^5.2.7",
|
|
76
76
|
"@fontsource/source-sans-3": "^5.2.9",
|
|
77
77
|
"@fontsource/tinos": "^5.2.7",
|
|
78
|
-
"@stll/folio-core": "^0.54.
|
|
78
|
+
"@stll/folio-core": "^0.54.2",
|
|
79
79
|
"better-result": "3.0.1",
|
|
80
80
|
"lucide-react": "1.24.0",
|
|
81
81
|
"prosemirror-history": "^1.5.0",
|