feat(desktop/print): integrate with offscreen rendering

This commit is contained in:
Elian Doran
2025-10-19 19:56:26 +03:00
parent 61bdcf2a53
commit fb0c3be7fa
2 changed files with 48 additions and 12 deletions

View File

@@ -28,7 +28,7 @@ import ContentWidgetTypeWidget from "./type_widgets/content_widget.js";
import AttachmentListTypeWidget from "./type_widgets/attachment_list.js";
import AttachmentDetailTypeWidget from "./type_widgets/attachment_detail.js";
import MindMapWidget from "./type_widgets/mind_map.js";
import utils from "../services/utils.js";
import utils, { isElectron } from "../services/utils.js";
import type { NoteType } from "../entities/fnote.js";
import type TypeWidget from "./type_widgets/type_widget.js";
import { MermaidTypeWidget } from "./type_widgets/mermaid.js";
@@ -303,18 +303,26 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
message: t("note_detail.printing"),
id: "printing"
});
const iframe = document.createElement('iframe');
iframe.src = `?print#${this.notePath}`;
iframe.className = "print-iframe";
document.body.appendChild(iframe);
iframe.onload = () => {
if (!iframe.contentWindow) return;
iframe.contentWindow.addEventListener("note-ready", () => {
toast.closePersistent("printing");
iframe.contentWindow?.print();
document.body.removeChild(iframe);
if (isElectron()) {
const { ipcRenderer } = utils.dynamicRequire("electron");
ipcRenderer.send("print-note", {
notePath: this.notePath
});
};
} else {
const iframe = document.createElement('iframe');
iframe.src = `?print#${this.notePath}`;
iframe.className = "print-iframe";
document.body.appendChild(iframe);
iframe.onload = () => {
if (!iframe.contentWindow) return;
iframe.contentWindow.addEventListener("note-ready", () => {
toast.closePersistent("printing");
iframe.contentWindow?.print();
document.body.removeChild(iframe);
});
};
}
}
async exportAsPdfEvent() {

View File

@@ -12,6 +12,8 @@ import type { App, BrowserWindowConstructorOptions, BrowserWindow, WebContents }
import { formatDownloadTitle, isDev, isMac, isWindows } from "./utils.js";
import { t } from "i18next";
import { RESOURCE_DIR } from "./resource_dir.js";
import { PerformanceObserverEntryList } from "perf_hooks";
import options from "./options.js";
// Prevent the window being garbage collected
let mainWindow: BrowserWindow | null;
@@ -67,12 +69,38 @@ electron.ipcMain.on("create-extra-window", (event, arg) => {
createExtraWindow(arg.extraWindowHash);
});
interface PrintOpts {
notePath: string;
}
interface ExportAsPdfOpts {
title: string;
landscape: boolean;
pageSize: "A0" | "A1" | "A2" | "A3" | "A4" | "A5" | "A6" | "Legal" | "Letter" | "Tabloid" | "Ledger";
}
electron.ipcMain.on("print-note", async (e, { notePath }: PrintOpts) => {
const browserWindow = new electron.BrowserWindow({
show: false,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
offscreen: true,
session: e.sender.session
},
});
await browserWindow.loadURL(`http://127.0.0.1:${port}/?print#${notePath}`);
await browserWindow.webContents.executeJavaScript(`
new Promise(resolve => {
if (window._noteReady) return resolve();
window.addEventListener("note-ready", () => resolve());
});
`);
browserWindow.webContents.print({}, () => {
browserWindow.destroy();
});
});
electron.ipcMain.on("export-as-pdf", async (e, opts: ExportAsPdfOpts) => {
const browserWindow = electron.BrowserWindow.fromWebContents(e.sender);
if (!browserWindow) {