Keep browser sign-ins across tabs and restarts (#2089)

* feat(desktop): share persistent browser data across tabs

Keep browser sign-ins and site storage across tabs and app restarts, with a Settings action to clear the shared profile.

* fix(settings): prevent duplicate browser data clears

* fix(desktop): complete browser data cleanup

Clear legacy per-tab profiles after upgrades and localize the browser data settings in every supported language.

* fix(desktop): close browser profile cleanup races
This commit is contained in:
Mohamed Boudra
2026-07-16 00:40:24 +08:00
committed by GitHub
parent 9423b091b9
commit 328361667f
32 changed files with 1413 additions and 148 deletions
+50 -5
View File
@@ -52,29 +52,70 @@
? Math.max(0, requestedWebviewCount)
: 2;
const webviews = [];
const profileAttachPromises = [];
const activeTokens = new Set();
let nextTokenId = 0;
let permanentParkingState = params.get("permanentParkingState") || "";
function appendHarnessWebview(sourceUrl) {
function createHarnessWebview({ sourceUrl, browserId, partition }) {
const index = webviews.length;
const webview = document.createElement("webview");
webview.id = `target-webview-${index + 1}`;
webview.className = "capture-harness-webview";
webview.setAttribute("data-paseo-browser-id", `capture-harness-${index + 1}`);
webview.setAttribute("partition", `persist:paseo-capture-harness-${index + 1}`);
webview.setAttribute("data-paseo-browser-id", browserId);
webview.setAttribute("partition", partition);
webview.setAttribute("allowpopups", "true");
webview.setAttribute("spellcheck", "false");
webview.setAttribute("autosize", "on");
webview.src = sourceUrl;
applyStackedWebviewStyle(webview);
return webview;
}
function appendHarnessWebview(sourceUrl) {
const index = webviews.length;
const webview = createHarnessWebview({
sourceUrl,
browserId: `capture-harness-${index + 1}`,
partition: `persist:paseo-capture-harness-${index + 1}`,
});
host.appendChild(webview);
webviews.push(webview);
return index;
}
for (let index = 0; index < webviewCount; index += 1) {
appendHarnessWebview(params.get("targetUrl") || "bright.html");
function appendProfileHarnessWebview({ browserId, partition, sourceUrl }) {
const webview = createHarnessWebview({ browserId, partition, sourceUrl });
const attached = new Promise((resolve) => {
webview.addEventListener(
"did-attach",
() => resolve({ browserId, webContentsId: webview.getWebContentsId() }),
{ once: true },
);
});
host.appendChild(webview);
webviews.push(webview);
profileAttachPromises.push(attached);
return attached;
}
const profilePartition = params.get("profilePartition");
const profileBrowserIds = (params.get("profileBrowserIds") || "").split(",").filter(Boolean);
let profileAttachSequence = Promise.resolve();
if (profilePartition && profileBrowserIds.length > 0) {
profileAttachSequence = (async () => {
for (const browserId of profileBrowserIds) {
await appendProfileHarnessWebview({
browserId,
partition: profilePartition,
sourceUrl: params.get("targetUrl") || "bright.html",
});
}
})();
} else {
for (let index = 0; index < webviewCount; index += 1) {
appendHarnessWebview(params.get("targetUrl") || "bright.html");
}
}
function applyHostParking() {
@@ -318,6 +359,10 @@
addWebview(sourceUrl) {
return appendHarnessWebview(sourceUrl || params.get("targetUrl") || "bright.html");
},
async profileIdentities() {
await profileAttachSequence;
return await Promise.all(profileAttachPromises);
},
addPermanentWebview(sourceUrl, stateName) {
const index = appendHarnessWebview(sourceUrl || params.get("targetUrl") || "bright.html");
applyPermanentParkingState(stateName || permanentParkingState);