fix: improve navigation handler in main.js to better manage external links
This commit is contained in:
2
cinny
2
cinny
Submodule cinny updated: 1f71fd7a51...09db721b7e
@@ -758,20 +758,28 @@ function createWindow() {
|
|||||||
return { action: 'allow' };
|
return { action: 'allow' };
|
||||||
});
|
});
|
||||||
|
|
||||||
// Navigation handler - open external links in browser
|
// Navigation handler - open external links in browser.
|
||||||
|
// Same-host navigations (e.g. Vite HMR full reload) must stay in-app;
|
||||||
|
// a hardcoded origin list breaks when the dev server port changes.
|
||||||
mainWindow.webContents.on('will-navigate', (event, url) => {
|
mainWindow.webContents.on('will-navigate', (event, url) => {
|
||||||
const allowedOrigins = [
|
if (url.startsWith('blob:') || url.startsWith('data:')) {
|
||||||
'http://localhost:8080',
|
return;
|
||||||
'http://localhost:44548',
|
}
|
||||||
'http://127.0.0.1:8080',
|
|
||||||
'http://127.0.0.1:44548'
|
|
||||||
];
|
|
||||||
|
|
||||||
const isAllowed = allowedOrigins.some(origin => url.startsWith(origin)) ||
|
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
||||||
url.startsWith('blob:') ||
|
return;
|
||||||
url.startsWith('data:');
|
}
|
||||||
|
|
||||||
if (!isAllowed && (url.startsWith('http://') || url.startsWith('https://'))) {
|
try {
|
||||||
|
const requestedHost = new URL(url).host;
|
||||||
|
const currentUrl = mainWindow.webContents.getURL();
|
||||||
|
const currentHost = currentUrl ? new URL(currentUrl).host : '';
|
||||||
|
|
||||||
|
if (requestedHost && requestedHost !== currentHost) {
|
||||||
|
event.preventDefault();
|
||||||
|
shell.openExternal(url);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
shell.openExternal(url);
|
shell.openExternal(url);
|
||||||
}
|
}
|
||||||
|
|||||||
104
scripts/migrate-icons.mjs
Normal file
104
scripts/migrate-icons.mjs
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import fs from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
const srcRoot = path.resolve(__dirname, '../cinny/src');
|
||||||
|
const iconsModule = path.resolve(srcRoot, 'app/components/icons');
|
||||||
|
|
||||||
|
const ICON_SYMBOLS = new Set(['Icon', 'Icons', 'IconName', 'IconSrc']);
|
||||||
|
|
||||||
|
function walk(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const fullPath = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
walk(fullPath, files);
|
||||||
|
} else if (/\.(tsx?)$/.test(entry.name)) {
|
||||||
|
files.push(fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIconsImportPath(filePath) {
|
||||||
|
const rel = path.relative(path.dirname(filePath), iconsModule).replace(/\\/g, '/');
|
||||||
|
return rel.startsWith('.') ? rel : `./${rel}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitFoldsImport(importClause) {
|
||||||
|
const match = importClause.match(/^\{([^}]+)\}(?:\s+as\s+\w+)?$/);
|
||||||
|
if (!match) return null;
|
||||||
|
|
||||||
|
const specifiers = match[1]
|
||||||
|
.split(',')
|
||||||
|
.map((part) => part.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
.map((part) => {
|
||||||
|
const [local, imported] = part.split(/\s+as\s+/).map((s) => s.trim());
|
||||||
|
return { local: local ?? imported, imported: imported ?? local };
|
||||||
|
});
|
||||||
|
|
||||||
|
const iconSpecs = specifiers.filter((s) => ICON_SYMBOLS.has(s.imported));
|
||||||
|
const foldsSpecs = specifiers.filter((s) => !ICON_SYMBOLS.has(s.imported));
|
||||||
|
|
||||||
|
if (iconSpecs.length === 0) return null;
|
||||||
|
|
||||||
|
return { iconSpecs, foldsSpecs };
|
||||||
|
}
|
||||||
|
|
||||||
|
function migrateFile(filePath) {
|
||||||
|
let content = fs.readFileSync(filePath, 'utf8');
|
||||||
|
const importRegex = /import\s+(\{[^}]+\})\s+from\s+['"]folds['"];?/g;
|
||||||
|
let changed = false;
|
||||||
|
const iconImports = new Map();
|
||||||
|
|
||||||
|
content = content.replace(importRegex, (fullMatch, importClause) => {
|
||||||
|
const split = splitFoldsImport(importClause);
|
||||||
|
if (!split) return fullMatch;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
for (const spec of split.iconSpecs) {
|
||||||
|
iconImports.set(spec.local, spec.imported);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (split.foldsSpecs.length === 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const foldsImport = split.foldsSpecs.map((s) => (s.local === s.imported ? s.local : `${s.imported} as ${s.local}`)).join(', ');
|
||||||
|
return `import { ${foldsImport} } from 'folds';`;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!changed) return false;
|
||||||
|
|
||||||
|
const iconsPath = getIconsImportPath(filePath);
|
||||||
|
const iconExportList = [...iconImports.entries()]
|
||||||
|
.map(([local, imported]) => (local === imported ? imported : `${imported} as ${local}`))
|
||||||
|
.join(', ');
|
||||||
|
|
||||||
|
const iconsImportLine = `import { ${iconExportList} } from '${iconsPath}';`;
|
||||||
|
|
||||||
|
const foldsImportMatch = content.match(/^import\s+\{[^}]+\}\s+from\s+['"]folds['"];?\s*$/m);
|
||||||
|
if (foldsImportMatch) {
|
||||||
|
const insertAt = content.indexOf(foldsImportMatch[0]) + foldsImportMatch[0].length;
|
||||||
|
content = `${content.slice(0, insertAt)}\n${iconsImportLine}${content.slice(insertAt)}`;
|
||||||
|
} else {
|
||||||
|
content = `${iconsImportLine}\n${content}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
content = content.replace(/\n{3,}/g, '\n\n');
|
||||||
|
fs.writeFileSync(filePath, content);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = walk(srcRoot);
|
||||||
|
let migrated = 0;
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
if (file.includes(`${path.sep}components${path.sep}icons${path.sep}`)) continue;
|
||||||
|
if (migrateFile(file)) {
|
||||||
|
migrated += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Migrated ${migrated} files.`);
|
||||||
Reference in New Issue
Block a user