release: v0.1.5 — theme system usability, extensibility, external theme following
feat(themes): comprehensive theme system enhancement
- Fix resolveTheme('auto') always resolves to system theme (no stale override)
- Add per-instance theme isolation via createInstanceTheme()
- Add MarkdownEditor.setTheme()/getTheme()/getThemeContext() instance methods
- Add 'themeChange' instance event with { theme, resolved, config } payload
- Multi-instance independent themes (no cross-contamination)
feat(themes): external theme following (v0.1.5)
- followExternalTheme() — follow theme via data attr, CSS class, or callback
- adoptFromParent() — inherit theme from parent container
- watch() — watch external theme source (function or selector)
feat(themes): extensibility (v0.1.5)
- registerTheme() supports 'extends' option for theme inheritance
- exportCSSVars() — export all CSS variable values from element
- getCSSVariable() — query single CSS variable
- applyThemeToElement() — apply theme to any DOM element
chore: bump version 0.1.4 → 0.1.5 across all files
test(themes): 30 new tests covering all v0.1.5 theme APIs (499 total)
This commit is contained in:
+45
-8
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* MetonaEditor Core - 编辑器核心
|
||||
* @module core
|
||||
* @version 0.1.4
|
||||
* @version 0.1.5
|
||||
* @description MarkdownEditor 类实现:DOM 构建、事件、渲染、历史栈、选区操作、模式切换
|
||||
*/
|
||||
|
||||
@@ -11,7 +11,7 @@ import { injectStyles } from './styles.js';
|
||||
import { t as i18nT, getCurrentLocale, getLocaleDirection } from './i18n.js';
|
||||
import { parseMarkdown } from './parser.js';
|
||||
import { presetPlugins } from './plugins.js';
|
||||
import { getTheme, applyTheme, saveTheme, getThemeConfig, setThemeVariables } from './themes.js';
|
||||
import { resolveTheme, getThemeConfig, setThemeVariables, createInstanceTheme } from './themes.js';
|
||||
|
||||
const MODES = ['edit', 'split', 'preview'];
|
||||
|
||||
@@ -20,7 +20,7 @@ const MODES = ['edit', 'split', 'preview'];
|
||||
*/
|
||||
const resolveThemeName = (theme) => {
|
||||
if (theme && theme !== 'auto') return theme;
|
||||
return getTheme('auto');
|
||||
return resolveTheme('auto');
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -99,13 +99,18 @@ class MarkdownEditor {
|
||||
injectStyles();
|
||||
this._buildDOM();
|
||||
|
||||
// 主题同步:用户显式传 theme 时覆盖全局 CSS 变量并持久化,否则尊重 localStorage
|
||||
// 实例级主题管理(v0.1.5: 隔离 CSS 变量到 wrapper,支持独立主题)
|
||||
this._themeCtx = createInstanceTheme(this);
|
||||
|
||||
// 向后兼容:用户显式传 theme 时同步到全局并持久化
|
||||
if (options.theme) {
|
||||
applyTheme(this.config.theme);
|
||||
saveTheme(this.config.theme);
|
||||
// 全局同步(保留原有行为)
|
||||
if (typeof document !== 'undefined') {
|
||||
document.documentElement.setAttribute('data-md-theme', resolveTheme(options.theme));
|
||||
}
|
||||
}
|
||||
|
||||
// 将 CSS 变量限定到当前实例的 wrapper 元素,避免污染全局样式
|
||||
// 确保 CSS 变量作用到实例 wrapper
|
||||
const resolvedThemeConfig = getThemeConfig(this.config.theme);
|
||||
setThemeVariables(resolvedThemeConfig, this.el);
|
||||
|
||||
@@ -981,6 +986,38 @@ class MarkdownEditor {
|
||||
|
||||
isDestroyed() { return this._destroyed; }
|
||||
|
||||
/**
|
||||
* 设置实例主题(v0.1.5: 实例隔离,不影响其他编辑器)
|
||||
* @param {string} theme - 主题名
|
||||
* @returns {MarkdownEditor}
|
||||
*/
|
||||
setTheme(theme) {
|
||||
if (!theme) return this;
|
||||
this.config.theme = theme;
|
||||
if (this._themeCtx) {
|
||||
this._themeCtx.set(theme);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实例当前主题名
|
||||
* @returns {string}
|
||||
*/
|
||||
getTheme() {
|
||||
if (this._themeCtx) return this._themeCtx.get();
|
||||
return this.config.theme || 'auto';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实例主题上下文(高级 API)
|
||||
* 提供 syncWithElement / adopt / watch 等外部跟随能力
|
||||
* @returns {Object|null}
|
||||
*/
|
||||
getThemeContext() {
|
||||
return this._themeCtx || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取编辑器状态
|
||||
*/
|
||||
@@ -988,7 +1025,7 @@ class MarkdownEditor {
|
||||
return {
|
||||
id: this.id,
|
||||
mode: this._mode,
|
||||
theme: this.config.theme,
|
||||
theme: this.getTheme(),
|
||||
locale: getCurrentLocale(),
|
||||
fullscreen: this._fullscreen,
|
||||
readOnly: this.config.readOnly || false,
|
||||
|
||||
Reference in New Issue
Block a user