feat: v0.2.2 — plugin refactor, i18n, outline tracking, formatTable, code title, fr locale
CI / test (18.x) (push) Canceled after 0s
CI / test (20.x) (push) Canceled after 0s
CI / test (22.x) (push) Canceled after 0s

## Added
- French (fr) locale with 60+ translations
- Outline panel scroll tracking with active heading highlight
- exec('formatTable') for auto-aligning Markdown table columns
- Code block title rendering via ```js title=hello.js```
- Escaped pipe \| support in table cells
- Custom block token fallback rendering as <div>
- Gutter incremental DOM update (no more full innerHTML)
- 694 tests (+10)

## Changed
- All 6 preset plugins refactored to closure-based state (no this pollution)
- shortcutHelp plugin now i18n-aware (shortcut labels follow locale)
- Context menu labels (Cut/Copy/Paste/Select All) i18n-translated
- Warm theme now has progressBg + closeHoverBg fields
This commit is contained in:
2026-07-25 09:26:54 +08:00
parent aa9f5f220e
commit de545d1da6
13 changed files with 535 additions and 187 deletions
+69
View File
@@ -1947,3 +1947,72 @@ describe('MarkdownEditor - v0.2.1 分隔条持久化', () => {
ed.destroy();
});
});
// ============ v0.2.2 formatTable 测试 ============
describe('MarkdownEditor - v0.2.2 formatTable', () => {
test('exec formatTable 对齐表格列', () => {
document.body.innerHTML = '';
const c = document.createElement('div');
document.body.appendChild(c);
const ed = new MarkdownEditor(c, { value: '| a | b |\n| --- | --- |\n| x | yyy |' });
ed.textarea.setSelectionRange(10, 10); // 光标在表格内
ed.exec('formatTable');
const v = ed.getValue();
// Both columns padded to max width
expect(v).toMatch(/\| a\s+\| b\s+\|/);
expect(v).toMatch(/\| x\s+\| yyy\s+\|/);
ed.destroy();
});
test('exec formatTable 无表格时不变', () => {
document.body.innerHTML = '';
const c = document.createElement('div');
document.body.appendChild(c);
const ed = new MarkdownEditor(c, { value: 'just some text' });
ed.exec('formatTable');
expect(ed.getValue()).toBe('just some text');
ed.destroy();
});
});
// ============ v0.2.2 gutter 增量更新 ============
describe('MarkdownEditor - v0.2.2 gutter 增量更新', () => {
test('行数减少时 gutter 正确移除多余行', () => {
document.body.innerHTML = '';
const c = document.createElement('div');
document.body.appendChild(c);
const ed = new MarkdownEditor(c, { value: 'a\nb\nc', lineNumbers: true });
expect(ed.gutter.children.length).toBe(3);
ed.setValue('a');
expect(ed.gutter.children.length).toBe(1);
ed.destroy();
});
test('行数增加时 gutter 正确追加', () => {
document.body.innerHTML = '';
const c = document.createElement('div');
document.body.appendChild(c);
const ed = new MarkdownEditor(c, { value: 'a', lineNumbers: true });
expect(ed.gutter.children.length).toBe(1);
ed.setValue('a\nb\nc\nd');
expect(ed.gutter.children.length).toBe(4);
ed.destroy();
});
});
// ============ v0.2.2 大纲滚动跟踪 ============
describe('MarkdownEditor - v0.2.2 大纲滚动跟踪', () => {
test('_trackOutlineScroll 注册滚动监听', () => {
document.body.innerHTML = '';
const c = document.createElement('div');
document.body.appendChild(c);
const ed = new MarkdownEditor(c, { value: '# H1\n## H2\n### H3', outline: true, mode: 'split' });
ed._buildOutline();
// 滚动 preview 应不抛错
expect(() => ed.previewPane.dispatchEvent(new Event('scroll'))).not.toThrow();
ed.destroy();
});
});