收口 MNote P0 P1 P2 审查尾项
- 归档 OnlyOffice live bridge、Page AI、mindmap、design governance 与相关 bug 条目 - 补齐 MinerU OCR 后端 runtime 合同与 smoke/test 基线 - 收口 ChatOnly/Doubao、ObjectIdentity、Page Aggregate compat 与 runtime owner 文档口径 验证: - cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1 - cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_bridge -- --test-threads=1 - git diff --check - git diff --cached --check - codegraph index . --force && codegraph status . - codegraph sync . && codegraph status .
This commit is contained in:
@@ -15,6 +15,18 @@ export const firstNonEmptyText = (...values) => {
|
||||
return '';
|
||||
};
|
||||
|
||||
export const normalizeMindmapDimension = (value, kind) => {
|
||||
const raw = typeof value === 'number'
|
||||
? value
|
||||
: typeof value === 'string'
|
||||
? Number(value.trim().replace(/px$/i, ''))
|
||||
: NaN;
|
||||
if (!Number.isFinite(raw)) return null;
|
||||
const rounded = Math.round(raw);
|
||||
const min = kind === 'height' ? 240 : 900;
|
||||
return rounded >= min ? rounded : null;
|
||||
};
|
||||
|
||||
// 过渡适配(TODO step-4):legacy→Tiptap inline marks 转换函数组。
|
||||
// AST/block 迁移 complete 后,前端应直接消费 block document 中的
|
||||
// tiptap 格式 marks(已由 Rust 侧 local_markdown_parser 输出),
|
||||
@@ -125,19 +137,26 @@ export const legacyBlockToTiptap = (block, index = 0) => {
|
||||
}
|
||||
if (type === 'divider' || type === 'horizontalRule' || type === 'horizontal_rule') return { type: 'horizontalRule', attrs: { blockId } };
|
||||
if (type === 'mindmap') {
|
||||
const attrs = block?.attrs && typeof block.attrs === 'object' ? block.attrs : null;
|
||||
const data = block?.props?.data && typeof block.props.data === 'object' ? block.props.data : null;
|
||||
const mindmapId = firstNonEmptyText(
|
||||
block?.props?.mindmapId,
|
||||
block?.props?.mindmap_id,
|
||||
block?.props?.sourcePath,
|
||||
block?.props?.source_path,
|
||||
attrs?.mindmapId,
|
||||
attrs?.mindmap_id,
|
||||
attrs?.sourcePath,
|
||||
attrs?.source_path,
|
||||
block?.mindmapId,
|
||||
block?.mindmap_id,
|
||||
data?.mindmapId,
|
||||
data?.mindmap_id,
|
||||
data?.id
|
||||
);
|
||||
const rootNodeId = firstNonEmptyText(block?.props?.rootNodeId, block?.props?.root_node_id, data?.rootNodeId, data?.root_node_id) || 'root';
|
||||
const rootNodeId = firstNonEmptyText(block?.props?.rootNodeId, block?.props?.root_node_id, attrs?.rootNodeId, attrs?.root_node_id, data?.rootNodeId, data?.root_node_id) || 'root';
|
||||
const mindmapWidth = normalizeMindmapDimension(block?.props?.mindmapWidth ?? block?.props?.mindmap_width ?? attrs?.mindmapWidth ?? attrs?.mindmap_width ?? data?.mindmapWidth ?? data?.mindmap_width, 'width');
|
||||
const mindmapHeight = normalizeMindmapDimension(block?.props?.mindmapHeight ?? block?.props?.mindmap_height ?? attrs?.mindmapHeight ?? attrs?.mindmap_height ?? data?.mindmapHeight ?? data?.mindmap_height, 'height');
|
||||
return {
|
||||
type: 'paragraph',
|
||||
attrs: withTextAlign({
|
||||
@@ -145,6 +164,8 @@ export const legacyBlockToTiptap = (block, index = 0) => {
|
||||
mnoteBlockType: 'mindmap',
|
||||
mindmapId,
|
||||
rootNodeId,
|
||||
...(mindmapWidth !== null ? { mindmapWidth } : {}),
|
||||
...(mindmapHeight !== null ? { mindmapHeight } : {}),
|
||||
}),
|
||||
};
|
||||
}
|
||||
@@ -225,7 +246,9 @@ export const mindmapDomDescriptors = (root) => {
|
||||
const rootNodeId = typeof node.dataset.mnoteRootNodeId === 'string' && node.dataset.mnoteRootNodeId.trim()
|
||||
? node.dataset.mnoteRootNodeId.trim()
|
||||
: 'root';
|
||||
return [{ mindmapId, rootNodeId }];
|
||||
const mindmapWidth = normalizeMindmapDimension(node.dataset.mnoteMindmapWidth, 'width');
|
||||
const mindmapHeight = normalizeMindmapDimension(node.dataset.mnoteMindmapHeight, 'height');
|
||||
return [{ mindmapId, rootNodeId, mindmapWidth, mindmapHeight }];
|
||||
});
|
||||
};
|
||||
|
||||
@@ -246,6 +269,12 @@ export const hydrateMindmapAttrsFromDom = (tiptapDocument, root) => {
|
||||
if (typeof node.attrs.rootNodeId !== 'string' || !node.attrs.rootNodeId.trim()) {
|
||||
node.attrs.rootNodeId = descriptor.rootNodeId;
|
||||
}
|
||||
if (normalizeMindmapDimension(node.attrs.mindmapWidth, 'width') === null && descriptor.mindmapWidth !== null) {
|
||||
node.attrs.mindmapWidth = descriptor.mindmapWidth;
|
||||
}
|
||||
if (normalizeMindmapDimension(node.attrs.mindmapHeight, 'height') === null && descriptor.mindmapHeight !== null) {
|
||||
node.attrs.mindmapHeight = descriptor.mindmapHeight;
|
||||
}
|
||||
}
|
||||
return tiptapDocument;
|
||||
};
|
||||
@@ -445,20 +474,17 @@ export const localizeTiptapAssetUrls = (node, context) => {
|
||||
};
|
||||
|
||||
export const pageBodyTiptapDocumentSource = (body, fallbackText = '') => {
|
||||
const blockDocument = body?.blockDocument || body?.block_document || body?.editorDocument || body?.editor_document || null;
|
||||
if (blockDocument) return 'page_aggregate.block_document';
|
||||
if (String(body?.projectionSource || body?.projection_source || '') === 'local_markdown.content' && body?.content) {
|
||||
return 'local_markdown.content';
|
||||
}
|
||||
const blockDocument = body?.blockDocument || body?.block_document || body?.editorDocument || body?.editor_document || null;
|
||||
if (blockDocument) return 'page_aggregate.block_document';
|
||||
if (body?.content) return 'compat.legacy_content';
|
||||
return fallbackText ? 'degraded.fallback_text' : 'empty';
|
||||
};
|
||||
|
||||
export const pageBodyTiptapDocument = (body, fallbackText = '', context = null) => {
|
||||
const projectionContext = { ...(context || {}), body };
|
||||
if (pageBodyTiptapDocumentSource(body, fallbackText) === 'local_markdown.content') {
|
||||
return localizeTiptapAssetUrls(toTiptapDocument(body.content, fallbackText), projectionContext);
|
||||
}
|
||||
const blockDocument = body?.blockDocument || body?.block_document || body?.editorDocument || body?.editor_document || null;
|
||||
if (blockDocument) return localizeTiptapAssetUrls(toTiptapDocument(blockDocument, fallbackText), projectionContext);
|
||||
return localizeTiptapAssetUrls(toTiptapDocument(body?.content, fallbackText), projectionContext);
|
||||
@@ -533,10 +559,14 @@ export const mindmapPropsFromAttrs = (attrs, fallbackMindmapId) => {
|
||||
);
|
||||
const rootNodeId = firstNonEmptyText(attrs?.rootNodeId, attrs?.root_node_id, data?.rootNodeId, data?.root_node_id) || 'root';
|
||||
const projectionVersion = Number(attrs?.projectionVersion ?? attrs?.projection_version);
|
||||
const mindmapWidth = normalizeMindmapDimension(attrs?.mindmapWidth ?? attrs?.mindmap_width ?? data?.mindmapWidth ?? data?.mindmap_width, 'width');
|
||||
const mindmapHeight = normalizeMindmapDimension(attrs?.mindmapHeight ?? attrs?.mindmap_height ?? data?.mindmapHeight ?? data?.mindmap_height, 'height');
|
||||
return {
|
||||
mindmapId,
|
||||
rootNodeId,
|
||||
...(Number.isFinite(projectionVersion) ? { projectionVersion } : {}),
|
||||
...(mindmapWidth !== null ? { mindmapWidth } : {}),
|
||||
...(mindmapHeight !== null ? { mindmapHeight } : {}),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user