Skip to content

Commit 3701fe5

Browse files
committed
🐛(frontend) interlinking are exported correctly in print mode
Interlinking are now exported correctly in print mode. The interlinking was not a link in print mode, but now it is.
1 parent 0f527a7 commit 3701fe5

6 files changed

Lines changed: 52 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to
1212

1313
### Fixed
1414

15+
- 🐛(frontend) interlinking are exported correctly in print mode #2269
1516
- 💬(frontend) add missing link in onboarding description #2233
1617
- 🐛(frontend) sanitize pasted and dropped content in document title #2210
1718
- 🐛(frontend) Emoji menu doesn't display above comment box #2229
@@ -20,7 +21,7 @@ and this project adheres to
2021

2122
### Security
2223

23-
- 🔒️(frontend) sanitize color during collaboration#2270
24+
- 🔒️(frontend) sanitize color during collaboration #2270
2425

2526

2627
## [v5.0.0] - 2026-04-08

src/frontend/apps/e2e/__tests__/app-impress/assets/base-content-test-pdf.txt

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Binary file not shown.
Binary file not shown.

src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/LinkSelected.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export const LinkSelected = ({
6666
<BoxButton
6767
as="span"
6868
className="--docs--interlinking-link-inline-content"
69+
data-href={href}
6970
onClick={handleClick}
7071
onAuxClick={handleAuxClick}
7172
draggable="false"

src/frontend/apps/impress/src/features/docs/doc-export/utils_print.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ const PRINT_ONLY_CONTENT_CSS = `
2828
[role="contentinfo"],
2929
div[data-is-empty-and-focused="true"],
3030
div[data-floating-ui-focusable],
31-
.collaboration-cursor-custom__base
31+
.collaboration-cursor-custom__base,
32+
.c__toast__container
3233
{
3334
display: none !important;
3435
}
@@ -243,6 +244,50 @@ function wrapMediaWithLink() {
243244
};
244245
}
245246

247+
/**
248+
* Wraps interlink inline content with anchor tags for printing,
249+
* so they appear as clickable links in the printed PDF.
250+
*/
251+
function wrapInterlinksWithAnchor() {
252+
const wrappedElements: Array<{
253+
el: Element;
254+
anchor: HTMLAnchorElement;
255+
parent: Node;
256+
}> = [];
257+
258+
document
259+
.querySelectorAll('.--docs--interlinking-link-inline-content[data-href]')
260+
.forEach((el) => {
261+
const href = el.getAttribute('data-href');
262+
if (!href || !isSafeUrl(href)) {
263+
return;
264+
}
265+
266+
const parent = el.parentNode;
267+
if (!parent) {
268+
return;
269+
}
270+
271+
const anchor = document.createElement('a');
272+
anchor.href = href;
273+
anchor.target = '_blank';
274+
anchor.rel = 'noopener noreferrer';
275+
anchor.setAttribute('data-print-link', 'true');
276+
277+
parent.insertBefore(anchor, el);
278+
anchor.appendChild(el);
279+
280+
wrappedElements.push({ el, anchor, parent });
281+
});
282+
283+
return () => {
284+
wrappedElements.forEach(({ el, anchor, parent }) => {
285+
parent.insertBefore(el, anchor);
286+
anchor.remove();
287+
});
288+
};
289+
}
290+
246291
export function printDocumentWithStyles() {
247292
if (typeof window === 'undefined') {
248293
return;
@@ -253,7 +298,9 @@ export function printDocumentWithStyles() {
253298
// Small delay to ensure styles are applied
254299
setTimeout(() => {
255300
const cleanupLinks = wrapMediaWithLink();
301+
const cleanupInterlinks = wrapInterlinksWithAnchor();
256302
const cleanup = () => {
303+
cleanupInterlinks();
257304
cleanupLinks();
258305
cleanupPrintStyles();
259306
};

0 commit comments

Comments
 (0)