release: v0.5.0 — 覆盖率96.42%达标、lint零警告、覆盖率门禁、CI强化、发布自动化
- 覆盖率 96.42%(行):新增 59 测试共 385 个,覆盖 DOM 交互事件、对话框按钮交互、Intl/localStorage 异常路径、React 渲染生命周期 - 测试环境重构:SSR 分支用 defineProperty 真正覆盖 document/window;新增 tests/dom.test.ts、tests/setup.ts - jest 覆盖率门禁 lines >= 95%;CI lint 改必过;新增 publish.yml(v* tag 自动发布到 Gitea registry) - 修复:Toast.off 空数组残留、Toast.on 取消函数 this 绑定、action close:false 冒泡关闭、use() 重复注册钩子、i18n catch 引用错误 - 删除死代码 autoApplySystemTheme;lint 零警告(no-console 策略 + caughtErrorsIgnorePattern)
This commit is contained in:
+22
-13
@@ -1,12 +1,11 @@
|
||||
/**
|
||||
* MetonaToast API — meToast 核心 API 对象
|
||||
* @module api
|
||||
* @version 0.4.0
|
||||
* @version 0.5.0
|
||||
*/
|
||||
|
||||
import { Toast, _containerCache } from './toast.js';
|
||||
import { DEFAULTS, VERSION } from './constants.js';
|
||||
import { escapeHTML } from './utils.js';
|
||||
import { t, setCurrentLocale } from './i18n.js';
|
||||
import { applyTheme } from './themes.js';
|
||||
import { confirmHTML, promptHTML, progressHTML, actionHTML } from './templates.js';
|
||||
@@ -395,8 +394,10 @@ const meToast: MeToast = {
|
||||
actions.forEach((a, i) => {
|
||||
const btn = toast.el?.querySelector(`.met-action-btn-${i}`) as HTMLElement | null;
|
||||
if (btn && typeof a.onClick === 'function') {
|
||||
btn.addEventListener('click', () => {
|
||||
try { a.onClick(toast); } catch (e) { console.error('Action onClick error:', e); }
|
||||
btn.addEventListener('click', (e: Event) => {
|
||||
// 阻止冒泡到 toast 的 closeOnClick 处理器,由 close 选项控制是否关闭
|
||||
e.stopPropagation();
|
||||
try { a.onClick(toast); } catch (err) { console.error('Action onClick error:', err); }
|
||||
if (a.close !== false) toast.close();
|
||||
});
|
||||
}
|
||||
@@ -658,22 +659,30 @@ const meToast: MeToast = {
|
||||
}
|
||||
this.plugins.register(plugin, { ...preset, ...options });
|
||||
|
||||
// 连接插件钩子
|
||||
// 连接插件钩子(重复 use 前先卸载旧钩子,防止重复注册)
|
||||
// 注意:off 引用存在已注册的插件对象上(stored),uninstall 时 this 即该对象
|
||||
const stored = this.plugins.get(plugin) as (Record<string, unknown> & Plugin) | null;
|
||||
if (plugin === 'accessibility') {
|
||||
Toast.on('afterShow', (toast: ToastInstance) => {
|
||||
const acc = preset as Record<string, (t: ToastInstance) => void>;
|
||||
if (typeof acc.announce === 'function') acc.announce(toast);
|
||||
});
|
||||
if (stored && typeof stored._off === 'function') { (stored._off as () => void)(); }
|
||||
const acc = preset as Record<string, (t: ToastInstance) => void>;
|
||||
if (stored) {
|
||||
stored._off = Toast.on('afterShow', (toast: ToastInstance) => {
|
||||
if (typeof acc.announce === 'function') acc.announce(toast);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (plugin === 'persistence') {
|
||||
if (stored && typeof stored._saveOff === 'function') { (stored._saveOff as () => void)(); }
|
||||
const saved = typeof preset.install === 'function'
|
||||
? preset.install(this.plugins as unknown as import('./types.js').PluginManager)
|
||||
: null;
|
||||
if (saved) this.configure(saved as Partial<ToastConfig>);
|
||||
Toast.on('afterClose', () => {
|
||||
const p = preset as Record<string, (c: unknown) => void>;
|
||||
if (typeof p.save === 'function') p.save(this.getConfig());
|
||||
});
|
||||
const p = preset as Record<string, (c: unknown) => void>;
|
||||
if (stored) {
|
||||
stored._saveOff = Toast.on('afterClose', () => {
|
||||
if (typeof p.save === 'function') p.save(this.getConfig());
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (plugin && typeof plugin === 'object') {
|
||||
this.plugins.register(plugin.name || 'custom', { ...plugin, ...options } as Plugin);
|
||||
|
||||
Reference in New Issue
Block a user