@file-viewer/pptx 2.1.17 → 2.1.18

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { PptxViewer } from './viewer';
2
2
  export { createPptxWorker } from './worker';
3
3
  export { RECOMMENDED_ZIP_LIMITS, createDefaultPptxOptions, resolvePptxEngineOptions, } from './options';
4
- export type { NativePptxEngineOptions, PptxFitMode, PptxListOptions, PptxSlideSize, PptxViewerOptions, PptxWorkerFactoryOptions, PptxWorkerMessage, PptxZipLimits, } from './types';
4
+ export type { NativePptxEngineOptions, PptxDiagnosticError, PptxDiagnosticErrorCode, PptxFitMode, PptxListOptions, PptxSlideSize, PptxViewerOptions, PptxWorkerFactoryOptions, PptxWorkerMessage, PptxZipLimits, } from './types';
package/dist/styles.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export declare const pptxViewerCss = "\n.flyfish-pptx-scale-box{position:relative;box-sizing:border-box;max-width:100%;margin:0 auto;min-width:0}\n.flyfish-pptx-content{position:absolute;top:0;left:0;box-sizing:border-box;max-width:none;min-width:0;transform-origin:top left;will-change:transform}\n.flyfish-pptx-content[data-render-state=\"loading\"]{opacity:.82}\n.flyfish-pptx-slide-slot{display:flow-root;box-sizing:border-box;width:100%;min-width:0}\n.flyfish-pptx-content .slide{background:#fff;box-shadow:0 18px 36px rgba(18,35,52,.12)}\n.flyfish-pptx-thumbnail{display:block;box-sizing:border-box;width:min(960px,100%);height:auto;margin:0 auto 28px;border-radius:12px;background:#fff;box-shadow:0 18px 36px rgba(18,35,52,.14)}\n\n.slide{position:relative;border:0;border-radius:0;overflow:hidden;margin-bottom:50px;margin-left:auto;margin-right:auto;z-index:100}\n.slide div.block{position:absolute;top:0;left:0;width:100%;line-height:1}\n.slide div.content{display:flex;flex-direction:column}\n.slide div.diagram-content{display:flex;flex-direction:column}\n.slide div.content-rtl{display:flex;flex-direction:column;direction:rtl}\n.slide .pregraph-rtl{direction:rtl}\n.slide .pregraph-ltr{direction:ltr}\n.slide .pregraph-inherit{direction:inherit}\n.slide .slide-prgrph{width:100%}\n.slide .line-break-br::before{content:\"\\A\";white-space:pre}\n.slide div.v-up{justify-content:flex-start}\n.slide div.v-mid{justify-content:center}\n.slide div.v-down{justify-content:flex-end}\n.slide div.h-left{justify-content:flex-start;align-items:flex-start;text-align:left}\n.slide div.h-left-rtl{justify-content:flex-end;align-items:flex-end;text-align:left}\n.slide div.h-mid{justify-content:center;align-items:center;text-align:center}\n.slide div.h-right{justify-content:flex-end;align-items:flex-end;text-align:right}\n.slide div.h-right-rtl{justify-content:flex-start;align-items:flex-start;text-align:right}\n.slide div.h-just,.slide div.h-dist{text-align:justify}\n.slide div.up-left{justify-content:flex-start;align-items:flex-start;text-align:left}\n.slide div.up-center{justify-content:flex-start;align-items:center}\n.slide div.up-right{justify-content:flex-start;align-items:flex-end}\n.slide div.center-left{justify-content:center;align-items:flex-start;text-align:left}\n.slide div.center-center{justify-content:center;align-items:center}\n.slide div.center-right{justify-content:center;align-items:flex-end}\n.slide div.down-left{justify-content:flex-end;align-items:flex-start;text-align:left}\n.slide div.down-center{justify-content:flex-end;align-items:center}\n.slide div.down-right{justify-content:flex-end;align-items:flex-end}\n.slide li.slide{margin:10px 0;font-size:18px}\n.slide table{position:absolute}\n.slide svg.drawing{position:absolute;overflow:visible}\n\n.flyfish-pptx-content > .slide:last-of-type{margin-bottom:0}\n.flyfish-pptx-slide-slot:last-of-type > .slide{margin-bottom:0}\n";
2
- export declare const ensurePptxViewerStyles: (documentRef: Document) => void;
2
+ export declare const ensurePptxViewerStyles: (documentRef: Document, root?: Document | ShadowRoot) => void;
package/dist/styles.js CHANGED
@@ -43,12 +43,19 @@ ${legacyPptxCss}
43
43
  .flyfish-pptx-slide-slot:last-of-type > .slide{margin-bottom:0}
44
44
  `;
45
45
  const PPTX_STYLE_ID = 'flyfish-pptx-native-style';
46
- export const ensurePptxViewerStyles = (documentRef) => {
47
- if (documentRef.getElementById(PPTX_STYLE_ID)) {
46
+ export const ensurePptxViewerStyles = (documentRef, root = documentRef) => {
47
+ if (root instanceof Document && root.getElementById(PPTX_STYLE_ID)) {
48
+ return;
49
+ }
50
+ if (!(root instanceof Document) && root.querySelector(`#${PPTX_STYLE_ID}`)) {
48
51
  return;
49
52
  }
50
53
  const style = documentRef.createElement('style');
51
54
  style.id = PPTX_STYLE_ID;
52
55
  style.textContent = pptxViewerCss;
53
- (documentRef.head || documentRef.documentElement).appendChild(style);
56
+ if (root instanceof Document) {
57
+ (root.head || root.documentElement).appendChild(style);
58
+ return;
59
+ }
60
+ root.appendChild(style);
54
61
  };
package/dist/types.d.ts CHANGED
@@ -34,7 +34,17 @@ export interface PptxSlideSize {
34
34
  height?: number;
35
35
  [key: string]: unknown;
36
36
  }
37
+ export type PptxDiagnosticErrorCode = 'PPTX_FILE_EMPTY' | 'PPTX_FILE_TOO_LARGE' | 'PPTX_INVALID_ZIP' | 'PPTX_MISSING_CONTENT_TYPES' | 'PPTX_MISSING_PRESENTATION' | 'PPTX_NO_SLIDES' | 'PPTX_MISSING_SLIDE' | 'PPTX_SLIDE_RENDER_FAILED' | 'PPTX_WORKER_FAILED' | 'PPTX_PARSE_FAILED' | (string & {});
38
+ export interface PptxDiagnosticError {
39
+ name: 'PptxDiagnosticError';
40
+ code: PptxDiagnosticErrorCode;
41
+ stage?: string;
42
+ message: string;
43
+ detail?: string;
44
+ hint?: string;
45
+ }
37
46
  export interface PptxViewerOptions extends PptxWorkerFactoryOptions {
47
+ styleRoot?: ShadowRoot;
38
48
  fitMode?: PptxFitMode;
39
49
  zoomPercent?: number;
40
50
  zipLimits?: PptxZipLimits;
package/dist/viewer.js CHANGED
@@ -9,13 +9,39 @@ const toPercent = (value) => {
9
9
  const numeric = typeof value === 'number' && Number.isFinite(value) ? value : 100;
10
10
  return clamp(numeric, 25, 300);
11
11
  };
12
+ const stringifyErrorDetail = (error) => {
13
+ if (error === undefined || error === null) {
14
+ return '';
15
+ }
16
+ if (typeof error === 'string') {
17
+ return error;
18
+ }
19
+ if (error instanceof Error && error.message) {
20
+ return error.message;
21
+ }
22
+ try {
23
+ const serialized = JSON.stringify(error);
24
+ return serialized && serialized !== '{}' ? serialized : String(error);
25
+ }
26
+ catch {
27
+ return String(error);
28
+ }
29
+ };
30
+ const createPptxDiagnosticError = (code, stage, message, detailOrError, hint) => ({
31
+ name: 'PptxDiagnosticError',
32
+ code,
33
+ stage,
34
+ message,
35
+ detail: stringifyErrorDetail(detailOrError),
36
+ hint,
37
+ });
12
38
  const ensureZipWithinLimits = (buffer, options) => {
13
39
  const limits = {
14
40
  ...RECOMMENDED_ZIP_LIMITS,
15
41
  ...options.zipLimits,
16
42
  };
17
43
  if (limits.maxFileBytes && buffer.byteLength > limits.maxFileBytes) {
18
- throw new Error(`PPTX file is too large to preview safely (${buffer.byteLength} bytes).`);
44
+ throw createPptxDiagnosticError('PPTX_FILE_TOO_LARGE', 'preflight', 'PPTX 文件超过浏览器安全预览体积限制。', `${buffer.byteLength} bytes > ${limits.maxFileBytes} bytes`, '请压缩图片、拆分演示文稿,或在业务侧提高 zipLimits.maxFileBytes 后再预览。');
19
45
  }
20
46
  };
21
47
  const appendHtml = (container, html) => {
@@ -81,7 +107,7 @@ export class PptxViewer {
81
107
  }
82
108
  async open() {
83
109
  ensureZipWithinLimits(this.buffer, this.options);
84
- ensurePptxViewerStyles(this.target.ownerDocument || document);
110
+ ensurePptxViewerStyles(this.target.ownerDocument || document, this.options.styleRoot);
85
111
  this.target.replaceChildren(this.scaleBox);
86
112
  this.attachResizeObserver();
87
113
  this.attachSlideWindowListeners();
@@ -117,15 +143,25 @@ export class PptxViewer {
117
143
  this.slideRecords = [];
118
144
  this.content.replaceChildren();
119
145
  this.content.dataset.renderState = 'loading';
120
- this.worker = createPptxWorker(this.options);
146
+ try {
147
+ this.worker = createPptxWorker(this.options);
148
+ }
149
+ catch (error) {
150
+ throw createPptxDiagnosticError('PPTX_WORKER_FAILED', 'start-worker', 'PPTX Worker 启动失败。', error, '请检查 presentation.workerUrl、Worker 文件是否 200 返回、MIME/CSP/跨域策略是否允许加载。');
151
+ }
121
152
  this.worker.addEventListener('message', event => this.processMessage(event.data));
122
- this.worker.addEventListener('error', event => this.fail(event.error || event.message));
123
- this.worker.postMessage({
124
- type: 'processPPTX',
125
- data: this.buffer,
126
- IE11: false,
127
- options: resolvePptxEngineOptions(this.options.engineOptions),
128
- });
153
+ this.worker.addEventListener('error', event => this.fail(createPptxDiagnosticError('PPTX_WORKER_FAILED', 'worker-runtime', 'PPTX Worker 运行失败。', event.error || event.message, '请检查 Worker 脚本是否完整、浏览器控制台是否有 CSP/MIME/跨域或语法错误。')));
154
+ try {
155
+ this.worker.postMessage({
156
+ type: 'processPPTX',
157
+ data: this.buffer,
158
+ IE11: false,
159
+ options: resolvePptxEngineOptions(this.options.engineOptions),
160
+ });
161
+ }
162
+ catch (error) {
163
+ throw createPptxDiagnosticError('PPTX_WORKER_FAILED', 'post-worker-message', 'PPTX 数据发送到 Worker 失败。', error, '请确认浏览器支持 Worker 消息传递,并避免传入已被释放或不可克隆的数据。');
164
+ }
129
165
  }
130
166
  processMessage(message) {
131
167
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;