diff --git a/renderer/customization.js b/renderer/customization.js
index eaf1c9d..5af1b36 100644
--- a/renderer/customization.js
+++ b/renderer/customization.js
@@ -478,10 +478,13 @@ class BrowserCustomizer {
applyThemeToPages() {
// This will be called to apply theme to home.html and other pages
- // We'll store the theme and let other pages load it
this.saveTheme();
-
- // If we have access to other windows/frames, apply there too
+
+ // Send theme update to host (for settings webview)
+ if (window.electronAPI && typeof window.electronAPI.sendToHost === 'function') {
+ window.electronAPI.sendToHost('theme-update', this.currentTheme);
+ }
+ // Fallback: send via postMessage (for iframe embedding)
try {
if (window.parent && window.parent !== window) {
window.parent.postMessage({
diff --git a/renderer/home.html b/renderer/home.html
index 35e505d..b7c6125 100644
--- a/renderer/home.html
+++ b/renderer/home.html
@@ -76,36 +76,39 @@
diff --git a/renderer/home.js b/renderer/home.js
index 9e64858..ef5c738 100644
--- a/renderer/home.js
+++ b/renderer/home.js
@@ -87,11 +87,16 @@ function renderBookmarks() {
// Navigate via IPC to host page
box.onclick = () => {
+ const url = b.url;
if (window.electronAPI && typeof window.electronAPI.sendToHost === 'function') {
- window.electronAPI.sendToHost('navigate', b.url);
+ window.electronAPI.sendToHost('navigate', url);
} else {
console.error('Unable to send navigation IPC to host');
}
+ // Fallback: post message to embedding page
+ if (window.parent && typeof window.parent.postMessage === 'function') {
+ window.parent.postMessage({ type: 'navigate', url }, '*');
+ }
};
box.appendChild(label);
@@ -205,7 +210,16 @@ searchBtn.addEventListener('click', () => {
const searchEngineUrl = searchEngines[selectedSearchEngine];
target = `${searchEngineUrl}${encodeURIComponent(input)}`;
}
- window.location.href = target;
+ // Always send navigation request to host
+ if (window.electronAPI && typeof window.electronAPI.sendToHost === 'function') {
+ window.electronAPI.sendToHost('navigate', target);
+ return;
+ }
+ // Fallback: post message to embedding page
+ if (window.parent && typeof window.parent.postMessage === 'function') {
+ window.parent.postMessage({ type: 'navigate', url: target }, '*');
+ return;
+ }
});
searchInput.addEventListener('keydown', e => {
diff --git a/renderer/script.js b/renderer/script.js
index f1f326b..076b352 100644
--- a/renderer/script.js
+++ b/renderer/script.js
@@ -75,7 +75,7 @@ async function saveBookmarks(newBookmarks) {
// Load bookmarks when the script starts
loadBookmarks();
-// Home tab will be created on DOMContentLoaded event
+// Initial home tab will be created on DOMContentLoaded
// Remove iframe-based navigation listener (using webview IPC now)
@@ -108,6 +108,8 @@ function createTab(inputUrl) {
};
tabs.push(tab);
setActiveTab(id);
+ // Render the tab bar so the new home tab appears
+ renderTabs();
return id;
}
@@ -116,16 +118,6 @@ function createTab(inputUrl) {
console.log('[DEBUG] createTab() resolvedUrl =', resolvedUrl);
const webview = document.createElement('webview');
-
- webview.id = `tab-${id}`;
- webview.src = resolvedUrl;
- webview.setAttribute('allowpopups', '');
- webview.setAttribute('partition', 'persist:default');
- webview.setAttribute('preload', '../preload.js');
- webview.classList.add('active');
-
- webview.addEventListener('did-fail-load', handleLoadFail(id));
- webview.addEventListener('page-title-updated', e => updateTabMetadata(id, 'title', e.title));
webview.addEventListener('page-favicon-updated', e => {
if (e.favicons.length > 0) updateTabMetadata(id, 'favicon', e.favicons[0]);
});
@@ -186,6 +178,14 @@ function createTab(inputUrl) {
createTab(e.url);
});
+ // After creating dynamic webview:
+ webview.addEventListener('ipc-message', e => {
+ if (e.channel === 'theme-update') {
+ const home = document.getElementById('home-webview');
+ if (home) home.send('theme-update', ...e.args);
+ }
+ });
+
webviewsEl.appendChild(webview);
tabs.push({
@@ -324,6 +324,14 @@ function convertHomeTabToWebview(tabId, inputUrl, resolvedUrl) {
createTab(e.url);
});
+ // After creating dynamic webview:
+ webview.addEventListener('ipc-message', e => {
+ if (e.channel === 'theme-update') {
+ const home = document.getElementById('home-webview');
+ if (home) home.send('theme-update', ...e.args);
+ }
+ });
+
// Add webview to DOM
webviewsEl.appendChild(webview);
@@ -486,7 +494,9 @@ function renderTabs() {
});
// add the “+” at the end
const plus = document.createElement('div');
- plus.className = 'tab'; plus.textContent = '+'; plus.onclick = () => createTab();
+ plus.className = 'tab';
+ plus.textContent = '+';
+ plus.onclick = () => createTab();
frag.appendChild(plus);
tabBarEl.innerHTML = ''; // clear once
@@ -533,10 +543,9 @@ function reload() {
}
}
-
+// Function to open the Settings page
function openSettings() {
- urlBox.value = 'browser://settings';
- navigate();
+ createTab('browser://settings');
}
// Toggle menu dropdown
@@ -562,16 +571,38 @@ window.addEventListener('DOMContentLoaded', () => {
}
createTab();
- // Listen for navigation IPC messages from home webview
- const homeWebview = document.getElementById('home-webview');
- if (homeWebview) {
- homeWebview.addEventListener('ipc-message', e => {
+ // Handle IPC messages from the static home webview (bookmarks navigation)
+ const staticHome = document.getElementById('home-webview');
+ if (staticHome) {
+ staticHome.addEventListener('ipc-message', (e) => {
if (e.channel === 'navigate' && e.args[0]) {
urlBox.value = e.args[0];
navigate();
}
});
}
+ // Listen for IPC messages from other webviews (e.g., settings)
+ webviewsEl.addEventListener('ipc-message', (e) => {
+ // Navigation messages from home or other pages
+ if (e.channel === 'navigate' && e.args[0]) {
+ urlBox.value = e.args[0];
+ navigate();
+ }
+ // Theme update from settings webview
+ if (e.channel === 'theme-update' && e.args[0]) {
+ const homeWebview = document.getElementById('home-webview');
+ if (homeWebview) {
+ homeWebview.send('theme-update', e.args[0]);
+ }
+ }
+ });
+ // Fallback: listen for postMessage navigations from home webview
+ window.addEventListener('message', (event) => {
+ if (event.data && event.data.type === 'navigate' && event.data.url) {
+ urlBox.value = event.data.url;
+ navigate();
+ }
+ });
// only now bind the reload button (guaranteed to exist)
const reloadBtn = document.getElementById('reload-btn');
reloadBtn.addEventListener('click', reload);
diff --git a/renderer/settings.js b/renderer/settings.js
index 5b4b870..31c7d43 100644
--- a/renderer/settings.js
+++ b/renderer/settings.js
@@ -1,4 +1,5 @@
// Use require('electron') since webviews have nodeIntegrationInSubFrames: true
+// In settings webview we use the same preload API as main windows
const { ipcRenderer } = require('electron');
const clearBtn = document.getElementById('clear-data-btn');
@@ -14,11 +15,10 @@ function showStatus(message) {
}
clearBtn.onclick = async () => {
- statusDiv.classList.remove('hidden'); // Show spinner immediately
- statusText.textContent = 'Clearing all browser data...'; // Update text while clearing
+ statusDiv.classList.remove('hidden');
+ statusText.textContent = 'Clearing all browser data...';
try {
- // Invoke the main process to clear cookies, local storage, and cache
const ok = await ipcRenderer.invoke('clear-browser-data');
showStatus(ok
? 'All browser data and bookmarks cleared!'
@@ -26,5 +26,11 @@ clearBtn.onclick = async () => {
} catch (error) {
console.error('Error clearing browser data:', error);
showStatus('An error occurred while clearing data.');
+ } finally {
+ // Send theme update to host after clearing
+ const currentTheme = window.browserCustomizer ? window.browserCustomizer.currentTheme : null;
+ if (currentTheme && window.electronAPI && typeof window.electronAPI.sendToHost === 'function') {
+ window.electronAPI.sendToHost('theme-update', currentTheme);
+ }
}
};
diff --git a/site-history.json b/site-history.json
index 7223fd2..53389b7 100644
--- a/site-history.json
+++ b/site-history.json
@@ -2,6 +2,11 @@
"https://www.youtube.com/",
"https://github.com/",
"file:///X:/Projects/Code/NebulaBrowser/renderer/index.html",
+ "https://youtube.com/",
+ "file:///X:/Projects/Code/NebulaBrowser/renderer/index.html",
+ "https://youtube.com/",
+ "file:///X:/Projects/Code/NebulaBrowser/renderer/index.html",
+ "file:///X:/Projects/Code/NebulaBrowser/renderer/index.html",
"file:///X:/Projects/Code/NebulaBrowser/renderer/index.html",
"file:///X:/Projects/Code/NebulaBrowser/renderer/index.html",
"file:///X:/Projects/Code/NebulaBrowser/renderer/index.html",