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)
|
|
20422
|
-
*
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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()) {
|