@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,297 +0,0 @@
1
- import { parseUmdBook, } from './umd/parser.js';
2
- const umdStyle = `
3
- .umd-viewer{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden;background:#eef1f4;color:#172033;box-sizing:border-box}
4
- .umd-toolbar{flex-shrink:0;display:grid;grid-template-columns:40px minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px 14px;border-bottom:1px solid rgba(15,23,42,.08);background:rgba(255,255,255,.94);box-sizing:border-box}
5
- .umd-title{min-width:0;display:flex;flex-direction:column;gap:3px}
6
- .umd-title strong,.umd-title span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
7
- .umd-title strong{font-size:14px}.umd-title span{color:#64748b;font-size:12px}
8
- .umd-icon-button,.umd-button{height:36px;border:1px solid rgba(15,23,42,.08);background:#fff;color:#172033;font:inherit;cursor:pointer}
9
- .umd-icon-button{width:40px;display:inline-flex;align-items:center;justify-content:center;border-radius:8px}
10
- .umd-icon-button span,.umd-icon-button span::before,.umd-icon-button span::after{width:16px;height:2px;display:block;border-radius:999px;background:currentColor}
11
- .umd-icon-button span{position:relative}.umd-icon-button span::before,.umd-icon-button span::after{content:'';position:absolute;left:0}.umd-icon-button span::before{top:-5px}.umd-icon-button span::after{top:5px}
12
- .umd-icon-button.active{border-color:rgba(2,132,199,.24);background:rgba(2,132,199,.08);color:#0369a1}
13
- .umd-actions{display:flex;align-items:center;gap:8px}.umd-button{min-width:68px;padding:0 12px;border-radius:8px;font-size:13px;font-weight:700}.umd-button:disabled{color:#94a3b8;cursor:not-allowed}
14
- .umd-progress{min-width:58px;color:#64748b;font-size:12px;text-align:center}
15
- .umd-body{flex:1;min-height:0;display:grid;grid-template-columns:minmax(180px,240px) minmax(0,1fr)}
16
- .umd-viewer--toc-hidden .umd-body{grid-template-columns:minmax(0,1fr)}
17
- .umd-toc{min-width:0;min-height:0;display:flex;flex-direction:column;border-right:1px solid rgba(15,23,42,.08);background:rgba(255,255,255,.82)}
18
- .umd-viewer--toc-hidden .umd-toc{display:none}
19
- .umd-toc-head{flex-shrink:0;display:flex;justify-content:space-between;gap:8px;padding:12px;color:#172033;font-size:13px}.umd-toc-head span{color:#64748b}
20
- .umd-toc-list{flex:1;min-height:0;overflow:auto;padding:0 8px 10px}
21
- .umd-toc-item{width:100%;min-height:34px;padding:7px 10px;border:0;border-radius:8px;background:transparent;color:#475569;font:inherit;font-size:12px;text-align:left;cursor:pointer}
22
- .umd-toc-item:hover,.umd-toc-item.active{background:rgba(2,132,199,.08);color:#0369a1}
23
- .umd-stage-wrap{position:relative;min-width:0;min-height:0;padding:18px;overflow:hidden;box-sizing:border-box}
24
- .umd-stage{width:100%;height:100%;overflow:auto;border-radius:8px;background:#fffef8;box-shadow:0 18px 45px rgba(15,23,42,.12),inset 0 0 0 1px rgba(15,23,42,.06);box-sizing:border-box}
25
- .umd-book-head{display:flex;gap:20px;max-width:820px;margin:0 auto;padding:32px 34px 8px;box-sizing:border-box}.umd-book-head img{width:96px;max-height:136px;object-fit:cover;border-radius:6px;box-shadow:0 12px 26px rgba(15,23,42,.16)}.umd-book-head div{min-width:0}
26
- .umd-book-head h1{margin:0;color:#111827;font-size:24px;line-height:1.3}.umd-book-head p{margin:8px 0 0;color:#64748b;font-size:13px;line-height:1.6}
27
- .umd-chapter{max-width:820px;margin:0 auto;padding:28px 34px 56px;box-sizing:border-box}.umd-chapter h2{margin:0 0 22px;color:#111827;font-size:22px;line-height:1.35}
28
- .umd-text{color:#1f2937;font-family:Georgia,'Times New Roman','Songti SC',SimSun,serif;font-size:17px;line-height:1.86;white-space:pre-wrap;word-break:break-word}
29
- .umd-image-list{display:grid;gap:18px}.umd-image-list figure{margin:0;text-align:center}.umd-image-list img{max-width:100%;height:auto;border-radius:6px;box-shadow:0 10px 24px rgba(15,23,42,.12)}
30
- .umd-empty,.umd-warning{color:#64748b;font-size:14px;line-height:1.7}.umd-warning{max-width:820px;margin:-28px auto 36px;padding:0 34px;color:#b45309;box-sizing:border-box}
31
- .umd-state{position:absolute;inset:18px;display:flex;align-items:center;justify-content:center;border-radius:8px;background:rgba(255,255,255,.92);color:#64748b;font-size:14px}.umd-state[hidden]{display:none!important}.umd-state.error{color:#b42318}
32
- .file-viewer[data-viewer-theme='dark'] .umd-viewer{background:#101820;color:#e5edf6}.file-viewer[data-viewer-theme='dark'] .umd-toolbar,.file-viewer[data-viewer-theme='dark'] .umd-toc{background:rgba(15,23,42,.92);border-color:rgba(148,163,184,.18)}
33
- .file-viewer[data-viewer-theme='dark'] .umd-stage{background:#111827;box-shadow:0 18px 45px rgba(0,0,0,.35),inset 0 0 0 1px rgba(148,163,184,.16)}
34
- .file-viewer[data-viewer-theme='dark'] .umd-book-head h1,.file-viewer[data-viewer-theme='dark'] .umd-chapter h2,.file-viewer[data-viewer-theme='dark'] .umd-text,.file-viewer[data-viewer-theme='dark'] .umd-toc-head{color:#e5edf6}
35
- .file-viewer[data-viewer-theme='dark'] .umd-title span,.file-viewer[data-viewer-theme='dark'] .umd-book-head p,.file-viewer[data-viewer-theme='dark'] .umd-toc-head span,.file-viewer[data-viewer-theme='dark'] .umd-progress{color:#94a3b8}
36
- .file-viewer[data-viewer-theme='dark'] .umd-button,.file-viewer[data-viewer-theme='dark'] .umd-icon-button{background:#172033;color:#e5edf6;border-color:rgba(148,163,184,.18)}
37
- @media (prefers-color-scheme:dark){.file-viewer[data-viewer-theme='system'] .umd-viewer{background:#101820;color:#e5edf6}.file-viewer[data-viewer-theme='system'] .umd-toolbar,.file-viewer[data-viewer-theme='system'] .umd-toc{background:rgba(15,23,42,.92);border-color:rgba(148,163,184,.18)}.file-viewer[data-viewer-theme='system'] .umd-stage{background:#111827;box-shadow:0 18px 45px rgba(0,0,0,.35),inset 0 0 0 1px rgba(148,163,184,.16)}.file-viewer[data-viewer-theme='system'] .umd-book-head h1,.file-viewer[data-viewer-theme='system'] .umd-chapter h2,.file-viewer[data-viewer-theme='system'] .umd-text,.file-viewer[data-viewer-theme='system'] .umd-toc-head{color:#e5edf6}.file-viewer[data-viewer-theme='system'] .umd-title span,.file-viewer[data-viewer-theme='system'] .umd-book-head p,.file-viewer[data-viewer-theme='system'] .umd-toc-head span,.file-viewer[data-viewer-theme='system'] .umd-progress{color:#94a3b8}.file-viewer[data-viewer-theme='system'] .umd-button,.file-viewer[data-viewer-theme='system'] .umd-icon-button{background:#172033;color:#e5edf6;border-color:rgba(148,163,184,.18)}}
38
- @media (max-width:720px){.umd-toolbar{grid-template-columns:40px minmax(0,1fr)}.umd-actions{grid-column:1/-1;justify-content:space-between}.umd-body{position:relative;grid-template-columns:minmax(0,1fr)}.umd-toc{position:absolute;z-index:5;top:0;bottom:0;left:0;width:min(82vw,280px);box-shadow:18px 0 40px rgba(15,23,42,.16)}.umd-stage-wrap{padding:12px}.umd-book-head{padding:24px 20px 0}.umd-chapter{padding:24px 20px 42px}}
39
- `;
40
- const createStyle = () => {
41
- const style = document.createElement('style');
42
- style.textContent = umdStyle;
43
- return style;
44
- };
45
- const appendText = (parent, tag, text, className) => {
46
- const element = document.createElement(tag);
47
- if (className) {
48
- element.className = className;
49
- }
50
- element.textContent = text;
51
- parent.appendChild(element);
52
- return element;
53
- };
54
- const createButton = (label, className) => {
55
- const button = document.createElement('button');
56
- button.type = 'button';
57
- button.className = className;
58
- button.textContent = label;
59
- return button;
60
- };
61
- const buildMetaLine = (book, chapter) => {
62
- if (!book) {
63
- return (chapter === null || chapter === void 0 ? void 0 : chapter.title) || '阅读中';
64
- }
65
- return [
66
- book.author,
67
- book.category,
68
- book.publishedAt,
69
- ].filter(Boolean).join(' / ') || (chapter === null || chapter === void 0 ? void 0 : chapter.title) || '阅读中';
70
- };
71
- const copyImageBytes = (image) => {
72
- const copy = new Uint8Array(image.bytes.byteLength);
73
- copy.set(image.bytes);
74
- return copy;
75
- };
76
- export default async function renderUmd(buffer, target) {
77
- const objectUrls = new Map();
78
- let book = null;
79
- let activeIndex = 0;
80
- let tocOpen = true;
81
- let disposed = false;
82
- const style = createStyle();
83
- const root = document.createElement('div');
84
- root.className = 'umd-viewer';
85
- const toolbar = document.createElement('div');
86
- toolbar.className = 'umd-toolbar';
87
- const tocButton = document.createElement('button');
88
- tocButton.type = 'button';
89
- tocButton.className = 'umd-icon-button active';
90
- tocButton.title = '目录';
91
- tocButton.appendChild(document.createElement('span'));
92
- const title = document.createElement('div');
93
- title.className = 'umd-title';
94
- const titleText = appendText(title, 'strong', 'UMD 电子书');
95
- const metaText = appendText(title, 'span', '阅读中');
96
- const actions = document.createElement('div');
97
- actions.className = 'umd-actions';
98
- const prevButton = createButton('上一章', 'umd-button');
99
- const progress = document.createElement('span');
100
- progress.className = 'umd-progress';
101
- progress.textContent = '0/0';
102
- const nextButton = createButton('下一章', 'umd-button');
103
- actions.append(prevButton, progress, nextButton);
104
- toolbar.append(tocButton, title, actions);
105
- const body = document.createElement('div');
106
- body.className = 'umd-body';
107
- const toc = document.createElement('aside');
108
- toc.className = 'umd-toc';
109
- const tocHead = document.createElement('div');
110
- tocHead.className = 'umd-toc-head';
111
- appendText(tocHead, 'strong', '目录');
112
- const tocCount = appendText(tocHead, 'span', '0 项');
113
- const tocList = document.createElement('div');
114
- tocList.className = 'umd-toc-list';
115
- toc.append(tocHead, tocList);
116
- const stageWrap = document.createElement('main');
117
- stageWrap.className = 'umd-stage-wrap';
118
- const stage = document.createElement('article');
119
- stage.className = 'umd-stage';
120
- const state = document.createElement('div');
121
- state.className = 'umd-state';
122
- state.textContent = '正在解析 UMD...';
123
- stageWrap.append(stage, state);
124
- body.append(toc, stageWrap);
125
- root.append(toolbar, body);
126
- target.replaceChildren(style, root);
127
- const revokeImageUrls = () => {
128
- objectUrls.forEach(url => URL.revokeObjectURL(url));
129
- objectUrls.clear();
130
- };
131
- const getImageUrl = (image) => {
132
- if (!image) {
133
- return '';
134
- }
135
- const existing = objectUrls.get(image.id);
136
- if (existing) {
137
- return existing;
138
- }
139
- const url = URL.createObjectURL(new Blob([copyImageBytes(image)], { type: image.mimeType }));
140
- objectUrls.set(image.id, url);
141
- return url;
142
- };
143
- const getCurrentChapter = () => book === null || book === void 0 ? void 0 : book.chapters[activeIndex];
144
- const updateChrome = () => {
145
- const chapter = getCurrentChapter();
146
- const total = (book === null || book === void 0 ? void 0 : book.chapters.length) || 0;
147
- titleText.textContent = (book === null || book === void 0 ? void 0 : book.title) || 'UMD 电子书';
148
- metaText.textContent = buildMetaLine(book, chapter);
149
- progress.textContent = total ? `${activeIndex + 1}/${total}` : '0/0';
150
- prevButton.disabled = !book || activeIndex <= 0;
151
- nextButton.disabled = !book || !total || activeIndex >= total - 1;
152
- tocButton.classList.toggle('active', tocOpen);
153
- root.classList.toggle('umd-viewer--toc-hidden', !tocOpen);
154
- tocCount.textContent = `${total} 项`;
155
- };
156
- const scrollToTop = () => {
157
- stage.scrollTo({ top: 0 });
158
- };
159
- const renderToc = () => {
160
- tocList.replaceChildren();
161
- book === null || book === void 0 ? void 0 : book.chapters.forEach((chapter, index) => {
162
- const item = createButton(chapter.title, 'umd-toc-item');
163
- item.classList.toggle('active', index === activeIndex);
164
- item.addEventListener('click', () => {
165
- activeIndex = index;
166
- tocOpen = false;
167
- renderReady();
168
- scrollToTop();
169
- });
170
- tocList.appendChild(item);
171
- });
172
- };
173
- const renderBookHead = (host) => {
174
- if (!book) {
175
- return;
176
- }
177
- const coverUrl = getImageUrl(book.cover);
178
- const metaLine = buildMetaLine(book);
179
- if (!coverUrl && !metaLine) {
180
- return;
181
- }
182
- const head = document.createElement('header');
183
- head.className = 'umd-book-head';
184
- if (coverUrl) {
185
- const image = document.createElement('img');
186
- image.src = coverUrl;
187
- image.alt = book.title;
188
- head.appendChild(image);
189
- }
190
- const info = document.createElement('div');
191
- appendText(info, 'h1', book.title);
192
- if (metaLine) {
193
- appendText(info, 'p', metaLine);
194
- }
195
- const publisher = [book.publisher, book.vendor].filter(Boolean).join(' / ');
196
- if (publisher) {
197
- appendText(info, 'p', publisher);
198
- }
199
- head.appendChild(info);
200
- host.appendChild(head);
201
- };
202
- const renderChapter = (chapter) => {
203
- const section = document.createElement('section');
204
- section.className = 'umd-chapter';
205
- section.dataset.viewerAnchorId = chapter.id;
206
- appendText(section, 'h2', chapter.title);
207
- if (chapter.images.length) {
208
- const images = document.createElement('div');
209
- images.className = 'umd-image-list';
210
- chapter.images.forEach(image => {
211
- const figure = document.createElement('figure');
212
- const img = document.createElement('img');
213
- img.src = getImageUrl(image);
214
- img.alt = chapter.title;
215
- figure.appendChild(img);
216
- images.appendChild(figure);
217
- });
218
- section.appendChild(images);
219
- }
220
- if (chapter.content) {
221
- appendText(section, 'div', chapter.content, 'umd-text');
222
- }
223
- else if (!chapter.images.length) {
224
- appendText(section, 'div', '未解析到正文内容', 'umd-empty');
225
- }
226
- return section;
227
- };
228
- const renderReady = () => {
229
- updateChrome();
230
- renderToc();
231
- state.hidden = true;
232
- stage.replaceChildren();
233
- renderBookHead(stage);
234
- const chapter = getCurrentChapter();
235
- if (chapter) {
236
- stage.appendChild(renderChapter(chapter));
237
- }
238
- const warningText = (book === null || book === void 0 ? void 0 : book.warnings.filter(Boolean).join(';')) || '';
239
- if (warningText) {
240
- appendText(stage, 'div', warningText, 'umd-warning');
241
- }
242
- };
243
- const renderError = (message) => {
244
- updateChrome();
245
- state.hidden = false;
246
- state.classList.add('error');
247
- state.textContent = message;
248
- };
249
- const toggleToc = () => {
250
- tocOpen = !tocOpen;
251
- updateChrome();
252
- };
253
- const goPrev = () => {
254
- if (!book || activeIndex <= 0) {
255
- return;
256
- }
257
- activeIndex -= 1;
258
- renderReady();
259
- scrollToTop();
260
- };
261
- const goNext = () => {
262
- const total = (book === null || book === void 0 ? void 0 : book.chapters.length) || 0;
263
- if (!book || activeIndex >= total - 1) {
264
- return;
265
- }
266
- activeIndex += 1;
267
- renderReady();
268
- scrollToTop();
269
- };
270
- tocButton.addEventListener('click', toggleToc);
271
- prevButton.addEventListener('click', goPrev);
272
- nextButton.addEventListener('click', goNext);
273
- try {
274
- book = parseUmdBook(buffer.slice(0));
275
- if (!disposed) {
276
- activeIndex = 0;
277
- renderReady();
278
- }
279
- }
280
- catch (error) {
281
- if (!disposed) {
282
- console.error(error);
283
- renderError(error instanceof Error ? error.message : String(error));
284
- }
285
- }
286
- return {
287
- $el: target,
288
- unmount() {
289
- disposed = true;
290
- tocButton.removeEventListener('click', toggleToc);
291
- prevButton.removeEventListener('click', goPrev);
292
- nextButton.removeEventListener('click', goNext);
293
- revokeImageUrls();
294
- target.replaceChildren();
295
- },
296
- };
297
- }
@@ -1,8 +0,0 @@
1
- import type { FileRenderContext, FileViewerRenderedInstance } from '../contracts/types';
2
- /**
3
- * Pure TypeScript video renderer.
4
- *
5
- * MP4/WebM use the native `<video>` element. HLS uses native browser support
6
- * first and imports `hls.js` only when the current browser needs it.
7
- */
8
- export default function renderVideo(buffer: ArrayBuffer, target: HTMLDivElement, type?: string, context?: FileRenderContext): Promise<FileViewerRenderedInstance>;
@@ -1,108 +0,0 @@
1
- const videoStyle = `
2
- .fv-video-viewer{width:100%;min-height:100%;display:flex;align-items:center;justify-content:center;padding:28px;background:#eef1f4;box-sizing:border-box}
3
- .fv-video-shell{width:min(100%,960px);border-radius:8px;border:1px solid rgba(15,23,42,.1);background:#fff;box-shadow:0 18px 48px rgba(15,23,42,.14);overflow:hidden}
4
- .fv-video-heading{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 18px;border-bottom:1px solid rgba(15,23,42,.08)}
5
- .fv-video-heading span{color:#0f766e;font-size:12px;font-weight:800}
6
- .fv-video-heading strong{color:#132235;font-size:16px}
7
- .fv-video-player{display:block;width:100%;aspect-ratio:16/9;background:#05070a}
8
- .fv-video-hint{margin:0;padding:12px 18px 16px;color:#64748b;font-size:13px;line-height:1.7}
9
- `;
10
- const VIDEO_MIME_MAP = {
11
- m3u8: 'application/vnd.apple.mpegurl',
12
- mp4: 'video/mp4',
13
- webm: 'video/webm'
14
- };
15
- const createElement = (tagName, className, text) => {
16
- const element = document.createElement(tagName);
17
- if (className) {
18
- element.className = className;
19
- }
20
- if (typeof text === 'string') {
21
- element.textContent = text;
22
- }
23
- return element;
24
- };
25
- const createStyle = () => {
26
- const style = document.createElement('style');
27
- style.textContent = videoStyle;
28
- return style;
29
- };
30
- const createRenderedInstance = (target, cleanup) => ({
31
- $el: target,
32
- unmount() {
33
- cleanup();
34
- target.replaceChildren();
35
- }
36
- });
37
- const getMimeType = (type) => {
38
- return VIDEO_MIME_MAP[type] || 'video/*';
39
- };
40
- const createLocalUrl = (buffer, type) => {
41
- return URL.createObjectURL(new Blob([buffer], { type: getMimeType(type) }));
42
- };
43
- /**
44
- * Pure TypeScript video renderer.
45
- *
46
- * MP4/WebM use the native `<video>` element. HLS uses native browser support
47
- * first and imports `hls.js` only when the current browser needs it.
48
- */
49
- export default async function renderVideo(buffer, target, type, context) {
50
- const normalizedType = (type || 'mp4').toLowerCase();
51
- let disposed = false;
52
- let objectUrl = '';
53
- let hls = null;
54
- const root = createElement('div', 'fv-video-viewer');
55
- const shell = createElement('section', 'fv-video-shell');
56
- const heading = createElement('div', 'fv-video-heading');
57
- heading.append(createElement('span', '', normalizedType.toUpperCase() || 'VIDEO'), createElement('strong', '', '视频预览'));
58
- const video = createElement('video', 'fv-video-player');
59
- video.controls = true;
60
- video.preload = 'metadata';
61
- video.textContent = '当前浏览器不支持该视频格式。';
62
- shell.append(heading, video);
63
- if (normalizedType === 'm3u8') {
64
- shell.append(createElement('p', 'fv-video-hint', 'HLS 会优先使用原始 URL 加载分片;如果传入的是本地单文件清单,请确保分片地址可被浏览器访问。'));
65
- }
66
- root.append(shell);
67
- target.replaceChildren(createStyle(), root);
68
- const resolveSource = () => {
69
- if (normalizedType === 'm3u8' && (context === null || context === void 0 ? void 0 : context.url)) {
70
- return context.url;
71
- }
72
- objectUrl = createLocalUrl(buffer, normalizedType);
73
- return objectUrl;
74
- };
75
- const mountVideo = async () => {
76
- const source = resolveSource();
77
- if (normalizedType === 'm3u8') {
78
- if (video.canPlayType('application/vnd.apple.mpegurl')) {
79
- video.src = source;
80
- return;
81
- }
82
- const { default: HlsConstructor } = await import('hls.js');
83
- if (disposed) {
84
- return;
85
- }
86
- if (HlsConstructor.isSupported()) {
87
- hls = new HlsConstructor({ enableWorker: true, lowLatencyMode: false });
88
- hls.loadSource(source);
89
- hls.attachMedia(video);
90
- return;
91
- }
92
- }
93
- video.src = source;
94
- };
95
- void mountVideo();
96
- return createRenderedInstance(target, () => {
97
- disposed = true;
98
- hls === null || hls === void 0 ? void 0 : hls.destroy();
99
- hls = null;
100
- video.pause();
101
- video.removeAttribute('src');
102
- video.load();
103
- if (objectUrl) {
104
- URL.revokeObjectURL(objectUrl);
105
- objectUrl = '';
106
- }
107
- });
108
- }
@@ -1,5 +0,0 @@
1
- import type { FileRenderContext, FileViewerRenderedInstance as AppWrapper } from '../contracts/types';
2
- /**
3
- * 渲染 doc 文件
4
- */
5
- export default function render(buffer: ArrayBuffer, target: HTMLDivElement, context?: FileRenderContext): Promise<AppWrapper>;