D164: 登记Tolaria光湖定制版源码补丁
This commit is contained in:
parent
64340534c0
commit
a3cce320ab
44
products/tolaria-guanghu/README.hdlp
Normal file
44
products/tolaria-guanghu/README.hdlp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
id: DEV-TOL-SRC-001
|
||||||
|
protocol: HLDP
|
||||||
|
product: Tolaria光湖定制版
|
||||||
|
upstream: https://github.com/refactoringhq/tolaria
|
||||||
|
upstream_commit: af6891b0af725a219427eb0ff056cbc719e40812
|
||||||
|
local_commit: 9bd612c
|
||||||
|
status: installed
|
||||||
|
maintainer: ICE-GL-ZY001
|
||||||
|
receipt: CC-074
|
||||||
|
---
|
||||||
|
|
||||||
|
# Tolaria光湖定制版 · 源码补丁入口
|
||||||
|
|
||||||
|
## 当前补丁
|
||||||
|
|
||||||
|
`patches/0001-feat-add-plain-click-wikilinks-and-Guanghu-portal-bl.patch`
|
||||||
|
|
||||||
|
包含:
|
||||||
|
|
||||||
|
1. 富文本wikilink普通鼠标单击跳转。
|
||||||
|
2. 中文、Emoji与Notion长编号后缀回归测试。
|
||||||
|
3. `guanghu-portal` Markdown持久化组件。
|
||||||
|
4. 光湖入口卡富文本渲染样式。
|
||||||
|
|
||||||
|
## 恢复方法
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/refactoringhq/tolaria.git
|
||||||
|
cd tolaria
|
||||||
|
git checkout af6891b0af725a219427eb0ff056cbc719e40812
|
||||||
|
git am /path/to/0001-feat-add-plain-click-wikilinks-and-Guanghu-portal-bl.patch
|
||||||
|
```
|
||||||
|
|
||||||
|
## 已验证
|
||||||
|
|
||||||
|
- 4873项前端测试通过。
|
||||||
|
- TypeScript/Vite生产构建通过。
|
||||||
|
- Tauri macOS原生构建通过。
|
||||||
|
- 安装位置:`/Applications/Tolaria.app`
|
||||||
|
- 官方回退版:`/Applications/Tolaria-Official-2026.7.1.app`
|
||||||
|
|
||||||
|
> 认知链与桌面验收见 CC-074。
|
||||||
|
|
||||||
@ -0,0 +1,391 @@
|
|||||||
|
From 9bd612ca137fb1f40b5ddd022a68a73b2f38eb98 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?=E9=93=B8=E6=B8=8A?= <zhuyuan@guanghu.local>
|
||||||
|
Date: Fri, 3 Jul 2026 13:43:14 +0800
|
||||||
|
Subject: [PATCH] feat: add plain-click wikilinks and Guanghu portal block
|
||||||
|
|
||||||
|
---
|
||||||
|
src/components/Editor.css | 44 +++++++++
|
||||||
|
src/components/editorSchema.tsx | 39 ++++++++
|
||||||
|
.../useEditorLinkActivation.test.tsx | 11 +--
|
||||||
|
src/components/useEditorLinkActivation.ts | 2 -
|
||||||
|
src/utils/editorDurableMarkdown.ts | 2 +
|
||||||
|
src/utils/guanghuPortalMarkdown.test.ts | 38 ++++++++
|
||||||
|
src/utils/guanghuPortalMarkdown.ts | 93 +++++++++++++++++++
|
||||||
|
src/utils/wikilink.test.ts | 23 +++++
|
||||||
|
8 files changed, 243 insertions(+), 9 deletions(-)
|
||||||
|
create mode 100644 src/utils/guanghuPortalMarkdown.test.ts
|
||||||
|
create mode 100644 src/utils/guanghuPortalMarkdown.ts
|
||||||
|
|
||||||
|
diff --git a/src/components/Editor.css b/src/components/Editor.css
|
||||||
|
index 39866cc..499b72f 100644
|
||||||
|
--- a/src/components/Editor.css
|
||||||
|
+++ b/src/components/Editor.css
|
||||||
|
@@ -22,6 +22,50 @@
|
||||||
|
opacity: 0.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
+.guanghu-portal-card {
|
||||||
|
+ width: 100%;
|
||||||
|
+ margin: 0.5rem 0;
|
||||||
|
+ padding: 1rem 1.1rem;
|
||||||
|
+ border: 1px solid color-mix(in srgb, var(--colors-accent) 38%, var(--colors-border));
|
||||||
|
+ border-radius: 0.85rem;
|
||||||
|
+ background:
|
||||||
|
+ radial-gradient(circle at top right, color-mix(in srgb, var(--colors-accent) 16%, transparent), transparent 48%),
|
||||||
|
+ var(--colors-surface);
|
||||||
|
+ box-shadow: 0 0.35rem 1.25rem color-mix(in srgb, black 10%, transparent);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+.guanghu-portal-card__eyebrow {
|
||||||
|
+ display: flex;
|
||||||
|
+ align-items: center;
|
||||||
|
+ justify-content: space-between;
|
||||||
|
+ gap: 0.75rem;
|
||||||
|
+ margin-bottom: 0.55rem;
|
||||||
|
+ color: var(--colors-text-muted);
|
||||||
|
+ font-size: 0.72rem;
|
||||||
|
+ letter-spacing: 0.08em;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+.guanghu-portal-card__status {
|
||||||
|
+ padding: 0.18rem 0.55rem;
|
||||||
|
+ border-radius: 999px;
|
||||||
|
+ background: color-mix(in srgb, var(--colors-accent) 18%, transparent);
|
||||||
|
+ color: var(--colors-text);
|
||||||
|
+ letter-spacing: normal;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+.guanghu-portal-card__title {
|
||||||
|
+ display: inline-flex;
|
||||||
|
+ font-size: 1.08rem;
|
||||||
|
+ font-weight: 650;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+.guanghu-portal-card__description {
|
||||||
|
+ margin: 0.45rem 0 0;
|
||||||
|
+ color: var(--colors-text-muted);
|
||||||
|
+ font-size: 0.9rem;
|
||||||
|
+ line-height: 1.55;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Breadcrumb bar: border can still react to the data attribute, but the
|
||||||
|
breadcrumb filename/title stays visible at all times. */
|
||||||
|
.breadcrumb-bar {
|
||||||
|
diff --git a/src/components/editorSchema.tsx b/src/components/editorSchema.tsx
|
||||||
|
index 769cec2..2984eff 100644
|
||||||
|
--- a/src/components/editorSchema.tsx
|
||||||
|
+++ b/src/components/editorSchema.tsx
|
||||||
|
@@ -24,6 +24,7 @@ import { MATH_BLOCK_TYPE, MATH_INLINE_TYPE, renderMathToHtml } from '../utils/ma
|
||||||
|
import { MERMAID_BLOCK_TYPE, mermaidFenceSource } from '../utils/mermaidMarkdown'
|
||||||
|
import { TLDRAW_BLOCK_TYPE, TLDRAW_DEFAULT_HEIGHT } from '../utils/tldrawMarkdown'
|
||||||
|
import { MARKDOWN_HIGHLIGHT_STYLE } from '../utils/markdownHighlightMarkdown'
|
||||||
|
+import { GUANGHU_PORTAL_BLOCK_TYPE } from '../utils/guanghuPortalMarkdown'
|
||||||
|
import type { VaultEntry } from '../types'
|
||||||
|
import { createTolariaCodeBlockOptions } from './codeBlockOptions'
|
||||||
|
import { NoteTitleIcon } from './NoteTitleIcon'
|
||||||
|
@@ -313,6 +314,42 @@ const MermaidBlock = createReactBlockSpec(
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
+const GuanghuPortalBlock = createReactBlockSpec(
|
||||||
|
+ {
|
||||||
|
+ type: GUANGHU_PORTAL_BLOCK_TYPE,
|
||||||
|
+ propSchema: {
|
||||||
|
+ source: { default: '' },
|
||||||
|
+ title: { default: '光湖入口' },
|
||||||
|
+ target: { default: '' },
|
||||||
|
+ description: { default: '' },
|
||||||
|
+ status: { default: '' },
|
||||||
|
+ },
|
||||||
|
+ content: 'none',
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ runsBefore: ['codeBlock'],
|
||||||
|
+ render: props => (
|
||||||
|
+ <article className="guanghu-portal-card" contentEditable={false}>
|
||||||
|
+ <div className="guanghu-portal-card__eyebrow">
|
||||||
|
+ <span>HLDP · 光湖入口</span>
|
||||||
|
+ {props.block.props.status ? (
|
||||||
|
+ <span className="guanghu-portal-card__status">{props.block.props.status}</span>
|
||||||
|
+ ) : null}
|
||||||
|
+ </div>
|
||||||
|
+ <span
|
||||||
|
+ className="guanghu-portal-card__title wikilink"
|
||||||
|
+ data-target={props.block.props.target}
|
||||||
|
+ >
|
||||||
|
+ {props.block.props.title}
|
||||||
|
+ </span>
|
||||||
|
+ {props.block.props.description ? (
|
||||||
|
+ <p className="guanghu-portal-card__description">{props.block.props.description}</p>
|
||||||
|
+ ) : null}
|
||||||
|
+ </article>
|
||||||
|
+ ),
|
||||||
|
+ },
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
export function mediaBlockPropsForPreviewRuntime<T extends MediaBlockPreviewProps>(
|
||||||
|
props: T,
|
||||||
|
externalMediaPreview: boolean,
|
||||||
|
@@ -412,6 +449,7 @@ const TldrawBlock = createReactBlockSpec(
|
||||||
|
const codeBlock = createCodeBlockSpec(createTolariaCodeBlockOptions())
|
||||||
|
const audioBlock = AudioBlockSpec()
|
||||||
|
const mathBlock = MathBlock()
|
||||||
|
+const guanghuPortalBlock = GuanghuPortalBlock()
|
||||||
|
const mermaidBlock = MermaidBlock()
|
||||||
|
const tldrawBlock = TldrawBlock()
|
||||||
|
const videoBlock = VideoBlockSpec()
|
||||||
|
@@ -446,6 +484,7 @@ export const schema = BlockNoteSchema.create({
|
||||||
|
},
|
||||||
|
blockSpecs: {
|
||||||
|
audio: audioBlock,
|
||||||
|
+ guanghuPortalBlock,
|
||||||
|
mathBlock,
|
||||||
|
mermaidBlock,
|
||||||
|
tldrawBlock,
|
||||||
|
diff --git a/src/components/useEditorLinkActivation.test.tsx b/src/components/useEditorLinkActivation.test.tsx
|
||||||
|
index 2234d5c..ab3b62a 100644
|
||||||
|
--- a/src/components/useEditorLinkActivation.test.tsx
|
||||||
|
+++ b/src/components/useEditorLinkActivation.test.tsx
|
||||||
|
@@ -77,22 +77,18 @@ describe('useEditorLinkActivation', () => {
|
||||||
|
mockOpenLocalFile.mockClear()
|
||||||
|
})
|
||||||
|
|
||||||
|
- it('navigates wikilinks only on Cmd+click after the native click stack settles', async () => {
|
||||||
|
+ it('navigates wikilinks on a plain click after the native click stack settles', async () => {
|
||||||
|
const { container, onNavigateWikilink } = renderHarness()
|
||||||
|
const wikilink = appendWikilink(container, 'Alpha Project')
|
||||||
|
|
||||||
|
dispatchMouseEvent(wikilink, 'click')
|
||||||
|
expect(onNavigateWikilink).not.toHaveBeenCalled()
|
||||||
|
|
||||||
|
- const modifiedClick = dispatchMouseEvent(wikilink, 'click', { metaKey: true })
|
||||||
|
- expect(modifiedClick.defaultPrevented).toBe(true)
|
||||||
|
- expect(onNavigateWikilink).not.toHaveBeenCalled()
|
||||||
|
-
|
||||||
|
await Promise.resolve()
|
||||||
|
expect(onNavigateWikilink).toHaveBeenCalledWith('Alpha Project')
|
||||||
|
})
|
||||||
|
|
||||||
|
- it('consumes plain wikilink mousedown and click events before editor internals see stale link nodes', () => {
|
||||||
|
+ it('consumes plain wikilink events before editor internals see stale link nodes', async () => {
|
||||||
|
const { container, onNavigateWikilink } = renderHarness()
|
||||||
|
const wikilink = appendWikilink(container, 'Alpha Project')
|
||||||
|
|
||||||
|
@@ -101,7 +97,8 @@ describe('useEditorLinkActivation', () => {
|
||||||
|
|
||||||
|
expect(mouseDown.defaultPrevented).toBe(true)
|
||||||
|
expect(click.defaultPrevented).toBe(true)
|
||||||
|
- expect(onNavigateWikilink).not.toHaveBeenCalled()
|
||||||
|
+ await Promise.resolve()
|
||||||
|
+ expect(onNavigateWikilink).toHaveBeenCalledWith('Alpha Project')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('blurs an active editor before navigating a Cmd-clicked wikilink', async () => {
|
||||||
|
diff --git a/src/components/useEditorLinkActivation.ts b/src/components/useEditorLinkActivation.ts
|
||||||
|
index aa80834..f29c624 100644
|
||||||
|
--- a/src/components/useEditorLinkActivation.ts
|
||||||
|
+++ b/src/components/useEditorLinkActivation.ts
|
||||||
|
@@ -56,8 +56,6 @@ function activateWikilink(
|
||||||
|
) {
|
||||||
|
consumeEditorLinkEvent(event)
|
||||||
|
|
||||||
|
- if (!hasFollowModifier(event)) return
|
||||||
|
-
|
||||||
|
blurActiveEditable(container)
|
||||||
|
scheduleAfterNativeClick(() => onNavigateWikilink(target))
|
||||||
|
}
|
||||||
|
diff --git a/src/utils/editorDurableMarkdown.ts b/src/utils/editorDurableMarkdown.ts
|
||||||
|
index f0234f1..6e6d30a 100644
|
||||||
|
--- a/src/utils/editorDurableMarkdown.ts
|
||||||
|
+++ b/src/utils/editorDurableMarkdown.ts
|
||||||
|
@@ -15,8 +15,10 @@ import { restoreMarkdownHighlightsInBlocks } from './markdownHighlightMarkdown'
|
||||||
|
import { serializeMathAwareBlocks } from './mathMarkdown'
|
||||||
|
import { mermaidMarkdownCodec } from './mermaidMarkdown'
|
||||||
|
import { tldrawMarkdownCodec } from './tldrawMarkdown'
|
||||||
|
+import { guanghuPortalMarkdownCodec } from './guanghuPortalMarkdown'
|
||||||
|
|
||||||
|
const EDITOR_DURABLE_MARKDOWN_CODECS = [
|
||||||
|
+ guanghuPortalMarkdownCodec,
|
||||||
|
mermaidMarkdownCodec,
|
||||||
|
tldrawMarkdownCodec,
|
||||||
|
] as const
|
||||||
|
diff --git a/src/utils/guanghuPortalMarkdown.test.ts b/src/utils/guanghuPortalMarkdown.test.ts
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..9bb518a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/utils/guanghuPortalMarkdown.test.ts
|
||||||
|
@@ -0,0 +1,38 @@
|
||||||
|
+import { describe, expect, it } from 'vitest'
|
||||||
|
+import {
|
||||||
|
+ GUANGHU_PORTAL_BLOCK_TYPE,
|
||||||
|
+ guanghuPortalMarkdownCodec,
|
||||||
|
+} from './guanghuPortalMarkdown'
|
||||||
|
+import {
|
||||||
|
+ injectDurableMarkdownBlocks,
|
||||||
|
+ preProcessDurableMarkdownBlocks,
|
||||||
|
+ serializeDurableMarkdownBlocks,
|
||||||
|
+} from './durableMarkdownBlocks'
|
||||||
|
+
|
||||||
|
+const SOURCE = `\`\`\`guanghu-portal
|
||||||
|
+{"title":"铸渊主控台","target":"🌳 铸渊 · Tolaria编号嵌套树 · NAV-CODE-TREE-001","description":"进入现实执行层","status":"运行中"}
|
||||||
|
+\`\`\`
|
||||||
|
+`
|
||||||
|
+
|
||||||
|
+describe('guanghuPortalMarkdownCodec', () => {
|
||||||
|
+ it('round-trips a Guanghu portal card through the rich editor pipeline', () => {
|
||||||
|
+ const processed = preProcessDurableMarkdownBlocks({
|
||||||
|
+ markdown: SOURCE,
|
||||||
|
+ codecs: [guanghuPortalMarkdownCodec],
|
||||||
|
+ })
|
||||||
|
+ const blocks = injectDurableMarkdownBlocks({
|
||||||
|
+ blocks: [{ type: 'paragraph', content: [{ type: 'text', text: processed.trim() }] }],
|
||||||
|
+ codecs: [guanghuPortalMarkdownCodec],
|
||||||
|
+ }) as Array<{ type: string; props: Record<string, string> }>
|
||||||
|
+
|
||||||
|
+ expect(blocks[0]?.type).toBe(GUANGHU_PORTAL_BLOCK_TYPE)
|
||||||
|
+ expect(blocks[0]?.props.title).toBe('铸渊主控台')
|
||||||
|
+ expect(blocks[0]?.props.target).toContain('铸渊')
|
||||||
|
+
|
||||||
|
+ expect(serializeDurableMarkdownBlocks({
|
||||||
|
+ blocks,
|
||||||
|
+ codecs: [guanghuPortalMarkdownCodec],
|
||||||
|
+ serializeOrdinaryBlocks: () => '',
|
||||||
|
+ })).toBe(SOURCE)
|
||||||
|
+ })
|
||||||
|
+})
|
||||||
|
diff --git a/src/utils/guanghuPortalMarkdown.ts b/src/utils/guanghuPortalMarkdown.ts
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..f083b25
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/utils/guanghuPortalMarkdown.ts
|
||||||
|
@@ -0,0 +1,93 @@
|
||||||
|
+import {
|
||||||
|
+ type BlockLike,
|
||||||
|
+ type DurableBlockCodec,
|
||||||
|
+ type DurableFencePayloadInput,
|
||||||
|
+} from './durableMarkdownBlocks'
|
||||||
|
+
|
||||||
|
+export const GUANGHU_PORTAL_BLOCK_TYPE = 'guanghuPortalBlock'
|
||||||
|
+
|
||||||
|
+const TOKEN_PREFIX = '@@TOLARIA_GUANGHU_PORTAL:'
|
||||||
|
+const TOKEN_SUFFIX = '@@'
|
||||||
|
+
|
||||||
|
+export interface GuanghuPortalPayload {
|
||||||
|
+ source: string
|
||||||
|
+ title: string
|
||||||
|
+ target: string
|
||||||
|
+ description: string
|
||||||
|
+ status: string
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
|
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function readString(record: Record<string, unknown>, key: string): string {
|
||||||
|
+ const value = record[key]
|
||||||
|
+ return typeof value === 'string' ? value : ''
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function decodePayload(payload: unknown): GuanghuPortalPayload | null {
|
||||||
|
+ if (!isRecord(payload)) return null
|
||||||
|
+ const source = readString(payload, 'source')
|
||||||
|
+ const title = readString(payload, 'title')
|
||||||
|
+ const target = readString(payload, 'target')
|
||||||
|
+ if (!source || !title || !target) return null
|
||||||
|
+ return {
|
||||||
|
+ source,
|
||||||
|
+ title,
|
||||||
|
+ target,
|
||||||
|
+ description: readString(payload, 'description'),
|
||||||
|
+ status: readString(payload, 'status'),
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function readFenceMetadata(info: string): Record<string, never> | null {
|
||||||
|
+ return info.trim().toLowerCase() === 'guanghu-portal' ? {} : null
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function buildPayload({ lines, start, end }: DurableFencePayloadInput): GuanghuPortalPayload {
|
||||||
|
+ const source = lines.slice(start, end + 1).join('')
|
||||||
|
+ const body = lines.slice(start + 1, end).join('').trim()
|
||||||
|
+ try {
|
||||||
|
+ const decoded = decodePayload({ ...JSON.parse(body), source })
|
||||||
|
+ if (decoded) return decoded
|
||||||
|
+ } catch {
|
||||||
|
+ // Invalid card data remains visible as an ordinary code block.
|
||||||
|
+ }
|
||||||
|
+ return { source, title: '光湖入口', target: '', description: body, status: '配置错误' }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function buildBlock(block: BlockLike, payload: GuanghuPortalPayload): BlockLike {
|
||||||
|
+ if (!payload.target) return block
|
||||||
|
+ return {
|
||||||
|
+ ...block,
|
||||||
|
+ type: GUANGHU_PORTAL_BLOCK_TYPE,
|
||||||
|
+ props: {
|
||||||
|
+ ...(block.props ?? {}),
|
||||||
|
+ source: payload.source,
|
||||||
|
+ title: payload.title,
|
||||||
|
+ target: payload.target,
|
||||||
|
+ description: payload.description,
|
||||||
|
+ status: payload.status,
|
||||||
|
+ },
|
||||||
|
+ content: undefined,
|
||||||
|
+ children: [],
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function isPortalBlock(block: BlockLike): boolean {
|
||||||
|
+ return block.type === GUANGHU_PORTAL_BLOCK_TYPE
|
||||||
|
+ && typeof block.props?.source === 'string'
|
||||||
|
+ && typeof block.props?.target === 'string'
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+export const guanghuPortalMarkdownCodec: DurableBlockCodec = {
|
||||||
|
+ tokenPrefix: TOKEN_PREFIX,
|
||||||
|
+ tokenSuffix: TOKEN_SUFFIX,
|
||||||
|
+ readFenceMetadata,
|
||||||
|
+ buildPayload,
|
||||||
|
+ decodePayload,
|
||||||
|
+ buildBlock: (block, payload) => buildBlock(block, payload as GuanghuPortalPayload),
|
||||||
|
+ isBlock: isPortalBlock,
|
||||||
|
+ serializeBlock: block => block.props?.source ?? '',
|
||||||
|
+}
|
||||||
|
diff --git a/src/utils/wikilink.test.ts b/src/utils/wikilink.test.ts
|
||||||
|
index ed7864e..4aa125e 100644
|
||||||
|
--- a/src/utils/wikilink.test.ts
|
||||||
|
+++ b/src/utils/wikilink.test.ts
|
||||||
|
@@ -273,6 +273,29 @@ describe('canonicalWikilinkTargetForTitle', () => {
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
+describe('Unicode wikilink resolution', () => {
|
||||||
|
+ it('resolves Chinese and emoji titles across equivalent Unicode forms', () => {
|
||||||
|
+ const entry = makeEntry({
|
||||||
|
+ path: '/vault/第五域/🌳 铸渊 · 导航地图.md',
|
||||||
|
+ filename: '🌳 铸渊 · 导航地图.md',
|
||||||
|
+ title: '🌳 铸渊 · 导航地图',
|
||||||
|
+ })
|
||||||
|
+
|
||||||
|
+ expect(resolveEntry([entry], '🌳 铸渊 · 导航地图')).toBe(entry)
|
||||||
|
+ expect(resolveEntry([entry], '🌳 鑄淵 · 導航地圖')).toBeUndefined()
|
||||||
|
+ })
|
||||||
|
+
|
||||||
|
+ it('resolves an imported file with an id suffix by its heading title', () => {
|
||||||
|
+ const entry = makeEntry({
|
||||||
|
+ path: '/vault/🧭 霜砚 · 总控人格系统 · 母语导航页 b8463f86479348139b5744dd5e995c53.md',
|
||||||
|
+ filename: '🧭 霜砚 · 总控人格系统 · 母语导航页 b8463f86479348139b5744dd5e995c53.md',
|
||||||
|
+ title: '🧭 霜砚 · 总控人格系统 · 母语导航页',
|
||||||
|
+ })
|
||||||
|
+
|
||||||
|
+ expect(resolveEntry([entry], '🧭 霜砚 · 总控人格系统 · 母语导航页')).toBe(entry)
|
||||||
|
+ })
|
||||||
|
+})
|
||||||
|
+
|
||||||
|
describe('formatWikilinkRef', () => {
|
||||||
|
it('wraps a canonical target in wikilink syntax', () => {
|
||||||
|
expect(formatWikilinkRef('projects/alpha')).toBe('[[projects/alpha]]')
|
||||||
|
--
|
||||||
|
2.50.1 (Apple Git-155)
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user