refactor: split sidebar filetree command runtime
This commit is contained in:
+1
-1
@@ -166,7 +166,7 @@ cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib routes::web_shell
|
||||
- [x] C1. `sidebar-workspace-runtime.js`:workspace source switch、sidebar tabs、collapse/resize 状态。
|
||||
- [ ] C2. `sidebar-page-tree-runtime.js`:page tree row selection、rename title patch、breadcrumb/title sync。
|
||||
- [x] C3. `sidebar-filetree-open-runtime.js`:local markdown / resource open target、active resource tab dispatch。
|
||||
- [ ] C4. `sidebar-filetree-command-runtime.js`:create/rename/delete/copy/move/trash/restore/purge command payload。
|
||||
- [x] C4. `sidebar-filetree-command-runtime.js`:create/rename/delete/copy/move/trash/restore/purge command payload。
|
||||
- [ ] C5. `sidebar-filetree-upload-runtime.js`:local upload target plan、drop/paste preflight、readonly guard。
|
||||
- [x] C6. `sidebar-attachment-open-runtime.js`:OnlyOffice/PDF/code/image open mode guard。
|
||||
- [x] C7. `sidebar-tree-live-apply-runtime.js`:WS/SSE snapshot/delta/resync DOM apply。
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -138,6 +138,10 @@ pub fn build_router(state: AppState) -> Router {
|
||||
"/api/mnote-browser-runtime/sidebar-filetree-open-runtime.js",
|
||||
get(web_shell::sidebar_filetree_open_runtime_asset),
|
||||
)
|
||||
.route(
|
||||
"/api/mnote-browser-runtime/sidebar-filetree-command-runtime.js",
|
||||
get(web_shell::sidebar_filetree_command_runtime_asset),
|
||||
)
|
||||
.route(
|
||||
"/api/mnote-browser-runtime/sidebar-attachment-open-runtime.js",
|
||||
get(web_shell::sidebar_attachment_open_runtime_asset),
|
||||
@@ -598,6 +602,7 @@ mod tests {
|
||||
"/api/mnote-browser-runtime/sidebar-workspace-runtime.js",
|
||||
"/api/mnote-browser-runtime/sidebar-tree-live-apply-runtime.js",
|
||||
"/api/mnote-browser-runtime/sidebar-filetree-open-runtime.js",
|
||||
"/api/mnote-browser-runtime/sidebar-filetree-command-runtime.js",
|
||||
"/api/mnote-browser-runtime/sidebar-attachment-open-runtime.js",
|
||||
"/api/mnote-browser-runtime/sidebar-tree-runtime.js",
|
||||
"/api/mnote-browser-runtime/tree-live-controller.js",
|
||||
|
||||
@@ -784,6 +784,20 @@ pub async fn sidebar_filetree_open_runtime_asset() -> Response {
|
||||
.unwrap_or_else(|_| Response::new(Body::empty()))
|
||||
}
|
||||
|
||||
pub async fn sidebar_filetree_command_runtime_asset() -> Response {
|
||||
const JS: &str = include_str!("../../browser/sidebar-filetree-command-runtime.js");
|
||||
Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header(
|
||||
header::CONTENT_TYPE,
|
||||
"application/javascript; charset=utf-8",
|
||||
)
|
||||
.header(header::CACHE_CONTROL, "no-store")
|
||||
.header(HEADER_MNOTE_WEB_OWNER, "mnote-web")
|
||||
.body(Body::from(JS))
|
||||
.unwrap_or_else(|_| Response::new(Body::empty()))
|
||||
}
|
||||
|
||||
pub async fn sidebar_attachment_open_runtime_asset() -> Response {
|
||||
const JS: &str = include_str!("../../browser/sidebar-attachment-open-runtime.js");
|
||||
Response::builder()
|
||||
|
||||
@@ -203,6 +203,8 @@ mod tests {
|
||||
include_str!("../../../browser/sidebar-tree-live-apply-runtime.js");
|
||||
const SIDEBAR_FILETREE_OPEN_RUNTIME_JS: &str =
|
||||
include_str!("../../../browser/sidebar-filetree-open-runtime.js");
|
||||
const SIDEBAR_FILETREE_COMMAND_RUNTIME_JS: &str =
|
||||
include_str!("../../../browser/sidebar-filetree-command-runtime.js");
|
||||
const SIDEBAR_ATTACHMENT_OPEN_RUNTIME_JS: &str =
|
||||
include_str!("../../../browser/sidebar-attachment-open-runtime.js");
|
||||
const SIDEBAR_SHELL_RUNTIME_JS: &str =
|
||||
@@ -313,7 +315,7 @@ mod tests {
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("tree.filetree.internal-drop"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("tree.filetree.external-drop"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("beginFileTreeInlineRename"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("tree-rename-input"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("tree-rename-input"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("sidebarFileTreeClipboard"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("pasteSidebarFileTreeClipboard"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("MNOTE_RECENT_LOCAL_ROOTS_KEY_PREFIX"));
|
||||
@@ -578,16 +580,18 @@ mod tests {
|
||||
fn sidebar_filetree_runtime_helpers_are_externalized_with_inline_fallback() {
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function fileTreeRuntimeFunction"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("window.__mnoteFileTreeRuntime"));
|
||||
assert!(
|
||||
SIDEBAR_TREE_RUNTIME_JS.contains("fileTreeRuntimeFunction('fileTreeRowDocumentId')")
|
||||
);
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("fileTreeRuntimeFunction('fileTreeRowAssetId')"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("fileTreeRuntimeFunction('fileTreeRowDocumentId')"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("fileTreeRuntimeFunction('fileTreeRowAssetId')"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("fileTreeRuntimeFunction('fileTreeRowLocalRelativePath')"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("fileTreeRuntimeFunction('fileTreeAssetDownloadDetail')"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("fileTreeRuntimeFunction('fileTreeRowsByRowIds')"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("fileTreeRuntimeFunction('fileTreeChildCount')"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("fileTreeRuntimeFunction('fileTreeRowsByRowIds')"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("fileTreeRuntimeFunction('fileTreeChildCount')"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("fileTreeRuntimeFunction('revealFileTreeRow')"));
|
||||
assert!(
|
||||
SIDEBAR_TREE_RUNTIME_JS.contains("fileTreeRuntimeFunction('revealFileTreeAssetRow')")
|
||||
@@ -631,7 +635,8 @@ mod tests {
|
||||
.contains("fileTreeRuntimeFunction('applyLocalFolderSidebarSnapshot')"));
|
||||
assert!(SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS
|
||||
.contains("fileTreeRuntimeFunction('markLocalFolderWatchApplied')"));
|
||||
let document_id_body = js_function_body(SIDEBAR_TREE_RUNTIME_JS, "fileTreeRowDocumentId");
|
||||
let document_id_body =
|
||||
js_function_body(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS, "fileTreeRowDocumentId");
|
||||
assert!(
|
||||
document_id_body.contains("data-document-id")
|
||||
&& document_id_body.contains("data-doc-id"),
|
||||
@@ -759,24 +764,29 @@ mod tests {
|
||||
fn sidebar_filetree_selection_runtime_helpers_are_externalized_with_inline_fallback() {
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function fileTreeSelectionRuntimeFunction"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("window.__mnoteFileTreeSelectionRuntime"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("fileTreeSelectionRuntimeFunction('visibleFileTreeRows')"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("fileTreeSelectionRuntimeFunction('syncSidebarFileTreeSelection')"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("fileTreeSelectionRuntimeFunction('selectSidebarFileTreeRow')"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("fileTreeSelectionRuntimeFunction('selectedSidebarFileTreeRowIdsForDrag')"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("fileTreeSelectionRuntimeFunction('selectedSidebarFileTreeRows')"));
|
||||
let select_body = js_function_body(SIDEBAR_TREE_RUNTIME_JS, "selectSidebarFileTreeRow");
|
||||
let select_body = js_function_body(
|
||||
SIDEBAR_FILETREE_COMMAND_RUNTIME_JS,
|
||||
"selectSidebarFileTreeRow",
|
||||
);
|
||||
assert!(
|
||||
select_body.contains("shiftKey && sidebarFileTreeSelection.anchorRowId")
|
||||
&& select_body.contains("ctrlKey"),
|
||||
"inline fallback 必须保留 shift range 与 ctrl/meta toggle"
|
||||
);
|
||||
let select_document_body =
|
||||
js_function_body(SIDEBAR_TREE_RUNTIME_JS, "selectSidebarFileTreeDocument");
|
||||
let select_document_body = js_function_body(
|
||||
SIDEBAR_FILETREE_COMMAND_RUNTIME_JS,
|
||||
"selectSidebarFileTreeDocument",
|
||||
);
|
||||
assert!(
|
||||
select_document_body
|
||||
.contains("selectSidebarFileTreeRow(row, { ctrlKey: false, metaKey: false, shiftKey: false })"),
|
||||
@@ -800,8 +810,10 @@ mod tests {
|
||||
#[test]
|
||||
fn sidebar_tree_runtime_focuses_restored_local_folder_row() {
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("applyPendingLocalFolderRestoreFocusOnce"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("mnote.pendingLocalFolderRestoreFiletreeRowId"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("data-mnote-local-folder-restore-focused-row-id"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("mnote.pendingLocalFolderRestoreFiletreeRowId"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("data-mnote-local-folder-restore-focused-row-id"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -885,29 +897,29 @@ mod tests {
|
||||
#[test]
|
||||
fn sidebar_tree_runtime_renders_context_menu_and_scoped_title_updates() {
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("openTreeContextMenu"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("mnote-tree-context-menu"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("复制访问链接"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("删除到垃圾桶"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("mnote-tree-context-menu"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("复制访问链接"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("删除到垃圾桶"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function createFileTreeFolder"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("action: 'create_folder'"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function fileTreeMenuTargetParentId"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("if (action === 'new-folder')"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("fileTreeCopyPath(detail, trigger)"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("function fileTreeMenuTargetParentId"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("if (action === 'new-folder')"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("fileTreeCopyPath(detail, trigger)"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("if (detail.contextKind === 'filetree' && action === 'download')"));
|
||||
assert!(
|
||||
SIDEBAR_TREE_RUNTIME_JS.contains("downloadSelectedFileTreeAssetRows(detail, trigger)")
|
||||
);
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function selectedSidebarFileTreeRowsForDownload"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("downloadSelectedFileTreeAssetRows(detail, trigger)"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("function selectedSidebarFileTreeRowsForDownload"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("function selectedSidebarFileTreeAssetRowsForDownload"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("data-local-relative-path"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("data-local-relative-path"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("targetRelativePath"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains(
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains(
|
||||
"recordFileTreeAction(downloads.length > 1 ? 'bulk-download' : 'download', primary)"
|
||||
));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("data-mnote-filetree-download-count"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function triggerBrowserDownload"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("data-mnote-filetree-download-count"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("function triggerBrowserDownload"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("openEditorAttachmentMenu(editorAttachmentLink, editorAttachmentLink, { x: event.clientX, y: event.clientY });"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
.contains("var localFilePath = localFilePathFromAssetId(assetId);"));
|
||||
@@ -974,36 +986,39 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn sidebar_tree_delete_to_trash_dispatches_archive_not_purge() {
|
||||
let delete_trash_start = SIDEBAR_TREE_RUNTIME_JS
|
||||
let delete_trash_start = SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.find("if (action === 'delete-trash'")
|
||||
.expect("delete-trash branch");
|
||||
let delete_trash_end = SIDEBAR_TREE_RUNTIME_JS[delete_trash_start..]
|
||||
let delete_trash_end = SIDEBAR_FILETREE_COMMAND_RUNTIME_JS[delete_trash_start..]
|
||||
.find("function appendTreeContextMenuButton")
|
||||
.map(|offset| delete_trash_start + offset)
|
||||
.expect("delete-trash branch end");
|
||||
let delete_trash_branch = &SIDEBAR_TREE_RUNTIME_JS[delete_trash_start..delete_trash_end];
|
||||
let delete_trash_branch =
|
||||
&SIDEBAR_FILETREE_COMMAND_RUNTIME_JS[delete_trash_start..delete_trash_end];
|
||||
assert!(delete_trash_branch.contains("action: 'archive'"));
|
||||
assert!(!delete_trash_branch.contains("action: 'purge'"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sidebar_filetree_delete_keys_support_mixed_doc_and_asset_selection() {
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function deleteSelectedSidebarFileTreeRows"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("function deleteSelectedSidebarFileTreeRows"));
|
||||
assert!(
|
||||
SIDEBAR_TREE_RUNTIME_JS.contains("event.key === 'Delete' || event.key === 'Backspace'")
|
||||
);
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("selectedFileTreeRows.length > 1"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("selectedFileTreeRows.length > 1"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("deleteSelectedSidebarFileTreeRows(trigger || document.body)"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains(
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains(
|
||||
"currentSourceKind() === 'local_folder' && fileTreeRowKind(row) === 'asset'"
|
||||
));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("if (currentSourceKind() === 'local_folder')"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("documentId: fileAssetIds[lf]"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("/api/media/batch"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("/api/mindmap/"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("/api/tables/"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("确认删除选中的 "));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("if (currentSourceKind() === 'local_folder')"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("documentId: fileAssetIds[lf]"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("/api/media/batch"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("/api/mindmap/"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("/api/tables/"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("确认删除选中的 "));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1011,23 +1026,31 @@ mod tests {
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function blockReadonlyFileTreeAction"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("data-mnote-filetree-readonly-blocked"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("data-mnote-filetree-readonly-message"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("recordFileTreeActionStatus('blocked'"));
|
||||
assert!(
|
||||
SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("recordFileTreeActionStatus('blocked'")
|
||||
);
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("/api/tree/filetree/drop-preflight"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("ensureFileTreeWritableTarget('paste'"));
|
||||
assert!(
|
||||
SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("ensureFileTreeWritableTarget('paste'")
|
||||
);
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("ensureFileTreeWritableTarget('drop'"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sidebar_filetree_command_context_helper_functions_exist() {
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function buildSidebarFileTreeContext"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function evaluateSidebarFileTreeWhen"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("__mnoteFileTreeContextMenuRuntime"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("'workspace.sourceKind'"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("'workspace.readonly'"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("'tree.focusKind'"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("'tree.selectionCount'"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("'tree.selectionResourceKind'"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("data-mnote-workspace-readonly"));
|
||||
assert!(
|
||||
SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("function buildSidebarFileTreeContext")
|
||||
);
|
||||
assert!(
|
||||
SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("function evaluateSidebarFileTreeWhen")
|
||||
);
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("__mnoteFileTreeContextMenuRuntime"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("'workspace.sourceKind'"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("'workspace.readonly'"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("'tree.focusKind'"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("'tree.selectionCount'"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("'tree.selectionResourceKind'"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("data-mnote-workspace-readonly"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1045,11 +1068,11 @@ mod tests {
|
||||
fn sidebar_filetree_context_menu_items_have_when_for_readonly() {
|
||||
// FileTree 分支的写操作必须带 when: '!workspace.readonly'。
|
||||
assert!(
|
||||
SIDEBAR_TREE_RUNTIME_JS.contains("when: '!workspace.readonly'"),
|
||||
SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains("when: '!workspace.readonly'"),
|
||||
"上下文菜单写操作应携带 when: '!workspace.readonly'"
|
||||
);
|
||||
// Verify at least one delete-trash item has the when expression
|
||||
let delete_trash_items = SIDEBAR_TREE_RUNTIME_JS
|
||||
let delete_trash_items = SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.match_indices("'delete-trash'")
|
||||
.count();
|
||||
assert!(delete_trash_items > 0, "应至少有一个 delete-trash 菜单项");
|
||||
@@ -1066,14 +1089,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn sidebar_filetree_local_table_bulk_delete_uses_tree_command() {
|
||||
let table_loop_start = SIDEBAR_TREE_RUNTIME_JS
|
||||
let table_loop_start = SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.find("for (var t = 0; t < plan.tableRows.length; t += 1)")
|
||||
.expect("table bulk delete loop");
|
||||
let table_loop_end = SIDEBAR_TREE_RUNTIME_JS[table_loop_start..]
|
||||
let table_loop_end = SIDEBAR_FILETREE_COMMAND_RUNTIME_JS[table_loop_start..]
|
||||
.find("sidebarFileTreeSelection.selectedRowIds")
|
||||
.map(|offset| table_loop_start + offset)
|
||||
.expect("table bulk delete loop end");
|
||||
let table_loop = &SIDEBAR_TREE_RUNTIME_JS[table_loop_start..table_loop_end];
|
||||
let table_loop = &SIDEBAR_FILETREE_COMMAND_RUNTIME_JS[table_loop_start..table_loop_end];
|
||||
assert!(table_loop.contains("currentSourceKind() === 'local_folder'"));
|
||||
assert!(table_loop.contains("dispatchTreeCommand(trigger || tableRow"));
|
||||
assert!(table_loop.contains("action: 'archive'"));
|
||||
@@ -1138,21 +1161,25 @@ mod tests {
|
||||
assert!(
|
||||
SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("params.set('mode', input.mode || 'view');")
|
||||
);
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains(
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains(
|
||||
"{ action: 'open-edit-mode', icon: 'edit_note', label: '使用编辑模式打开' }"
|
||||
));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("{ action: 'open-edit-mode', icon: 'edit_note', label: '弹窗编辑' }"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("{ action: 'new-window-edit', icon: 'open_in_new', label: '新窗口编辑' }"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function withOfficeEditModeGuard(callback)"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("data-mnote-last-office-edit-mode-requested"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("function withOfficeEditModeGuard(callback)"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("data-mnote-last-office-edit-mode-requested"));
|
||||
assert!(SIDEBAR_ATTACHMENT_OPEN_RUNTIME_JS
|
||||
.contains("function openEditorAttachmentEditTab(detail)"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("void openEditorAttachmentEditTab(detail);"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("void openEditorAttachmentEditTab(detail);"));
|
||||
assert!(SIDEBAR_ATTACHMENT_OPEN_RUNTIME_JS
|
||||
.contains("openLocalOfficeFileInActiveTab(detail, 'edit')"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("openEditorAttachmentNewWindow(detail, 'edit')"));
|
||||
assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS
|
||||
.contains("openEditorAttachmentNewWindow(detail, 'edit')"));
|
||||
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("forceEditMode ? 'edit' : 'view'"));
|
||||
assert!(SIDEBAR_ATTACHMENT_OPEN_RUNTIME_JS
|
||||
.contains("url.searchParams.set('mode', requestedMode);"));
|
||||
|
||||
Reference in New Issue
Block a user