@deepseek-ai/dsh-client-ui-sidebar-documentpreview 0.1.7-alpha.2 → 0.1.7-rc.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.
package/lib/client.js CHANGED
@@ -130,6 +130,16 @@ window.__ModuleLoader__.load({
130
130
  name: trimmed.slice(cut)
131
131
  };
132
132
  }
133
+ /**
134
+ * Address a decoded absolute file path through the authenticated file route.
135
+ * @param base - HTTP(S) application base, including its deployment prefix, or `dsh-app://app/`.
136
+ * @param path - Native file path; URL escapes in authored Markdown must already be decoded.
137
+ * @returns File URL, or undefined for unsupported transports and non-absolute paths.
138
+ */
139
+ function fileMediaUrl(base, path) {
140
+ if (!/^https?:/u.test(base) && !base.startsWith("dsh-app://app/") || !isAbsoluteWorkspacePath(path) || /^[/\\]{2}/u.test(path) || /[\u0000-\u001f\u007f]/u.test(path)) return void 0;
141
+ return new URL(`api/file?path=${encodeURIComponent(path)}`, base).href;
142
+ }
133
143
  //#endregion
134
144
  //#region lib/types/client/failure-line.js
135
145
  /** Render a byte count the way a person reads one. */
@@ -171,7 +181,7 @@ window.__ModuleLoader__.load({
171
181
  }
172
182
  //#endregion
173
183
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/LoadingIndicator.module.css.mjs
174
- const css$9 = ".tKrPPq_loading{vertical-align:middle;white-space:normal;align-items:center;gap:8px;display:inline-flex}";
184
+ const css$9 = ".tKrPPq_loading{box-sizing:border-box;width:100%;height:100%;min-height:0;color:var(--dsw-alias-label-secondary);font-family:var(--dsw-font,sans-serif);font-size:var(--dsh-content-font-size,14px);text-align:center;white-space:normal;flex-direction:column;justify-content:center;align-items:center;gap:12px;padding:24px;line-height:1.5;display:flex}.tKrPPq_inline{vertical-align:middle;flex-direction:row;gap:8px;width:auto;height:auto;padding:0;display:inline-flex}";
175
185
  const tagId$9 = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/LoadingIndicator.module.css";
176
186
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$9) + "]") === null) {
177
187
  const tag = document.createElement("style");
@@ -180,21 +190,26 @@ window.__ModuleLoader__.load({
180
190
  tag.textContent = css$9;
181
191
  document.head.appendChild(tag);
182
192
  }
183
- var LoadingIndicator_module_css_default = { "loading": "tKrPPq_loading" };
193
+ var LoadingIndicator_module_css_default = {
194
+ "inline": "tKrPPq_inline",
195
+ "loading": "tKrPPq_loading"
196
+ };
184
197
  //#endregion
185
198
  //#region lib/types/client/LoadingIndicator.js
186
199
  /**
187
- * @param props - localized status label, carried as the accessible name with
188
- * no visible text, and optional placement style.
189
- * @returns an animated, accessible loading status.
200
+ * @param props - localized status label and compact inline placement for additional pages.
201
+ * @returns a centered document loading status or an accessible inline spinner.
190
202
  */
191
- function LoadingIndicator({ label, className }) {
192
- return (0, react_jsx_runtime.jsx)("span", {
193
- className: clsx(LoadingIndicator_module_css_default.loading, className),
203
+ function LoadingIndicator({ label, inline = false }) {
204
+ return (0, react_jsx_runtime.jsxs)("span", {
205
+ className: clsx(LoadingIndicator_module_css_default.loading, inline && LoadingIndicator_module_css_default.inline),
194
206
  role: "status",
195
207
  "aria-label": label,
196
208
  "data-document-loading": true,
197
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "ongoing" })
209
+ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
210
+ state: "ongoing",
211
+ size: inline ? 14 : 28
212
+ }), !inline && (0, react_jsx_runtime.jsx)("span", { children: label })]
198
213
  });
199
214
  }
200
215
  //#endregion
@@ -473,7 +488,7 @@ window.__ModuleLoader__.load({
473
488
  }
474
489
  //#endregion
475
490
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/TextPreview.module.css.mjs
476
- const css$8 = ".dhJKeW_preview{flex-direction:column;flex:auto;height:100%;min-height:0;display:flex}.dhJKeW_header{box-sizing:border-box;border-bottom:.5px solid var(--dsw-alias-border-l3);flex:none;align-items:center;gap:4px;height:38px;padding:0 6px 0 16px;display:flex}.dhJKeW_path{margin-right:12px}.dhJKeW_changed{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);border-bottom:.5px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:10px;margin:0;padding:6px 10px;font-size:12px;display:flex}.dhJKeW_body{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);min-height:0;color:var(--dsw-alias-label-primary);font-size:var(--dsh-content-font-size-secondary,13px);font-family:var(--dsw-font-mono,ui-monospace, monospace);white-space:pre;flex:auto;margin:0;padding:0;line-height:1.6;position:relative;overflow:auto}.dhJKeW_body::-webkit-scrollbar-track{margin:2px}.dhJKeW_body:has([data-code-preview]){flex-direction:column;display:flex;overflow:hidden}.dhJKeW_body:has([data-pdf-preview]){background:var(--dsw-alias-bg-document-preview)}.dhJKeW_wrap{white-space:pre-wrap;word-break:break-word}.dhJKeW_textDocument{box-sizing:border-box;min-width:100%;min-height:100%;padding:8px}.dhJKeW_page{font:var(--dsw-font-markdown-code-block);white-space:inherit;margin:0}.dhJKeW_line{padding:0 10px}.dhJKeW_lineTarget{background:var(--dsw-alias-interactive-bg-hover)}.dhJKeW_empty{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-secondary);font-size:var(--dsh-content-font-size-secondary,13px);font-family:var(--dsw-font-family);text-align:center;white-space:normal;flex-direction:column;justify-content:center;align-items:center;gap:16px;padding:0 24px;line-height:1.6;display:flex}.dhJKeW_empty:after{content:\"\";flex:0 12%}.dhJKeW_emptyIcon{opacity:.6;filter:grayscale();flex:none}.dhJKeW_emptyLine{margin:0}.dhJKeW_retry{height:32px;color:var(--dsw-alias-label-primary);font-size:var(--dsh-content-font-size-secondary,13px);border:.5px solid var(--dsw-alias-border-l2);cursor:pointer;background:0 0;border-radius:16px;flex:none;align-items:center;gap:6px;padding:0 14px 0 12px;font-family:inherit;display:inline-flex}.dhJKeW_retry:hover{background:var(--dsw-alias-interactive-bg-hover)}.dhJKeW_titleIcon{flex:none}.dhJKeW_statusLine{color:var(--dsw-alias-label-secondary);font-size:var(--dsh-content-font-size-secondary,13px);white-space:normal;align-items:center;gap:10px;margin:0;padding:6px 10px;line-height:1.6;display:flex}.dhJKeW_status{box-sizing:border-box;flex-direction:column;justify-content:center;align-items:center;gap:8px;height:100%;padding:12px 10px;display:flex}.dhJKeW_bodyLoading{box-sizing:border-box;justify-content:center;width:100%;height:100%}.dhJKeW_action{color:var(--dsw-alias-label-primary);font-size:var(--dsh-content-font-size-secondary,13px);font-family:var(--dsw-font,inherit);white-space:normal;background:var(--dsw-alias-bg-layer-2);border:.5px solid var(--dsw-alias-border-l2);cursor:pointer;border-radius:6px;padding:4px 10px}.dhJKeW_action:hover{background:var(--dsw-alias-bg-layer-3)}.dhJKeW_more{color:var(--dsw-alias-label-secondary);font-size:12px;font-family:var(--dsw-font,inherit);white-space:normal;background:var(--dsw-alias-bg-layer-2);border:.5px solid var(--dsw-alias-border-l2);cursor:pointer;border-radius:6px;margin:8px 10px;padding:4px 10px;display:block}.dhJKeW_more:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3)}.dhJKeW_more:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.dhJKeW_tool{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:28px;flex:none;justify-content:center;align-items:center;padding:6px;line-height:1;display:inline-flex}.dhJKeW_tool svg{width:15px;height:15px}.dhJKeW_tool:hover,.dhJKeW_tool[data-textpreview-tool=auto-refresh][aria-pressed=true]{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.dhJKeW_viewerTool{width:auto;max-width:160px;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;flex:none;padding:0 6px;font-size:12px;overflow:hidden}";
491
+ const css$8 = ".dhJKeW_preview{flex-direction:column;flex:auto;height:100%;min-height:0;display:flex}.dhJKeW_header{box-sizing:border-box;border-bottom:.5px solid var(--dsw-alias-border-l3);flex:none;align-items:center;gap:4px;height:38px;padding:0 6px 0 16px;display:flex}.dhJKeW_path{margin-right:12px}.dhJKeW_changed{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);border-bottom:.5px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:10px;margin:0;padding:6px 10px;font-size:12px;display:flex}.dhJKeW_body{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);min-height:0;color:var(--dsw-alias-label-primary);font-size:var(--dsh-content-font-size-secondary,13px);font-family:var(--dsw-font-mono,ui-monospace, monospace);white-space:pre;flex:auto;margin:0;padding:0;line-height:1.6;position:relative;overflow:auto}.dhJKeW_body::-webkit-scrollbar-track{margin:2px}.dhJKeW_body:has([data-code-preview]){flex-direction:column;display:flex;overflow:hidden}.dhJKeW_body:has([data-pdf-preview]){background:var(--dsw-alias-bg-document-preview)}.dhJKeW_wrap{white-space:pre-wrap;word-break:break-word}.dhJKeW_textDocument{box-sizing:border-box;min-width:100%;min-height:100%;padding:8px}.dhJKeW_page{font:var(--dsw-font-markdown-code-block);white-space:inherit;margin:0}.dhJKeW_line{padding:0 10px}.dhJKeW_lineTarget{background:var(--dsw-alias-interactive-bg-hover)}.dhJKeW_empty{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-secondary);font-size:var(--dsh-content-font-size-secondary,13px);font-family:var(--dsw-font-family);text-align:center;white-space:normal;flex-direction:column;justify-content:center;align-items:center;gap:16px;padding:0 24px;line-height:1.6;display:flex}.dhJKeW_empty:after{content:\"\";flex:0 12%}.dhJKeW_emptyIcon{opacity:.6;filter:grayscale();flex:none}.dhJKeW_emptyLine{margin:0}.dhJKeW_retry{height:32px;color:var(--dsw-alias-label-primary);font-size:var(--dsh-content-font-size-secondary,13px);border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-md);cursor:pointer;background:0 0;flex:none;align-items:center;gap:6px;padding:0 14px 0 12px;font-family:inherit;display:inline-flex}.dhJKeW_retry:hover{background:var(--dsw-alias-interactive-bg-hover)}.dhJKeW_titleIcon{flex:none}.dhJKeW_statusLine{color:var(--dsw-alias-label-secondary);font-size:var(--dsh-content-font-size-secondary,13px);white-space:normal;align-items:center;gap:10px;margin:0;padding:6px 10px;line-height:1.6;display:flex}.dhJKeW_status{box-sizing:border-box;flex-direction:column;justify-content:center;align-items:center;gap:8px;height:100%;padding:12px 10px;display:flex}.dhJKeW_action{color:var(--dsw-alias-label-primary);font-size:var(--dsh-content-font-size-secondary,13px);font-family:var(--dsw-font,inherit);white-space:normal;background:var(--dsw-alias-bg-layer-2);border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-sm);cursor:pointer;padding:4px 10px}.dhJKeW_action:hover{background:var(--dsw-alias-bg-layer-3)}.dhJKeW_more{color:var(--dsw-alias-label-secondary);font-size:12px;font-family:var(--dsw-font,inherit);white-space:normal;background:var(--dsw-alias-bg-layer-2);border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-sm);cursor:pointer;margin:8px 10px;padding:4px 10px;display:block}.dhJKeW_more:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3)}.dhJKeW_more:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.dhJKeW_tool{width:28px;height:28px;color:var(--dsw-alias-label-secondary);border-radius:var(--dsw-radius-sm);cursor:pointer;background:0 0;border:none;flex:none;justify-content:center;align-items:center;padding:6px;line-height:1;display:inline-flex}.dhJKeW_tool svg{width:15px;height:15px}.dhJKeW_tool:hover,.dhJKeW_tool[data-textpreview-tool=auto-refresh][aria-pressed=true]{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.dhJKeW_viewerTool{width:auto;max-width:160px;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;flex:none;padding:0 6px;font-size:12px;overflow:hidden}";
477
492
  const tagId$8 = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/TextPreview.module.css";
478
493
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$8) + "]") === null) {
479
494
  const tag = document.createElement("style");
@@ -485,7 +500,6 @@ window.__ModuleLoader__.load({
485
500
  var TextPreview_module_css_default = {
486
501
  "action": "dhJKeW_action",
487
502
  "body": "dhJKeW_body",
488
- "bodyLoading": "dhJKeW_bodyLoading",
489
503
  "changed": "dhJKeW_changed",
490
504
  "empty": "dhJKeW_empty",
491
505
  "emptyIcon": "dhJKeW_emptyIcon",
@@ -722,6 +736,7 @@ window.__ModuleLoader__.load({
722
736
  signal,
723
737
  observedVersion
724
738
  ]);
739
+ (0, react.useEffect)(() => tab.actions.bindCommands({ refresh: reload }), [tab.actions, reload]);
725
740
  (0, react.useEffect)(() => {
726
741
  if (state?.autoRefresh && changed && current !== void 0 && !current.loading && meta.status === "live") reload();
727
742
  }, [
@@ -809,10 +824,7 @@ window.__ModuleLoader__.load({
809
824
  children: meta.status === "none" ? (0, react_jsx_runtime.jsx)("p", {
810
825
  className: TextPreview_module_css_default.statusLine,
811
826
  children: t("resourceUnavailable")
812
- }) : (0, react_jsx_runtime.jsx)(LoadingIndicator, {
813
- className: TextPreview_module_css_default.statusLine,
814
- label: t("loading")
815
- })
827
+ }) : (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") })
816
828
  });
817
829
  const next = loadedThrough + 1;
818
830
  const { name } = pathPartsOf(displayPath);
@@ -925,6 +937,7 @@ window.__ModuleLoader__.load({
925
937
  }),
926
938
  (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
927
939
  label: t("reload"),
940
+ shortcutKeys: tab.refreshShortcut?.keys,
928
941
  side: "bottom",
929
942
  delayMs: 500,
930
943
  children: (0, react_jsx_runtime.jsx)("button", {
@@ -932,6 +945,7 @@ window.__ModuleLoader__.load({
932
945
  className: TextPreview_module_css_default.tool,
933
946
  "aria-label": t("reload"),
934
947
  "data-textpreview-tool": "reload",
948
+ "aria-keyshortcuts": tab.refreshShortcut?.aria,
935
949
  onClick: reload,
936
950
  children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutlineRegular, {})
937
951
  })
@@ -953,10 +967,7 @@ window.__ModuleLoader__.load({
953
967
  if (mode === "text-pages" && current?.failure === void 0 && body.clientHeight > 0 && body.scrollTop + body.clientHeight >= body.scrollHeight - 1) loadNext();
954
968
  },
955
969
  children: [
956
- mode !== "renderer" && !hasContent && current?.failure === void 0 && (0, react_jsx_runtime.jsx)(LoadingIndicator, {
957
- className: clsx(TextPreview_module_css_default.statusLine, TextPreview_module_css_default.bodyLoading),
958
- label: t("loading")
959
- }),
970
+ mode !== "renderer" && !hasContent && current?.failure === void 0 && (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") }),
960
971
  content !== void 0 && renderSlot("sidebar.right.tab.document", {
961
972
  resourceAddress: tab.contentId,
962
973
  content,
@@ -1011,7 +1022,10 @@ window.__ModuleLoader__.load({
1011
1022
  disabled: current.loading,
1012
1023
  "data-textpreview-more": true,
1013
1024
  onClick: loadNext,
1014
- children: current.loading ? (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") }) : t("loadMore")
1025
+ children: current.loading ? (0, react_jsx_runtime.jsx)(LoadingIndicator, {
1026
+ inline: true,
1027
+ label: t("loading")
1028
+ }) : t("loadMore")
1015
1029
  })
1016
1030
  ]
1017
1031
  })
@@ -1434,7 +1448,7 @@ window.__ModuleLoader__.load({
1434
1448
  */
1435
1449
  /** Simplified Chinese dictionary and key-set source of truth. */
1436
1450
  const zh$7 = {
1437
- loading: "正在读取…",
1451
+ loading: "文档渲染中...",
1438
1452
  loadMore: "加载更多",
1439
1453
  changed: "文件已更新,当前显示为旧内容",
1440
1454
  reloadNow: "重新载入",
@@ -1459,7 +1473,7 @@ window.__ModuleLoader__.load({
1459
1473
  };
1460
1474
  /** English dictionary, checked against the Chinese key set. */
1461
1475
  const en$7 = {
1462
- loading: "Reading…",
1476
+ loading: "Rendering document...",
1463
1477
  loadMore: "Load more",
1464
1478
  changed: "The file has changed, showing the previous content.",
1465
1479
  reloadNow: "Reload",
@@ -1499,10 +1513,9 @@ window.__ModuleLoader__.load({
1499
1513
  * @param base - document base URI, including any deployment prefix.
1500
1514
  * @param documentPath - absolute source path reported by the Host, when available.
1501
1515
  * @param destination - authored Markdown image URL; query and fragment are not filename components.
1502
- * @returns an HTTP(S) file URL, or undefined for unsupported or malformed destinations.
1516
+ * @returns a Web or Desktop file URL, or undefined for unsupported or malformed destinations.
1503
1517
  */
1504
1518
  function markdownImageUrl(base, documentPath, destination) {
1505
- if (!base.startsWith("http:") && !base.startsWith("https:")) return void 0;
1506
1519
  const suffix = destination.search(/[?#]/u);
1507
1520
  let path;
1508
1521
  try {
@@ -1510,13 +1523,13 @@ window.__ModuleLoader__.load({
1510
1523
  } catch (_error) {
1511
1524
  return;
1512
1525
  }
1513
- if (path.length === 0 || path.includes("\0") || /^[/\\]{2}/u.test(path)) return void 0;
1526
+ if (path.length === 0) return void 0;
1514
1527
  if (!/^[a-z]:[/\\]/iu.test(path) && /^[a-z][a-z\d+.-]*:/iu.test(path)) return void 0;
1515
1528
  if (!isAbsoluteWorkspacePath(path)) {
1516
1529
  if (documentPath === void 0) return void 0;
1517
1530
  path = pathPartsOf(documentPath).directory + path;
1518
1531
  }
1519
- return new URL(`api/file?path=${encodeURIComponent(path)}`, base).href;
1532
+ return fileMediaUrl(base, path);
1520
1533
  }
1521
1534
  //#endregion
1522
1535
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/markdown/MarkdownBody.module.css.mjs
@@ -3931,7 +3944,7 @@ document.open();document.write(html);document.close();
3931
3944
  }
3932
3945
  //#endregion
3933
3946
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/html/HtmlBody.module.css.mjs
3934
- const css$6 = ".HyIruq_frame{background:var(--dsw-alias-bg-base);border:none;width:100%;height:100%;min-height:240px;display:block}.HyIruq_status{color:var(--dsw-alias-label-secondary);white-space:normal;margin:0;padding:10px}.HyIruq_opening{box-sizing:border-box;justify-content:center;width:100%;min-height:100%}";
3947
+ const css$6 = ".HyIruq_frame{background:var(--dsw-alias-bg-base);border:none;width:100%;height:100%;min-height:240px;display:block}.HyIruq_status{color:var(--dsw-alias-label-secondary);white-space:normal;margin:0;padding:10px}";
3935
3948
  const tagId$6 = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/HtmlBody.module.css";
3936
3949
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$6) + "]") === null) {
3937
3950
  const tag = document.createElement("style");
@@ -3942,14 +3955,13 @@ document.open();document.write(html);document.close();
3942
3955
  }
3943
3956
  var HtmlBody_module_css_default = {
3944
3957
  "frame": "HyIruq_frame",
3945
- "opening": "HyIruq_opening",
3946
3958
  "status": "HyIruq_status"
3947
3959
  };
3948
3960
  //#endregion
3949
3961
  //#region lib/types/client/html/HtmlBody.js
3950
3962
  /** Static or interactive HTML in an opaque iframe, without parent application access. */
3951
3963
  /** One mounted file owns its root Blob; replacing content also replaces the browsing context. */
3952
- function HtmlFrame({ data, resourceAddress, readRelated, addResource, setResources, signal, t }) {
3964
+ function HtmlFrame({ data, resourceAddress, readRelated, addResource, setResources, signal, frameName, t }) {
3953
3965
  const [frame, setFrame] = (0, react.useState)();
3954
3966
  (0, react.useEffect)(() => {
3955
3967
  const controller = new AbortController();
@@ -3992,16 +4004,14 @@ document.open();document.write(html);document.close();
3992
4004
  setResources,
3993
4005
  signal
3994
4006
  ]);
3995
- if (frame?.data !== data || frame.readRelated !== readRelated) return (0, react_jsx_runtime.jsx)(LoadingIndicator, {
3996
- className: clsx(HtmlBody_module_css_default.status, HtmlBody_module_css_default.opening),
3997
- label: t("loading")
3998
- });
4007
+ if (frame?.data !== data || frame.readRelated !== readRelated) return (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") });
3999
4008
  if (frame.url === void 0) return (0, react_jsx_runtime.jsx)("p", {
4000
4009
  className: HtmlBody_module_css_default.status,
4001
4010
  role: "alert",
4002
4011
  children: t("failed")
4003
4012
  });
4004
4013
  return (0, react_jsx_runtime.jsx)("iframe", {
4014
+ name: frameName,
4005
4015
  className: HtmlBody_module_css_default.frame,
4006
4016
  src: frame.url,
4007
4017
  sandbox: "allow-scripts",
@@ -4021,8 +4031,10 @@ document.open();document.write(html);document.close();
4021
4031
  if (!interactivePreview) setResources([]);
4022
4032
  }, [interactivePreview, setResources]);
4023
4033
  if (content.kind !== "bytes") return null;
4034
+ const frameName = `dsh-sidebar-html-${tab.id}`;
4024
4035
  if (!interactivePreview) return (0, react_jsx_runtime.jsx)(BasicHtmlFrame, {
4025
4036
  data: content.data,
4037
+ frameName,
4026
4038
  t
4027
4039
  });
4028
4040
  return (0, react_jsx_runtime.jsx)(HtmlFrame, {
@@ -4030,13 +4042,14 @@ document.open();document.write(html);document.close();
4030
4042
  resourceAddress,
4031
4043
  readRelated,
4032
4044
  signal: tab.signal,
4045
+ frameName,
4033
4046
  addResource,
4034
4047
  setResources,
4035
4048
  t
4036
4049
  }, resourceAddress);
4037
4050
  }
4038
4051
  /** Static preview mounts a separate browsing context so a mode change retires running scripts. */
4039
- function BasicHtmlFrame({ data, t }) {
4052
+ function BasicHtmlFrame({ data, frameName, t }) {
4040
4053
  const html = (0, react.useMemo)(() => {
4041
4054
  try {
4042
4055
  return createBasicHtmlDocument(data);
@@ -4050,6 +4063,7 @@ document.open();document.write(html);document.close();
4050
4063
  children: t("failed")
4051
4064
  });
4052
4065
  return (0, react_jsx_runtime.jsx)("iframe", {
4066
+ name: frameName,
4053
4067
  className: HtmlBody_module_css_default.frame,
4054
4068
  srcDoc: html,
4055
4069
  sandbox: "",
@@ -4063,14 +4077,14 @@ document.open();document.write(html);document.close();
4063
4077
  const zh$5 = {
4064
4078
  title: "HTML",
4065
4079
  frame: "HTML 文档预览",
4066
- loading: "正在读取…",
4080
+ loading: "文档渲染中...",
4067
4081
  failed: "无法预览这份 HTML 文档"
4068
4082
  };
4069
4083
  /** English dictionary with the same keys as the Chinese dictionary. */
4070
4084
  const en$5 = {
4071
4085
  title: "HTML",
4072
4086
  frame: "HTML document preview",
4073
- loading: "Reading…",
4087
+ loading: "Rendering document...",
4074
4088
  failed: "This HTML document could not be previewed."
4075
4089
  };
4076
4090
  //#endregion
@@ -4184,7 +4198,7 @@ document.open();document.write(html);document.close();
4184
4198
  const DEFAULT_ZOOM = FIT_WIDTH;
4185
4199
  //#endregion
4186
4200
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/zoom/ZoomControls.module.css.mjs
4187
- const css$5 = ".lyqg2a_panel{z-index:2;inset-inline-start:50%;box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l3);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);opacity:0;pointer-events:none;will-change:opacity, transform;border-radius:12px;align-items:center;gap:2px;padding:4px 6px;font-size:12px;line-height:18px;transition:opacity .16s ease-in,transform .16s cubic-bezier(.4,0,1,1);display:flex;position:absolute;bottom:14px;transform:translate(-50%,16px)scale(.98);box-shadow:0 8px 24px light-dark(#0000001a,#00000060),0 2px 5px light-dark(#00000009,#00000035)}.lyqg2a_visible{opacity:1;pointer-events:auto;transition:opacity .14s ease-out,transform .18s cubic-bezier(.22,1,.36,1);transform:translate(-50%)scale(1)}.lyqg2a_controlAnchor{display:flex}.lyqg2a_zoomButton{flex:none;width:28px;padding:0}.lyqg2a_percent{font-variant-numeric:tabular-nums;justify-content:center;align-items:center;gap:2px;min-width:58px;padding-inline:6px;display:inline-flex}.lyqg2a_zoomMenu{min-width:112px}@media (hover:none),(pointer:coarse){.lyqg2a_panel{opacity:1;pointer-events:auto;transform:translate(-50%)scale(1)}}@media (prefers-reduced-motion:reduce){.lyqg2a_panel,.lyqg2a_visible{transition-duration:.01ms}}";
4201
+ const css$5 = ".lyqg2a_panel{z-index:2;inset-inline-start:50%;box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-lg);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);opacity:0;pointer-events:none;will-change:opacity, transform;align-items:center;gap:2px;padding:4px 6px;font-size:12px;line-height:18px;transition:opacity .16s ease-in,transform .16s cubic-bezier(.4,0,1,1);display:flex;position:absolute;bottom:14px;transform:translate(-50%,16px)scale(.98);box-shadow:0 8px 24px light-dark(#0000001a,#00000060),0 2px 5px light-dark(#00000009,#00000035)}.lyqg2a_visible{opacity:1;pointer-events:auto;transition:opacity .14s ease-out,transform .18s cubic-bezier(.22,1,.36,1);transform:translate(-50%)scale(1)}.lyqg2a_controlAnchor{display:flex}.lyqg2a_zoomButton{flex:none;width:28px;padding:0}.lyqg2a_percent{font-variant-numeric:tabular-nums;justify-content:center;align-items:center;gap:2px;min-width:58px;padding-inline:6px;display:inline-flex}.lyqg2a_zoomMenu{min-width:112px}@media (hover:none),(pointer:coarse){.lyqg2a_panel{opacity:1;pointer-events:auto;transform:translate(-50%)scale(1)}}@media (prefers-reduced-motion:reduce){.lyqg2a_panel,.lyqg2a_visible{transition-duration:.01ms}}";
4188
4202
  const tagId$5 = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/ZoomControls.module.css";
4189
4203
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$5) + "]") === null) {
4190
4204
  const tag = document.createElement("style");
@@ -4513,7 +4527,12 @@ document.open();document.write(html);document.close();
4513
4527
  frame.current?.setAttribute("data-document-zoom-mode", props.preference.kind);
4514
4528
  frame.current?.style.setProperty("--document-zoom", String(zoom));
4515
4529
  controls.current?.showZoom(zoom);
4516
- }, [props.preference.kind, zoom]);
4530
+ props.onRenderZoom?.(zoom);
4531
+ }, [
4532
+ props.onRenderZoom,
4533
+ props.preference.kind,
4534
+ zoom
4535
+ ]);
4517
4536
  (0, react.useEffect)(() => {
4518
4537
  const node = scrollport.current;
4519
4538
  const clearPendingPinch = () => {
@@ -4593,7 +4612,7 @@ document.open();document.write(html);document.close();
4593
4612
  const zoomSurfaceClass = ZoomViewport_module_css_default.surface;
4594
4613
  //#endregion
4595
4614
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/image/ImageBody.module.css.mjs
4596
- const css$3 = ".JFRUHG_frame{box-sizing:border-box;width:100%;min-width:100%;height:max-content;min-height:100%;font-family:var(--dsw-font,sans-serif);white-space:normal;padding:12px;display:flex}.JFRUHG_surface{flex:none;max-width:none;margin:auto;display:block}.JFRUHG_surface[hidden]{display:none}.JFRUHG_image{user-select:none;border-radius:8px;width:100%;max-width:none;height:auto;max-height:none;display:block}.JFRUHG_status{box-sizing:border-box;width:100%;min-height:100%;color:var(--dsw-alias-label-secondary);white-space:normal;justify-content:center;align-items:center;margin:0;padding:10px;font-size:13px;line-height:1.5;display:flex}";
4615
+ const css$3 = ".JFRUHG_frame{box-sizing:border-box;width:100%;min-width:100%;height:max-content;min-height:100%;font-family:var(--dsw-font,sans-serif);white-space:normal;padding:12px;display:flex}.JFRUHG_frame:has([data-document-loading]){height:100%}.JFRUHG_surface{flex:none;max-width:none;margin:auto;display:block}.JFRUHG_surface[hidden]{display:none}.JFRUHG_image{border-radius:var(--dsw-radius-md);user-select:none;width:100%;max-width:none;height:auto;max-height:none;display:block}.JFRUHG_status{box-sizing:border-box;width:100%;min-height:100%;color:var(--dsw-alias-label-secondary);white-space:normal;justify-content:center;align-items:center;margin:0;padding:10px;font-size:13px;line-height:1.5;display:flex}";
4597
4616
  const tagId$3 = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/ImageBody.module.css";
4598
4617
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
4599
4618
  const tag = document.createElement("style");
@@ -4681,10 +4700,7 @@ document.open();document.write(html);document.close();
4681
4700
  role: "alert",
4682
4701
  children: t("unsupported")
4683
4702
  });
4684
- if (source?.data !== data || source.mediaType !== mediaType) return (0, react_jsx_runtime.jsx)(LoadingIndicator, {
4685
- className: ImageBody_module_css_default.status,
4686
- label: t("loading")
4687
- });
4703
+ if (source?.data !== data || source.mediaType !== mediaType) return (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") });
4688
4704
  if (source.kind === "failed") return (0, react_jsx_runtime.jsx)("p", {
4689
4705
  className: ImageBody_module_css_default.status,
4690
4706
  role: "alert",
@@ -4726,10 +4742,7 @@ document.open();document.write(html);document.close();
4726
4742
  className: ImageBody_module_css_default.frame,
4727
4743
  "data-image-preview": true,
4728
4744
  children: [
4729
- state === "loading" && (0, react_jsx_runtime.jsx)(LoadingIndicator, {
4730
- className: ImageBody_module_css_default.status,
4731
- label: t("loading")
4732
- }),
4745
+ state === "loading" && (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") }),
4733
4746
  state === "failed" && (0, react_jsx_runtime.jsx)("p", {
4734
4747
  className: ImageBody_module_css_default.status,
4735
4748
  role: "alert",
@@ -4787,7 +4800,7 @@ document.open();document.write(html);document.close();
4787
4800
  ...zoomZh,
4788
4801
  title: "图片",
4789
4802
  preview: "图片预览:{name}",
4790
- loading: "正在读取…",
4803
+ loading: "文档渲染中...",
4791
4804
  failed: "无法显示这张图片",
4792
4805
  unsupported: "图片预览需要完整文件内容"
4793
4806
  };
@@ -4796,7 +4809,7 @@ document.open();document.write(html);document.close();
4796
4809
  ...zoomEn,
4797
4810
  title: "Image",
4798
4811
  preview: "Image preview: {name}",
4799
- loading: "Reading…",
4812
+ loading: "Rendering document...",
4800
4813
  failed: "This image could not be displayed.",
4801
4814
  unsupported: "Image preview requires the complete file contents."
4802
4815
  };
@@ -4874,12 +4887,13 @@ document.open();document.write(html);document.close();
4874
4887
  * @returns the deferred PDF renderer.
4875
4888
  */
4876
4889
  function LazyPdfBody(props) {
4890
+ const loading = (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: props.t("loading") });
4877
4891
  return (0, react_jsx_runtime.jsx)(react.Suspense, {
4878
- fallback: (0, react_jsx_runtime.jsx)(LoadingIndicator, {
4879
- className: TextPreview_module_css_default.status,
4880
- label: props.t("loading")
4881
- }),
4882
- children: (0, react_jsx_runtime.jsx)(LoadedPdfBody, { ...props })
4892
+ fallback: loading,
4893
+ children: (0, react_jsx_runtime.jsx)(LoadedPdfBody, {
4894
+ ...props,
4895
+ loading
4896
+ })
4883
4897
  });
4884
4898
  }
4885
4899
  //#endregion
@@ -4923,7 +4937,7 @@ document.open();document.write(html);document.close();
4923
4937
  ...zoomZh,
4924
4938
  title: "PDF",
4925
4939
  pageImage: "PDF 第 {page} 页",
4926
- loading: "正在读取…",
4940
+ loading: "文档渲染中...",
4927
4941
  rendering: "正在绘制页面…",
4928
4942
  failed: "无法显示 PDF:{message}",
4929
4943
  password: "此 PDF 需要密码,暂不支持预览",
@@ -4936,7 +4950,7 @@ document.open();document.write(html);document.close();
4936
4950
  ...zoomEn,
4937
4951
  title: "PDF",
4938
4952
  pageImage: "PDF page {page}",
4939
- loading: "Reading…",
4953
+ loading: "Rendering document...",
4940
4954
  rendering: "Rendering page…",
4941
4955
  failed: "Cannot display PDF: {message}",
4942
4956
  password: "This PDF requires a password; password-protected previews are not supported.",
@@ -5088,7 +5102,7 @@ document.open();document.write(html);document.close();
5088
5102
  /** Office preview copy and Host render configuration guidance. */
5089
5103
  const zh$1 = {
5090
5104
  title: "Office 文档",
5091
- loading: "正在读取…",
5105
+ loading: "文档渲染中...",
5092
5106
  retry: "重试",
5093
5107
  viewMissingFonts: "缺失 {count} 种字体,点击查看",
5094
5108
  missingFontsTitle: "缺失的字体",
@@ -5106,7 +5120,7 @@ document.open();document.write(html);document.close();
5106
5120
  /** English translations checked against the Chinese key set. */
5107
5121
  const en$1 = {
5108
5122
  title: "Office document",
5109
- loading: "Reading…",
5123
+ loading: "Rendering document...",
5110
5124
  retry: "Retry",
5111
5125
  viewMissingFonts: "Missing fonts: {count}. Click to view.",
5112
5126
  missingFontsTitle: "Missing fonts",
@@ -5380,10 +5394,7 @@ document.open();document.write(html);document.close();
5380
5394
  ]
5381
5395
  });
5382
5396
  }
5383
- if (file === void 0) return (0, react_jsx_runtime.jsx)(LoadingIndicator, {
5384
- className: TextPreview_module_css_default.statusLine,
5385
- label: t("loading")
5386
- });
5397
+ if (file === void 0) return (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") });
5387
5398
  return (0, react_jsx_runtime.jsx)("div", {
5388
5399
  className: OfficeBody_module_css_default.body,
5389
5400
  children: props.renderSlot("sidebar.right.tab.document.office.pdf", {
@@ -5404,7 +5415,7 @@ document.open();document.write(html);document.close();
5404
5415
  }
5405
5416
  //#endregion
5406
5417
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/office/FontNotice.module.css.mjs
5407
- const css = ".JqwYuG_anchor{flex:none;display:inline-flex}.JqwYuG_anchor .JqwYuG_warning,.JqwYuG_anchor .JqwYuG_warning:hover{color:var(--dsw-alias-state-warn-label)}.JqwYuG_anchor .JqwYuG_warning:hover,.JqwYuG_anchor .JqwYuG_warning[aria-expanded=true]{background:var(--dsw-alias-state-warn-tertiary)}.JqwYuG_panel{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);z-index:100;box-sizing:border-box;width:min(340px,100vw - 24px);max-height:calc(100dvh - 24px);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);box-shadow:var(--dsw-elevation-prominent);border:0;border-radius:12px;padding:16px;font-size:13px;line-height:1.6;position:fixed;overflow:auto}.JqwYuG_panelHeader{justify-content:space-between;align-items:center;gap:12px;display:flex}.JqwYuG_panelHeader h3{margin:0;font-size:14px;font-weight:600}.JqwYuG_description{color:var(--dsw-alias-label-secondary);margin:8px 0 16px}.JqwYuG_count{color:var(--dsw-alias-label-tertiary);margin:0 0 6px;font-size:12px}.JqwYuG_fonts{overflow-wrap:anywhere;margin:0;padding:0;list-style:none}.JqwYuG_fonts li{border-top:.5px solid var(--dsw-alias-border-l2);padding:8px 0}";
5418
+ const css = ".JqwYuG_anchor{flex:none;display:inline-flex}.JqwYuG_anchor .JqwYuG_warning,.JqwYuG_anchor .JqwYuG_warning:hover{color:var(--dsw-alias-state-warn-label)}.JqwYuG_anchor .JqwYuG_warning:hover,.JqwYuG_anchor .JqwYuG_warning[aria-expanded=true]{background:var(--dsw-alias-state-warn-tertiary)}.JqwYuG_panel{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);z-index:100;box-sizing:border-box;width:min(340px,100vw - 24px);max-height:calc(100dvh - 24px);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border-radius:var(--dsw-radius-lg);box-shadow:var(--dsw-elevation-prominent);border:0;padding:16px;font-size:13px;line-height:1.6;position:fixed;overflow:auto}.JqwYuG_panelHeader{justify-content:space-between;align-items:center;gap:12px;display:flex}.JqwYuG_panelHeader h3{margin:0;font-size:14px;font-weight:600}.JqwYuG_description{color:var(--dsw-alias-label-secondary);margin:8px 0 16px}.JqwYuG_count{color:var(--dsw-alias-label-tertiary);margin:0 0 6px;font-size:12px}.JqwYuG_fonts{overflow-wrap:anywhere;margin:0;padding:0;list-style:none}.JqwYuG_fonts li{border-top:.5px solid var(--dsw-alias-border-l2);padding:8px 0}";
5408
5419
  const tagId = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/FontNotice.module.css";
5409
5420
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
5410
5421
  const tag = document.createElement("style");
@@ -5784,14 +5795,13 @@ document.open();document.write(html);document.close();
5784
5795
  */
5785
5796
  function LazyExcelBody(props) {
5786
5797
  const format = excelFormat(hostFileOf(props.resourceAddress).path);
5798
+ const loading = (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: props.t("loading") });
5787
5799
  return (0, react_jsx_runtime.jsx)(react.Suspense, {
5788
- fallback: (0, react_jsx_runtime.jsx)(LoadingIndicator, {
5789
- className: TextPreview_module_css_default.status,
5790
- label: props.t("loading")
5791
- }),
5800
+ fallback: loading,
5792
5801
  children: (0, react_jsx_runtime.jsx)(LoadedExcelBody, {
5793
5802
  ...props,
5794
- format
5803
+ format,
5804
+ loading
5795
5805
  })
5796
5806
  });
5797
5807
  }
@@ -5801,7 +5811,7 @@ document.open();document.write(html);document.close();
5801
5811
  const zh = {
5802
5812
  title: "表格",
5803
5813
  language: "zh",
5804
- loading: "正在打开表格…",
5814
+ loading: "文档渲染中...",
5805
5815
  invalid: "无法打开此表格。请检查文件格式、内容或密码保护。",
5806
5816
  tooLarge: "此表格超过预览大小限制。",
5807
5817
  timeout: "打开表格超时。请缩小文件后重试。",
@@ -5819,7 +5829,7 @@ document.open();document.write(html);document.close();
5819
5829
  const en = {
5820
5830
  title: "Spreadsheet",
5821
5831
  language: "en",
5822
- loading: "Opening spreadsheet…",
5832
+ loading: "Rendering document...",
5823
5833
  invalid: "This spreadsheet could not be opened. Check its format, contents, or password protection.",
5824
5834
  tooLarge: "This workbook exceeds the preview size limit.",
5825
5835
  timeout: "Opening this workbook timed out. Try a smaller file.",
@@ -6848,9 +6858,9 @@ document.open();document.write(html);document.close();
6848
6858
  apply$6(ctx);
6849
6859
  apply$5(ctx);
6850
6860
  apply$4(ctx);
6851
- apply$3(ctx);
6852
6861
  apply$2(ctx, config.office);
6853
6862
  apply$1(ctx, config.excel);
6863
+ apply$3(ctx);
6854
6864
  }
6855
6865
  //#endregion
6856
6866
  exports.apply = apply;