diff --git a/src/frontend/apps/impress/src/features/docs/doc-export/__tests__/utilsPrint.test.ts b/src/frontend/apps/impress/src/features/docs/doc-export/__tests__/utilsPrint.test.ts new file mode 100644 index 000000000..7421e58af --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-export/__tests__/utilsPrint.test.ts @@ -0,0 +1,70 @@ +import { afterEach, describe, expect, test } from 'vitest'; + +import { wrapInterlinksWithAnchor, wrapMediaWithLink } from '../utils_print'; + +describe('print DOM helpers', () => { + afterEach(() => { + document.body.innerHTML = ''; + }); + + test('wraps media links only inside the provided root', () => { + document.body.innerHTML = ` +
+
+
+
+
+
+
+
+
+
+ `; + + const root = document.getElementById('root'); + if (!root) { + throw new Error('missing root'); + } + + const cleanup = wrapMediaWithLink(root); + + const inside = document.getElementById('inside'); + const outside = document.getElementById('outside'); + + expect(inside?.firstElementChild?.shadowRoot?.textContent).toContain( + 'inside.mp3', + ); + expect(outside?.firstElementChild?.shadowRoot).toBeNull(); + + cleanup(); + + expect(inside?.firstElementChild?.shadowRoot).toBeNull(); + }); + + test('wraps interlinks only inside the provided root', () => { + document.body.innerHTML = ` +
+ outside +
+ inside +
+
+ `; + + const root = document.getElementById('root'); + if (!root) { + throw new Error('missing root'); + } + + const cleanup = wrapInterlinksWithAnchor(root); + + expect(root.querySelector('a[data-print-link]')?.textContent).toBe( + 'inside', + ); + expect(document.querySelectorAll('a[data-print-link]')).toHaveLength(1); + + cleanup(); + + expect(document.querySelectorAll('a[data-print-link]')).toHaveLength(0); + }); +}); diff --git a/src/frontend/apps/impress/src/features/docs/doc-export/utils_print.ts b/src/frontend/apps/impress/src/features/docs/doc-export/utils_print.ts index cdbd30bf1..168869215 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-export/utils_print.ts +++ b/src/frontend/apps/impress/src/features/docs/doc-export/utils_print.ts @@ -175,7 +175,7 @@ function appendPrintOnlyStyles() { /** * Wraps media elements with links to their source URLs for printing. */ -function wrapMediaWithLink() { +export function wrapMediaWithLink(root: ParentNode = document) { const createdShadowWrapper: HTMLElement[] = []; const prependLink = ( @@ -222,7 +222,7 @@ function wrapMediaWithLink() { createdShadowWrapper.push(shadowWrapper); }; - document + root .querySelectorAll( '[data-content-type="pdf"], [data-content-type="file"], [data-content-type="audio"], [data-content-type="video"]', ) @@ -248,14 +248,14 @@ function wrapMediaWithLink() { * Wraps interlink inline content with anchor tags for printing, * so they appear as clickable links in the printed PDF. */ -function wrapInterlinksWithAnchor() { +export function wrapInterlinksWithAnchor(root: ParentNode = document) { const wrappedElements: Array<{ el: Element; anchor: HTMLAnchorElement; parent: Node; }> = []; - document + root .querySelectorAll('.--docs--interlinking-link-inline-content[data-href]') .forEach((el) => { const href = el.getAttribute('data-href');