feat: consolidate local-first mnote web runtime
This commit is contained in:
@@ -27,6 +27,9 @@ pub fn HomePage(
|
||||
/// 当前选中的页面标题(可选)
|
||||
#[prop(optional)]
|
||||
active_page_title: Option<String>,
|
||||
/// 导航页主体 HTML(可选)
|
||||
#[prop(optional)]
|
||||
navigation_html: String,
|
||||
/// 是否显示管理员授权入口
|
||||
#[prop(optional)]
|
||||
show_admin_access_policy: bool,
|
||||
@@ -37,6 +40,9 @@ pub fn HomePage(
|
||||
.filter(|value| !value.is_empty())
|
||||
.unwrap_or_else(|| "个人".to_string());
|
||||
let has_active_page = !active_page_id.trim().is_empty();
|
||||
let navigation_html = Some(navigation_html)
|
||||
.map(|value| value.trim().to_string())
|
||||
.filter(|value| !value.is_empty());
|
||||
let workspace_id = workspace_id
|
||||
.map(|value| value.trim().to_string())
|
||||
.filter(|value| !value.is_empty());
|
||||
@@ -63,6 +69,57 @@ pub fn HomePage(
|
||||
</section>
|
||||
</main>
|
||||
}.into_any()
|
||||
} else if let Some(navigation_html) = navigation_html.clone() {
|
||||
view! {
|
||||
<main
|
||||
class="document-workspace mnote-navigation-page-workspace"
|
||||
data-testid="mnote-document-workspace"
|
||||
data-has-secondary-pane="false"
|
||||
data-workspace-id={workspace_id.clone().unwrap_or_default()}
|
||||
>
|
||||
<section class="document-main-editor-group" data-testid="mnote-main-editor-tab-host" data-pane-role="primary">
|
||||
<div class="mnote-main-tab-strip" data-mnote-main-tab-strip="true" data-pane-role="primary" role="tablist" aria-label="主编辑区标签页">
|
||||
<button
|
||||
type="button"
|
||||
class="mnote-main-tab is-active"
|
||||
data-mnote-main-tab="page"
|
||||
data-mnote-tab-kind="page"
|
||||
data-pane-role="primary"
|
||||
data-workspace-id={workspace_id.clone().unwrap_or_default()}
|
||||
role="tab"
|
||||
aria-selected="true"
|
||||
tabindex="0"
|
||||
>
|
||||
<span class="mnote-main-tab-badge" aria-hidden="true"></span>
|
||||
<span class="mnote-main-tab-title">"主页"</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="mnote-main-tab-panels">
|
||||
<div
|
||||
data-mnote-page-tab-panel="true"
|
||||
data-pane-role="primary"
|
||||
>
|
||||
<div
|
||||
class="mnote-navigation-page-host"
|
||||
data-mnote-navigation-page-placeholder="true"
|
||||
data-pane-role="primary"
|
||||
>
|
||||
<div inner_html={navigation_html}></div>
|
||||
</div>
|
||||
</div>
|
||||
<section
|
||||
class="mnote-resource-tab-host"
|
||||
data-mnote-resource-tab-host="true"
|
||||
data-pane-role="primary"
|
||||
data-testid="mnote-resource-tab-host"
|
||||
hidden=true
|
||||
>
|
||||
<div class="mnote-resource-tab-panel-root" data-mnote-resource-tab-panel-root="true" data-pane-role="primary"></div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
}.into_any()
|
||||
} else {
|
||||
let empty_primary_model = DocumentPaneViewModel {
|
||||
pane_role: "primary",
|
||||
|
||||
@@ -94,7 +94,7 @@ pub fn PageLayout(
|
||||
let tree_live_bootstrap = serde_json::json!({
|
||||
"schema": "mnote.tree_live_bootstrap.v1",
|
||||
"disabled": !enable_tree_live,
|
||||
"transport": if enable_tree_live { "convex-command-log-ws" } else { "disabled" },
|
||||
"transport": if enable_tree_live { "tree-live-ws" } else { "disabled" },
|
||||
"workspaceId": null,
|
||||
"rootIds": [],
|
||||
"initialRevision": null,
|
||||
@@ -356,15 +356,18 @@ mod tests {
|
||||
assert!(SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS
|
||||
.contains("mnote.sidebarTreeViewState.v1:{userId}:{workspaceId}:{sourceKind}:{treeKind}:{rootUriHash}:{scopeHash}"));
|
||||
|
||||
let render_page_rows = js_function_body(SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS, "renderPageRows");
|
||||
let render_page_rows =
|
||||
js_function_body(SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS, "renderPageRows");
|
||||
assert!(render_page_rows.contains("sidebarTreeViewStateFor('pagetree'"));
|
||||
assert!(render_page_rows.contains("expandedIds"));
|
||||
assert!(
|
||||
!render_page_rows.contains("var expanded = expandable && item.expandedByDefault !== false"),
|
||||
!render_page_rows
|
||||
.contains("var expanded = expandable && item.expandedByDefault !== false"),
|
||||
"PageTree 不能只依赖 projection expandedByDefault 决定展开"
|
||||
);
|
||||
|
||||
let render_file_rows = js_function_body(SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS, "renderFileRows");
|
||||
let render_file_rows =
|
||||
js_function_body(SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS, "renderFileRows");
|
||||
assert!(render_file_rows.contains("sidebarTreeViewStateFor('filetree'"));
|
||||
assert!(render_file_rows.contains("expandedRelativePaths"));
|
||||
}
|
||||
@@ -387,6 +390,11 @@ mod tests {
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("/api/sidebar/shortcuts"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("toggle-sidebar-shortcut"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("openStarredFolderShortcut"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function openNavigationPageForFolder"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("/api/navigation/recent"));
|
||||
assert!(!SIDEBAR_TREE_RUNTIME_JS.contains("authRedirectUrl"));
|
||||
assert!(!SIDEBAR_TREE_RUNTIME_JS.contains("window.location.assign(authRedirectUrl())"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("window.location.assign(url)"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("rootUri: currentRootUri()"));
|
||||
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("var rootUri = readShortcutRootUri(row);"));
|
||||
assert!(!SIDEBAR_TREE_RUNTIME_JS.contains("inferLocalRootUriFromWorkspaceId"));
|
||||
@@ -414,6 +422,18 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sidebar_filetree_folder_click_toggles_instead_of_navigation_page() {
|
||||
let folder_branch = SIDEBAR_TREE_RUNTIME_JS
|
||||
.split("if (fileAction === 'open' && rowKind === 'folder') {")
|
||||
.nth(1)
|
||||
.and_then(|rest| rest.split("return;").next())
|
||||
.expect("filetree folder open branch exists");
|
||||
assert!(folder_branch.contains("toggleChildren(fileRow"));
|
||||
assert!(!folder_branch.contains("openNavigationPageForFolder"));
|
||||
assert!(!folder_branch.contains("window.location.assign"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn page_ai_context_uses_page_aggregate_subtree_as_single_truth() {
|
||||
assert!(
|
||||
@@ -655,6 +675,10 @@ mod tests {
|
||||
injection.contains("closestAction"),
|
||||
"attachment open runtime 需要显式注入 closestAction,避免首屏点击监听安装时 ReferenceError"
|
||||
);
|
||||
assert!(
|
||||
injection.contains("hydrateEditorAttachmentMeta"),
|
||||
"attachment open runtime 需要显式注入 hydrateEditorAttachmentMeta,避免上传附件增强时 ReferenceError"
|
||||
);
|
||||
assert!(
|
||||
SIDEBAR_ATTACHMENT_OPEN_RUNTIME_JS
|
||||
.contains("closestAction = typeof injectedClosestAction === 'function'")
|
||||
@@ -1412,9 +1436,16 @@ mod tests {
|
||||
#[test]
|
||||
fn sidebar_filetree_context_evaluator_uses_readonly_and_selection_count_for_delete_key() {
|
||||
assert!(
|
||||
SIDEBAR_TREE_RUNTIME_JS
|
||||
.contains("evaluateSidebarFileTreeWhen(delCtx, '!workspace.readonly')"),
|
||||
"Delete/Backspace 快捷键应至少评估 workspace.readonly 上下文"
|
||||
SIDEBAR_TREE_RUNTIME_JS.contains(
|
||||
"evaluateSidebarFileTreeWhen(delCtx, '!workspace.readonly && !editor.dirty')"
|
||||
),
|
||||
"Delete/Backspace 快捷键应评估 workspace.readonly 与 editor.dirty 上下文"
|
||||
);
|
||||
assert!(
|
||||
SIDEBAR_TREE_RUNTIME_JS.contains(
|
||||
"evaluateSidebarFileTreeWhen(renameCtx, '!workspace.readonly && !editor.dirty')"
|
||||
),
|
||||
"F2 快捷键应与菜单重命名共用 command context"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1435,6 +1466,12 @@ mod tests {
|
||||
assert!(table_loop.contains("/api/tables/"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sidebar_filetree_runtime_does_not_keep_retired_table_engine_branches() {
|
||||
let retired_table_engine = ["lucky", "sheet"].concat();
|
||||
assert!(!SIDEBAR_FILETREE_COMMAND_RUNTIME_JS.contains(&retired_table_engine));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sidebar_filetree_asset_open_uses_owner_document_id() {
|
||||
assert!(
|
||||
@@ -1520,6 +1557,18 @@ mod tests {
|
||||
#[test]
|
||||
fn sidebar_tree_runtime_opens_pdf_and_code_assets_with_builtin_tools() {
|
||||
assert!(SIDEBAR_ATTACHMENT_OPEN_RUNTIME_JS.contains("function openPdfEditorAttachment"));
|
||||
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("function buildPdfPreviewOpenUrl"));
|
||||
assert!(SIDEBAR_ATTACHMENT_OPEN_RUNTIME_JS.contains("buildPdfPreviewOpenUrl"));
|
||||
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS
|
||||
.contains("var localOpenUrl = isPdfAttachmentFileName(localFileName) ? buildPdfPreviewOpenUrl(localFileUrl, localFileName) : localFileUrl;"));
|
||||
let open_pdf_body = js_function_body(
|
||||
SIDEBAR_ATTACHMENT_OPEN_RUNTIME_JS,
|
||||
"openPdfEditorAttachment",
|
||||
);
|
||||
assert!(open_pdf_body.contains("buildPdfPreviewOpenUrl(resolved.url, title)"));
|
||||
assert!(
|
||||
!open_pdf_body.contains("window.open(resolved.url, '_blank', 'noopener,noreferrer');")
|
||||
);
|
||||
assert!(SIDEBAR_ATTACHMENT_OPEN_RUNTIME_JS.contains("function openCodeEditorAttachment"));
|
||||
assert!(SIDEBAR_ATTACHMENT_OPEN_RUNTIME_JS.contains("function resolveEditorAttachmentUrl"));
|
||||
assert!(SIDEBAR_ATTACHMENT_OPEN_RUNTIME_JS
|
||||
@@ -1553,8 +1602,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn tree_live_controller_marks_transport_and_closes_source_on_pagehide() {
|
||||
assert!(TREE_LIVE_CONTROLLER_JS.contains("convex-command-log-sse"));
|
||||
assert!(TREE_LIVE_CONTROLLER_JS.contains("convex-command-log-ws"));
|
||||
assert!(TREE_LIVE_CONTROLLER_JS.contains("tree-live-sse"));
|
||||
assert!(TREE_LIVE_CONTROLLER_JS.contains("tree-live-ws"));
|
||||
assert!(TREE_LIVE_CONTROLLER_JS.contains("new WebSocket(url.toString())"));
|
||||
assert!(TREE_LIVE_CONTROLLER_JS.contains("startWithSseFallback"));
|
||||
assert!(TREE_LIVE_CONTROLLER_JS.contains("data-mnote-tree-live-transport"));
|
||||
|
||||
@@ -1651,8 +1651,8 @@ body {
|
||||
|
||||
.sidebar-tree .tree-row[data-active="true"],
|
||||
.sidebar-tree .tree-row[data-selected="true"] {
|
||||
background: rgba(255, 71, 71, 0.1);
|
||||
color: #E0525B;
|
||||
background: rgba(55, 53, 47, 0.08);
|
||||
color: #2D2E2E;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-row[data-drop-feedback="true"],
|
||||
@@ -1676,26 +1676,30 @@ body {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: 1;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-toggle:hover {
|
||||
background: rgba(27, 28, 28, 0.06);
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-toggle-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
.sidebar-tree .tree-toggle::before {
|
||||
content: "";
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 4px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
border-left: 5px solid currentColor;
|
||||
display: block;
|
||||
fill: #878787;
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-toggle[aria-expanded="true"] .tree-toggle-icon {
|
||||
.sidebar-tree .tree-row[aria-expanded="true"] > .tree-toggle::before {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-row[data-active="true"] .tree-toggle-icon {
|
||||
fill: #CF5659;
|
||||
.sidebar-tree .tree-row[data-active="true"] .tree-toggle {
|
||||
color: #8F8A84;
|
||||
}
|
||||
|
||||
.sidebar-tree:not([data-tree-shell-mode="filetree"]) .tree-kind-badge[data-kind="page"] {
|
||||
@@ -1703,58 +1707,137 @@ body {
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge {
|
||||
--mnote-filetree-icon-file: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 2h7l3 3v9H3zM10 2v3h3' fill='none' stroke='black' stroke-width='1.4'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-folder: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 4h5l1 2h8v8H1z' fill='none' stroke='black' stroke-width='1.4'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-markdown: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 2h5l3 3v9H4zM9 2v3h3M6 8h4M6 10h4M6 12h2' fill='none' stroke='black' stroke-width='1.35'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-table: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1.5 2.5h13v11h-13zM1.5 6h13M1.5 9.5h13M6 2.5v11m4-11v11' fill='none' stroke='black' stroke-width='1.4'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1.5 3h13v10h-13zM3 11l3-3 2 2 2-2 3 3M5 6h.1' fill='none' stroke='black' stroke-width='1.4'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-mindmap: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 4h3v3H3zM10 2h3v3h-3zM10 11h3v3h-3zM6 6l4-2M6 6l4 6' fill='none' stroke='black' stroke-width='1.4'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-pdf: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 2h7l3 3v9H3zM4.5 9h7M4.5 11h7M10 2v3h3' fill='none' stroke='black' stroke-width='1.4'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-word: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 2h10v12H3zM5 5h6M5 8h6M5 11h4' fill='none' stroke='black' stroke-width='1.4'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-ppt: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 3h12v8H2zM5 14h6M8 11v3M5 6h6M5 8h4' fill='none' stroke='black' stroke-width='1.4'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-sheet: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 2h12v12H2zM2 6h12M2 10h12M6 2v12m4-12v12' fill='none' stroke='black' stroke-width='1.4'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-code: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M5 5 2 8l3 3V9H4V7h1zm6 0v2h1v2h-1v2l3-3zm-2-2H7L5 13h2z'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-web: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M2 3h12v10H2zm1 3v6h10V6zm0-2v1h10V4z'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-config: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 4h10v2H3zm0 3h10v2H3zm0 3h10v2H3zM5 3h2v4H5zm4 3h2v4H9z'/%3E%3C/svg%3E");
|
||||
--mnote-filetree-icon-office: var(--mnote-filetree-icon-word);
|
||||
--mnote-filetree-icon-mask: var(--mnote-filetree-icon-file);
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 20px;
|
||||
color: #111111;
|
||||
font-size: 15px;
|
||||
color: #9A958F;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge::before {
|
||||
content: "□";
|
||||
font-family: var(--wolai-font-sans);
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
content: "";
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
display: block;
|
||||
background: currentColor;
|
||||
-webkit-mask: var(--mnote-filetree-icon-mask) center / contain no-repeat;
|
||||
mask: var(--mnote-filetree-icon-mask) center / contain no-repeat;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="page"]::before {
|
||||
content: "";
|
||||
--mnote-filetree-icon-mask: var(--mnote-filetree-icon-file);
|
||||
}
|
||||
|
||||
.sidebar-tree[data-tree-shell-mode="filetree"] .tree-kind-badge[data-kind="page"]::before,
|
||||
.sidebar-tree .tree-kind-badge[data-kind="document"]::before {
|
||||
content: "◇";
|
||||
--mnote-filetree-icon-mask: var(--mnote-filetree-icon-file);
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="index"]::before {
|
||||
content: "▤";
|
||||
color: var(--atelier-secondary);
|
||||
.sidebar-tree .tree-kind-badge[data-kind="index"]::before,
|
||||
.sidebar-tree .tree-kind-badge[data-kind="markdown"]::before {
|
||||
--mnote-filetree-icon-mask: var(--mnote-filetree-icon-markdown);
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="index"],
|
||||
.sidebar-tree .tree-kind-badge[data-kind="markdown"],
|
||||
.sidebar-tree .tree-kind-badge[data-kind="code"] {
|
||||
color: #111111;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="code"]::before { --mnote-filetree-icon-mask: var(--mnote-filetree-icon-code); }
|
||||
.sidebar-tree .tree-kind-badge[data-kind="web"]::before { --mnote-filetree-icon-mask: var(--mnote-filetree-icon-web); }
|
||||
.sidebar-tree .tree-kind-badge[data-kind="config"]::before { --mnote-filetree-icon-mask: var(--mnote-filetree-icon-config); }
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="folder"]::before,
|
||||
.sidebar-tree .tree-kind-badge[data-kind="asset_folder"]::before {
|
||||
content: "▱";
|
||||
color: #D08A1F;
|
||||
--mnote-filetree-icon-mask: var(--mnote-filetree-icon-folder);
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="folder"],
|
||||
.sidebar-tree .tree-kind-badge[data-kind="asset_folder"] {
|
||||
color: #B8751A;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="image"] {
|
||||
color: #5B6CF0;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="image"]::before {
|
||||
content: "▧";
|
||||
color: #5B7CFA;
|
||||
--mnote-filetree-icon-mask: var(--mnote-filetree-icon-image);
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="mindmap"] {
|
||||
color: #4F8F68;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="mindmap"]::before {
|
||||
content: "⌘";
|
||||
color: #31AA4D;
|
||||
--mnote-filetree-icon-mask: var(--mnote-filetree-icon-mindmap);
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="table"]::before,
|
||||
.sidebar-tree .tree-kind-badge[data-kind="luckysheet"]::before {
|
||||
content: "▦";
|
||||
color: #2367F6;
|
||||
.sidebar-tree .tree-kind-badge[data-kind="pdf"]::before {
|
||||
--mnote-filetree-icon-mask: var(--mnote-filetree-icon-pdf);
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="pdf"] {
|
||||
color: #E74C3C;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="office"]::before,
|
||||
.sidebar-tree .tree-kind-badge[data-kind="onlyoffice"]::before,
|
||||
.sidebar-tree .tree-kind-badge[data-kind="word"]::before {
|
||||
--mnote-filetree-icon-mask: var(--mnote-filetree-icon-word);
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="ppt"]::before,
|
||||
.sidebar-tree .tree-kind-badge[data-kind="presentation"]::before {
|
||||
--mnote-filetree-icon-mask: var(--mnote-filetree-icon-ppt);
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="sheet"]::before {
|
||||
--mnote-filetree-icon-mask: var(--mnote-filetree-icon-sheet);
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="office"],
|
||||
.sidebar-tree .tree-kind-badge[data-kind="onlyoffice"],
|
||||
.sidebar-tree .tree-kind-badge[data-kind="web"],
|
||||
.sidebar-tree .tree-kind-badge[data-kind="word"] {
|
||||
color: #4F7DF3;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="ppt"],
|
||||
.sidebar-tree .tree-kind-badge[data-kind="presentation"] {
|
||||
color: #D94841;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="sheet"] {
|
||||
color: #2F9E44;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="table"]::before {
|
||||
--mnote-filetree-icon-mask: var(--mnote-filetree-icon-table);
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-kind-badge[data-kind="table"],
|
||||
.sidebar-tree .tree-kind-badge[data-kind="config"] {
|
||||
color: #5572A2;
|
||||
}
|
||||
|
||||
.sidebar-tree .tree-link {
|
||||
@@ -2357,6 +2440,93 @@ body {
|
||||
grid-template-columns: minmax(0, 1fr) var(--mnote-secondary-pane-resizer-width) var(--mnote-secondary-pane-width);
|
||||
}
|
||||
|
||||
.mnote-navigation-page-host {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
background: var(--wolai-bg-main);
|
||||
}
|
||||
|
||||
.mnote-navigation-page {
|
||||
width: min(960px, calc(100% - 64px));
|
||||
margin: 0 auto;
|
||||
padding: 56px 0 96px;
|
||||
}
|
||||
|
||||
.mnote-navigation-page__header {
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.mnote-navigation-page__header h1 {
|
||||
margin: 0;
|
||||
font-size: 28px;
|
||||
font-weight: 650;
|
||||
line-height: 1.25;
|
||||
color: var(--wolai-text-primary);
|
||||
}
|
||||
|
||||
.mnote-navigation-page__header p {
|
||||
margin: 8px 0 0;
|
||||
color: var(--wolai-text-secondary);
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.mnote-navigation-page__section {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.mnote-navigation-page__notice {
|
||||
margin: 0 0 20px;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid rgba(210, 180, 90, 0.42);
|
||||
border-radius: 6px;
|
||||
background: rgba(255, 247, 221, 0.72);
|
||||
color: var(--wolai-text-primary);
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.mnote-navigation-page__notice span {
|
||||
display: block;
|
||||
margin-top: 4px;
|
||||
color: var(--wolai-text-secondary);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.mnote-navigation-page__section h2 {
|
||||
margin: 0 0 10px;
|
||||
font-size: 13px;
|
||||
font-weight: 650;
|
||||
color: var(--wolai-text-secondary);
|
||||
}
|
||||
|
||||
.mnote-navigation-page__section p {
|
||||
margin: 0;
|
||||
color: var(--wolai-text-secondary);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.mnote-navigation-page__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 34px;
|
||||
padding: 6px 8px;
|
||||
border-radius: 6px;
|
||||
color: var(--wolai-text-primary);
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
text-decoration: none;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.mnote-navigation-page__item:hover {
|
||||
background: var(--wolai-bg-sidebar);
|
||||
}
|
||||
|
||||
.document-main-editor-group {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
@@ -4236,6 +4406,20 @@ button.wolai-page-ai-message-text {
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
.wolai-page-ai-agent-selector,
|
||||
.wolai-page-ai-context-refs,
|
||||
.wolai-page-ai-allowed-roots {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 8px 0;
|
||||
}
|
||||
|
||||
.wolai-page-ai-allowed-roots {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.wolai-page-ai-composer:focus-within {
|
||||
border-color: rgba(27, 28, 28, 0.32);
|
||||
}
|
||||
@@ -4515,11 +4699,62 @@ mod tests {
|
||||
assert!(MNOTE_CSS.contains(".mnote-tree-context-menu"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sidebar_filetree_icons_use_css_masks_instead_of_text_glyphs() {
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-file"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-folder"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-markdown"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-table"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-image"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-mindmap"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-pdf"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-office"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-word"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-ppt"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-sheet"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-code"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-web"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-config"));
|
||||
assert!(MNOTE_CSS.contains("xmlns='http://www.w3.org/2000/svg'"));
|
||||
assert!(
|
||||
MNOTE_CSS.contains("mask: var(--mnote-filetree-icon-mask) center / contain no-repeat")
|
||||
);
|
||||
assert!(
|
||||
MNOTE_CSS.contains("--mnote-filetree-icon-mask: var(--mnote-filetree-icon-folder);")
|
||||
);
|
||||
assert!(
|
||||
MNOTE_CSS.contains("--mnote-filetree-icon-mask: var(--mnote-filetree-icon-markdown);")
|
||||
);
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-mask: var(--mnote-filetree-icon-table);"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-mask: var(--mnote-filetree-icon-image);"));
|
||||
assert!(
|
||||
MNOTE_CSS.contains("--mnote-filetree-icon-mask: var(--mnote-filetree-icon-mindmap);")
|
||||
);
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-mask: var(--mnote-filetree-icon-pdf);"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-mask: var(--mnote-filetree-icon-word);"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-mask: var(--mnote-filetree-icon-ppt);"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-mask: var(--mnote-filetree-icon-sheet);"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-mask: var(--mnote-filetree-icon-code);"));
|
||||
assert!(MNOTE_CSS.contains("--mnote-filetree-icon-mask: var(--mnote-filetree-icon-web);"));
|
||||
assert!(
|
||||
MNOTE_CSS.contains("--mnote-filetree-icon-mask: var(--mnote-filetree-icon-config);")
|
||||
);
|
||||
let retired_table_engine = ["lucky", "sheet"].concat();
|
||||
assert!(!MNOTE_CSS.contains(&retired_table_engine));
|
||||
assert!(MNOTE_CSS.contains("color: #4F7DF3;"));
|
||||
assert!(MNOTE_CSS.contains("color: #D94841;"));
|
||||
assert!(MNOTE_CSS.contains("color: #2F9E44;"));
|
||||
assert!(MNOTE_CSS.contains("color: #E74C3C;"));
|
||||
assert!(!MNOTE_CSS.contains(
|
||||
"font-family: var(--wolai-font-sans);\n font-size: 18px;\n line-height: 1;\n}"
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mnote_css_is_reasonably_sized() {
|
||||
// 至少 2000 字符才能包含完整样式
|
||||
assert!(MNOTE_CSS.len() > 2000);
|
||||
// 当前整合了工作区壳、编辑器样式、树菜单、页面 AI、账号弹窗与授权管理控制面,仍保持在单文件可审阅范围内。
|
||||
assert!(MNOTE_CSS.len() < 110000);
|
||||
// 当前整合了工作区壳、编辑器样式、树菜单、文件树图标、页面 AI、账号弹窗与授权管理控制面,仍保持在单文件可审阅范围内。
|
||||
assert!(MNOTE_CSS.len() < 114000);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user