@file-viewer/pptx 2.2.4 → 2.2.5

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/chart.d.ts CHANGED
@@ -1 +1,5 @@
1
- export declare const renderPptxPostProcessing: (charts: unknown, root: ParentNode) => Promise<void>;
1
+ export type PptxPostProcessingHandle = {
2
+ destroy: () => void;
3
+ };
4
+ export declare const findPptxChartTarget: (root: ParentNode, chartID: string) => HTMLElement | null;
5
+ export declare const renderPptxPostProcessing: (charts: unknown, root: ParentNode) => Promise<PptxPostProcessingHandle>;
package/dist/chart.js CHANGED
@@ -1,6 +1,14 @@
1
1
  const asChartQueue = (charts) => {
2
2
  return Array.isArray(charts === null || charts === void 0 ? void 0 : charts.MsgQueue) ? charts.MsgQueue : [];
3
3
  };
4
+ export const findPptxChartTarget = (root, chartID) => {
5
+ const rootElement = root;
6
+ if (rootElement.id === chartID) {
7
+ return rootElement;
8
+ }
9
+ return Array.from(root.querySelectorAll('[id]'))
10
+ .find(element => element.id === chartID) || null;
11
+ };
4
12
  const getNumericBulletText = (type, index) => {
5
13
  switch (type) {
6
14
  case 'arabicPeriod':
@@ -141,18 +149,24 @@ const fitOverflowingTextBlocks = (root) => {
141
149
  .querySelectorAll('.slide div.content, .slide div.content-rtl')
142
150
  .forEach(fitOverflowingTextBlock);
143
151
  };
144
- const renderChart = async (message) => {
152
+ const renderChart = async (message, root) => {
145
153
  var _a;
146
154
  const payload = message.data;
147
155
  if (!(payload === null || payload === void 0 ? void 0 : payload.chartID) || !payload.chartType || !payload.chartData) {
148
156
  return;
149
157
  }
158
+ const chartTarget = findPptxChartTarget(root, payload.chartID);
159
+ if (!chartTarget) {
160
+ return;
161
+ }
150
162
  const billboard = await import('billboard.js');
151
163
  const d3Format = await import('d3-format');
152
164
  const bb = billboard.default || billboard;
153
165
  const { area, bar, line, pie, scatter } = billboard;
154
166
  const chart = {
155
- bindto: `#${payload.chartID}`,
167
+ // A selector makes Billboard query the main document. That misses chart
168
+ // placeholders inside the viewer Shadow DOM and makes it fall back to body.
169
+ bindto: chartTarget,
156
170
  };
157
171
  const chartData = payload.chartData;
158
172
  const axis = {
@@ -249,20 +263,44 @@ const renderChart = async (message) => {
249
263
  return;
250
264
  }
251
265
  if (chart.data) {
252
- bb.generate(chart);
266
+ return bb.generate(chart);
253
267
  }
254
268
  };
255
269
  export const renderPptxPostProcessing = async (charts, root) => {
256
270
  restoreNumericBullets(root);
257
271
  fitOverflowingTextBlocks(root);
258
272
  const queue = asChartQueue(charts);
259
- if (!queue.length) {
260
- return;
261
- }
262
- try {
263
- await Promise.all(queue.map(renderChart));
264
- }
265
- catch (error) {
266
- console.warn('PPTX chart rendering skipped:', error);
273
+ const chartInstances = [];
274
+ if (queue.length) {
275
+ const results = await Promise.allSettled(queue.map(message => renderChart(message, root)));
276
+ for (const result of results) {
277
+ if (result.status === 'fulfilled') {
278
+ if (result.value) {
279
+ chartInstances.push(result.value);
280
+ }
281
+ }
282
+ else {
283
+ console.warn('PPTX chart rendering skipped:', result.reason);
284
+ }
285
+ }
267
286
  }
287
+ let destroyed = false;
288
+ return {
289
+ destroy() {
290
+ var _a;
291
+ if (destroyed) {
292
+ return;
293
+ }
294
+ destroyed = true;
295
+ for (const chart of chartInstances) {
296
+ try {
297
+ (_a = chart.destroy) === null || _a === void 0 ? void 0 : _a.call(chart);
298
+ }
299
+ catch {
300
+ // The DOM may already be detached during framework unmount.
301
+ }
302
+ }
303
+ chartInstances.length = 0;
304
+ },
305
+ };
268
306
  };
package/dist/viewer.d.ts CHANGED
@@ -20,6 +20,7 @@ export declare class PptxViewer {
20
20
  private slideWindowListeners;
21
21
  private slideWindowFrame;
22
22
  private charts;
23
+ private readonly chartHandles;
23
24
  private readonly mediaRecords;
24
25
  private disposed;
25
26
  private completed;
@@ -60,6 +61,9 @@ export declare class PptxViewer {
60
61
  cloneForExport(): Promise<HTMLElement>;
61
62
  private complete;
62
63
  private fail;
64
+ private trackChartHandle;
65
+ private releaseChartHandle;
66
+ private releaseCharts;
63
67
  private storeMedia;
64
68
  private hydrateMedia;
65
69
  private releaseMedia;
package/dist/viewer.js CHANGED
@@ -100,6 +100,7 @@ export class PptxViewer {
100
100
  this.slideWindowListeners = [];
101
101
  this.slideWindowFrame = 0;
102
102
  this.charts = null;
103
+ this.chartHandles = new Set();
103
104
  this.mediaRecords = new Map();
104
105
  this.disposed = false;
105
106
  this.completed = false;
@@ -140,6 +141,7 @@ export class PptxViewer {
140
141
  var _a, _b, _c, _d;
141
142
  this.disposed = true;
142
143
  this.previewThumbnailDataUrl = null;
144
+ this.releaseCharts();
143
145
  this.releaseMedia();
144
146
  (_a = this.worker) === null || _a === void 0 ? void 0 : _a.terminate();
145
147
  this.worker = null;
@@ -157,6 +159,7 @@ export class PptxViewer {
157
159
  startWorker() {
158
160
  var _a;
159
161
  (_a = this.worker) === null || _a === void 0 ? void 0 : _a.terminate();
162
+ this.releaseCharts();
160
163
  this.releaseMedia();
161
164
  this.completed = false;
162
165
  this.charts = null;
@@ -327,6 +330,8 @@ export class PptxViewer {
327
330
  notified: false,
328
331
  postProcessed: false,
329
332
  postProcessPromise: null,
333
+ postProcessVersion: 0,
334
+ chartHandle: null,
330
335
  };
331
336
  }
332
337
  getDesignerCanvases(record) {
@@ -344,6 +349,7 @@ export class PptxViewer {
344
349
  record.slot.append(...designerCanvases);
345
350
  record.rendered = true;
346
351
  record.postProcessed = false;
352
+ record.postProcessVersion += 1;
347
353
  this.updateMeasuredSlideHeight(record);
348
354
  if (!record.notified) {
349
355
  record.notified = true;
@@ -359,6 +365,9 @@ export class PptxViewer {
359
365
  return;
360
366
  }
361
367
  this.updateMeasuredSlideHeight(record);
368
+ this.releaseChartHandle(record.chartHandle);
369
+ record.chartHandle = null;
370
+ record.postProcessVersion += 1;
362
371
  record.slot.replaceChildren();
363
372
  record.element = null;
364
373
  record.rendered = false;
@@ -538,7 +547,8 @@ export class PptxViewer {
538
547
  }
539
548
  async postProcessRenderedContent(charts) {
540
549
  if (!this.shouldWindowSlides()) {
541
- await renderPptxPostProcessing(charts, this.content);
550
+ const handle = await renderPptxPostProcessing(charts, this.content);
551
+ this.trackChartHandle(handle);
542
552
  return;
543
553
  }
544
554
  await Promise.all(this.slideRecords
@@ -550,16 +560,24 @@ export class PptxViewer {
550
560
  return;
551
561
  }
552
562
  if (!record.postProcessPromise) {
553
- record.postProcessPromise = (async () => {
554
- await renderPptxPostProcessing(this.charts, record.slot);
555
- if (this.disposed) {
563
+ const version = record.postProcessVersion;
564
+ const postProcessPromise = (async () => {
565
+ const handle = await renderPptxPostProcessing(this.charts, record.slot);
566
+ if (this.disposed || !record.rendered || record.postProcessVersion !== version) {
567
+ handle === null || handle === void 0 ? void 0 : handle.destroy();
556
568
  return;
557
569
  }
570
+ this.releaseChartHandle(record.chartHandle);
571
+ record.chartHandle = handle;
572
+ this.trackChartHandle(handle);
558
573
  record.postProcessed = true;
559
574
  this.updateMeasuredSlideHeight(record);
560
575
  })().finally(() => {
561
- record.postProcessPromise = null;
576
+ if (record.postProcessPromise === postProcessPromise) {
577
+ record.postProcessPromise = null;
578
+ }
562
579
  });
580
+ record.postProcessPromise = postProcessPromise;
563
581
  }
564
582
  await record.postProcessPromise;
565
583
  }
@@ -611,10 +629,37 @@ export class PptxViewer {
611
629
  this.completed = true;
612
630
  (_a = this.worker) === null || _a === void 0 ? void 0 : _a.terminate();
613
631
  this.worker = null;
632
+ this.releaseCharts();
614
633
  this.releaseMedia();
615
634
  this.content.dataset.renderState = 'error';
616
635
  (_c = (_b = this.options).onError) === null || _c === void 0 ? void 0 : _c.call(_b, error);
617
636
  }
637
+ trackChartHandle(handle) {
638
+ if (!handle) {
639
+ return;
640
+ }
641
+ if (this.disposed) {
642
+ handle.destroy();
643
+ return;
644
+ }
645
+ this.chartHandles.add(handle);
646
+ }
647
+ releaseChartHandle(handle) {
648
+ if (!handle) {
649
+ return;
650
+ }
651
+ this.chartHandles.delete(handle);
652
+ handle.destroy();
653
+ }
654
+ releaseCharts() {
655
+ for (const handle of this.chartHandles) {
656
+ handle.destroy();
657
+ }
658
+ this.chartHandles.clear();
659
+ for (const record of this.slideRecords) {
660
+ record.chartHandle = null;
661
+ }
662
+ }
618
663
  storeMedia(data) {
619
664
  if (!data || typeof data !== 'object') {
620
665
  return;