@deepseek-ai/dsh-client-ui-sidebar-documentpreview 0.1.7-rc.1 → 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/README.i18n.yaml +45 -5
- package/README.md +10 -6
- package/README.zh.md +10 -6
- package/lib/client.excel.js +6 -10
- package/lib/client.js +65 -69
- package/lib/client.pdf.js +4 -10
- package/lib/types/client/LoadingIndicator.d.ts +4 -5
- package/lib/types/client/excel/LazyExcelBody.d.ts +2 -1
- package/lib/types/client/excel/excel.d.ts +1 -1
- package/lib/types/client/markdown/path-images.d.ts +1 -1
- package/lib/types/client/pdf/pdf.d.ts +4 -2
- package/package.json +20 -20
package/README.i18n.yaml
CHANGED
|
@@ -1,6 +1,46 @@
|
|
|
1
|
-
# Bilingual-pair consistency record (docs/i18n/README.md):
|
|
2
|
-
#
|
|
3
|
-
#
|
|
1
|
+
# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
|
|
2
|
+
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
|
|
3
|
+
# After editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/client/ui-sidebar-documentpreview/README.md
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/:
|
|
6
|
+
en: ef50065f5ff17aa1
|
|
7
|
+
zh: ee5d2b7986739fca
|
|
8
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview:
|
|
9
|
+
en: 5168e03d461318f5
|
|
10
|
+
zh: 7ad97d70ee331bfd
|
|
11
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview/summary:
|
|
12
|
+
en: a74c16667d0baada
|
|
13
|
+
zh: 4fd709ff9f98b84f
|
|
14
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview/table-of-contents:
|
|
15
|
+
en: 0dd8c3a22e28aacf
|
|
16
|
+
zh: c27c11bf4b5cceba
|
|
17
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview/what-it-registers:
|
|
18
|
+
en: a8eaf01a3a3390ee
|
|
19
|
+
zh: ddea36dbcc4a0159
|
|
20
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview/addresses:
|
|
21
|
+
en: 949156aa02ec8b07
|
|
22
|
+
zh: d3675754e2a37b5d
|
|
23
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview/how-it-reads:
|
|
24
|
+
en: 5d8bf2e43d9b6dd0
|
|
25
|
+
zh: b0d2d1d5a6f520db
|
|
26
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview/excel-preview:
|
|
27
|
+
en: b99b0e0b8efc2853
|
|
28
|
+
zh: 4327352d1334fc6b
|
|
29
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview/office-preview:
|
|
30
|
+
en: 372d8ce6492e6896
|
|
31
|
+
zh: 912f613bc9221aa3
|
|
32
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview/navigation:
|
|
33
|
+
en: 5cd81a7b3cdc83bd
|
|
34
|
+
zh: 4cdd1b7ede497925
|
|
35
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview/model-experience:
|
|
36
|
+
en: ca1deb99d0e44755
|
|
37
|
+
zh: f285fc56cee669ec
|
|
38
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview/model-experience/kv-cache-effect:
|
|
39
|
+
en: 7edb4c0bb5f13847
|
|
40
|
+
zh: ae5d0bbebe4aa563
|
|
41
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview/known-limitations-and-deferred-work:
|
|
42
|
+
en: 7be2ad2e198131f8
|
|
43
|
+
zh: 21b35eae72a49ad2
|
|
44
|
+
/deepseek-ai-dsh-client-ui-sidebar-documentpreview/known-limitations-and-deferred-work/dev-note:
|
|
45
|
+
en: 3d8904cb970145a3
|
|
46
|
+
zh: a0c0cddcfedf9e42
|
package/README.md
CHANGED
|
@@ -46,7 +46,9 @@ After all text pages load, Markdown images use the authenticated `/api/file` rou
|
|
|
46
46
|
<a id="how-it-reads"></a>
|
|
47
47
|
## How it reads
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Coding Tools selects the HTML preview policy in both Web and desktop. The renderer receives `interactivePreview` from plugin assembly. Off uses a DOMPurify-sanitized complete static document in an iframe with no sandbox permissions: CSP blocks scripts, external resources, connections, forms, and nested frames; all `href` and `xlink:href` attributes, refresh directives, and declarative shadow roots are removed before reparsing. Inline styles and data images remain visible, and related files are not read. On uses the scripted Blob preview described below. A mode change unmounts the previous frame and aborts its pending related-file reads. Static preview releases CSS/JS resource subscriptions and keeps the root file watched. Other document formats retain their own policies.
|
|
50
|
+
|
|
51
|
+
Both HTML modes set the initial iframe name to `dsh-sidebar-html-<tab-id>` for Desktop shortcut routing. This correlation does not grant the preview access to the parent document.
|
|
50
52
|
|
|
51
53
|
The body reads its record, navigation and lifetime through `useTabInfo().tab`. `useResource<'file'>(tab.contentId)` supplies metadata; ordinary inject callbacks supply content reads:
|
|
52
54
|
|
|
@@ -55,22 +57,22 @@ The body reads its record, navigation and lifetime through `useTabInfo().tab`. `
|
|
|
55
57
|
- **Complete bytes** — PDF, HTML, common images, and spreadsheets call `remote.workspaceFiles.readBytes(sessionId, path, {}, signal)`. The binary Remote returns `data: Uint8Array<ArrayBuffer>` directly for `{ kind: 'bytes', data }`. The Host's `maxFileBytes` cap rejects oversized files rather than truncating them. PDF and spreadsheet renderers copy retained bytes before Worker transfer, keeping the Preview buffer usable. Bytes stay in transient view state, never persisted layouts or Session JSONL. Loading-mode changes retire previous results.
|
|
56
58
|
- **Reload** — manual reload rereads only the current Preview tab through its Remote callbacks, preserving its scroll preference and retiring older requests. Automatic refresh uses the same callbacks after a `ResourceGroup` member changes. Each member's first metadata establishes a baseline without triggering reload or first-read version reconciliation; later changes received during a read remain pending for another refresh. Reads neither refresh shared metadata nor clear another tab's notice.
|
|
57
59
|
|
|
58
|
-
When
|
|
60
|
+
When Coding Tools is enabled, HTML fills the body edge to edge in a Blob iframe with exactly `sandbox="allow-scripts"`, without `allow-same-origin`; scripts cannot access the parent application's origin or file reader. The renderer loads directly declared relative `.js` classic scripts and `.css` stylesheets through its injected Remote callback, with fixed safety limits of 4 MiB per asset, 32 MiB total, and 64 distinct assets. Host code resolves the related path, and `readBytes` with `baseFile` returns native bytes. The dependency Resource is added after the read returns, using its `absolutePath` or a string `error.details.path` on failure; without a Host path, the Client does not guess one. Inside the renderer, base64 is used only to embed the iframe bootstrap payload in script text. A `<base href>` leaves dependency resolution to the browser, as do HTTPS resources. Local module imports, CSS `url()`/`@import`, and dynamic `fetch` do not use Host file access. Read failures, invalid UTF-8, or exceeded limits fail the preview rather than publishing a partial asset package. Replacing or unmounting the document releases its Blob URL.
|
|
59
61
|
|
|
60
62
|
PNG, JPEG, GIF, WebP, BMP, ICO, and SVG render through Blob URLs in an `<img>` static-image context, rounded inside a 12px inset. Images default to fit width without enlarging content smaller than the pane; 100% uses the image's intrinsic CSS-pixel width. The shared zoom controls can produce horizontal and vertical scrolling, but do not provide drag-to-pan. Zoom changes retain the same `<img>` and Blob URL, so animated images continue playing. Raster formats can soften above their intrinsic size, while SVG remains on the browser's vector rendering path. SVG markup never enters the application DOM or an iframe, so its scripts cannot execute or reach the parent page. Replacing or unmounting the image revokes its Blob URL.
|
|
61
63
|
|
|
62
|
-
Shared copy comes from `sidebarDocumentPreview`; each builtin renderer owns its localized labels. PDF and converted Office previews use a
|
|
64
|
+
Shared copy comes from `sidebarDocumentPreview`; each builtin renderer owns its localized labels. PDF and converted Office previews use a cool light-grey background in light mode and a matte-black background in dark mode, with subtle page shadows and original document colors. PDF and image previews share a floating control with **Fit width**, 25%, 50%, 100%, 150%, and 200% choices plus 25% incremental zoom across the 25%–400% fixed range. Fit width is the default and tracks pane resizing; 100% means the PDF's 96-DPI page size or the image's intrinsic CSS-pixel size. On fine pointers, the control starts hidden, slides up when the pointer enters the bottom 72 CSS pixels, and slides down after a 420 ms leave delay; hover, keyboard focus, an open menu, and an active gesture keep it visible, while devices without hover keep it visible continuously. Chromium maps a macOS trackpad pinch to the same live, pointer-anchored path as Ctrl+wheel; the control displays the gesture percentage, and the settled value survives body remounts until the tab closes. HTML previews do not expose zoom controls. After zoom settles or fit width changes, nearby PDF pages redraw at the resolved scale multiplied by the device pixel ratio. The previous bitmap and selectable text stay visible until the replacement bitmap is ready; offscreen pages refresh when they approach the viewport.
|
|
63
65
|
|
|
64
|
-
Initial reads
|
|
66
|
+
Initial reads and renderer preparation, including Office conversion, share a centered 28px ongoing `StateDot` with the visible localized status “Rendering document...”. The status exposes the same accessible name and respects reduced-motion preferences. Additional text pages keep a compact inline spinner while loaded content stays visible. The PDF body loads its package-local `client.pdf.js` chunk only when a PDF preview mounts; PDF.js, its Worker source, and embedded support data stay out of the startup `client.js`. PDF and converted Word/PowerPoint pages form a vertical sequence with 12px page gaps and a 12px outer inset showing the theme-specific document background; fit width reserves this inset, and pages render lazily near the viewport; an unrendered page holds its place as a quiet 3:4 placeholder block. PDF.js’s official TextLayerBuilder manages selection boundaries and normalized copying over an aligned text layer. Its companion styles keep blank line breaks unhighlighted; alignment accounts for PDF page units, page rotation, and viewport resizing, and page disposal cancels both layers. Image-only PDFs contain no selectable text. Code previews show a tertiary-colored language label and a copy icon with a tooltip; wrapping remains in the document toolbar. They show source line numbers by default without including them in copied text; plain text uses the same font size and line height as code. Code sits on the pane's own background rather than the chat card's fill; its banner is adjacent to a full-height inner scrollport, so both scrollbars begin below the copy control.
|
|
65
67
|
|
|
66
68
|
<a id="excel-preview"></a>
|
|
67
69
|
## Excel preview
|
|
68
70
|
|
|
69
|
-
Open `.xlsx`, `.xls`, `.csv`, and `.tsv` directly in the browser with worksheet tabs, cell selection, copying, and a read-only formula bar. XLSX retains fonts, solid fills, borders, number formats, rich text, merged cells, row and column sizes, hidden rows/columns/sheets, and frozen headings. XLS retains saved values, formulas, number formats, merges, and available row/column metadata; fonts, borders, and frozen panes are unsupported. Workbooks display saved formula results without recalculating; missing results remain blank, and a compact formula-bar warning marks workbooks whose displayed results may be incomplete or inaccurate. The workbook viewport fills the preview pane and follows its size changes without reloading its sheets or selection. Worksheet tabs start at the left edge; overflowing tabs scroll with horizontal trackpad gestures or left/right navigation beside a separate zoom control. Spreadsheet controls retain dark text on their light background in both app themes. Pixel-based trackpad gestures pan the grid on both axes together, including diagonally, at the gesture’s speed; frozen headings stay fixed. Selection statistics and inactive worksheet menu arrows are hidden. Frozen headings remain fixed while scrolling, without freeze dividers or drag handles. Spreadsheet preview does not call the Office conversion service.
|
|
71
|
+
Open `.xlsx`, `.xls`, `.csv`, and `.tsv` directly in the browser with worksheet tabs, cell selection, copying, and a read-only formula bar. XLSX retains fonts, solid fills, borders, number formats, rich text, merged cells, row and column sizes, hidden rows/columns/sheets, and frozen headings. XLS retains saved values, formulas, number formats, merges, and available row/column metadata; fonts, borders, and frozen panes are unsupported. Workbooks display saved formula results without recalculating; missing results remain blank, and a compact formula-bar warning marks workbooks whose displayed results may be incomplete or inaccurate. The workbook viewport fills the preview pane and follows its size changes without reloading its sheets or selection. Worksheet tabs start at the left edge; overflowing tabs scroll with horizontal trackpad gestures or left/right navigation beside a separate zoom control. Spreadsheet controls retain dark text on their light background in both app themes. Pixel-based trackpad gestures pan the grid on both axes together, including diagonally, at the gesture’s speed; frozen headings stay fixed. Reversing direction at a sheet edge retains the next gesture’s movement. Selection statistics and inactive worksheet menu arrows are hidden. Frozen headings remain fixed while scrolling, without freeze dividers or drag handles. Spreadsheet preview does not call the Office conversion service.
|
|
70
72
|
|
|
71
73
|
XLSX preview omits DrawingML parts from an in-memory copy before parsing and ignores worksheet drawing references. The original file and worksheet XML remain unchanged. A notice above the table lists detected charts, images, shapes, and conditional formatting that are not displayed, and recommends opening the workbook in a system application. Files without these detected features have no notice; formula warnings remain separate.
|
|
72
74
|
|
|
73
|
-
CSV and TSV default to the spreadsheet viewer and also offer Plain text. Commas and tabs delimit their fields respectively; quoted separators, escaped quotes, multiline fields, empty fields, and unequal row lengths are supported. The first row remains data. Values remain literal strings, including leading zeros, dates, booleans, and formula-looking text. Text files accept UTF-8 or BOM-marked UTF-16; invalid encoding receives conversion guidance. Malformed quoted fields fail the table preview rather than silently dropping data.
|
|
75
|
+
CSV and TSV default to the spreadsheet viewer and also offer Plain text; CSV additionally offers syntax-highlighted Code. Commas and tabs delimit their fields respectively; quoted separators, escaped quotes, multiline fields, empty fields, and unequal row lengths are supported. The first row remains data. Values remain literal strings, including leading zeros, dates, booleans, and formula-looking text. Text files accept UTF-8 or BOM-marked UTF-16; invalid encoding receives conversion guidance. Malformed quoted fields fail the table preview rather than silently dropping data.
|
|
74
76
|
|
|
75
77
|
Configure `excel` on the same `ui-sidebar-documentpreview` entry. These limits complement the Host's complete-file read limit; they do not cap browser process memory or decompression allocations.
|
|
76
78
|
|
|
@@ -112,6 +114,8 @@ Office registration, loading, caching, and font notices live in `src/client/offi
|
|
|
112
114
|
|
|
113
115
|
The Office Remote returns converted PDFs as native `Uint8Array` values through Connection's multipart binary transport. Renderers borrow retained bytes read-only and copy them before Worker transfer.
|
|
114
116
|
|
|
117
|
+
The page refresh shortcut reuses the selected preview’s reload operation, including its request retirement and scroll retention. The header reload tooltip and ARIA combination follow the effective shortcut binding.
|
|
118
|
+
|
|
115
119
|
</details>
|
|
116
120
|
|
|
117
121
|
<a id="navigation"></a>
|
package/README.zh.md
CHANGED
|
@@ -46,7 +46,9 @@ tab 使用 `fileAddressFor` 构造的 Session 地址,携带相对或绝对路
|
|
|
46
46
|
<a id="how-it-reads"></a>
|
|
47
47
|
## 怎么读
|
|
48
48
|
|
|
49
|
-
Web
|
|
49
|
+
Web 和桌面端均通过代码工作工具选择 HTML 预览策略。渲染器从插件组装层接收 `interactivePreview`。关闭时,将经 DOMPurify 清理的完整静态文档放入不授予沙箱权限的 iframe:CSP 禁止脚本、外部资源、连接、表单和嵌套框架;所有 `href` 和 `xlink:href` 属性、刷新指令及声明式 Shadow DOM 均在重新解析前被移除。行内样式和 data 图片仍可显示,不读取关联文件。开启时使用下述支持脚本的 Blob 预览。切换模式会卸载之前的框架并中止其待处理关联文件读取。静态预览释放 CSS/JS 的 Resource 订阅,根文件继续监听。其他文档格式保持各自策略。
|
|
50
|
+
|
|
51
|
+
两种 HTML 模式均将 iframe 初始名称设为 `dsh-sidebar-html-<tab-id>`,供 Desktop 快捷键路由关联目标。这种关联不授予预览访问父文档的权限。
|
|
50
52
|
|
|
51
53
|
正文通过 `useTabInfo().tab` 读取记录、导航和生命周期。`useResource<'file'>(tab.contentId)` 提供元数据,普通 inject 回调提供内容读取:
|
|
52
54
|
|
|
@@ -55,22 +57,22 @@ Web 和桌面端均通过开发者工具选择 HTML 预览策略。渲染器从
|
|
|
55
57
|
- **完整字节** —— PDF、HTML、常见图片和表格调用 `remote.workspaceFiles.readBytes(sessionId, path, {}, signal)`。二进制 Remote 直接返回 `data: Uint8Array<ArrayBuffer>`,供 `{ kind: 'bytes', data }` 使用。Host 的 `maxFileBytes` 上限拒绝超大文件,不截断。PDF 和表格渲染器在传给 Worker 前复制保留的字节,使 Preview 缓冲区仍可使用。字节仅保存在临时视图状态中,绝不进入持久布局或 Session JSONL。加载模式变化会淘汰先前结果。
|
|
56
58
|
- **重新载入** —— 手动重新载入仅让当前 Preview tab 通过自己的 Remote 回调重读,保留滚动偏好并淘汰旧请求。`ResourceGroup` 成员变化后,自动刷新使用相同回调。各成员首次元数据仅建立基线,不触发重新载入或首读版本对账;后续在读取期间收到的变化仍会留待下一次刷新。读取既不刷新共享元数据,也不清除其它 tab 的提示。
|
|
57
59
|
|
|
58
|
-
|
|
60
|
+
开启代码工作工具时,HTML 以贴合正文四边的 Blob iframe 运行,沙箱属性严格为 `sandbox="allow-scripts"`,不含 `allow-same-origin`;脚本无法访问父应用的源或文件读取接口。渲染器通过注入的 Remote 回调,加载直接声明的相对 `.js` 经典脚本和 `.css` 样式表;固定安全上限为单个资源 4 MiB、总计 32 MiB、64 个不同资源。Host 代码解析关联路径,带 `baseFile` 的 `readBytes` 返回原生字节。依赖 Resource 在读取返回后加入,使用返回的 `absolutePath`,失败时则使用字符串类型的 `error.details.path`;没有 Host 路径时,Client 不自行猜测。在渲染器内部,base64 仅用于把 iframe 引导载荷嵌入脚本文本。`<base href>` 将依赖解析交给浏览器,HTTPS 资源也由浏览器处理。本地模块 import、CSS `url()`/`@import` 和动态 `fetch` 不使用 Host 文件访问。读取失败、无效 UTF-8 或超出上限都使预览失败,不发布部分资源包。替换或卸载文档会释放其 Blob URL。
|
|
59
61
|
|
|
60
62
|
PNG、JPEG、GIF、WebP、BMP、ICO 和 SVG 通过 Blob URL 在 `<img>` 静态图片上下文中渲染,带 12px 内边距和圆角。图片默认适应宽度,但不会放大小于面板的内容;100% 使用图片的固有 CSS 像素宽度。共享缩放控件可产生横向和纵向滚动,但不提供拖拽平移。缩放不会替换 `<img>` 或 Blob URL,因此动画图片会继续播放。位图超过固有尺寸后可能变虚,SVG 则继续使用浏览器的矢量渲染路径。SVG 标记绝不进入应用 DOM 或 iframe,因此其中的脚本无法执行,也无法访问父页面。替换或卸载图片会撤销其 Blob URL。
|
|
61
63
|
|
|
62
|
-
共享文案来自 `sidebarDocumentPreview`;各内置渲染器拥有自己的本地化标签。PDF 与转换后的 Office
|
|
64
|
+
共享文案来自 `sidebarDocumentPreview`;各内置渲染器拥有自己的本地化标签。PDF 与转换后的 Office 预览在浅色模式下使用冷调浅灰底色,在深色模式下使用哑黑底色,页面带有轻微阴影并保留文档原色。PDF 与图片预览共用浮动控件,提供**适应宽度**、25%、50%、100%、150% 和 200% 选项,并在 25%–400% 固定范围内按 25% 逐级缩放。适应宽度是默认模式并跟随面板尺寸;100% 表示 PDF 的 96 DPI 页面尺寸或图片的固有 CSS 像素尺寸。在精细指针设备上,控件初始隐藏;指针进入底部 72 个 CSS 像素时向上滑入,离开 420 ms 后向下退出;控件悬停、键盘焦点、菜单展开和手势进行期间保持显示,无 hover 的设备则始终显示。Chromium 将 macOS 触控板捏合映射到与 Ctrl+滚轮相同的实时指针锚定路径;控件同步显示手势比例,静止后的值在正文重新挂载后继续保留,直至 tab 关闭。HTML 预览不显示缩放控件。缩放稳定或适应宽度发生变化后,视口附近的 PDF 页面按最终缩放比例乘以设备像素比重绘。新位图完成前保留原有画面和可选文字层;屏幕外的页面在接近视口时更新。
|
|
63
65
|
|
|
64
|
-
|
|
66
|
+
首次读取及渲染器准备(包括 Office 转换)共用居中的 28px ongoing `StateDot`,下方显示本地化状态文字“文档渲染中...”。状态向辅助技术提供相同的名称,并遵循减少动态效果偏好。追加文本页时使用紧凑的行内转圈,同时保留已显示的内容。PDF 正文仅在 PDF 预览挂载时加载包内 `client.pdf.js` chunk;PDF.js、Worker 源码和内嵌支持数据不会进入启动 `client.js`。PDF 与转换后的 Word/PowerPoint 页面组成纵向序列,页间距与四周留白均为 12px,露出当前主题的文档背景色;适应宽度会预留此留白,页面在接近视口时惰性渲染;未渲染的页以安静的 3:4 占位块保持位置。PDF.js 官方 TextLayerBuilder 在与画面重合的文字层上管理选区边界和复制文本规范化。配套样式不高亮空白换行;对齐同时考虑 PDF 页面单位、页面旋转与视口宽度变化,页面释放时取消两层渲染。纯图片 PDF 不包含可选取的文字。代码预览使用 tertiary 色的语言名称和带提示的复制图标;换行仍由文档工具栏控制。默认显示源码行号,但复制文本不包含行号;纯文本与代码使用相同字号和行高。代码直接坐在分栏自身的背景上,而不是会话卡片的填充色;复制条与占满剩余高度的内部滚动区相邻,因此横纵滚动条都从复制控件下方开始。
|
|
65
67
|
|
|
66
68
|
<a id="excel-preview"></a>
|
|
67
69
|
## Excel 预览
|
|
68
70
|
|
|
69
|
-
直接在浏览器中打开 `.xlsx`、`.xls`、`.csv` 和 `.tsv`,支持工作表标签、单元格选择、复制和只读公式栏。XLSX 保留字体、纯色填充、边框、数字格式、富文本、合并单元格、行列尺寸、隐藏行列及工作表,以及冻结标题。XLS
|
|
71
|
+
直接在浏览器中打开 `.xlsx`、`.xls`、`.csv` 和 `.tsv`,支持工作表标签、单元格选择、复制和只读公式栏。XLSX 保留字体、纯色填充、边框、数字格式、富文本、合并单元格、行列尺寸、隐藏行列及工作表,以及冻结标题。XLS 保留已保存的值、公式、数字格式、合并及可用的行列元数据;不支持字体、边框和冻结窗格。工作簿显示已保存的公式结果而不重新计算;缺少的结果保持为空,公式栏旁的紧凑提示会标记显示结果可能不完整或不准确的工作簿。工作簿视图填满预览面板,并随面板尺寸变化自动调整,无需重新加载工作表或选择状态。工作表标签从左侧边缘开始排列;标签溢出时可用触控板横向手势或左右按钮滚动,缩放控件独立占位。表格控件在应用的明暗两种主题下均保持浅色背景和深色文字。触控板的像素位移可同时平移表格的横纵两个方向,包括斜向平移,移动距离跟随手势;冻结标题保持固定。到达工作表边缘后反向移动,仍会保留下一次手势的位移。隐藏选区统计栏及无效的工作表菜单箭头。冻结标题在滚动时保持固定,不显示冻结分隔线和拖拽条。表格预览不调用 Office 转换服务。
|
|
70
72
|
|
|
71
73
|
XLSX 预览在解析前从内存副本中移除 DrawingML 部件,并忽略工作表的绘图引用。原文件和工作表 XML 保持不变。表格上方的提示列出实际检测到但未展示的图表、图片、形状和条件格式,并建议使用系统应用打开工作簿。未检测到这些内容的文件不显示此提示;公式提示保持独立。
|
|
72
74
|
|
|
73
|
-
CSV 和 TSV
|
|
75
|
+
CSV 和 TSV 默认使用表格查看器,也可选择纯文本;CSV 还提供带语法高亮的 Code 预览。两者分别以逗号和制表符分隔字段,支持引号内分隔符、转义引号、多行字段、空字段和不等长行。首行仍作为数据。值保持为字面字符串,包括前导零、日期、布尔值和类似公式的文本。文本文件支持 UTF-8 或带 BOM 的 UTF-16;无效编码会显示转换提示。引号字段格式错误会使表格预览失败,不会静默丢弃数据。
|
|
74
76
|
|
|
75
77
|
在同一个 `ui-sidebar-documentpreview` 条目上配置 `excel`。这些限制补充 Host 的完整文件读取限制,但不限制浏览器进程内存或解压分配量。
|
|
76
78
|
|
|
@@ -112,6 +114,8 @@ Office 注册、加载、缓存和字体提示位于 `src/client/office/`。注
|
|
|
112
114
|
|
|
113
115
|
Office Remote 通过 Connection 的 multipart 二进制传输返回原生 `Uint8Array` PDF。渲染器以只读方式借用保留的字节,并在传给 Worker 前复制。
|
|
114
116
|
|
|
117
|
+
页面刷新快捷键复用所选预览的重载操作,包括旧请求失效与滚动位置保留。头部重载 Tooltip 和 ARIA 组合随有效快捷键绑定更新。
|
|
118
|
+
|
|
115
119
|
</details>
|
|
116
120
|
|
|
117
121
|
<a id="navigation"></a>
|
package/lib/client.excel.js
CHANGED
|
@@ -28117,7 +28117,7 @@ window.__ModuleLoader__.load({
|
|
|
28117
28117
|
return stringify(rnds);
|
|
28118
28118
|
}
|
|
28119
28119
|
//#endregion
|
|
28120
|
-
//#region ../../../node_modules/.pnpm/@fortune-sheet+core@1.0.4_patch_hash=
|
|
28120
|
+
//#region ../../../node_modules/.pnpm/@fortune-sheet+core@1.0.4_patch_hash=8791a230763dbf853fd65d627c68c31de37209992851377855e16cf08ea70532/node_modules/@fortune-sheet/core/dist/index.esm.js
|
|
28121
28121
|
function _arrayLikeToArray$1(r, a) {
|
|
28122
28122
|
(null == a || a > r.length) && (a = r.length);
|
|
28123
28123
|
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
@@ -119987,6 +119987,8 @@ window.__ModuleLoader__.load({
|
|
|
119987
119987
|
if (ctx.allowEdit === false && e.deltaMode === 0) {
|
|
119988
119988
|
scrollbarX.scrollLeft += e.deltaX;
|
|
119989
119989
|
scrollbarY.scrollTop += e.deltaY;
|
|
119990
|
+
ctx.scrollLeft = scrollbarX.scrollLeft;
|
|
119991
|
+
ctx.scrollTop = scrollbarY.scrollTop;
|
|
119990
119992
|
e.preventDefault();
|
|
119991
119993
|
return;
|
|
119992
119994
|
}
|
|
@@ -133666,7 +133668,7 @@ window.__ModuleLoader__.load({
|
|
|
133666
133668
|
}
|
|
133667
133669
|
//#endregion
|
|
133668
133670
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/excel/ExcelBody.module.css.mjs
|
|
133669
|
-
const css = "._3HaaOG_body{white-space:normal;height:100%;min-height:0;font-family:var(--dsw-font,sans-serif);flex-direction:column;display:flex;overflow:hidden}._3HaaOG_workbook{color-scheme:light;color:canvastext;flex:1;min-width:0;min-height:0;position:relative}._3HaaOG_workbook .fortune-stat-area,._3HaaOG_workbook .luckysheet-sheets-item-function,._3HaaOG_workbook .fortune-cols-freeze-handle,._3HaaOG_workbook .fortune-rows-freeze-handle{display:none}._3HaaOG_workbook .luckysheet-sheet-area div.luckysheet-sheets-item{padding-right:5px}._3HaaOG_workbook .luckysheet-sheet-area{padding:0}._3HaaOG_workbook #luckysheet-sheet-content{flex:1;min-width:0}._3HaaOG_workbook .fortune-sheettab-container{flex:1;min-width:0;max-width:100%}._3HaaOG_workbook .fortune-sheettab-container .fortune-sheettab-container-c{overscroll-behavior-x:contain;scrollbar-width:none;overflow:auto hidden}._3HaaOG_workbook .fortune-sheettab-scroll,._3HaaOG_workbook .fortune-sheet-area-right{flex:none}._3HaaOG_workbook .fortune-fx-input-container{min-width:0}._3HaaOG_workbook .fortune-fx-input{white-space:nowrap;scrollbar-width:none;min-width:0;overflow:auto hidden}._3HaaOG_notice{color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);overflow-wrap:anywhere;flex:none;align-items:flex-start;gap:8px;padding:8px 12px;line-height:1.5;display:flex}._3HaaOG_notice>svg{flex:none;margin-top:2px}._3HaaOG_formulaWarning{z-index:3;width:20px;height:20px;color:var(--dsw-alias-state-warn-label);background:0 0;border:0;
|
|
133671
|
+
const css = "._3HaaOG_body{white-space:normal;height:100%;min-height:0;font-family:var(--dsw-font,sans-serif);flex-direction:column;display:flex;overflow:hidden}._3HaaOG_workbook{color-scheme:light;color:canvastext;flex:1;min-width:0;min-height:0;position:relative}._3HaaOG_workbook .fortune-stat-area,._3HaaOG_workbook .luckysheet-sheets-item-function,._3HaaOG_workbook .fortune-cols-freeze-handle,._3HaaOG_workbook .fortune-rows-freeze-handle{display:none}._3HaaOG_workbook .luckysheet-sheet-area div.luckysheet-sheets-item{padding-right:5px}._3HaaOG_workbook .luckysheet-sheet-area{padding:0}._3HaaOG_workbook #luckysheet-sheet-content{flex:1;min-width:0}._3HaaOG_workbook .fortune-sheettab-container{flex:1;min-width:0;max-width:100%}._3HaaOG_workbook .fortune-sheettab-container .fortune-sheettab-container-c{overscroll-behavior-x:contain;scrollbar-width:none;overflow:auto hidden}._3HaaOG_workbook .fortune-sheettab-scroll,._3HaaOG_workbook .fortune-sheet-area-right{flex:none}._3HaaOG_workbook .fortune-fx-input-container{min-width:0}._3HaaOG_workbook .fortune-fx-input{white-space:nowrap;scrollbar-width:none;min-width:0;overflow:auto hidden}._3HaaOG_notice{color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);overflow-wrap:anywhere;flex:none;align-items:flex-start;gap:8px;padding:8px 12px;line-height:1.5;display:flex}._3HaaOG_notice>svg{flex:none;margin-top:2px}._3HaaOG_formulaWarning{z-index:3;width:20px;height:20px;color:var(--dsw-alias-state-warn-label);border-radius:var(--dsw-radius-sm);background:0 0;border:0;padding:3px;display:flex;position:absolute;top:4px;left:142px}._3HaaOG_formulaWarning:hover,._3HaaOG_formulaWarning:focus-visible{background:var(--dsw-alias-state-warn-tertiary);outline:none}._3HaaOG_withFormulaWarning .fortune-fx-input{padding-left:24px}._3HaaOG_status{height:100%;color:var(--dsw-alias-label-secondary);justify-content:center;align-items:center;gap:8px;padding:16px;display:flex}";
|
|
133670
133672
|
const tagId = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/ExcelBody.module.css";
|
|
133671
133673
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
133672
133674
|
const tag = document.createElement("style");
|
|
@@ -133693,7 +133695,7 @@ window.__ModuleLoader__.load({
|
|
|
133693
133695
|
* @param props - Complete workbook bytes, limits, and locale.
|
|
133694
133696
|
* @returns An isolated spreadsheet surface with cancellable loading.
|
|
133695
133697
|
*/
|
|
133696
|
-
function ExcelBody({ content, format, limits, t }) {
|
|
133698
|
+
function ExcelBody({ content, format, limits, t, loading }) {
|
|
133697
133699
|
const data = content.kind === "bytes" ? content.data : void 0;
|
|
133698
133700
|
const [state, setState] = (0, react.useState)();
|
|
133699
133701
|
const [attempt, setAttempt] = (0, react.useState)(0);
|
|
@@ -133740,13 +133742,7 @@ window.__ModuleLoader__.load({
|
|
|
133740
133742
|
role: "alert",
|
|
133741
133743
|
children: t("invalid")
|
|
133742
133744
|
});
|
|
133743
|
-
if (state?.data !== data || state.format !== format) return
|
|
133744
|
-
className: ExcelBody_module_css_default.status,
|
|
133745
|
-
role: "status",
|
|
133746
|
-
"aria-label": t("loading"),
|
|
133747
|
-
"data-document-loading": true,
|
|
133748
|
-
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "ongoing" })
|
|
133749
|
-
});
|
|
133745
|
+
if (state?.data !== data || state.format !== format) return loading;
|
|
133750
133746
|
if ("error" in state) return (0, react_jsx_runtime.jsxs)("div", {
|
|
133751
133747
|
className: ExcelBody_module_css_default.status,
|
|
133752
133748
|
role: "alert",
|
package/lib/client.js
CHANGED
|
@@ -132,12 +132,12 @@ window.__ModuleLoader__.load({
|
|
|
132
132
|
}
|
|
133
133
|
/**
|
|
134
134
|
* Address a decoded absolute file path through the authenticated file route.
|
|
135
|
-
* @param base - HTTP(S) application base, including its deployment prefix
|
|
135
|
+
* @param base - HTTP(S) application base, including its deployment prefix, or `dsh-app://app/`.
|
|
136
136
|
* @param path - Native file path; URL escapes in authored Markdown must already be decoded.
|
|
137
137
|
* @returns File URL, or undefined for unsupported transports and non-absolute paths.
|
|
138
138
|
*/
|
|
139
139
|
function fileMediaUrl(base, path) {
|
|
140
|
-
if (!/^https?:/u.test(base) || !isAbsoluteWorkspacePath(path) || /^[/\\]{2}/u.test(path) || /[\u0000-\u001f\u007f]/u.test(path)) return void 0;
|
|
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
141
|
return new URL(`api/file?path=${encodeURIComponent(path)}`, base).href;
|
|
142
142
|
}
|
|
143
143
|
//#endregion
|
|
@@ -181,7 +181,7 @@ window.__ModuleLoader__.load({
|
|
|
181
181
|
}
|
|
182
182
|
//#endregion
|
|
183
183
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/LoadingIndicator.module.css.mjs
|
|
184
|
-
const css$9 = ".tKrPPq_loading{
|
|
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}";
|
|
185
185
|
const tagId$9 = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/LoadingIndicator.module.css";
|
|
186
186
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$9) + "]") === null) {
|
|
187
187
|
const tag = document.createElement("style");
|
|
@@ -190,21 +190,26 @@ window.__ModuleLoader__.load({
|
|
|
190
190
|
tag.textContent = css$9;
|
|
191
191
|
document.head.appendChild(tag);
|
|
192
192
|
}
|
|
193
|
-
var LoadingIndicator_module_css_default = {
|
|
193
|
+
var LoadingIndicator_module_css_default = {
|
|
194
|
+
"inline": "tKrPPq_inline",
|
|
195
|
+
"loading": "tKrPPq_loading"
|
|
196
|
+
};
|
|
194
197
|
//#endregion
|
|
195
198
|
//#region lib/types/client/LoadingIndicator.js
|
|
196
199
|
/**
|
|
197
|
-
* @param props - localized status label
|
|
198
|
-
*
|
|
199
|
-
* @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.
|
|
200
202
|
*/
|
|
201
|
-
function LoadingIndicator({ label,
|
|
202
|
-
return (0, react_jsx_runtime.
|
|
203
|
-
className: clsx(LoadingIndicator_module_css_default.loading,
|
|
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),
|
|
204
206
|
role: "status",
|
|
205
207
|
"aria-label": label,
|
|
206
208
|
"data-document-loading": true,
|
|
207
|
-
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
|
|
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 })]
|
|
208
213
|
});
|
|
209
214
|
}
|
|
210
215
|
//#endregion
|
|
@@ -483,7 +488,7 @@ window.__ModuleLoader__.load({
|
|
|
483
488
|
}
|
|
484
489
|
//#endregion
|
|
485
490
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/TextPreview.module.css.mjs
|
|
486
|
-
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;
|
|
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}";
|
|
487
492
|
const tagId$8 = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/TextPreview.module.css";
|
|
488
493
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$8) + "]") === null) {
|
|
489
494
|
const tag = document.createElement("style");
|
|
@@ -495,7 +500,6 @@ window.__ModuleLoader__.load({
|
|
|
495
500
|
var TextPreview_module_css_default = {
|
|
496
501
|
"action": "dhJKeW_action",
|
|
497
502
|
"body": "dhJKeW_body",
|
|
498
|
-
"bodyLoading": "dhJKeW_bodyLoading",
|
|
499
503
|
"changed": "dhJKeW_changed",
|
|
500
504
|
"empty": "dhJKeW_empty",
|
|
501
505
|
"emptyIcon": "dhJKeW_emptyIcon",
|
|
@@ -732,6 +736,7 @@ window.__ModuleLoader__.load({
|
|
|
732
736
|
signal,
|
|
733
737
|
observedVersion
|
|
734
738
|
]);
|
|
739
|
+
(0, react.useEffect)(() => tab.actions.bindCommands({ refresh: reload }), [tab.actions, reload]);
|
|
735
740
|
(0, react.useEffect)(() => {
|
|
736
741
|
if (state?.autoRefresh && changed && current !== void 0 && !current.loading && meta.status === "live") reload();
|
|
737
742
|
}, [
|
|
@@ -819,10 +824,7 @@ window.__ModuleLoader__.load({
|
|
|
819
824
|
children: meta.status === "none" ? (0, react_jsx_runtime.jsx)("p", {
|
|
820
825
|
className: TextPreview_module_css_default.statusLine,
|
|
821
826
|
children: t("resourceUnavailable")
|
|
822
|
-
}) : (0, react_jsx_runtime.jsx)(LoadingIndicator, {
|
|
823
|
-
className: TextPreview_module_css_default.statusLine,
|
|
824
|
-
label: t("loading")
|
|
825
|
-
})
|
|
827
|
+
}) : (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") })
|
|
826
828
|
});
|
|
827
829
|
const next = loadedThrough + 1;
|
|
828
830
|
const { name } = pathPartsOf(displayPath);
|
|
@@ -935,6 +937,7 @@ window.__ModuleLoader__.load({
|
|
|
935
937
|
}),
|
|
936
938
|
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
937
939
|
label: t("reload"),
|
|
940
|
+
shortcutKeys: tab.refreshShortcut?.keys,
|
|
938
941
|
side: "bottom",
|
|
939
942
|
delayMs: 500,
|
|
940
943
|
children: (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -942,6 +945,7 @@ window.__ModuleLoader__.load({
|
|
|
942
945
|
className: TextPreview_module_css_default.tool,
|
|
943
946
|
"aria-label": t("reload"),
|
|
944
947
|
"data-textpreview-tool": "reload",
|
|
948
|
+
"aria-keyshortcuts": tab.refreshShortcut?.aria,
|
|
945
949
|
onClick: reload,
|
|
946
950
|
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutlineRegular, {})
|
|
947
951
|
})
|
|
@@ -963,10 +967,7 @@ window.__ModuleLoader__.load({
|
|
|
963
967
|
if (mode === "text-pages" && current?.failure === void 0 && body.clientHeight > 0 && body.scrollTop + body.clientHeight >= body.scrollHeight - 1) loadNext();
|
|
964
968
|
},
|
|
965
969
|
children: [
|
|
966
|
-
mode !== "renderer" && !hasContent && current?.failure === void 0 && (0, react_jsx_runtime.jsx)(LoadingIndicator, {
|
|
967
|
-
className: clsx(TextPreview_module_css_default.statusLine, TextPreview_module_css_default.bodyLoading),
|
|
968
|
-
label: t("loading")
|
|
969
|
-
}),
|
|
970
|
+
mode !== "renderer" && !hasContent && current?.failure === void 0 && (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") }),
|
|
970
971
|
content !== void 0 && renderSlot("sidebar.right.tab.document", {
|
|
971
972
|
resourceAddress: tab.contentId,
|
|
972
973
|
content,
|
|
@@ -1021,7 +1022,10 @@ window.__ModuleLoader__.load({
|
|
|
1021
1022
|
disabled: current.loading,
|
|
1022
1023
|
"data-textpreview-more": true,
|
|
1023
1024
|
onClick: loadNext,
|
|
1024
|
-
children: current.loading ? (0, react_jsx_runtime.jsx)(LoadingIndicator, {
|
|
1025
|
+
children: current.loading ? (0, react_jsx_runtime.jsx)(LoadingIndicator, {
|
|
1026
|
+
inline: true,
|
|
1027
|
+
label: t("loading")
|
|
1028
|
+
}) : t("loadMore")
|
|
1025
1029
|
})
|
|
1026
1030
|
]
|
|
1027
1031
|
})
|
|
@@ -1444,7 +1448,7 @@ window.__ModuleLoader__.load({
|
|
|
1444
1448
|
*/
|
|
1445
1449
|
/** Simplified Chinese dictionary and key-set source of truth. */
|
|
1446
1450
|
const zh$7 = {
|
|
1447
|
-
loading: "
|
|
1451
|
+
loading: "文档渲染中...",
|
|
1448
1452
|
loadMore: "加载更多",
|
|
1449
1453
|
changed: "文件已更新,当前显示为旧内容",
|
|
1450
1454
|
reloadNow: "重新载入",
|
|
@@ -1469,7 +1473,7 @@ window.__ModuleLoader__.load({
|
|
|
1469
1473
|
};
|
|
1470
1474
|
/** English dictionary, checked against the Chinese key set. */
|
|
1471
1475
|
const en$7 = {
|
|
1472
|
-
loading: "
|
|
1476
|
+
loading: "Rendering document...",
|
|
1473
1477
|
loadMore: "Load more",
|
|
1474
1478
|
changed: "The file has changed, showing the previous content.",
|
|
1475
1479
|
reloadNow: "Reload",
|
|
@@ -1509,7 +1513,7 @@ window.__ModuleLoader__.load({
|
|
|
1509
1513
|
* @param base - document base URI, including any deployment prefix.
|
|
1510
1514
|
* @param documentPath - absolute source path reported by the Host, when available.
|
|
1511
1515
|
* @param destination - authored Markdown image URL; query and fragment are not filename components.
|
|
1512
|
-
* @returns
|
|
1516
|
+
* @returns a Web or Desktop file URL, or undefined for unsupported or malformed destinations.
|
|
1513
1517
|
*/
|
|
1514
1518
|
function markdownImageUrl(base, documentPath, destination) {
|
|
1515
1519
|
const suffix = destination.search(/[?#]/u);
|
|
@@ -3940,7 +3944,7 @@ document.open();document.write(html);document.close();
|
|
|
3940
3944
|
}
|
|
3941
3945
|
//#endregion
|
|
3942
3946
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/html/HtmlBody.module.css.mjs
|
|
3943
|
-
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}
|
|
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}";
|
|
3944
3948
|
const tagId$6 = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/HtmlBody.module.css";
|
|
3945
3949
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$6) + "]") === null) {
|
|
3946
3950
|
const tag = document.createElement("style");
|
|
@@ -3951,14 +3955,13 @@ document.open();document.write(html);document.close();
|
|
|
3951
3955
|
}
|
|
3952
3956
|
var HtmlBody_module_css_default = {
|
|
3953
3957
|
"frame": "HyIruq_frame",
|
|
3954
|
-
"opening": "HyIruq_opening",
|
|
3955
3958
|
"status": "HyIruq_status"
|
|
3956
3959
|
};
|
|
3957
3960
|
//#endregion
|
|
3958
3961
|
//#region lib/types/client/html/HtmlBody.js
|
|
3959
3962
|
/** Static or interactive HTML in an opaque iframe, without parent application access. */
|
|
3960
3963
|
/** One mounted file owns its root Blob; replacing content also replaces the browsing context. */
|
|
3961
|
-
function HtmlFrame({ data, resourceAddress, readRelated, addResource, setResources, signal, t }) {
|
|
3964
|
+
function HtmlFrame({ data, resourceAddress, readRelated, addResource, setResources, signal, frameName, t }) {
|
|
3962
3965
|
const [frame, setFrame] = (0, react.useState)();
|
|
3963
3966
|
(0, react.useEffect)(() => {
|
|
3964
3967
|
const controller = new AbortController();
|
|
@@ -4001,16 +4004,14 @@ document.open();document.write(html);document.close();
|
|
|
4001
4004
|
setResources,
|
|
4002
4005
|
signal
|
|
4003
4006
|
]);
|
|
4004
|
-
if (frame?.data !== data || frame.readRelated !== readRelated) return (0, react_jsx_runtime.jsx)(LoadingIndicator, {
|
|
4005
|
-
className: clsx(HtmlBody_module_css_default.status, HtmlBody_module_css_default.opening),
|
|
4006
|
-
label: t("loading")
|
|
4007
|
-
});
|
|
4007
|
+
if (frame?.data !== data || frame.readRelated !== readRelated) return (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") });
|
|
4008
4008
|
if (frame.url === void 0) return (0, react_jsx_runtime.jsx)("p", {
|
|
4009
4009
|
className: HtmlBody_module_css_default.status,
|
|
4010
4010
|
role: "alert",
|
|
4011
4011
|
children: t("failed")
|
|
4012
4012
|
});
|
|
4013
4013
|
return (0, react_jsx_runtime.jsx)("iframe", {
|
|
4014
|
+
name: frameName,
|
|
4014
4015
|
className: HtmlBody_module_css_default.frame,
|
|
4015
4016
|
src: frame.url,
|
|
4016
4017
|
sandbox: "allow-scripts",
|
|
@@ -4030,8 +4031,10 @@ document.open();document.write(html);document.close();
|
|
|
4030
4031
|
if (!interactivePreview) setResources([]);
|
|
4031
4032
|
}, [interactivePreview, setResources]);
|
|
4032
4033
|
if (content.kind !== "bytes") return null;
|
|
4034
|
+
const frameName = `dsh-sidebar-html-${tab.id}`;
|
|
4033
4035
|
if (!interactivePreview) return (0, react_jsx_runtime.jsx)(BasicHtmlFrame, {
|
|
4034
4036
|
data: content.data,
|
|
4037
|
+
frameName,
|
|
4035
4038
|
t
|
|
4036
4039
|
});
|
|
4037
4040
|
return (0, react_jsx_runtime.jsx)(HtmlFrame, {
|
|
@@ -4039,13 +4042,14 @@ document.open();document.write(html);document.close();
|
|
|
4039
4042
|
resourceAddress,
|
|
4040
4043
|
readRelated,
|
|
4041
4044
|
signal: tab.signal,
|
|
4045
|
+
frameName,
|
|
4042
4046
|
addResource,
|
|
4043
4047
|
setResources,
|
|
4044
4048
|
t
|
|
4045
4049
|
}, resourceAddress);
|
|
4046
4050
|
}
|
|
4047
4051
|
/** Static preview mounts a separate browsing context so a mode change retires running scripts. */
|
|
4048
|
-
function BasicHtmlFrame({ data, t }) {
|
|
4052
|
+
function BasicHtmlFrame({ data, frameName, t }) {
|
|
4049
4053
|
const html = (0, react.useMemo)(() => {
|
|
4050
4054
|
try {
|
|
4051
4055
|
return createBasicHtmlDocument(data);
|
|
@@ -4059,6 +4063,7 @@ document.open();document.write(html);document.close();
|
|
|
4059
4063
|
children: t("failed")
|
|
4060
4064
|
});
|
|
4061
4065
|
return (0, react_jsx_runtime.jsx)("iframe", {
|
|
4066
|
+
name: frameName,
|
|
4062
4067
|
className: HtmlBody_module_css_default.frame,
|
|
4063
4068
|
srcDoc: html,
|
|
4064
4069
|
sandbox: "",
|
|
@@ -4072,14 +4077,14 @@ document.open();document.write(html);document.close();
|
|
|
4072
4077
|
const zh$5 = {
|
|
4073
4078
|
title: "HTML",
|
|
4074
4079
|
frame: "HTML 文档预览",
|
|
4075
|
-
loading: "
|
|
4080
|
+
loading: "文档渲染中...",
|
|
4076
4081
|
failed: "无法预览这份 HTML 文档"
|
|
4077
4082
|
};
|
|
4078
4083
|
/** English dictionary with the same keys as the Chinese dictionary. */
|
|
4079
4084
|
const en$5 = {
|
|
4080
4085
|
title: "HTML",
|
|
4081
4086
|
frame: "HTML document preview",
|
|
4082
|
-
loading: "
|
|
4087
|
+
loading: "Rendering document...",
|
|
4083
4088
|
failed: "This HTML document could not be previewed."
|
|
4084
4089
|
};
|
|
4085
4090
|
//#endregion
|
|
@@ -4193,7 +4198,7 @@ document.open();document.write(html);document.close();
|
|
|
4193
4198
|
const DEFAULT_ZOOM = FIT_WIDTH;
|
|
4194
4199
|
//#endregion
|
|
4195
4200
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/zoom/ZoomControls.module.css.mjs
|
|
4196
|
-
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;
|
|
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}}";
|
|
4197
4202
|
const tagId$5 = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/ZoomControls.module.css";
|
|
4198
4203
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$5) + "]") === null) {
|
|
4199
4204
|
const tag = document.createElement("style");
|
|
@@ -4607,7 +4612,7 @@ document.open();document.write(html);document.close();
|
|
|
4607
4612
|
const zoomSurfaceClass = ZoomViewport_module_css_default.surface;
|
|
4608
4613
|
//#endregion
|
|
4609
4614
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/image/ImageBody.module.css.mjs
|
|
4610
|
-
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;
|
|
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}";
|
|
4611
4616
|
const tagId$3 = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/ImageBody.module.css";
|
|
4612
4617
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
4613
4618
|
const tag = document.createElement("style");
|
|
@@ -4695,10 +4700,7 @@ document.open();document.write(html);document.close();
|
|
|
4695
4700
|
role: "alert",
|
|
4696
4701
|
children: t("unsupported")
|
|
4697
4702
|
});
|
|
4698
|
-
if (source?.data !== data || source.mediaType !== mediaType) return (0, react_jsx_runtime.jsx)(LoadingIndicator, {
|
|
4699
|
-
className: ImageBody_module_css_default.status,
|
|
4700
|
-
label: t("loading")
|
|
4701
|
-
});
|
|
4703
|
+
if (source?.data !== data || source.mediaType !== mediaType) return (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") });
|
|
4702
4704
|
if (source.kind === "failed") return (0, react_jsx_runtime.jsx)("p", {
|
|
4703
4705
|
className: ImageBody_module_css_default.status,
|
|
4704
4706
|
role: "alert",
|
|
@@ -4740,10 +4742,7 @@ document.open();document.write(html);document.close();
|
|
|
4740
4742
|
className: ImageBody_module_css_default.frame,
|
|
4741
4743
|
"data-image-preview": true,
|
|
4742
4744
|
children: [
|
|
4743
|
-
state === "loading" && (0, react_jsx_runtime.jsx)(LoadingIndicator, {
|
|
4744
|
-
className: ImageBody_module_css_default.status,
|
|
4745
|
-
label: t("loading")
|
|
4746
|
-
}),
|
|
4745
|
+
state === "loading" && (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") }),
|
|
4747
4746
|
state === "failed" && (0, react_jsx_runtime.jsx)("p", {
|
|
4748
4747
|
className: ImageBody_module_css_default.status,
|
|
4749
4748
|
role: "alert",
|
|
@@ -4801,7 +4800,7 @@ document.open();document.write(html);document.close();
|
|
|
4801
4800
|
...zoomZh,
|
|
4802
4801
|
title: "图片",
|
|
4803
4802
|
preview: "图片预览:{name}",
|
|
4804
|
-
loading: "
|
|
4803
|
+
loading: "文档渲染中...",
|
|
4805
4804
|
failed: "无法显示这张图片",
|
|
4806
4805
|
unsupported: "图片预览需要完整文件内容"
|
|
4807
4806
|
};
|
|
@@ -4810,7 +4809,7 @@ document.open();document.write(html);document.close();
|
|
|
4810
4809
|
...zoomEn,
|
|
4811
4810
|
title: "Image",
|
|
4812
4811
|
preview: "Image preview: {name}",
|
|
4813
|
-
loading: "
|
|
4812
|
+
loading: "Rendering document...",
|
|
4814
4813
|
failed: "This image could not be displayed.",
|
|
4815
4814
|
unsupported: "Image preview requires the complete file contents."
|
|
4816
4815
|
};
|
|
@@ -4888,12 +4887,13 @@ document.open();document.write(html);document.close();
|
|
|
4888
4887
|
* @returns the deferred PDF renderer.
|
|
4889
4888
|
*/
|
|
4890
4889
|
function LazyPdfBody(props) {
|
|
4890
|
+
const loading = (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: props.t("loading") });
|
|
4891
4891
|
return (0, react_jsx_runtime.jsx)(react.Suspense, {
|
|
4892
|
-
fallback:
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4892
|
+
fallback: loading,
|
|
4893
|
+
children: (0, react_jsx_runtime.jsx)(LoadedPdfBody, {
|
|
4894
|
+
...props,
|
|
4895
|
+
loading
|
|
4896
|
+
})
|
|
4897
4897
|
});
|
|
4898
4898
|
}
|
|
4899
4899
|
//#endregion
|
|
@@ -4937,7 +4937,7 @@ document.open();document.write(html);document.close();
|
|
|
4937
4937
|
...zoomZh,
|
|
4938
4938
|
title: "PDF",
|
|
4939
4939
|
pageImage: "PDF 第 {page} 页",
|
|
4940
|
-
loading: "
|
|
4940
|
+
loading: "文档渲染中...",
|
|
4941
4941
|
rendering: "正在绘制页面…",
|
|
4942
4942
|
failed: "无法显示 PDF:{message}",
|
|
4943
4943
|
password: "此 PDF 需要密码,暂不支持预览",
|
|
@@ -4950,7 +4950,7 @@ document.open();document.write(html);document.close();
|
|
|
4950
4950
|
...zoomEn,
|
|
4951
4951
|
title: "PDF",
|
|
4952
4952
|
pageImage: "PDF page {page}",
|
|
4953
|
-
loading: "
|
|
4953
|
+
loading: "Rendering document...",
|
|
4954
4954
|
rendering: "Rendering page…",
|
|
4955
4955
|
failed: "Cannot display PDF: {message}",
|
|
4956
4956
|
password: "This PDF requires a password; password-protected previews are not supported.",
|
|
@@ -5102,7 +5102,7 @@ document.open();document.write(html);document.close();
|
|
|
5102
5102
|
/** Office preview copy and Host render configuration guidance. */
|
|
5103
5103
|
const zh$1 = {
|
|
5104
5104
|
title: "Office 文档",
|
|
5105
|
-
loading: "
|
|
5105
|
+
loading: "文档渲染中...",
|
|
5106
5106
|
retry: "重试",
|
|
5107
5107
|
viewMissingFonts: "缺失 {count} 种字体,点击查看",
|
|
5108
5108
|
missingFontsTitle: "缺失的字体",
|
|
@@ -5120,7 +5120,7 @@ document.open();document.write(html);document.close();
|
|
|
5120
5120
|
/** English translations checked against the Chinese key set. */
|
|
5121
5121
|
const en$1 = {
|
|
5122
5122
|
title: "Office document",
|
|
5123
|
-
loading: "
|
|
5123
|
+
loading: "Rendering document...",
|
|
5124
5124
|
retry: "Retry",
|
|
5125
5125
|
viewMissingFonts: "Missing fonts: {count}. Click to view.",
|
|
5126
5126
|
missingFontsTitle: "Missing fonts",
|
|
@@ -5394,10 +5394,7 @@ document.open();document.write(html);document.close();
|
|
|
5394
5394
|
]
|
|
5395
5395
|
});
|
|
5396
5396
|
}
|
|
5397
|
-
if (file === void 0) return (0, react_jsx_runtime.jsx)(LoadingIndicator, {
|
|
5398
|
-
className: TextPreview_module_css_default.statusLine,
|
|
5399
|
-
label: t("loading")
|
|
5400
|
-
});
|
|
5397
|
+
if (file === void 0) return (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: t("loading") });
|
|
5401
5398
|
return (0, react_jsx_runtime.jsx)("div", {
|
|
5402
5399
|
className: OfficeBody_module_css_default.body,
|
|
5403
5400
|
children: props.renderSlot("sidebar.right.tab.document.office.pdf", {
|
|
@@ -5418,7 +5415,7 @@ document.open();document.write(html);document.close();
|
|
|
5418
5415
|
}
|
|
5419
5416
|
//#endregion
|
|
5420
5417
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/office/FontNotice.module.css.mjs
|
|
5421
|
-
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;
|
|
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}";
|
|
5422
5419
|
const tagId = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/FontNotice.module.css";
|
|
5423
5420
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
5424
5421
|
const tag = document.createElement("style");
|
|
@@ -5798,14 +5795,13 @@ document.open();document.write(html);document.close();
|
|
|
5798
5795
|
*/
|
|
5799
5796
|
function LazyExcelBody(props) {
|
|
5800
5797
|
const format = excelFormat(hostFileOf(props.resourceAddress).path);
|
|
5798
|
+
const loading = (0, react_jsx_runtime.jsx)(LoadingIndicator, { label: props.t("loading") });
|
|
5801
5799
|
return (0, react_jsx_runtime.jsx)(react.Suspense, {
|
|
5802
|
-
fallback:
|
|
5803
|
-
className: TextPreview_module_css_default.status,
|
|
5804
|
-
label: props.t("loading")
|
|
5805
|
-
}),
|
|
5800
|
+
fallback: loading,
|
|
5806
5801
|
children: (0, react_jsx_runtime.jsx)(LoadedExcelBody, {
|
|
5807
5802
|
...props,
|
|
5808
|
-
format
|
|
5803
|
+
format,
|
|
5804
|
+
loading
|
|
5809
5805
|
})
|
|
5810
5806
|
});
|
|
5811
5807
|
}
|
|
@@ -5815,7 +5811,7 @@ document.open();document.write(html);document.close();
|
|
|
5815
5811
|
const zh = {
|
|
5816
5812
|
title: "表格",
|
|
5817
5813
|
language: "zh",
|
|
5818
|
-
loading: "
|
|
5814
|
+
loading: "文档渲染中...",
|
|
5819
5815
|
invalid: "无法打开此表格。请检查文件格式、内容或密码保护。",
|
|
5820
5816
|
tooLarge: "此表格超过预览大小限制。",
|
|
5821
5817
|
timeout: "打开表格超时。请缩小文件后重试。",
|
|
@@ -5833,7 +5829,7 @@ document.open();document.write(html);document.close();
|
|
|
5833
5829
|
const en = {
|
|
5834
5830
|
title: "Spreadsheet",
|
|
5835
5831
|
language: "en",
|
|
5836
|
-
loading: "
|
|
5832
|
+
loading: "Rendering document...",
|
|
5837
5833
|
invalid: "This spreadsheet could not be opened. Check its format, contents, or password protection.",
|
|
5838
5834
|
tooLarge: "This workbook exceeds the preview size limit.",
|
|
5839
5835
|
timeout: "Opening this workbook timed out. Try a smaller file.",
|
|
@@ -6862,9 +6858,9 @@ document.open();document.write(html);document.close();
|
|
|
6862
6858
|
apply$6(ctx);
|
|
6863
6859
|
apply$5(ctx);
|
|
6864
6860
|
apply$4(ctx);
|
|
6865
|
-
apply$3(ctx);
|
|
6866
6861
|
apply$2(ctx, config.office);
|
|
6867
6862
|
apply$1(ctx, config.excel);
|
|
6863
|
+
apply$3(ctx);
|
|
6868
6864
|
}
|
|
6869
6865
|
//#endregion
|
|
6870
6866
|
exports.apply = apply;
|
package/lib/client.pdf.js
CHANGED
|
@@ -32376,7 +32376,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
32376
32376
|
}
|
|
32377
32377
|
//#endregion
|
|
32378
32378
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/pdf/PdfBody.module.css.mjs
|
|
32379
|
-
const css = ".E0GbtG_body{box-sizing:border-box;background:var(--dsw-alias-bg-document-preview);width:100%;min-width:100%;min-height:
|
|
32379
|
+
const css = ".E0GbtG_body{box-sizing:border-box;background:var(--dsw-alias-bg-document-preview);width:100%;min-width:100%;min-height:100%;font-family:var(--dsw-font,sans-serif);white-space:normal;flex-direction:column;gap:12px;padding:12px;display:flex;overflow:visible}[data-document-zoom-mode=fixed] .E0GbtG_body{width:max-content}.E0GbtG_page{box-sizing:border-box;width:100%;min-width:0;overflow-x:visible}.E0GbtG_placeholder{aspect-ratio:3/4;background:var(--dsw-alias-bg-skeleton);width:100%}.E0GbtG_canvas{width:100%;max-width:none;height:auto;margin-inline:auto;display:block}.E0GbtG_surface{max-width:none;box-shadow:var(--dsw-elevation-prominent);margin-inline:auto;position:relative}.E0GbtG_surface[hidden]{display:none}.E0GbtG_text{position:absolute;inset:0;overflow:clip}.E0GbtG_text .textLayer{text-align:initial;letter-spacing:normal;word-spacing:normal;text-size-adjust:none;forced-color-adjust:none;transform-origin:0 0;caret-color:canvastext;z-index:0;--text-scale-factor:calc(var(--total-scale-factor) * var(--min-font-size));--min-font-size-inv:calc(1 / var(--min-font-size));line-height:1;position:absolute;inset:0;overflow:clip}.E0GbtG_text .textLayer[data-main-rotation=\"90\"]{transform:rotate(90deg)translateY(-100%)}.E0GbtG_text .textLayer[data-main-rotation=\"180\"]{transform:rotate(180deg)translate(-100%,-100%)}.E0GbtG_text .textLayer[data-main-rotation=\"270\"]{transform:rotate(270deg)translate(-100%)}.E0GbtG_text :is(span,br){color:#0000;white-space:pre;cursor:text;transform-origin:0 0;user-select:text;position:absolute}.E0GbtG_text .textLayer>:not(.markedContent),.E0GbtG_text .markedContent span:not(.markedContent){z-index:1;--font-height:0;--scale-x:1;--rotate:0deg;font-size:calc(var(--text-scale-factor) * var(--font-height));transform:rotate(var(--rotate)) scaleX(var(--scale-x)) scale(var(--min-font-size-inv))}.E0GbtG_text .markedContent{display:contents}.E0GbtG_text ::selection{background:var(--dsw-alias-interactive-bg-hover-accent);color:#0000}.E0GbtG_text br::selection{background:0 0}.E0GbtG_text .textLayer .endOfContent{z-index:0;cursor:default;user-select:none;display:block;position:absolute;inset:100% 0 0}.E0GbtG_text .selecting .endOfContent{top:0}.E0GbtG_status{color:var(--dsw-alias-label-secondary);align-items:center;gap:8px;padding:10px;font-size:13px;line-height:1.5;display:flex}.E0GbtG_body .E0GbtG_status{color:var(--dsw-alias-label-document-preview)}";
|
|
32380
32380
|
const tagId = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/PdfBody.module.css";
|
|
32381
32381
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
32382
32382
|
const tag = document.createElement("style");
|
|
@@ -32388,7 +32388,6 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
32388
32388
|
var PdfBody_module_css_default = {
|
|
32389
32389
|
"body": "E0GbtG_body",
|
|
32390
32390
|
"canvas": "E0GbtG_canvas",
|
|
32391
|
-
"opening": "E0GbtG_opening",
|
|
32392
32391
|
"page": "E0GbtG_page",
|
|
32393
32392
|
"placeholder": "E0GbtG_placeholder",
|
|
32394
32393
|
"status": "E0GbtG_status",
|
|
@@ -32402,7 +32401,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
32402
32401
|
const FIT_WIDTH = { kind: "fit-width" };
|
|
32403
32402
|
/**
|
|
32404
32403
|
* Present a PDF with tab-local viewing preferences and component-owned rendering resources.
|
|
32405
|
-
* @param props - complete bytes
|
|
32404
|
+
* @param props - complete bytes, framework-owned tab/store/locale seats, and main-bundle loading content.
|
|
32406
32405
|
* @returns the PDF reader.
|
|
32407
32406
|
*/
|
|
32408
32407
|
function PdfBody(props) {
|
|
@@ -32475,13 +32474,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
32475
32474
|
role: "alert",
|
|
32476
32475
|
children: t("unsupported")
|
|
32477
32476
|
});
|
|
32478
|
-
if (load?.data !== data) return
|
|
32479
|
-
className: `${PdfBody_module_css_default.status} ${PdfBody_module_css_default.opening}`,
|
|
32480
|
-
role: "status",
|
|
32481
|
-
"aria-label": t("loading"),
|
|
32482
|
-
"data-document-loading": true,
|
|
32483
|
-
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "ongoing" })
|
|
32484
|
-
});
|
|
32477
|
+
if (load?.data !== data) return props.loading;
|
|
32485
32478
|
if (load.kind === "failed") return (0, react_jsx_runtime.jsxs)("div", {
|
|
32486
32479
|
className: PdfBody_module_css_default.status,
|
|
32487
32480
|
role: "alert",
|
|
@@ -32511,6 +32504,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
32511
32504
|
return (0, react_jsx_runtime.jsx)(ZoomViewport, {
|
|
32512
32505
|
preference,
|
|
32513
32506
|
intrinsicWidth: pageWidth,
|
|
32507
|
+
horizontalInset: 24,
|
|
32514
32508
|
labels,
|
|
32515
32509
|
signal: tab.signal,
|
|
32516
32510
|
scrollportRef: props.scrollportRef,
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/** Shared indeterminate loading feedback for document reads and rendering. */
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
3
|
/**
|
|
4
|
-
* @param props - localized status label
|
|
5
|
-
*
|
|
6
|
-
* @returns an animated, accessible loading status.
|
|
4
|
+
* @param props - localized status label and compact inline placement for additional pages.
|
|
5
|
+
* @returns a centered document loading status or an accessible inline spinner.
|
|
7
6
|
*/
|
|
8
|
-
export declare function LoadingIndicator({ label,
|
|
7
|
+
export declare function LoadingIndicator({ label, inline }: {
|
|
9
8
|
label: string;
|
|
10
|
-
|
|
9
|
+
inline?: boolean;
|
|
11
10
|
}): ReactNode;
|
|
12
11
|
//# sourceMappingURL=LoadingIndicator.d.ts.map
|
|
@@ -8,9 +8,10 @@ import type { ExcelLimits } from './model.ts';
|
|
|
8
8
|
export type ExcelBodyProps = DocumentPreviewProps & PropsLocale<'sidebarExcel'> & {
|
|
9
9
|
readonly limits: ExcelLimits;
|
|
10
10
|
};
|
|
11
|
-
/** Lazily loaded renderer input with the
|
|
11
|
+
/** Lazily loaded renderer input with the parser choice and main-bundle loading content. */
|
|
12
12
|
export type LoadedExcelBodyProps = ExcelBodyProps & {
|
|
13
13
|
readonly format: ExcelFormat;
|
|
14
|
+
readonly loading: ReactNode;
|
|
14
15
|
};
|
|
15
16
|
/**
|
|
16
17
|
* Load the browser spreadsheet renderer for every registered format.
|
|
@@ -7,5 +7,5 @@ import type { LoadedExcelBodyProps } from './LazyExcelBody.tsx';
|
|
|
7
7
|
* @param props - Complete workbook bytes, limits, and locale.
|
|
8
8
|
* @returns An isolated spreadsheet surface with cancellable loading.
|
|
9
9
|
*/
|
|
10
|
-
export declare function ExcelBody({ content, format, limits, t }: LoadedExcelBodyProps): ReactNode;
|
|
10
|
+
export declare function ExcelBody({ content, format, limits, t, loading }: LoadedExcelBodyProps): ReactNode;
|
|
11
11
|
//# sourceMappingURL=excel.d.ts.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @param base - document base URI, including any deployment prefix.
|
|
4
4
|
* @param documentPath - absolute source path reported by the Host, when available.
|
|
5
5
|
* @param destination - authored Markdown image URL; query and fragment are not filename components.
|
|
6
|
-
* @returns
|
|
6
|
+
* @returns a Web or Desktop file URL, or undefined for unsupported or malformed destinations.
|
|
7
7
|
*/
|
|
8
8
|
export declare function markdownImageUrl(base: string, documentPath: string | undefined, destination: string): string | undefined;
|
|
9
9
|
//# sourceMappingURL=path-images.d.ts.map
|
|
@@ -22,8 +22,10 @@ export interface PdfBodyInjected {
|
|
|
22
22
|
export type PdfBodyProps = DocumentPreviewProps & PropsLocale<'sidebarPdf'> & PropsStore<PdfStore> & PdfBodyInjected;
|
|
23
23
|
/**
|
|
24
24
|
* Present a PDF with tab-local viewing preferences and component-owned rendering resources.
|
|
25
|
-
* @param props - complete bytes
|
|
25
|
+
* @param props - complete bytes, framework-owned tab/store/locale seats, and main-bundle loading content.
|
|
26
26
|
* @returns the PDF reader.
|
|
27
27
|
*/
|
|
28
|
-
export declare function PdfBody(props: PdfBodyProps
|
|
28
|
+
export declare function PdfBody(props: PdfBodyProps & {
|
|
29
|
+
readonly loading: ReactNode;
|
|
30
|
+
}): ReactNode;
|
|
29
31
|
//# sourceMappingURL=pdf.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-sidebar-documentpreview",
|
|
3
3
|
"description": "Extensible Sidebar previews for Office documents, spreadsheets, Markdown, code, images, PDF, HTML, and plain text",
|
|
4
|
-
"version": "0.1.7-rc.
|
|
4
|
+
"version": "0.1.7-rc.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -62,25 +62,25 @@
|
|
|
62
62
|
"react-dom": "^18.2.0",
|
|
63
63
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
|
|
64
64
|
"@deepseek-ai/cordis": "~4.0.4",
|
|
65
|
-
"@deepseek-ai/dsh-api-
|
|
66
|
-
"@deepseek-ai/dsh-api-
|
|
67
|
-
"@deepseek-ai/dsh-
|
|
68
|
-
"@deepseek-ai/dsh-
|
|
69
|
-
"@deepseek-ai/dsh-client-locale": "0.1.7-rc.
|
|
70
|
-
"@deepseek-ai/dsh-client-resources": "0.1.7-rc.
|
|
71
|
-
"@deepseek-ai/dsh-client-
|
|
72
|
-
"@deepseek-ai/dsh-client-test-runtime": "0.1.7-rc.
|
|
73
|
-
"@deepseek-ai/dsh-client-ui-
|
|
74
|
-
"@deepseek-ai/dsh-client-ui-
|
|
75
|
-
"@deepseek-ai/dsh-client-ui-
|
|
76
|
-
"@deepseek-ai/dsh-client-
|
|
77
|
-
"@deepseek-ai/dsh-client-ui-
|
|
78
|
-
"@deepseek-ai/dsh-client-ui-
|
|
79
|
-
"@deepseek-ai/dsh-office-to-pdf": "0.1.7-rc.
|
|
80
|
-
"@deepseek-ai/dsh-host-webserver": "0.1.7-rc.
|
|
81
|
-
"@deepseek-ai/dsh-session": "0.1.7-rc.
|
|
82
|
-
"@deepseek-ai/dsh-util-workspace-path": "0.1.7-rc.
|
|
83
|
-
"@deepseek-ai/dsh-client-ui-
|
|
65
|
+
"@deepseek-ai/dsh-api-remotes": "0.1.7-rc.2",
|
|
66
|
+
"@deepseek-ai/dsh-api-workspace-files": "0.1.7-rc.2",
|
|
67
|
+
"@deepseek-ai/dsh-client-connection": "0.1.7-rc.2",
|
|
68
|
+
"@deepseek-ai/dsh-api-gateway": "0.1.7-rc.2",
|
|
69
|
+
"@deepseek-ai/dsh-client-locale": "0.1.7-rc.2",
|
|
70
|
+
"@deepseek-ai/dsh-client-resources": "0.1.7-rc.2",
|
|
71
|
+
"@deepseek-ai/dsh-client-store": "0.1.7-rc.2",
|
|
72
|
+
"@deepseek-ai/dsh-client-test-runtime": "0.1.7-rc.2",
|
|
73
|
+
"@deepseek-ai/dsh-client-ui-dockkit": "0.1.7-rc.2",
|
|
74
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2",
|
|
75
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.2",
|
|
76
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.2",
|
|
77
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2",
|
|
78
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.7-rc.2",
|
|
79
|
+
"@deepseek-ai/dsh-office-to-pdf": "0.1.7-rc.2",
|
|
80
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.7-rc.2",
|
|
81
|
+
"@deepseek-ai/dsh-session": "0.1.7-rc.2",
|
|
82
|
+
"@deepseek-ai/dsh-util-workspace-path": "0.1.7-rc.2",
|
|
83
|
+
"@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.2"
|
|
84
84
|
},
|
|
85
85
|
"files": [
|
|
86
86
|
"lib/index.js",
|