From 20fecca8989f96b2b4bee0ce658645cf0cb9f44f Mon Sep 17 00:00:00 2001 From: Nystik <236107-Nystik@users.noreply.gitlab.com> Date: Fri, 13 Mar 2026 20:43:38 +0100 Subject: [PATCH] improve PDF export popup handling --- server/config.js | 4 +- shims/electron/ipc-renderer.js | 20 ++++-- shims/electron/remote/window.js | 107 +++++++++++++++++++++++++++++++- shims/loader.js | 32 ++++++++++ 4 files changed, 155 insertions(+), 8 deletions(-) diff --git a/server/config.js b/server/config.js index e729840..3dc16c4 100644 --- a/server/config.js +++ b/server/config.js @@ -63,12 +63,12 @@ module.exports = { }, obsidianAssetsPath: process.env.OBSIDIAN_ASSETS_PATH || - path.join(__dirname, "..", "investigation", "obsidian.asar.unpacked"), + path.join(__dirname, "..", "investigation", "obsidian_1.12.4_unpacked"), get obsidianVersion() { const assetsPath = process.env.OBSIDIAN_ASSETS_PATH || - path.join(__dirname, "..", "investigation", "obsidian.asar.unpacked"); + path.join(__dirname, "..", "investigation", "obsidian_1.12.4_unpacked"); try { const pkg = JSON.parse( fs.readFileSync(path.join(assetsPath, "package.json"), "utf-8"), diff --git a/shims/electron/ipc-renderer.js b/shims/electron/ipc-renderer.js index 05edc19..60a62d3 100644 --- a/shims/electron/ipc-renderer.js +++ b/shims/electron/ipc-renderer.js @@ -159,11 +159,21 @@ export const ipcRenderer = { } if (channel === "print-to-pdf") { - const [options] = args; - window.print(); - queueMicrotask(() => { - ipcRenderer._emit("print-to-pdf", { success: true }); - }); + const iframe = window.__popupIframe; + if (iframe) { + setTimeout(() => { + iframe.contentWindow.print(); + setTimeout(() => { + iframe.contentWindow.close(); + ipcRenderer._emit("print-to-pdf", { success: true }); + }, 500); + }, 200); + } else { + window.print(); + queueMicrotask(() => { + ipcRenderer._emit("print-to-pdf", { success: true }); + }); + } return; } }, diff --git a/shims/electron/remote/window.js b/shims/electron/remote/window.js index 8a2496a..78f8739 100644 --- a/shims/electron/remote/window.js +++ b/shims/electron/remote/window.js @@ -221,17 +221,122 @@ const currentWebContents = { set isSecured(v) {}, }; +// Popup tracking for PDF export etc. +let _popupWindow = null; +let _popupWebContents = null; + +export function registerPopupWindow() { + _popupWebContents = { + id: 2, + _zoomLevel: 0, + getZoomFactor() { + return 1; + }, + getZoomLevel() { + return 0; + }, + setZoomLevel() {}, + printToPDF(options) { + return Promise.resolve(Buffer.from([])); + }, + executeJavaScript(code) { + try { + return Promise.resolve(eval(code)); + } catch (e) { + return Promise.reject(e); + } + }, + on() { + return _popupWebContents; + }, + once() { + return _popupWebContents; + }, + removeListener() { + return _popupWebContents; + }, + isDestroyed() { + return false; + }, + isFocused() { + return false; + }, + }; + _popupWindow = { + id: 2, + webContents: _popupWebContents, + isDestroyed() { + return false; + }, + isFocused() { + return false; + }, + isVisible() { + return false; + }, + close() { + _popupWindow = null; + _popupWebContents = null; + }, + destroy() { + _popupWindow = null; + _popupWebContents = null; + }, + on() { + return _popupWindow; + }, + once() { + return _popupWindow; + }, + removeListener() { + return _popupWindow; + }, + }; + return _popupWindow; +} + +export function unregisterPopupWindow() { + _popupWindow = null; + _popupWebContents = null; +} + export const windowShim = { _current: () => currentWindow, getFocusedWindow() { return currentWindow; }, + + getAllWindows() { + const wins = [currentWindow]; + if (_popupWindow) wins.push(_popupWindow); + return wins; + }, + + fromId(id) { + if (id === currentWindow.id) return currentWindow; + if (_popupWindow && id === _popupWindow.id) return _popupWindow; + return null; + }, + + fromWebContents(wc) { + if (wc === currentWebContents) return currentWindow; + if (_popupWebContents && wc === _popupWebContents) return _popupWindow; + return null; + }, }; export const webContentsShim = { _current: () => currentWebContents, fromId(id) { - return id === currentWebContents.id ? currentWebContents : null; + if (id === currentWebContents.id) return currentWebContents; + if (_popupWebContents && id === _popupWebContents.id) + return _popupWebContents; + return null; + }, + getAllWebContents() { + const wcs = [currentWebContents]; + if (_popupWebContents) wcs.push(_popupWebContents); + return wcs; }, }; diff --git a/shims/loader.js b/shims/loader.js index 9ac1782..4f36d78 100644 --- a/shims/loader.js +++ b/shims/loader.js @@ -6,6 +6,10 @@ import { urlShim } from "./url.js"; import { cryptoShim } from "./crypto/index.js"; import { processShim } from "./process.js"; import { installRequestUrlShim } from "./request-url.js"; +import { + registerPopupWindow, + unregisterPopupWindow, +} from "./electron/remote/window.js"; import * as childProcessShim from "./node/child_process.js"; import * as eventsShim from "./node/events.js"; import * as osShim from "./node/os.js"; @@ -118,6 +122,34 @@ window.close = function () { console.log("[ignis] window.close() blocked"); }; +window.__popupIframe = null; +const _originalOpen = window.open; +window.open = function (url, target, features) { + if (url === "about:blank" || (features && features.includes("popup"))) { + console.log("[ignis] intercepted popup:", url, features); + registerPopupWindow(); + const iframe = document.createElement("iframe"); + iframe.style.cssText = + "position:fixed;left:-9999px;width:0;height:0;border:none;"; + document.body.appendChild(iframe); + window.__popupIframe = iframe; + const iframeWin = iframe.contentWindow; + iframeWin.require = window.require; + iframeWin.module = window.module; + iframeWin.Buffer = window.Buffer; + iframeWin.process = window.process; + iframeWin.global = iframeWin; + iframeWin.globalEnhance = window.globalEnhance; + iframeWin.close = function () { + unregisterPopupWindow(); + iframe.remove(); + window.__popupIframe = null; + }; + return iframeWin; + } + return _originalOpen.call(window, url, target, features); +}; + window.addEventListener( "contextmenu", (e) => {