Skip to content

MDeX-2.1.1

Choose a tag to compare

@fwzheng fwzheng released this 01 Aug 06:33

v2.1.1

热修: 修复了部分文档编辑区与预览区滚动不同步的问题——编辑器滞后于预览区若干段落,且越往文档后部越明显。

Hotfix: Fixed out-of-sync scrolling between the editor and preview in some documents — the editor lagged behind the preview by several paragraphs, with the issue worsening toward the end of the document.

修复 / Fixes

  • 修复编辑↔预览块级对齐错位
    问题根因: srcBlockOffsets(预览区每个块对应的源码偏移量)原先是通过按空行 \n\n 切分源码来定义「块」的,这与 marked 解析器的实际顶层块划分逻辑不一致。
    具体而言,marked 会将「标题紧跟列表/段落(中间无空行)」的情况拆分为 heading + list 两个顶层元素,或将 loose list(松散列表)及其续文段落合并为一个 list token。这种逻辑差异导致按空行切分得到的块数与 marked 解析出的实际块数不匹配。

    错位后果: renderIntoPreview 随后使用 children[i] ↔ srcBlockOffsets[i] 的方式按下标一一对应分配 data-src-offset。一旦出现块数分歧,后续所有偏移量即开始产生单调错位。在一份包含大量「标题紧跟列表」与「列表续文段落」的测试文档中,66 个预览块里有 58 个标注了错误的偏移量。这导致 syncAnchors 的中线映射将编辑器和预览锚定到了不同的段落,表现为编辑器持续滞后于预览,且越往后偏移越严重。

    解决方案: 改用 marked.lexer 的顶层 token 在源码中按顺序定位每个块的起始偏移。这使得源码映射与预览的顶层元素严格同源、一一对应,从而彻底消除了错位。

    测试: 附带了 tools/check-align.js(块切分对比工具)与 tools/test-align-e2e.mjs(真实浏览器端到端对齐回归测试)。


    Fixed Edit↔Preview block-alignment drift
    Root Cause: srcBlockOffsets (each preview block's corresponding source offset) was originally derived by splitting the source on blank lines (\n\n). This method did not align with marked's actual top-level block parsing logic. Specifically, marked splits "a heading immediately followed by a list/paragraph (no blank line)" into two separate top-level elements (heading + list), while merging loose lists and their continuation paragraphs into a single list token. Consequently, the block count obtained by splitting on blank lines differed from marked's parsed output.

    Impact: renderIntoPreview then assigned data-src-offset by pairing children[i] with srcBlockOffsets[i] based on index. From the first point of divergence, all subsequent offsets began to drift monotonically. In a test document full of "heading-then-list" and "list-continuation" patterns, 58 out of 66 preview blocks were assigned incorrect offsets. This caused syncAnchors to map the editor and preview to different paragraphs, manifesting as the editor consistently lagging behind the preview, with the error worsening toward the end.

    Fix: The offset of each block is now located sequentially using marked.lexer's top-level tokens. This ensures the source mapping is strictly co-sourced with the preview's top-level elements in a one-to-one correspondence, eliminating the drift.

    Tests: Added tools/check-align.js (block-split diff utility) and tools/test-align-e2e.mjs (real-browser end-to-end alignment regression test).

  • 版本号升级至 2.1.1。 / Version bumped to 2.1.1.

重构 / Refactor

  • app.js 拆分(内部重构,无功能变化)
    改动内容: 将 17 种语言的界面文案(I18N,共 491 行)抽离至 src/i18n.js;将帮助文档数据(HELP_STRINGS 及其依赖项 SK/sc/CITE_HELP_*,共 1090 行)抽离至 src/help.js。此举使 src/app.js 从 6580 行缩减至 5006 行(−24%)。

    实现细节: app.js 内部通过 const X = window.X 重新引用这些模块(下游 6 处引用零改动)。build-html.mjs 现改为拼接 i18n + help + app 并内联至同一个 <script> 标签中,保持了单文件离线产物的特性,且无需引入打包器。

    验证: 经过四层验证确保功能正常:

    1. 构建成功;
    2. npm test 通过 (20/20);
    3. 真实浏览器对齐端到端测试通过(66 个块,0 错位);
    4. 运行时确认 window.I18N / window.HELP_DATA 数据完整,UI 文案与帮助文档显示正常。

    **app.js split (internal refactor, no behavior change)** **Changes:** Extracted the 17-language UI strings (`I18N`, 491 lines) into `src/i18n.js` and the help-document data (`HELP_STRINGS` plus dependencies `SK`/`sc`/`CITE_HELP_*`, 1090 lines) into `src/help.js`. This reduced `src/app.js` from 6580 to 5006 lines (−24%).

    Implementation: app.js reimports these modules via const X = window.X (zero downstream edits required). build-html.mjs now concatenates i18n + help + app into a single inlined <script> tag, preserving the self-contained offline build without a bundler.

    Verification: Verified through four layers:

    1. Build succeeds;
    2. npm test passes (20/20);
    3. Real-browser alignment e2e test passes (66 blocks, 0 drift);
    4. Runtime confirmation that window.I18N/window.HELP_DATA are fully populated, and UI labels/help docs render correctly.