release: v0.1.6 — plugin v2, i18n instance isolation, shortcuts, toolbar, toast
feat(plugins): plugin system v2
- depends: declarative plugin dependencies with topological sort (Kahn algorithm)
- async plugins: install() returning Promise auto-await
- editor.unuse(name): uninstall individual plugins
- pluginUtils.validateConfig(schema, config): configuration validation
- plugin priority field controls install order within same dependency level
feat(i18n): instance-level locale isolation, pluralization, dynamic loading
- createInstanceI18n(): per-editor independent locale contexts
- editor.setLocale()/getLocale()/t() instance methods
- Plural rules: t('items', { count: 5 }) auto-selects one/other/few/many
- i18nUtils.loadRemote(url, locale): fetch translation packs from remote
- editor.on('localeChange') event
feat(core): toolbar & shortcut customization, context menu, toast
- editor.registerShortcut(combo, handler): custom keyboard shortcuts
- editor.configureToolbar(tools): dynamic toolbar rebuild
- editor.removeToolbarButton(action): remove single button
- editor.registerContextMenu(items): right-click context menu
- editor.toast(msg, {type, duration, animation}): toast notifications
style: toast notifications, context menu, dropdown CSS
- .me-toast with success/error/warning/info types, fade/slide animations
- .me-context-menu with items, separators, shortcut hints
test: 22 new tests covering plugin deps, unuse, shortcuts, toast, i18n plural (521 total)
chore: bump version 0.1.5 → 0.1.6 across all files, site, types
This commit is contained in:
@@ -410,3 +410,78 @@ describe('createI18nManager', () => {
|
||||
expect(m.t('bold')).toBe('Bold');
|
||||
});
|
||||
});
|
||||
|
||||
// ============ v0.1.6 新增测试 ============
|
||||
|
||||
describe('v0.1.6 实例级 i18n', () => {
|
||||
const { createInstanceI18n } = require('../src/i18n.js');
|
||||
|
||||
test('createInstanceI18n 创建独立上下文', () => {
|
||||
const mockEditor = {
|
||||
config: { locale: 'en-US' },
|
||||
el: document.createElement('div'),
|
||||
textarea: document.createElement('textarea'),
|
||||
toolbarEl: document.createElement('div'),
|
||||
_emit: jest.fn(),
|
||||
};
|
||||
document.body.appendChild(mockEditor.el);
|
||||
const ctx = createInstanceI18n(mockEditor);
|
||||
expect(ctx.get()).toBe('en-US');
|
||||
expect(typeof ctx.set).toBe('function');
|
||||
expect(typeof ctx.t).toBe('function');
|
||||
document.body.removeChild(mockEditor.el);
|
||||
});
|
||||
|
||||
test('实例 setLocale 触发 localeChange 事件', () => {
|
||||
const mockEditor = {
|
||||
config: { locale: 'zh-CN' },
|
||||
el: document.createElement('div'),
|
||||
textarea: document.createElement('textarea'),
|
||||
toolbarEl: document.createElement('div'),
|
||||
_emit: jest.fn(),
|
||||
};
|
||||
document.body.appendChild(mockEditor.el);
|
||||
const ctx = createInstanceI18n(mockEditor);
|
||||
ctx.set('en-US');
|
||||
expect(mockEditor._emit).toHaveBeenCalledWith('localeChange', expect.objectContaining({ locale: 'en-US' }));
|
||||
document.body.removeChild(mockEditor.el);
|
||||
});
|
||||
|
||||
test('实例 t 函数正确翻译', () => {
|
||||
const mockEditor = {
|
||||
config: { locale: 'zh-CN' },
|
||||
el: document.createElement('div'),
|
||||
textarea: document.createElement('textarea'),
|
||||
toolbarEl: document.createElement('div'),
|
||||
_emit: jest.fn(),
|
||||
};
|
||||
document.body.appendChild(mockEditor.el);
|
||||
const ctx = createInstanceI18n(mockEditor);
|
||||
expect(ctx.t('bold')).toBe('粗体');
|
||||
document.body.removeChild(mockEditor.el);
|
||||
});
|
||||
});
|
||||
|
||||
describe('v0.1.6 复数规则', () => {
|
||||
const { addTranslations, t, setCurrentLocale } = require('../src/i18n.js');
|
||||
|
||||
beforeEach(() => {
|
||||
setCurrentLocale('en-US');
|
||||
});
|
||||
|
||||
test('单数 one 形式', () => {
|
||||
addTranslations('en-US', { items: { one: '{count} item', other: '{count} items' } });
|
||||
expect(t('items', { count: 1 })).toBe('1 item');
|
||||
});
|
||||
|
||||
test('复数 other 形式', () => {
|
||||
addTranslations('en-US', { items: { one: '{count} item', other: '{count} items' } });
|
||||
expect(t('items', { count: 5 })).toBe('5 items');
|
||||
});
|
||||
|
||||
test('中文 always other', () => {
|
||||
addTranslations('zh-CN', { items: { other: '{count} 个项目' } });
|
||||
setCurrentLocale('zh-CN');
|
||||
expect(t('items', { count: 3 })).toBe('3 个项目');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user