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:
@@ -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
@@ -775,43 +775,31 @@ const extractInlineCodes = (text, codes) => {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* 单遍内联扫描正则(模块级常量,避免每次调用重新编译)
|
||||
*/
|
||||
const INLINE_RE = new RegExp([
|
||||
'(!\\[[^\\]]*\\]\\([^)]+\\))',
|
||||
'|(?<!!)(\\[[^\\]]+\\]\\([^)]+\\))',
|
||||
'|(!\\[[^\\]]*\\]\\[[^\\]]*\\])',
|
||||
'|(?<!!)(\\[[^\\]]+\\]\\[[^\\]]*\\])',
|
||||
'|(<https?:\\/\\/[^\\s&]+>)',
|
||||
'|(\\*\\*[^*\\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([
|
||||
// 图片 
|
||||
'(!\\[[^\\]]*\\]\\([^)]+\\))',
|
||||
// 链接 [...](...) - 需要忽略图片前缀
|
||||
'|(?<!!)(\\[[^\\]]+\\]\\([^)]+\\))',
|
||||
// 图片引用 ![...][...]
|
||||
'|(!\\[[^\\]]*\\]\\[[^\\]]*\\])',
|
||||
// 链接引用 [...][...] 或快捷引用 [...][]
|
||||
'|(?<!!)(\\[[^\\]]+\\]\\[[^\\]]*\\])',
|
||||
// 自动链接已经转义的 <url>
|
||||
'|(<https?:\\/\\/[^\\s&]+>)',
|
||||
// 粗体 **...**(内容不跨换行)
|
||||
'|(\\*\\*[^*\\n][^*\\n]*?\\*\\*)',
|
||||
// 粗体 __...__
|
||||
'|(__[^_\\n][^_\\n]*?__)',
|
||||
// 删除线 ~~...~~(放在斜体之前防歧义)
|
||||
'|(~~[^\\n]+?~~)',
|
||||
// 高亮 ==...==
|
||||
'|(==[^\\n]+?==)',
|
||||
// 斜体 *...*(非贪婪,需避开 **)
|
||||
'|((?<=^|[^*])\\*(?!\\*)([^*\\n]+?)\\*(?!\\*))',
|
||||
// 斜体 _..._(非贪婪,需避开 __)
|
||||
'|((?<=^|[^_])_(?!_)([^_\\n]+?)_(?!_))',
|
||||
// 上标 ^...^(非空白,不跨行)
|
||||
'|(\\^[^\\s^][^\\s^]*?\\^)',
|
||||
// 下标 ~...~(非空白,不跨行,排除 ~~ 删除线)
|
||||
'|(~[^\\s~][^\\s~]*?~)',
|
||||
// 行内公式 $...$(非 $$)
|
||||
'|(?<!\\$)(\\$(?!\\$)[^\\n]+?\\$(?!\\$))',
|
||||
// 脚注引用 [^...]
|
||||
'|(\\[\\^[^\\]]+\\])',
|
||||
].join(''), 'g');
|
||||
|
||||
// 先保护代码占位符 \u0000N\u0000,避免被正则破坏
|
||||
const placeholderMap = new Map();
|
||||
|
||||
Reference in New Issue
Block a user