对齐 Wolai 编辑器搜索与文档画布

This commit is contained in:
lix-2026
2026-04-30 18:36:50 +08:00
parent afb2a5b8a0
commit 2b88ecb4b9
14 changed files with 317 additions and 138 deletions
+6 -4
View File
@@ -214,10 +214,10 @@ fn runtime_block_type_for_raw_type(raw_type: &str) -> (&'static str, bool) {
match raw_type {
"paragraph" => ("paragraph", true),
"heading" => ("heading", true),
"bulletListItem" => ("bullet_list_item", true),
"numberedListItem" => ("numbered_list_item", true),
"checkListItem" | "advancedTodo" => ("todo", true),
"quote" => ("quote", true),
"bulletListItem" | "bullet_list_item" => ("bullet_list_item", true),
"numberedListItem" | "numbered_list_item" => ("numbered_list_item", true),
"checkListItem" | "advancedTodo" | "todo" => ("todo", true),
"quote" | "blockquote" => ("quote", true),
"divider" => ("divider", true),
"codeBlock" => ("code_block", true),
"pageReference" => ("page_reference", false),
@@ -237,6 +237,8 @@ fn raw_type_for_runtime_block_type(block_type: &str, fallback_raw_type: &str) ->
"todo" => {
if fallback_raw_type == "advancedTodo" {
"advancedTodo".into()
} else if fallback_raw_type == "todo" {
"todo".into()
} else {
"checkListItem".into()
}
@@ -266,6 +266,22 @@ fn fallback_search_dataset(workspace_id: &str) -> Value {
"rawText": "mnote-web search documents transport",
"createdAt": "2026-04-28T00:00:00Z",
"updatedAt": "2026-04-28T00:00:00Z"
},
{
"id": "doc_hermes",
"workspaceId": workspace_id,
"title": "Hermes",
"rawText": "Hermes 技能知识图谱开发 Wolai aline fixture",
"createdAt": "2026-04-30T00:00:00Z",
"updatedAt": "2026-04-30T00:00:00Z"
},
{
"id": "doc_hermes_skill",
"workspaceId": workspace_id,
"title": "技能知识图谱开发",
"rawText": "Hermes 页面路径 个人 软件开发",
"createdAt": "2026-04-30T00:00:00Z",
"updatedAt": "2026-04-30T00:00:00Z"
}
],
"mindmaps": [],
@@ -315,16 +315,16 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
const level = Number(block?.props?.level || block?.level || 1) || 1;
return { type: 'heading', attrs: { level: Math.max(1, Math.min(6, level)) }, content };
}
if (type === 'bulletListItem') {
if (type === 'bulletListItem' || type === 'bullet_list_item') {
return { type: 'bulletList', content: [{ type: 'listItem', content: [{ type: 'paragraph', content }] }] };
}
if (type === 'numberedListItem') {
if (type === 'numberedListItem' || type === 'numbered_list_item') {
return { type: 'orderedList', content: [{ type: 'listItem', content: [{ type: 'paragraph', content }] }] };
}
if (type === 'checkListItem' || type === 'advancedTodo') {
if (type === 'checkListItem' || type === 'advancedTodo' || type === 'todo') {
return { type: 'taskList', content: [{ type: 'taskItem', attrs: { checked: Boolean(block?.props?.checked) }, content: [{ type: 'paragraph', content }] }] };
}
if (type === 'quote') {
if (type === 'quote' || type === 'blockquote') {
return { type: 'blockquote', content: [{ type: 'paragraph', content }] };
}
if (type === 'codeBlock') {
+113 -46
View File
@@ -663,33 +663,34 @@ const SIDEBAR_TREE_JS: &str = r##"
'<div class="wolai-search-dialog">' +
'<div class="wolai-search-input-row">' +
'<span class="material-symbols-outlined wolai-search-input-icon" data-icon="search" aria-hidden="true"></span>' +
'<input data-testid="wolai-search-input" class="wolai-search-input" type="text" autocomplete="off" placeholder="在当前工作区中搜索" />' +
'<input data-testid="wolai-search-input" class="wolai-search-input" type="search" autocomplete="off" placeholder="在当前工作区中搜索" />' +
'<button type="button" class="wolai-search-close" data-testid="wolai-search-close" aria-label="关闭搜索">×</button>' +
'</div>' +
'<div class="wolai-search-options" aria-label="搜索选项">' +
'<div class="wolai-search-options" data-testid="wolai-search-options" aria-label="搜索选项" hidden>' +
'<div class="wolai-search-options-left">' +
'<span class="wolai-search-switch-control"><span>仅匹配标题</span><button type="button" class="wolai-search-switch is-on" data-search-switch="title" role="switch" aria-checked="true" aria-label="仅匹配标题"></button></span>' +
'<span class="wolai-search-switch-control"><span>仅匹配标题</span><button type="button" class="wolai-search-switch" data-search-switch="title" role="switch" aria-checked="false" aria-label="仅匹配标题"></button></span>' +
'<span class="wolai-search-switch-control"><span>精确匹配</span><button type="button" class="wolai-search-switch" data-search-switch="exact" role="switch" aria-checked="false" aria-label="精确匹配"></button></span>' +
'<span class="wolai-search-sort-control"><span>按编辑时间</span><button type="button" class="wolai-search-sort-value" data-search-sort="updated" aria-label="按编辑时间范围">所有</button></span>' +
'<span class="wolai-search-sort-control"><span>按创建时间</span><button type="button" class="wolai-search-sort-value" data-search-sort="created" aria-label="按创建时间范围">所有</button></span>' +
'</div>' +
'<div class="wolai-search-options-right">' +
'<span class="wolai-search-switch-control"><span>页面内搜索</span><button type="button" class="wolai-search-switch is-on" data-search-switch="page" role="switch" aria-checked="true" aria-label="页面内搜索"></button></span>' +
'<span class="wolai-search-switch-control"><span>页面内搜索</span><button type="button" class="wolai-search-switch" data-search-switch="page" role="switch" aria-checked="false" aria-label="页面内搜索"></button></span>' +
'</div>' +
'</div>' +
'<div class="wolai-search-result-meta" data-testid="wolai-search-result-meta"></div>' +
'<div class="wolai-search-results" data-testid="wolai-search-results"></div>' +
'<div class="wolai-search-results" data-testid="wolai-search-results" data-search-results-owner="rust-kernel"></div>' +
'</div>';
document.body.appendChild(overlay);
var input = overlay.querySelector('[data-testid="wolai-search-input"]');
var closeButton = overlay.querySelector('[data-testid="wolai-search-close"]');
if (input) input.addEventListener('input', renderSearchResults);
if (input) input.addEventListener('input', scheduleSearchResultsRender);
overlay.querySelectorAll('[data-search-switch]').forEach(function(button) {
button.addEventListener('click', function() {
var isOn = button.getAttribute('aria-checked') !== 'true';
button.setAttribute('aria-checked', isOn ? 'true' : 'false');
button.classList.toggle('is-on', isOn);
scheduleSearchResultsRender();
});
});
if (closeButton) closeButton.addEventListener('click', closeSearchModal);
@@ -699,26 +700,33 @@ const SIDEBAR_TREE_JS: &str = r##"
return overlay;
}
var activeSearchRequestId = 0;
var searchRenderTimer = 0;
function searchText(value) {
return String(value == null ? '' : value).replace(/\s+/g, ' ').trim();
}
function collectSearchCandidates() {
var seen = Object.create(null);
var candidates = [];
function add(title, source) {
title = searchText(title);
if (!title || seen[title]) return;
seen[title] = true;
candidates.push({ title: title, source: source || '当前工作区' });
}
document.querySelectorAll('.tree-link-title, .wolai-row-title, [data-page-title-current="true"], .document-title-input, .document-read-view h1, .document-shell h1').forEach(function(node) {
add(node.textContent, '页面');
});
document.querySelectorAll('.mnote-content h1, .mnote-content h2, .mnote-content h3, .mnote-content p, .mnote-content a').forEach(function(node) {
add(node.textContent, '当前页面');
});
return candidates.slice(0, 120);
function currentWorkspaceName() {
var name = document.querySelector('.sidebar-workspace-name');
return searchText(name && name.textContent) || '当前工作区';
}
function currentDocumentId() {
var shell = document.querySelector('.document-shell[data-document-id]');
var bodyId = document.body && document.body.getAttribute('data-document-id');
return searchText(shell && shell.getAttribute('data-document-id')) || searchText(bodyId);
}
function searchSwitchValue(overlay, name) {
var button = overlay.querySelector('[data-search-switch="' + name + '"]');
return button instanceof HTMLElement && button.getAttribute('aria-checked') === 'true';
}
function highlightedHtml(value) {
return escapeHtml(value)
.replace(/&lt;mark&gt;/g, '<mark>')
.replace(/&lt;\/mark&gt;/g, '</mark>');
}
function highlightSearchTitle(title, query) {
@@ -732,31 +740,82 @@ const SIDEBAR_TREE_JS: &str = r##"
escapeHtml(cleanTitle.slice(index + cleanQuery.length));
}
function renderSearchResults() {
function renderSearchRecentState(overlay) {
var options = overlay.querySelector('[data-testid="wolai-search-options"]');
var meta = overlay.querySelector('[data-testid="wolai-search-result-meta"]');
var results = overlay.querySelector('[data-testid="wolai-search-results"]');
if (options instanceof HTMLElement) options.hidden = true;
if (meta) meta.innerHTML = '<span>最近浏览</span><span>Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开</span>';
if (results) {
results.innerHTML = '<div class="wolai-search-recent" data-testid="wolai-search-recent">暂无最近浏览</div>';
}
}
function scheduleSearchResultsRender() {
window.clearTimeout(searchRenderTimer);
searchRenderTimer = window.setTimeout(function() { void renderSearchResults(); }, 120);
}
async function renderSearchResults() {
var overlay = document.querySelector('[data-testid="wolai-search-modal"]');
if (!(overlay instanceof HTMLElement)) return;
var input = overlay.querySelector('[data-testid="wolai-search-input"]');
var options = overlay.querySelector('[data-testid="wolai-search-options"]');
var meta = overlay.querySelector('[data-testid="wolai-search-result-meta"]');
var results = overlay.querySelector('[data-testid="wolai-search-results"]');
if (!input || !meta || !results) return;
var query = searchText(input.value);
var candidates = collectSearchCandidates();
var filtered = query
? candidates.filter(function(item) { return item.title.toLowerCase().indexOf(query.toLowerCase()) >= 0; })
: candidates.slice(0, 8);
filtered = filtered.slice(0, 100);
meta.innerHTML = '<span>共 ' + filtered.length + ' 条匹配结果</span><span>Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开</span>';
if (!filtered.length) {
results.innerHTML = '<div class="wolai-search-empty">暂无匹配结果</div>';
if (!query) {
activeSearchRequestId += 1;
renderSearchRecentState(overlay);
return;
}
results.innerHTML = filtered.map(function(item) {
return '<button type="button" class="wolai-search-result-row">' +
'<span class="material-symbols-outlined wolai-search-result-icon" data-icon="link" aria-hidden="true"></span>' +
'<span class="wolai-search-result-main"><span class="wolai-search-result-title">' + highlightSearchTitle(item.title, query) + '</span>' +
'<span class="wolai-search-result-snippet">' + escapeHtml(item.source) + ' · 当前工作区</span></span>' +
'</button>';
}).join('');
if (options instanceof HTMLElement) options.hidden = false;
var requestId = ++activeSearchRequestId;
meta.innerHTML = '<span>搜索中…</span><span>Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开</span>';
results.innerHTML = '<div class="wolai-search-empty" data-search-loading="true">搜索中…</div>';
try {
var response = await fetch('/api/search/documents', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
workspaceId: resolveWorkspaceId(document.body),
documentId: currentDocumentId() || null,
query: query,
limit: 30,
filters: {
titleOnly: searchSwitchValue(overlay, 'title'),
exact: searchSwitchValue(overlay, 'exact'),
includeOcr: false,
onlyCurrentPage: searchSwitchValue(overlay, 'page'),
timeRange: 'any',
timeField: 'updated'
}
})
});
var payload = await response.json();
if (requestId !== activeSearchRequestId) return;
var items = Array.isArray(payload.results) ? payload.results : [];
meta.innerHTML = '<span>共 ' + items.length + ' 条匹配结果</span><span>Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开</span>';
if (!items.length) {
results.innerHTML = '<div class="wolai-search-empty" data-search-empty="true">没有搜索结果</div>';
return;
}
results.innerHTML = items.map(function(item) {
var title = searchText(item.title || item.name || item.documentTitle || '无标题');
var snippet = searchText(item.snippet || (Array.isArray(item.evidence) && item.evidence[0] && item.evidence[0].snippet) || '');
var path = searchText(item.path || item.parentTitle || item.workspaceName || currentWorkspaceName());
return '<button type="button" class="wolai-search-result-row" data-testid="wolai-search-result-row" data-search-result-owner="rust-kernel" data-document-id="' + escapeHtml(item.documentId || item.nodeId || item.id || '') + '">' +
'<span class="material-symbols-outlined wolai-search-result-icon" data-icon="article" aria-hidden="true"></span>' +
'<span class="wolai-search-result-main"><span class="wolai-search-result-title">' + highlightSearchTitle(title, query) + '</span>' +
'<span class="wolai-search-result-snippet">' + (snippet ? highlightedHtml(snippet) : escapeHtml(path)) + '</span></span>' +
'</button>';
}).join('');
} catch (error) {
if (requestId !== activeSearchRequestId) return;
meta.innerHTML = '<span>共 0 条匹配结果</span><span>Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开</span>';
results.innerHTML = '<div class="wolai-search-empty" data-search-empty="true">没有搜索结果</div>';
}
}
function isSearchModalOpen() {
@@ -768,8 +827,9 @@ const SIDEBAR_TREE_JS: &str = r##"
var overlay = ensureSearchModal();
overlay.hidden = false;
document.documentElement.setAttribute('data-mnote-search-modal-open', 'true');
renderSearchResults();
var input = overlay.querySelector('[data-testid="wolai-search-input"]');
if (input) input.setAttribute('placeholder', '在 ' + currentWorkspaceName() + ' 中搜索');
void renderSearchResults();
if (input) {
setTimeout(function() { input.focus(); input.select(); }, 0);
}
@@ -793,7 +853,12 @@ const SIDEBAR_TREE_JS: &str = r##"
var searchTrigger = closestAction(e.target, '[data-mnote-action="open-search-modal"]');
if (searchTrigger) {
e.preventDefault();
openSearchModal();
toggleSearchModal();
return;
}
var searchDialog = closestAction(e.target, '.wolai-search-dialog');
if (isSearchModalOpen() && !searchDialog) {
closeSearchModal();
return;
}
@@ -1305,7 +1370,7 @@ pub fn PageLayout(
<aside class="mnote-sidebar wolai-sidebar" data-testid="wolai-sidebar">
<div class="mnote-sidebar-header wolai-sidebar-header" data-testid="wolai-workspace-identity">
<a href="/" class="mnote-sidebar-brand wolai-avatar" aria-label="工作区首页">"L"</a>
<span class="sidebar-workspace-name">{ws_name}</span>
<span class="sidebar-workspace-name">{ws_name.clone()}</span>
<span class="wolai-sidebar-chevron" aria-hidden="true">""</span>
</div>
<nav class="mnote-sidebar-nav wolai-quick-actions" aria-label="快捷操作">
@@ -1326,17 +1391,19 @@ pub fn PageLayout(
<div class="wolai-topbar-left">
<button type="button" class="wolai-icon-button wolai-menu-button" aria-label="切换侧栏"><span class="material-symbols-outlined" data-icon="menu" aria-hidden="true"></span></button>
<nav class="wolai-breadcrumb" aria-label="页面路径">
<span class="wolai-breadcrumb-root">"The Digital Atelier"</span>
<span class="wolai-breadcrumb-separator" aria-hidden="true">"/"</span>
<span class="wolai-breadcrumb-root">{ws_name.clone()}</span>
<span class="wolai-breadcrumb-separator" aria-hidden="true">""</span>
<span class="wolai-breadcrumb-current"><span class="material-symbols-outlined wolai-home-icon" data-icon="home" aria-hidden="true"></span><span data-page-title-current="true">{topbar_title}</span></span>
</nav>
</div>
<div class="wolai-topbar-actions" aria-label="页面操作">
<span class="wolai-public-pill"><span aria-hidden="true">""</span>"Public"</span>
<span class="wolai-public-pill" data-testid="wolai-public-state">"全网公开"</span>
<button type="button" class="wolai-icon-button" title="收藏" aria-label="收藏"><span class="material-symbols-outlined" data-icon="star" aria-hidden="true"></span></button>
<button type="button" class="wolai-icon-button" title="演示" aria-label="演示"><span class="material-symbols-outlined" data-icon="slideshow" aria-hidden="true"></span></button>
<button type="button" class="wolai-icon-button" title="评论" aria-label="评论"><span class="material-symbols-outlined" data-icon="comment" aria-hidden="true"></span></button>
<button type="button" class="wolai-icon-button" title="分享" aria-label="分享"><span class="material-symbols-outlined" data-icon="share" aria-hidden="true"></span></button>
<button type="button" class="wolai-icon-button" title="成员" aria-label="成员"><span class="material-symbols-outlined" data-icon="person_add" aria-hidden="true"></span></button>
<button type="button" class="wolai-icon-button" title="历史" aria-label="历史"><span class="material-symbols-outlined" data-icon="history" aria-hidden="true"></span></button>
<button type="button" class="wolai-icon-button wolai-ai-inline" title="AI" aria-label="AI"><span class="material-symbols-outlined material-symbols-filled" data-icon="auto_awesome" aria-hidden="true"></span></button>
<button type="button" class="wolai-icon-button" title="搜索" aria-label="搜索" data-mnote-action="open-search-modal"><span class="material-symbols-outlined" data-icon="search" aria-hidden="true"></span></button>
<button type="button" class="wolai-icon-button" title="更多" aria-label="更多"><span class="material-symbols-outlined" data-icon="more_horiz" aria-hidden="true"></span></button>
</div>
</header>
+70 -64
View File
@@ -170,6 +170,11 @@ a:hover {
.material-symbols-outlined[data-icon="right_panel_open"] { --mnote-icon-mask: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4 5h16v14H4zM14 5v14M8 12h6M11 9l3 3-3 3' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.material-symbols-outlined[data-icon="open_in_new"] { --mnote-icon-mask: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 6H5v13h13v-3M12 5h7v7M10 14 19 5' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.material-symbols-outlined[data-icon="share"] { --mnote-icon-mask: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='18' cy='5' r='3' fill='none' stroke='black' stroke-width='2'/%3E%3Ccircle cx='6' cy='12' r='3' fill='none' stroke='black' stroke-width='2'/%3E%3Ccircle cx='18' cy='19' r='3' fill='none' stroke='black' stroke-width='2'/%3E%3Cpath d='m8.7 10.7 6.6-4.4M8.7 13.3l6.6 4.4' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E"); }
.material-symbols-outlined[data-icon="comment"] { --mnote-icon-mask: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5 5h14v10H9l-4 4V5Z' fill='none' stroke='black' stroke-width='2' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.material-symbols-outlined[data-icon="person_add"] { --mnote-icon-mask: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='9' cy='8' r='3.2' fill='none' stroke='black' stroke-width='2'/%3E%3Cpath d='M3.5 20a5.5 5.5 0 0 1 11 0M18 8v6M15 11h6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E"); }
.material-symbols-outlined[data-icon="slideshow"] { --mnote-icon-mask: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4 5h16v12H4z' fill='none' stroke='black' stroke-width='2' stroke-linejoin='round'/%3E%3Cpath d='m10 9 5 2-5 2zM9 21h6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.material-symbols-outlined[data-icon="article"] { --mnote-icon-mask: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6 4h12v16H6zM9 8h6M9 12h6M9 16h4' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.material-symbols-outlined[data-icon="link"] { --mnote-icon-mask: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9.5 14.5 14.5 9.5M10.8 6.2l1.1-1.1a4 4 0 0 1 5.7 5.7l-1.6 1.6M13.2 17.8l-1.1 1.1a4 4 0 0 1-5.7-5.7L8 11.6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E"); }
.material-symbols-outlined[data-icon="content_copy"],
.material-symbols-outlined[data-icon="file_copy"] { --mnote-icon-mask: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 8h10v12H8zM6 16H4V4h10v2' fill='none' stroke='black' stroke-width='2' stroke-linejoin='round'/%3E%3C/svg%3E"); }
@@ -912,15 +917,17 @@ a:hover {
/* ===== 响应式 ===== */
.wolai-search-overlay{position:fixed;inset:0;z-index:1200;display:flex;align-items:flex-start;justify-content:center;padding:92px 24px 24px;background:rgba(0,0,0,.32)}
.wolai-search-overlay{position:fixed;inset:0;z-index:1200;display:flex;align-items:flex-start;justify-content:center;padding:92px 24px 24px;background:rgba(0,0,0,.32);pointer-events:none}
.wolai-search-overlay[hidden]{display:none!important}
.wolai-search-dialog{width:min(680px,100%);max-height:min(720px,calc(100vh - 128px));overflow:hidden;display:flex;flex-direction:column;background:#FFF;border:1px solid rgba(27,28,28,.10);border-radius:6px;box-shadow:0 18px 48px rgba(15,23,42,.22),0 2px 8px rgba(15,23,42,.08);color:#37352F}
.wolai-search-dialog{width:min(680px,100%);max-height:min(720px,calc(100vh - 128px));overflow:hidden;display:flex;flex-direction:column;background:#FFF;border:1px solid rgba(27,28,28,.10);border-radius:6px;box-shadow:0 18px 48px rgba(15,23,42,.22),0 2px 8px rgba(15,23,42,.08);color:#37352F;pointer-events:auto}
.wolai-search-input-row{display:flex;align-items:center;min-height:58px;padding:0 12px 0 18px;border-bottom:1px solid rgba(27,28,28,.08)}
.wolai-search-input-icon{width:22px;height:22px;color:#8B8780;margin-right:10px}
.wolai-search-input{flex:1 1 auto;min-width:0;height:56px;border:0;outline:none;background:transparent;color:#24211D;font:400 18px/1.4 var(--wolai-font-sans);letter-spacing:0}
.wolai-search-input::placeholder{color:#A29E97}
.wolai-search-input::-webkit-search-cancel-button{appearance:none;-webkit-appearance:none;display:none}
.wolai-search-close{width:28px;height:28px;border:0;border-radius:4px;background:transparent;color:#8B8780;cursor:pointer;font-size:20px;line-height:1}
.wolai-search-options{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 14px 8px;border-bottom:1px solid rgba(27,28,28,.06);color:#A7A39D;font-size:12px;line-height:1}
.wolai-search-options[hidden]{display:none!important}
.wolai-search-options-left,.wolai-search-options-right,.wolai-search-switch-control,.wolai-search-sort-control{display:inline-flex;align-items:center}
.wolai-search-options-left{min-width:0;flex-wrap:wrap;gap:8px 12px}
.wolai-search-options-right{margin-left:auto;flex:0 0 auto}
@@ -939,9 +946,9 @@ a:hover {
.wolai-search-result-icon{width:18px;height:18px;margin-top:2px;color:#8B8780}
.wolai-search-result-main{min-width:0;display:flex;flex-direction:column;gap:3px}
.wolai-search-result-title{color:#2F2D29;font-size:14px;line-height:1.35;word-break:break-word}
.wolai-search-result-title mark{padding:0 1px;border-radius:2px;background:#FFE9E6;color:#D83A32}
.wolai-search-result-title mark,.wolai-search-result-snippet mark{padding:0 1px;border-radius:2px;background:#FFE9E6;color:#D83A32}
.wolai-search-result-snippet,.wolai-search-empty{color:#8B8780;font-size:12px;line-height:1.35}
.wolai-search-empty{padding:28px 12px 32px;text-align:center}
.wolai-search-empty,.wolai-search-recent{padding:28px 12px 32px;text-align:center;color:#8B8780;font-size:12px;line-height:1.35}
@media (max-width: 768px) {
.mnote-sidebar {
@@ -963,6 +970,7 @@ a:hover {
.document-shell-header h1 {
font-size: 28px;
line-height: 36px;
}
#mnote-editor-island {
@@ -1555,7 +1563,7 @@ body {
}
.wolai-topbar {
height: 44px;
height: 40px;
padding: 0 20px 0 22px;
background: rgba(255, 255, 255, 0.92);
color: #5A5A5A;
@@ -1626,22 +1634,17 @@ body {
}
.wolai-public-pill {
height: 26px;
height: 22px;
display: inline-flex;
align-items: center;
gap: 5px;
padding: 0 11px;
border: 1px solid #D6F2DC;
border-radius: 999px;
padding: 0 8px;
border: 0;
border-radius: 3px;
background: #ECFCEF;
color: #087B31;
font-size: 12px;
font-weight: 600;
}
.wolai-public-pill span {
color: var(--atelier-primary-container);
font-size: 12px;
font-weight: 500;
}
.wolai-ai-inline {
@@ -1649,25 +1652,21 @@ body {
}
.document-shell {
max-width: 880px;
min-height: calc(100vh - 44px);
padding: 78px 48px 160px;
box-sizing: border-box;
width: min(100%, 760px);
min-height: calc(100vh - 40px);
padding: 68px 0 160px;
margin: 0 auto;
}
.document-shell-header {
max-width: none;
padding: 0;
margin: 0 0 28px;
margin: 0 0 50px;
}
.document-page-icon {
height: 82px;
display: flex;
align-items: center;
color: #111111;
line-height: 1;
margin-bottom: 12px;
display: none;
}
.mnote-material-page-icon {
@@ -1683,18 +1682,18 @@ body {
.document-title-heading,
.document-shell-header h1 {
padding: 0;
margin: 0 0 14px;
margin: 0;
color: var(--atelier-text);
font-size: 42px;
font-weight: 700;
line-height: 1.12;
font-size: 34px;
font-weight: 600;
line-height: 44px;
letter-spacing: 0;
text-align: left;
}
.document-title-input {
width: 100%;
min-height: 52px;
min-height: 44px;
display: block;
resize: none;
overflow: hidden;
@@ -1719,15 +1718,7 @@ body {
}
.document-shell-meta {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 18px;
padding-bottom: 28px;
border-bottom: 1px solid #F0EFED;
color: #A19D97;
font-size: 14px;
line-height: 1.4;
display: none;
}
.document-shell-meta span {
@@ -1759,7 +1750,7 @@ body {
.ProseMirror {
color: var(--atelier-text);
font-size: 16px;
line-height: 1.65;
line-height: 24px;
outline: none;
}
@@ -1789,7 +1780,33 @@ body {
}
#mnote-leptos-tiptap-island-editor-root .ProseMirror p {
margin: 0 0 24px;
margin: 0 0 8px;
}
#mnote-leptos-tiptap-island-editor-root .ProseMirror ul,
#mnote-leptos-tiptap-island-editor-root .ProseMirror ol {
margin: 4px 0 8px;
padding-left: 1.5em;
}
#mnote-leptos-tiptap-island-editor-root .ProseMirror li {
margin: 2px 0;
padding-left: 2px;
}
#mnote-leptos-tiptap-island-editor-root .ProseMirror blockquote {
margin: 8px 0;
padding: 2px 0 2px 14px;
border-left: 3px solid #D9D6D0;
color: #5F5B56;
}
#mnote-leptos-tiptap-island-editor-root .ProseMirror input[type="checkbox"] {
width: 16px;
height: 16px;
margin: 0 8px 0 0;
vertical-align: -3px;
accent-color: #2EA44F;
}
#mnote-leptos-tiptap-island-editor-root .ProseMirror h1,
@@ -1823,8 +1840,9 @@ body {
.wolai-floating-actions {
right: 24px;
bottom: 24px;
gap: 10px;
bottom: 44px;
flex-direction: column-reverse;
gap: 16px;
z-index: 50;
}
@@ -1848,13 +1866,13 @@ body {
}
.wolai-floating-button--ai {
width: 52px;
height: 52px;
border: 0;
background: linear-gradient(135deg, var(--atelier-primary), var(--atelier-primary-container));
color: #FFFFFF;
box-shadow: 0 16px 32px rgba(0, 110, 40, 0.22);
font-size: 23px;
width: 40px;
height: 40px;
border: 1px solid rgba(27, 28, 28, 0.1);
background: #FFFFFF;
color: #5A5A5A;
box-shadow: 0 10px 24px rgba(27, 28, 28, 0.08);
font-size: 18px;
}
@media (max-width: 768px) {
@@ -1874,25 +1892,13 @@ body {
}
.document-shell {
width: 100%;
padding: 48px 28px 120px;
}
.document-page-icon {
height: 60px;
}
.mnote-material-page-icon {
width: 48px;
height: 48px;
font-size: 48px;
}
.mnote-material-page-icon::before {
font-size: 48px;
}
.document-shell-header h1 {
font-size: 32px;
line-height: 40px;
}
#mnote-leptos-tiptap-island-editor-root .block-handle-shell {