fix: stability improvements — initialize _outlineTimer, extract INLINE_RE constant

- core.js: initialize this._outlineTimer = null in constructor (fixes clearTimeout(undefined))
- parser.js: extract INLINE_RE to module-level constant (avoid recompilation on every scanInline call)
This commit is contained in:
2026-07-24 11:26:10 +08:00
parent 5d9b934a2d
commit a44abea401
2 changed files with 22 additions and 33 deletions
+1
View File
@@ -109,6 +109,7 @@ class MarkdownEditor {
this._shortcuts = []; // v0.1.6: 快捷键注册表
this._contextMenuItems = []; // v0.1.6: 右键菜单项
this._customActions = {}; // 自定义工具栏动作
this._outlineTimer = null; // 大纲防抖计时器
// 渲染函数:自定义覆盖内置解析器
this._renderFn = (typeof this.config.render === 'function') ? this.config.render : parseMarkdown;
+21 -33
View File
@@ -775,43 +775,31 @@ const extractInlineCodes = (text, codes) => {
return result;
};
/**
* 单遍内联扫描正则(模块级常量,避免每次调用重新编译)
*/
const INLINE_RE = new RegExp([
'(!\\[[^\\]]*\\]\\([^)]+\\))',
'|(?<!!)(\\[[^\\]]+\\]\\([^)]+\\))',
'|(!\\[[^\\]]*\\]\\[[^\\]]*\\])',
'|(?<!!)(\\[[^\\]]+\\]\\[[^\\]]*\\])',
'|(&lt;https?:\\/\\/[^\\s&]+&gt;)',
'|(\\*\\*[^*\\n][^*\\n]*?\\*\\*)',
'|(__[^_\\n][^_\\n]*?__)',
'|(~~[^\\n]+?~~)',
'|(==[^\\n]+?==)',
'|((?<=^|[^*])\\*(?!\\*)([^*\\n]+?)\\*(?!\\*))',
'|((?<=^|[^_])_(?!_)([^_\\n]+?)_(?!_))',
'|(\\^[^\\s^][^\\s^]*?\\^)',
'|(~[^\\s~][^\\s~]*?~)',
'|(?<!\\$)(\\$(?!\\$)[^\\n]+?\\$(?!\\$))',
'|(\\[\\^[^\\]]+\\])',
].join(''), 'g');
/**
* 单遍内联扫描(将所有内联语法合并到一个正则处理)
*/
const scanInline = (s, codes, env) => {
// 组合正则:按优先级从左到右
const INLINE_RE = new RegExp([
// 图片 ![...](...)
'(!\\[[^\\]]*\\]\\([^)]+\\))',
// 链接 [...](...) - 需要忽略图片前缀
'|(?<!!)(\\[[^\\]]+\\]\\([^)]+\\))',
// 图片引用 ![...][...]
'|(!\\[[^\\]]*\\]\\[[^\\]]*\\])',
// 链接引用 [...][...] 或快捷引用 [...][]
'|(?<!!)(\\[[^\\]]+\\]\\[[^\\]]*\\])',
// 自动链接已经转义的 &lt;url&gt;
'|(&lt;https?:\\/\\/[^\\s&]+&gt;)',
// 粗体 **...**(内容不跨换行)
'|(\\*\\*[^*\\n][^*\\n]*?\\*\\*)',
// 粗体 __...__
'|(__[^_\\n][^_\\n]*?__)',
// 删除线 ~~...~~(放在斜体之前防歧义)
'|(~~[^\\n]+?~~)',
// 高亮 ==...==
'|(==[^\\n]+?==)',
// 斜体 *...*(非贪婪,需避开 **)
'|((?<=^|[^*])\\*(?!\\*)([^*\\n]+?)\\*(?!\\*))',
// 斜体 _..._(非贪婪,需避开 __)
'|((?<=^|[^_])_(?!_)([^_\\n]+?)_(?!_))',
// 上标 ^...^(非空白,不跨行)
'|(\\^[^\\s^][^\\s^]*?\\^)',
// 下标 ~...~(非空白,不跨行,排除 ~~ 删除线)
'|(~[^\\s~][^\\s~]*?~)',
// 行内公式 $...$(非 $$
'|(?<!\\$)(\\$(?!\\$)[^\\n]+?\\$(?!\\$))',
// 脚注引用 [^...]
'|(\\[\\^[^\\]]+\\])',
].join(''), 'g');
// 先保护代码占位符 \u0000N\u0000,避免被正则破坏
const placeholderMap = new Map();