fix: handle local mindmap trash and block insertion
This commit is contained in:
@@ -4309,8 +4309,9 @@ fn resolve_local_directory_id(root: &Path, entry_id: &str) -> Result<Option<Path
|
|||||||
fn resolve_local_raw_file_id(root: &Path, entry_id: &str) -> Result<Option<PathBuf>, WebError> {
|
fn resolve_local_raw_file_id(root: &Path, entry_id: &str) -> Result<Option<PathBuf>, WebError> {
|
||||||
let trimmed = entry_id.trim();
|
let trimmed = entry_id.trim();
|
||||||
let Some(relative_path) = trimmed
|
let Some(relative_path) = trimmed
|
||||||
.strip_prefix("local:node:")
|
.strip_prefix("local-file:")
|
||||||
.or_else(|| trimmed.strip_prefix("local:asset:"))
|
.or_else(|| trimmed.strip_prefix("local:asset:"))
|
||||||
|
.or_else(|| trimmed.strip_prefix("local:node:"))
|
||||||
else {
|
else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
@@ -7675,6 +7676,37 @@ fn main() {}
|
|||||||
let _ = std::fs::remove_dir_all(&root);
|
let _ = std::fs::remove_dir_all(&root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn local_tree_command_delete_local_file_id_uses_trash_index() {
|
||||||
|
let root = temp_root("mnote-local-delete-local-file-id");
|
||||||
|
init_workspace(&root);
|
||||||
|
std::fs::create_dir_all(root.join("docs")).expect("create docs");
|
||||||
|
std::fs::write(root.join("docs").join("photo.png"), b"png").expect("write asset");
|
||||||
|
let root_uri = format!("file://{}", root.display());
|
||||||
|
|
||||||
|
let result = execute_local_tree_command(
|
||||||
|
&root_uri,
|
||||||
|
"delete",
|
||||||
|
"local-file:docs/photo.png",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.expect("delete local-file asset");
|
||||||
|
|
||||||
|
assert_eq!(result["resourceKind"].as_str(), Some("local_file"));
|
||||||
|
assert_eq!(
|
||||||
|
result["trashEntryId"].as_str(),
|
||||||
|
Some("local-file:docs/photo.png")
|
||||||
|
);
|
||||||
|
assert!(!root.join("docs").join("photo.png").exists());
|
||||||
|
assert!(root.join(".mnote").join("trash").join("photo.png").exists());
|
||||||
|
let trash_index = std::fs::read_to_string(root.join(".mnote").join("trash-index.json"))
|
||||||
|
.expect("trash index");
|
||||||
|
assert!(trash_index.contains("local-file:docs/photo.png"));
|
||||||
|
|
||||||
|
let _ = std::fs::remove_dir_all(&root);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn local_markdown_save_refreshes_search_index_after_write() {
|
fn local_markdown_save_refreshes_search_index_after_write() {
|
||||||
let root = temp_root("mnote-local-save-refresh-search-index");
|
let root = temp_root("mnote-local-save-refresh-search-index");
|
||||||
|
|||||||
@@ -4,11 +4,14 @@ use crate::error::WebError;
|
|||||||
use crate::routes::command_support::{
|
use crate::routes::command_support::{
|
||||||
execute_runtime_command_via_convex_with_artifacts, runtime_context,
|
execute_runtime_command_via_convex_with_artifacts, runtime_context,
|
||||||
};
|
};
|
||||||
|
use crate::routes::local_folder_source::{
|
||||||
|
ensure_local_workspace_access, execute_local_tree_command,
|
||||||
|
};
|
||||||
use crate::transport::convex::{
|
use crate::transport::convex::{
|
||||||
execute_convex_mutation_by_name, execute_convex_query_by_name,
|
execute_convex_mutation_by_name, execute_convex_query_by_name,
|
||||||
persist_runtime_command_artifacts,
|
persist_runtime_command_artifacts,
|
||||||
};
|
};
|
||||||
use axum::extract::{Extension, Path, State};
|
use axum::extract::{Extension, Path, Query, State};
|
||||||
use axum::http::{HeaderMap, HeaderName, HeaderValue, StatusCode};
|
use axum::http::{HeaderMap, HeaderName, HeaderValue, StatusCode};
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
use bridge_runtime::{
|
use bridge_runtime::{
|
||||||
@@ -51,6 +54,13 @@ pub struct MindmapTrashRequest {
|
|||||||
pub action: String,
|
pub action: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct MindmapLocalQuery {
|
||||||
|
pub source_kind: Option<String>,
|
||||||
|
pub root_uri: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct TableTrashRequest {
|
pub struct TableTrashRequest {
|
||||||
@@ -761,10 +771,30 @@ pub async fn mindmap_delete(
|
|||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Extension(context): Extension<RequestContext>,
|
Extension(context): Extension<RequestContext>,
|
||||||
Path((doc_id, mindmap_id)): Path<(String, String)>,
|
Path((doc_id, mindmap_id)): Path<(String, String)>,
|
||||||
|
Query(query): Query<MindmapLocalQuery>,
|
||||||
) -> Result<(StatusCode, HeaderMap, Json<Value>), WebError> {
|
) -> Result<(StatusCode, HeaderMap, Json<Value>), WebError> {
|
||||||
let user_id = current_user_id(&state, &context).await;
|
let user_id = current_user_id(&state, &context).await;
|
||||||
let doc_id = require_id(&context, &doc_id, "docId")?;
|
let doc_id = require_id(&context, &doc_id, "docId")?;
|
||||||
let mindmap_id = require_id(&context, &mindmap_id, "mindmapId")?;
|
let mindmap_id = require_id(&context, &mindmap_id, "mindmapId")?;
|
||||||
|
if query.source_kind.as_deref() == Some("local_folder") {
|
||||||
|
let root_uri = query
|
||||||
|
.root_uri
|
||||||
|
.as_deref()
|
||||||
|
.map(str::trim)
|
||||||
|
.filter(|value| !value.is_empty())
|
||||||
|
.ok_or_else(|| {
|
||||||
|
WebError::bad_request_code("local_folder_root_required", "缺少本地文件夹 rootUri")
|
||||||
|
.with_context(&context)
|
||||||
|
})?;
|
||||||
|
ensure_local_workspace_access(&context, root_uri)
|
||||||
|
.map_err(|error| error.with_context(&context))?;
|
||||||
|
let execution = execute_local_tree_command(root_uri, "delete", &mindmap_id, None, None)
|
||||||
|
.map_err(|error| error.with_context(&context))?;
|
||||||
|
return Ok(ok_response(
|
||||||
|
&context,
|
||||||
|
annotate_resource_lifecycle_result(execution, "tree.resource.archive", "mindmap"),
|
||||||
|
));
|
||||||
|
}
|
||||||
let workspace_id = fetch_document_workspace_id(&state, &context, doc_id).await;
|
let workspace_id = fetch_document_workspace_id(&state, &context, doc_id).await;
|
||||||
let command = resource_command(
|
let command = resource_command(
|
||||||
&context,
|
&context,
|
||||||
@@ -1199,6 +1229,64 @@ mod tests {
|
|||||||
serde_json::from_slice(&body).expect("json")
|
serde_json::from_slice(&body).expect("json")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn local_folder_mindmap_delete_moves_resource_file_to_trash() {
|
||||||
|
let root =
|
||||||
|
std::env::temp_dir().join(format!("mnote-local-mindmap-trash-{}", std::process::id()));
|
||||||
|
let _ = std::fs::remove_dir_all(&root);
|
||||||
|
std::fs::create_dir_all(root.join("Page")).expect("create page");
|
||||||
|
std::fs::write(root.join("Page").join("Page.md"), "# Page\n").expect("write md");
|
||||||
|
std::fs::write(
|
||||||
|
root.join("Page").join("map.mindmap.json"),
|
||||||
|
r#"{"data":{"uid":"root","text":"KMIND"},"children":[]}"#,
|
||||||
|
)
|
||||||
|
.expect("write mindmap");
|
||||||
|
let root_uri = format!("file://{}", root.display());
|
||||||
|
crate::routes::local_folder_source::initialize_local_workspace_for_actor(
|
||||||
|
"user_real",
|
||||||
|
&root_uri,
|
||||||
|
)
|
||||||
|
.expect("init workspace");
|
||||||
|
|
||||||
|
let response = app()
|
||||||
|
.oneshot(
|
||||||
|
Request::builder()
|
||||||
|
.method("DELETE")
|
||||||
|
.uri(format!(
|
||||||
|
"/api/mindmap/local-md:Page~2FPage.md/local-file:Page%2Fmap.mindmap.json?sourceKind=local_folder&rootUri={root_uri}"
|
||||||
|
))
|
||||||
|
.header("x-mnote-actor-id", "user_real")
|
||||||
|
.header("x-mnote-actor-type", "user")
|
||||||
|
.body(Body::empty())
|
||||||
|
.expect("request"),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("response");
|
||||||
|
let status = response.status();
|
||||||
|
let body = to_bytes(response.into_body(), usize::MAX)
|
||||||
|
.await
|
||||||
|
.expect("body");
|
||||||
|
let payload: Value = serde_json::from_slice(&body).expect("json");
|
||||||
|
|
||||||
|
assert_eq!(status, StatusCode::OK, "{}", String::from_utf8_lossy(&body));
|
||||||
|
assert_eq!(
|
||||||
|
payload["result"]["canonicalCommand"],
|
||||||
|
"tree.resource.archive"
|
||||||
|
);
|
||||||
|
assert_eq!(payload["result"]["sourceKind"], "local_folder");
|
||||||
|
assert!(!root.join("Page").join("map.mindmap.json").exists());
|
||||||
|
assert!(root
|
||||||
|
.join(".mnote")
|
||||||
|
.join("trash")
|
||||||
|
.join("map.mindmap.json")
|
||||||
|
.exists());
|
||||||
|
let trash_index = std::fs::read_to_string(root.join(".mnote").join("trash-index.json"))
|
||||||
|
.expect("trash index");
|
||||||
|
assert!(trash_index.contains("local-file:Page/map.mindmap.json"));
|
||||||
|
|
||||||
|
let _ = std::fs::remove_dir_all(&root);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn media_trash_routes_delete_restore_purge_and_empty() {
|
async fn media_trash_routes_delete_restore_purge_and_empty() {
|
||||||
let deleted = post_json(
|
let deleted = post_json(
|
||||||
|
|||||||
@@ -7567,7 +7567,7 @@ mod tests {
|
|||||||
std::fs::write(root.join("docs").join("photo.png"), b"png").expect("write asset");
|
std::fs::write(root.join("docs").join("photo.png"), b"png").expect("write asset");
|
||||||
let root_uri = format!("file://{}", root.display());
|
let root_uri = format!("file://{}", root.display());
|
||||||
init_local_workspace(&root, "user_test");
|
init_local_workspace(&root, "user_test");
|
||||||
let asset_id = "local:asset:docs/photo.png";
|
let asset_id = "local-file:docs/photo.png";
|
||||||
|
|
||||||
let delete_response = app()
|
let delete_response = app()
|
||||||
.oneshot(
|
.oneshot(
|
||||||
|
|||||||
@@ -2648,15 +2648,20 @@ const SIDEBAR_TREE_JS: &str = r##"
|
|||||||
|
|
||||||
function appendUploadedAssetRow(asset, documentId) {
|
function appendUploadedAssetRow(asset, documentId) {
|
||||||
var assetId = String(asset && asset.id || '').trim();
|
var assetId = String(asset && asset.id || '').trim();
|
||||||
if (!assetId) return;
|
if (!assetId) return false;
|
||||||
if (revealFileTreeAssetRow(assetId)) return;
|
if (revealFileTreeAssetRow(assetId)) return true;
|
||||||
|
var objectKind = String(asset && (asset.objectKind || asset.resourceKind || '') || '').trim();
|
||||||
|
if (!objectKind && (String(asset && (asset.asset_type || asset.assetType) || '').trim() === 'mindmap' || /\.mindmap\.json$/i.test(assetId))) {
|
||||||
|
objectKind = 'mindmap';
|
||||||
|
}
|
||||||
var targetDocumentId = String(documentId || asset.document_id || asset.documentId || currentDocumentId() || '').trim();
|
var targetDocumentId = String(documentId || asset.document_id || asset.documentId || currentDocumentId() || '').trim();
|
||||||
var parentRow = targetDocumentId
|
var parentRow = targetDocumentId
|
||||||
? document.querySelector('.tree-row[data-shell-mode="filetree"][data-row-id="' + cssEscape('doc:' + targetDocumentId) + '"]')
|
? document.querySelector('.tree-row[data-shell-mode="filetree"][data-row-id="' + cssEscape('doc:' + targetDocumentId) + '"]')
|
||||||
: null;
|
: null;
|
||||||
|
if (!parentRow && currentSourceKind() === 'local_folder' && objectKind === 'mindmap') return false;
|
||||||
if (!parentRow) parentRow = document.querySelector('.tree-row[data-shell-mode="filetree"][data-row-kind="document"]');
|
if (!parentRow) parentRow = document.querySelector('.tree-row[data-shell-mode="filetree"][data-row-kind="document"]');
|
||||||
var root = document.querySelector('#sidebar-file-tree-root .tree-root');
|
var root = document.querySelector('#sidebar-file-tree-root .tree-root');
|
||||||
if (!root && !parentRow) return;
|
if (!root && !parentRow) return false;
|
||||||
var parentLi = parentRow ? parentRow.closest('.tree-node') : null;
|
var parentLi = parentRow ? parentRow.closest('.tree-node') : null;
|
||||||
var children = parentLi ? parentLi.querySelector(':scope > .tree-children') : null;
|
var children = parentLi ? parentLi.querySelector(':scope > .tree-children') : null;
|
||||||
if (parentLi && !children) {
|
if (parentLi && !children) {
|
||||||
@@ -2675,10 +2680,6 @@ const SIDEBAR_TREE_JS: &str = r##"
|
|||||||
var container = children || root;
|
var container = children || root;
|
||||||
var li = document.createElement('li');
|
var li = document.createElement('li');
|
||||||
li.className = 'tree-node';
|
li.className = 'tree-node';
|
||||||
var objectKind = String(asset && (asset.objectKind || asset.resourceKind || '') || '').trim();
|
|
||||||
if (!objectKind && (String(asset && (asset.asset_type || asset.assetType) || '').trim() === 'mindmap' || /\.mindmap\.json$/i.test(assetId))) {
|
|
||||||
objectKind = 'mindmap';
|
|
||||||
}
|
|
||||||
var objectIdentity = {
|
var objectIdentity = {
|
||||||
objectKind: objectKind || 'attachment',
|
objectKind: objectKind || 'attachment',
|
||||||
documentId: targetDocumentId || null,
|
documentId: targetDocumentId || null,
|
||||||
@@ -2697,6 +2698,7 @@ const SIDEBAR_TREE_JS: &str = r##"
|
|||||||
container.appendChild(li);
|
container.appendChild(li);
|
||||||
revealFileTreeRow(li.querySelector('.tree-row'));
|
revealFileTreeRow(li.querySelector('.tree-row'));
|
||||||
document.documentElement.setAttribute('data-mnote-last-upload-asset-id', assetId);
|
document.documentElement.setAttribute('data-mnote-last-upload-asset-id', assetId);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeFileTreeAssetRow(assetId) {
|
function removeFileTreeAssetRow(assetId) {
|
||||||
@@ -2826,7 +2828,8 @@ const SIDEBAR_TREE_JS: &str = r##"
|
|||||||
if (!target || !target.documentId || !target.mindmapId) return;
|
if (!target || !target.documentId || !target.mindmapId) return;
|
||||||
var asset = mindmapAssetFromTarget(target.documentId, target.mindmapId, payload && payload.writeResult);
|
var asset = mindmapAssetFromTarget(target.documentId, target.mindmapId, payload && payload.writeResult);
|
||||||
if (!asset) return;
|
if (!asset) return;
|
||||||
appendUploadedAssetRow(asset, target.documentId);
|
var appended = appendUploadedAssetRow(asset, target.documentId);
|
||||||
|
if (!appended && currentSourceKind() === 'local_folder') void refreshLocalFolderSidebarSnapshot();
|
||||||
document.documentElement.setAttribute('data-mnote-assets-local-applied', 'true');
|
document.documentElement.setAttribute('data-mnote-assets-local-applied', 'true');
|
||||||
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', asset.id || target.mindmapId);
|
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', asset.id || target.mindmapId);
|
||||||
}
|
}
|
||||||
@@ -8914,6 +8917,8 @@ mod tests {
|
|||||||
assert!(SIDEBAR_TREE_JS.contains("withLocalMindmapSourceParams"));
|
assert!(SIDEBAR_TREE_JS.contains("withLocalMindmapSourceParams"));
|
||||||
assert!(SIDEBAR_TREE_JS.contains("url.searchParams.set('sourceKind', 'local_folder')"));
|
assert!(SIDEBAR_TREE_JS.contains("url.searchParams.set('sourceKind', 'local_folder')"));
|
||||||
assert!(SIDEBAR_TREE_JS.contains("url.searchParams.set('rootUri', rootUri)"));
|
assert!(SIDEBAR_TREE_JS.contains("url.searchParams.set('rootUri', rootUri)"));
|
||||||
|
assert!(SIDEBAR_TREE_JS.contains("if (!parentRow && currentSourceKind() === 'local_folder' && objectKind === 'mindmap') return false;"));
|
||||||
|
assert!(SIDEBAR_TREE_JS.contains("if (!appended && currentSourceKind() === 'local_folder') void refreshLocalFolderSidebarSnapshot();"));
|
||||||
assert!(SIDEBAR_TREE_JS
|
assert!(SIDEBAR_TREE_JS
|
||||||
.contains("data-mnote-last-mindmap-asset-open-mode', 'local-mindmap-object-shell'"));
|
.contains("data-mnote-last-mindmap-asset-open-mode', 'local-mindmap-object-shell'"));
|
||||||
assert!(SIDEBAR_TREE_JS.contains("buildLocalOnlyOfficeOpenUrl"));
|
assert!(SIDEBAR_TREE_JS.contains("buildLocalOnlyOfficeOpenUrl"));
|
||||||
|
|||||||
+20
-20
@@ -48,32 +48,32 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
|
|||||||
|
|
||||||
export interface InitOutput {
|
export interface InitOutput {
|
||||||
readonly memory: WebAssembly.Memory;
|
readonly memory: WebAssembly.Memory;
|
||||||
readonly mount: (a: any, b: any) => [number, number, number];
|
|
||||||
readonly mount_mindmap_shell: (a: any, b: any) => [number, number, number];
|
readonly mount_mindmap_shell: (a: any, b: any) => [number, number, number];
|
||||||
readonly unmount: (a: number) => [number, number];
|
|
||||||
readonly unmount_mindmap_shell: (a: number) => [number, number];
|
readonly unmount_mindmap_shell: (a: number) => [number, number];
|
||||||
readonly __wbg_intounderlyingbytesource_free: (a: number, b: number) => void;
|
readonly mount: (a: any, b: any) => [number, number, number];
|
||||||
readonly intounderlyingbytesource_autoAllocateChunkSize: (a: number) => number;
|
readonly unmount: (a: number) => [number, number];
|
||||||
readonly intounderlyingbytesource_cancel: (a: number) => void;
|
|
||||||
readonly intounderlyingbytesource_pull: (a: number, b: any) => any;
|
|
||||||
readonly intounderlyingbytesource_start: (a: number, b: any) => void;
|
|
||||||
readonly intounderlyingbytesource_type: (a: number) => number;
|
|
||||||
readonly __wbg_intounderlyingsink_free: (a: number, b: number) => void;
|
readonly __wbg_intounderlyingsink_free: (a: number, b: number) => void;
|
||||||
readonly intounderlyingsink_abort: (a: number, b: any) => any;
|
|
||||||
readonly intounderlyingsink_close: (a: number) => any;
|
|
||||||
readonly intounderlyingsink_write: (a: number, b: any) => any;
|
readonly intounderlyingsink_write: (a: number, b: any) => any;
|
||||||
|
readonly intounderlyingsink_close: (a: number) => any;
|
||||||
|
readonly intounderlyingsink_abort: (a: number, b: any) => any;
|
||||||
|
readonly __wbg_intounderlyingbytesource_free: (a: number, b: number) => void;
|
||||||
|
readonly intounderlyingbytesource_type: (a: number) => number;
|
||||||
|
readonly intounderlyingbytesource_autoAllocateChunkSize: (a: number) => number;
|
||||||
|
readonly intounderlyingbytesource_start: (a: number, b: any) => void;
|
||||||
|
readonly intounderlyingbytesource_pull: (a: number, b: any) => any;
|
||||||
|
readonly intounderlyingbytesource_cancel: (a: number) => void;
|
||||||
readonly __wbg_intounderlyingsource_free: (a: number, b: number) => void;
|
readonly __wbg_intounderlyingsource_free: (a: number, b: number) => void;
|
||||||
readonly intounderlyingsource_cancel: (a: number) => void;
|
|
||||||
readonly intounderlyingsource_pull: (a: number, b: any) => any;
|
readonly intounderlyingsource_pull: (a: number, b: any) => any;
|
||||||
readonly wasm_bindgen__convert__closures_____invoke__h854f4676fa692669: (a: number, b: number, c: any) => [number, number];
|
readonly intounderlyingsource_cancel: (a: number) => void;
|
||||||
readonly wasm_bindgen__convert__closures_____invoke__h1a94ffe1b1ed8350: (a: number, b: number, c: any, d: any) => void;
|
readonly wasm_bindgen__convert__closures_____invoke__h3a3182d847094e12: (a: number, b: number, c: any) => [number, number];
|
||||||
readonly wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f: (a: number, b: number, c: any) => void;
|
readonly wasm_bindgen__convert__closures_____invoke__h0accad0f5d87788a: (a: number, b: number, c: any, d: any) => void;
|
||||||
readonly wasm_bindgen__convert__closures_____invoke__h4916074fb8b30849: (a: number, b: number, c: any) => void;
|
readonly wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5: (a: number, b: number, c: any) => void;
|
||||||
readonly wasm_bindgen__convert__closures_____invoke__h10d35e1548938147: (a: number, b: number, c: any) => void;
|
readonly wasm_bindgen__convert__closures_____invoke__hde8e7b4803478c08: (a: number, b: number, c: any) => void;
|
||||||
readonly wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f_4: (a: number, b: number, c: any) => void;
|
readonly wasm_bindgen__convert__closures_____invoke__h0abd2b2fe4652e2a: (a: number, b: number, c: any) => void;
|
||||||
readonly wasm_bindgen__convert__closures_____invoke__h68fbbcff54846097: (a: number, b: number) => void;
|
readonly wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5_4: (a: number, b: number, c: any) => void;
|
||||||
readonly wasm_bindgen__convert__closures_____invoke__had164c21c04063ef: (a: number, b: number) => void;
|
readonly wasm_bindgen__convert__closures_____invoke__h794babeffd4f821f: (a: number, b: number) => void;
|
||||||
readonly wasm_bindgen__convert__closures_____invoke__h5921057d3102c7f1: (a: number, b: number) => void;
|
readonly wasm_bindgen__convert__closures_____invoke__h2b648e7ac8ec1fb5: (a: number, b: number) => void;
|
||||||
|
readonly wasm_bindgen__convert__closures_____invoke__h0b7fb40a8610550c: (a: number, b: number) => void;
|
||||||
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
||||||
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
||||||
readonly __externref_table_alloc: () => number;
|
readonly __externref_table_alloc: () => number;
|
||||||
|
|||||||
+35
-35
@@ -824,7 +824,7 @@ function __wbg_get_imports() {
|
|||||||
const a = state0.a;
|
const a = state0.a;
|
||||||
state0.a = 0;
|
state0.a = 0;
|
||||||
try {
|
try {
|
||||||
return wasm_bindgen__convert__closures_____invoke__h1a94ffe1b1ed8350(a, state0.b, arg0, arg1);
|
return wasm_bindgen__convert__closures_____invoke__h0accad0f5d87788a(a, state0.b, arg0, arg1);
|
||||||
} finally {
|
} finally {
|
||||||
state0.a = a;
|
state0.a = a;
|
||||||
}
|
}
|
||||||
@@ -1223,43 +1223,43 @@ function __wbg_get_imports() {
|
|||||||
}
|
}
|
||||||
}, arguments); },
|
}, arguments); },
|
||||||
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1114, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1129, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
||||||
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f);
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000002: function(arg0, arg1) {
|
__wbindgen_cast_0000000000000002: function(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1176, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1181, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
||||||
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h854f4676fa692669);
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h3a3182d847094e12);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000003: function(arg0, arg1) {
|
__wbindgen_cast_0000000000000003: function(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 984, ret: Unit, inner_ret: Some(Unit) }, mutable: false }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 957, ret: Unit, inner_ret: Some(Unit) }, mutable: false }) -> Externref`.
|
||||||
const ret = makeClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h4916074fb8b30849);
|
const ret = makeClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__hde8e7b4803478c08);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000004: function(arg0, arg1) {
|
__wbindgen_cast_0000000000000004: function(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 1082, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 1079, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
||||||
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h10d35e1548938147);
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h0abd2b2fe4652e2a);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000005: function(arg0, arg1) {
|
__wbindgen_cast_0000000000000005: function(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 1114, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 1129, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
||||||
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f_4);
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5_4);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000006: function(arg0, arg1) {
|
__wbindgen_cast_0000000000000006: function(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1084, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1081, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
||||||
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h68fbbcff54846097);
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h794babeffd4f821f);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000007: function(arg0, arg1) {
|
__wbindgen_cast_0000000000000007: function(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1099, ret: Unit, inner_ret: Some(Unit) }, mutable: false }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1096, ret: Unit, inner_ret: Some(Unit) }, mutable: false }) -> Externref`.
|
||||||
const ret = makeClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__had164c21c04063ef);
|
const ret = makeClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h2b648e7ac8ec1fb5);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000008: function(arg0, arg1) {
|
__wbindgen_cast_0000000000000008: function(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1116, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1132, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
||||||
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h5921057d3102c7f1);
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h0b7fb40a8610550c);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000009: function(arg0) {
|
__wbindgen_cast_0000000000000009: function(arg0) {
|
||||||
@@ -1302,43 +1302,43 @@ function __wbg_get_imports() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasm_bindgen__convert__closures_____invoke__h68fbbcff54846097(arg0, arg1) {
|
function wasm_bindgen__convert__closures_____invoke__h794babeffd4f821f(arg0, arg1) {
|
||||||
wasm.wasm_bindgen__convert__closures_____invoke__h68fbbcff54846097(arg0, arg1);
|
wasm.wasm_bindgen__convert__closures_____invoke__h794babeffd4f821f(arg0, arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasm_bindgen__convert__closures_____invoke__had164c21c04063ef(arg0, arg1) {
|
function wasm_bindgen__convert__closures_____invoke__h2b648e7ac8ec1fb5(arg0, arg1) {
|
||||||
wasm.wasm_bindgen__convert__closures_____invoke__had164c21c04063ef(arg0, arg1);
|
wasm.wasm_bindgen__convert__closures_____invoke__h2b648e7ac8ec1fb5(arg0, arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasm_bindgen__convert__closures_____invoke__h5921057d3102c7f1(arg0, arg1) {
|
function wasm_bindgen__convert__closures_____invoke__h0b7fb40a8610550c(arg0, arg1) {
|
||||||
wasm.wasm_bindgen__convert__closures_____invoke__h5921057d3102c7f1(arg0, arg1);
|
wasm.wasm_bindgen__convert__closures_____invoke__h0b7fb40a8610550c(arg0, arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f(arg0, arg1, arg2) {
|
function wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5(arg0, arg1, arg2) {
|
||||||
wasm.wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f(arg0, arg1, arg2);
|
wasm.wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5(arg0, arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasm_bindgen__convert__closures_____invoke__h4916074fb8b30849(arg0, arg1, arg2) {
|
function wasm_bindgen__convert__closures_____invoke__hde8e7b4803478c08(arg0, arg1, arg2) {
|
||||||
wasm.wasm_bindgen__convert__closures_____invoke__h4916074fb8b30849(arg0, arg1, arg2);
|
wasm.wasm_bindgen__convert__closures_____invoke__hde8e7b4803478c08(arg0, arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasm_bindgen__convert__closures_____invoke__h10d35e1548938147(arg0, arg1, arg2) {
|
function wasm_bindgen__convert__closures_____invoke__h0abd2b2fe4652e2a(arg0, arg1, arg2) {
|
||||||
wasm.wasm_bindgen__convert__closures_____invoke__h10d35e1548938147(arg0, arg1, arg2);
|
wasm.wasm_bindgen__convert__closures_____invoke__h0abd2b2fe4652e2a(arg0, arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f_4(arg0, arg1, arg2) {
|
function wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5_4(arg0, arg1, arg2) {
|
||||||
wasm.wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f_4(arg0, arg1, arg2);
|
wasm.wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5_4(arg0, arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasm_bindgen__convert__closures_____invoke__h854f4676fa692669(arg0, arg1, arg2) {
|
function wasm_bindgen__convert__closures_____invoke__h3a3182d847094e12(arg0, arg1, arg2) {
|
||||||
const ret = wasm.wasm_bindgen__convert__closures_____invoke__h854f4676fa692669(arg0, arg1, arg2);
|
const ret = wasm.wasm_bindgen__convert__closures_____invoke__h3a3182d847094e12(arg0, arg1, arg2);
|
||||||
if (ret[1]) {
|
if (ret[1]) {
|
||||||
throw takeFromExternrefTable0(ret[0]);
|
throw takeFromExternrefTable0(ret[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasm_bindgen__convert__closures_____invoke__h1a94ffe1b1ed8350(arg0, arg1, arg2, arg3) {
|
function wasm_bindgen__convert__closures_____invoke__h0accad0f5d87788a(arg0, arg1, arg2, arg3) {
|
||||||
wasm.wasm_bindgen__convert__closures_____invoke__h1a94ffe1b1ed8350(arg0, arg1, arg2, arg3);
|
wasm.wasm_bindgen__convert__closures_____invoke__h0accad0f5d87788a(arg0, arg1, arg2, arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
BIN
Binary file not shown.
Vendored
+20
-20
@@ -1,32 +1,32 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
export const memory: WebAssembly.Memory;
|
export const memory: WebAssembly.Memory;
|
||||||
export const mount: (a: any, b: any) => [number, number, number];
|
|
||||||
export const mount_mindmap_shell: (a: any, b: any) => [number, number, number];
|
export const mount_mindmap_shell: (a: any, b: any) => [number, number, number];
|
||||||
export const unmount: (a: number) => [number, number];
|
|
||||||
export const unmount_mindmap_shell: (a: number) => [number, number];
|
export const unmount_mindmap_shell: (a: number) => [number, number];
|
||||||
export const __wbg_intounderlyingbytesource_free: (a: number, b: number) => void;
|
export const mount: (a: any, b: any) => [number, number, number];
|
||||||
export const intounderlyingbytesource_autoAllocateChunkSize: (a: number) => number;
|
export const unmount: (a: number) => [number, number];
|
||||||
export const intounderlyingbytesource_cancel: (a: number) => void;
|
|
||||||
export const intounderlyingbytesource_pull: (a: number, b: any) => any;
|
|
||||||
export const intounderlyingbytesource_start: (a: number, b: any) => void;
|
|
||||||
export const intounderlyingbytesource_type: (a: number) => number;
|
|
||||||
export const __wbg_intounderlyingsink_free: (a: number, b: number) => void;
|
export const __wbg_intounderlyingsink_free: (a: number, b: number) => void;
|
||||||
export const intounderlyingsink_abort: (a: number, b: any) => any;
|
|
||||||
export const intounderlyingsink_close: (a: number) => any;
|
|
||||||
export const intounderlyingsink_write: (a: number, b: any) => any;
|
export const intounderlyingsink_write: (a: number, b: any) => any;
|
||||||
|
export const intounderlyingsink_close: (a: number) => any;
|
||||||
|
export const intounderlyingsink_abort: (a: number, b: any) => any;
|
||||||
|
export const __wbg_intounderlyingbytesource_free: (a: number, b: number) => void;
|
||||||
|
export const intounderlyingbytesource_type: (a: number) => number;
|
||||||
|
export const intounderlyingbytesource_autoAllocateChunkSize: (a: number) => number;
|
||||||
|
export const intounderlyingbytesource_start: (a: number, b: any) => void;
|
||||||
|
export const intounderlyingbytesource_pull: (a: number, b: any) => any;
|
||||||
|
export const intounderlyingbytesource_cancel: (a: number) => void;
|
||||||
export const __wbg_intounderlyingsource_free: (a: number, b: number) => void;
|
export const __wbg_intounderlyingsource_free: (a: number, b: number) => void;
|
||||||
export const intounderlyingsource_cancel: (a: number) => void;
|
|
||||||
export const intounderlyingsource_pull: (a: number, b: any) => any;
|
export const intounderlyingsource_pull: (a: number, b: any) => any;
|
||||||
export const wasm_bindgen__convert__closures_____invoke__h854f4676fa692669: (a: number, b: number, c: any) => [number, number];
|
export const intounderlyingsource_cancel: (a: number) => void;
|
||||||
export const wasm_bindgen__convert__closures_____invoke__h1a94ffe1b1ed8350: (a: number, b: number, c: any, d: any) => void;
|
export const wasm_bindgen__convert__closures_____invoke__h3a3182d847094e12: (a: number, b: number, c: any) => [number, number];
|
||||||
export const wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f: (a: number, b: number, c: any) => void;
|
export const wasm_bindgen__convert__closures_____invoke__h0accad0f5d87788a: (a: number, b: number, c: any, d: any) => void;
|
||||||
export const wasm_bindgen__convert__closures_____invoke__h4916074fb8b30849: (a: number, b: number, c: any) => void;
|
export const wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5: (a: number, b: number, c: any) => void;
|
||||||
export const wasm_bindgen__convert__closures_____invoke__h10d35e1548938147: (a: number, b: number, c: any) => void;
|
export const wasm_bindgen__convert__closures_____invoke__hde8e7b4803478c08: (a: number, b: number, c: any) => void;
|
||||||
export const wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f_4: (a: number, b: number, c: any) => void;
|
export const wasm_bindgen__convert__closures_____invoke__h0abd2b2fe4652e2a: (a: number, b: number, c: any) => void;
|
||||||
export const wasm_bindgen__convert__closures_____invoke__h68fbbcff54846097: (a: number, b: number) => void;
|
export const wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5_4: (a: number, b: number, c: any) => void;
|
||||||
export const wasm_bindgen__convert__closures_____invoke__had164c21c04063ef: (a: number, b: number) => void;
|
export const wasm_bindgen__convert__closures_____invoke__h794babeffd4f821f: (a: number, b: number) => void;
|
||||||
export const wasm_bindgen__convert__closures_____invoke__h5921057d3102c7f1: (a: number, b: number) => void;
|
export const wasm_bindgen__convert__closures_____invoke__h2b648e7ac8ec1fb5: (a: number, b: number) => void;
|
||||||
|
export const wasm_bindgen__convert__closures_____invoke__h0b7fb40a8610550c: (a: number, b: number) => void;
|
||||||
export const __wbindgen_malloc: (a: number, b: number) => number;
|
export const __wbindgen_malloc: (a: number, b: number) => number;
|
||||||
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
||||||
export const __externref_table_alloc: () => number;
|
export const __externref_table_alloc: () => number;
|
||||||
|
|||||||
@@ -3349,6 +3349,38 @@ mod tests {
|
|||||||
"mnote.leptos-tiptap-spike.document:mindmap-object:doc-a:mind-a"
|
"mnote.leptos-tiptap-spike.document:mindmap-object:doc-a:mind-a"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mindmap_empty_paragraph_has_textblock_boundary_size() {
|
||||||
|
let node = json!({
|
||||||
|
"type": "paragraph",
|
||||||
|
"attrs": {
|
||||||
|
"mnoteBlockType": "mindmap",
|
||||||
|
"mindmapId": "思维导图123456.json",
|
||||||
|
"rootNodeId": "root",
|
||||||
|
"projectionVersion": 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assert_eq!(prosemirror_node_size(&node), Some(2));
|
||||||
|
|
||||||
|
let document = json!({
|
||||||
|
"type": "doc",
|
||||||
|
"content": [
|
||||||
|
{"type": "paragraph", "content": [{"type": "text", "text": "上"}]},
|
||||||
|
node,
|
||||||
|
{"type": "paragraph", "content": [{"type": "text", "text": "下"}]}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
top_level_block_boundary_position(&document, 1, true),
|
||||||
|
Some(3)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
top_level_block_boundary_position(&document, 1, false),
|
||||||
|
Some(5)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
@@ -5335,7 +5367,13 @@ fn prosemirror_node_size(node: &Value) -> Option<u32> {
|
|||||||
Some("hardBreak") | Some("horizontalRule") => Some(1),
|
Some("hardBreak") | Some("horizontalRule") => Some(1),
|
||||||
_ => {
|
_ => {
|
||||||
let Some(children) = node.get("content").and_then(Value::as_array) else {
|
let Some(children) = node.get("content").and_then(Value::as_array) else {
|
||||||
return Some(1);
|
return Some(match node.get("type").and_then(Value::as_str) {
|
||||||
|
Some("paragraph") | Some("heading") | Some("blockquote")
|
||||||
|
| Some("codeBlock") | Some("bulletList") | Some("orderedList")
|
||||||
|
| Some("taskList") | Some("listItem") | Some("taskItem") | Some("table")
|
||||||
|
| Some("tableRow") | Some("tableCell") | Some("tableHeader") => 2,
|
||||||
|
_ => 1,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let content_size = children.iter().try_fold(0_u32, |acc, child| {
|
let content_size = children.iter().try_fold(0_u32, |acc, child| {
|
||||||
|
|||||||
Reference in New Issue
Block a user