Resolve CSS imports in window bootstrap stage

pull/158/head
Matthew_Cash 7 months ago
parent 403878f068
commit 753dad3b5b
No known key found for this signature in database
GPG Key ID: 7449B33FA8E4C190

63
src/bootstrap.js vendored

@ -1,6 +1,9 @@
const { app, session } = require('electron');
const { readFileSync } = require('fs');
const { join } = require('path');
const { readFile } = require('fs/promises');
const { join, dirname } = require('path');
const http = require('http');
const https = require('https');
if (!settings.get('enableHardwareAcceleration', true)) app.disableHardwareAcceleration();
process.env.PULSE_LATENCY_MSEC = process.env.PULSE_LATENCY_MSEC ?? 30;
@ -25,13 +28,67 @@ const updater = require('./updater/updater');
const moduleUpdater = require('./updater/moduleUpdater');
const autoStart = require('./autoStart');
const fetchText = protocol => url => new Promise((resolve, reject) => {
protocol.get(url, res => {
if (res.statusCode !== 200) {
return void reject(new Error(`CSS import failed, code ${res.statusCode}`));
}
let data = '';
res.on('data', chunk => data += chunk);
res.once('end', () => resolve(data));
}).once('error', reject);
});
const httpFetchers = {
'http:': fetchText(http),
'https:': fetchText(https)
};
const importRegex = /@import\s+(?:url\()?\s*['"](.+?)['"]\s*(?:\))?\s*;/g;
const resolveImports = async (cssString, prevImport) => {
const resolvedCss = await Promise.all(
cssString.match(importRegex)?.map(async cssImport => {
// Extract the URL from the import statement
const importString = cssImport.match(/['"](.+?)['"]/)[1];
// Try to parse the import string as a complete URL. If it fails, prepend the previous path and try again
let url;
try {
url = new URL(importString);
} catch {
url = new URL(join(prevImport, importString));
}
let importedCss, fetcher;
if (url.protocol === 'file:') {
importedCss = (await readFile(url)).toString();
} else if (fetcher = httpFetchers[url.protocol]) {
importedCss = await fetcher(url).catch(() => `/* Import failed for: ${importString} */`);
} else {
throw new Error(`Cannot handle protocol ${url.protocol} for url: ${importString}!`)
}
return resolveImports(importedCss, dirname(importString));
}) ?? []
);
cssString.match(importRegex)?.forEach((importStatement, index) => {
cssString = cssString.replace(importStatement, resolvedCss[index]);
});
return cssString;
};
let desktopCore;
const startCore = () => {
const startCore = async () => {
if (oaConfig.js || oaConfig.css) session.defaultSession.webRequest.onHeadersReceived((d, cb) => {
delete d.responseHeaders['content-security-policy'];
cb(d);
});
const css = await resolveImports(oaConfig.css);
app.on('browser-window-created', (e, bw) => { // Main window injection
bw.webContents.on('dom-ready', () => {
if (!bw.resizable) return; // Main window only
@ -43,7 +100,7 @@ const startCore = () => {
.replaceAll('<hash>', hash).replaceAll('<channel>', channel)
.replaceAll('<notrack>', oaConfig.noTrack !== false)
.replaceAll('<domopt>', oaConfig.domOptimizer !== false)
.replace('<css>', (oaConfig.css ?? '').replaceAll('\\', '\\\\').replaceAll('`', '\\`')));
.replace('<css>', css.replaceAll('\\', '\\\\').replaceAll('`', '\\`')));
if (oaConfig.js) bw.webContents.executeJavaScript(oaConfig.js);
});

Loading…
Cancel
Save