fix local markdown attachment regressions

This commit is contained in:
lix-2026
2026-05-29 11:13:05 +08:00
parent 1109e3c0d8
commit cbe789e034
63 changed files with 3249 additions and 1502 deletions
+55 -12
View File
@@ -24,6 +24,15 @@ const SIDEBAR_TREE_JS: &str = r##"
"##;
fn browser_runtime_src(asset: &str) -> String {
let base = format!("/api/mnote-browser-runtime/{asset}");
if let Some(cache_buster) = crate::routes::dev_hot::dev_hot_cache_buster() {
format!("{base}?devHot={cache_buster}")
} else {
base
}
}
/// MNOTE Wolai 风格页面布局
///
/// 包含左侧栏 + 内容区的双栏布局。
@@ -152,17 +161,17 @@ pub fn PageLayout(
<div hidden data-testid="mnote-admin-access-policy-template-admin" inner_html={admin_access_policy_template}></div>
<div hidden data-testid="mnote-admin-access-policy-template-user" inner_html={user_access_policy_template}></div>
<script inner_html={crate::ssr::pages::admin::ADMIN_POLICY_SCRIPT.to_string()}></script>
<script type="module" src="/api/mnote-browser-runtime/resource-open-runtime.js"></script>
<script type="module" src="/api/mnote-browser-runtime/local-upload-runtime.js"></script>
<script type="module" src="/api/mnote-browser-runtime/filetree-runtime.js"></script>
<script type="module" src="/api/mnote-browser-runtime/filetree-selection-runtime.js"></script>
<script type="module" src="/api/mnote-browser-runtime/filetree-context-menu-runtime.js"></script>
<script type="module" src="/api/mnote-browser-runtime/filetree-dnd-runtime.js"></script>
<script type="module" src="/api/mnote-browser-runtime/filetree-keyboard-runtime.js"></script>
<script type="module" src="/api/mnote-browser-runtime/sidebar-shell-runtime.js"></script>
<script type="module" src="/api/mnote-browser-runtime/sidebar-tree-runtime.js"></script>
<script type="module" src={browser_runtime_src("resource-open-runtime.js")}></script>
<script type="module" src={browser_runtime_src("local-upload-runtime.js")}></script>
<script type="module" src={browser_runtime_src("filetree-runtime.js")}></script>
<script type="module" src={browser_runtime_src("filetree-selection-runtime.js")}></script>
<script type="module" src={browser_runtime_src("filetree-context-menu-runtime.js")}></script>
<script type="module" src={browser_runtime_src("filetree-dnd-runtime.js")}></script>
<script type="module" src={browser_runtime_src("filetree-keyboard-runtime.js")}></script>
<script type="module" src={browser_runtime_src("sidebar-shell-runtime.js")}></script>
<script type="module" src={browser_runtime_src("sidebar-tree-runtime.js")}></script>
<script inner_html={SIDEBAR_TREE_JS.to_string()}></script>
<script type="module" src="/api/mnote-browser-runtime/tree-live-controller.js"></script>
<script type="module" src={browser_runtime_src("tree-live-controller.js")}></script>
</aside>
<div class="mnote-sidebar-resizer" data-mnote-sidebar-resizer="true" role="separator" aria-orientation="vertical" aria-label="调整侧栏宽度"></div>
<div class="mnote-main">
@@ -385,6 +394,29 @@ mod tests {
assert!(html.contains(r#"data-mnote-shortcut-kind="page""#));
}
#[test]
fn page_layout_adds_dev_hot_cache_buster_to_browser_runtime_scripts() {
let _guard = crate::test_support::hermes_env_lock()
.lock()
.expect("env lock");
std::env::set_var("MNOTE_WEB_DEV_HOT_RELOAD", "1");
let html = crate::ssr::render_view(leptos::view! {
<super::PageLayout current_nav="documents" topbar_title={"个人".to_string()}>
<main>"正文"</main>
</super::PageLayout>
});
std::env::remove_var("MNOTE_WEB_DEV_HOT_RELOAD");
assert!(
html.contains("/api/mnote-browser-runtime/tree-live-controller.js?devHot="),
"dev:hot 下 tree live controller URL 必须带 cache buster,避免浏览器继续执行旧 WS/SSE 逻辑"
);
assert!(
html.contains("/api/mnote-browser-runtime/sidebar-tree-runtime.js?devHot="),
"dev:hot 下 sidebar runtime URL 也必须带 cache buster"
);
}
#[test]
fn sidebar_runtime_supports_shortcuts_and_scoped_filetree() {
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("/api/sidebar/shortcuts"));
@@ -587,12 +619,11 @@ mod tests {
}
#[test]
fn sidebar_tree_runtime_polls_local_folder_without_browser_reload() {
fn sidebar_tree_runtime_uses_local_folder_events_without_browser_reload() {
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("startLocalFolderSidebarWatch"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("refreshLocalFolderSidebarSnapshot"));
assert!(SIDEBAR_WORKSPACE_RUNTIME_JS.contains("function currentWorkspaceId()"));
assert!(SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS.contains("var rootUri = currentRootUri();"));
assert!(SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS.contains("/api/tree/local-folder-watch"));
assert!(SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS.contains("/api/tree/projections/sidebar"));
assert!(SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS.contains("/api/tree/projections/file"));
assert!(SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS
@@ -604,6 +635,18 @@ mod tests {
assert!(
SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS.contains("data-mnote-local-folder-watch-applied")
);
assert!(
SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS.contains("data-mnote-local-folder-watch-disabled")
);
assert!(
TREE_LIVE_CONTROLLER_JS.contains("body.getAttribute('data-mnote-source-kind')"),
"根入口由 SSR body 暴露 local_folder 时,tree live 不能误走 retired Convex WS/SSE"
);
assert!(
TREE_LIVE_CONTROLLER_JS.contains("bootstrap.transport === 'local-folder-events'"),
"本地文件夹 bootstrap transport 应直接选择 /api/local-folder/events"
);
assert!(!SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS.contains("/api/tree/local-folder-watch"));
assert!(!SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS
.contains("fetch(window.location.href, { headers: { accept: 'text/html' } })"));
assert!(!SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS