@hyebook/vue3-adapter 0.2.3 → 0.2.5

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 +1 @@
1
- {"version":3,"file":"editor-workbench.d.ts","sourceRoot":"","sources":["../../../../../core/src/workbench/editor-workbench.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"editor-workbench.d.ts","sourceRoot":"","sources":["../../../../../core/src/workbench/editor-workbench.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,QAAQ,EAKR,kBAAkB,EAWnB,MAAM,gBAAgB,CAAC;AA8KxB,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC5C,kBAAkB,CAAC,EAAE,uCAAuC,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,4BAA4B,CAAC;IACtC,UAAU,CAAC,EAAE,gCAAgC,CAAC;IAC9C,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC5C;AAED,MAAM,WAAW,uCAAuC;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,uCAAuC;IACtD,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,wBAAwB,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC;IAClD,iBAAiB,CAAC,EAAE,uCAAuC,CAAC;CAC7D;AAED,MAAM,WAAW,gCAAgC;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,OAAO,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,qBAAqB,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3D;AAED,MAAM,WAAW,wBAAyB,SAAQ,2BAA2B;CAAG;AAEhF,MAAM,WAAW,uBAAwB,SAAQ,2BAA2B;IAC1E,SAAS,EAAE,qBAAqB,CAAC;CAClC;AAED,MAAM,WAAW,4BAA4B;IAC3C,UAAU,CAAC,EAAE,CACX,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,uBAAuB,KAC7B,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,CACZ,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,wBAAwB,KAC9B,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,QAAQ,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9B,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;IACjD,sBAAsB,EAAE,CACtB,WAAW,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,KAC/C,kBAAkB,CAAC;IACxB,WAAW,EAAE,MAAM,uBAAuB,CAAC;IAC3C,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,uBAAuB,CAAC,KAAK,IAAI,CAAC;CACnE;AAED,eAAO,MAAM,iCAAiC,EAAE,uBAM/C,CAAC;AAEF,KAAK,IAAI,GAAG,QAAQ,GAAG,SAAS,CAAC;AAoSjC,wBAAgB,8BAA8B,IAAI,QAAQ,CA6GzD;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,WAAW,EACtB,OAAO,GAAE,sBAA2B,GACnC,qBAAqB,CAwjKvB"}
@@ -3,10 +3,12 @@ import { EditorEngine } from "../editor/engine";
3
3
  const WORKBENCH_STYLE_ID = "hy-ebook-workbench-style";
4
4
  const WORKBENCH_STYLE_VERSION = "0.2.3";
5
5
  const WORKBENCH_CSS = `
6
- .hyewb-root{font-family:"Noto Sans SC","PingFang SC","Microsoft YaHei",sans-serif;color:#0f172a;background:#f8fbff;border:1px solid #d8e0ea;border-radius:12px;padding:12px;display:grid;gap:10px}
6
+ .hyewb-root{font-family:"Noto Sans SC","PingFang SC","Microsoft YaHei",sans-serif;color:#0f172a;background:#f8fbff;border:1px solid #d8e0ea;border-radius:12px;padding:12px;display:grid;gap:10px;position:relative;--hyewb-top-shield-height:0px}
7
+ .hyewb-root::before{content:"";position:absolute;left:0;right:0;top:0;height:var(--hyewb-top-shield-height);background:#f8fbff;z-index:119500;pointer-events:none}
7
8
  .hyewb-header{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}
8
9
  .hyewb-title{font-size:14px;font-weight:600}
9
10
  .hyewb-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
11
+ .hyewb-top-control{position:relative;z-index:120000;background:#f8fbff;isolation:isolate}
10
12
  .hyewb-btn{border:1px solid #94a3b8;background:#fff;color:#0f172a;border-radius:8px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;width:34px;height:34px;flex:0 0 auto}
11
13
  .hyewb-btn.active{border-color:#0b7285;background:#0b7285;color:#fff}
12
14
  .hyewb-btn:disabled{cursor:not-allowed;opacity:.55}
@@ -438,14 +440,14 @@ export function mountEditorWorkbench(container, options = {}) {
438
440
  const root = document.createElement("section");
439
441
  root.className = "hyewb-root";
440
442
  const header = document.createElement("header");
441
- header.className = "hyewb-header";
443
+ header.className = "hyewb-header hyewb-top-control";
442
444
  const title = document.createElement("div");
443
445
  title.className = "hyewb-title";
444
446
  title.textContent = options.title ?? "hy-ebook Editor Workbench";
445
447
  const fullscreenBtn = createButton("fullscreen");
446
448
  header.append(title);
447
449
  const toolbar = document.createElement("div");
448
- toolbar.className = "hyewb-row";
450
+ toolbar.className = "hyewb-row hyewb-top-control";
449
451
  const boldBtn = createButton("bold");
450
452
  const italicBtn = createButton("italic");
451
453
  const underlineBtn = createButton("underline");
@@ -706,7 +708,7 @@ export function mountEditorWorkbench(container, options = {}) {
706
708
  const ctxStyleBorder = createTableContextItem("行/列边框样式");
707
709
  tableContextMenu.append(ctxInsertRowUp, ctxInsertRowDown, ctxDeleteRow, ctxInsertColLeft, ctxInsertColRight, ctxDeleteCol, ctxSetRowHeight, ctxSetColWidth, ctxSelectRow, ctxSelectCol, ctxStyleBg, ctxStyleColor, ctxStyleAlign, ctxStyleBoldItalic, ctxStyleBorder);
708
710
  const pageRow = document.createElement("div");
709
- pageRow.className = "hyewb-row";
711
+ pageRow.className = "hyewb-row hyewb-top-control";
710
712
  const prevPageBtn = createButton("prevPage");
711
713
  const nextPageBtn = createButton("nextPage");
712
714
  const addPageBtn = createButton("addPage");
@@ -744,7 +746,7 @@ export function mountEditorWorkbench(container, options = {}) {
744
746
  annotationPanel.className = "hyewb-preview-annotation-panel";
745
747
  const annotationTitle = document.createElement("h3");
746
748
  annotationTitle.className = "hyewb-preview-annotation-title";
747
- annotationTitle.textContent = "预览标注";
749
+ annotationTitle.textContent = "我的笔记";
748
750
  const annotationTabs = document.createElement("div");
749
751
  annotationTabs.className = "hyewb-preview-annotation-tabs";
750
752
  const annotationHighlightTab = document.createElement("button");
@@ -853,7 +855,8 @@ export function mountEditorWorkbench(container, options = {}) {
853
855
  colorPalette.append(colorGrid);
854
856
  root.append(header, toolbar, pageRow, previewLayout, status, colorPalette, tablePicker, tableTools, tableRowDeleteBtn, tableMoveHandle, tableScaleHandle, tableColEdgeLayer, tableRowEdgeLayer, tableRowGapInsertBtn, tableColGapInsertBtn, tableDropIndicator, tableContextMenu, uploadBackdrop, docxInput, previewSelectionToolbar);
855
857
  container.innerHTML = "";
856
- container.append(root, floatingToolbar);
858
+ root.append(floatingToolbar);
859
+ container.append(root);
857
860
  renderWorkbenchIcons();
858
861
  let editorRenderKey = "";
859
862
  let lastSelection = null;
@@ -894,6 +897,7 @@ export function mountEditorWorkbench(container, options = {}) {
894
897
  speedMbps: undefined,
895
898
  error: undefined,
896
899
  };
900
+ let shouldRestoreFullscreenAfterFilePicker = false;
897
901
  const setButtonIcon = (button, iconName) => {
898
902
  button.innerHTML = "";
899
903
  button.append(createIconPlaceholder(iconName));
@@ -922,6 +926,28 @@ export function mountEditorWorkbench(container, options = {}) {
922
926
  const nextHeight = Math.max(320, Math.floor(viewportHeight - top - bottomPadding));
923
927
  shell.style.maxHeight = `${nextHeight}px`;
924
928
  };
929
+ const updateTopControlShieldHeight = () => {
930
+ const rootRect = root.getBoundingClientRect();
931
+ const controls = [header, toolbar, pageRow];
932
+ let maxBottom = 0;
933
+ controls.forEach((control) => {
934
+ if (control.style.display === "none") {
935
+ return;
936
+ }
937
+ const rect = control.getBoundingClientRect();
938
+ const relativeBottom = rect.bottom - rootRect.top;
939
+ maxBottom = Math.max(maxBottom, relativeBottom);
940
+ });
941
+ root.style.setProperty("--hyewb-top-shield-height", `${Math.max(0, Math.ceil(maxBottom + 6))}px`);
942
+ };
943
+ const clampFloatingTop = (top) => {
944
+ return Math.round(top);
945
+ };
946
+ const clampFloatingTopWithHeight = (top, elementHeight) => {
947
+ const maxTop = Math.round(window.innerHeight - elementHeight - 8);
948
+ const rounded = Math.round(top);
949
+ return Math.min(rounded, maxTop);
950
+ };
925
951
  const requestWorkbenchFullscreen = async () => {
926
952
  const target = root;
927
953
  if (typeof target.requestFullscreen === "function") {
@@ -965,6 +991,26 @@ export function mountEditorWorkbench(container, options = {}) {
965
991
  updateShellViewportHeight();
966
992
  }
967
993
  };
994
+ const restoreWorkbenchFullscreenIfNeeded = async () => {
995
+ if (!shouldRestoreFullscreenAfterFilePicker) {
996
+ return;
997
+ }
998
+ shouldRestoreFullscreenAfterFilePicker = false;
999
+ if (isWorkbenchFullscreen()) {
1000
+ return;
1001
+ }
1002
+ try {
1003
+ await requestWorkbenchFullscreen();
1004
+ }
1005
+ catch {
1006
+ // Ignore restore failure when browser blocks fullscreen without activation.
1007
+ }
1008
+ finally {
1009
+ updateFullscreenButtonState();
1010
+ updateShellViewportHeight();
1011
+ updateTopControlShieldHeight();
1012
+ }
1013
+ };
968
1014
  const formatUploadProgress = (percent) => {
969
1015
  const safe = Number.isFinite(percent) ? percent : 0;
970
1016
  const clamped = Math.max(0, Math.min(100, safe));
@@ -1640,7 +1686,7 @@ export function mountEditorWorkbench(container, options = {}) {
1640
1686
  text: selection.toString().trim(),
1641
1687
  };
1642
1688
  previewSelectionToolbar.style.left = `${Math.round(rect.left + rect.width / 2)}px`;
1643
- previewSelectionToolbar.style.top = `${Math.round(rect.top - 8)}px`;
1689
+ previewSelectionToolbar.style.top = `${clampFloatingTop(rect.top - 8)}px`;
1644
1690
  previewSelectionToolbar.classList.add("show");
1645
1691
  };
1646
1692
  const hideFloatingToolbar = () => {
@@ -1697,7 +1743,7 @@ export function mountEditorWorkbench(container, options = {}) {
1697
1743
  const nextLeft = Math.max(8, Math.min(buttonRect.left, window.innerWidth - pickerRect.width - 8));
1698
1744
  const nextTop = Math.min(window.innerHeight - pickerRect.height - 8, buttonRect.bottom + 8);
1699
1745
  tablePicker.style.left = `${Math.round(nextLeft)}px`;
1700
- tablePicker.style.top = `${Math.max(8, Math.round(nextTop))}px`;
1746
+ tablePicker.style.top = `${clampFloatingTopWithHeight(Math.max(8, Math.round(nextTop)), pickerRect.height)}px`;
1701
1747
  };
1702
1748
  const hideTableTools = () => {
1703
1749
  if (tableToolsHideTimer !== null) {
@@ -1802,18 +1848,18 @@ export function mountEditorWorkbench(container, options = {}) {
1802
1848
  cancelTableToolsHide();
1803
1849
  const tableRect = activeTableElement.getBoundingClientRect();
1804
1850
  tableMoveHandle.style.left = `${Math.round(tableRect.left - 14)}px`;
1805
- tableMoveHandle.style.top = `${Math.round(tableRect.top - 14)}px`;
1851
+ tableMoveHandle.style.top = `${clampFloatingTop(tableRect.top - 14)}px`;
1806
1852
  tableMoveHandle.classList.add("show");
1807
1853
  tableScaleHandle.style.left = `${Math.round(tableRect.right - 10)}px`;
1808
- tableScaleHandle.style.top = `${Math.round(tableRect.bottom - 10)}px`;
1854
+ tableScaleHandle.style.top = `${clampFloatingTop(tableRect.bottom - 10)}px`;
1809
1855
  tableScaleHandle.classList.add("show");
1810
1856
  tableColEdgeLayer.style.left = `${Math.round(tableRect.left)}px`;
1811
- tableColEdgeLayer.style.top = `${Math.round(tableRect.top - 12)}px`;
1857
+ tableColEdgeLayer.style.top = `${clampFloatingTop(tableRect.top - 12)}px`;
1812
1858
  tableColEdgeLayer.style.width = `${Math.max(0, Math.round(tableRect.width))}px`;
1813
1859
  tableColEdgeLayer.style.height = "14px";
1814
1860
  tableColEdgeLayer.classList.add("show");
1815
1861
  tableRowEdgeLayer.style.left = `${Math.round(tableRect.left - 12)}px`;
1816
- tableRowEdgeLayer.style.top = `${Math.round(tableRect.top)}px`;
1862
+ tableRowEdgeLayer.style.top = `${clampFloatingTop(tableRect.top)}px`;
1817
1863
  tableRowEdgeLayer.style.width = "14px";
1818
1864
  tableRowEdgeLayer.style.height = `${Math.max(0, Math.round(tableRect.height))}px`;
1819
1865
  tableRowEdgeLayer.classList.add("show");
@@ -1821,7 +1867,7 @@ export function mountEditorWorkbench(container, options = {}) {
1821
1867
  if (activeTableRowElement) {
1822
1868
  const rowRect = activeTableRowElement.getBoundingClientRect();
1823
1869
  tableRowDeleteBtn.style.left = `${Math.round(rowRect.right - 2)}px`;
1824
- tableRowDeleteBtn.style.top = `${Math.round(rowRect.top + rowRect.height / 2 - 10)}px`;
1870
+ tableRowDeleteBtn.style.top = `${clampFloatingTop(rowRect.top + rowRect.height / 2 - 10)}px`;
1825
1871
  tableRowDeleteBtn.classList.add("show");
1826
1872
  }
1827
1873
  else {
@@ -2086,7 +2132,7 @@ export function mountEditorWorkbench(container, options = {}) {
2086
2132
  ? Math.round(targetRow.top)
2087
2133
  : Math.round(tableRect.bottom);
2088
2134
  tableDropIndicator.style.left = `${Math.round(tableRect.left)}px`;
2089
- tableDropIndicator.style.top = `${y - 1}px`;
2135
+ tableDropIndicator.style.top = `${clampFloatingTop(y - 1)}px`;
2090
2136
  tableDropIndicator.style.width = `${Math.max(0, Math.round(tableRect.width))}px`;
2091
2137
  tableDropIndicator.style.height = "2px";
2092
2138
  }
@@ -2097,7 +2143,7 @@ export function mountEditorWorkbench(container, options = {}) {
2097
2143
  ? Math.round(targetCol.left)
2098
2144
  : Math.round(tableRect.right);
2099
2145
  tableDropIndicator.style.left = `${x - 1}px`;
2100
- tableDropIndicator.style.top = `${Math.round(tableRect.top)}px`;
2146
+ tableDropIndicator.style.top = `${clampFloatingTop(tableRect.top)}px`;
2101
2147
  tableDropIndicator.style.width = "2px";
2102
2148
  tableDropIndicator.style.height = `${Math.max(0, Math.round(tableRect.height))}px`;
2103
2149
  }
@@ -2180,14 +2226,14 @@ export function mountEditorWorkbench(container, options = {}) {
2180
2226
  tableColGapInsertBtn.classList.remove("show");
2181
2227
  // Row button offset is managed independently.
2182
2228
  tableRowGapInsertBtn.style.left = `${Math.round(hover.x + rowGapOffset.x)}px`;
2183
- tableRowGapInsertBtn.style.top = `${Math.round(hover.y + rowGapOffset.y)}px`;
2229
+ tableRowGapInsertBtn.style.top = `${clampFloatingTop(hover.y + rowGapOffset.y)}px`;
2184
2230
  tableRowGapInsertBtn.classList.add("show");
2185
2231
  return;
2186
2232
  }
2187
2233
  tableRowGapInsertBtn.classList.remove("show");
2188
2234
  // Column button offset is managed independently.
2189
2235
  tableColGapInsertBtn.style.left = `${Math.round(hover.x + colGapOffset.x)}px`;
2190
- tableColGapInsertBtn.style.top = `${Math.round(hover.y + colGapOffset.y)}px`;
2236
+ tableColGapInsertBtn.style.top = `${clampFloatingTop(hover.y + colGapOffset.y)}px`;
2191
2237
  tableColGapInsertBtn.classList.add("show");
2192
2238
  };
2193
2239
  const resolveRowDropIndex = (table, clientY) => {
@@ -2368,7 +2414,7 @@ export function mountEditorWorkbench(container, options = {}) {
2368
2414
  const left = Math.max(8, Math.min(clientX, window.innerWidth - rect.width - 8));
2369
2415
  const top = Math.max(8, Math.min(clientY, window.innerHeight - rect.height - 8));
2370
2416
  tableContextMenu.style.left = `${Math.round(left)}px`;
2371
- tableContextMenu.style.top = `${Math.round(top)}px`;
2417
+ tableContextMenu.style.top = `${clampFloatingTopWithHeight(top, rect.height)}px`;
2372
2418
  };
2373
2419
  const openColorPalette = (anchor, target) => {
2374
2420
  activeColorTarget = target;
@@ -2677,18 +2723,34 @@ export function mountEditorWorkbench(container, options = {}) {
2677
2723
  const updateFloatingToolbarBySelection = () => {
2678
2724
  const activeElement = document.activeElement;
2679
2725
  const isToolbarFocused = Boolean(activeElement && floatingToolbar.contains(activeElement));
2680
- const keepToolbarVisible = keepSelectionOnToolbar || isToolbarFocused;
2726
+ const liveSelection = window.getSelection();
2727
+ if (liveSelection && liveSelection.rangeCount > 0) {
2728
+ const liveRange = liveSelection.getRangeAt(0);
2729
+ const insideEditor = editorArea.contains(liveRange.startContainer) &&
2730
+ editorArea.contains(liveRange.endContainer);
2731
+ if (insideEditor && liveSelection.isCollapsed) {
2732
+ lastSelection = null;
2733
+ }
2734
+ }
2735
+ const hasExpandedSnapshot = () => {
2736
+ const snapshotRange = lastSelection?.range || rememberedRange;
2737
+ return Boolean(snapshotRange && !snapshotRange.collapsed);
2738
+ };
2739
+ const keepToolbarVisible = (keepSelectionOnToolbar || isToolbarFocused) && hasExpandedSnapshot();
2681
2740
  const restoreFloatingToolbarFromSnapshot = () => {
2682
2741
  const snapshotRange = lastSelection?.range || rememberedRange;
2683
2742
  if (!snapshotRange) {
2684
2743
  return false;
2685
2744
  }
2745
+ if (snapshotRange.collapsed) {
2746
+ return false;
2747
+ }
2686
2748
  try {
2687
2749
  const rect = snapshotRange.getBoundingClientRect();
2688
2750
  if (!rect.width && !rect.height) {
2689
2751
  return false;
2690
2752
  }
2691
- const top = Math.max(8, rect.top - 52);
2753
+ const top = clampFloatingTop(rect.top - 52);
2692
2754
  const left = rect.left + rect.width / 2;
2693
2755
  floatingToolbar.style.top = `${top}px`;
2694
2756
  floatingToolbar.style.left = `${left}px`;
@@ -2740,7 +2802,7 @@ export function mountEditorWorkbench(container, options = {}) {
2740
2802
  range: range.cloneRange(),
2741
2803
  rect,
2742
2804
  };
2743
- const top = Math.max(8, rect.top - 52);
2805
+ const top = clampFloatingTop(rect.top - 52);
2744
2806
  const left = rect.left + rect.width / 2;
2745
2807
  floatingToolbar.style.top = `${top}px`;
2746
2808
  floatingToolbar.style.left = `${left}px`;
@@ -2751,7 +2813,9 @@ export function mountEditorWorkbench(container, options = {}) {
2751
2813
  const shouldKeepFloatingToolbarVisible = () => {
2752
2814
  const activeElement = document.activeElement;
2753
2815
  const isToolbarFocused = Boolean(activeElement && floatingToolbar.contains(activeElement));
2754
- return keepSelectionOnToolbar || isToolbarFocused;
2816
+ const snapshotRange = lastSelection?.range || rememberedRange;
2817
+ const hasExpandedSnapshot = Boolean(snapshotRange && !snapshotRange.collapsed);
2818
+ return (keepSelectionOnToolbar || isToolbarFocused) && hasExpandedSnapshot;
2755
2819
  };
2756
2820
  const withSelectionCommand = (action, successMessage) => {
2757
2821
  if (state.mode !== "editor") {
@@ -3359,6 +3423,8 @@ export function mountEditorWorkbench(container, options = {}) {
3359
3423
  toolbar.style.display =
3360
3424
  showEditorControls && state.features.textToolbar ? "flex" : "none";
3361
3425
  pageRow.style.display = state.features.pageNav ? "flex" : "none";
3426
+ addPageBtn.style.display =
3427
+ showEditorControls && state.features.pageNav ? "inline-flex" : "none";
3362
3428
  videoAddBtn.style.display = state.features.video ? "inline-block" : "none";
3363
3429
  imageUploadBtn.style.display = "inline-block";
3364
3430
  status.style.display = showEditorControls ? "block" : "none";
@@ -3373,6 +3439,7 @@ export function mountEditorWorkbench(container, options = {}) {
3373
3439
  hideTablePicker();
3374
3440
  hideTableTools();
3375
3441
  }
3442
+ updateTopControlShieldHeight();
3376
3443
  prevPageBtn.disabled = state.pageIndex <= 0;
3377
3444
  nextPageBtn.disabled = state.pageIndex >= state.doc.pages.length - 1;
3378
3445
  pageInfo.textContent = `当前页 ${state.pageIndex + 1} / ${state.doc.pages.length}`;
@@ -4347,6 +4414,7 @@ export function mountEditorWorkbench(container, options = {}) {
4347
4414
  };
4348
4415
  const handleWindowResize = () => {
4349
4416
  updateShellViewportHeight();
4417
+ updateTopControlShieldHeight();
4350
4418
  updateInlineResizeOverlay();
4351
4419
  syncTableToolsPosition();
4352
4420
  syncFocusedTableControls();
@@ -4357,6 +4425,7 @@ export function mountEditorWorkbench(container, options = {}) {
4357
4425
  };
4358
4426
  const handleWindowScroll = () => {
4359
4427
  updateShellViewportHeight();
4428
+ updateTopControlShieldHeight();
4360
4429
  updateInlineResizeOverlay();
4361
4430
  updateFloatingToolbarBySelection();
4362
4431
  syncTableToolsPosition();
@@ -4381,6 +4450,7 @@ export function mountEditorWorkbench(container, options = {}) {
4381
4450
  window.requestAnimationFrame(() => {
4382
4451
  updateFullscreenButtonState();
4383
4452
  updateShellViewportHeight();
4453
+ updateTopControlShieldHeight();
4384
4454
  updateInlineResizeOverlay();
4385
4455
  syncTableToolsPosition();
4386
4456
  syncFocusedTableControls();
@@ -4492,10 +4562,12 @@ export function mountEditorWorkbench(container, options = {}) {
4492
4562
  status.textContent = "请先切换到编辑模式后再导入 Word";
4493
4563
  return;
4494
4564
  }
4565
+ shouldRestoreFullscreenAfterFilePicker = isWorkbenchFullscreen();
4495
4566
  docxInput.value = "";
4496
4567
  docxInput.click();
4497
4568
  });
4498
4569
  docxInput.addEventListener("change", () => {
4570
+ void restoreWorkbenchFullscreenIfNeeded();
4499
4571
  const picked = docxInput.files?.[0] || null;
4500
4572
  docxInput.value = "";
4501
4573
  if (!picked) {
@@ -4503,7 +4575,11 @@ export function mountEditorWorkbench(container, options = {}) {
4503
4575
  }
4504
4576
  void importDocxFile(picked);
4505
4577
  });
4578
+ uploadInput.addEventListener("click", () => {
4579
+ shouldRestoreFullscreenAfterFilePicker = isWorkbenchFullscreen();
4580
+ });
4506
4581
  uploadInput.addEventListener("change", () => {
4582
+ void restoreWorkbenchFullscreenIfNeeded();
4507
4583
  const picked = uploadInput.files?.[0] || null;
4508
4584
  uploadState.progress = 0;
4509
4585
  uploadState.speedMbps = undefined;
@@ -4538,6 +4614,10 @@ export function mountEditorWorkbench(container, options = {}) {
4538
4614
  uploadDialog.addEventListener("click", (event) => {
4539
4615
  event.stopPropagation();
4540
4616
  });
4617
+ const handleWindowFocusForFullscreenRestore = () => {
4618
+ void restoreWorkbenchFullscreenIfNeeded();
4619
+ };
4620
+ window.addEventListener("focus", handleWindowFocusForFullscreenRestore);
4541
4621
  prevPageBtn.addEventListener("click", () => jumpPage(-1));
4542
4622
  nextPageBtn.addEventListener("click", () => jumpPage(1));
4543
4623
  addPageBtn.addEventListener("click", addPage);
@@ -4555,6 +4635,7 @@ export function mountEditorWorkbench(container, options = {}) {
4555
4635
  document.removeEventListener("pointerup", onMediaPointerUp);
4556
4636
  window.removeEventListener("resize", handleWindowResize);
4557
4637
  window.removeEventListener("scroll", handleWindowScroll, true);
4638
+ window.removeEventListener("focus", handleWindowFocusForFullscreenRestore);
4558
4639
  document.removeEventListener("pointerdown", handleDocumentPointerDownForPalette);
4559
4640
  document.removeEventListener("keydown", handleDocumentKeyDown);
4560
4641
  document.removeEventListener("fullscreenchange", handleFullscreenChange);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyebook/vue3-adapter",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Vue3 adapter for hy-ebook core",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,7 +17,7 @@
17
17
  "dist"
18
18
  ],
19
19
  "dependencies": {
20
- "@hyebook/core": "^0.2.3"
20
+ "@hyebook/core": "^0.2.5"
21
21
  },
22
22
  "scripts": {
23
23
  "build": "tsc -p tsconfig.json",