Add support for wysiwyg markdown preview

This commit is contained in:
gsb
2026-04-29 05:01:51 +00:00
parent 86d59877f1
commit 4237a3f6a2
10 changed files with 430 additions and 72 deletions
+17 -11
View File
@@ -6,7 +6,7 @@ import { HopDown } from './hopdown';
import { defaultTheme } from './default-theme';
import { ThemeManager } from './theme-manager';
import { RibbitEmitter, type RibbitEventMap } from './events';
import { buildMacroTags, type MacroDef } from './macros';
import { type MacroDef } from './macros';
import type { RibbitTheme } from './types';
export interface RibbitSettings {
@@ -174,14 +174,11 @@ export class Ribbit {
setState(newState: string): void {
const previous = this.state;
if (previous) {
this.element.classList.remove(previous);
}
this.state = newState;
Object.values(this.states).forEach(state => {
if (state === newState) {
this.element.classList.add(state);
} else {
this.element.classList.remove(state);
}
});
this.element.classList.add(newState);
this.emitter.emit('modeChange', {
current: newState,
previous,
@@ -193,14 +190,14 @@ export class Ribbit {
}
getHTML(): string {
if (this.changed || !this.cachedHTML) {
if (this.cachedHTML === null) {
this.cachedHTML = this.markdownToHTML(this.getMarkdown());
}
return this.cachedHTML;
}
getMarkdown(): string {
if (!this.cachedMarkdown) {
if (this.cachedMarkdown === null) {
this.cachedMarkdown = this.element.textContent || '';
}
return this.cachedMarkdown;
@@ -226,12 +223,21 @@ export class Ribbit {
this.element.contentEditable = 'false';
}
/**
* Invalidate cached markdown and HTML. Called when content changes.
* The next call to getMarkdown() or getHTML() will recompute.
*/
invalidateCache(): void {
this.changed = true;
this.cachedMarkdown = null;
this.cachedHTML = null;
}
/**
* Notify that content has changed. Called internally by the editor
* on input events. Fires the 'change' event with current content.
*/
notifyChange(): void {
this.changed = true;
this.emitter.emit('change', {
markdown: this.getMarkdown(),
html: this.getHTML(),