@file-viewer/core 2.0.11 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.en.md +2 -2
  2. package/README.md +2 -2
  3. package/dist/config/options.d.ts +1 -1
  4. package/dist/config/options.js +1 -1
  5. package/dist/contracts/types.d.ts +71 -1
  6. package/dist/headless.d.ts +2 -2
  7. package/dist/headless.js +1 -1
  8. package/dist/index.d.ts +9 -6
  9. package/dist/index.js +105 -48
  10. package/dist/platform/assets.d.ts +3 -1
  11. package/dist/platform/assets.js +18 -2
  12. package/dist/registry/capabilities.d.ts +2 -2
  13. package/dist/registry/capabilities.js +2 -1
  14. package/dist/registry/formats.d.ts +20 -7
  15. package/dist/registry/formats.js +14 -5
  16. package/dist/registry/registry.d.ts +8 -1
  17. package/dist/registry/registry.js +29 -0
  18. package/dist/renderers/image.js +1 -10
  19. package/dist/renderers/index.d.ts +320 -2
  20. package/dist/renderers/index.js +27 -157
  21. package/dist/viewer/createViewer.js +86 -3
  22. package/package.json +17 -44
  23. package/dist/renderers/archive.d.ts +0 -2
  24. package/dist/renderers/archive.js +0 -547
  25. package/dist/renderers/archiveCache.d.ts +0 -10
  26. package/dist/renderers/archiveCache.js +0 -96
  27. package/dist/renderers/archiveFallback.d.ts +0 -7
  28. package/dist/renderers/archiveFallback.js +0 -166
  29. package/dist/renderers/archiveShared.d.ts +0 -23
  30. package/dist/renderers/archiveShared.js +0 -71
  31. package/dist/renderers/audio.d.ts +0 -8
  32. package/dist/renderers/audio.js +0 -219
  33. package/dist/renderers/cad.d.ts +0 -2
  34. package/dist/renderers/cad.js +0 -446
  35. package/dist/renderers/code.d.ts +0 -11
  36. package/dist/renderers/code.js +0 -233
  37. package/dist/renderers/data.d.ts +0 -7
  38. package/dist/renderers/data.js +0 -370
  39. package/dist/renderers/drawing.d.ts +0 -10
  40. package/dist/renderers/drawing.js +0 -882
  41. package/dist/renderers/eda.d.ts +0 -2
  42. package/dist/renderers/eda.js +0 -434
  43. package/dist/renderers/edaParser.d.ts +0 -77
  44. package/dist/renderers/edaParser.js +0 -569
  45. package/dist/renderers/email.d.ts +0 -2
  46. package/dist/renderers/email.js +0 -463
  47. package/dist/renderers/epub.d.ts +0 -2
  48. package/dist/renderers/epub.js +0 -331
  49. package/dist/renderers/geo.d.ts +0 -2
  50. package/dist/renderers/geo.js +0 -284
  51. package/dist/renderers/markdown.d.ts +0 -2
  52. package/dist/renderers/markdown.js +0 -83
  53. package/dist/renderers/model.d.ts +0 -2
  54. package/dist/renderers/model.js +0 -567
  55. package/dist/renderers/ofd.d.ts +0 -2
  56. package/dist/renderers/ofd.js +0 -256
  57. package/dist/renderers/openDocument.d.ts +0 -2
  58. package/dist/renderers/openDocument.js +0 -122
  59. package/dist/renderers/pdf.d.ts +0 -3
  60. package/dist/renderers/pdf.js +0 -1001
  61. package/dist/renderers/pdfStyles.d.ts +0 -1
  62. package/dist/renderers/pdfStyles.js +0 -1
  63. package/dist/renderers/pptx.d.ts +0 -2
  64. package/dist/renderers/pptx.js +0 -217
  65. package/dist/renderers/spreadsheet/state.d.ts +0 -80
  66. package/dist/renderers/spreadsheet/state.js +0 -96
  67. package/dist/renderers/spreadsheet/view.d.ts +0 -25
  68. package/dist/renderers/spreadsheet/view.js +0 -833
  69. package/dist/renderers/spreadsheet/worker/index.d.ts +0 -2
  70. package/dist/renderers/spreadsheet/worker/index.js +0 -1
  71. package/dist/renderers/spreadsheet/worker/sheetjs/SheetJsModel.d.ts +0 -73
  72. package/dist/renderers/spreadsheet/worker/sheetjs/SheetJsModel.js +0 -623
  73. package/dist/renderers/spreadsheet/worker/sheetjs/color.d.ts +0 -2
  74. package/dist/renderers/spreadsheet/worker/sheetjs/color.js +0 -73
  75. package/dist/renderers/spreadsheet/worker/sheetjs/index.d.ts +0 -1
  76. package/dist/renderers/spreadsheet/worker/sheetjs/index.js +0 -1
  77. package/dist/renderers/spreadsheet/worker/sheetjs/parser.d.ts +0 -18
  78. package/dist/renderers/spreadsheet/worker/sheetjs/parser.js +0 -106
  79. package/dist/renderers/spreadsheet/worker/sheetjs/sheet.worker.d.ts +0 -1
  80. package/dist/renderers/spreadsheet/worker/sheetjs/sheet.worker.js +0 -11
  81. package/dist/renderers/spreadsheet/worker/type.d.ts +0 -57
  82. package/dist/renderers/spreadsheet/worker/type.js +0 -1
  83. package/dist/renderers/spreadsheet.d.ts +0 -3
  84. package/dist/renderers/spreadsheet.js +0 -929
  85. package/dist/renderers/typst.d.ts +0 -8
  86. package/dist/renderers/typst.js +0 -547
  87. package/dist/renderers/umd/parser.d.ts +0 -30
  88. package/dist/renderers/umd/parser.js +0 -408
  89. package/dist/renderers/umd.d.ts +0 -2
  90. package/dist/renderers/umd.js +0 -297
  91. package/dist/renderers/video.d.ts +0 -8
  92. package/dist/renderers/video.js +0 -108
  93. package/dist/renderers/wordDoc.d.ts +0 -5
  94. package/dist/renderers/wordDoc.js +0 -284
  95. package/dist/renderers/wordDocx.d.ts +0 -5
  96. package/dist/renderers/wordDocx.js +0 -985
  97. package/dist/renderers/wordDocx.worker.d.ts +0 -1
  98. package/dist/renderers/wordDocx.worker.js +0 -96
  99. package/vendor/ofd/dltech/jbig2/arithmetic_decoder.js +0 -183
  100. package/vendor/ofd/dltech/jbig2/ccitt.js +0 -1070
  101. package/vendor/ofd/dltech/jbig2/compatibility.js +0 -12
  102. package/vendor/ofd/dltech/jbig2/core_utils.js +0 -180
  103. package/vendor/ofd/dltech/jbig2/is_node.js +0 -27
  104. package/vendor/ofd/dltech/jbig2/jbig2.js +0 -2589
  105. package/vendor/ofd/dltech/jbig2/jbig2_stream.js +0 -81
  106. package/vendor/ofd/dltech/jbig2/primitives.js +0 -387
  107. package/vendor/ofd/dltech/jbig2/stream.js +0 -1348
  108. package/vendor/ofd/dltech/jbig2/util.js +0 -972
  109. package/vendor/ofd/dltech/ofd/ofd.d.ts +0 -11
  110. package/vendor/ofd/dltech/ofd/ofd.js +0 -100
  111. package/vendor/ofd/dltech/ofd/ofd_parser.js +0 -395
  112. package/vendor/ofd/dltech/ofd/ofd_render.js +0 -473
  113. package/vendor/ofd/dltech/ofd/ofd_util.js +0 -350
  114. package/vendor/ofd/dltech/ofd/pipeline.js +0 -26
@@ -1,233 +0,0 @@
1
- import { createFileViewerZoomChangeEmitter as createZoomChangeEmitter } from '../features/document/zoom.js';
2
- import { readFileViewerText as readText } from '../source/index.js';
3
- import { registerFileViewerZoomProvider, unregisterFileViewerZoomProvider } from '../features/document/dom/index.js';
4
- const languageMap = {
5
- bash: 'bash',
6
- c: 'cpp',
7
- cc: 'cpp',
8
- cjs: 'javascript',
9
- cpp: 'cpp',
10
- cs: 'csharp',
11
- css: 'css',
12
- diff: 'diff',
13
- gv: 'plaintext',
14
- go: 'go',
15
- h: 'cpp',
16
- hcl: 'plaintext',
17
- hpp: 'cpp',
18
- html: 'xml',
19
- htm: 'xml',
20
- http: 'http',
21
- ini: 'ini',
22
- ipynb: 'json',
23
- java: 'java',
24
- js: 'javascript',
25
- json: 'json',
26
- json5: 'json',
27
- jsonc: 'json',
28
- jsx: 'javascript',
29
- kt: 'kotlin',
30
- log: 'plaintext',
31
- md: 'markdown',
32
- markdown: 'markdown',
33
- mjs: 'javascript',
34
- php: 'php',
35
- proto: 'protobuf',
36
- py: 'python',
37
- rb: 'ruby',
38
- react: 'javascript',
39
- rs: 'rust',
40
- sh: 'bash',
41
- sql: 'sql',
42
- swift: 'swift',
43
- tex: 'latex',
44
- toml: 'ini',
45
- ts: 'typescript',
46
- tsx: 'typescript',
47
- txt: 'plaintext',
48
- vue: 'xml',
49
- xml: 'xml',
50
- yaml: 'yaml',
51
- yml: 'yaml'
52
- };
53
- const languageLoaders = {
54
- bash: () => import('highlight.js/lib/languages/bash'),
55
- cpp: () => import('highlight.js/lib/languages/cpp'),
56
- csharp: () => import('highlight.js/lib/languages/csharp'),
57
- css: () => import('highlight.js/lib/languages/css'),
58
- diff: () => import('highlight.js/lib/languages/diff'),
59
- go: () => import('highlight.js/lib/languages/go'),
60
- http: () => import('highlight.js/lib/languages/http'),
61
- ini: () => import('highlight.js/lib/languages/ini'),
62
- java: () => import('highlight.js/lib/languages/java'),
63
- javascript: () => import('highlight.js/lib/languages/javascript'),
64
- json: () => import('highlight.js/lib/languages/json'),
65
- kotlin: () => import('highlight.js/lib/languages/kotlin'),
66
- latex: () => import('highlight.js/lib/languages/latex'),
67
- markdown: () => import('highlight.js/lib/languages/markdown'),
68
- php: () => import('highlight.js/lib/languages/php'),
69
- protobuf: () => import('highlight.js/lib/languages/protobuf'),
70
- python: () => import('highlight.js/lib/languages/python'),
71
- ruby: () => import('highlight.js/lib/languages/ruby'),
72
- rust: () => import('highlight.js/lib/languages/rust'),
73
- sql: () => import('highlight.js/lib/languages/sql'),
74
- swift: () => import('highlight.js/lib/languages/swift'),
75
- typescript: () => import('highlight.js/lib/languages/typescript'),
76
- xml: () => import('highlight.js/lib/languages/xml'),
77
- yaml: () => import('highlight.js/lib/languages/yaml')
78
- };
79
- const codeStyle = `
80
- .code-viewer{min-height:100%;--code-bg:#f6f8fa;--code-toolbar-bg:rgba(255,255,255,.92);--code-border:rgba(31,35,40,.12);--code-text:#24292f;--code-muted:#57606a;--code-keyword:#cf222e;--code-title:#8250df;--code-string:#0a3069;--code-number:#0550ae;--code-comment:#6e7781;--code-attr:#953800;--code-built-in:#116329;background:var(--code-bg);color:var(--code-text);box-sizing:border-box}
81
- .code-toolbar{position:sticky;top:0;z-index:1;display:flex;height:42px;align-items:center;justify-content:space-between;gap:16px;padding:0 16px;border-bottom:1px solid var(--code-border);background:var(--code-toolbar-bg);backdrop-filter:blur(12px);box-sizing:border-box}
82
- .code-toolbar span,.code-toolbar strong{color:var(--code-muted);font-size:12px;font-weight:700;letter-spacing:0}
83
- .code-area{display:block;min-width:min-content;margin:0;padding:18px 20px 28px;overflow:auto;background:transparent;box-sizing:border-box}
84
- .code-area code{display:block;padding:0;overflow:visible;background:transparent;color:inherit;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono',monospace;font-size:var(--code-font-size,13px);line-height:1.7;tab-size:2;white-space:pre}
85
- .code-area .hljs-comment,.code-area .hljs-quote{color:var(--code-comment)}
86
- .code-area .hljs-keyword,.code-area .hljs-selector-tag,.code-area .hljs-subst{color:var(--code-keyword)}
87
- .code-area .hljs-string,.code-area .hljs-doctag,.code-area .hljs-regexp{color:var(--code-string)}
88
- .code-area .hljs-title,.code-area .hljs-section,.code-area .hljs-selector-id{color:var(--code-title);font-weight:700}
89
- .code-area .hljs-number,.code-area .hljs-literal,.code-area .hljs-variable,.code-area .hljs-template-variable{color:var(--code-number)}
90
- .code-area .hljs-attr,.code-area .hljs-attribute,.code-area .hljs-name,.code-area .hljs-selector-class{color:var(--code-attr)}
91
- .code-area .hljs-built_in,.code-area .hljs-type,.code-area .hljs-class .hljs-title{color:var(--code-built-in)}
92
- .file-viewer[data-viewer-theme='dark'] .code-viewer{--code-bg:#0d1117;--code-toolbar-bg:rgba(13,17,23,.92);--code-border:rgba(139,148,158,.24);--code-text:#e6edf3;--code-muted:#8b949e;--code-keyword:#ff7b72;--code-title:#d2a8ff;--code-string:#a5d6ff;--code-number:#79c0ff;--code-comment:#8b949e;--code-attr:#ffa657;--code-built-in:#7ee787}
93
- @media (prefers-color-scheme:dark){.file-viewer[data-viewer-theme='system'] .code-viewer{--code-bg:#0d1117;--code-toolbar-bg:rgba(13,17,23,.92);--code-border:rgba(139,148,158,.24);--code-text:#e6edf3;--code-muted:#8b949e;--code-keyword:#ff7b72;--code-title:#d2a8ff;--code-string:#a5d6ff;--code-number:#79c0ff;--code-comment:#8b949e;--code-attr:#ffa657;--code-built-in:#7ee787}}
94
- `;
95
- let highlighterPromise = null;
96
- const registeredLanguages = new Set();
97
- const createElement = (tagName, className, text) => {
98
- const element = document.createElement(tagName);
99
- if (className) {
100
- element.className = className;
101
- }
102
- if (typeof text === 'string') {
103
- element.textContent = text;
104
- }
105
- return element;
106
- };
107
- const createStyle = () => {
108
- const style = document.createElement('style');
109
- style.textContent = codeStyle;
110
- return style;
111
- };
112
- const resolveLanguage = (type) => {
113
- return languageMap[type.trim().toLowerCase()] || 'plaintext';
114
- };
115
- const escapeHtml = (value) => {
116
- return value.replace(/[&<>"']/g, char => {
117
- const entities = {
118
- '&': '&amp;',
119
- '<': '&lt;',
120
- '>': '&gt;',
121
- '"': '&quot;',
122
- "'": '&#39;'
123
- };
124
- return entities[char];
125
- });
126
- };
127
- const loadHighlighter = async () => {
128
- if (!highlighterPromise) {
129
- highlighterPromise = import('highlight.js/lib/core').then(module => module.default);
130
- }
131
- return highlighterPromise;
132
- };
133
- const registerLanguageOnce = async (hljs, name) => {
134
- if (registeredLanguages.has(name)) {
135
- return true;
136
- }
137
- const loader = languageLoaders[name];
138
- if (!loader) {
139
- return false;
140
- }
141
- const { default: language } = await loader();
142
- hljs.registerLanguage(name, language);
143
- registeredLanguages.add(name);
144
- return true;
145
- };
146
- const clampZoom = (value) => {
147
- return Math.min(2.6, Math.max(0.6, Number(value.toFixed(2))));
148
- };
149
- const lineCountOf = (value) => {
150
- return value.split(/\r\n|\r|\n/).length;
151
- };
152
- /**
153
- * Framework-neutral text/code renderer.
154
- *
155
- * highlight.js core and language definitions are loaded lazily by format. HTML
156
- * and XML are highlighted as escaped source text, never executed as real DOM.
157
- * @param buffer 文本二进制内容
158
- * @param target 目标
159
- * @param type 文件扩展名,用于选择 highlight.js 语言
160
- */
161
- export default async function renderText(buffer, target, type) {
162
- const text = await readText(buffer);
163
- const extension = type || 'txt';
164
- const language = resolveLanguage(extension);
165
- let disposed = false;
166
- let zoom = 1;
167
- const zoomEmitter = createZoomChangeEmitter();
168
- const root = createElement('div', 'code-viewer');
169
- root.dataset.viewerZoomProvider = 'code';
170
- const toolbar = createElement('div', 'code-toolbar');
171
- toolbar.append(createElement('span', '', extension.toUpperCase()), createElement('strong', '', `${lineCountOf(text)} lines`));
172
- const pre = createElement('pre', 'code-area');
173
- const code = createElement('code', `hljs language-${language}`);
174
- code.innerHTML = language === 'plaintext'
175
- ? escapeHtml(text)
176
- : '正在加载高亮...';
177
- pre.append(code);
178
- root.append(toolbar, pre);
179
- root.style.setProperty('--code-font-size', `${13 * zoom}px`);
180
- target.replaceChildren(createStyle(), root);
181
- const updateHighlighted = async () => {
182
- if (language === 'plaintext') {
183
- return;
184
- }
185
- try {
186
- const hljs = await loadHighlighter();
187
- const hasLanguage = await registerLanguageOnce(hljs, language);
188
- if (disposed) {
189
- return;
190
- }
191
- code.innerHTML = hasLanguage
192
- ? hljs.highlight(text, { language, ignoreIllegals: true }).value
193
- : escapeHtml(text);
194
- }
195
- catch {
196
- if (!disposed) {
197
- code.innerHTML = escapeHtml(text);
198
- }
199
- }
200
- };
201
- void updateHighlighted();
202
- const getZoomState = () => ({
203
- scale: zoom,
204
- label: `${Math.round(zoom * 100)}%`,
205
- canZoomIn: zoom < 2.6,
206
- canZoomOut: zoom > 0.6,
207
- canReset: zoom !== 1,
208
- minScale: 0.6,
209
- maxScale: 2.6
210
- });
211
- const setZoom = (scale) => {
212
- zoom = clampZoom(scale);
213
- root.style.setProperty('--code-font-size', `${13 * zoom}px`);
214
- zoomEmitter.emit();
215
- return getZoomState();
216
- };
217
- registerFileViewerZoomProvider(root, {
218
- zoomIn: () => setZoom(zoom + 0.1),
219
- zoomOut: () => setZoom(zoom - 0.1),
220
- resetZoom: () => setZoom(1),
221
- setZoom,
222
- getState: getZoomState,
223
- subscribe: zoomEmitter.subscribe
224
- });
225
- return {
226
- $el: target,
227
- unmount() {
228
- disposed = true;
229
- unregisterFileViewerZoomProvider(root);
230
- target.replaceChildren();
231
- }
232
- };
233
- }
@@ -1,7 +0,0 @@
1
- import type { FileRenderContext, FileViewerRenderedInstance } from '../contracts/types';
2
- declare global {
3
- interface Window {
4
- __FLYFISH_DATA_SQL_WASM_URL__?: string;
5
- }
6
- }
7
- export default function renderDataAsset(buffer: ArrayBuffer, target: HTMLDivElement, type?: string, context?: FileRenderContext): Promise<FileViewerRenderedInstance>;
@@ -1,370 +0,0 @@
1
- import { resolveFileViewerDataSqlWasmUrl } from '../platform/assets.js';
2
- const dataStyle = `
3
- .data-viewer{min-height:100%;padding:28px;background:#eef1f4;color:#132235}
4
- .data-card{max-width:1080px;margin:0 auto;overflow:hidden;border:1px solid rgba(15,23,42,.08);border-radius:8px;background:#fff;box-shadow:0 18px 48px rgba(15,23,42,.12)}
5
- .data-header{padding:20px 24px;border-bottom:1px solid rgba(15,23,42,.08)}
6
- .data-header span{color:#0f766e;font-size:12px;font-weight:800}
7
- .data-header h2{margin:6px 0 0;font-size:24px}
8
- .data-summary{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:1px;background:rgba(15,23,42,.08)}
9
- .data-summary div{min-width:0;padding:15px 18px;background:#f8fafc}
10
- .data-summary span{display:block;color:#64748b;font-size:12px}
11
- .data-summary strong{display:block;margin-top:5px;overflow:hidden;color:#132235;font-size:15px;text-overflow:ellipsis;white-space:nowrap}
12
- .font-preview{padding:34px 28px;border-top:1px solid rgba(15,23,42,.08);font-size:42px;line-height:1.45;word-break:break-word}
13
- .asset-image{padding:24px;border-top:1px solid rgba(15,23,42,.08);background:#f8fafc;text-align:center}
14
- .asset-image img{max-width:100%;max-height:70vh;box-shadow:0 10px 30px rgba(15,23,42,.16)}
15
- .asset-text{margin:0;padding:18px 24px;overflow:auto;border-top:1px solid rgba(15,23,42,.08);background:#111827;color:#e5e7eb;font-size:13px;line-height:1.7}
16
- .data-table-wrap{max-height:520px;overflow:auto;border-top:1px solid rgba(15,23,42,.08)}
17
- .data-table{width:100%;border-collapse:collapse;font-size:13px}
18
- .data-table th,.data-table td{max-width:260px;padding:10px 12px;border-bottom:1px solid rgba(15,23,42,.08);overflow:hidden;text-align:left;text-overflow:ellipsis;white-space:nowrap}
19
- .data-table th{position:sticky;top:0;background:#f8fafc;color:#64748b;z-index:1}
20
- `;
21
- const fontMimeMap = {
22
- otf: 'font/otf',
23
- ttf: 'font/ttf',
24
- woff: 'font/woff',
25
- woff2: 'font/woff2',
26
- };
27
- const sampleText = 'Flyfish Viewer 轻量预览 AaBbCc 1234567890';
28
- const createStyle = (documentRef) => {
29
- const style = documentRef.createElement('style');
30
- style.textContent = dataStyle;
31
- return style;
32
- };
33
- const createElement = (documentRef, tagName, className, text) => {
34
- const element = documentRef.createElement(tagName);
35
- if (className) {
36
- element.className = className;
37
- }
38
- if (text !== undefined) {
39
- element.textContent = text;
40
- }
41
- return element;
42
- };
43
- const formatBytes = (value) => {
44
- if (value < 1024) {
45
- return `${value} B`;
46
- }
47
- if (value < 1024 * 1024) {
48
- return `${(value / 1024).toFixed(1)} KB`;
49
- }
50
- return `${(value / 1024 / 1024).toFixed(1)} MB`;
51
- };
52
- const makeRows = (rows) => {
53
- return rows.slice(0, 30).map(row => {
54
- const next = {};
55
- Object.entries(row).slice(0, 24).forEach(([key, value]) => {
56
- if (typeof value === 'bigint') {
57
- next[key] = value.toString();
58
- }
59
- else if (value instanceof Uint8Array) {
60
- next[key] = `[bytes:${value.byteLength}]`;
61
- }
62
- else if (value && typeof value === 'object') {
63
- next[key] = JSON.stringify(value).slice(0, 180);
64
- }
65
- else {
66
- next[key] = value;
67
- }
68
- });
69
- return next;
70
- });
71
- };
72
- const extractReadableText = (buffer, max = 8000) => {
73
- const bytes = new Uint8Array(buffer);
74
- const ascii = Array.from(bytes.slice(0, Math.min(bytes.length, max)))
75
- .map(byte => (byte >= 32 && byte <= 126) || byte === 10 || byte === 13 || byte === 9
76
- ? String.fromCharCode(byte)
77
- : ' ')
78
- .join('')
79
- .replace(/[ \t]{3,}/g, ' ');
80
- return ascii.trim().slice(0, max);
81
- };
82
- const readMagic = (buffer, length = 12) => {
83
- return String.fromCharCode(...new Uint8Array(buffer.slice(0, length)));
84
- };
85
- const imageDataToUrl = (documentRef, imageData) => {
86
- const canvas = documentRef.createElement('canvas');
87
- canvas.width = imageData.width;
88
- canvas.height = imageData.height;
89
- const context = canvas.getContext('2d');
90
- context === null || context === void 0 ? void 0 : context.putImageData(imageData, 0, 0);
91
- return canvas.toDataURL('image/png');
92
- };
93
- const getWindowSqlWasmOverride = (documentRef) => {
94
- var _a;
95
- return ((_a = documentRef.defaultView) === null || _a === void 0 ? void 0 : _a.__FLYFISH_DATA_SQL_WASM_URL__) ||
96
- (typeof window !== 'undefined' ? window.__FLYFISH_DATA_SQL_WASM_URL__ : undefined);
97
- };
98
- const renderFont = async (documentRef, buffer, type) => {
99
- var _a;
100
- const family = `FlyfishPreviewFont-${Date.now()}-${Math.random().toString(36).slice(2)}`;
101
- const ownerWindow = documentRef.defaultView || (typeof window !== 'undefined' ? window : undefined);
102
- const FontFaceConstructor = (ownerWindow === null || ownerWindow === void 0 ? void 0 : ownerWindow.FontFace) || (typeof FontFace !== 'undefined' ? FontFace : undefined);
103
- if (!FontFaceConstructor) {
104
- throw new Error('当前浏览器不支持 FontFace API');
105
- }
106
- const face = new FontFaceConstructor(family, buffer);
107
- await face.load();
108
- (_a = documentRef.fonts) === null || _a === void 0 ? void 0 : _a.add(face);
109
- return {
110
- title: '字体文件预览',
111
- fontFamily: family,
112
- summary: [
113
- { label: '格式', value: type.toUpperCase() },
114
- { label: '大小', value: formatBytes(buffer.byteLength) },
115
- { label: '渲染方式', value: 'Browser FontFace API' },
116
- ],
117
- };
118
- };
119
- const renderPsd = async (documentRef, buffer) => {
120
- var _a;
121
- const { readPsd } = await import('ag-psd');
122
- const psd = readPsd(buffer, { useImageData: true });
123
- const image = psd.imageData ? imageDataToUrl(documentRef, psd.imageData) : undefined;
124
- return {
125
- title: 'PSD 图像结构预览',
126
- image,
127
- summary: [
128
- { label: '画布', value: `${psd.width || 0} x ${psd.height || 0}` },
129
- { label: '图层', value: String(((_a = psd.children) === null || _a === void 0 ? void 0 : _a.length) || 0) },
130
- { label: '渲染方式', value: 'ag-psd' },
131
- ],
132
- rows: makeRows((psd.children || []).map((layer) => ({
133
- name: layer.name || '-',
134
- left: layer.left,
135
- top: layer.top,
136
- right: layer.right,
137
- bottom: layer.bottom,
138
- hidden: Boolean(layer.hidden),
139
- }))),
140
- };
141
- };
142
- const renderSqlite = async (documentRef, buffer, context) => {
143
- var _a, _b, _c;
144
- const { default: initSqlJs } = await import('sql.js');
145
- const sqlWasmUrl = resolveFileViewerDataSqlWasmUrl((_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.data, [
146
- getWindowSqlWasmOverride(documentRef),
147
- ], documentRef.baseURI);
148
- const SQL = await initSqlJs({ locateFile: () => sqlWasmUrl });
149
- const db = new SQL.Database(new Uint8Array(buffer));
150
- try {
151
- const tableResult = db.exec("select name, type from sqlite_master where type in ('table','view') and name not like 'sqlite_%' order by type, name");
152
- const tables = ((_b = tableResult[0]) === null || _b === void 0 ? void 0 : _b.values) || [];
153
- const firstTable = String(((_c = tables[0]) === null || _c === void 0 ? void 0 : _c[0]) || '');
154
- const rows = firstTable
155
- ? db.exec(`select * from "${firstTable.replace(/"/g, '""')}" limit 30`)[0]
156
- : null;
157
- return {
158
- title: 'SQLite 数据库预览',
159
- summary: [
160
- { label: '对象数', value: String(tables.length) },
161
- { label: '示例表', value: firstTable || '-' },
162
- { label: '渲染方式', value: 'sql.js WASM' },
163
- ],
164
- rows: rows
165
- ? makeRows(rows.values.map((values) => Object.fromEntries(rows.columns.map((column, index) => [column, values[index]]))))
166
- : makeRows(tables.map((value) => ({ name: value[0], type: value[1] }))),
167
- };
168
- }
169
- finally {
170
- db.close();
171
- }
172
- };
173
- const renderParquet = async (buffer) => {
174
- var _a, _b, _c;
175
- const { parquetMetadataAsync, parquetReadObjects } = await import('hyparquet');
176
- const file = {
177
- byteLength: buffer.byteLength,
178
- slice: (start, end) => buffer.slice(start, end),
179
- };
180
- const metadata = await parquetMetadataAsync(file);
181
- const rows = await parquetReadObjects({ file, rowFormat: 'object', rowEnd: 30 });
182
- return {
183
- title: 'Parquet 列式数据预览',
184
- summary: [
185
- { label: '行数', value: ((_b = (_a = metadata.num_rows) === null || _a === void 0 ? void 0 : _a.toString) === null || _b === void 0 ? void 0 : _b.call(_a)) || '-' },
186
- { label: '列数', value: String(((_c = metadata.schema) === null || _c === void 0 ? void 0 : _c.filter(item => item.name).length) || 0) },
187
- { label: '渲染方式', value: 'hyparquet' },
188
- ],
189
- rows: makeRows(rows),
190
- };
191
- };
192
- const renderAvro = async (buffer) => {
193
- const avro = await import('avsc/etc/browser/avsc.js');
194
- const decoder = avro.createBlobDecoder(new Blob([buffer]));
195
- const rows = [];
196
- let schema = '';
197
- await new Promise((resolve, reject) => {
198
- decoder.on('metadata', (type) => {
199
- var _a;
200
- schema = ((_a = type === null || type === void 0 ? void 0 : type.toString) === null || _a === void 0 ? void 0 : _a.call(type)) || '';
201
- });
202
- decoder.on('data', (value) => {
203
- if (rows.length < 30) {
204
- rows.push(value);
205
- }
206
- });
207
- decoder.on('end', resolve);
208
- decoder.on('error', reject);
209
- });
210
- return {
211
- title: 'Avro 对象容器预览',
212
- summary: [
213
- { label: '示例行', value: String(rows.length) },
214
- { label: 'Schema', value: schema ? '已读取' : '未读取' },
215
- { label: '渲染方式', value: 'avsc' },
216
- ],
217
- rows: makeRows(rows),
218
- text: schema.slice(0, 6000),
219
- };
220
- };
221
- const renderWasm = async (buffer) => {
222
- const module = await WebAssembly.compile(buffer.slice(0));
223
- const imports = WebAssembly.Module.imports(module);
224
- const exports = WebAssembly.Module.exports(module);
225
- return {
226
- title: 'WebAssembly 模块预览',
227
- summary: [
228
- { label: '导入', value: String(imports.length) },
229
- { label: '导出', value: String(exports.length) },
230
- { label: '渲染方式', value: 'WebAssembly.Module' },
231
- ],
232
- rows: makeRows([
233
- ...imports.map(item => ({ kind: 'import', module: item.module, name: item.name, type: item.kind })),
234
- ...exports.map(item => ({ kind: 'export', module: '-', name: item.name, type: item.kind })),
235
- ]),
236
- };
237
- };
238
- const renderPostScriptLike = async (buffer, type) => ({
239
- title: type === 'eps' ? 'EPS 矢量文件摘要' : 'Illustrator 文件摘要',
240
- summary: [
241
- { label: 'Magic', value: readMagic(buffer).replace(/\s/g, ' ') },
242
- { label: '大小', value: formatBytes(buffer.byteLength) },
243
- { label: '说明', value: type === 'ai' ? '非 PDF-compatible AI 按摘要展示' : 'PostScript 摘要展示' },
244
- ],
245
- text: extractReadableText(buffer),
246
- });
247
- const renderWebArchive = async (buffer) => ({
248
- title: 'WebArchive 摘要预览',
249
- summary: [
250
- { label: '容器', value: readMagic(buffer).startsWith('bplist') ? 'Binary plist' : 'WebArchive' },
251
- { label: '大小', value: formatBytes(buffer.byteLength) },
252
- { label: '说明', value: '安全提取可读片段,不执行网页脚本' },
253
- ],
254
- text: extractReadableText(buffer),
255
- });
256
- const buildPreview = async (documentRef, buffer, type, context) => {
257
- if (type in fontMimeMap) {
258
- return renderFont(documentRef, buffer, type);
259
- }
260
- if (type === 'psd') {
261
- return renderPsd(documentRef, buffer);
262
- }
263
- if (type === 'sqlite') {
264
- return renderSqlite(documentRef, buffer, context);
265
- }
266
- if (type === 'parquet') {
267
- return renderParquet(buffer);
268
- }
269
- if (type === 'avro') {
270
- return renderAvro(buffer);
271
- }
272
- if (type === 'wasm') {
273
- return renderWasm(buffer);
274
- }
275
- if (type === 'ai' || type === 'eps') {
276
- return renderPostScriptLike(buffer, type);
277
- }
278
- if (type === 'webarchive') {
279
- return renderWebArchive(buffer);
280
- }
281
- return {
282
- title: '数据资产摘要',
283
- summary: [
284
- { label: '格式', value: type.toUpperCase() },
285
- { label: '大小', value: formatBytes(buffer.byteLength) },
286
- ],
287
- text: extractReadableText(buffer),
288
- };
289
- };
290
- const appendSummary = (documentRef, parent, summary) => {
291
- const summaryRoot = createElement(documentRef, 'div', 'data-summary');
292
- summary.forEach(item => {
293
- const cell = createElement(documentRef, 'div');
294
- cell.append(createElement(documentRef, 'span', undefined, item.label), createElement(documentRef, 'strong', undefined, item.value));
295
- summaryRoot.appendChild(cell);
296
- });
297
- parent.appendChild(summaryRoot);
298
- };
299
- const appendRows = (documentRef, parent, rows) => {
300
- if (!(rows === null || rows === void 0 ? void 0 : rows.length)) {
301
- return;
302
- }
303
- const keys = Object.keys(rows[0]);
304
- const wrap = createElement(documentRef, 'div', 'data-table-wrap');
305
- const table = createElement(documentRef, 'table', 'data-table');
306
- const thead = createElement(documentRef, 'thead');
307
- const headRow = createElement(documentRef, 'tr');
308
- keys.forEach(key => {
309
- headRow.appendChild(createElement(documentRef, 'th', undefined, key));
310
- });
311
- thead.appendChild(headRow);
312
- const tbody = createElement(documentRef, 'tbody');
313
- rows.forEach(row => {
314
- const tr = createElement(documentRef, 'tr');
315
- keys.forEach(key => {
316
- var _a;
317
- tr.appendChild(createElement(documentRef, 'td', undefined, String((_a = row[key]) !== null && _a !== void 0 ? _a : '')));
318
- });
319
- tbody.appendChild(tr);
320
- });
321
- table.append(thead, tbody);
322
- wrap.appendChild(table);
323
- parent.appendChild(wrap);
324
- };
325
- const renderPreviewDom = (documentRef, preview, type) => {
326
- const root = createElement(documentRef, 'div', 'data-viewer');
327
- const card = createElement(documentRef, 'section', 'data-card');
328
- const header = createElement(documentRef, 'header', 'data-header');
329
- header.append(createElement(documentRef, 'span', undefined, type.toUpperCase()), createElement(documentRef, 'h2', undefined, preview.title));
330
- card.appendChild(header);
331
- appendSummary(documentRef, card, preview.summary);
332
- if (preview.fontFamily) {
333
- const fontPreview = createElement(documentRef, 'div', 'font-preview', sampleText);
334
- fontPreview.style.fontFamily = preview.fontFamily;
335
- card.appendChild(fontPreview);
336
- }
337
- if (preview.image) {
338
- const imageWrap = createElement(documentRef, 'div', 'asset-image');
339
- const image = createElement(documentRef, 'img');
340
- image.src = preview.image;
341
- image.alt = '资产预览';
342
- imageWrap.appendChild(image);
343
- card.appendChild(imageWrap);
344
- }
345
- if (preview.text) {
346
- card.appendChild(createElement(documentRef, 'pre', 'asset-text', preview.text));
347
- }
348
- appendRows(documentRef, card, preview.rows);
349
- root.appendChild(card);
350
- return root;
351
- };
352
- export default async function renderDataAsset(buffer, target, type = 'bin', context) {
353
- const documentRef = target.ownerDocument || document;
354
- const normalizedType = type.toLowerCase();
355
- if (normalizedType === 'ai' && readMagic(buffer, 5) === '%PDF-' && (context === null || context === void 0 ? void 0 : context.renderNestedBuffer)) {
356
- const rendered = await context.renderNestedBuffer(buffer, 'pdf', target, context);
357
- if (rendered) {
358
- return rendered;
359
- }
360
- }
361
- const preview = await buildPreview(documentRef, buffer, normalizedType, context);
362
- const root = renderPreviewDom(documentRef, preview, normalizedType);
363
- target.replaceChildren(createStyle(documentRef), root);
364
- return {
365
- $el: root,
366
- unmount() {
367
- target.replaceChildren();
368
- },
369
- };
370
- }
@@ -1,10 +0,0 @@
1
- import type { FileRenderContext, FileViewerRenderedInstance } from '../contracts/types';
2
- declare global {
3
- interface Window {
4
- GraphViewer?: {
5
- createViewerForElement: (element: HTMLElement, callback?: (viewer: unknown) => void) => unknown;
6
- processElements: (className?: string) => void;
7
- };
8
- }
9
- }
10
- export default function renderDrawing(buffer: ArrayBuffer, target: HTMLDivElement, type?: string, context?: FileRenderContext): Promise<FileViewerRenderedInstance>;