pptx-angular-viewer 1.13.1 → 1.13.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/CHANGELOG.md CHANGED
@@ -4,6 +4,8 @@ All notable changes to this project are documented here.
4
4
  This file is generated from [Conventional Commits](https://www.conventionalcommits.org)
5
5
  by [git-cliff](https://git-cliff.org); do not edit it by hand.
6
6
 
7
+ ## [1.13.1](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-angular-viewer@1.13.1) - 2026-07-09
8
+
7
9
  ## [1.13.0](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-angular-viewer@1.13.0) - 2026-07-09
8
10
 
9
11
  ### Other
@@ -20400,6 +20400,39 @@ function buildRunEffectStyle(style) {
20400
20400
  return css;
20401
20401
  }
20402
20402
 
20403
+ /**
20404
+ * DOMPurify wrappers shared by every markup-sanitising call site (MathML/SVG
20405
+ * equation rendering, print-document/SVG assembly). DOMPurify's factory has
20406
+ * no working `sanitize` until handed a `window`, so in non-DOM contexts
20407
+ * (node-based tests, SSR without jsdom) these degrade rather than throw.
20408
+ *
20409
+ * Two degradation strategies, picked per call site by how the sanitised
20410
+ * output is used:
20411
+ * - {@link sanitizeMarkupOrRaw}: returns the untouched input outside a DOM.
20412
+ * Safe when the caller only ever renders the result in the browser (e.g.
20413
+ * `dangerouslySetInnerHTML` / `v-html`), so the fallback path never
20414
+ * reaches a real sink.
20415
+ * - {@link sanitizeMarkupOrEmpty}: returns `''` outside a DOM (fail closed).
20416
+ * Used where the sanitised string is unconditionally spliced into a
20417
+ * larger assembled document (print HTML/SVG) with no further gate, so a
20418
+ * silent pass-through of the raw, unsanitised input would defeat the
20419
+ * sanitisation entirely.
20420
+ */
20421
+ function purifyFn() {
20422
+ const purify = DOMPurify;
20423
+ return typeof purify.sanitize === 'function' ? purify.sanitize : undefined;
20424
+ }
20425
+ /** Sanitise `markup`; outside a DOM, returns the raw input unchanged. */
20426
+ function sanitizeMarkupOrRaw(markup, config) {
20427
+ const sanitize = purifyFn();
20428
+ return sanitize ? sanitize(markup, config) : markup;
20429
+ }
20430
+ /** Sanitise `markup`; outside a DOM, returns `''` (fail closed). */
20431
+ function sanitizeMarkupOrEmpty(markup, config) {
20432
+ const sanitize = purifyFn();
20433
+ return sanitize ? sanitize(markup, config) : '';
20434
+ }
20435
+
20403
20436
  /**
20404
20437
  * MathML / SVG markup sanitisation, shared by every binding's equation
20405
20438
  * renderer.
@@ -20418,20 +20451,15 @@ function buildRunEffectStyle(style) {
20418
20451
  * Safely sanitise a MathML/SVG markup string.
20419
20452
  *
20420
20453
  * In browser environments DOMPurify ships with `sanitize` ready to go. In
20421
- * non-DOM contexts (node-based tests, SSR without jsdom) DOMPurify returns a
20422
- * factory that lacks `sanitize` until handed a window; there we fall back to
20423
- * the raw input. The XSS surface only matters in the browser, so this fallback
20454
+ * non-DOM contexts (node-based tests, SSR without jsdom) it falls back to the
20455
+ * raw input; the XSS surface only matters in the browser, so this fallback
20424
20456
  * is safe for non-DOM consumers.
20425
20457
  *
20426
20458
  * @param markup - MathML (optionally with embedded SVG) markup to sanitise.
20427
20459
  * @returns The sanitised markup, or the raw input when no DOM is available.
20428
20460
  */
20429
20461
  function sanitizeMathMl(markup) {
20430
- const purify = DOMPurify;
20431
- if (typeof purify.sanitize !== 'function') {
20432
- return markup;
20433
- }
20434
- return purify.sanitize(markup, { USE_PROFILES: { mathMl: true, svg: true } });
20462
+ return sanitizeMarkupOrRaw(markup, { USE_PROFILES: { mathMl: true, svg: true } });
20435
20463
  }
20436
20464
 
20437
20465
  /**
@@ -33982,13 +34010,13 @@ function buildNotesTextStream(lines, startY) {
33982
34010
  }
33983
34011
 
33984
34012
  /**
33985
- * Pure SVG-print string helpers shared by bindings that offer a vector print
34013
+ * Pure SVG-print string helpers, shared by bindings that offer a vector print
33986
34014
  * path (currently React). These build self-contained SVG / print-HTML strings
33987
34015
  * and escape text; they touch no DOM.
33988
34016
  *
33989
34017
  * The DOM-bound driver pieces (cloning the live element tree, reading
33990
34018
  * `getComputedStyle`, fetching images to base64, `Blob` wrapping) stay in the
33991
- * binding only the string assembly and escaping live here.
34019
+ * binding; only the string assembly and escaping live here.
33992
34020
  */
33993
34021
  /* ------------------------------------------------------------------ */
33994
34022
  /* XML escaping */
@@ -34122,7 +34150,14 @@ function buildPrintDocument(svgs, width, height, options = {}) {
34122
34150
  const safeColorFilter = sanitizeCssDeclaration(colorFilter);
34123
34151
  const slidePages = svgs
34124
34152
  .map((svg, i) => {
34125
- const safeSvg = isSafeSvgMarkup(svg) ? svg : '';
34153
+ // Belt-and-suspenders: the structural allow/deny-list guard runs
34154
+ // first, then DOMPurify's SVG profile actually transforms the
34155
+ // markup (stripping `<script>`/`<foreignObject>`/event handlers/
34156
+ // `javascript:` URIs) before it is spliced in, rather than merely
34157
+ // gating the raw, untransformed string behind a boolean check.
34158
+ const safeSvg = isSafeSvgMarkup(svg)
34159
+ ? sanitizeMarkupOrEmpty(svg, { USE_PROFILES: { svg: true } })
34160
+ : '';
34126
34161
  return `<section class="print-slide-page" aria-label="Slide ${i + 1}">
34127
34162
  ${safeSvg}
34128
34163
  </section>`;
@@ -35621,6 +35656,8 @@ function isSafePrintBodyHtml(html) {
35621
35656
  }
35622
35657
  return !EVENT_HANDLER_ATTR_RE.test(html);
35623
35658
  }
35659
+ /** DOMPurify config for the assembled print-window body: plain HTML, no MathML/SVG needed. */
35660
+ const PRINT_BODY_SANITIZE_CONFIG = { USE_PROFILES: { html: true } };
35624
35661
  /**
35625
35662
  * Assemble the complete printable HTML document string (doctype + head with
35626
35663
  * print CSS + body). Pure: the caller writes it into a print window.
@@ -35629,7 +35666,13 @@ function buildPrintHtmlDocument(options) {
35629
35666
  const { title, bodyHtml, frameSlides } = options;
35630
35667
  const orientation = sanitizeOrientation(options.orientation);
35631
35668
  const colorFilter = options.colorFilter;
35632
- const safeBodyHtml = isSafePrintBodyHtml(bodyHtml) ? bodyHtml : '';
35669
+ // Belt-and-suspenders: the deny-list guard runs first, then DOMPurify
35670
+ // actually transforms the markup (stripping `<script>`/`<iframe>`/event
35671
+ // handlers/`javascript:` URIs) before it is spliced in, rather than
35672
+ // merely gating the raw, untransformed string behind a boolean check.
35673
+ const safeBodyHtml = isSafePrintBodyHtml(bodyHtml)
35674
+ ? sanitizeMarkupOrEmpty(bodyHtml, PRINT_BODY_SANITIZE_CONFIG)
35675
+ : '';
35633
35676
  const frameStyle = frameSlides
35634
35677
  ? 'img.slide-img, .notes-slide, .handout-cell img { border: 2px solid #000 !important; }'
35635
35678
  : '';
@@ -75869,7 +75912,7 @@ class RibbonComponent {
75869
75912
 
75870
75913
  <!-- ── Ribbon content (collapsible via the ribbon toggle) ──────────── -->
75871
75914
  <div
75872
- class="flex flex-nowrap items-stretch gap-1.5 overflow-x-auto px-2 py-1.5"
75915
+ class="flex flex-nowrap items-center gap-1.5 overflow-x-auto px-2 py-1"
75873
75916
  [style.display]="ribbonExpanded() ? null : 'none'"
75874
75917
  >
75875
75918
  @switch (activeTab()) {
@@ -76175,7 +76218,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
76175
76218
 
76176
76219
  <!-- ── Ribbon content (collapsible via the ribbon toggle) ──────────── -->
76177
76220
  <div
76178
- class="flex flex-nowrap items-stretch gap-1.5 overflow-x-auto px-2 py-1.5"
76221
+ class="flex flex-nowrap items-center gap-1.5 overflow-x-auto px-2 py-1"
76179
76222
  [style.display]="ribbonExpanded() ? null : 'none'"
76180
76223
  >
76181
76224
  @switch (activeTab()) {