BetterCurseForge/bettercf/core/preload.js

80 lines
2.7 KiB
JavaScript
Raw Permalink Normal View History

// BetterCurseForge — Preload Script
// ==================================
// Injected into every BrowserWindow's preload phase.
// Chain-loads the original CurseForge preload, then injects the renderer runtime.
// Since contextIsolation is false, we have direct access to the renderer's JS context.
const { ipcRenderer } = require('electron');
const path = require('path');
const fs = require('fs');
// ── Find and load original preload ────────────────────────────
const args = process.argv;
let originalPreloadPath = null;
for (const arg of args) {
if (arg.startsWith('--bcf-original-preload=')) {
originalPreloadPath = arg.split('=')[1];
break;
}
}
if (originalPreloadPath && fs.existsSync(originalPreloadPath)) {
try {
require(originalPreloadPath);
console.log('[BetterCF] Original preload loaded:', originalPreloadPath);
} catch (err) {
console.error('[BetterCF] Failed to load original preload:', err);
}
}
// ── Inject Renderer Runtime ───────────────────────────────────
const bcfInjected = args.some(a => a === '--bcf-injected=true');
if (bcfInjected) {
// Wait for DOM to be ready, then inject our renderer
const injectRenderer = () => {
const bcfCorePath = path.join(__dirname, 'bettercf', 'core');
const rendererPath = path.join(bcfCorePath, 'renderer.js');
if (!fs.existsSync(rendererPath)) {
console.warn('[BetterCF] renderer.js not found at', rendererPath);
return;
}
// Read renderer code and inject via inline script
// CSP allows 'unsafe-inline' so this works
const rendererCode = fs.readFileSync(rendererPath, 'utf-8');
// Create the BetterCurseForge API on the window object
// This needs to bridge to the main process via IPC
const apiSetup = `
window.__BCF_IPC__ = {
invoke: (...args) => require('electron').ipcRenderer.invoke(...args),
};
window.__BCF_PRELOAD_PATH__ = ${JSON.stringify(bcfCorePath)};
`;
// Inject API setup immediately
const apiScript = document.createElement('script');
apiScript.textContent = apiSetup;
(document.head || document.documentElement).appendChild(apiScript);
// Inject renderer after a short delay to ensure DOM is ready
const rendererScript = document.createElement('script');
rendererScript.type = 'module';
rendererScript.textContent = rendererCode;
(document.head || document.documentElement).appendChild(rendererScript);
console.log('[BetterCF] Renderer injected.');
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', injectRenderer);
} else {
injectRenderer();
}
}