fix: 修复本地文件夹垃圾箱恢复聚焦

This commit is contained in:
lix-2026
2026-05-21 14:39:38 +08:00
parent b0fa1e53d8
commit 83ad32dd67
17 changed files with 680 additions and 39 deletions
@@ -100,6 +100,12 @@ function treeUrl(root, mode) {
return url.toString();
}
function treeUrlWithRestoreFocus(root, rowId) {
const url = new URL(treeUrl(root, "filetree"));
url.searchParams.set("restoreFocusRowId", rowId);
return url.toString();
}
/**
* 构建 trash 页 URL
*/
@@ -184,6 +190,24 @@ function checkFocusEvidence(page, rowId) {
}, rowId);
}
async function waitForFocusEvidence(page, rowId) {
const deadline = Date.now() + UI_TIMEOUT_MS;
let last = null;
while (Date.now() < deadline) {
last = await checkFocusEvidence(page, rowId);
const attrs = last?.attrs || {};
const hasFocusEvidence = last?.found && (
attrs["data-active"] === "true"
|| attrs["data-selected"] === "true"
|| attrs["data-focused"] === "true"
|| /\bis-active\b|\bis-selected\b|\bis-focused\b/.test(String(attrs.class || ""))
);
if (hasFocusEvidence) return last;
await page.waitForTimeout(250);
}
return last || checkFocusEvidence(page, rowId);
}
async function main() {
const root = fs.mkdtempSync(path.join(os.tmpdir(), `mnote-${TASK}-`));
const rootUri = fileUrl(root);
@@ -228,6 +252,7 @@ async function main() {
assetId,
steps: [],
focusAfterRestore: null,
restoreFocusDebug: {},
navEventsAfterRestore: [],
restoreNavFree: null,
fileReappearsInFiletree: null,
@@ -236,7 +261,7 @@ async function main() {
try {
// === 步骤1:登录并打开 filetree 页 ===
await quickLogin(page);
await page.goto(treeUrl(root, "filetree"), { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS });
await page.goto(treeUrlWithRestoreFocus(root, assetRowIdStr), { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS });
await waitForFileTreeRoot(page);
// 等待初始文件加载
await waitForFileTreeRow(page, "local:markdown:README.md");
@@ -279,6 +304,10 @@ async function main() {
const navAfterRestore = navigationEvents.length;
const restoreNavDelta = navAfterRestore - navBeforeRestore;
evidence.restoreFocusDebug.pendingAfterRestore = await page.evaluate(() => (
window.localStorage ? window.localStorage.getItem("mnote.pendingLocalFolderRestoreFiletreeRowId") : null
)).catch(() => null);
evidence.restoreFocusDebug.windowNameAfterRestore = await page.evaluate(() => window.name).catch(() => null);
evidence.restoreNavFree = { navBeforeRestore, navAfterRestore, delta: restoreNavDelta };
evidence.navEventsAfterRestore = navigationEvents.slice(navBeforeRestore);
@@ -314,8 +343,14 @@ async function main() {
// 回到 filetree 页 — 这一步本身是页面导航(用户主动操作)
const navBeforeFiletree = navigationEvents.length;
await page.goto(treeUrl(root, "filetree"), { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS });
const navAfterFiletreeLoad = navigationEvents.length;
await waitForFileTreeRoot(page);
evidence.restoreFocusDebug.filetreeNavDelta = navAfterFiletreeLoad - navBeforeFiletree;
evidence.restoreFocusDebug.filetreeNavEvents = navigationEvents.slice(navBeforeFiletree);
evidence.restoreFocusDebug.filetreeUrlAfterLoad = page.url();
evidence.restoreFocusDebug.localStorageKeysAfterFiletreeLoad = await page.evaluate(() => (
Object.keys(window.localStorage || {}).filter((key) => key.indexOf("mnote") >= 0)
)).catch(() => []);
// 等待轮询检测到变化后文件行重现(最长 1200ms polling + 180ms debounce
try {
await waitForFileTreeRow(page, assetRowIdStr);
@@ -341,8 +376,22 @@ async function main() {
});
// === 步骤9:检查 restore 后是否有 focus/reveal ===
const focusData = await checkFocusEvidence(page, assetRowIdStr);
const focusData = await waitForFocusEvidence(page, assetRowIdStr).catch(() => checkFocusEvidence(page, assetRowIdStr));
evidence.focusAfterRestore = focusData;
evidence.restoreFocusDebug.pendingAfterFiletreeLoad = await page.evaluate(() => (
window.localStorage ? window.localStorage.getItem("mnote.pendingLocalFolderRestoreFiletreeRowId") : null
)).catch(() => null);
evidence.restoreFocusDebug.windowNameAfterFiletreeLoad = await page.evaluate(() => window.name).catch(() => null);
evidence.restoreFocusDebug.markerAfterFiletreeLoad = await page.evaluate(() => (
document.documentElement.getAttribute("data-mnote-local-folder-restore-focused-row-id")
)).catch(() => null);
evidence.restoreFocusDebug.pendingMarkerAfterFiletreeLoad = await page.evaluate(() => (
document.documentElement.getAttribute("data-mnote-local-folder-restore-pending-row-id")
)).catch(() => null);
evidence.restoreFocusDebug.focusStatusAfterFiletreeLoad = await page.evaluate(() => (
document.documentElement.getAttribute("data-mnote-local-folder-restore-focus-status")
)).catch(() => null);
evidence.restoreFocusDebug.filetreeHtmlSnippet = await page.locator(`#sidebar-file-tree-root .tree-row[data-row-id="${assetRowIdStr}"]`).evaluate((row) => row.outerHTML).catch(() => null);
const hasFocusEvidence = focusData.found && (
focusData.attrs?.["data-active"] === "true"
@@ -362,7 +411,7 @@ async function main() {
: "restore 后有 focus 证据",
});
evidence.ok = true;
evidence.ok = hasFocusEvidence;
} catch (error) {
evidence.error = error instanceof Error ? error.stack || error.message : String(error);
// 尝试读取当前 filetree 文本以便诊断