markdown/.trae/documents/修复 Markdown 标记显隐与样式生效问题.md

3.9 KiB
Raw Permalink Blame History

问题定位

用户反馈“还是没有实现很多md的标签都没有生效鼠标放入的时候才显示源码”这表明

  1. CSS 样式优先级不足或选择器错误:虽然 liveMarkdownDecorations.js 添加了 DecorationLivePreviewEditor.vue 中的 CSS 类可能没生效,或者被 CodeMirror 默认样式覆盖。特别是隐藏逻辑(.cm-md-hidden-mark),如果优先级不够,opacity: 0 就不会生效,导致 # 等符号一直显示(或者变淡但仍可见)。
  2. 隐藏逻辑可能过于保守:目前的逻辑是 Decoration.replace({ widget: new HiddenWidget() }),这通常是有效的,但可能与 display: none 的处理有关。如果是 Decoration.mark 加上 opacity: 0,则需要确保光标交互逻辑正确。
  3. 语法树节点名称不匹配lezer-markdown 的节点名称可能与我想象的不完全一致(例如 ATXHeading1 vs ATXHeading + level,或者 HeaderMark 的层级关系)。需要通过打印语法树来确认真实的节点结构。
  4. 光标交互体验:用户期望的是“鼠标放入的时候才显示源码”,这通常指整块元素(如整个标题行、整个代码块、整个引用块)在非激活状态下只显示渲染后的样子,激活(光标进入)时才显示 Markdown 源码标记。目前的实现可能只是针对标记本身(如 #)做了显隐,但整体视觉变化不够明显,或者光标判断逻辑(isCursorInRange)导致在行内移动时频繁闪烁。

解决方案

1. 调试与确认节点名称 (Debug & Verify)

  • 编写一个简单的 console.log 遍历器,在控制台打印当前文档的 syntax tree 结构,确认 HeaderMark, QuoteMark, FencedCode, CodeMark 等节点的准确名称和嵌套关系。

2. 增强隐藏策略 (Robust Hiding)

  • 强制隐藏:对于 Decoration.replace 使用的 HiddenWidget,确保 span.style.display = 'none' 生效。
  • CSS 覆盖:在 LivePreviewEditor.vue 中使用 !important 或更高优先级的选择器来确保隐藏样式(opacity: 0font-size: 0)生效。
  • 针对不同标记的策略
    • # (Heading): 使用 Decoration.replace 替换为空白 Widget占位为0光标进入时移除替换。
    • **(CodeFence)**: 首行和尾行的 标记,在非激活状态下使用 Decoration.replace 隐藏。
    • > (Quote): 同样使用 Decoration.replace

3. 优化光标感知逻辑 (Refine Interaction)

  • 目前逻辑是 isCursorInRange(state, nodeFrom, nodeTo)。对于块级元素(如 FencedCode应该检查光标是否在整块范围内,而不仅仅是标记范围。
  • 代码块优化
    • 当光标在代码块内部时,显示首尾的 ``` 和语言标识。
    • 当光标离开代码块时,隐藏首尾的 ```,保留语言标识(或显示为右上角小标签)。

4. 完善样式 (Polishing Styles)

  • 确保 H1-H6 的字体大小、粗细、下划线足够明显。
  • 代码块背景色需要更明显的区分(目前可能太浅)。
  • 引用块的左侧竖线颜色加深。

实施计划

  1. Debug: 在 liveMarkdownDecorations.js 中临时加入日志,确认节点名。
  2. Refactor JS:
    • 修正节点匹配逻辑(基于 Debug 结果)。
    • 统一使用 Decoration.replace 处理需要隐藏的标记HeaderMark, QuoteMark, ListMark等确保它们在 DOM 中彻底消失(不占位)。
    • 优化 FencedCode 的处理:识别整个块,判断光标是否在块内。
  3. Update CSS: 增强 CSS 规则,确保样式生效。
  4. Verify: 自测 H1, Quote, CodeBlock 的显隐效果。